github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/action/node_modules/@octokit/endpoint/dist-web/index.js (about)

     1  import { isPlainObject } from 'is-plain-object';
     2  import { getUserAgent } from 'universal-user-agent';
     3  
     4  function lowercaseKeys(object) {
     5      if (!object) {
     6          return {};
     7      }
     8      return Object.keys(object).reduce((newObj, key) => {
     9          newObj[key.toLowerCase()] = object[key];
    10          return newObj;
    11      }, {});
    12  }
    13  
    14  function mergeDeep(defaults, options) {
    15      const result = Object.assign({}, defaults);
    16      Object.keys(options).forEach((key) => {
    17          if (isPlainObject(options[key])) {
    18              if (!(key in defaults))
    19                  Object.assign(result, { [key]: options[key] });
    20              else
    21                  result[key] = mergeDeep(defaults[key], options[key]);
    22          }
    23          else {
    24              Object.assign(result, { [key]: options[key] });
    25          }
    26      });
    27      return result;
    28  }
    29  
    30  function removeUndefinedProperties(obj) {
    31      for (const key in obj) {
    32          if (obj[key] === undefined) {
    33              delete obj[key];
    34          }
    35      }
    36      return obj;
    37  }
    38  
    39  function merge(defaults, route, options) {
    40      if (typeof route === "string") {
    41          let [method, url] = route.split(" ");
    42          options = Object.assign(url ? { method, url } : { url: method }, options);
    43      }
    44      else {
    45          options = Object.assign({}, route);
    46      }
    47      // lowercase header names before merging with defaults to avoid duplicates
    48      options.headers = lowercaseKeys(options.headers);
    49      // remove properties with undefined values before merging
    50      removeUndefinedProperties(options);
    51      removeUndefinedProperties(options.headers);
    52      const mergedOptions = mergeDeep(defaults || {}, options);
    53      // mediaType.previews arrays are merged, instead of overwritten
    54      if (defaults && defaults.mediaType.previews.length) {
    55          mergedOptions.mediaType.previews = defaults.mediaType.previews
    56              .filter((preview) => !mergedOptions.mediaType.previews.includes(preview))
    57              .concat(mergedOptions.mediaType.previews);
    58      }
    59      mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map((preview) => preview.replace(/-preview/, ""));
    60      return mergedOptions;
    61  }
    62  
    63  function addQueryParameters(url, parameters) {
    64      const separator = /\?/.test(url) ? "&" : "?";
    65      const names = Object.keys(parameters);
    66      if (names.length === 0) {
    67          return url;
    68      }
    69      return (url +
    70          separator +
    71          names
    72              .map((name) => {
    73              if (name === "q") {
    74                  return ("q=" + parameters.q.split("+").map(encodeURIComponent).join("+"));
    75              }
    76              return `${name}=${encodeURIComponent(parameters[name])}`;
    77          })
    78              .join("&"));
    79  }
    80  
    81  const urlVariableRegex = /\{[^}]+\}/g;
    82  function removeNonChars(variableName) {
    83      return variableName.replace(/^\W+|\W+$/g, "").split(/,/);
    84  }
    85  function extractUrlVariableNames(url) {
    86      const matches = url.match(urlVariableRegex);
    87      if (!matches) {
    88          return [];
    89      }
    90      return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);
    91  }
    92  
    93  function omit(object, keysToOmit) {
    94      return Object.keys(object)
    95          .filter((option) => !keysToOmit.includes(option))
    96          .reduce((obj, key) => {
    97          obj[key] = object[key];
    98          return obj;
    99      }, {});
   100  }
   101  
   102  // Based on https://github.com/bramstein/url-template, licensed under BSD
   103  // TODO: create separate package.
   104  //
   105  // Copyright (c) 2012-2014, Bram Stein
   106  // All rights reserved.
   107  // Redistribution and use in source and binary forms, with or without
   108  // modification, are permitted provided that the following conditions
   109  // are met:
   110  //  1. Redistributions of source code must retain the above copyright
   111  //     notice, this list of conditions and the following disclaimer.
   112  //  2. Redistributions in binary form must reproduce the above copyright
   113  //     notice, this list of conditions and the following disclaimer in the
   114  //     documentation and/or other materials provided with the distribution.
   115  //  3. The name of the author may not be used to endorse or promote products
   116  //     derived from this software without specific prior written permission.
   117  // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
   118  // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   119  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
   120  // EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   121  // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   122  // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   123  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
   124  // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   125  // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   126  // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   127  /* istanbul ignore file */
   128  function encodeReserved(str) {
   129      return str
   130          .split(/(%[0-9A-Fa-f]{2})/g)
   131          .map(function (part) {
   132          if (!/%[0-9A-Fa-f]/.test(part)) {
   133              part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]");
   134          }
   135          return part;
   136      })
   137          .join("");
   138  }
   139  function encodeUnreserved(str) {
   140      return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
   141          return "%" + c.charCodeAt(0).toString(16).toUpperCase();
   142      });
   143  }
   144  function encodeValue(operator, value, key) {
   145      value =
   146          operator === "+" || operator === "#"
   147              ? encodeReserved(value)
   148              : encodeUnreserved(value);
   149      if (key) {
   150          return encodeUnreserved(key) + "=" + value;
   151      }
   152      else {
   153          return value;
   154      }
   155  }
   156  function isDefined(value) {
   157      return value !== undefined && value !== null;
   158  }
   159  function isKeyOperator(operator) {
   160      return operator === ";" || operator === "&" || operator === "?";
   161  }
   162  function getValues(context, operator, key, modifier) {
   163      var value = context[key], result = [];
   164      if (isDefined(value) && value !== "") {
   165          if (typeof value === "string" ||
   166              typeof value === "number" ||
   167              typeof value === "boolean") {
   168              value = value.toString();
   169              if (modifier && modifier !== "*") {
   170                  value = value.substring(0, parseInt(modifier, 10));
   171              }
   172              result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : ""));
   173          }
   174          else {
   175              if (modifier === "*") {
   176                  if (Array.isArray(value)) {
   177                      value.filter(isDefined).forEach(function (value) {
   178                          result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : ""));
   179                      });
   180                  }
   181                  else {
   182                      Object.keys(value).forEach(function (k) {
   183                          if (isDefined(value[k])) {
   184                              result.push(encodeValue(operator, value[k], k));
   185                          }
   186                      });
   187                  }
   188              }
   189              else {
   190                  const tmp = [];
   191                  if (Array.isArray(value)) {
   192                      value.filter(isDefined).forEach(function (value) {
   193                          tmp.push(encodeValue(operator, value));
   194                      });
   195                  }
   196                  else {
   197                      Object.keys(value).forEach(function (k) {
   198                          if (isDefined(value[k])) {
   199                              tmp.push(encodeUnreserved(k));
   200                              tmp.push(encodeValue(operator, value[k].toString()));
   201                          }
   202                      });
   203                  }
   204                  if (isKeyOperator(operator)) {
   205                      result.push(encodeUnreserved(key) + "=" + tmp.join(","));
   206                  }
   207                  else if (tmp.length !== 0) {
   208                      result.push(tmp.join(","));
   209                  }
   210              }
   211          }
   212      }
   213      else {
   214          if (operator === ";") {
   215              if (isDefined(value)) {
   216                  result.push(encodeUnreserved(key));
   217              }
   218          }
   219          else if (value === "" && (operator === "&" || operator === "?")) {
   220              result.push(encodeUnreserved(key) + "=");
   221          }
   222          else if (value === "") {
   223              result.push("");
   224          }
   225      }
   226      return result;
   227  }
   228  function parseUrl(template) {
   229      return {
   230          expand: expand.bind(null, template),
   231      };
   232  }
   233  function expand(template, context) {
   234      var operators = ["+", "#", ".", "/", ";", "?", "&"];
   235      return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
   236          if (expression) {
   237              let operator = "";
   238              const values = [];
   239              if (operators.indexOf(expression.charAt(0)) !== -1) {
   240                  operator = expression.charAt(0);
   241                  expression = expression.substr(1);
   242              }
   243              expression.split(/,/g).forEach(function (variable) {
   244                  var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
   245                  values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
   246              });
   247              if (operator && operator !== "+") {
   248                  var separator = ",";
   249                  if (operator === "?") {
   250                      separator = "&";
   251                  }
   252                  else if (operator !== "#") {
   253                      separator = operator;
   254                  }
   255                  return (values.length !== 0 ? operator : "") + values.join(separator);
   256              }
   257              else {
   258                  return values.join(",");
   259              }
   260          }
   261          else {
   262              return encodeReserved(literal);
   263          }
   264      });
   265  }
   266  
   267  function parse(options) {
   268      // https://fetch.spec.whatwg.org/#methods
   269      let method = options.method.toUpperCase();
   270      // replace :varname with {varname} to make it RFC 6570 compatible
   271      let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}");
   272      let headers = Object.assign({}, options.headers);
   273      let body;
   274      let parameters = omit(options, [
   275          "method",
   276          "baseUrl",
   277          "url",
   278          "headers",
   279          "request",
   280          "mediaType",
   281      ]);
   282      // extract variable names from URL to calculate remaining variables later
   283      const urlVariableNames = extractUrlVariableNames(url);
   284      url = parseUrl(url).expand(parameters);
   285      if (!/^http/.test(url)) {
   286          url = options.baseUrl + url;
   287      }
   288      const omittedParameters = Object.keys(options)
   289          .filter((option) => urlVariableNames.includes(option))
   290          .concat("baseUrl");
   291      const remainingParameters = omit(parameters, omittedParameters);
   292      const isBinaryRequest = /application\/octet-stream/i.test(headers.accept);
   293      if (!isBinaryRequest) {
   294          if (options.mediaType.format) {
   295              // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw
   296              headers.accept = headers.accept
   297                  .split(/,/)
   298                  .map((preview) => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`))
   299                  .join(",");
   300          }
   301          if (options.mediaType.previews.length) {
   302              const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || [];
   303              headers.accept = previewsFromAcceptHeader
   304                  .concat(options.mediaType.previews)
   305                  .map((preview) => {
   306                  const format = options.mediaType.format
   307                      ? `.${options.mediaType.format}`
   308                      : "+json";
   309                  return `application/vnd.github.${preview}-preview${format}`;
   310              })
   311                  .join(",");
   312          }
   313      }
   314      // for GET/HEAD requests, set URL query parameters from remaining parameters
   315      // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters
   316      if (["GET", "HEAD"].includes(method)) {
   317          url = addQueryParameters(url, remainingParameters);
   318      }
   319      else {
   320          if ("data" in remainingParameters) {
   321              body = remainingParameters.data;
   322          }
   323          else {
   324              if (Object.keys(remainingParameters).length) {
   325                  body = remainingParameters;
   326              }
   327              else {
   328                  headers["content-length"] = 0;
   329              }
   330          }
   331      }
   332      // default content-type for JSON if body is set
   333      if (!headers["content-type"] && typeof body !== "undefined") {
   334          headers["content-type"] = "application/json; charset=utf-8";
   335      }
   336      // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.
   337      // fetch does not allow to set `content-length` header, but we can set body to an empty string
   338      if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") {
   339          body = "";
   340      }
   341      // Only return body/request keys if present
   342      return Object.assign({ method, url, headers }, typeof body !== "undefined" ? { body } : null, options.request ? { request: options.request } : null);
   343  }
   344  
   345  function endpointWithDefaults(defaults, route, options) {
   346      return parse(merge(defaults, route, options));
   347  }
   348  
   349  function withDefaults(oldDefaults, newDefaults) {
   350      const DEFAULTS = merge(oldDefaults, newDefaults);
   351      const endpoint = endpointWithDefaults.bind(null, DEFAULTS);
   352      return Object.assign(endpoint, {
   353          DEFAULTS,
   354          defaults: withDefaults.bind(null, DEFAULTS),
   355          merge: merge.bind(null, DEFAULTS),
   356          parse,
   357      });
   358  }
   359  
   360  const VERSION = "6.0.12";
   361  
   362  const userAgent = `octokit-endpoint.js/${VERSION} ${getUserAgent()}`;
   363  // DEFAULTS has all properties set that EndpointOptions has, except url.
   364  // So we use RequestParameters and add method as additional required property.
   365  const DEFAULTS = {
   366      method: "GET",
   367      baseUrl: "https://api.github.com",
   368      headers: {
   369          accept: "application/vnd.github.v3+json",
   370          "user-agent": userAgent,
   371      },
   372      mediaType: {
   373          format: "",
   374          previews: [],
   375      },
   376  };
   377  
   378  const endpoint = withDefaults(null, DEFAULTS);
   379  
   380  export { endpoint };
   381  //# sourceMappingURL=index.js.map