{"version":3,"sources":["/Users/erunion/code/readme/oas/packages/oas/dist/chunk-FGPV2UXT.cjs","../src/index.ts","../src/lib/get-auth.ts","../src/lib/get-user-variable.ts","../src/lib/urls.ts"],"names":[],"mappings":"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","file":"/Users/erunion/code/readme/oas/packages/oas/dist/chunk-FGPV2UXT.cjs","sourcesContent":[null,"import type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Extensions } from './extensions.js';\nimport type { PathMatch, PathMatches } from './lib/urls.js';\nimport type {\n  AuthForHAR,\n  HttpMethods,\n  OASDocument,\n  OperationObject,\n  SecuritySchemeObject,\n  ServerObject,\n  Servers,\n  ServerVariable,\n  ServerVariablesObject,\n  User,\n} from './types.js';\n\nimport { dereference } from '@readme/openapi-parser';\n\nimport {\n  CODE_SAMPLES,\n  extensionDefaults,\n  getExtension,\n  HEADERS,\n  hasRootExtension,\n  OAUTH_OPTIONS,\n  PARAMETER_ORDERING,\n  SAMPLES_LANGUAGES,\n  validateParameterOrdering,\n} from './extensions.js';\nimport { getAuth } from './lib/get-auth.js';\nimport getUserVariable from './lib/get-user-variable.js';\nimport { decorateComponentSchemasWithRefName, dereferenceRef, getDereferencingOptions } from './lib/refs.js';\nimport {\n  filterPathMethods,\n  findTargetPath,\n  generatePathMatches,\n  normalizedURL,\n  stripTrailingSlash,\n  transformURLIntoRegex,\n} from './lib/urls.js';\nimport { Operation, Webhook } from './operation/index.js';\nimport { isOpenAPI31, isRef } from './types.js';\nimport { SERVER_VARIABLE_REGEX, supportedMethods } from './utils.js';\n\n// biome-ignore lint/style/noDefaultExport: This file doesn't have any other exports so this is fine.\nexport default class Oas {\n  /**\n   * The current OpenAPI definition.\n   */\n  api: OASDocument;\n\n  /**\n   * The current user that we should use when pulling auth tokens from security schemes.\n   */\n  user: User;\n\n  /**\n   * Internal storage array that the library utilizes to keep track of the times the\n   * {@see Oas.dereference} has been called so that if you initiate multiple promises they'll all\n   * end up returning the same data set once the initial dereference call completed.\n   */\n  protected promises: {\n    reject: any;\n    resolve: any;\n  }[];\n\n  /**\n   * Internal storage array that the library utilizes to keep track of its `dereferencing` state so\n   * it doesn't initiate multiple dereferencing processes.\n   */\n  protected dereferencing: {\n    circularRefs: string[];\n    complete: boolean;\n    processing: boolean;\n  };\n\n  /**\n   * Have the component schemas within this API definition been decorated with our\n   * `x-readme-ref-name` extension?\n   *\n   * @see {@link decorateComponentSchemas}\n   */\n  protected schemasDecorated: boolean = false;\n\n  /**\n   * @param oas An OpenAPI definition.\n   * @param user The information about a user that we should use when pulling auth tokens from\n   *    security schemes.\n   */\n  constructor(oas: OASDocument | string, user?: User) {\n    if (typeof oas === 'string') {\n      this.api = (JSON.parse(oas) || {}) as OASDocument;\n    } else {\n      this.api = oas || ({} as OASDocument);\n    }\n\n    this.user = user || {};\n\n    this.promises = [];\n    this.dereferencing = {\n      processing: false,\n      complete: false,\n      circularRefs: [],\n    };\n  }\n\n  /**\n   * This will initialize a new instance of the `Oas` class. This method is useful if you're using\n   * Typescript and are attempting to supply an untyped JSON object into `Oas` as it will force-type\n   * that object to an `OASDocument` for you.\n   *\n   * @param oas An OpenAPI definition.\n   * @param user The information about a user that we should use when pulling auth tokens from\n   *    security schemes.\n   */\n  static init(oas: OASDocument | Record<string, unknown>, user?: User): Oas {\n    return new Oas(oas as OASDocument, user);\n  }\n\n  /**\n   * Retrieve the OpenAPI version that this API definition is targeted for.\n   */\n  getVersion(): string {\n    if (this.api.openapi) {\n      return this.api.openapi;\n    }\n\n    throw new Error('Unable to recognize what specification version this API definition conforms to.');\n  }\n\n  /**\n   * Retrieve the current OpenAPI API Definition.\n   *\n   */\n  getDefinition(): OASDocument {\n    return this.api;\n  }\n\n  url(selected = 0, variables?: ServerVariable): string {\n    const url = normalizedURL(this.api, selected);\n    return this.replaceUrl(url, variables || this.defaultVariables(selected)).trim();\n  }\n\n  variables(selected = 0): ServerVariablesObject {\n    return this.api.servers?.[selected]?.variables || {};\n  }\n\n  defaultVariables(selected = 0): ServerVariable {\n    const variables = this.variables(selected);\n    const defaults: ServerVariable = {};\n\n    Object.keys(variables).forEach(key => {\n      defaults[key] = getUserVariable(this.user, key) || variables[key].default || '';\n    });\n\n    return defaults;\n  }\n\n  splitUrl(selected = 0): (\n    | {\n        /**\n         * A unique key, where the `value` is concatenated to its index\n         */\n        key: string;\n        type: 'text';\n        value: string;\n      }\n    | {\n        /**\n         * An optional description for the server variable.\n         *\n         * @see {@link https://spec.openapis.org/oas/v3.1.0#fixed-fields-4}\n         */\n        description?: string;\n\n        /**\n         * An enumeration of string values to be used if the substitution options are from a limited set.\n         *\n         * @see {@link https://spec.openapis.org/oas/v3.1.0#fixed-fields-4}\n         */\n        enum?: string[];\n\n        /**\n         * A unique key, where the `value` is concatenated to its index\n         */\n        key: string;\n        type: 'variable';\n        value: string;\n      }\n  )[] {\n    const url = normalizedURL(this.api, selected);\n    const variables = this.variables(selected);\n\n    return url\n      .split(/({.+?})/)\n      .filter(Boolean)\n      .map((part, i) => {\n        const isVariable = part.match(/[{}]/);\n        const value = part.replace(/[{}]/g, '');\n        // To ensure unique keys, we're going to create a key\n        // with the value concatenated to its index.\n        const key = `${value}-${i}`;\n\n        if (!isVariable) {\n          return {\n            type: 'text',\n            value,\n            key,\n          };\n        }\n\n        const variable = variables?.[value];\n\n        return {\n          type: 'variable',\n          value,\n          key,\n          description: variable?.description,\n          enum: variable?.enum,\n        };\n      });\n  }\n\n  /**\n   * With a fully composed server URL, run through our list of known OAS servers and return back\n   * which server URL was selected along with any contained server variables split out.\n   *\n   * For example, if you have an OAS server URL of `https://{name}.example.com:{port}/{basePath}`,\n   * and pass in `https://buster.example.com:3000/pet` to this function, you'll get back the\n   * following:\n   *\n   *    { selected: 0, variables: { name: 'buster', port: 3000, basePath: 'pet' } }\n   *\n   * Re-supplying this data to `oas.url()` should return the same URL you passed into this method.\n   *\n   * @param baseUrl A given URL to extract server variables out of.\n   */\n  splitVariables(baseUrl: string): Servers | false {\n    const matchedServer = (this.api.servers || [])\n      .map((server, i) => {\n        const rgx = transformURLIntoRegex(server.url);\n        const found = new RegExp(rgx).exec(baseUrl);\n        if (!found) {\n          return false;\n        }\n\n        // While it'd be nice to use named regex groups to extract path parameters from the URL and\n        // match them up with the variables that we have present in it, JS unfortunately doesn't\n        // support having the groups duplicated. So instead of doing that we need to re-regex the\n        // server URL, this time splitting on the path parameters -- this way we'll be able to\n        // extract the parameter names and match them up with the matched server that we obtained\n        // above.\n        const variables: Record<string, number | string> = {};\n        Array.from(server.url.matchAll(SERVER_VARIABLE_REGEX)).forEach((variable, y) => {\n          variables[variable[1]] = found[y + 1];\n        });\n\n        return {\n          selected: i,\n          variables,\n        };\n      })\n      .filter(item => item !== false);\n\n    return matchedServer.length ? matchedServer[0] : false;\n  }\n\n  /**\n   * Replace templated variables with supplied data in a given URL.\n   *\n   * There are a couple ways that this will utilize variable data:\n   *\n   *  - Supplying a `variables` object. If this is supplied, this data will always take priority.\n   *    This incoming `variables` object can be two formats:\n   *    `{ variableName: { default: 'value' } }` and `{ variableName: 'value' }`. If the former is\n   *    present, that will take precedence over the latter.\n   *  - If the supplied `variables` object is empty or does not match the current template name,\n   *    we fallback to the data stored in `this.user` and attempt to match against that.\n   *    See `getUserVariable` for some more information on how this data is pulled from `this.user`.\n   *\n   * If no variables supplied match up with the template name, the template name will instead be\n   * used as the variable data.\n   *\n   * @param url A URL to swap variables into.\n   * @param variables An object containing variables to swap into the URL.\n   */\n  replaceUrl(url: string, variables: ServerVariable = {}): string {\n    // When we're constructing URLs, server URLs with trailing slashes cause problems with doing\n    // lookups, so if we have one here on, slice it off.\n    return stripTrailingSlash(\n      url.replace(SERVER_VARIABLE_REGEX, (original: string, key: string) => {\n        if (key in variables) {\n          const data = variables[key];\n          if (typeof data === 'object') {\n            if (!Array.isArray(data) && data !== null && 'default' in data) {\n              return String(data.default);\n            }\n          } else {\n            return String(data);\n          }\n        }\n\n        const userVariable = getUserVariable(this.user, key);\n        if (userVariable) {\n          return String(userVariable);\n        }\n\n        return original;\n      }),\n    );\n  }\n\n  /**\n   * Retrieve an Operation of Webhook class instance for a given path and method.\n   *\n   * @param path Path to lookup and retrieve.\n   * @param method HTTP Method to retrieve on the path.\n   */\n  operation(\n    path: string,\n    method: HttpMethods,\n    opts: {\n      /**\n       * If you prefer to first look for a webhook with this path and method.\n       */\n      isWebhook?: boolean;\n    } = {},\n  ): Operation {\n    // If we're unable to locate an operation for this path+method combination within the API\n    // definition, we should still set an empty schema on the operation in the `Operation` class\n    // because if we don't trying to use any of the accessors on that class are going to fail as\n    // `schema` will be `undefined`.\n    let operation: OperationObject = {\n      parameters: [],\n    };\n\n    if (opts.isWebhook) {\n      if (isOpenAPI31(this.api)) {\n        const webhookPath = dereferenceRef(this.api?.webhooks?.[path], this.api);\n        if (webhookPath && !isRef(webhookPath)) {\n          if (webhookPath?.[method]) {\n            operation = webhookPath[method];\n            return new Webhook(this, path, method, operation);\n          }\n        }\n      }\n    }\n\n    if (this?.api?.paths?.[path]) {\n      const pathItem = dereferenceRef(this.api.paths[path], this.api);\n      if (pathItem?.[method]) {\n        operation = dereferenceRef(pathItem[method], this.api);\n      }\n    }\n\n    return new Operation(this, path, method, operation);\n  }\n\n  findOperationMatches(url: string): PathMatches | undefined {\n    const { origin, hostname } = new URL(url);\n    const originRegExp = new RegExp(origin, 'i');\n    const { servers, paths } = this.api;\n\n    let pathName: string | undefined;\n    let targetServer: ServerObject | undefined;\n    let matchedServer: ServerObject | undefined;\n\n    if (!servers || !servers.length) {\n      // If this API definition doesn't have any servers set up let's treat it as if it were\n      // https://example.com because that's the default origin we add in `normalizedUrl` under the\n      // same circumstances. Without this we won't be able to match paths within what is otherwise\n      // a valid OpenAPI definition.\n      matchedServer = {\n        url: 'https://example.com',\n      };\n    } else {\n      matchedServer = servers.find(s => originRegExp.exec(this.replaceUrl(s.url, s.variables || {})));\n      if (!matchedServer) {\n        const hostnameRegExp = new RegExp(hostname);\n        matchedServer = servers.find(s => hostnameRegExp.exec(this.replaceUrl(s.url, s.variables || {})));\n      }\n    }\n\n    if (matchedServer) {\n      // Instead of setting `url` directly against `matchedServer` we need to set it to an\n      // intermediary object as directly modifying `matchedServer.url` will in turn update\n      // `this.servers[idx].url` which we absolutely do not want to happen.\n      targetServer = {\n        ...matchedServer,\n        url: this.replaceUrl(matchedServer.url, matchedServer.variables || {}),\n      };\n\n      [, pathName] = url.split(new RegExp(targetServer.url, 'i'));\n    }\n\n    // If we **still** haven't found a matching server, then the OAS server URL might have server\n    // variables and we should loosen it up with regex to try to discover a matching path.\n    //\n    // For example if an OAS has `https://{region}.node.example.com/v14` set as its server URL, and\n    // the `this.user` object has a `region` value of `us`, if we're trying to locate an operation\n    // for https://eu.node.example.com/v14/api/esm we won't be able to because normally the users\n    // `region` of `us` will be transposed in and we'll be trying to locate `eu.node.example.com`\n    // in `us.node.example.com` -- which won't work.\n    //\n    // So what this does is transform `https://{region}.node.example.com/v14` into\n    // `https://([-_a-zA-Z0-9[\\\\]]+).node.example.com/v14`, and from there we'll be able to match\n    // https://eu.node.example.com/v14/api/esm and ultimately find the operation matches for\n    // `/api/esm`.\n    if (!matchedServer || !pathName) {\n      const matchedServerAndPath = (servers || [])\n        .map(server => {\n          const rgx = transformURLIntoRegex(server.url);\n          const found = new RegExp(rgx).exec(url);\n          if (!found) {\n            return undefined;\n          }\n\n          return {\n            matchedServer: server,\n            pathName: url.split(new RegExp(rgx)).slice(-1).pop(),\n          };\n        })\n        .filter((item): item is { matchedServer: ServerObject; pathName: string | undefined } => item !== undefined);\n\n      if (!matchedServerAndPath.length) {\n        return undefined;\n      }\n\n      pathName = matchedServerAndPath[0].pathName;\n      targetServer = {\n        ...matchedServerAndPath[0].matchedServer,\n      };\n    }\n\n    if (pathName === undefined) return undefined;\n    if (pathName === '') pathName = '/';\n    if (!paths || !targetServer) return undefined;\n    const annotatedPaths = generatePathMatches(paths, pathName, targetServer.url);\n    if (!annotatedPaths.length) return undefined;\n\n    return annotatedPaths;\n  }\n\n  /**\n   * Discover an operation in an OAS from a fully-formed URL and HTTP method. Will return an object\n   * containing a `url` object and another one for `operation`. This differs from `getOperation()`\n   * in that it does not return an instance of the `Operation` class.\n   *\n   * @param url A full URL to look up.\n   * @param method The cooresponding HTTP method to look up.\n   */\n  findOperation(url: string, method: HttpMethods): PathMatch | undefined {\n    const annotatedPaths = this.findOperationMatches(url);\n    if (!annotatedPaths) {\n      return undefined;\n    }\n\n    const matches = filterPathMethods(annotatedPaths, method);\n    if (!matches.length) return undefined;\n    return findTargetPath(matches);\n  }\n\n  /**\n   * Discover an operation in an OAS from a fully-formed URL without an HTTP method. Will return an\n   * object containing a `url` object and another one for `operation`.\n   *\n   * @param url A full URL to look up.\n   */\n  findOperationWithoutMethod(url: string): PathMatch | undefined {\n    const annotatedPaths = this.findOperationMatches(url);\n    if (!annotatedPaths) {\n      return undefined;\n    }\n\n    return findTargetPath(annotatedPaths);\n  }\n\n  /**\n   * Retrieve an operation in an OAS from a fully-formed URL and HTTP method. Differs from\n   * `findOperation` in that while this method will return an `Operation` instance,\n   * `findOperation()` does not.\n   *\n   * @param url A full URL to look up.\n   * @param method The cooresponding HTTP method to look up.\n   */\n  getOperation(url: string, method: HttpMethods): Operation | undefined {\n    const op = this.findOperation(url, method);\n    if (op === undefined) {\n      return undefined;\n    }\n\n    return this.operation(op.url.nonNormalizedPath, method);\n  }\n\n  /**\n   * Retrieve an operation in an OAS by an `operationId`.\n   *\n   * If an operation does not have an `operationId` one will be generated in place, using the\n   * default behavior of `Operation.getOperationId()`, and then asserted against your query.\n   *\n   * Note that because `operationId`s are unique that uniqueness does include casing so the ID\n   * you are looking for will be asserted as an exact match.\n   *\n   * @see {Operation.getOperationId()}\n   * @param id The `operationId` to look up.\n   */\n  getOperationById(id: string): Operation | Webhook | undefined {\n    let found: Operation | Webhook | undefined;\n\n    Object.values(this.getPaths()).forEach(operations => {\n      if (found) return;\n      found = Object.values(operations).find(operation => operation.getOperationId() === id);\n    });\n\n    if (found) {\n      return found;\n    }\n\n    Object.entries(this.getWebhooks()).forEach(([, webhooks]) => {\n      if (found) return;\n      found = Object.values(webhooks).find(webhook => webhook.getOperationId() === id);\n    });\n\n    return found;\n  }\n\n  /**\n   * With an object of user information, retrieve the appropriate API auth keys from the current\n   * OAS definition.\n   *\n   * @see {@link https://docs.readme.com/docs/passing-data-to-jwt}\n   * @param user User\n   * @param selectedApp The user app to retrieve an auth key for.\n   */\n  getAuth(user: User, selectedApp?: number | string): AuthForHAR {\n    if (!this.api?.components?.securitySchemes) {\n      return {};\n    }\n\n    return getAuth(this.api, user, selectedApp);\n  }\n\n  /**\n   * Determine if a security scheme exists within the API definition.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#security-scheme-object}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#security-scheme-object}\n   * @param name The name of the security scheme to check for.\n   */\n  hasSecurityScheme(name: string): boolean {\n    return Boolean(this.api?.components?.securitySchemes?.[name]);\n  }\n\n  /**\n   * Retrieve a security scheme from the API definition.\n   *\n   * If the found security scheme is a `$ref` pointer it will be lazily dereferenced; if the scheme\n   * cannot be resolved after that process (eg. it's circular or is an invalid `$ref`) then\n   * `undefined` will be returned.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#security-scheme-object}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#security-scheme-object}\n   * @param name The name of the security scheme to retrieve.\n   */\n  getSecurityScheme(name: string): SecuritySchemeObject | undefined {\n    if (!this.hasSecurityScheme(name)) {\n      return undefined;\n    }\n\n    let scheme = this.api?.components?.securitySchemes?.[name];\n    if (!scheme) return undefined;\n    if (isRef(scheme)) {\n      scheme = dereferenceRef(scheme, this.api);\n      if (!scheme || isRef(scheme)) return undefined;\n    }\n\n    return scheme;\n  }\n\n  /**\n   * Returns the `paths` object that exists in this API definition but with every `method` mapped\n   * to an instance of the `Operation` class.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#openapi-object}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#openapi-object}\n   */\n  getPaths(): Record<string, Record<HttpMethods, Operation | Webhook>> {\n    const paths: Record<string, Record<HttpMethods, Operation | Webhook>> = {};\n    if (!this.api.paths) {\n      return paths;\n    }\n\n    Object.keys(this.api.paths).forEach(path => {\n      // If this is a specification extension then we should ignore it.\n      if (path.startsWith('x-')) {\n        return;\n      }\n\n      paths[path] = {} as Record<HttpMethods, Operation | Webhook>;\n\n      // biome-ignore-start lint/style/noNonNullAssertion: We're guaranteed to have `api.paths[path]` from the `.keys()` loop.\n      let pathItem = this.api.paths![path];\n      if (!pathItem) {\n        return;\n      } else if (isRef(pathItem)) {\n        // Though this library is generally unaware of `$ref` pointers we're making a singular\n        // exception with this accessor out of convenience.\n        this.api.paths![path] = dereferenceRef(pathItem, this.api);\n        pathItem = this.api.paths![path];\n        if (!pathItem || isRef(pathItem)) {\n          return;\n        }\n      }\n\n      Object.keys(pathItem).forEach(method => {\n        /**\n         * Because a path doesn't need to contain a keyed-object of HTTP methods, we should exclude\n         * anything from within the paths object that isn't a known HTTP method.\n         *\n         * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#fixed-fields-7}\n         * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#fixed-fields-7}\n         */\n        if (!supportedMethods.includes(method as HttpMethods)) {\n          return;\n        }\n\n        paths[path][method as HttpMethods] = this.operation(path, method as HttpMethods);\n      });\n      // biome-ignore-end lint/style/noNonNullAssertion: --end--\n    });\n\n    return paths;\n  }\n\n  /**\n   * Returns the `webhooks` object that exists in this API definition but with every `method`\n   * mapped to an instance of the `Webhook` class.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#openapi-object}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#openapi-object}\n   */\n  getWebhooks(): Record<string, Record<HttpMethods, Webhook>> {\n    const webhooks: Record<string, Record<HttpMethods, Webhook>> = {};\n    if (!isOpenAPI31(this.api) || !this.api.webhooks) {\n      return webhooks;\n    }\n\n    Object.keys(this.api.webhooks).forEach(id => {\n      webhooks[id] = {} as Record<HttpMethods, Webhook>;\n\n      const webhookPath = dereferenceRef((this.api as OpenAPIV3_1.Document).webhooks?.[id], this.api);\n      if (webhookPath) {\n        Object.keys(webhookPath).forEach(method => {\n          if (!supportedMethods.includes(method as HttpMethods)) {\n            return;\n          }\n\n          webhooks[id][method as HttpMethods] = this.operation(id, method as HttpMethods, {\n            isWebhook: true,\n          }) as Webhook;\n        });\n      }\n    });\n\n    return webhooks;\n  }\n\n  /**\n   * Return an array of all tag names that exist on this API definition.\n   *\n   * If the API definition uses the `x-disable-tag-sorting` extension then tags will be returned in\n   * the order they're defined.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#openapi-object}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#openapi-object}\n   * @param setIfMissing If a tag is not present on an operation that operations path will be added\n   *    into the list of tags returned.\n   */\n  getTags(setIfMissing = false): string[] {\n    const allTags = new Set<string>();\n\n    const oasTags = this.api.tags?.map(tag => tag.name) || [];\n\n    const disableTagSorting = getExtension('disable-tag-sorting', this.api);\n\n    Object.entries(this.getPaths()).forEach(([path, operations]) => {\n      Object.values(operations).forEach(operation => {\n        const tags = operation.getTags();\n        if (setIfMissing && !tags.length) {\n          allTags.add(path);\n          return;\n        }\n\n        tags.forEach(tag => {\n          allTags.add(tag.name);\n        });\n      });\n    });\n\n    Object.entries(this.getWebhooks()).forEach(([path, webhooks]) => {\n      Object.values(webhooks).forEach(webhook => {\n        const tags = webhook.getTags();\n        if (setIfMissing && !tags.length) {\n          allTags.add(path);\n          return;\n        }\n\n        tags.forEach(tag => {\n          allTags.add(tag.name);\n        });\n      });\n    });\n\n    // Tags that exist only on the endpoint\n    const endpointTags: string[] = [];\n    // Tags that the user has defined in the `tags` array\n    const tagsArray: string[] = [];\n\n    // Distinguish between which tags exist in the `tags` array and which tags\n    // exist only at the endpoint level. For tags that exist only at the\n    // endpoint level, we'll just tack that on to the end of the sorted tags.\n    if (disableTagSorting) {\n      return Array.from(allTags);\n    }\n\n    Array.from(allTags).forEach(tag => {\n      if (oasTags.includes(tag)) {\n        tagsArray.push(tag);\n      } else {\n        endpointTags.push(tag);\n      }\n    });\n\n    let sortedTags = tagsArray.sort((a, b) => {\n      return oasTags.indexOf(a) - oasTags.indexOf(b);\n    });\n\n    sortedTags = sortedTags.concat(endpointTags);\n\n    return sortedTags;\n  }\n\n  /**\n   * Determine if a given a custom specification extension exists within the API definition.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions}\n   * @param extension Specification extension to lookup.\n   */\n  hasExtension(extension: string): boolean {\n    return hasRootExtension(extension, this.api);\n  }\n\n  /**\n   * Retrieve a custom specification extension off of the API definition.\n   *\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions}\n   * @param extension Specification extension to lookup.\n   */\n  getExtension(extension: string | keyof Extensions, operation?: Operation): any {\n    return getExtension(extension, this.api, operation);\n  }\n\n  /**\n   * Determine if a given OpenAPI custom extension is valid or not.\n   *\n   * @see {@link https://docs.readme.com/docs/openapi-extensions}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions}\n   * @param extension Specification extension to validate.\n   * @throws\n   */\n  validateExtension(extension: keyof Extensions): void {\n    if (this.hasExtension('x-readme')) {\n      const data = this.getExtension('x-readme') satisfies Extensions;\n      if (typeof data !== 'object' || Array.isArray(data) || data === null) {\n        throw new TypeError('\"x-readme\" must be of type \"Object\"');\n      }\n\n      if (extension in data) {\n        if ([CODE_SAMPLES, HEADERS, PARAMETER_ORDERING, SAMPLES_LANGUAGES].includes(extension)) {\n          if (data[extension] !== undefined) {\n            if (!Array.isArray(data[extension])) {\n              throw new TypeError(`\"x-readme.${extension}\" must be of type \"Array\"`);\n            }\n\n            if (extension === PARAMETER_ORDERING) {\n              validateParameterOrdering(data[extension], `x-readme.${extension}`);\n            }\n          }\n        } else if (extension === OAUTH_OPTIONS) {\n          if (typeof data[extension] !== 'object') {\n            throw new TypeError(`\"x-readme.${extension}\" must be of type \"Object\"`);\n          }\n        } else if (typeof data[extension] !== 'boolean') {\n          throw new TypeError(`\"x-readme.${extension}\" must be of type \"Boolean\"`);\n        }\n      }\n    }\n\n    // If the extension isn't grouped under `x-readme`, we need to look for them with `x-` prefixes.\n    if (this.hasExtension(`x-${extension}`)) {\n      const data = this.getExtension(`x-${extension}`);\n      if ([CODE_SAMPLES, HEADERS, PARAMETER_ORDERING, SAMPLES_LANGUAGES].includes(extension)) {\n        if (!Array.isArray(data)) {\n          throw new TypeError(`\"x-${extension}\" must be of type \"Array\"`);\n        }\n\n        if (extension === PARAMETER_ORDERING) {\n          validateParameterOrdering(data, `x-${extension}`);\n        }\n      } else if (extension === OAUTH_OPTIONS) {\n        if (typeof data !== 'object') {\n          throw new TypeError(`\"x-${extension}\" must be of type \"Object\"`);\n        }\n      } else if (typeof data !== 'boolean') {\n        throw new TypeError(`\"x-${extension}\" must be of type \"Boolean\"`);\n      }\n    }\n  }\n\n  /**\n   * Validate all of our custom or known OpenAPI extensions, throwing exceptions when necessary.\n   *\n   * @see {@link https://docs.readme.com/docs/openapi-extensions}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions}\n   * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions}\n   */\n  validateExtensions(): void {\n    Object.keys(extensionDefaults).forEach(extension => {\n      this.validateExtension(extension as keyof Extensions);\n    });\n  }\n\n  /**\n   * Dereference the current API definition so it can be parsed free from the hassle of resolving\n   * `$ref` schemas and circular structures.\n   *\n   */\n  async dereference(opts?: {\n    /**\n     * A callback method can be supplied to be called when dereferencing is complete. Used for\n     * debugging that the multi-promise handling within this method works.\n     *\n     * @private\n     */\n    cb?: () => void;\n  }): Promise<(typeof this.promises)[] | boolean> {\n    if (this.dereferencing.complete) {\n      return new Promise(resolve => {\n        resolve(true);\n      });\n    }\n\n    if (this.dereferencing.processing) {\n      return new Promise((resolve, reject) => {\n        this.promises.push({ resolve, reject });\n      });\n    }\n\n    this.dereferencing.processing = true;\n\n    // Because referencing will eliminate any lineage back to the original `$ref`, information that\n    // we might need at some point, we should run through all available component schemas and denote\n    // what their name is so that when dereferencing happens below those names will be preserved.\n    if (!this.schemasDecorated) {\n      decorateComponentSchemasWithRefName(this.api);\n      this.schemasDecorated = true;\n    }\n\n    const { api, promises } = this;\n\n    const circularRefs: Set<string> = new Set();\n    const dereferencingOptions = getDereferencingOptions(circularRefs);\n\n    return dereference<OASDocument>(api, dereferencingOptions)\n      .then((dereferenced: OASDocument) => {\n        this.api = dereferenced;\n\n        this.promises = promises;\n        this.dereferencing = {\n          processing: false,\n          complete: true,\n          // We need to convert our `Set` to an array in order to match the typings.\n          circularRefs: [...circularRefs],\n        };\n\n        // Used for debugging that dereferencing promise awaiting works.\n        if (opts?.cb) {\n          opts?.cb();\n        }\n      })\n      .then(() => {\n        return this.promises.map(deferred => deferred.resolve());\n      })\n      .catch(err => {\n        this.dereferencing.processing = false;\n        this.promises.map(deferred => deferred.reject(err));\n        throw err;\n      });\n  }\n\n  /**\n   * Determine if the current API definition has been dereferenced or not.\n   *\n   * @see Oas.dereference\n   */\n  isDereferenced(): boolean {\n    return this.dereferencing.processing || this.dereferencing.complete;\n  }\n\n  /**\n   * Retrieve any circular `$ref` pointers that maybe present within the API definition.\n   *\n   * This method requires that you first dereference the definition.\n   *\n   * @see Oas.dereference\n   */\n  getCircularReferences(): string[] {\n    if (!this.dereferencing.complete) {\n      throw new Error('.dereference() must be called first in order for this method to obtain circular references.');\n    }\n\n    return this.dereferencing.circularRefs;\n  }\n}\n","import type { AuthForHAR, KeyedSecuritySchemeObject, OASDocument, User } from '../types.js';\n\nimport { isRef } from '../types.js';\nimport { dereferenceRef } from './refs.js';\n\ntype authKey = unknown | { password: number | string; user: number | string } | null;\n\n/**\n * @param user User to retrieve retrieve an auth key for.\n * @param scheme The type of security scheme that we want a key for.\n */\nfunction getKey(user: User, scheme: KeyedSecuritySchemeObject): authKey {\n  switch (scheme.type) {\n    case 'oauth2':\n    case 'apiKey':\n      return user[scheme._key] || user.apiKey || scheme['x-default'] || null;\n\n    case 'http':\n      if (scheme.scheme === 'basic') {\n        return user[scheme._key] || { user: user.user || null, pass: user.pass || null };\n      }\n\n      if (scheme.scheme === 'bearer') {\n        return user[scheme._key] || user.apiKey || scheme['x-default'] || null;\n      }\n      return null;\n\n    default:\n      return null;\n  }\n}\n\n/**\n * Retrieve auth keys for a specific security scheme for a given user for a specific \"app\" that\n * they have configured.\n *\n * For `scheme` we're typing it to a union of `SecurityScheme` and `any` because we have handling\n * and tests for an unknown or unrecognized `type` and though it's not possible with the\n * `SecurityScheme.type` to be unrecognized it may still be possible to get an unrecognized scheme\n * with this method in the wild as we have API definitions in our database that were ingested\n * before we had good validation in place.\n *\n * @param user User\n * @param scheme Security scheme to get auth keys for.\n * @param selectedApp The user app to retrieve an auth key for.\n */\nexport function getByScheme(\n  user: User,\n  scheme = {} as KeyedSecuritySchemeObject,\n  selectedApp?: number | string,\n): authKey {\n  if (user?.keys?.length) {\n    if (selectedApp) {\n      const userKey = user.keys.find(k => k.name === selectedApp);\n      if (!userKey) {\n        return null;\n      }\n\n      return getKey(userKey, scheme);\n    }\n\n    return getKey(user.keys[0], scheme);\n  }\n\n  return getKey(user, scheme);\n}\n\n/**\n * Retrieve auth keys for an API definition from a given user for a specific \"app\" that they have\n * configured.\n *\n * @param api API definition\n * @param user User\n * @param selectedApp The user app to retrieve an auth key for.\n */\nexport function getAuth(api: OASDocument, user: User, selectedApp?: number | string): AuthForHAR {\n  return Object.keys(api?.components?.securitySchemes || {})\n    .map(scheme => {\n      const securityScheme = dereferenceRef(api.components?.securitySchemes?.[scheme], api);\n      if (!securityScheme || isRef(securityScheme)) {\n        // If this security scheme is invalid or an unresolvable `$ref` pointer then we should skip\n        // it.\n        return false;\n      }\n\n      return {\n        [scheme]: getByScheme(\n          user,\n          {\n            ...securityScheme,\n            _key: scheme,\n          },\n          selectedApp,\n        ),\n      };\n    })\n    .filter((item): item is AuthForHAR => item !== undefined)\n    .reduce((prev, next) => Object.assign(prev, next), {});\n}\n","import type { User } from '../types.js';\n\n/**\n * Retrieve a user variable off of a given user.\n *\n * @see {@link https://docs.readme.com/docs/passing-data-to-jwt}\n * @param user The user to get a user variable for.\n * @param property The name of the variable to retrieve.\n * @param selectedApp The user app to retrieve an auth key for.\n */\n// biome-ignore lint/style/noDefaultExport: This is safe for now.\nexport default function getUserVariable(user: User, property: string, selectedApp?: number | string): unknown {\n  let key: User | undefined = user;\n\n  if ('keys' in user && Array.isArray(user.keys) && user.keys.length) {\n    if (selectedApp) {\n      key = user.keys.find(k => k.name === selectedApp);\n    } else {\n      key = user.keys[0];\n    }\n  }\n\n  return key?.[property] || user[property] || null;\n}\n","import type { Match, ParamData } from 'path-to-regexp';\nimport type { HttpMethods, OASDocument, PathsObject } from '../types';\n\nimport { match, pathToRegexp } from 'path-to-regexp';\n\nimport { SERVER_VARIABLE_REGEX } from '../utils';\n\nexport interface PathMatch {\n  match?: Match<ParamData>;\n  operation: PathsObject;\n  url: {\n    method?: HttpMethods;\n    nonNormalizedPath: string;\n    origin: string;\n    path: string;\n    slugs: Record<string, string>;\n  };\n}\n\nexport type PathMatches = PathMatch[];\n\nexport function stripTrailingSlash(url: string): string {\n  if (url[url.length - 1] === '/') {\n    return url.slice(0, -1);\n  }\n\n  return url;\n}\n\nfunction ensureProtocol(url: string) {\n  // Add protocol to urls starting with // e.g. //example.com\n  // This is because httpsnippet throws a HARError when it doesnt have a protocol\n  if (url.match(/^\\/\\//)) {\n    return `https:${url}`;\n  }\n\n  // Add protocol to urls with no // within them\n  // This is because httpsnippet throws a HARError when it doesnt have a protocol\n  if (!url.match(/\\/\\//)) {\n    return `https://${url}`;\n  }\n\n  return url;\n}\n\n/**\n * Normalize a OpenAPI server URL by ensuring that it has a proper HTTP protocol and doesn't have a\n * trailing slash.\n *\n * @param api The API definition that we're processing.\n * @param selected The index of the `servers` array in the API definition that we want to normalize.\n */\nexport function normalizedURL(api: OASDocument, selected: number): string {\n  const exampleDotCom = 'https://example.com';\n  let url: string | undefined;\n  try {\n    url = api.servers?.[selected].url;\n    // This is to catch the case where servers = [{}]\n    if (!url) throw new Error('no url');\n\n    // Stripping the '/' off the end\n    url = stripTrailingSlash(url);\n\n    // Check if the URL is just a path a missing an origin, for example `/api/v3`. If so, then make\n    // `example.com` the origin to avoid it becoming something invalid like `https:///api/v3`.\n    // RM-1044\n    if (url.startsWith('/') && !url.startsWith('//')) {\n      const urlWithOrigin = new URL(exampleDotCom);\n      urlWithOrigin.pathname = url;\n      url = urlWithOrigin.href;\n    }\n  } catch {\n    url = exampleDotCom;\n  }\n\n  return ensureProtocol(url);\n}\n\n/**\n * With a URL that may contain server variables, transform those server variables into regex that\n * we can query against.\n *\n * For example, when given `https://{region}.node.example.com/v14` this will return back:\n *\n *    https://([-_a-zA-Z0-9:.[\\\\]]+).node.example.com/v14\n *\n * @param url URL to transform\n */\nexport function transformURLIntoRegex(url: string): string {\n  return stripTrailingSlash(url.replace(SERVER_VARIABLE_REGEX, '([-_a-zA-Z0-9:.[\\\\]]+)'));\n}\n\n/**\n * Normalize a path so that we can use it with `path-to-regexp` to do operation lookups.\n *\n * @param path Path to normalize.\n */\nfunction normalizePath(path: string) {\n  return (\n    path\n      // This regex transforms `{pathParam}` into `:pathParam` so we can regex against it. We're\n      // also handling quirks here like if there's an optional proceeding or trailing curly bracket\n      // (`{{pathParam}` or `{pathParam}}`) as any unescaped curlys, which would be present in\n      // `:pathParam}`, will throw a regex exception.\n      .replace(/({?){(.*?)}(}?)/g, (str, ...args) => {\n        // If a path contains a path parameter with hyphens, like `:dlc-release`, when it's regexd\n        // with `path-to-regexp` it match against the `:dlc` portion of the parameter, breaking all\n        // matching against the full path.\n        //\n        // For example on `/games/:game/dlc/:dlc-release` the regex that's actually used to search\n        // against a path like `/games/destiny-2/dlc/witch-queen` is the following:\n        //    /^\\/games(?:\\/([^\\/#\\?]+?))\\/dlc(?:\\/([^\\/#\\?]+?))-release[\\/#\\?]?$/i\n        //\n        // However if `:dlc-release` is rewritten to `:dlcrelease` we end up with a functional\n        // regex: /^\\/games(?:\\/([^\\/#\\?]+?))\\/dlc(?:\\/([^\\/#\\?]+?))[\\/#\\?]?$/i.\n        return `:${args[1].replace('-', '')}`;\n      })\n\n      // In addition to transforming `{pathParam}` into `:pathParam` we also need to escape cases\n      // where a non-variabled colon is next to a variabled-colon because if we don't then\n      // `path-to-regexp` won't be able to correct identify where the variable starts.\n      //\n      // For example if the URL is `/post/:param1::param2` we'll be escaping it to\n      // `/post/:param1\\::param2`.\n      .replace(/::/, '\\\\::')\n\n      // We also need to escape question marks too because they're treated as regex modifiers.\n      .split('?')[0]\n  );\n}\n\n/**\n * Generate path matches for a given path and origin on a set of OpenAPI path objects.\n *\n * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object}\n * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#paths-object}\n * @param paths The OpenAPI Paths Object to process.\n * @param pathName Path to look for a match.\n * @param origin The origin that we're matching against.\n */\nexport function generatePathMatches(paths: PathsObject, pathName: string, origin: string): PathMatches {\n  const prunedPathName = pathName.split('?')[0];\n  const matches: PathMatches = Object.keys(paths)\n    .map(path => {\n      const cleanedPath = normalizePath(path);\n\n      let matchResult: PathMatch['match'];\n      try {\n        const matchStatement = match(cleanedPath, { decode: decodeURIComponent });\n        matchResult = matchStatement(prunedPathName);\n      } catch {\n        // If path matching fails for whatever reason (maybe they have a malformed path parameter)\n        // then we shouldn't also fail.\n        return false;\n      }\n\n      const slugs: Record<string, string> = {};\n\n      if (matchResult && Object.keys(matchResult.params).length) {\n        Object.keys(matchResult.params).forEach(param => {\n          slugs[`:${param}`] = (matchResult.params as Record<string, string>)[param];\n        });\n      }\n\n      return {\n        url: {\n          origin,\n          path: cleanedPath.replace(/\\\\::/, '::'),\n          nonNormalizedPath: path,\n          slugs,\n        },\n        operation: paths[path] as PathsObject,\n        match: matchResult,\n      } satisfies PathMatch;\n    })\n    .filter(item => item !== false);\n\n  return matches.filter(p => p.match);\n}\n\n/**\n * @param pathMatches Array of path matches to filter down.\n * @param targetMethod HTTP method to look for.\n * @returns Filtered down path matches.\n */\nexport function filterPathMethods(pathMatches: PathMatches, targetMethod: HttpMethods): PathMatch[] {\n  const regExp = pathToRegexp(targetMethod);\n  return pathMatches\n    .map(p => {\n      const captures = Object.keys(p.operation).filter(r => regExp.regexp.exec(r));\n\n      if (captures.length) {\n        const method = captures[0];\n        p.url.method = method.toUpperCase() as HttpMethods;\n\n        return {\n          url: p.url,\n          operation: p.operation[method],\n        };\n      }\n\n      return false;\n    })\n    .filter((item): item is PathMatch => Boolean(item));\n}\n\n/**\n * @param pathMatches URL and PathsObject matches to narrow down to find a target path.\n * @returns An object containing matches that were discovered in the API definition.\n */\nexport function findTargetPath(pathMatches: PathMatch[]): PathMatch | undefined {\n  if (!pathMatches.length) {\n    return undefined;\n  }\n\n  let minCount = Object.keys(pathMatches[0].url.slugs).length;\n  let found: PathMatch | undefined;\n\n  for (let m = 0; m < pathMatches.length; m += 1) {\n    const selection = pathMatches[m];\n    const paramCount = Object.keys(selection.url.slugs).length;\n    if (paramCount <= minCount) {\n      minCount = paramCount;\n      found = selection;\n    }\n  }\n\n  return found;\n}\n"]}