openapi-typesafe 1.0.0-rc.5 → 1.0.0-rc.6

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 (148) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/adapters/redocly-loader/query-document-names.cjs +50 -0
  3. package/dist/adapters/redocly-loader/query-document-names.cjs.map +1 -0
  4. package/dist/adapters/redocly-loader/query-document-names.mjs +48 -0
  5. package/dist/adapters/redocly-loader/query-document-names.mjs.map +1 -0
  6. package/dist/adapters/redocly-loader/query-named-components.cjs +29 -37
  7. package/dist/adapters/redocly-loader/query-named-components.cjs.map +1 -1
  8. package/dist/adapters/redocly-loader/query-named-components.mjs +29 -37
  9. package/dist/adapters/redocly-loader/query-named-components.mjs.map +1 -1
  10. package/dist/adapters/redocly-loader/redocly-config-source.cjs +3 -0
  11. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
  12. package/dist/adapters/redocly-loader/redocly-config-source.mjs +4 -1
  13. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +16 -7
  15. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  16. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +17 -8
  17. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  18. package/dist/adapters/redocly-loader/ref-access.cjs +9 -1
  19. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  20. package/dist/adapters/redocly-loader/ref-access.mjs +10 -2
  21. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  22. package/dist/adapters/redocly-loader/remote-fetch.cjs +16 -1
  23. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  24. package/dist/adapters/redocly-loader/remote-fetch.mjs +16 -2
  25. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  26. package/dist/api/cwd-option.cjs +58 -0
  27. package/dist/api/cwd-option.cjs.map +1 -0
  28. package/dist/api/cwd-option.mjs +52 -0
  29. package/dist/api/cwd-option.mjs.map +1 -0
  30. package/dist/api/default-ports.cjs +15 -7
  31. package/dist/api/default-ports.cjs.map +1 -1
  32. package/dist/api/default-ports.mjs +14 -8
  33. package/dist/api/default-ports.mjs.map +1 -1
  34. package/dist/api/document-run.cjs +2 -16
  35. package/dist/api/document-run.cjs.map +1 -1
  36. package/dist/api/document-run.mjs +2 -12
  37. package/dist/api/document-run.mjs.map +1 -1
  38. package/dist/api/legacy-utils.cjs +1 -1
  39. package/dist/api/legacy-utils.cjs.map +1 -1
  40. package/dist/api/legacy-utils.mjs +1 -1
  41. package/dist/api/legacy-utils.mjs.map +1 -1
  42. package/dist/api/openapi-ts.cjs.map +1 -1
  43. package/dist/api/openapi-ts.mjs.map +1 -1
  44. package/dist/api/option-errors.cjs +24 -0
  45. package/dist/api/option-errors.cjs.map +1 -0
  46. package/dist/api/option-errors.mjs +21 -0
  47. package/dist/api/option-errors.mjs.map +1 -0
  48. package/dist/api/ref-limit-options.cjs +19 -24
  49. package/dist/api/ref-limit-options.cjs.map +1 -1
  50. package/dist/api/ref-limit-options.mjs +15 -20
  51. package/dist/api/ref-limit-options.mjs.map +1 -1
  52. package/dist/application/transform/document/path-template-refs.cjs +12 -2
  53. package/dist/application/transform/document/path-template-refs.cjs.map +1 -1
  54. package/dist/application/transform/document/path-template-refs.mjs +12 -2
  55. package/dist/application/transform/document/path-template-refs.mjs.map +1 -1
  56. package/dist/application/transform/ref-pointer/generated-shape.cjs +28 -10
  57. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -1
  58. package/dist/application/transform/ref-pointer/generated-shape.mjs +29 -11
  59. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -1
  60. package/dist/application/transform/ref-pointer/original-index.cjs +1 -1
  61. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -1
  62. package/dist/application/transform/ref-pointer/original-index.mjs +1 -1
  63. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -1
  64. package/dist/application/transform/ref-pointer/property-shape.cjs +5 -0
  65. package/dist/application/transform/ref-pointer/property-shape.cjs.map +1 -1
  66. package/dist/application/transform/ref-pointer/property-shape.mjs +5 -1
  67. package/dist/application/transform/ref-pointer/property-shape.mjs.map +1 -1
  68. package/dist/application/transform/ref-pointer/typed-walk.cjs +11 -1
  69. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -1
  70. package/dist/application/transform/ref-pointer/typed-walk.mjs +12 -2
  71. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -1
  72. package/dist/cli/api-settings.cjs +3 -2
  73. package/dist/cli/api-settings.cjs.map +1 -1
  74. package/dist/cli/api-settings.mjs +2 -1
  75. package/dist/cli/api-settings.mjs.map +1 -1
  76. package/dist/cli/api-writes.cjs +7 -1
  77. package/dist/cli/api-writes.cjs.map +1 -1
  78. package/dist/cli/api-writes.mjs +7 -1
  79. package/dist/cli/api-writes.mjs.map +1 -1
  80. package/dist/cli/cli-arguments.cjs +25 -107
  81. package/dist/cli/cli-arguments.cjs.map +1 -1
  82. package/dist/cli/cli-arguments.mjs +18 -100
  83. package/dist/cli/cli-arguments.mjs.map +1 -1
  84. package/dist/cli/cli-errors.cjs +1 -0
  85. package/dist/cli/cli-errors.cjs.map +1 -1
  86. package/dist/cli/cli-errors.mjs +1 -0
  87. package/dist/cli/cli-errors.mjs.map +1 -1
  88. package/dist/cli/cli-flag-names.cjs +77 -0
  89. package/dist/cli/cli-flag-names.cjs.map +1 -0
  90. package/dist/cli/cli-flag-names.mjs +64 -0
  91. package/dist/cli/cli-flag-names.mjs.map +1 -0
  92. package/dist/cli/cli-output.cjs +7 -2
  93. package/dist/cli/cli-output.cjs.map +1 -1
  94. package/dist/cli/cli-output.mjs +7 -2
  95. package/dist/cli/cli-output.mjs.map +1 -1
  96. package/dist/cli/main.cjs +1 -1
  97. package/dist/cli/main.cjs.map +1 -1
  98. package/dist/cli/main.mjs +1 -1
  99. package/dist/cli/main.mjs.map +1 -1
  100. package/dist/cli/redocly-apis.cjs +14 -4
  101. package/dist/cli/redocly-apis.cjs.map +1 -1
  102. package/dist/cli/redocly-apis.mjs +14 -4
  103. package/dist/cli/redocly-apis.mjs.map +1 -1
  104. package/dist/cli/written-flags.cjs +83 -0
  105. package/dist/cli/written-flags.cjs.map +1 -0
  106. package/dist/cli/written-flags.mjs +77 -0
  107. package/dist/cli/written-flags.mjs.map +1 -0
  108. package/dist/domain/errors.cjs +1 -0
  109. package/dist/domain/errors.cjs.map +1 -1
  110. package/dist/domain/errors.mjs +1 -0
  111. package/dist/domain/errors.mjs.map +1 -1
  112. package/dist/domain/location-text.cjs +7 -1
  113. package/dist/domain/location-text.cjs.map +1 -1
  114. package/dist/domain/location-text.mjs +7 -1
  115. package/dist/domain/location-text.mjs.map +1 -1
  116. package/dist/index.d.cts +3 -0
  117. package/dist/index.d.mts +3 -0
  118. package/dist/index.d.ts +3 -0
  119. package/package.json +1 -1
  120. package/src/adapters/redocly-loader/query-document-names.ts +79 -0
  121. package/src/adapters/redocly-loader/query-named-components.ts +48 -49
  122. package/src/adapters/redocly-loader/redocly-config-source.ts +11 -1
  123. package/src/adapters/redocly-loader/redocly-schema-loader.ts +20 -6
  124. package/src/adapters/redocly-loader/ref-access.ts +16 -2
  125. package/src/adapters/redocly-loader/remote-fetch.ts +26 -0
  126. package/src/api/cwd-option.ts +76 -0
  127. package/src/api/default-ports.ts +33 -10
  128. package/src/api/document-run.ts +2 -17
  129. package/src/api/legacy-utils.ts +1 -1
  130. package/src/api/openapi-ts.ts +14 -1
  131. package/src/api/option-errors.ts +22 -0
  132. package/src/api/ref-limit-options.ts +17 -24
  133. package/src/application/ports/redocly-config-source.ts +5 -0
  134. package/src/application/transform/document/path-template-refs.ts +28 -7
  135. package/src/application/transform/ref-pointer/generated-shape.ts +57 -14
  136. package/src/application/transform/ref-pointer/original-index.ts +6 -3
  137. package/src/application/transform/ref-pointer/property-shape.ts +9 -0
  138. package/src/application/transform/ref-pointer/typed-walk.ts +26 -4
  139. package/src/cli/api-writes.ts +11 -3
  140. package/src/cli/cli-arguments.ts +42 -153
  141. package/src/cli/cli-errors.ts +1 -0
  142. package/src/cli/cli-flag-names.ts +99 -0
  143. package/src/cli/cli-output.ts +20 -6
  144. package/src/cli/main.ts +2 -1
  145. package/src/cli/redocly-apis.ts +21 -5
  146. package/src/cli/written-flags.ts +131 -0
  147. package/src/domain/errors.ts +1 -0
  148. package/src/domain/location-text.ts +17 -2
@@ -1 +1 @@
1
- {"version":3,"file":"path-template-refs.cjs","sources":["../../../../src/application/transform/document/path-template-refs.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { PathsObject } from \"../../../domain/openapi/path-item-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport type { PathKeyPart } from \"./path-key-overlaps.js\";\nimport { booleanExpandedKeys, pathTemplateParts, templateText } from \"./path-template-key.js\";\nimport { isUntakenKey, pathKeyOf } from \"./paths.js\";\n\n/**\n * `--path-params-as-types` and `$ref`s into a templated path. Such a path is an index signature\n * of `paths` (`` [path: `/pets/${number}`] ``), so `paths[\"/pets/{id}\"]`, the type of a `$ref`\n * to it, names no key: `{id}` is no number (TS2339). The reference indexes `paths` by the\n * template instead, which reaches the signature. With only `${string}` placeholders the URL\n * itself matches the template and the output compiles, so it stays as it is.\n */\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/**\n * The index of a templated path: the union of the keys it is written with. A `${boolean}` key the\n * document's own path took (`/flags/true` next to `/flags/{enabled}`) is left out, so the index\n * names only this path's members. Undefined when every key was taken: the path has no member.\n */\nfunction templateIndexText(url: string, parts: readonly PathKeyPart[], takenUrls: Set<string>) {\n const keys = booleanExpandedKeys(parts)\n .map(pathKeyOf)\n .filter((key) => isUntakenKey(url, key, takenUrls));\n const texts = keys.map((key) =>\n key.kind === \"literal\" ? JSON.stringify(key.url) : templateText(key.parts),\n );\n return texts.length === 0 ? undefined : texts.join(\" | \");\n}\n\n/** The index of each templated path whose URL does not match its keys, by URL. */\nexport function unmatchedTemplateKeys(\n paths: PathsObject | null | undefined,\n context: TransformContext,\n): ReadonlyMap<string, string> {\n const keys = new Map<string, string>();\n // A document may hold any value as `paths`; one that is no object has no paths.\n if (!context.options.pathParamsAsTypes || typeof paths !== \"object\" || paths === null) {\n return keys;\n }\n // The same walk as `pathMembers`, so a URL is taken by the same path as there.\n const takenUrls = new Set(Object.keys(paths));\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\" || \"$ref\" in pathItem || !url.includes(\"{\")) {\n continue;\n }\n const parts = pathTemplateParts(url, pathItem, context);\n const index = parts === null ? undefined : templateIndexText(url, parts, takenUrls);\n const isUnmatched = parts?.some(\n (part) => part.kind === \"placeholder\" && part.type !== \"string\",\n );\n if (isUnmatched && index !== undefined) {\n keys.set(url, index);\n }\n }\n return keys;\n}\n\nfunction isNode(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** `paths[\"<url>\"]`: an index of the `paths` root by a string literal. */\nfunction pathsIndexUrl(node: Readonly<Record<string, unknown>>): string | undefined {\n const object = node.object as Readonly<Record<string, unknown>> | undefined;\n const index = node.index as Readonly<Record<string, unknown>> | undefined;\n const isPathsIndex =\n node.kind === \"indexedAccess\" &&\n object?.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n (object.typeArguments as readonly unknown[] | undefined)?.length === 0 &&\n index?.kind === \"stringLiteral\";\n return isPathsIndex ? (index.value as string) : undefined;\n}\n\nfunction rewrittenNode(value: unknown, keys: ReadonlyMap<string, string>): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => rewrittenNode(item, keys));\n }\n if (!isNode(value)) {\n return value;\n }\n const template = keys.get(pathsIndexUrl(value) ?? \"\");\n if (template !== undefined) {\n return { ...value, index: irRaw(template) };\n }\n // `origin` holds the compiler node a raw type was printed from; it is not IR.\n return Object.fromEntries(\n Object.entries(value).map(([key, child]) => [\n key,\n key === \"origin\" ? child : rewrittenNode(child, keys),\n ]),\n );\n}\n\n/** The declarations with each `paths[\"<url>\"]` of an unmatched template indexed by it. */\nexport function withTemplatePathRefs<T extends IrDeclaration>(\n declarations: readonly T[],\n keys: ReadonlyMap<string, string>,\n): T[] {\n return keys.size === 0 ? [...declarations] : (rewrittenNode(declarations, keys) as T[]);\n}\n"],"names":["booleanExpandedKeys","pathKeyOf","isUntakenKey","templateText","documentEntries","pathTemplateParts","irRaw"],"mappings":"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"}
1
+ {"version":3,"file":"path-template-refs.cjs","sources":["../../../../src/application/transform/document/path-template-refs.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { PathsObject } from \"../../../domain/openapi/path-item-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { HELPER_TYPES } from \"../helper-types.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport type { PathKeyPart } from \"./path-key-overlaps.js\";\nimport { booleanExpandedKeys, pathTemplateParts, templateText } from \"./path-template-key.js\";\nimport { isUntakenKey, pathKeyOf } from \"./paths.js\";\n\n/**\n * `--path-params-as-types` and `$ref`s into a templated path. Such a path is an index signature\n * of `paths` (`` [path: `/pets/${number}`] ``), so `paths[\"/pets/{id}\"]`, the type of a `$ref`\n * to it, names no key: `{id}` is no number (TS2339). The reference indexes `paths` by the\n * template instead, which reaches the signature; so does the type of an `--enum-values` array,\n * which indexes `FlattenedDeepRequired<paths>`. With only `${string}` placeholders the URL\n * itself matches the template and the output compiles, so it stays as it is.\n */\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/**\n * The index of a templated path: the union of the keys it is written with. A `${boolean}` key the\n * document's own path took (`/flags/true` next to `/flags/{enabled}`) is left out, so the index\n * names only this path's members. Undefined when every key was taken: the path has no member.\n */\nfunction templateIndexText(url: string, parts: readonly PathKeyPart[], takenUrls: Set<string>) {\n const keys = booleanExpandedKeys(parts)\n .map(pathKeyOf)\n .filter((key) => isUntakenKey(url, key, takenUrls));\n const texts = keys.map((key) =>\n key.kind === \"literal\" ? JSON.stringify(key.url) : templateText(key.parts),\n );\n return texts.length === 0 ? undefined : texts.join(\" | \");\n}\n\n/** The index of each templated path whose URL does not match its keys, by URL. */\nexport function unmatchedTemplateKeys(\n paths: PathsObject | null | undefined,\n context: TransformContext,\n): ReadonlyMap<string, string> {\n const keys = new Map<string, string>();\n // A document may hold any value as `paths`; one that is no object has no paths.\n if (!context.options.pathParamsAsTypes || typeof paths !== \"object\" || paths === null) {\n return keys;\n }\n // The same walk as `pathMembers`, so a URL is taken by the same path as there.\n const takenUrls = new Set(Object.keys(paths));\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\" || \"$ref\" in pathItem || !url.includes(\"{\")) {\n continue;\n }\n const parts = pathTemplateParts(url, pathItem, context);\n const index = parts === null ? undefined : templateIndexText(url, parts, takenUrls);\n const isUnmatched = parts?.some(\n (part) => part.kind === \"placeholder\" && part.type !== \"string\",\n );\n if (isUnmatched && index !== undefined) {\n keys.set(url, index);\n }\n }\n return keys;\n}\n\nfunction isNode(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isBarePathsReference(node: unknown): boolean {\n const reference = node as Readonly<Record<string, unknown>> | undefined;\n return (\n reference?.kind === \"reference\" &&\n reference.name === PATHS_TYPE_NAME &&\n (reference.typeArguments as readonly unknown[] | undefined)?.length === 0\n );\n}\n\n/**\n * The `paths` root as a `$ref` or an `--enum-values` array indexes it: `paths`, or\n * `FlattenedDeepRequired<paths>` (`rootType`), whose mapped keys are those of `paths`.\n */\nfunction isPathsRoot(node: unknown): boolean {\n const reference = node as Readonly<Record<string, unknown>> | undefined;\n const typeArguments = reference?.typeArguments as readonly unknown[] | undefined;\n const isDeepRoot =\n reference?.kind === \"reference\" &&\n reference.name === HELPER_TYPES.flattenedDeepRequired.name &&\n typeArguments?.length === 1 &&\n isBarePathsReference(typeArguments[0]);\n return isDeepRoot || isBarePathsReference(node);\n}\n\n/** `paths[\"<url>\"]`: an index of the `paths` root by a string literal. */\nfunction pathsIndexUrl(node: Readonly<Record<string, unknown>>): string | undefined {\n const index = node.index as Readonly<Record<string, unknown>> | undefined;\n const isPathsIndex =\n node.kind === \"indexedAccess\" && isPathsRoot(node.object) && index?.kind === \"stringLiteral\";\n return isPathsIndex ? (index.value as string) : undefined;\n}\n\nfunction rewrittenNode(value: unknown, keys: ReadonlyMap<string, string>): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => rewrittenNode(item, keys));\n }\n if (!isNode(value)) {\n return value;\n }\n const template = keys.get(pathsIndexUrl(value) ?? \"\");\n if (template !== undefined) {\n return { ...value, index: irRaw(template) };\n }\n // `origin` holds the compiler node a raw type was printed from; it is not IR.\n return Object.fromEntries(\n Object.entries(value).map(([key, child]) => [\n key,\n key === \"origin\" ? child : rewrittenNode(child, keys),\n ]),\n );\n}\n\n/** The declarations with each `paths[\"<url>\"]` of an unmatched template indexed by it. */\nexport function withTemplatePathRefs<T extends IrDeclaration>(\n declarations: readonly T[],\n keys: ReadonlyMap<string, string>,\n): T[] {\n return keys.size === 0 ? [...declarations] : (rewrittenNode(declarations, keys) as T[]);\n}\n"],"names":["booleanExpandedKeys","pathKeyOf","isUntakenKey","templateText","documentEntries","pathTemplateParts","HELPER_TYPES","irRaw"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { irRaw } from '../../../domain/ir/constructors.mjs';
2
2
  import { documentEntries } from '../document-entries.mjs';
3
+ import { HELPER_TYPES } from '../helper-types.mjs';
3
4
  import { pathTemplateParts, booleanExpandedKeys, templateText } from './path-template-key.mjs';
4
5
  import { pathKeyOf, isUntakenKey } from './paths.mjs';
5
6
 
@@ -35,10 +36,19 @@ function unmatchedTemplateKeys(paths, context) {
35
36
  function isNode(value) {
36
37
  return typeof value === "object" && value !== null;
37
38
  }
39
+ function isBarePathsReference(node) {
40
+ const reference = node;
41
+ return reference?.kind === "reference" && reference.name === PATHS_TYPE_NAME && reference.typeArguments?.length === 0;
42
+ }
43
+ function isPathsRoot(node) {
44
+ const reference = node;
45
+ const typeArguments = reference?.typeArguments;
46
+ const isDeepRoot = reference?.kind === "reference" && reference.name === HELPER_TYPES.flattenedDeepRequired.name && typeArguments?.length === 1 && isBarePathsReference(typeArguments[0]);
47
+ return isDeepRoot || isBarePathsReference(node);
48
+ }
38
49
  function pathsIndexUrl(node) {
39
- const object = node.object;
40
50
  const index = node.index;
41
- const isPathsIndex = node.kind === "indexedAccess" && object?.kind === "reference" && object.name === PATHS_TYPE_NAME && object.typeArguments?.length === 0 && index?.kind === "stringLiteral";
51
+ const isPathsIndex = node.kind === "indexedAccess" && isPathsRoot(node.object) && index?.kind === "stringLiteral";
42
52
  return isPathsIndex ? index.value : void 0;
43
53
  }
44
54
  function rewrittenNode(value, keys) {
@@ -1 +1 @@
1
- {"version":3,"file":"path-template-refs.mjs","sources":["../../../../src/application/transform/document/path-template-refs.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { PathsObject } from \"../../../domain/openapi/path-item-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport type { PathKeyPart } from \"./path-key-overlaps.js\";\nimport { booleanExpandedKeys, pathTemplateParts, templateText } from \"./path-template-key.js\";\nimport { isUntakenKey, pathKeyOf } from \"./paths.js\";\n\n/**\n * `--path-params-as-types` and `$ref`s into a templated path. Such a path is an index signature\n * of `paths` (`` [path: `/pets/${number}`] ``), so `paths[\"/pets/{id}\"]`, the type of a `$ref`\n * to it, names no key: `{id}` is no number (TS2339). The reference indexes `paths` by the\n * template instead, which reaches the signature. With only `${string}` placeholders the URL\n * itself matches the template and the output compiles, so it stays as it is.\n */\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/**\n * The index of a templated path: the union of the keys it is written with. A `${boolean}` key the\n * document's own path took (`/flags/true` next to `/flags/{enabled}`) is left out, so the index\n * names only this path's members. Undefined when every key was taken: the path has no member.\n */\nfunction templateIndexText(url: string, parts: readonly PathKeyPart[], takenUrls: Set<string>) {\n const keys = booleanExpandedKeys(parts)\n .map(pathKeyOf)\n .filter((key) => isUntakenKey(url, key, takenUrls));\n const texts = keys.map((key) =>\n key.kind === \"literal\" ? JSON.stringify(key.url) : templateText(key.parts),\n );\n return texts.length === 0 ? undefined : texts.join(\" | \");\n}\n\n/** The index of each templated path whose URL does not match its keys, by URL. */\nexport function unmatchedTemplateKeys(\n paths: PathsObject | null | undefined,\n context: TransformContext,\n): ReadonlyMap<string, string> {\n const keys = new Map<string, string>();\n // A document may hold any value as `paths`; one that is no object has no paths.\n if (!context.options.pathParamsAsTypes || typeof paths !== \"object\" || paths === null) {\n return keys;\n }\n // The same walk as `pathMembers`, so a URL is taken by the same path as there.\n const takenUrls = new Set(Object.keys(paths));\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\" || \"$ref\" in pathItem || !url.includes(\"{\")) {\n continue;\n }\n const parts = pathTemplateParts(url, pathItem, context);\n const index = parts === null ? undefined : templateIndexText(url, parts, takenUrls);\n const isUnmatched = parts?.some(\n (part) => part.kind === \"placeholder\" && part.type !== \"string\",\n );\n if (isUnmatched && index !== undefined) {\n keys.set(url, index);\n }\n }\n return keys;\n}\n\nfunction isNode(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** `paths[\"<url>\"]`: an index of the `paths` root by a string literal. */\nfunction pathsIndexUrl(node: Readonly<Record<string, unknown>>): string | undefined {\n const object = node.object as Readonly<Record<string, unknown>> | undefined;\n const index = node.index as Readonly<Record<string, unknown>> | undefined;\n const isPathsIndex =\n node.kind === \"indexedAccess\" &&\n object?.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n (object.typeArguments as readonly unknown[] | undefined)?.length === 0 &&\n index?.kind === \"stringLiteral\";\n return isPathsIndex ? (index.value as string) : undefined;\n}\n\nfunction rewrittenNode(value: unknown, keys: ReadonlyMap<string, string>): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => rewrittenNode(item, keys));\n }\n if (!isNode(value)) {\n return value;\n }\n const template = keys.get(pathsIndexUrl(value) ?? \"\");\n if (template !== undefined) {\n return { ...value, index: irRaw(template) };\n }\n // `origin` holds the compiler node a raw type was printed from; it is not IR.\n return Object.fromEntries(\n Object.entries(value).map(([key, child]) => [\n key,\n key === \"origin\" ? child : rewrittenNode(child, keys),\n ]),\n );\n}\n\n/** The declarations with each `paths[\"<url>\"]` of an unmatched template indexed by it. */\nexport function withTemplatePathRefs<T extends IrDeclaration>(\n declarations: readonly T[],\n keys: ReadonlyMap<string, string>,\n): T[] {\n return keys.size === 0 ? [...declarations] : (rewrittenNode(declarations, keys) as T[]);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"path-template-refs.mjs","sources":["../../../../src/application/transform/document/path-template-refs.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { PathsObject } from \"../../../domain/openapi/path-item-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { HELPER_TYPES } from \"../helper-types.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport type { PathKeyPart } from \"./path-key-overlaps.js\";\nimport { booleanExpandedKeys, pathTemplateParts, templateText } from \"./path-template-key.js\";\nimport { isUntakenKey, pathKeyOf } from \"./paths.js\";\n\n/**\n * `--path-params-as-types` and `$ref`s into a templated path. Such a path is an index signature\n * of `paths` (`` [path: `/pets/${number}`] ``), so `paths[\"/pets/{id}\"]`, the type of a `$ref`\n * to it, names no key: `{id}` is no number (TS2339). The reference indexes `paths` by the\n * template instead, which reaches the signature; so does the type of an `--enum-values` array,\n * which indexes `FlattenedDeepRequired<paths>`. With only `${string}` placeholders the URL\n * itself matches the template and the output compiles, so it stays as it is.\n */\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/**\n * The index of a templated path: the union of the keys it is written with. A `${boolean}` key the\n * document's own path took (`/flags/true` next to `/flags/{enabled}`) is left out, so the index\n * names only this path's members. Undefined when every key was taken: the path has no member.\n */\nfunction templateIndexText(url: string, parts: readonly PathKeyPart[], takenUrls: Set<string>) {\n const keys = booleanExpandedKeys(parts)\n .map(pathKeyOf)\n .filter((key) => isUntakenKey(url, key, takenUrls));\n const texts = keys.map((key) =>\n key.kind === \"literal\" ? JSON.stringify(key.url) : templateText(key.parts),\n );\n return texts.length === 0 ? undefined : texts.join(\" | \");\n}\n\n/** The index of each templated path whose URL does not match its keys, by URL. */\nexport function unmatchedTemplateKeys(\n paths: PathsObject | null | undefined,\n context: TransformContext,\n): ReadonlyMap<string, string> {\n const keys = new Map<string, string>();\n // A document may hold any value as `paths`; one that is no object has no paths.\n if (!context.options.pathParamsAsTypes || typeof paths !== \"object\" || paths === null) {\n return keys;\n }\n // The same walk as `pathMembers`, so a URL is taken by the same path as there.\n const takenUrls = new Set(Object.keys(paths));\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\" || \"$ref\" in pathItem || !url.includes(\"{\")) {\n continue;\n }\n const parts = pathTemplateParts(url, pathItem, context);\n const index = parts === null ? undefined : templateIndexText(url, parts, takenUrls);\n const isUnmatched = parts?.some(\n (part) => part.kind === \"placeholder\" && part.type !== \"string\",\n );\n if (isUnmatched && index !== undefined) {\n keys.set(url, index);\n }\n }\n return keys;\n}\n\nfunction isNode(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isBarePathsReference(node: unknown): boolean {\n const reference = node as Readonly<Record<string, unknown>> | undefined;\n return (\n reference?.kind === \"reference\" &&\n reference.name === PATHS_TYPE_NAME &&\n (reference.typeArguments as readonly unknown[] | undefined)?.length === 0\n );\n}\n\n/**\n * The `paths` root as a `$ref` or an `--enum-values` array indexes it: `paths`, or\n * `FlattenedDeepRequired<paths>` (`rootType`), whose mapped keys are those of `paths`.\n */\nfunction isPathsRoot(node: unknown): boolean {\n const reference = node as Readonly<Record<string, unknown>> | undefined;\n const typeArguments = reference?.typeArguments as readonly unknown[] | undefined;\n const isDeepRoot =\n reference?.kind === \"reference\" &&\n reference.name === HELPER_TYPES.flattenedDeepRequired.name &&\n typeArguments?.length === 1 &&\n isBarePathsReference(typeArguments[0]);\n return isDeepRoot || isBarePathsReference(node);\n}\n\n/** `paths[\"<url>\"]`: an index of the `paths` root by a string literal. */\nfunction pathsIndexUrl(node: Readonly<Record<string, unknown>>): string | undefined {\n const index = node.index as Readonly<Record<string, unknown>> | undefined;\n const isPathsIndex =\n node.kind === \"indexedAccess\" && isPathsRoot(node.object) && index?.kind === \"stringLiteral\";\n return isPathsIndex ? (index.value as string) : undefined;\n}\n\nfunction rewrittenNode(value: unknown, keys: ReadonlyMap<string, string>): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => rewrittenNode(item, keys));\n }\n if (!isNode(value)) {\n return value;\n }\n const template = keys.get(pathsIndexUrl(value) ?? \"\");\n if (template !== undefined) {\n return { ...value, index: irRaw(template) };\n }\n // `origin` holds the compiler node a raw type was printed from; it is not IR.\n return Object.fromEntries(\n Object.entries(value).map(([key, child]) => [\n key,\n key === \"origin\" ? child : rewrittenNode(child, keys),\n ]),\n );\n}\n\n/** The declarations with each `paths[\"<url>\"]` of an unmatched template indexed by it. */\nexport function withTemplatePathRefs<T extends IrDeclaration>(\n declarations: readonly T[],\n keys: ReadonlyMap<string, string>,\n): T[] {\n return keys.size === 0 ? [...declarations] : (rewrittenNode(declarations, keys) as T[]);\n}\n"],"names":[],"mappings":"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"}
@@ -34,23 +34,41 @@ function emptyObjectMember(node, options) {
34
34
  function isBuiltInMember(key, prototype) {
35
35
  return key in prototype;
36
36
  }
37
- function indexMember(owner, options) {
37
+ function isUnknownValue(value) {
38
+ return value === true || locatedNode.isJsonObject(value) && Object.keys(value).length === 0;
39
+ }
40
+ function typedIndexValues(owner) {
38
41
  const { additionalProperties: values, patternProperties: patterns } = owner.node;
39
- if (locatedNode.isJsonObject(patterns) && Object.keys(patterns).length > 0) {
40
- return OPAQUE;
42
+ const located = [];
43
+ if (locatedNode.isJsonObject(values)) {
44
+ located.push({ node: values, location: locatedNode.childLocation(owner.location, "additionalProperties") });
41
45
  }
42
- if (locatedNode.isJsonObject(values) && Object.keys(values).length > 0) {
43
- const location = locatedNode.childLocation(owner.location, "additionalProperties");
44
- return { kind: "index", node: values, location };
46
+ for (const [pattern, node] of locatedNode.isJsonObject(patterns) ? Object.entries(patterns) : []) {
47
+ located.push({ node, location: locatedNode.childLocation(owner.location, "patternProperties", pattern) });
48
+ }
49
+ return located;
50
+ }
51
+ function indexMember(owner, isExcludedKey, input) {
52
+ const { additionalProperties: values, patternProperties: patterns } = owner.node;
53
+ const patternValues = locatedNode.isJsonObject(patterns) ? Object.values(patterns) : [];
54
+ const isUnknown = isUnknownValue(values) || patternValues.some(isUnknownValue) || !values && input.options.additionalProperties;
55
+ if (isUnknown) {
56
+ return { kind: "index", node: void 0, location: void 0, isOtherType: isExcludedKey };
57
+ }
58
+ const typed = typedIndexValues(owner);
59
+ const [only] = typed;
60
+ if (only === void 0 || typed.length > 1) {
61
+ return only === void 0 ? null : OPAQUE;
45
62
  }
46
- const isImplicit = values === true || locatedNode.isJsonObject(values) && Object.keys(values).length === 0;
47
- return isImplicit || !values && options.additionalProperties ? { kind: "index", node: void 0, location: void 0 } : null;
63
+ const isOtherType = isExcludedKey || propertyShape.hasKeptProperties(owner.node, input.options, input.refs);
64
+ return { kind: "index", ...only, isOtherType };
48
65
  }
49
66
  function objectMember(owner, key, input) {
50
67
  const { options } = input;
51
68
  const { node } = owner;
52
69
  const properties = locatedNode.isJsonObject(node.properties) ? node.properties : {};
53
- if (Object.hasOwn(properties, key) && !propertyShape.isExcludedProperty(properties[key], options, input.refs)) {
70
+ const isExcludedKey = Object.hasOwn(properties, key) && propertyShape.isExcludedProperty(properties[key], options, input.refs);
71
+ if (Object.hasOwn(properties, key) && !isExcludedKey) {
54
72
  if (locatedNode.isJsonObject(node.discriminator)) {
55
73
  return OPAQUE;
56
74
  }
@@ -63,7 +81,7 @@ function objectMember(owner, key, input) {
63
81
  if (isBuiltInMember(key, {}) || key === "$defs" || isUnknownShape) {
64
82
  return OPAQUE;
65
83
  }
66
- return hasObjectKeywords(node) ? indexMember(owner, options) ?? MISSING : emptyObjectMember(node, options);
84
+ return hasObjectKeywords(node) ? indexMember(owner, isExcludedKey, input) ?? MISSING : emptyObjectMember(node, options);
67
85
  }
68
86
  function membersOf(node, keyword) {
69
87
  const members = node[keyword];
@@ -1 +1 @@
1
- {"version":3,"file":"generated-shape.cjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport {\n childLocation,\n followLocated,\n isJsonObject,\n type JsonObject,\n type LocatedNode,\n} from \"./located-node.js\";\nimport {\n isExcludedProperty,\n isMarkedProperty,\n isNullableSchema,\n isOptionalProperty,\n} from \"./property-shape.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | {\n readonly kind: \"property\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOptional: boolean;\n /** `$Read<T>` or `$Write<T>` (`isMarkedProperty`): no member but the marker's own. */\n readonly isMarked: boolean;\n }\n /** An index signature; `node` is undefined when its value type is `unknown`. */\n | { readonly kind: \"index\"; readonly node: unknown; readonly location: string | undefined }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\nfunction indexMember(owner: LocatedNode & { node: JsonObject }, options: SchemaOptions) {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {\n return OPAQUE;\n }\n if (isJsonObject(values) && Object.keys(values).length > 0) {\n const location = childLocation(owner.location, \"additionalProperties\");\n return { kind: \"index\", node: values, location } satisfies GeneratedMember;\n }\n const isImplicit = values === true || (isJsonObject(values) && Object.keys(values).length === 0);\n return isImplicit || (!values && options.additionalProperties)\n ? ({ kind: \"index\", node: undefined, location: undefined } satisfies GeneratedMember)\n : null;\n}\n\nfunction objectMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { options } = input;\n const { node } = owner;\n const properties = isJsonObject(node.properties) ? node.properties : {};\n if (Object.hasOwn(properties, key) && !isExcludedProperty(properties[key], options, input.refs)) {\n if (isJsonObject(node.discriminator)) {\n return OPAQUE;\n }\n const location = childLocation(owner.location, \"properties\", key);\n const isOptional = isOptionalProperty(owner, key, options);\n const isMarked = isMarkedProperty(properties[key], options, input.refs);\n return { kind: \"property\", node: properties[key], location, isOptional, isMarked };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(owner, options) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\n/** The members of a composition keyword with their locations. */\nfunction locatedMembers(owner: LocatedNode & { node: JsonObject }, keyword: string): LocatedNode[] {\n return membersOf(owner.node, keyword).map((node, index) => ({\n node,\n location: childLocation(owner.location, keyword, String(index)),\n }));\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { node } = owner;\n const variants = [...locatedMembers(owner, \"anyOf\"), ...locatedMembers(owner, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const ownPart = { node: own, location: owner.location };\n const parts = [...locatedMembers(owner, \"allOf\"), ...(hasOwn ? [ownPart] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: LocatedNode, key: string, input: MemberInput): GeneratedMember {\n const followed = followLocated(schema, input.refs);\n const { node } = followed;\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n const owner = { ...followed, node };\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(owner, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(owner, key, input);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: LocatedNode,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":["isJsonObject","childLocation","isExcludedProperty","isOptionalProperty","isMarkedProperty","followLocated","isNullableSchema","isRawBinarySchema"],"mappings":"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"}
1
+ {"version":3,"file":"generated-shape.cjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport {\n childLocation,\n followLocated,\n isJsonObject,\n type JsonObject,\n type LocatedNode,\n} from \"./located-node.js\";\nimport {\n hasKeptProperties,\n isExcludedProperty,\n isMarkedProperty,\n isNullableSchema,\n isOptionalProperty,\n} from \"./property-shape.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | {\n readonly kind: \"property\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOptional: boolean;\n /** `$Read<T>` or `$Write<T>` (`isMarkedProperty`): no member but the marker's own. */\n readonly isMarked: boolean;\n }\n /**\n * An index signature; `node` is undefined when its value type is `unknown`. `isOtherType`: the\n * type read is not the type of the node the key names (`indexMember`).\n */\n | {\n readonly kind: \"index\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOtherType: boolean;\n }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\n/** `additionalProperties: true` or `{}` (also as a pattern's schema): a value of `unknown`. */\nfunction isUnknownValue(value: unknown): boolean {\n return value === true || (isJsonObject(value) && Object.keys(value).length === 0);\n}\n\n/** The value schemas of an index signature none of whose values is `unknown`, located. */\nfunction typedIndexValues(owner: LocatedNode & { node: JsonObject }): LocatedNode[] {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n const located: LocatedNode[] = [];\n if (isJsonObject(values)) {\n located.push({ node: values, location: childLocation(owner.location, \"additionalProperties\") });\n }\n for (const [pattern, node] of isJsonObject(patterns) ? Object.entries(patterns) : []) {\n located.push({ node, location: childLocation(owner.location, \"patternProperties\", pattern) });\n }\n return located;\n}\n\n/**\n * The index signature of an object schema, or null without one. Its type is the union of its\n * value schemas' types (`unknown` if one is `unknown`); a union of several counts as opaque. It\n * also holds the kept property types (`withPropertyTypes`), and a key that names a property\n * `--exclude-deprecated` left out reads it instead of that property: both are `isOtherType`.\n */\nfunction indexMember(\n owner: LocatedNode & { node: JsonObject },\n isExcludedKey: boolean,\n input: MemberInput,\n): GeneratedMember | null {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n const patternValues = isJsonObject(patterns) ? Object.values(patterns) : [];\n const isUnknown =\n isUnknownValue(values) ||\n patternValues.some(isUnknownValue) ||\n (!values && input.options.additionalProperties);\n if (isUnknown) {\n return { kind: \"index\", node: undefined, location: undefined, isOtherType: isExcludedKey };\n }\n const typed = typedIndexValues(owner);\n const [only] = typed;\n if (only === undefined || typed.length > 1) {\n return only === undefined ? null : OPAQUE;\n }\n const isOtherType = isExcludedKey || hasKeptProperties(owner.node, input.options, input.refs);\n return { kind: \"index\", ...only, isOtherType };\n}\n\nfunction objectMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { options } = input;\n const { node } = owner;\n const properties = isJsonObject(node.properties) ? node.properties : {};\n const isExcludedKey =\n Object.hasOwn(properties, key) && isExcludedProperty(properties[key], options, input.refs);\n if (Object.hasOwn(properties, key) && !isExcludedKey) {\n if (isJsonObject(node.discriminator)) {\n return OPAQUE;\n }\n const location = childLocation(owner.location, \"properties\", key);\n const isOptional = isOptionalProperty(owner, key, options);\n const isMarked = isMarkedProperty(properties[key], options, input.refs);\n return { kind: \"property\", node: properties[key], location, isOptional, isMarked };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(owner, isExcludedKey, input) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\n/** The members of a composition keyword with their locations. */\nfunction locatedMembers(owner: LocatedNode & { node: JsonObject }, keyword: string): LocatedNode[] {\n return membersOf(owner.node, keyword).map((node, index) => ({\n node,\n location: childLocation(owner.location, keyword, String(index)),\n }));\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { node } = owner;\n const variants = [...locatedMembers(owner, \"anyOf\"), ...locatedMembers(owner, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const ownPart = { node: own, location: owner.location };\n const parts = [...locatedMembers(owner, \"allOf\"), ...(hasOwn ? [ownPart] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: LocatedNode, key: string, input: MemberInput): GeneratedMember {\n const followed = followLocated(schema, input.refs);\n const { node } = followed;\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n const owner = { ...followed, node };\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(owner, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(owner, key, input);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: LocatedNode,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":["isJsonObject","childLocation","hasKeptProperties","isExcludedProperty","isOptionalProperty","isMarkedProperty","followLocated","isNullableSchema","isRawBinarySchema"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { isRawBinarySchema } from '../../../domain/openapi/binary-content.mjs';
2
2
  import { followLocated, isJsonObject, childLocation } from './located-node.mjs';
3
- import { isNullableSchema, isExcludedProperty, isOptionalProperty, isMarkedProperty } from './property-shape.mjs';
3
+ import { isNullableSchema, isExcludedProperty, isOptionalProperty, isMarkedProperty, hasKeptProperties } from './property-shape.mjs';
4
4
 
5
5
  const OPAQUE_KEYS = ["not", "enum", "const", "$ref"];
6
6
  const MAX_DEPTH = 8;
@@ -32,23 +32,41 @@ function emptyObjectMember(node, options) {
32
32
  function isBuiltInMember(key, prototype) {
33
33
  return key in prototype;
34
34
  }
35
- function indexMember(owner, options) {
35
+ function isUnknownValue(value) {
36
+ return value === true || isJsonObject(value) && Object.keys(value).length === 0;
37
+ }
38
+ function typedIndexValues(owner) {
36
39
  const { additionalProperties: values, patternProperties: patterns } = owner.node;
37
- if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {
38
- return OPAQUE;
40
+ const located = [];
41
+ if (isJsonObject(values)) {
42
+ located.push({ node: values, location: childLocation(owner.location, "additionalProperties") });
39
43
  }
40
- if (isJsonObject(values) && Object.keys(values).length > 0) {
41
- const location = childLocation(owner.location, "additionalProperties");
42
- return { kind: "index", node: values, location };
44
+ for (const [pattern, node] of isJsonObject(patterns) ? Object.entries(patterns) : []) {
45
+ located.push({ node, location: childLocation(owner.location, "patternProperties", pattern) });
46
+ }
47
+ return located;
48
+ }
49
+ function indexMember(owner, isExcludedKey, input) {
50
+ const { additionalProperties: values, patternProperties: patterns } = owner.node;
51
+ const patternValues = isJsonObject(patterns) ? Object.values(patterns) : [];
52
+ const isUnknown = isUnknownValue(values) || patternValues.some(isUnknownValue) || !values && input.options.additionalProperties;
53
+ if (isUnknown) {
54
+ return { kind: "index", node: void 0, location: void 0, isOtherType: isExcludedKey };
55
+ }
56
+ const typed = typedIndexValues(owner);
57
+ const [only] = typed;
58
+ if (only === void 0 || typed.length > 1) {
59
+ return only === void 0 ? null : OPAQUE;
43
60
  }
44
- const isImplicit = values === true || isJsonObject(values) && Object.keys(values).length === 0;
45
- return isImplicit || !values && options.additionalProperties ? { kind: "index", node: void 0, location: void 0 } : null;
61
+ const isOtherType = isExcludedKey || hasKeptProperties(owner.node, input.options, input.refs);
62
+ return { kind: "index", ...only, isOtherType };
46
63
  }
47
64
  function objectMember(owner, key, input) {
48
65
  const { options } = input;
49
66
  const { node } = owner;
50
67
  const properties = isJsonObject(node.properties) ? node.properties : {};
51
- if (Object.hasOwn(properties, key) && !isExcludedProperty(properties[key], options, input.refs)) {
68
+ const isExcludedKey = Object.hasOwn(properties, key) && isExcludedProperty(properties[key], options, input.refs);
69
+ if (Object.hasOwn(properties, key) && !isExcludedKey) {
52
70
  if (isJsonObject(node.discriminator)) {
53
71
  return OPAQUE;
54
72
  }
@@ -61,7 +79,7 @@ function objectMember(owner, key, input) {
61
79
  if (isBuiltInMember(key, {}) || key === "$defs" || isUnknownShape) {
62
80
  return OPAQUE;
63
81
  }
64
- return hasObjectKeywords(node) ? indexMember(owner, options) ?? MISSING : emptyObjectMember(node, options);
82
+ return hasObjectKeywords(node) ? indexMember(owner, isExcludedKey, input) ?? MISSING : emptyObjectMember(node, options);
65
83
  }
66
84
  function membersOf(node, keyword) {
67
85
  const members = node[keyword];
@@ -1 +1 @@
1
- {"version":3,"file":"generated-shape.mjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport {\n childLocation,\n followLocated,\n isJsonObject,\n type JsonObject,\n type LocatedNode,\n} from \"./located-node.js\";\nimport {\n isExcludedProperty,\n isMarkedProperty,\n isNullableSchema,\n isOptionalProperty,\n} from \"./property-shape.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | {\n readonly kind: \"property\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOptional: boolean;\n /** `$Read<T>` or `$Write<T>` (`isMarkedProperty`): no member but the marker's own. */\n readonly isMarked: boolean;\n }\n /** An index signature; `node` is undefined when its value type is `unknown`. */\n | { readonly kind: \"index\"; readonly node: unknown; readonly location: string | undefined }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\nfunction indexMember(owner: LocatedNode & { node: JsonObject }, options: SchemaOptions) {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {\n return OPAQUE;\n }\n if (isJsonObject(values) && Object.keys(values).length > 0) {\n const location = childLocation(owner.location, \"additionalProperties\");\n return { kind: \"index\", node: values, location } satisfies GeneratedMember;\n }\n const isImplicit = values === true || (isJsonObject(values) && Object.keys(values).length === 0);\n return isImplicit || (!values && options.additionalProperties)\n ? ({ kind: \"index\", node: undefined, location: undefined } satisfies GeneratedMember)\n : null;\n}\n\nfunction objectMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { options } = input;\n const { node } = owner;\n const properties = isJsonObject(node.properties) ? node.properties : {};\n if (Object.hasOwn(properties, key) && !isExcludedProperty(properties[key], options, input.refs)) {\n if (isJsonObject(node.discriminator)) {\n return OPAQUE;\n }\n const location = childLocation(owner.location, \"properties\", key);\n const isOptional = isOptionalProperty(owner, key, options);\n const isMarked = isMarkedProperty(properties[key], options, input.refs);\n return { kind: \"property\", node: properties[key], location, isOptional, isMarked };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(owner, options) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\n/** The members of a composition keyword with their locations. */\nfunction locatedMembers(owner: LocatedNode & { node: JsonObject }, keyword: string): LocatedNode[] {\n return membersOf(owner.node, keyword).map((node, index) => ({\n node,\n location: childLocation(owner.location, keyword, String(index)),\n }));\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { node } = owner;\n const variants = [...locatedMembers(owner, \"anyOf\"), ...locatedMembers(owner, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const ownPart = { node: own, location: owner.location };\n const parts = [...locatedMembers(owner, \"allOf\"), ...(hasOwn ? [ownPart] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: LocatedNode, key: string, input: MemberInput): GeneratedMember {\n const followed = followLocated(schema, input.refs);\n const { node } = followed;\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n const owner = { ...followed, node };\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(owner, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(owner, key, input);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: LocatedNode,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generated-shape.mjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport {\n childLocation,\n followLocated,\n isJsonObject,\n type JsonObject,\n type LocatedNode,\n} from \"./located-node.js\";\nimport {\n hasKeptProperties,\n isExcludedProperty,\n isMarkedProperty,\n isNullableSchema,\n isOptionalProperty,\n} from \"./property-shape.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | {\n readonly kind: \"property\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOptional: boolean;\n /** `$Read<T>` or `$Write<T>` (`isMarkedProperty`): no member but the marker's own. */\n readonly isMarked: boolean;\n }\n /**\n * An index signature; `node` is undefined when its value type is `unknown`. `isOtherType`: the\n * type read is not the type of the node the key names (`indexMember`).\n */\n | {\n readonly kind: \"index\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOtherType: boolean;\n }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\n/** `additionalProperties: true` or `{}` (also as a pattern's schema): a value of `unknown`. */\nfunction isUnknownValue(value: unknown): boolean {\n return value === true || (isJsonObject(value) && Object.keys(value).length === 0);\n}\n\n/** The value schemas of an index signature none of whose values is `unknown`, located. */\nfunction typedIndexValues(owner: LocatedNode & { node: JsonObject }): LocatedNode[] {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n const located: LocatedNode[] = [];\n if (isJsonObject(values)) {\n located.push({ node: values, location: childLocation(owner.location, \"additionalProperties\") });\n }\n for (const [pattern, node] of isJsonObject(patterns) ? Object.entries(patterns) : []) {\n located.push({ node, location: childLocation(owner.location, \"patternProperties\", pattern) });\n }\n return located;\n}\n\n/**\n * The index signature of an object schema, or null without one. Its type is the union of its\n * value schemas' types (`unknown` if one is `unknown`); a union of several counts as opaque. It\n * also holds the kept property types (`withPropertyTypes`), and a key that names a property\n * `--exclude-deprecated` left out reads it instead of that property: both are `isOtherType`.\n */\nfunction indexMember(\n owner: LocatedNode & { node: JsonObject },\n isExcludedKey: boolean,\n input: MemberInput,\n): GeneratedMember | null {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n const patternValues = isJsonObject(patterns) ? Object.values(patterns) : [];\n const isUnknown =\n isUnknownValue(values) ||\n patternValues.some(isUnknownValue) ||\n (!values && input.options.additionalProperties);\n if (isUnknown) {\n return { kind: \"index\", node: undefined, location: undefined, isOtherType: isExcludedKey };\n }\n const typed = typedIndexValues(owner);\n const [only] = typed;\n if (only === undefined || typed.length > 1) {\n return only === undefined ? null : OPAQUE;\n }\n const isOtherType = isExcludedKey || hasKeptProperties(owner.node, input.options, input.refs);\n return { kind: \"index\", ...only, isOtherType };\n}\n\nfunction objectMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { options } = input;\n const { node } = owner;\n const properties = isJsonObject(node.properties) ? node.properties : {};\n const isExcludedKey =\n Object.hasOwn(properties, key) && isExcludedProperty(properties[key], options, input.refs);\n if (Object.hasOwn(properties, key) && !isExcludedKey) {\n if (isJsonObject(node.discriminator)) {\n return OPAQUE;\n }\n const location = childLocation(owner.location, \"properties\", key);\n const isOptional = isOptionalProperty(owner, key, options);\n const isMarked = isMarkedProperty(properties[key], options, input.refs);\n return { kind: \"property\", node: properties[key], location, isOptional, isMarked };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(owner, isExcludedKey, input) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\n/** The members of a composition keyword with their locations. */\nfunction locatedMembers(owner: LocatedNode & { node: JsonObject }, keyword: string): LocatedNode[] {\n return membersOf(owner.node, keyword).map((node, index) => ({\n node,\n location: childLocation(owner.location, keyword, String(index)),\n }));\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { node } = owner;\n const variants = [...locatedMembers(owner, \"anyOf\"), ...locatedMembers(owner, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const ownPart = { node: own, location: owner.location };\n const parts = [...locatedMembers(owner, \"allOf\"), ...(hasOwn ? [ownPart] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: LocatedNode, key: string, input: MemberInput): GeneratedMember {\n const followed = followLocated(schema, input.refs);\n const { node } = followed;\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n const owner = { ...followed, node };\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(owner, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(owner, key, input);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: LocatedNode,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ function schemaStep(walk, segment, isLast, input) {
9
9
  return { step: "continue", walk };
10
10
  }
11
11
  const member = generatedShape.generatedMember(walk, segment, input.options, input.refs);
12
- if (member.kind === "missing") {
12
+ if (member.kind === "missing" || member.kind === "index" && member.isOtherType) {
13
13
  return { step: "fails", walk };
14
14
  }
15
15
  if (member.kind === "opaque") {
@@ -1 +1 @@
1
- {"version":3,"file":"original-index.cjs","sources":["../../../../src/application/transform/ref-pointer/original-index.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { generatedMember } from \"./generated-shape.js\";\nimport { childLocation, followLocated, isJsonObject } from \"./located-node.js\";\nimport {\n type ContentForm,\n headerParameterContentForm,\n isExcludedOperation,\n isOptionalHeader,\n isOptionalRequestBody,\n isParameterList,\n isTypedAsSchema,\n leadingLocated,\n leadingSegmentsOf,\n type RefPointer,\n startsInSchema,\n} from \"./pointer-walk.js\";\n\n/**\n * Whether the type the original wrote for a `$ref` (`refType`: every segment indexed by name,\n * `properties` skipped) surely fails to compile. It walks the document as TypeScript walks the\n * generated types and answers true only where TypeScript reports an error for sure; where the\n * answer depends on a shape it does not model, it answers false, so that output stays as it was.\n */\n\ntype Step = \"fails\" | \"compiles\" | \"continue\";\n\ninterface OriginalWalk {\n readonly node: unknown;\n /** The node's JSON Pointer (`LocatedNode`). */\n readonly location: string | undefined;\n readonly isSchema: boolean;\n}\n\ninterface WalkInput {\n readonly pointer: RefPointer;\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction schemaStep(walk: OriginalWalk, segment: string, isLast: boolean, input: WalkInput) {\n if (segment === \"properties\") {\n return { step: \"continue\" as Step, walk };\n }\n const member = generatedMember(walk, segment, input.options, input.refs);\n if (member.kind === \"missing\") {\n return { step: \"fails\" as Step, walk };\n }\n if (member.kind === \"opaque\") {\n return { step: \"compiles\" as Step, walk };\n }\n const isAbsentValue = member.kind === \"index\" && member.node === undefined;\n const isUnsafe =\n member.kind === \"property\" ? member.isOptional || member.isMarked : isAbsentValue;\n return {\n step: (isUnsafe && !isLast ? \"fails\" : \"continue\") as Step,\n walk: { ...walk, node: member.node, location: member.location },\n };\n}\n\nfunction containerStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n if (isExcludedOperation(input.pointer, index, walk.node, input)) {\n return { step: \"fails\" as Step, walk };\n }\n const isOptional =\n (segment === \"requestBody\" && isOptionalRequestBody(walk.node, input.refs)) ||\n isOptionalHeader(input.pointer, index, walk.node);\n if (isOptional && !isLast) {\n return { step: \"fails\" as Step, walk };\n }\n const child = followLocated(\n {\n node: isJsonObject(walk.node) ? walk.node[segment] : undefined,\n location: childLocation(walk.location, segment),\n },\n input.refs,\n );\n return {\n step: (child.node === undefined ? \"compiles\" : \"continue\") as Step,\n walk: { ...walk, ...child },\n };\n}\n\n/** The schema of the first media type of a `content` map, `$ref`s followed. */\nfunction firstMediaTypeSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk | null {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (!isJsonObject(content)) {\n return null;\n }\n const [mediaType] = Object.keys(content);\n if (mediaType === undefined) {\n return null;\n }\n const location = childLocation(childLocation(walk.location, \"content\"), mediaType);\n const entry = followLocated({ node: content[mediaType], location }, refs);\n return ownSchema({ ...entry, isSchema: false }, refs);\n}\n\n/** The schema a header or parameter is typed by, `$ref`s followed. */\nfunction ownSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk {\n const schema = isJsonObject(walk.node) ? walk.node.schema : undefined;\n const location = childLocation(walk.location, \"schema\");\n return { ...followLocated({ node: schema, location }, refs), isSchema: true };\n}\n\n/** The schema whose type a header or parameter is, when not its media type members. */\nfunction contentSchema(\n walk: OriginalWalk,\n form: Exclude<ContentForm, \"media-type-members\">,\n refs: RefResolver,\n): OriginalWalk | null {\n switch (form) {\n case \"first-media-type\":\n return firstMediaTypeSchema(walk, refs);\n case \"schema\":\n return ownSchema(walk, refs);\n case \"string\":\n return null;\n }\n}\n\n/**\n * The original indexes the `content` of a header or parameter by name. The media type members\n * have no `content` unless a media type is named so, and `string` and `unknown` (no media type)\n * have none; the schema of the first media type, or the `schema` next to `content`, is walked on.\n */\nfunction contentStep(walk: OriginalWalk, form: ContentForm, isLast: boolean, input: WalkInput) {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (form === \"media-type-members\") {\n const hasMember = isJsonObject(content) && Object.hasOwn(content, \"content\");\n return { step: (hasMember ? \"compiles\" : \"fails\") as Step, walk };\n }\n const schema = contentSchema(walk, form, input.refs);\n return schema === null\n ? { step: \"fails\" as Step, walk }\n : schemaStep(schema, \"content\", isLast, input);\n}\n\n/**\n * A step outside a schema: a header's or parameter's `content`, a schema's container, or another.\n */\nfunction documentStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n const form = headerParameterContentForm(input.pointer, index, walk.node, input.options);\n if (form !== null) {\n return contentStep(walk, form, isLast, input);\n }\n if (isTypedAsSchema(input.pointer, index) && isJsonObject(walk.node)) {\n // The container's type is its schema's type: the segment indexes that type.\n return schemaStep(ownSchema(walk, input.refs), segment, isLast, input);\n }\n return containerStep(walk, index, input);\n}\n\n/** True when the original type of the `$ref` does not compile for sure. */\nexport function originalIndexFails(input: WalkInput): boolean {\n const { segments } = input.pointer;\n let walk: OriginalWalk = {\n ...leadingLocated(input.pointer, input.refs),\n isSchema: startsInSchema(input.pointer),\n };\n for (let index = leadingSegmentsOf(input.pointer); index < segments.length; index++) {\n if (!walk.isSchema && isParameterList(input.pointer, index)) {\n return true;\n }\n const isLast = index === segments.length - 1;\n const result = walk.isSchema\n ? schemaStep(walk, segments[index] as string, isLast, input)\n : documentStep(walk, index, input);\n if (result.step !== \"continue\") {\n return result.step === \"fails\";\n }\n walk = result.walk;\n }\n return false;\n}\n"],"names":["generatedMember","isExcludedOperation","isOptionalRequestBody","isOptionalHeader","followLocated","isJsonObject","childLocation","headerParameterContentForm","isTypedAsSchema","leadingLocated","startsInSchema","leadingSegmentsOf","isParameterList"],"mappings":"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"}
1
+ {"version":3,"file":"original-index.cjs","sources":["../../../../src/application/transform/ref-pointer/original-index.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { generatedMember } from \"./generated-shape.js\";\nimport { childLocation, followLocated, isJsonObject } from \"./located-node.js\";\nimport {\n type ContentForm,\n headerParameterContentForm,\n isExcludedOperation,\n isOptionalHeader,\n isOptionalRequestBody,\n isParameterList,\n isTypedAsSchema,\n leadingLocated,\n leadingSegmentsOf,\n type RefPointer,\n startsInSchema,\n} from \"./pointer-walk.js\";\n\n/**\n * Whether the type the original wrote for a `$ref` (`refType`: every segment indexed by name,\n * `properties` skipped) surely fails to compile. It walks the document as TypeScript walks the\n * generated types and answers true only where TypeScript reports an error for sure, or where the\n * type compiles but is read through an index signature that is not the target's type alone\n * (`isOtherType`); where the answer depends on a shape it does not model, it answers false, so\n * that output stays as it was.\n */\n\ntype Step = \"fails\" | \"compiles\" | \"continue\";\n\ninterface OriginalWalk {\n readonly node: unknown;\n /** The node's JSON Pointer (`LocatedNode`). */\n readonly location: string | undefined;\n readonly isSchema: boolean;\n}\n\ninterface WalkInput {\n readonly pointer: RefPointer;\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction schemaStep(walk: OriginalWalk, segment: string, isLast: boolean, input: WalkInput) {\n if (segment === \"properties\") {\n return { step: \"continue\" as Step, walk };\n }\n const member = generatedMember(walk, segment, input.options, input.refs);\n // Such an index signature compiles, but its type is not the target's alone.\n if (member.kind === \"missing\" || (member.kind === \"index\" && member.isOtherType)) {\n return { step: \"fails\" as Step, walk };\n }\n if (member.kind === \"opaque\") {\n return { step: \"compiles\" as Step, walk };\n }\n const isAbsentValue = member.kind === \"index\" && member.node === undefined;\n const isUnsafe =\n member.kind === \"property\" ? member.isOptional || member.isMarked : isAbsentValue;\n return {\n step: (isUnsafe && !isLast ? \"fails\" : \"continue\") as Step,\n walk: { ...walk, node: member.node, location: member.location },\n };\n}\n\nfunction containerStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n if (isExcludedOperation(input.pointer, index, walk.node, input)) {\n return { step: \"fails\" as Step, walk };\n }\n const isOptional =\n (segment === \"requestBody\" && isOptionalRequestBody(walk.node, input.refs)) ||\n isOptionalHeader(input.pointer, index, walk.node);\n if (isOptional && !isLast) {\n return { step: \"fails\" as Step, walk };\n }\n const child = followLocated(\n {\n node: isJsonObject(walk.node) ? walk.node[segment] : undefined,\n location: childLocation(walk.location, segment),\n },\n input.refs,\n );\n return {\n step: (child.node === undefined ? \"compiles\" : \"continue\") as Step,\n walk: { ...walk, ...child },\n };\n}\n\n/** The schema of the first media type of a `content` map, `$ref`s followed. */\nfunction firstMediaTypeSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk | null {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (!isJsonObject(content)) {\n return null;\n }\n const [mediaType] = Object.keys(content);\n if (mediaType === undefined) {\n return null;\n }\n const location = childLocation(childLocation(walk.location, \"content\"), mediaType);\n const entry = followLocated({ node: content[mediaType], location }, refs);\n return ownSchema({ ...entry, isSchema: false }, refs);\n}\n\n/** The schema a header or parameter is typed by, `$ref`s followed. */\nfunction ownSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk {\n const schema = isJsonObject(walk.node) ? walk.node.schema : undefined;\n const location = childLocation(walk.location, \"schema\");\n return { ...followLocated({ node: schema, location }, refs), isSchema: true };\n}\n\n/** The schema whose type a header or parameter is, when not its media type members. */\nfunction contentSchema(\n walk: OriginalWalk,\n form: Exclude<ContentForm, \"media-type-members\">,\n refs: RefResolver,\n): OriginalWalk | null {\n switch (form) {\n case \"first-media-type\":\n return firstMediaTypeSchema(walk, refs);\n case \"schema\":\n return ownSchema(walk, refs);\n case \"string\":\n return null;\n }\n}\n\n/**\n * The original indexes the `content` of a header or parameter by name. The media type members\n * have no `content` unless a media type is named so, and `string` and `unknown` (no media type)\n * have none; the schema of the first media type, or the `schema` next to `content`, is walked on.\n */\nfunction contentStep(walk: OriginalWalk, form: ContentForm, isLast: boolean, input: WalkInput) {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (form === \"media-type-members\") {\n const hasMember = isJsonObject(content) && Object.hasOwn(content, \"content\");\n return { step: (hasMember ? \"compiles\" : \"fails\") as Step, walk };\n }\n const schema = contentSchema(walk, form, input.refs);\n return schema === null\n ? { step: \"fails\" as Step, walk }\n : schemaStep(schema, \"content\", isLast, input);\n}\n\n/**\n * A step outside a schema: a header's or parameter's `content`, a schema's container, or another.\n */\nfunction documentStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n const form = headerParameterContentForm(input.pointer, index, walk.node, input.options);\n if (form !== null) {\n return contentStep(walk, form, isLast, input);\n }\n if (isTypedAsSchema(input.pointer, index) && isJsonObject(walk.node)) {\n // The container's type is its schema's type: the segment indexes that type.\n return schemaStep(ownSchema(walk, input.refs), segment, isLast, input);\n }\n return containerStep(walk, index, input);\n}\n\n/** True when the original type of the `$ref` does not compile for sure. */\nexport function originalIndexFails(input: WalkInput): boolean {\n const { segments } = input.pointer;\n let walk: OriginalWalk = {\n ...leadingLocated(input.pointer, input.refs),\n isSchema: startsInSchema(input.pointer),\n };\n for (let index = leadingSegmentsOf(input.pointer); index < segments.length; index++) {\n if (!walk.isSchema && isParameterList(input.pointer, index)) {\n return true;\n }\n const isLast = index === segments.length - 1;\n const result = walk.isSchema\n ? schemaStep(walk, segments[index] as string, isLast, input)\n : documentStep(walk, index, input);\n if (result.step !== \"continue\") {\n return result.step === \"fails\";\n }\n walk = result.walk;\n }\n return false;\n}\n"],"names":["generatedMember","isExcludedOperation","isOptionalRequestBody","isOptionalHeader","followLocated","isJsonObject","childLocation","headerParameterContentForm","isTypedAsSchema","leadingLocated","startsInSchema","leadingSegmentsOf","isParameterList"],"mappings":"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"}
@@ -7,7 +7,7 @@ function schemaStep(walk, segment, isLast, input) {
7
7
  return { step: "continue", walk };
8
8
  }
9
9
  const member = generatedMember(walk, segment, input.options, input.refs);
10
- if (member.kind === "missing") {
10
+ if (member.kind === "missing" || member.kind === "index" && member.isOtherType) {
11
11
  return { step: "fails", walk };
12
12
  }
13
13
  if (member.kind === "opaque") {
@@ -1 +1 @@
1
- {"version":3,"file":"original-index.mjs","sources":["../../../../src/application/transform/ref-pointer/original-index.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { generatedMember } from \"./generated-shape.js\";\nimport { childLocation, followLocated, isJsonObject } from \"./located-node.js\";\nimport {\n type ContentForm,\n headerParameterContentForm,\n isExcludedOperation,\n isOptionalHeader,\n isOptionalRequestBody,\n isParameterList,\n isTypedAsSchema,\n leadingLocated,\n leadingSegmentsOf,\n type RefPointer,\n startsInSchema,\n} from \"./pointer-walk.js\";\n\n/**\n * Whether the type the original wrote for a `$ref` (`refType`: every segment indexed by name,\n * `properties` skipped) surely fails to compile. It walks the document as TypeScript walks the\n * generated types and answers true only where TypeScript reports an error for sure; where the\n * answer depends on a shape it does not model, it answers false, so that output stays as it was.\n */\n\ntype Step = \"fails\" | \"compiles\" | \"continue\";\n\ninterface OriginalWalk {\n readonly node: unknown;\n /** The node's JSON Pointer (`LocatedNode`). */\n readonly location: string | undefined;\n readonly isSchema: boolean;\n}\n\ninterface WalkInput {\n readonly pointer: RefPointer;\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction schemaStep(walk: OriginalWalk, segment: string, isLast: boolean, input: WalkInput) {\n if (segment === \"properties\") {\n return { step: \"continue\" as Step, walk };\n }\n const member = generatedMember(walk, segment, input.options, input.refs);\n if (member.kind === \"missing\") {\n return { step: \"fails\" as Step, walk };\n }\n if (member.kind === \"opaque\") {\n return { step: \"compiles\" as Step, walk };\n }\n const isAbsentValue = member.kind === \"index\" && member.node === undefined;\n const isUnsafe =\n member.kind === \"property\" ? member.isOptional || member.isMarked : isAbsentValue;\n return {\n step: (isUnsafe && !isLast ? \"fails\" : \"continue\") as Step,\n walk: { ...walk, node: member.node, location: member.location },\n };\n}\n\nfunction containerStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n if (isExcludedOperation(input.pointer, index, walk.node, input)) {\n return { step: \"fails\" as Step, walk };\n }\n const isOptional =\n (segment === \"requestBody\" && isOptionalRequestBody(walk.node, input.refs)) ||\n isOptionalHeader(input.pointer, index, walk.node);\n if (isOptional && !isLast) {\n return { step: \"fails\" as Step, walk };\n }\n const child = followLocated(\n {\n node: isJsonObject(walk.node) ? walk.node[segment] : undefined,\n location: childLocation(walk.location, segment),\n },\n input.refs,\n );\n return {\n step: (child.node === undefined ? \"compiles\" : \"continue\") as Step,\n walk: { ...walk, ...child },\n };\n}\n\n/** The schema of the first media type of a `content` map, `$ref`s followed. */\nfunction firstMediaTypeSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk | null {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (!isJsonObject(content)) {\n return null;\n }\n const [mediaType] = Object.keys(content);\n if (mediaType === undefined) {\n return null;\n }\n const location = childLocation(childLocation(walk.location, \"content\"), mediaType);\n const entry = followLocated({ node: content[mediaType], location }, refs);\n return ownSchema({ ...entry, isSchema: false }, refs);\n}\n\n/** The schema a header or parameter is typed by, `$ref`s followed. */\nfunction ownSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk {\n const schema = isJsonObject(walk.node) ? walk.node.schema : undefined;\n const location = childLocation(walk.location, \"schema\");\n return { ...followLocated({ node: schema, location }, refs), isSchema: true };\n}\n\n/** The schema whose type a header or parameter is, when not its media type members. */\nfunction contentSchema(\n walk: OriginalWalk,\n form: Exclude<ContentForm, \"media-type-members\">,\n refs: RefResolver,\n): OriginalWalk | null {\n switch (form) {\n case \"first-media-type\":\n return firstMediaTypeSchema(walk, refs);\n case \"schema\":\n return ownSchema(walk, refs);\n case \"string\":\n return null;\n }\n}\n\n/**\n * The original indexes the `content` of a header or parameter by name. The media type members\n * have no `content` unless a media type is named so, and `string` and `unknown` (no media type)\n * have none; the schema of the first media type, or the `schema` next to `content`, is walked on.\n */\nfunction contentStep(walk: OriginalWalk, form: ContentForm, isLast: boolean, input: WalkInput) {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (form === \"media-type-members\") {\n const hasMember = isJsonObject(content) && Object.hasOwn(content, \"content\");\n return { step: (hasMember ? \"compiles\" : \"fails\") as Step, walk };\n }\n const schema = contentSchema(walk, form, input.refs);\n return schema === null\n ? { step: \"fails\" as Step, walk }\n : schemaStep(schema, \"content\", isLast, input);\n}\n\n/**\n * A step outside a schema: a header's or parameter's `content`, a schema's container, or another.\n */\nfunction documentStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n const form = headerParameterContentForm(input.pointer, index, walk.node, input.options);\n if (form !== null) {\n return contentStep(walk, form, isLast, input);\n }\n if (isTypedAsSchema(input.pointer, index) && isJsonObject(walk.node)) {\n // The container's type is its schema's type: the segment indexes that type.\n return schemaStep(ownSchema(walk, input.refs), segment, isLast, input);\n }\n return containerStep(walk, index, input);\n}\n\n/** True when the original type of the `$ref` does not compile for sure. */\nexport function originalIndexFails(input: WalkInput): boolean {\n const { segments } = input.pointer;\n let walk: OriginalWalk = {\n ...leadingLocated(input.pointer, input.refs),\n isSchema: startsInSchema(input.pointer),\n };\n for (let index = leadingSegmentsOf(input.pointer); index < segments.length; index++) {\n if (!walk.isSchema && isParameterList(input.pointer, index)) {\n return true;\n }\n const isLast = index === segments.length - 1;\n const result = walk.isSchema\n ? schemaStep(walk, segments[index] as string, isLast, input)\n : documentStep(walk, index, input);\n if (result.step !== \"continue\") {\n return result.step === \"fails\";\n }\n walk = result.walk;\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"original-index.mjs","sources":["../../../../src/application/transform/ref-pointer/original-index.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { generatedMember } from \"./generated-shape.js\";\nimport { childLocation, followLocated, isJsonObject } from \"./located-node.js\";\nimport {\n type ContentForm,\n headerParameterContentForm,\n isExcludedOperation,\n isOptionalHeader,\n isOptionalRequestBody,\n isParameterList,\n isTypedAsSchema,\n leadingLocated,\n leadingSegmentsOf,\n type RefPointer,\n startsInSchema,\n} from \"./pointer-walk.js\";\n\n/**\n * Whether the type the original wrote for a `$ref` (`refType`: every segment indexed by name,\n * `properties` skipped) surely fails to compile. It walks the document as TypeScript walks the\n * generated types and answers true only where TypeScript reports an error for sure, or where the\n * type compiles but is read through an index signature that is not the target's type alone\n * (`isOtherType`); where the answer depends on a shape it does not model, it answers false, so\n * that output stays as it was.\n */\n\ntype Step = \"fails\" | \"compiles\" | \"continue\";\n\ninterface OriginalWalk {\n readonly node: unknown;\n /** The node's JSON Pointer (`LocatedNode`). */\n readonly location: string | undefined;\n readonly isSchema: boolean;\n}\n\ninterface WalkInput {\n readonly pointer: RefPointer;\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction schemaStep(walk: OriginalWalk, segment: string, isLast: boolean, input: WalkInput) {\n if (segment === \"properties\") {\n return { step: \"continue\" as Step, walk };\n }\n const member = generatedMember(walk, segment, input.options, input.refs);\n // Such an index signature compiles, but its type is not the target's alone.\n if (member.kind === \"missing\" || (member.kind === \"index\" && member.isOtherType)) {\n return { step: \"fails\" as Step, walk };\n }\n if (member.kind === \"opaque\") {\n return { step: \"compiles\" as Step, walk };\n }\n const isAbsentValue = member.kind === \"index\" && member.node === undefined;\n const isUnsafe =\n member.kind === \"property\" ? member.isOptional || member.isMarked : isAbsentValue;\n return {\n step: (isUnsafe && !isLast ? \"fails\" : \"continue\") as Step,\n walk: { ...walk, node: member.node, location: member.location },\n };\n}\n\nfunction containerStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n if (isExcludedOperation(input.pointer, index, walk.node, input)) {\n return { step: \"fails\" as Step, walk };\n }\n const isOptional =\n (segment === \"requestBody\" && isOptionalRequestBody(walk.node, input.refs)) ||\n isOptionalHeader(input.pointer, index, walk.node);\n if (isOptional && !isLast) {\n return { step: \"fails\" as Step, walk };\n }\n const child = followLocated(\n {\n node: isJsonObject(walk.node) ? walk.node[segment] : undefined,\n location: childLocation(walk.location, segment),\n },\n input.refs,\n );\n return {\n step: (child.node === undefined ? \"compiles\" : \"continue\") as Step,\n walk: { ...walk, ...child },\n };\n}\n\n/** The schema of the first media type of a `content` map, `$ref`s followed. */\nfunction firstMediaTypeSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk | null {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (!isJsonObject(content)) {\n return null;\n }\n const [mediaType] = Object.keys(content);\n if (mediaType === undefined) {\n return null;\n }\n const location = childLocation(childLocation(walk.location, \"content\"), mediaType);\n const entry = followLocated({ node: content[mediaType], location }, refs);\n return ownSchema({ ...entry, isSchema: false }, refs);\n}\n\n/** The schema a header or parameter is typed by, `$ref`s followed. */\nfunction ownSchema(walk: OriginalWalk, refs: RefResolver): OriginalWalk {\n const schema = isJsonObject(walk.node) ? walk.node.schema : undefined;\n const location = childLocation(walk.location, \"schema\");\n return { ...followLocated({ node: schema, location }, refs), isSchema: true };\n}\n\n/** The schema whose type a header or parameter is, when not its media type members. */\nfunction contentSchema(\n walk: OriginalWalk,\n form: Exclude<ContentForm, \"media-type-members\">,\n refs: RefResolver,\n): OriginalWalk | null {\n switch (form) {\n case \"first-media-type\":\n return firstMediaTypeSchema(walk, refs);\n case \"schema\":\n return ownSchema(walk, refs);\n case \"string\":\n return null;\n }\n}\n\n/**\n * The original indexes the `content` of a header or parameter by name. The media type members\n * have no `content` unless a media type is named so, and `string` and `unknown` (no media type)\n * have none; the schema of the first media type, or the `schema` next to `content`, is walked on.\n */\nfunction contentStep(walk: OriginalWalk, form: ContentForm, isLast: boolean, input: WalkInput) {\n const content = isJsonObject(walk.node) ? walk.node.content : undefined;\n if (form === \"media-type-members\") {\n const hasMember = isJsonObject(content) && Object.hasOwn(content, \"content\");\n return { step: (hasMember ? \"compiles\" : \"fails\") as Step, walk };\n }\n const schema = contentSchema(walk, form, input.refs);\n return schema === null\n ? { step: \"fails\" as Step, walk }\n : schemaStep(schema, \"content\", isLast, input);\n}\n\n/**\n * A step outside a schema: a header's or parameter's `content`, a schema's container, or another.\n */\nfunction documentStep(walk: OriginalWalk, index: number, input: WalkInput) {\n const segment = input.pointer.segments[index] as string;\n const isLast = index === input.pointer.segments.length - 1;\n const form = headerParameterContentForm(input.pointer, index, walk.node, input.options);\n if (form !== null) {\n return contentStep(walk, form, isLast, input);\n }\n if (isTypedAsSchema(input.pointer, index) && isJsonObject(walk.node)) {\n // The container's type is its schema's type: the segment indexes that type.\n return schemaStep(ownSchema(walk, input.refs), segment, isLast, input);\n }\n return containerStep(walk, index, input);\n}\n\n/** True when the original type of the `$ref` does not compile for sure. */\nexport function originalIndexFails(input: WalkInput): boolean {\n const { segments } = input.pointer;\n let walk: OriginalWalk = {\n ...leadingLocated(input.pointer, input.refs),\n isSchema: startsInSchema(input.pointer),\n };\n for (let index = leadingSegmentsOf(input.pointer); index < segments.length; index++) {\n if (!walk.isSchema && isParameterList(input.pointer, index)) {\n return true;\n }\n const isLast = index === segments.length - 1;\n const result = walk.isSchema\n ? schemaStep(walk, segments[index] as string, isLast, input)\n : documentStep(walk, index, input);\n if (result.step !== \"continue\") {\n return result.step === \"fails\";\n }\n walk = result.walk;\n }\n return false;\n}\n"],"names":[],"mappings":";;;;AAyCA,SAAS,UAAA,CAAW,IAAA,EAAoB,OAAA,EAAiB,MAAA,EAAiB,KAAA,EAAkB;AAC1F,EAAA,IAAI,YAAY,YAAA,EAAc;AAC5B,IAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAoB,IAAA,EAAK;AAAA,EAC1C;AACA,EAAA,MAAM,SAAS,eAAA,CAAgB,IAAA,EAAM,SAAS,KAAA,CAAM,OAAA,EAAS,MAAM,IAAI,CAAA;AAEvE,EAAA,IAAI,OAAO,IAAA,KAAS,SAAA,IAAc,OAAO,IAAA,KAAS,OAAA,IAAW,OAAO,WAAA,EAAc;AAChF,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAiB,IAAA,EAAK;AAAA,EACvC;AACA,EAAA,IAAI,MAAA,CAAO,SAAS,QAAA,EAAU;AAC5B,IAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAoB,IAAA,EAAK;AAAA,EAC1C;AACA,EAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,IAAA,KAAS,OAAA,IAAW,OAAO,IAAA,KAAS,MAAA;AACjE,EAAA,MAAM,WACJ,MAAA,CAAO,IAAA,KAAS,aAAa,MAAA,CAAO,UAAA,IAAc,OAAO,QAAA,GAAW,aAAA;AACtE,EAAA,OAAO;AAAA,IACL,IAAA,EAAO,QAAA,IAAY,CAAC,MAAA,GAAS,OAAA,GAAU,UAAA;AAAA,IACvC,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,MAAM,MAAA,CAAO,IAAA,EAAM,QAAA,EAAU,MAAA,CAAO,QAAA;AAAS,GAChE;AACF;AAEA,SAAS,aAAA,CAAc,IAAA,EAAoB,KAAA,EAAe,KAAA,EAAkB;AAC1E,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,KAAA,KAAU,KAAA,CAAM,OAAA,CAAQ,SAAS,MAAA,GAAS,CAAA;AACzD,EAAA,IAAI,oBAAoB,KAAA,CAAM,OAAA,EAAS,OAAO,IAAA,CAAK,IAAA,EAAM,KAAK,CAAA,EAAG;AAC/D,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAiB,IAAA,EAAK;AAAA,EACvC;AACA,EAAA,MAAM,UAAA,GACH,OAAA,KAAY,aAAA,IAAiB,qBAAA,CAAsB,KAAK,IAAA,EAAM,KAAA,CAAM,IAAI,CAAA,IACzE,gBAAA,CAAiB,KAAA,CAAM,OAAA,EAAS,KAAA,EAAO,KAAK,IAAI,CAAA;AAClD,EAAA,IAAI,UAAA,IAAc,CAAC,MAAA,EAAQ;AACzB,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAiB,IAAA,EAAK;AAAA,EACvC;AACA,EAAA,MAAM,KAAA,GAAQ,aAAA;AAAA,IACZ;AAAA,MACE,IAAA,EAAM,aAAa,IAAA,CAAK,IAAI,IAAI,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA,GAAI,MAAA;AAAA,MACrD,QAAA,EAAU,aAAA,CAAc,IAAA,CAAK,QAAA,EAAU,OAAO;AAAA,KAChD;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AACA,EAAA,OAAO;AAAA,IACL,IAAA,EAAO,KAAA,CAAM,IAAA,KAAS,MAAA,GAAY,UAAA,GAAa,UAAA;AAAA,IAC/C,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,GAAG,KAAA;AAAM,GAC5B;AACF;AAGA,SAAS,oBAAA,CAAqB,MAAoB,IAAA,EAAwC;AACxF,EAAA,MAAM,UAAU,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA,CAAK,KAAK,OAAA,GAAU,MAAA;AAC9D,EAAA,IAAI,CAAC,YAAA,CAAa,OAAO,CAAA,EAAG;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,CAAC,SAAS,CAAA,GAAI,MAAA,CAAO,KAAK,OAAO,CAAA;AACvC,EAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,WAAW,aAAA,CAAc,aAAA,CAAc,KAAK,QAAA,EAAU,SAAS,GAAG,SAAS,CAAA;AACjF,EAAA,MAAM,KAAA,GAAQ,cAAc,EAAE,IAAA,EAAM,QAAQ,SAAS,CAAA,EAAG,QAAA,EAAS,EAAG,IAAI,CAAA;AACxE,EAAA,OAAO,UAAU,EAAE,GAAG,KAAuB,GAAG,IAAI,CAAA;AACtD;AAGA,SAAS,SAAA,CAAU,MAAoB,IAAA,EAAiC;AACtE,EAAA,MAAM,SAAS,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA,CAAK,KAAK,MAAA,GAAS,MAAA;AAC5D,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAA;AACtD,EAAA,OAAO,EAAE,GAAG,aAAA,CAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAA,EAAS,EAAG,IAAI,CAAA,EAAG,QAAA,EAAU,IAAA,EAAK;AAC9E;AAGA,SAAS,aAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,EACqB;AACrB,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,kBAAA;AACH,MAAA,OAAO,oBAAA,CAAqB,MAAM,IAAI,CAAA;AAAA,IACxC,KAAK,QAAA;AACH,MAAA,OAAO,SAAA,CAAU,MAAM,IAAI,CAAA;AAAA,IAC7B,KAAK,QAAA;AACH,MAAA,OAAO,IAAA;AAAA;AAEb;AAOA,SAAS,WAAA,CAAY,IAAA,EAAoB,IAAA,EAAmB,MAAA,EAAiB,KAAA,EAAkB;AAC7F,EAAA,MAAM,UAAU,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA,CAAK,KAAK,OAAA,GAAU,MAAA;AAC9D,EAAA,IAAI,SAAS,oBAAA,EAAsB;AACjC,IAAA,MAAM,YAAY,YAAA,CAAa,OAAO,KAAK,MAAA,CAAO,MAAA,CAAO,SAAS,SAAS,CAAA;AAC3E,IAAA,OAAO,EAAE,IAAA,EAAO,SAAA,GAAY,UAAA,GAAa,SAAkB,IAAA,EAAK;AAAA,EAClE;AACA,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;AACnD,EAAA,OAAO,MAAA,KAAW,IAAA,GACd,EAAE,IAAA,EAAM,OAAA,EAAiB,IAAA,EAAK,GAC9B,UAAA,CAAW,MAAA,EAAQ,SAAA,EAAW,MAAA,EAAQ,KAAK,CAAA;AACjD;AAKA,SAAS,YAAA,CAAa,IAAA,EAAoB,KAAA,EAAe,KAAA,EAAkB;AACzE,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,KAAA,KAAU,KAAA,CAAM,OAAA,CAAQ,SAAS,MAAA,GAAS,CAAA;AACzD,EAAA,MAAM,IAAA,GAAO,2BAA2B,KAAA,CAAM,OAAA,EAAS,OAAO,IAAA,CAAK,IAAA,EAAM,MAAM,OAAO,CAAA;AACtF,EAAA,IAAI,SAAS,IAAA,EAAM;AACjB,IAAA,OAAO,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,KAAK,CAAA;AAAA,EAC9C;AACA,EAAA,IAAI,eAAA,CAAgB,MAAM,OAAA,EAAS,KAAK,KAAK,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,EAAG;AAEpE,IAAA,OAAO,UAAA,CAAW,UAAU,IAAA,EAAM,KAAA,CAAM,IAAI,CAAA,EAAG,OAAA,EAAS,QAAQ,KAAK,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA;AACzC;AAGO,SAAS,mBAAmB,KAAA,EAA2B;AAC5D,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,KAAA,CAAM,OAAA;AAC3B,EAAA,IAAI,IAAA,GAAqB;AAAA,IACvB,GAAG,cAAA,CAAe,KAAA,CAAM,OAAA,EAAS,MAAM,IAAI,CAAA;AAAA,IAC3C,QAAA,EAAU,cAAA,CAAe,KAAA,CAAM,OAAO;AAAA,GACxC;AACA,EAAA,KAAA,IAAS,KAAA,GAAQ,kBAAkB,KAAA,CAAM,OAAO,GAAG,KAAA,GAAQ,QAAA,CAAS,QAAQ,KAAA,EAAA,EAAS;AACnF,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,IAAY,gBAAgB,KAAA,CAAM,OAAA,EAAS,KAAK,CAAA,EAAG;AAC3D,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAM,MAAA,GAAS,KAAA,KAAU,QAAA,CAAS,MAAA,GAAS,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,GAChB,UAAA,CAAW,MAAM,QAAA,CAAS,KAAK,CAAA,EAAa,MAAA,EAAQ,KAAK,CAAA,GACzD,YAAA,CAAa,IAAA,EAAM,OAAO,KAAK,CAAA;AACnC,IAAA,IAAI,MAAA,CAAO,SAAS,UAAA,EAAY;AAC9B,MAAA,OAAO,OAAO,IAAA,KAAS,OAAA;AAAA,IACzB;AACA,IAAA,IAAA,GAAO,MAAA,CAAO,IAAA;AAAA,EAChB;AACA,EAAA,OAAO,KAAA;AACT;;"}