@sdk-it/spec 0.45.0 → 0.46.0

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.
Files changed (121) hide show
  1. package/dist/index.d.ts +5 -3
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +9 -3
  4. package/dist/index.js.map +2 -2
  5. package/dist/lib/find-polymorphic-varients.d.ts.map +1 -1
  6. package/dist/lib/find-polymorphic-varients.js +5 -10
  7. package/dist/lib/find-polymorphic-varients.js.map +2 -2
  8. package/dist/lib/for-each-operation.d.ts +11 -3
  9. package/dist/lib/for-each-operation.d.ts.map +1 -1
  10. package/dist/lib/for-each-operation.js +23 -15
  11. package/dist/lib/for-each-operation.js.map +2 -2
  12. package/dist/lib/format-name.d.ts.map +1 -1
  13. package/dist/lib/format-name.js +0 -1
  14. package/dist/lib/format-name.js.map +2 -2
  15. package/dist/lib/ir.d.ts +2 -2
  16. package/dist/lib/ir.d.ts.map +1 -1
  17. package/dist/lib/ir.js +6 -120
  18. package/dist/lib/ir.js.map +2 -2
  19. package/dist/lib/is.d.ts.map +1 -1
  20. package/dist/lib/is.js +1 -3
  21. package/dist/lib/is.js.map +2 -2
  22. package/dist/lib/loaders/postman/postman-converter.d.ts.map +1 -1
  23. package/dist/lib/loaders/postman/postman-converter.js +1 -11
  24. package/dist/lib/loaders/postman/postman-converter.js.map +2 -2
  25. package/dist/lib/options.d.ts +7 -45
  26. package/dist/lib/options.d.ts.map +1 -1
  27. package/dist/lib/options.js +26 -28
  28. package/dist/lib/options.js.map +2 -2
  29. package/dist/lib/overview-docs/overview-pagination.d.ts +1 -1
  30. package/dist/lib/overview-docs/overview-pagination.d.ts.map +1 -1
  31. package/dist/lib/overview-docs/overview-pagination.js +1 -1
  32. package/dist/lib/overview-docs/overview-pagination.js.map +2 -2
  33. package/dist/lib/pagination/guess-pagination.d.ts.map +1 -1
  34. package/dist/lib/pagination/guess-pagination.js.map +2 -2
  35. package/dist/lib/pagination/pagination-result.d.ts.map +1 -1
  36. package/dist/lib/pagination/pagination-result.js +15 -5
  37. package/dist/lib/pagination/pagination-result.js.map +2 -2
  38. package/dist/lib/pagination/pagination.d.ts.map +1 -1
  39. package/dist/lib/pagination/pagination.js +7 -6
  40. package/dist/lib/pagination/pagination.js.map +2 -2
  41. package/dist/lib/processing-plugins/canonicalize-spec.d.ts +3 -0
  42. package/dist/lib/processing-plugins/canonicalize-spec.d.ts.map +1 -0
  43. package/dist/lib/processing-plugins/canonicalize-spec.js +29 -0
  44. package/dist/lib/processing-plugins/canonicalize-spec.js.map +7 -0
  45. package/dist/lib/processing-plugins/create-default-processing-plugins.d.ts +5 -0
  46. package/dist/lib/processing-plugins/create-default-processing-plugins.d.ts.map +1 -0
  47. package/dist/lib/processing-plugins/create-default-processing-plugins.js +30 -0
  48. package/dist/lib/processing-plugins/create-default-processing-plugins.js.map +7 -0
  49. package/dist/lib/processing-plugins/enrich-examples.d.ts +25 -0
  50. package/dist/lib/processing-plugins/enrich-examples.d.ts.map +1 -0
  51. package/dist/lib/processing-plugins/enrich-examples.js +93 -0
  52. package/dist/lib/processing-plugins/enrich-examples.js.map +7 -0
  53. package/dist/lib/processing-plugins/extract-inline-schemas.d.ts +3 -0
  54. package/dist/lib/processing-plugins/extract-inline-schemas.d.ts.map +1 -0
  55. package/dist/lib/processing-plugins/extract-inline-schemas.js +14 -0
  56. package/dist/lib/processing-plugins/extract-inline-schemas.js.map +7 -0
  57. package/dist/lib/processing-plugins/extract-overview-docs.d.ts +3 -0
  58. package/dist/lib/processing-plugins/extract-overview-docs.d.ts.map +1 -0
  59. package/dist/lib/processing-plugins/extract-overview-docs.js +13 -0
  60. package/dist/lib/processing-plugins/extract-overview-docs.js.map +7 -0
  61. package/dist/lib/processing-plugins/index.d.ts +14 -0
  62. package/dist/lib/processing-plugins/index.d.ts.map +1 -0
  63. package/dist/lib/processing-plugins/index.js +14 -0
  64. package/dist/lib/processing-plugins/index.js.map +7 -0
  65. package/dist/lib/processing-plugins/infer-pagination.d.ts +3 -0
  66. package/dist/lib/processing-plugins/infer-pagination.d.ts.map +1 -0
  67. package/dist/lib/processing-plugins/infer-pagination.js +21 -0
  68. package/dist/lib/processing-plugins/infer-pagination.js.map +7 -0
  69. package/dist/lib/processing-plugins/normalize-operation-ids.d.ts +3 -0
  70. package/dist/lib/processing-plugins/normalize-operation-ids.d.ts.map +1 -0
  71. package/dist/lib/processing-plugins/normalize-operation-ids.js +74 -0
  72. package/dist/lib/processing-plugins/normalize-operation-ids.js.map +7 -0
  73. package/dist/lib/processing-plugins/normalize-parameters.d.ts +3 -0
  74. package/dist/lib/processing-plugins/normalize-parameters.d.ts.map +1 -0
  75. package/dist/lib/processing-plugins/normalize-parameters.js +29 -0
  76. package/dist/lib/processing-plugins/normalize-parameters.js.map +7 -0
  77. package/dist/lib/processing-plugins/normalize-paths.d.ts +3 -0
  78. package/dist/lib/processing-plugins/normalize-paths.d.ts.map +1 -0
  79. package/dist/lib/processing-plugins/normalize-paths.js +67 -0
  80. package/dist/lib/processing-plugins/normalize-paths.js.map +7 -0
  81. package/dist/lib/processing-plugins/normalize-request-bodies.d.ts +3 -0
  82. package/dist/lib/processing-plugins/normalize-request-bodies.d.ts.map +1 -0
  83. package/dist/lib/processing-plugins/normalize-request-bodies.js +44 -0
  84. package/dist/lib/processing-plugins/normalize-request-bodies.js.map +7 -0
  85. package/dist/lib/processing-plugins/normalize-responses.d.ts +3 -0
  86. package/dist/lib/processing-plugins/normalize-responses.d.ts.map +1 -0
  87. package/dist/lib/processing-plugins/normalize-responses.js +38 -0
  88. package/dist/lib/processing-plugins/normalize-responses.js.map +7 -0
  89. package/dist/lib/processing-plugins/normalize-schemas.d.ts +3 -0
  90. package/dist/lib/processing-plugins/normalize-schemas.d.ts.map +1 -0
  91. package/dist/lib/processing-plugins/normalize-schemas.js +13 -0
  92. package/dist/lib/processing-plugins/normalize-schemas.js.map +7 -0
  93. package/dist/lib/processing-plugins/normalize-tags.d.ts +3 -0
  94. package/dist/lib/processing-plugins/normalize-tags.d.ts.map +1 -0
  95. package/dist/lib/processing-plugins/normalize-tags.js +18 -0
  96. package/dist/lib/processing-plugins/normalize-tags.js.map +7 -0
  97. package/dist/lib/processing.d.ts +33 -0
  98. package/dist/lib/processing.d.ts.map +1 -0
  99. package/dist/lib/processing.js +41 -0
  100. package/dist/lib/processing.js.map +7 -0
  101. package/dist/lib/reserved-keywords.d.ts.map +1 -1
  102. package/dist/lib/reserved-keywords.js +18 -1
  103. package/dist/lib/reserved-keywords.js.map +2 -2
  104. package/dist/lib/tag.js +2 -2
  105. package/dist/lib/tag.js.map +2 -2
  106. package/dist/lib/tune-request-body.d.ts.map +1 -1
  107. package/dist/lib/tune-request-body.js +22 -12
  108. package/dist/lib/tune-request-body.js.map +2 -2
  109. package/dist/lib/tune-response.d.ts.map +1 -1
  110. package/dist/lib/tune-response.js +16 -12
  111. package/dist/lib/tune-response.js.map +2 -2
  112. package/dist/lib/tune.d.ts.map +1 -1
  113. package/dist/lib/tune.js +31 -7
  114. package/dist/lib/tune.js.map +2 -2
  115. package/dist/lib/types.d.ts +4 -1
  116. package/dist/lib/types.d.ts.map +1 -1
  117. package/dist/lib/walk-schemas.d.ts +8 -0
  118. package/dist/lib/walk-schemas.d.ts.map +1 -0
  119. package/dist/lib/walk-schemas.js +51 -0
  120. package/dist/lib/walk-schemas.js.map +7 -0
  121. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/loaders/postman/postman-converter.ts"],
