@sdk-it/spec 0.46.0 → 0.46.2

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 (41) hide show
  1. package/README.md +65 -0
  2. package/dist/index.d.ts +0 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +0 -6
  5. package/dist/index.js.map +2 -2
  6. package/dist/lib/find-polymorphic-varients.js +1 -1
  7. package/dist/lib/find-polymorphic-varients.js.map +1 -1
  8. package/dist/lib/is-primitive-schema.js +1 -1
  9. package/dist/lib/is-primitive-schema.js.map +1 -1
  10. package/dist/lib/is.d.ts +2 -0
  11. package/dist/lib/is.d.ts.map +1 -1
  12. package/dist/lib/is.js +5 -0
  13. package/dist/lib/is.js.map +2 -2
  14. package/dist/lib/pagination/guess-pagination.js +1 -1
  15. package/dist/lib/pagination/guess-pagination.js.map +1 -1
  16. package/dist/lib/processing-plugins/extract-inline-schemas.d.ts.map +1 -1
  17. package/dist/lib/processing-plugins/extract-inline-schemas.js +151 -3
  18. package/dist/lib/processing-plugins/extract-inline-schemas.js.map +2 -2
  19. package/dist/lib/processing-plugins/normalize-request-bodies.d.ts +3 -0
  20. package/dist/lib/processing-plugins/normalize-request-bodies.d.ts.map +1 -1
  21. package/dist/lib/processing-plugins/normalize-request-bodies.js +99 -4
  22. package/dist/lib/processing-plugins/normalize-request-bodies.js.map +2 -2
  23. package/dist/lib/processing-plugins/normalize-responses.d.ts.map +1 -1
  24. package/dist/lib/processing-plugins/normalize-responses.js +126 -3
  25. package/dist/lib/processing-plugins/normalize-responses.js.map +2 -2
  26. package/dist/lib/processing-plugins/normalize-schemas.d.ts.map +1 -1
  27. package/dist/lib/processing-plugins/normalize-schemas.js +159 -2
  28. package/dist/lib/processing-plugins/normalize-schemas.js.map +3 -3
  29. package/package.json +2 -2
  30. package/dist/lib/tune-request-body.d.ts +0 -5
  31. package/dist/lib/tune-request-body.d.ts.map +0 -1
  32. package/dist/lib/tune-request-body.js +0 -101
  33. package/dist/lib/tune-request-body.js.map +0 -7
  34. package/dist/lib/tune-response.d.ts +0 -5
  35. package/dist/lib/tune-response.d.ts.map +0 -1
  36. package/dist/lib/tune-response.js +0 -135
  37. package/dist/lib/tune-response.js.map +0 -7
  38. package/dist/lib/tune.d.ts +0 -11
  39. package/dist/lib/tune.d.ts.map +0 -1
  40. package/dist/lib/tune.js +0 -315
  41. package/dist/lib/tune.js.map +0 -7
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # @sdk-it/spec
2
+
3
+ Load OpenAPI or Postman documents and normalize them into the intermediate
4
+ representation shared by SDK-IT generators.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ npm install @sdk-it/spec
10
+ ```
11
+
12
+ ## Load and process a specification
13
+
14
+ ```typescript
15
+ import { loadSpec, toIR } from '@sdk-it/spec';
16
+
17
+ const spec = await loadSpec('./openapi.yaml');
18
+ const ir = await toIR({
19
+ spec,
20
+ responses: { flattenErrorResponses: true },
21
+ });
22
+
23
+ console.log(ir.paths);
24
+ ```
25
+
26
+ `loadSpec` accepts local JSON or YAML paths and HTTP(S) URLs. It also detects
27
+ Postman collections and converts them to OpenAPI. `toIR` runs the default
28
+ ordered processing pipeline and returns the normalized `IR`.
29
+
30
+ ## Add a processing plugin
31
+
32
+ ```typescript
33
+ import {
34
+ createDefaultProcessingPlugins,
35
+ iterateOperations,
36
+ loadSpec,
37
+ toIR,
38
+ } from '@sdk-it/spec';
39
+
40
+ const spec = await loadSpec('./openapi.yaml');
41
+ const plugins = createDefaultProcessingPlugins();
42
+
43
+ plugins.splice(-1, 0, {
44
+ name: 'require-operation-summaries',
45
+ process({ spec, report }) {
46
+ for (const { entry, operation } of iterateOperations(spec)) {
47
+ if (!operation.summary) {
48
+ report({
49
+ severity: 'warning',
50
+ code: 'missing-summary',
51
+ message: 'Operation has no summary',
52
+ path: `${entry.method.toUpperCase()} ${entry.path}`,
53
+ });
54
+ }
55
+ }
56
+ },
57
+ });
58
+
59
+ const ir = await toIR({ spec, plugins });
60
+ ```
61
+
62
+ The example inserts the diagnostic plugin before the final canonicalization
63
+ step. Plugins run sequentially and may be asynchronous. See the
64
+ [processing-plugin architecture](../../docs/architecture/spec-processing-plugins.md)
65
+ for the default order, diagnostics, cancellation, and extension rules.
package/dist/index.d.ts CHANGED
@@ -19,8 +19,6 @@ export * from './lib/reserved-keywords.js';
19
19
  export * from './lib/security.js';
20
20
  export * from './lib/sidebar.js';
21
21
  export * from './lib/tag.js';
22
- export { patchParameters } from './lib/tune-request-body.js';
23
- export { coerceTypes } from './lib/tune.js';
24
22
  export * from './lib/types.js';
25
23
  export * from './lib/walk-schemas.js';
26
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,aAAa,CAAC;AAC5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,aAAa,CAAC;AAC5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -19,12 +19,6 @@ export * from "./lib/reserved-keywords.js";
19
19
  export * from "./lib/security.js";
20
20
  export * from "./lib/sidebar.js";
21
21
  export * from "./lib/tag.js";
22
- import { patchParameters } from "./lib/tune-request-body.js";
23
- import { coerceTypes } from "./lib/tune.js";
24
22
  export * from "./lib/types.js";
25
23
  export * from "./lib/walk-schemas.js";
26
- export {
27
- coerceTypes,
28
- patchParameters
29
- };
30
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export * from './lib/create-operation.js';\nexport * from './lib/find-polymorphic-varients.js';\nexport * from './lib/find-unique-schema-name.js';\nexport * from './lib/for-each-operation.js';\nexport * from './lib/format-name.js';\nexport * from './lib/get-ref-usage.js';\nexport * from './lib/ir.js';\nexport * from './lib/is-primitive-schema.js';\nexport * from './lib/is.js';\nexport * from './lib/loaders/load-spec.js';\nexport * from './lib/loaders/local-loader.js';\nexport * from './lib/loaders/remote-loader.js';\nexport * from './lib/metadata.js';\nexport * from './lib/options.js';\nexport * from './lib/processing-plugins/index.js';\nexport * from './lib/processing.js';\nexport * from './lib/overview-docs/overview-errors.js';\nexport * from './lib/reserved-keywords.js';\nexport * from './lib/security.js';\nexport * from './lib/sidebar.js';\nexport * from './lib/tag.js';\nexport { patchParameters } from './lib/tune-request-body.js';\nexport { coerceTypes } from './lib/tune.js';\nexport * from './lib/types.js';\nexport * from './lib/walk-schemas.js';\n"],
5
- "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export * from './lib/create-operation.js';\nexport * from './lib/find-polymorphic-varients.js';\nexport * from './lib/find-unique-schema-name.js';\nexport * from './lib/for-each-operation.js';\nexport * from './lib/format-name.js';\nexport * from './lib/get-ref-usage.js';\nexport * from './lib/ir.js';\nexport * from './lib/is-primitive-schema.js';\nexport * from './lib/is.js';\nexport * from './lib/loaders/load-spec.js';\nexport * from './lib/loaders/local-loader.js';\nexport * from './lib/loaders/remote-loader.js';\nexport * from './lib/metadata.js';\nexport * from './lib/options.js';\nexport * from './lib/processing-plugins/index.js';\nexport * from './lib/processing.js';\nexport * from './lib/overview-docs/overview-errors.js';\nexport * from './lib/reserved-keywords.js';\nexport * from './lib/security.js';\nexport * from './lib/sidebar.js';\nexport * from './lib/tag.js';\nexport * from './lib/types.js';\nexport * from './lib/walk-schemas.js';\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { groupBy, uniqBy } from "lodash-es";
2
2
  import { camelcase, isEmpty, isRef, resolveRef } from "@sdk-it/core";
3
- import { coerceTypes } from "./tune.js";
3
+ import { coerceTypes } from "./is.js";
4
4
  const groupSchemasByType = (spec, schemas) => {
5
5
  const groups = schemas.reduce((acc, schema, index) => {
6
6
  if (isRef(schema)) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/find-polymorphic-varients.ts"],
4
- "sourcesContent": ["import { groupBy, uniqBy } from 'lodash-es';\nimport type {\n ReferenceObject,\n SchemaObject,\n SchemaObjectType,\n} from 'openapi3-ts/oas31';\n\nimport { camelcase, isEmpty, isRef, resolveRef } from '@sdk-it/core';\n\nimport { coerceTypes } from './tune.js';\nimport type { IR } from './types.js';\n\nexport type Varient = {\n name: string;\n type: string;\n position: number;\n priority?: number;\n description?: string;\n source?: string;\n static?: boolean;\n subtype?: SchemaObjectType;\n};\n\nconst groupSchemasByType = (\n spec: IR,\n schemas: (SchemaObject | ReferenceObject)[],\n) => {\n const groups = schemas.reduce<\n Partial<{\n [\n K in SchemaObjectType | '$ref' | 'oneOf' | 'anyOf'\n ]: K extends SchemaObjectType\n ? { schema: SchemaObject; position: number }[]\n : K extends 'oneOf' | 'anyOf'\n ? { schema: (SchemaObject | ReferenceObject)[]; position: number }[]\n : { schema: ReferenceObject; position: number }[];\n }>\n >((acc, schema, index) => {\n if (isRef(schema)) {\n const referenced = resolveRef<SchemaObject>(spec, schema);\n const [type] = coerceTypes(referenced, false);\n acc[type] ??= [];\n acc[type].push({ schema: referenced, position: index });\n return acc;\n }\n\n if (isRef(schema.items)) {\n const referenced = resolveRef<SchemaObject>(spec, schema.items);\n acc.array ??= [];\n acc.array.push({\n schema: { ...schema, items: referenced },\n position: index,\n });\n return acc;\n }\n if (schema.oneOf) {\n acc['oneOf'] ??= [];\n acc['oneOf'].push({ schema: schema.oneOf, position: index });\n return acc;\n }\n if (schema.anyOf) {\n acc['oneOf'] ??= [];\n acc['oneOf'].push({ schema: schema.anyOf, position: index });\n return acc;\n }\n if (schema.const) {\n switch (typeof schema.const) {\n case 'string':\n acc.string ??= [];\n acc.string.push({ schema, position: index });\n return acc;\n case 'number':\n acc.number ??= [];\n acc.number.push({ schema, position: index });\n return acc;\n case 'boolean':\n acc.boolean ??= [];\n acc.boolean.push({ schema, position: index });\n return acc;\n default:\n throw new Error(\n `Unsupported const type: ${typeof schema.const} for ${schema.const}`,\n );\n }\n }\n\n const [type] = coerceTypes(schema, false);\n acc[type] ??= [];\n acc[type].push({ schema, position: index });\n return acc;\n }, {});\n\n return groups;\n};\n\nexport function findVarients(\n spec: IR,\n schemas: (SchemaObject | ReferenceObject)[],\n): Varient[] {\n let varients: Varient[] = [];\n const schemasByType = groupSchemasByType(spec, schemas);\n if (!isEmpty(schemasByType.string)) {\n for (const { schema, position } of schemasByType.string) {\n if (schema.const !== undefined) {\n varients.push({\n name: schema.const || 'empty',\n type: 'string',\n position,\n priority: 100 - varients.length,\n });\n continue;\n }\n\n if (schema.format) {\n varients.push({\n name: camelcase(schema.format),\n type: 'string',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n\n // if (!isEmpty(schema.enum)) {\n // for (const enumValue of schema.enum) {\n // if (enumValue === '') {\n // varients.push({\n // name: 'empty',\n // type: 'string',\n // position,\n // priority: 80 - varients.length,\n // });\n // continue;\n // }\n // varients.push({\n // name: enumValue,\n // type: 'string',\n // position,\n // priority: 80 - varients.length,\n // });\n // }\n // continue;\n // }\n\n varients.push({ name: 'text', type: 'string', position });\n }\n varients = uniqBy(varients, (it) => it.name);\n }\n\n if (!isEmpty(schemasByType.number) || !isEmpty(schemasByType.integer)) {\n const schemas = [\n ...(schemasByType.number ?? []),\n ...(schemasByType.integer ?? []),\n ];\n for (const { schema, position } of schemas) {\n if (schema.format === 'int64') {\n varients.push({\n name: 'integer',\n type: 'number',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n if (schema.format === 'float') {\n varients.push({\n name: 'float',\n type: 'number',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n if (schema.format === 'double') {\n varients.push({\n name: 'double',\n type: 'number',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n varients.push({ name: 'number', type: 'number', position });\n }\n }\n\n if (!isEmpty(schemasByType.array)) {\n for (const { schema, position } of schemasByType.array) {\n const items = schema.items;\n if (!items) {\n varients.push({ name: 'any', type: 'array', position });\n continue;\n }\n const [type] = coerceTypes(items as SchemaObject);\n if (type === 'string') {\n varients.push({\n name: 'textList',\n type: 'array',\n subtype: 'string',\n position,\n });\n continue;\n }\n if (type === 'number') {\n varients.push({\n name: 'numList',\n type: 'array',\n subtype: 'number',\n position,\n });\n continue;\n }\n if (type === 'integer') {\n varients.push({\n name: 'intList',\n type: 'array',\n subtype: 'integer',\n position,\n });\n continue;\n }\n if (type === 'object') {\n const subvarients = findVarients(spec, [items]);\n for (const subvarient of subvarients) {\n varients.push({\n ...subvarient,\n type: 'array',\n position,\n });\n }\n continue;\n }\n if (type === 'array') {\n const subvarients = findVarients(spec, [items]);\n for (const subvarient of subvarients) {\n varients.push({\n ...subvarient,\n name: `${subvarient.name}Matrix`,\n type: 'array',\n position,\n });\n }\n continue;\n }\n varients.push({ name: 'list', type: 'array', position });\n }\n }\n\n if (!isEmpty(schemasByType.$ref)) {\n const subvarients = findVarients(\n spec,\n schemasByType.$ref.map((it) => resolveRef(spec, it.schema)),\n );\n varients.push(\n ...subvarients.map((it) => ({\n ...it,\n })),\n );\n }\n\n if (!isEmpty(schemasByType.oneOf)) {\n for (const { schema, position } of schemasByType.oneOf) {\n const subvarients = findVarients(spec, schema);\n varients.push(\n ...subvarients.map((it) => ({\n ...it,\n position,\n })),\n );\n }\n }\n\n const matrix: Varient[][] = [];\n\n for (const { schema, position } of schemasByType.object ?? []) {\n if (schema.additionalProperties) {\n varients.push({ name: 'object', type: 'object', position });\n continue;\n }\n if (isEmpty({ ...schema.properties, ...schema['x-properties'] })) {\n continue;\n }\n\n for (const key of ['properties', 'x-properties'] as const) {\n if (!schema[key]) continue;\n const list = (\n Object.entries(schema[key]) as [\n string,\n SchemaObject | ReferenceObject,\n ][]\n ).map(([name, schemaOrRef]) => {\n const schema = resolveRef<SchemaObject>(spec, schemaOrRef);\n name = schema.const ?? schema.enum?.[0] ?? name;\n if (schema.type === 'string') {\n return {\n static: true,\n subtype: 'string',\n source: name,\n name: name,\n type: 'object',\n position,\n } satisfies Varient;\n }\n return {\n subtype: 'string',\n source: name,\n name: name,\n type: 'object',\n position,\n } satisfies Varient;\n });\n matrix.push([...new Set(list)].sort((a) => (a.static ? -1 : 1)));\n }\n if (matrix.length === 0) {\n throw new Error(\n 'No valid objects found. Please check your OpenAPI spec.',\n );\n }\n }\n\n for (const row of matrix) {\n for (const prop of row) {\n // check if this prop is unique across all rows\n const isUnique = matrix.every((it) =>\n it === row ? true : !it.some((p) => p.name === prop.name),\n );\n if (isUnique) {\n varients.push(prop);\n break;\n }\n }\n }\n\n // Sort all variants by priority (highest first), then by original position\n return varients.sort((a, b) => {\n const aHasPriority = a.priority !== undefined;\n const bHasPriority = b.priority !== undefined;\n\n if (aHasPriority && bHasPriority) {\n // Both have priority\n if (a.priority !== b.priority) {\n return b.priority! - a.priority!; // Higher priority first\n }\n // Priorities are equal, sort by original position as a tie-breaker\n return a.position - b.position;\n } else if (aHasPriority) {\n return -1; // 'a' comes first\n } else if (bHasPriority) {\n return 1; // 'b' comes first\n } else {\n // Neither has priority. Keep their relative order from before this sort.\n // This relies on a stable sort (standard in ES2019+).\n // Returning 0 preserves the order in which they were added to the 'varients' array.\n return 0;\n }\n });\n}\n\nexport function findPolymorphicVarients(\n spec: IR,\n schemas: (SchemaObject | ReferenceObject)[],\n): Varient[] {\n const varients = findVarients(spec, schemas);\n // prepend '-' to prevent key sortings\n return Object.values(groupBy(varients, (it) => '-' + it.position)).map(\n (group) => {\n return (group ?? [])[0];\n },\n );\n}\n"],
4
+ "sourcesContent": ["import { groupBy, uniqBy } from 'lodash-es';\nimport type {\n ReferenceObject,\n SchemaObject,\n SchemaObjectType,\n} from 'openapi3-ts/oas31';\n\nimport { camelcase, isEmpty, isRef, resolveRef } from '@sdk-it/core';\n\nimport { coerceTypes } from './is.js';\nimport type { IR } from './types.js';\n\nexport type Varient = {\n name: string;\n type: string;\n position: number;\n priority?: number;\n description?: string;\n source?: string;\n static?: boolean;\n subtype?: SchemaObjectType;\n};\n\nconst groupSchemasByType = (\n spec: IR,\n schemas: (SchemaObject | ReferenceObject)[],\n) => {\n const groups = schemas.reduce<\n Partial<{\n [\n K in SchemaObjectType | '$ref' | 'oneOf' | 'anyOf'\n ]: K extends SchemaObjectType\n ? { schema: SchemaObject; position: number }[]\n : K extends 'oneOf' | 'anyOf'\n ? { schema: (SchemaObject | ReferenceObject)[]; position: number }[]\n : { schema: ReferenceObject; position: number }[];\n }>\n >((acc, schema, index) => {\n if (isRef(schema)) {\n const referenced = resolveRef<SchemaObject>(spec, schema);\n const [type] = coerceTypes(referenced, false);\n acc[type] ??= [];\n acc[type].push({ schema: referenced, position: index });\n return acc;\n }\n\n if (isRef(schema.items)) {\n const referenced = resolveRef<SchemaObject>(spec, schema.items);\n acc.array ??= [];\n acc.array.push({\n schema: { ...schema, items: referenced },\n position: index,\n });\n return acc;\n }\n if (schema.oneOf) {\n acc['oneOf'] ??= [];\n acc['oneOf'].push({ schema: schema.oneOf, position: index });\n return acc;\n }\n if (schema.anyOf) {\n acc['oneOf'] ??= [];\n acc['oneOf'].push({ schema: schema.anyOf, position: index });\n return acc;\n }\n if (schema.const) {\n switch (typeof schema.const) {\n case 'string':\n acc.string ??= [];\n acc.string.push({ schema, position: index });\n return acc;\n case 'number':\n acc.number ??= [];\n acc.number.push({ schema, position: index });\n return acc;\n case 'boolean':\n acc.boolean ??= [];\n acc.boolean.push({ schema, position: index });\n return acc;\n default:\n throw new Error(\n `Unsupported const type: ${typeof schema.const} for ${schema.const}`,\n );\n }\n }\n\n const [type] = coerceTypes(schema, false);\n acc[type] ??= [];\n acc[type].push({ schema, position: index });\n return acc;\n }, {});\n\n return groups;\n};\n\nexport function findVarients(\n spec: IR,\n schemas: (SchemaObject | ReferenceObject)[],\n): Varient[] {\n let varients: Varient[] = [];\n const schemasByType = groupSchemasByType(spec, schemas);\n if (!isEmpty(schemasByType.string)) {\n for (const { schema, position } of schemasByType.string) {\n if (schema.const !== undefined) {\n varients.push({\n name: schema.const || 'empty',\n type: 'string',\n position,\n priority: 100 - varients.length,\n });\n continue;\n }\n\n if (schema.format) {\n varients.push({\n name: camelcase(schema.format),\n type: 'string',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n\n // if (!isEmpty(schema.enum)) {\n // for (const enumValue of schema.enum) {\n // if (enumValue === '') {\n // varients.push({\n // name: 'empty',\n // type: 'string',\n // position,\n // priority: 80 - varients.length,\n // });\n // continue;\n // }\n // varients.push({\n // name: enumValue,\n // type: 'string',\n // position,\n // priority: 80 - varients.length,\n // });\n // }\n // continue;\n // }\n\n varients.push({ name: 'text', type: 'string', position });\n }\n varients = uniqBy(varients, (it) => it.name);\n }\n\n if (!isEmpty(schemasByType.number) || !isEmpty(schemasByType.integer)) {\n const schemas = [\n ...(schemasByType.number ?? []),\n ...(schemasByType.integer ?? []),\n ];\n for (const { schema, position } of schemas) {\n if (schema.format === 'int64') {\n varients.push({\n name: 'integer',\n type: 'number',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n if (schema.format === 'float') {\n varients.push({\n name: 'float',\n type: 'number',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n if (schema.format === 'double') {\n varients.push({\n name: 'double',\n type: 'number',\n position,\n priority: 90 - varients.length,\n });\n continue;\n }\n varients.push({ name: 'number', type: 'number', position });\n }\n }\n\n if (!isEmpty(schemasByType.array)) {\n for (const { schema, position } of schemasByType.array) {\n const items = schema.items;\n if (!items) {\n varients.push({ name: 'any', type: 'array', position });\n continue;\n }\n const [type] = coerceTypes(items as SchemaObject);\n if (type === 'string') {\n varients.push({\n name: 'textList',\n type: 'array',\n subtype: 'string',\n position,\n });\n continue;\n }\n if (type === 'number') {\n varients.push({\n name: 'numList',\n type: 'array',\n subtype: 'number',\n position,\n });\n continue;\n }\n if (type === 'integer') {\n varients.push({\n name: 'intList',\n type: 'array',\n subtype: 'integer',\n position,\n });\n continue;\n }\n if (type === 'object') {\n const subvarients = findVarients(spec, [items]);\n for (const subvarient of subvarients) {\n varients.push({\n ...subvarient,\n type: 'array',\n position,\n });\n }\n continue;\n }\n if (type === 'array') {\n const subvarients = findVarients(spec, [items]);\n for (const subvarient of subvarients) {\n varients.push({\n ...subvarient,\n name: `${subvarient.name}Matrix`,\n type: 'array',\n position,\n });\n }\n continue;\n }\n varients.push({ name: 'list', type: 'array', position });\n }\n }\n\n if (!isEmpty(schemasByType.$ref)) {\n const subvarients = findVarients(\n spec,\n schemasByType.$ref.map((it) => resolveRef(spec, it.schema)),\n );\n varients.push(\n ...subvarients.map((it) => ({\n ...it,\n })),\n );\n }\n\n if (!isEmpty(schemasByType.oneOf)) {\n for (const { schema, position } of schemasByType.oneOf) {\n const subvarients = findVarients(spec, schema);\n varients.push(\n ...subvarients.map((it) => ({\n ...it,\n position,\n })),\n );\n }\n }\n\n const matrix: Varient[][] = [];\n\n for (const { schema, position } of schemasByType.object ?? []) {\n if (schema.additionalProperties) {\n varients.push({ name: 'object', type: 'object', position });\n continue;\n }\n if (isEmpty({ ...schema.properties, ...schema['x-properties'] })) {\n continue;\n }\n\n for (const key of ['properties', 'x-properties'] as const) {\n if (!schema[key]) continue;\n const list = (\n Object.entries(schema[key]) as [\n string,\n SchemaObject | ReferenceObject,\n ][]\n ).map(([name, schemaOrRef]) => {\n const schema = resolveRef<SchemaObject>(spec, schemaOrRef);\n name = schema.const ?? schema.enum?.[0] ?? name;\n if (schema.type === 'string') {\n return {\n static: true,\n subtype: 'string',\n source: name,\n name: name,\n type: 'object',\n position,\n } satisfies Varient;\n }\n return {\n subtype: 'string',\n source: name,\n name: name,\n type: 'object',\n position,\n } satisfies Varient;\n });\n matrix.push([...new Set(list)].sort((a) => (a.static ? -1 : 1)));\n }\n if (matrix.length === 0) {\n throw new Error(\n 'No valid objects found. Please check your OpenAPI spec.',\n );\n }\n }\n\n for (const row of matrix) {\n for (const prop of row) {\n // check if this prop is unique across all rows\n const isUnique = matrix.every((it) =>\n it === row ? true : !it.some((p) => p.name === prop.name),\n );\n if (isUnique) {\n varients.push(prop);\n break;\n }\n }\n }\n\n // Sort all variants by priority (highest first), then by original position\n return varients.sort((a, b) => {\n const aHasPriority = a.priority !== undefined;\n const bHasPriority = b.priority !== undefined;\n\n if (aHasPriority && bHasPriority) {\n // Both have priority\n if (a.priority !== b.priority) {\n return b.priority! - a.priority!; // Higher priority first\n }\n // Priorities are equal, sort by original position as a tie-breaker\n return a.position - b.position;\n } else if (aHasPriority) {\n return -1; // 'a' comes first\n } else if (bHasPriority) {\n return 1; // 'b' comes first\n } else {\n // Neither has priority. Keep their relative order from before this sort.\n // This relies on a stable sort (standard in ES2019+).\n // Returning 0 preserves the order in which they were added to the 'varients' array.\n return 0;\n }\n });\n}\n\nexport function findPolymorphicVarients(\n spec: IR,\n schemas: (SchemaObject | ReferenceObject)[],\n): Varient[] {\n const varients = findVarients(spec, schemas);\n // prepend '-' to prevent key sortings\n return Object.values(groupBy(varients, (it) => '-' + it.position)).map(\n (group) => {\n return (group ?? [])[0];\n },\n );\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["type", "schemas", "schema"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import { coerceTypes } from "./tune.js";
1
+ import { coerceTypes } from "./is.js";
2
2
  function isPrimitiveSchema(schema) {
3
3
  const types = coerceTypes(schema, false);
4
4
  if (!types || types.length === 0) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/is-primitive-schema.ts"],
4
- "sourcesContent": ["import type { SchemaObject } from 'openapi3-ts/oas31';\n\nimport { coerceTypes } from './tune.js';\n\nexport function isPrimitiveSchema(schema: SchemaObject) {\n const types = coerceTypes(schema, false);\n if (!types || types.length === 0) {\n return false;\n }\n return types.includes('object') === false;\n}\n"],
4
+ "sourcesContent": ["import type { SchemaObject } from 'openapi3-ts/oas31';\n\nimport { coerceTypes } from './is.js';\n\nexport function isPrimitiveSchema(schema: SchemaObject) {\n const types = coerceTypes(schema, false);\n if (!types || types.length === 0) {\n return false;\n }\n return types.includes('object') === false;\n}\n"],
5
5
  "mappings": "AAEA,SAAS,mBAAmB;AAErB,SAAS,kBAAkB,QAAsB;AACtD,QAAM,QAAQ,YAAY,QAAQ,KAAK;AACvC,MAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AACA,SAAO,MAAM,SAAS,QAAQ,MAAM;AACtC;",
6
6
  "names": []
7
7
  }
package/dist/lib/is.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { SchemaObject, SchemaObjectType } from 'openapi3-ts/oas31';
2
+ export declare function coerceTypes(schema: SchemaObject, excludeNull?: boolean): SchemaObjectType[];
1
3
  export declare function isStreamingContentType(contentType: string | null | undefined): boolean;
2
4
  export declare function isBinaryContentType(contentType: string | null | undefined): boolean;
3
5
  export declare function isSuccessStatusCode(statusCode: number | string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"is.d.ts","sourceRoot":"","sources":["../../src/lib/is.ts"],"names":[],"mappings":"AAAA,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAET;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAkET;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAMxE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CActE;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,iBAuB1E;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAiBT;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAoBT"}
1
+ {"version":3,"file":"is.d.ts","sourceRoot":"","sources":["../../src/lib/is.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAExE,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,WAAW,UAAO,GACjB,gBAAgB,EAAE,CAOpB;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAET;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAkET;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAMxE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CActE;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,iBAuB1E;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAiBT;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAoBT"}
package/dist/lib/is.js CHANGED
@@ -1,3 +1,7 @@
1
+ function coerceTypes(schema, excludeNull = true) {
2
+ const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
3
+ return excludeNull ? types.filter((type) => type !== "null") : types;
4
+ }
1
5
  function isStreamingContentType(contentType) {
2
6
  return contentType === "application/octet-stream";
3
7
  }
@@ -119,6 +123,7 @@ function isSseContentType(contentType) {
119
123
  return mainType === "text/event-stream";
120
124
  }
121
125
  export {
126
+ coerceTypes,
122
127
  isBinaryContentType,
123
128
  isErrorStatusCode,
124
129
  isSseContentType,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/is.ts"],
4
- "sourcesContent": ["export function isStreamingContentType(\n contentType: string | null | undefined,\n): boolean {\n return contentType === 'application/octet-stream';\n}\n\nexport function isBinaryContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false;\n }\n\n let mainType = contentType.trim();\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n mainType = mainType.toLowerCase();\n\n if (mainType.startsWith('text/')) {\n return false;\n }\n if (mainType.endsWith('/json') || mainType.endsWith('+json')) {\n return false;\n }\n if (mainType.endsWith('/xml') || mainType.endsWith('+xml')) {\n return false;\n }\n if (mainType === 'application/xml' || mainType === 'text/xml') {\n return false;\n }\n if (\n mainType === 'application/x-www-form-urlencoded' ||\n mainType === 'multipart/form-data'\n ) {\n return false;\n }\n\n if (mainType.startsWith('image/')) {\n return true;\n }\n if (mainType.startsWith('audio/')) {\n return true;\n }\n if (mainType.startsWith('video/')) {\n return true;\n }\n if (mainType === 'application/pdf') {\n return true;\n }\n if (mainType === 'application/zip') {\n return true;\n }\n if (mainType === 'application/gzip') {\n return true;\n }\n if (mainType === 'application/x-7z-compressed') {\n return true;\n }\n if (mainType === 'application/x-tar') {\n return true;\n }\n if (mainType.startsWith('application/vnd.openxmlformats-officedocument.')) {\n return true;\n }\n if (mainType.startsWith('application/vnd.ms-')) {\n return true;\n }\n if (mainType === 'application/msword') {\n return true;\n }\n\n return false;\n}\n\nexport function isSuccessStatusCode(statusCode: number | string): boolean {\n if (typeof statusCode === 'string') {\n return /^2(?:\\d{2}|xx)$/i.test(statusCode.trim());\n }\n statusCode = Number(statusCode);\n return statusCode >= 200 && statusCode < 300;\n}\n\nexport function isErrorStatusCode(statusCode: number | string): boolean {\n if (typeof statusCode === 'string') {\n const statusGroup = +statusCode.slice(0, 1);\n const status = Number(statusCode);\n return (\n status < 200 ||\n status >= 300 ||\n statusGroup >= 4 ||\n statusGroup === 0 ||\n statusGroup === 1\n );\n }\n statusCode = Number(statusCode);\n return statusCode < 200 || statusCode >= 300;\n}\n\nexport function parseJsonContentType(contentType: string | null | undefined) {\n if (!contentType) {\n return null;\n }\n\n // 1. Trim whitespace\n let mainType = contentType.trim();\n\n // 2. Remove parameters (anything after the first ';')\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim(); // Trim potential space before ';'\n }\n\n // 3. Convert to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n if (mainType.endsWith('/json')) {\n return mainType.split('/')[1];\n } else if (mainType.endsWith('+json')) {\n return mainType.split('+')[1];\n }\n return null;\n}\n\nexport function isTextContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n // 4. Compare against the standard text MIME types\n return mainType.startsWith('text/'); // Catch-all for other text/* types\n}\n\n/**\n * Checks if a given content type string represents Server-Sent Events (SSE).\n * Handles case-insensitivity, parameters (like charset), and leading/trailing whitespace.\n *\n * @param contentType The content type string to check (e.g., from a Content-Type header).\n * @returns True if the content type is 'text/event-stream', false otherwise.\n */\nexport function isSseContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n // 4. Compare against the standard SSE MIME type\n return mainType === 'text/event-stream';\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { SchemaObject, SchemaObjectType } from 'openapi3-ts/oas31';\n\nexport function coerceTypes(\n schema: SchemaObject,\n excludeNull = true,\n): SchemaObjectType[] {\n const types = Array.isArray(schema.type)\n ? schema.type\n : schema.type\n ? [schema.type]\n : [];\n return excludeNull ? types.filter((type) => type !== 'null') : types;\n}\n\nexport function isStreamingContentType(\n contentType: string | null | undefined,\n): boolean {\n return contentType === 'application/octet-stream';\n}\n\nexport function isBinaryContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false;\n }\n\n let mainType = contentType.trim();\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n mainType = mainType.toLowerCase();\n\n if (mainType.startsWith('text/')) {\n return false;\n }\n if (mainType.endsWith('/json') || mainType.endsWith('+json')) {\n return false;\n }\n if (mainType.endsWith('/xml') || mainType.endsWith('+xml')) {\n return false;\n }\n if (mainType === 'application/xml' || mainType === 'text/xml') {\n return false;\n }\n if (\n mainType === 'application/x-www-form-urlencoded' ||\n mainType === 'multipart/form-data'\n ) {\n return false;\n }\n\n if (mainType.startsWith('image/')) {\n return true;\n }\n if (mainType.startsWith('audio/')) {\n return true;\n }\n if (mainType.startsWith('video/')) {\n return true;\n }\n if (mainType === 'application/pdf') {\n return true;\n }\n if (mainType === 'application/zip') {\n return true;\n }\n if (mainType === 'application/gzip') {\n return true;\n }\n if (mainType === 'application/x-7z-compressed') {\n return true;\n }\n if (mainType === 'application/x-tar') {\n return true;\n }\n if (mainType.startsWith('application/vnd.openxmlformats-officedocument.')) {\n return true;\n }\n if (mainType.startsWith('application/vnd.ms-')) {\n return true;\n }\n if (mainType === 'application/msword') {\n return true;\n }\n\n return false;\n}\n\nexport function isSuccessStatusCode(statusCode: number | string): boolean {\n if (typeof statusCode === 'string') {\n return /^2(?:\\d{2}|xx)$/i.test(statusCode.trim());\n }\n statusCode = Number(statusCode);\n return statusCode >= 200 && statusCode < 300;\n}\n\nexport function isErrorStatusCode(statusCode: number | string): boolean {\n if (typeof statusCode === 'string') {\n const statusGroup = +statusCode.slice(0, 1);\n const status = Number(statusCode);\n return (\n status < 200 ||\n status >= 300 ||\n statusGroup >= 4 ||\n statusGroup === 0 ||\n statusGroup === 1\n );\n }\n statusCode = Number(statusCode);\n return statusCode < 200 || statusCode >= 300;\n}\n\nexport function parseJsonContentType(contentType: string | null | undefined) {\n if (!contentType) {\n return null;\n }\n\n // 1. Trim whitespace\n let mainType = contentType.trim();\n\n // 2. Remove parameters (anything after the first ';')\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim(); // Trim potential space before ';'\n }\n\n // 3. Convert to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n if (mainType.endsWith('/json')) {\n return mainType.split('/')[1];\n } else if (mainType.endsWith('+json')) {\n return mainType.split('+')[1];\n }\n return null;\n}\n\nexport function isTextContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n // 4. Compare against the standard text MIME types\n return mainType.startsWith('text/'); // Catch-all for other text/* types\n}\n\n/**\n * Checks if a given content type string represents Server-Sent Events (SSE).\n * Handles case-insensitivity, parameters (like charset), and leading/trailing whitespace.\n *\n * @param contentType The content type string to check (e.g., from a Content-Type header).\n * @returns True if the content type is 'text/event-stream', false otherwise.\n */\nexport function isSseContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n // 4. Compare against the standard SSE MIME type\n return mainType === 'text/event-stream';\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { isRef } from "@sdk-it/core/ref.js";
2
2
  import { isEmpty } from "@sdk-it/core/utils.js";
3
- import { coerceTypes } from "../tune.js";
3
+ import { coerceTypes } from "../is.js";
4
4
  import { getHasMoreName, getItemsName } from "./pagination-result.js";
5
5
  const OFFSET_PARAM_REGEXES = [
6
6
  /\boffset\b/i,
@@ -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 | 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"],
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 '../is.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
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extract-inline-schemas.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/extract-inline-schemas.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,wBAAgB,oBAAoB,IAAI,gBAAgB,CAQvD"}
1
+ {"version":3,"file":"extract-inline-schemas.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/extract-inline-schemas.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AA4LzD,wBAAgB,oBAAoB,IAAI,gBAAgB,CAOvD"}
@@ -1,10 +1,158 @@
1
- import { expandSpec } from "../tune.js";
1
+ import { isEmpty, isRef, joinSkipDigits, pascalcase } from "@sdk-it/core";
2
+ import { findUniqueSchemaName } from "../find-unique-schema-name.js";
3
+ function extractInlineSchemaComponents(spec, schemas) {
4
+ for (const [name, schema] of Object.entries(schemas)) {
5
+ if (isRef(schema)) continue;
6
+ if (!isEmpty(schema.properties)) {
7
+ if (!isEmpty(schema.oneOf)) {
8
+ for (const [oneOfIndex, oneOf] of schema.oneOf.entries()) {
9
+ if (isRef(oneOf)) continue;
10
+ const requiredProperty = oneOf.required?.[0];
11
+ if (requiredProperty && isEmpty(oneOf.properties) && isEmpty(oneOf["x-properties"])) {
12
+ schema.oneOf[oneOfIndex] = schema.properties?.[requiredProperty] ?? schema["x-properties"]?.[requiredProperty] ?? oneOf;
13
+ }
14
+ }
15
+ delete schema.type;
16
+ extractInlineUnion(spec, name, schema, "oneOf");
17
+ }
18
+ if (schema.additionalProperties) {
19
+ continue;
20
+ }
21
+ spec.components.schemas[name] = schema;
22
+ const properties = schema.properties;
23
+ for (const [propertyName, value] of Object.entries(properties)) {
24
+ if (isRef(value)) continue;
25
+ const fixedPropertyName = propertyName.replace("[]", "");
26
+ const refName = findUniqueSchemaName(
27
+ spec,
28
+ pascalcase(joinSkipDigits([name, fixedPropertyName], " ")),
29
+ ["Property", "Field", "Attribute"]
30
+ );
31
+ if (!isEmpty(value.properties)) {
32
+ spec.components.schemas[refName] = value;
33
+ properties[propertyName] = {
34
+ $ref: `#/components/schemas/${refName}`
35
+ };
36
+ extractInlineSchemaComponents(spec, { [refName]: value });
37
+ } else if (!isEmpty(value.oneOf)) {
38
+ extractInlineUnion(spec, name, value, "oneOf");
39
+ spec.components.schemas[refName] = value;
40
+ properties[propertyName] = {
41
+ $ref: `#/components/schemas/${refName}`
42
+ };
43
+ extractInlineSchemaComponents(spec, { [refName]: value });
44
+ } else if (!isEmpty(value.anyOf)) {
45
+ extractInlineUnion(spec, name, value, "anyOf");
46
+ spec.components.schemas[refName] = value;
47
+ properties[propertyName] = {
48
+ $ref: `#/components/schemas/${refName}`
49
+ };
50
+ extractInlineSchemaComponents(spec, { [refName]: value });
51
+ } else {
52
+ extractInlineSchemaComponents(spec, { [refName]: value });
53
+ }
54
+ }
55
+ continue;
56
+ }
57
+ if (!isEmpty(schema["x-properties"])) {
58
+ spec.components.schemas[name] = schema;
59
+ const properties = schema["x-properties"];
60
+ for (const [propertyName, value] of Object.entries(properties)) {
61
+ if (isRef(value)) continue;
62
+ const fixedPropertyName = propertyName.replace("[]", "");
63
+ const refName = findUniqueSchemaName(
64
+ spec,
65
+ pascalcase(joinSkipDigits([name, fixedPropertyName], " ")),
66
+ ["Property", "Field", "Attribute"]
67
+ );
68
+ if (!isEmpty(value.properties)) {
69
+ spec.components.schemas[refName] = value;
70
+ properties[propertyName] = {
71
+ $ref: `#/components/schemas/${refName}`
72
+ };
73
+ extractInlineSchemaComponents(spec, { [refName]: value });
74
+ } else if (!isEmpty(value.oneOf)) {
75
+ extractInlineUnion(spec, name, value, "oneOf");
76
+ spec.components.schemas[refName] = value;
77
+ properties[propertyName] = {
78
+ $ref: `#/components/schemas/${refName}`
79
+ };
80
+ extractInlineSchemaComponents(spec, { [refName]: value });
81
+ } else if (!isEmpty(value.anyOf)) {
82
+ extractInlineUnion(spec, name, value, "anyOf");
83
+ spec.components.schemas[refName] = value;
84
+ properties[propertyName] = {
85
+ $ref: `#/components/schemas/${refName}`
86
+ };
87
+ extractInlineSchemaComponents(spec, { [refName]: value });
88
+ } else {
89
+ extractInlineSchemaComponents(spec, { [refName]: value });
90
+ }
91
+ }
92
+ continue;
93
+ }
94
+ if (schema.type === "array") {
95
+ if (isRef(schema.items) || isEmpty(schema.items)) continue;
96
+ const refName = findUniqueSchemaName(spec, name, ["Item", "Entry"]);
97
+ if (schema.items.type === "object") {
98
+ spec.components.schemas[refName] = schema.items;
99
+ extractInlineSchemaComponents(spec, { [refName]: schema.items });
100
+ schema.items = { $ref: `#/components/schemas/${refName}` };
101
+ continue;
102
+ }
103
+ if (schema.items.type === "array") {
104
+ extractInlineSchemaComponents(spec, { [refName]: schema.items });
105
+ continue;
106
+ }
107
+ if (!isEmpty(schema.items.oneOf)) {
108
+ extractInlineUnion(spec, refName, schema.items, "oneOf");
109
+ continue;
110
+ }
111
+ if (!isEmpty(schema.items.anyOf)) {
112
+ extractInlineUnion(spec, refName, schema.items, "anyOf");
113
+ continue;
114
+ }
115
+ }
116
+ if (!isEmpty(schema.oneOf)) {
117
+ extractInlineUnion(spec, name, schema, "oneOf");
118
+ continue;
119
+ }
120
+ if (!isEmpty(schema.anyOf)) {
121
+ extractInlineUnion(spec, name, schema, "anyOf");
122
+ }
123
+ }
124
+ }
125
+ function extractInlineUnion(spec, name, schema, kind) {
126
+ const varients = schema["x-varients"];
127
+ if (!varients || varients.length === 0) {
128
+ console.warn(
129
+ `No varients found for ${name}. This might be an error in the OpenAPI spec.`
130
+ );
131
+ }
132
+ varients.forEach((varient) => {
133
+ const varientSchema = schema[kind][varient.position];
134
+ if (isRef(varientSchema)) return;
135
+ const refName = findUniqueSchemaName(
136
+ spec,
137
+ pascalcase(`${name} ${varient.name}`),
138
+ ["Varient"]
139
+ );
140
+ if (varientSchema.type === "object") {
141
+ spec.components.schemas[refName] = varientSchema;
142
+ extractInlineSchemaComponents(spec, { [refName]: varientSchema });
143
+ schema[kind][varient.position] = {
144
+ $ref: `#/components/schemas/${refName}`
145
+ };
146
+ } else {
147
+ extractInlineSchemaComponents(spec, { [refName]: varientSchema });
148
+ }
149
+ });
150
+ }
2
151
  function extractInlineSchemas() {
3
152
  return {
4
153
  name: "extract-inline-schemas",
5
154
  process({ spec }) {
6
- const refs = [];
7
- expandSpec(spec, spec.components.schemas, refs);
155
+ extractInlineSchemaComponents(spec, spec.components.schemas);
8
156
  }
9
157
  };
10
158
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/processing-plugins/extract-inline-schemas.ts"],
4
- "sourcesContent": ["import type { SchemaObject } from 'openapi3-ts/oas31';\n\nimport type { ProcessingPlugin } from '../processing.js';\nimport { expandSpec } from '../tune.js';\n\nexport function extractInlineSchemas(): ProcessingPlugin {\n return {\n name: 'extract-inline-schemas',\n process({ spec }) {\n const refs: { name: string; value: SchemaObject }[] = [];\n expandSpec(spec, spec.components.schemas, refs);\n },\n };\n}\n"],
5
- "mappings": "AAGA,SAAS,kBAAkB;AAEpB,SAAS,uBAAyC;AACvD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,EAAE,KAAK,GAAG;AAChB,YAAM,OAAgD,CAAC;AACvD,iBAAW,MAAM,KAAK,WAAW,SAAS,IAAI;AAAA,IAChD;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { ReferenceObject, SchemaObject } from 'openapi3-ts/oas31';\n\nimport { isEmpty, isRef, joinSkipDigits, pascalcase } from '@sdk-it/core';\n\nimport type { Varient } from '../find-polymorphic-varients.js';\nimport { findUniqueSchemaName } from '../find-unique-schema-name.js';\nimport type { ProcessingPlugin } from '../processing.js';\nimport type { IR } from '../types.js';\n\nfunction extractInlineSchemaComponents(\n spec: IR,\n schemas: Record<string, SchemaObject | ReferenceObject>,\n) {\n for (const [name, schema] of Object.entries(schemas)) {\n if (isRef(schema)) continue;\n\n if (!isEmpty(schema.properties)) {\n if (!isEmpty(schema.oneOf)) {\n for (const [oneOfIndex, oneOf] of schema.oneOf.entries()) {\n if (isRef(oneOf)) continue;\n\n const requiredProperty = oneOf.required?.[0];\n if (\n requiredProperty &&\n isEmpty(oneOf.properties) &&\n isEmpty(oneOf['x-properties'])\n ) {\n schema.oneOf[oneOfIndex] =\n schema.properties?.[requiredProperty] ??\n schema['x-properties']?.[requiredProperty] ??\n oneOf;\n }\n }\n delete schema.type;\n extractInlineUnion(spec, name, schema, 'oneOf');\n }\n if (schema.additionalProperties) {\n continue;\n }\n spec.components.schemas[name] = schema;\n const properties = schema.properties as Record<\n string,\n SchemaObject | ReferenceObject\n >;\n for (const [propertyName, value] of Object.entries(properties)) {\n if (isRef(value)) continue;\n\n const fixedPropertyName = propertyName.replace('[]', '');\n const refName = findUniqueSchemaName(\n spec,\n pascalcase(joinSkipDigits([name, fixedPropertyName], ' ')),\n ['Property', 'Field', 'Attribute'],\n );\n\n if (!isEmpty(value.properties)) {\n spec.components.schemas[refName] = value;\n properties[propertyName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n extractInlineSchemaComponents(spec, { [refName]: value });\n } else if (!isEmpty(value.oneOf)) {\n extractInlineUnion(spec, name, value, 'oneOf');\n\n spec.components.schemas[refName] = value;\n properties[propertyName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n extractInlineSchemaComponents(spec, { [refName]: value });\n } else if (!isEmpty(value.anyOf)) {\n extractInlineUnion(spec, name, value, 'anyOf');\n\n spec.components.schemas[refName] = value;\n properties[propertyName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n extractInlineSchemaComponents(spec, { [refName]: value });\n } else {\n extractInlineSchemaComponents(spec, { [refName]: value });\n }\n }\n\n continue;\n }\n if (!isEmpty(schema['x-properties'])) {\n spec.components.schemas[name] = schema;\n\n const properties = schema['x-properties'] as Record<\n string,\n SchemaObject | ReferenceObject\n >;\n for (const [propertyName, value] of Object.entries(properties)) {\n if (isRef(value)) continue;\n\n const fixedPropertyName = propertyName.replace('[]', '');\n const refName = findUniqueSchemaName(\n spec,\n pascalcase(joinSkipDigits([name, fixedPropertyName], ' ')),\n ['Property', 'Field', 'Attribute'],\n );\n\n if (!isEmpty(value.properties)) {\n spec.components.schemas[refName] = value;\n properties[propertyName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n extractInlineSchemaComponents(spec, { [refName]: value });\n } else if (!isEmpty(value.oneOf)) {\n extractInlineUnion(spec, name, value, 'oneOf');\n\n spec.components.schemas[refName] = value;\n properties[propertyName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n extractInlineSchemaComponents(spec, { [refName]: value });\n } else if (!isEmpty(value.anyOf)) {\n extractInlineUnion(spec, name, value, 'anyOf');\n\n spec.components.schemas[refName] = value;\n properties[propertyName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n extractInlineSchemaComponents(spec, { [refName]: value });\n } else {\n extractInlineSchemaComponents(spec, { [refName]: value });\n }\n }\n continue;\n }\n\n if (schema.type === 'array') {\n if (isRef(schema.items) || isEmpty(schema.items)) continue;\n const refName = findUniqueSchemaName(spec, name, ['Item', 'Entry']);\n if (schema.items.type === 'object') {\n spec.components.schemas[refName] = schema.items;\n extractInlineSchemaComponents(spec, { [refName]: schema.items });\n schema.items = { $ref: `#/components/schemas/${refName}` };\n continue;\n }\n if (schema.items.type === 'array') {\n extractInlineSchemaComponents(spec, { [refName]: schema.items });\n continue;\n }\n if (!isEmpty(schema.items.oneOf)) {\n extractInlineUnion(spec, refName, schema.items, 'oneOf');\n continue;\n }\n if (!isEmpty(schema.items.anyOf)) {\n extractInlineUnion(spec, refName, schema.items, 'anyOf');\n continue;\n }\n }\n if (!isEmpty(schema.oneOf)) {\n extractInlineUnion(spec, name, schema, 'oneOf');\n continue;\n }\n if (!isEmpty(schema.anyOf)) {\n extractInlineUnion(spec, name, schema, 'anyOf');\n }\n }\n}\n\nfunction extractInlineUnion(\n spec: IR,\n name: string,\n schema: SchemaObject,\n kind: 'oneOf' | 'anyOf',\n) {\n const varients = schema['x-varients'] as Varient[];\n if (!varients || varients.length === 0) {\n console.warn(\n `No varients found for ${name}. This might be an error in the OpenAPI spec.`,\n );\n }\n varients.forEach((varient) => {\n const varientSchema = schema[kind]![varient.position];\n if (isRef(varientSchema)) return;\n const refName = findUniqueSchemaName(\n spec,\n pascalcase(`${name} ${varient.name}`),\n ['Varient'],\n );\n\n if (varientSchema.type === 'object') {\n spec.components.schemas[refName] = varientSchema;\n extractInlineSchemaComponents(spec, { [refName]: varientSchema });\n schema[kind]![varient.position] = {\n $ref: `#/components/schemas/${refName}`,\n };\n } else {\n extractInlineSchemaComponents(spec, { [refName]: varientSchema });\n }\n });\n}\n\nexport function extractInlineSchemas(): ProcessingPlugin {\n return {\n name: 'extract-inline-schemas',\n process({ spec }) {\n extractInlineSchemaComponents(spec, spec.components.schemas);\n },\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,6 @@
1
+ import type { ParameterObject, SchemaObject, SecurityRequirementObject } from 'openapi3-ts/oas31';
1
2
  import type { ProcessingPlugin } from '../processing.js';
3
+ import type { IR } from '../types.js';
4
+ export declare function patchParameters(spec: IR, schema: SchemaObject, parameters: ParameterObject[], security: SecurityRequirementObject[]): void;
2
5
  export declare function normalizeRequestBodies(): ProcessingPlugin;
3
6
  //# sourceMappingURL=normalize-request-bodies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-request-bodies.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/normalize-request-bodies.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzD,wBAAgB,sBAAsB,IAAI,gBAAgB,CAwCzD"}
1
+ {"version":3,"file":"normalize-request-bodies.d.ts","sourceRoot":"","sources":["../../../src/lib/processing-plugins/normalize-request-bodies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,YAAY,EACZ,yBAAyB,EAC1B,MAAM,mBAAmB,CAAC;AAO3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EACV,EAAE,EAGH,MAAM,aAAa,CAAC;AAErB,wBAAgB,eAAe,CAC7B,IAAI,EAAE,EAAE,EACR,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,eAAe,EAAE,EAC7B,QAAQ,EAAE,yBAAyB,EAAE,QAiCtC;AA+ED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAwCzD"}