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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/adapters/redocly-loader/query-document-names.cjs +50 -0
  3. package/dist/adapters/redocly-loader/query-document-names.cjs.map +1 -0
  4. package/dist/adapters/redocly-loader/query-document-names.mjs +48 -0
  5. package/dist/adapters/redocly-loader/query-document-names.mjs.map +1 -0
  6. package/dist/adapters/redocly-loader/query-named-components.cjs +29 -37
  7. package/dist/adapters/redocly-loader/query-named-components.cjs.map +1 -1
  8. package/dist/adapters/redocly-loader/query-named-components.mjs +29 -37
  9. package/dist/adapters/redocly-loader/query-named-components.mjs.map +1 -1
  10. package/dist/adapters/redocly-loader/redocly-config-source.cjs +3 -0
  11. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
  12. package/dist/adapters/redocly-loader/redocly-config-source.mjs +4 -1
  13. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +16 -7
  15. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  16. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +17 -8
  17. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  18. package/dist/adapters/redocly-loader/ref-access.cjs +9 -1
  19. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  20. package/dist/adapters/redocly-loader/ref-access.mjs +10 -2
  21. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  22. package/dist/adapters/redocly-loader/remote-fetch.cjs +16 -1
  23. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  24. package/dist/adapters/redocly-loader/remote-fetch.mjs +16 -2
  25. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  26. package/dist/api/cwd-option.cjs +58 -0
  27. package/dist/api/cwd-option.cjs.map +1 -0
  28. package/dist/api/cwd-option.mjs +52 -0
  29. package/dist/api/cwd-option.mjs.map +1 -0
  30. package/dist/api/default-ports.cjs +15 -7
  31. package/dist/api/default-ports.cjs.map +1 -1
  32. package/dist/api/default-ports.mjs +14 -8
  33. package/dist/api/default-ports.mjs.map +1 -1
  34. package/dist/api/document-run.cjs +2 -16
  35. package/dist/api/document-run.cjs.map +1 -1
  36. package/dist/api/document-run.mjs +2 -12
  37. package/dist/api/document-run.mjs.map +1 -1
  38. package/dist/api/legacy-utils.cjs +1 -1
  39. package/dist/api/legacy-utils.cjs.map +1 -1
  40. package/dist/api/legacy-utils.mjs +1 -1
  41. package/dist/api/legacy-utils.mjs.map +1 -1
  42. package/dist/api/openapi-ts.cjs.map +1 -1
  43. package/dist/api/openapi-ts.mjs.map +1 -1
  44. package/dist/api/option-errors.cjs +24 -0
  45. package/dist/api/option-errors.cjs.map +1 -0
  46. package/dist/api/option-errors.mjs +21 -0
  47. package/dist/api/option-errors.mjs.map +1 -0
  48. package/dist/api/ref-limit-options.cjs +19 -24
  49. package/dist/api/ref-limit-options.cjs.map +1 -1
  50. package/dist/api/ref-limit-options.mjs +15 -20
  51. package/dist/api/ref-limit-options.mjs.map +1 -1
  52. package/dist/application/transform/document/path-template-refs.cjs +12 -2
  53. package/dist/application/transform/document/path-template-refs.cjs.map +1 -1
  54. package/dist/application/transform/document/path-template-refs.mjs +12 -2
  55. package/dist/application/transform/document/path-template-refs.mjs.map +1 -1
  56. package/dist/application/transform/ref-pointer/generated-shape.cjs +28 -10
  57. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -1
  58. package/dist/application/transform/ref-pointer/generated-shape.mjs +29 -11
  59. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -1
  60. package/dist/application/transform/ref-pointer/original-index.cjs +1 -1
  61. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -1
  62. package/dist/application/transform/ref-pointer/original-index.mjs +1 -1
  63. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -1
  64. package/dist/application/transform/ref-pointer/property-shape.cjs +5 -0
  65. package/dist/application/transform/ref-pointer/property-shape.cjs.map +1 -1
  66. package/dist/application/transform/ref-pointer/property-shape.mjs +5 -1
  67. package/dist/application/transform/ref-pointer/property-shape.mjs.map +1 -1
  68. package/dist/application/transform/ref-pointer/typed-walk.cjs +11 -1
  69. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -1
  70. package/dist/application/transform/ref-pointer/typed-walk.mjs +12 -2
  71. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -1
  72. package/dist/cli/api-settings.cjs +3 -2
  73. package/dist/cli/api-settings.cjs.map +1 -1
  74. package/dist/cli/api-settings.mjs +2 -1
  75. package/dist/cli/api-settings.mjs.map +1 -1
  76. package/dist/cli/api-writes.cjs +7 -1
  77. package/dist/cli/api-writes.cjs.map +1 -1
  78. package/dist/cli/api-writes.mjs +7 -1
  79. package/dist/cli/api-writes.mjs.map +1 -1
  80. package/dist/cli/cli-arguments.cjs +25 -107
  81. package/dist/cli/cli-arguments.cjs.map +1 -1
  82. package/dist/cli/cli-arguments.mjs +18 -100
  83. package/dist/cli/cli-arguments.mjs.map +1 -1
  84. package/dist/cli/cli-errors.cjs +1 -0
  85. package/dist/cli/cli-errors.cjs.map +1 -1
  86. package/dist/cli/cli-errors.mjs +1 -0
  87. package/dist/cli/cli-errors.mjs.map +1 -1
  88. package/dist/cli/cli-flag-names.cjs +77 -0
  89. package/dist/cli/cli-flag-names.cjs.map +1 -0
  90. package/dist/cli/cli-flag-names.mjs +64 -0
  91. package/dist/cli/cli-flag-names.mjs.map +1 -0
  92. package/dist/cli/cli-output.cjs +7 -2
  93. package/dist/cli/cli-output.cjs.map +1 -1
  94. package/dist/cli/cli-output.mjs +7 -2
  95. package/dist/cli/cli-output.mjs.map +1 -1
  96. package/dist/cli/main.cjs +1 -1
  97. package/dist/cli/main.cjs.map +1 -1
  98. package/dist/cli/main.mjs +1 -1
  99. package/dist/cli/main.mjs.map +1 -1
  100. package/dist/cli/redocly-apis.cjs +14 -4
  101. package/dist/cli/redocly-apis.cjs.map +1 -1
  102. package/dist/cli/redocly-apis.mjs +14 -4
  103. package/dist/cli/redocly-apis.mjs.map +1 -1
  104. package/dist/cli/written-flags.cjs +83 -0
  105. package/dist/cli/written-flags.cjs.map +1 -0
  106. package/dist/cli/written-flags.mjs +77 -0
  107. package/dist/cli/written-flags.mjs.map +1 -0
  108. package/dist/domain/errors.cjs +1 -0
  109. package/dist/domain/errors.cjs.map +1 -1
  110. package/dist/domain/errors.mjs +1 -0
  111. package/dist/domain/errors.mjs.map +1 -1
  112. package/dist/domain/location-text.cjs +7 -1
  113. package/dist/domain/location-text.cjs.map +1 -1
  114. package/dist/domain/location-text.mjs +7 -1
  115. package/dist/domain/location-text.mjs.map +1 -1
  116. package/dist/index.d.cts +3 -0
  117. package/dist/index.d.mts +3 -0
  118. package/dist/index.d.ts +3 -0
  119. package/package.json +1 -1
  120. package/src/adapters/redocly-loader/query-document-names.ts +79 -0
  121. package/src/adapters/redocly-loader/query-named-components.ts +48 -49
  122. package/src/adapters/redocly-loader/redocly-config-source.ts +11 -1
  123. package/src/adapters/redocly-loader/redocly-schema-loader.ts +20 -6
  124. package/src/adapters/redocly-loader/ref-access.ts +16 -2
  125. package/src/adapters/redocly-loader/remote-fetch.ts +26 -0
  126. package/src/api/cwd-option.ts +76 -0
  127. package/src/api/default-ports.ts +33 -10
  128. package/src/api/document-run.ts +2 -17
  129. package/src/api/legacy-utils.ts +1 -1
  130. package/src/api/openapi-ts.ts +14 -1
  131. package/src/api/option-errors.ts +22 -0
  132. package/src/api/ref-limit-options.ts +17 -24
  133. package/src/application/ports/redocly-config-source.ts +5 -0
  134. package/src/application/transform/document/path-template-refs.ts +28 -7
  135. package/src/application/transform/ref-pointer/generated-shape.ts +57 -14
  136. package/src/application/transform/ref-pointer/original-index.ts +6 -3
  137. package/src/application/transform/ref-pointer/property-shape.ts +9 -0
  138. package/src/application/transform/ref-pointer/typed-walk.ts +26 -4
  139. package/src/cli/api-writes.ts +11 -3
  140. package/src/cli/cli-arguments.ts +42 -153
  141. package/src/cli/cli-errors.ts +1 -0
  142. package/src/cli/cli-flag-names.ts +99 -0
  143. package/src/cli/cli-output.ts +20 -6
  144. package/src/cli/main.ts +2 -1
  145. package/src/cli/redocly-apis.ts +21 -5
  146. package/src/cli/written-flags.ts +131 -0
  147. package/src/domain/errors.ts +1 -0
  148. package/src/domain/location-text.ts +17 -2
@@ -1 +1 @@
1
- {"version":3,"file":"redocly-apis.cjs","sources":["../../src/cli/redocly-apis.ts"],"sourcesContent":["import type { RedoclyConfig } from \"../application/ports/redocly-config-source.js\";\nimport type { GeneratorOptions } from \"../types.js\";\nimport {\n type ApiSettings,\n apiFixNames,\n apiFlags,\n apiOutputOf,\n apiRefLimitOptions,\n OUTPUT_SETTING,\n unknownSettingWarnings,\n} from \"./api-settings.js\";\nimport { type GeneratedApi, writeGeneratedApis } from \"./api-writes.js\";\nimport { ineffectiveFlagNotices } from \"./cli-arguments.js\";\nimport { ApiFailure, cliError } from \"./cli-errors.js\";\nimport {\n type CliRun,\n ensureOutputIsNotSchema,\n ensureOutputIsOwn,\n filesReadBy,\n type NamedFile,\n outputFileOf,\n parseLocationUrl,\n redoclyConfigFiles,\n resolveLocationUrl,\n} from \"./cli-output.js\";\nimport { MULTIPLE_SCHEMAS_DOCS_URL } from \"./docs-links.js\";\nimport { fixOption } from \"./fix-option.js\";\nimport { type RefLimitOptions, refLimitOptions } from \"./ref-limits.js\";\n\n/** The `apis` of a Redocly config: each API is generated into its `x-openapi-ts.output`. */\n\n/** The key of an API's openapi-typesafe settings in `redocly.yaml`. */\nconst REDOCLY_CONFIG_KEY = \"x-openapi-ts\";\n\n/** An API of the config as written: `root` and the settings are not checked yet. */\ninterface RedoclyApi {\n readonly name: string;\n readonly root: unknown;\n readonly settings: unknown;\n}\n\nfunction redoclyApisOf(redocly: RedoclyConfig): RedoclyApi[] {\n return Object.entries(redocly.apis ?? {}).map(([name, api]) => {\n const fields = api as Readonly<Record<string, unknown>>;\n return { name, root: fields.root, settings: fields[REDOCLY_CONFIG_KEY] };\n });\n}\n\nexport function hasRedoclyApis(redocly: RedoclyConfig): boolean {\n return Object.keys(redocly.apis ?? {}).length > 0;\n}\n\n/** Paths in the config are relative to the config file; without a file, to the working dir. */\nfunction configRootOf(redocly: RedoclyConfig, cwd: URL): URL {\n return redocly.configFile ? resolveLocationUrl(redocly.configFile, cwd) : cwd;\n}\n\n/** An API whose root and settings are usable, and the directory its paths are relative to. */\ninterface ApiTarget {\n readonly name: string;\n readonly root: string;\n readonly settings: ApiSettings;\n readonly configRoot: URL;\n}\n\nfunction isSettingsMap(value: unknown): value is ApiSettings {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The API with its settings. Fails with `CLI_CONFIG_OUTPUT_MISSING` when they name no output, and\n * with `CLI_CONFIG_INVALID` when they are no map or `root` is no path or URL; only this API then\n * fails, the others are still generated.\n */\nfunction apiTarget(api: RedoclyApi, configRoot: URL): ApiTarget {\n const { name, root, settings } = api;\n if (settings !== undefined && !isSettingsMap(settings)) {\n throw cliError(\"CLI_CONFIG_INVALID\", `API ${name}: \\`${REDOCLY_CONFIG_KEY}\\` must be a map`);\n }\n if (!settings?.[OUTPUT_SETTING]) {\n throw cliError(\n \"CLI_CONFIG_OUTPUT_MISSING\",\n `API ${name} is missing an \\`${REDOCLY_CONFIG_KEY}.output\\` key. ` +\n `See ${MULTIPLE_SCHEMAS_DOCS_URL}`,\n );\n }\n if (typeof root !== \"string\" || root === \"\") {\n throw cliError(\n \"CLI_CONFIG_INVALID\",\n `API ${name}: \\`root\\` in redocly.yaml must be the path or URL of its schema`,\n );\n }\n return { name, root, settings, configRoot };\n}\n\n/**\n * What every API of a run shares: the config, the files of all APIs, and the reference limits of\n * the command line, which are checked once before any API, so an invalid flag fails the run once.\n */\ninterface ApiRun {\n readonly redocly: RedoclyConfig;\n readonly files: ConfigFiles;\n readonly refLimits: RefLimitOptions;\n}\n\n/**\n * The generator options of one API: its own settings win over the CLI's flags. A flag that has\n * no effect with the merged flags is named for this API, since its settings may turn on the flag\n * that the command line lacks, or set one that has no effect themselves.\n */\nfunction apiOptions(run: CliRun, apiRun: ApiRun, target: ApiTarget): GeneratorOptions {\n const { name, settings, configRoot } = target;\n const flags = { ...run.args.generatorFlags, ...apiFlags(name, settings) };\n for (const notice of ineffectiveFlagNotices(flags)) {\n run.deps.console.notice(`API ${name}: ${notice}`);\n }\n return {\n ...flags,\n ...apiRun.refLimits,\n ...apiRefLimitOptions(name, settings, configRoot),\n ...fixOption(apiFixNames(name, settings) ?? run.args.fix),\n redocly: apiRun.redocly,\n };\n}\n\n/** The schemas and outputs of every API of the config, keyed by API name for the outputs. */\ninterface ConfigFiles {\n readonly schemas: readonly NamedFile[];\n readonly outputs: ReadonlyMap<string, URL>;\n}\n\n/** The outputs of the other APIs, as `ensureOutputIsOwn` names them. */\nfunction otherOutputs(files: ConfigFiles, apiName: string): NamedFile[] {\n return [...files.outputs]\n .filter(([name]) => name !== apiName)\n .map(([name, location]) => ({ name: `API ${name}`, location }));\n}\n\n/**\n * Generate the types of one API. Its output must not be a file the run reads before any API is\n * loaded (the root of any API, the Redocly config) nor another API's output.\n */\nasync function generateApi(run: CliRun, apiRun: ApiRun, target: ApiTarget): Promise<GeneratedApi> {\n const { files } = apiRun;\n for (const warning of unknownSettingWarnings(target.name, target.settings)) {\n run.deps.logger.warn(warning);\n }\n const output = apiOutputOf(target.name, target.settings);\n const outputFile = outputFileOf(run, { source: target.name, output }, target.configRoot);\n ensureOutputIsNotSchema(run, outputFile, files.schemas);\n ensureOutputIsOwn(run, outputFile, otherOutputs(files, target.name));\n const source = resolveLocationUrl(target.root, target.configRoot);\n const options = apiOptions(run, apiRun, target);\n try {\n const types = await run.deps.generate(source, options, target.name);\n return { name: target.name, outputFile, types };\n } catch (error) {\n throw new ApiFailure(target.name, error);\n }\n}\n\n/**\n * The schema and the output of every API, and the config file itself. A location that is no\n * text or no valid URL is left out: it is no file that an output could be, and its own API fails\n * on it, not every API.\n */\nfunction configFilesOf(run: CliRun, redocly: RedoclyConfig, apis: readonly RedoclyApi[]) {\n const configRoot = configRootOf(redocly, run.deps.cwd);\n const roots = apis.flatMap(({ name, root }) => {\n const location = typeof root === \"string\" ? parseLocationUrl(root, configRoot) : undefined;\n return location ? [{ name: `schema ${root} of API ${name}`, location }] : [];\n });\n const outputs = new Map<string, URL>();\n for (const api of apis) {\n const output = isSettingsMap(api.settings) ? api.settings[OUTPUT_SETTING] : undefined;\n const location = typeof output === \"string\" ? parseLocationUrl(output, configRoot) : undefined;\n if (location) {\n outputs.set(api.name, location);\n }\n }\n const schemas = [...roots, ...redoclyConfigFiles(run, redocly)];\n return { configRoot, files: { schemas, outputs } satisfies ConfigFiles };\n}\n\n/** What `task` gives for each item, run one after another: the next starts when one settles. */\nasync function settledInTurn<T, R>(\n items: readonly T[],\n task: (item: T) => Promise<R>,\n): Promise<PromiseSettledResult<R>[]> {\n const results: PromiseSettledResult<R>[] = [];\n for (const item of items) {\n try {\n results.push({ status: \"fulfilled\", value: await task(item) });\n } catch (reason) {\n results.push({ status: \"rejected\", reason });\n }\n }\n return results;\n}\n\n/**\n * Generate every API of the config, one after another in the order of the config, then write\n * them. One at a time, so a run takes the memory of its largest API, not the sum of all of them,\n * and the work of one API cannot hold up the fetches of another until their timeout ends them.\n * Nothing is written until every API is read and every output is claimed, so no output can\n * replace a file that another API still reads; an output that is a file any API read (a `$ref`'d\n * schema) fails with `CLI_OUTPUT_IS_INPUT`. Every API is generated or checked even when another\n * fails, so `--check` reports a stale output wherever it is; the failures are returned in the\n * order of the config.\n */\nexport async function generateRedoclyApis(run: CliRun, redocly: RedoclyConfig): Promise<unknown[]> {\n const apis = redoclyApisOf(redocly);\n const { configRoot, files } = configFilesOf(run, redocly, apis);\n const apiRun = { redocly, files, refLimits: refLimitOptions(run.args, run.deps.cwd) };\n const results = await settledInTurn(apis, (api) =>\n generateApi(run, apiRun, apiTarget(api, configRoot)),\n );\n const generated = results.flatMap((result) =>\n result.status === \"fulfilled\" ? [result.value] : [],\n );\n const readFiles = generated.flatMap(({ name, types }) => filesReadBy(run, types, `API ${name}`));\n const writeFailures = writeGeneratedApis(run, generated, readFiles);\n return results.flatMap((result) =>\n result.status === \"rejected\" ? [result.reason] : (writeFailures.get(result.value.name) ?? []),\n );\n}\n"],"names":["resolveLocationUrl","cliError","OUTPUT_SETTING","MULTIPLE_SCHEMAS_DOCS_URL","apiFlags","ineffectiveFlagNotices","apiRefLimitOptions","fixOption","apiFixNames","unknownSettingWarnings","apiOutputOf","outputFileOf","ensureOutputIsNotSchema","ensureOutputIsOwn","ApiFailure","parseLocationUrl","redoclyConfigFiles","refLimitOptions","filesReadBy","writeGeneratedApis"],"mappings":"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"}
1
+ {"version":3,"file":"redocly-apis.cjs","sources":["../../src/cli/redocly-apis.ts"],"sourcesContent":["import type { RedoclyConfig } from \"../application/ports/redocly-config-source.js\";\nimport type { GeneratorOptions } from \"../types.js\";\nimport {\n type ApiSettings,\n apiFixNames,\n apiFlags,\n apiOutputOf,\n apiRefLimitOptions,\n OUTPUT_SETTING,\n unknownSettingWarnings,\n} from \"./api-settings.js\";\nimport { type GeneratedApi, writeGeneratedApis } from \"./api-writes.js\";\nimport { ineffectiveFlagNotices } from \"./cli-arguments.js\";\nimport { ApiFailure, cliError } from \"./cli-errors.js\";\nimport {\n type CliRun,\n ensureOutputIsNotSchema,\n ensureOutputIsOwn,\n filesReadBy,\n type NamedFile,\n outputFileOf,\n parseLocationUrl,\n redoclyConfigFiles,\n resolveLocationUrl,\n} from \"./cli-output.js\";\nimport { MULTIPLE_SCHEMAS_DOCS_URL } from \"./docs-links.js\";\nimport { fixOption } from \"./fix-option.js\";\nimport { type RefLimitOptions, refLimitOptions } from \"./ref-limits.js\";\n\n/** The `apis` of a Redocly config: each API is generated into its `x-openapi-ts.output`. */\n\n/** The key of an API's openapi-typesafe settings in `redocly.yaml`. */\nconst REDOCLY_CONFIG_KEY = \"x-openapi-ts\";\n\n/** An API of the config as written: `root` and the settings are not checked yet. */\ninterface RedoclyApi {\n readonly name: string;\n readonly root: unknown;\n readonly settings: unknown;\n}\n\nfunction redoclyApisOf(redocly: RedoclyConfig): RedoclyApi[] {\n return Object.entries(redocly.apis ?? {}).map(([name, api]) => {\n const fields = api as Readonly<Record<string, unknown>>;\n return { name, root: fields.root, settings: fields[REDOCLY_CONFIG_KEY] };\n });\n}\n\nexport function hasRedoclyApis(redocly: RedoclyConfig): boolean {\n return Object.keys(redocly.apis ?? {}).length > 0;\n}\n\n/** Paths in the config are relative to the config file; without a file, to the working dir. */\nfunction configRootOf(redocly: RedoclyConfig, cwd: URL): URL {\n return redocly.configFile ? resolveLocationUrl(redocly.configFile, cwd) : cwd;\n}\n\n/** An API whose root and settings are usable, and the directory its paths are relative to. */\ninterface ApiTarget {\n readonly name: string;\n readonly root: string;\n readonly settings: ApiSettings;\n readonly configRoot: URL;\n}\n\nfunction isSettingsMap(value: unknown): value is ApiSettings {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The API with its settings. Fails with `CLI_CONFIG_OUTPUT_MISSING` when they name no output, and\n * with `CLI_CONFIG_INVALID` when they are no map or `root` is no path or URL; only this API then\n * fails, the others are still generated.\n */\nfunction apiTarget(api: RedoclyApi, configRoot: URL): ApiTarget {\n const { name, root, settings } = api;\n if (settings !== undefined && !isSettingsMap(settings)) {\n throw cliError(\"CLI_CONFIG_INVALID\", `API ${name}: \\`${REDOCLY_CONFIG_KEY}\\` must be a map`);\n }\n if (!settings?.[OUTPUT_SETTING]) {\n throw cliError(\n \"CLI_CONFIG_OUTPUT_MISSING\",\n `API ${name} is missing an \\`${REDOCLY_CONFIG_KEY}.output\\` key. ` +\n `See ${MULTIPLE_SCHEMAS_DOCS_URL}`,\n );\n }\n if (typeof root !== \"string\" || root === \"\") {\n throw cliError(\n \"CLI_CONFIG_INVALID\",\n `API ${name}: \\`root\\` in redocly.yaml must be the path or URL of its schema`,\n );\n }\n return { name, root, settings, configRoot };\n}\n\n/**\n * What every API of a run shares: the config, the files of all APIs, and the reference limits of\n * the command line, which are checked once before any API, so an invalid flag fails the run once.\n */\ninterface ApiRun {\n readonly redocly: RedoclyConfig;\n readonly files: ConfigFiles;\n readonly refLimits: RefLimitOptions;\n}\n\n/**\n * The generator options of one API: its own settings win over the CLI's flags, and its own lint\n * rules in `redocly.yaml` over the root's (upstream used the root's only). A flag that has\n * no effect with the merged flags is named for this API, since its settings may turn on the flag\n * that the command line lacks, or set one that has no effect themselves.\n */\nfunction apiOptions(run: CliRun, apiRun: ApiRun, target: ApiTarget): GeneratorOptions {\n const { name, settings, configRoot } = target;\n const flags = { ...run.args.generatorFlags, ...apiFlags(name, settings) };\n for (const notice of ineffectiveFlagNotices(flags)) {\n run.deps.console.notice(`API ${name}: ${notice}`);\n }\n return {\n ...flags,\n ...apiRun.refLimits,\n ...apiRefLimitOptions(name, settings, configRoot),\n ...fixOption(apiFixNames(name, settings) ?? run.args.fix),\n redocly: run.deps.redoclyConfigs.forApi(apiRun.redocly, name),\n };\n}\n\n/** The schemas and outputs of every API of the config, keyed by API name for the outputs. */\ninterface ConfigFiles {\n readonly schemas: readonly NamedFile[];\n readonly outputs: ReadonlyMap<string, URL>;\n}\n\n/** The outputs of the other APIs, as `ensureOutputIsOwn` names them. */\nfunction otherOutputs(files: ConfigFiles, apiName: string): NamedFile[] {\n return [...files.outputs]\n .filter(([name]) => name !== apiName)\n .map(([name, location]) => ({ name: `API ${name}`, location }));\n}\n\n/**\n * Generate the types of one API. Its output must not be a file the run reads before any API is\n * loaded (the root of any API, the Redocly config) nor another API's output.\n */\nasync function generateApi(run: CliRun, apiRun: ApiRun, target: ApiTarget): Promise<GeneratedApi> {\n const { files } = apiRun;\n for (const warning of unknownSettingWarnings(target.name, target.settings)) {\n run.deps.logger.warn(warning);\n }\n const output = apiOutputOf(target.name, target.settings);\n const outputFile = failingAsApi(target.name, () => {\n const file = outputFileOf(run, { source: target.name, output }, target.configRoot);\n ensureOutputIsNotSchema(run, file, files.schemas);\n ensureOutputIsOwn(run, file, otherOutputs(files, target.name));\n return file;\n });\n const source = resolveLocationUrl(target.root, target.configRoot);\n const options = apiOptions(run, apiRun, target);\n try {\n const types = await run.deps.generate(source, options, target.name);\n return { name: target.name, outputFile, types };\n } catch (error) {\n throw new ApiFailure(target.name, error);\n }\n}\n\n/**\n * The result of a step of one API, whose failure is reported with the API's name. Errors of an\n * API's settings name the API in their own message and are not wrapped.\n */\nfunction failingAsApi<T>(apiName: string, step: () => T): T {\n try {\n return step();\n } catch (error) {\n throw new ApiFailure(apiName, error);\n }\n}\n\n/**\n * The schema and the output of every API, and the config file itself. A location that is no\n * text or no valid URL is left out: it is no file that an output could be, and its own API fails\n * on it, not every API.\n */\nfunction configFilesOf(run: CliRun, redocly: RedoclyConfig, apis: readonly RedoclyApi[]) {\n const configRoot = configRootOf(redocly, run.deps.cwd);\n const roots = apis.flatMap(({ name, root }) => {\n const location = typeof root === \"string\" ? parseLocationUrl(root, configRoot) : undefined;\n return location ? [{ name: `schema ${root} of API ${name}`, location }] : [];\n });\n const outputs = new Map<string, URL>();\n for (const api of apis) {\n const output = isSettingsMap(api.settings) ? api.settings[OUTPUT_SETTING] : undefined;\n const location = typeof output === \"string\" ? parseLocationUrl(output, configRoot) : undefined;\n if (location) {\n outputs.set(api.name, location);\n }\n }\n const schemas = [...roots, ...redoclyConfigFiles(run, redocly)];\n return { configRoot, files: { schemas, outputs } satisfies ConfigFiles };\n}\n\n/** What `task` gives for each item, run one after another: the next starts when one settles. */\nasync function settledInTurn<T, R>(\n items: readonly T[],\n task: (item: T) => Promise<R>,\n): Promise<PromiseSettledResult<R>[]> {\n const results: PromiseSettledResult<R>[] = [];\n for (const item of items) {\n try {\n results.push({ status: \"fulfilled\", value: await task(item) });\n } catch (reason) {\n results.push({ status: \"rejected\", reason });\n }\n }\n return results;\n}\n\n/**\n * Generate every API of the config, one after another in the order of the config, then write\n * them. One at a time, so a run takes the memory of its largest API, not the sum of all of them,\n * and the work of one API cannot hold up the fetches of another until their timeout ends them.\n * Nothing is written until every API is read and every output is claimed, so no output can\n * replace a file that another API still reads; an output that is a file any API read (a `$ref`'d\n * schema) fails with `CLI_OUTPUT_IS_INPUT`. Every API is generated or checked even when another\n * fails, so `--check` reports a stale output wherever it is; the failures are returned in the\n * order of the config.\n */\nexport async function generateRedoclyApis(run: CliRun, redocly: RedoclyConfig): Promise<unknown[]> {\n const apis = redoclyApisOf(redocly);\n const { configRoot, files } = configFilesOf(run, redocly, apis);\n const apiRun = { redocly, files, refLimits: refLimitOptions(run.args, run.deps.cwd) };\n const results = await settledInTurn(apis, (api) =>\n generateApi(run, apiRun, apiTarget(api, configRoot)),\n );\n const generated = results.flatMap((result) =>\n result.status === \"fulfilled\" ? [result.value] : [],\n );\n const readFiles = generated.flatMap(({ name, types }) => filesReadBy(run, types, `API ${name}`));\n const writeFailures = writeGeneratedApis(run, generated, readFiles);\n return results.flatMap((result) =>\n result.status === \"rejected\" ? [result.reason] : (writeFailures.get(result.value.name) ?? []),\n );\n}\n"],"names":["resolveLocationUrl","cliError","OUTPUT_SETTING","MULTIPLE_SCHEMAS_DOCS_URL","apiFlags","ineffectiveFlagNotices","apiRefLimitOptions","fixOption","apiFixNames","unknownSettingWarnings","apiOutputOf","outputFileOf","ensureOutputIsNotSchema","ensureOutputIsOwn","ApiFailure","parseLocationUrl","redoclyConfigFiles","refLimitOptions","filesReadBy","writeGeneratedApis"],"mappings":";;;;;;;;;;;AAgCA,MAAM,kBAAA,GAAqB,cAAA;AAS3B,SAAS,cAAc,OAAA,EAAsC;AAC3D,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,IAAA,IAAQ,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,GAAG,CAAA,KAAM;AAC7D,IAAA,MAAM,MAAA,GAAS,GAAA;AACf,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,MAAA,CAAO,MAAM,QAAA,EAAU,MAAA,CAAO,kBAAkB,CAAA,EAAE;AAAA,EACzE,CAAC,CAAA;AACH;AAEO,SAAS,eAAe,OAAA,EAAiC;AAC9D,EAAA,OAAO,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAQ,EAAE,EAAE,MAAA,GAAS,CAAA;AAClD;AAGA,SAAS,YAAA,CAAa,SAAwB,GAAA,EAAe;AAC3D,EAAA,OAAO,QAAQ,UAAA,GAAaA,4BAAA,CAAmB,OAAA,CAAQ,UAAA,EAAY,GAAG,CAAA,GAAI,GAAA;AAC5E;AAUA,SAAS,cAAc,KAAA,EAAsC;AAC3D,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAOA,SAAS,SAAA,CAAU,KAAiB,UAAA,EAA4B;AAC9D,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS,GAAI,GAAA;AACjC,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,CAAC,aAAA,CAAc,QAAQ,CAAA,EAAG;AACtD,IAAA,MAAMC,mBAAS,oBAAA,EAAsB,CAAA,IAAA,EAAO,IAAI,CAAA,IAAA,EAAO,kBAAkB,CAAA,gBAAA,CAAkB,CAAA;AAAA,EAC7F;AACA,EAAA,IAAI,CAAC,QAAA,GAAWC,0BAAc,CAAA,EAAG;AAC/B,IAAA,MAAMD,kBAAA;AAAA,MACJ,2BAAA;AAAA,MACA,CAAA,IAAA,EAAO,IAAI,CAAA,iBAAA,EAAoB,kBAAkB,sBACxCE,mCAAyB,CAAA;AAAA,KACpC;AAAA,EACF;AACA,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,EAAA,EAAI;AAC3C,IAAA,MAAMF,kBAAA;AAAA,MACJ,oBAAA;AAAA,MACA,OAAO,IAAI,CAAA,gEAAA;AAAA,KACb;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,QAAA,EAAU,UAAA,EAAW;AAC5C;AAkBA,SAAS,UAAA,CAAW,GAAA,EAAa,MAAA,EAAgB,MAAA,EAAqC;AACpF,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAA,EAAW,GAAI,MAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,GAAA,CAAI,IAAA,CAAK,gBAAgB,GAAGG,oBAAA,CAAS,IAAA,EAAM,QAAQ,CAAA,EAAE;AACxE,EAAA,KAAA,MAAW,MAAA,IAAUC,mCAAA,CAAuB,KAAK,CAAA,EAAG;AAClD,IAAA,GAAA,CAAI,KAAK,OAAA,CAAQ,MAAA,CAAO,OAAO,IAAI,CAAA,EAAA,EAAK,MAAM,CAAA,CAAE,CAAA;AAAA,EAClD;AACA,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,GAAG,MAAA,CAAO,SAAA;AAAA,IACV,GAAGC,8BAAA,CAAmB,IAAA,EAAM,QAAA,EAAU,UAAU,CAAA;AAAA,IAChD,GAAGC,oBAAUC,uBAAA,CAAY,IAAA,EAAM,QAAQ,CAAA,IAAK,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,IACxD,SAAS,GAAA,CAAI,IAAA,CAAK,eAAe,MAAA,CAAO,MAAA,CAAO,SAAS,IAAI;AAAA,GAC9D;AACF;AASA,SAAS,YAAA,CAAa,OAAoB,OAAA,EAA8B;AACtE,EAAA,OAAO,CAAC,GAAG,KAAA,CAAM,OAAO,CAAA,CACrB,OAAO,CAAC,CAAC,IAAI,CAAA,KAAM,IAAA,KAAS,OAAO,EACnC,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,QAAQ,CAAA,MAAO,EAAE,IAAA,EAAM,CAAA,IAAA,EAAO,IAAI,CAAA,CAAA,EAAI,QAAA,EAAS,CAAE,CAAA;AAClE;AAMA,eAAe,WAAA,CAAY,GAAA,EAAa,MAAA,EAAgB,MAAA,EAA0C;AAChG,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAClB,EAAA,KAAA,MAAW,WAAWC,kCAAA,CAAuB,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,QAAQ,CAAA,EAAG;AAC1E,IAAA,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,MAAA,GAASC,uBAAA,CAAY,MAAA,CAAO,IAAA,EAAM,OAAO,QAAQ,CAAA;AACvD,EAAA,MAAM,UAAA,GAAa,YAAA,CAAa,MAAA,CAAO,IAAA,EAAM,MAAM;AACjD,IAAA,MAAM,IAAA,GAAOC,sBAAA,CAAa,GAAA,EAAK,EAAE,MAAA,EAAQ,OAAO,IAAA,EAAM,MAAA,EAAO,EAAG,MAAA,CAAO,UAAU,CAAA;AACjF,IAAAC,iCAAA,CAAwB,GAAA,EAAK,IAAA,EAAM,KAAA,CAAM,OAAO,CAAA;AAChD,IAAAC,2BAAA,CAAkB,KAAK,IAAA,EAAM,YAAA,CAAa,KAAA,EAAO,MAAA,CAAO,IAAI,CAAC,CAAA;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,MAAM,MAAA,GAASb,4BAAA,CAAmB,MAAA,CAAO,IAAA,EAAM,OAAO,UAAU,CAAA;AAChE,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,GAAA,EAAK,MAAA,EAAQ,MAAM,CAAA;AAC9C,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,CAAK,SAAS,MAAA,EAAQ,OAAA,EAAS,OAAO,IAAI,CAAA;AAClE,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,YAAY,KAAA,EAAM;AAAA,EAChD,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAIc,oBAAA,CAAW,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA;AAAA,EACzC;AACF;AAMA,SAAS,YAAA,CAAgB,SAAiB,IAAA,EAAkB;AAC1D,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,EAAK;AAAA,EACd,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAIA,oBAAA,CAAW,OAAA,EAAS,KAAK,CAAA;AAAA,EACrC;AACF;AAOA,SAAS,aAAA,CAAc,GAAA,EAAa,OAAA,EAAwB,IAAA,EAA6B;AACvF,EAAA,MAAM,UAAA,GAAa,YAAA,CAAa,OAAA,EAAS,GAAA,CAAI,KAAK,GAAG,CAAA;AACrD,EAAA,MAAM,QAAQ,IAAA,CAAK,OAAA,CAAQ,CAAC,EAAE,IAAA,EAAM,MAAK,KAAM;AAC7C,IAAA,MAAM,WAAW,OAAO,IAAA,KAAS,WAAWC,0BAAA,CAAiB,IAAA,EAAM,UAAU,CAAA,GAAI,MAAA;AACjF,IAAA,OAAO,QAAA,GAAW,CAAC,EAAE,IAAA,EAAM,CAAA,OAAA,EAAU,IAAI,CAAA,QAAA,EAAW,IAAI,CAAA,CAAA,EAAI,QAAA,EAAU,CAAA,GAAI,EAAC;AAAA,EAC7E,CAAC,CAAA;AACD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAiB;AACrC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,MAAA,GAAS,cAAc,GAAA,CAAI,QAAQ,IAAI,GAAA,CAAI,QAAA,CAASb,0BAAc,CAAA,GAAI,MAAA;AAC5E,IAAA,MAAM,WAAW,OAAO,MAAA,KAAW,WAAWa,0BAAA,CAAiB,MAAA,EAAQ,UAAU,CAAA,GAAI,MAAA;AACrF,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,QAAQ,CAAA;AAAA,IAChC;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,KAAA,EAAO,GAAGC,4BAAA,CAAmB,GAAA,EAAK,OAAO,CAAC,CAAA;AAC9D,EAAA,OAAO,EAAE,UAAA,EAAY,KAAA,EAAO,EAAE,OAAA,EAAS,SAAQ,EAAwB;AACzE;AAGA,eAAe,aAAA,CACb,OACA,IAAA,EACoC;AACpC,EAAA,MAAM,UAAqC,EAAC;AAC5C,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,MAAA,EAAQ,WAAA,EAAa,OAAO,MAAM,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA;AAAA,IAC/D,SAAS,MAAA,EAAQ;AACf,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,MAAA,EAAQ,UAAA,EAAY,QAAQ,CAAA;AAAA,IAC7C;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAYA,eAAsB,mBAAA,CAAoB,KAAa,OAAA,EAA4C;AACjG,EAAA,MAAM,IAAA,GAAO,cAAc,OAAO,CAAA;AAClC,EAAA,MAAM,EAAE,UAAA,EAAY,KAAA,KAAU,aAAA,CAAc,GAAA,EAAK,SAAS,IAAI,CAAA;AAC9D,EAAA,MAAM,MAAA,GAAS,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,EAAWC,yBAAA,CAAgB,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,GAAG,CAAA,EAAE;AACpF,EAAA,MAAM,UAAU,MAAM,aAAA;AAAA,IAAc,IAAA;AAAA,IAAM,CAAC,QACzC,WAAA,CAAY,GAAA,EAAK,QAAQ,SAAA,CAAU,GAAA,EAAK,UAAU,CAAC;AAAA,GACrD;AACA,EAAA,MAAM,YAAY,OAAA,CAAQ,OAAA;AAAA,IAAQ,CAAC,WACjC,MAAA,CAAO,MAAA,KAAW,cAAc,CAAC,MAAA,CAAO,KAAK,CAAA,GAAI;AAAC,GACpD;AACA,EAAA,MAAM,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,CAAC,EAAE,IAAA,EAAM,KAAA,EAAM,KAAMC,qBAAA,CAAY,GAAA,EAAK,KAAA,EAAO,CAAA,IAAA,EAAO,IAAI,EAAE,CAAC,CAAA;AAC/F,EAAA,MAAM,aAAA,GAAgBC,4BAAA,CAAmB,GAAA,EAAK,SAAA,EAAW,SAAS,CAAA;AAClE,EAAA,OAAO,OAAA,CAAQ,OAAA;AAAA,IAAQ,CAAC,MAAA,KACtB,MAAA,CAAO,MAAA,KAAW,aAAa,CAAC,MAAA,CAAO,MAAM,CAAA,GAAK,cAAc,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,IAAI,KAAK;AAAC,GAC7F;AACF;;;"}
@@ -53,7 +53,7 @@ function apiOptions(run, apiRun, target) {
53
53
  ...apiRun.refLimits,
54
54
  ...apiRefLimitOptions(name, settings, configRoot),
55
55
  ...fixOption(apiFixNames(name, settings) ?? run.args.fix),
56
- redocly: apiRun.redocly
56
+ redocly: run.deps.redoclyConfigs.forApi(apiRun.redocly, name)
57
57
  };
