openapi-typesafe 1.0.0-rc.1 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- 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 +9 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +8 -1
- package/dist/api/default-ports.mjs.map +1 -1
- package/dist/api/discriminator-patch.cjs +5 -1
- package/dist/api/discriminator-patch.cjs.map +1 -1
- package/dist/api/discriminator-patch.mjs +5 -1
- package/dist/api/discriminator-patch.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 +4 -2
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +4 -2
- 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 +4 -1
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +4 -1
- 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 +2 -1
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +3 -2
- package/dist/api/openapi-ts.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.map +1 -1
- 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/parameters.cjs +1 -1
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +1 -1
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +1 -1
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +1 -1
- 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/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/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/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 +9 -1
- package/dist/domain/warnings.cjs.map +1 -1
- package/dist/domain/warnings.mjs +9 -1
- package/dist/domain/warnings.mjs.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1160 -53
- package/dist/index.d.mts +1160 -53
- package/dist/index.d.ts +1160 -53
- package/dist/index.mjs +1 -0
- 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 +6 -5
- 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 +16 -0
- package/src/api/discriminator-patch.ts +7 -2
- package/src/api/document-refs.ts +19 -15
- package/src/api/document-run.ts +9 -6
- package/src/api/footer-sink.ts +34 -2
- package/src/api/legacy-callback-warning.ts +7 -3
- package/src/api/legacy-ts-helpers.ts +7 -5
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +2 -0
- package/src/api/run-context.ts +34 -0
- package/src/api/transform-context.ts +10 -8
- package/src/api/transform-schema.ts +6 -5
- package/src/application/print/type-printer.ts +2 -1
- package/src/application/transform/document/parameters.ts +2 -1
- package/src/application/transform/document/paths.ts +2 -1
- 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/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/errors.ts +8 -2
- 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/url-credentials.ts +18 -0
- package/src/domain/warnings.ts +8 -0
- package/src/index.ts +1 -0
- 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":"discriminator-patch.mjs","sources":["../../src/api/discriminator-patch.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport type { DiscriminatorObject, OpenAPI3, SchemaObject } from \"../types.js\";\nimport { addEnumProperty, declaresValues, type EnumPatch } from \"./discriminator-enum.js\";\nimport {\n type DiscriminatorOwner,\n type EnumParent,\n enumParentOf,\n} from \"./discriminator-enum-parent.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\n\n/**\n * The state of the discriminator pre-pass and the in-place patch of a mapped schema: the enum\n * property that the generated union narrows by. Two discriminators of one property may patch one\n * schema; how they combine is the `discriminator-values` fix (ADR-021, roadmap R12).\n */\n\n/** How to scan: the warnings, and the output fixes of the run (ADR-021). */\nexport interface DiscriminatorScanOptions {\n readonly silent: boolean;\n readonly logger: Logger;\n readonly fixes: ReadonlySet<OutputFix>;\n}\n\n/** What the two passes share: the document they patch and what they found so far. */\nexport interface ScanState extends DiscriminatorScanOptions {\n readonly schema: OpenAPI3;\n readonly objects: Record<string, DiscriminatorObject>;\n /** The schemas that define a discriminator themselves (pass 1), not by inheritance. */\n readonly owners: Set<string>;\n readonly refsHandled: string[];\n /** With the fix: the enum added to each schema, by schema and property, so values merge. */\n readonly patchedEnums: Map<string, SchemaObject>;\n /** With the fix: schema-name values, applied after both passes where no mapping names one. */\n readonly inferredPatches: EnumPatch[];\n /** With the fix: schema-name values of other properties (`inheritOtherOwners`). */\n readonly otherInferredPatches: EnumPatch[];\n /** With the fix: the other properties each schema got a value of (`inheritOtherOwners`). */\n readonly otherProperties: Record<string, string[]>;\n /** With `discriminator-values`: the enum keys that a schema declares itself. */\n readonly declaredKeys: Set<string>;\n /** With `discriminator-values`: the owner's enum of each added enum, by that enum. */\n readonly enumParents: Map<object, EnumParent>;\n}\n\n/** Whether `discriminator-values` is on: values of two discriminators merge into one enum. */\nexport function mergesValues(state: ScanState): boolean {\n return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES);\n}\n\nfunction patchedSchema(state: ScanState, patch: EnumPatch): SchemaObject | undefined {\n const { silent, logger } = state;\n return resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });\n}\n\n/**\n * With `discriminator-values`: the schema at `patch.ref` requires the property with\n * exactly these values already, so a patch would only repeat it (#2124).\n */\nfunction isDeclared(state: ScanState, patch: EnumPatch): boolean {\n return (\n state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) &&\n declaresValues(patchedSchema(state, patch), patch)\n );\n}\n\n/**\n * With `discriminator-values`: the enum of the owner's property, for `key`: an enum the scan\n * added, or a discriminator object that a schema inherited.\n */\nexport function recordEnumParent(state: ScanState, owner: DiscriminatorOwner, key: object): void {\n if (!state.fixes.has(OutputFix.DISCRIMINATOR_VALUES)) {\n return;\n }\n const { silent, logger } = state;\n const parent = enumParentOf(owner, (ref) =>\n resolveDocumentRef(state.schema, ref, { silent, logger }),\n );\n if (parent !== undefined) {\n state.enumParents.set(key, parent);\n }\n}\n\n/** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */\nfunction addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {\n const added = addEnumProperty(patchedSchema(state, patch), patch);\n if (added === null) {\n warnInvalidMapping(patch, state.logger);\n } else {\n recordEnumParent(state, patch, added);\n }\n return added;\n}\n\n/** One schema and discriminator property; two discriminators of one property share an enum. */\nexport function enumKey(patch: EnumPatch): string {\n return `${patch.ref}\\n${patch.discriminator.propertyName}`;\n}\n\n/** With the fix, a second discriminator of the same property adds its values to the first enum. */\nfunction mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {\n const patched = state.patchedEnums.get(key);\n if (patched === undefined) {\n return false;\n }\n const merged = patched.enum as unknown[];\n merged.push(...values.filter((value) => !merged.includes(value)));\n return true;\n}\n\n/**\n * Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a\n * warning, when that schema is neither an `allOf` nor an object schema. Without the fix every\n * patch adds a property, so two discriminators with different values intersect to `never`.\n */\nexport function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {\n if (isDeclared(state, patch)) {\n state.declaredKeys.add(enumKey(patch));\n return true;\n }\n if (!mergesValues(state)) {\n return addDiscriminatorEnum(state, patch) !== null;\n }\n const key = enumKey(patch);\n if (mergeIntoPatchedEnum(state, key, patch.values)) {\n return true;\n }\n const added = addDiscriminatorEnum(state, patch);\n if (added !== null) {\n state.patchedEnums.set(key, added);\n }\n return added !== null;\n}\n\nexport function markHandled(state: ScanState, ref: string): void {\n if (!state.refsHandled.includes(ref)) {\n state.refsHandled.push(ref);\n }\n}\n\nfunction warnInvalidMapping(patch: EnumPatch, logger: Logger): void {\n const mapped = `${patch.ref} => ${patch.values.join(\", \")}`;\n logger.warn(\n \"Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): \" +\n
|
|
1
|
+
{"version":3,"file":"discriminator-patch.mjs","sources":["../../src/api/discriminator-patch.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport type { DiscriminatorObject, OpenAPI3, SchemaObject } from \"../types.js\";\nimport { addEnumProperty, declaresValues, type EnumPatch } from \"./discriminator-enum.js\";\nimport {\n type DiscriminatorOwner,\n type EnumParent,\n enumParentOf,\n} from \"./discriminator-enum-parent.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\n\n/**\n * The state of the discriminator pre-pass and the in-place patch of a mapped schema: the enum\n * property that the generated union narrows by. Two discriminators of one property may patch one\n * schema; how they combine is the `discriminator-values` fix (ADR-021, roadmap R12).\n */\n\n/** How to scan: the warnings, and the output fixes of the run (ADR-021). */\nexport interface DiscriminatorScanOptions {\n readonly silent: boolean;\n readonly logger: Logger;\n readonly fixes: ReadonlySet<OutputFix>;\n}\n\n/** What the two passes share: the document they patch and what they found so far. */\nexport interface ScanState extends DiscriminatorScanOptions {\n readonly schema: OpenAPI3;\n readonly objects: Record<string, DiscriminatorObject>;\n /** The schemas that define a discriminator themselves (pass 1), not by inheritance. */\n readonly owners: Set<string>;\n readonly refsHandled: string[];\n /** With the fix: the enum added to each schema, by schema and property, so values merge. */\n readonly patchedEnums: Map<string, SchemaObject>;\n /** With the fix: schema-name values, applied after both passes where no mapping names one. */\n readonly inferredPatches: EnumPatch[];\n /** With the fix: schema-name values of other properties (`inheritOtherOwners`). */\n readonly otherInferredPatches: EnumPatch[];\n /** With the fix: the other properties each schema got a value of (`inheritOtherOwners`). */\n readonly otherProperties: Record<string, string[]>;\n /** With `discriminator-values`: the enum keys that a schema declares itself. */\n readonly declaredKeys: Set<string>;\n /** With `discriminator-values`: the owner's enum of each added enum, by that enum. */\n readonly enumParents: Map<object, EnumParent>;\n}\n\n/** Whether `discriminator-values` is on: values of two discriminators merge into one enum. */\nexport function mergesValues(state: ScanState): boolean {\n return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES);\n}\n\nfunction patchedSchema(state: ScanState, patch: EnumPatch): SchemaObject | undefined {\n const { silent, logger } = state;\n return resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });\n}\n\n/**\n * With `discriminator-values`: the schema at `patch.ref` requires the property with\n * exactly these values already, so a patch would only repeat it (#2124).\n */\nfunction isDeclared(state: ScanState, patch: EnumPatch): boolean {\n return (\n state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) &&\n declaresValues(patchedSchema(state, patch), patch)\n );\n}\n\n/**\n * With `discriminator-values`: the enum of the owner's property, for `key`: an enum the scan\n * added, or a discriminator object that a schema inherited.\n */\nexport function recordEnumParent(state: ScanState, owner: DiscriminatorOwner, key: object): void {\n if (!state.fixes.has(OutputFix.DISCRIMINATOR_VALUES)) {\n return;\n }\n const { silent, logger } = state;\n const parent = enumParentOf(owner, (ref) =>\n resolveDocumentRef(state.schema, ref, { silent, logger }),\n );\n if (parent !== undefined) {\n state.enumParents.set(key, parent);\n }\n}\n\n/** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */\nfunction addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {\n const added = addEnumProperty(patchedSchema(state, patch), patch);\n if (added === null) {\n warnInvalidMapping(patch, state.logger);\n } else {\n recordEnumParent(state, patch, added);\n }\n return added;\n}\n\n/** One schema and discriminator property; two discriminators of one property share an enum. */\nexport function enumKey(patch: EnumPatch): string {\n return `${patch.ref}\\n${patch.discriminator.propertyName}`;\n}\n\n/** With the fix, a second discriminator of the same property adds its values to the first enum. */\nfunction mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {\n const patched = state.patchedEnums.get(key);\n if (patched === undefined) {\n return false;\n }\n const merged = patched.enum as unknown[];\n merged.push(...values.filter((value) => !merged.includes(value)));\n return true;\n}\n\n/**\n * Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a\n * warning, when that schema is neither an `allOf` nor an object schema. Without the fix every\n * patch adds a property, so two discriminators with different values intersect to `never`.\n */\nexport function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {\n if (isDeclared(state, patch)) {\n state.declaredKeys.add(enumKey(patch));\n return true;\n }\n if (!mergesValues(state)) {\n return addDiscriminatorEnum(state, patch) !== null;\n }\n const key = enumKey(patch);\n if (mergeIntoPatchedEnum(state, key, patch.values)) {\n return true;\n }\n const added = addDiscriminatorEnum(state, patch);\n if (added !== null) {\n state.patchedEnums.set(key, added);\n }\n return added !== null;\n}\n\nexport function markHandled(state: ScanState, ref: string): void {\n if (!state.refsHandled.includes(ref)) {\n state.refsHandled.push(ref);\n }\n}\n\nfunction warnInvalidMapping(patch: EnumPatch, logger: Logger): void {\n const mapped = `${patch.ref} => ${patch.values.join(\", \")}`;\n logger.warn(\n warningText(\n \"Discriminator mapping has an invalid schema \" +\n \"(neither an object schema nor an allOf array): \" +\n `${mapped} (Discriminator: ${patch.discriminatorRef})`,\n WARNING_CODES.DISCRIMINATOR_MAPPING_INVALID,\n ),\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const refUtils_js = require('@redocly/openapi-core/lib/ref-utils.js');
|
|
4
|
+
const warnings = require('../domain/warnings.cjs');
|
|
4
5
|
const defaultPorts = require('./default-ports.cjs');
|
|
5
6
|
|
|
7
|
+
function isObject(value) {
|
|
8
|
+
return typeof value === "object" && value !== null;
|
|
9
|
+
}
|
|
6
10
|
function resolveDocumentRef(schema, $ref, options) {
|
|
7
11
|
const { visited = [] } = options;
|
|
8
12
|
const logger = options.logger ?? defaultPorts.defaultLogger(options.silent ?? false);
|
|
@@ -12,23 +16,22 @@ function resolveDocumentRef(schema, $ref, options) {
|
|
|
12
16
|
}
|
|
13
17
|
let node = schema;
|
|
14
18
|
for (const key of pointer) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
logger.warn(`Could not resolve $ref "${$ref}"`);
|
|
19
|
+
const child = isObject(node) ? node[key] : void 0;
|
|
20
|
+
if (!child) {
|
|
21
|
+
logger.warn(warnings.warningText(`Could not resolve $ref "${$ref}"`, warnings.WARNING_CODES.REF_NOT_FOUND));
|
|
19
22
|
return void 0;
|
|
20
23
|
}
|
|
24
|
+
node = child;
|
|
21
25
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
const next = isObject(node) ? node.$ref : void 0;
|
|
27
|
+
if (typeof next === "string" && next) {
|
|
28
|
+
if (visited.includes(next)) {
|
|
29
|
+
logger.warn(
|
|
30
|
+
warnings.warningText(`Could not resolve circular $ref "${$ref}"`, warnings.WARNING_CODES.REF_CIRCULAR)
|
|
31
|
+
);
|
|
25
32
|
return void 0;
|
|
26
33
|
}
|
|
27
|
-
return resolveDocumentRef(schema,
|
|
28
|
-
...options,
|
|
29
|
-
logger,
|
|
30
|
-
visited: [...visited, node.$ref]
|
|
31
|
-
});
|
|
34
|
+
return resolveDocumentRef(schema, next, { ...options, logger, visited: [...visited, next] });
|
|
32
35
|
}
|
|
33
36
|
return node;
|
|
34
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-refs.cjs","sources":["../../src/api/document-refs.ts"],"sourcesContent":["import { parseRef } from \"@redocly/openapi-core/lib/ref-utils.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport { defaultLogger } from \"./default-ports.js\";\n\n/** `$ref` resolution and the document walk that the generator's pre-pass uses. */\n\nexport interface ResolveRefOptions {\n silent: boolean;\n visited?: string[];\n /** @internal Where warnings go; the default terminal logger (respecting `silent`) if absent. */\n logger?: Logger;\n}\n\n/** Resolve a `$ref` in a document; warns and returns undefined when it cannot. */\nexport function resolveDocumentRef<T>(\n schema:
|
|
1
|
+
{"version":3,"file":"document-refs.cjs","sources":["../../src/api/document-refs.ts"],"sourcesContent":["import { parseRef } from \"@redocly/openapi-core/lib/ref-utils.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport { defaultLogger } from \"./default-ports.js\";\n\n/** `$ref` resolution and the document walk that the generator's pre-pass uses. */\n\nexport interface ResolveRefOptions {\n silent: boolean;\n visited?: string[];\n /** @internal Where warnings go; the default terminal logger (respecting `silent`) if absent. */\n logger?: Logger;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** Resolve a `$ref` in a document; warns and returns undefined when it cannot. */\nexport function resolveDocumentRef<T>(\n schema: unknown,\n $ref: string,\n options: ResolveRefOptions,\n): T | undefined {\n const { visited = [] } = options;\n const logger = options.logger ?? defaultLogger(options.silent ?? false);\n const { pointer } = parseRef($ref);\n if (!pointer.length) {\n return undefined;\n }\n let node: unknown = schema;\n for (const key of pointer) {\n const child = isObject(node) ? node[key] : undefined;\n if (!child) {\n logger.warn(warningText(`Could not resolve $ref \"${$ref}\"`, WARNING_CODES.REF_NOT_FOUND));\n return undefined;\n }\n node = child;\n }\n\n // if this is also a $ref, keep tracing\n const next = isObject(node) ? node.$ref : undefined;\n if (typeof next === \"string\" && next) {\n if (visited.includes(next)) {\n logger.warn(\n warningText(`Could not resolve circular $ref \"${$ref}\"`, WARNING_CODES.REF_CIRCULAR),\n );\n return undefined;\n }\n return resolveDocumentRef(schema, next, { ...options, logger, visited: [...visited, next] });\n }\n\n return node as T;\n}\n\n/** Call `cb` for every object in a JSON-serializable (non-circular) value, depth first. */\nexport function walkDocument(\n obj: unknown,\n cb: (value: Record<string, unknown>, path: (string | number)[]) => void,\n path: (string | number)[] = [],\n): void {\n if (!obj || typeof obj !== \"object\") {\n return;\n }\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n walkDocument(obj[i], cb, path.concat(i));\n }\n return;\n }\n cb(obj as Record<string, unknown>, path);\n for (const k of Object.keys(obj)) {\n walkDocument((obj as Record<string, unknown>)[k], cb, path.concat(k));\n }\n}\n"],"names":["defaultLogger","parseRef","warningText","WARNING_CODES"],"mappings":";;;;;;AAcA,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA;AAChD;AAGO,SAAS,kBAAA,CACd,MAAA,EACA,IAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAA,GAAU,EAAC,EAAE,GAAI,OAAA;AACzB,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,IAAUA,0BAAA,CAAc,OAAA,CAAQ,UAAU,KAAK,CAAA;AACtE,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAIC,oBAAA,CAAS,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,IAAA,GAAgB,MAAA;AACpB,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAM,QAAQ,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA;AAC3C,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAA,CAAO,KAAKC,oBAAA,CAAY,CAAA,wBAAA,EAA2B,IAAI,CAAA,CAAA,CAAA,EAAKC,sBAAA,CAAc,aAAa,CAAC,CAAA;AACxF,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IAAA,GAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAI,CAAA,GAAI,KAAK,IAAA,GAAO,MAAA;AAC1C,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,EAAM;AACpC,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,MAAA,MAAA,CAAO,IAAA;AAAA,QACLD,oBAAA,CAAY,CAAA,iCAAA,EAAoC,IAAI,CAAA,CAAA,CAAA,EAAKC,uBAAc,YAAY;AAAA,OACrF;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,kBAAA,CAAmB,MAAA,EAAQ,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAS,CAAC,GAAG,OAAA,EAAS,IAAI,GAAG,CAAA;AAAA,EAC7F;AAEA,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAA,CACd,GAAA,EACA,EAAA,EACA,IAAA,GAA4B,EAAC,EACvB;AACN,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,IAAA;AAAA,EACF;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,MAAA,YAAA,CAAa,IAAI,CAAC,CAAA,EAAG,IAAI,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IACzC;AACA,IAAA;AAAA,EACF;AACA,EAAA,EAAA,CAAG,KAAgC,IAAI,CAAA;AACvC,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG;AAChC,IAAA,YAAA,CAAc,IAAgC,CAAC,CAAA,EAAG,IAAI,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACtE;AACF;;;"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { parseRef } from '@redocly/openapi-core/lib/ref-utils.js';
|
|
2
|
+
import { warningText, WARNING_CODES } from '../domain/warnings.mjs';
|
|
2
3
|
import { defaultLogger } from './default-ports.mjs';
|
|
3
4
|
|
|
5
|
+
function isObject(value) {
|
|
6
|
+
return typeof value === "object" && value !== null;
|
|
7
|
+
}
|
|
4
8
|
function resolveDocumentRef(schema, $ref, options) {
|
|
5
9
|
const { visited = [] } = options;
|
|
6
10
|
const logger = options.logger ?? defaultLogger(options.silent ?? false);
|
|
@@ -10,23 +14,22 @@ function resolveDocumentRef(schema, $ref, options) {
|
|
|
10
14
|
}
|
|
11
15
|
let node = schema;
|
|
12
16
|
for (const key of pointer) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
logger.warn(`Could not resolve $ref "${$ref}"`);
|
|
17
|
+
const child = isObject(node) ? node[key] : void 0;
|
|
18
|
+
if (!child) {
|
|
19
|
+
logger.warn(warningText(`Could not resolve $ref "${$ref}"`, WARNING_CODES.REF_NOT_FOUND));
|
|
17
20
|
return void 0;
|
|
18
21
|
}
|
|
22
|
+
node = child;
|
|
19
23
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
const next = isObject(node) ? node.$ref : void 0;
|
|
25
|
+
if (typeof next === "string" && next) {
|
|
26
|
+
if (visited.includes(next)) {
|
|
27
|
+
logger.warn(
|
|
28
|
+
warningText(`Could not resolve circular $ref "${$ref}"`, WARNING_CODES.REF_CIRCULAR)
|
|
29
|
+
);
|
|
23
30
|
return void 0;
|
|
24
31
|
}
|
|
25
|
-
return resolveDocumentRef(schema,
|
|
26
|
-
...options,
|
|
27
|
-
logger,
|
|
28
|
-
visited: [...visited, node.$ref]
|
|
29
|
-
});
|
|
32
|
+
return resolveDocumentRef(schema, next, { ...options, logger, visited: [...visited, next] });
|
|
30
33
|
}
|
|
31
34
|
return node;
|
|
32
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-refs.mjs","sources":["../../src/api/document-refs.ts"],"sourcesContent":["import { parseRef } from \"@redocly/openapi-core/lib/ref-utils.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport { defaultLogger } from \"./default-ports.js\";\n\n/** `$ref` resolution and the document walk that the generator's pre-pass uses. */\n\nexport interface ResolveRefOptions {\n silent: boolean;\n visited?: string[];\n /** @internal Where warnings go; the default terminal logger (respecting `silent`) if absent. */\n logger?: Logger;\n}\n\n/** Resolve a `$ref` in a document; warns and returns undefined when it cannot. */\nexport function resolveDocumentRef<T>(\n schema:
|
|
1
|
+
{"version":3,"file":"document-refs.mjs","sources":["../../src/api/document-refs.ts"],"sourcesContent":["import { parseRef } from \"@redocly/openapi-core/lib/ref-utils.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport { defaultLogger } from \"./default-ports.js\";\n\n/** `$ref` resolution and the document walk that the generator's pre-pass uses. */\n\nexport interface ResolveRefOptions {\n silent: boolean;\n visited?: string[];\n /** @internal Where warnings go; the default terminal logger (respecting `silent`) if absent. */\n logger?: Logger;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** Resolve a `$ref` in a document; warns and returns undefined when it cannot. */\nexport function resolveDocumentRef<T>(\n schema: unknown,\n $ref: string,\n options: ResolveRefOptions,\n): T | undefined {\n const { visited = [] } = options;\n const logger = options.logger ?? defaultLogger(options.silent ?? false);\n const { pointer } = parseRef($ref);\n if (!pointer.length) {\n return undefined;\n }\n let node: unknown = schema;\n for (const key of pointer) {\n const child = isObject(node) ? node[key] : undefined;\n if (!child) {\n logger.warn(warningText(`Could not resolve $ref \"${$ref}\"`, WARNING_CODES.REF_NOT_FOUND));\n return undefined;\n }\n node = child;\n }\n\n // if this is also a $ref, keep tracing\n const next = isObject(node) ? node.$ref : undefined;\n if (typeof next === \"string\" && next) {\n if (visited.includes(next)) {\n logger.warn(\n warningText(`Could not resolve circular $ref \"${$ref}\"`, WARNING_CODES.REF_CIRCULAR),\n );\n return undefined;\n }\n return resolveDocumentRef(schema, next, { ...options, logger, visited: [...visited, next] });\n }\n\n return node as T;\n}\n\n/** Call `cb` for every object in a JSON-serializable (non-circular) value, depth first. */\nexport function walkDocument(\n obj: unknown,\n cb: (value: Record<string, unknown>, path: (string | number)[]) => void,\n path: (string | number)[] = [],\n): void {\n if (!obj || typeof obj !== \"object\") {\n return;\n }\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n walkDocument(obj[i], cb, path.concat(i));\n }\n return;\n }\n cb(obj as Record<string, unknown>, path);\n for (const k of Object.keys(obj)) {\n walkDocument((obj as Record<string, unknown>)[k], cb, path.concat(k));\n }\n}\n"],"names":[],"mappings":";;;;AAcA,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA;AAChD;AAGO,SAAS,kBAAA,CACd,MAAA,EACA,IAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAA,GAAU,EAAC,EAAE,GAAI,OAAA;AACzB,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,IAAU,aAAA,CAAc,OAAA,CAAQ,UAAU,KAAK,CAAA;AACtE,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,QAAA,CAAS,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,IAAA,GAAgB,MAAA;AACpB,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,MAAM,QAAQ,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA;AAC3C,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAA,CAAO,KAAK,WAAA,CAAY,CAAA,wBAAA,EAA2B,IAAI,CAAA,CAAA,CAAA,EAAK,aAAA,CAAc,aAAa,CAAC,CAAA;AACxF,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IAAA,GAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAI,CAAA,GAAI,KAAK,IAAA,GAAO,MAAA;AAC1C,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,EAAM;AACpC,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,WAAA,CAAY,CAAA,iCAAA,EAAoC,IAAI,CAAA,CAAA,CAAA,EAAK,cAAc,YAAY;AAAA,OACrF;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,kBAAA,CAAmB,MAAA,EAAQ,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAS,CAAC,GAAG,OAAA,EAAS,IAAI,GAAG,CAAA;AAAA,EAC7F;AAEA,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAA,CACd,GAAA,EACA,EAAA,EACA,IAAA,GAA4B,EAAC,EACvB;AACN,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,IAAA;AAAA,EACF;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,MAAA,YAAA,CAAa,IAAI,CAAC,CAAA,EAAG,IAAI,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IACzC;AACA,IAAA;AAAA,EACF;AACA,EAAA,EAAA,CAAG,KAAgC,IAAI,CAAA;AACvC,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG;AAChC,IAAA,YAAA,CAAc,IAAgC,CAAC,CAAA,EAAG,IAAI,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EACtE;AACF;;"}
|
|
@@ -5,6 +5,8 @@ const node_url = require('node:url');
|
|
|
5
5
|
const schemaLoadErrors = require('../adapters/redocly-loader/schema-load-errors.cjs');
|
|
6
6
|
const stackOverflow = require('../application/stack-overflow.cjs');
|
|
7
7
|
const outputFixes = require('../domain/output-fixes.cjs');
|
|
8
|
+
const warnings = require('../domain/warnings.cjs');
|
|
9
|
+
const defaultPorts = require('./default-ports.cjs');
|
|
8
10
|
const discriminatorConflictWarnings = require('./discriminator-conflict-warnings.cjs');
|
|
9
11
|
const discriminatorScan = require('./discriminator-scan.cjs');
|
|
10
12
|
const documentRefs = require('./document-refs.cjs');
|
|
@@ -20,7 +22,7 @@ function sourceCwd(options) {
|
|
|
20
22
|
if (cwd instanceof URL) {
|
|
21
23
|
return cwd.pathname.endsWith("/") ? cwd : new URL(`${cwd.pathname}/`, cwd);
|
|
22
24
|
}
|
|
23
|
-
const directory = path__default.resolve(cwd === void 0 ?
|
|
25
|
+
const directory = path__default.resolve(cwd === void 0 ? defaultPorts.processCwd() : cwd.toString());
|
|
24
26
|
return node_url.pathToFileURL(path__default.join(directory, path__default.sep));
|
|
25
27
|
}
|
|
26
28
|
function refAccessOf(options, cwd) {
|
|
@@ -70,7 +72,7 @@ function contextFlags(options) {
|
|
|
70
72
|
function outputFixesOf(options, logger) {
|
|
71
73
|
const names = outputFixes.outputFixNamesOf(options.fix ?? []);
|
|
72
74
|
for (const notice of outputFixes.ineffectiveFixNotices(names, (option) => options[option] === true)) {
|
|
73
|
-
logger.warn(notice);
|
|
75
|
+
logger.warn(warnings.warningText(notice, warnings.WARNING_CODES.FIX_NEEDS_OPTION));
|
|
74
76
|
}
|
|
75
77
|
return [...outputFixes.resolveOutputFixes(names)];
|
|
76
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-run.cjs","sources":["../../src/api/document-run.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport { sourceEmptyError } from \"../adapters/redocly-loader/schema-load-errors.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport type { RefAccess, SchemaLoader } from \"../application/ports/schema-loader.js\";\nimport { withStackOverflowReported } from \"../application/stack-overflow.js\";\nimport {\n ineffectiveFixNotices,\n type OutputFix,\n outputFixNamesOf,\n resolveOutputFixes,\n} from \"../domain/output-fixes.js\";\nimport type { GeneratorOptions, GlobalContext, OpenAPI3, SchemaSource } from \"../types.js\";\nimport { warnDiscriminatorValueConflicts } from \"./discriminator-conflict-warnings.js\";\nimport { findDiscriminators } from \"./discriminator-scan.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\nimport { warnIdenticalPathTemplates } from \"./path-template-warnings.js\";\nimport { warnUnsupportedFeatures } from \"./unsupported-feature-warnings.js\";\n\n/** The ports of one generator run, wired by the Node API or the CLI (ENGINEERING_PLAN 4.5). */\nexport interface GeneratorPorts {\n readonly loader: SchemaLoader;\n readonly logger: Logger;\n /** The Redocly config the loader uses; the run's context exposes it as `ctx.redoc`. */\n readonly redoc: RedoclyConfig;\n /** A monotonic time in milliseconds, for debug durations. */\n readonly now: () => number;\n}\n\n/** A validated, bundled document and the context of one generator run. */\nexport interface DocumentRun {\n readonly schema: OpenAPI3;\n readonly ctx: GlobalContext;\n}\n\n/** The context fields that are user flags, with the original defaults. */\ntype ContextFlags = Omit<\n GlobalContext,\n | \"discriminators\"\n | \"injectFooter\"\n | \"redoc\"\n | \"resolve\"\n | \"runFooter\"\n | \"legacyCallbackWarnings\"\n | \"logger\"\n | \"fix\"\n>;\n\n/**\n * The directory that relative `$ref`s of an inline source resolve against, as a URL that ends in\n * a slash. A path is resolved and encoded (`#`, `%`, spaces); a URL without the slash gets one.\n */\nfunction sourceCwd(options: GeneratorOptions): URL {\n const { cwd } = options;\n if (cwd instanceof URL) {\n return cwd.pathname.endsWith(\"/\") ? cwd : new URL(`${cwd.pathname}/`, cwd);\n }\n const directory = path.resolve(cwd === undefined ? process.cwd() : cwd.toString());\n return pathToFileURL(path.join(directory, path.sep));\n}\n\n/** The `$ref` limits of the options; a relative local root resolves against the cwd. */\nfunction refAccessOf(options: GeneratorOptions, cwd: URL): RefAccess {\n const { localRefRoot, remoteRefHosts } = options;\n const localRoot =\n typeof localRefRoot === \"string\"\n ? pathToFileURL(path.resolve(fileURLToPath(cwd), localRefRoot))\n : localRefRoot;\n return {\n ...(localRoot === undefined ? {} : { localRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteHosts: remoteRefHosts }),\n };\n}\n\nfunction callbackOptions(options: GeneratorOptions) {\n return {\n irCallbacks: options.irCallbacks === true,\n postTransform: typeof options.postTransform === \"function\" ? options.postTransform : undefined,\n transform: typeof options.transform === \"function\" ? options.transform : undefined,\n transformProperty:\n typeof options.transformProperty === \"function\" ? options.transformProperty : undefined,\n };\n}\n\nfunction contextFlags(options: GeneratorOptions): ContextFlags {\n return {\n additionalProperties: options.additionalProperties ?? false,\n alphabetize: options.alphabetize ?? false,\n arrayLength: options.arrayLength ?? false,\n binaryAsBlob: options.binaryAsBlob ?? false,\n defaultNonNullable: options.defaultNonNullable ?? true,\n emptyObjectsUnknown: options.emptyObjectsUnknown ?? false,\n enum: options.enum ?? false,\n enumValues: options.enumValues ?? false,\n conditionalEnums: options.conditionalEnums ?? false,\n dedupeEnums: options.dedupeEnums ?? false,\n excludeDeprecated: options.excludeDeprecated ?? false,\n exportType: options.exportType ?? false,\n immutable: options.immutable ?? false,\n rootTypes: options.rootTypes ?? false,\n rootTypesNoSchemaPrefix: options.rootTypesNoSchemaPrefix ?? false,\n rootTypesKeepCasing: options.rootTypesKeepCasing ?? false,\n pathParamsAsTypes: options.pathParamsAsTypes ?? false,\n propertiesRequiredByDefault: options.propertiesRequiredByDefault ?? false,\n silent: options.silent ?? false,\n ...(options.inject === undefined ? {} : { inject: options.inject }),\n makePathsEnum: options.makePathsEnum ?? false,\n generatePathParams: options.generatePathParams ?? false,\n readWriteMarkers: options.readWriteMarkers ?? false,\n ...callbackOptions(options),\n };\n}\n\n/**\n * The fixes of the options, `all` expanded; fails with `OPTION_FIX_UNKNOWN` for another name.\n * A fix named without the option it needs is reported, since it changes nothing.\n */\nfunction outputFixesOf(options: GeneratorOptions, logger: Logger): readonly OutputFix[] {\n const names = outputFixNamesOf(options.fix ?? []);\n for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {\n logger.warn(notice);\n }\n return [...resolveOutputFixes(names)];\n}\n\n/** The warnings about the loaded document itself, before it is transformed. */\nfunction warnAboutDocument(schema: OpenAPI3, fix: readonly OutputFix[], logger: Logger): void {\n withStackOverflowReported(\"transform\", () => warnUnsupportedFeatures(schema, logger));\n withStackOverflowReported(\"transform\", () =>\n warnDiscriminatorValueConflicts(schema, fix, logger),\n );\n warnIdenticalPathTemplates(schema, logger);\n}\n\n/**\n * Load the source through the ports, then build the run's context from the options. The fix names\n * are checked first, so a typo fails before the document is read.\n */\nexport async function createDocumentRun(\n source: SchemaSource,\n options: GeneratorOptions,\n ports: GeneratorPorts,\n): Promise<DocumentRun> {\n if (!source) {\n throw sourceEmptyError(\"Empty schema. Please specify a URL, file path, or Redocly Config\");\n }\n const { logger } = ports;\n const fix = outputFixesOf(options, logger);\n const silent = options.silent ?? false;\n const cwd = sourceCwd(options);\n const schema = await ports.loader.load({\n source,\n cwd,\n shouldLint: options.lint ?? true,\n refAccess: refAccessOf(options, cwd),\n });\n warnAboutDocument(schema, fix, logger);\n const ctx: GlobalContext = {\n ...contextFlags(options),\n fix,\n // The scan walks every schema before the transform does, so on a larger stack, where loading\n // passed, it is the first step to run out.\n discriminators: withStackOverflowReported(\"transform\", () =>\n findDiscriminators(schema, {\n silent,\n logger,\n fixes: new Set(fix),\n }),\n ),\n injectFooter: [],\n redoc: ports.redoc,\n resolve: ($ref) => resolveDocumentRef(schema, $ref, { silent, logger }),\n logger,\n };\n return { schema, ctx };\n}\n"],"names":["path","pathToFileURL","fileURLToPath","outputFixNamesOf","ineffectiveFixNotices","resolveOutputFixes","withStackOverflowReported","warnUnsupportedFeatures","warnDiscriminatorValueConflicts","warnIdenticalPathTemplates","sourceEmptyError","findDiscriminators","resolveDocumentRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-run.cjs","sources":["../../src/api/document-run.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport { sourceEmptyError } from \"../adapters/redocly-loader/schema-load-errors.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport type { RefAccess, SchemaLoader } from \"../application/ports/schema-loader.js\";\nimport { withStackOverflowReported } from \"../application/stack-overflow.js\";\nimport {\n ineffectiveFixNotices,\n type OutputFix,\n outputFixNamesOf,\n resolveOutputFixes,\n} from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport type { GeneratorOptions, OpenAPI3, SchemaSource } from \"../types.js\";\nimport { processCwd } from \"./default-ports.js\";\nimport { warnDiscriminatorValueConflicts } from \"./discriminator-conflict-warnings.js\";\nimport { findDiscriminators } from \"./discriminator-scan.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\nimport { warnIdenticalPathTemplates } from \"./path-template-warnings.js\";\nimport type { RunContext } from \"./run-context.js\";\nimport { warnUnsupportedFeatures } from \"./unsupported-feature-warnings.js\";\n\n/** The ports of one generator run, wired by the Node API or the CLI (ENGINEERING_PLAN 4.5). */\nexport interface GeneratorPorts {\n readonly loader: SchemaLoader;\n readonly logger: Logger;\n /** The Redocly config the loader uses; the run's context exposes it as `ctx.redoc`. */\n readonly redoc: RedoclyConfig;\n /** A monotonic time in milliseconds, for debug durations. */\n readonly now: () => number;\n}\n\n/** A validated, bundled document and the context of one generator run. */\nexport interface DocumentRun {\n readonly schema: OpenAPI3;\n readonly ctx: RunContext;\n}\n\n/** The context fields that are user flags, with the original defaults. */\ntype ContextFlags = Omit<\n RunContext,\n | \"discriminators\"\n | \"injectFooter\"\n | \"redoc\"\n | \"resolve\"\n | \"runFooter\"\n | \"legacyCallbackWarnings\"\n | \"logger\"\n | \"fix\"\n>;\n\n/**\n * The directory that relative `$ref`s of an inline source resolve against, as a URL that ends in\n * a slash. A path is resolved and encoded (`#`, `%`, spaces); a URL without the slash gets one.\n */\nfunction sourceCwd(options: GeneratorOptions): URL {\n const { cwd } = options;\n if (cwd instanceof URL) {\n return cwd.pathname.endsWith(\"/\") ? cwd : new URL(`${cwd.pathname}/`, cwd);\n }\n const directory = path.resolve(cwd === undefined ? processCwd() : cwd.toString());\n return pathToFileURL(path.join(directory, path.sep));\n}\n\n/** The `$ref` limits of the options; a relative local root resolves against the cwd. */\nfunction refAccessOf(options: GeneratorOptions, cwd: URL): RefAccess {\n const { localRefRoot, remoteRefHosts } = options;\n const localRoot =\n typeof localRefRoot === \"string\"\n ? pathToFileURL(path.resolve(fileURLToPath(cwd), localRefRoot))\n : localRefRoot;\n return {\n ...(localRoot === undefined ? {} : { localRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteHosts: remoteRefHosts }),\n };\n}\n\nfunction callbackOptions(options: GeneratorOptions) {\n return {\n irCallbacks: options.irCallbacks === true,\n postTransform: typeof options.postTransform === \"function\" ? options.postTransform : undefined,\n transform: typeof options.transform === \"function\" ? options.transform : undefined,\n transformProperty:\n typeof options.transformProperty === \"function\" ? options.transformProperty : undefined,\n };\n}\n\nfunction contextFlags(options: GeneratorOptions): ContextFlags {\n return {\n additionalProperties: options.additionalProperties ?? false,\n alphabetize: options.alphabetize ?? false,\n arrayLength: options.arrayLength ?? false,\n binaryAsBlob: options.binaryAsBlob ?? false,\n defaultNonNullable: options.defaultNonNullable ?? true,\n emptyObjectsUnknown: options.emptyObjectsUnknown ?? false,\n enum: options.enum ?? false,\n enumValues: options.enumValues ?? false,\n conditionalEnums: options.conditionalEnums ?? false,\n dedupeEnums: options.dedupeEnums ?? false,\n excludeDeprecated: options.excludeDeprecated ?? false,\n exportType: options.exportType ?? false,\n immutable: options.immutable ?? false,\n rootTypes: options.rootTypes ?? false,\n rootTypesNoSchemaPrefix: options.rootTypesNoSchemaPrefix ?? false,\n rootTypesKeepCasing: options.rootTypesKeepCasing ?? false,\n pathParamsAsTypes: options.pathParamsAsTypes ?? false,\n propertiesRequiredByDefault: options.propertiesRequiredByDefault ?? false,\n silent: options.silent ?? false,\n ...(options.inject === undefined ? {} : { inject: options.inject }),\n makePathsEnum: options.makePathsEnum ?? false,\n generatePathParams: options.generatePathParams ?? false,\n readWriteMarkers: options.readWriteMarkers ?? false,\n ...callbackOptions(options),\n };\n}\n\n/**\n * The fixes of the options, `all` expanded; fails with `OPTION_FIX_UNKNOWN` for another name.\n * A fix named without the option it needs is reported, since it changes nothing.\n */\nfunction outputFixesOf(options: GeneratorOptions, logger: Logger): readonly OutputFix[] {\n const names = outputFixNamesOf(options.fix ?? []);\n for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {\n logger.warn(warningText(notice, WARNING_CODES.FIX_NEEDS_OPTION));\n }\n return [...resolveOutputFixes(names)];\n}\n\n/** The warnings about the loaded document itself, before it is transformed. */\nfunction warnAboutDocument(schema: OpenAPI3, fix: readonly OutputFix[], logger: Logger): void {\n withStackOverflowReported(\"transform\", () => warnUnsupportedFeatures(schema, logger));\n withStackOverflowReported(\"transform\", () =>\n warnDiscriminatorValueConflicts(schema, fix, logger),\n );\n warnIdenticalPathTemplates(schema, logger);\n}\n\n/**\n * Load the source through the ports, then build the run's context from the options. The fix names\n * are checked first, so a typo fails before the document is read.\n */\nexport async function createDocumentRun(\n source: SchemaSource,\n options: GeneratorOptions,\n ports: GeneratorPorts,\n): Promise<DocumentRun> {\n if (!source) {\n throw sourceEmptyError(\"Empty schema. Please specify a URL, file path, or Redocly Config\");\n }\n const { logger } = ports;\n const fix = outputFixesOf(options, logger);\n const silent = options.silent ?? false;\n const cwd = sourceCwd(options);\n const schema = await ports.loader.load({\n source,\n cwd,\n shouldLint: options.lint ?? true,\n refAccess: refAccessOf(options, cwd),\n });\n warnAboutDocument(schema, fix, logger);\n const ctx: RunContext = {\n ...contextFlags(options),\n fix,\n // The scan walks every schema before the transform does, so on a larger stack, where loading\n // passed, it is the first step to run out.\n discriminators: withStackOverflowReported(\"transform\", () =>\n findDiscriminators(schema, {\n silent,\n logger,\n fixes: new Set(fix),\n }),\n ),\n injectFooter: [],\n redoc: ports.redoc,\n resolve: ($ref) => resolveDocumentRef(schema, $ref, { silent, logger }),\n logger,\n };\n return { schema, ctx };\n}\n"],"names":["path","processCwd","pathToFileURL","fileURLToPath","outputFixNamesOf","ineffectiveFixNotices","warningText","WARNING_CODES","resolveOutputFixes","withStackOverflowReported","warnUnsupportedFeatures","warnDiscriminatorValueConflicts","warnIdenticalPathTemplates","sourceEmptyError","findDiscriminators","resolveDocumentRef"],"mappings":"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"}
|
|
@@ -3,6 +3,8 @@ import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
|
3
3
|
import { sourceEmptyError } from '../adapters/redocly-loader/schema-load-errors.mjs';
|
|
4
4
|
import { withStackOverflowReported } from '../application/stack-overflow.mjs';
|
|
5
5
|
import { outputFixNamesOf, ineffectiveFixNotices, resolveOutputFixes } from '../domain/output-fixes.mjs';
|
|
6
|
+
import { warningText, WARNING_CODES } from '../domain/warnings.mjs';
|
|
7
|
+
import { processCwd } from './default-ports.mjs';
|
|
6
8
|
import { warnDiscriminatorValueConflicts } from './discriminator-conflict-warnings.mjs';
|
|
7
9
|
import { findDiscriminators } from './discriminator-scan.mjs';
|
|
8
10
|
import { resolveDocumentRef } from './document-refs.mjs';
|
|
@@ -14,7 +16,7 @@ function sourceCwd(options) {
|
|
|
14
16
|
if (cwd instanceof URL) {
|
|
15
17
|
return cwd.pathname.endsWith("/") ? cwd : new URL(`${cwd.pathname}/`, cwd);
|
|
16
18
|
}
|
|
17
|
-
const directory = path.resolve(cwd === void 0 ?
|
|
19
|
+
const directory = path.resolve(cwd === void 0 ? processCwd() : cwd.toString());
|
|
18
20
|
return pathToFileURL(path.join(directory, path.sep));
|
|
19
21
|
}
|
|
20
22
|
function refAccessOf(options, cwd) {
|
|
@@ -64,7 +66,7 @@ function contextFlags(options) {
|
|
|
64
66
|
function outputFixesOf(options, logger) {
|
|
65
67
|
const names = outputFixNamesOf(options.fix ?? []);
|
|
66
68
|
for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {
|
|
67
|
-
logger.warn(notice);
|
|
69
|
+
logger.warn(warningText(notice, WARNING_CODES.FIX_NEEDS_OPTION));
|
|
68
70
|
}
|
|
69
71
|
return [...resolveOutputFixes(names)];
|
|
70
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-run.mjs","sources":["../../src/api/document-run.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport { sourceEmptyError } from \"../adapters/redocly-loader/schema-load-errors.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport type { RefAccess, SchemaLoader } from \"../application/ports/schema-loader.js\";\nimport { withStackOverflowReported } from \"../application/stack-overflow.js\";\nimport {\n ineffectiveFixNotices,\n type OutputFix,\n outputFixNamesOf,\n resolveOutputFixes,\n} from \"../domain/output-fixes.js\";\nimport type { GeneratorOptions, GlobalContext, OpenAPI3, SchemaSource } from \"../types.js\";\nimport { warnDiscriminatorValueConflicts } from \"./discriminator-conflict-warnings.js\";\nimport { findDiscriminators } from \"./discriminator-scan.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\nimport { warnIdenticalPathTemplates } from \"./path-template-warnings.js\";\nimport { warnUnsupportedFeatures } from \"./unsupported-feature-warnings.js\";\n\n/** The ports of one generator run, wired by the Node API or the CLI (ENGINEERING_PLAN 4.5). */\nexport interface GeneratorPorts {\n readonly loader: SchemaLoader;\n readonly logger: Logger;\n /** The Redocly config the loader uses; the run's context exposes it as `ctx.redoc`. */\n readonly redoc: RedoclyConfig;\n /** A monotonic time in milliseconds, for debug durations. */\n readonly now: () => number;\n}\n\n/** A validated, bundled document and the context of one generator run. */\nexport interface DocumentRun {\n readonly schema: OpenAPI3;\n readonly ctx: GlobalContext;\n}\n\n/** The context fields that are user flags, with the original defaults. */\ntype ContextFlags = Omit<\n GlobalContext,\n | \"discriminators\"\n | \"injectFooter\"\n | \"redoc\"\n | \"resolve\"\n | \"runFooter\"\n | \"legacyCallbackWarnings\"\n | \"logger\"\n | \"fix\"\n>;\n\n/**\n * The directory that relative `$ref`s of an inline source resolve against, as a URL that ends in\n * a slash. A path is resolved and encoded (`#`, `%`, spaces); a URL without the slash gets one.\n */\nfunction sourceCwd(options: GeneratorOptions): URL {\n const { cwd } = options;\n if (cwd instanceof URL) {\n return cwd.pathname.endsWith(\"/\") ? cwd : new URL(`${cwd.pathname}/`, cwd);\n }\n const directory = path.resolve(cwd === undefined ? process.cwd() : cwd.toString());\n return pathToFileURL(path.join(directory, path.sep));\n}\n\n/** The `$ref` limits of the options; a relative local root resolves against the cwd. */\nfunction refAccessOf(options: GeneratorOptions, cwd: URL): RefAccess {\n const { localRefRoot, remoteRefHosts } = options;\n const localRoot =\n typeof localRefRoot === \"string\"\n ? pathToFileURL(path.resolve(fileURLToPath(cwd), localRefRoot))\n : localRefRoot;\n return {\n ...(localRoot === undefined ? {} : { localRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteHosts: remoteRefHosts }),\n };\n}\n\nfunction callbackOptions(options: GeneratorOptions) {\n return {\n irCallbacks: options.irCallbacks === true,\n postTransform: typeof options.postTransform === \"function\" ? options.postTransform : undefined,\n transform: typeof options.transform === \"function\" ? options.transform : undefined,\n transformProperty:\n typeof options.transformProperty === \"function\" ? options.transformProperty : undefined,\n };\n}\n\nfunction contextFlags(options: GeneratorOptions): ContextFlags {\n return {\n additionalProperties: options.additionalProperties ?? false,\n alphabetize: options.alphabetize ?? false,\n arrayLength: options.arrayLength ?? false,\n binaryAsBlob: options.binaryAsBlob ?? false,\n defaultNonNullable: options.defaultNonNullable ?? true,\n emptyObjectsUnknown: options.emptyObjectsUnknown ?? false,\n enum: options.enum ?? false,\n enumValues: options.enumValues ?? false,\n conditionalEnums: options.conditionalEnums ?? false,\n dedupeEnums: options.dedupeEnums ?? false,\n excludeDeprecated: options.excludeDeprecated ?? false,\n exportType: options.exportType ?? false,\n immutable: options.immutable ?? false,\n rootTypes: options.rootTypes ?? false,\n rootTypesNoSchemaPrefix: options.rootTypesNoSchemaPrefix ?? false,\n rootTypesKeepCasing: options.rootTypesKeepCasing ?? false,\n pathParamsAsTypes: options.pathParamsAsTypes ?? false,\n propertiesRequiredByDefault: options.propertiesRequiredByDefault ?? false,\n silent: options.silent ?? false,\n ...(options.inject === undefined ? {} : { inject: options.inject }),\n makePathsEnum: options.makePathsEnum ?? false,\n generatePathParams: options.generatePathParams ?? false,\n readWriteMarkers: options.readWriteMarkers ?? false,\n ...callbackOptions(options),\n };\n}\n\n/**\n * The fixes of the options, `all` expanded; fails with `OPTION_FIX_UNKNOWN` for another name.\n * A fix named without the option it needs is reported, since it changes nothing.\n */\nfunction outputFixesOf(options: GeneratorOptions, logger: Logger): readonly OutputFix[] {\n const names = outputFixNamesOf(options.fix ?? []);\n for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {\n logger.warn(notice);\n }\n return [...resolveOutputFixes(names)];\n}\n\n/** The warnings about the loaded document itself, before it is transformed. */\nfunction warnAboutDocument(schema: OpenAPI3, fix: readonly OutputFix[], logger: Logger): void {\n withStackOverflowReported(\"transform\", () => warnUnsupportedFeatures(schema, logger));\n withStackOverflowReported(\"transform\", () =>\n warnDiscriminatorValueConflicts(schema, fix, logger),\n );\n warnIdenticalPathTemplates(schema, logger);\n}\n\n/**\n * Load the source through the ports, then build the run's context from the options. The fix names\n * are checked first, so a typo fails before the document is read.\n */\nexport async function createDocumentRun(\n source: SchemaSource,\n options: GeneratorOptions,\n ports: GeneratorPorts,\n): Promise<DocumentRun> {\n if (!source) {\n throw sourceEmptyError(\"Empty schema. Please specify a URL, file path, or Redocly Config\");\n }\n const { logger } = ports;\n const fix = outputFixesOf(options, logger);\n const silent = options.silent ?? false;\n const cwd = sourceCwd(options);\n const schema = await ports.loader.load({\n source,\n cwd,\n shouldLint: options.lint ?? true,\n refAccess: refAccessOf(options, cwd),\n });\n warnAboutDocument(schema, fix, logger);\n const ctx: GlobalContext = {\n ...contextFlags(options),\n fix,\n // The scan walks every schema before the transform does, so on a larger stack, where loading\n // passed, it is the first step to run out.\n discriminators: withStackOverflowReported(\"transform\", () =>\n findDiscriminators(schema, {\n silent,\n logger,\n fixes: new Set(fix),\n }),\n ),\n injectFooter: [],\n redoc: ports.redoc,\n resolve: ($ref) => resolveDocumentRef(schema, $ref, { silent, logger }),\n logger,\n };\n return { schema, ctx };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document-run.mjs","sources":["../../src/api/document-run.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport { sourceEmptyError } from \"../adapters/redocly-loader/schema-load-errors.js\";\nimport type { Logger } from \"../application/ports/logger.js\";\nimport type { RefAccess, SchemaLoader } from \"../application/ports/schema-loader.js\";\nimport { withStackOverflowReported } from \"../application/stack-overflow.js\";\nimport {\n ineffectiveFixNotices,\n type OutputFix,\n outputFixNamesOf,\n resolveOutputFixes,\n} from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport type { GeneratorOptions, OpenAPI3, SchemaSource } from \"../types.js\";\nimport { processCwd } from \"./default-ports.js\";\nimport { warnDiscriminatorValueConflicts } from \"./discriminator-conflict-warnings.js\";\nimport { findDiscriminators } from \"./discriminator-scan.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\nimport { warnIdenticalPathTemplates } from \"./path-template-warnings.js\";\nimport type { RunContext } from \"./run-context.js\";\nimport { warnUnsupportedFeatures } from \"./unsupported-feature-warnings.js\";\n\n/** The ports of one generator run, wired by the Node API or the CLI (ENGINEERING_PLAN 4.5). */\nexport interface GeneratorPorts {\n readonly loader: SchemaLoader;\n readonly logger: Logger;\n /** The Redocly config the loader uses; the run's context exposes it as `ctx.redoc`. */\n readonly redoc: RedoclyConfig;\n /** A monotonic time in milliseconds, for debug durations. */\n readonly now: () => number;\n}\n\n/** A validated, bundled document and the context of one generator run. */\nexport interface DocumentRun {\n readonly schema: OpenAPI3;\n readonly ctx: RunContext;\n}\n\n/** The context fields that are user flags, with the original defaults. */\ntype ContextFlags = Omit<\n RunContext,\n | \"discriminators\"\n | \"injectFooter\"\n | \"redoc\"\n | \"resolve\"\n | \"runFooter\"\n | \"legacyCallbackWarnings\"\n | \"logger\"\n | \"fix\"\n>;\n\n/**\n * The directory that relative `$ref`s of an inline source resolve against, as a URL that ends in\n * a slash. A path is resolved and encoded (`#`, `%`, spaces); a URL without the slash gets one.\n */\nfunction sourceCwd(options: GeneratorOptions): URL {\n const { cwd } = options;\n if (cwd instanceof URL) {\n return cwd.pathname.endsWith(\"/\") ? cwd : new URL(`${cwd.pathname}/`, cwd);\n }\n const directory = path.resolve(cwd === undefined ? processCwd() : cwd.toString());\n return pathToFileURL(path.join(directory, path.sep));\n}\n\n/** The `$ref` limits of the options; a relative local root resolves against the cwd. */\nfunction refAccessOf(options: GeneratorOptions, cwd: URL): RefAccess {\n const { localRefRoot, remoteRefHosts } = options;\n const localRoot =\n typeof localRefRoot === \"string\"\n ? pathToFileURL(path.resolve(fileURLToPath(cwd), localRefRoot))\n : localRefRoot;\n return {\n ...(localRoot === undefined ? {} : { localRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteHosts: remoteRefHosts }),\n };\n}\n\nfunction callbackOptions(options: GeneratorOptions) {\n return {\n irCallbacks: options.irCallbacks === true,\n postTransform: typeof options.postTransform === \"function\" ? options.postTransform : undefined,\n transform: typeof options.transform === \"function\" ? options.transform : undefined,\n transformProperty:\n typeof options.transformProperty === \"function\" ? options.transformProperty : undefined,\n };\n}\n\nfunction contextFlags(options: GeneratorOptions): ContextFlags {\n return {\n additionalProperties: options.additionalProperties ?? false,\n alphabetize: options.alphabetize ?? false,\n arrayLength: options.arrayLength ?? false,\n binaryAsBlob: options.binaryAsBlob ?? false,\n defaultNonNullable: options.defaultNonNullable ?? true,\n emptyObjectsUnknown: options.emptyObjectsUnknown ?? false,\n enum: options.enum ?? false,\n enumValues: options.enumValues ?? false,\n conditionalEnums: options.conditionalEnums ?? false,\n dedupeEnums: options.dedupeEnums ?? false,\n excludeDeprecated: options.excludeDeprecated ?? false,\n exportType: options.exportType ?? false,\n immutable: options.immutable ?? false,\n rootTypes: options.rootTypes ?? false,\n rootTypesNoSchemaPrefix: options.rootTypesNoSchemaPrefix ?? false,\n rootTypesKeepCasing: options.rootTypesKeepCasing ?? false,\n pathParamsAsTypes: options.pathParamsAsTypes ?? false,\n propertiesRequiredByDefault: options.propertiesRequiredByDefault ?? false,\n silent: options.silent ?? false,\n ...(options.inject === undefined ? {} : { inject: options.inject }),\n makePathsEnum: options.makePathsEnum ?? false,\n generatePathParams: options.generatePathParams ?? false,\n readWriteMarkers: options.readWriteMarkers ?? false,\n ...callbackOptions(options),\n };\n}\n\n/**\n * The fixes of the options, `all` expanded; fails with `OPTION_FIX_UNKNOWN` for another name.\n * A fix named without the option it needs is reported, since it changes nothing.\n */\nfunction outputFixesOf(options: GeneratorOptions, logger: Logger): readonly OutputFix[] {\n const names = outputFixNamesOf(options.fix ?? []);\n for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {\n logger.warn(warningText(notice, WARNING_CODES.FIX_NEEDS_OPTION));\n }\n return [...resolveOutputFixes(names)];\n}\n\n/** The warnings about the loaded document itself, before it is transformed. */\nfunction warnAboutDocument(schema: OpenAPI3, fix: readonly OutputFix[], logger: Logger): void {\n withStackOverflowReported(\"transform\", () => warnUnsupportedFeatures(schema, logger));\n withStackOverflowReported(\"transform\", () =>\n warnDiscriminatorValueConflicts(schema, fix, logger),\n );\n warnIdenticalPathTemplates(schema, logger);\n}\n\n/**\n * Load the source through the ports, then build the run's context from the options. The fix names\n * are checked first, so a typo fails before the document is read.\n */\nexport async function createDocumentRun(\n source: SchemaSource,\n options: GeneratorOptions,\n ports: GeneratorPorts,\n): Promise<DocumentRun> {\n if (!source) {\n throw sourceEmptyError(\"Empty schema. Please specify a URL, file path, or Redocly Config\");\n }\n const { logger } = ports;\n const fix = outputFixesOf(options, logger);\n const silent = options.silent ?? false;\n const cwd = sourceCwd(options);\n const schema = await ports.loader.load({\n source,\n cwd,\n shouldLint: options.lint ?? true,\n refAccess: refAccessOf(options, cwd),\n });\n warnAboutDocument(schema, fix, logger);\n const ctx: RunContext = {\n ...contextFlags(options),\n fix,\n // The scan walks every schema before the transform does, so on a larger stack, where loading\n // passed, it is the first step to run out.\n discriminators: withStackOverflowReported(\"transform\", () =>\n findDiscriminators(schema, {\n silent,\n logger,\n fixes: new Set(fix),\n }),\n ),\n injectFooter: [],\n redoc: ports.redoc,\n resolve: ($ref) => resolveDocumentRef(schema, $ref, { silent, logger }),\n logger,\n };\n return { schema, ctx };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/api/footer-sink.cjs
CHANGED
|
@@ -7,6 +7,12 @@ const footerEntry = require('./footer-entry.cjs');
|
|
|
7
7
|
const OPERATIONS_NAME = "operations";
|
|
8
8
|
class ContextFooterSink {
|
|
9
9
|
footer;
|
|
10
|
+
/**
|
|
11
|
+
* The IR `operations` entry this sink wrote last, with its members array that only this sink
|
|
12
|
+
* holds. Adding to it in place keeps a run linear: copying the members on every operation was
|
|
13
|
+
* quadratic (about 0.4 s on Microsoft Graph beta).
|
|
14
|
+
*/
|
|
15
|
+
owned = null;
|
|
10
16
|
constructor(footer) {
|
|
11
17
|
this.footer = footer;
|
|
12
18
|
}
|
|
@@ -22,6 +28,11 @@ class ContextFooterSink {
|
|
|
22
28
|
* the member in place, as in the original.
|
|
23
29
|
*/
|
|
24
30
|
addOperation(build) {
|
|
31
|
+
const owned = this.currentOwnedOperations();
|
|
32
|
+
if (owned !== null) {
|
|
33
|
+
owned.members.push(build());
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
25
36
|
const existing = this.findOperations();
|
|
26
37
|
if (existing !== null && !footerEntry.isIrDeclaration(existing.entry)) {
|
|
27
38
|
const ts = loadTypescript.loadTypeScript();
|
|
@@ -32,9 +43,21 @@ class ContextFooterSink {
|
|
|
32
43
|
return;
|
|
33
44
|
}
|
|
34
45
|
const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;
|
|
35
|
-
|
|
46
|
+
this.takeOwnership(index).members.push(build());
|
|
47
|
+
}
|
|
48
|
+
/** The owned entry, unless user code replaced or moved it in the footer since. */
|
|
49
|
+
currentOwnedOperations() {
|
|
50
|
+
const owned = this.owned;
|
|
51
|
+
return owned !== null && this.footer[owned.index] === owned.entry ? owned : null;
|
|
52
|
+
}
|
|
53
|
+
/** Replace the IR entry at `index` with a copy whose members array only this sink holds. */
|
|
54
|
+
takeOwnership(index) {
|
|
36
55
|
const operations = this.footer[index];
|
|
37
|
-
|
|
56
|
+
const members = [...operations.members];
|
|
57
|
+
const entry = { ...operations, members };
|
|
58
|
+
this.footer[index] = entry;
|
|
59
|
+
this.owned = { entry, members, index };
|
|
60
|
+
return this.owned;
|
|
38
61
|
}
|
|
39
62
|
/** The first `operations` interface: the generator's (IR) or a user's (TypeScript). */
|
|
40
63
|
findOperations() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer-sink.cjs","sources":["../../src/api/footer-sink.ts"],"sourcesContent":["import { appendMember, asInterfaceNamed } from \"../adapters/type-ast-bridge/footer-nodes.js\";\nimport { loadTypeScript } from \"../adapters/type-ast-bridge/load-typescript.js\";\nimport type { FooterSink } from \"../application/transform/footer/document-footer.js\";\nimport type {\n IrDeclaration,\n IrInterfaceDeclaration,\n IrPropertySignature,\n} from \"../domain/ir/nodes.js\";\nimport { declaresTypeAlias, type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/**\n * The footer of a run is its `ctx.injectFooter` list. The generator adds IR declarations; user\n * code may add IR declarations or TypeScript nodes (ENGINEERING_PLAN 6.2).\n */\nexport class ContextFooterSink implements FooterSink {\n private readonly footer: FooterEntry[];\n\n constructor(footer: FooterEntry[]) {\n this.footer = footer;\n }\n\n hasTypeAlias(name: string): boolean {\n return this.footer.some((entry) => declaresTypeAlias(entry, name));\n }\n\n add(declaration: IrDeclaration): void {\n this.footer.push(declaration);\n }\n\n /**\n * Add a member to the `operations` interface, declared first (exported) when missing, so it\n * comes before any declaration `build` adds. A user's TypeScript `operations` interface gets\n * the member in place, as in the original.\n */\n addOperation(build: () => IrPropertySignature): void {\n const existing = this.findOperations();\n if (existing !== null && !isIrDeclaration(existing.entry)) {\n const ts = loadTypeScript();\n const node = asInterfaceNamed(ts, existing.entry, OPERATIONS_NAME);\n if (node) {\n appendMember(ts, node, build());\n }\n return;\n }\n const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;\n const
|
|
1
|
+
{"version":3,"file":"footer-sink.cjs","sources":["../../src/api/footer-sink.ts"],"sourcesContent":["import { appendMember, asInterfaceNamed } from \"../adapters/type-ast-bridge/footer-nodes.js\";\nimport { loadTypeScript } from \"../adapters/type-ast-bridge/load-typescript.js\";\nimport type { FooterSink } from \"../application/transform/footer/document-footer.js\";\nimport type {\n IrDeclaration,\n IrInterfaceDeclaration,\n IrMember,\n IrPropertySignature,\n} from \"../domain/ir/nodes.js\";\nimport { declaresTypeAlias, type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/**\n * The footer of a run is its `ctx.injectFooter` list. The generator adds IR declarations; user\n * code may add IR declarations or TypeScript nodes (ENGINEERING_PLAN 6.2).\n */\nexport class ContextFooterSink implements FooterSink {\n private readonly footer: FooterEntry[];\n /**\n * The IR `operations` entry this sink wrote last, with its members array that only this sink\n * holds. Adding to it in place keeps a run linear: copying the members on every operation was\n * quadratic (about 0.4 s on Microsoft Graph beta).\n */\n private owned: OwnedOperations | null = null;\n\n constructor(footer: FooterEntry[]) {\n this.footer = footer;\n }\n\n hasTypeAlias(name: string): boolean {\n return this.footer.some((entry) => declaresTypeAlias(entry, name));\n }\n\n add(declaration: IrDeclaration): void {\n this.footer.push(declaration);\n }\n\n /**\n * Add a member to the `operations` interface, declared first (exported) when missing, so it\n * comes before any declaration `build` adds. A user's TypeScript `operations` interface gets\n * the member in place, as in the original.\n */\n addOperation(build: () => IrPropertySignature): void {\n const owned = this.currentOwnedOperations();\n if (owned !== null) {\n owned.members.push(build());\n return;\n }\n const existing = this.findOperations();\n if (existing !== null && !isIrDeclaration(existing.entry)) {\n const ts = loadTypeScript();\n const node = asInterfaceNamed(ts, existing.entry, OPERATIONS_NAME);\n if (node) {\n appendMember(ts, node, build());\n }\n return;\n }\n const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;\n this.takeOwnership(index).members.push(build());\n }\n\n /** The owned entry, unless user code replaced or moved it in the footer since. */\n private currentOwnedOperations(): OwnedOperations | null {\n const owned = this.owned;\n return owned !== null && this.footer[owned.index] === owned.entry ? owned : null;\n }\n\n /** Replace the IR entry at `index` with a copy whose members array only this sink holds. */\n private takeOwnership(index: number): OwnedOperations {\n const operations = this.footer[index] as IrInterfaceDeclaration;\n const members: IrMember[] = [...operations.members];\n const entry: IrInterfaceDeclaration = { ...operations, members };\n this.footer[index] = entry;\n this.owned = { entry, members, index };\n return this.owned;\n }\n\n /** The first `operations` interface: the generator's (IR) or a user's (TypeScript). */\n private findOperations(): { entry: FooterEntry; index: number } | null {\n const index = this.footer.findIndex((entry) =>\n isIrDeclaration(entry)\n ? entry.kind === \"interface\" && entry.name === OPERATIONS_NAME\n : asInterfaceNamed(loadTypeScript(), entry, OPERATIONS_NAME) !== null,\n );\n const entry = this.footer[index];\n return entry === undefined ? null : { entry, index };\n }\n}\n\ninterface OwnedOperations {\n readonly entry: IrInterfaceDeclaration;\n readonly members: IrMember[];\n readonly index: number;\n}\n\nfunction emptyOperations(): IrInterfaceDeclaration {\n return { kind: \"interface\", name: OPERATIONS_NAME, isExported: true, members: [], comments: [] };\n}\n"],"names":["declaresTypeAlias","isIrDeclaration","loadTypeScript","asInterfaceNamed","appendMember","entry"],"mappings":"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"}
|
package/dist/api/footer-sink.mjs
CHANGED
|
@@ -5,6 +5,12 @@ import { declaresTypeAlias, isIrDeclaration } from './footer-entry.mjs';
|
|
|
5
5
|
const OPERATIONS_NAME = "operations";
|
|
6
6
|
class ContextFooterSink {
|
|
7
7
|
footer;
|
|
8
|
+
/**
|
|
9
|
+
* The IR `operations` entry this sink wrote last, with its members array that only this sink
|
|
10
|
+
* holds. Adding to it in place keeps a run linear: copying the members on every operation was
|
|
11
|
+
* quadratic (about 0.4 s on Microsoft Graph beta).
|
|
12
|
+
*/
|
|
13
|
+
owned = null;
|
|
8
14
|
constructor(footer) {
|
|
9
15
|
this.footer = footer;
|
|
10
16
|
}
|
|
@@ -20,6 +26,11 @@ class ContextFooterSink {
|
|
|
20
26
|
* the member in place, as in the original.
|
|
21
27
|
*/
|
|
22
28
|
addOperation(build) {
|
|
29
|
+
const owned = this.currentOwnedOperations();
|
|
30
|
+
if (owned !== null) {
|
|
31
|
+
owned.members.push(build());
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
23
34
|
const existing = this.findOperations();
|
|
24
35
|
if (existing !== null && !isIrDeclaration(existing.entry)) {
|
|
25
36
|
const ts = loadTypeScript();
|
|
@@ -30,9 +41,21 @@ class ContextFooterSink {
|
|
|
30
41
|
return;
|
|
31
42
|
}
|
|
32
43
|
const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;
|
|
33
|
-
|
|
44
|
+
this.takeOwnership(index).members.push(build());
|
|
45
|
+
}
|
|
46
|
+
/** The owned entry, unless user code replaced or moved it in the footer since. */
|
|
47
|
+
currentOwnedOperations() {
|
|
48
|
+
const owned = this.owned;
|
|
49
|
+
return owned !== null && this.footer[owned.index] === owned.entry ? owned : null;
|
|
50
|
+
}
|
|
51
|
+
/** Replace the IR entry at `index` with a copy whose members array only this sink holds. */
|
|
52
|
+
takeOwnership(index) {
|
|
34
53
|
const operations = this.footer[index];
|
|
35
|
-
|
|
54
|
+
const members = [...operations.members];
|
|
55
|
+
const entry = { ...operations, members };
|
|
56
|
+
this.footer[index] = entry;
|
|
57
|
+
this.owned = { entry, members, index };
|
|
58
|
+
return this.owned;
|
|
36
59
|
}
|
|
37
60
|
/** The first `operations` interface: the generator's (IR) or a user's (TypeScript). */
|
|
38
61
|
findOperations() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer-sink.mjs","sources":["../../src/api/footer-sink.ts"],"sourcesContent":["import { appendMember, asInterfaceNamed } from \"../adapters/type-ast-bridge/footer-nodes.js\";\nimport { loadTypeScript } from \"../adapters/type-ast-bridge/load-typescript.js\";\nimport type { FooterSink } from \"../application/transform/footer/document-footer.js\";\nimport type {\n IrDeclaration,\n IrInterfaceDeclaration,\n IrPropertySignature,\n} from \"../domain/ir/nodes.js\";\nimport { declaresTypeAlias, type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/**\n * The footer of a run is its `ctx.injectFooter` list. The generator adds IR declarations; user\n * code may add IR declarations or TypeScript nodes (ENGINEERING_PLAN 6.2).\n */\nexport class ContextFooterSink implements FooterSink {\n private readonly footer: FooterEntry[];\n\n constructor(footer: FooterEntry[]) {\n this.footer = footer;\n }\n\n hasTypeAlias(name: string): boolean {\n return this.footer.some((entry) => declaresTypeAlias(entry, name));\n }\n\n add(declaration: IrDeclaration): void {\n this.footer.push(declaration);\n }\n\n /**\n * Add a member to the `operations` interface, declared first (exported) when missing, so it\n * comes before any declaration `build` adds. A user's TypeScript `operations` interface gets\n * the member in place, as in the original.\n */\n addOperation(build: () => IrPropertySignature): void {\n const existing = this.findOperations();\n if (existing !== null && !isIrDeclaration(existing.entry)) {\n const ts = loadTypeScript();\n const node = asInterfaceNamed(ts, existing.entry, OPERATIONS_NAME);\n if (node) {\n appendMember(ts, node, build());\n }\n return;\n }\n const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;\n const
|
|
1
|
+
{"version":3,"file":"footer-sink.mjs","sources":["../../src/api/footer-sink.ts"],"sourcesContent":["import { appendMember, asInterfaceNamed } from \"../adapters/type-ast-bridge/footer-nodes.js\";\nimport { loadTypeScript } from \"../adapters/type-ast-bridge/load-typescript.js\";\nimport type { FooterSink } from \"../application/transform/footer/document-footer.js\";\nimport type {\n IrDeclaration,\n IrInterfaceDeclaration,\n IrMember,\n IrPropertySignature,\n} from \"../domain/ir/nodes.js\";\nimport { declaresTypeAlias, type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/**\n * The footer of a run is its `ctx.injectFooter` list. The generator adds IR declarations; user\n * code may add IR declarations or TypeScript nodes (ENGINEERING_PLAN 6.2).\n */\nexport class ContextFooterSink implements FooterSink {\n private readonly footer: FooterEntry[];\n /**\n * The IR `operations` entry this sink wrote last, with its members array that only this sink\n * holds. Adding to it in place keeps a run linear: copying the members on every operation was\n * quadratic (about 0.4 s on Microsoft Graph beta).\n */\n private owned: OwnedOperations | null = null;\n\n constructor(footer: FooterEntry[]) {\n this.footer = footer;\n }\n\n hasTypeAlias(name: string): boolean {\n return this.footer.some((entry) => declaresTypeAlias(entry, name));\n }\n\n add(declaration: IrDeclaration): void {\n this.footer.push(declaration);\n }\n\n /**\n * Add a member to the `operations` interface, declared first (exported) when missing, so it\n * comes before any declaration `build` adds. A user's TypeScript `operations` interface gets\n * the member in place, as in the original.\n */\n addOperation(build: () => IrPropertySignature): void {\n const owned = this.currentOwnedOperations();\n if (owned !== null) {\n owned.members.push(build());\n return;\n }\n const existing = this.findOperations();\n if (existing !== null && !isIrDeclaration(existing.entry)) {\n const ts = loadTypeScript();\n const node = asInterfaceNamed(ts, existing.entry, OPERATIONS_NAME);\n if (node) {\n appendMember(ts, node, build());\n }\n return;\n }\n const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;\n this.takeOwnership(index).members.push(build());\n }\n\n /** The owned entry, unless user code replaced or moved it in the footer since. */\n private currentOwnedOperations(): OwnedOperations | null {\n const owned = this.owned;\n return owned !== null && this.footer[owned.index] === owned.entry ? owned : null;\n }\n\n /** Replace the IR entry at `index` with a copy whose members array only this sink holds. */\n private takeOwnership(index: number): OwnedOperations {\n const operations = this.footer[index] as IrInterfaceDeclaration;\n const members: IrMember[] = [...operations.members];\n const entry: IrInterfaceDeclaration = { ...operations, members };\n this.footer[index] = entry;\n this.owned = { entry, members, index };\n return this.owned;\n }\n\n /** The first `operations` interface: the generator's (IR) or a user's (TypeScript). */\n private findOperations(): { entry: FooterEntry; index: number } | null {\n const index = this.footer.findIndex((entry) =>\n isIrDeclaration(entry)\n ? entry.kind === \"interface\" && entry.name === OPERATIONS_NAME\n : asInterfaceNamed(loadTypeScript(), entry, OPERATIONS_NAME) !== null,\n );\n const entry = this.footer[index];\n return entry === undefined ? null : { entry, index };\n }\n}\n\ninterface OwnedOperations {\n readonly entry: IrInterfaceDeclaration;\n readonly members: IrMember[];\n readonly index: number;\n}\n\nfunction emptyOperations(): IrInterfaceDeclaration {\n return { kind: \"interface\", name: OPERATIONS_NAME, isExported: true, members: [], comments: [] };\n}\n"],"names":["entry"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const warnings = require('../domain/warnings.cjs');
|
|
3
4
|
const defaultPorts = require('./default-ports.cjs');
|
|
4
5
|
|
|
5
6
|
const IR_CALLBACKS_GUIDE_URL = "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/node.md#ir-callbacks";
|
|
@@ -17,7 +18,9 @@ function warnLegacyCallback(ctx, name) {
|
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
20
|
ctx.legacyCallbackWarnings.add(name);
|
|
20
|
-
(ctx.logger ?? defaultPorts.defaultLogger(ctx.silent)).warn(
|
|
21
|
+
(ctx.logger ?? defaultPorts.defaultLogger(ctx.silent)).warn(
|
|
22
|
+
warnings.warningText(message(name), warnings.WARNING_CODES.LEGACY_CALLBACK_DEPRECATED)
|
|
23
|
+
);
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
exports.IR_CALLBACKS_GUIDE_URL = IR_CALLBACKS_GUIDE_URL;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-callback-warning.cjs","sources":["../../src/api/legacy-callback-warning.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"legacy-callback-warning.cjs","sources":["../../src/api/legacy-callback-warning.ts"],"sourcesContent":["import { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport type { LegacyCallbackName } from \"../types.js\";\nimport { defaultLogger } from \"./default-ports.js\";\nimport type { RunContext } from \"./run-context.js\";\n\n/** Where the IR callbacks are documented; the warning points users there. */\nexport const IR_CALLBACKS_GUIDE_URL =\n \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/node.md#ir-callbacks\";\n\nconst USES: Readonly<Record<LegacyCallbackName, string>> = {\n transform: \"`transform` returned a TypeScript node\",\n postTransform: \"`postTransform` receives TypeScript nodes\",\n transformProperty: \"`transformProperty` receives TypeScript nodes\",\n};\n\nfunction message(name: LegacyCallbackName): string {\n return (\n `${USES[name]}. This form works in 1.x through the TypeScript bridge and is removed in 2.0. ` +\n `Use irCallbacks: true and return IR or type text instead: ${IR_CALLBACKS_GUIDE_URL}`\n );\n}\n\n/** Warn once per run and callback; `silent` runs record the use but print nothing. */\nexport function warnLegacyCallback(ctx: RunContext, name: LegacyCallbackName): void {\n ctx.legacyCallbackWarnings ??= new Set();\n if (ctx.legacyCallbackWarnings.has(name)) {\n return;\n }\n ctx.legacyCallbackWarnings.add(name);\n (ctx.logger ?? defaultLogger(ctx.silent)).warn(\n warningText(message(name), WARNING_CODES.LEGACY_CALLBACK_DEPRECATED),\n );\n}\n"],"names":["defaultLogger","warningText","WARNING_CODES"],"mappings":";;;;;AAMO,MAAM,sBAAA,GACX;AAEF,MAAM,IAAA,GAAqD;AAAA,EACzD,SAAA,EAAW,wCAAA;AAAA,EACX,aAAA,EAAe,2CAAA;AAAA,EACf,iBAAA,EAAmB;AACrB,CAAA;AAEA,SAAS,QAAQ,IAAA,EAAkC;AACjD,EAAA,OACE,CAAA,EAAG,IAAA,CAAK,IAAI,CAAC,2IACgD,sBAAsB,CAAA,CAAA;AAEvF;AAGO,SAAS,kBAAA,CAAmB,KAAiB,IAAA,EAAgC;AAClF,EAAA,GAAA,CAAI,sBAAA,yBAA+B,GAAA,EAAI;AACvC,EAAA,IAAI,GAAA,CAAI,sBAAA,CAAuB,GAAA,CAAI,IAAI,CAAA,EAAG;AACxC,IAAA;AAAA,EACF;AACA,EAAA,GAAA,CAAI,sBAAA,CAAuB,IAAI,IAAI,CAAA;AACnC,EAAA,CAAC,GAAA,CAAI,MAAA,IAAUA,0BAAA,CAAc,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA;AAAA,IACxCC,oBAAA,CAAY,OAAA,CAAQ,IAAI,CAAA,EAAGC,uBAAc,0BAA0B;AAAA,GACrE;AACF;;;"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { warningText, WARNING_CODES } from '../domain/warnings.mjs';
|
|
1
2
|
import { defaultLogger } from './default-ports.mjs';
|
|
2
3
|
|
|
3
4
|
const IR_CALLBACKS_GUIDE_URL = "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/node.md#ir-callbacks";
|
|
@@ -15,7 +16,9 @@ function warnLegacyCallback(ctx, name) {
|
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
17
18
|
ctx.legacyCallbackWarnings.add(name);
|
|
18
|
-
(ctx.logger ?? defaultLogger(ctx.silent)).warn(
|
|
19
|
+
(ctx.logger ?? defaultLogger(ctx.silent)).warn(
|
|
20
|
+
warningText(message(name), WARNING_CODES.LEGACY_CALLBACK_DEPRECATED)
|
|
21
|
+
);
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
export { IR_CALLBACKS_GUIDE_URL, warnLegacyCallback };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-callback-warning.mjs","sources":["../../src/api/legacy-callback-warning.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"legacy-callback-warning.mjs","sources":["../../src/api/legacy-callback-warning.ts"],"sourcesContent":["import { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport type { LegacyCallbackName } from \"../types.js\";\nimport { defaultLogger } from \"./default-ports.js\";\nimport type { RunContext } from \"./run-context.js\";\n\n/** Where the IR callbacks are documented; the warning points users there. */\nexport const IR_CALLBACKS_GUIDE_URL =\n \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/node.md#ir-callbacks\";\n\nconst USES: Readonly<Record<LegacyCallbackName, string>> = {\n transform: \"`transform` returned a TypeScript node\",\n postTransform: \"`postTransform` receives TypeScript nodes\",\n transformProperty: \"`transformProperty` receives TypeScript nodes\",\n};\n\nfunction message(name: LegacyCallbackName): string {\n return (\n `${USES[name]}. This form works in 1.x through the TypeScript bridge and is removed in 2.0. ` +\n `Use irCallbacks: true and return IR or type text instead: ${IR_CALLBACKS_GUIDE_URL}`\n );\n}\n\n/** Warn once per run and callback; `silent` runs record the use but print nothing. */\nexport function warnLegacyCallback(ctx: RunContext, name: LegacyCallbackName): void {\n ctx.legacyCallbackWarnings ??= new Set();\n if (ctx.legacyCallbackWarnings.has(name)) {\n return;\n }\n ctx.legacyCallbackWarnings.add(name);\n (ctx.logger ?? defaultLogger(ctx.silent)).warn(\n warningText(message(name), WARNING_CODES.LEGACY_CALLBACK_DEPRECATED),\n );\n}\n"],"names":[],"mappings":";;;AAMO,MAAM,sBAAA,GACX;AAEF,MAAM,IAAA,GAAqD;AAAA,EACzD,SAAA,EAAW,wCAAA;AAAA,EACX,aAAA,EAAe,2CAAA;AAAA,EACf,iBAAA,EAAmB;AACrB,CAAA;AAEA,SAAS,QAAQ,IAAA,EAAkC;AACjD,EAAA,OACE,CAAA,EAAG,IAAA,CAAK,IAAI,CAAC,2IACgD,sBAAsB,CAAA,CAAA;AAEvF;AAGO,SAAS,kBAAA,CAAmB,KAAiB,IAAA,EAAgC;AAClF,EAAA,GAAA,CAAI,sBAAA,yBAA+B,GAAA,EAAI;AACvC,EAAA,IAAI,GAAA,CAAI,sBAAA,CAAuB,GAAA,CAAI,IAAI,CAAA,EAAG;AACxC,IAAA;AAAA,EACF;AACA,EAAA,GAAA,CAAI,sBAAA,CAAuB,IAAI,IAAI,CAAA;AACnC,EAAA,CAAC,GAAA,CAAI,MAAA,IAAU,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA;AAAA,IACxC,WAAA,CAAY,OAAA,CAAQ,IAAI,CAAA,EAAG,cAAc,0BAA0B;AAAA,GACrE;AACF;;"}
|