@unshared/client 0.7.3 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"B_Gz6Yz8.js","sources":["../../openapi/getServerUrl.ts","../../openapi/resolveOperation.ts","../../openapi/isOpenAPIV3.ts","../../openapi/resolveOperationTokenOptions.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/** Get the base URL of an OpenAPI specification. */\nexport type ServerUrl<T> =\n\n // --- Handle OpenAPI 2.0 specifications.\n T extends {\n host: infer Host extends string\n basePath?: infer BasePath extends string\n schemes?: Array<infer Scheme extends string>\n }\n ? `${Scheme}://${Host}${BasePath}`\n\n // --- Handle OpenAPI 3.0 specifications.\n : T extends { servers: Array<{ url: infer U extends string }> }\n ? U\n : string\n\n/**\n * Given an OpenAPI specification, get the first base URL.\n *\n * @param specification The OpenAPI specification.\n * @returns The first base URL.\n * @example getBaseUrl(specification) // 'https://api.example.com/v1'\n */\nexport function getServerUrl<T>(specification: T): ServerUrl<T> {\n\n // --- Ensure the specification is an object.\n if (\n !specification\n || typeof specification !== 'object'\n || specification === null)\n throw new Error('Invalid OpenAPI specification.')\n\n // --- Handle OpenAPI 3.0 specifications.\n if (\n 'servers' in specification\n && Array.isArray(specification.servers)\n && specification.servers.length > 0\n && 'url' in specification.servers[0]\n && typeof specification.servers[0].url === 'string'\n && specification.servers[0].url.length > 0)\n return specification.servers[0].url as ServerUrl<T>\n\n // --- Handle OpenAPI 2.0 specifications.\n if (\n 'host' in specification\n && typeof specification.host === 'string') {\n\n const scheme = (\n 'schemes' in specification\n && Array.isArray(specification.schemes)\n && specification.schemes.length > 0\n && typeof specification.schemes[0] === 'string')\n ? specification.schemes[0]\n : 'https'\n\n const basePath = (\n 'basePath' in specification\n && typeof specification.basePath === 'string'\n && specification.basePath.length > 0)\n ? specification.basePath\n : '/'\n\n return `${scheme}://${specification.host}${basePath}` as ServerUrl<T>\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { CollectKey, Pretty } from '@unshared/types'\nimport type { OpenAPI } from 'openapi-types'\nimport type { FetchMethod } from '../utils/parseRequest'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/** Union of all operation IDs in the specification. */\nexport type OperationId<T> =\nT extends { paths: infer P }\n ? P extends Record<string, infer R>\n ? R extends Record<string, infer O>\n ? O extends { operationId: infer N }\n ? N\n : string\n : string\n : string\n : string\n\n/** A union of possible Operations types in the specification. */\nexport type Operation = OpenAPI.Operation & { method: FetchMethod; path: string }\n\n/** Find an operation by its operationId in an OpenAPI specification. */\nexport type OperationById<T, U extends OperationId<T>> =\n T extends { paths: infer P }\n ? CollectKey<P> extends Record<string, infer R>\n ? CollectKey<R> extends Record<string, infer O>\n ? O extends { $key: [infer P extends string, infer M extends string]; operationId: U }\n ? Pretty<Omit<O, '$key'> & { method: M; path: P }>\n : never\n : never\n : never\n : never\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param document The OpenAPI specification document.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example resolveOperation(document, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U>\nexport function resolveOperation(document: object, operationId: string): Operation\nexport function resolveOperation(document: object, operationId: string): Operation {\n\n // --- Validate the specification.\n if (!document\n || typeof document !== 'object'\n || document === null\n || 'paths' in document === false\n || typeof document.paths !== 'object'\n || document.paths === null)\n throw new Error('Missing paths object in the OpenAPI specification.')\n\n // --- Search for the operation in the specification's paths.\n const paths = document.paths as OpenAPI.Document['paths']\n for (const path in paths) {\n const route = paths[path]\n if (typeof route !== 'object' || route === null) continue\n\n // --- Search in each method for the operation.\n for (const method of methods) {\n const operation = route[method]\n if (method in route === false\n || typeof operation !== 'object'\n || operation === null\n || 'operationId' in operation === false\n || operation.operationId !== operationId) continue\n\n // --- Route was found, return the operation.\n return { ...route[method], method, path }\n }\n }\n\n // --- Throw an error if the operation was not found.\n throw new Error(`Operation \"${operationId}\" not found in specification.`)\n}\n","/* eslint-disable unicorn/filename-case */\nimport type { OpenAPIV3 } from 'openapi-types'\n\n/**\n * Check if the given document is an OpenAPI v3.0 specification.\n *\n * @param value The document to check.\n * @returns `true` if the document is an OpenAPI v3.0 specification, `false` otherwise.\n * @example isOpenAPIV3({ openapi: '3.0.0', info: { title: 'Test API', version: '1.0.0' } }) // => true\n */\nexport function isOpenAPIV3(value: unknown): value is OpenAPIV3.Document {\n return typeof value === 'object'\n && value !== null\n && 'openapi' in value\n && value.openapi === '3.0.0'\n}\n","import type { OpenAPI, OpenAPIV3 as V3 } from 'openapi-types'\nimport { isOpenAPIV3 } from './isOpenAPIV3'\n\nexport interface TokenOptions {\n tokenLocation?: 'cookie' | 'header' | 'query'\n tokenProperty?: string\n}\n\n/**\n * Resolve the location of the apiKey token based on the OpenAPI specification.\n *\n * @param document The OpenAPI specification document.\n * @param operation The OpenAPI operation object.\n * @returns The location of the apiKey token ('query' | 'cookie' | 'header').\n * @example resolveOperationTokenOptions(document, operation) // => { tokenLocation: 'header', tokenProperty: 'X-API-Key' }\n */\nexport function resolveOperationTokenOptions(document: object, operation: OpenAPI.Operation): TokenOptions {\n if (!isOpenAPIV3(document)) return {}\n\n // --- Find the security scheme in the OpenAPI specification.\n const security = operation.security ?? document.security\n if (!security) return {}\n const securityScheme = document?.components?.securitySchemes\n if (!securityScheme) return {}\n\n // --- Find the first security scheme that is an apiKey.\n for (const requirement of security) {\n for (const key in requirement) {\n const scheme = securityScheme[key] as V3.SecuritySchemeObject\n if (typeof scheme !== 'object' || scheme === null) continue\n if (scheme.type === 'apiKey') {\n return {\n tokenLocation: scheme.in as 'cookie' | 'header' | 'query',\n tokenProperty: scheme.name,\n }\n }\n }\n }\n\n // --- Return an empty object if no apiKey was found.\n return {}\n}\n"],"names":[],"mappings":"AAwBO,SAAS,aAAgB,eAAgC;AAG9D,MACE,CAAC,iBACE,OAAO,iBAAkB,YACzB,kBAAkB;AACrB,UAAM,IAAI,MAAM,gCAAgC;AAGlD,MACE,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,SAAS,cAAc,QAAQ,CAAC,KAChC,OAAO,cAAc,QAAQ,CAAC,EAAE,OAAQ,YACxC,cAAc,QAAQ,CAAC,EAAE,IAAI,SAAS;AACzC,WAAO,cAAc,QAAQ,CAAC,EAAE;AAGlC,MACE,UAAU,iBACP,OAAO,cAAc,QAAS,UAAU;AAE3C,UAAM,SACJ,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,OAAO,cAAc,QAAQ,CAAC,KAAM,WACrC,cAAc,QAAQ,CAAC,IACvB,SAEE,WACJ,cAAc,iBACX,OAAO,cAAc,YAAa,YAClC,cAAc,SAAS,SAAS,IACjC,cAAc,WACd;AAEJ,WAAO,GAAG,MAAM,MAAM,cAAc,IAAI,GAAG,QAAQ;AAAA,EACrD;AAEA,QAAM,IAAI,MAAM,iDAAiD;AACnE;AC9DA,MAAM,UAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,OAAO;AAuCpE,SAAS,iBAAiB,UAAkB,aAAgC;AAGjF,MAAI,CAAC,YACA,OAAO,YAAa,YACpB,aAAa,QACb,EAAA,WAAW,aACX,OAAO,SAAS,SAAU,YAC1B,SAAS,UAAU;AACtB,UAAM,IAAI,MAAM,oDAAoD;AAGtE,QAAM,QAAQ,SAAS;AACvB,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,MAAM,IAAI;AACxB,QAAI,EAAA,OAAO,SAAU,YAAY,UAAU;AAG3C,iBAAW,UAAU,SAAS;AAC5B,cAAM,YAAY,MAAM,MAAM;AAC9B,YAAI,EAAA,EAAA,UAAU,UACT,OAAO,aAAc,YACrB,cAAc,QACd,EAAA,iBAAiB,cACjB,UAAU,gBAAgB;AAG/B,iBAAO,EAAE,GAAG,MAAM,MAAM,GAAG,QAAQ,KAAA;AAAA,MACrC;AAAA,EACF;AAGA,QAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAC1E;ACnEO,SAAS,YAAY,OAA6C;AACvE,SAAO,OAAO,SAAU,YACnB,UAAU,QACV,aAAa,SACb,MAAM,YAAY;AACzB;ACCO,SAAS,6BAA6B,UAAkB,WAA4C;AACzG,MAAI,CAAC,YAAY,QAAQ,UAAU,CAAA;AAGnC,QAAM,WAAW,UAAU,YAAY,SAAS;AAChD,MAAI,CAAC,SAAU,QAAO,CAAA;AACtB,QAAM,iBAAiB,UAAU,YAAY;AAC7C,MAAI,CAAC,eAAgB,QAAO,CAAA;AAG5B,aAAW,eAAe;AACxB,eAAW,OAAO,aAAa;AAC7B,YAAM,SAAS,eAAe,GAAG;AACjC,UAAI,SAAO,UAAW,YAAY,WAAW,SACzC,OAAO,SAAS;AAClB,eAAO;AAAA,UACL,eAAe,OAAO;AAAA,UACtB,eAAe,OAAO;AAAA,QAAA;AAAA,IAG5B;AAIF,SAAO,CAAA;AACT;"}
1
+ {"version":3,"file":"B_Gz6Yz8.js","sources":["../../openapi/getServerUrl.ts","../../openapi/resolveOperation.ts","../../openapi/isOpenAPIV3.ts","../../openapi/resolveOperationTokenOptions.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/** Get the base URL of an OpenAPI specification. */\nexport type ServerUrl<T> =\n\n // --- Handle OpenAPI 2.0 specifications.\n T extends {\n host: infer Host extends string\n basePath?: infer BasePath extends string\n schemes?: Array<infer Scheme extends string>\n }\n ? `${Scheme}://${Host}${BasePath}`\n\n // --- Handle OpenAPI 3.0 specifications.\n : T extends { servers: Array<{ url: infer U extends string }> }\n ? U\n : string\n\n/**\n * Given an OpenAPI specification, get the first base URL.\n *\n * @param specification The OpenAPI specification.\n * @returns The first base URL.\n * @example getBaseUrl(specification) // 'https://api.example.com/v1'\n */\nexport function getServerUrl<T>(specification: T): ServerUrl<T> {\n\n // --- Ensure the specification is an object.\n if (\n !specification\n || typeof specification !== 'object'\n || specification === null)\n throw new Error('Invalid OpenAPI specification.')\n\n // --- Handle OpenAPI 3.0 specifications.\n if (\n 'servers' in specification\n && Array.isArray(specification.servers)\n && specification.servers.length > 0\n && 'url' in specification.servers[0]\n && typeof specification.servers[0].url === 'string'\n && specification.servers[0].url.length > 0)\n return specification.servers[0].url as ServerUrl<T>\n\n // --- Handle OpenAPI 2.0 specifications.\n if (\n 'host' in specification\n && typeof specification.host === 'string') {\n\n const scheme = (\n 'schemes' in specification\n && Array.isArray(specification.schemes)\n && specification.schemes.length > 0\n && typeof specification.schemes[0] === 'string')\n ? specification.schemes[0]\n : 'https'\n\n const basePath = (\n 'basePath' in specification\n && typeof specification.basePath === 'string'\n && specification.basePath.length > 0)\n ? specification.basePath\n : '/'\n\n return `${scheme}://${specification.host}${basePath}` as ServerUrl<T>\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { CollectKey, Pretty } from '@unshared/types'\nimport type { OpenAPI } from 'openapi-types'\nimport type { FetchMethod } from '../utils/parseRequest'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/** Union of all operation IDs in the specification. */\nexport type OperationId<T> =\n T extends { paths: infer P }\n ? P extends Record<string, infer R>\n ? R extends Record<string, infer O>\n ? O extends { operationId: infer N }\n ? N\n : string\n : string\n : string\n : string\n\n/** A union of possible Operations types in the specification. */\nexport type Operation = OpenAPI.Operation & { method: FetchMethod; path: string }\n\n/** Find an operation by its operationId in an OpenAPI specification. */\nexport type OperationById<T, U extends OperationId<T>> =\n T extends { paths: infer P }\n ? CollectKey<P> extends Record<string, infer R>\n ? CollectKey<R> extends Record<string, infer O>\n ? O extends { $key: [infer P extends string, infer M extends string]; operationId: U }\n ? Pretty<Omit<O, '$key'> & { method: M; path: P }>\n : never\n : never\n : never\n : never\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param document The OpenAPI specification document.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example resolveOperation(document, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U>\nexport function resolveOperation(document: object, operationId: string): Operation\nexport function resolveOperation(document: object, operationId: string): Operation {\n\n // --- Validate the specification.\n if (!document\n || typeof document !== 'object'\n || document === null\n || 'paths' in document === false\n || typeof document.paths !== 'object'\n || document.paths === null)\n throw new Error('Missing paths object in the OpenAPI specification.')\n\n // --- Search for the operation in the specification's paths.\n const paths = document.paths as OpenAPI.Document['paths']\n for (const path in paths) {\n const route = paths[path]\n if (typeof route !== 'object' || route === null) continue\n\n // --- Search in each method for the operation.\n for (const method of methods) {\n const operation = route[method]\n if (method in route === false\n || typeof operation !== 'object'\n || operation === null\n || 'operationId' in operation === false\n || operation.operationId !== operationId) continue\n\n // --- Route was found, return the operation.\n return { ...route[method], method, path }\n }\n }\n\n // --- Throw an error if the operation was not found.\n throw new Error(`Operation \"${operationId}\" not found in specification.`)\n}\n","/* eslint-disable unicorn/filename-case */\nimport type { OpenAPIV3 } from 'openapi-types'\n\n/**\n * Check if the given document is an OpenAPI v3.0 specification.\n *\n * @param value The document to check.\n * @returns `true` if the document is an OpenAPI v3.0 specification, `false` otherwise.\n * @example isOpenAPIV3({ openapi: '3.0.0', info: { title: 'Test API', version: '1.0.0' } }) // => true\n */\nexport function isOpenAPIV3(value: unknown): value is OpenAPIV3.Document {\n return typeof value === 'object'\n && value !== null\n && 'openapi' in value\n && value.openapi === '3.0.0'\n}\n","import type { OpenAPI, OpenAPIV3 as V3 } from 'openapi-types'\nimport { isOpenAPIV3 } from './isOpenAPIV3'\n\nexport interface TokenOptions {\n tokenLocation?: 'cookie' | 'header' | 'query'\n tokenProperty?: string\n}\n\n/**\n * Resolve the location of the apiKey token based on the OpenAPI specification.\n *\n * @param document The OpenAPI specification document.\n * @param operation The OpenAPI operation object.\n * @returns The location of the apiKey token ('query' | 'cookie' | 'header').\n * @example resolveOperationTokenOptions(document, operation) // => { tokenLocation: 'header', tokenProperty: 'X-API-Key' }\n */\nexport function resolveOperationTokenOptions(document: object, operation: OpenAPI.Operation): TokenOptions {\n if (!isOpenAPIV3(document)) return {}\n\n // --- Find the security scheme in the OpenAPI specification.\n const security = operation.security ?? document.security\n if (!security) return {}\n const securityScheme = document?.components?.securitySchemes\n if (!securityScheme) return {}\n\n // --- Find the first security scheme that is an apiKey.\n for (const requirement of security) {\n for (const key in requirement) {\n const scheme = securityScheme[key] as V3.SecuritySchemeObject\n if (typeof scheme !== 'object' || scheme === null) continue\n if (scheme.type === 'apiKey') {\n return {\n tokenLocation: scheme.in as 'cookie' | 'header' | 'query',\n tokenProperty: scheme.name,\n }\n }\n }\n }\n\n // --- Return an empty object if no apiKey was found.\n return {}\n}\n"],"names":[],"mappings":"AAwBO,SAAS,aAAgB,eAAgC;AAG9D,MACE,CAAC,iBACE,OAAO,iBAAkB,YACzB,kBAAkB;AACrB,UAAM,IAAI,MAAM,gCAAgC;AAGlD,MACE,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,SAAS,cAAc,QAAQ,CAAC,KAChC,OAAO,cAAc,QAAQ,CAAC,EAAE,OAAQ,YACxC,cAAc,QAAQ,CAAC,EAAE,IAAI,SAAS;AACzC,WAAO,cAAc,QAAQ,CAAC,EAAE;AAGlC,MACE,UAAU,iBACP,OAAO,cAAc,QAAS,UAAU;AAE3C,UAAM,SACJ,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,OAAO,cAAc,QAAQ,CAAC,KAAM,WACrC,cAAc,QAAQ,CAAC,IACvB,SAEE,WACJ,cAAc,iBACX,OAAO,cAAc,YAAa,YAClC,cAAc,SAAS,SAAS,IACjC,cAAc,WACd;AAEJ,WAAO,GAAG,MAAM,MAAM,cAAc,IAAI,GAAG,QAAQ;AAAA,EACrD;AAEA,QAAM,IAAI,MAAM,iDAAiD;AACnE;AC9DA,MAAM,UAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,OAAO;AAuCpE,SAAS,iBAAiB,UAAkB,aAAgC;AAGjF,MAAI,CAAC,YACA,OAAO,YAAa,YACpB,aAAa,QACb,EAAA,WAAW,aACX,OAAO,SAAS,SAAU,YAC1B,SAAS,UAAU;AACtB,UAAM,IAAI,MAAM,oDAAoD;AAGtE,QAAM,QAAQ,SAAS;AACvB,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,MAAM,IAAI;AACxB,QAAI,EAAA,OAAO,SAAU,YAAY,UAAU;AAG3C,iBAAW,UAAU,SAAS;AAC5B,cAAM,YAAY,MAAM,MAAM;AAC9B,YAAI,EAAA,EAAA,UAAU,UACT,OAAO,aAAc,YACrB,cAAc,QACd,EAAA,iBAAiB,cACjB,UAAU,gBAAgB;AAG/B,iBAAO,EAAE,GAAG,MAAM,MAAM,GAAG,QAAQ,KAAA;AAAA,MACrC;AAAA,EACF;AAGA,QAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAC1E;ACnEO,SAAS,YAAY,OAA6C;AACvE,SAAO,OAAO,SAAU,YACnB,UAAU,QACV,aAAa,SACb,MAAM,YAAY;AACzB;ACCO,SAAS,6BAA6B,UAAkB,WAA4C;AACzG,MAAI,CAAC,YAAY,QAAQ,UAAU,CAAA;AAGnC,QAAM,WAAW,UAAU,YAAY,SAAS;AAChD,MAAI,CAAC,SAAU,QAAO,CAAA;AACtB,QAAM,iBAAiB,UAAU,YAAY;AAC7C,MAAI,CAAC,eAAgB,QAAO,CAAA;AAG5B,aAAW,eAAe;AACxB,eAAW,OAAO,aAAa;AAC7B,YAAM,SAAS,eAAe,GAAG;AACjC,UAAI,SAAO,UAAW,YAAY,WAAW,SACzC,OAAO,SAAS;AAClB,eAAO;AAAA,UACL,eAAe,OAAO;AAAA,UACtB,eAAe,OAAO;AAAA,QAAA;AAAA,IAG5B;AAIF,SAAO,CAAA;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"DEyigyGy.cjs","sources":["../../openapi/getServerUrl.ts","../../openapi/resolveOperation.ts","../../openapi/isOpenAPIV3.ts","../../openapi/resolveOperationTokenOptions.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/** Get the base URL of an OpenAPI specification. */\nexport type ServerUrl<T> =\n\n // --- Handle OpenAPI 2.0 specifications.\n T extends {\n host: infer Host extends string\n basePath?: infer BasePath extends string\n schemes?: Array<infer Scheme extends string>\n }\n ? `${Scheme}://${Host}${BasePath}`\n\n // --- Handle OpenAPI 3.0 specifications.\n : T extends { servers: Array<{ url: infer U extends string }> }\n ? U\n : string\n\n/**\n * Given an OpenAPI specification, get the first base URL.\n *\n * @param specification The OpenAPI specification.\n * @returns The first base URL.\n * @example getBaseUrl(specification) // 'https://api.example.com/v1'\n */\nexport function getServerUrl<T>(specification: T): ServerUrl<T> {\n\n // --- Ensure the specification is an object.\n if (\n !specification\n || typeof specification !== 'object'\n || specification === null)\n throw new Error('Invalid OpenAPI specification.')\n\n // --- Handle OpenAPI 3.0 specifications.\n if (\n 'servers' in specification\n && Array.isArray(specification.servers)\n && specification.servers.length > 0\n && 'url' in specification.servers[0]\n && typeof specification.servers[0].url === 'string'\n && specification.servers[0].url.length > 0)\n return specification.servers[0].url as ServerUrl<T>\n\n // --- Handle OpenAPI 2.0 specifications.\n if (\n 'host' in specification\n && typeof specification.host === 'string') {\n\n const scheme = (\n 'schemes' in specification\n && Array.isArray(specification.schemes)\n && specification.schemes.length > 0\n && typeof specification.schemes[0] === 'string')\n ? specification.schemes[0]\n : 'https'\n\n const basePath = (\n 'basePath' in specification\n && typeof specification.basePath === 'string'\n && specification.basePath.length > 0)\n ? specification.basePath\n : '/'\n\n return `${scheme}://${specification.host}${basePath}` as ServerUrl<T>\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { CollectKey, Pretty } from '@unshared/types'\nimport type { OpenAPI } from 'openapi-types'\nimport type { FetchMethod } from '../utils/parseRequest'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/** Union of all operation IDs in the specification. */\nexport type OperationId<T> =\nT extends { paths: infer P }\n ? P extends Record<string, infer R>\n ? R extends Record<string, infer O>\n ? O extends { operationId: infer N }\n ? N\n : string\n : string\n : string\n : string\n\n/** A union of possible Operations types in the specification. */\nexport type Operation = OpenAPI.Operation & { method: FetchMethod; path: string }\n\n/** Find an operation by its operationId in an OpenAPI specification. */\nexport type OperationById<T, U extends OperationId<T>> =\n T extends { paths: infer P }\n ? CollectKey<P> extends Record<string, infer R>\n ? CollectKey<R> extends Record<string, infer O>\n ? O extends { $key: [infer P extends string, infer M extends string]; operationId: U }\n ? Pretty<Omit<O, '$key'> & { method: M; path: P }>\n : never\n : never\n : never\n : never\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param document The OpenAPI specification document.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example resolveOperation(document, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U>\nexport function resolveOperation(document: object, operationId: string): Operation\nexport function resolveOperation(document: object, operationId: string): Operation {\n\n // --- Validate the specification.\n if (!document\n || typeof document !== 'object'\n || document === null\n || 'paths' in document === false\n || typeof document.paths !== 'object'\n || document.paths === null)\n throw new Error('Missing paths object in the OpenAPI specification.')\n\n // --- Search for the operation in the specification's paths.\n const paths = document.paths as OpenAPI.Document['paths']\n for (const path in paths) {\n const route = paths[path]\n if (typeof route !== 'object' || route === null) continue\n\n // --- Search in each method for the operation.\n for (const method of methods) {\n const operation = route[method]\n if (method in route === false\n || typeof operation !== 'object'\n || operation === null\n || 'operationId' in operation === false\n || operation.operationId !== operationId) continue\n\n // --- Route was found, return the operation.\n return { ...route[method], method, path }\n }\n }\n\n // --- Throw an error if the operation was not found.\n throw new Error(`Operation \"${operationId}\" not found in specification.`)\n}\n","/* eslint-disable unicorn/filename-case */\nimport type { OpenAPIV3 } from 'openapi-types'\n\n/**\n * Check if the given document is an OpenAPI v3.0 specification.\n *\n * @param value The document to check.\n * @returns `true` if the document is an OpenAPI v3.0 specification, `false` otherwise.\n * @example isOpenAPIV3({ openapi: '3.0.0', info: { title: 'Test API', version: '1.0.0' } }) // => true\n */\nexport function isOpenAPIV3(value: unknown): value is OpenAPIV3.Document {\n return typeof value === 'object'\n && value !== null\n && 'openapi' in value\n && value.openapi === '3.0.0'\n}\n","import type { OpenAPI, OpenAPIV3 as V3 } from 'openapi-types'\nimport { isOpenAPIV3 } from './isOpenAPIV3'\n\nexport interface TokenOptions {\n tokenLocation?: 'cookie' | 'header' | 'query'\n tokenProperty?: string\n}\n\n/**\n * Resolve the location of the apiKey token based on the OpenAPI specification.\n *\n * @param document The OpenAPI specification document.\n * @param operation The OpenAPI operation object.\n * @returns The location of the apiKey token ('query' | 'cookie' | 'header').\n * @example resolveOperationTokenOptions(document, operation) // => { tokenLocation: 'header', tokenProperty: 'X-API-Key' }\n */\nexport function resolveOperationTokenOptions(document: object, operation: OpenAPI.Operation): TokenOptions {\n if (!isOpenAPIV3(document)) return {}\n\n // --- Find the security scheme in the OpenAPI specification.\n const security = operation.security ?? document.security\n if (!security) return {}\n const securityScheme = document?.components?.securitySchemes\n if (!securityScheme) return {}\n\n // --- Find the first security scheme that is an apiKey.\n for (const requirement of security) {\n for (const key in requirement) {\n const scheme = securityScheme[key] as V3.SecuritySchemeObject\n if (typeof scheme !== 'object' || scheme === null) continue\n if (scheme.type === 'apiKey') {\n return {\n tokenLocation: scheme.in as 'cookie' | 'header' | 'query',\n tokenProperty: scheme.name,\n }\n }\n }\n }\n\n // --- Return an empty object if no apiKey was found.\n return {}\n}\n"],"names":[],"mappings":";AAwBO,SAAS,aAAgB,eAAgC;AAG9D,MACE,CAAC,iBACE,OAAO,iBAAkB,YACzB,kBAAkB;AACrB,UAAM,IAAI,MAAM,gCAAgC;AAGlD,MACE,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,SAAS,cAAc,QAAQ,CAAC,KAChC,OAAO,cAAc,QAAQ,CAAC,EAAE,OAAQ,YACxC,cAAc,QAAQ,CAAC,EAAE,IAAI,SAAS;AACzC,WAAO,cAAc,QAAQ,CAAC,EAAE;AAGlC,MACE,UAAU,iBACP,OAAO,cAAc,QAAS,UAAU;AAE3C,UAAM,SACJ,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,OAAO,cAAc,QAAQ,CAAC,KAAM,WACrC,cAAc,QAAQ,CAAC,IACvB,SAEE,WACJ,cAAc,iBACX,OAAO,cAAc,YAAa,YAClC,cAAc,SAAS,SAAS,IACjC,cAAc,WACd;AAEJ,WAAO,GAAG,MAAM,MAAM,cAAc,IAAI,GAAG,QAAQ;AAAA,EACrD;AAEA,QAAM,IAAI,MAAM,iDAAiD;AACnE;AC9DA,MAAM,UAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,OAAO;AAuCpE,SAAS,iBAAiB,UAAkB,aAAgC;AAGjF,MAAI,CAAC,YACA,OAAO,YAAa,YACpB,aAAa,QACb,EAAA,WAAW,aACX,OAAO,SAAS,SAAU,YAC1B,SAAS,UAAU;AACtB,UAAM,IAAI,MAAM,oDAAoD;AAGtE,QAAM,QAAQ,SAAS;AACvB,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,MAAM,IAAI;AACxB,QAAI,EAAA,OAAO,SAAU,YAAY,UAAU;AAG3C,iBAAW,UAAU,SAAS;AAC5B,cAAM,YAAY,MAAM,MAAM;AAC9B,YAAI,EAAA,EAAA,UAAU,UACT,OAAO,aAAc,YACrB,cAAc,QACd,EAAA,iBAAiB,cACjB,UAAU,gBAAgB;AAG/B,iBAAO,EAAE,GAAG,MAAM,MAAM,GAAG,QAAQ,KAAA;AAAA,MACrC;AAAA,EACF;AAGA,QAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAC1E;ACnEO,SAAS,YAAY,OAA6C;AACvE,SAAO,OAAO,SAAU,YACnB,UAAU,QACV,aAAa,SACb,MAAM,YAAY;AACzB;ACCO,SAAS,6BAA6B,UAAkB,WAA4C;AACzG,MAAI,CAAC,YAAY,QAAQ,UAAU,CAAA;AAGnC,QAAM,WAAW,UAAU,YAAY,SAAS;AAChD,MAAI,CAAC,SAAU,QAAO,CAAA;AACtB,QAAM,iBAAiB,UAAU,YAAY;AAC7C,MAAI,CAAC,eAAgB,QAAO,CAAA;AAG5B,aAAW,eAAe;AACxB,eAAW,OAAO,aAAa;AAC7B,YAAM,SAAS,eAAe,GAAG;AACjC,UAAI,SAAO,UAAW,YAAY,WAAW,SACzC,OAAO,SAAS;AAClB,eAAO;AAAA,UACL,eAAe,OAAO;AAAA,UACtB,eAAe,OAAO;AAAA,QAAA;AAAA,IAG5B;AAIF,SAAO,CAAA;AACT;;;;;"}
1
+ {"version":3,"file":"DEyigyGy.cjs","sources":["../../openapi/getServerUrl.ts","../../openapi/resolveOperation.ts","../../openapi/isOpenAPIV3.ts","../../openapi/resolveOperationTokenOptions.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/** Get the base URL of an OpenAPI specification. */\nexport type ServerUrl<T> =\n\n // --- Handle OpenAPI 2.0 specifications.\n T extends {\n host: infer Host extends string\n basePath?: infer BasePath extends string\n schemes?: Array<infer Scheme extends string>\n }\n ? `${Scheme}://${Host}${BasePath}`\n\n // --- Handle OpenAPI 3.0 specifications.\n : T extends { servers: Array<{ url: infer U extends string }> }\n ? U\n : string\n\n/**\n * Given an OpenAPI specification, get the first base URL.\n *\n * @param specification The OpenAPI specification.\n * @returns The first base URL.\n * @example getBaseUrl(specification) // 'https://api.example.com/v1'\n */\nexport function getServerUrl<T>(specification: T): ServerUrl<T> {\n\n // --- Ensure the specification is an object.\n if (\n !specification\n || typeof specification !== 'object'\n || specification === null)\n throw new Error('Invalid OpenAPI specification.')\n\n // --- Handle OpenAPI 3.0 specifications.\n if (\n 'servers' in specification\n && Array.isArray(specification.servers)\n && specification.servers.length > 0\n && 'url' in specification.servers[0]\n && typeof specification.servers[0].url === 'string'\n && specification.servers[0].url.length > 0)\n return specification.servers[0].url as ServerUrl<T>\n\n // --- Handle OpenAPI 2.0 specifications.\n if (\n 'host' in specification\n && typeof specification.host === 'string') {\n\n const scheme = (\n 'schemes' in specification\n && Array.isArray(specification.schemes)\n && specification.schemes.length > 0\n && typeof specification.schemes[0] === 'string')\n ? specification.schemes[0]\n : 'https'\n\n const basePath = (\n 'basePath' in specification\n && typeof specification.basePath === 'string'\n && specification.basePath.length > 0)\n ? specification.basePath\n : '/'\n\n return `${scheme}://${specification.host}${basePath}` as ServerUrl<T>\n }\n\n throw new Error('No base URL found in the OpenAPI specification.')\n}\n","import type { CollectKey, Pretty } from '@unshared/types'\nimport type { OpenAPI } from 'openapi-types'\nimport type { FetchMethod } from '../utils/parseRequest'\n\n/** The HTTP methods supported by OpenAPI. */\nconst methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] as const\n\n/** Union of all operation IDs in the specification. */\nexport type OperationId<T> =\n T extends { paths: infer P }\n ? P extends Record<string, infer R>\n ? R extends Record<string, infer O>\n ? O extends { operationId: infer N }\n ? N\n : string\n : string\n : string\n : string\n\n/** A union of possible Operations types in the specification. */\nexport type Operation = OpenAPI.Operation & { method: FetchMethod; path: string }\n\n/** Find an operation by its operationId in an OpenAPI specification. */\nexport type OperationById<T, U extends OperationId<T>> =\n T extends { paths: infer P }\n ? CollectKey<P> extends Record<string, infer R>\n ? CollectKey<R> extends Record<string, infer O>\n ? O extends { $key: [infer P extends string, infer M extends string]; operationId: U }\n ? Pretty<Omit<O, '$key'> & { method: M; path: P }>\n : never\n : never\n : never\n : never\n\n/**\n * Given an OpenAPI specification, find an operation by its operationId.\n *\n * @param document The OpenAPI specification document.\n * @param operationId The operationId of the operation to resolve.\n * @returns The resolved operation.\n * @example resolveOperation(document, 'getUser') // { method: 'get', path: '/users/{username}', ... }\n */\nexport function resolveOperation<T, U extends OperationId<T>>(document: T, operationId: U): OperationById<T, U>\nexport function resolveOperation(document: object, operationId: string): Operation\nexport function resolveOperation(document: object, operationId: string): Operation {\n\n // --- Validate the specification.\n if (!document\n || typeof document !== 'object'\n || document === null\n || 'paths' in document === false\n || typeof document.paths !== 'object'\n || document.paths === null)\n throw new Error('Missing paths object in the OpenAPI specification.')\n\n // --- Search for the operation in the specification's paths.\n const paths = document.paths as OpenAPI.Document['paths']\n for (const path in paths) {\n const route = paths[path]\n if (typeof route !== 'object' || route === null) continue\n\n // --- Search in each method for the operation.\n for (const method of methods) {\n const operation = route[method]\n if (method in route === false\n || typeof operation !== 'object'\n || operation === null\n || 'operationId' in operation === false\n || operation.operationId !== operationId) continue\n\n // --- Route was found, return the operation.\n return { ...route[method], method, path }\n }\n }\n\n // --- Throw an error if the operation was not found.\n throw new Error(`Operation \"${operationId}\" not found in specification.`)\n}\n","/* eslint-disable unicorn/filename-case */\nimport type { OpenAPIV3 } from 'openapi-types'\n\n/**\n * Check if the given document is an OpenAPI v3.0 specification.\n *\n * @param value The document to check.\n * @returns `true` if the document is an OpenAPI v3.0 specification, `false` otherwise.\n * @example isOpenAPIV3({ openapi: '3.0.0', info: { title: 'Test API', version: '1.0.0' } }) // => true\n */\nexport function isOpenAPIV3(value: unknown): value is OpenAPIV3.Document {\n return typeof value === 'object'\n && value !== null\n && 'openapi' in value\n && value.openapi === '3.0.0'\n}\n","import type { OpenAPI, OpenAPIV3 as V3 } from 'openapi-types'\nimport { isOpenAPIV3 } from './isOpenAPIV3'\n\nexport interface TokenOptions {\n tokenLocation?: 'cookie' | 'header' | 'query'\n tokenProperty?: string\n}\n\n/**\n * Resolve the location of the apiKey token based on the OpenAPI specification.\n *\n * @param document The OpenAPI specification document.\n * @param operation The OpenAPI operation object.\n * @returns The location of the apiKey token ('query' | 'cookie' | 'header').\n * @example resolveOperationTokenOptions(document, operation) // => { tokenLocation: 'header', tokenProperty: 'X-API-Key' }\n */\nexport function resolveOperationTokenOptions(document: object, operation: OpenAPI.Operation): TokenOptions {\n if (!isOpenAPIV3(document)) return {}\n\n // --- Find the security scheme in the OpenAPI specification.\n const security = operation.security ?? document.security\n if (!security) return {}\n const securityScheme = document?.components?.securitySchemes\n if (!securityScheme) return {}\n\n // --- Find the first security scheme that is an apiKey.\n for (const requirement of security) {\n for (const key in requirement) {\n const scheme = securityScheme[key] as V3.SecuritySchemeObject\n if (typeof scheme !== 'object' || scheme === null) continue\n if (scheme.type === 'apiKey') {\n return {\n tokenLocation: scheme.in as 'cookie' | 'header' | 'query',\n tokenProperty: scheme.name,\n }\n }\n }\n }\n\n // --- Return an empty object if no apiKey was found.\n return {}\n}\n"],"names":[],"mappings":";AAwBO,SAAS,aAAgB,eAAgC;AAG9D,MACE,CAAC,iBACE,OAAO,iBAAkB,YACzB,kBAAkB;AACrB,UAAM,IAAI,MAAM,gCAAgC;AAGlD,MACE,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,SAAS,cAAc,QAAQ,CAAC,KAChC,OAAO,cAAc,QAAQ,CAAC,EAAE,OAAQ,YACxC,cAAc,QAAQ,CAAC,EAAE,IAAI,SAAS;AACzC,WAAO,cAAc,QAAQ,CAAC,EAAE;AAGlC,MACE,UAAU,iBACP,OAAO,cAAc,QAAS,UAAU;AAE3C,UAAM,SACJ,aAAa,iBACV,MAAM,QAAQ,cAAc,OAAO,KACnC,cAAc,QAAQ,SAAS,KAC/B,OAAO,cAAc,QAAQ,CAAC,KAAM,WACrC,cAAc,QAAQ,CAAC,IACvB,SAEE,WACJ,cAAc,iBACX,OAAO,cAAc,YAAa,YAClC,cAAc,SAAS,SAAS,IACjC,cAAc,WACd;AAEJ,WAAO,GAAG,MAAM,MAAM,cAAc,IAAI,GAAG,QAAQ;AAAA,EACrD;AAEA,QAAM,IAAI,MAAM,iDAAiD;AACnE;AC9DA,MAAM,UAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,OAAO;AAuCpE,SAAS,iBAAiB,UAAkB,aAAgC;AAGjF,MAAI,CAAC,YACA,OAAO,YAAa,YACpB,aAAa,QACb,EAAA,WAAW,aACX,OAAO,SAAS,SAAU,YAC1B,SAAS,UAAU;AACtB,UAAM,IAAI,MAAM,oDAAoD;AAGtE,QAAM,QAAQ,SAAS;AACvB,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,MAAM,IAAI;AACxB,QAAI,EAAA,OAAO,SAAU,YAAY,UAAU;AAG3C,iBAAW,UAAU,SAAS;AAC5B,cAAM,YAAY,MAAM,MAAM;AAC9B,YAAI,EAAA,EAAA,UAAU,UACT,OAAO,aAAc,YACrB,cAAc,QACd,EAAA,iBAAiB,cACjB,UAAU,gBAAgB;AAG/B,iBAAO,EAAE,GAAG,MAAM,MAAM,GAAG,QAAQ,KAAA;AAAA,MACrC;AAAA,EACF;AAGA,QAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAC1E;ACnEO,SAAS,YAAY,OAA6C;AACvE,SAAO,OAAO,SAAU,YACnB,UAAU,QACV,aAAa,SACb,MAAM,YAAY;AACzB;ACCO,SAAS,6BAA6B,UAAkB,WAA4C;AACzG,MAAI,CAAC,YAAY,QAAQ,UAAU,CAAA;AAGnC,QAAM,WAAW,UAAU,YAAY,SAAS;AAChD,MAAI,CAAC,SAAU,QAAO,CAAA;AACtB,QAAM,iBAAiB,UAAU,YAAY;AAC7C,MAAI,CAAC,eAAgB,QAAO,CAAA;AAG5B,aAAW,eAAe;AACxB,eAAW,OAAO,aAAa;AAC7B,YAAM,SAAS,eAAe,GAAG;AACjC,UAAI,SAAO,UAAW,YAAY,WAAW,SACzC,OAAO,SAAS;AAClB,eAAO;AAAA,UACL,eAAe,OAAO;AAAA,UACtB,eAAe,OAAO;AAAA,QAAA;AAAA,IAG5B;AAIF,SAAO,CAAA;AACT;;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unshared/client",
3
3
  "type": "module",
4
- "version": "0.7.3",
4
+ "version": "0.7.5",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
7
7
  "author": "Stanley Horwood <stanley@hsjm.io>",
@@ -68,12 +68,12 @@
68
68
  "LICENSE.md"
69
69
  ],
70
70
  "dependencies": {
71
- "@unshared/functions": "0.7.3",
72
- "@unshared/types": "0.7.3",
71
+ "@unshared/functions": "0.7.5",
72
+ "@unshared/types": "0.7.5",
73
73
  "openapi-types": "12.1.3"
74
74
  },
75
75
  "devDependencies": {
76
- "@unshared/scripts": "0.7.3"
76
+ "@unshared/scripts": "0.7.5"
77
77
  },
78
78
  "scripts": {
79
79
  "build:httpMethods": "tsx ./scripts/buildHttpMethods.ts",