4
- "sourcesContent": ["import { parse } from 'fast-content-type-parse';\nimport type {\n ContentObject,\n OpenAPIObject,\n OperationObject,\n ParameterObject,\n PathsObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n SecuritySchemeObject,\n TagObject,\n} from 'openapi3-ts/oas31';\n\nimport type {\n Auth,\n Description,\n Folder,\n Header,\n Headers,\n Item,\n Items,\n PostmanCollection,\n PostmanRequest,\n QueryParam,\n Request,\n RequestBody,\n Url,\n Variable,\n} from './spec-types';\n\nfunction descriptionToText(description?: Description) {\n if (!description) {\n return undefined;\n }\n if (typeof description === 'string') {\n return description;\n }\n if (description.content) {\n return description.content;\n }\n return undefined;\n}\n\ntype OurQueryParam = Omit<QueryParam, 'key'> & {\n key: string;\n description?: string;\n};\ntype OurVariable = Omit<QueryParam, 'key'> & {\n key: string;\n description?: string;\n};\ntype OurUrl = {\n path: string[];\n query: OurQueryParam[];\n variable: OurVariable[];\n};\n\nfunction isFolder(item: Items): item is Folder & { name: string } {\n return 'item' in item;\n}\n\nfunction isRequest(\n item: Items,\n): item is Item & { name: string; request: Request } {\n return !!item.request;\n}\n\n/**\n * Recursively processes items and folders in a Postman collection\n * @param items Array of Postman items (requests or folders)\n * @param parentTags Array of parent folder tags for proper nesting\n */\nfunction processItems(\n items: Items[],\n parentTags: string[],\n globalTags: TagObject[],\n paths: PathsObject,\n securitySchemes: Record<string, SecuritySchemeObject>,\n) {\n for (const item of items) {\n if (!isFolder(item) && !isRequest(item)) {\n console.warn(\n `Skipping item ${item.name} because it is not a folder or request`,\n );\n continue;\n }\n\n if (isFolder(item)) {\n // Process folder-level auth if it exists\n if (item.auth) {\n processAuthScheme(item.auth, securitySchemes);\n }\n\n // Add this folder as a tag if not already added\n if (!globalTags.some((tag) => tag.name === item.name)) {\n globalTags.push({\n name: item.name,\n description: descriptionToText(item.description),\n });\n }\n\n const currentTags = [...parentTags, item.name];\n processItems(item.item, currentTags, globalTags, paths, securitySchemes);\n } else if (isRequest(item)) {\n // Process this request\n let operation: ReturnType<typeof requestToOperation>;\n if (typeof item.request === 'string') {\n const url = new URL(item.request);\n operation = requestToOperation(\n {\n name: url.pathname,\n response: [{ code: 200 }],\n request: {\n method: 'get',\n url: {\n path: url.pathname.split('/').slice(1),\n },\n },\n },\n securitySchemes,\n );\n } else {\n const auth = item.request.auth;\n operation = requestToOperation(\n {\n name: item.name,\n request: { ...item.request, auth },\n response: item.response,\n },\n securitySchemes,\n );\n }\n\n paths[operation.path] ??= {};\n Object.assign(paths[operation.path], {\n [operation.method]: {\n tags: parentTags.length ? parentTags : undefined,\n ...operation.operation,\n },\n });\n }\n }\n}\n\nfunction coerceVariable(query: Variable): OurVariable {\n if (!query.key) {\n throw new Error('Invalid query parameter format');\n }\n return {\n key: query.key,\n description: descriptionToText(query.description),\n };\n}\nfunction coerceQuery(query: QueryParam): OurQueryParam {\n if (!query.key) {\n throw new Error('Invalid query parameter format');\n }\n return {\n key: query.key,\n description: descriptionToText(query.description),\n };\n}\nfunction coerceUrl(url?: Url): OurUrl {\n if (!url) {\n throw new Error('Invalid URL format');\n }\n if (typeof url === 'string') {\n return {\n path: url.split('/').slice(1),\n query: [],\n variable: [],\n };\n }\n if (typeof url.path === 'string') {\n return {\n path: url.path.split('/').slice(1),\n query: (url.query ?? []).map(coerceQuery),\n variable: (url.variable ?? []).map(coerceVariable),\n };\n }\n return {\n path: (url.path ?? []).map((p) => {\n if (typeof p === 'string') {\n return p;\n }\n throw new Error('Invalid URL path format');\n }),\n query: (url.query ?? []).map(coerceQuery),\n variable: (url.variable ?? []).map(coerceVariable),\n };\n}\n\nfunction coerceResponseHeader(header?: Headers) {\n if (!header) {\n return [];\n }\n if (typeof header === 'string') {\n throw new Error(`Invalid header format: ${header}`);\n }\n return header.map((h) => {\n if (typeof h === 'string') {\n return {\n key: h,\n value: null,\n };\n }\n return h;\n });\n}\n\n/**\n * Process an auth scheme and add it to securitySchemes\n */\nfunction processAuthScheme(\n auth: Auth,\n securitySchemes: Record<string, SecuritySchemeObject>,\n): string | null {\n if (!auth || auth.type === 'noauth') return null;\n\n const getAuthAttr = (key: string): string | undefined => {\n if (!auth || auth.type === 'noauth') return undefined;\n const authType = auth[auth.type];\n if (!authType) return undefined;\n const attr = authType.find((a) => a.key === key);\n return attr ? String(attr.value) : undefined;\n };\n\n const schemeId = `${auth.type}Auth`;\n\n switch (auth.type) {\n case 'apikey': {\n const key = getAuthAttr('key') || 'api_key';\n const in_ = getAuthAttr('in') || 'header';\n securitySchemes[schemeId] = {\n type: 'apiKey',\n name: key,\n in: in_ as 'header' | 'query' | 'cookie',\n description: 'API key authentication',\n };\n break;\n }\n case 'basic':\n securitySchemes[schemeId] = {\n type: 'http',\n scheme: 'basic',\n description: 'Basic HTTP authentication',\n };\n break;\n case 'bearer': {\n const token = getAuthAttr('token');\n securitySchemes[schemeId] = {\n type: 'http',\n scheme: 'bearer',\n description: 'Bearer token authentication',\n ...(token ? { bearerFormat: 'JWT' } : {}),\n };\n break;\n }\n case 'oauth2': {\n const flowType = getAuthAttr('grant_type') || 'implicit';\n securitySchemes[schemeId] = {\n type: 'oauth2',\n description: 'OAuth 2.0 authentication',\n flows: {\n [flowType === 'authorization_code' ? 'authorizationCode' : flowType]:\n {\n authorizationUrl:\n getAuthAttr('authUrl') || 'https://example.com/oauth/authorize',\n tokenUrl:\n getAuthAttr('tokenUrl') || 'https://example.com/oauth/token',\n scopes: {},\n },\n },\n };\n break;\n }\n case 'digest':\n securitySchemes[schemeId] = {\n type: 'http',\n scheme: 'digest',\n description: 'Digest authentication',\n };\n break;\n case 'awsv4':\n securitySchemes[schemeId] = {\n type: 'apiKey',\n name: 'Authorization',\n in: 'header',\n description: 'AWS Signature v4 authentication',\n };\n break;\n default:\n securitySchemes[schemeId] = {\n type: 'apiKey',\n name: 'Authorization',\n in: 'header',\n description: `${auth.type} authentication`,\n };\n }\n\n return schemeId;\n}\n\nfunction generateSecurityRequirement(\n auth: Auth,\n securitySchemes: Record<string, SecuritySchemeObject>,\n) {\n if (!auth || auth.type === 'noauth') return [];\n\n const schemeId = `${auth.type}Auth`;\n\n // Only include if the scheme was successfully processed\n if (securitySchemes[schemeId]) {\n return [{ [schemeId]: [] }];\n }\n\n return [];\n}\n\nfunction requestToOperation(\n item: Exclude<Item, 'name' | 'request'> & {\n name: string;\n request: PostmanRequest;\n },\n securitySchemes: Record<string, SecuritySchemeObject>,\n) {\n const url = coerceUrl(item.request.url);\n const headers = Array.isArray(item.request.header)\n ? item.request.header\n : ([] as Header[]);\n\n const parameters: ParameterObject[] = [\n ...url.query\n .filter((param) => !param.disabled)\n .map((param) => {\n return {\n in: 'query',\n name: param.key,\n required: false,\n description: param.description,\n schema: {\n ...(param.value && !isNaN(Number(param.value))\n ? { type: 'number' }\n : param.value === 'true' || param.value === 'false'\n ? { type: 'boolean' }\n : { type: 'string' }),\n },\n } satisfies ParameterObject;\n }),\n\n ...url.variable.map((param) => {\n return {\n in: 'path',\n name: param.key,\n required: true,\n description: param.description,\n schema: {\n ...(param.value && !isNaN(Number(param.value))\n ? { type: 'number' }\n : param.value === 'true' || param.value === 'false'\n ? { type: 'boolean' }\n : { type: 'string' }),\n },\n } satisfies ParameterObject;\n }),\n\n ...headers\n .filter(\n (h) =>\n !h.disabled &&\n h.key.toLowerCase() !== 'accept' &&\n h.key.toLowerCase() !== 'content-type',\n )\n .map((header) => {\n return {\n in: 'header',\n name: header.key,\n required: false,\n description: descriptionToText(header.description),\n schema: {\n type: 'string',\n },\n } satisfies ParameterObject;\n }),\n ];\n\n // Extract Accept and Content-Type headers\n const acceptHeaderIdx = headers.findIndex(\n (h) => h.key.toLowerCase() === 'accept',\n );\n const contentTypeIdx = headers.findIndex(\n (h) => h.key.toLowerCase() === 'content-type',\n );\n const [acceptHeaderValue] =\n acceptHeaderIdx !== -1\n ? headers.splice(acceptHeaderIdx, 1).map((h) => h.value)\n : [];\n const [contentTypeValue] =\n contentTypeIdx !== -1\n ? headers.splice(contentTypeIdx, 1).map((h) => h.value)\n : [];\n\n let security;\n if (item.request.auth) {\n const schemeId = processAuthScheme(item.request.auth, securitySchemes);\n if (schemeId) {\n security = [{ [schemeId]: [] }];\n }\n }\n\n return {\n path: `/${url.path.join('/')}`.replace(/:([^/]+)/g, '{$1}'),\n method: (item.request.method ?? 'get').toLowerCase(),\n operation: {\n summary: item.name,\n description: descriptionToText(item.request.description),\n parameters,\n security,\n responses:\n !item.response || item.response.length === 0\n ? {\n 200: {\n description: 'Successful response',\n },\n }\n : item.response.reduce((acc, response) => {\n const headers = coerceResponseHeader(response.header);\n const contentTypeIdx = headers.findIndex(\n (h) => h.key.toLowerCase() === 'content-type',\n );\n const [contentTypeValue] =\n contentTypeIdx !== -1\n ? headers.splice(contentTypeIdx).map((h) => h.value)\n : [];\n\n let contentType = response.body\n ? parse(contentTypeValue || 'application/json')?.type\n : null;\n contentType ??= 'application/octet-stream';\n\n return {\n ...acc,\n [response.code ?? 200]: {\n description: response.name\n ? response.name\n : `Response for ${response.code}`,\n content: {\n [contentType]: {\n schema: bodyToSchema(response.body),\n },\n },\n } satisfies ResponseObject,\n };\n }, {}),\n requestBody: item.request.body\n ? requestBodyToOperationBody(\n contentTypeValue || 'application/json',\n item.request.body,\n )\n : undefined,\n } satisfies OperationObject,\n };\n}\n\n/**\n * Helper function to determine the likely type of a value\n */\nfunction inferSchemaType(value: string | null): { type: string } {\n if (!value) return { type: 'string' };\n\n // Check if value is a number\n if (!isNaN(Number(value))) {\n return { type: 'number' };\n }\n\n // Check if value is a boolean\n if (value === 'true' || value === 'false') {\n return { type: 'boolean' };\n }\n\n // Default to string\n return { type: 'string' };\n}\n\nfunction requestBodyToOperationBody(\n contentType: string,\n body: RequestBody,\n): RequestBodyObject {\n if (body.mode === 'raw') {\n return {\n content: {\n [contentType]: {\n schema: bodyToSchema(body.raw),\n },\n },\n };\n } else if (body.mode === 'urlencoded') {\n const properties: Record<string, any> = {};\n (body.urlencoded || [])\n .filter((param) => !param.disabled)\n .forEach((param) => {\n properties[param.key] = {\n type: 'string',\n description: descriptionToText(param.description),\n };\n });\n\n return {\n content: {\n 'application/x-www-form-urlencoded': {\n schema: {\n type: 'object',\n properties,\n },\n },\n } satisfies ContentObject,\n };\n } else if (body.mode === 'formdata') {\n const properties: SchemaObject['properties'] = {};\n (body.formdata || [])\n .filter((param) => !param.disabled)\n .forEach((param) => {\n if (param.type === 'text') {\n properties[param.key] = {\n type: 'string',\n description: descriptionToText(param.description),\n };\n } else if (param.type === 'file') {\n properties[param.key] = {\n type: 'string',\n format: 'binary',\n description: descriptionToText(param.description),\n };\n }\n });\n\n return {\n content: {\n 'multipart/form-data': {\n schema: {\n type: 'object',\n properties,\n },\n },\n } satisfies ContentObject,\n };\n }\n\n throw new Error(\n `Unsupported request body mode: ${body.mode}. Supported modes are: raw, urlencoded, formdata`,\n );\n}\n\nfunction bodyToSchema(bodyString?: string | null): SchemaObject | undefined {\n if (!bodyString) {\n return undefined;\n }\n\n let body: unknown;\n try {\n body = JSON.parse(bodyString.normalize('NFKD'));\n } catch (error) {\n console.warn(\n `Failed to parse JSON body: ${bodyString}. Treating as plain string.`,\n error,\n );\n return { type: 'string', example: bodyString };\n }\n\n return toSchema(body);\n}\n\nfunction toSchema(body: unknown | unknown[]): any {\n const typeMap: Record<string, string> = {\n '<number>': 'number',\n '<string>': 'string',\n '<boolean>': 'boolean',\n false: 'boolean',\n true: 'boolean',\n };\n if (Array.isArray(body)) {\n return {\n type: 'array',\n items: toSchema(body[0]),\n };\n }\n if (typeof body === 'object' && body !== null) {\n const properties: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(body)) {\n properties[key] = toSchema(value);\n }\n return {\n type: 'object',\n properties,\n };\n }\n if (typeof body === 'string') {\n return {\n type: typeMap[body] ?? 'string',\n };\n }\n if (typeof body === 'number') {\n return {\n type: 'number',\n };\n }\n if (typeof body === 'boolean') {\n return {\n type: 'boolean',\n };\n }\n if (body === null) {\n return {\n type: 'null',\n };\n }\n console.warn(`Unknown type for body: ${body}. Defaulting to string.`, body);\n return {\n type: 'string',\n };\n}\n\nexport function convertPostmanToOpenAPI(\n collection: PostmanCollection,\n): OpenAPIObject {\n const tags: TagObject[] = [];\n const paths: PathsObject = {};\n const securitySchemes: Record<string, SecuritySchemeObject> = {};\n\n if (collection.auth) {\n processAuthScheme(collection.auth, securitySchemes);\n }\n processItems(collection.item, [], tags, paths, securitySchemes);\n return {\n openapi: '3.1.0',\n info: {\n title: collection.info.name,\n version: '1.0.0',\n description: descriptionToText(collection.info.description),\n },\n tags,\n paths,\n // Only add security at top level if there's collection auth\n security: collection.auth\n ? generateSecurityRequirement(collection.auth, securitySchemes)\n : undefined,\n components:\n Object.keys(securitySchemes).length > 0\n ? {\n securitySchemes,\n }\n : undefined,\n };\n}\n"],
5
- "mappings": "AAAA,SAAS,aAAa;AA+BtB,SAAS,kBAAkB,aAA2B;AACpD,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO;AAAA,EACT;AACA,MAAI,YAAY,SAAS;AACvB,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AACT;AAgBA,SAAS,SAAS,MAAgD;AAChE,SAAO,UAAU;AACnB;AAEA,SAAS,UACP,MACmD;AACnD,SAAO,CAAC,CAAC,KAAK;AAChB;AAOA,SAAS,aACP,OACA,YACA,YACA,OACA,iBACA;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,IAAI,GAAG;AACvC,cAAQ;AAAA,QACN,iBAAiB,KAAK,IAAI;AAAA,MAC5B;AACA;AAAA,IACF;AAEA,QAAI,SAAS,IAAI,GAAG;AAElB,UAAI,KAAK,MAAM;AACb,0BAAkB,KAAK,MAAM,eAAe;AAAA,MAC9C;AAGA,UAAI,CAAC,WAAW,KAAK,CAAC,QAAQ,IAAI,SAAS,KAAK,IAAI,GAAG;AACrD,mBAAW,KAAK;AAAA,UACd,MAAM,KAAK;AAAA,UACX,aAAa,kBAAkB,KAAK,WAAW;AAAA,QACjD,CAAC;AAAA,MACH;AAEA,YAAM,cAAc,CAAC,GAAG,YAAY,KAAK,IAAI;AAC7C,mBAAa,KAAK,MAAM,aAAa,YAAY,OAAO,eAAe;AAAA,IACzE,WAAW,UAAU,IAAI,GAAG;AAE1B,UAAI;AACJ,UAAI,OAAO,KAAK,YAAY,UAAU;AACpC,cAAM,MAAM,IAAI,IAAI,KAAK,OAAO;AAChC,oBAAY;AAAA,UACV;AAAA,YACE,MAAM,IAAI;AAAA,YACV,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;AAAA,YACxB,SAAS;AAAA,cACP,QAAQ;AAAA,cACR,KAAK;AAAA,gBACH,MAAM,IAAI,SAAS,MAAM,GAAG,EAAE,MAAM,CAAC;AAAA,cACvC;AAAA,YACF;AAAA,UACF;AAAA,UACA;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,OAAO,KAAK,QAAQ;AAC1B,oBAAY;AAAA,UACV;AAAA,YACE,MAAM,KAAK;AAAA,YACX,SAAS,EAAE,GAAG,KAAK,SAAS,KAAK;AAAA,YACjC,UAAU,KAAK;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,IAAI,MAAM,CAAC;AAC3B,aAAO,OAAO,MAAM,UAAU,IAAI,GAAG;AAAA,QACnC,CAAC,UAAU,MAAM,GAAG;AAAA,UAClB,MAAM,WAAW,SAAS,aAAa;AAAA,UACvC,GAAG,UAAU;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,eAAe,OAA8B;AACpD,MAAI,CAAC,MAAM,KAAK;AACd,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACA,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX,aAAa,kBAAkB,MAAM,WAAW;AAAA,EAClD;AACF;AACA,SAAS,YAAY,OAAkC;AACrD,MAAI,CAAC,MAAM,KAAK;AACd,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACA,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX,aAAa,kBAAkB,MAAM,WAAW;AAAA,EAClD;AACF;AACA,SAAS,UAAU,KAAmB;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,MACL,MAAM,IAAI,MAAM,GAAG,EAAE,MAAM,CAAC;AAAA,MAC5B,OAAO,CAAC;AAAA,MACR,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AACA,MAAI,OAAO,IAAI,SAAS,UAAU;AAChC,WAAO;AAAA,MACL,MAAM,IAAI,KAAK,MAAM,GAAG,EAAE,MAAM,CAAC;AAAA,MACjC,QAAQ,IAAI,SAAS,CAAC,GAAG,IAAI,WAAW;AAAA,MACxC,WAAW,IAAI,YAAY,CAAC,GAAG,IAAI,cAAc;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM;AAChC,UAAI,OAAO,MAAM,UAAU;AACzB,eAAO;AAAA,MACT;AACA,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C,CAAC;AAAA,IACD,QAAQ,IAAI,SAAS,CAAC,GAAG,IAAI,WAAW;AAAA,IACxC,WAAW,IAAI,YAAY,CAAC,GAAG,IAAI,cAAc;AAAA,EACnD;AACF;AAEA,SAAS,qBAAqB,QAAkB;AAC9C,MAAI,CAAC,QAAQ;AACX,WAAO,CAAC;AAAA,EACV;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,IAAI,MAAM,0BAA0B,MAAM,EAAE;AAAA,EACpD;AACA,SAAO,OAAO,IAAI,CAAC,MAAM;AACvB,QAAI,OAAO,MAAM,UAAU;AACzB,aAAO;AAAA,QACL,KAAK;AAAA,QACL,OAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAKA,SAAS,kBACP,MACA,iBACe;AACf,MAAI,CAAC,QAAQ,KAAK,SAAS,SAAU,QAAO;AAE5C,QAAM,cAAc,CAAC,QAAoC;AACvD,QAAI,CAAC,QAAQ,KAAK,SAAS,SAAU,QAAO;AAC5C,UAAM,WAAW,KAAK,KAAK,IAAI;AAC/B,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAC/C,WAAO,OAAO,OAAO,KAAK,KAAK,IAAI;AAAA,EACrC;AAEA,QAAM,WAAW,GAAG,KAAK,IAAI;AAE7B,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,UAAU;AACb,YAAM,MAAM,YAAY,KAAK,KAAK;AAClC,YAAM,MAAM,YAAY,IAAI,KAAK;AACjC,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa;AAAA,MACf;AACA;AAAA,IACF;AAAA,IACA,KAAK;AACH,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,aAAa;AAAA,MACf;AACA;AAAA,IACF,KAAK,UAAU;AACb,YAAM,QAAQ,YAAY,OAAO;AACjC,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,GAAI,QAAQ,EAAE,cAAc,MAAM,IAAI,CAAC;AAAA,MACzC;AACA;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,YAAM,WAAW,YAAY,YAAY,KAAK;AAC9C,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,aAAa;AAAA,QACb,OAAO;AAAA,UACL,CAAC,aAAa,uBAAuB,sBAAsB,QAAQ,GACjE;AAAA,YACE,kBACE,YAAY,SAAS,KAAK;AAAA,YAC5B,UACE,YAAY,UAAU,KAAK;AAAA,YAC7B,QAAQ,CAAC;AAAA,UACX;AAAA,QACJ;AAAA,MACF;AACA;AAAA,IACF;AAAA,IACA,KAAK;AACH,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,aAAa;AAAA,MACf;AACA;AAAA,IACF,KAAK;AACH,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa;AAAA,MACf;AACA;AAAA,IACF;AACE,sBAAgB,QAAQ,IAAI;AAAA,QAC1B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa,GAAG,KAAK,IAAI;AAAA,MAC3B;AAAA,EACJ;AAEA,SAAO;AACT;AAEA,SAAS,4BACP,MACA,iBACA;AACA,MAAI,CAAC,QAAQ,KAAK,SAAS,SAAU,QAAO,CAAC;AAE7C,QAAM,WAAW,GAAG,KAAK,IAAI;AAG7B,MAAI,gBAAgB,QAAQ,GAAG;AAC7B,WAAO,CAAC,EAAE,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;AAAA,EAC5B;AAEA,SAAO,CAAC;AACV;AAEA,SAAS,mBACP,MAIA,iBACA;AACA,QAAM,MAAM,UAAU,KAAK,QAAQ,GAAG;AACtC,QAAM,UAAU,MAAM,QAAQ,KAAK,QAAQ,MAAM,IAC7C,KAAK,QAAQ,SACZ,CAAC;AAEN,QAAM,aAAgC;AAAA,IACpC,GAAG,IAAI,MACJ,OAAO,CAAC,UAAU,CAAC,MAAM,QAAQ,EACjC,IAAI,CAAC,UAAU;AACd,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM,MAAM;AAAA,QACZ,UAAU;AAAA,QACV,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,UACN,GAAI,MAAM,SAAS,CAAC,MAAM,OAAO,MAAM,KAAK,CAAC,IACzC,EAAE,MAAM,SAAS,IACjB,MAAM,UAAU,UAAU,MAAM,UAAU,UACxC,EAAE,MAAM,UAAU,IAClB,EAAE,MAAM,SAAS;AAAA,QACzB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAEH,GAAG,IAAI,SAAS,IAAI,CAAC,UAAU;AAC7B,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM,MAAM;AAAA,QACZ,UAAU;AAAA,QACV,aAAa,MAAM;AAAA,QACnB,QAAQ;AAAA,UACN,GAAI,MAAM,SAAS,CAAC,MAAM,OAAO,MAAM,KAAK,CAAC,IACzC,EAAE,MAAM,SAAS,IACjB,MAAM,UAAU,UAAU,MAAM,UAAU,UACxC,EAAE,MAAM,UAAU,IAClB,EAAE,MAAM,SAAS;AAAA,QACzB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAED,GAAG,QACA;AAAA,MACC,CAAC,MACC,CAAC,EAAE,YACH,EAAE,IAAI,YAAY,MAAM,YACxB,EAAE,IAAI,YAAY,MAAM;AAAA,IAC5B,EACC,IAAI,CAAC,WAAW;AACf,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM,OAAO;AAAA,QACb,UAAU;AAAA,QACV,aAAa,kBAAkB,OAAO,WAAW;AAAA,QACjD,QAAQ;AAAA,UACN,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACL;AAGA,QAAM,kBAAkB,QAAQ;AAAA,IAC9B,CAAC,MAAM,EAAE,IAAI,YAAY,MAAM;AAAA,EACjC;AACA,QAAM,iBAAiB,QAAQ;AAAA,IAC7B,CAAC,MAAM,EAAE,IAAI,YAAY,MAAM;AAAA,EACjC;AACA,QAAM,CAAC,iBAAiB,IACtB,oBAAoB,KAChB,QAAQ,OAAO,iBAAiB,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IACrD,CAAC;AACP,QAAM,CAAC,gBAAgB,IACrB,mBAAmB,KACf,QAAQ,OAAO,gBAAgB,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IACpD,CAAC;AAEP,MAAI;AACJ,MAAI,KAAK,QAAQ,MAAM;AACrB,UAAM,WAAW,kBAAkB,KAAK,QAAQ,MAAM,eAAe;AACrE,QAAI,UAAU;AACZ,iBAAW,CAAC,EAAE,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,GAAG,QAAQ,aAAa,MAAM;AAAA,IAC1D,SAAS,KAAK,QAAQ,UAAU,OAAO,YAAY;AAAA,IACnD,WAAW;AAAA,MACT,SAAS,KAAK;AAAA,MACd,aAAa,kBAAkB,KAAK,QAAQ,WAAW;AAAA,MACvD;AAAA,MACA;AAAA,MACA,WACE,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,IACvC;AAAA,QACE,KAAK;AAAA,UACH,aAAa;AAAA,QACf;AAAA,MACF,IACA,KAAK,SAAS,OAAO,CAAC,KAAK,aAAa;AACtC,cAAMA,WAAU,qBAAqB,SAAS,MAAM;AACpD,cAAMC,kBAAiBD,SAAQ;AAAA,UAC7B,CAAC,MAAM,EAAE,IAAI,YAAY,MAAM;AAAA,QACjC;AACA,cAAM,CAACE,iBAAgB,IACrBD,oBAAmB,KACfD,SAAQ,OAAOC,eAAc,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IACjD,CAAC;AAEP,YAAI,cAAc,SAAS,OACvB,MAAMC,qBAAoB,kBAAkB,GAAG,OAC/C;AACJ,wBAAgB;AAEhB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,SAAS,QAAQ,GAAG,GAAG;AAAA,YACtB,aAAa,SAAS,OAClB,SAAS,OACT,gBAAgB,SAAS,IAAI;AAAA,YACjC,SAAS;AAAA,cACP,CAAC,WAAW,GAAG;AAAA,gBACb,QAAQ,aAAa,SAAS,IAAI;AAAA,cACpC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,GAAG,CAAC,CAAC;AAAA,MACX,aAAa,KAAK,QAAQ,OACtB;AAAA,QACE,oBAAoB;AAAA,QACpB,KAAK,QAAQ;AAAA,MACf,IACA;AAAA,IACN;AAAA,EACF;AACF;AAKA,SAAS,gBAAgB,OAAwC;AAC/D,MAAI,CAAC,MAAO,QAAO,EAAE,MAAM,SAAS;AAGpC,MAAI,CAAC,MAAM,OAAO,KAAK,CAAC,GAAG;AACzB,WAAO,EAAE,MAAM,SAAS;AAAA,EAC1B;AAGA,MAAI,UAAU,UAAU,UAAU,SAAS;AACzC,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AAGA,SAAO,EAAE,MAAM,SAAS;AAC1B;AAEA,SAAS,2BACP,aACA,MACmB;AACnB,MAAI,KAAK,SAAS,OAAO;AACvB,WAAO;AAAA,MACL,SAAS;AAAA,QACP,CAAC,WAAW,GAAG;AAAA,UACb,QAAQ,aAAa,KAAK,GAAG;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,KAAK,SAAS,cAAc;AACrC,UAAM,aAAkC,CAAC;AACzC,KAAC,KAAK,cAAc,CAAC,GAClB,OAAO,CAAC,UAAU,CAAC,MAAM,QAAQ,EACjC,QAAQ,CAAC,UAAU;AAClB,iBAAW,MAAM,GAAG,IAAI;AAAA,QACtB,MAAM;AAAA,QACN,aAAa,kBAAkB,MAAM,WAAW;AAAA,MAClD;AAAA,IACF,CAAC;AAEH,WAAO;AAAA,MACL,SAAS;AAAA,QACP,qCAAqC;AAAA,UACnC,QAAQ;AAAA,YACN,MAAM;AAAA,YACN;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,KAAK,SAAS,YAAY;AACnC,UAAM,aAAyC,CAAC;AAChD,KAAC,KAAK,YAAY,CAAC,GAChB,OAAO,CAAC,UAAU,CAAC,MAAM,QAAQ,EACjC,QAAQ,CAAC,UAAU;AAClB,UAAI,MAAM,SAAS,QAAQ;AACzB,mBAAW,MAAM,GAAG,IAAI;AAAA,UACtB,MAAM;AAAA,UACN,aAAa,kBAAkB,MAAM,WAAW;AAAA,QAClD;AAAA,MACF,WAAW,MAAM,SAAS,QAAQ;AAChC,mBAAW,MAAM,GAAG,IAAI;AAAA,UACtB,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,aAAa,kBAAkB,MAAM,WAAW;AAAA,QAClD;AAAA,MACF;AAAA,IACF,CAAC;AAEH,WAAO;AAAA,MACL,SAAS;AAAA,QACP,uBAAuB;AAAA,UACrB,QAAQ;AAAA,YACN,MAAM;AAAA,YACN;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,kCAAkC,KAAK,IAAI;AAAA,EAC7C;AACF;AAEA,SAAS,aAAa,YAAsD;AAC1E,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,WAAW,UAAU,MAAM,CAAC;AAAA,EAChD,SAAS,OAAO;AACd,YAAQ;AAAA,MACN,8BAA8B,UAAU;AAAA,MACxC;AAAA,IACF;AACA,WAAO,EAAE,MAAM,UAAU,SAAS,WAAW;AAAA,EAC/C;AAEA,SAAO,SAAS,IAAI;AACtB;AAEA,SAAS,SAAS,MAAgC;AAChD,QAAM,UAAkC;AAAA,IACtC,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,SAAS,KAAK,CAAC,CAAC;AAAA,IACzB;AAAA,EACF;AACA,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,UAAM,aAAsC,CAAC;AAC7C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,iBAAW,GAAG,IAAI,SAAS,KAAK;AAAA,IAClC;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,MACL,MAAM,QAAQ,IAAI,KAAK;AAAA,IACzB;AAAA,EACF;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AACA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AACA,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AACA,UAAQ,KAAK,0BAA0B,IAAI,2BAA2B,IAAI;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEO,SAAS,wBACd,YACe;AACf,QAAM,OAAoB,CAAC;AAC3B,QAAM,QAAqB,CAAC;AAC5B,QAAM,kBAAwD,CAAC;AAE/D,MAAI,WAAW,MAAM;AACnB,sBAAkB,WAAW,MAAM,eAAe;AAAA,EACpD;AACA,eAAa,WAAW,MAAM,CAAC,GAAG,MAAM,OAAO,eAAe;AAC9D,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,OAAO,WAAW,KAAK;AAAA,MACvB,SAAS;AAAA,MACT,aAAa,kBAAkB,WAAW,KAAK,WAAW;AAAA,IAC5D;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,UAAU,WAAW,OACjB,4BAA4B,WAAW,MAAM,eAAe,IAC5D;AAAA,IACJ,YACE,OAAO,KAAK,eAAe,EAAE,SAAS,IAClC;AAAA,MACE;AAAA,IACF,IACA;AAAA,EACR;AACF;",
4
+ "sourcesContent": ["import { parse } from 'fast-content-type-parse';\nimport type {\n ContentObject,\n OpenAPIObject,\n OperationObject,\n ParameterObject,\n PathsObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n SecuritySchemeObject,\n TagObject,\n} from 'openapi3-ts/oas31';\n\nimport type {\n Auth,\n Description,\n Folder,\n Header,\n Headers,\n Item,\n Items,\n PostmanCollection,\n PostmanRequest,\n QueryParam,\n Request,\n RequestBody,\n Url,\n Variable,\n} from './spec-types';\n\nfunction descriptionToText(description?: Description) {\n if (!description) {\n return undefined;\n }\n if (typeof description === 'string') {\n return description;\n }\n if (description.content) {\n return description.content;\n }\n return undefined;\n}\n\ntype OurQueryParam = Omit<QueryParam, 'key'> & {\n key: string;\n description?: string;\n};\ntype OurVariable = Omit<QueryParam, 'key'> & {\n key: string;\n description?: string;\n};\ntype OurUrl = {\n path: string[];\n query: OurQueryParam[];\n variable: OurVariable[];\n};\n\nfunction isFolder(item: Items): item is Folder & { name: string } {\n return 'item' in item;\n}\n\nfunction isRequest(\n item: Items,\n): item is Item & { name: string; request: Request } {\n return !!item.request;\n}\n\n/**\n * Recursively processes items and folders in a Postman collection\n * @param items Array of Postman items (requests or folders)\n * @param parentTags Array of parent folder tags for proper nesting\n */\nfunction processItems(\n items: Items[],\n parentTags: string[],\n globalTags: TagObject[],\n paths: PathsObject,\n securitySchemes: Record<string, SecuritySchemeObject>,\n) {\n for (const item of items) {\n if (!isFolder(item) && !isRequest(item)) {\n console.warn(\n `Skipping item ${item.name} because it is not a folder or request`,\n );\n continue;\n }\n\n if (isFolder(item)) {\n // Process folder-level auth if it exists\n if (item.auth) {\n processAuthScheme(item.auth, securitySchemes);\n }\n\n // Add this folder as a tag if not already added\n if (!globalTags.some((tag) => tag.name === item.name)) {\n globalTags.push({\n name: item.name,\n description: descriptionToText(item.description),\n });\n }\n\n const currentTags = [...parentTags, item.name];\n processItems(item.item, currentTags, globalTags, paths, securitySchemes);\n } else if (isRequest(item)) {\n // Process this request\n let operation: ReturnType<typeof requestToOperation>;\n if (typeof item.request === 'string') {\n const url = new URL(item.request);\n operation = requestToOperation(\n {\n name: url.pathname,\n response: [{ code: 200 }],\n request: {\n method: 'get',\n url: {\n path: url.pathname.split('/').slice(1),\n },\n },\n },\n securitySchemes,\n );\n } else {\n const auth = item.request.auth;\n operation = requestToOperation(\n {\n name: item.name,\n request: { ...item.request, auth },\n response: item.response,\n },\n securitySchemes,\n );\n }\n\n paths[operation.path] ??= {};\n Object.assign(paths[operation.path], {\n [operation.method]: {\n tags: parentTags.length ? parentTags : undefined,\n ...operation.operation,\n },\n });\n }\n }\n}\n\nfunction coerceVariable(query: Variable): OurVariable {\n if (!query.key) {\n throw new Error('Invalid query parameter format');\n }\n return {\n key: query.key,\n description: descriptionToText(query.description),\n };\n}\nfunction coerceQuery(query: QueryParam): OurQueryParam {\n if (!query.key) {\n throw new Error('Invalid query parameter format');\n }\n return {\n key: query.key,\n description: descriptionToText(query.description),\n };\n}\nfunction coerceUrl(url?: Url): OurUrl {\n if (!url) {\n throw new Error('Invalid URL format');\n }\n if (typeof url === 'string') {\n return {\n path: url.split('/').slice(1),\n query: [],\n variable: [],\n };\n }\n if (typeof url.path === 'string') {\n return {\n path: url.path.split('/').slice(1),\n query: (url.query ?? []).map(coerceQuery),\n variable: (url.variable ?? []).map(coerceVariable),\n };\n }\n return {\n path: (url.path ?? []).map((p) => {\n if (typeof p === 'string') {\n return p;\n }\n throw new Error('Invalid URL path format');\n }),\n query: (url.query ?? []).map(coerceQuery),\n variable: (url.variable ?? []).map(coerceVariable),\n };\n}\n\nfunction coerceResponseHeader(header?: Headers) {\n if (!header) {\n return [];\n }\n if (typeof header === 'string') {\n throw new Error(`Invalid header format: ${header}`);\n }\n return header.map((h) => {\n if (typeof h === 'string') {\n return {\n key: h,\n value: null,\n };\n }\n return h;\n });\n}\n\n/**\n * Process an auth scheme and add it to securitySchemes\n */\nfunction processAuthScheme(\n auth: Auth,\n securitySchemes: Record<string, SecuritySchemeObject>,\n): string | null {\n if (!auth || auth.type === 'noauth') return null;\n\n const getAuthAttr = (key: string): string | undefined => {\n if (!auth || auth.type === 'noauth') return undefined;\n const authType = auth[auth.type];\n if (!authType) return undefined;\n const attr = authType.find((a) => a.key === key);\n return attr ? String(attr.value) : undefined;\n };\n\n const schemeId = `${auth.type}Auth`;\n\n switch (auth.type) {\n case 'apikey': {\n const key = getAuthAttr('key') || 'api_key';\n const in_ = getAuthAttr('in') || 'header';\n securitySchemes[schemeId] = {\n type: 'apiKey',\n name: key,\n in: in_ as 'header' | 'query' | 'cookie',\n description: 'API key authentication',\n };\n break;\n }\n case 'basic':\n securitySchemes[schemeId] = {\n type: 'http',\n scheme: 'basic',\n description: 'Basic HTTP authentication',\n };\n break;\n case 'bearer': {\n const token = getAuthAttr('token');\n securitySchemes[schemeId] = {\n type: 'http',\n scheme: 'bearer',\n description: 'Bearer token authentication',\n ...(token ? { bearerFormat: 'JWT' } : {}),\n };\n break;\n }\n case 'oauth2': {\n const flowType = getAuthAttr('grant_type') || 'implicit';\n securitySchemes[schemeId] = {\n type: 'oauth2',\n description: 'OAuth 2.0 authentication',\n flows: {\n [flowType === 'authorization_code' ? 'authorizationCode' : flowType]:\n {\n authorizationUrl:\n getAuthAttr('authUrl') || 'https://example.com/oauth/authorize',\n tokenUrl:\n getAuthAttr('tokenUrl') || 'https://example.com/oauth/token',\n scopes: {},\n },\n },\n };\n break;\n }\n case 'digest':\n securitySchemes[schemeId] = {\n type: 'http',\n scheme: 'digest',\n description: 'Digest authentication',\n };\n break;\n case 'awsv4':\n securitySchemes[schemeId] = {\n type: 'apiKey',\n name: 'Authorization',\n in: 'header',\n description: 'AWS Signature v4 authentication',\n };\n break;\n default:\n securitySchemes[schemeId] = {\n type: 'apiKey',\n name: 'Authorization',\n in: 'header',\n description: `${auth.type} authentication`,\n };\n }\n\n return schemeId;\n}\n\nfunction generateSecurityRequirement(\n auth: Auth,\n securitySchemes: Record<string, SecuritySchemeObject>,\n) {\n if (!auth || auth.type === 'noauth') return [];\n\n const schemeId = `${auth.type}Auth`;\n\n // Only include if the scheme was successfully processed\n if (securitySchemes[schemeId]) {\n return [{ [schemeId]: [] }];\n }\n\n return [];\n}\n\nfunction requestToOperation(\n item: Exclude<Item, 'name' | 'request'> & {\n name: string;\n request: PostmanRequest;\n },\n securitySchemes: Record<string, SecuritySchemeObject>,\n) {\n const url = coerceUrl(item.request.url);\n const headers = Array.isArray(item.request.header)\n ? item.request.header\n : ([] as Header[]);\n\n const parameters: ParameterObject[] = [\n ...url.query\n .filter((param) => !param.disabled)\n .map((param) => {\n return {\n in: 'query',\n name: param.key,\n required: false,\n description: param.description,\n schema: {\n ...(param.value && !isNaN(Number(param.value))\n ? { type: 'number' }\n : param.value === 'true' || param.value === 'false'\n ? { type: 'boolean' }\n : { type: 'string' }),\n },\n } satisfies ParameterObject;\n }),\n\n ...url.variable.map((param) => {\n return {\n in: 'path',\n name: param.key,\n required: true,\n description: param.description,\n schema: {\n ...(param.value && !isNaN(Number(param.value))\n ? { type: 'number' }\n : param.value === 'true' || param.value === 'false'\n ? { type: 'boolean' }\n : { type: 'string' }),\n },\n } satisfies ParameterObject;\n }),\n\n ...headers\n .filter(\n (h) =>\n !h.disabled &&\n h.key.toLowerCase() !== 'accept' &&\n h.key.toLowerCase() !== 'content-type',\n )\n .map((header) => {\n return {\n in: 'header',\n name: header.key,\n required: false,\n description: descriptionToText(header.description),\n schema: {\n type: 'string',\n },\n } satisfies ParameterObject;\n }),\n ];\n\n // Extract Accept and Content-Type headers\n const acceptHeaderIdx = headers.findIndex(\n (h) => h.key.toLowerCase() === 'accept',\n );\n const contentTypeIdx = headers.findIndex(\n (h) => h.key.toLowerCase() === 'content-type',\n );\n if (acceptHeaderIdx !== -1) headers.splice(acceptHeaderIdx, 1);\n const [contentTypeValue] =\n contentTypeIdx !== -1\n ? headers.splice(contentTypeIdx, 1).map((h) => h.value)\n : [];\n\n let security;\n if (item.request.auth) {\n const schemeId = processAuthScheme(item.request.auth, securitySchemes);\n if (schemeId) {\n security = [{ [schemeId]: [] }];\n }\n }\n\n return {\n path: `/${url.path.join('/')}`.replace(/:([^/]+)/g, '{$1}'),\n method: (item.request.method ?? 'get').toLowerCase(),\n operation: {\n summary: item.name,\n description: descriptionToText(item.request.description),\n parameters,\n security,\n responses:\n !item.response || item.response.length === 0\n ? {\n 200: {\n description: 'Successful response',\n },\n }\n : item.response.reduce((acc, response) => {\n const headers = coerceResponseHeader(response.header);\n const contentTypeIdx = headers.findIndex(\n (h) => h.key.toLowerCase() === 'content-type',\n );\n const [contentTypeValue] =\n contentTypeIdx !== -1\n ? headers.splice(contentTypeIdx).map((h) => h.value)\n : [];\n\n let contentType = response.body\n ? parse(contentTypeValue || 'application/json')?.type\n : null;\n contentType ??= 'application/octet-stream';\n\n return {\n ...acc,\n [response.code ?? 200]: {\n description: response.name\n ? response.name\n : `Response for ${response.code}`,\n content: {\n [contentType]: {\n schema: bodyToSchema(response.body),\n },\n },\n } satisfies ResponseObject,\n };\n }, {}),\n requestBody: item.request.body\n ? requestBodyToOperationBody(\n contentTypeValue || 'application/json',\n item.request.body,\n )\n : undefined,\n } satisfies OperationObject,\n };\n}\n\nfunction requestBodyToOperationBody(\n contentType: string,\n body: RequestBody,\n): RequestBodyObject {\n if (body.mode === 'raw') {\n return {\n content: {\n [contentType]: {\n schema: bodyToSchema(body.raw),\n },\n },\n };\n } else if (body.mode === 'urlencoded') {\n const properties: Record<string, any> = {};\n (body.urlencoded || [])\n .filter((param) => !param.disabled)\n .forEach((param) => {\n properties[param.key] = {\n type: 'string',\n description: descriptionToText(param.description),\n };\n });\n\n return {\n content: {\n 'application/x-www-form-urlencoded': {\n schema: {\n type: 'object',\n properties,\n },\n },\n } satisfies ContentObject,\n };\n } else if (body.mode === 'formdata') {\n const properties: SchemaObject['properties'] = {};\n (body.formdata || [])\n .filter((param) => !param.disabled)\n .forEach((param) => {\n if (param.type === 'text') {\n properties[param.key] = {\n type: 'string',\n description: descriptionToText(param.description),\n };\n } else if (param.type === 'file') {\n properties[param.key] = {\n type: 'string',\n format: 'binary',\n description: descriptionToText(param.description),\n };\n }\n });\n\n return {\n content: {\n 'multipart/form-data': {\n schema: {\n type: 'object',\n properties,\n },\n },\n } satisfies ContentObject,\n };\n }\n\n throw new Error(\n `Unsupported request body mode: ${body.mode}. Supported modes are: raw, urlencoded, formdata`,\n );\n}\n\nfunction bodyToSchema(bodyString?: string | null): SchemaObject | undefined {\n if (!bodyString) {\n return undefined;\n }\n\n let body: unknown;\n try {\n body = JSON.parse(bodyString.normalize('NFKD'));\n } catch (error) {\n console.warn(\n `Failed to parse JSON body: ${bodyString}. Treating as plain string.`,\n error,\n );\n return { type: 'string', example: bodyString };\n }\n\n return toSchema(body);\n}\n\nfunction toSchema(body: unknown | unknown[]): any {\n const typeMap: Record<string, string> = {\n '<number>': 'number',\n '<string>': 'string',\n '<boolean>': 'boolean',\n false: 'boolean',\n true: 'boolean',\n };\n if (Array.isArray(body)) {\n return {\n type: 'array',\n items: toSchema(body[0]),\n };\n }\n if (typeof body === 'object' && body !== null) {\n const properties: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(body)) {\n properties[key] = toSchema(value);\n }\n return {\n type: 'object',\n properties,\n };\n }\n if (typeof body === 'string') {\n return {\n type: typeMap[body] ?? 'string',\n };\n }\n if (typeof body === 'number') {\n return {\n type: 'number',\n };\n }\n if (typeof body === 'boolean') {\n return {\n type: 'boolean',\n };\n }\n if (body === null) {\n return {\n type: 'null',\n };\n }\n console.warn(`Unknown type for body: ${body}. Defaulting to string.`, body);\n return {\n type: 'string',\n };\n}\n\nexport function convertPostmanToOpenAPI(\n collection: PostmanCollection,\n): OpenAPIObject {\n const tags: TagObject[] = [];\n const paths: PathsObject = {};\n const securitySchemes: Record<string, SecuritySchemeObject> = {};\n\n if (collection.auth) {\n processAuthScheme(collection.auth, securitySchemes);\n }\n processItems(collection.item, [], tags, paths, securitySchemes);\n return {\n openapi: '3.1.0',\n info: {\n title: collection.info.name,\n version: '1.0.0',\n description: descriptionToText(collection.info.description),\n },\n tags,\n paths,\n // Only add security at top level if there's collection auth\n security: collection.auth\n ? generateSecurityRequirement(collection.auth, securitySchemes)\n : undefined,\n components:\n Object.keys(securitySchemes).length > 0\n ? {\n securitySchemes,\n }\n : undefined,\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["headers", "contentTypeIdx", "contentTypeValue"]
7
7
  }
