234 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			234 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import deepmerge from 'deepmerge';
							 | 
						||
| 
								 | 
							
								import isPlainObject from 'is-plain-object';
							 | 
						||
| 
								 | 
							
								import urlTemplate from 'url-template';
							 | 
						||
| 
								 | 
							
								import getUserAgent from 'universal-user-agent';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _slicedToArray(arr, i) {
							 | 
						||
| 
								 | 
							
								  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _arrayWithHoles(arr) {
							 | 
						||
| 
								 | 
							
								  if (Array.isArray(arr)) return arr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _iterableToArrayLimit(arr, i) {
							 | 
						||
| 
								 | 
							
								  var _arr = [];
							 | 
						||
| 
								 | 
							
								  var _n = true;
							 | 
						||
| 
								 | 
							
								  var _d = false;
							 | 
						||
| 
								 | 
							
								  var _e = undefined;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
							 | 
						||
| 
								 | 
							
								      _arr.push(_s.value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (i && _arr.length === i) break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } catch (err) {
							 | 
						||
| 
								 | 
							
								    _d = true;
							 | 
						||
| 
								 | 
							
								    _e = err;
							 | 
						||
| 
								 | 
							
								  } finally {
							 | 
						||
| 
								 | 
							
								    try {
							 | 
						||
| 
								 | 
							
								      if (!_n && _i["return"] != null) _i["return"]();
							 | 
						||
| 
								 | 
							
								    } finally {
							 | 
						||
| 
								 | 
							
								      if (_d) throw _e;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return _arr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _nonIterableRest() {
							 | 
						||
| 
								 | 
							
								  throw new TypeError("Invalid attempt to destructure non-iterable instance");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function lowercaseKeys(object) {
							 | 
						||
| 
								 | 
							
								  if (!object) {
							 | 
						||
| 
								 | 
							
								    return {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return Object.keys(object).reduce((newObj, key) => {
							 | 
						||
| 
								 | 
							
								    newObj[key.toLowerCase()] = object[key];
							 | 
						||
| 
								 | 
							
								    return newObj;
							 | 
						||
| 
								 | 
							
								  }, {});
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function merge(defaults, route, options) {
							 | 
						||
| 
								 | 
							
								  if (typeof route === "string") {
							 | 
						||
| 
								 | 
							
								    let _route$split = route.split(" "),
							 | 
						||
| 
								 | 
							
								        _route$split2 = _slicedToArray(_route$split, 2),
							 | 
						||
| 
								 | 
							
								        method = _route$split2[0],
							 | 
						||
| 
								 | 
							
								        url = _route$split2[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    options = Object.assign(url ? {
							 | 
						||
| 
								 | 
							
								      method,
							 | 
						||
| 
								 | 
							
								      url
							 | 
						||
| 
								 | 
							
								    } : {
							 | 
						||
| 
								 | 
							
								      url: method
							 | 
						||
| 
								 | 
							
								    }, options);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    options = route || {};
							 | 
						||
| 
								 | 
							
								  } // lowercase header names before merging with defaults to avoid duplicates
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  options.headers = lowercaseKeys(options.headers);
							 | 
						||
| 
								 | 
							
								  const mergedOptions = deepmerge.all([defaults, options].filter(Boolean), {
							 | 
						||
| 
								 | 
							
								    isMergeableObject: isPlainObject
							 | 
						||
| 
								 | 
							
								  }); // mediaType.previews arrays are merged, instead of overwritten
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (defaults && defaults.mediaType.previews.length) {
							 | 
						||
| 
								 | 
							
								    mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, ""));
							 | 
						||
| 
								 | 
							
								  return mergedOptions;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function addQueryParameters(url, parameters) {
							 | 
						||
| 
								 | 
							
								  const separator = /\?/.test(url) ? "&" : "?";
							 | 
						||
| 
								 | 
							
								  const names = Object.keys(parameters);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (names.length === 0) {
							 | 
						||
| 
								 | 
							
								    return url;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return url + separator + names.map(name => {
							 | 
						||
| 
								 | 
							
								    if (name === "q") {
							 | 
						||
| 
								 | 
							
								      return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return "".concat(name, "=").concat(encodeURIComponent(parameters[name]));
							 | 
						||
| 
								 | 
							
								  }).join("&");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const urlVariableRegex = /\{[^}]+\}/g;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function removeNonChars(variableName) {
							 | 
						||
| 
								 | 
							
								  return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function extractUrlVariableNames(url) {
							 | 
						||
| 
								 | 
							
								  const matches = url.match(urlVariableRegex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!matches) {
							 | 
						||
| 
								 | 
							
								    return [];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function omit(object, keysToOmit) {
							 | 
						||
| 
								 | 
							
								  return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => {
							 | 
						||
| 
								 | 
							
								    obj[key] = object[key];
							 | 
						||
| 
								 | 
							
								    return obj;
							 | 
						||
| 
								 | 
							
								  }, {});
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function parse(options) {
							 | 
						||
| 
								 | 
							
								  // https://fetch.spec.whatwg.org/#methods
							 | 
						||
| 
								 | 
							
								  let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let url = options.url.replace(/:([a-z]\w+)/g, "{+$1}");
							 | 
						||
| 
								 | 
							
								  let headers = Object.assign({}, options.headers);
							 | 
						||
| 
								 | 
							
								  let body;
							 | 
						||
| 
								 | 
							
								  let parameters = omit(options, ["method", "baseUrl", "url", "headers", "request", "mediaType"]); // extract variable names from URL to calculate remaining variables later
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const urlVariableNames = extractUrlVariableNames(url);
							 | 
						||
| 
								 | 
							
								  url = urlTemplate.parse(url).expand(parameters);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!/^http/.test(url)) {
							 | 
						||
| 
								 | 
							
								    url = options.baseUrl + url;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat("baseUrl");
							 | 
						||
| 
								 | 
							
								  const remainingParameters = omit(parameters, omittedParameters);
							 | 
						||
| 
								 | 
							
								  const isBinaryRequset = /application\/octet-stream/i.test(headers.accept);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!isBinaryRequset) {
							 | 
						||
| 
								 | 
							
								    if (options.mediaType.format) {
							 | 
						||
| 
								 | 
							
								      // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
							 | 
						||
| 
								 | 
							
								      headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, "application/vnd$1$2.".concat(options.mediaType.format))).join(",");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (options.mediaType.previews.length) {
							 | 
						||
| 
								 | 
							
								      const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
							 | 
						||
| 
								 | 
							
								      headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => {
							 | 
						||
| 
								 | 
							
								        const format = options.mediaType.format ? ".".concat(options.mediaType.format) : "+json";
							 | 
						||
| 
								 | 
							
								        return "application/vnd.github.".concat(preview, "-preview").concat(format);
							 | 
						||
| 
								 | 
							
								      }).join(",");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } // for GET/HEAD requests, set URL query parameters from remaining parameters
							 | 
						||
| 
								 | 
							
								  // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (["GET", "HEAD"].includes(method)) {
							 | 
						||
| 
								 | 
							
								    url = addQueryParameters(url, remainingParameters);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    if ("data" in remainingParameters) {
							 | 
						||
| 
								 | 
							
								      body = remainingParameters.data;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      if (Object.keys(remainingParameters).length) {
							 | 
						||
| 
								 | 
							
								        body = remainingParameters;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        headers["content-length"] = 0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } // default content-type for JSON if body is set
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!headers["content-type"] && typeof body !== "undefined") {
							 | 
						||
| 
								 | 
							
								    headers["content-type"] = "application/json; charset=utf-8";
							 | 
						||
| 
								 | 
							
								  } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
							 | 
						||
| 
								 | 
							
								  // fetch does not allow to set `content-length` header, but we can set body to an empty string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
							 | 
						||
| 
								 | 
							
								    body = "";
							 | 
						||
| 
								 | 
							
								  } // Only return body/request keys if present
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return Object.assign({
							 | 
						||
| 
								 | 
							
								    method,
							 | 
						||
| 
								 | 
							
								    url,
							 | 
						||
| 
								 | 
							
								    headers
							 | 
						||
| 
								 | 
							
								  }, typeof body !== "undefined" ? {
							 | 
						||
| 
								 | 
							
								    body
							 | 
						||
| 
								 | 
							
								  } : null, options.request ? {
							 | 
						||
| 
								 | 
							
								    request: options.request
							 | 
						||
| 
								 | 
							
								  } : null);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function endpointWithDefaults(defaults, route, options) {
							 | 
						||
| 
								 | 
							
								  return parse(merge(defaults, route, options));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function withDefaults(oldDefaults, newDefaults) {
							 | 
						||
| 
								 | 
							
								  const DEFAULTS = merge(oldDefaults, newDefaults);
							 | 
						||
| 
								 | 
							
								  const endpoint = endpointWithDefaults.bind(null, DEFAULTS);
							 | 
						||
| 
								 | 
							
								  return Object.assign(endpoint, {
							 | 
						||
| 
								 | 
							
								    DEFAULTS,
							 | 
						||
| 
								 | 
							
								    defaults: withDefaults.bind(null, DEFAULTS),
							 | 
						||
| 
								 | 
							
								    merge: merge.bind(null, DEFAULTS),
							 | 
						||
| 
								 | 
							
								    parse
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const VERSION = "0.0.0-development";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const userAgent = "octokit-endpoint.js/".concat(VERSION, " ").concat(getUserAgent());
							 | 
						||
| 
								 | 
							
								const DEFAULTS = {
							 | 
						||
| 
								 | 
							
								  method: "GET",
							 | 
						||
| 
								 | 
							
								  baseUrl: "https://api.github.com",
							 | 
						||
| 
								 | 
							
								  headers: {
							 | 
						||
| 
								 | 
							
								    accept: "application/vnd.github.v3+json",
							 | 
						||
| 
								 | 
							
								    "user-agent": userAgent
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  mediaType: {
							 | 
						||
| 
								 | 
							
								    format: "",
							 | 
						||
| 
								 | 
							
								    previews: []
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const endpoint = withDefaults(null, DEFAULTS);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export { endpoint };
							 |