openapi-typesafe 1.0.0-rc.1 → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/adapters/node-deprecations/node-deprecations.cjs +14 -0
- package/dist/adapters/node-deprecations/node-deprecations.cjs.map +1 -0
- package/dist/adapters/node-deprecations/node-deprecations.mjs +12 -0
- package/dist/adapters/node-deprecations/node-deprecations.mjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +19 -6
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +18 -5
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +2 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +2 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
- package/dist/api/default-ports.cjs +14 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +12 -1
- package/dist/api/default-ports.mjs.map +1 -1
- package/dist/api/discriminator-conflict-warnings.cjs +1 -1
- package/dist/api/discriminator-conflict-warnings.cjs.map +1 -1
- package/dist/api/discriminator-conflict-warnings.mjs +2 -2
- package/dist/api/discriminator-conflict-warnings.mjs.map +1 -1
- package/dist/api/discriminator-patch.cjs +8 -4
- package/dist/api/discriminator-patch.cjs.map +1 -1
- package/dist/api/discriminator-patch.mjs +9 -5
- package/dist/api/discriminator-patch.mjs.map +1 -1
- package/dist/api/discriminator-scan.cjs +2 -2
- package/dist/api/discriminator-scan.cjs.map +1 -1
- package/dist/api/discriminator-scan.mjs +3 -3
- package/dist/api/discriminator-scan.mjs.map +1 -1
- package/dist/api/document-refs.cjs +15 -12
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +15 -12
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +6 -3
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +6 -3
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/footer-sink.cjs +25 -2
- package/dist/api/footer-sink.cjs.map +1 -1
- package/dist/api/footer-sink.mjs +25 -2
- package/dist/api/footer-sink.mjs.map +1 -1
- package/dist/api/legacy-callback-warning.cjs +7 -1
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +8 -2
- package/dist/api/legacy-callback-warning.mjs.map +1 -1
- package/dist/api/legacy-ts-helpers.cjs.map +1 -1
- package/dist/api/legacy-ts-helpers.mjs.map +1 -1
- package/dist/api/legacy-utils.cjs.map +1 -1
- package/dist/api/legacy-utils.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +3 -2
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +4 -3
- package/dist/api/openapi-ts.mjs.map +1 -1
- package/dist/api/string-to-ast.cjs +7 -9
- package/dist/api/string-to-ast.cjs.map +1 -1
- package/dist/api/string-to-ast.mjs +8 -9
- package/dist/api/string-to-ast.mjs.map +1 -1
- package/dist/api/transform-context.cjs +1 -1
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +1 -1
- package/dist/api/transform-context.mjs.map +1 -1
- package/dist/api/transform-schema.cjs +2 -2
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +3 -3
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/application/print/type-printer.cjs +2 -1
- package/dist/application/print/type-printer.cjs.map +1 -1
- package/dist/application/print/type-printer.mjs +2 -1
- package/dist/application/print/type-printer.mjs.map +1 -1
- package/dist/application/transform/document/components.cjs +1 -1
- package/dist/application/transform/document/components.cjs.map +1 -1
- package/dist/application/transform/document/components.mjs +2 -2
- package/dist/application/transform/document/components.mjs.map +1 -1
- package/dist/application/transform/document/parameters.cjs +2 -2
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +3 -3
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +2 -2
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +3 -3
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/footer/evaluation.cjs +9 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -1
- package/dist/application/transform/footer/evaluation.mjs +8 -1
- package/dist/application/transform/footer/evaluation.mjs.map +1 -1
- package/dist/application/transform/footer/type-evaluation.cjs +4 -112
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
- package/dist/application/transform/footer/type-evaluation.mjs +4 -112
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
- package/dist/application/transform/footer/type-indexing.cjs +107 -0
- package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.mjs +105 -0
- package/dist/application/transform/footer/type-indexing.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.mjs +2 -2
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
- package/dist/application/transform/schema/access-flags.cjs +1 -1
- package/dist/application/transform/schema/access-flags.cjs.map +1 -1
- package/dist/application/transform/schema/access-flags.mjs +2 -2
- package/dist/application/transform/schema/access-flags.mjs.map +1 -1
- package/dist/application/transform/schema/array-type.cjs +2 -2
- package/dist/application/transform/schema/array-type.cjs.map +1 -1
- package/dist/application/transform/schema/array-type.mjs +3 -3
- package/dist/application/transform/schema/array-type.mjs.map +1 -1
- package/dist/application/transform/schema/composition-type.cjs +3 -3
- package/dist/application/transform/schema/composition-type.cjs.map +1 -1
- package/dist/application/transform/schema/composition-type.mjs +4 -4
- package/dist/application/transform/schema/composition-type.mjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.cjs +3 -5
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.mjs +4 -6
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
- package/dist/application/transform/schema/presence-members.cjs +1 -1
- package/dist/application/transform/schema/presence-members.cjs.map +1 -1
- package/dist/application/transform/schema/presence-members.mjs +2 -2
- package/dist/application/transform/schema/presence-members.mjs.map +1 -1
- package/dist/application/transform/schema/required-variants.cjs +2 -2
- package/dist/application/transform/schema/required-variants.cjs.map +1 -1
- package/dist/application/transform/schema/required-variants.mjs +3 -3
- package/dist/application/transform/schema/required-variants.mjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.cjs +1 -1
- package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.mjs +2 -2
- package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
- package/dist/application/transform/schema-comment.cjs +1 -1
- package/dist/application/transform/schema-comment.cjs.map +1 -1
- package/dist/application/transform/schema-comment.mjs +2 -2
- package/dist/application/transform/schema-comment.mjs.map +1 -1
- package/dist/cli/api-settings.cjs +78 -0
- package/dist/cli/api-settings.cjs.map +1 -0
- package/dist/cli/api-settings.mjs +73 -0
- package/dist/cli/api-settings.mjs.map +1 -0
- package/dist/cli/cli-arguments.cjs +1 -0
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +1 -1
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/help-text.cjs +3 -3
- package/dist/cli/help-text.cjs.map +1 -1
- package/dist/cli/help-text.mjs +3 -3
- package/dist/cli/help-text.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +8 -4
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +7 -3
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +5 -1
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +5 -1
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/deprecations.cjs +11 -0
- package/dist/domain/deprecations.cjs.map +1 -0
- package/dist/domain/deprecations.mjs +9 -0
- package/dist/domain/deprecations.mjs.map +1 -0
- package/dist/domain/errors.cjs +4 -1
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +4 -1
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/constructors.cjs +2 -0
- package/dist/domain/ir/constructors.cjs.map +1 -1
- package/dist/domain/ir/constructors.mjs +2 -1
- package/dist/domain/ir/constructors.mjs.map +1 -1
- package/dist/domain/openapi/path-templates.cjs +1 -1
- package/dist/domain/openapi/path-templates.cjs.map +1 -1
- package/dist/domain/openapi/path-templates.mjs +1 -1
- package/dist/domain/openapi/path-templates.mjs.map +1 -1
- package/dist/domain/output-fixes.cjs +11 -14
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +11 -13
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/url-credentials.cjs +10 -0
- package/dist/domain/url-credentials.cjs.map +1 -0
- package/dist/domain/url-credentials.mjs +8 -0
- package/dist/domain/url-credentials.mjs.map +1 -0
- package/dist/domain/warnings.cjs +8 -1
- package/dist/domain/warnings.cjs.map +1 -1
- package/dist/domain/warnings.mjs +8 -1
- package/dist/domain/warnings.mjs.map +1 -1
- package/dist/index.cjs +4 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1185 -59
- package/dist/index.d.mts +1185 -59
- package/dist/index.d.ts +1185 -59
- package/dist/index.mjs +4 -2
- package/dist/index.mjs.map +1 -1
- package/dist/transform/path-item-object.cjs.map +1 -1
- package/dist/transform/path-item-object.mjs.map +1 -1
- package/package.json +5 -4
- package/src/adapters/node-deprecations/node-deprecations.ts +14 -0
- package/src/adapters/redocly-loader/configured-headers.ts +65 -0
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +22 -7
- package/src/adapters/redocly-loader/ref-access.ts +60 -5
- package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
- package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
- package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
- package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
- package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +2 -1
- package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
- package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
- package/src/api/default-ports.ts +23 -0
- package/src/api/discriminator-conflict-warnings.ts +2 -2
- package/src/api/discriminator-patch.ts +11 -7
- package/src/api/discriminator-scan.ts +3 -3
- package/src/api/document-refs.ts +19 -15
- package/src/api/document-run.ts +14 -6
- package/src/api/footer-sink.ts +34 -2
- package/src/api/legacy-callback-warning.ts +16 -5
- package/src/api/legacy-ts-helpers.ts +7 -5
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +8 -2
- package/src/api/run-context.ts +37 -0
- package/src/api/string-to-ast.ts +11 -15
- package/src/api/transform-context.ts +10 -8
- package/src/api/transform-schema.ts +9 -8
- package/src/application/ports/deprecation-reporter.ts +9 -0
- package/src/application/print/type-printer.ts +2 -1
- package/src/application/transform/document/components.ts +2 -2
- package/src/application/transform/document/parameters.ts +4 -3
- package/src/application/transform/document/paths.ts +4 -3
- package/src/application/transform/footer/evaluation.ts +10 -0
- package/src/application/transform/footer/type-evaluation.ts +6 -133
- package/src/application/transform/footer/type-indexing.ts +152 -0
- package/src/application/transform/ref-pointer/pointer-type.ts +2 -4
- package/src/application/transform/schema/access-flags.ts +2 -2
- package/src/application/transform/schema/array-type.ts +3 -5
- package/src/application/transform/schema/composition-type.ts +4 -4
- package/src/application/transform/schema/enum-rule.ts +4 -6
- package/src/application/transform/schema/presence-members.ts +2 -2
- package/src/application/transform/schema/required-variants.ts +3 -3
- package/src/application/transform/schema/unevaluated-properties.ts +2 -2
- package/src/application/transform/schema-comment.ts +2 -2
- package/src/cli/api-settings.ts +109 -0
- package/src/cli/cli-arguments.ts +5 -2
- package/src/cli/help-text.ts +4 -4
- package/src/cli/redocly-apis.ts +13 -7
- package/src/cli/run-cli.ts +5 -1
- package/src/domain/deprecations.ts +15 -0
- package/src/domain/errors.ts +16 -4
- package/src/domain/ir/constructors.ts +3 -0
- package/src/domain/ir/nodes.ts +9 -6
- package/src/domain/openapi/path-templates.ts +2 -1
- package/src/domain/output-fixes.ts +16 -16
- package/src/domain/url-credentials.ts +18 -0
- package/src/domain/warnings.ts +7 -0
- package/src/index.ts +3 -6
- package/src/transform/path-item-object.ts +6 -2
- package/src/types/generator-options.ts +12 -32
- package/src/types/openapi-common.ts +1 -0
- package/src/types/openapi-request.ts +3 -0
- package/src/types/openapi-schema.ts +2 -0
- package/src/types/openapi-security.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unsupported-keys.cjs","sources":["../../../src/adapters/redocly-loader/unsupported-keys.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * Keys Redocly 1.34 cannot walk. It looks up the type of every key with `type.properties[key]`,\n * which also finds inherited `Object.prototype` members; it then calls a found function with no\n * `this`, and these methods throw a `TypeError` for that. Redocly 2.x looks up own keys only\n * (ADR-005 keeps 1.34). `toString`
|
|
1
|
+
{"version":3,"file":"unsupported-keys.cjs","sources":["../../../src/adapters/redocly-loader/unsupported-keys.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * Keys Redocly 1.34 cannot walk. It looks up the type of every key with `type.properties[key]`,\n * which also finds inherited `Object.prototype` members; it then calls a found function with no\n * `this`, and these methods throw a `TypeError` for that. Redocly 2.x looks up own keys only\n * (ADR-005 keeps 1.34). `toString` does not throw, and loads as it should.\n *\n * Redocly does not walk every value (`default` and `const` are data), so a document with such a\n * key is not rejected up front: the loader looks for them only after Redocly threw a `TypeError`.\n */\nexport const UNSUPPORTED_KEYS: ReadonlySet<string> = new Set([\n \"hasOwnProperty\",\n \"isPrototypeOf\",\n \"propertyIsEnumerable\",\n \"toLocaleString\",\n \"valueOf\",\n \"__defineGetter__\",\n \"__defineSetter__\",\n \"__lookupGetter__\",\n \"__lookupSetter__\",\n]);\n\n/**\n * `constructor` finds `Object`, which returns the value it is called with. Redocly then takes the\n * value for a node type when it has a string `name` (a security scheme, a header with a `name`),\n * and fails reading the type's fields. Any other `constructor` key loads.\n */\nconst CONSTRUCTOR_KEY = \"constructor\";\n\nfunction isUnsupportedEntry(key: string, value: unknown): boolean {\n if (UNSUPPORTED_KEYS.has(key)) {\n return true;\n }\n const name = (value as { name?: unknown } | null | undefined)?.name;\n return key === CONSTRUCTOR_KEY && typeof value === \"object\" && typeof name === \"string\";\n}\n\n/** Enough found keys in the message to act on; `details.keys` has all of them. */\nconst KEYS_IN_MESSAGE = 5;\n\n/** A parsed document and where it was loaded from. */\nexport interface LoadedDocument {\n readonly source: string;\n readonly parsed: unknown;\n}\n\n/** An unsupported key: its JSON pointer and the document that has it. */\nexport interface UnsupportedKey {\n readonly key: string;\n readonly pointer: string;\n readonly source: string;\n}\n\ninterface PendingNode {\n readonly value: object;\n readonly pointer: string;\n}\n\n/** RFC 6901: `~` becomes `~0` and `/` becomes `~1`. */\nfunction escapePointerSegment(segment: string): string {\n return segment.replaceAll(\"~\", \"~0\").replaceAll(\"/\", \"~1\");\n}\n\n/**\n * The unsupported keys of one parsed document. The walk uses its own stack, so a deeply nested\n * document is checked without running out of call stack; nodes shared by YAML aliases are checked\n * once.\n */\nfunction unsupportedKeysOf(document: LoadedDocument): UnsupportedKey[] {\n const found: UnsupportedKey[] = [];\n const visited = new WeakSet<object>();\n const pending: PendingNode[] = [];\n const enqueue = (value: unknown, pointer: string): void => {\n if (typeof value === \"object\" && value !== null && !visited.has(value)) {\n visited.add(value);\n pending.push({ value, pointer });\n }\n };\n enqueue(document.parsed, \"#\");\n for (let node = pending.pop(); node !== undefined; node = pending.pop()) {\n for (const [key, child] of Object.entries(node.value)) {\n const pointer = `${node.pointer}/${escapePointerSegment(key)}`;\n if (isUnsupportedEntry(key, child)) {\n found.push({ key, pointer, source: document.source });\n }\n enqueue(child, pointer);\n }\n }\n return found;\n}\n\n/** Every unsupported key of the given documents. */\nexport function findUnsupportedKeys(documents: readonly LoadedDocument[]): UnsupportedKey[] {\n return documents.flatMap(unsupportedKeysOf);\n}\n\nfunction describeKey(found: UnsupportedKey): string {\n return `\"${found.key}\" at ${found.pointer} in ${found.source}`;\n}\n\n/** The typed error for the keys the schema loader failed on; `cause` is Redocly's `TypeError`. */\nexport function unsupportedKeysError(\n keys: readonly UnsupportedKey[],\n cause: unknown,\n): OpenAPITypesafeError {\n const listed = keys.slice(0, KEYS_IN_MESSAGE).map(describeKey);\n const more = keys.length > KEYS_IN_MESSAGE ? ` and ${keys.length - KEYS_IN_MESSAGE} more` : \"\";\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_KEY_UNSUPPORTED,\n message:\n \"The schema loader (Redocly 1.x) failed on a key named like a built-in object method. \" +\n `Rename it: ${listed.join(\", \")}${more}.`,\n details: { keys: keys.map((found) => ({ ...found })) },\n cause,\n });\n}\n"],"names":["OpenAPITypesafeError","ERROR_CODES"],"mappings":"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"}
|
|
@@ -11,6 +11,14 @@ const UNSUPPORTED_KEYS = /* @__PURE__ */ new Set([
|
|
|
11
11
|
"__lookupGetter__",
|
|
12
12
|
"__lookupSetter__"
|
|
13
13
|
]);
|
|
14
|
+
const CONSTRUCTOR_KEY = "constructor";
|
|
15
|
+
function isUnsupportedEntry(key, value) {
|
|
16
|
+
if (UNSUPPORTED_KEYS.has(key)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
const name = value?.name;
|
|
20
|
+
return key === CONSTRUCTOR_KEY && typeof value === "object" && typeof name === "string";
|
|
21
|
+
}
|
|
14
22
|
const KEYS_IN_MESSAGE = 5;
|
|
15
23
|
function escapePointerSegment(segment) {
|
|
16
24
|
return segment.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
@@ -29,7 +37,7 @@ function unsupportedKeysOf(document) {
|
|
|
29
37
|
for (let node = pending.pop(); node !== void 0; node = pending.pop()) {
|
|
30
38
|
for (const [key, child] of Object.entries(node.value)) {
|
|
31
39
|
const pointer = `${node.pointer}/${escapePointerSegment(key)}`;
|
|
32
|
-
if (
|
|
40
|
+
if (isUnsupportedEntry(key, child)) {
|
|
33
41
|
found.push({ key, pointer, source: document.source });
|
|
34
42
|
}
|
|
35
43
|
enqueue(child, pointer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unsupported-keys.mjs","sources":["../../../src/adapters/redocly-loader/unsupported-keys.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * Keys Redocly 1.34 cannot walk. It looks up the type of every key with `type.properties[key]`,\n * which also finds inherited `Object.prototype` members; it then calls a found function with no\n * `this`, and these methods throw a `TypeError` for that. Redocly 2.x looks up own keys only\n * (ADR-005 keeps 1.34). `toString`
|
|
1
|
+
{"version":3,"file":"unsupported-keys.mjs","sources":["../../../src/adapters/redocly-loader/unsupported-keys.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * Keys Redocly 1.34 cannot walk. It looks up the type of every key with `type.properties[key]`,\n * which also finds inherited `Object.prototype` members; it then calls a found function with no\n * `this`, and these methods throw a `TypeError` for that. Redocly 2.x looks up own keys only\n * (ADR-005 keeps 1.34). `toString` does not throw, and loads as it should.\n *\n * Redocly does not walk every value (`default` and `const` are data), so a document with such a\n * key is not rejected up front: the loader looks for them only after Redocly threw a `TypeError`.\n */\nexport const UNSUPPORTED_KEYS: ReadonlySet<string> = new Set([\n \"hasOwnProperty\",\n \"isPrototypeOf\",\n \"propertyIsEnumerable\",\n \"toLocaleString\",\n \"valueOf\",\n \"__defineGetter__\",\n \"__defineSetter__\",\n \"__lookupGetter__\",\n \"__lookupSetter__\",\n]);\n\n/**\n * `constructor` finds `Object`, which returns the value it is called with. Redocly then takes the\n * value for a node type when it has a string `name` (a security scheme, a header with a `name`),\n * and fails reading the type's fields. Any other `constructor` key loads.\n */\nconst CONSTRUCTOR_KEY = \"constructor\";\n\nfunction isUnsupportedEntry(key: string, value: unknown): boolean {\n if (UNSUPPORTED_KEYS.has(key)) {\n return true;\n }\n const name = (value as { name?: unknown } | null | undefined)?.name;\n return key === CONSTRUCTOR_KEY && typeof value === \"object\" && typeof name === \"string\";\n}\n\n/** Enough found keys in the message to act on; `details.keys` has all of them. */\nconst KEYS_IN_MESSAGE = 5;\n\n/** A parsed document and where it was loaded from. */\nexport interface LoadedDocument {\n readonly source: string;\n readonly parsed: unknown;\n}\n\n/** An unsupported key: its JSON pointer and the document that has it. */\nexport interface UnsupportedKey {\n readonly key: string;\n readonly pointer: string;\n readonly source: string;\n}\n\ninterface PendingNode {\n readonly value: object;\n readonly pointer: string;\n}\n\n/** RFC 6901: `~` becomes `~0` and `/` becomes `~1`. */\nfunction escapePointerSegment(segment: string): string {\n return segment.replaceAll(\"~\", \"~0\").replaceAll(\"/\", \"~1\");\n}\n\n/**\n * The unsupported keys of one parsed document. The walk uses its own stack, so a deeply nested\n * document is checked without running out of call stack; nodes shared by YAML aliases are checked\n * once.\n */\nfunction unsupportedKeysOf(document: LoadedDocument): UnsupportedKey[] {\n const found: UnsupportedKey[] = [];\n const visited = new WeakSet<object>();\n const pending: PendingNode[] = [];\n const enqueue = (value: unknown, pointer: string): void => {\n if (typeof value === \"object\" && value !== null && !visited.has(value)) {\n visited.add(value);\n pending.push({ value, pointer });\n }\n };\n enqueue(document.parsed, \"#\");\n for (let node = pending.pop(); node !== undefined; node = pending.pop()) {\n for (const [key, child] of Object.entries(node.value)) {\n const pointer = `${node.pointer}/${escapePointerSegment(key)}`;\n if (isUnsupportedEntry(key, child)) {\n found.push({ key, pointer, source: document.source });\n }\n enqueue(child, pointer);\n }\n }\n return found;\n}\n\n/** Every unsupported key of the given documents. */\nexport function findUnsupportedKeys(documents: readonly LoadedDocument[]): UnsupportedKey[] {\n return documents.flatMap(unsupportedKeysOf);\n}\n\nfunction describeKey(found: UnsupportedKey): string {\n return `\"${found.key}\" at ${found.pointer} in ${found.source}`;\n}\n\n/** The typed error for the keys the schema loader failed on; `cause` is Redocly's `TypeError`. */\nexport function unsupportedKeysError(\n keys: readonly UnsupportedKey[],\n cause: unknown,\n): OpenAPITypesafeError {\n const listed = keys.slice(0, KEYS_IN_MESSAGE).map(describeKey);\n const more = keys.length > KEYS_IN_MESSAGE ? ` and ${keys.length - KEYS_IN_MESSAGE} more` : \"\";\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_KEY_UNSUPPORTED,\n message:\n \"The schema loader (Redocly 1.x) failed on a key named like a built-in object method. \" +\n `Rename it: ${listed.join(\", \")}${more}.`,\n details: { keys: keys.map((found) => ({ ...found })) },\n cause,\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const colors = require('ansi-colors');
|
|
4
|
+
const urlCredentials = require('../../domain/url-credentials.cjs');
|
|
4
5
|
|
|
5
6
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
6
7
|
|
|
@@ -45,16 +46,17 @@ class TerminalLogger {
|
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? "info"}`);
|
|
48
|
-
const time = durationMs === void 0 ? "" : this.#palette.green(` ${formatDuration(durationMs)} `);
|
|
49
|
-
|
|
49
|
+
const time = durationMs === void 0 ? " " : this.#palette.green(` ${formatDuration(durationMs)} `);
|
|
50
|
+
const text = urlCredentials.redactUrlCredentials(message);
|
|
51
|
+
this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${text}`);
|
|
50
52
|
}
|
|
51
53
|
warn(message) {
|
|
52
54
|
if (!this.#options.silent) {
|
|
53
|
-
this.#options.sink.warn(this.#palette.yellow(` \u26A0 ${message}`));
|
|
55
|
+
this.#options.sink.warn(this.#palette.yellow(` \u26A0 ${urlCredentials.redactUrlCredentials(message)}`));
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
error(message) {
|
|
57
|
-
this.#options.sink.error(this.#palette.red(` \u2718 ${message}`));
|
|
59
|
+
this.#options.sink.error(this.#palette.red(` \u2718 ${urlCredentials.redactUrlCredentials(message)}`));
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
function createTerminalLogger(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-logger.cjs","sources":["../../../src/adapters/terminal-logger/terminal-logger.ts"],"sourcesContent":["import colors from \"ansi-colors\";\nimport type { DebugGroup, Logger } from \"../../application/ports/logger.js\";\n\n/**\n * The Logger port on a terminal, with the original output format: ` ⚠ ` warnings, ` ✘ `\n * errors, and `openapi-ts:<group>` debug lines filtered by `DEBUG` (ENGINEERING_PLAN 4.5).\n */\n\n/** Where the lines go: `console` in production, a recording sink in tests. */\nexport interface TerminalSink {\n debug(line: string): void;\n warn(line: string): void;\n error(line: string): void;\n}\n\nexport interface TerminalLoggerOptions {\n /** Drop warnings (errors and debug lines are still written). */\n readonly silent: boolean;\n /** The value of `DEBUG`: `*`, `openapi-ts:*` or `openapi-ts:<group>` turn debug lines on. */\n readonly debugFilter: string | undefined;\n readonly useColors: boolean;\n readonly sink: TerminalSink;\n}\n\ntype Colors = ReturnType<typeof colors.create>;\n\nconst MILLISECONDS_PER_SECOND = 1000;\nconst MILLISECONDS_PER_MINUTE = 60_000;\n\n/** A duration as the original prints it: one decimal, in ms, s or m. */\nexport function formatDuration(milliseconds: number): string {\n if (milliseconds < MILLISECONDS_PER_SECOND) {\n return `${Math.round(10 * milliseconds) / 10}ms`;\n }\n if (milliseconds < MILLISECONDS_PER_MINUTE) {\n return `${Math.round(milliseconds / 100) / 10}s`;\n }\n return `${Math.round(milliseconds / 6000) / 10}m`;\n}\n\nfunction groupColor(palette: Colors, group: DebugGroup | undefined): (text: string) => string {\n const byGroup: Readonly<Partial<Record<DebugGroup, (text: string) => string>>> = {\n redoc: palette.cyanBright,\n lint: palette.yellowBright,\n bundle: palette.magentaBright,\n ts: palette.blueBright,\n };\n return (group && byGroup[group]) || palette.whiteBright;\n}\n\n/** Whether `DEBUG` asks for this group (the original check, case-insensitive for the group). */\nexport function isDebugEnabled(filter: string | undefined, group: DebugGroup | undefined): boolean {\n if (!filter) {\n return false;\n }\n return (\n !group ||\n filter === \"*\" ||\n filter === \"openapi-ts:*\" ||\n filter.toLocaleLowerCase() === `openapi-ts:${group.toLocaleLowerCase()}`\n );\n}\n\nclass TerminalLogger implements Logger {\n readonly #options: TerminalLoggerOptions;\n readonly #palette: Colors;\n\n constructor(options: TerminalLoggerOptions) {\n this.#options = options;\n this.#palette = colors.create();\n this.#palette.enabled = options.useColors;\n }\n\n debug(message: string, group?: DebugGroup, durationMs?: number): void {\n if (!isDebugEnabled(this.#options.debugFilter, group)) {\n return;\n }\n const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? \"info\"}`);\n const time =\n durationMs === undefined ? \"\" : this.#palette.green(` ${formatDuration(durationMs)} `);\n this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${
|
|
1
|
+
{"version":3,"file":"terminal-logger.cjs","sources":["../../../src/adapters/terminal-logger/terminal-logger.ts"],"sourcesContent":["import colors from \"ansi-colors\";\nimport type { DebugGroup, Logger } from \"../../application/ports/logger.js\";\nimport { redactUrlCredentials } from \"../../domain/url-credentials.js\";\n\n/**\n * The Logger port on a terminal, with the original output format: ` ⚠ ` warnings, ` ✘ `\n * errors, and `openapi-ts:<group>` debug lines filtered by `DEBUG` (ENGINEERING_PLAN 4.5). No\n * line shows the user info of a URL.\n */\n\n/** Where the lines go: `console` in production, a recording sink in tests. */\nexport interface TerminalSink {\n debug(line: string): void;\n warn(line: string): void;\n error(line: string): void;\n}\n\nexport interface TerminalLoggerOptions {\n /** Drop warnings (errors and debug lines are still written). */\n readonly silent: boolean;\n /** The value of `DEBUG`: `*`, `openapi-ts:*` or `openapi-ts:<group>` turn debug lines on. */\n readonly debugFilter: string | undefined;\n readonly useColors: boolean;\n readonly sink: TerminalSink;\n}\n\ntype Colors = ReturnType<typeof colors.create>;\n\nconst MILLISECONDS_PER_SECOND = 1000;\nconst MILLISECONDS_PER_MINUTE = 60_000;\n\n/** A duration as the original prints it: one decimal, in ms, s or m. */\nexport function formatDuration(milliseconds: number): string {\n if (milliseconds < MILLISECONDS_PER_SECOND) {\n return `${Math.round(10 * milliseconds) / 10}ms`;\n }\n if (milliseconds < MILLISECONDS_PER_MINUTE) {\n return `${Math.round(milliseconds / 100) / 10}s`;\n }\n return `${Math.round(milliseconds / 6000) / 10}m`;\n}\n\nfunction groupColor(palette: Colors, group: DebugGroup | undefined): (text: string) => string {\n const byGroup: Readonly<Partial<Record<DebugGroup, (text: string) => string>>> = {\n redoc: palette.cyanBright,\n lint: palette.yellowBright,\n bundle: palette.magentaBright,\n ts: palette.blueBright,\n };\n return (group && byGroup[group]) || palette.whiteBright;\n}\n\n/** Whether `DEBUG` asks for this group (the original check, case-insensitive for the group). */\nexport function isDebugEnabled(filter: string | undefined, group: DebugGroup | undefined): boolean {\n if (!filter) {\n return false;\n }\n return (\n !group ||\n filter === \"*\" ||\n filter === \"openapi-ts:*\" ||\n filter.toLocaleLowerCase() === `openapi-ts:${group.toLocaleLowerCase()}`\n );\n}\n\nclass TerminalLogger implements Logger {\n readonly #options: TerminalLoggerOptions;\n readonly #palette: Colors;\n\n constructor(options: TerminalLoggerOptions) {\n this.#options = options;\n this.#palette = colors.create();\n this.#palette.enabled = options.useColors;\n }\n\n debug(message: string, group?: DebugGroup, durationMs?: number): void {\n if (!isDebugEnabled(this.#options.debugFilter, group)) {\n return;\n }\n const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? \"info\"}`);\n // The original wrote no space without a duration (`openapi-ts:lintIgnored …`).\n const time =\n durationMs === undefined ? \" \" : this.#palette.green(` ${formatDuration(durationMs)} `);\n const text = redactUrlCredentials(message);\n this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${text}`);\n }\n\n warn(message: string): void {\n if (!this.#options.silent) {\n this.#options.sink.warn(this.#palette.yellow(` ⚠ ${redactUrlCredentials(message)}`));\n }\n }\n\n error(message: string): void {\n this.#options.sink.error(this.#palette.red(` ✘ ${redactUrlCredentials(message)}`));\n }\n}\n\n/** A Logger that writes to a terminal sink. */\nexport function createTerminalLogger(options: TerminalLoggerOptions): Logger {\n return new TerminalLogger(options);\n}\n"],"names":["colors","redactUrlCredentials"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import colors from 'ansi-colors';
|
|
2
|
+
import { redactUrlCredentials } from '../../domain/url-credentials.mjs';
|
|
2
3
|
|
|
3
4
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
4
5
|
const MILLISECONDS_PER_MINUTE = 6e4;
|
|
@@ -39,16 +40,17 @@ class TerminalLogger {
|
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
42
|
const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? "info"}`);
|
|
42
|
-
const time = durationMs === void 0 ? "" : this.#palette.green(` ${formatDuration(durationMs)} `);
|
|
43
|
-
|
|
43
|
+
const time = durationMs === void 0 ? " " : this.#palette.green(` ${formatDuration(durationMs)} `);
|
|
44
|
+
const text = redactUrlCredentials(message);
|
|
45
|
+
this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${text}`);
|
|
44
46
|
}
|
|
45
47
|
warn(message) {
|
|
46
48
|
if (!this.#options.silent) {
|
|
47
|
-
this.#options.sink.warn(this.#palette.yellow(` \u26A0 ${message}`));
|
|
49
|
+
this.#options.sink.warn(this.#palette.yellow(` \u26A0 ${redactUrlCredentials(message)}`));
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
error(message) {
|
|
51
|
-
this.#options.sink.error(this.#palette.red(` \u2718 ${message}`));
|
|
53
|
+
this.#options.sink.error(this.#palette.red(` \u2718 ${redactUrlCredentials(message)}`));
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
function createTerminalLogger(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-logger.mjs","sources":["../../../src/adapters/terminal-logger/terminal-logger.ts"],"sourcesContent":["import colors from \"ansi-colors\";\nimport type { DebugGroup, Logger } from \"../../application/ports/logger.js\";\n\n/**\n * The Logger port on a terminal, with the original output format: ` ⚠ ` warnings, ` ✘ `\n * errors, and `openapi-ts:<group>` debug lines filtered by `DEBUG` (ENGINEERING_PLAN 4.5).\n */\n\n/** Where the lines go: `console` in production, a recording sink in tests. */\nexport interface TerminalSink {\n debug(line: string): void;\n warn(line: string): void;\n error(line: string): void;\n}\n\nexport interface TerminalLoggerOptions {\n /** Drop warnings (errors and debug lines are still written). */\n readonly silent: boolean;\n /** The value of `DEBUG`: `*`, `openapi-ts:*` or `openapi-ts:<group>` turn debug lines on. */\n readonly debugFilter: string | undefined;\n readonly useColors: boolean;\n readonly sink: TerminalSink;\n}\n\ntype Colors = ReturnType<typeof colors.create>;\n\nconst MILLISECONDS_PER_SECOND = 1000;\nconst MILLISECONDS_PER_MINUTE = 60_000;\n\n/** A duration as the original prints it: one decimal, in ms, s or m. */\nexport function formatDuration(milliseconds: number): string {\n if (milliseconds < MILLISECONDS_PER_SECOND) {\n return `${Math.round(10 * milliseconds) / 10}ms`;\n }\n if (milliseconds < MILLISECONDS_PER_MINUTE) {\n return `${Math.round(milliseconds / 100) / 10}s`;\n }\n return `${Math.round(milliseconds / 6000) / 10}m`;\n}\n\nfunction groupColor(palette: Colors, group: DebugGroup | undefined): (text: string) => string {\n const byGroup: Readonly<Partial<Record<DebugGroup, (text: string) => string>>> = {\n redoc: palette.cyanBright,\n lint: palette.yellowBright,\n bundle: palette.magentaBright,\n ts: palette.blueBright,\n };\n return (group && byGroup[group]) || palette.whiteBright;\n}\n\n/** Whether `DEBUG` asks for this group (the original check, case-insensitive for the group). */\nexport function isDebugEnabled(filter: string | undefined, group: DebugGroup | undefined): boolean {\n if (!filter) {\n return false;\n }\n return (\n !group ||\n filter === \"*\" ||\n filter === \"openapi-ts:*\" ||\n filter.toLocaleLowerCase() === `openapi-ts:${group.toLocaleLowerCase()}`\n );\n}\n\nclass TerminalLogger implements Logger {\n readonly #options: TerminalLoggerOptions;\n readonly #palette: Colors;\n\n constructor(options: TerminalLoggerOptions) {\n this.#options = options;\n this.#palette = colors.create();\n this.#palette.enabled = options.useColors;\n }\n\n debug(message: string, group?: DebugGroup, durationMs?: number): void {\n if (!isDebugEnabled(this.#options.debugFilter, group)) {\n return;\n }\n const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? \"info\"}`);\n const time =\n durationMs === undefined ? \"\" : this.#palette.green(` ${formatDuration(durationMs)} `);\n this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${
|
|
1
|
+
{"version":3,"file":"terminal-logger.mjs","sources":["../../../src/adapters/terminal-logger/terminal-logger.ts"],"sourcesContent":["import colors from \"ansi-colors\";\nimport type { DebugGroup, Logger } from \"../../application/ports/logger.js\";\nimport { redactUrlCredentials } from \"../../domain/url-credentials.js\";\n\n/**\n * The Logger port on a terminal, with the original output format: ` ⚠ ` warnings, ` ✘ `\n * errors, and `openapi-ts:<group>` debug lines filtered by `DEBUG` (ENGINEERING_PLAN 4.5). No\n * line shows the user info of a URL.\n */\n\n/** Where the lines go: `console` in production, a recording sink in tests. */\nexport interface TerminalSink {\n debug(line: string): void;\n warn(line: string): void;\n error(line: string): void;\n}\n\nexport interface TerminalLoggerOptions {\n /** Drop warnings (errors and debug lines are still written). */\n readonly silent: boolean;\n /** The value of `DEBUG`: `*`, `openapi-ts:*` or `openapi-ts:<group>` turn debug lines on. */\n readonly debugFilter: string | undefined;\n readonly useColors: boolean;\n readonly sink: TerminalSink;\n}\n\ntype Colors = ReturnType<typeof colors.create>;\n\nconst MILLISECONDS_PER_SECOND = 1000;\nconst MILLISECONDS_PER_MINUTE = 60_000;\n\n/** A duration as the original prints it: one decimal, in ms, s or m. */\nexport function formatDuration(milliseconds: number): string {\n if (milliseconds < MILLISECONDS_PER_SECOND) {\n return `${Math.round(10 * milliseconds) / 10}ms`;\n }\n if (milliseconds < MILLISECONDS_PER_MINUTE) {\n return `${Math.round(milliseconds / 100) / 10}s`;\n }\n return `${Math.round(milliseconds / 6000) / 10}m`;\n}\n\nfunction groupColor(palette: Colors, group: DebugGroup | undefined): (text: string) => string {\n const byGroup: Readonly<Partial<Record<DebugGroup, (text: string) => string>>> = {\n redoc: palette.cyanBright,\n lint: palette.yellowBright,\n bundle: palette.magentaBright,\n ts: palette.blueBright,\n };\n return (group && byGroup[group]) || palette.whiteBright;\n}\n\n/** Whether `DEBUG` asks for this group (the original check, case-insensitive for the group). */\nexport function isDebugEnabled(filter: string | undefined, group: DebugGroup | undefined): boolean {\n if (!filter) {\n return false;\n }\n return (\n !group ||\n filter === \"*\" ||\n filter === \"openapi-ts:*\" ||\n filter.toLocaleLowerCase() === `openapi-ts:${group.toLocaleLowerCase()}`\n );\n}\n\nclass TerminalLogger implements Logger {\n readonly #options: TerminalLoggerOptions;\n readonly #palette: Colors;\n\n constructor(options: TerminalLoggerOptions) {\n this.#options = options;\n this.#palette = colors.create();\n this.#palette.enabled = options.useColors;\n }\n\n debug(message: string, group?: DebugGroup, durationMs?: number): void {\n if (!isDebugEnabled(this.#options.debugFilter, group)) {\n return;\n }\n const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? \"info\"}`);\n // The original wrote no space without a duration (`openapi-ts:lintIgnored …`).\n const time =\n durationMs === undefined ? \" \" : this.#palette.green(` ${formatDuration(durationMs)} `);\n const text = redactUrlCredentials(message);\n this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${text}`);\n }\n\n warn(message: string): void {\n if (!this.#options.silent) {\n this.#options.sink.warn(this.#palette.yellow(` ⚠ ${redactUrlCredentials(message)}`));\n }\n }\n\n error(message: string): void {\n this.#options.sink.error(this.#palette.red(` ✘ ${redactUrlCredentials(message)}`));\n }\n}\n\n/** A Logger that writes to a terminal sink. */\nexport function createTerminalLogger(options: TerminalLoggerOptions): Logger {\n return new TerminalLogger(options);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const assertNever = require('../../domain/assert-never.cjs');
|
|
4
|
+
const constructors = require('../../domain/ir/constructors.cjs');
|
|
4
5
|
|
|
5
6
|
function keywordKind(ts, keyword) {
|
|
6
7
|
const kinds = {
|
|
@@ -40,7 +41,7 @@ function toLeafTypeNode(ts, type) {
|
|
|
40
41
|
case "keyword":
|
|
41
42
|
return toKeywordType(ts, type.keyword);
|
|
42
43
|
case "stringLiteral":
|
|
43
|
-
return toStringLiteralType(ts, type.value, type.encoding);
|
|
44
|
+
return toStringLiteralType(ts, type.value, type.encoding ?? constructors.DEFAULT_STRING_ENCODING);
|
|
44
45
|
case "numberLiteral":
|
|
45
46
|
return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));
|
|
46
47
|
case "booleanLiteral":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-to-typescript.cjs","sources":["../../../src/adapters/type-ast-bridge/ir-to-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { assertNever } from \"../../domain/assert-never.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\n\n/**\n * Convert IR to TypeScript AST nodes with the same factory calls the original generator makes.\n * Printing the result with the TypeScript printer gives the original output, which is how the\n * printer parity tests (ENGINEERING_PLAN 4.3) define \"byte-identical\". Every function takes the\n * TypeScript module to build with (ADR-004, decision 4): the nodes must come from the same module\n * that later reads or prints them.\n */\n\ntype KeywordName = Exclude<IrKeyword, \"null\">;\n\nfunction keywordKind(ts: TypeScriptModule, keyword: KeywordName): ts.KeywordTypeSyntaxKind {\n const kinds: Readonly<Record<KeywordName, ts.KeywordTypeSyntaxKind>> = {\n string: ts.SyntaxKind.StringKeyword,\n number: ts.SyntaxKind.NumberKeyword,\n boolean: ts.SyntaxKind.BooleanKeyword,\n undefined: ts.SyntaxKind.UndefinedKeyword,\n unknown: ts.SyntaxKind.UnknownKeyword,\n never: ts.SyntaxKind.NeverKeyword,\n };\n return kinds[keyword];\n}\n\nfunction toKeywordType(ts: TypeScriptModule, keyword: IrKeyword): ts.TypeNode {\n return keyword === \"null\"\n ? ts.factory.createLiteralTypeNode(ts.factory.createNull())\n : ts.factory.createKeywordTypeNode(keywordKind(ts, keyword));\n}\n\n/**\n * Numbers as the original writes them: a negative value is a prefix minus on its absolute value.\n */\nfunction toNumberExpression(\n ts: TypeScriptModule,\n value: number,\n): ts.PrefixUnaryExpression | ts.NumericLiteral {\n return value < 0\n ? ts.factory.createPrefixUnaryExpression(\n ts.SyntaxKind.MinusToken,\n ts.factory.createNumericLiteral(Math.abs(value)),\n )\n : ts.factory.createNumericLiteral(value);\n}\n\n/** An enum member or array element value, written as the original writes it. */\nexport function toValueExpression(ts: TypeScriptModule, value: string | number): ts.Expression {\n return typeof value === \"number\"\n ? toNumberExpression(ts, value)\n : ts.factory.createStringLiteral(value);\n}\n\n/** The original writes JSON-encoded literal types as identifiers to keep UTF-8 readable. */\nfunction toStringLiteralType(\n ts: TypeScriptModule,\n value: string,\n encoding: \"json\" | \"escaped\",\n): ts.TypeNode {\n return encoding === \"json\"\n ? (ts.factory.createIdentifier(JSON.stringify(value)) as unknown as ts.TypeNode)\n : ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value));\n}\n\nfunction toTupleElement(ts: TypeScriptModule, element: IrTupleElement): ts.TypeNode {\n const type = toTypeNode(ts, element.type);\n if (element.isOptional) {\n return ts.factory.createOptionalTypeNode(type);\n }\n return element.isRest ? ts.factory.createRestTypeNode(type) : type;\n}\n\ntype LeafType = Extract<\n IrType,\n { kind: \"keyword\" | \"stringLiteral\" | \"numberLiteral\" | \"booleanLiteral\" | \"raw\" }\n>;\n\nfunction toLeafTypeNode(ts: TypeScriptModule, type: LeafType): ts.TypeNode {\n switch (type.kind) {\n case \"keyword\":\n return toKeywordType(ts, type.keyword);\n case \"stringLiteral\":\n return toStringLiteralType(ts, type.value, type.encoding);\n case \"numberLiteral\":\n return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));\n case \"booleanLiteral\":\n return ts.factory.createLiteralTypeNode(\n type.value ? ts.factory.createTrue() : ts.factory.createFalse(),\n );\n case \"raw\":\n // A node read from TypeScript goes back as it was, so the TypeScript printer indents it.\n return (\n (type.origin as ts.TypeNode | undefined) ??\n (ts.factory.createIdentifier(type.text) as unknown as ts.TypeNode)\n );\n default:\n return assertNever(type);\n }\n}\n\nfunction toReferenceNode(\n ts: TypeScriptModule,\n type: Extract<IrType, { kind: \"reference\" }>,\n): ts.TypeNode {\n const typeArguments =\n type.typeArguments.length > 0\n ? type.typeArguments.map((argument) => toTypeNode(ts, argument))\n : undefined;\n return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type.name), typeArguments);\n}\n\n/** Convert one IR type. */\nexport function toTypeNode(ts: TypeScriptModule, type: IrType): ts.TypeNode {\n const convert = (inner: IrType) => toTypeNode(ts, inner);\n const { factory } = ts;\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n case \"raw\":\n return toLeafTypeNode(ts, type);\n case \"reference\":\n return toReferenceNode(ts, type);\n case \"array\":\n return factory.createArrayTypeNode(convert(type.element));\n case \"tuple\":\n return factory.createTupleTypeNode(\n type.elements.map((element) => toTupleElement(ts, element)),\n );\n case \"union\":\n return factory.createUnionTypeNode(type.types.map(convert));\n case \"intersection\":\n return factory.createIntersectionTypeNode(type.types.map(convert));\n case \"object\":\n return factory.createTypeLiteralNode(type.members.map((member) => toTypeElement(ts, member)));\n case \"indexedAccess\":\n return factory.createIndexedAccessTypeNode(convert(type.object), convert(type.index));\n case \"readonly\":\n return factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, convert(type.type));\n default:\n return assertNever(type);\n }\n}\n\n/** Attach IR comments to a node as synthetic leading comments, as the original does. */\nexport function withComments<T extends ts.Node>(\n ts: TypeScriptModule,\n node: T,\n comments: readonly IrComment[],\n): T {\n for (const comment of comments) {\n const kind =\n comment.kind === \"block\"\n ? ts.SyntaxKind.MultiLineCommentTrivia\n : ts.SyntaxKind.SingleLineCommentTrivia;\n ts.addSyntheticLeadingComment(node, kind, comment.text, true);\n }\n return node;\n}\n\nfunction toPropertyName(ts: TypeScriptModule, name: IrPropertyName): ts.PropertyName {\n switch (name.kind) {\n case \"identifier\":\n return ts.factory.createIdentifier(name.text);\n case \"string\":\n return ts.factory.createStringLiteral(name.value);\n case \"number\":\n return ts.factory.createNumericLiteral(name.text);\n default:\n return assertNever(name);\n }\n}\n\nfunction readonlyModifiers(ts: TypeScriptModule, isReadonly: boolean): ts.Modifier[] | undefined {\n return isReadonly ? [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined;\n}\n\n/** Convert one property signature (for callbacks that receive a `ts.PropertySignature`). */\nexport function toPropertySignature(\n ts: TypeScriptModule,\n property: IrPropertySignature,\n): ts.PropertySignature {\n const questionToken = property.isOptional\n ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)\n : undefined;\n const signature = ts.factory.createPropertySignature(\n readonlyModifiers(ts, property.isReadonly),\n toPropertyName(ts, property.name),\n questionToken,\n toTypeNode(ts, property.type),\n );\n return withComments(ts, signature, property.comments);\n}\n\nexport function toTypeElement(ts: TypeScriptModule, member: IrMember): ts.TypeElement {\n if (member.kind === \"property\") {\n return toPropertySignature(ts, member);\n }\n const parameter = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n member.parameterName,\n undefined,\n toTypeNode(ts, member.parameterType),\n );\n const signature = ts.factory.createIndexSignature(\n readonlyModifiers(ts, member.isReadonly),\n [parameter],\n toTypeNode(ts, member.type),\n );\n return withComments(ts, signature, member.comments);\n}\n"],"names":["assertNever"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ir-to-typescript.cjs","sources":["../../../src/adapters/type-ast-bridge/ir-to-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { assertNever } from \"../../domain/assert-never.js\";\nimport { DEFAULT_STRING_ENCODING } from \"../../domain/ir/constructors.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\n\n/**\n * Convert IR to TypeScript AST nodes with the same factory calls the original generator makes.\n * Printing the result with the TypeScript printer gives the original output, which is how the\n * printer parity tests (ENGINEERING_PLAN 4.3) define \"byte-identical\". Every function takes the\n * TypeScript module to build with (ADR-004, decision 4): the nodes must come from the same module\n * that later reads or prints them.\n */\n\ntype KeywordName = Exclude<IrKeyword, \"null\">;\n\nfunction keywordKind(ts: TypeScriptModule, keyword: KeywordName): ts.KeywordTypeSyntaxKind {\n const kinds: Readonly<Record<KeywordName, ts.KeywordTypeSyntaxKind>> = {\n string: ts.SyntaxKind.StringKeyword,\n number: ts.SyntaxKind.NumberKeyword,\n boolean: ts.SyntaxKind.BooleanKeyword,\n undefined: ts.SyntaxKind.UndefinedKeyword,\n unknown: ts.SyntaxKind.UnknownKeyword,\n never: ts.SyntaxKind.NeverKeyword,\n };\n return kinds[keyword];\n}\n\nfunction toKeywordType(ts: TypeScriptModule, keyword: IrKeyword): ts.TypeNode {\n return keyword === \"null\"\n ? ts.factory.createLiteralTypeNode(ts.factory.createNull())\n : ts.factory.createKeywordTypeNode(keywordKind(ts, keyword));\n}\n\n/**\n * Numbers as the original writes them: a negative value is a prefix minus on its absolute value.\n */\nfunction toNumberExpression(\n ts: TypeScriptModule,\n value: number,\n): ts.PrefixUnaryExpression | ts.NumericLiteral {\n return value < 0\n ? ts.factory.createPrefixUnaryExpression(\n ts.SyntaxKind.MinusToken,\n ts.factory.createNumericLiteral(Math.abs(value)),\n )\n : ts.factory.createNumericLiteral(value);\n}\n\n/** An enum member or array element value, written as the original writes it. */\nexport function toValueExpression(ts: TypeScriptModule, value: string | number): ts.Expression {\n return typeof value === \"number\"\n ? toNumberExpression(ts, value)\n : ts.factory.createStringLiteral(value);\n}\n\n/** The original writes JSON-encoded literal types as identifiers to keep UTF-8 readable. */\nfunction toStringLiteralType(\n ts: TypeScriptModule,\n value: string,\n encoding: \"json\" | \"escaped\",\n): ts.TypeNode {\n return encoding === \"json\"\n ? (ts.factory.createIdentifier(JSON.stringify(value)) as unknown as ts.TypeNode)\n : ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value));\n}\n\nfunction toTupleElement(ts: TypeScriptModule, element: IrTupleElement): ts.TypeNode {\n const type = toTypeNode(ts, element.type);\n if (element.isOptional) {\n return ts.factory.createOptionalTypeNode(type);\n }\n return element.isRest ? ts.factory.createRestTypeNode(type) : type;\n}\n\ntype LeafType = Extract<\n IrType,\n { kind: \"keyword\" | \"stringLiteral\" | \"numberLiteral\" | \"booleanLiteral\" | \"raw\" }\n>;\n\nfunction toLeafTypeNode(ts: TypeScriptModule, type: LeafType): ts.TypeNode {\n switch (type.kind) {\n case \"keyword\":\n return toKeywordType(ts, type.keyword);\n case \"stringLiteral\":\n return toStringLiteralType(ts, type.value, type.encoding ?? DEFAULT_STRING_ENCODING);\n case \"numberLiteral\":\n return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));\n case \"booleanLiteral\":\n return ts.factory.createLiteralTypeNode(\n type.value ? ts.factory.createTrue() : ts.factory.createFalse(),\n );\n case \"raw\":\n // A node read from TypeScript goes back as it was, so the TypeScript printer indents it.\n return (\n (type.origin as ts.TypeNode | undefined) ??\n (ts.factory.createIdentifier(type.text) as unknown as ts.TypeNode)\n );\n default:\n return assertNever(type);\n }\n}\n\nfunction toReferenceNode(\n ts: TypeScriptModule,\n type: Extract<IrType, { kind: \"reference\" }>,\n): ts.TypeNode {\n const typeArguments =\n type.typeArguments.length > 0\n ? type.typeArguments.map((argument) => toTypeNode(ts, argument))\n : undefined;\n return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type.name), typeArguments);\n}\n\n/** Convert one IR type. */\nexport function toTypeNode(ts: TypeScriptModule, type: IrType): ts.TypeNode {\n const convert = (inner: IrType) => toTypeNode(ts, inner);\n const { factory } = ts;\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n case \"raw\":\n return toLeafTypeNode(ts, type);\n case \"reference\":\n return toReferenceNode(ts, type);\n case \"array\":\n return factory.createArrayTypeNode(convert(type.element));\n case \"tuple\":\n return factory.createTupleTypeNode(\n type.elements.map((element) => toTupleElement(ts, element)),\n );\n case \"union\":\n return factory.createUnionTypeNode(type.types.map(convert));\n case \"intersection\":\n return factory.createIntersectionTypeNode(type.types.map(convert));\n case \"object\":\n return factory.createTypeLiteralNode(type.members.map((member) => toTypeElement(ts, member)));\n case \"indexedAccess\":\n return factory.createIndexedAccessTypeNode(convert(type.object), convert(type.index));\n case \"readonly\":\n return factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, convert(type.type));\n default:\n return assertNever(type);\n }\n}\n\n/** Attach IR comments to a node as synthetic leading comments, as the original does. */\nexport function withComments<T extends ts.Node>(\n ts: TypeScriptModule,\n node: T,\n comments: readonly IrComment[],\n): T {\n for (const comment of comments) {\n const kind =\n comment.kind === \"block\"\n ? ts.SyntaxKind.MultiLineCommentTrivia\n : ts.SyntaxKind.SingleLineCommentTrivia;\n ts.addSyntheticLeadingComment(node, kind, comment.text, true);\n }\n return node;\n}\n\nfunction toPropertyName(ts: TypeScriptModule, name: IrPropertyName): ts.PropertyName {\n switch (name.kind) {\n case \"identifier\":\n return ts.factory.createIdentifier(name.text);\n case \"string\":\n return ts.factory.createStringLiteral(name.value);\n case \"number\":\n return ts.factory.createNumericLiteral(name.text);\n default:\n return assertNever(name);\n }\n}\n\nfunction readonlyModifiers(ts: TypeScriptModule, isReadonly: boolean): ts.Modifier[] | undefined {\n return isReadonly ? [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined;\n}\n\n/** Convert one property signature (for callbacks that receive a `ts.PropertySignature`). */\nexport function toPropertySignature(\n ts: TypeScriptModule,\n property: IrPropertySignature,\n): ts.PropertySignature {\n const questionToken = property.isOptional\n ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)\n : undefined;\n const signature = ts.factory.createPropertySignature(\n readonlyModifiers(ts, property.isReadonly),\n toPropertyName(ts, property.name),\n questionToken,\n toTypeNode(ts, property.type),\n );\n return withComments(ts, signature, property.comments);\n}\n\nexport function toTypeElement(ts: TypeScriptModule, member: IrMember): ts.TypeElement {\n if (member.kind === \"property\") {\n return toPropertySignature(ts, member);\n }\n const parameter = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n member.parameterName,\n undefined,\n toTypeNode(ts, member.parameterType),\n );\n const signature = ts.factory.createIndexSignature(\n readonlyModifiers(ts, member.isReadonly),\n [parameter],\n toTypeNode(ts, member.type),\n );\n return withComments(ts, signature, member.comments);\n}\n"],"names":["DEFAULT_STRING_ENCODING","assertNever"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertNever } from '../../domain/assert-never.mjs';
|
|
2
|
+
import { DEFAULT_STRING_ENCODING } from '../../domain/ir/constructors.mjs';
|
|
2
3
|
|
|
3
4
|
function keywordKind(ts, keyword) {
|
|
4
5
|
const kinds = {
|
|
@@ -38,7 +39,7 @@ function toLeafTypeNode(ts, type) {
|
|
|
38
39
|
case "keyword":
|
|
39
40
|
return toKeywordType(ts, type.keyword);
|
|
40
41
|
case "stringLiteral":
|
|
41
|
-
return toStringLiteralType(ts, type.value, type.encoding);
|
|
42
|
+
return toStringLiteralType(ts, type.value, type.encoding ?? DEFAULT_STRING_ENCODING);
|
|
42
43
|
case "numberLiteral":
|
|
43
44
|
return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));
|
|
44
45
|
case "booleanLiteral":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-to-typescript.mjs","sources":["../../../src/adapters/type-ast-bridge/ir-to-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { assertNever } from \"../../domain/assert-never.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\n\n/**\n * Convert IR to TypeScript AST nodes with the same factory calls the original generator makes.\n * Printing the result with the TypeScript printer gives the original output, which is how the\n * printer parity tests (ENGINEERING_PLAN 4.3) define \"byte-identical\". Every function takes the\n * TypeScript module to build with (ADR-004, decision 4): the nodes must come from the same module\n * that later reads or prints them.\n */\n\ntype KeywordName = Exclude<IrKeyword, \"null\">;\n\nfunction keywordKind(ts: TypeScriptModule, keyword: KeywordName): ts.KeywordTypeSyntaxKind {\n const kinds: Readonly<Record<KeywordName, ts.KeywordTypeSyntaxKind>> = {\n string: ts.SyntaxKind.StringKeyword,\n number: ts.SyntaxKind.NumberKeyword,\n boolean: ts.SyntaxKind.BooleanKeyword,\n undefined: ts.SyntaxKind.UndefinedKeyword,\n unknown: ts.SyntaxKind.UnknownKeyword,\n never: ts.SyntaxKind.NeverKeyword,\n };\n return kinds[keyword];\n}\n\nfunction toKeywordType(ts: TypeScriptModule, keyword: IrKeyword): ts.TypeNode {\n return keyword === \"null\"\n ? ts.factory.createLiteralTypeNode(ts.factory.createNull())\n : ts.factory.createKeywordTypeNode(keywordKind(ts, keyword));\n}\n\n/**\n * Numbers as the original writes them: a negative value is a prefix minus on its absolute value.\n */\nfunction toNumberExpression(\n ts: TypeScriptModule,\n value: number,\n): ts.PrefixUnaryExpression | ts.NumericLiteral {\n return value < 0\n ? ts.factory.createPrefixUnaryExpression(\n ts.SyntaxKind.MinusToken,\n ts.factory.createNumericLiteral(Math.abs(value)),\n )\n : ts.factory.createNumericLiteral(value);\n}\n\n/** An enum member or array element value, written as the original writes it. */\nexport function toValueExpression(ts: TypeScriptModule, value: string | number): ts.Expression {\n return typeof value === \"number\"\n ? toNumberExpression(ts, value)\n : ts.factory.createStringLiteral(value);\n}\n\n/** The original writes JSON-encoded literal types as identifiers to keep UTF-8 readable. */\nfunction toStringLiteralType(\n ts: TypeScriptModule,\n value: string,\n encoding: \"json\" | \"escaped\",\n): ts.TypeNode {\n return encoding === \"json\"\n ? (ts.factory.createIdentifier(JSON.stringify(value)) as unknown as ts.TypeNode)\n : ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value));\n}\n\nfunction toTupleElement(ts: TypeScriptModule, element: IrTupleElement): ts.TypeNode {\n const type = toTypeNode(ts, element.type);\n if (element.isOptional) {\n return ts.factory.createOptionalTypeNode(type);\n }\n return element.isRest ? ts.factory.createRestTypeNode(type) : type;\n}\n\ntype LeafType = Extract<\n IrType,\n { kind: \"keyword\" | \"stringLiteral\" | \"numberLiteral\" | \"booleanLiteral\" | \"raw\" }\n>;\n\nfunction toLeafTypeNode(ts: TypeScriptModule, type: LeafType): ts.TypeNode {\n switch (type.kind) {\n case \"keyword\":\n return toKeywordType(ts, type.keyword);\n case \"stringLiteral\":\n return toStringLiteralType(ts, type.value, type.encoding);\n case \"numberLiteral\":\n return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));\n case \"booleanLiteral\":\n return ts.factory.createLiteralTypeNode(\n type.value ? ts.factory.createTrue() : ts.factory.createFalse(),\n );\n case \"raw\":\n // A node read from TypeScript goes back as it was, so the TypeScript printer indents it.\n return (\n (type.origin as ts.TypeNode | undefined) ??\n (ts.factory.createIdentifier(type.text) as unknown as ts.TypeNode)\n );\n default:\n return assertNever(type);\n }\n}\n\nfunction toReferenceNode(\n ts: TypeScriptModule,\n type: Extract<IrType, { kind: \"reference\" }>,\n): ts.TypeNode {\n const typeArguments =\n type.typeArguments.length > 0\n ? type.typeArguments.map((argument) => toTypeNode(ts, argument))\n : undefined;\n return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type.name), typeArguments);\n}\n\n/** Convert one IR type. */\nexport function toTypeNode(ts: TypeScriptModule, type: IrType): ts.TypeNode {\n const convert = (inner: IrType) => toTypeNode(ts, inner);\n const { factory } = ts;\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n case \"raw\":\n return toLeafTypeNode(ts, type);\n case \"reference\":\n return toReferenceNode(ts, type);\n case \"array\":\n return factory.createArrayTypeNode(convert(type.element));\n case \"tuple\":\n return factory.createTupleTypeNode(\n type.elements.map((element) => toTupleElement(ts, element)),\n );\n case \"union\":\n return factory.createUnionTypeNode(type.types.map(convert));\n case \"intersection\":\n return factory.createIntersectionTypeNode(type.types.map(convert));\n case \"object\":\n return factory.createTypeLiteralNode(type.members.map((member) => toTypeElement(ts, member)));\n case \"indexedAccess\":\n return factory.createIndexedAccessTypeNode(convert(type.object), convert(type.index));\n case \"readonly\":\n return factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, convert(type.type));\n default:\n return assertNever(type);\n }\n}\n\n/** Attach IR comments to a node as synthetic leading comments, as the original does. */\nexport function withComments<T extends ts.Node>(\n ts: TypeScriptModule,\n node: T,\n comments: readonly IrComment[],\n): T {\n for (const comment of comments) {\n const kind =\n comment.kind === \"block\"\n ? ts.SyntaxKind.MultiLineCommentTrivia\n : ts.SyntaxKind.SingleLineCommentTrivia;\n ts.addSyntheticLeadingComment(node, kind, comment.text, true);\n }\n return node;\n}\n\nfunction toPropertyName(ts: TypeScriptModule, name: IrPropertyName): ts.PropertyName {\n switch (name.kind) {\n case \"identifier\":\n return ts.factory.createIdentifier(name.text);\n case \"string\":\n return ts.factory.createStringLiteral(name.value);\n case \"number\":\n return ts.factory.createNumericLiteral(name.text);\n default:\n return assertNever(name);\n }\n}\n\nfunction readonlyModifiers(ts: TypeScriptModule, isReadonly: boolean): ts.Modifier[] | undefined {\n return isReadonly ? [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined;\n}\n\n/** Convert one property signature (for callbacks that receive a `ts.PropertySignature`). */\nexport function toPropertySignature(\n ts: TypeScriptModule,\n property: IrPropertySignature,\n): ts.PropertySignature {\n const questionToken = property.isOptional\n ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)\n : undefined;\n const signature = ts.factory.createPropertySignature(\n readonlyModifiers(ts, property.isReadonly),\n toPropertyName(ts, property.name),\n questionToken,\n toTypeNode(ts, property.type),\n );\n return withComments(ts, signature, property.comments);\n}\n\nexport function toTypeElement(ts: TypeScriptModule, member: IrMember): ts.TypeElement {\n if (member.kind === \"property\") {\n return toPropertySignature(ts, member);\n }\n const parameter = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n member.parameterName,\n undefined,\n toTypeNode(ts, member.parameterType),\n );\n const signature = ts.factory.createIndexSignature(\n readonlyModifiers(ts, member.isReadonly),\n [parameter],\n toTypeNode(ts, member.type),\n );\n return withComments(ts, signature, member.comments);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ir-to-typescript.mjs","sources":["../../../src/adapters/type-ast-bridge/ir-to-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { assertNever } from \"../../domain/assert-never.js\";\nimport { DEFAULT_STRING_ENCODING } from \"../../domain/ir/constructors.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\n\n/**\n * Convert IR to TypeScript AST nodes with the same factory calls the original generator makes.\n * Printing the result with the TypeScript printer gives the original output, which is how the\n * printer parity tests (ENGINEERING_PLAN 4.3) define \"byte-identical\". Every function takes the\n * TypeScript module to build with (ADR-004, decision 4): the nodes must come from the same module\n * that later reads or prints them.\n */\n\ntype KeywordName = Exclude<IrKeyword, \"null\">;\n\nfunction keywordKind(ts: TypeScriptModule, keyword: KeywordName): ts.KeywordTypeSyntaxKind {\n const kinds: Readonly<Record<KeywordName, ts.KeywordTypeSyntaxKind>> = {\n string: ts.SyntaxKind.StringKeyword,\n number: ts.SyntaxKind.NumberKeyword,\n boolean: ts.SyntaxKind.BooleanKeyword,\n undefined: ts.SyntaxKind.UndefinedKeyword,\n unknown: ts.SyntaxKind.UnknownKeyword,\n never: ts.SyntaxKind.NeverKeyword,\n };\n return kinds[keyword];\n}\n\nfunction toKeywordType(ts: TypeScriptModule, keyword: IrKeyword): ts.TypeNode {\n return keyword === \"null\"\n ? ts.factory.createLiteralTypeNode(ts.factory.createNull())\n : ts.factory.createKeywordTypeNode(keywordKind(ts, keyword));\n}\n\n/**\n * Numbers as the original writes them: a negative value is a prefix minus on its absolute value.\n */\nfunction toNumberExpression(\n ts: TypeScriptModule,\n value: number,\n): ts.PrefixUnaryExpression | ts.NumericLiteral {\n return value < 0\n ? ts.factory.createPrefixUnaryExpression(\n ts.SyntaxKind.MinusToken,\n ts.factory.createNumericLiteral(Math.abs(value)),\n )\n : ts.factory.createNumericLiteral(value);\n}\n\n/** An enum member or array element value, written as the original writes it. */\nexport function toValueExpression(ts: TypeScriptModule, value: string | number): ts.Expression {\n return typeof value === \"number\"\n ? toNumberExpression(ts, value)\n : ts.factory.createStringLiteral(value);\n}\n\n/** The original writes JSON-encoded literal types as identifiers to keep UTF-8 readable. */\nfunction toStringLiteralType(\n ts: TypeScriptModule,\n value: string,\n encoding: \"json\" | \"escaped\",\n): ts.TypeNode {\n return encoding === \"json\"\n ? (ts.factory.createIdentifier(JSON.stringify(value)) as unknown as ts.TypeNode)\n : ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value));\n}\n\nfunction toTupleElement(ts: TypeScriptModule, element: IrTupleElement): ts.TypeNode {\n const type = toTypeNode(ts, element.type);\n if (element.isOptional) {\n return ts.factory.createOptionalTypeNode(type);\n }\n return element.isRest ? ts.factory.createRestTypeNode(type) : type;\n}\n\ntype LeafType = Extract<\n IrType,\n { kind: \"keyword\" | \"stringLiteral\" | \"numberLiteral\" | \"booleanLiteral\" | \"raw\" }\n>;\n\nfunction toLeafTypeNode(ts: TypeScriptModule, type: LeafType): ts.TypeNode {\n switch (type.kind) {\n case \"keyword\":\n return toKeywordType(ts, type.keyword);\n case \"stringLiteral\":\n return toStringLiteralType(ts, type.value, type.encoding ?? DEFAULT_STRING_ENCODING);\n case \"numberLiteral\":\n return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));\n case \"booleanLiteral\":\n return ts.factory.createLiteralTypeNode(\n type.value ? ts.factory.createTrue() : ts.factory.createFalse(),\n );\n case \"raw\":\n // A node read from TypeScript goes back as it was, so the TypeScript printer indents it.\n return (\n (type.origin as ts.TypeNode | undefined) ??\n (ts.factory.createIdentifier(type.text) as unknown as ts.TypeNode)\n );\n default:\n return assertNever(type);\n }\n}\n\nfunction toReferenceNode(\n ts: TypeScriptModule,\n type: Extract<IrType, { kind: \"reference\" }>,\n): ts.TypeNode {\n const typeArguments =\n type.typeArguments.length > 0\n ? type.typeArguments.map((argument) => toTypeNode(ts, argument))\n : undefined;\n return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type.name), typeArguments);\n}\n\n/** Convert one IR type. */\nexport function toTypeNode(ts: TypeScriptModule, type: IrType): ts.TypeNode {\n const convert = (inner: IrType) => toTypeNode(ts, inner);\n const { factory } = ts;\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n case \"raw\":\n return toLeafTypeNode(ts, type);\n case \"reference\":\n return toReferenceNode(ts, type);\n case \"array\":\n return factory.createArrayTypeNode(convert(type.element));\n case \"tuple\":\n return factory.createTupleTypeNode(\n type.elements.map((element) => toTupleElement(ts, element)),\n );\n case \"union\":\n return factory.createUnionTypeNode(type.types.map(convert));\n case \"intersection\":\n return factory.createIntersectionTypeNode(type.types.map(convert));\n case \"object\":\n return factory.createTypeLiteralNode(type.members.map((member) => toTypeElement(ts, member)));\n case \"indexedAccess\":\n return factory.createIndexedAccessTypeNode(convert(type.object), convert(type.index));\n case \"readonly\":\n return factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, convert(type.type));\n default:\n return assertNever(type);\n }\n}\n\n/** Attach IR comments to a node as synthetic leading comments, as the original does. */\nexport function withComments<T extends ts.Node>(\n ts: TypeScriptModule,\n node: T,\n comments: readonly IrComment[],\n): T {\n for (const comment of comments) {\n const kind =\n comment.kind === \"block\"\n ? ts.SyntaxKind.MultiLineCommentTrivia\n : ts.SyntaxKind.SingleLineCommentTrivia;\n ts.addSyntheticLeadingComment(node, kind, comment.text, true);\n }\n return node;\n}\n\nfunction toPropertyName(ts: TypeScriptModule, name: IrPropertyName): ts.PropertyName {\n switch (name.kind) {\n case \"identifier\":\n return ts.factory.createIdentifier(name.text);\n case \"string\":\n return ts.factory.createStringLiteral(name.value);\n case \"number\":\n return ts.factory.createNumericLiteral(name.text);\n default:\n return assertNever(name);\n }\n}\n\nfunction readonlyModifiers(ts: TypeScriptModule, isReadonly: boolean): ts.Modifier[] | undefined {\n return isReadonly ? [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined;\n}\n\n/** Convert one property signature (for callbacks that receive a `ts.PropertySignature`). */\nexport function toPropertySignature(\n ts: TypeScriptModule,\n property: IrPropertySignature,\n): ts.PropertySignature {\n const questionToken = property.isOptional\n ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)\n : undefined;\n const signature = ts.factory.createPropertySignature(\n readonlyModifiers(ts, property.isReadonly),\n toPropertyName(ts, property.name),\n questionToken,\n toTypeNode(ts, property.type),\n );\n return withComments(ts, signature, property.comments);\n}\n\nexport function toTypeElement(ts: TypeScriptModule, member: IrMember): ts.TypeElement {\n if (member.kind === \"property\") {\n return toPropertySignature(ts, member);\n }\n const parameter = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n member.parameterName,\n undefined,\n toTypeNode(ts, member.parameterType),\n );\n const signature = ts.factory.createIndexSignature(\n readonlyModifiers(ts, member.isReadonly),\n [parameter],\n toTypeNode(ts, member.type),\n );\n return withComments(ts, signature, member.comments);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-typescript.cjs","sources":["../../../src/adapters/type-ast-bridge/print-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\n\n/** Options of `astToString` for the TypeScript printer, as in the original. */\nexport interface AstToStringOptions {\n fileName?: string;\n sourceText?: string;\n formatOptions?:
|
|
1
|
+
{"version":3,"file":"print-typescript.cjs","sources":["../../../src/adapters/type-ast-bridge/print-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\nimport type { ts as CompilerTypes } from \"./typescript-types.js\";\n\n/** Options of `astToString` for the TypeScript printer, as in the original. */\nexport interface AstToStringOptions {\n fileName?: string;\n sourceText?: string;\n /** The installed compiler's printer options (ADR-032: named without `ts.PrinterOptions`). */\n formatOptions?: CompilerTypes.PrinterOptions;\n}\n\n/** Print TypeScript nodes as the original `astToString` did. */\nexport function printWithTypeScript(\n ts: TypeScriptModule,\n nodes: readonly ts.Node[],\n options?: AstToStringOptions,\n): string {\n const sourceFile = ts.createSourceFile(\n options?.fileName ?? \"openapi-ts.ts\",\n options?.sourceText ?? \"\",\n ts.ScriptTarget.ESNext,\n false,\n ts.ScriptKind.TS,\n );\n // The source file is new and not shared, so its statements can be set once.\n (sourceFile as { statements: ts.NodeArray<ts.Statement> }).statements =\n ts.factory.createNodeArray(nodes as readonly ts.Statement[]);\n const printer = ts.createPrinter({\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n ...options?.formatOptions,\n });\n return printer.printFile(sourceFile);\n}\n"],"names":[],"mappings":";;AAaO,SAAS,mBAAA,CACd,EAAA,EACA,KAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,aAAa,EAAA,CAAG,gBAAA;AAAA,IACpB,SAAS,QAAA,IAAY,eAAA;AAAA,IACrB,SAAS,UAAA,IAAc,EAAA;AAAA,IACvB,GAAG,YAAA,CAAa,MAAA;AAAA,IAChB,KAAA;AAAA,IACA,GAAG,UAAA,CAAW;AAAA,GAChB;AAEA,EAAC,UAAA,CAA0D,UAAA,GACzD,EAAA,CAAG,OAAA,CAAQ,gBAAgB,KAAgC,CAAA;AAC7D,EAAA,MAAM,OAAA,GAAU,GAAG,aAAA,CAAc;AAAA,IAC/B,OAAA,EAAS,GAAG,WAAA,CAAY,QAAA;AAAA,IACxB,cAAA,EAAgB,KAAA;AAAA,IAChB,GAAG,OAAA,EAAS;AAAA,GACb,CAAA;AACD,EAAA,OAAO,OAAA,CAAQ,UAAU,UAAU,CAAA;AACrC;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-typescript.mjs","sources":["../../../src/adapters/type-ast-bridge/print-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\n\n/** Options of `astToString` for the TypeScript printer, as in the original. */\nexport interface AstToStringOptions {\n fileName?: string;\n sourceText?: string;\n formatOptions?:
|
|
1
|
+
{"version":3,"file":"print-typescript.mjs","sources":["../../../src/adapters/type-ast-bridge/print-typescript.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\nimport type { ts as CompilerTypes } from \"./typescript-types.js\";\n\n/** Options of `astToString` for the TypeScript printer, as in the original. */\nexport interface AstToStringOptions {\n fileName?: string;\n sourceText?: string;\n /** The installed compiler's printer options (ADR-032: named without `ts.PrinterOptions`). */\n formatOptions?: CompilerTypes.PrinterOptions;\n}\n\n/** Print TypeScript nodes as the original `astToString` did. */\nexport function printWithTypeScript(\n ts: TypeScriptModule,\n nodes: readonly ts.Node[],\n options?: AstToStringOptions,\n): string {\n const sourceFile = ts.createSourceFile(\n options?.fileName ?? \"openapi-ts.ts\",\n options?.sourceText ?? \"\",\n ts.ScriptTarget.ESNext,\n false,\n ts.ScriptKind.TS,\n );\n // The source file is new and not shared, so its statements can be set once.\n (sourceFile as { statements: ts.NodeArray<ts.Statement> }).statements =\n ts.factory.createNodeArray(nodes as readonly ts.Statement[]);\n const printer = ts.createPrinter({\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n ...options?.formatOptions,\n });\n return printer.printFile(sourceFile);\n}\n"],"names":[],"mappings":"AAaO,SAAS,mBAAA,CACd,EAAA,EACA,KAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,aAAa,EAAA,CAAG,gBAAA;AAAA,IACpB,SAAS,QAAA,IAAY,eAAA;AAAA,IACrB,SAAS,UAAA,IAAc,EAAA;AAAA,IACvB,GAAG,YAAA,CAAa,MAAA;AAAA,IAChB,KAAA;AAAA,IACA,GAAG,UAAA,CAAW;AAAA,GAChB;AAEA,EAAC,UAAA,CAA0D,UAAA,GACzD,EAAA,CAAG,OAAA,CAAQ,gBAAgB,KAAgC,CAAA;AAC7D,EAAA,MAAM,OAAA,GAAU,GAAG,aAAA,CAAc;AAAA,IAC/B,OAAA,EAAS,GAAG,WAAA,CAAY,QAAA;AAAA,IACxB,cAAA,EAAgB,KAAA;AAAA,IAChB,GAAG,OAAA,EAAS;AAAA,GACb,CAAA;AACD,EAAA,OAAO,OAAA,CAAQ,UAAU,UAAU,CAAA;AACrC;;"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const node_perf_hooks = require('node:perf_hooks');
|
|
4
4
|
const openapiCore = require('@redocly/openapi-core');
|
|
5
5
|
const supportsColor = require('supports-color');
|
|
6
|
+
const nodeDeprecations = require('../adapters/node-deprecations/node-deprecations.cjs');
|
|
6
7
|
const terminalLogger = require('../adapters/terminal-logger/terminal-logger.cjs');
|
|
7
8
|
|
|
8
9
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -21,7 +22,17 @@ function defaultLogger(silent) {
|
|
|
21
22
|
sink: console
|
|
22
23
|
});
|
|
23
24
|
}
|
|
25
|
+
function defaultDeprecationReporter() {
|
|
26
|
+
return nodeDeprecations.createNodeDeprecationReporter();
|
|
27
|
+
}
|
|
24
28
|
const REMOTE_REF_TIMEOUT_MS = 6e4;
|
|
29
|
+
const DEFAULT_REMOTE_DOCUMENT_LIMITS = {
|
|
30
|
+
maxDocuments: 1e4,
|
|
31
|
+
maxParallelFetches: 16
|
|
32
|
+
};
|
|
33
|
+
function processCwd() {
|
|
34
|
+
return process.cwd();
|
|
35
|
+
}
|
|
25
36
|
function monotonicNow() {
|
|
26
37
|
return node_perf_hooks.performance.now();
|
|
27
38
|
}
|
|
@@ -30,9 +41,12 @@ function defaultRedoclyConfig() {
|
|
|
30
41
|
return openapiCore.createConfig({ rules }, { extends: ["minimal"] });
|
|
31
42
|
}
|
|
32
43
|
|
|
44
|
+
exports.DEFAULT_REMOTE_DOCUMENT_LIMITS = DEFAULT_REMOTE_DOCUMENT_LIMITS;
|
|
33
45
|
exports.REMOTE_REF_TIMEOUT_MS = REMOTE_REF_TIMEOUT_MS;
|
|
46
|
+
exports.defaultDeprecationReporter = defaultDeprecationReporter;
|
|
34
47
|
exports.defaultLogger = defaultLogger;
|
|
35
48
|
exports.defaultRedoclyConfig = defaultRedoclyConfig;
|
|
36
49
|
exports.monotonicNow = monotonicNow;
|
|
50
|
+
exports.processCwd = processCwd;
|
|
37
51
|
exports.terminalSupportsColor = terminalSupportsColor;
|
|
38
52
|
//# sourceMappingURL=default-ports.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-ports.cjs","sources":["../../src/api/default-ports.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { createConfig, type Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport supportsColor from \"supports-color\";\nimport { createTerminalLogger } from \"../adapters/terminal-logger/terminal-logger.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\n\n/**\n * The default adapters of the Node API (ENGINEERING_PLAN 4.5): this module and the CLI's\n * composition root are where the process environment is read.\n */\n\n/** Colors when the terminal supports them, as the original decided. */\nexport function terminalSupportsColor(): boolean {\n const stdout = supportsColor.stdout;\n return Boolean(stdout) && stdout !== false && stdout.hasBasic !== false;\n}\n\n/** The terminal logger with `DEBUG` from the environment, writing to the console. */\nexport function defaultLogger(silent: boolean): Logger {\n return createTerminalLogger({\n silent,\n debugFilter: process.env.DEBUG,\n useColors: terminalSupportsColor(),\n sink: console,\n });\n}\n\n/**\n * How long one remote `$ref` (or a remote source) may take to load. Large documents (the 27 MB\n * Cloudflare spec) download in seconds; a minute covers slow hosts, while Node's own fetch would\n * wait five minutes for a server that never answers (ENGINEERING_PLAN 8.5).\n */\nexport const REMOTE_REF_TIMEOUT_MS = 60_000;\n\n/** A monotonic clock in milliseconds, for debug durations. */\nexport function monotonicNow(): number {\n return performance.now();\n}\n\n/** The default Redocly config: minimal rules, and duplicate operation IDs are an error. */\nexport function defaultRedoclyConfig(): Promise<RedoclyConfig> {\n const rules = { \"operation-operationId-unique\": { severity: \"error\" as const } };\n return createConfig({ rules }, { extends: [\"minimal\"] });\n}\n"],"names":["supportsColor","createTerminalLogger","performance","createConfig"],"mappings":"
|
|
1
|
+
{"version":3,"file":"default-ports.cjs","sources":["../../src/api/default-ports.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { createConfig, type Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport supportsColor from \"supports-color\";\nimport { createNodeDeprecationReporter } from \"../adapters/node-deprecations/node-deprecations.js\";\nimport type { RemoteDocumentLimits } from \"../adapters/redocly-loader/remote-fetch.js\";\nimport { createTerminalLogger } from \"../adapters/terminal-logger/terminal-logger.js\";\nimport type { DeprecationReporter } from \"../application/ports/deprecation-reporter.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\n\n/**\n * The default adapters of the Node API (ENGINEERING_PLAN 4.5): this module and the CLI's\n * composition root are where the process environment is read.\n */\n\n/** Colors when the terminal supports them, as the original decided. */\nexport function terminalSupportsColor(): boolean {\n const stdout = supportsColor.stdout;\n return Boolean(stdout) && stdout !== false && stdout.hasBasic !== false;\n}\n\n/** The terminal logger with `DEBUG` from the environment, writing to the console. */\nexport function defaultLogger(silent: boolean): Logger {\n return createTerminalLogger({\n silent,\n debugFilter: process.env.DEBUG,\n useColors: terminalSupportsColor(),\n sink: console,\n });\n}\n\n/** Deprecations as Node.js `DeprecationWarning`s, each code once per process. */\nexport function defaultDeprecationReporter(): DeprecationReporter {\n return createNodeDeprecationReporter();\n}\n\n/**\n * How long one remote `$ref` (or a remote source) may take to load. Large documents (the 27 MB\n * Cloudflare spec) download in seconds; a minute covers slow hosts, while Node's own fetch would\n * wait five minutes for a server that never answers (ENGINEERING_PLAN 8.5).\n */\nexport const REMOTE_REF_TIMEOUT_MS = 60_000;\n\n/**\n * Bounds on the remote documents of one run (ADR-033). Large split documents have a few thousand\n * files, so 10,000 leaves room and still ends an endless fan-out. 16 parallel fetches keep a\n * multi-file document fast without exhausting local ports.\n */\nexport const DEFAULT_REMOTE_DOCUMENT_LIMITS: RemoteDocumentLimits = {\n maxDocuments: 10_000,\n maxParallelFetches: 16,\n};\n\n/** The working directory of the process: the default `cwd` of an inline source. */\nexport function processCwd(): string {\n return process.cwd();\n}\n\n/** A monotonic clock in milliseconds, for debug durations. */\nexport function monotonicNow(): number {\n return performance.now();\n}\n\n/** The default Redocly config: minimal rules, and duplicate operation IDs are an error. */\nexport function defaultRedoclyConfig(): Promise<RedoclyConfig> {\n const rules = { \"operation-operationId-unique\": { severity: \"error\" as const } };\n return createConfig({ rules }, { extends: [\"minimal\"] });\n}\n"],"names":["supportsColor","createTerminalLogger","createNodeDeprecationReporter","performance","createConfig"],"mappings":";;;;;;;;;;;;AAeO,SAAS,qBAAA,GAAiC;AAC/C,EAAA,MAAM,SAASA,sBAAA,CAAc,MAAA;AAC7B,EAAA,OAAO,QAAQ,MAAM,CAAA,IAAK,MAAA,KAAW,KAAA,IAAS,OAAO,QAAA,KAAa,KAAA;AACpE;AAGO,SAAS,cAAc,MAAA,EAAyB;AACrD,EAAA,OAAOC,mCAAA,CAAqB;AAAA,IAC1B,MAAA;AAAA,IACA,WAAA,EAAa,QAAQ,GAAA,CAAI,KAAA;AAAA,IACzB,WAAW,qBAAA,EAAsB;AAAA,IACjC,IAAA,EAAM;AAAA,GACP,CAAA;AACH;AAGO,SAAS,0BAAA,GAAkD;AAChE,EAAA,OAAOC,8CAAA,EAA8B;AACvC;AAOO,MAAM,qBAAA,GAAwB;AAO9B,MAAM,8BAAA,GAAuD;AAAA,EAClE,YAAA,EAAc,GAAA;AAAA,EACd,kBAAA,EAAoB;AACtB;AAGO,SAAS,UAAA,GAAqB;AACnC,EAAA,OAAO,QAAQ,GAAA,EAAI;AACrB;AAGO,SAAS,YAAA,GAAuB;AACrC,EAAA,OAAOC,4BAAY,GAAA,EAAI;AACzB;AAGO,SAAS,oBAAA,GAA+C;AAC7D,EAAA,MAAM,QAAQ,EAAE,8BAAA,EAAgC,EAAE,QAAA,EAAU,SAAiB,EAAE;AAC/E,EAAA,OAAOC,wBAAA,CAAa,EAAE,KAAA,EAAM,EAAG,EAAE,OAAA,EAAS,CAAC,SAAS,CAAA,EAAG,CAAA;AACzD;;;;;;;;;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { performance } from 'node:perf_hooks';
|
|
2
2
|
import { createConfig } from '@redocly/openapi-core';
|
|
3
3
|
import supportsColor from 'supports-color';
|
|
4
|
+
import { createNodeDeprecationReporter } from '../adapters/node-deprecations/node-deprecations.mjs';
|
|
4
5
|
import { createTerminalLogger } from '../adapters/terminal-logger/terminal-logger.mjs';
|
|
5
6
|
|
|
6
7
|
function terminalSupportsColor() {
|
|
@@ -15,7 +16,17 @@ function defaultLogger(silent) {
|
|
|
15
16
|
sink: console
|
|
16
17
|
});
|
|
17
18
|
}
|
|
19
|
+
function defaultDeprecationReporter() {
|
|
20
|
+
return createNodeDeprecationReporter();
|
|
21
|
+
}
|
|
18
22
|
const REMOTE_REF_TIMEOUT_MS = 6e4;
|
|
23
|
+
const DEFAULT_REMOTE_DOCUMENT_LIMITS = {
|
|
24
|
+
maxDocuments: 1e4,
|
|
25
|
+
maxParallelFetches: 16
|
|
26
|
+
};
|
|
27
|
+
function processCwd() {
|
|
28
|
+
return process.cwd();
|
|
29
|
+
}
|
|
19
30
|
function monotonicNow() {
|
|
20
31
|
return performance.now();
|
|
21
32
|
}
|
|
@@ -24,5 +35,5 @@ function defaultRedoclyConfig() {
|
|
|
24
35
|
return createConfig({ rules }, { extends: ["minimal"] });
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
export { REMOTE_REF_TIMEOUT_MS, defaultLogger, defaultRedoclyConfig, monotonicNow, terminalSupportsColor };
|
|
38
|
+
export { DEFAULT_REMOTE_DOCUMENT_LIMITS, REMOTE_REF_TIMEOUT_MS, defaultDeprecationReporter, defaultLogger, defaultRedoclyConfig, monotonicNow, processCwd, terminalSupportsColor };
|
|
28
39
|
//# sourceMappingURL=default-ports.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-ports.mjs","sources":["../../src/api/default-ports.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { createConfig, type Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport supportsColor from \"supports-color\";\nimport { createTerminalLogger } from \"../adapters/terminal-logger/terminal-logger.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\n\n/**\n * The default adapters of the Node API (ENGINEERING_PLAN 4.5): this module and the CLI's\n * composition root are where the process environment is read.\n */\n\n/** Colors when the terminal supports them, as the original decided. */\nexport function terminalSupportsColor(): boolean {\n const stdout = supportsColor.stdout;\n return Boolean(stdout) && stdout !== false && stdout.hasBasic !== false;\n}\n\n/** The terminal logger with `DEBUG` from the environment, writing to the console. */\nexport function defaultLogger(silent: boolean): Logger {\n return createTerminalLogger({\n silent,\n debugFilter: process.env.DEBUG,\n useColors: terminalSupportsColor(),\n sink: console,\n });\n}\n\n/**\n * How long one remote `$ref` (or a remote source) may take to load. Large documents (the 27 MB\n * Cloudflare spec) download in seconds; a minute covers slow hosts, while Node's own fetch would\n * wait five minutes for a server that never answers (ENGINEERING_PLAN 8.5).\n */\nexport const REMOTE_REF_TIMEOUT_MS = 60_000;\n\n/** A monotonic clock in milliseconds, for debug durations. */\nexport function monotonicNow(): number {\n return performance.now();\n}\n\n/** The default Redocly config: minimal rules, and duplicate operation IDs are an error. */\nexport function defaultRedoclyConfig(): Promise<RedoclyConfig> {\n const rules = { \"operation-operationId-unique\": { severity: \"error\" as const } };\n return createConfig({ rules }, { extends: [\"minimal\"] });\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"default-ports.mjs","sources":["../../src/api/default-ports.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { createConfig, type Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport supportsColor from \"supports-color\";\nimport { createNodeDeprecationReporter } from \"../adapters/node-deprecations/node-deprecations.js\";\nimport type { RemoteDocumentLimits } from \"../adapters/redocly-loader/remote-fetch.js\";\nimport { createTerminalLogger } from \"../adapters/terminal-logger/terminal-logger.js\";\nimport type { DeprecationReporter } from \"../application/ports/deprecation-reporter.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\n\n/**\n * The default adapters of the Node API (ENGINEERING_PLAN 4.5): this module and the CLI's\n * composition root are where the process environment is read.\n */\n\n/** Colors when the terminal supports them, as the original decided. */\nexport function terminalSupportsColor(): boolean {\n const stdout = supportsColor.stdout;\n return Boolean(stdout) && stdout !== false && stdout.hasBasic !== false;\n}\n\n/** The terminal logger with `DEBUG` from the environment, writing to the console. */\nexport function defaultLogger(silent: boolean): Logger {\n return createTerminalLogger({\n silent,\n debugFilter: process.env.DEBUG,\n useColors: terminalSupportsColor(),\n sink: console,\n });\n}\n\n/** Deprecations as Node.js `DeprecationWarning`s, each code once per process. */\nexport function defaultDeprecationReporter(): DeprecationReporter {\n return createNodeDeprecationReporter();\n}\n\n/**\n * How long one remote `$ref` (or a remote source) may take to load. Large documents (the 27 MB\n * Cloudflare spec) download in seconds; a minute covers slow hosts, while Node's own fetch would\n * wait five minutes for a server that never answers (ENGINEERING_PLAN 8.5).\n */\nexport const REMOTE_REF_TIMEOUT_MS = 60_000;\n\n/**\n * Bounds on the remote documents of one run (ADR-033). Large split documents have a few thousand\n * files, so 10,000 leaves room and still ends an endless fan-out. 16 parallel fetches keep a\n * multi-file document fast without exhausting local ports.\n */\nexport const DEFAULT_REMOTE_DOCUMENT_LIMITS: RemoteDocumentLimits = {\n maxDocuments: 10_000,\n maxParallelFetches: 16,\n};\n\n/** The working directory of the process: the default `cwd` of an inline source. */\nexport function processCwd(): string {\n return process.cwd();\n}\n\n/** A monotonic clock in milliseconds, for debug durations. */\nexport function monotonicNow(): number {\n return performance.now();\n}\n\n/** The default Redocly config: minimal rules, and duplicate operation IDs are an error. */\nexport function defaultRedoclyConfig(): Promise<RedoclyConfig> {\n const rules = { \"operation-operationId-unique\": { severity: \"error\" as const } };\n return createConfig({ rules }, { extends: [\"minimal\"] });\n}\n"],"names":[],"mappings":";;;;;;AAeO,SAAS,qBAAA,GAAiC;AAC/C,EAAA,MAAM,SAAS,aAAA,CAAc,MAAA;AAC7B,EAAA,OAAO,QAAQ,MAAM,CAAA,IAAK,MAAA,KAAW,KAAA,IAAS,OAAO,QAAA,KAAa,KAAA;AACpE;AAGO,SAAS,cAAc,MAAA,EAAyB;AACrD,EAAA,OAAO,oBAAA,CAAqB;AAAA,IAC1B,MAAA;AAAA,IACA,WAAA,EAAa,QAAQ,GAAA,CAAI,KAAA;AAAA,IACzB,WAAW,qBAAA,EAAsB;AAAA,IACjC,IAAA,EAAM;AAAA,GACP,CAAA;AACH;AAGO,SAAS,0BAAA,GAAkD;AAChE,EAAA,OAAO,6BAAA,EAA8B;AACvC;AAOO,MAAM,qBAAA,GAAwB;AAO9B,MAAM,8BAAA,GAAuD;AAAA,EAClE,YAAA,EAAc,GAAA;AAAA,EACd,kBAAA,EAAoB;AACtB;AAGO,SAAS,UAAA,GAAqB;AACnC,EAAA,OAAO,QAAQ,GAAA,EAAI;AACrB;AAGO,SAAS,YAAA,GAAuB;AACrC,EAAA,OAAO,YAAY,GAAA,EAAI;AACzB;AAGO,SAAS,oBAAA,GAA+C;AAC7D,EAAA,MAAM,QAAQ,EAAE,8BAAA,EAAgC,EAAE,QAAA,EAAU,SAAiB,EAAE;AAC/E,EAAA,OAAO,YAAA,CAAa,EAAE,KAAA,EAAM,EAAG,EAAE,OAAA,EAAS,CAAC,SAAS,CAAA,EAAG,CAAA;AACzD;;"}
|
|
@@ -15,7 +15,7 @@ function warningOf(conflict) {
|
|
|
15
15
|
return `${member}: the discriminator "${propertyName}" of ${owner} gives this schema the value ${listed(values)}, which its "${propertyName}" property does not allow (${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} See ${DOCS_URL}`;
|
|
16
16
|
}
|
|
17
17
|
function warnDiscriminatorValueConflicts(document, fixes, logger) {
|
|
18
|
-
const isUnionReused = fixes.includes(outputFixes.
|
|
18
|
+
const isUnionReused = fixes.includes(outputFixes.FIX.ALLOF_DISCRIMINATED_UNION);
|
|
19
19
|
for (const conflict of discriminatorConflicts.findDiscriminatorValueConflicts(document, { isUnionReused })) {
|
|
20
20
|
logger.warn(warnings.warningText(warningOf(conflict), warnings.WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discriminator-conflict-warnings.cjs","sources":["../../src/api/discriminator-conflict-warnings.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport {\n type DiscriminatorValueConflict,\n findDiscriminatorValueConflicts,\n} from \"../domain/openapi/discriminator-conflicts.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\n\nconst DOCS_BASE_URL = \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs\";\nconst DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;\n\nfunction listed(values: readonly unknown[]): string {\n return values.map((value) => JSON.stringify(value)).join(\", \");\n}\n\nfunction warningOf(conflict: DiscriminatorValueConflict): string {\n const { member, owner, propertyName, values, allowed, isImplicit } = conflict;\n const rule = isImplicit\n ? \"A Discriminator Object without a mapping entry for a schema gives it its schema name as \" +\n `the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: \"${member}\".`\n : \"The Discriminator Object maps these values to the schema; map the values it allows.\";\n return (\n `${member}: the discriminator \"${propertyName}\" of ${owner} gives this schema the value ` +\n `${listed(values)}, which its \"${propertyName}\" property does not allow ` +\n `(${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} ` +\n `See ${DOCS_URL}`\n );\n}\n\n/**\n * Warn once per discriminator member whose value its own property does not allow. The members\n * depend on the run's fixes (`allof-discriminated-union`).\n */\nexport function warnDiscriminatorValueConflicts(\n document: unknown,\n fixes: readonly OutputFix[],\n logger: Logger,\n): void {\n const isUnionReused = fixes.includes(
|
|
1
|
+
{"version":3,"file":"discriminator-conflict-warnings.cjs","sources":["../../src/api/discriminator-conflict-warnings.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport {\n type DiscriminatorValueConflict,\n findDiscriminatorValueConflicts,\n} from \"../domain/openapi/discriminator-conflicts.js\";\nimport { FIX, type OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\n\nconst DOCS_BASE_URL = \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs\";\nconst DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;\n\nfunction listed(values: readonly unknown[]): string {\n return values.map((value) => JSON.stringify(value)).join(\", \");\n}\n\nfunction warningOf(conflict: DiscriminatorValueConflict): string {\n const { member, owner, propertyName, values, allowed, isImplicit } = conflict;\n const rule = isImplicit\n ? \"A Discriminator Object without a mapping entry for a schema gives it its schema name as \" +\n `the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: \"${member}\".`\n : \"The Discriminator Object maps these values to the schema; map the values it allows.\";\n return (\n `${member}: the discriminator \"${propertyName}\" of ${owner} gives this schema the value ` +\n `${listed(values)}, which its \"${propertyName}\" property does not allow ` +\n `(${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} ` +\n `See ${DOCS_URL}`\n );\n}\n\n/**\n * Warn once per discriminator member whose value its own property does not allow. The members\n * depend on the run's fixes (`allof-discriminated-union`).\n */\nexport function warnDiscriminatorValueConflicts(\n document: unknown,\n fixes: readonly OutputFix[],\n logger: Logger,\n): void {\n const isUnionReused = fixes.includes(FIX.ALLOF_DISCRIMINATED_UNION);\n for (const conflict of findDiscriminatorValueConflicts(document, { isUnionReused })) {\n logger.warn(warningText(warningOf(conflict), WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));\n }\n}\n"],"names":["FIX","findDiscriminatorValueConflicts","warningText","WARNING_CODES"],"mappings":";;;;;;AAQA,MAAM,aAAA,GAAgB,qEAAA;AACtB,MAAM,QAAA,GAAW,GAAG,aAAa,CAAA,iCAAA,CAAA;AAEjC,SAAS,OAAO,MAAA,EAAoC;AAClD,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,IAAA,CAAK,UAAU,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC/D;AAEA,SAAS,UAAU,QAAA,EAA8C;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,cAAc,MAAA,EAAQ,OAAA,EAAS,YAAW,GAAI,QAAA;AACrE,EAAA,MAAM,IAAA,GAAO,UAAA,GACT,CAAA,+HAAA,EAC0C,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,GAAA,EAAM,MAAM,CAAA,EAAA,CAAA,GAChF,qFAAA;AACJ,EAAA,OACE,GAAG,MAAM,CAAA,qBAAA,EAAwB,YAAY,CAAA,KAAA,EAAQ,KAAK,gCACvD,MAAA,CAAO,MAAM,CAAC,CAAA,aAAA,EAAgB,YAAY,8BACzC,MAAA,CAAO,OAAO,CAAC,CAAA,wDAAA,EAA2D,IAAI,QAC3E,QAAQ,CAAA,CAAA;AAEnB;AAMO,SAAS,+BAAA,CACd,QAAA,EACA,KAAA,EACA,MAAA,EACM;AACN,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,QAAA,CAASA,eAAA,CAAI,yBAAyB,CAAA;AAClE,EAAA,KAAA,MAAW,YAAYC,sDAAA,CAAgC,QAAA,EAAU,EAAE,aAAA,EAAe,CAAA,EAAG;AACnF,IAAA,MAAA,CAAO,KAAKC,oBAAA,CAAY,SAAA,CAAU,QAAQ,CAAA,EAAGC,sBAAA,CAAc,+BAA+B,CAAC,CAAA;AAAA,EAC7F;AACF;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { findDiscriminatorValueConflicts } from '../domain/openapi/discriminator-conflicts.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import { FIX } from '../domain/output-fixes.mjs';
|
|
3
3
|
import { warningText, WARNING_CODES } from '../domain/warnings.mjs';
|
|
4
4
|
|
|
5
5
|
const DOCS_BASE_URL = "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs";
|
|
@@ -13,7 +13,7 @@ function warningOf(conflict) {
|
|
|
13
13
|
return `${member}: the discriminator "${propertyName}" of ${owner} gives this schema the value ${listed(values)}, which its "${propertyName}" property does not allow (${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} See ${DOCS_URL}`;
|
|
14
14
|
}
|
|
15
15
|
function warnDiscriminatorValueConflicts(document, fixes, logger) {
|
|
16
|
-
const isUnionReused = fixes.includes(
|
|
16
|
+
const isUnionReused = fixes.includes(FIX.ALLOF_DISCRIMINATED_UNION);
|
|
17
17
|
for (const conflict of findDiscriminatorValueConflicts(document, { isUnionReused })) {
|
|
18
18
|
logger.warn(warningText(warningOf(conflict), WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discriminator-conflict-warnings.mjs","sources":["../../src/api/discriminator-conflict-warnings.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport {\n type DiscriminatorValueConflict,\n findDiscriminatorValueConflicts,\n} from \"../domain/openapi/discriminator-conflicts.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\n\nconst DOCS_BASE_URL = \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs\";\nconst DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;\n\nfunction listed(values: readonly unknown[]): string {\n return values.map((value) => JSON.stringify(value)).join(\", \");\n}\n\nfunction warningOf(conflict: DiscriminatorValueConflict): string {\n const { member, owner, propertyName, values, allowed, isImplicit } = conflict;\n const rule = isImplicit\n ? \"A Discriminator Object without a mapping entry for a schema gives it its schema name as \" +\n `the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: \"${member}\".`\n : \"The Discriminator Object maps these values to the schema; map the values it allows.\";\n return (\n `${member}: the discriminator \"${propertyName}\" of ${owner} gives this schema the value ` +\n `${listed(values)}, which its \"${propertyName}\" property does not allow ` +\n `(${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} ` +\n `See ${DOCS_URL}`\n );\n}\n\n/**\n * Warn once per discriminator member whose value its own property does not allow. The members\n * depend on the run's fixes (`allof-discriminated-union`).\n */\nexport function warnDiscriminatorValueConflicts(\n document: unknown,\n fixes: readonly OutputFix[],\n logger: Logger,\n): void {\n const isUnionReused = fixes.includes(
|
|
1
|
+
{"version":3,"file":"discriminator-conflict-warnings.mjs","sources":["../../src/api/discriminator-conflict-warnings.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport {\n type DiscriminatorValueConflict,\n findDiscriminatorValueConflicts,\n} from \"../domain/openapi/discriminator-conflicts.js\";\nimport { FIX, type OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\n\nconst DOCS_BASE_URL = \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs\";\nconst DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;\n\nfunction listed(values: readonly unknown[]): string {\n return values.map((value) => JSON.stringify(value)).join(\", \");\n}\n\nfunction warningOf(conflict: DiscriminatorValueConflict): string {\n const { member, owner, propertyName, values, allowed, isImplicit } = conflict;\n const rule = isImplicit\n ? \"A Discriminator Object without a mapping entry for a schema gives it its schema name as \" +\n `the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: \"${member}\".`\n : \"The Discriminator Object maps these values to the schema; map the values it allows.\";\n return (\n `${member}: the discriminator \"${propertyName}\" of ${owner} gives this schema the value ` +\n `${listed(values)}, which its \"${propertyName}\" property does not allow ` +\n `(${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} ` +\n `See ${DOCS_URL}`\n );\n}\n\n/**\n * Warn once per discriminator member whose value its own property does not allow. The members\n * depend on the run's fixes (`allof-discriminated-union`).\n */\nexport function warnDiscriminatorValueConflicts(\n document: unknown,\n fixes: readonly OutputFix[],\n logger: Logger,\n): void {\n const isUnionReused = fixes.includes(FIX.ALLOF_DISCRIMINATED_UNION);\n for (const conflict of findDiscriminatorValueConflicts(document, { isUnionReused })) {\n logger.warn(warningText(warningOf(conflict), WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));\n }\n}\n"],"names":[],"mappings":";;;;AAQA,MAAM,aAAA,GAAgB,qEAAA;AACtB,MAAM,QAAA,GAAW,GAAG,aAAa,CAAA,iCAAA,CAAA;AAEjC,SAAS,OAAO,MAAA,EAAoC;AAClD,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,IAAA,CAAK,UAAU,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC/D;AAEA,SAAS,UAAU,QAAA,EAA8C;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,cAAc,MAAA,EAAQ,OAAA,EAAS,YAAW,GAAI,QAAA;AACrE,EAAA,MAAM,IAAA,GAAO,UAAA,GACT,CAAA,+HAAA,EAC0C,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,GAAA,EAAM,MAAM,CAAA,EAAA,CAAA,GAChF,qFAAA;AACJ,EAAA,OACE,GAAG,MAAM,CAAA,qBAAA,EAAwB,YAAY,CAAA,KAAA,EAAQ,KAAK,gCACvD,MAAA,CAAO,MAAM,CAAC,CAAA,aAAA,EAAgB,YAAY,8BACzC,MAAA,CAAO,OAAO,CAAC,CAAA,wDAAA,EAA2D,IAAI,QAC3E,QAAQ,CAAA,CAAA;AAEnB;AAMO,SAAS,+BAAA,CACd,QAAA,EACA,KAAA,EACA,MAAA,EACM;AACN,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,yBAAyB,CAAA;AAClE,EAAA,KAAA,MAAW,YAAY,+BAAA,CAAgC,QAAA,EAAU,EAAE,aAAA,EAAe,CAAA,EAAG;AACnF,IAAA,MAAA,CAAO,KAAK,WAAA,CAAY,SAAA,CAAU,QAAQ,CAAA,EAAG,aAAA,CAAc,+BAA+B,CAAC,CAAA;AAAA,EAC7F;AACF;;"}
|