@@ -1,10 +1,15 @@
1
- import type { OpenAPIObject, OperationObject, SecuritySchemeObject } from 'openapi3-ts/oas31';
1
+ import type { OpenAPIObject, OperationObject } from 'openapi3-ts/oas31';
2
+ import type { ProcessingDiagnostic, ProcessingPlugin } from './processing.js';
3
+ import type { IR } from './types.js';
2
4
  export interface GenerateSdkConfig {
3
5
  spec: OpenAPIObject;
4
6
  responses?: ResponsesConfig;
5
7
  pagination?: PaginationConfig | false;
6
8
  operationId?: (operation: OperationObject, path: string, method: string) => string;
7
9
  tag?: (operation: OperationObject, path: string) => string;
10
+ plugins?: readonly ProcessingPlugin[];
11
+ signal?: AbortSignal;
12
+ onDiagnostic?: (diagnostic: ProcessingDiagnostic) => void;
8
13
  }
9
14
  export interface ResponsesConfig {
10
15
  flattenErrorResponses?: boolean;
@@ -20,50 +25,7 @@ export declare function coeraceConfig(config: GenerateSdkConfig): {
20
25
  enabled: boolean;
21
26
  };
22
27
  responses: ResponsesConfig;
23
- spec: {
24
- components: {
25
- schemas: {
26
- [schema: string]: import("openapi3-ts/oas31").SchemaObject | import("openapi3-ts/oas31").ReferenceObject;
27
- };
28
- securitySchemes: {
29
- [k: string]: SecuritySchemeObject;
30
- };
31
- responses?: {
32
- [response: string]: import("openapi3-ts/oas31").ResponseObject | import("openapi3-ts/oas31").ReferenceObject;
33
- };
34
- parameters?: {
35
- [parameter: string]: import("openapi3-ts/oas31").ParameterObject | import("openapi3-ts/oas31").ReferenceObject;
36
- };
37
- examples?: {
38
- [example: string]: import("openapi3-ts/oas31").ExampleObject | import("openapi3-ts/oas31").ReferenceObject;
39
- };
40
- requestBodies?: {
41
- [request: string]: import("openapi3-ts/oas31").RequestBodyObject | import("openapi3-ts/oas31").ReferenceObject;
42
- };
43
- headers?: {
44
- [header: string]: import("openapi3-ts/oas31").HeaderObject | import("openapi3-ts/oas31").ReferenceObject;
45
- };
46
- links?: {
47
- [link: string]: import("openapi3-ts/oas31").LinkObject | import("openapi3-ts/oas31").ReferenceObject;
48
- };
49
- callbacks?: {
50
- [callback: string]: import("openapi3-ts/oas31").CallbackObject | import("openapi3-ts/oas31").ReferenceObject;
51
- };
52
- pathItems?: {
53
- [pathItem: string]: import("openapi3-ts/oas31").PathItemObject | import("openapi3-ts/oas31").ReferenceObject;
54
- };
55
- };
56
- paths: import("openapi3-ts/oas31").PathsObject;
57
- 'x-docs': never[];
58
- 'x-tagGroups': any;
59
- servers: import("openapi3-ts/oas31").ServerObject[];
60
- tags: import("openapi3-ts/oas31").TagObject[];
61
- openapi: string;
62
- info: import("openapi3-ts/oas31").InfoObject;
63
- security?: import("openapi3-ts/oas31").SecurityRequirementObject[];
64
- externalDocs?: import("openapi3-ts/oas31").ExternalDocumentationObject;
65
- webhooks?: import("openapi3-ts/oas31").PathsObject;
66
- };
28
+ spec: IR;
67
29
  operationId: (operation: OperationObject, path: string, method: string) => string;
68
30
  tag: (operation: OperationObject, path: string) => string;
69
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAO3B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;IACtC,WAAW,CAAC,EAAE,CACZ,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,KACX,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC5D;AACD,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAIF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,UAEnD;AAED,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/C,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,KAAK,CAAC,CAkBxD,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAzCxC,eAAe,QACpB,MAAM,UACJ,MAAM,KACX,MAAM;qBACO,eAAe,QAAQ,MAAM,KAAK,MAAM;EAqE3D;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,KAAK;;;EAmB9C"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/lib/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;IACtC,WAAW,CAAC,EAAE,CACZ,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,KACX,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,OAAO,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC3D;AACD,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AACF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,UAEnD;AAED,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/C,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,KAAK,CAAC,CAkBxD,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB;;;;;;;6BAzCxC,eAAe,QACpB,MAAM,UACJ,MAAM,KACX,MAAM;qBACO,eAAe,QAAQ,MAAM,KAAK,MAAM;EAuE3D;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,KAAK;;;EAmB9C"}
@@ -1,8 +1,5 @@
1
1
  import { camelcase, resolveRef } from "@sdk-it/core";