58
58
  }
59
59
  function otherOutputs(files, apiName) {
@@ -65,9 +65,12 @@ async function generateApi(run, apiRun, target) {
65
65
  run.deps.logger.warn(warning);
66
66
  }
67
67
  const output = apiOutputOf(target.name, target.settings);
68
- const outputFile = outputFileOf(run, { source: target.name, output }, target.configRoot);
69
- ensureOutputIsNotSchema(run, outputFile, files.schemas);
70
- ensureOutputIsOwn(run, outputFile, otherOutputs(files, target.name));
68
+ const outputFile = failingAsApi(target.name, () => {
69
+ const file = outputFileOf(run, { source: target.name, output }, target.configRoot);
70
+ ensureOutputIsNotSchema(run, file, files.schemas);
71
+ ensureOutputIsOwn(run, file, otherOutputs(files, target.name));
72
+ return file;
73
+ });
71
74
  const source = resolveLocationUrl(target.root, target.configRoot);
72
75
  const options = apiOptions(run, apiRun, target);
73
76
  try {
@@ -77,6 +80,13 @@ async function generateApi(run, apiRun, target) {
77
80
  throw new ApiFailure(target.name, error);
78
81
  }
79
82
  }
83
+ function failingAsApi(apiName, step) {
84
+ try {
85
+ return step();
86
+ } catch (error) {
87
+ throw new ApiFailure(apiName, error);
88
+ }
89
+ }
80
90
  function configFilesOf(run, redocly, apis) {
81
91
  const configRoot = configRootOf(redocly, run.deps.cwd);
82
92
  const roots = apis.flatMap(({ name, root }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"redocly-apis.mjs","sources":["../../src/cli/redocly-apis.ts"],"sourcesContent":["import type { RedoclyConfig } from \"../application/ports/redocly-config-source.js\";\nimport type { GeneratorOptions } from \"../types.js\";\nimport {\n type ApiSettings,\n apiFixNames,\n apiFlags,\n apiOutputOf,\n apiRefLimitOptions,\n OUTPUT_SETTING,\n unknownSettingWarnings,\n} from \"./api-settings.js\";\nimport { type GeneratedApi, writeGeneratedApis } from \"./api-writes.js\";\nimport { ineffectiveFlagNotices } from \"./cli-arguments.js\";\nimport { ApiFailure, cliError } from \"./cli-errors.js\";\nimport {\n type CliRun,\n ensureOutputIsNotSchema,\n ensureOutputIsOwn,\n filesReadBy,\n type NamedFile,\n outputFileOf,\n parseLocationUrl,\n redoclyConfigFiles,\n resolveLocationUrl,\n} from \"./cli-output.js\";\nimport { MULTIPLE_SCHEMAS_DOCS_URL } from \"./docs-links.js\";\nimport { fixOption } from \"./fix-option.js\";\nimport { type RefLimitOptions, refLimitOptions } from \"./ref-limits.js\";\n\n/** The `apis` of a Redocly config: each API is generated into its `x-openapi-ts.output`. */\n\n/** The key of an API's openapi-typesafe settings in `redocly.yaml`. */\nconst REDOCLY_CONFIG_KEY = \"x-openapi-ts\";\n\n/** An API of the config as written: `root` and the settings are not checked yet. */\ninterface RedoclyApi {\n readonly name: string;\n readonly root: unknown;\n readonly settings: unknown;\n}\n\nfunction redoclyApisOf(redocly: RedoclyConfig): RedoclyApi[] {\n return Object.entries(redocly.apis ?? {}).map(([name, api]) => {\n const fields = api as Readonly<Record<string, unknown>>;\n return { name, root: fields.root, settings: fields[REDOCLY_CONFIG_KEY] };\n });\n}\n\nexport function hasRedoclyApis(redocly: RedoclyConfig): boolean {\n return Object.keys(redocly.apis ?? {}).length > 0;\n}\n\n/** Paths in the config are relative to the config file; without a file, to the working dir. */\nfunction configRootOf(redocly: RedoclyConfig, cwd: URL): URL {\n return redocly.configFile ? resolveLocationUrl(redocly.configFile, cwd) : cwd;\n}\n\n/** An API whose root and settings are usable, and the directory its paths are relative to. */\ninterface ApiTarget {\n readonly name: string;\n readonly root: string;\n readonly settings: ApiSettings;\n readonly configRoot: URL;\n}\n\nfunction isSettingsMap(value: unknown): value is ApiSettings {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The API with its settings. Fails with `CLI_CONFIG_OUTPUT_MISSING` when they name no output, and\n * with `CLI_CONFIG_INVALID` when they are no map or `root` is no path or URL; only this API then\n * fails, the others are still generated.\n */\nfunction apiTarget(api: RedoclyApi, configRoot: URL): ApiTarget {\n const { name, root, settings } = api;\n if (settings !== undefined && !isSettingsMap(settings)) {\n throw cliError(\"CLI_CONFIG_INVALID\", `API ${name}: \\`${REDOCLY_CONFIG_KEY}\\` must be a map`);\n }\n if (!settings?.[OUTPUT_SETTING]) {\n throw cliError(\n \"CLI_CONFIG_OUTPUT_MISSING\",\n `API ${name} is missing an \\`${REDOCLY_CONFIG_KEY}.output\\` key. ` +\n `See ${MULTIPLE_SCHEMAS_DOCS_URL}`,\n );\n }\n if (typeof root !== \"string\" || root === \"\") {\n throw cliError(\n \"CLI_CONFIG_INVALID\",\n `API ${name}: \\`root\\` in redocly.yaml must be the path or URL of its schema`,\n );\n }\n return { name, root, settings, configRoot };\n}\n\n/**\n * What every API of a run shares: the config, the files of all APIs, and the reference limits of\n * the command line, which are checked once before any API, so an invalid flag fails the run once.\n */\ninterface ApiRun {\n readonly redocly: RedoclyConfig;\n readonly files: ConfigFiles;\n readonly refLimits: RefLimitOptions;\n}\n\n/**\n * The generator options of one API: its own settings win over the CLI's flags. A flag that has\n * no effect with the merged flags is named for this API, since its settings may turn on the flag\n * that the command line lacks, or set one that has no effect themselves.\n */\nfunction apiOptions(run: CliRun, apiRun: ApiRun, target: ApiTarget): GeneratorOptions {\n const { name, settings, configRoot } = target;\n const flags = { ...run.args.generatorFlags, ...apiFlags(name, settings) };\n for (const notice of ineffectiveFlagNotices(flags)) {\n run.deps.console.notice(`API ${name}: ${notice}`);\n }\n return {\n ...flags,\n ...apiRun.refLimits,\n ...apiRefLimitOptions(name, settings, configRoot),\n ...fixOption(apiFixNames(name, settings) ?? run.args.fix),\n redocly: apiRun.redocly,\n };\n}\n\n/** The schemas and outputs of every API of the config, keyed by API name for the outputs. */\ninterface ConfigFiles {\n readonly schemas: readonly NamedFile[];\n readonly outputs: ReadonlyMap<string, URL>;\n}\n\n/** The outputs of the other APIs, as `ensureOutputIsOwn` names them. */\nfunction otherOutputs(files: ConfigFiles, apiName: string): NamedFile[] {\n return [...files.outputs]\n .filter(([name]) => name !== apiName)\n .map(([name, location]) => ({ name: `API ${name}`, location }));\n}\n\n/**\n * Generate the types of one API. Its output must not be a file the run reads before any API is\n * loaded (the root of any API, the Redocly config) nor another API's output.\n */\nasync function generateApi(run: CliRun, apiRun: ApiRun, target: ApiTarget): Promise<GeneratedApi> {\n const { files } = apiRun;\n for (const warning of unknownSettingWarnings(target.name, target.settings)) {\n run.deps.logger.warn(warning);\n }\n const output = apiOutputOf(target.name, target.settings);\n const outputFile = outputFileOf(run, { source: target.name, output }, target.configRoot);\n ensureOutputIsNotSchema(run, outputFile, files.schemas);\n ensureOutputIsOwn(run, outputFile, otherOutputs(files, target.name));\n const source = resolveLocationUrl(target.root, target.configRoot);\n const options = apiOptions(run, apiRun, target);\n try {\n const types = await run.deps.generate(source, options, target.name);\n return { name: target.name, outputFile, types };\n } catch (error) {\n throw new ApiFailure(target.name, error);\n }\n}\n\n/**\n * The schema and the output of every API, and the config file itself. A location that is no\n * text or no valid URL is left out: it is no file that an output could be, and its own API fails\n * on it, not every API.\n */\nfunction configFilesOf(run: CliRun, redocly: RedoclyConfig, apis: readonly RedoclyApi[]) {\n const configRoot = configRootOf(redocly, run.deps.cwd);\n const roots = apis.flatMap(({ name, root }) => {\n const location = typeof root === \"string\" ? parseLocationUrl(root, configRoot) : undefined;\n return location ? [{ name: `schema ${root} of API ${name}`, location }] : [];\n });\n const outputs = new Map<string, URL>();\n for (const api of apis) {\n const output = isSettingsMap(api.settings) ? api.settings[OUTPUT_SETTING] : undefined;\n const location = typeof output === \"string\" ? parseLocationUrl(output, configRoot) : undefined;\n if (location) {\n outputs.set(api.name, location);\n }\n }\n const schemas = [...roots, ...redoclyConfigFiles(run, redocly)];\n return { configRoot, files: { schemas, outputs } satisfies ConfigFiles };\n}\n\n/** What `task` gives for each item, run one after another: the next starts when one settles. */\nasync function settledInTurn<T, R>(\n items: readonly T[],\n task: (item: T) => Promise<R>,\n): Promise<PromiseSettledResult<R>[]> {\n const results: PromiseSettledResult<R>[] = [];\n for (const item of items) {\n try {\n results.push({ status: \"fulfilled\", value: await task(item) });\n } catch (reason) {\n results.push({ status: \"rejected\", reason });\n }\n }\n return results;\n}\n\n/**\n * Generate every API of the config, one after another in the order of the config, then write\n * them. One at a time, so a run takes the memory of its largest API, not the sum of all of them,\n * and the work of one API cannot hold up the fetches of another until their timeout ends them.\n * Nothing is written until every API is read and every output is claimed, so no output can\n * replace a file that another API still reads; an output that is a file any API read (a `$ref`'d\n * schema) fails with `CLI_OUTPUT_IS_INPUT`. Every API is generated or checked even when another\n * fails, so `--check` reports a stale output wherever it is; the failures are returned in the\n * order of the config.\n */\nexport async function generateRedoclyApis(run: CliRun, redocly: RedoclyConfig): Promise<unknown[]> {\n const apis = redoclyApisOf(redocly);\n const { configRoot, files } = configFilesOf(run, redocly, apis);\n const apiRun = { redocly, files, refLimits: refLimitOptions(run.args, run.deps.cwd) };\n const results = await settledInTurn(apis, (api) =>\n generateApi(run, apiRun, apiTarget(api, configRoot)),\n );\n const generated = results.flatMap((result) =>\n result.status === \"fulfilled\" ? [result.value] : [],\n );\n const readFiles = generated.flatMap(({ name, types }) => filesReadBy(run, types, `API ${name}`));\n const writeFailures = writeGeneratedApis(run, generated, readFiles);\n return results.flatMap((result) =>\n result.status === \"rejected\" ? [result.reason] : (writeFailures.get(result.value.name) ?? []),\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAgCA,MAAM,kBAAA,GAAqB,cAAA;AAS3B,SAAS,cAAc,OAAA,EAAsC;AAC3D,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,IAAA,IAAQ,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,GAAG,CAAA,KAAM;AAC7D,IAAA,MAAM,MAAA,GAAS,GAAA;AACf,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,MAAA,CAAO,MAAM,QAAA,EAAU,MAAA,CAAO,kBAAkB,CAAA,EAAE;AAAA,EACzE,CAAC,CAAA;AACH;AAEO,SAAS,eAAe,OAAA,EAAiC;AAC9D,EAAA,OAAO,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAQ,EAAE,EAAE,MAAA,GAAS,CAAA;AAClD;AAGA,SAAS,YAAA,CAAa,SAAwB,GAAA,EAAe;AAC3D,EAAA,OAAO,QAAQ,UAAA,GAAa,kBAAA,CAAmB,OAAA,CAAQ,UAAA,EAAY,GAAG,CAAA,GAAI,GAAA;AAC5E;AAUA,SAAS,cAAc,KAAA,EAAsC;AAC3D,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAOA,SAAS,SAAA,CAAU,KAAiB,UAAA,EAA4B;AAC9D,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS,GAAI,GAAA;AACjC,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,CAAC,aAAA,CAAc,QAAQ,CAAA,EAAG;AACtD,IAAA,MAAM,SAAS,oBAAA,EAAsB,CAAA,IAAA,EAAO,IAAI,CAAA,IAAA,EAAO,kBAAkB,CAAA,gBAAA,CAAkB,CAAA;AAAA,EAC7F;AACA,EAAA,IAAI,CAAC,QAAA,GAAW,cAAc,CAAA,EAAG;AAC/B,IAAA,MAAM,QAAA;AAAA,MACJ,2BAAA;AAAA,MACA,CAAA,IAAA,EAAO,IAAI,CAAA,iBAAA,EAAoB,kBAAkB,sBACxC,yBAAyB,CAAA;AAAA,KACpC;AAAA,EACF;AACA,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,EAAA,EAAI;AAC3C,IAAA,MAAM,QAAA;AAAA,MACJ,oBAAA;AAAA,MACA,OAAO,IAAI,CAAA,gEAAA;AAAA,KACb;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,QAAA,EAAU,UAAA,EAAW;AAC5C;AAiBA,SAAS,UAAA,CAAW,GAAA,EAAa,MAAA,EAAgB,MAAA,EAAqC;AACpF,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAA,EAAW,GAAI,MAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,GAAA,CAAI,IAAA,CAAK,gBAAgB,GAAG,QAAA,CAAS,IAAA,EAAM,QAAQ,CAAA,EAAE;AACxE,EAAA,KAAA,MAAW,MAAA,IAAU,sBAAA,CAAuB,KAAK,CAAA,EAAG;AAClD,IAAA,GAAA,CAAI,KAAK,OAAA,CAAQ,MAAA,CAAO,OAAO,IAAI,CAAA,EAAA,EAAK,MAAM,CAAA,CAAE,CAAA;AAAA,EAClD;AACA,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,GAAG,MAAA,CAAO,SAAA;AAAA,IACV,GAAG,kBAAA,CAAmB,IAAA,EAAM,QAAA,EAAU,UAAU,CAAA;AAAA,IAChD,GAAG,UAAU,WAAA,CAAY,IAAA,EAAM,QAAQ,CAAA,IAAK,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,IACxD,SAAS,MAAA,CAAO;AAAA,GAClB;AACF;AASA,SAAS,YAAA,CAAa,OAAoB,OAAA,EAA8B;AACtE,EAAA,OAAO,CAAC,GAAG,KAAA,CAAM,OAAO,CAAA,CACrB,OAAO,CAAC,CAAC,IAAI,CAAA,KAAM,IAAA,KAAS,OAAO,EACnC,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,QAAQ,CAAA,MAAO,EAAE,IAAA,EAAM,CAAA,IAAA,EAAO,IAAI,CAAA,CAAA,EAAI,QAAA,EAAS,CAAE,CAAA;AAClE;AAMA,eAAe,WAAA,CAAY,GAAA,EAAa,MAAA,EAAgB,MAAA,EAA0C;AAChG,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAClB,EAAA,KAAA,MAAW,WAAW,sBAAA,CAAuB,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,QAAQ,CAAA,EAAG;AAC1E,IAAA,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,MAAA,CAAO,IAAA,EAAM,OAAO,QAAQ,CAAA;AACvD,EAAA,MAAM,UAAA,GAAa,YAAA,CAAa,GAAA,EAAK,EAAE,MAAA,EAAQ,OAAO,IAAA,EAAM,MAAA,EAAO,EAAG,MAAA,CAAO,UAAU,CAAA;AACvF,EAAA,uBAAA,CAAwB,GAAA,EAAK,UAAA,EAAY,KAAA,CAAM,OAAO,CAAA;AACtD,EAAA,iBAAA,CAAkB,KAAK,UAAA,EAAY,YAAA,CAAa,KAAA,EAAO,MAAA,CAAO,IAAI,CAAC,CAAA;AACnE,EAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,MAAA,CAAO,IAAA,EAAM,OAAO,UAAU,CAAA;AAChE,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,GAAA,EAAK,MAAA,EAAQ,MAAM,CAAA;AAC9C,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,CAAK,SAAS,MAAA,EAAQ,OAAA,EAAS,OAAO,IAAI,CAAA;AAClE,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,YAAY,KAAA,EAAM;AAAA,EAChD,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA;AAAA,EACzC;AACF;AAOA,SAAS,aAAA,CAAc,GAAA,EAAa,OAAA,EAAwB,IAAA,EAA6B;AACvF,EAAA,MAAM,UAAA,GAAa,YAAA,CAAa,OAAA,EAAS,GAAA,CAAI,KAAK,GAAG,CAAA;AACrD,EAAA,MAAM,QAAQ,IAAA,CAAK,OAAA,CAAQ,CAAC,EAAE,IAAA,EAAM,MAAK,KAAM;AAC7C,IAAA,MAAM,WAAW,OAAO,IAAA,KAAS,WAAW,gBAAA,CAAiB,IAAA,EAAM,UAAU,CAAA,GAAI,MAAA;AACjF,IAAA,OAAO,QAAA,GAAW,CAAC,EAAE,IAAA,EAAM,CAAA,OAAA,EAAU,IAAI,CAAA,QAAA,EAAW,IAAI,CAAA,CAAA,EAAI,QAAA,EAAU,CAAA,GAAI,EAAC;AAAA,EAC7E,CAAC,CAAA;AACD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAiB;AACrC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,MAAA,GAAS,cAAc,GAAA,CAAI,QAAQ,IAAI,GAAA,CAAI,QAAA,CAAS,cAAc,CAAA,GAAI,MAAA;AAC5E,IAAA,MAAM,WAAW,OAAO,MAAA,KAAW,WAAW,gBAAA,CAAiB,MAAA,EAAQ,UAAU,CAAA,GAAI,MAAA;AACrF,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,QAAQ,CAAA;AAAA,IAChC;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,KAAA,EAAO,GAAG,kBAAA,CAAmB,GAAA,EAAK,OAAO,CAAC,CAAA;AAC9D,EAAA,OAAO,EAAE,UAAA,EAAY,KAAA,EAAO,EAAE,OAAA,EAAS,SAAQ,EAAwB;AACzE;AAGA,eAAe,aAAA,CACb,OACA,IAAA,EACoC;AACpC,EAAA,MAAM,UAAqC,EAAC;AAC5C,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,MAAA,EAAQ,WAAA,EAAa,OAAO,MAAM,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA;AAAA,IAC/D,SAAS,MAAA,EAAQ;AACf,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,MAAA,EAAQ,UAAA,EAAY,QAAQ,CAAA;AAAA,IAC7C;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAYA,eAAsB,mBAAA,CAAoB,KAAa,OAAA,EAA4C;AACjG,EAAA,MAAM,IAAA,GAAO,cAAc,OAAO,CAAA;AAClC,EAAA,MAAM,EAAE,UAAA,EAAY,KAAA,KAAU,aAAA,CAAc,GAAA,EAAK,SAAS,IAAI,CAAA;AAC9D,EAAA,MAAM,MAAA,GAAS,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,eAAA,CAAgB,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,GAAG,CAAA,EAAE;AACpF,EAAA,MAAM,UAAU,MAAM,aAAA;AAAA,IAAc,IAAA;AAAA,IAAM,CAAC,QACzC,WAAA,CAAY,GAAA,EAAK,QAAQ,SAAA,CAAU,GAAA,EAAK,UAAU,CAAC;AAAA,GACrD;AACA,EAAA,MAAM,YAAY,OAAA,CAAQ,OAAA;AAAA,IAAQ,CAAC,WACjC,MAAA,CAAO,MAAA,KAAW,cAAc,CAAC,MAAA,CAAO,KAAK,CAAA,GAAI;AAAC,GACpD;AACA,EAAA,MAAM,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,CAAC,EAAE,IAAA,EAAM,KAAA,EAAM,KAAM,WAAA,CAAY,GAAA,EAAK,KAAA,EAAO,CAAA,IAAA,EAAO,IAAI,EAAE,CAAC,CAAA;AAC/F,EAAA,MAAM,aAAA,GAAgB,kBAAA,CAAmB,GAAA,EAAK,SAAA,EAAW,SAAS,CAAA;AAClE,EAAA,OAAO,OAAA,CAAQ,OAAA;AAAA,IAAQ,CAAC,MAAA,KACtB,MAAA,CAAO,MAAA,KAAW,aAAa,CAAC,MAAA,CAAO,MAAM,CAAA,GAAK,cAAc,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,IAAI,KAAK;AAAC,GAC7F;AACF;;"}
1
+ {"version":3,"file":"redocly-apis.mjs","sources":["../../src/cli/redocly-apis.ts"],"sourcesContent":["import type { RedoclyConfig } from \"../application/ports/redocly-config-source.js\";\nimport type { GeneratorOptions } from \"../types.js\";\nimport {\n type ApiSettings,\n apiFixNames,\n apiFlags,\n apiOutputOf,\n apiRefLimitOptions,\n OUTPUT_SETTING,\n unknownSettingWarnings,\n} from \"./api-settings.js\";\nimport { type GeneratedApi, writeGeneratedApis } from \"./api-writes.js\";\nimport { ineffectiveFlagNotices } from \"./cli-arguments.js\";\nimport { ApiFailure, cliError } from \"./cli-errors.js\";\nimport {\n type CliRun,\n ensureOutputIsNotSchema,\n ensureOutputIsOwn,\n filesReadBy,\n type NamedFile,\n outputFileOf,\n parseLocationUrl,\n redoclyConfigFiles,\n resolveLocationUrl,\n} from \"./cli-output.js\";\nimport { MULTIPLE_SCHEMAS_DOCS_URL } from \"./docs-links.js\";\nimport { fixOption } from \"./fix-option.js\";\nimport { type RefLimitOptions, refLimitOptions } from \"./ref-limits.js\";\n\n/** The `apis` of a Redocly config: each API is generated into its `x-openapi-ts.output`. */\n\n/** The key of an API's openapi-typesafe settings in `redocly.yaml`. */\nconst REDOCLY_CONFIG_KEY = \"x-openapi-ts\";\n\n/** An API of the config as written: `root` and the settings are not checked yet. */\ninterface RedoclyApi {\n readonly name: string;\n readonly root: unknown;\n readonly settings: unknown;\n}\n\nfunction redoclyApisOf(redocly: RedoclyConfig): RedoclyApi[] {\n return Object.entries(redocly.apis ?? {}).map(([name, api]) => {\n const fields = api as Readonly<Record<string, unknown>>;\n return { name, root: fields.root, settings: fields[REDOCLY_CONFIG_KEY] };\n });\n}\n\nexport function hasRedoclyApis(redocly: RedoclyConfig): boolean {\n return Object.keys(redocly.apis ?? {}).length > 0;\n}\n\n/** Paths in the config are relative to the config file; without a file, to the working dir. */\nfunction configRootOf(redocly: RedoclyConfig, cwd: URL): URL {\n return redocly.configFile ? resolveLocationUrl(redocly.configFile, cwd) : cwd;\n}\n\n/** An API whose root and settings are usable, and the directory its paths are relative to. */\ninterface ApiTarget {\n readonly name: string;\n readonly root: string;\n readonly settings: ApiSettings;\n readonly configRoot: URL;\n}\n\nfunction isSettingsMap(value: unknown): value is ApiSettings {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The API with its settings. Fails with `CLI_CONFIG_OUTPUT_MISSING` when they name no output, and\n * with `CLI_CONFIG_INVALID` when they are no map or `root` is no path or URL; only this API then\n * fails, the others are still generated.\n */\nfunction apiTarget(api: RedoclyApi, configRoot: URL): ApiTarget {\n const { name, root, settings } = api;\n if (settings !== undefined && !isSettingsMap(settings)) {\n throw cliError(\"CLI_CONFIG_INVALID\", `API ${name}: \\`${REDOCLY_CONFIG_KEY}\\` must be a map`);\n }\n if (!settings?.[OUTPUT_SETTING]) {\n throw cliError(\n \"CLI_CONFIG_OUTPUT_MISSING\",\n `API ${name} is missing an \\`${REDOCLY_CONFIG_KEY}.output\\` key. ` +\n `See ${MULTIPLE_SCHEMAS_DOCS_URL}`,\n );\n }\n if (typeof root !== \"string\" || root === \"\") {\n throw cliError(\n \"CLI_CONFIG_INVALID\",\n `API ${name}: \\`root\\` in redocly.yaml must be the path or URL of its schema`,\n );\n }\n return { name, root, settings, configRoot };\n}\n\n/**\n * What every API of a run shares: the config, the files of all APIs, and the reference limits of\n * the command line, which are checked once before any API, so an invalid flag fails the run once.\n */\ninterface ApiRun {\n readonly redocly: RedoclyConfig;\n readonly files: ConfigFiles;\n readonly refLimits: RefLimitOptions;\n}\n\n/**\n * The generator options of one API: its own settings win over the CLI's flags, and its own lint\n * rules in `redocly.yaml` over the root's (upstream used the root's only). A flag that has\n * no effect with the merged flags is named for this API, since its settings may turn on the flag\n * that the command line lacks, or set one that has no effect themselves.\n */\nfunction apiOptions(run: CliRun, apiRun: ApiRun, target: ApiTarget): GeneratorOptions {\n const { name, settings, configRoot } = target;\n const flags = { ...run.args.generatorFlags, ...apiFlags(name, settings) };\n for (const notice of ineffectiveFlagNotices(flags)) {\n run.deps.console.notice(`API ${name}: ${notice}`);\n }\n return {\n ...flags,\n ...apiRun.refLimits,\n ...apiRefLimitOptions(name, settings, configRoot),\n ...fixOption(apiFixNames(name, settings) ?? run.args.fix),\n redocly: run.deps.redoclyConfigs.forApi(apiRun.redocly, name),\n };\n}\n\n/** The schemas and outputs of every API of the config, keyed by API name for the outputs. */\ninterface ConfigFiles {\n readonly schemas: readonly NamedFile[];\n readonly outputs: ReadonlyMap<string, URL>;\n}\n\n/** The outputs of the other APIs, as `ensureOutputIsOwn` names them. */\nfunction otherOutputs(files: ConfigFiles, apiName: string): NamedFile[] {\n return [...files.outputs]\n .filter(([name]) => name !== apiName)\n .map(([name, location]) => ({ name: `API ${name}`, location }));\n}\n\n/**\n * Generate the types of one API. Its output must not be a file the run reads before any API is\n * loaded (the root of any API, the Redocly config) nor another API's output.\n */\nasync function generateApi(run: CliRun, apiRun: ApiRun, target: ApiTarget): Promise<GeneratedApi> {\n const { files } = apiRun;\n for (const warning of unknownSettingWarnings(target.name, target.settings)) {\n run.deps.logger.warn(warning);\n }\n const output = apiOutputOf(target.name, target.settings);\n const outputFile = failingAsApi(target.name, () => {\n const file = outputFileOf(run, { source: target.name, output }, target.configRoot);\n ensureOutputIsNotSchema(run, file, files.schemas);\n ensureOutputIsOwn(run, file, otherOutputs(files, target.name));\n return file;\n });\n const source = resolveLocationUrl(target.root, target.configRoot);\n const options = apiOptions(run, apiRun, target);\n try {\n const types = await run.deps.generate(source, options, target.name);\n return { name: target.name, outputFile, types };\n } catch (error) {\n throw new ApiFailure(target.name, error);\n }\n}\n\n/**\n * The result of a step of one API, whose failure is reported with the API's name. Errors of an\n * API's settings name the API in their own message and are not wrapped.\n */\nfunction failingAsApi<T>(apiName: string, step: () => T): T {\n try {\n return step();\n } catch (error) {\n throw new ApiFailure(apiName, error);\n }\n}\n\n/**\n * The schema and the output of every API, and the config file itself. A location that is no\n * text or no valid URL is left out: it is no file that an output could be, and its own API fails\n * on it, not every API.\n */\nfunction configFilesOf(run: CliRun, redocly: RedoclyConfig, apis: readonly RedoclyApi[]) {\n const configRoot = configRootOf(redocly, run.deps.cwd);\n const roots = apis.flatMap(({ name, root }) => {\n const location = typeof root === \"string\" ? parseLocationUrl(root, configRoot) : undefined;\n return location ? [{ name: `schema ${root} of API ${name}`, location }] : [];\n });\n const outputs = new Map<string, URL>();\n for (const api of apis) {\n const output = isSettingsMap(api.settings) ? api.settings[OUTPUT_SETTING] : undefined;\n const location = typeof output === \"string\" ? parseLocationUrl(output, configRoot) : undefined;\n if (location) {\n outputs.set(api.name, location);\n }\n }\n const schemas = [...roots, ...redoclyConfigFiles(run, redocly)];\n return { configRoot, files: { schemas, outputs } satisfies ConfigFiles };\n}\n\n/** What `task` gives for each item, run one after another: the next starts when one settles. */\nasync function settledInTurn<T, R>(\n items: readonly T[],\n task: (item: T) => Promise<R>,\n): Promise<PromiseSettledResult<R>[]> {\n const results: PromiseSettledResult<R>[] = [];\n for (const item of items) {\n try {\n results.push({ status: \"fulfilled\", value: await task(item) });\n } catch (reason) {\n results.push({ status: \"rejected\", reason });\n }\n }\n return results;\n}\n\n/**\n * Generate every API of the config, one after another in the order of the config, then write\n * them. One at a time, so a run takes the memory of its largest API, not the sum of all of them,\n * and the work of one API cannot hold up the fetches of another until their timeout ends them.\n * Nothing is written until every API is read and every output is claimed, so no output can\n * replace a file that another API still reads; an output that is a file any API read (a `$ref`'d\n * schema) fails with `CLI_OUTPUT_IS_INPUT`. Every API is generated or checked even when another\n * fails, so `--check` reports a stale output wherever it is; the failures are returned in the\n * order of the config.\n */\nexport async function generateRedoclyApis(run: CliRun, redocly: RedoclyConfig): Promise<unknown[]> {\n const apis = redoclyApisOf(redocly);\n const { configRoot, files } = configFilesOf(run, redocly, apis);\n const apiRun = { redocly, files, refLimits: refLimitOptions(run.args, run.deps.cwd) };\n const results = await settledInTurn(apis, (api) =>\n generateApi(run, apiRun, apiTarget(api, configRoot)),\n );\n const generated = results.flatMap((result) =>\n result.status === \"fulfilled\" ? [result.value] : [],\n );\n const readFiles = generated.flatMap(({ name, types }) => filesReadBy(run, types, `API ${name}`));\n const writeFailures = writeGeneratedApis(run, generated, readFiles);\n return results.flatMap((result) =>\n result.status === \"rejected\" ? [result.reason] : (writeFailures.get(result.value.name) ?? []),\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ 'use strict';
2
+
3
+ const scule = require('scule');
4
+ const cliErrors = require('./cli-errors.cjs');
5
+ const cliFlagNames = require('./cli-flag-names.cjs');
6
+
7
+ const REMOVED_FLAGS = [
8
+ ["-ap", `The -ap alias has been deprecated. Use "--additional-properties" instead.`],
9
+ ["--immutable-types", `The --immutable-types flag has been renamed to "--immutable".`],
10
+ [
11
+ "--support-array-length",
12
+ `The --support-array-length flag has been renamed to "--array-length".`
13
+ ],
14
+ ["-it", `The -it alias has been deprecated. Use "--immutable" instead.`],
15
+ ["--redoc", `The --redoc config flag has been renamed to "--redocly" (or -c as shorthand).`]
16
+ ];
17
+ const OPTIONS_END = "--";
18
+ const VALUE_SEPARATOR = "=";
19
+ const BOOLEAN_VALUES = /* @__PURE__ */ new Set(["true", "false"]);
20
+ const LETTER = /^[a-z]$/i;
21
+ function writtenFlags(argv) {
22
+ const end = argv.indexOf(OPTIONS_END);
23
+ return (end === -1 ? argv : argv.slice(0, end)).filter((arg) => arg.startsWith(cliFlagNames.SHORT_PREFIX) && arg !== cliFlagNames.SHORT_PREFIX).map((arg) => {
24
+ const at = arg.indexOf(VALUE_SEPARATOR);
25
+ return at === -1 ? { name: arg, value: void 0 } : { name: arg.slice(0, at), value: arg.slice(at + 1) };
26
+ });
27
+ }
28
+ function canonicalFlagName(name) {
29
+ if (!name.startsWith(cliFlagNames.LONG_PREFIX)) {
30
+ return name;
31
+ }
32
+ const bare = name.startsWith(cliFlagNames.NEGATION_PREFIX) ? name.slice(cliFlagNames.NEGATION_PREFIX.length) : name.slice(cliFlagNames.LONG_PREFIX.length);
33
+ return `${cliFlagNames.LONG_PREFIX}${scule.kebabCase(bare)}`;
34
+ }
35
+ function rejectRemovedFlags(flags) {
36
+ const names = new Set(flags.map(({ name }) => canonicalFlagName(name)));
37
+ for (const [flag, message] of REMOVED_FLAGS) {
38
+ if (names.has(flag)) {
39
+ throw cliErrors.cliError("CLI_FLAG_REMOVED", message);
40
+ }
41
+ }
42
+ }
43
+ function rejectInvalidBooleans(flags) {
44
+ for (const { name, value } of flags) {
45
+ const negated = name.startsWith(cliFlagNames.NEGATION_PREFIX) ? `${cliFlagNames.LONG_PREFIX}${name.slice(cliFlagNames.NEGATION_PREFIX.length)}` : void 0;
46
+ const isNegatedWithValue = negated !== void 0 && cliFlagNames.BOOLEAN_FLAG_NAMES.has(negated);
47
+ const isInvalid = cliFlagNames.BOOLEAN_FLAG_NAMES.has(name) && !BOOLEAN_VALUES.has(value ?? "true");
48
+ if (value !== void 0 && (isNegatedWithValue || isInvalid)) {
49
+ throw cliErrors.cliError(
50
+ "CLI_FLAG_INVALID",
51
+ `${name}=${value}: a boolean flag takes no value, or =true or =false.`
52
+ );
53
+ }
54
+ }
55
+ }
56
+ function rejectNegatedValueFlags(flags) {
57
+ for (const { name } of flags) {
58
+ if (name.startsWith(cliFlagNames.NEGATION_PREFIX) && cliFlagNames.VALUE_FLAG_NAMES.has(canonicalFlagName(name))) {
59
+ throw cliErrors.cliError(
60
+ "CLI_FLAG_INVALID",
61
+ `${name}: a flag that takes a value has no --no- form. Leave the flag out instead.`
62
+ );
63
+ }
64
+ }
65
+ }
66
+ function unknownNamesOf({ name }) {
67
+ if (name.startsWith(cliFlagNames.LONG_PREFIX)) {
68
+ return cliFlagNames.KNOWN_LONG_FLAG_NAMES.has(canonicalFlagName(name)) ? [] : [name.slice(cliFlagNames.LONG_PREFIX.length)];
69
+ }
70
+ return [...name.slice(cliFlagNames.SHORT_PREFIX.length)].filter(
71
+ (letter) => LETTER.test(letter) && !cliFlagNames.KNOWN_SHORT_FLAGS.has(letter)
72
+ );
73
+ }
74
+ function unknownFlagNames(flags) {
75
+ return [...new Set(flags.flatMap(unknownNamesOf))];
76
+ }
77
+
78
+ exports.rejectInvalidBooleans = rejectInvalidBooleans;
79
+ exports.rejectNegatedValueFlags = rejectNegatedValueFlags;
80
+ exports.rejectRemovedFlags = rejectRemovedFlags;
81
+ exports.unknownFlagNames = unknownFlagNames;
82
+ exports.writtenFlags = writtenFlags;
83
+ //# sourceMappingURL=written-flags.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"written-flags.cjs","sources":["../../src/cli/written-flags.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport { cliError } from \"./cli-errors.js\";\nimport {\n BOOLEAN_FLAG_NAMES,\n KNOWN_LONG_FLAG_NAMES,\n KNOWN_SHORT_FLAGS,\n LONG_PREFIX,\n NEGATION_PREFIX,\n SHORT_PREFIX,\n VALUE_FLAG_NAMES,\n} from \"./cli-flag-names.js\";\n\n/**\n * Checks of the flags as the user wrote them, before yargs-parser reads them: yargs-parser accepts\n * any spelling and value, so what it cannot tell apart is checked here.\n */\n\n/** Flags of older versions that were removed or renamed, with the message for each. */\nconst REMOVED_FLAGS: readonly (readonly [string, string])[] = [\n [\"-ap\", `The -ap alias has been deprecated. Use \"--additional-properties\" instead.`],\n [\"--immutable-types\", `The --immutable-types flag has been renamed to \"--immutable\".`],\n [\n \"--support-array-length\",\n `The --support-array-length flag has been renamed to \"--array-length\".`,\n ],\n [\"-it\", `The -it alias has been deprecated. Use \"--immutable\" instead.`],\n [\"--redoc\", `The --redoc config flag has been renamed to \"--redocly\" (or -c as shorthand).`],\n];\n\nconst OPTIONS_END = \"--\";\nconst VALUE_SEPARATOR = \"=\";\nconst BOOLEAN_VALUES: ReadonlySet<string> = new Set([\"true\", \"false\"]);\nconst LETTER = /^[a-z]$/i;\n\n/** A flag as written before `--`: its name (`--redoc`, `-o`) and the text after `=`, if any. */\nexport interface WrittenFlag {\n readonly name: string;\n readonly value: string | undefined;\n}\n\nexport function writtenFlags(argv: readonly string[]): WrittenFlag[] {\n const end = argv.indexOf(OPTIONS_END);\n return (end === -1 ? argv : argv.slice(0, end))\n .filter((arg) => arg.startsWith(SHORT_PREFIX) && arg !== SHORT_PREFIX)\n .map((arg) => {\n const at = arg.indexOf(VALUE_SEPARATOR);\n return at === -1\n ? { name: arg, value: undefined }\n : { name: arg.slice(0, at), value: arg.slice(at + 1) };\n });\n}\n\n/**\n * A long flag as yargs-parser reads it: in kebab-case and without `--no-`, so `--immutableTypes`\n * and `--no-immutable-types` are `--immutable-types`. A short flag stays as written.\n */\nfunction canonicalFlagName(name: string): string {\n if (!name.startsWith(LONG_PREFIX)) {\n return name;\n }\n const bare = name.startsWith(NEGATION_PREFIX)\n ? name.slice(NEGATION_PREFIX.length)\n : name.slice(LONG_PREFIX.length);\n return `${LONG_PREFIX}${kebabCase(bare)}`;\n}\n\n/** An old flag fails by its name in any spelling, also with a value (`--redoc=redocly.yaml`). */\nexport function rejectRemovedFlags(flags: readonly WrittenFlag[]): void {\n const names = new Set(flags.map(({ name }) => canonicalFlagName(name)));\n for (const [flag, message] of REMOVED_FLAGS) {\n if (names.has(flag)) {\n throw cliError(\"CLI_FLAG_REMOVED\", message);\n }\n }\n}\n\n/**\n * A boolean flag takes `=true` or `=false`, and its `--no-` form takes no value. yargs-parser read\n * any other value as false (`--enum=1`, `--alphabetize=yes`), which turned the option off.\n */\nexport function rejectInvalidBooleans(flags: readonly WrittenFlag[]): void {\n for (const { name, value } of flags) {\n const negated = name.startsWith(NEGATION_PREFIX)\n ? `${LONG_PREFIX}${name.slice(NEGATION_PREFIX.length)}`\n : undefined;\n const isNegatedWithValue = negated !== undefined && BOOLEAN_FLAG_NAMES.has(negated);\n const isInvalid = BOOLEAN_FLAG_NAMES.has(name) && !BOOLEAN_VALUES.has(value ?? \"true\");\n if (value !== undefined && (isNegatedWithValue || isInvalid)) {\n throw cliError(\n \"CLI_FLAG_INVALID\",\n `${name}=${value}: a boolean flag takes no value, or =true or =false.`,\n );\n }\n }\n}\n\n/**\n * A flag that takes a value has no `--no-` form: yargs-parser gave it the value false, which the\n * CLI read as the text \"false\" (`--no-output` wrote a file named `false`).\n */\nexport function rejectNegatedValueFlags(flags: readonly WrittenFlag[]): void {\n for (const { name } of flags) {\n if (name.startsWith(NEGATION_PREFIX) && VALUE_FLAG_NAMES.has(canonicalFlagName(name))) {\n throw cliError(\n \"CLI_FLAG_INVALID\",\n `${name}: a flag that takes a value has no --no- form. Leave the flag out instead.`,\n );\n }\n }\n}\n\n/** The bare names of the unknown flags in a written long flag or a group of short flags. */\nfunction unknownNamesOf({ name }: WrittenFlag): string[] {\n if (name.startsWith(LONG_PREFIX)) {\n return KNOWN_LONG_FLAG_NAMES.has(canonicalFlagName(name))\n ? []\n : [name.slice(LONG_PREFIX.length)];\n }\n return [...name.slice(SHORT_PREFIX.length)].filter(\n (letter) => LETTER.test(letter) && !KNOWN_SHORT_FLAGS.has(letter),\n );\n}\n\n/**\n * The unknown flags, to declare as boolean: yargs-parser gives an undeclared flag the next\n * argument as its value, so `--alphabetise api.yaml` took the schema path and read stdin. An\n * unknown flag is ignored, so it takes a value only as `--flag=value`.\n */\nexport function unknownFlagNames(flags: readonly WrittenFlag[]): string[] {\n return [...new Set(flags.flatMap(unknownNamesOf))];\n}\n"],"names":["SHORT_PREFIX","LONG_PREFIX","NEGATION_PREFIX","kebabCase","cliError","BOOLEAN_FLAG_NAMES","VALUE_FLAG_NAMES","KNOWN_LONG_FLAG_NAMES","KNOWN_SHORT_FLAGS"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { kebabCase } from 'scule';
2
+ import { cliError } from './cli-errors.mjs';
3
+ import { SHORT_PREFIX, NEGATION_PREFIX, LONG_PREFIX, BOOLEAN_FLAG_NAMES, VALUE_FLAG_NAMES, KNOWN_LONG_FLAG_NAMES, KNOWN_SHORT_FLAGS } from './cli-flag-names.mjs';
4
+
5
+ const REMOVED_FLAGS = [
6
+ ["-ap", `The -ap alias has been deprecated. Use "--additional-properties" instead.`],
7
+ ["--immutable-types", `The --immutable-types flag has been renamed to "--immutable".`],
8
+ [
9
+ "--support-array-length",
10
+ `The --support-array-length flag has been renamed to "--array-length".`
11
+ ],
12
+ ["-it", `The -it alias has been deprecated. Use "--immutable" instead.`],
13
+ ["--redoc", `The --redoc config flag has been renamed to "--redocly" (or -c as shorthand).`]
14
+ ];
15
+ const OPTIONS_END = "--";
16
+ const VALUE_SEPARATOR = "=";
17
+ const BOOLEAN_VALUES = /* @__PURE__ */ new Set(["true", "false"]);
18
+ const LETTER = /^[a-z]$/i;
19
+ function writtenFlags(argv) {
20
+ const end = argv.indexOf(OPTIONS_END);
21
+ return (end === -1 ? argv : argv.slice(0, end)).filter((arg) => arg.startsWith(SHORT_PREFIX) && arg !== SHORT_PREFIX).map((arg) => {
22
+ const at = arg.indexOf(VALUE_SEPARATOR);
23
+ return at === -1 ? { name: arg, value: void 0 } : { name: arg.slice(0, at), value: arg.slice(at + 1) };
24
+ });
25
+ }
26
+ function canonicalFlagName(name) {
27
+ if (!name.startsWith(LONG_PREFIX)) {
28
+ return name;
29
+ }
30
+ const bare = name.startsWith(NEGATION_PREFIX) ? name.slice(NEGATION_PREFIX.length) : name.slice(LONG_PREFIX.length);
31
+ return `${LONG_PREFIX}${kebabCase(bare)}`;
32
+ }
33
+ function rejectRemovedFlags(flags) {
34
+ const names = new Set(flags.map(({ name }) => canonicalFlagName(name)));
35
+ for (const [flag, message] of REMOVED_FLAGS) {
36
+ if (names.has(flag)) {
37
+ throw cliError("CLI_FLAG_REMOVED", message);
38
+ }
39
+ }
40
+ }
41
+ function rejectInvalidBooleans(flags) {
42
+ for (const { name, value } of flags) {
43
+ const negated = name.startsWith(NEGATION_PREFIX) ? `${LONG_PREFIX}${name.slice(NEGATION_PREFIX.length)}` : void 0;
44
+ const isNegatedWithValue = negated !== void 0 && BOOLEAN_FLAG_NAMES.has(negated);
45
+ const isInvalid = BOOLEAN_FLAG_NAMES.has(name) && !BOOLEAN_VALUES.has(value ?? "true");
46
+ if (value !== void 0 && (isNegatedWithValue || isInvalid)) {
47
+ throw cliError(
48
+ "CLI_FLAG_INVALID",
49
+ `${name}=${value}: a boolean flag takes no value, or =true or =false.`
50
+ );
51
+ }
52
+ }
53
+ }
54
+ function rejectNegatedValueFlags(flags) {
55
+ for (const { name } of flags) {
56
+ if (name.startsWith(NEGATION_PREFIX) && VALUE_FLAG_NAMES.has(canonicalFlagName(name))) {
57
+ throw cliError(
58
+ "CLI_FLAG_INVALID",
59
+ `${name}: a flag that takes a value has no --no- form. Leave the flag out instead.`
60
+ );
61
+ }
62
+ }
63
+ }
64
+ function unknownNamesOf({ name }) {
65
+ if (name.startsWith(LONG_PREFIX)) {
66
+ return KNOWN_LONG_FLAG_NAMES.has(canonicalFlagName(name)) ? [] : [name.slice(LONG_PREFIX.length)];
67
+ }
68
+ return [...name.slice(SHORT_PREFIX.length)].filter(
69
+ (letter) => LETTER.test(letter) && !KNOWN_SHORT_FLAGS.has(letter)
70
+ );
71
+ }
72
+ function unknownFlagNames(flags) {
73
+ return [...new Set(flags.flatMap(unknownNamesOf))];
74
+ }
75
+
76
+ export { rejectInvalidBooleans, rejectNegatedValueFlags, rejectRemovedFlags, unknownFlagNames, writtenFlags };
77
+ //# sourceMappingURL=written-flags.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"written-flags.mjs","sources":["../../src/cli/written-flags.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport { cliError } from \"./cli-errors.js\";\nimport {\n BOOLEAN_FLAG_NAMES,\n KNOWN_LONG_FLAG_NAMES,\n KNOWN_SHORT_FLAGS,\n LONG_PREFIX,\n NEGATION_PREFIX,\n SHORT_PREFIX,\n VALUE_FLAG_NAMES,\n} from \"./cli-flag-names.js\";\n\n/**\n * Checks of the flags as the user wrote them, before yargs-parser reads them: yargs-parser accepts\n * any spelling and value, so what it cannot tell apart is checked here.\n */\n\n/** Flags of older versions that were removed or renamed, with the message for each. */\nconst REMOVED_FLAGS: readonly (readonly [string, string])[] = [\n [\"-ap\", `The -ap alias has been deprecated. Use \"--additional-properties\" instead.`],\n [\"--immutable-types\", `The --immutable-types flag has been renamed to \"--immutable\".`],\n [\n \"--support-array-length\",\n `The --support-array-length flag has been renamed to \"--array-length\".`,\n ],\n [\"-it\", `The -it alias has been deprecated. Use \"--immutable\" instead.`],\n [\"--redoc\", `The --redoc config flag has been renamed to \"--redocly\" (or -c as shorthand).`],\n];\n\nconst OPTIONS_END = \"--\";\nconst VALUE_SEPARATOR = \"=\";\nconst BOOLEAN_VALUES: ReadonlySet<string> = new Set([\"true\", \"false\"]);\nconst LETTER = /^[a-z]$/i;\n\n/** A flag as written before `--`: its name (`--redoc`, `-o`) and the text after `=`, if any. */\nexport interface WrittenFlag {\n readonly name: string;\n readonly value: string | undefined;\n}\n\nexport function writtenFlags(argv: readonly string[]): WrittenFlag[] {\n const end = argv.indexOf(OPTIONS_END);\n return (end === -1 ? argv : argv.slice(0, end))\n .filter((arg) => arg.startsWith(SHORT_PREFIX) && arg !== SHORT_PREFIX)\n .map((arg) => {\n const at = arg.indexOf(VALUE_SEPARATOR);\n return at === -1\n ? { name: arg, value: undefined }\n : { name: arg.slice(0, at), value: arg.slice(at + 1) };\n });\n}\n\n/**\n * A long flag as yargs-parser reads it: in kebab-case and without `--no-`, so `--immutableTypes`\n * and `--no-immutable-types` are `--immutable-types`. A short flag stays as written.\n */\nfunction canonicalFlagName(name: string): string {\n if (!name.startsWith(LONG_PREFIX)) {\n return name;\n }\n const bare = name.startsWith(NEGATION_PREFIX)\n ? name.slice(NEGATION_PREFIX.length)\n : name.slice(LONG_PREFIX.length);\n return `${LONG_PREFIX}${kebabCase(bare)}`;\n}\n\n/** An old flag fails by its name in any spelling, also with a value (`--redoc=redocly.yaml`). */\nexport function rejectRemovedFlags(flags: readonly WrittenFlag[]): void {\n const names = new Set(flags.map(({ name }) => canonicalFlagName(name)));\n for (const [flag, message] of REMOVED_FLAGS) {\n if (names.has(flag)) {\n throw cliError(\"CLI_FLAG_REMOVED\", message);\n }\n }\n}\n\n/**\n * A boolean flag takes `=true` or `=false`, and its `--no-` form takes no value. yargs-parser read\n * any other value as false (`--enum=1`, `--alphabetize=yes`), which turned the option off.\n */\nexport function rejectInvalidBooleans(flags: readonly WrittenFlag[]): void {\n for (const { name, value } of flags) {\n const negated = name.startsWith(NEGATION_PREFIX)\n ? `${LONG_PREFIX}${name.slice(NEGATION_PREFIX.length)}`\n : undefined;\n const isNegatedWithValue = negated !== undefined && BOOLEAN_FLAG_NAMES.has(negated);\n const isInvalid = BOOLEAN_FLAG_NAMES.has(name) && !BOOLEAN_VALUES.has(value ?? \"true\");\n if (value !== undefined && (isNegatedWithValue || isInvalid)) {\n throw cliError(\n \"CLI_FLAG_INVALID\",\n `${name}=${value}: a boolean flag takes no value, or =true or =false.`,\n );\n }\n }\n}\n\n/**\n * A flag that takes a value has no `--no-` form: yargs-parser gave it the value false, which the\n * CLI read as the text \"false\" (`--no-output` wrote a file named `false`).\n */\nexport function rejectNegatedValueFlags(flags: readonly WrittenFlag[]): void {\n for (const { name } of flags) {\n if (name.startsWith(NEGATION_PREFIX) && VALUE_FLAG_NAMES.has(canonicalFlagName(name))) {\n throw cliError(\n \"CLI_FLAG_INVALID\",\n `${name}: a flag that takes a value has no --no- form. Leave the flag out instead.`,\n );\n }\n }\n}\n\n/** The bare names of the unknown flags in a written long flag or a group of short flags. */\nfunction unknownNamesOf({ name }: WrittenFlag): string[] {\n if (name.startsWith(LONG_PREFIX)) {\n return KNOWN_LONG_FLAG_NAMES.has(canonicalFlagName(name))\n ? []\n : [name.slice(LONG_PREFIX.length)];\n }\n return [...name.slice(SHORT_PREFIX.length)].filter(\n (letter) => LETTER.test(letter) && !KNOWN_SHORT_FLAGS.has(letter),\n );\n}\n\n/**\n * The unknown flags, to declare as boolean: yargs-parser gives an undeclared flag the next\n * argument as its value, so `--alphabetise api.yaml` took the schema path and read stdin. An\n * unknown flag is ignored, so it takes a value only as `--flag=value`.\n */\nexport function unknownFlagNames(flags: readonly WrittenFlag[]): string[] {\n return [...new Set(flags.flatMap(unknownNamesOf))];\n}\n"],"names":[],"mappings":";;;;AAkBA,MAAM,aAAA,GAAwD;AAAA,EAC5D,CAAC,OAAO,CAAA,yEAAA,CAA2E,CAAA;AAAA,EACnF,CAAC,qBAAqB,CAAA,6DAAA,CAA+D,CAAA;AAAA,EACrF;AAAA,IACE,wBAAA;AAAA,IACA,CAAA,qEAAA;AAAA,GACF;AAAA,EACA,CAAC,OAAO,CAAA,6DAAA,CAA+D,CAAA;AAAA,EACvE,CAAC,WAAW,CAAA,6EAAA,CAA+E;AAC7F,CAAA;AAEA,MAAM,WAAA,GAAc,IAAA;AACpB,MAAM,eAAA,GAAkB,GAAA;AACxB,MAAM,iCAAsC,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,OAAO,CAAC,CAAA;AACrE,MAAM,MAAA,GAAS,UAAA;AAQR,SAAS,aAAa,IAAA,EAAwC;AACnE,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,WAAW,CAAA;AACpC,EAAA,OAAA,CAAQ,GAAA,KAAQ,KAAK,IAAA,GAAO,IAAA,CAAK,MAAM,CAAA,EAAG,GAAG,GAC1C,MAAA,CAAO,CAAC,QAAQ,GAAA,CAAI,UAAA,CAAW,YAAY,CAAA,IAAK,GAAA,KAAQ,YAAY,CAAA,CACpE,GAAA,CAAI,CAAC,GAAA,KAAQ;AACZ,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,eAAe,CAAA;AACtC,IAAA,OAAO,EAAA,KAAO,KACV,EAAE,IAAA,EAAM,KAAK,KAAA,EAAO,MAAA,KACpB,EAAE,IAAA,EAAM,IAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAG,KAAA,EAAO,IAAI,KAAA,CAAM,EAAA,GAAK,CAAC,CAAA,EAAE;AAAA,EACzD,CAAC,CAAA;AACL;AAMA,SAAS,kBAAkB,IAAA,EAAsB;AAC/C,EAAA,IAAI,CAAC,IAAA,CAAK,UAAA,CAAW,WAAW,CAAA,EAAG;AACjC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAW,eAAe,CAAA,GACxC,IAAA,CAAK,KAAA,CAAM,eAAA,CAAgB,MAAM,CAAA,GACjC,IAAA,CAAK,KAAA,CAAM,YAAY,MAAM,CAAA;AACjC,EAAA,OAAO,CAAA,EAAG,WAAW,CAAA,EAAG,SAAA,CAAU,IAAI,CAAC,CAAA,CAAA;AACzC;AAGO,SAAS,mBAAmB,KAAA,EAAqC;AACtE,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,EAAE,IAAA,EAAK,KAAM,iBAAA,CAAkB,IAAI,CAAC,CAAC,CAAA;AACtE,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,CAAA,IAAK,aAAA,EAAe;AAC3C,IAAA,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AACnB,MAAA,MAAM,QAAA,CAAS,oBAAoB,OAAO,CAAA;AAAA,IAC5C;AAAA,EACF;AACF;AAMO,SAAS,sBAAsB,KAAA,EAAqC;AACzE,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,KAAA,EAAM,IAAK,KAAA,EAAO;AACnC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,UAAA,CAAW,eAAe,CAAA,GAC3C,CAAA,EAAG,WAAW,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,eAAA,CAAgB,MAAM,CAAC,CAAA,CAAA,GACnD,MAAA;AACJ,IAAA,MAAM,kBAAA,GAAqB,OAAA,KAAY,MAAA,IAAa,kBAAA,CAAmB,IAAI,OAAO,CAAA;AAClF,IAAA,MAAM,SAAA,GAAY,mBAAmB,GAAA,CAAI,IAAI,KAAK,CAAC,cAAA,CAAe,GAAA,CAAI,KAAA,IAAS,MAAM,CAAA;AACrF,IAAA,IAAI,KAAA,KAAU,MAAA,KAAc,kBAAA,IAAsB,SAAA,CAAA,EAAY;AAC5D,MAAA,MAAM,QAAA;AAAA,QACJ,kBAAA;AAAA,QACA,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,oDAAA;AAAA,OAClB;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,wBAAwB,KAAA,EAAqC;AAC3E,EAAA,KAAA,MAAW,EAAE,IAAA,EAAK,IAAK,KAAA,EAAO;AAC5B,IAAA,IAAI,IAAA,CAAK,WAAW,eAAe,CAAA,IAAK,iBAAiB,GAAA,CAAI,iBAAA,CAAkB,IAAI,CAAC,CAAA,EAAG;AACrF,MAAA,MAAM,QAAA;AAAA,QACJ,kBAAA;AAAA,QACA,GAAG,IAAI,CAAA,0EAAA;AAAA,OACT;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,cAAA,CAAe,EAAE,IAAA,EAAK,EAA0B;AACvD,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,WAAW,CAAA,EAAG;AAChC,IAAA,OAAO,qBAAA,CAAsB,GAAA,CAAI,iBAAA,CAAkB,IAAI,CAAC,CAAA,GACpD,EAAC,GACD,CAAC,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,MAAM,CAAC,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,CAAC,GAAG,IAAA,CAAK,MAAM,YAAA,CAAa,MAAM,CAAC,CAAA,CAAE,MAAA;AAAA,IAC1C,CAAC,WAAW,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,IAAK,CAAC,iBAAA,CAAkB,GAAA,CAAI,MAAM;AAAA,GAClE;AACF;AAOO,SAAS,iBAAiB,KAAA,EAAyC;AACxE,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,MAAM,OAAA,CAAQ,cAAc,CAAC,CAAC,CAAA;AACnD;;"}
@@ -29,6 +29,7 @@ const ERROR_CODES = {
29
29
  CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING",
30
30
  CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING",
31
31
  CLI_INPUT_MISSING: "CLI_INPUT_MISSING",
32
+ CLI_INPUT_EXTRA: "CLI_INPUT_EXTRA",
32
33
  CLI_OUTPUT_IS_INPUT: "CLI_OUTPUT_IS_INPUT",
33
34
  CLI_OUTPUT_DUPLICATE: "CLI_OUTPUT_DUPLICATE",
34
35
  CLI_OUTPUT_INVALID: "CLI_OUTPUT_INVALID",
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n OPTION_INVALID: \"OPTION_INVALID\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_FLAG_INVALID: \"CLI_FLAG_INVALID\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":["redactUrlSecrets","redactCauseSecrets"],"mappings":";;;;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAUA,2BAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQC,+BAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;;;"}
1
+ {"version":3,"file":"errors.cjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n OPTION_INVALID: \"OPTION_INVALID\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_FLAG_INVALID: \"CLI_FLAG_INVALID\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_INPUT_EXTRA: \"CLI_INPUT_EXTRA\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":["redactUrlSecrets","redactCauseSecrets"],"mappings":";;;;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,eAAA,EAAiB,iBAAA;AAAA,EACjB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAUA,2BAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQC,+BAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;;;"}
@@ -27,6 +27,7 @@ const ERROR_CODES = {
27
27
  CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING",
28
28
  CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING",
29
29
  CLI_INPUT_MISSING: "CLI_INPUT_MISSING",
30
+ CLI_INPUT_EXTRA: "CLI_INPUT_EXTRA",
30
31
  CLI_OUTPUT_IS_INPUT: "CLI_OUTPUT_IS_INPUT",
31
32
  CLI_OUTPUT_DUPLICATE: "CLI_OUTPUT_DUPLICATE",
32
33
  CLI_OUTPUT_INVALID: "CLI_OUTPUT_INVALID",
@@ -1 +1 @@
1
- {"version":3,"file":"errors.mjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n OPTION_INVALID: \"OPTION_INVALID\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_FLAG_INVALID: \"CLI_FLAG_INVALID\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":[],"mappings":";;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;"}
1
+ {"version":3,"file":"errors.mjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n OPTION_INVALID: \"OPTION_INVALID\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_FLAG_INVALID: \"CLI_FLAG_INVALID\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_INPUT_EXTRA: \"CLI_INPUT_EXTRA\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":[],"mappings":";;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,eAAA,EAAiB,iBAAA;AAAA,EACjB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;"}
@@ -1,8 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const URL_SCHEME = /^[a-z][a-z\d+.-]+:/i;
4
+ const READ_SCHEMES = /* @__PURE__ */ new Set(["file:", "http:", "https:"]);
5
+ const AUTHORITY_START = "//";
4
6
  function hasUrlScheme(location) {
5
- return URL_SCHEME.test(location);
7
+ const scheme = URL_SCHEME.exec(location)?.[0];
8
+ if (scheme === void 0) {
9
+ return false;
10
+ }
11
+ return READ_SCHEMES.has(scheme.toLowerCase()) || location.startsWith(AUTHORITY_START, scheme.length);
6
12
  }
7
13
 
8
14
  exports.hasUrlScheme = hasUrlScheme;
@@ -1 +1 @@
1
- {"version":3,"file":"location-text.cjs","sources":["../../src/domain/location-text.ts"],"sourcesContent":["/** How a location the user writes, as a CLI argument or an option string, is read. */\n\n/**\n * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so\n * `C:\\\\specs\\\\api.yaml` stays a path.\n */\nconst URL_SCHEME = /^[a-z][a-z\\d+.-]+:/i;\n\n/** Whether the location is written as a URL, not as a file path. */\nexport function hasUrlScheme(location: string): boolean {\n return URL_SCHEME.test(location);\n}\n"],"names":[],"mappings":";;AAMA,MAAM,UAAA,GAAa,qBAAA;AAGZ,SAAS,aAAa,QAAA,EAA2B;AACtD,EAAA,OAAO,UAAA,CAAW,KAAK,QAAQ,CAAA;AACjC;;"}
1
+ {"version":3,"file":"location-text.cjs","sources":["../../src/domain/location-text.ts"],"sourcesContent":["/** How a location the user writes, as a CLI argument or an option string, is read. */\n\n/**\n * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so\n * `C:\\\\specs\\\\api.yaml` stays a path.\n */\nconst URL_SCHEME = /^[a-z][a-z\\d+.-]+:/i;\n\n/** The schemes the generator reads, which mark a URL also without `//` (`file:api.yaml`). */\nconst READ_SCHEMES: ReadonlySet<string> = new Set([\"file:\", \"http:\", \"https:\"]);\n\nconst AUTHORITY_START = \"//\";\n\n/**\n * Whether the location is written as a URL, not as a file path: a scheme the generator reads, or\n * any scheme followed by `//` (`s3://bucket/api.yaml`). Another text before a colon is part of a\n * file name, as it is on POSIX file systems (`out:v2.ts`, `spec:v2.yaml`).\n */\nexport function hasUrlScheme(location: string): boolean {\n const scheme = URL_SCHEME.exec(location)?.[0];\n if (scheme === undefined) {\n return false;\n }\n return (\n READ_SCHEMES.has(scheme.toLowerCase()) || location.startsWith(AUTHORITY_START, scheme.length)\n );\n}\n"],"names":[],"mappings":";;AAMA,MAAM,UAAA,GAAa,qBAAA;AAGnB,MAAM,+BAAoC,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,OAAA,EAAS,QAAQ,CAAC,CAAA;AAE9E,MAAM,eAAA,GAAkB,IAAA;AAOjB,SAAS,aAAa,QAAA,EAA2B;AACtD,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,QAAQ,IAAI,CAAC,CAAA;AAC5C,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OACE,YAAA,CAAa,GAAA,CAAI,MAAA,CAAO,WAAA,EAAa,KAAK,QAAA,CAAS,UAAA,CAAW,eAAA,EAAiB,MAAA,CAAO,MAAM,CAAA;AAEhG;;"}
@@ -1,6 +1,12 @@
1
1
  const URL_SCHEME = /^[a-z][a-z\d+.-]+:/i;
2
+ const READ_SCHEMES = /* @__PURE__ */ new Set(["file:", "http:", "https:"]);
3
+ const AUTHORITY_START = "//";
2
4
  function hasUrlScheme(location) {
3
- return URL_SCHEME.test(location);
5
+ const scheme = URL_SCHEME.exec(location)?.[0];
6
+ if (scheme === void 0) {
7
+ return false;
8
+ }
9
+ return READ_SCHEMES.has(scheme.toLowerCase()) || location.startsWith(AUTHORITY_START, scheme.length);
4
10
  }
5
11
 
6
12
  export { hasUrlScheme };
@@ -1 +1 @@
1
- {"version":3,"file":"location-text.mjs","sources":["../../src/domain/location-text.ts"],"sourcesContent":["/** How a location the user writes, as a CLI argument or an option string, is read. */\n\n/**\n * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so\n * `C:\\\\specs\\\\api.yaml` stays a path.\n */\nconst URL_SCHEME = /^[a-z][a-z\\d+.-]+:/i;\n\n/** Whether the location is written as a URL, not as a file path. */\nexport function hasUrlScheme(location: string): boolean {\n return URL_SCHEME.test(location);\n}\n"],"names":[],"mappings":"AAMA,MAAM,UAAA,GAAa,qBAAA;AAGZ,SAAS,aAAa,QAAA,EAA2B;AACtD,EAAA,OAAO,UAAA,CAAW,KAAK,QAAQ,CAAA;AACjC;;"}
1
+ {"version":3,"file":"location-text.mjs","sources":["../../src/domain/location-text.ts"],"sourcesContent":["/** How a location the user writes, as a CLI argument or an option string, is read. */\n\n/**\n * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so\n * `C:\\\\specs\\\\api.yaml` stays a path.\n */\nconst URL_SCHEME = /^[a-z][a-z\\d+.-]+:/i;\n\n/** The schemes the generator reads, which mark a URL also without `//` (`file:api.yaml`). */\nconst READ_SCHEMES: ReadonlySet<string> = new Set([\"file:\", \"http:\", \"https:\"]);\n\nconst AUTHORITY_START = \"//\";\n\n/**\n * Whether the location is written as a URL, not as a file path: a scheme the generator reads, or\n * any scheme followed by `//` (`s3://bucket/api.yaml`). Another text before a colon is part of a\n * file name, as it is on POSIX file systems (`out:v2.ts`, `spec:v2.yaml`).\n */\nexport function hasUrlScheme(location: string): boolean {\n const scheme = URL_SCHEME.exec(location)?.[0];\n if (scheme === undefined) {\n return false;\n }\n return (\n READ_SCHEMES.has(scheme.toLowerCase()) || location.startsWith(AUTHORITY_START, scheme.length)\n );\n}\n"],"names":[],"mappings":"AAMA,MAAM,UAAA,GAAa,qBAAA;AAGnB,MAAM,+BAAoC,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,OAAA,EAAS,QAAQ,CAAC,CAAA;AAE9E,MAAM,eAAA,GAAkB,IAAA;AAOjB,SAAS,aAAa,QAAA,EAA2B;AACtD,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,QAAQ,IAAI,CAAC,CAAA;AAC5C,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OACE,YAAA,CAAa,GAAA,CAAI,MAAA,CAAO,WAAA,EAAa,KAAK,QAAA,CAAS,UAAA,CAAW,eAAA,EAAiB,MAAA,CAAO,MAAM,CAAA;AAEhG;;"}
package/dist/index.d.cts CHANGED
@@ -1503,6 +1503,8 @@ type DeprecationCode = (typeof DEPRECATION_CODES)[keyof typeof DEPRECATION_CODES
1503
1503
  * - URL: URL to a YAML or JSON file (local or remote)
1504
1504
  * - Readable: Readable stream of YAML or JSON
1505
1505
  */
1506
+ declare function openapiTS(source: SchemaSource, options?: OpenAPITSOptions): Promise<IrDeclaration[]>;
1507
+ /** Convert an OpenAPI schema to IR declarations, with either form of the options. */
1506
1508
  declare function openapiTS(source: SchemaSource, options?: GeneratorOptions): Promise<IrDeclaration[]>;
1507
1509
 
1508
1510
  /**
@@ -1541,6 +1543,7 @@ declare const ERROR_CODES: {
1541
1543
  readonly CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING";
1542
1544
  readonly CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING";
1543
1545
  readonly CLI_INPUT_MISSING: "CLI_INPUT_MISSING";
1546
+ readonly CLI_INPUT_EXTRA: "CLI_INPUT_EXTRA";
1544
1547
  readonly CLI_OUTPUT_IS_INPUT: "CLI_OUTPUT_IS_INPUT";
1545
1548
  readonly CLI_OUTPUT_DUPLICATE: "CLI_OUTPUT_DUPLICATE";
1546
1549
  readonly CLI_OUTPUT_INVALID: "CLI_OUTPUT_INVALID";
package/dist/index.d.mts CHANGED
@@ -1503,6 +1503,8 @@ type DeprecationCode = (typeof DEPRECATION_CODES)[keyof typeof DEPRECATION_CODES
1503
1503
  * - URL: URL to a YAML or JSON file (local or remote)
1504
1504
  * - Readable: Readable stream of YAML or JSON
1505
1505
  */
1506
+ declare function openapiTS(source: SchemaSource, options?: OpenAPITSOptions): Promise<IrDeclaration[]>;
1507
+ /** Convert an OpenAPI schema to IR declarations, with either form of the options. */
1506
1508
  declare function openapiTS(source: SchemaSource, options?: GeneratorOptions): Promise<IrDeclaration[]>;
1507
1509
 
1508
1510
  /**
@@ -1541,6 +1543,7 @@ declare const ERROR_CODES: {
1541
1543
  readonly CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING";
1542
1544
  readonly CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING";
1543
1545
  readonly CLI_INPUT_MISSING: "CLI_INPUT_MISSING";
1546
+ readonly CLI_INPUT_EXTRA: "CLI_INPUT_EXTRA";
1544
1547
  readonly CLI_OUTPUT_IS_INPUT: "CLI_OUTPUT_IS_INPUT";
1545
1548
  readonly CLI_OUTPUT_DUPLICATE: "CLI_OUTPUT_DUPLICATE";
1546
1549
  readonly CLI_OUTPUT_INVALID: "CLI_OUTPUT_INVALID";
package/dist/index.d.ts CHANGED
@@ -1503,6 +1503,8 @@ type DeprecationCode = (typeof DEPRECATION_CODES)[keyof typeof DEPRECATION_CODES
1503
1503
  * - URL: URL to a YAML or JSON file (local or remote)
1504
1504
  * - Readable: Readable stream of YAML or JSON
1505
1505
  */
1506
+ declare function openapiTS(source: SchemaSource, options?: OpenAPITSOptions): Promise<IrDeclaration[]>;
1507
+ /** Convert an OpenAPI schema to IR declarations, with either form of the options. */
1506
1508
  declare function openapiTS(source: SchemaSource, options?: GeneratorOptions): Promise<IrDeclaration[]>;
1507
1509
 
1508
1510
  /**
@@ -1541,6 +1543,7 @@ declare const ERROR_CODES: {
1541
1543
  readonly CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING";
1542
1544
  readonly CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING";
1543
1545
  readonly CLI_INPUT_MISSING: "CLI_INPUT_MISSING";
1546
+ readonly CLI_INPUT_EXTRA: "CLI_INPUT_EXTRA";
1544
1547
  readonly CLI_OUTPUT_IS_INPUT: "CLI_OUTPUT_IS_INPUT";
1545
1548
  readonly CLI_OUTPUT_DUPLICATE: "CLI_OUTPUT_DUPLICATE";
1546
1549
  readonly CLI_OUTPUT_INVALID: "CLI_OUTPUT_INVALID";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "openapi-typesafe",
3
3
  "description": "Convert OpenAPI 3.0, 3.1 & 3.2 schemas to TypeScript",
4
- "version": "1.0.0-rc.5",
4
+ "version": "1.0.0-rc.6",
5
5
  "author": {
6
6
  "name": "Fedor Chishchin",
7
7
  "url": "https://github.com/fedorello"