| | |
| | import { getUserAgent } from "universal-user-agent"; |
| |
|
| | |
| | var VERSION = "9.0.1"; |
| |
|
| | |
| | var userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`; |
| | var DEFAULTS = { |
| | method: "GET", |
| | baseUrl: "https://api.github.com", |
| | headers: { |
| | accept: "application/vnd.github.v3+json", |
| | "user-agent": userAgent |
| | }, |
| | mediaType: { |
| | format: "" |
| | } |
| | }; |
| |
|
| | |
| | function lowercaseKeys(object) { |
| | if (!object) { |
| | return {}; |
| | } |
| | return Object.keys(object).reduce((newObj, key) => { |
| | newObj[key.toLowerCase()] = object[key]; |
| | return newObj; |
| | }, {}); |
| | } |
| |
|
| | |
| | import { isPlainObject } from "is-plain-object"; |
| | function mergeDeep(defaults, options) { |
| | const result = Object.assign({}, defaults); |
| | Object.keys(options).forEach((key) => { |
| | if (isPlainObject(options[key])) { |
| | if (!(key in defaults)) |
| | Object.assign(result, { [key]: options[key] }); |
| | else |
| | result[key] = mergeDeep(defaults[key], options[key]); |
| | } else { |
| | Object.assign(result, { [key]: options[key] }); |
| | } |
| | }); |
| | return result; |
| | } |
| |
|
| | |
| | function removeUndefinedProperties(obj) { |
| | for (const key in obj) { |
| | if (obj[key] === void 0) { |
| | delete obj[key]; |
| | } |
| | } |
| | return obj; |
| | } |
| |
|
| | |
| | function merge(defaults, route, options) { |
| | if (typeof route === "string") { |
| | let [method, url] = route.split(" "); |
| | options = Object.assign(url ? { method, url } : { url: method }, options); |
| | } else { |
| | options = Object.assign({}, route); |
| | } |
| | options.headers = lowercaseKeys(options.headers); |
| | removeUndefinedProperties(options); |
| | removeUndefinedProperties(options.headers); |
| | const mergedOptions = mergeDeep(defaults || {}, options); |
| | if (options.url === "/graphql") { |
| | 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 `${name}=${encodeURIComponent(parameters[name])}`; |
| | }).join("&"); |
| | } |
| |
|
| | |
| | var 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 encodeReserved(str) { |
| | return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) { |
| | if (!/%[0-9A-Fa-f]/.test(part)) { |
| | part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); |
| | } |
| | return part; |
| | }).join(""); |
| | } |
| | function encodeUnreserved(str) { |
| | return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { |
| | return "%" + c.charCodeAt(0).toString(16).toUpperCase(); |
| | }); |
| | } |
| | function encodeValue(operator, value, key) { |
| | value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); |
| | if (key) { |
| | return encodeUnreserved(key) + "=" + value; |
| | } else { |
| | return value; |
| | } |
| | } |
| | function isDefined(value) { |
| | return value !== void 0 && value !== null; |
| | } |
| | function isKeyOperator(operator) { |
| | return operator === ";" || operator === "&" || operator === "?"; |
| | } |
| | function getValues(context, operator, key, modifier) { |
| | var value = context[key], result = []; |
| | if (isDefined(value) && value !== "") { |
| | if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { |
| | value = value.toString(); |
| | if (modifier && modifier !== "*") { |
| | value = value.substring(0, parseInt(modifier, 10)); |
| | } |
| | result.push( |
| | encodeValue(operator, value, isKeyOperator(operator) ? key : "") |
| | ); |
| | } else { |
| | if (modifier === "*") { |
| | if (Array.isArray(value)) { |
| | value.filter(isDefined).forEach(function(value2) { |
| | result.push( |
| | encodeValue(operator, value2, isKeyOperator(operator) ? key : "") |
| | ); |
| | }); |
| | } else { |
| | Object.keys(value).forEach(function(k) { |
| | if (isDefined(value[k])) { |
| | result.push(encodeValue(operator, value[k], k)); |
| | } |
| | }); |
| | } |
| | } else { |
| | const tmp = []; |
| | if (Array.isArray(value)) { |
| | value.filter(isDefined).forEach(function(value2) { |
| | tmp.push(encodeValue(operator, value2)); |
| | }); |
| | } else { |
| | Object.keys(value).forEach(function(k) { |
| | if (isDefined(value[k])) { |
| | tmp.push(encodeUnreserved(k)); |
| | tmp.push(encodeValue(operator, value[k].toString())); |
| | } |
| | }); |
| | } |
| | if (isKeyOperator(operator)) { |
| | result.push(encodeUnreserved(key) + "=" + tmp.join(",")); |
| | } else if (tmp.length !== 0) { |
| | result.push(tmp.join(",")); |
| | } |
| | } |
| | } |
| | } else { |
| | if (operator === ";") { |
| | if (isDefined(value)) { |
| | result.push(encodeUnreserved(key)); |
| | } |
| | } else if (value === "" && (operator === "&" || operator === "?")) { |
| | result.push(encodeUnreserved(key) + "="); |
| | } else if (value === "") { |
| | result.push(""); |
| | } |
| | } |
| | return result; |
| | } |
| | function parseUrl(template) { |
| | return { |
| | expand: expand.bind(null, template) |
| | }; |
| | } |
| | function expand(template, context) { |
| | var operators = ["+", "#", ".", "/", ";", "?", "&"]; |
| | return template.replace( |
| | /\{([^\{\}]+)\}|([^\{\}]+)/g, |
| | function(_, expression, literal) { |
| | if (expression) { |
| | let operator = ""; |
| | const values = []; |
| | if (operators.indexOf(expression.charAt(0)) !== -1) { |
| | operator = expression.charAt(0); |
| | expression = expression.substr(1); |
| | } |
| | expression.split(/,/g).forEach(function(variable) { |
| | var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); |
| | values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3])); |
| | }); |
| | if (operator && operator !== "+") { |
| | var separator = ","; |
| | if (operator === "?") { |
| | separator = "&"; |
| | } else if (operator !== "#") { |
| | separator = operator; |
| | } |
| | return (values.length !== 0 ? operator : "") + values.join(separator); |
| | } else { |
| | return values.join(","); |
| | } |
| | } else { |
| | return encodeReserved(literal); |
| | } |
| | } |
| | ); |
| | } |
| |
|
| | |
| | function parse(options) { |
| | let method = options.method.toUpperCase(); |
| | 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" |
| | ]); |
| | const urlVariableNames = extractUrlVariableNames(url); |
| | url = parseUrl(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 isBinaryRequest = /application\/octet-stream/i.test(headers.accept); |
| | if (!isBinaryRequest) { |
| | if (options.mediaType.format) { |
| | headers.accept = headers.accept.split(/,/).map( |
| | (format) => format.replace( |
| | /application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, |
| | `application/vnd$1$2.${options.mediaType.format}` |
| | ) |
| | ).join(","); |
| | } |
| | if (url.endsWith("/graphql")) { |
| | 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 ? `.${options.mediaType.format}` : "+json"; |
| | return `application/vnd.github.${preview}-preview${format}`; |
| | }).join(","); |
| | } |
| | } |
| | } |
| | 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; |
| | } |
| | } |
| | } |
| | if (!headers["content-type"] && typeof body !== "undefined") { |
| | headers["content-type"] = "application/json; charset=utf-8"; |
| | } |
| | if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") { |
| | body = ""; |
| | } |
| | 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 DEFAULTS2 = merge(oldDefaults, newDefaults); |
| | const endpoint2 = endpointWithDefaults.bind(null, DEFAULTS2); |
| | return Object.assign(endpoint2, { |
| | DEFAULTS: DEFAULTS2, |
| | defaults: withDefaults.bind(null, DEFAULTS2), |
| | merge: merge.bind(null, DEFAULTS2), |
| | parse |
| | }); |
| | } |
| |
|
| | |
| | var endpoint = withDefaults(null, DEFAULTS); |
| | export { |
| | endpoint |
| | }; |
| |
|