2
2
  import { determineGenericTag, sanitizeTag } from "./tag.js";
3
- function removeHyphensBeforeDigits(text) {
4
- return text.replace(/-(?=\d)/g, "");
5
- }
6
3
  function cleanOperationId(operationId) {
7
4
  return camelcase(operationId.split("#").pop());
8
5
  }
@@ -20,34 +17,35 @@ const defaults = {
20
17
  }
21
18
  };
22
19
  function coeraceConfig(config) {
20
+ const spec = {
21
+ ...config.spec,
22
+ components: {
23
+ ...config.spec.components,
24
+ schemas: config.spec.components?.schemas ?? {},
25
+ securitySchemes: Object.fromEntries(
26
+ Object.entries(config.spec.components?.securitySchemes ?? {}).map(
27
+ ([name, schema]) => [
28
+ name,
29
+ resolveRef(config.spec, schema)
30
+ ]
31
+ )
32
+ )
33
+ },
34
+ paths: config.spec.paths ?? {},
35
+ "x-docs": [],
36
+ "x-tagGroups": config.spec["x-tagGroups"] ?? [
37
+ {
38
+ name: "API",
39
+ tags: config.spec.tags?.map((tag) => tag.name) ?? []
40
+ }
41
+ ],
42
+ servers: config.spec.servers ?? [],
43
+ tags: config.spec.tags ?? []
44
+ };
23
45
  return {
24
46
  pagination: coercePaginationConfig(config.pagination),
25
47
  responses: config.responses ?? {},
26
- spec: {
27
- ...config.spec,
28
- components: {
29
- ...config.spec.components,
30
- schemas: config.spec.components?.schemas ?? {},
31
- securitySchemes: Object.fromEntries(
32
- Object.entries(config.spec.components?.securitySchemes ?? {}).map(
33
- ([name, schema]) => [
34
- name,
35
- resolveRef(config.spec, schema)
36
- ]
37
- )
38
- )
39
- },
40
- paths: config.spec.paths ?? {},
41
- "x-docs": [],
42
- "x-tagGroups": config.spec["x-tagGroups"] ?? [
43
- {
44
- name: "API",
45
- tags: config.spec.tags?.map((tag) => tag.name) ?? []
46
- }
47
- ],
48
- servers: config.spec.servers ?? [],
49
- tags: config.spec.tags ?? []
50
- },
48
+ spec,
51
49
  operationId: config.operationId ?? defaults.operationId,
52
50
  tag: config.tag ?? defaults.tag
53
51
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/options.ts"],
4
- "sourcesContent": ["import type {\n OpenAPIObject,\n OperationObject,\n SecuritySchemeObject,\n} from 'openapi3-ts/oas31';\n\nimport { camelcase, resolveRef } from '@sdk-it/core';\n\nimport { determineGenericTag, sanitizeTag } from './tag.js';\nimport type { IR } from './types.js';\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n responses?: ResponsesConfig;\n pagination?: PaginationConfig | false;\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n tag?: (operation: OperationObject, path: string) => string;\n}\nexport interface ResponsesConfig {\n flattenErrorResponses?: boolean;\n}\n\nexport type PaginationConfig = {\n guess?: boolean;\n};\nfunction removeHyphensBeforeDigits(text: string): string {\n return text.replace(/-(?=\\d)/g, '');\n}\nexport function cleanOperationId(operationId: string) {\n return camelcase(operationId.split('#').pop()!);\n}\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>> = {\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return cleanOperationId(operation.operationId);\n }\n\n return camelcase(\n [method, ...path.replace(/[\\\\/\\\\{\\\\}]/g, ' ').split(' ')]\n .filter(Boolean)\n .join(' ')\n .trim(),\n );\n },\n tag: (operation, path) => {\n return operation.tags?.[0]\n ? sanitizeTag(operation.tags?.[0])\n : determineGenericTag(path, operation);\n },\n};\n\nexport function coeraceConfig(config: GenerateSdkConfig) {\n return {\n pagination: coercePaginationConfig(config.pagination),\n responses: config.responses ?? {},\n spec: {\n ...config.spec,\n components: {\n ...config.spec.components,\n schemas: config.spec.components?.schemas ?? {},\n securitySchemes: Object.fromEntries(\n Object.entries(config.spec.components?.securitySchemes ?? {}).map(\n ([name, schema]) => [\n name,\n resolveRef<SecuritySchemeObject>(config.spec, schema),\n ],\n ),\n ),\n },\n paths: config.spec.paths ?? {},\n 'x-docs': [],\n 'x-tagGroups': config.spec['x-tagGroups'] ?? [\n {\n name: 'API',\n tags: config.spec.tags?.map((tag) => tag.name) ?? [],\n },\n ],\n servers: config.spec.servers ?? [],\n tags: config.spec.tags ?? [],\n } satisfies IR,\n operationId: config.operationId ?? defaults.operationId,\n tag: config.tag ?? defaults.tag,\n };\n}\n\nexport function coercePaginationConfig(\n options: PaginationConfig | undefined | false,\n) {\n if (options === undefined) {\n return {\n guess: true,\n enabled: true,\n };\n }\n if (options === false) {\n return {\n enabled: false,\n guess: false,\n };\n }\n // If options is true, we assume pagination is enabled with guessing\n return {\n guess: options.guess ?? true,\n enabled: true,\n };\n}\n"],
5
- "mappings": "AAMA,SAAS,WAAW,kBAAkB;AAEtC,SAAS,qBAAqB,mBAAmB;AAqBjD,SAAS,0BAA0B,MAAsB;AACvD,SAAO,KAAK,QAAQ,YAAY,EAAE;AACpC;AACO,SAAS,iBAAiB,aAAqB;AACpD,SAAO,UAAU,YAAY,MAAM,GAAG,EAAE,IAAI,CAAE;AAChD;AAEO,MAAM,WACgD;AAAA,EAC3D,aAAa,CAAC,WAAW,MAAM,WAAW;AACxC,QAAI,UAAU,aAAa;AACzB,aAAO,iBAAiB,UAAU,WAAW;AAAA,IAC/C;AAEA,WAAO;AAAA,MACL,CAAC,QAAQ,GAAG,KAAK,QAAQ,gBAAgB,GAAG,EAAE,MAAM,GAAG,CAAC,EACrD,OAAO,OAAO,EACd,KAAK,GAAG,EACR,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EACA,KAAK,CAAC,WAAW,SAAS;AACxB,WAAO,UAAU,OAAO,CAAC,IACrB,YAAY,UAAU,OAAO,CAAC,CAAC,IAC/B,oBAAoB,MAAM,SAAS;AAAA,EACzC;AACF;AAEO,SAAS,cAAc,QAA2B;AACvD,SAAO;AAAA,IACL,YAAY,uBAAuB,OAAO,UAAU;AAAA,IACpD,WAAW,OAAO,aAAa,CAAC;AAAA,IAChC,MAAM;AAAA,MACJ,GAAG,OAAO;AAAA,MACV,YAAY;AAAA,QACV,GAAG,OAAO,KAAK;AAAA,QACf,SAAS,OAAO,KAAK,YAAY,WAAW,CAAC;AAAA,QAC7C,iBAAiB,OAAO;AAAA,UACtB,OAAO,QAAQ,OAAO,KAAK,YAAY,mBAAmB,CAAC,CAAC,EAAE;AAAA,YAC5D,CAAC,CAAC,MAAM,MAAM,MAAM;AAAA,cAClB;AAAA,cACA,WAAiC,OAAO,MAAM,MAAM;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,OAAO,OAAO,KAAK,SAAS,CAAC;AAAA,MAC7B,UAAU,CAAC;AAAA,MACX,eAAe,OAAO,KAAK,aAAa,KAAK;AAAA,QAC3C;AAAA,UACE,MAAM;AAAA,UACN,MAAM,OAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,CAAC;AAAA,QACrD;AAAA,MACF;AAAA,MACA,SAAS,OAAO,KAAK,WAAW,CAAC;AAAA,MACjC,MAAM,OAAO,KAAK,QAAQ,CAAC;AAAA,IAC7B;AAAA,IACA,aAAa,OAAO,eAAe,SAAS;AAAA,IAC5C,KAAK,OAAO,OAAO,SAAS;AAAA,EAC9B;AACF;AAEO,SAAS,uBACd,SACA;AACA,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,YAAY,OAAO;AACrB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS;AAAA,IACxB,SAAS;AAAA,EACX;AACF;",
4
+ "sourcesContent": ["import type {\n OpenAPIObject,\n OperationObject,\n SecuritySchemeObject,\n} from 'openapi3-ts/oas31';\n\nimport { camelcase, resolveRef } from '@sdk-it/core';\n\nimport type { ProcessingDiagnostic, ProcessingPlugin } from './processing.js';\nimport { determineGenericTag, sanitizeTag } from './tag.js';\nimport type { IR } from './types.js';\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n responses?: ResponsesConfig;\n pagination?: PaginationConfig | false;\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n tag?: (operation: OperationObject, path: string) => string;\n plugins?: readonly ProcessingPlugin[];\n signal?: AbortSignal;\n onDiagnostic?: (diagnostic: ProcessingDiagnostic) => void;\n}\nexport interface ResponsesConfig {\n flattenErrorResponses?: boolean;\n}\n\nexport type PaginationConfig = {\n guess?: boolean;\n};\nexport function cleanOperationId(operationId: string) {\n return camelcase(operationId.split('#').pop()!);\n}\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>> = {\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return cleanOperationId(operation.operationId);\n }\n\n return camelcase(\n [method, ...path.replace(/[\\\\/\\\\{\\\\}]/g, ' ').split(' ')]\n .filter(Boolean)\n .join(' ')\n .trim(),\n );\n },\n tag: (operation, path) => {\n return operation.tags?.[0]\n ? sanitizeTag(operation.tags?.[0])\n : determineGenericTag(path, operation);\n },\n};\n\nexport function coeraceConfig(config: GenerateSdkConfig) {\n const spec: IR = {\n ...config.spec,\n components: {\n ...config.spec.components,\n schemas: config.spec.components?.schemas ?? {},\n securitySchemes: Object.fromEntries(\n Object.entries(config.spec.components?.securitySchemes ?? {}).map(\n ([name, schema]) => [\n name,\n resolveRef<SecuritySchemeObject>(config.spec, schema),\n ],\n ),\n ),\n },\n paths: config.spec.paths ?? {},\n 'x-docs': [],\n 'x-tagGroups': config.spec['x-tagGroups'] ?? [\n {\n name: 'API',\n tags: config.spec.tags?.map((tag) => tag.name) ?? [],\n },\n ],\n servers: config.spec.servers ?? [],\n tags: config.spec.tags ?? [],\n };\n\n return {\n pagination: coercePaginationConfig(config.pagination),\n responses: config.responses ?? {},\n spec,\n operationId: config.operationId ?? defaults.operationId,\n tag: config.tag ?? defaults.tag,\n };\n}\n\nexport function coercePaginationConfig(\n options: PaginationConfig | undefined | false,\n) {\n if (options === undefined) {\n return {\n guess: true,\n enabled: true,\n };\n }\n if (options === false) {\n return {\n enabled: false,\n guess: false,\n };\n }\n // If options is true, we assume pagination is enabled with guessing\n return {\n guess: options.guess ?? true,\n enabled: true,\n };\n}\n"],
5
+ "mappings": "AAMA,SAAS,WAAW,kBAAkB;AAGtC,SAAS,qBAAqB,mBAAmB;AAwB1C,SAAS,iBAAiB,aAAqB;AACpD,SAAO,UAAU,YAAY,MAAM,GAAG,EAAE,IAAI,CAAE;AAChD;AAEO,MAAM,WACgD;AAAA,EAC3D,aAAa,CAAC,WAAW,MAAM,WAAW;AACxC,QAAI,UAAU,aAAa;AACzB,aAAO,iBAAiB,UAAU,WAAW;AAAA,IAC/C;AAEA,WAAO;AAAA,MACL,CAAC,QAAQ,GAAG,KAAK,QAAQ,gBAAgB,GAAG,EAAE,MAAM,GAAG,CAAC,EACrD,OAAO,OAAO,EACd,KAAK,GAAG,EACR,KAAK;AAAA,IACV;AAAA,EACF;AAAA,EACA,KAAK,CAAC,WAAW,SAAS;AACxB,WAAO,UAAU,OAAO,CAAC,IACrB,YAAY,UAAU,OAAO,CAAC,CAAC,IAC/B,oBAAoB,MAAM,SAAS;AAAA,EACzC;AACF;AAEO,SAAS,cAAc,QAA2B;AACvD,QAAM,OAAW;AAAA,IACf,GAAG,OAAO;AAAA,IACV,YAAY;AAAA,MACV,GAAG,OAAO,KAAK;AAAA,MACf,SAAS,OAAO,KAAK,YAAY,WAAW,CAAC;AAAA,MAC7C,iBAAiB,OAAO;AAAA,QACtB,OAAO,QAAQ,OAAO,KAAK,YAAY,mBAAmB,CAAC,CAAC,EAAE;AAAA,UAC5D,CAAC,CAAC,MAAM,MAAM,MAAM;AAAA,YAClB;AAAA,YACA,WAAiC,OAAO,MAAM,MAAM;AAAA,UACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO,OAAO,KAAK,SAAS,CAAC;AAAA,IAC7B,UAAU,CAAC;AAAA,IACX,eAAe,OAAO,KAAK,aAAa,KAAK;AAAA,MAC3C;AAAA,QACE,MAAM;AAAA,QACN,MAAM,OAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,IACA,SAAS,OAAO,KAAK,WAAW,CAAC;AAAA,IACjC,MAAM,OAAO,KAAK,QAAQ,CAAC;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,YAAY,uBAAuB,OAAO,UAAU;AAAA,IACpD,WAAW,OAAO,aAAa,CAAC;AAAA,IAChC;AAAA,IACA,aAAa,OAAO,eAAe,SAAS;AAAA,IAC5C,KAAK,OAAO,OAAO,SAAS;AAAA,EAC9B;AACF;AAEO,SAAS,uBACd,SACA;AACA,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,YAAY,OAAO;AACrB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,QAAQ,SAAS;AAAA,IACxB,SAAS;AAAA,EACX;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
1
  import type { NavItem } from '../sidebar.js';
2
2
  import type { IR } from '../types.js';
3
- export declare function generatePaginationOverview(spec: IR): NavItem;
3
+ export declare function generatePaginationOverview(_spec: IR): NavItem;
4
4
  //# sourceMappingURL=overview-pagination.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overview-pagination.d.ts","sourceRoot":"","sources":["../../../src/lib/overview-docs/overview-pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEtC,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAoG5D"}
1
+ {"version":3,"file":"overview-pagination.d.ts","sourceRoot":"","sources":["../../../src/lib/overview-docs/overview-pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEtC,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,CAoG7D"}
@@ -1,4 +1,4 @@
1
- function generatePaginationOverview(spec) {
1
+ function generatePaginationOverview(_spec) {
2
2
  const markdown = [];
3
3
  markdown.push(`# Pagination`);
4
4
  markdown.push(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/overview-docs/overview-pagination.ts"],
4
- "sourcesContent": ["import type { NavItem } from '../sidebar.js';\nimport type { IR } from '../types.js';\n\nexport function generatePaginationOverview(spec: IR): NavItem {\n const markdown: string[] = [];\n\n markdown.push(`# Pagination`);\n markdown.push(\n `This API uses cursor-based pagination to efficiently navigate through large datasets.`,\n );\n\n markdown.push(`## How Pagination Works`);\n markdown.push(\n `When making requests to endpoints that return multiple items, you can control the number of results and navigate through pages using the following parameters:`,\n );\n markdown.push('');\n markdown.push(\n `- **limit** - The maximum number of items to return per page (default: 20, max: 100)`,\n );\n markdown.push(\n `- **cursor** - A token representing the position in the dataset to start from`,\n );\n markdown.push('');\n\n markdown.push(`## Example Usage`);\n markdown.push('');\n markdown.push('### TypeScript');\n markdown.push('```typescript');\n markdown.push('// First page');\n markdown.push('const firstPage = await client.items.list({');\n markdown.push(' limit: 25');\n markdown.push('});');\n markdown.push('');\n markdown.push('// Next page');\n markdown.push('if (firstPage.nextCursor) {');\n markdown.push(' const secondPage = await client.items.list({');\n markdown.push(' limit: 25,');\n markdown.push(' cursor: firstPage.nextCursor');\n markdown.push(' });');\n markdown.push('}');\n markdown.push('```');\n markdown.push('');\n\n markdown.push(`## Response Structure`);\n markdown.push(`Paginated responses follow this structure:`);\n markdown.push('');\n markdown.push('```json');\n markdown.push('{');\n markdown.push(' \"data\": [...], // Array of items');\n markdown.push(\n ' \"nextCursor\": \"eyJpZCI6MTAwfQ==\", // Token for next page (null if last page)',\n );\n markdown.push(' \"hasMore\": true, // Whether more pages exist');\n markdown.push(' \"totalCount\": 150 // Total number of items (if available)');\n markdown.push('}');\n markdown.push('```');\n markdown.push('');\n\n markdown.push(`## Iterating Through All Pages`);\n markdown.push('');\n markdown.push('### TypeScript');\n markdown.push('```typescript');\n markdown.push('async function getAllItems() {');\n markdown.push(' const allItems = [];');\n markdown.push(' let cursor = undefined;');\n markdown.push(' ');\n markdown.push(' do {');\n markdown.push(' const page = await client.items.list({');\n markdown.push(' limit: 100,');\n markdown.push(' cursor');\n markdown.push(' });');\n markdown.push(' ');\n markdown.push(' allItems.push(...page.data);');\n markdown.push(' cursor = page.nextCursor;');\n markdown.push(' } while (cursor);');\n markdown.push(' ');\n markdown.push(' return allItems;');\n markdown.push('}');\n markdown.push('```');\n markdown.push('');\n\n markdown.push(`## Best Practices`);\n markdown.push('');\n markdown.push(\n `1. **Use appropriate page sizes** - Balance between number of requests and response size`,\n );\n markdown.push(\n `2. **Handle cursors securely** - Don't modify cursor values; treat them as opaque tokens`,\n );\n markdown.push(\n `3. **Implement retry logic** - Handle temporary failures when iterating through pages`,\n );\n markdown.push(\n `4. **Consider rate limits** - Be mindful of API rate limits when fetching multiple pages`,\n );\n\n return {\n id: 'generated-pagination',\n title: 'Pagination',\n url: '/pagination',\n description: 'Learn how to navigate through paginated API responses',\n content: markdown.join('\\n'),\n };\n}\n"],
5
- "mappings": "AAGO,SAAS,2BAA2B,MAAmB;AAC5D,QAAM,WAAqB,CAAC;AAE5B,WAAS,KAAK,cAAc;AAC5B,WAAS;AAAA,IACP;AAAA,EACF;AAEA,WAAS,KAAK,yBAAyB;AACvC,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,EAAE;AAChB,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,kBAAkB;AAChC,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,gBAAgB;AAC9B,WAAS,KAAK,eAAe;AAC7B,WAAS,KAAK,eAAe;AAC7B,WAAS,KAAK,6CAA6C;AAC3D,WAAS,KAAK,aAAa;AAC3B,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,cAAc;AAC5B,WAAS,KAAK,6BAA6B;AAC3C,WAAS,KAAK,gDAAgD;AAC9D,WAAS,KAAK,gBAAgB;AAC9B,WAAS,KAAK,kCAAkC;AAChD,WAAS,KAAK,OAAO;AACrB,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,uBAAuB;AACrC,WAAS,KAAK,4CAA4C;AAC1D,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,SAAS;AACvB,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,oCAAoC;AAClD,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,gDAAgD;AAC9D,WAAS,KAAK,6DAA6D;AAC3E,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,gCAAgC;AAC9C,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,gBAAgB;AAC9B,WAAS,KAAK,eAAe;AAC7B,WAAS,KAAK,gCAAgC;AAC9C,WAAS,KAAK,wBAAwB;AACtC,WAAS,KAAK,2BAA2B;AACzC,WAAS,KAAK,IAAI;AAClB,WAAS,KAAK,QAAQ;AACtB,WAAS,KAAK,4CAA4C;AAC1D,WAAS,KAAK,mBAAmB;AACjC,WAAS,KAAK,cAAc;AAC5B,WAAS,KAAK,SAAS;AACvB,WAAS,KAAK,MAAM;AACpB,WAAS,KAAK,kCAAkC;AAChD,WAAS,KAAK,+BAA+B;AAC7C,WAAS,KAAK,qBAAqB;AACnC,WAAS,KAAK,IAAI;AAClB,WAAS,KAAK,oBAAoB;AAClC,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,mBAAmB;AACjC,WAAS,KAAK,EAAE;AAChB,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,IACb,SAAS,SAAS,KAAK,IAAI;AAAA,EAC7B;AACF;",
4
+ "sourcesContent": ["import type { NavItem } from '../sidebar.js';\nimport type { IR } from '../types.js';\n\nexport function generatePaginationOverview(_spec: IR): NavItem {\n const markdown: string[] = [];\n\n markdown.push(`# Pagination`);\n markdown.push(\n `This API uses cursor-based pagination to efficiently navigate through large datasets.`,\n );\n\n markdown.push(`## How Pagination Works`);\n markdown.push(\n `When making requests to endpoints that return multiple items, you can control the number of results and navigate through pages using the following parameters:`,\n );\n markdown.push('');\n markdown.push(\n `- **limit** - The maximum number of items to return per page (default: 20, max: 100)`,\n );\n markdown.push(\n `- **cursor** - A token representing the position in the dataset to start from`,\n );\n markdown.push('');\n\n markdown.push(`## Example Usage`);\n markdown.push('');\n markdown.push('### TypeScript');\n markdown.push('```typescript');\n markdown.push('// First page');\n markdown.push('const firstPage = await client.items.list({');\n markdown.push(' limit: 25');\n markdown.push('});');\n markdown.push('');\n markdown.push('// Next page');\n markdown.push('if (firstPage.nextCursor) {');\n markdown.push(' const secondPage = await client.items.list({');\n markdown.push(' limit: 25,');\n markdown.push(' cursor: firstPage.nextCursor');\n markdown.push(' });');\n markdown.push('}');\n markdown.push('```');\n markdown.push('');\n\n markdown.push(`## Response Structure`);\n markdown.push(`Paginated responses follow this structure:`);\n markdown.push('');\n markdown.push('```json');\n markdown.push('{');\n markdown.push(' \"data\": [...], // Array of items');\n markdown.push(\n ' \"nextCursor\": \"eyJpZCI6MTAwfQ==\", // Token for next page (null if last page)',\n );\n markdown.push(' \"hasMore\": true, // Whether more pages exist');\n markdown.push(' \"totalCount\": 150 // Total number of items (if available)');\n markdown.push('}');\n markdown.push('```');\n markdown.push('');\n\n markdown.push(`## Iterating Through All Pages`);\n markdown.push('');\n markdown.push('### TypeScript');\n markdown.push('```typescript');\n markdown.push('async function getAllItems() {');\n markdown.push(' const allItems = [];');\n markdown.push(' let cursor = undefined;');\n markdown.push(' ');\n markdown.push(' do {');\n markdown.push(' const page = await client.items.list({');\n markdown.push(' limit: 100,');\n markdown.push(' cursor');\n markdown.push(' });');\n markdown.push(' ');\n markdown.push(' allItems.push(...page.data);');\n markdown.push(' cursor = page.nextCursor;');\n markdown.push(' } while (cursor);');\n markdown.push(' ');\n markdown.push(' return allItems;');\n markdown.push('}');\n markdown.push('```');\n markdown.push('');\n\n markdown.push(`## Best Practices`);\n markdown.push('');\n markdown.push(\n `1. **Use appropriate page sizes** - Balance between number of requests and response size`,\n );\n markdown.push(\n `2. **Handle cursors securely** - Don't modify cursor values; treat them as opaque tokens`,\n );\n markdown.push(\n `3. **Implement retry logic** - Handle temporary failures when iterating through pages`,\n );\n markdown.push(\n `4. **Consider rate limits** - Be mindful of API rate limits when fetching multiple pages`,\n );\n\n return {\n id: 'generated-pagination',\n title: 'Pagination',\n url: '/pagination',\n description: 'Learn how to navigate through paginated API responses',\n content: markdown.join('\\n'),\n };\n}\n"],
5
+ "mappings": "AAGO,SAAS,2BAA2B,OAAoB;AAC7D,QAAM,WAAqB,CAAC;AAE5B,WAAS,KAAK,cAAc;AAC5B,WAAS;AAAA,IACP;AAAA,EACF;AAEA,WAAS,KAAK,yBAAyB;AACvC,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,EAAE;AAChB,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,kBAAkB;AAChC,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,gBAAgB;AAC9B,WAAS,KAAK,eAAe;AAC7B,WAAS,KAAK,eAAe;AAC7B,WAAS,KAAK,6CAA6C;AAC3D,WAAS,KAAK,aAAa;AAC3B,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,cAAc;AAC5B,WAAS,KAAK,6BAA6B;AAC3C,WAAS,KAAK,gDAAgD;AAC9D,WAAS,KAAK,gBAAgB;AAC9B,WAAS,KAAK,kCAAkC;AAChD,WAAS,KAAK,OAAO;AACrB,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,uBAAuB;AACrC,WAAS,KAAK,4CAA4C;AAC1D,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,SAAS;AACvB,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,oCAAoC;AAClD,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS,KAAK,gDAAgD;AAC9D,WAAS,KAAK,6DAA6D;AAC3E,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,gCAAgC;AAC9C,WAAS,KAAK,EAAE;AAChB,WAAS,KAAK,gBAAgB;AAC9B,WAAS,KAAK,eAAe;AAC7B,WAAS,KAAK,gCAAgC;AAC9C,WAAS,KAAK,wBAAwB;AACtC,WAAS,KAAK,2BAA2B;AACzC,WAAS,KAAK,IAAI;AAClB,WAAS,KAAK,QAAQ;AACtB,WAAS,KAAK,4CAA4C;AAC1D,WAAS,KAAK,mBAAmB;AACjC,WAAS,KAAK,cAAc;AAC5B,WAAS,KAAK,SAAS;AACvB,WAAS,KAAK,MAAM;AACpB,WAAS,KAAK,kCAAkC;AAChD,WAAS,KAAK,+BAA+B;AAC7C,WAAS,KAAK,qBAAqB;AACnC,WAAS,KAAK,IAAI;AAClB,WAAS,KAAK,oBAAoB;AAClC,WAAS,KAAK,GAAG;AACjB,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,EAAE;AAEhB,WAAS,KAAK,mBAAmB;AACjC,WAAS,KAAK,EAAE;AAChB,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AACA,WAAS;AAAA,IACP;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,IACb,SAAS,SAAS,KAAK,IAAI;AAAA,EAC7B;AACF;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"guess-pagination.d.ts","sourceRoot":"","sources":["../../../src/lib/pagination/guess-pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAM3B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,eAAe,GACvB,CAAC,CACG,sBAAsB,GACtB,oBAAoB,GACpB,sBAAsB,CACzB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACvC,kBAAkB,CAAC;AAIvB,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAKxC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,MAAM,EAU/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAMvC,CAAC;AAGF,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAUrC,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,MAAM,EAWlC,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAUxC,CAAC;AA+JF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,oBAAoB,EAC/B,IAAI,CAAC,EAAE,YAAY,EACnB,QAAQ,CAAC,EAAE,YAAY,GACtB,eAAe,CAqCjB"}
1
+ {"version":3,"file":"guess-pagination.d.ts","sourceRoot":"","sources":["../../../src/lib/pagination/guess-pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAM3B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,eAAe,GACvB,CAAC,CACC,sBAAsB,GAAG,oBAAoB,GAAG,sBAAsB,CACvE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACvC,kBAAkB,CAAC;AAIvB,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAKxC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,MAAM,EAU/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAMvC,CAAC;AAGF,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAUrC,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,MAAM,EAWlC,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAUxC,CAAC;AA+JF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,oBAAoB,EAC/B,IAAI,CAAC,EAAE,YAAY,EACnB,QAAQ,CAAC,EAAE,YAAY,GACtB,eAAe,CAqCjB"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/pagination/guess-pagination.ts"],
4
- "sourcesContent": ["import type {\n ReferenceObject,\n SchemaObject,\n SchemasObject,\n} from 'openapi3-ts/oas31';\n\nimport { isRef } from '@sdk-it/core/ref.js';\nimport { isEmpty } from '@sdk-it/core/utils.js';\n\nimport { coerceTypes } from '../tune.js';\nimport type { TunedOperationObject } from '../types.js';\nimport { getHasMoreName, getItemsName } from './pagination-result.js';\n\ninterface PaginationResultBase {\n type: 'offset' | 'page' | 'cursor' | 'none';\n}\n\nexport interface OffsetPaginationResult extends PaginationResultBase {\n type: 'offset';\n offsetParamName: string;\n offsetKeyword: string; // The actual part of param name that matched\n limitParamName: string;\n limitKeyword: string; // The actual part of param name that matched\n}\n\nexport interface PagePaginationResult extends PaginationResultBase {\n type: 'page';\n pageNumberParamName: string;\n pageNumberKeyword: string;\n pageSizeParamName: string;\n pageSizeKeyword: string;\n}\n\nexport interface CursorPaginationResult extends PaginationResultBase {\n type: 'cursor';\n cursorParamName: string;\n cursorKeyword: string;\n limitParamName: string;\n limitKeyword: string;\n}\n\nexport interface NoPaginationResult extends PaginationResultBase {\n type: 'none';\n reason: string;\n}\n\nexport type PaginationGuess =\n | ((\n | OffsetPaginationResult\n | PagePaginationResult\n | CursorPaginationResult\n ) & { items: string; hasMore: string })\n | NoPaginationResult;\n\n// --- Keyword Regex Definitions ---\n\nexport const OFFSET_PARAM_REGEXES: RegExp[] = [\n /\\boffset\\b/i,\n /\\bskip\\b/i,\n /\\bstart(?:ing_at|_index)?\\b/i, // e.g., start, starting_at, start_index\n /\\bfrom\\b/i,\n];\n\nexport const GENERIC_LIMIT_PARAM_REGEXES: RegExp[] = [\n /\\blimit\\b/i,\n /\\bcount\\b/i,\n /\\b(?:page_?)?size\\b/i, // e.g., size, page_size, pagesize\n /\\bmax_results\\b/i,\n /\\bnum_results\\b/i,\n /\\bshow\\b/i, // Can sometimes mean limit\n /\\bper_?page\\b/i, // e.g., per_page, perpage\n /\\bper-page\\b/i,\n /\\btake\\b/i,\n];\n\nexport const PAGE_NUMBER_REGEXES: RegExp[] = [\n // /^(currentPage)?page$/i, // Exact match for \"page\"\n // /^currentPage$/i, // Exact match for \"currentPage\"\n /^p$/i, // Exact match for \"p\" (common shorthand)\n // /\\bpage_?(?:number|no|num|idx|index)\\b/i, // e.g., page_number, pageNumber, page_num, page_idx\n /^(current)?_?page(_?)(?:number|no|num|idx|index)?\\b/i,\n];\n\n// Regexes for parameters indicating page size (when used with page number)\nexport const PAGE_SIZE_REGEXES: RegExp[] = [\n /\\bpage_?size\\b/i, // e.g., page_size, pagesize\n /^size$/i, // Exact \"size\"\n // /\\bsize\\b/i, // Broader \"size\" - can be ambiguous, prefer more specific ones first\n /\\blimit\\b/i, // Limit is often used for page size\n /\\bcount\\b/i, // Count can also be used for page size\n /\\bper_?page\\b/i, // e.g., per_page, perpage\n /\\bper-page\\b/i,\n /\\bnum_?(?:items|records|results)\\b/i, // e.g., num_items, numitems\n /\\bresults_?per_?page\\b/i,\n];\n\n// Regexes for parameters indicating a cursor\nexport const CURSOR_REGEXES: RegExp[] = [\n /\\bmarker\\b/i,\n /\\bcursor\\b/i,\n /\\bafter(?:_?cursor)?\\b/i, // e.g., after, after_cursor\n /\\bbefore(?:_?cursor)?\\b/i, // e.g., before, before_cursor\n /\\b(next|prev|previous)_?(?:page_?)?token\\b/i, // e.g., next_page_token, nextPageToken, prev_token\n /\\b(next|prev|previous)_?cursor\\b/i, // e.g., next_cursor, previousCursor\n /\\bcontinuation(?:_?token)?\\b/i, // e.g., continuation, continuation_token\n /\\bpage(?:_?(token|id))?\\b/i, // e.g., after, after_cursor\n\n /\\bstart_?(?:key|cursor|token|after)\\b/i, // e.g., start_key, startCursor, startToken, startAfter\n];\n\n// Regexes for parameters indicating a limit when used with cursors\nexport const CURSOR_LIMIT_REGEXES: RegExp[] = [\n /\\blimit\\b/i,\n /\\bcount\\b/i,\n /\\bsize\\b/i, // General size\n /\\bfirst\\b/i, // Common in Relay-style cursor pagination (forward pagination)\n /\\blast\\b/i, // Common in Relay-style cursor pagination (backward pagination)\n /\\bpage_?size\\b/i, // Sometimes page_size is used with cursors\n /\\bnum_?(?:items|records|results)\\b/i, // e.g., num_items\n /\\bmax_?items\\b/i,\n /\\btake\\b/i,\n];\n\n// --- Helper Function ---\nfunction findParamAndKeyword(\n queryParams: { name: string }[],\n regexes: RegExp[],\n excludeParamName?: string,\n) {\n for (const param of queryParams) {\n if (param.name === excludeParamName) {\n continue;\n }\n for (const regex of regexes) {\n const match = param.name.match(regex);\n if (match) {\n return { param, keyword: match[0] }; // match[0] is the actual matched substring\n }\n }\n }\n return null;\n}\n\nfunction coerceParameters(\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[],\n) {\n const cleanedParameters: {\n name: string;\n schema: Omit<SchemaObject, 'type'> & {\n type: string[]; // Ensure type is always an array\n };\n }[] = [];\n for (const param of parameters) {\n if (!param.schema) {\n continue;\n }\n if (isRef(param.schema)) {\n continue;\n }\n if (param.schema.anyOf || param.schema.oneOf || param.schema.allOf) {\n const schemas = (\n param.schema.anyOf ||\n param.schema.oneOf ||\n param.schema.allOf ||\n []\n ).filter((it): it is SchemaObject => !isRef(it));\n schemas.forEach((schema) => {\n if (schema.type) {\n cleanedParameters.push({\n ...param,\n schema: {\n ...schema,\n type: coerceTypes(schema),\n },\n });\n }\n });\n continue;\n }\n if (!param.schema.type) {\n continue;\n }\n if (param.schema) {\n cleanedParameters.push({\n ...param,\n schema: {\n ...param.schema,\n type: coerceTypes(param.schema),\n },\n });\n }\n }\n return cleanedParameters;\n}\n\nfunction isOffsetPagination(\n operation: TunedOperationObject,\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[],\n): OffsetPaginationResult | null {\n const params = coerceParameters(parameters).filter(\n (it) =>\n it.schema.type.includes('integer') || it.schema.type.includes('number'),\n );\n\n const offsetMatch = findParamAndKeyword(params, OFFSET_PARAM_REGEXES);\n\n if (!offsetMatch) return null;\n\n const limitMatch = findParamAndKeyword(\n params,\n GENERIC_LIMIT_PARAM_REGEXES,\n offsetMatch.param.name,\n );\n if (!limitMatch) return null;\n\n return {\n type: 'offset',\n offsetParamName: offsetMatch.param.name,\n offsetKeyword: offsetMatch.keyword,\n limitParamName: limitMatch.param.name,\n limitKeyword: limitMatch.keyword,\n };\n}\n\nfunction isPagePagination(\n operation: TunedOperationObject,\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[],\n): PagePaginationResult | null {\n const params = coerceParameters(parameters).filter(\n (it) =>\n it.schema.type.includes('integer') || it.schema.type.includes('number'),\n );\n\n if (params.length < 2) return null;\n\n const pageNoMatch = findParamAndKeyword(params, PAGE_NUMBER_REGEXES);\n if (!pageNoMatch) return null;\n\n const pageSizeMatch = findParamAndKeyword(\n params,\n PAGE_SIZE_REGEXES,\n pageNoMatch.param.name,\n );\n if (!pageSizeMatch) return null;\n\n return {\n type: 'page',\n pageNumberParamName: pageNoMatch.param.name,\n pageNumberKeyword: pageNoMatch.keyword,\n pageSizeParamName: pageSizeMatch.param.name,\n pageSizeKeyword: pageSizeMatch.keyword,\n };\n}\n\nfunction isCursorPagination(\n operation: TunedOperationObject,\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[] = [],\n): CursorPaginationResult | null {\n const queryParams = parameters;\n if (queryParams.length < 2) return null; // Need at least a cursor and a limit-like param\n\n const cursorMatch = findParamAndKeyword(queryParams, CURSOR_REGEXES);\n if (!cursorMatch) return null;\n\n const limitMatch = findParamAndKeyword(\n queryParams,\n CURSOR_LIMIT_REGEXES,\n cursorMatch.param.name,\n );\n if (!limitMatch) return null;\n\n return {\n type: 'cursor',\n cursorParamName: cursorMatch.param.name,\n cursorKeyword: cursorMatch.keyword,\n limitParamName: limitMatch.param.name,\n limitKeyword: limitMatch.keyword,\n };\n}\n\n/**\n * Guesses the pagination strategy of an OpenAPI operation based on its query parameters.\n * It checks for offset, page-based, and cursor-based pagination in that order.\n *\n * @param operation The OpenAPI operation object.\n * @returns A PaginationGuess object indicating the detected type and relevant parameters.\n */\nexport function guessPagination(\n operation: TunedOperationObject,\n body?: SchemaObject,\n response?: SchemaObject,\n): PaginationGuess {\n const bodyParameters =\n body && body.properties\n ? Object.entries(body.properties).map(([it, schema]) => ({\n name: it,\n schema,\n }))\n : [];\n const parameters = operation.parameters;\n\n if (isEmpty(operation.parameters) && isEmpty(bodyParameters)) {\n return { type: 'none', reason: 'no parameters' };\n }\n if (!response) {\n return { type: 'none', reason: 'no response' };\n }\n if (!response.properties) {\n return { type: 'none', reason: 'empty response' };\n }\n const properties = response.properties as SchemasObject;\n\n const itemsKey = getItemsName(properties);\n if (!itemsKey) {\n return { type: 'none', reason: 'no items key' };\n }\n const hasMoreKey = getHasMoreName(excludeKey(properties, itemsKey));\n\n if (!hasMoreKey) {\n return { type: 'none', reason: 'no hasMore key' };\n }\n const pagination =\n isOffsetPagination(operation, [...parameters, ...bodyParameters]) ||\n isPagePagination(operation, [...parameters, ...bodyParameters]) ||\n isCursorPagination(operation, [...parameters, ...bodyParameters]);\n return pagination\n ? { ...pagination, items: itemsKey, hasMore: hasMoreKey }\n : { type: 'none', reason: 'no pagination' };\n}\n\nfunction excludeKey<T extends Record<string, any>>(\n obj: T,\n key: string,\n): Omit<T, typeof key> {\n const { [key]: _, ...rest } = obj;\n return rest;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n ReferenceObject,\n SchemaObject,\n SchemasObject,\n} from 'openapi3-ts/oas31';\n\nimport { isRef } from '@sdk-it/core/ref.js';\nimport { isEmpty } from '@sdk-it/core/utils.js';\n\nimport { coerceTypes } from '../tune.js';\nimport type { TunedOperationObject } from '../types.js';\nimport { getHasMoreName, getItemsName } from './pagination-result.js';\n\ninterface PaginationResultBase {\n type: 'offset' | 'page' | 'cursor' | 'none';\n}\n\nexport interface OffsetPaginationResult extends PaginationResultBase {\n type: 'offset';\n offsetParamName: string;\n offsetKeyword: string; // The actual part of param name that matched\n limitParamName: string;\n limitKeyword: string; // The actual part of param name that matched\n}\n\nexport interface PagePaginationResult extends PaginationResultBase {\n type: 'page';\n pageNumberParamName: string;\n pageNumberKeyword: string;\n pageSizeParamName: string;\n pageSizeKeyword: string;\n}\n\nexport interface CursorPaginationResult extends PaginationResultBase {\n type: 'cursor';\n cursorParamName: string;\n cursorKeyword: string;\n limitParamName: string;\n limitKeyword: string;\n}\n\nexport interface NoPaginationResult extends PaginationResultBase {\n type: 'none';\n reason: string;\n}\n\nexport type PaginationGuess =\n | ((\n OffsetPaginationResult | PagePaginationResult | CursorPaginationResult\n ) & { items: string; hasMore: string })\n | NoPaginationResult;\n\n// --- Keyword Regex Definitions ---\n\nexport const OFFSET_PARAM_REGEXES: RegExp[] = [\n /\\boffset\\b/i,\n /\\bskip\\b/i,\n /\\bstart(?:ing_at|_index)?\\b/i, // e.g., start, starting_at, start_index\n /\\bfrom\\b/i,\n];\n\nexport const GENERIC_LIMIT_PARAM_REGEXES: RegExp[] = [\n /\\blimit\\b/i,\n /\\bcount\\b/i,\n /\\b(?:page_?)?size\\b/i, // e.g., size, page_size, pagesize\n /\\bmax_results\\b/i,\n /\\bnum_results\\b/i,\n /\\bshow\\b/i, // Can sometimes mean limit\n /\\bper_?page\\b/i, // e.g., per_page, perpage\n /\\bper-page\\b/i,\n /\\btake\\b/i,\n];\n\nexport const PAGE_NUMBER_REGEXES: RegExp[] = [\n // /^(currentPage)?page$/i, // Exact match for \"page\"\n // /^currentPage$/i, // Exact match for \"currentPage\"\n /^p$/i, // Exact match for \"p\" (common shorthand)\n // /\\bpage_?(?:number|no|num|idx|index)\\b/i, // e.g., page_number, pageNumber, page_num, page_idx\n /^(current)?_?page(_?)(?:number|no|num|idx|index)?\\b/i,\n];\n\n// Regexes for parameters indicating page size (when used with page number)\nexport const PAGE_SIZE_REGEXES: RegExp[] = [\n /\\bpage_?size\\b/i, // e.g., page_size, pagesize\n /^size$/i, // Exact \"size\"\n // /\\bsize\\b/i, // Broader \"size\" - can be ambiguous, prefer more specific ones first\n /\\blimit\\b/i, // Limit is often used for page size\n /\\bcount\\b/i, // Count can also be used for page size\n /\\bper_?page\\b/i, // e.g., per_page, perpage\n /\\bper-page\\b/i,\n /\\bnum_?(?:items|records|results)\\b/i, // e.g., num_items, numitems\n /\\bresults_?per_?page\\b/i,\n];\n\n// Regexes for parameters indicating a cursor\nexport const CURSOR_REGEXES: RegExp[] = [\n /\\bmarker\\b/i,\n /\\bcursor\\b/i,\n /\\bafter(?:_?cursor)?\\b/i, // e.g., after, after_cursor\n /\\bbefore(?:_?cursor)?\\b/i, // e.g., before, before_cursor\n /\\b(next|prev|previous)_?(?:page_?)?token\\b/i, // e.g., next_page_token, nextPageToken, prev_token\n /\\b(next|prev|previous)_?cursor\\b/i, // e.g., next_cursor, previousCursor\n /\\bcontinuation(?:_?token)?\\b/i, // e.g., continuation, continuation_token\n /\\bpage(?:_?(token|id))?\\b/i, // e.g., after, after_cursor\n\n /\\bstart_?(?:key|cursor|token|after)\\b/i, // e.g., start_key, startCursor, startToken, startAfter\n];\n\n// Regexes for parameters indicating a limit when used with cursors\nexport const CURSOR_LIMIT_REGEXES: RegExp[] = [\n /\\blimit\\b/i,\n /\\bcount\\b/i,\n /\\bsize\\b/i, // General size\n /\\bfirst\\b/i, // Common in Relay-style cursor pagination (forward pagination)\n /\\blast\\b/i, // Common in Relay-style cursor pagination (backward pagination)\n /\\bpage_?size\\b/i, // Sometimes page_size is used with cursors\n /\\bnum_?(?:items|records|results)\\b/i, // e.g., num_items\n /\\bmax_?items\\b/i,\n /\\btake\\b/i,\n];\n\n// --- Helper Function ---\nfunction findParamAndKeyword(\n queryParams: { name: string }[],\n regexes: RegExp[],\n excludeParamName?: string,\n) {\n for (const param of queryParams) {\n if (param.name === excludeParamName) {\n continue;\n }\n for (const regex of regexes) {\n const match = param.name.match(regex);\n if (match) {\n return { param, keyword: match[0] }; // match[0] is the actual matched substring\n }\n }\n }\n return null;\n}\n\nfunction coerceParameters(\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[],\n) {\n const cleanedParameters: {\n name: string;\n schema: Omit<SchemaObject, 'type'> & {\n type: string[]; // Ensure type is always an array\n };\n }[] = [];\n for (const param of parameters) {\n if (!param.schema) {\n continue;\n }\n if (isRef(param.schema)) {\n continue;\n }\n if (param.schema.anyOf || param.schema.oneOf || param.schema.allOf) {\n const schemas = (\n param.schema.anyOf ||\n param.schema.oneOf ||\n param.schema.allOf ||\n []\n ).filter((it): it is SchemaObject => !isRef(it));\n schemas.forEach((schema) => {\n if (schema.type) {\n cleanedParameters.push({\n ...param,\n schema: {\n ...schema,\n type: coerceTypes(schema),\n },\n });\n }\n });\n continue;\n }\n if (!param.schema.type) {\n continue;\n }\n if (param.schema) {\n cleanedParameters.push({\n ...param,\n schema: {\n ...param.schema,\n type: coerceTypes(param.schema),\n },\n });\n }\n }\n return cleanedParameters;\n}\n\nfunction isOffsetPagination(\n operation: TunedOperationObject,\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[],\n): OffsetPaginationResult | null {\n const params = coerceParameters(parameters).filter(\n (it) =>\n it.schema.type.includes('integer') || it.schema.type.includes('number'),\n );\n\n const offsetMatch = findParamAndKeyword(params, OFFSET_PARAM_REGEXES);\n\n if (!offsetMatch) return null;\n\n const limitMatch = findParamAndKeyword(\n params,\n GENERIC_LIMIT_PARAM_REGEXES,\n offsetMatch.param.name,\n );\n if (!limitMatch) return null;\n\n return {\n type: 'offset',\n offsetParamName: offsetMatch.param.name,\n offsetKeyword: offsetMatch.keyword,\n limitParamName: limitMatch.param.name,\n limitKeyword: limitMatch.keyword,\n };\n}\n\nfunction isPagePagination(\n operation: TunedOperationObject,\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[],\n): PagePaginationResult | null {\n const params = coerceParameters(parameters).filter(\n (it) =>\n it.schema.type.includes('integer') || it.schema.type.includes('number'),\n );\n\n if (params.length < 2) return null;\n\n const pageNoMatch = findParamAndKeyword(params, PAGE_NUMBER_REGEXES);\n if (!pageNoMatch) return null;\n\n const pageSizeMatch = findParamAndKeyword(\n params,\n PAGE_SIZE_REGEXES,\n pageNoMatch.param.name,\n );\n if (!pageSizeMatch) return null;\n\n return {\n type: 'page',\n pageNumberParamName: pageNoMatch.param.name,\n pageNumberKeyword: pageNoMatch.keyword,\n pageSizeParamName: pageSizeMatch.param.name,\n pageSizeKeyword: pageSizeMatch.keyword,\n };\n}\n\nfunction isCursorPagination(\n operation: TunedOperationObject,\n parameters: { name: string; schema?: SchemaObject | ReferenceObject }[] = [],\n): CursorPaginationResult | null {\n const queryParams = parameters;\n if (queryParams.length < 2) return null; // Need at least a cursor and a limit-like param\n\n const cursorMatch = findParamAndKeyword(queryParams, CURSOR_REGEXES);\n if (!cursorMatch) return null;\n\n const limitMatch = findParamAndKeyword(\n queryParams,\n CURSOR_LIMIT_REGEXES,\n cursorMatch.param.name,\n );\n if (!limitMatch) return null;\n\n return {\n type: 'cursor',\n cursorParamName: cursorMatch.param.name,\n cursorKeyword: cursorMatch.keyword,\n limitParamName: limitMatch.param.name,\n limitKeyword: limitMatch.keyword,\n };\n}\n\n/**\n * Guesses the pagination strategy of an OpenAPI operation based on its query parameters.\n * It checks for offset, page-based, and cursor-based pagination in that order.\n *\n * @param operation The OpenAPI operation object.\n * @returns A PaginationGuess object indicating the detected type and relevant parameters.\n */\nexport function guessPagination(\n operation: TunedOperationObject,\n body?: SchemaObject,\n response?: SchemaObject,\n): PaginationGuess {\n const bodyParameters =\n body && body.properties\n ? Object.entries(body.properties).map(([it, schema]) => ({\n name: it,\n schema,\n }))\n : [];\n const parameters = operation.parameters;\n\n if (isEmpty(operation.parameters) && isEmpty(bodyParameters)) {\n return { type: 'none', reason: 'no parameters' };\n }\n if (!response) {\n return { type: 'none', reason: 'no response' };\n }\n if (!response.properties) {\n return { type: 'none', reason: 'empty response' };\n }\n const properties = response.properties as SchemasObject;\n\n const itemsKey = getItemsName(properties);\n if (!itemsKey) {\n return { type: 'none', reason: 'no items key' };\n }\n const hasMoreKey = getHasMoreName(excludeKey(properties, itemsKey));\n\n if (!hasMoreKey) {\n return { type: 'none', reason: 'no hasMore key' };\n }\n const pagination =\n isOffsetPagination(operation, [...parameters, ...bodyParameters]) ||\n isPagePagination(operation, [...parameters, ...bodyParameters]) ||\n isCursorPagination(operation, [...parameters, ...bodyParameters]);\n return pagination\n ? { ...pagination, items: itemsKey, hasMore: hasMoreKey }\n : { type: 'none', reason: 'no pagination' };\n}\n\nfunction excludeKey<T extends Record<string, any>>(\n obj: T,\n key: string,\n): Omit<T, typeof key> {\n const { [key]: _, ...rest } = obj;\n return rest;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-result.d.ts","sourceRoot":"","sources":["../../../src/lib/pagination/pagination-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoHrE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GACvC,MAAM,GAAG,IAAI,CAmFf;AAmFD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAevE"}
1
+ {"version":3,"file":"pagination-result.d.ts","sourceRoot":"","sources":["../../../src/lib/pagination/pagination-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAmIrE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GACvC,MAAM,GAAG,IAAI,CAqFf;AAmFD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAevE"}
@@ -22,6 +22,12 @@ const PRIMARY_OTHER_KEYWORDS = [
22
22
  "events"
23
23
  ];
24
24
  const SECONDARY_KEYWORDS = ["entries", "rows", "elements"];
25
+ function lastWord(propName) {
26
+ return propName.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).at(-1) ?? "";
27
+ }
28
+ function hasKeyword(propName, keywords) {
29
+ return keywords.includes(lastWord(propName));
30
+ }
25
31
  const PLURAL_DEPRIORITIZE_LIST = [
26
32
  "status",
27
33
  "success",
@@ -46,6 +52,7 @@ const PLURAL_DEPRIORITIZE_LIST = [
46
52
  "actions",
47
53
  "attributes",
48
54
  "categories",
55
+ "configurations",
49
56
  "features",
50
57
  "includes",
51
58
  "tags"
@@ -131,23 +138,26 @@ function getItemsName(properties) {
131
138
  };
132
139
  for (const propName of arrayPropertyNames) {
133
140
  const lowerPropName = propName.toLowerCase();
134
- if (PRIMARY_TOP_TIER_KEYWORDS.includes(lowerPropName)) {
141
+ const finalWord = lastWord(propName);
142
+ const isDeprioritized = PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName);
143
+ const isCompoundMetadata = finalWord !== lowerPropName && PLURAL_DEPRIORITIZE_LIST.includes(finalWord);
144
+ if (hasKeyword(propName, PRIMARY_TOP_TIER_KEYWORDS)) {
135
145
  updateCandidate(propName, 2);
136
146
  continue;
137
147
  }
138
- if (candidateRank > 3 && PRIMARY_OTHER_KEYWORDS.includes(lowerPropName)) {
148
+ if (candidateRank > 3 && hasKeyword(propName, PRIMARY_OTHER_KEYWORDS)) {
139
149
  updateCandidate(propName, 3);
140
150
  continue;
141
151
  }
142
- if (candidateRank > 4 && SECONDARY_KEYWORDS.includes(lowerPropName)) {
152
+ if (candidateRank > 4 && hasKeyword(propName, SECONDARY_KEYWORDS)) {
143
153
  updateCandidate(propName, 4);
144
154
  continue;
145
155
  }
146
- if (candidateRank > 5 && pluralize.isPlural(propName) && !PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)) {
156
+ if (candidateRank > 5 && pluralize.isPlural(propName) && !isDeprioritized && !isCompoundMetadata) {
147
157
  updateCandidate(propName, 5);
148
158
  continue;
149
159
  }
150
- if (candidateRank > 6 && pluralize.isPlural(propName) && PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)) {
160
+ if (candidateRank > 6 && pluralize.isPlural(propName) && isDeprioritized) {
151
161
  updateCandidate(propName, 6);
152
162
  continue;
153
163
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/pagination/pagination-result.ts"],
4
- "sourcesContent": ["import type { SchemaObject, SchemasObject } from 'openapi3-ts/oas31';\nimport pluralize from 'pluralize';\n\nconst PRIMARY_TOP_TIER_KEYWORDS: string[] = [\n 'data',\n 'items',\n 'results',\n 'value',\n];\nconst PRIMARY_OTHER_KEYWORDS: string[] = [\n 'records',\n 'content',\n 'list',\n 'payload',\n 'entities',\n 'collection',\n 'users',\n 'products',\n 'orders',\n 'bookings',\n 'articles',\n 'posts',\n 'documents',\n 'events',\n];\nconst SECONDARY_KEYWORDS: string[] = ['entries', 'rows', 'elements'];\n\nconst PLURAL_DEPRIORITIZE_LIST: string[] = [\n 'status',\n 'success',\n 'address',\n 'details',\n 'properties',\n 'params',\n 'headers',\n 'cookies',\n 'series',\n 'links',\n 'meta',\n 'metadata',\n 'statistics',\n 'settings',\n 'options',\n 'permissions',\n 'credentials',\n 'diagnostics',\n 'warnings',\n 'errors',\n 'actions',\n 'attributes',\n 'categories',\n 'features',\n 'includes',\n 'tags',\n];\n\n// For exact matches (normalized: lowercase, no underscores/hyphens)\nconst HAS_MORE_PRIMARY_POSITIVE_EXACT: string[] = [\n 'hasmore',\n 'hasnext',\n 'hasnextpage',\n 'moreitems',\n 'moreitemsavailable',\n 'nextpage',\n 'nextpageexists',\n 'nextpageavailable',\n 'hasadditionalresults',\n 'moreresultsavailable',\n 'canloadmore',\n 'hasadditional',\n 'additionalitems',\n 'fetchmore',\n];\n\nconst HAS_MORE_SECONDARY_POSITIVE_EXACT: string[] = ['more', 'next'];\n\nconst HAS_MORE_PRIMARY_INVERTED_EXACT: string[] = [\n 'islast',\n 'lastpage',\n 'endofresults',\n 'endoflist',\n 'nomoreitems',\n 'nomoredata',\n 'allitemsloaded',\n 'iscomplete',\n 'completed',\n];\n\n// For regex-based sub-phrase matching (tested against original propName, case-insensitive)\n// These regexes look for meaningful phrases, often using word boundaries (\\b)\n// and allowing for optional underscores.\nconst HAS_MORE_POSITIVE_REGEX_PATTERNS: string[] = [\n '\\\\bhas_?more\\\\b',\n '\\\\bhas_?next\\\\b', // e.g., itemsHasNext, items_has_next\n '\\\\bmore_?items\\\\b',\n '\\\\bnext_?page\\\\b', // e.g., userNextPageFlag\n '\\\\badditional\\\\b', // e.g., hasAdditionalData, additional_results_exist\n '\\\\bcontinuation\\\\b', // e.g., continuationAvailable, has_continuation_token\n '\\\\bmore_?results\\\\b',\n '\\\\bpage_?available\\\\b',\n '\\\\bnext(?:_?(page|marker))?\\\\b',\n];\nconst COMPILED_HAS_MORE_POSITIVE_REGEXES: RegExp[] =\n HAS_MORE_POSITIVE_REGEX_PATTERNS.map((p) => new RegExp(p, 'i'));\n\nconst HAS_MORE_INVERTED_REGEX_PATTERNS: string[] = [\n '\\\\bis_?last\\\\b', // e.g., pageIsLast\n '\\\\blast_?page\\\\b', // e.g., resultsAreLastPage\n '\\\\bend_?of_?(data|results|list|items|stream)\\\\b',\n '\\\\bno_?more_?(items|data|results)?\\\\b',\n '\\\\ball_?(items_?)?loaded\\\\b',\n '\\\\bis_?complete\\\\b',\n];\nconst COMPILED_HAS_MORE_INVERTED_REGEXES: RegExp[] =\n HAS_MORE_INVERTED_REGEX_PATTERNS.map((p) => new RegExp(p, 'i'));\n\n/**\n * Tries to guess the name of the property that holds the main list of items\n * within an object schema using a series of heuristics.\n *\n * @param schema The OpenAPI SchemaObject, expected to be of type 'object'.\n * @returns The name of the most likely property containing the items array,\n * or null if no array properties are found in the schema.\n */\nexport function getItemsName(\n properties: Record<string, SchemaObject>,\n): string | null {\n const arrayPropertyNames: string[] = [];\n for (const propName in properties) {\n if (propName in properties) {\n const propSchema = properties[propName] as SchemaObject;\n if (propSchema && propSchema.type === 'array') {\n arrayPropertyNames.push(propName);\n }\n }\n }\n\n // Heuristic 0: No array properties at all.\n if (arrayPropertyNames.length === 0) {\n return null;\n }\n\n // Heuristic 1: Exactly one array property. This is the strongest signal.\n if (arrayPropertyNames.length === 1) {\n return arrayPropertyNames[0];\n }\n\n // Multiple array properties exist. Apply ranked heuristics:\n let bestCandidate: string | null = null;\n let candidateRank = Infinity; // Lower is better\n\n const updateCandidate = (propName: string, rank: number) => {\n if (rank < candidateRank) {\n bestCandidate = propName;\n candidateRank = rank;\n }\n };\n\n for (const propName of arrayPropertyNames) {\n const lowerPropName = propName.toLowerCase();\n\n // Heuristic 2: Top-tier primary keywords (e.g., \"data\", \"items\")\n if (PRIMARY_TOP_TIER_KEYWORDS.includes(lowerPropName)) {\n updateCandidate(propName, 2);\n continue; // Move to next property, this is a strong match for this prop\n }\n\n // Heuristic 3: Other primary keywords\n if (candidateRank > 3 && PRIMARY_OTHER_KEYWORDS.includes(lowerPropName)) {\n updateCandidate(propName, 3);\n continue;\n }\n\n // Heuristic 4: Secondary keywords\n if (candidateRank > 4 && SECONDARY_KEYWORDS.includes(lowerPropName)) {\n updateCandidate(propName, 4);\n continue;\n }\n\n // Heuristic 5: Pluralized name, not on the deprioritize list\n if (\n candidateRank > 5 &&\n pluralize.isPlural(propName) &&\n !PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)\n ) {\n updateCandidate(propName, 5);\n continue;\n }\n\n // Heuristic 6: Pluralized name, IS on the deprioritize list (less preferred plural)\n if (\n candidateRank > 6 &&\n pluralize.isPlural(propName) &&\n PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)\n ) {\n updateCandidate(propName, 6);\n continue;\n }\n }\n\n // If any of the above heuristics found a candidate, return it.\n if (bestCandidate) {\n return bestCandidate;\n }\n\n // Heuristic 7: Fallback - If no keywords or clear plurals,\n // and multiple arrays exist, return the first array property encountered.\n // This ensures we always return a name if arrays are present.\n return arrayPropertyNames[0];\n}\n\nfunction guess(properties: Record<string, SchemaObject>) {\n const booleanPropertyNames: string[] = [];\n for (const propName in properties) {\n const propSchema = properties[propName] as SchemaObject;\n if (\n propSchema.type === 'boolean' ||\n propSchema.type === 'integer' ||\n propSchema.type === 'string'\n ) {\n booleanPropertyNames.push(propName);\n }\n }\n\n if (booleanPropertyNames.length === 0) {\n return null;\n }\n\n if (booleanPropertyNames.length === 1) {\n return booleanPropertyNames[0];\n }\n\n let bestCandidate: string | null = null;\n let candidateRank = Infinity;\n\n const updateCandidate = (propName: string, rank: number) => {\n if (rank < candidateRank) {\n bestCandidate = propName;\n candidateRank = rank;\n }\n };\n\n for (const propName of booleanPropertyNames) {\n const normalizedForExactMatch = propName.toLowerCase().replace(/[-_]/g, '');\n let currentPropRank = Infinity;\n\n // Rank 1: Primary Exact Positive Match\n if (HAS_MORE_PRIMARY_POSITIVE_EXACT.includes(normalizedForExactMatch)) {\n currentPropRank = 1;\n }\n // Rank 2: Secondary Exact Positive Match\n else if (\n HAS_MORE_SECONDARY_POSITIVE_EXACT.includes(normalizedForExactMatch)\n ) {\n currentPropRank = 2;\n }\n // Rank 3: Positive Regex Match (sub-phrase)\n else {\n let foundPositiveRegex = false;\n for (const regex of COMPILED_HAS_MORE_POSITIVE_REGEXES) {\n if (regex.test(propName)) {\n // Test against original propName\n currentPropRank = 3;\n foundPositiveRegex = true;\n break;\n }\n }\n\n // Only proceed to inverted matches if no positive match of any kind (Rank 1, 2, or 3) was found\n if (!foundPositiveRegex) {\n // Rank 4: Primary Exact Inverted Match\n if (HAS_MORE_PRIMARY_INVERTED_EXACT.includes(normalizedForExactMatch)) {\n currentPropRank = 4;\n }\n // Rank 5: Inverted Regex Match (sub-phrase)\n else {\n for (const regex of COMPILED_HAS_MORE_INVERTED_REGEXES) {\n if (regex.test(propName)) {\n // Test against original propName\n currentPropRank = 5;\n break;\n }\n }\n }\n }\n }\n\n updateCandidate(propName, currentPropRank);\n }\n return bestCandidate;\n}\n\n/**\n * Tries to guess the name of a boolean property that indicates if there are more items\n * to fetch (e.g., for pagination).\n *\n * @param schema The OpenAPI SchemaObject, expected to be of type 'object'.\n * @returns The name of the most likely boolean property indicating \"has more\",\n * or null if no suitable boolean property is found.\n */\nexport function getHasMoreName(properties: SchemasObject): string | null {\n const rootGuess = guess(properties);\n if (rootGuess) {\n return rootGuess;\n }\n for (const propName in properties) {\n const propSchema = properties[propName];\n if (propSchema.type === 'object' && propSchema.properties) {\n const nested = getHasMoreName(propSchema.properties as SchemasObject);\n if (nested) {\n return propName + '.' + nested;\n }\n }\n }\n return null;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { SchemaObject, SchemasObject } from 'openapi3-ts/oas31';\nimport pluralize from 'pluralize';\n\nconst PRIMARY_TOP_TIER_KEYWORDS: string[] = [\n 'data',\n 'items',\n 'results',\n 'value',\n];\nconst PRIMARY_OTHER_KEYWORDS: string[] = [\n 'records',\n 'content',\n 'list',\n 'payload',\n 'entities',\n 'collection',\n 'users',\n 'products',\n 'orders',\n 'bookings',\n 'articles',\n 'posts',\n 'documents',\n 'events',\n];\nconst SECONDARY_KEYWORDS: string[] = ['entries', 'rows', 'elements'];\n\nfunction lastWord(propName: string) {\n return (\n propName\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean)\n .at(-1) ?? ''\n );\n}\n\nfunction hasKeyword(propName: string, keywords: string[]) {\n return keywords.includes(lastWord(propName));\n}\n\nconst PLURAL_DEPRIORITIZE_LIST: string[] = [\n 'status',\n 'success',\n 'address',\n 'details',\n 'properties',\n 'params',\n 'headers',\n 'cookies',\n 'series',\n 'links',\n 'meta',\n 'metadata',\n 'statistics',\n 'settings',\n 'options',\n 'permissions',\n 'credentials',\n 'diagnostics',\n 'warnings',\n 'errors',\n 'actions',\n 'attributes',\n 'categories',\n 'configurations',\n 'features',\n 'includes',\n 'tags',\n];\n\n// For exact matches (normalized: lowercase, no underscores/hyphens)\nconst HAS_MORE_PRIMARY_POSITIVE_EXACT: string[] = [\n 'hasmore',\n 'hasnext',\n 'hasnextpage',\n 'moreitems',\n 'moreitemsavailable',\n 'nextpage',\n 'nextpageexists',\n 'nextpageavailable',\n 'hasadditionalresults',\n 'moreresultsavailable',\n 'canloadmore',\n 'hasadditional',\n 'additionalitems',\n 'fetchmore',\n];\n\nconst HAS_MORE_SECONDARY_POSITIVE_EXACT: string[] = ['more', 'next'];\n\nconst HAS_MORE_PRIMARY_INVERTED_EXACT: string[] = [\n 'islast',\n 'lastpage',\n 'endofresults',\n 'endoflist',\n 'nomoreitems',\n 'nomoredata',\n 'allitemsloaded',\n 'iscomplete',\n 'completed',\n];\n\n// For regex-based sub-phrase matching (tested against original propName, case-insensitive)\n// These regexes look for meaningful phrases, often using word boundaries (\\b)\n// and allowing for optional underscores.\nconst HAS_MORE_POSITIVE_REGEX_PATTERNS: string[] = [\n '\\\\bhas_?more\\\\b',\n '\\\\bhas_?next\\\\b', // e.g., itemsHasNext, items_has_next\n '\\\\bmore_?items\\\\b',\n '\\\\bnext_?page\\\\b', // e.g., userNextPageFlag\n '\\\\badditional\\\\b', // e.g., hasAdditionalData, additional_results_exist\n '\\\\bcontinuation\\\\b', // e.g., continuationAvailable, has_continuation_token\n '\\\\bmore_?results\\\\b',\n '\\\\bpage_?available\\\\b',\n '\\\\bnext(?:_?(page|marker))?\\\\b',\n];\nconst COMPILED_HAS_MORE_POSITIVE_REGEXES: RegExp[] =\n HAS_MORE_POSITIVE_REGEX_PATTERNS.map((p) => new RegExp(p, 'i'));\n\nconst HAS_MORE_INVERTED_REGEX_PATTERNS: string[] = [\n '\\\\bis_?last\\\\b', // e.g., pageIsLast\n '\\\\blast_?page\\\\b', // e.g., resultsAreLastPage\n '\\\\bend_?of_?(data|results|list|items|stream)\\\\b',\n '\\\\bno_?more_?(items|data|results)?\\\\b',\n '\\\\ball_?(items_?)?loaded\\\\b',\n '\\\\bis_?complete\\\\b',\n];\nconst COMPILED_HAS_MORE_INVERTED_REGEXES: RegExp[] =\n HAS_MORE_INVERTED_REGEX_PATTERNS.map((p) => new RegExp(p, 'i'));\n\n/**\n * Tries to guess the name of the property that holds the main list of items\n * within an object schema using a series of heuristics.\n *\n * @param schema The OpenAPI SchemaObject, expected to be of type 'object'.\n * @returns The name of the most likely property containing the items array,\n * or null if no array properties are found in the schema.\n */\nexport function getItemsName(\n properties: Record<string, SchemaObject>,\n): string | null {\n const arrayPropertyNames: string[] = [];\n for (const propName in properties) {\n if (propName in properties) {\n const propSchema = properties[propName] as SchemaObject;\n if (propSchema && propSchema.type === 'array') {\n arrayPropertyNames.push(propName);\n }\n }\n }\n\n // Heuristic 0: No array properties at all.\n if (arrayPropertyNames.length === 0) {\n return null;\n }\n\n // Heuristic 1: Exactly one array property. This is the strongest signal.\n if (arrayPropertyNames.length === 1) {\n return arrayPropertyNames[0];\n }\n\n // Multiple array properties exist. Apply ranked heuristics:\n let bestCandidate: string | null = null;\n let candidateRank = Infinity; // Lower is better\n\n const updateCandidate = (propName: string, rank: number) => {\n if (rank < candidateRank) {\n bestCandidate = propName;\n candidateRank = rank;\n }\n };\n\n for (const propName of arrayPropertyNames) {\n const lowerPropName = propName.toLowerCase();\n const finalWord = lastWord(propName);\n const isDeprioritized = PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName);\n const isCompoundMetadata =\n finalWord !== lowerPropName &&\n PLURAL_DEPRIORITIZE_LIST.includes(finalWord);\n\n // Heuristic 2: Top-tier primary keywords (e.g., \"data\", \"items\")\n if (hasKeyword(propName, PRIMARY_TOP_TIER_KEYWORDS)) {\n updateCandidate(propName, 2);\n continue; // Move to next property, this is a strong match for this prop\n }\n\n // Heuristic 3: Other primary keywords\n if (candidateRank > 3 && hasKeyword(propName, PRIMARY_OTHER_KEYWORDS)) {\n updateCandidate(propName, 3);\n continue;\n }\n\n // Heuristic 4: Secondary keywords\n if (candidateRank > 4 && hasKeyword(propName, SECONDARY_KEYWORDS)) {\n updateCandidate(propName, 4);\n continue;\n }\n\n // Heuristic 5: Pluralized name, not on the deprioritize list\n if (\n candidateRank > 5 &&\n pluralize.isPlural(propName) &&\n !isDeprioritized &&\n !isCompoundMetadata\n ) {\n updateCandidate(propName, 5);\n continue;\n }\n\n // Heuristic 6: Pluralized name, IS on the deprioritize list (less preferred plural)\n if (candidateRank > 6 && pluralize.isPlural(propName) && isDeprioritized) {\n updateCandidate(propName, 6);\n continue;\n }\n }\n\n // If any of the above heuristics found a candidate, return it.\n if (bestCandidate) {\n return bestCandidate;\n }\n\n // Heuristic 7: Fallback - If no keywords or clear plurals,\n // and multiple arrays exist, return the first array property encountered.\n // This ensures we always return a name if arrays are present.\n return arrayPropertyNames[0];\n}\n\nfunction guess(properties: Record<string, SchemaObject>) {\n const booleanPropertyNames: string[] = [];\n for (const propName in properties) {\n const propSchema = properties[propName] as SchemaObject;\n if (\n propSchema.type === 'boolean' ||\n propSchema.type === 'integer' ||\n propSchema.type === 'string'\n ) {\n booleanPropertyNames.push(propName);\n }\n }\n\n if (booleanPropertyNames.length === 0) {\n return null;\n }\n\n if (booleanPropertyNames.length === 1) {\n return booleanPropertyNames[0];\n }\n\n let bestCandidate: string | null = null;\n let candidateRank = Infinity;\n\n const updateCandidate = (propName: string, rank: number) => {\n if (rank < candidateRank) {\n bestCandidate = propName;\n candidateRank = rank;\n }\n };\n\n for (const propName of booleanPropertyNames) {\n const normalizedForExactMatch = propName.toLowerCase().replace(/[-_]/g, '');\n let currentPropRank = Infinity;\n\n // Rank 1: Primary Exact Positive Match\n if (HAS_MORE_PRIMARY_POSITIVE_EXACT.includes(normalizedForExactMatch)) {\n currentPropRank = 1;\n }\n // Rank 2: Secondary Exact Positive Match\n else if (\n HAS_MORE_SECONDARY_POSITIVE_EXACT.includes(normalizedForExactMatch)\n ) {\n currentPropRank = 2;\n }\n // Rank 3: Positive Regex Match (sub-phrase)\n else {\n let foundPositiveRegex = false;\n for (const regex of COMPILED_HAS_MORE_POSITIVE_REGEXES) {\n if (regex.test(propName)) {\n // Test against original propName\n currentPropRank = 3;\n foundPositiveRegex = true;\n break;\n }\n }\n\n // Only proceed to inverted matches if no positive match of any kind (Rank 1, 2, or 3) was found\n if (!foundPositiveRegex) {\n // Rank 4: Primary Exact Inverted Match\n if (HAS_MORE_PRIMARY_INVERTED_EXACT.includes(normalizedForExactMatch)) {\n currentPropRank = 4;\n }\n // Rank 5: Inverted Regex Match (sub-phrase)\n else {\n for (const regex of COMPILED_HAS_MORE_INVERTED_REGEXES) {\n if (regex.test(propName)) {\n // Test against original propName\n currentPropRank = 5;\n break;\n }\n }\n }\n }\n }\n\n updateCandidate(propName, currentPropRank);\n }\n return bestCandidate;\n}\n\n/**\n * Tries to guess the name of a boolean property that indicates if there are more items\n * to fetch (e.g., for pagination).\n *\n * @param schema The OpenAPI SchemaObject, expected to be of type 'object'.\n * @returns The name of the most likely boolean property indicating \"has more\",\n * or null if no suitable boolean property is found.\n */\nexport function getHasMoreName(properties: SchemasObject): string | null {\n const rootGuess = guess(properties);\n if (rootGuess) {\n return rootGuess;\n }\n for (const propName in properties) {\n const propSchema = properties[propName];\n if (propSchema.type === 'object' && propSchema.properties) {\n const nested = getHasMoreName(propSchema.properties as SchemasObject);\n if (nested) {\n return propName + '.' + nested;\n }\n }\n }\n return null;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }