@scalar/postman-to-openapi 0.4.9 → 0.4.10

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @scalar/postman-to-openapi
2
2
 
3
+ ## 0.4.10
4
+
5
+ ### Patch Changes
6
+
7
+ #### Updated Dependencies
8
+
9
+ - **@scalar/openapi-types@0.5.4**
10
+ - [#8275](https://github.com/scalar/scalar/pull/8275): fix(openapi-types): make the `$ref` property in the `ReferenceObject` type required
11
+
12
+ - **@scalar/helpers@0.2.18**
13
+ - [#8314](https://github.com/scalar/scalar/pull/8314): chore: limit concurrent operations while migrating workspaces
14
+
3
15
  ## 0.4.9
4
16
 
5
17
  ### Patch Changes
@@ -139,6 +139,20 @@ function processItem(item, parentTags = [], parentPath = "") {
139
139
  pathItem[method] = operationObject;
140
140
  return { paths, components, serverUsage };
141
141
  }
142
+ const OPENAPI_PARAM_SCHEMA_TYPES = ["string", "number", "integer", "boolean", "object", "array"];
143
+ function toOpenApiParamSchemaType(s) {
144
+ const value = s ?? "string";
145
+ for (const t of OPENAPI_PARAM_SCHEMA_TYPES) {
146
+ if (t === value) return t;
147
+ }
148
+ return "string";
149
+ }
150
+ function parameterSchemaFromType(type) {
151
+ if (type === "array") {
152
+ return { type: "array" };
153
+ }
154
+ return { type };
155
+ }
142
156
  function parseParametersFromDescription(description) {
143
157
  const lines = description.split("\n");
144
158
  let inTable = false;
@@ -175,7 +189,7 @@ function parseParametersFromDescription(description) {
175
189
  in: row.object,
176
190
  description: row.description,
177
191
  required: row.required === "true",
178
- schema: { type: row.type || "string" }
192
+ schema: parameterSchemaFromType(toOpenApiParamSchemaType(row.type))
179
193
  };
180
194
  if (row.example) {
181
195
  param.example = row.example;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/helpers/path-items.ts"],
4
- "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport type { Item, ItemGroup } from '@/types'\n\nimport { processAuth } from './auth'\nimport { parseMdTable } from './markdown'\nimport { extractParameters } from './parameters'\nimport { processPostResponseScripts } from './post-response-scripts'\nimport { processPreRequestScripts } from './pre-request-scripts'\nimport { extractRequestBody } from './request-body'\nimport { extractResponses } from './responses'\nimport { extractPathFromUrl, extractPathParameterNames, extractServerFromUrl, normalizePath } from './urls'\n\ntype HttpMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace'\n\n/**\n * Information about server usage for an operation.\n */\nexport type ServerUsage = {\n serverUrl: string\n path: string\n method: HttpMethods\n}\n\nfunction ensureRequestBodyContent(requestBody: OpenAPIV3_1.RequestBodyObject): void {\n const content = requestBody.content ?? {}\n\n if (Object.keys(content).length === 0) {\n requestBody.content = {\n 'text/plain': {},\n }\n return\n }\n\n if ('text/plain' in content) {\n const textContent = content['text/plain']\n if (!textContent?.schema || (textContent.schema && Object.keys(textContent.schema).length === 0)) {\n content['text/plain'] = {}\n }\n }\n}\n\n/**\n * Processes a Postman collection item or item group and returns\n * the corresponding OpenAPI paths and components.\n * Handles nested item groups, extracts request details, and generates corresponding\n * OpenAPI path items and operations.\n */\nexport function processItem(\n item: Item | ItemGroup,\n parentTags: string[] = [],\n parentPath: string = '',\n): {\n paths: OpenAPIV3_1.PathsObject\n components: OpenAPIV3_1.ComponentsObject\n serverUsage: ServerUsage[]\n} {\n const paths: OpenAPIV3_1.PathsObject = {}\n const components: OpenAPIV3_1.ComponentsObject = {}\n const serverUsage: ServerUsage[] = []\n\n if ('item' in item && Array.isArray(item.item)) {\n const newParentTags = item.name ? [...parentTags, item.name] : parentTags\n item.item.forEach((childItem) => {\n const childResult = processItem(childItem, newParentTags, `${parentPath}/${item.name || ''}`)\n // Merge child paths and components\n for (const [pathKey, pathItem] of Object.entries(childResult.paths)) {\n if (!paths[pathKey]) {\n paths[pathKey] = pathItem\n } else {\n paths[pathKey] = {\n ...paths[pathKey],\n ...pathItem,\n }\n }\n }\n\n // Merge components.securitySchemes\n if (childResult.components.securitySchemes) {\n components.securitySchemes = {\n ...components.securitySchemes,\n ...childResult.components.securitySchemes,\n }\n }\n\n // Merge server usage\n serverUsage.push(...childResult.serverUsage)\n })\n return { paths, components, serverUsage }\n }\n\n if (!('request' in item)) {\n return { paths, components, serverUsage }\n }\n\n const { request, name, response } = item\n const method = (typeof request === 'string' ? 'get' : request.method || 'get').toLowerCase() as HttpMethods\n\n const requestUrl =\n typeof request === 'string' ? request : typeof request.url === 'string' ? request.url : (request.url?.raw ?? '')\n\n const path = extractPathFromUrl(requestUrl)\n\n // Normalize path parameters from ':param' to '{param}'\n const normalizedPath = normalizePath(path)\n\n // Extract server URL from request URL\n const serverUrl = extractServerFromUrl(requestUrl)\n if (serverUrl) {\n serverUsage.push({\n serverUrl,\n path: normalizedPath,\n method,\n })\n }\n\n // Extract path parameter names\n const pathParameterNames = extractPathParameterNames(normalizedPath)\n\n // Extract operation ID if present\n const { operationId, summary } = extractOperationInfo(name)\n\n const description =\n typeof request === 'string'\n ? ''\n : typeof request.description === 'string'\n ? request.description\n : (request.description?.content ?? '')\n\n const operationObject: OpenAPIV3_1.OperationObject = {\n tags: parentTags.length > 0 ? [parentTags.join(' > ')] : undefined,\n summary,\n description,\n responses: extractResponses(response || [], item),\n parameters: [],\n }\n\n // Add pre-request scripts if present\n const preRequestScript = processPreRequestScripts(item.event)\n if (preRequestScript) {\n operationObject['x-pre-request'] = preRequestScript\n }\n\n // Add post-response scripts if present\n const postResponseScript = processPostResponseScripts(item.event)\n if (postResponseScript) {\n operationObject['x-post-response'] = postResponseScript\n }\n\n // Only add operationId if it was explicitly provided\n if (operationId) {\n operationObject.operationId = operationId\n }\n\n // Extract parameters from the request (query, path, header)\n // This should always happen, regardless of whether a description exists\n const extractedParameters = extractParameters(request)\n\n // Merge parameters, giving priority to those from the Markdown table if description exists\n const mergedParameters = new Map<string, OpenAPIV3_1.ParameterObject>()\n\n // Add extracted parameters, filtering out path parameters not in the path\n extractedParameters.forEach((param) => {\n if (param.name) {\n if (param.in === 'path' && !pathParameterNames.includes(param.name)) {\n return\n }\n mergedParameters.set(param.name, param)\n }\n })\n\n // Parse parameters from the description's Markdown table if description exists\n if (operationObject.description) {\n const { descriptionWithoutTable, parametersFromTable } = parseParametersFromDescription(operationObject.description)\n operationObject.description = descriptionWithoutTable.trim()\n\n // Add parameters from table, filtering out path parameters not in the path\n // These take priority over extracted parameters\n parametersFromTable.forEach((param) => {\n if (param.name) {\n if (param.in === 'path' && !pathParameterNames.includes(param.name)) {\n return\n }\n mergedParameters.set(param.name, param)\n }\n })\n }\n\n // Set parameters if we have any\n if (mergedParameters.size > 0) {\n operationObject.parameters = Array.from(mergedParameters.values())\n }\n\n if (typeof request !== 'string' && request.auth) {\n if (!operationObject.security) {\n operationObject.security = []\n }\n const { securitySchemes, security } = processAuth(request.auth)\n\n if (!components.securitySchemes) {\n components.securitySchemes = {}\n }\n components.securitySchemes = {\n ...components.securitySchemes,\n ...securitySchemes,\n }\n\n operationObject.security.push(...security)\n }\n\n // Allow request bodies for all methods (including GET) if body is present\n if (typeof request !== 'string' && request.body) {\n const requestBody = extractRequestBody(request.body)\n ensureRequestBodyContent(requestBody)\n // Only add requestBody if it has content\n if (requestBody.content && Object.keys(requestBody.content).length > 0) {\n operationObject.requestBody = requestBody\n }\n }\n\n if (!paths[path]) {\n paths[path] = {}\n }\n const pathItem = paths[path] as OpenAPIV3_1.PathItemObject\n pathItem[method] = operationObject\n\n return { paths, components, serverUsage }\n}\n\n// Helper function to parse parameters from the description if it is markdown\ntype ParameterRow = {\n object?: 'query' | 'header' | 'path' | string\n name?: string\n description?: string\n required?: string\n type?: string\n example?: string\n}\n\nfunction parseParametersFromDescription(description: string): {\n descriptionWithoutTable: string\n parametersFromTable: OpenAPIV3_1.ParameterObject[]\n} {\n const lines = description.split('\\n')\n let inTable = false\n const tableLines: string[] = []\n const descriptionLines: string[] = []\n\n for (const line of lines) {\n // Detect the start of the table\n if (line.trim().startsWith('|')) {\n // Remove any preceding headers or empty lines before the table\n while (\n descriptionLines.length > 0 &&\n (descriptionLines[descriptionLines.length - 1]?.trim() === '' ||\n descriptionLines[descriptionLines.length - 1]?.trim().startsWith('#'))\n ) {\n descriptionLines.pop()\n }\n\n // Start collecting table lines\n inTable = true\n }\n\n if (inTable) {\n tableLines.push(line)\n // Detect the end of the table (any line that doesn't start with '|', excluding the alignment line)\n if (!line.trim().startsWith('|') && !line.trim().match(/^-+$/)) {\n inTable = false\n }\n } else {\n descriptionLines.push(line)\n }\n }\n\n const tableMarkdown = tableLines.join('\\n')\n const parsedTable = parseMdTable(tableMarkdown)\n const parametersFromTable = Object.values(parsedTable)\n .map((paramData) => {\n const row = paramData as ParameterRow\n if (row.object !== 'query' && row.object !== 'header' && row.object !== 'path') {\n return undefined\n }\n\n if (!row.name) {\n return undefined\n }\n\n const param: OpenAPIV3_1.ParameterObject = {\n name: row.name,\n in: row.object,\n description: row.description,\n required: row.required === 'true',\n schema: { type: row.type || 'string' },\n }\n\n if (row.example) {\n param.example = row.example\n }\n\n return param\n })\n .filter((param): param is OpenAPIV3_1.ParameterObject => Boolean(param))\n\n const descriptionWithoutTable = descriptionLines.join('\\n')\n return { descriptionWithoutTable, parametersFromTable }\n}\n\n// Instead of using regex with \\s*, let's split this into two steps\nfunction extractOperationInfo(name: string | undefined) {\n if (!name) {\n return { operationId: undefined, summary: undefined }\n }\n\n // First check if the string ends with something in brackets\n const match = name.match(/\\[([^[\\]]{0,1000})\\]$/)\n if (!match) {\n return { operationId: undefined, summary: name }\n }\n\n // Get the operation ID from inside brackets\n const operationId = match[1]\n\n // Trim the brackets part from the end using string operations instead of regex\n const lastBracketIndex = name.lastIndexOf('[')\n const summary = name.substring(0, lastBracketIndex).trim()\n\n return { operationId, summary }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport type { Item, ItemGroup } from '@/types'\n\nimport { processAuth } from './auth'\nimport { parseMdTable } from './markdown'\nimport { extractParameters } from './parameters'\nimport { processPostResponseScripts } from './post-response-scripts'\nimport { processPreRequestScripts } from './pre-request-scripts'\nimport { extractRequestBody } from './request-body'\nimport { extractResponses } from './responses'\nimport { extractPathFromUrl, extractPathParameterNames, extractServerFromUrl, normalizePath } from './urls'\n\ntype HttpMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace'\n\n/**\n * Information about server usage for an operation.\n */\nexport type ServerUsage = {\n serverUrl: string\n path: string\n method: HttpMethods\n}\n\nfunction ensureRequestBodyContent(requestBody: OpenAPIV3_1.RequestBodyObject): void {\n const content = requestBody.content ?? {}\n\n if (Object.keys(content).length === 0) {\n requestBody.content = {\n 'text/plain': {},\n }\n return\n }\n\n if ('text/plain' in content) {\n const textContent = content['text/plain']\n if (!textContent?.schema || (textContent.schema && Object.keys(textContent.schema).length === 0)) {\n content['text/plain'] = {}\n }\n }\n}\n\n/**\n * Processes a Postman collection item or item group and returns\n * the corresponding OpenAPI paths and components.\n * Handles nested item groups, extracts request details, and generates corresponding\n * OpenAPI path items and operations.\n */\nexport function processItem(\n item: Item | ItemGroup,\n parentTags: string[] = [],\n parentPath: string = '',\n): {\n paths: OpenAPIV3_1.PathsObject\n components: OpenAPIV3_1.ComponentsObject\n serverUsage: ServerUsage[]\n} {\n const paths: OpenAPIV3_1.PathsObject = {}\n const components: OpenAPIV3_1.ComponentsObject = {}\n const serverUsage: ServerUsage[] = []\n\n if ('item' in item && Array.isArray(item.item)) {\n const newParentTags = item.name ? [...parentTags, item.name] : parentTags\n item.item.forEach((childItem) => {\n const childResult = processItem(childItem, newParentTags, `${parentPath}/${item.name || ''}`)\n // Merge child paths and components\n for (const [pathKey, pathItem] of Object.entries(childResult.paths)) {\n if (!paths[pathKey]) {\n paths[pathKey] = pathItem\n } else {\n paths[pathKey] = {\n ...paths[pathKey],\n ...pathItem,\n }\n }\n }\n\n // Merge components.securitySchemes\n if (childResult.components.securitySchemes) {\n components.securitySchemes = {\n ...components.securitySchemes,\n ...childResult.components.securitySchemes,\n }\n }\n\n // Merge server usage\n serverUsage.push(...childResult.serverUsage)\n })\n return { paths, components, serverUsage }\n }\n\n if (!('request' in item)) {\n return { paths, components, serverUsage }\n }\n\n const { request, name, response } = item\n const method = (typeof request === 'string' ? 'get' : request.method || 'get').toLowerCase() as HttpMethods\n\n const requestUrl =\n typeof request === 'string' ? request : typeof request.url === 'string' ? request.url : (request.url?.raw ?? '')\n\n const path = extractPathFromUrl(requestUrl)\n\n // Normalize path parameters from ':param' to '{param}'\n const normalizedPath = normalizePath(path)\n\n // Extract server URL from request URL\n const serverUrl = extractServerFromUrl(requestUrl)\n if (serverUrl) {\n serverUsage.push({\n serverUrl,\n path: normalizedPath,\n method,\n })\n }\n\n // Extract path parameter names\n const pathParameterNames = extractPathParameterNames(normalizedPath)\n\n // Extract operation ID if present\n const { operationId, summary } = extractOperationInfo(name)\n\n const description =\n typeof request === 'string'\n ? ''\n : typeof request.description === 'string'\n ? request.description\n : (request.description?.content ?? '')\n\n const operationObject: OpenAPIV3_1.OperationObject = {\n tags: parentTags.length > 0 ? [parentTags.join(' > ')] : undefined,\n summary,\n description,\n responses: extractResponses(response || [], item),\n parameters: [],\n }\n\n // Add pre-request scripts if present\n const preRequestScript = processPreRequestScripts(item.event)\n if (preRequestScript) {\n operationObject['x-pre-request'] = preRequestScript\n }\n\n // Add post-response scripts if present\n const postResponseScript = processPostResponseScripts(item.event)\n if (postResponseScript) {\n operationObject['x-post-response'] = postResponseScript\n }\n\n // Only add operationId if it was explicitly provided\n if (operationId) {\n operationObject.operationId = operationId\n }\n\n // Extract parameters from the request (query, path, header)\n // This should always happen, regardless of whether a description exists\n const extractedParameters = extractParameters(request)\n\n // Merge parameters, giving priority to those from the Markdown table if description exists\n const mergedParameters = new Map<string, OpenAPIV3_1.ParameterObject>()\n\n // Add extracted parameters, filtering out path parameters not in the path\n extractedParameters.forEach((param) => {\n if (param.name) {\n if (param.in === 'path' && !pathParameterNames.includes(param.name)) {\n return\n }\n mergedParameters.set(param.name, param)\n }\n })\n\n // Parse parameters from the description's Markdown table if description exists\n if (operationObject.description) {\n const { descriptionWithoutTable, parametersFromTable } = parseParametersFromDescription(operationObject.description)\n operationObject.description = descriptionWithoutTable.trim()\n\n // Add parameters from table, filtering out path parameters not in the path\n // These take priority over extracted parameters\n parametersFromTable.forEach((param) => {\n if (param.name) {\n if (param.in === 'path' && !pathParameterNames.includes(param.name)) {\n return\n }\n mergedParameters.set(param.name, param)\n }\n })\n }\n\n // Set parameters if we have any\n if (mergedParameters.size > 0) {\n operationObject.parameters = Array.from(mergedParameters.values())\n }\n\n if (typeof request !== 'string' && request.auth) {\n if (!operationObject.security) {\n operationObject.security = []\n }\n const { securitySchemes, security } = processAuth(request.auth)\n\n if (!components.securitySchemes) {\n components.securitySchemes = {}\n }\n components.securitySchemes = {\n ...components.securitySchemes,\n ...securitySchemes,\n }\n\n operationObject.security.push(...security)\n }\n\n // Allow request bodies for all methods (including GET) if body is present\n if (typeof request !== 'string' && request.body) {\n const requestBody = extractRequestBody(request.body)\n ensureRequestBodyContent(requestBody)\n // Only add requestBody if it has content\n if (requestBody.content && Object.keys(requestBody.content).length > 0) {\n operationObject.requestBody = requestBody\n }\n }\n\n if (!paths[path]) {\n paths[path] = {}\n }\n const pathItem = paths[path] as OpenAPIV3_1.PathItemObject\n pathItem[method] = operationObject\n\n return { paths, components, serverUsage }\n}\n\n// Helper function to parse parameters from the description if it is markdown\ntype ParameterRow = {\n object?: 'query' | 'header' | 'path' | string\n name?: string\n description?: string\n required?: string\n type?: string\n example?: string\n}\n\n/** OpenAPI 3.1 parameter schema types (ParameterObject uses OpenAPIV3_1). */\nconst OPENAPI_PARAM_SCHEMA_TYPES = ['string', 'number', 'integer', 'boolean', 'object', 'array'] as const\n\ntype OpenApiParamSchemaType = (typeof OPENAPI_PARAM_SCHEMA_TYPES)[number]\n\nfunction toOpenApiParamSchemaType(s: string | undefined): OpenApiParamSchemaType {\n const value = s ?? 'string'\n for (const t of OPENAPI_PARAM_SCHEMA_TYPES) {\n if (t === value) return t\n }\n return 'string'\n}\n\nfunction parameterSchemaFromType(type: OpenApiParamSchemaType): OpenAPIV3_1.ParameterObject['schema'] {\n if (type === 'array') {\n return { type: 'array' }\n }\n return { type }\n}\n\nfunction parseParametersFromDescription(description: string): {\n descriptionWithoutTable: string\n parametersFromTable: OpenAPIV3_1.ParameterObject[]\n} {\n const lines = description.split('\\n')\n let inTable = false\n const tableLines: string[] = []\n const descriptionLines: string[] = []\n\n for (const line of lines) {\n // Detect the start of the table\n if (line.trim().startsWith('|')) {\n // Remove any preceding headers or empty lines before the table\n while (\n descriptionLines.length > 0 &&\n (descriptionLines[descriptionLines.length - 1]?.trim() === '' ||\n descriptionLines[descriptionLines.length - 1]?.trim().startsWith('#'))\n ) {\n descriptionLines.pop()\n }\n\n // Start collecting table lines\n inTable = true\n }\n\n if (inTable) {\n tableLines.push(line)\n // Detect the end of the table (any line that doesn't start with '|', excluding the alignment line)\n if (!line.trim().startsWith('|') && !line.trim().match(/^-+$/)) {\n inTable = false\n }\n } else {\n descriptionLines.push(line)\n }\n }\n\n const tableMarkdown = tableLines.join('\\n')\n const parsedTable = parseMdTable(tableMarkdown)\n const parametersFromTable = Object.values(parsedTable)\n .map((paramData) => {\n const row = paramData as ParameterRow\n if (row.object !== 'query' && row.object !== 'header' && row.object !== 'path') {\n return undefined\n }\n\n if (!row.name) {\n return undefined\n }\n\n const param: OpenAPIV3_1.ParameterObject = {\n name: row.name,\n in: row.object,\n description: row.description,\n required: row.required === 'true',\n schema: parameterSchemaFromType(toOpenApiParamSchemaType(row.type)),\n }\n\n if (row.example) {\n param.example = row.example\n }\n\n return param\n })\n .filter((param): param is OpenAPIV3_1.ParameterObject => Boolean(param))\n\n const descriptionWithoutTable = descriptionLines.join('\\n')\n return { descriptionWithoutTable, parametersFromTable }\n}\n\n// Instead of using regex with \\s*, let's split this into two steps\nfunction extractOperationInfo(name: string | undefined) {\n if (!name) {\n return { operationId: undefined, summary: undefined }\n }\n\n // First check if the string ends with something in brackets\n const match = name.match(/\\[([^[\\]]{0,1000})\\]$/)\n if (!match) {\n return { operationId: undefined, summary: name }\n }\n\n // Get the operation ID from inside brackets\n const operationId = match[1]\n\n // Trim the brackets part from the end using string operations instead of regex\n const lastBracketIndex = name.lastIndexOf('[')\n const summary = name.substring(0, lastBracketIndex).trim()\n\n return { operationId, summary }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["pathItem"]
7
7
  }
@@ -11,5 +11,5 @@ export declare function inferSchemaFromExample(example: any): OpenAPIV3_1.Schema
11
11
  * by checking its JavaScript type and attempting to parse it
12
12
  * as a number or boolean if it's a string.
13
13
  */
14
- export declare function inferSchemaType(value: any): OpenAPIV3_1.SchemaObject;
14
+ export declare function inferSchemaType(value: any): OpenAPIV3_1.NonArraySchemaObject;
15
15
  //# sourceMappingURL=schemas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/helpers/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,CAAC,YAAY,CAoB7E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,WAAW,CAAC,YAAY,CAiBpE"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/helpers/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,CAAC,YAAY,CAoB7E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,WAAW,CAAC,oBAAoB,CAsB5E"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/helpers/schemas.ts"],
4
- "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\n/**\n * Infers the schema of an OpenAPI object based on an example value.\n * This function recursively analyzes the structure of the example value\n * and returns a corresponding OpenAPI schema object.\n */\nexport function inferSchemaFromExample(example: any): OpenAPIV3_1.SchemaObject {\n if (Array.isArray(example)) {\n return {\n type: 'array',\n items: example.length > 0 ? inferSchemaFromExample(example[0]) : {},\n }\n }\n if (typeof example === 'object' && example !== null) {\n const properties: { [key: string]: OpenAPIV3_1.SchemaObject } = {}\n for (const [key, value] of Object.entries(example)) {\n properties[key] = inferSchemaFromExample(value)\n }\n return {\n type: 'object',\n properties,\n }\n }\n return {\n type: typeof example as OpenAPIV3_1.NonArraySchemaObjectType,\n }\n}\n\n/**\n * Infers the schema type of a value based on its type.\n * This function determines the OpenAPI schema type of a value\n * by checking its JavaScript type and attempting to parse it\n * as a number or boolean if it's a string.\n */\nexport function inferSchemaType(value: any): OpenAPIV3_1.SchemaObject {\n if (typeof value === 'number') {\n return { type: Number.isInteger(value) ? 'integer' : 'number' }\n }\n if (typeof value === 'boolean') {\n return { type: 'boolean' }\n }\n if (typeof value === 'string') {\n const num = Number(value)\n if (!isNaN(num)) {\n return { type: Number.isInteger(num) ? 'integer' : 'number' }\n }\n if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {\n return { type: 'boolean' }\n }\n }\n return { type: 'string' }\n}\n"],
5
- "mappings": "AAOO,SAAS,uBAAuB,SAAwC;AAC7E,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ,SAAS,IAAI,uBAAuB,QAAQ,CAAC,CAAC,IAAI,CAAC;AAAA,IACpE;AAAA,EACF;AACA,MAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AACnD,UAAM,aAA0D,CAAC;AACjE,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,iBAAW,GAAG,IAAI,uBAAuB,KAAK;AAAA,IAChD;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,EACf;AACF;AAQO,SAAS,gBAAgB,OAAsC;AACpE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,EAAE,MAAM,OAAO,UAAU,KAAK,IAAI,YAAY,SAAS;AAAA,EAChE;AACA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,MAAM,OAAO,KAAK;AACxB,QAAI,CAAC,MAAM,GAAG,GAAG;AACf,aAAO,EAAE,MAAM,OAAO,UAAU,GAAG,IAAI,YAAY,SAAS;AAAA,IAC9D;AACA,QAAI,MAAM,YAAY,MAAM,UAAU,MAAM,YAAY,MAAM,SAAS;AACrE,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AAAA,EACF;AACA,SAAO,EAAE,MAAM,SAAS;AAC1B;",
4
+ "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\n/**\n * Infers the schema of an OpenAPI object based on an example value.\n * This function recursively analyzes the structure of the example value\n * and returns a corresponding OpenAPI schema object.\n */\nexport function inferSchemaFromExample(example: any): OpenAPIV3_1.SchemaObject {\n if (Array.isArray(example)) {\n return {\n type: 'array',\n items: example.length > 0 ? inferSchemaFromExample(example[0]) : {},\n }\n }\n if (typeof example === 'object' && example !== null) {\n const properties: { [key: string]: OpenAPIV3_1.SchemaObject } = {}\n for (const [key, value] of Object.entries(example)) {\n properties[key] = inferSchemaFromExample(value)\n }\n return {\n type: 'object',\n properties,\n }\n }\n return {\n type: typeof example as OpenAPIV3_1.NonArraySchemaObjectType,\n }\n}\n\n/**\n * Infers the schema type of a value based on its type.\n * This function determines the OpenAPI schema type of a value\n * by checking its JavaScript type and attempting to parse it\n * as a number or boolean if it's a string.\n */\nexport function inferSchemaType(value: any): OpenAPIV3_1.NonArraySchemaObject {\n if (typeof value === 'number') {\n return { type: Number.isInteger(value) ? 'integer' : 'number' }\n }\n\n if (typeof value === 'boolean') {\n return { type: 'boolean' }\n }\n\n if (typeof value === 'string') {\n const num = Number(value)\n\n if (!isNaN(num)) {\n return { type: Number.isInteger(num) ? 'integer' : 'number' }\n }\n\n if (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') {\n return { type: 'boolean' }\n }\n }\n\n return { type: 'string' }\n}\n"],
5
+ "mappings": "AAOO,SAAS,uBAAuB,SAAwC;AAC7E,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ,SAAS,IAAI,uBAAuB,QAAQ,CAAC,CAAC,IAAI,CAAC;AAAA,IACpE;AAAA,EACF;AACA,MAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AACnD,UAAM,aAA0D,CAAC;AACjE,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,iBAAW,GAAG,IAAI,uBAAuB,KAAK;AAAA,IAChD;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,EACf;AACF;AAQO,SAAS,gBAAgB,OAA8C;AAC5E,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,EAAE,MAAM,OAAO,UAAU,KAAK,IAAI,YAAY,SAAS;AAAA,EAChE;AAEA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,MAAM,OAAO,KAAK;AAExB,QAAI,CAAC,MAAM,GAAG,GAAG;AACf,aAAO,EAAE,MAAM,OAAO,UAAU,GAAG,IAAI,YAAY,SAAS;AAAA,IAC9D;AAEA,QAAI,MAAM,YAAY,MAAM,UAAU,MAAM,YAAY,MAAM,SAAS;AACrE,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS;AAC1B;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "export",
20
20
  "scalar"
21
21
  ],
22
- "version": "0.4.9",
22
+ "version": "0.4.10",
23
23
  "engines": {
24
24
  "node": ">=20"
25
25
  },
@@ -38,8 +38,8 @@
38
38
  "CHANGELOG.md"
39
39
  ],
40
40
  "dependencies": {
41
- "@scalar/helpers": "0.2.17",
42
- "@scalar/openapi-types": "0.5.3"
41
+ "@scalar/helpers": "0.2.18",
42
+ "@scalar/openapi-types": "0.5.4"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^22.19.3",