@scalar/oas-utils 0.4.17 → 0.4.20
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.
- package/CHANGELOG.md +51 -0
- package/dist/entities/spec/request-examples.d.ts +55 -55
- package/dist/entities/spec/request-examples.d.ts.map +1 -1
- package/dist/entities/spec/request-examples.js.map +2 -2
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +2 -0
- package/dist/helpers/index.js.map +2 -2
- package/dist/helpers/operation-to-har/operation-to-har.d.ts +1 -2
- package/dist/helpers/operation-to-har/operation-to-har.d.ts.map +1 -1
- package/dist/helpers/operation-to-har/operation-to-har.js +16 -8
- package/dist/helpers/operation-to-har/operation-to-har.js.map +2 -2
- package/dist/helpers/operation-to-har/process-body.d.ts +5 -2
- package/dist/helpers/operation-to-har/process-body.d.ts.map +1 -1
- package/dist/helpers/operation-to-har/process-body.js +3 -4
- package/dist/helpers/operation-to-har/process-body.js.map +2 -2
- package/dist/helpers/operation-to-har/process-parameters.d.ts +2 -4
- package/dist/helpers/operation-to-har/process-parameters.d.ts.map +1 -1
- package/dist/helpers/operation-to-har/process-parameters.js +24 -8
- package/dist/helpers/operation-to-har/process-parameters.js.map +2 -2
- package/dist/helpers/operation-to-har/process-security-schemes.js +1 -1
- package/dist/helpers/operation-to-har/process-security-schemes.js.map +2 -2
- package/dist/helpers/servers.d.ts +24 -0
- package/dist/helpers/servers.d.ts.map +1 -0
- package/dist/helpers/servers.js +97 -0
- package/dist/helpers/servers.js.map +7 -0
- package/dist/spec-getters/get-example-from-schema.d.ts +3 -2
- package/dist/spec-getters/get-example-from-schema.d.ts.map +1 -1
- package/dist/spec-getters/get-example-from-schema.js +52 -39
- package/dist/spec-getters/get-example-from-schema.js.map +2 -2
- package/dist/spec-getters/get-parameters-from-operation.d.ts.map +1 -1
- package/dist/spec-getters/get-parameters-from-operation.js +4 -1
- package/dist/spec-getters/get-parameters-from-operation.js.map +2 -2
- package/dist/spec-getters/get-request-body-from-operation.d.ts.map +1 -1
- package/dist/spec-getters/get-request-body-from-operation.js +5 -4
- package/dist/spec-getters/get-request-body-from-operation.js.map +2 -2
- package/dist/transforms/import-spec.d.ts +0 -4
- package/dist/transforms/import-spec.d.ts.map +1 -1
- package/dist/transforms/import-spec.js +2 -69
- package/dist/transforms/import-spec.js.map +2 -2
- package/dist/transforms/index.d.ts +1 -1
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/index.js +0 -2
- package/dist/transforms/index.js.map +2 -2
- package/package.json +9 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/helpers/operation-to-har/process-parameters.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ParameterObject } from '@scalar/workspace-store/schemas/v3.1/strict/parameter'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/path-operations'\nimport type { ReferenceObject } from '@scalar/workspace-store/schemas/v3.1/strict/reference'\nimport { isReference, type Dereference } from '@scalar/workspace-store/schemas/v3.1/type-guard'\nimport type { Request as HarRequest } from 'har-format'\n\ntype ProcessedParameters = {\n url: string\n headers: HarRequest['headers']\n queryString: HarRequest['queryString']\n cookies: HarRequest['cookies']\n}\n\n/** Ensures we don't have any references in the parameters */\nexport const deReferenceParams = (params: Dereference<OperationObject>['parameters']): ParameterObject[] => {\n if (isReference(params)) {\n return []\n }\n return (params ?? []).filter((param) => !isReference(param)) as ParameterObject[]\n}\n\n/**\n * Get the style and explode values for a parameter according to OpenAPI 3.1.1 specification.\n * Handles defaults and validation for parameter location restrictions.\n */\nconst getParameterStyleAndExplode = (param: ParameterObject): { style: string; explode: boolean } => {\n // Headers only support 'simple' style\n if (param.in === 'header') {\n const explode = 'explode' in param && param.explode !== undefined ? param.explode : false\n return { style: 'simple', explode }\n }\n\n // Cookies only support 'form' style\n if (param.in === 'cookie') {\n const explode = 'explode' in param && param.explode !== undefined ? param.explode : true\n return { style: 'form', explode }\n }\n\n const defaultStyle = {\n path: 'simple',\n query: 'form',\n header: 'simple',\n cookie: 'form',\n }[param.in]\n\n // Use provided style or default based on location\n const style = 'style' in param && param.style ? param.style : defaultStyle\n\n // Determine explode value: use provided value or default based on style\n const explode = 'explode' in param && param.explode !== undefined ? param.explode : style === 'form'\n\n return { style, explode }\n}\n\n/**\n * Process OpenAPI parameters and return the updated properties.\n * Handles path, query, and header parameters with various styles and explode options.\n *\n * @see https://spec.openapis.org/oas/latest.html#style-values\n */\nexport const processParameters = (\n harRequest: HarRequest,\n parameters: (ParameterObject | ReferenceObject)[],\n example?: unknown,\n): ProcessedParameters => {\n // Create copies of the arrays to avoid modifying the input\n const newHeaders = [...harRequest.headers]\n const newQueryString = [...harRequest.queryString]\n let newUrl = harRequest.url\n\n // Filter out references\n const deReferencedParams = deReferenceParams(parameters)\n\n for (const param of deReferencedParams) {\n if (!param.in || !param.name) {\n continue\n }\n\n const paramValue =\n example && typeof example === 'object' ? (example as Record<string, unknown>)[param.name] : undefined\n\n if (paramValue === undefined) {\n continue\n }\n\n const { style, explode } = getParameterStyleAndExplode(param)\n\n switch (param.in) {\n case 'path': {\n newUrl = processPathParameters(newUrl, param, paramValue, style, explode)\n break\n }\n case 'query': {\n // Handle query parameters\n switch (style) {\n case 'form': {\n if (explode) {\n // Form explode array: color=blue&color=black&color=brown\n if (Array.isArray(paramValue)) {\n for (const value of paramValue as unknown[]) {\n newQueryString.push({ name: param.name, value: String(value) })\n }\n }\n // Form explode object: R=100&G=200&B=150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n for (const [key, value] of Object.entries(paramValue as Record<string, unknown>)) {\n newQueryString.push({ name: key, value: String(value) })\n }\n }\n // Form explode primitive: color=blue\n else {\n newQueryString.push({ name: param.name, value: String(paramValue) })\n }\n } else {\n // Form no explode array: color=blue,black,brown\n if (Array.isArray(paramValue)) {\n newQueryString.push({ name: param.name, value: (paramValue as unknown[]).join(',') })\n }\n // Form no explode object: color=R,100,G,200,B,150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n newQueryString.push({ name: param.name, value: values })\n }\n // Form no explode primitive: color=blue\n else {\n newQueryString.push({ name: param.name, value: String(paramValue) })\n }\n }\n break\n }\n case 'spaceDelimited': {\n // SpaceDelimited array: color=blue black brown\n if (Array.isArray(paramValue)) {\n newQueryString.push({ name: param.name, value: (paramValue as unknown[]).join(' ') })\n }\n // SpaceDelimited object: color=R 100 G 200 B 150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k} ${v}`)\n .join(' ')\n newQueryString.push({ name: param.name, value: values })\n }\n break\n }\n case 'pipeDelimited': {\n // PipeDelimited array: color=blue|black|brown\n if (Array.isArray(paramValue)) {\n newQueryString.push({ name: param.name, value: (paramValue as unknown[]).join('|') })\n }\n // PipeDelimited object: color=R|100|G|200|B|150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .flat()\n .join('|')\n newQueryString.push({ name: param.name, value: values })\n }\n break\n }\n case 'deepObject': {\n // DeepObject: color[R]=100&color[G]=200&color[B]=150\n if (explode && typeof paramValue === 'object' && paramValue !== null) {\n for (const [key, value] of Object.entries(paramValue as Record<string, unknown>)) {\n newQueryString.push({ name: `${param.name}[${key}]`, value: String(value) })\n }\n }\n break\n }\n\n // Default to form style\n default:\n newQueryString.push({ name: param.name, value: String(paramValue) })\n }\n break\n }\n case 'header':\n // Headers only support 'simple' style according to OpenAPI 3.1.1\n if (explode) {\n // Simple explode array: multiple header values\n if (Array.isArray(paramValue)) {\n for (const value of paramValue as unknown[]) {\n newHeaders.push({ name: param.name, value: String(value) })\n }\n }\n // Simple explode object: key=value pairs\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n newHeaders.push({ name: param.name, value: values })\n }\n // Simple explode primitive: single value\n else {\n newHeaders.push({ name: param.name, value: String(paramValue) })\n }\n }\n // Simple no explode: all values joined with commas\n else {\n // Handle array values without explode\n if (Array.isArray(paramValue)) {\n newHeaders.push({ name: param.name, value: (paramValue as unknown[]).join(',') })\n }\n // Handle object values without explode\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n newHeaders.push({ name: param.name, value: values })\n }\n // Handle primitive values without explode\n else {\n newHeaders.push({ name: param.name, value: String(paramValue) })\n }\n }\n break\n case 'cookie':\n // Cookies only support 'form' style according to OpenAPI 3.1.1\n if (explode) {\n // Handle array values with explode\n if (Array.isArray(paramValue)) {\n for (const value of paramValue as unknown[]) {\n harRequest.cookies.push({ name: param.name, value: value === null ? 'null' : String(value) })\n }\n }\n // Handle object values with explode\n else if (typeof paramValue === 'object' && paramValue !== null) {\n for (const [key, value] of Object.entries(paramValue as Record<string, unknown>)) {\n harRequest.cookies.push({ name: key, value: value === null ? 'null' : String(value) })\n }\n }\n // Handle primitive values with explode\n else {\n harRequest.cookies.push({ name: param.name, value: paramValue === null ? 'null' : String(paramValue) })\n }\n } else {\n // Handle array values without explode\n if (Array.isArray(paramValue)) {\n const serializedValues = (paramValue as unknown[]).map((v) => (v === null ? 'null' : String(v))).join(',')\n harRequest.cookies.push({ name: param.name, value: serializedValues })\n }\n // Handle object values without explode\n else if (typeof paramValue === 'object' && paramValue !== null) {\n // Handle nested objects by recursively flattening them\n const flattenObject = (obj: Record<string, unknown>): string[] => {\n const result: string[] = []\n\n for (const [key, value] of Object.entries(obj)) {\n // Recursively flatten nested objects\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n result.push(key, ...flattenObject(value as Record<string, unknown>))\n }\n // Handle primitive values\n else {\n result.push(key, value === null ? 'null' : String(value))\n }\n }\n\n return result\n }\n\n const values = flattenObject(paramValue as Record<string, unknown>).join(',')\n harRequest.cookies.push({ name: param.name, value: values })\n }\n // Handle primitive values without explode\n else {\n harRequest.cookies.push({ name: param.name, value: paramValue === null ? 'null' : String(paramValue) })\n }\n }\n break\n }\n }\n\n return {\n url: newUrl,\n headers: newHeaders,\n queryString: newQueryString,\n cookies: harRequest.cookies,\n }\n}\n\n/**\n * Process path parameters according to OpenAPI specification.\n * Handles matrix, label, and simple styles with explode options.\n *\n * @param url - The URL to process\n * @param param - The parameter object\n * @param paramValue - The value of the parameter\n * @param style - The style of the parameter (matrix, label, simple)\n * @param explode - Whether to explode the parameter\n * @returns The updated URL with processed path parameters\n */\nconst processPathParameters = (\n url: string,\n param: ParameterObject,\n paramValue: unknown,\n style: string,\n explode: boolean,\n): string => {\n switch (style) {\n case 'matrix': {\n if (explode) {\n // Matrix explode array: ;color=blue;color=black;color=brown\n if (Array.isArray(paramValue)) {\n const values = (paramValue as unknown[]).map((v) => `${param.name}=${v}`).join(';')\n return url.replace(`{;${param.name}}`, `;${values}`)\n }\n\n // Matrix explode object: ;R=100;G=200;B=150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join(';')\n return url.replace(`{;${param.name}}`, `;${values}`)\n }\n\n // Matrix explode primitive: ;color=blue\n return url.replace(`{;${param.name}}`, `;${param.name}=${paramValue}`)\n }\n\n // Matrix no explode array: ;color=blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{;${param.name}}`, `;${param.name}=${(paramValue as unknown[]).join(',')}`)\n }\n\n // Matrix no explode object: ;color=R,100,G,200,B,150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n return url.replace(`{;${param.name}}`, `;${param.name}=${values}`)\n }\n\n // Matrix no explode primitive: ;color=blue\n return url.replace(`{;${param.name}}`, `;${param.name}=${paramValue}`)\n }\n case 'label': {\n if (explode) {\n // Label explode array: .blue.black.brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{.${param.name}}`, `.${(paramValue as unknown[]).join('.')}`)\n }\n\n // Label explode object: .R=100.G=200.B=150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join('.')\n\n return url.replace(`{.${param.name}}`, `.${values}`)\n }\n\n // Label explode primitive: .blue\n return url.replace(`{.${param.name}}`, `.${paramValue}`)\n }\n\n // Label no explode array: .blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{.${param.name}}`, `.${(paramValue as unknown[]).join(',')}`)\n }\n\n // Label no explode object: .R,100,G,200,B,150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n\n return url.replace(`{.${param.name}}`, `.${values}`)\n }\n\n // Label no explode primitive: .blue\n return url.replace(`{.${param.name}}`, `.${paramValue}`)\n }\n\n case 'simple': {\n if (explode) {\n // Simple explode array: blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{${param.name}}`, (paramValue as unknown[]).join(','))\n }\n\n // Simple explode object: R=100,G=200,B=150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n\n return url.replace(`{${param.name}}`, values)\n }\n\n // Simple explode primitive: blue\n return url.replace(`{${param.name}}`, String(paramValue))\n }\n // Simple no explode array: blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{${param.name}}`, (paramValue as unknown[]).join(','))\n }\n\n // Simple no explode object: R,100,G,200,B,150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n\n return url.replace(`{${param.name}}`, values)\n }\n\n // Simple no explode primitive: blue\n return url.replace(`{${param.name}}`, String(paramValue))\n }\n\n // Default to simple style\n default:\n return url.replace(`{${param.name}}`, String(paramValue))\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { getExampleFromSchema } from '@/spec-getters/get-example-from-schema'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { ExampleObject } from '@scalar/workspace-store/schemas/v3.1/strict/example'\nimport type { ParameterObject } from '@scalar/workspace-store/schemas/v3.1/strict/parameter'\nimport type { OperationObject } from '@scalar/workspace-store/schemas/v3.1/strict/path-operations'\nimport type { Request as HarRequest } from 'har-format'\n\ntype ProcessedParameters = {\n url: string\n headers: HarRequest['headers']\n queryString: HarRequest['queryString']\n cookies: HarRequest['cookies']\n}\n\n/** Ensures we don't have any references in the parameters */\nexport const deReferenceParams = (params: OperationObject['parameters']): ParameterObject[] =>\n (params ?? []).map((param) => getResolvedRef(param))\n\n/**\n * Get the style and explode values for a parameter according to OpenAPI 3.1.1 specification.\n * Handles defaults and validation for parameter location restrictions.\n */\nconst getParameterStyleAndExplode = (param: ParameterObject): { style: string; explode: boolean } => {\n // Headers only support 'simple' style\n if (param.in === 'header') {\n const explode = 'explode' in param && param.explode !== undefined ? param.explode : false\n return { style: 'simple', explode }\n }\n\n // Cookies only support 'form' style\n if (param.in === 'cookie') {\n const explode = 'explode' in param && param.explode !== undefined ? param.explode : true\n return { style: 'form', explode }\n }\n\n const defaultStyle = {\n path: 'simple',\n query: 'form',\n header: 'simple',\n cookie: 'form',\n }[param.in]\n\n // Use provided style or default based on location\n const style = 'style' in param && param.style ? param.style : defaultStyle\n\n // Determine explode value: use provided value or default based on style\n const explode = 'explode' in param && param.explode !== undefined ? param.explode : style === 'form'\n\n return { style, explode }\n}\n\n/**\n * Extract the value for a parameter from example data or schema.\n * Prioritizes example data over schema examples.\n */\nconst getParameterValue = (param: ParameterObject, example?: unknown): unknown => {\n // First try to get value from example data\n if (example && typeof example === 'object' && param.name) {\n const exampleValue = (example as Record<string, unknown>)[param.name]\n if (exampleValue !== undefined) {\n return exampleValue\n }\n }\n\n // Check if the parameter itself has an example\n if ('example' in param && param.example) {\n return param.example\n }\n\n // Or multiple examples\n if ('examples' in param && param.examples) {\n const examples = param.examples as Record<string, unknown>\n return examples[param.name] || (Object.values(examples)[0] as ExampleObject | undefined)?.value\n }\n\n // Fall back to schema example if available\n if ('schema' in param && param.schema) {\n const options = param.in === 'path' ? { emptyString: `{${param.name}}` } : {}\n return getExampleFromSchema(getResolvedRef(param.schema), options)\n }\n\n return undefined\n}\n\n/**\n * Process OpenAPI parameters and return the updated properties.\n * Handles path, query, and header parameters with various styles and explode options.\n *\n * @see https://spec.openapis.org/oas/latest.html#style-values\n */\nexport const processParameters = (\n harRequest: HarRequest,\n parameters: OperationObject['parameters'],\n example?: unknown,\n): ProcessedParameters => {\n // Create copies of the arrays to avoid modifying the input\n const newHeaders = [...harRequest.headers]\n const newQueryString = [...harRequest.queryString]\n let newUrl = harRequest.url\n\n // Filter out references\n const deReferencedParams = deReferenceParams(parameters)\n\n for (const param of deReferencedParams) {\n if (!param.in || !param.name) {\n continue\n }\n\n const paramValue = getParameterValue(param, example)\n\n if (paramValue === undefined) {\n continue\n }\n\n const { style, explode } = getParameterStyleAndExplode(param)\n\n switch (param.in) {\n case 'path': {\n newUrl = processPathParameters(newUrl, param, paramValue, style, explode)\n break\n }\n case 'query': {\n // Handle query parameters\n switch (style) {\n case 'form': {\n if (explode) {\n // Form explode array: color=blue&color=black&color=brown\n if (Array.isArray(paramValue)) {\n for (const value of paramValue as unknown[]) {\n newQueryString.push({ name: param.name, value: String(value) })\n }\n }\n // Form explode object: R=100&G=200&B=150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n for (const [key, value] of Object.entries(paramValue as Record<string, unknown>)) {\n newQueryString.push({ name: key, value: String(value) })\n }\n }\n // Form explode primitive: color=blue\n else {\n newQueryString.push({ name: param.name, value: String(paramValue) })\n }\n } else {\n // Form no explode array: color=blue,black,brown\n if (Array.isArray(paramValue)) {\n newQueryString.push({ name: param.name, value: (paramValue as unknown[]).join(',') })\n }\n // Form no explode object: color=R,100,G,200,B,150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n newQueryString.push({ name: param.name, value: values })\n }\n // Form no explode primitive: color=blue\n else {\n newQueryString.push({ name: param.name, value: String(paramValue) })\n }\n }\n break\n }\n case 'spaceDelimited': {\n // SpaceDelimited array: color=blue black brown\n if (Array.isArray(paramValue)) {\n newQueryString.push({ name: param.name, value: (paramValue as unknown[]).join(' ') })\n }\n // SpaceDelimited object: color=R 100 G 200 B 150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k} ${v}`)\n .join(' ')\n newQueryString.push({ name: param.name, value: values })\n }\n break\n }\n case 'pipeDelimited': {\n // PipeDelimited array: color=blue|black|brown\n if (Array.isArray(paramValue)) {\n newQueryString.push({ name: param.name, value: (paramValue as unknown[]).join('|') })\n }\n // PipeDelimited object: color=R|100|G|200|B|150\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .flat()\n .join('|')\n newQueryString.push({ name: param.name, value: values })\n }\n break\n }\n case 'deepObject': {\n // DeepObject: color[R]=100&color[G]=200&color[B]=150\n if (explode && typeof paramValue === 'object' && paramValue !== null) {\n for (const [key, value] of Object.entries(paramValue as Record<string, unknown>)) {\n newQueryString.push({ name: `${param.name}[${key}]`, value: String(value) })\n }\n }\n break\n }\n\n // Default to form style\n default:\n newQueryString.push({ name: param.name, value: String(paramValue) })\n }\n break\n }\n case 'header':\n // Headers only support 'simple' style according to OpenAPI 3.1.1\n if (explode) {\n // Simple explode array: multiple header values\n if (Array.isArray(paramValue)) {\n for (const value of paramValue as unknown[]) {\n newHeaders.push({ name: param.name, value: String(value) })\n }\n }\n // Simple explode object: key=value pairs\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n newHeaders.push({ name: param.name, value: values })\n }\n // Simple explode primitive: single value\n else {\n newHeaders.push({ name: param.name, value: String(paramValue) })\n }\n }\n // Simple no explode: all values joined with commas\n else {\n // Handle array values without explode\n if (Array.isArray(paramValue)) {\n newHeaders.push({ name: param.name, value: (paramValue as unknown[]).join(',') })\n }\n // Handle object values without explode\n else if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n newHeaders.push({ name: param.name, value: values })\n }\n // Handle primitive values without explode\n else {\n newHeaders.push({ name: param.name, value: String(paramValue) })\n }\n }\n break\n case 'cookie':\n // Cookies only support 'form' style according to OpenAPI 3.1.1\n if (explode) {\n // Handle array values with explode\n if (Array.isArray(paramValue)) {\n for (const value of paramValue as unknown[]) {\n harRequest.cookies.push({ name: param.name, value: value === null ? 'null' : String(value) })\n }\n }\n // Handle object values with explode\n else if (typeof paramValue === 'object' && paramValue !== null) {\n for (const [key, value] of Object.entries(paramValue as Record<string, unknown>)) {\n harRequest.cookies.push({ name: key, value: value === null ? 'null' : String(value) })\n }\n }\n // Handle primitive values with explode\n else {\n harRequest.cookies.push({ name: param.name, value: paramValue === null ? 'null' : String(paramValue) })\n }\n } else {\n // Handle array values without explode\n if (Array.isArray(paramValue)) {\n const serializedValues = (paramValue as unknown[]).map((v) => (v === null ? 'null' : String(v))).join(',')\n harRequest.cookies.push({ name: param.name, value: serializedValues })\n }\n // Handle object values without explode\n else if (typeof paramValue === 'object' && paramValue !== null) {\n // Handle nested objects by recursively flattening them\n const flattenObject = (obj: Record<string, unknown>): string[] => {\n const result: string[] = []\n\n for (const [key, value] of Object.entries(obj)) {\n // Recursively flatten nested objects\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n result.push(key, ...flattenObject(value as Record<string, unknown>))\n }\n // Handle primitive values\n else {\n result.push(key, value === null ? 'null' : String(value))\n }\n }\n\n return result\n }\n\n const values = flattenObject(paramValue as Record<string, unknown>).join(',')\n harRequest.cookies.push({ name: param.name, value: values })\n }\n // Handle primitive values without explode\n else {\n harRequest.cookies.push({ name: param.name, value: paramValue === null ? 'null' : String(paramValue) })\n }\n }\n break\n }\n }\n\n return {\n url: newUrl,\n headers: newHeaders,\n queryString: newQueryString,\n cookies: harRequest.cookies,\n }\n}\n\n/**\n * Process path parameters according to OpenAPI specification.\n * Handles matrix, label, and simple styles with explode options.\n *\n * @param url - The URL to process\n * @param param - The parameter object\n * @param paramValue - The value of the parameter\n * @param style - The style of the parameter (matrix, label, simple)\n * @param explode - Whether to explode the parameter\n * @returns The updated URL with processed path parameters\n */\nconst processPathParameters = (\n url: string,\n param: ParameterObject,\n paramValue: unknown,\n style: string,\n explode: boolean,\n): string => {\n switch (style) {\n case 'matrix': {\n if (explode) {\n // Matrix explode array: ;color=blue;color=black;color=brown\n if (Array.isArray(paramValue)) {\n const values = (paramValue as unknown[]).map((v) => `${param.name}=${v}`).join(';')\n return url.replace(`{;${param.name}}`, `;${values}`)\n }\n\n // Matrix explode object: ;R=100;G=200;B=150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join(';')\n return url.replace(`{;${param.name}}`, `;${values}`)\n }\n\n // Matrix explode primitive: ;color=blue\n return url.replace(`{;${param.name}}`, `;${param.name}=${paramValue}`)\n }\n\n // Matrix no explode array: ;color=blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{;${param.name}}`, `;${param.name}=${(paramValue as unknown[]).join(',')}`)\n }\n\n // Matrix no explode object: ;color=R,100,G,200,B,150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n return url.replace(`{;${param.name}}`, `;${param.name}=${values}`)\n }\n\n // Matrix no explode primitive: ;color=blue\n return url.replace(`{;${param.name}}`, `;${param.name}=${paramValue}`)\n }\n case 'label': {\n if (explode) {\n // Label explode array: .blue.black.brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{.${param.name}}`, `.${(paramValue as unknown[]).join('.')}`)\n }\n\n // Label explode object: .R=100.G=200.B=150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join('.')\n\n return url.replace(`{.${param.name}}`, `.${values}`)\n }\n\n // Label explode primitive: .blue\n return url.replace(`{.${param.name}}`, `.${paramValue}`)\n }\n\n // Label no explode array: .blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{.${param.name}}`, `.${(paramValue as unknown[]).join(',')}`)\n }\n\n // Label no explode object: .R,100,G,200,B,150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n\n return url.replace(`{.${param.name}}`, `.${values}`)\n }\n\n // Label no explode primitive: .blue\n return url.replace(`{.${param.name}}`, `.${paramValue}`)\n }\n\n case 'simple': {\n if (explode) {\n // Simple explode array: blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{${param.name}}`, (paramValue as unknown[]).join(','))\n }\n\n // Simple explode object: R=100,G=200,B=150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k}=${v}`)\n .join(',')\n\n return url.replace(`{${param.name}}`, values)\n }\n\n // Simple explode primitive: blue\n return url.replace(`{${param.name}}`, String(paramValue))\n }\n // Simple no explode array: blue,black,brown\n if (Array.isArray(paramValue)) {\n return url.replace(`{${param.name}}`, (paramValue as unknown[]).join(','))\n }\n\n // Simple no explode object: R,100,G,200,B,150\n if (typeof paramValue === 'object' && paramValue !== null) {\n const values = Object.entries(paramValue as Record<string, unknown>)\n .map(([k, v]) => `${k},${v}`)\n .join(',')\n\n return url.replace(`{${param.name}}`, values)\n }\n\n // Simple no explode primitive: blue\n return url.replace(`{${param.name}}`, String(paramValue))\n }\n\n // Default to simple style\n default:\n return url.replace(`{${param.name}}`, String(paramValue))\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["explode"]
|
|
7
7
|
}
|
|
@@ -29,7 +29,7 @@ const processSecuritySchemes = (securitySchemes) => {
|
|
|
29
29
|
const username = scheme["x-scalar-secret-username"] || "";
|
|
30
30
|
const password = scheme["x-scalar-secret-password"] || "";
|
|
31
31
|
const value = `${username}:${password}`;
|
|
32
|
-
const auth = value === ":" ? "username:password" :
|
|
32
|
+
const auth = value === ":" ? "username:password" : btoa(value);
|
|
33
33
|
result.headers.push({
|
|
34
34
|
name: "Authorization",
|
|
35
35
|
value: `Basic ${auth}`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/helpers/operation-to-har/process-security-schemes.ts"],
|
|
4
|
-
"sourcesContent": ["import type { SecuritySchemeObject } from '@scalar/workspace-store/schemas/v3.1/strict/security-scheme'\nimport type { Request as HarRequest } from 'har-format'\n\ntype ProcessedSecuritySchemesReturn = {\n headers: HarRequest['headers']\n queryString: HarRequest['queryString']\n cookies: HarRequest['cookies']\n}\n\n/**\n * Process security schemes into whichever parameters they are applicable to\n *\n * TODO: we probably want to be able to disable YOUR_SECRET_TOKEN placeholder text + or allow it to be customzied\n */\nexport const processSecuritySchemes = (securitySchemes: SecuritySchemeObject[]): ProcessedSecuritySchemesReturn => {\n const result: ProcessedSecuritySchemesReturn = {\n headers: [],\n queryString: [],\n cookies: [],\n }\n\n for (const scheme of securitySchemes) {\n // Handle apiKey type\n if (scheme.type === 'apiKey') {\n const value =
|
|
5
|
-
"mappings": "AAcO,MAAM,yBAAyB,CAAC,oBAA4E;AACjH,QAAM,SAAyC;AAAA,IAC7C,SAAS,CAAC;AAAA,IACV,aAAa,CAAC;AAAA,IACd,SAAS,CAAC;AAAA,EACZ;AAEA,aAAW,UAAU,iBAAiB;AAEpC,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,
|
|
4
|
+
"sourcesContent": ["import type { SecuritySchemeObject } from '@scalar/workspace-store/schemas/v3.1/strict/security-scheme'\nimport type { Request as HarRequest } from 'har-format'\n\ntype ProcessedSecuritySchemesReturn = {\n headers: HarRequest['headers']\n queryString: HarRequest['queryString']\n cookies: HarRequest['cookies']\n}\n\n/**\n * Process security schemes into whichever parameters they are applicable to\n *\n * TODO: we probably want to be able to disable YOUR_SECRET_TOKEN placeholder text + or allow it to be customzied\n */\nexport const processSecuritySchemes = (securitySchemes: SecuritySchemeObject[]): ProcessedSecuritySchemesReturn => {\n const result: ProcessedSecuritySchemesReturn = {\n headers: [],\n queryString: [],\n cookies: [],\n }\n\n for (const scheme of securitySchemes) {\n // Handle apiKey type\n if (scheme.type === 'apiKey') {\n const value = scheme['x-scalar-secret-token'] || 'YOUR_SECRET_TOKEN'\n if (!scheme.name) {\n continue\n }\n\n const param = { name: scheme.name, value }\n\n switch (scheme.in) {\n case 'header':\n result.headers.push(param)\n break\n case 'query':\n result.queryString.push(param)\n break\n case 'cookie':\n result.cookies.push(param)\n break\n }\n continue\n }\n\n // Handle http type\n if (scheme.type === 'http') {\n if (scheme.scheme === 'basic') {\n const username = scheme['x-scalar-secret-username'] || ''\n const password = scheme['x-scalar-secret-password'] || ''\n\n const value = `${username}:${password}`\n const auth = value === ':' ? 'username:password' : btoa(value)\n\n result.headers.push({\n name: 'Authorization',\n value: `Basic ${auth}`,\n })\n } else if (scheme.scheme === 'bearer') {\n const token = scheme['x-scalar-secret-token'] || 'YOUR_SECRET_TOKEN'\n\n result.headers.push({\n name: 'Authorization',\n value: `Bearer ${token}`,\n })\n }\n continue\n }\n\n // Handle oauth2 type\n if (scheme.type === 'oauth2' && scheme.flows) {\n const flows = Object.values(scheme.flows)\n\n // Find the first flow with a token\n const flow = flows.find((f) => f['x-scalar-secret-token'])\n const token = flow?.['x-scalar-secret-token'] || 'YOUR_SECRET_TOKEN'\n\n result.headers.push({\n name: 'Authorization',\n value: `Bearer ${token}`,\n })\n }\n }\n\n return result\n}\n"],
|
|
5
|
+
"mappings": "AAcO,MAAM,yBAAyB,CAAC,oBAA4E;AACjH,QAAM,SAAyC;AAAA,IAC7C,SAAS,CAAC;AAAA,IACV,aAAa,CAAC;AAAA,IACd,SAAS,CAAC;AAAA,EACZ;AAEA,aAAW,UAAU,iBAAiB;AAEpC,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,QAAQ,OAAO,uBAAuB,KAAK;AACjD,UAAI,CAAC,OAAO,MAAM;AAChB;AAAA,MACF;AAEA,YAAM,QAAQ,EAAE,MAAM,OAAO,MAAM,MAAM;AAEzC,cAAQ,OAAO,IAAI;AAAA,QACjB,KAAK;AACH,iBAAO,QAAQ,KAAK,KAAK;AACzB;AAAA,QACF,KAAK;AACH,iBAAO,YAAY,KAAK,KAAK;AAC7B;AAAA,QACF,KAAK;AACH,iBAAO,QAAQ,KAAK,KAAK;AACzB;AAAA,MACJ;AACA;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,QAAQ;AAC1B,UAAI,OAAO,WAAW,SAAS;AAC7B,cAAM,WAAW,OAAO,0BAA0B,KAAK;AACvD,cAAM,WAAW,OAAO,0BAA0B,KAAK;AAEvD,cAAM,QAAQ,GAAG,QAAQ,IAAI,QAAQ;AACrC,cAAM,OAAO,UAAU,MAAM,sBAAsB,KAAK,KAAK;AAE7D,eAAO,QAAQ,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,OAAO,SAAS,IAAI;AAAA,QACtB,CAAC;AAAA,MACH,WAAW,OAAO,WAAW,UAAU;AACrC,cAAM,QAAQ,OAAO,uBAAuB,KAAK;AAEjD,eAAO,QAAQ,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,OAAO,UAAU,KAAK;AAAA,QACxB,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,YAAY,OAAO,OAAO;AAC5C,YAAM,QAAQ,OAAO,OAAO,OAAO,KAAK;AAGxC,YAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,uBAAuB,CAAC;AACzD,YAAM,QAAQ,OAAO,uBAAuB,KAAK;AAEjD,aAAO,QAAQ,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,OAAO,UAAU,KAAK;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Server } from '../entities/spec/server.js';
|
|
2
|
+
import type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/server';
|
|
3
|
+
/**
|
|
4
|
+
* Server processing options containing base URLs for resolving relative server URLs.
|
|
5
|
+
*/
|
|
6
|
+
type ServerProcessingOptions = {
|
|
7
|
+
baseServerURL?: string;
|
|
8
|
+
documentUrl?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Retrieves and processes servers from an OpenAPI document.
|
|
12
|
+
*
|
|
13
|
+
* This function handles several scenarios:
|
|
14
|
+
* 1. No servers provided - creates a default server from document URL or fallback
|
|
15
|
+
* 2. Invalid server configurations - filters them out with warnings
|
|
16
|
+
* 3. Relative URLs - resolves them to absolute URLs using available base URLs
|
|
17
|
+
*
|
|
18
|
+
* @param servers - Array of OpenAPI server objects from the document
|
|
19
|
+
* @param options - Configuration options for server processing
|
|
20
|
+
* @returns Array of validated Server entities
|
|
21
|
+
*/
|
|
22
|
+
export declare function getServersFromDocument(servers: ServerObject[] | undefined, options?: ServerProcessingOptions): Server[];
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=servers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../src/helpers/servers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,wBAAwB,CAAA;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oDAAoD,CAAA;AAEtF;;GAEG;AACH,KAAK,uBAAuB,GAAG;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,EAAE,GAAG,SAAS,EACnC,OAAO,GAAE,uBAA4B,GACpC,MAAM,EAAE,CAsBV"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { serverSchema } from "../entities/spec/server.js";
|
|
2
|
+
import { isDefined } from "@scalar/helpers/array/is-defined";
|
|
3
|
+
import { combineUrlAndPath } from "@scalar/helpers/url/merge-urls";
|
|
4
|
+
function getServersFromDocument(servers, options = {}) {
|
|
5
|
+
if (!servers?.length) {
|
|
6
|
+
const fallbackServer = createFallbackServer(options);
|
|
7
|
+
return fallbackServer ? [fallbackServer] : [];
|
|
8
|
+
}
|
|
9
|
+
if (!Array.isArray(servers)) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const validServers = servers.map((server) => processServerObject(server, options)).filter(isDefined);
|
|
13
|
+
if (validServers.length === 0) {
|
|
14
|
+
const fallbackServer = createFallbackServer(options);
|
|
15
|
+
return fallbackServer ? [fallbackServer] : [];
|
|
16
|
+
}
|
|
17
|
+
return validServers;
|
|
18
|
+
}
|
|
19
|
+
function extractBaseUrlFromDocumentUrl(documentUrl) {
|
|
20
|
+
try {
|
|
21
|
+
const url = new URL(documentUrl);
|
|
22
|
+
const port = url.port ? `:${url.port}` : "";
|
|
23
|
+
return `${url.protocol}//${url.hostname}${port}`;
|
|
24
|
+
} catch {
|
|
25
|
+
return void 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getFallbackUrl() {
|
|
29
|
+
if (typeof window === "undefined" || typeof window?.location?.origin !== "string") {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
return window.location.origin;
|
|
33
|
+
}
|
|
34
|
+
function createServerFromUrl(url, context) {
|
|
35
|
+
try {
|
|
36
|
+
return serverSchema.parse({ url });
|
|
37
|
+
} catch {
|
|
38
|
+
console.warn(`Failed to create server from ${context}:`, url);
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function createDefaultServerFromDocumentUrl(documentUrl) {
|
|
43
|
+
const baseUrl = extractBaseUrlFromDocumentUrl(documentUrl);
|
|
44
|
+
if (!baseUrl) {
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
return createServerFromUrl(baseUrl, "document URL");
|
|
48
|
+
}
|
|
49
|
+
function createDefaultServerFromFallback() {
|
|
50
|
+
const fallbackUrl = getFallbackUrl();
|
|
51
|
+
if (!fallbackUrl) {
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
return createServerFromUrl(fallbackUrl, "fallback URL");
|
|
55
|
+
}
|
|
56
|
+
function resolveRelativeServerUrl(serverUrl, options) {
|
|
57
|
+
const { baseServerURL, documentUrl } = options;
|
|
58
|
+
if (baseServerURL) {
|
|
59
|
+
return combineUrlAndPath(baseServerURL, serverUrl);
|
|
60
|
+
}
|
|
61
|
+
if (documentUrl) {
|
|
62
|
+
const baseUrl = extractBaseUrlFromDocumentUrl(documentUrl);
|
|
63
|
+
if (baseUrl) {
|
|
64
|
+
return combineUrlAndPath(baseUrl, serverUrl);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const fallbackUrl = getFallbackUrl();
|
|
68
|
+
if (fallbackUrl) {
|
|
69
|
+
return combineUrlAndPath(fallbackUrl, serverUrl);
|
|
70
|
+
}
|
|
71
|
+
return serverUrl;
|
|
72
|
+
}
|
|
73
|
+
function processServerObject(server, options) {
|
|
74
|
+
try {
|
|
75
|
+
const parsedServer = serverSchema.parse(server);
|
|
76
|
+
if (parsedServer.url?.startsWith("/")) {
|
|
77
|
+
parsedServer.url = resolveRelativeServerUrl(parsedServer.url, options);
|
|
78
|
+
}
|
|
79
|
+
return parsedServer;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.warn("Invalid server configuration:", server, "Error:", error);
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function createFallbackServer(options) {
|
|
86
|
+
if (options.documentUrl) {
|
|
87
|
+
const defaultServer = createDefaultServerFromDocumentUrl(options.documentUrl);
|
|
88
|
+
if (defaultServer) {
|
|
89
|
+
return defaultServer;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return createDefaultServerFromFallback();
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
getServersFromDocument
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/helpers/servers.ts"],
|
|
4
|
+
"sourcesContent": ["import { type Server, serverSchema } from '@/entities/spec/server'\nimport { isDefined } from '@scalar/helpers/array/is-defined'\nimport { combineUrlAndPath } from '@scalar/helpers/url/merge-urls'\nimport type { ServerObject } from '@scalar/workspace-store/schemas/v3.1/strict/server'\n\n/**\n * Server processing options containing base URLs for resolving relative server URLs.\n */\ntype ServerProcessingOptions = {\n baseServerURL?: string\n documentUrl?: string\n}\n\n/**\n * Retrieves and processes servers from an OpenAPI document.\n *\n * This function handles several scenarios:\n * 1. No servers provided - creates a default server from document URL or fallback\n * 2. Invalid server configurations - filters them out with warnings\n * 3. Relative URLs - resolves them to absolute URLs using available base URLs\n *\n * @param servers - Array of OpenAPI server objects from the document\n * @param options - Configuration options for server processing\n * @returns Array of validated Server entities\n */\nexport function getServersFromDocument(\n servers: ServerObject[] | undefined,\n options: ServerProcessingOptions = {},\n): Server[] {\n // Handle case where no servers are provided\n if (!servers?.length) {\n const fallbackServer = createFallbackServer(options)\n return fallbackServer ? [fallbackServer] : []\n }\n\n // Handle invalid server array\n if (!Array.isArray(servers)) {\n return []\n }\n\n // Process each server and filter out invalid ones\n const validServers = servers.map((server) => processServerObject(server, options)).filter(isDefined)\n\n // If all servers were invalid, provide a fallback\n if (validServers.length === 0) {\n const fallbackServer = createFallbackServer(options)\n return fallbackServer ? [fallbackServer] : []\n }\n\n return validServers\n}\n\n/**\n * Extracts the base URL (protocol + hostname) from a document URL.\n * Returns undefined if the URL is invalid.\n */\nfunction extractBaseUrlFromDocumentUrl(documentUrl: string): string | undefined {\n try {\n const url = new URL(documentUrl)\n const port = url.port ? `:${url.port}` : ''\n return `${url.protocol}//${url.hostname}${port}`\n } catch {\n return undefined\n }\n}\n\n/**\n * Gets the fallback URL from window.location.origin if available.\n */\nfunction getFallbackUrl(): string | undefined {\n if (typeof window === 'undefined' || typeof window?.location?.origin !== 'string') {\n return undefined\n }\n return window.location.origin\n}\n\n/**\n * Creates a server object from a URL string, with error handling.\n */\nfunction createServerFromUrl(url: string, context: string): Server | undefined {\n try {\n return serverSchema.parse({ url })\n } catch {\n console.warn(`Failed to create server from ${context}:`, url)\n return undefined\n }\n}\n\n/**\n * Creates a default server using the document URL as the base.\n */\nfunction createDefaultServerFromDocumentUrl(documentUrl: string): Server | undefined {\n const baseUrl = extractBaseUrlFromDocumentUrl(documentUrl)\n if (!baseUrl) {\n return undefined\n }\n\n return createServerFromUrl(baseUrl, 'document URL')\n}\n\n/**\n * Creates a default server using the fallback URL (window.location.origin).\n */\nfunction createDefaultServerFromFallback(): Server | undefined {\n const fallbackUrl = getFallbackUrl()\n if (!fallbackUrl) {\n return undefined\n }\n\n return createServerFromUrl(fallbackUrl, 'fallback URL')\n}\n\n/**\n * Resolves a relative server URL to an absolute URL using available base URLs.\n * Uses a priority system: baseServerURL > documentUrl > fallbackUrl.\n */\nfunction resolveRelativeServerUrl(serverUrl: string, options: ServerProcessingOptions): string {\n const { baseServerURL, documentUrl } = options\n\n // Priority 1: Use provided base server URL\n if (baseServerURL) {\n return combineUrlAndPath(baseServerURL, serverUrl)\n }\n\n // Priority 2: Extract base URL from document URL\n if (documentUrl) {\n const baseUrl = extractBaseUrlFromDocumentUrl(documentUrl)\n if (baseUrl) {\n return combineUrlAndPath(baseUrl, serverUrl)\n }\n }\n\n // Priority 3: Use fallback URL (window.location.origin)\n const fallbackUrl = getFallbackUrl()\n if (fallbackUrl) {\n return combineUrlAndPath(fallbackUrl, serverUrl)\n }\n\n // If no base URL is available, return the original URL\n return serverUrl\n}\n\n/**\n * Processes a single server object, handling validation and URL resolution.\n */\nfunction processServerObject(server: ServerObject, options: ServerProcessingOptions): Server | undefined {\n try {\n const parsedServer = serverSchema.parse(server)\n\n // Resolve relative URLs to absolute URLs\n if (parsedServer.url?.startsWith('/')) {\n parsedServer.url = resolveRelativeServerUrl(parsedServer.url, options)\n }\n\n return parsedServer\n } catch (error) {\n console.warn('Invalid server configuration:', server, 'Error:', error)\n return undefined\n }\n}\n\n/**\n * Creates a fallback server when no valid servers are available.\n * Uses document URL first, then fallback URL.\n */\nfunction createFallbackServer(options: ServerProcessingOptions): Server | undefined {\n // Priority 1: Try to create default server from document URL\n if (options.documentUrl) {\n const defaultServer = createDefaultServerFromDocumentUrl(options.documentUrl)\n\n if (defaultServer) {\n return defaultServer\n }\n }\n\n // Priority 2: Try to create default server from fallback URL\n return createDefaultServerFromFallback()\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAsB,oBAAoB;AAC1C,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAuB3B,SAAS,uBACd,SACA,UAAmC,CAAC,GAC1B;AAEV,MAAI,CAAC,SAAS,QAAQ;AACpB,UAAM,iBAAiB,qBAAqB,OAAO;AACnD,WAAO,iBAAiB,CAAC,cAAc,IAAI,CAAC;AAAA,EAC9C;AAGA,MAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,WAAO,CAAC;AAAA,EACV;AAGA,QAAM,eAAe,QAAQ,IAAI,CAAC,WAAW,oBAAoB,QAAQ,OAAO,CAAC,EAAE,OAAO,SAAS;AAGnG,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,iBAAiB,qBAAqB,OAAO;AACnD,WAAO,iBAAiB,CAAC,cAAc,IAAI,CAAC;AAAA,EAC9C;AAEA,SAAO;AACT;AAMA,SAAS,8BAA8B,aAAyC;AAC9E,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,WAAW;AAC/B,UAAM,OAAO,IAAI,OAAO,IAAI,IAAI,IAAI,KAAK;AACzC,WAAO,GAAG,IAAI,QAAQ,KAAK,IAAI,QAAQ,GAAG,IAAI;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,iBAAqC;AAC5C,MAAI,OAAO,WAAW,eAAe,OAAO,QAAQ,UAAU,WAAW,UAAU;AACjF,WAAO;AAAA,EACT;AACA,SAAO,OAAO,SAAS;AACzB;AAKA,SAAS,oBAAoB,KAAa,SAAqC;AAC7E,MAAI;AACF,WAAO,aAAa,MAAM,EAAE,IAAI,CAAC;AAAA,EACnC,QAAQ;AACN,YAAQ,KAAK,gCAAgC,OAAO,KAAK,GAAG;AAC5D,WAAO;AAAA,EACT;AACF;AAKA,SAAS,mCAAmC,aAAyC;AACnF,QAAM,UAAU,8BAA8B,WAAW;AACzD,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,SAAS,cAAc;AACpD;AAKA,SAAS,kCAAsD;AAC7D,QAAM,cAAc,eAAe;AACnC,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,aAAa,cAAc;AACxD;AAMA,SAAS,yBAAyB,WAAmB,SAA0C;AAC7F,QAAM,EAAE,eAAe,YAAY,IAAI;AAGvC,MAAI,eAAe;AACjB,WAAO,kBAAkB,eAAe,SAAS;AAAA,EACnD;AAGA,MAAI,aAAa;AACf,UAAM,UAAU,8BAA8B,WAAW;AACzD,QAAI,SAAS;AACX,aAAO,kBAAkB,SAAS,SAAS;AAAA,IAC7C;AAAA,EACF;AAGA,QAAM,cAAc,eAAe;AACnC,MAAI,aAAa;AACf,WAAO,kBAAkB,aAAa,SAAS;AAAA,EACjD;AAGA,SAAO;AACT;AAKA,SAAS,oBAAoB,QAAsB,SAAsD;AACvG,MAAI;AACF,UAAM,eAAe,aAAa,MAAM,MAAM;AAG9C,QAAI,aAAa,KAAK,WAAW,GAAG,GAAG;AACrC,mBAAa,MAAM,yBAAyB,aAAa,KAAK,OAAO;AAAA,IACvE;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,KAAK,iCAAiC,QAAQ,UAAU,KAAK;AACrE,WAAO;AAAA,EACT;AACF;AAMA,SAAS,qBAAqB,SAAsD;AAElF,MAAI,QAAQ,aAAa;AACvB,UAAM,gBAAgB,mCAAmC,QAAQ,WAAW;AAE5E,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AAAA,EACF;AAGA,SAAO,gCAAgC;AACzC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/schema';
|
|
1
2
|
/**
|
|
2
3
|
* This function takes an OpenAPI schema and generates an example from it
|
|
3
4
|
*/
|
|
4
|
-
export declare const getExampleFromSchema: (
|
|
5
|
+
export declare const getExampleFromSchema: (_schema: SchemaObject, options?: {
|
|
5
6
|
/**
|
|
6
7
|
* The fallback string for empty string values.
|
|
7
8
|
* @default ''
|
|
@@ -26,5 +27,5 @@ export declare const getExampleFromSchema: (schema: Record<string, any>, options
|
|
|
26
27
|
* @default false
|
|
27
28
|
*/
|
|
28
29
|
omitEmptyAndOptionalProperties?: boolean;
|
|
29
|
-
}, level?: number, parentSchema?:
|
|
30
|
+
}, level?: number, parentSchema?: SchemaObject, name?: string) => any;
|
|
30
31
|
//# sourceMappingURL=get-example-from-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-example-from-schema.d.ts","sourceRoot":"","sources":["../../src/spec-getters/get-example-from-schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-example-from-schema.d.ts","sourceRoot":"","sources":["../../src/spec-getters/get-example-from-schema.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oDAAoD,CAAA;AAkEtF;;GAEG;AACH,eAAO,MAAM,oBAAoB,YACtB,YAAY,YACX;IACR;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC/B;;;OAGG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAA;CACzC,UACM,MAAM,iBACE,YAAY,SACpB,MAAM,KACZ,GAoTF,CAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isDefined } from "@scalar/helpers/array/is-defined";
|
|
2
|
+
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
|
|
1
3
|
const MAX_LEVELS_DEEP = 5;
|
|
2
4
|
const MAX_PROPERTIES = 10;
|
|
3
5
|
const DEFAULT_ADDITIONAL_PROPERTIES_NAME = "propertyName*";
|
|
@@ -36,7 +38,7 @@ function guessFromFormat(schema, makeUpRandomData = false, fallback = "") {
|
|
|
36
38
|
if (schema.format === "binary") {
|
|
37
39
|
return new File([""], "filename");
|
|
38
40
|
}
|
|
39
|
-
return makeUpRandomData ? genericExampleValues[schema.format] ?? fallback : "";
|
|
41
|
+
return makeUpRandomData ? genericExampleValues[schema.format ?? ""] ?? fallback : "";
|
|
40
42
|
}
|
|
41
43
|
const resultCache = /* @__PURE__ */ new WeakMap();
|
|
42
44
|
function cache(schema, result) {
|
|
@@ -46,7 +48,8 @@ function cache(schema, result) {
|
|
|
46
48
|
resultCache.set(schema, result);
|
|
47
49
|
return result;
|
|
48
50
|
}
|
|
49
|
-
const getExampleFromSchema = (
|
|
51
|
+
const getExampleFromSchema = (_schema, options, level = 0, parentSchema, name) => {
|
|
52
|
+
const schema = getResolvedRef(_schema);
|
|
50
53
|
if (resultCache.has(schema)) {
|
|
51
54
|
return resultCache.get(schema);
|
|
52
55
|
}
|
|
@@ -87,7 +90,11 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
87
90
|
}
|
|
88
91
|
const isObjectOrArray = schema.type === "object" || schema.type === "array" || !!schema.allOf?.at?.(0) || !!schema.anyOf?.at?.(0) || !!schema.oneOf?.at?.(0);
|
|
89
92
|
if (!isObjectOrArray && options?.omitEmptyAndOptionalProperties === true) {
|
|
90
|
-
const isRequired =
|
|
93
|
+
const isRequired = (
|
|
94
|
+
// @ts-expect-error - I suppose old schema used to allow `required: true` remove when moving to new store
|
|
95
|
+
schema.required === true || // @ts-expect-error - I suppose old schema used to allow `required: true` remove when moving to new store
|
|
96
|
+
parentSchema?.required === true || parentSchema?.required?.includes(name ?? schema.title ?? "")
|
|
97
|
+
);
|
|
91
98
|
if (!isRequired) {
|
|
92
99
|
return void 0;
|
|
93
100
|
}
|
|
@@ -102,8 +109,11 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
102
109
|
response["..."] = "[Additional Properties Truncated]";
|
|
103
110
|
break;
|
|
104
111
|
}
|
|
105
|
-
const property = schema.properties[propertyName];
|
|
106
|
-
const propertyXmlTagName = options?.xml ? property
|
|
112
|
+
const property = getResolvedRef(schema.properties[propertyName]);
|
|
113
|
+
const propertyXmlTagName = options?.xml ? property?.xml?.name : void 0;
|
|
114
|
+
if (!property) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
107
117
|
const value = getExampleFromSchema(property, options, level + 1, schema, propertyName);
|
|
108
118
|
if (typeof value !== "undefined") {
|
|
109
119
|
response[propertyXmlTagName ?? propertyName] = value;
|
|
@@ -115,7 +125,10 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
115
125
|
if (schema.patternProperties !== void 0) {
|
|
116
126
|
for (const pattern in schema.patternProperties) {
|
|
117
127
|
if (Object.prototype.hasOwnProperty.call(schema.patternProperties, pattern)) {
|
|
118
|
-
const property = schema.patternProperties[pattern];
|
|
128
|
+
const property = getResolvedRef(schema.patternProperties[pattern]);
|
|
129
|
+
if (!property) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
119
132
|
const exampleKey = pattern;
|
|
120
133
|
response[exampleKey] = getExampleFromSchema(property, options, level + 1, schema, exampleKey);
|
|
121
134
|
}
|
|
@@ -127,59 +140,59 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
127
140
|
schema.additionalProperties === true || // or an empty object {}
|
|
128
141
|
typeof schema.additionalProperties === "object" && !Object.keys(schema.additionalProperties).length
|
|
129
142
|
);
|
|
130
|
-
const
|
|
143
|
+
const additionalProperties = getResolvedRef(schema.additionalProperties);
|
|
144
|
+
const additionalPropertiesName = typeof additionalProperties === "object" && additionalProperties["x-additionalPropertiesName"] && typeof additionalProperties["x-additionalPropertiesName"] === "string" && additionalProperties["x-additionalPropertiesName"].trim().length > 0 ? `${additionalProperties["x-additionalPropertiesName"].trim()}*` : DEFAULT_ADDITIONAL_PROPERTIES_NAME;
|
|
131
145
|
if (anyTypeIsValid) {
|
|
132
146
|
response[additionalPropertiesName] = "anything";
|
|
133
|
-
} else if (
|
|
134
|
-
response[additionalPropertiesName] = getExampleFromSchema(
|
|
147
|
+
} else if (typeof additionalProperties === "object") {
|
|
148
|
+
response[additionalPropertiesName] = getExampleFromSchema(additionalProperties, options, level + 1);
|
|
135
149
|
}
|
|
136
150
|
}
|
|
137
|
-
if (schema.anyOf
|
|
138
|
-
Object.assign(response, getExampleFromSchema(schema.anyOf[0], options, level + 1));
|
|
139
|
-
} else if (schema.oneOf !== void 0) {
|
|
140
|
-
Object.assign(response, getExampleFromSchema(schema.oneOf[0], options, level + 1));
|
|
141
|
-
} else if (schema.allOf
|
|
151
|
+
if (schema.anyOf?.[0]) {
|
|
152
|
+
Object.assign(response, getExampleFromSchema(getResolvedRef(schema.anyOf[0]), options, level + 1));
|
|
153
|
+
} else if (schema.oneOf?.[0] !== void 0) {
|
|
154
|
+
Object.assign(response, getExampleFromSchema(getResolvedRef(schema.oneOf[0]), options, level + 1));
|
|
155
|
+
} else if (schema.allOf?.[0]) {
|
|
142
156
|
Object.assign(
|
|
143
157
|
response,
|
|
144
|
-
...schema.allOf.map((item) => getExampleFromSchema(item, options, level + 1, schema))
|
|
158
|
+
...schema.allOf.filter(isDefined).map((item) => getExampleFromSchema(getResolvedRef(item), options, level + 1, schema))
|
|
145
159
|
);
|
|
146
160
|
}
|
|
147
161
|
return cache(schema, response);
|
|
148
162
|
}
|
|
149
163
|
if (schema.type === "array" || schema.items !== void 0) {
|
|
150
|
-
const
|
|
164
|
+
const items = getResolvedRef(schema.items);
|
|
165
|
+
const itemsXmlTagName = items?.xml?.name;
|
|
151
166
|
const wrapItems = !!(options?.xml && schema.xml?.wrapped && itemsXmlTagName);
|
|
152
167
|
if (schema.example !== void 0) {
|
|
153
168
|
return cache(schema, wrapItems ? { [itemsXmlTagName]: schema.example } : schema.example);
|
|
154
169
|
}
|
|
155
|
-
if (
|
|
156
|
-
if (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
schema
|
|
163
|
-
);
|
|
170
|
+
if (items) {
|
|
171
|
+
if (items.allOf) {
|
|
172
|
+
const allOf = items.allOf.filter(isDefined);
|
|
173
|
+
const firstItem = getResolvedRef(allOf[0]);
|
|
174
|
+
if (firstItem?.type === "object") {
|
|
175
|
+
const combined = { type: "object", allOf };
|
|
176
|
+
const mergedExample = getExampleFromSchema(combined, options, level + 1, schema);
|
|
164
177
|
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: mergedExample }] : [mergedExample]);
|
|
165
178
|
}
|
|
166
|
-
const examples =
|
|
179
|
+
const examples = allOf.map((item) => getExampleFromSchema(getResolvedRef(item), options, level + 1, schema)).filter(isDefined);
|
|
167
180
|
return cache(schema, wrapItems ? examples.map((example) => ({ [itemsXmlTagName]: example })) : examples);
|
|
168
181
|
}
|
|
169
182
|
const rules = ["anyOf", "oneOf"];
|
|
170
183
|
for (const rule of rules) {
|
|
171
|
-
if (!
|
|
184
|
+
if (!items[rule]) {
|
|
172
185
|
continue;
|
|
173
186
|
}
|
|
174
|
-
const schemas =
|
|
175
|
-
const exampleFromRule = schemas.map((item) => getExampleFromSchema(item, options, level + 1, schema)).filter(
|
|
187
|
+
const schemas = items[rule].slice(0, 1);
|
|
188
|
+
const exampleFromRule = schemas.map((item) => getExampleFromSchema(getResolvedRef(item), options, level + 1, schema)).filter(isDefined);
|
|
176
189
|
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: exampleFromRule }] : exampleFromRule);
|
|
177
190
|
}
|
|
178
191
|
}
|
|
179
|
-
const isObject =
|
|
180
|
-
const isArray =
|
|
181
|
-
if (
|
|
182
|
-
const exampleFromSchema = getExampleFromSchema(
|
|
192
|
+
const isObject = items?.type === "object" || items?.properties !== void 0;
|
|
193
|
+
const isArray = items?.type === "array" || items?.items !== void 0;
|
|
194
|
+
if (items?.type || isObject || isArray) {
|
|
195
|
+
const exampleFromSchema = getExampleFromSchema(items, options, level + 1);
|
|
183
196
|
return wrapItems ? [{ [itemsXmlTagName]: exampleFromSchema }] : [exampleFromSchema];
|
|
184
197
|
}
|
|
185
198
|
return [];
|
|
@@ -187,16 +200,16 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
187
200
|
const exampleValues = {
|
|
188
201
|
string: guessFromFormat(schema, makeUpRandomData, options?.emptyString),
|
|
189
202
|
boolean: true,
|
|
190
|
-
integer: schema.
|
|
191
|
-
number: schema.
|
|
203
|
+
integer: schema.minimum ?? 1,
|
|
204
|
+
number: schema.minimum ?? 1,
|
|
192
205
|
array: []
|
|
193
206
|
};
|
|
194
|
-
if (schema.type
|
|
207
|
+
if (schema.type && !Array.isArray(schema.type) && exampleValues[schema.type] !== void 0) {
|
|
195
208
|
return cache(schema, exampleValues[schema.type]);
|
|
196
209
|
}
|
|
197
210
|
const discriminateSchema = schema.oneOf || schema.anyOf;
|
|
198
211
|
if (Array.isArray(discriminateSchema) && discriminateSchema.length > 0) {
|
|
199
|
-
const firstNonNullItem = discriminateSchema.find((item) => item.type !== "null");
|
|
212
|
+
const firstNonNullItem = discriminateSchema.map((item) => getResolvedRef(item)).find((item) => item.type !== "null");
|
|
200
213
|
if (firstNonNullItem) {
|
|
201
214
|
return getExampleFromSchema(firstNonNullItem, options, level + 1);
|
|
202
215
|
}
|
|
@@ -205,7 +218,7 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
205
218
|
if (Array.isArray(schema.allOf)) {
|
|
206
219
|
let example = null;
|
|
207
220
|
schema.allOf.forEach((allOfItem) => {
|
|
208
|
-
const newExample = getExampleFromSchema(allOfItem, options, level + 1);
|
|
221
|
+
const newExample = getExampleFromSchema(getResolvedRef(allOfItem), options, level + 1);
|
|
209
222
|
example = typeof newExample === "object" && typeof example === "object" ? {
|
|
210
223
|
...example ?? {},
|
|
211
224
|
...newExample
|
|
@@ -217,7 +230,7 @@ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) =>
|
|
|
217
230
|
if (schema.type.includes("null")) {
|
|
218
231
|
return null;
|
|
219
232
|
}
|
|
220
|
-
const exampleValue = exampleValues[schema.type[0]];
|
|
233
|
+
const exampleValue = exampleValues[schema.type[0] ?? ""];
|
|
221
234
|
if (exampleValue !== void 0) {
|
|
222
235
|
return cache(schema, exampleValue);
|
|
223
236
|
}
|