2022-01-21 08:28:41 +00:00
'use strict' ;
Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
var isPlainObject = require ( 'is-plain-object' ) ;
var universalUserAgent = require ( 'universal-user-agent' ) ;
function lowercaseKeys ( object ) {
if ( ! object ) {
return { } ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
return Object . keys ( object ) . reduce ( ( newObj , key ) => {
newObj [ key . toLowerCase ( ) ] = object [ key ] ;
return newObj ;
} , { } ) ;
}
function mergeDeep ( defaults , options ) {
const result = Object . assign ( { } , defaults ) ;
Object . keys ( options ) . forEach ( key => {
if ( isPlainObject . 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 ] === undefined ) {
delete obj [ key ] ;
}
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ) ;
2023-08-17 09:47:40 +00:00
} // lowercase header names before merging with defaults to avoid duplicates
options . headers = lowercaseKeys ( options . headers ) ; // remove properties with undefined values before merging
2022-01-21 08:28:41 +00:00
removeUndefinedProperties ( options ) ;
removeUndefinedProperties ( options . headers ) ;
2023-08-17 09:47:40 +00:00
const mergedOptions = mergeDeep ( defaults || { } , options ) ; // mediaType.previews arrays are merged, instead of overwritten
2022-01-21 08:28:41 +00:00
if ( defaults && defaults . mediaType . previews . length ) {
mergedOptions . mediaType . previews = defaults . mediaType . previews . filter ( preview => ! mergedOptions . mediaType . previews . includes ( preview ) ) . concat ( mergedOptions . mediaType . previews ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( names . length === 0 ) {
return url ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
return url + separator + names . map ( name => {
if ( name === "q" ) {
return "q=" + parameters . q . split ( "+" ) . map ( encodeURIComponent ) . join ( "+" ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
return ` ${ name } = ${ encodeURIComponent ( parameters [ name ] ) } ` ;
} ) . join ( "&" ) ;
}
const urlVariableRegex = /\{[^}]+\}/g ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function removeNonChars ( variableName ) {
return variableName . replace ( /^\W+|\W+$/g , "" ) . split ( /,/ ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function extractUrlVariableNames ( url ) {
const matches = url . match ( urlVariableRegex ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( ! matches ) {
return [ ] ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ;
} , { } ) ;
}
// Based on https://github.com/bramstein/url-template, licensed under BSD
// TODO: create separate package.
//
// Copyright (c) 2012-2014, Bram Stein
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
/* istanbul ignore file */
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 , "]" ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
return part ;
} ) . join ( "" ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function encodeUnreserved ( str ) {
return encodeURIComponent ( str ) . replace ( /[!'()*]/g , function ( c ) {
return "%" + c . charCodeAt ( 0 ) . toString ( 16 ) . toUpperCase ( ) ;
} ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function encodeValue ( operator , value , key ) {
value = operator === "+" || operator === "#" ? encodeReserved ( value ) : encodeUnreserved ( value ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( key ) {
return encodeUnreserved ( key ) + "=" + value ;
} else {
return value ;
}
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function isDefined ( value ) {
return value !== undefined && value !== null ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function isKeyOperator ( operator ) {
return operator === ";" || operator === "&" || operator === "?" ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function getValues ( context , operator , key , modifier ) {
var value = context [ key ] ,
2023-08-17 09:47:40 +00:00
result = [ ] ;
2022-01-21 08:28:41 +00:00
if ( isDefined ( value ) && value !== "" ) {
if ( typeof value === "string" || typeof value === "number" || typeof value === "boolean" ) {
value = value . toString ( ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( modifier && modifier !== "*" ) {
value = value . substring ( 0 , parseInt ( modifier , 10 ) ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
result . push ( encodeValue ( operator , value , isKeyOperator ( operator ) ? key : "" ) ) ;
} else {
if ( modifier === "*" ) {
if ( Array . isArray ( value ) ) {
value . filter ( isDefined ) . forEach ( function ( value ) {
result . push ( encodeValue ( operator , value , isKeyOperator ( operator ) ? key : "" ) ) ;
} ) ;
} else {
Object . keys ( value ) . forEach ( function ( k ) {
if ( isDefined ( value [ k ] ) ) {
result . push ( encodeValue ( operator , value [ k ] , k ) ) ;
}
} ) ;
}
} else {
const tmp = [ ] ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( Array . isArray ( value ) ) {
value . filter ( isDefined ) . forEach ( function ( value ) {
tmp . push ( encodeValue ( operator , value ) ) ;
} ) ;
} else {
Object . keys ( value ) . forEach ( function ( k ) {
if ( isDefined ( value [ k ] ) ) {
tmp . push ( encodeUnreserved ( k ) ) ;
tmp . push ( encodeValue ( operator , value [ k ] . toString ( ) ) ) ;
}
} ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ( "" ) ;
}
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
return result ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function parseUrl ( template ) {
return {
expand : expand . bind ( null , template )
} ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
function expand ( template , context ) {
var operators = [ "+" , "#" , "." , "/" , ";" , "?" , "&" ] ;
return template . replace ( /\{([^\{\}]+)\}|([^\{\}]+)/g , function ( _ , expression , literal ) {
if ( expression ) {
let operator = "" ;
const values = [ ] ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( operators . indexOf ( expression . charAt ( 0 ) ) !== - 1 ) {
operator = expression . charAt ( 0 ) ;
expression = expression . substr ( 1 ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
expression . split ( /,/g ) . forEach ( function ( variable ) {
var tmp = /([^:\*]*)(?::(\d+)|(\*))?/ . exec ( variable ) ;
values . push ( getValues ( context , operator , tmp [ 1 ] , tmp [ 2 ] || tmp [ 3 ] ) ) ;
} ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( operator && operator !== "+" ) {
var separator = "," ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( operator === "?" ) {
separator = "&" ;
} else if ( operator !== "#" ) {
separator = operator ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
return ( values . length !== 0 ? operator : "" ) + values . join ( separator ) ;
} else {
return values . join ( "," ) ;
}
} else {
return encodeReserved ( literal ) ;
}
} ) ;
}
function parse ( options ) {
// https://fetch.spec.whatwg.org/#methods
2023-08-17 09:47:40 +00:00
let method = options . method . toUpperCase ( ) ; // replace :varname with {varname} to make it RFC 6570 compatible
2022-01-21 08:28:41 +00:00
let url = ( options . url || "/" ) . replace ( /:([a-z]\w+)/g , "{$1}" ) ;
let headers = Object . assign ( { } , options . headers ) ;
let body ;
2023-08-17 09:47:40 +00:00
let parameters = omit ( options , [ "method" , "baseUrl" , "url" , "headers" , "request" , "mediaType" ] ) ; // extract variable names from URL to calculate remaining variables later
2022-01-21 08:28:41 +00:00
const urlVariableNames = extractUrlVariableNames ( url ) ;
url = parseUrl ( url ) . expand ( parameters ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( ! /^http/ . test ( url ) ) {
url = options . baseUrl + url ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ) ;
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( ! isBinaryRequest ) {
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. ${ options . mediaType . format } ` ) ) . join ( "," ) ;
}
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ( "," ) ;
}
2023-08-17 09:47:40 +00:00
} // for GET/HEAD requests, set URL query parameters from remaining parameters
2022-01-21 08:28:41 +00:00
// for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ;
2023-08-17 09:47:40 +00:00
} else {
headers [ "content-length" ] = 0 ;
2022-01-21 08:28:41 +00:00
}
}
2023-08-17 09:47:40 +00:00
} // default content-type for JSON if body is set
2022-01-21 08:28:41 +00:00
if ( ! headers [ "content-type" ] && typeof body !== "undefined" ) {
headers [ "content-type" ] = "application/json; charset=utf-8" ;
2023-08-17 09:47:40 +00:00
} // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
2022-01-21 08:28:41 +00:00
// fetch does not allow to set `content-length` header, but we can set body to an empty string
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
if ( [ "PATCH" , "PUT" ] . includes ( method ) && typeof body === "undefined" ) {
body = "" ;
2023-08-17 09:47:40 +00:00
} // Only return body/request keys if present
2022-01-21 08:28:41 +00:00
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
} ) ;
}
2023-08-17 09:47:40 +00:00
const VERSION = "6.0.12" ;
2022-01-21 08:28:41 +00:00
2023-08-17 09:47:40 +00:00
const userAgent = ` octokit-endpoint.js/ ${ VERSION } ${ universalUserAgent . getUserAgent ( ) } ` ; // DEFAULTS has all properties set that EndpointOptions has, except url.
2022-01-21 08:28:41 +00:00
// So we use RequestParameters and add method as additional required property.
2023-08-17 09:47:40 +00:00
2022-01-21 08:28:41 +00:00
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 ) ;
exports . endpoint = endpoint ;
//# sourceMappingURL=index.js.map