openapi-typesafe 1.0.0-rc.1 → 1.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/README.md +12 -5
  2. package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
  3. package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
  4. package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
  5. package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
  6. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +19 -6
  7. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  8. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +18 -5
  9. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  10. package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
  11. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  12. package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
  13. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
  15. package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
  16. package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
  17. package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
  18. package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
  19. package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
  20. package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
  21. package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
  22. package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
  23. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  24. package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
  25. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  26. package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
  27. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
  28. package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
  29. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
  30. package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
  31. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
  32. package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
  33. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
  34. package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
  35. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  36. package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
  37. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  38. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +2 -1
  39. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
  40. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +2 -1
  41. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
  42. package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
  43. package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
  44. package/dist/api/default-ports.cjs +9 -0
  45. package/dist/api/default-ports.cjs.map +1 -1
  46. package/dist/api/default-ports.mjs +8 -1
  47. package/dist/api/default-ports.mjs.map +1 -1
  48. package/dist/api/discriminator-patch.cjs +5 -1
  49. package/dist/api/discriminator-patch.cjs.map +1 -1
  50. package/dist/api/discriminator-patch.mjs +5 -1
  51. package/dist/api/discriminator-patch.mjs.map +1 -1
  52. package/dist/api/document-refs.cjs +15 -12
  53. package/dist/api/document-refs.cjs.map +1 -1
  54. package/dist/api/document-refs.mjs +15 -12
  55. package/dist/api/document-refs.mjs.map +1 -1
  56. package/dist/api/document-run.cjs +4 -2
  57. package/dist/api/document-run.cjs.map +1 -1
  58. package/dist/api/document-run.mjs +4 -2
  59. package/dist/api/document-run.mjs.map +1 -1
  60. package/dist/api/footer-sink.cjs +25 -2
  61. package/dist/api/footer-sink.cjs.map +1 -1
  62. package/dist/api/footer-sink.mjs +25 -2
  63. package/dist/api/footer-sink.mjs.map +1 -1
  64. package/dist/api/legacy-callback-warning.cjs +4 -1
  65. package/dist/api/legacy-callback-warning.cjs.map +1 -1
  66. package/dist/api/legacy-callback-warning.mjs +4 -1
  67. package/dist/api/legacy-callback-warning.mjs.map +1 -1
  68. package/dist/api/legacy-ts-helpers.cjs.map +1 -1
  69. package/dist/api/legacy-ts-helpers.mjs.map +1 -1
  70. package/dist/api/legacy-utils.cjs.map +1 -1
  71. package/dist/api/legacy-utils.mjs.map +1 -1
  72. package/dist/api/openapi-ts.cjs +2 -1
  73. package/dist/api/openapi-ts.cjs.map +1 -1
  74. package/dist/api/openapi-ts.mjs +3 -2
  75. package/dist/api/openapi-ts.mjs.map +1 -1
  76. package/dist/api/transform-context.cjs +1 -1
  77. package/dist/api/transform-context.cjs.map +1 -1
  78. package/dist/api/transform-context.mjs +1 -1
  79. package/dist/api/transform-context.mjs.map +1 -1
  80. package/dist/api/transform-schema.cjs.map +1 -1
  81. package/dist/api/transform-schema.mjs.map +1 -1
  82. package/dist/application/print/type-printer.cjs +2 -1
  83. package/dist/application/print/type-printer.cjs.map +1 -1
  84. package/dist/application/print/type-printer.mjs +2 -1
  85. package/dist/application/print/type-printer.mjs.map +1 -1
  86. package/dist/application/transform/document/parameters.cjs +1 -1
  87. package/dist/application/transform/document/parameters.cjs.map +1 -1
  88. package/dist/application/transform/document/parameters.mjs +1 -1
  89. package/dist/application/transform/document/parameters.mjs.map +1 -1
  90. package/dist/application/transform/document/paths.cjs +1 -1
  91. package/dist/application/transform/document/paths.cjs.map +1 -1
  92. package/dist/application/transform/document/paths.mjs +1 -1
  93. package/dist/application/transform/document/paths.mjs.map +1 -1
  94. package/dist/application/transform/footer/evaluation.cjs +9 -0
  95. package/dist/application/transform/footer/evaluation.cjs.map +1 -1
  96. package/dist/application/transform/footer/evaluation.mjs +8 -1
  97. package/dist/application/transform/footer/evaluation.mjs.map +1 -1
  98. package/dist/application/transform/footer/type-evaluation.cjs +4 -112
  99. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
  100. package/dist/application/transform/footer/type-evaluation.mjs +4 -112
  101. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
  102. package/dist/application/transform/footer/type-indexing.cjs +107 -0
  103. package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
  104. package/dist/application/transform/footer/type-indexing.mjs +105 -0
  105. package/dist/application/transform/footer/type-indexing.mjs.map +1 -0
  106. package/dist/cli/api-settings.cjs +78 -0
  107. package/dist/cli/api-settings.cjs.map +1 -0
  108. package/dist/cli/api-settings.mjs +73 -0
  109. package/dist/cli/api-settings.mjs.map +1 -0
  110. package/dist/cli/cli-arguments.cjs +1 -0
  111. package/dist/cli/cli-arguments.cjs.map +1 -1
  112. package/dist/cli/cli-arguments.mjs +1 -1
  113. package/dist/cli/cli-arguments.mjs.map +1 -1
  114. package/dist/cli/help-text.cjs +3 -3
  115. package/dist/cli/help-text.cjs.map +1 -1
  116. package/dist/cli/help-text.mjs +3 -3
  117. package/dist/cli/help-text.mjs.map +1 -1
  118. package/dist/cli/redocly-apis.cjs +8 -4
  119. package/dist/cli/redocly-apis.cjs.map +1 -1
  120. package/dist/cli/redocly-apis.mjs +7 -3
  121. package/dist/cli/redocly-apis.mjs.map +1 -1
  122. package/dist/cli/run-cli.cjs +5 -1
  123. package/dist/cli/run-cli.cjs.map +1 -1
  124. package/dist/cli/run-cli.mjs +5 -1
  125. package/dist/cli/run-cli.mjs.map +1 -1
  126. package/dist/domain/errors.cjs +4 -1
  127. package/dist/domain/errors.cjs.map +1 -1
  128. package/dist/domain/errors.mjs +4 -1
  129. package/dist/domain/errors.mjs.map +1 -1
  130. package/dist/domain/ir/constructors.cjs +2 -0
  131. package/dist/domain/ir/constructors.cjs.map +1 -1
  132. package/dist/domain/ir/constructors.mjs +2 -1
  133. package/dist/domain/ir/constructors.mjs.map +1 -1
  134. package/dist/domain/openapi/path-templates.cjs +1 -1
  135. package/dist/domain/openapi/path-templates.cjs.map +1 -1
  136. package/dist/domain/openapi/path-templates.mjs +1 -1
  137. package/dist/domain/openapi/path-templates.mjs.map +1 -1
  138. package/dist/domain/url-credentials.cjs +10 -0
  139. package/dist/domain/url-credentials.cjs.map +1 -0
  140. package/dist/domain/url-credentials.mjs +8 -0
  141. package/dist/domain/url-credentials.mjs.map +1 -0
  142. package/dist/domain/warnings.cjs +9 -1
  143. package/dist/domain/warnings.cjs.map +1 -1
  144. package/dist/domain/warnings.mjs +9 -1
  145. package/dist/domain/warnings.mjs.map +1 -1
  146. package/dist/index.cjs +2 -0
  147. package/dist/index.cjs.map +1 -1
  148. package/dist/index.d.cts +1160 -53
  149. package/dist/index.d.mts +1160 -53
  150. package/dist/index.d.ts +1160 -53
  151. package/dist/index.mjs +1 -0
  152. package/dist/index.mjs.map +1 -1
  153. package/dist/transform/path-item-object.cjs.map +1 -1
  154. package/dist/transform/path-item-object.mjs.map +1 -1
  155. package/package.json +6 -5
  156. package/src/adapters/redocly-loader/configured-headers.ts +65 -0
  157. package/src/adapters/redocly-loader/redocly-schema-loader.ts +22 -7
  158. package/src/adapters/redocly-loader/ref-access.ts +60 -5
  159. package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
  160. package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
  161. package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
  162. package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
  163. package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
  164. package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
  165. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +2 -1
  166. package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
  167. package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
  168. package/src/api/default-ports.ts +16 -0
  169. package/src/api/discriminator-patch.ts +7 -2
  170. package/src/api/document-refs.ts +19 -15
  171. package/src/api/document-run.ts +9 -6
  172. package/src/api/footer-sink.ts +34 -2
  173. package/src/api/legacy-callback-warning.ts +7 -3
  174. package/src/api/legacy-ts-helpers.ts +7 -5
  175. package/src/api/legacy-utils.ts +1 -1
  176. package/src/api/openapi-ts.ts +2 -0
  177. package/src/api/run-context.ts +34 -0
  178. package/src/api/transform-context.ts +10 -8
  179. package/src/api/transform-schema.ts +6 -5
  180. package/src/application/print/type-printer.ts +2 -1
  181. package/src/application/transform/document/parameters.ts +2 -1
  182. package/src/application/transform/document/paths.ts +2 -1
  183. package/src/application/transform/footer/evaluation.ts +10 -0
  184. package/src/application/transform/footer/type-evaluation.ts +6 -133
  185. package/src/application/transform/footer/type-indexing.ts +152 -0
  186. package/src/cli/api-settings.ts +109 -0
  187. package/src/cli/cli-arguments.ts +5 -2
  188. package/src/cli/help-text.ts +4 -4
  189. package/src/cli/redocly-apis.ts +13 -7
  190. package/src/cli/run-cli.ts +5 -1
  191. package/src/domain/errors.ts +8 -2
  192. package/src/domain/ir/constructors.ts +3 -0
  193. package/src/domain/ir/nodes.ts +9 -6
  194. package/src/domain/openapi/path-templates.ts +2 -1
  195. package/src/domain/url-credentials.ts +18 -0
  196. package/src/domain/warnings.ts +8 -0
  197. package/src/index.ts +1 -0
  198. package/src/transform/path-item-object.ts +6 -2
  199. package/src/types/generator-options.ts +12 -32
  200. package/src/types/openapi-common.ts +1 -0
  201. package/src/types/openapi-request.ts +3 -0
  202. package/src/types/openapi-schema.ts +2 -0
  203. package/src/types/openapi-security.ts +1 -0
@@ -0,0 +1,105 @@
1
+ import { MISSING, OPAQUE, unionType, isNullish, NEVER, intersectionType, propertyKey } from './evaluation.mjs';
2
+ import { isNeverIntersection, declaredFirst } from './type-rules.mjs';
3
+
4
+ function indexType(types, value, index) {
5
+ const owner = types.expand(value);
6
+ if (owner.kind !== "type") {
7
+ return owner;
8
+ }
9
+ if (types.membersOf(owner).length > 1) {
10
+ return unionIndex(types, owner, index);
11
+ }
12
+ const { type } = owner;
13
+ switch (type.kind) {
14
+ case "object":
15
+ return memberType(types, owner, type.members, index);
16
+ case "intersection":
17
+ return partsIndex(types, owner, type.types, index);
18
+ case "union":
19
+ return unionIndex(types, owner, index);
20
+ case "array":
21
+ return isNumberIndex(index) ? flattened(types, owner, type.element) : builtInIndex(index);
22
+ case "keyword":
23
+ return type.keyword === "never" ? owner : builtInIndex(index);
24
+ default:
25
+ return builtInIndex(index);
26
+ }
27
+ }
28
+ function memberType(types, owner, members, index) {
29
+ const key = indexKey(index);
30
+ const property = members.find(
31
+ (member) => member.kind === "property" && key !== null && propertyKey(member.name) === key
32
+ );
33
+ if (property !== void 0) {
34
+ return flattened(types, owner, property.type);
35
+ }
36
+ const signature = members.find((member) => member.kind === "indexSignature");
37
+ if (signature !== void 0) {
38
+ return flattened(types, owner, signature.type);
39
+ }
40
+ return key === null || isObjectBuiltIn(key) ? OPAQUE : MISSING;
41
+ }
42
+ function partsIndex(types, owner, parts, index) {
43
+ if (isNeverIntersection(types, owner, parts)) {
44
+ return { ...owner, type: NEVER };
45
+ }
46
+ const found = parts.map((type) => types.index({ ...owner, type }, index));
47
+ if (found.some((part) => part.kind === "opaque")) {
48
+ return OPAQUE;
49
+ }
50
+ const read = parts.map((type, at) => ({ type, found: found[at] }));
51
+ const kept = declaredFirst(types, owner, indexKey(index), read).flatMap(
52
+ (part) => part.kind === "type" ? [part.type] : []
53
+ );
54
+ return kept.length === 0 ? MISSING : { ...owner, type: intersectionType(kept) };
55
+ }
56
+ function unionIndex(types, owner, index) {
57
+ const found = types.membersOf(owner).map((member) => member.kind === "type" ? types.index(member, index) : member);
58
+ if (found.some((member) => member.kind === "missing")) {
59
+ return MISSING;
60
+ }
61
+ if (found.some((member) => member.kind === "opaque")) {
62
+ return OPAQUE;
63
+ }
64
+ return { ...owner, type: unionType(found.map((member) => member.type)) };
65
+ }
66
+ function flattened(types, owner, type) {
67
+ const member = { ...owner, type };
68
+ if (!owner.deep) {
69
+ return types.expand(member);
70
+ }
71
+ const members = types.membersOf(member);
72
+ if (members.some((candidate) => candidate.kind !== "type")) {
73
+ return OPAQUE;
74
+ }
75
+ const present = members.filter((candidate) => !isNullish(candidate.type));
76
+ const elements = present.map((candidate) => arrayElement(candidate.type));
77
+ if (present.length > 0 && elements.every((element) => element !== null)) {
78
+ return types.expand({ ...owner, type: unionType(elements) });
79
+ }
80
+ return { ...owner, type: unionType(present.map((candidate) => candidate.type)) };
81
+ }
82
+ function arrayElement(type) {
83
+ return type.kind === "array" ? type.element : null;
84
+ }
85
+ function indexKey(index) {
86
+ if (index.kind === "stringLiteral") {
87
+ return index.value;
88
+ }
89
+ return index.kind === "numberLiteral" ? String(index.value) : null;
90
+ }
91
+ function isNumberIndex(index) {
92
+ const key = indexKey(index);
93
+ return index.kind === "keyword" && index.keyword === "number" || /^\d+$/.test(key ?? "");
94
+ }
95
+ function isObjectBuiltIn(key) {
96
+ return key in {};
97
+ }
98
+ function builtInIndex(index) {
99
+ const key = indexKey(index);
100
+ const isBuiltIn = key === null || key in String.prototype || key in Array.prototype;
101
+ return isBuiltIn || key in Number.prototype ? OPAQUE : MISSING;
102
+ }
103
+
104
+ export { indexType };
105
+ //# sourceMappingURL=type-indexing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-indexing.mjs","sources":["../../../../src/application/transform/footer/type-indexing.ts"],"sourcesContent":["import type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport {\n type Evaluated,\n type Evaluation,\n intersectionType,\n isNullish,\n MISSING,\n NEVER,\n OPAQUE,\n propertyKey,\n unionType,\n} from \"./evaluation.js\";\nimport { declaredFirst, isNeverIntersection, type TypeExpansion } from \"./type-rules.js\";\n\n/**\n * Indexed access (`T[\"key\"]`, `T[number]`) on the generated types, as TypeScript reads it, for\n * the evaluator of the `--enum-values` check (ADR-027).\n */\n\n/** The part of the evaluator that indexed access uses. */\nexport interface IndexedTypes extends TypeExpansion {\n expand(value: Evaluated): Evaluation;\n index(value: Evaluated, index: IrType): Evaluation;\n}\n\n/** `value[index]` for a string literal, `string` or `number` index. */\nexport function indexType(types: IndexedTypes, value: Evaluated, index: IrType): Evaluation {\n const owner = types.expand(value);\n if (owner.kind !== \"type\") {\n return owner;\n }\n if (types.membersOf(owner).length > 1) {\n return unionIndex(types, owner, index);\n }\n const { type } = owner;\n switch (type.kind) {\n case \"object\":\n return memberType(types, owner, type.members, index);\n case \"intersection\":\n return partsIndex(types, owner, type.types, index);\n case \"union\":\n return unionIndex(types, owner, index);\n case \"array\":\n return isNumberIndex(index) ? flattened(types, owner, type.element) : builtInIndex(index);\n case \"keyword\":\n return type.keyword === \"never\" ? owner : builtInIndex(index);\n default:\n return builtInIndex(index);\n }\n}\n\nfunction memberType(\n types: IndexedTypes,\n owner: Evaluated,\n members: readonly IrMember[],\n index: IrType,\n): Evaluation {\n const key = indexKey(index);\n const property = members.find(\n (member) => member.kind === \"property\" && key !== null && propertyKey(member.name) === key,\n );\n if (property !== undefined) {\n return flattened(types, owner, property.type);\n }\n const signature = members.find((member) => member.kind === \"indexSignature\");\n if (signature !== undefined) {\n return flattened(types, owner, signature.type);\n }\n return key === null || isObjectBuiltIn(key) ? OPAQUE : MISSING;\n}\n\nfunction partsIndex(\n types: IndexedTypes,\n owner: Evaluated,\n parts: readonly IrType[],\n index: IrType,\n): Evaluation {\n if (isNeverIntersection(types, owner, parts)) {\n return { ...owner, type: NEVER };\n }\n const found = parts.map((type) => types.index({ ...owner, type }, index));\n if (found.some((part) => part.kind === \"opaque\")) {\n return OPAQUE;\n }\n const read = parts.map((type, at) => ({ type, found: found[at] as Evaluation }));\n const kept = declaredFirst(types, owner, indexKey(index), read).flatMap((part) =>\n part.kind === \"type\" ? [part.type] : [],\n );\n return kept.length === 0 ? MISSING : { ...owner, type: intersectionType(kept) };\n}\n\nfunction unionIndex(types: IndexedTypes, owner: Evaluated, index: IrType): Evaluation {\n const found = types\n .membersOf(owner)\n .map((member) => (member.kind === \"type\" ? types.index(member, index) : member));\n if (found.some((member) => member.kind === \"missing\")) {\n return MISSING;\n }\n if (found.some((member) => member.kind === \"opaque\")) {\n return OPAQUE;\n }\n return { ...owner, type: unionType((found as Evaluated[]).map((member) => member.type)) };\n}\n\n/**\n * A member read through `FlattenedDeepRequired`: a value that is only arrays (and `undefined` or\n * `null`) is replaced by its elements, anything else loses `undefined` and `null`.\n */\nfunction flattened(types: IndexedTypes, owner: Evaluated, type: IrType): Evaluation {\n const member: Evaluated = { ...owner, type };\n if (!owner.deep) {\n return types.expand(member);\n }\n const members = types.membersOf(member);\n if (members.some((candidate) => candidate.kind !== \"type\")) {\n return OPAQUE;\n }\n const present = (members as Evaluated[]).filter((candidate) => !isNullish(candidate.type));\n const elements = present.map((candidate) => arrayElement(candidate.type));\n if (present.length > 0 && elements.every((element) => element !== null)) {\n return types.expand({ ...owner, type: unionType(elements as IrType[]) });\n }\n return { ...owner, type: unionType(present.map((candidate) => candidate.type)) };\n}\n\n/** The element of an expanded member; expanding already dropped `readonly`. */\nfunction arrayElement(type: IrType): IrType | null {\n return type.kind === \"array\" ? type.element : null;\n}\n\nfunction indexKey(index: IrType): string | null {\n if (index.kind === \"stringLiteral\") {\n return index.value;\n }\n return index.kind === \"numberLiteral\" ? String(index.value) : null;\n}\n\nfunction isNumberIndex(index: IrType): boolean {\n const key = indexKey(index);\n return (index.kind === \"keyword\" && index.keyword === \"number\") || /^\\d+$/.test(key ?? \"\");\n}\n\nfunction isObjectBuiltIn(key: string): boolean {\n return key in {};\n}\n\n/** A key of a primitive or an array: a built-in member is opaque, any other key is missing. */\nfunction builtInIndex(index: IrType): Evaluation {\n const key = indexKey(index);\n const isBuiltIn = key === null || key in String.prototype || key in Array.prototype;\n return isBuiltIn || key in Number.prototype ? OPAQUE : MISSING;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ const scule = require('scule');
4
+ const warnings = require('../domain/warnings.cjs');
5
+ const cliArguments = require('./cli-arguments.cjs');
6
+ const cliErrors = require('./cli-errors.cjs');
7
+ const cliOutput = require('./cli-output.cjs');
8
+
9
+ const OUTPUT_SETTING = "output";
10
+ const FIX_SETTING = "fix";
11
+ const LOCAL_REF_ROOT_SETTING = "localRefRoot";
12
+ const REMOTE_REF_HOSTS_SETTING = "remoteRefHosts";
13
+ const IGNORED_SETTINGS = ["contentNever"];
14
+ const CAMEL_CASE_SETTINGS = [
15
+ OUTPUT_SETTING,
16
+ FIX_SETTING,
17
+ LOCAL_REF_ROOT_SETTING,
18
+ REMOTE_REF_HOSTS_SETTING,
19
+ ...cliArguments.GENERATOR_FLAGS,
20
+ ...IGNORED_SETTINGS
21
+ ];
22
+ const KNOWN_SETTINGS = /* @__PURE__ */ new Set([
23
+ ...CAMEL_CASE_SETTINGS,
24
+ ...CAMEL_CASE_SETTINGS.map((name) => scule.kebabCase(name))
25
+ ]);
26
+ function unknownSettingWarnings(apiName, settings) {
27
+ return Object.keys(settings).filter((key) => !KNOWN_SETTINGS.has(key)).map(
28
+ (key) => warnings.warningText(
29
+ `API ${apiName}: the setting \`${key}\` is not an openapi-typesafe option and is ignored`,
30
+ warnings.WARNING_CODES.CONFIG_SETTING_UNKNOWN
31
+ )
32
+ );
33
+ }
34
+ function settingValue(settings, name) {
35
+ return name in settings ? settings[name] : settings[scule.kebabCase(name)];
36
+ }
37
+ function hasSetting(settings, name) {
38
+ return name in settings || scule.kebabCase(name) in settings;
39
+ }
40
+ function invalidSetting(apiName, name, expected) {
41
+ return cliErrors.cliError(
42
+ "CLI_CONFIG_INVALID",
43
+ `API ${apiName}: \`${scule.kebabCase(name)}\` in x-openapi-ts must be ${expected}`
44
+ );
45
+ }
46
+ function localRefRootOf(apiName, settings, configRoot) {
47
+ if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {
48
+ return {};
49
+ }
50
+ const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? "";
51
+ if (typeof value !== "string") {
52
+ throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, "a directory path");
53
+ }
54
+ return { localRefRoot: cliOutput.resolveLocationUrl(value === "" ? "." : value, configRoot) };
55
+ }
56
+ function remoteRefHostsOf(apiName, settings) {
57
+ if (!hasSetting(settings, REMOTE_REF_HOSTS_SETTING)) {
58
+ return {};
59
+ }
60
+ const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];
61
+ const entries = [value].flat();
62
+ if (entries.some((entry) => typeof entry !== "string")) {
63
+ throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, "a host list");
64
+ }
65
+ return { remoteRefHosts: cliArguments.hostList(entries) ?? [] };
66
+ }
67
+ function apiRefLimitOptions(apiName, settings, configRoot) {
68
+ return {
69
+ ...localRefRootOf(apiName, settings, configRoot),
70
+ ...remoteRefHostsOf(apiName, settings)
71
+ };
72
+ }
73
+
74
+ exports.FIX_SETTING = FIX_SETTING;
75
+ exports.OUTPUT_SETTING = OUTPUT_SETTING;
76
+ exports.apiRefLimitOptions = apiRefLimitOptions;
77
+ exports.unknownSettingWarnings = unknownSettingWarnings;
78
+ //# sourceMappingURL=api-settings.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-settings.cjs","sources":["../../src/cli/api-settings.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport { GENERATOR_FLAGS, hostList } from \"./cli-arguments.js\";\nimport { cliError } from \"./cli-errors.js\";\nimport { resolveLocationUrl } from \"./cli-output.js\";\nimport type { RefLimitOptions } from \"./ref-limits.js\";\n\n/**\n * The settings of one API in `redocly.yaml` (`apis.<name>.x-openapi-ts`). A setting has the name\n * of its CLI flag, in kebab-case or camelCase (ADR-021, decision 1); a setting the CLI does not\n * read gets a warning, as an unknown flag gets a notice.\n */\n\nexport type ApiSettings = Readonly<Record<string, unknown>>;\n\n/** The setting that names the output file. */\nexport const OUTPUT_SETTING = \"output\";\n\n/** The setting that lists the API's output fixes. */\nexport const FIX_SETTING = \"fix\";\n\nconst LOCAL_REF_ROOT_SETTING = \"localRefRoot\";\nconst REMOTE_REF_HOSTS_SETTING = \"remoteRefHosts\";\n\n/** `--content-never` is accepted and has no effect, as on the command line. */\nconst IGNORED_SETTINGS = [\"contentNever\"] as const;\n\nconst CAMEL_CASE_SETTINGS = [\n OUTPUT_SETTING,\n FIX_SETTING,\n LOCAL_REF_ROOT_SETTING,\n REMOTE_REF_HOSTS_SETTING,\n ...GENERATOR_FLAGS,\n ...IGNORED_SETTINGS,\n];\n\nconst KNOWN_SETTINGS = new Set<string>([\n ...CAMEL_CASE_SETTINGS,\n ...CAMEL_CASE_SETTINGS.map((name) => kebabCase(name)),\n]);\n\n/** The warning for each setting of an API that no code reads. */\nexport function unknownSettingWarnings(apiName: string, settings: ApiSettings): string[] {\n return Object.keys(settings)\n .filter((key) => !KNOWN_SETTINGS.has(key))\n .map((key) =>\n warningText(\n `API ${apiName}: the setting \\`${key}\\` is not an openapi-typesafe option and is ignored`,\n WARNING_CODES.CONFIG_SETTING_UNKNOWN,\n ),\n );\n}\n\n/** The value of a setting in camelCase, else in kebab-case; `undefined` when it is absent. */\nfunction settingValue(settings: ApiSettings, name: string): unknown {\n return name in settings ? settings[name] : settings[kebabCase(name)];\n}\n\nfunction hasSetting(settings: ApiSettings, name: string): boolean {\n return name in settings || kebabCase(name) in settings;\n}\n\nfunction invalidSetting(apiName: string, name: string, expected: string): Error {\n return cliError(\n \"CLI_CONFIG_INVALID\",\n `API ${apiName}: \\`${kebabCase(name)}\\` in x-openapi-ts must be ${expected}`,\n );\n}\n\n/** `local-ref-root: dir`, relative to the config file; empty means the config file's directory. */\nfunction localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL): RefLimitOptions {\n if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {\n return {};\n }\n const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? \"\";\n if (typeof value !== \"string\") {\n throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, \"a directory path\");\n }\n return { localRefRoot: resolveLocationUrl(value === \"\" ? \".\" : value, configRoot) };\n}\n\n/** `remote-ref-hosts: [a, b]` or `a,b`; an empty list or value allows no host. */\nfunction remoteRefHostsOf(apiName: string, settings: ApiSettings): RefLimitOptions {\n if (!hasSetting(settings, REMOTE_REF_HOSTS_SETTING)) {\n return {};\n }\n const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];\n const entries = [value].flat();\n if (entries.some((entry) => typeof entry !== \"string\")) {\n throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, \"a host list\");\n }\n return { remoteRefHosts: hostList(entries) ?? [] };\n}\n\n/**\n * The `$ref` limits an API sets (threat model R1, R2). Each one replaces the CLI flag of the same\n * name for this API, as its boolean settings and `fix` do; fails with `CLI_CONFIG_INVALID` for a\n * value of another type.\n */\nexport function apiRefLimitOptions(\n apiName: string,\n settings: ApiSettings,\n configRoot: URL,\n): RefLimitOptions {\n return {\n ...localRefRootOf(apiName, settings, configRoot),\n ...remoteRefHostsOf(apiName, settings),\n };\n}\n"],"names":["GENERATOR_FLAGS","kebabCase","warningText","WARNING_CODES","cliError","resolveLocationUrl","hostList"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { kebabCase } from 'scule';
2
+ import { warningText, WARNING_CODES } from '../domain/warnings.mjs';
3
+ import { GENERATOR_FLAGS, hostList } from './cli-arguments.mjs';
4
+ import { cliError } from './cli-errors.mjs';
5
+ import { resolveLocationUrl } from './cli-output.mjs';
6
+
7
+ const OUTPUT_SETTING = "output";
8
+ const FIX_SETTING = "fix";
9
+ const LOCAL_REF_ROOT_SETTING = "localRefRoot";
10
+ const REMOTE_REF_HOSTS_SETTING = "remoteRefHosts";
11
+ const IGNORED_SETTINGS = ["contentNever"];
12
+ const CAMEL_CASE_SETTINGS = [
13
+ OUTPUT_SETTING,
14
+ FIX_SETTING,
15
+ LOCAL_REF_ROOT_SETTING,
16
+ REMOTE_REF_HOSTS_SETTING,
17
+ ...GENERATOR_FLAGS,
18
+ ...IGNORED_SETTINGS
19
+ ];
20
+ const KNOWN_SETTINGS = /* @__PURE__ */ new Set([
21
+ ...CAMEL_CASE_SETTINGS,
22
+ ...CAMEL_CASE_SETTINGS.map((name) => kebabCase(name))
23
+ ]);
24
+ function unknownSettingWarnings(apiName, settings) {
25
+ return Object.keys(settings).filter((key) => !KNOWN_SETTINGS.has(key)).map(
26
+ (key) => warningText(
27
+ `API ${apiName}: the setting \`${key}\` is not an openapi-typesafe option and is ignored`,
28
+ WARNING_CODES.CONFIG_SETTING_UNKNOWN
29
+ )
30
+ );
31
+ }
32
+ function settingValue(settings, name) {
33
+ return name in settings ? settings[name] : settings[kebabCase(name)];
34
+ }
35
+ function hasSetting(settings, name) {
36
+ return name in settings || kebabCase(name) in settings;
37
+ }
38
+ function invalidSetting(apiName, name, expected) {
39
+ return cliError(
40
+ "CLI_CONFIG_INVALID",
41
+ `API ${apiName}: \`${kebabCase(name)}\` in x-openapi-ts must be ${expected}`
42
+ );
43
+ }
44
+ function localRefRootOf(apiName, settings, configRoot) {
45
+ if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {
46
+ return {};
47
+ }
48
+ const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? "";
49
+ if (typeof value !== "string") {
50
+ throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, "a directory path");
51
+ }
52
+ return { localRefRoot: resolveLocationUrl(value === "" ? "." : value, configRoot) };
53
+ }
54
+ function remoteRefHostsOf(apiName, settings) {
55
+ if (!hasSetting(settings, REMOTE_REF_HOSTS_SETTING)) {
56
+ return {};
57
+ }
58
+ const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];
59
+ const entries = [value].flat();
60
+ if (entries.some((entry) => typeof entry !== "string")) {
61
+ throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, "a host list");
62
+ }
63
+ return { remoteRefHosts: hostList(entries) ?? [] };
64
+ }
65
+ function apiRefLimitOptions(apiName, settings, configRoot) {
66
+ return {
67
+ ...localRefRootOf(apiName, settings, configRoot),
68
+ ...remoteRefHostsOf(apiName, settings)
69
+ };
70
+ }
71
+
72
+ export { FIX_SETTING, OUTPUT_SETTING, apiRefLimitOptions, unknownSettingWarnings };
73
+ //# sourceMappingURL=api-settings.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-settings.mjs","sources":["../../src/cli/api-settings.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\nimport { GENERATOR_FLAGS, hostList } from \"./cli-arguments.js\";\nimport { cliError } from \"./cli-errors.js\";\nimport { resolveLocationUrl } from \"./cli-output.js\";\nimport type { RefLimitOptions } from \"./ref-limits.js\";\n\n/**\n * The settings of one API in `redocly.yaml` (`apis.<name>.x-openapi-ts`). A setting has the name\n * of its CLI flag, in kebab-case or camelCase (ADR-021, decision 1); a setting the CLI does not\n * read gets a warning, as an unknown flag gets a notice.\n */\n\nexport type ApiSettings = Readonly<Record<string, unknown>>;\n\n/** The setting that names the output file. */\nexport const OUTPUT_SETTING = \"output\";\n\n/** The setting that lists the API's output fixes. */\nexport const FIX_SETTING = \"fix\";\n\nconst LOCAL_REF_ROOT_SETTING = \"localRefRoot\";\nconst REMOTE_REF_HOSTS_SETTING = \"remoteRefHosts\";\n\n/** `--content-never` is accepted and has no effect, as on the command line. */\nconst IGNORED_SETTINGS = [\"contentNever\"] as const;\n\nconst CAMEL_CASE_SETTINGS = [\n OUTPUT_SETTING,\n FIX_SETTING,\n LOCAL_REF_ROOT_SETTING,\n REMOTE_REF_HOSTS_SETTING,\n ...GENERATOR_FLAGS,\n ...IGNORED_SETTINGS,\n];\n\nconst KNOWN_SETTINGS = new Set<string>([\n ...CAMEL_CASE_SETTINGS,\n ...CAMEL_CASE_SETTINGS.map((name) => kebabCase(name)),\n]);\n\n/** The warning for each setting of an API that no code reads. */\nexport function unknownSettingWarnings(apiName: string, settings: ApiSettings): string[] {\n return Object.keys(settings)\n .filter((key) => !KNOWN_SETTINGS.has(key))\n .map((key) =>\n warningText(\n `API ${apiName}: the setting \\`${key}\\` is not an openapi-typesafe option and is ignored`,\n WARNING_CODES.CONFIG_SETTING_UNKNOWN,\n ),\n );\n}\n\n/** The value of a setting in camelCase, else in kebab-case; `undefined` when it is absent. */\nfunction settingValue(settings: ApiSettings, name: string): unknown {\n return name in settings ? settings[name] : settings[kebabCase(name)];\n}\n\nfunction hasSetting(settings: ApiSettings, name: string): boolean {\n return name in settings || kebabCase(name) in settings;\n}\n\nfunction invalidSetting(apiName: string, name: string, expected: string): Error {\n return cliError(\n \"CLI_CONFIG_INVALID\",\n `API ${apiName}: \\`${kebabCase(name)}\\` in x-openapi-ts must be ${expected}`,\n );\n}\n\n/** `local-ref-root: dir`, relative to the config file; empty means the config file's directory. */\nfunction localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL): RefLimitOptions {\n if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {\n return {};\n }\n const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? \"\";\n if (typeof value !== \"string\") {\n throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, \"a directory path\");\n }\n return { localRefRoot: resolveLocationUrl(value === \"\" ? \".\" : value, configRoot) };\n}\n\n/** `remote-ref-hosts: [a, b]` or `a,b`; an empty list or value allows no host. */\nfunction remoteRefHostsOf(apiName: string, settings: ApiSettings): RefLimitOptions {\n if (!hasSetting(settings, REMOTE_REF_HOSTS_SETTING)) {\n return {};\n }\n const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];\n const entries = [value].flat();\n if (entries.some((entry) => typeof entry !== \"string\")) {\n throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, \"a host list\");\n }\n return { remoteRefHosts: hostList(entries) ?? [] };\n}\n\n/**\n * The `$ref` limits an API sets (threat model R1, R2). Each one replaces the CLI flag of the same\n * name for this API, as its boolean settings and `fix` do; fails with `CLI_CONFIG_INVALID` for a\n * value of another type.\n */\nexport function apiRefLimitOptions(\n apiName: string,\n settings: ApiSettings,\n configRoot: URL,\n): RefLimitOptions {\n return {\n ...localRefRootOf(apiName, settings, configRoot),\n ...remoteRefHostsOf(apiName, settings),\n };\n}\n"],"names":[],"mappings":"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"}
@@ -140,6 +140,7 @@ function parseCliArguments(argv) {
140
140
  }
141
141
 
142
142
  exports.GENERATOR_FLAGS = GENERATOR_FLAGS;
143
+ exports.hostList = hostList;
143
144
  exports.ineffectiveFlagNotices = ineffectiveFlagNotices;
144
145
  exports.parseCliArguments = parseCliArguments;
145
146
  //# sourceMappingURL=cli-arguments.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-arguments.cjs","sources":["../../src/cli/cli-arguments.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport parser from \"yargs-parser\";\nimport type { OutputFixName } from \"../domain/output-fixes.js\";\nimport { cliError } from \"./cli-errors.js\";\nimport { fixNamesOf } from \"./fix-option.js\";\n\n/** The CLI's arguments, parsed as the original CLI parsed them (yargs-parser). */\n\n/** Boolean flags that become generator options (camelCase; yargs also accepts kebab-case). */\nexport const GENERATOR_FLAGS = [\n \"additionalProperties\",\n \"alphabetize\",\n \"arrayLength\",\n \"binaryAsBlob\",\n \"conditionalEnums\",\n \"dedupeEnums\",\n \"defaultNonNullable\",\n \"emptyObjectsUnknown\",\n \"enum\",\n \"enumValues\",\n \"excludeDeprecated\",\n \"exportType\",\n \"generatePathParams\",\n \"immutable\",\n \"lint\",\n \"makePathsEnum\",\n \"pathParamsAsTypes\",\n \"propertiesRequiredByDefault\",\n \"readWriteMarkers\",\n \"rootTypes\",\n \"rootTypesKeepCasing\",\n \"rootTypesNoSchemaPrefix\",\n] as const;\n\nexport type GeneratorFlag = (typeof GENERATOR_FLAGS)[number];\n\nexport type GeneratorFlags = Readonly<Partial<Record<GeneratorFlag, boolean>>>;\n\n// `contentNever` was a boolean flag of the original CLI that no code reads; it stays in the list\n// so that `--content-never <input>` keeps parsing as a flag and an input.\nconst CAMEL_CASE_BOOLEAN_FLAGS = [...GENERATOR_FLAGS, \"check\", \"contentNever\", \"help\"];\n\n// yargs-parser matches the `boolean` list by the exact spelling of the flag: with camelCase names\n// only, `--root-types schema.yaml` took the path as the flag's value (upstream #2523). Both\n// spellings are listed.\nconst BOOLEAN_FLAGS = [\n ...CAMEL_CASE_BOOLEAN_FLAGS,\n ...CAMEL_CASE_BOOLEAN_FLAGS.map((flag) => kebabCase(flag)),\n];\n\n/** The `$ref` limits as the user wrote them; unset flags are absent. */\nexport interface CliRefLimits {\n readonly localRefRoot?: string;\n readonly remoteRefHosts?: readonly string[];\n}\n\nexport interface CliArguments {\n /** The schema path or URL; none means stdin, or the APIs of the Redocly config. */\n readonly input: string | undefined;\n readonly output: string | undefined;\n readonly redocly: string | undefined;\n readonly isCheck: boolean;\n readonly isHelp: boolean;\n readonly isVersion: boolean;\n readonly generatorFlags: GeneratorFlags;\n readonly refLimits: CliRefLimits;\n /** `--fix`, comma-separated and repeatable (ADR-021); unset when the flag is not given. */\n readonly fix: readonly OutputFixName[] | undefined;\n /** Flags the CLI does not know, as written on the command line (`--bogus`, `-x`). */\n readonly unknownFlags: readonly string[];\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\n/** Flags that only work together with `--root-types`. */\nconst ROOT_TYPES_FLAGS = [\"--root-types-no-schema-prefix\", \"--root-types-keep-casing\"] as const;\n\nfunction rejectRemovedFlags(argv: readonly string[]): void {\n for (const [flag, message] of REMOVED_FLAGS) {\n if (argv.includes(flag)) {\n throw cliError(\"CLI_FLAG_REMOVED\", message);\n }\n }\n}\n\n/** Notices for flags that have no effect in this combination, printed before the run. */\nexport function ineffectiveFlagNotices(argv: readonly string[]): string[] {\n if (argv.includes(\"--root-types\")) {\n return [];\n }\n return ROOT_TYPES_FLAGS.filter((flag) => argv.includes(flag)).map(\n (flag) => `${flag} has no effect without --root-types flag`,\n );\n}\n\nfunction generatorFlagsOf(parsed: parser.Arguments): GeneratorFlags {\n const flags: Partial<Record<GeneratorFlag, boolean>> = {};\n for (const name of GENERATOR_FLAGS) {\n if (typeof parsed[name] === \"boolean\") {\n flags[name] = parsed[name];\n }\n }\n return flags;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return value === undefined ? undefined : String(value);\n}\n\n/** The last value of a flag that may be given more than once. */\nfunction lastString(value: unknown): string | undefined {\n return optionalString(Array.isArray(value) ? value.at(-1) : value);\n}\n\n/** `--remote-ref-hosts a.example,b.example`, repeatable; an empty value allows no host. */\nfunction hostList(value: unknown): string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n return [value]\n .flat()\n .flatMap((entry) => String(entry).split(\",\"))\n .map((host) => host.trim())\n .filter((host) => host !== \"\");\n}\n\nfunction refLimitsOf(parsed: parser.Arguments): CliRefLimits {\n const localRefRoot = lastString(parsed.localRefRoot);\n const remoteRefHosts = hostList(parsed.remoteRefHosts);\n return {\n ...(localRefRoot === undefined ? {} : { localRefRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteRefHosts }),\n };\n}\n\n/** String flags, in both spellings, so that a value such as `8080` is not read as a number. */\nconst STRING_FLAGS = [\n \"output\",\n \"redocly\",\n \"fix\",\n ...[\"localRefRoot\", \"remoteRefHosts\"].flatMap((flag) => [flag, kebabCase(flag)]),\n];\n\nconst ALIASES = { redocly: [\"c\"], exportType: [\"t\"], output: [\"o\"] };\n\n/** Every name yargs-parser can return for a flag this CLI reads. */\nconst KNOWN_FLAGS = new Set<string>([\n ...BOOLEAN_FLAGS,\n ...STRING_FLAGS,\n ...Object.values(ALIASES).flat(),\n \"version\",\n]);\n\n/**\n * Flags that no code reads. The original CLI ignored them silently, so a typo such as\n * `--alphabetise` gave other output with no hint; they still do not fail the run.\n */\nfunction unknownFlagsOf(parsed: parser.Arguments, argv: readonly string[]): string[] {\n const names = Object.keys(parsed)\n .filter((key) => key !== \"_\" && key !== \"--\" && !KNOWN_FLAGS.has(key))\n .map((key) => writtenFlagName(key, argv));\n return [...new Set(names)];\n}\n\n/** The flag as the user wrote it: yargs-parser reads `--no-x` as `x: false`. */\nfunction writtenFlagName(key: string, argv: readonly string[]): string {\n if (key.length === 1) {\n return `-${key}`;\n }\n const negated = `--no-${kebabCase(key)}`;\n const isNegated = argv.some((arg) => arg === negated || arg.startsWith(`${negated}=`));\n return isNegated ? negated : `--${kebabCase(key)}`;\n}\n\n/**\n * Parse the arguments after `node cli.js`. Fails with `CLI_FLAG_REMOVED` for an old flag and with\n * `OPTION_FIX_UNKNOWN` for an unknown `--fix` name.\n */\nexport function parseCliArguments(argv: readonly string[]): CliArguments {\n rejectRemovedFlags(argv);\n const parsed = parser([...argv], {\n boolean: BOOLEAN_FLAGS,\n string: STRING_FLAGS,\n alias: ALIASES,\n });\n return {\n input: optionalString(parsed._[0]),\n output: optionalString(parsed.output),\n redocly: optionalString(parsed.redocly),\n isCheck: parsed.check === true,\n isHelp: \"help\" in parsed,\n isVersion: \"version\" in parsed,\n generatorFlags: generatorFlagsOf(parsed),\n refLimits: refLimitsOf(parsed),\n fix: fixNamesOf(parsed.fix),\n unknownFlags: unknownFlagsOf(parsed, argv),\n };\n}\n"],"names":["kebabCase","cliError","parser","fixNamesOf"],"mappings":";;;;;;;;;;;AASO,MAAM,eAAA,GAAkB;AAAA,EAC7B,sBAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,kBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,qBAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,mBAAA;AAAA,EACA,YAAA;AAAA,EACA,oBAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,mBAAA;AAAA,EACA,6BAAA;AAAA,EACA,kBAAA;AAAA,EACA,WAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF;AAQA,MAAM,2BAA2B,CAAC,GAAG,eAAA,EAAiB,OAAA,EAAS,gBAAgB,MAAM,CAAA;AAKrF,MAAM,aAAA,GAAgB;AAAA,EACpB,GAAG,wBAAA;AAAA,EACH,GAAG,wBAAA,CAAyB,GAAA,CAAI,CAAC,IAAA,KAASA,eAAA,CAAU,IAAI,CAAC;AAC3D,CAAA;AAyBA,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;AAGA,MAAM,gBAAA,GAAmB,CAAC,+BAAA,EAAiC,0BAA0B,CAAA;AAErF,SAAS,mBAAmB,IAAA,EAA+B;AACzD,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,CAAA,IAAK,aAAA,EAAe;AAC3C,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AACvB,MAAA,MAAMC,kBAAA,CAAS,oBAAoB,OAAO,CAAA;AAAA,IAC5C;AAAA,EACF;AACF;AAGO,SAAS,uBAAuB,IAAA,EAAmC;AACxE,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,cAAc,CAAA,EAAG;AACjC,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,OAAO,gBAAA,CAAiB,OAAO,CAAC,IAAA,KAAS,KAAK,QAAA,CAAS,IAAI,CAAC,CAAA,CAAE,GAAA;AAAA,IAC5D,CAAC,IAAA,KAAS,CAAA,EAAG,IAAI,CAAA,wCAAA;AAAA,GACnB;AACF;AAEA,SAAS,iBAAiB,MAAA,EAA0C;AAClE,EAAA,MAAM,QAAiD,EAAC;AACxD,EAAA,KAAA,MAAW,QAAQ,eAAA,EAAiB;AAClC,IAAA,IAAI,OAAO,MAAA,CAAO,IAAI,CAAA,KAAM,SAAA,EAAW;AACrC,MAAA,KAAA,CAAM,IAAI,CAAA,GAAI,MAAA,CAAO,IAAI,CAAA;AAAA,IAC3B;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAe,KAAA,EAAoC;AAC1D,EAAA,OAAO,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,MAAA,CAAO,KAAK,CAAA;AACvD;AAGA,SAAS,WAAW,KAAA,EAAoC;AACtD,EAAA,OAAO,cAAA,CAAe,MAAM,OAAA,CAAQ,KAAK,IAAI,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,GAAI,KAAK,CAAA;AACnE;AAGA,SAAS,SAAS,KAAA,EAAsC;AACtD,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAC,KAAK,CAAA,CACV,IAAA,EAAK,CACL,OAAA,CAAQ,CAAC,KAAA,KAAU,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA,CAC3C,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,CAAA,CACzB,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,KAAS,EAAE,CAAA;AACjC;AAEA,SAAS,YAAY,MAAA,EAAwC;AAC3D,EAAA,MAAM,YAAA,GAAe,UAAA,CAAW,MAAA,CAAO,YAAY,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,MAAA,CAAO,cAAc,CAAA;AACrD,EAAA,OAAO;AAAA,IACL,GAAI,YAAA,KAAiB,MAAA,GAAY,EAAC,GAAI,EAAE,YAAA,EAAa;AAAA,IACrD,GAAI,cAAA,KAAmB,MAAA,GAAY,EAAC,GAAI,EAAE,cAAA;AAAe,GAC3D;AACF;AAGA,MAAM,YAAA,GAAe;AAAA,EACnB,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG,CAAC,cAAA,EAAgB,gBAAgB,CAAA,CAAE,OAAA,CAAQ,CAAC,IAAA,KAAS,CAAC,IAAA,EAAMD,eAAA,CAAU,IAAI,CAAC,CAAC;AACjF,CAAA;AAEA,MAAM,OAAA,GAAU,EAAE,OAAA,EAAS,CAAC,GAAG,CAAA,EAAG,UAAA,EAAY,CAAC,GAAG,CAAA,EAAG,MAAA,EAAQ,CAAC,GAAG,CAAA,EAAE;AAGnE,MAAM,WAAA,uBAAkB,GAAA,CAAY;AAAA,EAClC,GAAG,aAAA;AAAA,EACH,GAAG,YAAA;AAAA,EACH,GAAG,MAAA,CAAO,MAAA,CAAO,OAAO,EAAE,IAAA,EAAK;AAAA,EAC/B;AACF,CAAC,CAAA;AAMD,SAAS,cAAA,CAAe,QAA0B,IAAA,EAAmC;AACnF,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAC7B,OAAO,CAAC,GAAA,KAAQ,GAAA,KAAQ,GAAA,IAAO,GAAA,KAAQ,IAAA,IAAQ,CAAC,WAAA,CAAY,GAAA,CAAI,GAAG,CAAC,CAAA,CACpE,GAAA,CAAI,CAAC,GAAA,KAAQ,eAAA,CAAgB,GAAA,EAAK,IAAI,CAAC,CAAA;AAC1C,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AAC3B;AAGA,SAAS,eAAA,CAAgB,KAAa,IAAA,EAAiC;AACrE,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,OAAO,IAAI,GAAG,CAAA,CAAA;AAAA,EAChB;AACA,EAAA,MAAM,OAAA,GAAU,CAAA,KAAA,EAAQA,eAAA,CAAU,GAAG,CAAC,CAAA,CAAA;AACtC,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,KAAQ,OAAA,IAAW,GAAA,CAAI,UAAA,CAAW,CAAA,EAAG,OAAO,CAAA,CAAA,CAAG,CAAC,CAAA;AACrF,EAAA,OAAO,SAAA,GAAY,OAAA,GAAU,CAAA,EAAA,EAAKA,eAAA,CAAU,GAAG,CAAC,CAAA,CAAA;AAClD;AAMO,SAAS,kBAAkB,IAAA,EAAuC;AACvE,EAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,EAAA,MAAM,MAAA,GAASE,eAAA,CAAO,CAAC,GAAG,IAAI,CAAA,EAAG;AAAA,IAC/B,OAAA,EAAS,aAAA;AAAA,IACT,MAAA,EAAQ,YAAA;AAAA,IACR,KAAA,EAAO;AAAA,GACR,CAAA;AACD,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,cAAA,CAAe,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,IACjC,MAAA,EAAQ,cAAA,CAAe,MAAA,CAAO,MAAM,CAAA;AAAA,IACpC,OAAA,EAAS,cAAA,CAAe,MAAA,CAAO,OAAO,CAAA;AAAA,IACtC,OAAA,EAAS,OAAO,KAAA,KAAU,IAAA;AAAA,IAC1B,QAAQ,MAAA,IAAU,MAAA;AAAA,IAClB,WAAW,SAAA,IAAa,MAAA;AAAA,IACxB,cAAA,EAAgB,iBAAiB,MAAM,CAAA;AAAA,IACvC,SAAA,EAAW,YAAY,MAAM,CAAA;AAAA,IAC7B,GAAA,EAAKC,oBAAA,CAAW,MAAA,CAAO,GAAG,CAAA;AAAA,IAC1B,YAAA,EAAc,cAAA,CAAe,MAAA,EAAQ,IAAI;AAAA,GAC3C;AACF;;;;"}
1
+ {"version":3,"file":"cli-arguments.cjs","sources":["../../src/cli/cli-arguments.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport parser from \"yargs-parser\";\nimport type { OutputFixName } from \"../domain/output-fixes.js\";\nimport { cliError } from \"./cli-errors.js\";\nimport { fixNamesOf } from \"./fix-option.js\";\n\n/** The CLI's arguments, parsed as the original CLI parsed them (yargs-parser). */\n\n/** Boolean flags that become generator options (camelCase; yargs also accepts kebab-case). */\nexport const GENERATOR_FLAGS = [\n \"additionalProperties\",\n \"alphabetize\",\n \"arrayLength\",\n \"binaryAsBlob\",\n \"conditionalEnums\",\n \"dedupeEnums\",\n \"defaultNonNullable\",\n \"emptyObjectsUnknown\",\n \"enum\",\n \"enumValues\",\n \"excludeDeprecated\",\n \"exportType\",\n \"generatePathParams\",\n \"immutable\",\n \"lint\",\n \"makePathsEnum\",\n \"pathParamsAsTypes\",\n \"propertiesRequiredByDefault\",\n \"readWriteMarkers\",\n \"rootTypes\",\n \"rootTypesKeepCasing\",\n \"rootTypesNoSchemaPrefix\",\n] as const;\n\nexport type GeneratorFlag = (typeof GENERATOR_FLAGS)[number];\n\nexport type GeneratorFlags = Readonly<Partial<Record<GeneratorFlag, boolean>>>;\n\n// `contentNever` was a boolean flag of the original CLI that no code reads; it stays in the list\n// so that `--content-never <input>` keeps parsing as a flag and an input.\nconst CAMEL_CASE_BOOLEAN_FLAGS = [...GENERATOR_FLAGS, \"check\", \"contentNever\", \"help\"];\n\n// yargs-parser matches the `boolean` list by the exact spelling of the flag: with camelCase names\n// only, `--root-types schema.yaml` took the path as the flag's value (upstream #2523). Both\n// spellings are listed.\nconst BOOLEAN_FLAGS = [\n ...CAMEL_CASE_BOOLEAN_FLAGS,\n ...CAMEL_CASE_BOOLEAN_FLAGS.map((flag) => kebabCase(flag)),\n];\n\n/** The `$ref` limits as the user wrote them; unset flags are absent. */\nexport interface CliRefLimits {\n readonly localRefRoot?: string;\n readonly remoteRefHosts?: readonly string[];\n}\n\nexport interface CliArguments {\n /** The schema path or URL; none means stdin, or the APIs of the Redocly config. */\n readonly input: string | undefined;\n readonly output: string | undefined;\n readonly redocly: string | undefined;\n readonly isCheck: boolean;\n readonly isHelp: boolean;\n readonly isVersion: boolean;\n readonly generatorFlags: GeneratorFlags;\n readonly refLimits: CliRefLimits;\n /** `--fix`, comma-separated and repeatable (ADR-021); unset when the flag is not given. */\n readonly fix: readonly OutputFixName[] | undefined;\n /** Flags the CLI does not know, as written on the command line (`--bogus`, `-x`). */\n readonly unknownFlags: readonly string[];\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\n/** Flags that only work together with `--root-types`. */\nconst ROOT_TYPES_FLAGS = [\"--root-types-no-schema-prefix\", \"--root-types-keep-casing\"] as const;\n\nfunction rejectRemovedFlags(argv: readonly string[]): void {\n for (const [flag, message] of REMOVED_FLAGS) {\n if (argv.includes(flag)) {\n throw cliError(\"CLI_FLAG_REMOVED\", message);\n }\n }\n}\n\n/** Notices for flags that have no effect in this combination, printed before the run. */\nexport function ineffectiveFlagNotices(argv: readonly string[]): string[] {\n if (argv.includes(\"--root-types\")) {\n return [];\n }\n return ROOT_TYPES_FLAGS.filter((flag) => argv.includes(flag)).map(\n (flag) => `${flag} has no effect without --root-types flag`,\n );\n}\n\nfunction generatorFlagsOf(parsed: parser.Arguments): GeneratorFlags {\n const flags: Partial<Record<GeneratorFlag, boolean>> = {};\n for (const name of GENERATOR_FLAGS) {\n if (typeof parsed[name] === \"boolean\") {\n flags[name] = parsed[name];\n }\n }\n return flags;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return value === undefined ? undefined : String(value);\n}\n\n/** The last value of a flag that may be given more than once. */\nfunction lastString(value: unknown): string | undefined {\n return optionalString(Array.isArray(value) ? value.at(-1) : value);\n}\n\n/**\n * `--remote-ref-hosts a.example,b.example`, repeatable; an empty value allows no host. The\n * `remote-ref-hosts` setting of a `redocly.yaml` API is read the same way.\n */\nexport function hostList(value: unknown): string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n return [value]\n .flat()\n .flatMap((entry) => String(entry).split(\",\"))\n .map((host) => host.trim())\n .filter((host) => host !== \"\");\n}\n\nfunction refLimitsOf(parsed: parser.Arguments): CliRefLimits {\n const localRefRoot = lastString(parsed.localRefRoot);\n const remoteRefHosts = hostList(parsed.remoteRefHosts);\n return {\n ...(localRefRoot === undefined ? {} : { localRefRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteRefHosts }),\n };\n}\n\n/** String flags, in both spellings, so that a value such as `8080` is not read as a number. */\nconst STRING_FLAGS = [\n \"output\",\n \"redocly\",\n \"fix\",\n ...[\"localRefRoot\", \"remoteRefHosts\"].flatMap((flag) => [flag, kebabCase(flag)]),\n];\n\nconst ALIASES = { redocly: [\"c\"], exportType: [\"t\"], output: [\"o\"] };\n\n/** Every name yargs-parser can return for a flag this CLI reads. */\nconst KNOWN_FLAGS = new Set<string>([\n ...BOOLEAN_FLAGS,\n ...STRING_FLAGS,\n ...Object.values(ALIASES).flat(),\n \"version\",\n]);\n\n/**\n * Flags that no code reads. The original CLI ignored them silently, so a typo such as\n * `--alphabetise` gave other output with no hint; they still do not fail the run.\n */\nfunction unknownFlagsOf(parsed: parser.Arguments, argv: readonly string[]): string[] {\n const names = Object.keys(parsed)\n .filter((key) => key !== \"_\" && key !== \"--\" && !KNOWN_FLAGS.has(key))\n .map((key) => writtenFlagName(key, argv));\n return [...new Set(names)];\n}\n\n/** The flag as the user wrote it: yargs-parser reads `--no-x` as `x: false`. */\nfunction writtenFlagName(key: string, argv: readonly string[]): string {\n if (key.length === 1) {\n return `-${key}`;\n }\n const negated = `--no-${kebabCase(key)}`;\n const isNegated = argv.some((arg) => arg === negated || arg.startsWith(`${negated}=`));\n return isNegated ? negated : `--${kebabCase(key)}`;\n}\n\n/**\n * Parse the arguments after `node cli.js`. Fails with `CLI_FLAG_REMOVED` for an old flag and with\n * `OPTION_FIX_UNKNOWN` for an unknown `--fix` name.\n */\nexport function parseCliArguments(argv: readonly string[]): CliArguments {\n rejectRemovedFlags(argv);\n const parsed = parser([...argv], {\n boolean: BOOLEAN_FLAGS,\n string: STRING_FLAGS,\n alias: ALIASES,\n });\n return {\n input: optionalString(parsed._[0]),\n output: optionalString(parsed.output),\n redocly: optionalString(parsed.redocly),\n isCheck: parsed.check === true,\n isHelp: \"help\" in parsed,\n isVersion: \"version\" in parsed,\n generatorFlags: generatorFlagsOf(parsed),\n refLimits: refLimitsOf(parsed),\n fix: fixNamesOf(parsed.fix),\n unknownFlags: unknownFlagsOf(parsed, argv),\n };\n}\n"],"names":["kebabCase","cliError","parser","fixNamesOf"],"mappings":"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"}
@@ -133,5 +133,5 @@ function parseCliArguments(argv) {
133
133
  };
134
134
  }
135
135
 
136
- export { GENERATOR_FLAGS, ineffectiveFlagNotices, parseCliArguments };
136
+ export { GENERATOR_FLAGS, hostList, ineffectiveFlagNotices, parseCliArguments };
137
137
  //# sourceMappingURL=cli-arguments.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-arguments.mjs","sources":["../../src/cli/cli-arguments.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport parser from \"yargs-parser\";\nimport type { OutputFixName } from \"../domain/output-fixes.js\";\nimport { cliError } from \"./cli-errors.js\";\nimport { fixNamesOf } from \"./fix-option.js\";\n\n/** The CLI's arguments, parsed as the original CLI parsed them (yargs-parser). */\n\n/** Boolean flags that become generator options (camelCase; yargs also accepts kebab-case). */\nexport const GENERATOR_FLAGS = [\n \"additionalProperties\",\n \"alphabetize\",\n \"arrayLength\",\n \"binaryAsBlob\",\n \"conditionalEnums\",\n \"dedupeEnums\",\n \"defaultNonNullable\",\n \"emptyObjectsUnknown\",\n \"enum\",\n \"enumValues\",\n \"excludeDeprecated\",\n \"exportType\",\n \"generatePathParams\",\n \"immutable\",\n \"lint\",\n \"makePathsEnum\",\n \"pathParamsAsTypes\",\n \"propertiesRequiredByDefault\",\n \"readWriteMarkers\",\n \"rootTypes\",\n \"rootTypesKeepCasing\",\n \"rootTypesNoSchemaPrefix\",\n] as const;\n\nexport type GeneratorFlag = (typeof GENERATOR_FLAGS)[number];\n\nexport type GeneratorFlags = Readonly<Partial<Record<GeneratorFlag, boolean>>>;\n\n// `contentNever` was a boolean flag of the original CLI that no code reads; it stays in the list\n// so that `--content-never <input>` keeps parsing as a flag and an input.\nconst CAMEL_CASE_BOOLEAN_FLAGS = [...GENERATOR_FLAGS, \"check\", \"contentNever\", \"help\"];\n\n// yargs-parser matches the `boolean` list by the exact spelling of the flag: with camelCase names\n// only, `--root-types schema.yaml` took the path as the flag's value (upstream #2523). Both\n// spellings are listed.\nconst BOOLEAN_FLAGS = [\n ...CAMEL_CASE_BOOLEAN_FLAGS,\n ...CAMEL_CASE_BOOLEAN_FLAGS.map((flag) => kebabCase(flag)),\n];\n\n/** The `$ref` limits as the user wrote them; unset flags are absent. */\nexport interface CliRefLimits {\n readonly localRefRoot?: string;\n readonly remoteRefHosts?: readonly string[];\n}\n\nexport interface CliArguments {\n /** The schema path or URL; none means stdin, or the APIs of the Redocly config. */\n readonly input: string | undefined;\n readonly output: string | undefined;\n readonly redocly: string | undefined;\n readonly isCheck: boolean;\n readonly isHelp: boolean;\n readonly isVersion: boolean;\n readonly generatorFlags: GeneratorFlags;\n readonly refLimits: CliRefLimits;\n /** `--fix`, comma-separated and repeatable (ADR-021); unset when the flag is not given. */\n readonly fix: readonly OutputFixName[] | undefined;\n /** Flags the CLI does not know, as written on the command line (`--bogus`, `-x`). */\n readonly unknownFlags: readonly string[];\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\n/** Flags that only work together with `--root-types`. */\nconst ROOT_TYPES_FLAGS = [\"--root-types-no-schema-prefix\", \"--root-types-keep-casing\"] as const;\n\nfunction rejectRemovedFlags(argv: readonly string[]): void {\n for (const [flag, message] of REMOVED_FLAGS) {\n if (argv.includes(flag)) {\n throw cliError(\"CLI_FLAG_REMOVED\", message);\n }\n }\n}\n\n/** Notices for flags that have no effect in this combination, printed before the run. */\nexport function ineffectiveFlagNotices(argv: readonly string[]): string[] {\n if (argv.includes(\"--root-types\")) {\n return [];\n }\n return ROOT_TYPES_FLAGS.filter((flag) => argv.includes(flag)).map(\n (flag) => `${flag} has no effect without --root-types flag`,\n );\n}\n\nfunction generatorFlagsOf(parsed: parser.Arguments): GeneratorFlags {\n const flags: Partial<Record<GeneratorFlag, boolean>> = {};\n for (const name of GENERATOR_FLAGS) {\n if (typeof parsed[name] === \"boolean\") {\n flags[name] = parsed[name];\n }\n }\n return flags;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return value === undefined ? undefined : String(value);\n}\n\n/** The last value of a flag that may be given more than once. */\nfunction lastString(value: unknown): string | undefined {\n return optionalString(Array.isArray(value) ? value.at(-1) : value);\n}\n\n/** `--remote-ref-hosts a.example,b.example`, repeatable; an empty value allows no host. */\nfunction hostList(value: unknown): string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n return [value]\n .flat()\n .flatMap((entry) => String(entry).split(\",\"))\n .map((host) => host.trim())\n .filter((host) => host !== \"\");\n}\n\nfunction refLimitsOf(parsed: parser.Arguments): CliRefLimits {\n const localRefRoot = lastString(parsed.localRefRoot);\n const remoteRefHosts = hostList(parsed.remoteRefHosts);\n return {\n ...(localRefRoot === undefined ? {} : { localRefRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteRefHosts }),\n };\n}\n\n/** String flags, in both spellings, so that a value such as `8080` is not read as a number. */\nconst STRING_FLAGS = [\n \"output\",\n \"redocly\",\n \"fix\",\n ...[\"localRefRoot\", \"remoteRefHosts\"].flatMap((flag) => [flag, kebabCase(flag)]),\n];\n\nconst ALIASES = { redocly: [\"c\"], exportType: [\"t\"], output: [\"o\"] };\n\n/** Every name yargs-parser can return for a flag this CLI reads. */\nconst KNOWN_FLAGS = new Set<string>([\n ...BOOLEAN_FLAGS,\n ...STRING_FLAGS,\n ...Object.values(ALIASES).flat(),\n \"version\",\n]);\n\n/**\n * Flags that no code reads. The original CLI ignored them silently, so a typo such as\n * `--alphabetise` gave other output with no hint; they still do not fail the run.\n */\nfunction unknownFlagsOf(parsed: parser.Arguments, argv: readonly string[]): string[] {\n const names = Object.keys(parsed)\n .filter((key) => key !== \"_\" && key !== \"--\" && !KNOWN_FLAGS.has(key))\n .map((key) => writtenFlagName(key, argv));\n return [...new Set(names)];\n}\n\n/** The flag as the user wrote it: yargs-parser reads `--no-x` as `x: false`. */\nfunction writtenFlagName(key: string, argv: readonly string[]): string {\n if (key.length === 1) {\n return `-${key}`;\n }\n const negated = `--no-${kebabCase(key)}`;\n const isNegated = argv.some((arg) => arg === negated || arg.startsWith(`${negated}=`));\n return isNegated ? negated : `--${kebabCase(key)}`;\n}\n\n/**\n * Parse the arguments after `node cli.js`. Fails with `CLI_FLAG_REMOVED` for an old flag and with\n * `OPTION_FIX_UNKNOWN` for an unknown `--fix` name.\n */\nexport function parseCliArguments(argv: readonly string[]): CliArguments {\n rejectRemovedFlags(argv);\n const parsed = parser([...argv], {\n boolean: BOOLEAN_FLAGS,\n string: STRING_FLAGS,\n alias: ALIASES,\n });\n return {\n input: optionalString(parsed._[0]),\n output: optionalString(parsed.output),\n redocly: optionalString(parsed.redocly),\n isCheck: parsed.check === true,\n isHelp: \"help\" in parsed,\n isVersion: \"version\" in parsed,\n generatorFlags: generatorFlagsOf(parsed),\n refLimits: refLimitsOf(parsed),\n fix: fixNamesOf(parsed.fix),\n unknownFlags: unknownFlagsOf(parsed, argv),\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-arguments.mjs","sources":["../../src/cli/cli-arguments.ts"],"sourcesContent":["import { kebabCase } from \"scule\";\nimport parser from \"yargs-parser\";\nimport type { OutputFixName } from \"../domain/output-fixes.js\";\nimport { cliError } from \"./cli-errors.js\";\nimport { fixNamesOf } from \"./fix-option.js\";\n\n/** The CLI's arguments, parsed as the original CLI parsed them (yargs-parser). */\n\n/** Boolean flags that become generator options (camelCase; yargs also accepts kebab-case). */\nexport const GENERATOR_FLAGS = [\n \"additionalProperties\",\n \"alphabetize\",\n \"arrayLength\",\n \"binaryAsBlob\",\n \"conditionalEnums\",\n \"dedupeEnums\",\n \"defaultNonNullable\",\n \"emptyObjectsUnknown\",\n \"enum\",\n \"enumValues\",\n \"excludeDeprecated\",\n \"exportType\",\n \"generatePathParams\",\n \"immutable\",\n \"lint\",\n \"makePathsEnum\",\n \"pathParamsAsTypes\",\n \"propertiesRequiredByDefault\",\n \"readWriteMarkers\",\n \"rootTypes\",\n \"rootTypesKeepCasing\",\n \"rootTypesNoSchemaPrefix\",\n] as const;\n\nexport type GeneratorFlag = (typeof GENERATOR_FLAGS)[number];\n\nexport type GeneratorFlags = Readonly<Partial<Record<GeneratorFlag, boolean>>>;\n\n// `contentNever` was a boolean flag of the original CLI that no code reads; it stays in the list\n// so that `--content-never <input>` keeps parsing as a flag and an input.\nconst CAMEL_CASE_BOOLEAN_FLAGS = [...GENERATOR_FLAGS, \"check\", \"contentNever\", \"help\"];\n\n// yargs-parser matches the `boolean` list by the exact spelling of the flag: with camelCase names\n// only, `--root-types schema.yaml` took the path as the flag's value (upstream #2523). Both\n// spellings are listed.\nconst BOOLEAN_FLAGS = [\n ...CAMEL_CASE_BOOLEAN_FLAGS,\n ...CAMEL_CASE_BOOLEAN_FLAGS.map((flag) => kebabCase(flag)),\n];\n\n/** The `$ref` limits as the user wrote them; unset flags are absent. */\nexport interface CliRefLimits {\n readonly localRefRoot?: string;\n readonly remoteRefHosts?: readonly string[];\n}\n\nexport interface CliArguments {\n /** The schema path or URL; none means stdin, or the APIs of the Redocly config. */\n readonly input: string | undefined;\n readonly output: string | undefined;\n readonly redocly: string | undefined;\n readonly isCheck: boolean;\n readonly isHelp: boolean;\n readonly isVersion: boolean;\n readonly generatorFlags: GeneratorFlags;\n readonly refLimits: CliRefLimits;\n /** `--fix`, comma-separated and repeatable (ADR-021); unset when the flag is not given. */\n readonly fix: readonly OutputFixName[] | undefined;\n /** Flags the CLI does not know, as written on the command line (`--bogus`, `-x`). */\n readonly unknownFlags: readonly string[];\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\n/** Flags that only work together with `--root-types`. */\nconst ROOT_TYPES_FLAGS = [\"--root-types-no-schema-prefix\", \"--root-types-keep-casing\"] as const;\n\nfunction rejectRemovedFlags(argv: readonly string[]): void {\n for (const [flag, message] of REMOVED_FLAGS) {\n if (argv.includes(flag)) {\n throw cliError(\"CLI_FLAG_REMOVED\", message);\n }\n }\n}\n\n/** Notices for flags that have no effect in this combination, printed before the run. */\nexport function ineffectiveFlagNotices(argv: readonly string[]): string[] {\n if (argv.includes(\"--root-types\")) {\n return [];\n }\n return ROOT_TYPES_FLAGS.filter((flag) => argv.includes(flag)).map(\n (flag) => `${flag} has no effect without --root-types flag`,\n );\n}\n\nfunction generatorFlagsOf(parsed: parser.Arguments): GeneratorFlags {\n const flags: Partial<Record<GeneratorFlag, boolean>> = {};\n for (const name of GENERATOR_FLAGS) {\n if (typeof parsed[name] === \"boolean\") {\n flags[name] = parsed[name];\n }\n }\n return flags;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return value === undefined ? undefined : String(value);\n}\n\n/** The last value of a flag that may be given more than once. */\nfunction lastString(value: unknown): string | undefined {\n return optionalString(Array.isArray(value) ? value.at(-1) : value);\n}\n\n/**\n * `--remote-ref-hosts a.example,b.example`, repeatable; an empty value allows no host. The\n * `remote-ref-hosts` setting of a `redocly.yaml` API is read the same way.\n */\nexport function hostList(value: unknown): string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n return [value]\n .flat()\n .flatMap((entry) => String(entry).split(\",\"))\n .map((host) => host.trim())\n .filter((host) => host !== \"\");\n}\n\nfunction refLimitsOf(parsed: parser.Arguments): CliRefLimits {\n const localRefRoot = lastString(parsed.localRefRoot);\n const remoteRefHosts = hostList(parsed.remoteRefHosts);\n return {\n ...(localRefRoot === undefined ? {} : { localRefRoot }),\n ...(remoteRefHosts === undefined ? {} : { remoteRefHosts }),\n };\n}\n\n/** String flags, in both spellings, so that a value such as `8080` is not read as a number. */\nconst STRING_FLAGS = [\n \"output\",\n \"redocly\",\n \"fix\",\n ...[\"localRefRoot\", \"remoteRefHosts\"].flatMap((flag) => [flag, kebabCase(flag)]),\n];\n\nconst ALIASES = { redocly: [\"c\"], exportType: [\"t\"], output: [\"o\"] };\n\n/** Every name yargs-parser can return for a flag this CLI reads. */\nconst KNOWN_FLAGS = new Set<string>([\n ...BOOLEAN_FLAGS,\n ...STRING_FLAGS,\n ...Object.values(ALIASES).flat(),\n \"version\",\n]);\n\n/**\n * Flags that no code reads. The original CLI ignored them silently, so a typo such as\n * `--alphabetise` gave other output with no hint; they still do not fail the run.\n */\nfunction unknownFlagsOf(parsed: parser.Arguments, argv: readonly string[]): string[] {\n const names = Object.keys(parsed)\n .filter((key) => key !== \"_\" && key !== \"--\" && !KNOWN_FLAGS.has(key))\n .map((key) => writtenFlagName(key, argv));\n return [...new Set(names)];\n}\n\n/** The flag as the user wrote it: yargs-parser reads `--no-x` as `x: false`. */\nfunction writtenFlagName(key: string, argv: readonly string[]): string {\n if (key.length === 1) {\n return `-${key}`;\n }\n const negated = `--no-${kebabCase(key)}`;\n const isNegated = argv.some((arg) => arg === negated || arg.startsWith(`${negated}=`));\n return isNegated ? negated : `--${kebabCase(key)}`;\n}\n\n/**\n * Parse the arguments after `node cli.js`. Fails with `CLI_FLAG_REMOVED` for an old flag and with\n * `OPTION_FIX_UNKNOWN` for an unknown `--fix` name.\n */\nexport function parseCliArguments(argv: readonly string[]): CliArguments {\n rejectRemovedFlags(argv);\n const parsed = parser([...argv], {\n boolean: BOOLEAN_FLAGS,\n string: STRING_FLAGS,\n alias: ALIASES,\n });\n return {\n input: optionalString(parsed._[0]),\n output: optionalString(parsed.output),\n redocly: optionalString(parsed.redocly),\n isCheck: parsed.check === true,\n isHelp: \"help\" in parsed,\n isVersion: \"version\" in parsed,\n generatorFlags: generatorFlagsOf(parsed),\n refLimits: refLimitsOf(parsed),\n fix: fixNamesOf(parsed.fix),\n unknownFlags: unknownFlagsOf(parsed, argv),\n };\n}\n"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ const HELP_TEXT = [
5
5
  " $ openapi-typesafe [input] [options]",
6
6
  "",
7
7
  "Options",
8
- " --help Display this",
8
+ " --help Show this help",
9
9
  " --version Display the version",
10
10
  " --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)",
11
11
  " --output, -o Specify output file (if not specified in redocly.yaml)",
@@ -18,7 +18,7 @@ const HELP_TEXT = [
18
18
  " --immutable Generate readonly types",
19
19
  " --additional-properties Treat schema objects as if `additionalProperties: true` is set",
20
20
  " --empty-objects-unknown Generate `unknown` instead of `Record<string, never>` for empty objects",
21
- " --default-non-nullable Set to `false` to ignore default values when generating non-nullable types",
21
+ " --default-non-nullable A property with a `default` is required (default: true; =false makes it optional)",
22
22
  " --properties-required-by-default",
23
23
  " Treat schema objects as if `required` is set to all properties by default",
24
24
  " --array-length Generate tuples using array minItems / maxItems",
@@ -28,7 +28,7 @@ const HELP_TEXT = [
28
28
  " --generate-path-params Generate path parameters for all paths where they are undefined by schema",
29
29
  " --alphabetize Sort object keys alphabetically",
30
30
  " --exclude-deprecated Exclude deprecated types",
31
- " --root-types Export schemas types at root level",
31
+ " --root-types Export `components` types as root-level aliases",
32
32
  " --root-types-no-schema-prefix",
33
33
  ' Do not add "Schema" prefix to types at the root level (should only be used with --root-types)',
34
34
  " --root-types-keep-casing Keep casing of root types (should only be used with --root-types)",
@@ -1 +1 @@
1
- {"version":3,"file":"help-text.cjs","sources":["../../src/cli/help-text.ts"],"sourcesContent":["/** The text of `--help`, as in the original CLI; long lines are split only in this source. */\nexport const HELP_TEXT = [\n \"Usage\",\n \" $ openapi-typesafe [input] [options]\",\n \"\",\n \"Options\",\n \" --help Display this\",\n \" --version Display the version\",\n \" --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)\",\n \" --output, -o Specify output file (if not specified in redocly.yaml)\",\n \" --enum Export true TS enums instead of unions\",\n \" --enum-values Export enum values as arrays\",\n \" --conditional-enums Only generate true TS enums when enum\" +\n \" metadata is available (default: false)\",\n \" --dedupe-enums Dedupe enum types when `--enum=true` is set\",\n \" --check Check that the generated types are\" +\n \" up-to-date. (default: false)\",\n \" --export-type, -t Export top-level `type` instead of `interface`\",\n \" --immutable Generate readonly types\",\n \" --additional-properties Treat schema objects as if `additionalProperties: true` is set\",\n \" --empty-objects-unknown Generate `unknown` instead of\" +\n \" `Record<string, never>` for empty objects\",\n \" --default-non-nullable Set to `false` to ignore default values\" +\n \" when generating non-nullable types\",\n \" --properties-required-by-default\",\n \" Treat schema objects as if `required` is\" +\n \" set to all properties by default\",\n \" --array-length Generate tuples using array minItems / maxItems\",\n \" --binary-as-blob Type raw binary strings (format: binary,\" +\n \" contentMediaType) as Blob\",\n \" --fix [names] Turn on output fixes, comma-separated, or\" +\n ' \"all\" (see docs/cli.md#fix)',\n \" --path-params-as-types Convert paths to template literal types\",\n \" --generate-path-params Generate path parameters for all paths where they are\" +\n \" undefined by schema\",\n \" --alphabetize Sort object keys alphabetically\",\n \" --exclude-deprecated Exclude deprecated types\",\n \" --root-types Export schemas types at root level\",\n \" --root-types-no-schema-prefix\",\n ' Do not add \"Schema\" prefix to types at' +\n \" the root level (should only be used with --root-types)\",\n \" --root-types-keep-casing Keep casing of root types (should only be\" +\n \" used with --root-types)\",\n \" --make-paths-enum Generate ApiPaths enum for all paths\",\n \" --read-write-markers Generate $Read/$Write markers for\" +\n \" readOnly/writeOnly properties\",\n \" --no-lint Skip the Redocly lint (bundling errors still fail)\",\n \" --local-ref-root [dir] Load local $ref files only from this directory\",\n \" --remote-ref-hosts [hosts] Load remote $ref documents only from these\" +\n \" comma-separated hosts (empty: none)\",\n \"\",\n].join(\"\\n\");\n"],"names":[],"mappings":";;AACO,MAAM,SAAA,GAAY;AAAA,EACvB,OAAA;AAAA,EACA,wCAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,2CAAA;AAAA,EACA,kDAAA;AAAA,EACA,qFAAA;AAAA,EACA,qFAAA;AAAA,EACA,qEAAA;AAAA,EACA,2DAAA;AAAA,EACA,2GAAA;AAAA,EAEA,0EAAA;AAAA,EACA,8FAAA;AAAA,EAEA,6EAAA;AAAA,EACA,sDAAA;AAAA,EACA,6FAAA;AAAA,EACA,sGAAA;AAAA,EAEA,yGAAA;AAAA,EAEA,oCAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8EAAA;AAAA,EACA,iGAAA;AAAA,EAEA,oGAAA;AAAA,EAEA,sEAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8DAAA;AAAA,EACA,uDAAA;AAAA,EACA,iEAAA;AAAA,EACA,iCAAA;AAAA,EACA,4HAAA;AAAA,EAEA,gGAAA;AAAA,EAEA,mEAAA;AAAA,EACA,8FAAA;AAAA,EAEA,iFAAA;AAAA,EACA,6EAAA;AAAA,EACA,6GAAA;AAAA,EAEA;AACF,CAAA,CAAE,KAAK,IAAI;;"}
1
+ {"version":3,"file":"help-text.cjs","sources":["../../src/cli/help-text.ts"],"sourcesContent":["/** The text of `--help`, as in the original CLI; long lines are split only in this source. */\nexport const HELP_TEXT = [\n \"Usage\",\n \" $ openapi-typesafe [input] [options]\",\n \"\",\n \"Options\",\n \" --help Show this help\",\n \" --version Display the version\",\n \" --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)\",\n \" --output, -o Specify output file (if not specified in redocly.yaml)\",\n \" --enum Export true TS enums instead of unions\",\n \" --enum-values Export enum values as arrays\",\n \" --conditional-enums Only generate true TS enums when enum\" +\n \" metadata is available (default: false)\",\n \" --dedupe-enums Dedupe enum types when `--enum=true` is set\",\n \" --check Check that the generated types are\" +\n \" up-to-date. (default: false)\",\n \" --export-type, -t Export top-level `type` instead of `interface`\",\n \" --immutable Generate readonly types\",\n \" --additional-properties Treat schema objects as if `additionalProperties: true` is set\",\n \" --empty-objects-unknown Generate `unknown` instead of\" +\n \" `Record<string, never>` for empty objects\",\n \" --default-non-nullable A property with a `default` is required\" +\n \" (default: true; =false makes it optional)\",\n \" --properties-required-by-default\",\n \" Treat schema objects as if `required` is\" +\n \" set to all properties by default\",\n \" --array-length Generate tuples using array minItems / maxItems\",\n \" --binary-as-blob Type raw binary strings (format: binary,\" +\n \" contentMediaType) as Blob\",\n \" --fix [names] Turn on output fixes, comma-separated, or\" +\n ' \"all\" (see docs/cli.md#fix)',\n \" --path-params-as-types Convert paths to template literal types\",\n \" --generate-path-params Generate path parameters for all paths where they are\" +\n \" undefined by schema\",\n \" --alphabetize Sort object keys alphabetically\",\n \" --exclude-deprecated Exclude deprecated types\",\n \" --root-types Export `components` types as root-level aliases\",\n \" --root-types-no-schema-prefix\",\n ' Do not add \"Schema\" prefix to types at' +\n \" the root level (should only be used with --root-types)\",\n \" --root-types-keep-casing Keep casing of root types (should only be\" +\n \" used with --root-types)\",\n \" --make-paths-enum Generate ApiPaths enum for all paths\",\n \" --read-write-markers Generate $Read/$Write markers for\" +\n \" readOnly/writeOnly properties\",\n \" --no-lint Skip the Redocly lint (bundling errors still fail)\",\n \" --local-ref-root [dir] Load local $ref files only from this directory\",\n \" --remote-ref-hosts [hosts] Load remote $ref documents only from these\" +\n \" comma-separated hosts (empty: none)\",\n \"\",\n].join(\"\\n\");\n"],"names":[],"mappings":";;AACO,MAAM,SAAA,GAAY;AAAA,EACvB,OAAA;AAAA,EACA,wCAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,6CAAA;AAAA,EACA,kDAAA;AAAA,EACA,qFAAA;AAAA,EACA,qFAAA;AAAA,EACA,qEAAA;AAAA,EACA,2DAAA;AAAA,EACA,2GAAA;AAAA,EAEA,0EAAA;AAAA,EACA,8FAAA;AAAA,EAEA,6EAAA;AAAA,EACA,sDAAA;AAAA,EACA,6FAAA;AAAA,EACA,sGAAA;AAAA,EAEA,gHAAA;AAAA,EAEA,oCAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8EAAA;AAAA,EACA,iGAAA;AAAA,EAEA,oGAAA;AAAA,EAEA,sEAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8DAAA;AAAA,EACA,uDAAA;AAAA,EACA,8EAAA;AAAA,EACA,iCAAA;AAAA,EACA,4HAAA;AAAA,EAEA,gGAAA;AAAA,EAEA,mEAAA;AAAA,EACA,8FAAA;AAAA,EAEA,iFAAA;AAAA,EACA,6EAAA;AAAA,EACA,6GAAA;AAAA,EAEA;AACF,CAAA,CAAE,KAAK,IAAI;;"}
@@ -3,7 +3,7 @@ const HELP_TEXT = [
3
3
  " $ openapi-typesafe [input] [options]",
4
4
  "",
5
5
  "Options",
6
- " --help Display this",
6
+ " --help Show this help",
7
7
  " --version Display the version",
8
8
  " --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)",
9
9
  " --output, -o Specify output file (if not specified in redocly.yaml)",
@@ -16,7 +16,7 @@ const HELP_TEXT = [
16
16
  " --immutable Generate readonly types",
17
17
  " --additional-properties Treat schema objects as if `additionalProperties: true` is set",
18
18
  " --empty-objects-unknown Generate `unknown` instead of `Record<string, never>` for empty objects",
19
- " --default-non-nullable Set to `false` to ignore default values when generating non-nullable types",
19
+ " --default-non-nullable A property with a `default` is required (default: true; =false makes it optional)",
20
20
  " --properties-required-by-default",
21
21
  " Treat schema objects as if `required` is set to all properties by default",
22
22
  " --array-length Generate tuples using array minItems / maxItems",
@@ -26,7 +26,7 @@ const HELP_TEXT = [
26
26
  " --generate-path-params Generate path parameters for all paths where they are undefined by schema",
27
27
  " --alphabetize Sort object keys alphabetically",
28
28
  " --exclude-deprecated Exclude deprecated types",
29
- " --root-types Export schemas types at root level",
29
+ " --root-types Export `components` types as root-level aliases",
30
30
  " --root-types-no-schema-prefix",
31
31
  ' Do not add "Schema" prefix to types at the root level (should only be used with --root-types)',
32
32
  " --root-types-keep-casing Keep casing of root types (should only be used with --root-types)",
@@ -1 +1 @@
1
- {"version":3,"file":"help-text.mjs","sources":["../../src/cli/help-text.ts"],"sourcesContent":["/** The text of `--help`, as in the original CLI; long lines are split only in this source. */\nexport const HELP_TEXT = [\n \"Usage\",\n \" $ openapi-typesafe [input] [options]\",\n \"\",\n \"Options\",\n \" --help Display this\",\n \" --version Display the version\",\n \" --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)\",\n \" --output, -o Specify output file (if not specified in redocly.yaml)\",\n \" --enum Export true TS enums instead of unions\",\n \" --enum-values Export enum values as arrays\",\n \" --conditional-enums Only generate true TS enums when enum\" +\n \" metadata is available (default: false)\",\n \" --dedupe-enums Dedupe enum types when `--enum=true` is set\",\n \" --check Check that the generated types are\" +\n \" up-to-date. (default: false)\",\n \" --export-type, -t Export top-level `type` instead of `interface`\",\n \" --immutable Generate readonly types\",\n \" --additional-properties Treat schema objects as if `additionalProperties: true` is set\",\n \" --empty-objects-unknown Generate `unknown` instead of\" +\n \" `Record<string, never>` for empty objects\",\n \" --default-non-nullable Set to `false` to ignore default values\" +\n \" when generating non-nullable types\",\n \" --properties-required-by-default\",\n \" Treat schema objects as if `required` is\" +\n \" set to all properties by default\",\n \" --array-length Generate tuples using array minItems / maxItems\",\n \" --binary-as-blob Type raw binary strings (format: binary,\" +\n \" contentMediaType) as Blob\",\n \" --fix [names] Turn on output fixes, comma-separated, or\" +\n ' \"all\" (see docs/cli.md#fix)',\n \" --path-params-as-types Convert paths to template literal types\",\n \" --generate-path-params Generate path parameters for all paths where they are\" +\n \" undefined by schema\",\n \" --alphabetize Sort object keys alphabetically\",\n \" --exclude-deprecated Exclude deprecated types\",\n \" --root-types Export schemas types at root level\",\n \" --root-types-no-schema-prefix\",\n ' Do not add \"Schema\" prefix to types at' +\n \" the root level (should only be used with --root-types)\",\n \" --root-types-keep-casing Keep casing of root types (should only be\" +\n \" used with --root-types)\",\n \" --make-paths-enum Generate ApiPaths enum for all paths\",\n \" --read-write-markers Generate $Read/$Write markers for\" +\n \" readOnly/writeOnly properties\",\n \" --no-lint Skip the Redocly lint (bundling errors still fail)\",\n \" --local-ref-root [dir] Load local $ref files only from this directory\",\n \" --remote-ref-hosts [hosts] Load remote $ref documents only from these\" +\n \" comma-separated hosts (empty: none)\",\n \"\",\n].join(\"\\n\");\n"],"names":[],"mappings":"AACO,MAAM,SAAA,GAAY;AAAA,EACvB,OAAA;AAAA,EACA,wCAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,2CAAA;AAAA,EACA,kDAAA;AAAA,EACA,qFAAA;AAAA,EACA,qFAAA;AAAA,EACA,qEAAA;AAAA,EACA,2DAAA;AAAA,EACA,2GAAA;AAAA,EAEA,0EAAA;AAAA,EACA,8FAAA;AAAA,EAEA,6EAAA;AAAA,EACA,sDAAA;AAAA,EACA,6FAAA;AAAA,EACA,sGAAA;AAAA,EAEA,yGAAA;AAAA,EAEA,oCAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8EAAA;AAAA,EACA,iGAAA;AAAA,EAEA,oGAAA;AAAA,EAEA,sEAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8DAAA;AAAA,EACA,uDAAA;AAAA,EACA,iEAAA;AAAA,EACA,iCAAA;AAAA,EACA,4HAAA;AAAA,EAEA,gGAAA;AAAA,EAEA,mEAAA;AAAA,EACA,8FAAA;AAAA,EAEA,iFAAA;AAAA,EACA,6EAAA;AAAA,EACA,6GAAA;AAAA,EAEA;AACF,CAAA,CAAE,KAAK,IAAI;;"}
1
+ {"version":3,"file":"help-text.mjs","sources":["../../src/cli/help-text.ts"],"sourcesContent":["/** The text of `--help`, as in the original CLI; long lines are split only in this source. */\nexport const HELP_TEXT = [\n \"Usage\",\n \" $ openapi-typesafe [input] [options]\",\n \"\",\n \"Options\",\n \" --help Show this help\",\n \" --version Display the version\",\n \" --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)\",\n \" --output, -o Specify output file (if not specified in redocly.yaml)\",\n \" --enum Export true TS enums instead of unions\",\n \" --enum-values Export enum values as arrays\",\n \" --conditional-enums Only generate true TS enums when enum\" +\n \" metadata is available (default: false)\",\n \" --dedupe-enums Dedupe enum types when `--enum=true` is set\",\n \" --check Check that the generated types are\" +\n \" up-to-date. (default: false)\",\n \" --export-type, -t Export top-level `type` instead of `interface`\",\n \" --immutable Generate readonly types\",\n \" --additional-properties Treat schema objects as if `additionalProperties: true` is set\",\n \" --empty-objects-unknown Generate `unknown` instead of\" +\n \" `Record<string, never>` for empty objects\",\n \" --default-non-nullable A property with a `default` is required\" +\n \" (default: true; =false makes it optional)\",\n \" --properties-required-by-default\",\n \" Treat schema objects as if `required` is\" +\n \" set to all properties by default\",\n \" --array-length Generate tuples using array minItems / maxItems\",\n \" --binary-as-blob Type raw binary strings (format: binary,\" +\n \" contentMediaType) as Blob\",\n \" --fix [names] Turn on output fixes, comma-separated, or\" +\n ' \"all\" (see docs/cli.md#fix)',\n \" --path-params-as-types Convert paths to template literal types\",\n \" --generate-path-params Generate path parameters for all paths where they are\" +\n \" undefined by schema\",\n \" --alphabetize Sort object keys alphabetically\",\n \" --exclude-deprecated Exclude deprecated types\",\n \" --root-types Export `components` types as root-level aliases\",\n \" --root-types-no-schema-prefix\",\n ' Do not add \"Schema\" prefix to types at' +\n \" the root level (should only be used with --root-types)\",\n \" --root-types-keep-casing Keep casing of root types (should only be\" +\n \" used with --root-types)\",\n \" --make-paths-enum Generate ApiPaths enum for all paths\",\n \" --read-write-markers Generate $Read/$Write markers for\" +\n \" readOnly/writeOnly properties\",\n \" --no-lint Skip the Redocly lint (bundling errors still fail)\",\n \" --local-ref-root [dir] Load local $ref files only from this directory\",\n \" --remote-ref-hosts [hosts] Load remote $ref documents only from these\" +\n \" comma-separated hosts (empty: none)\",\n \"\",\n].join(\"\\n\");\n"],"names":[],"mappings":"AACO,MAAM,SAAA,GAAY;AAAA,EACvB,OAAA;AAAA,EACA,wCAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,6CAAA;AAAA,EACA,kDAAA;AAAA,EACA,qFAAA;AAAA,EACA,qFAAA;AAAA,EACA,qEAAA;AAAA,EACA,2DAAA;AAAA,EACA,2GAAA;AAAA,EAEA,0EAAA;AAAA,EACA,8FAAA;AAAA,EAEA,6EAAA;AAAA,EACA,sDAAA;AAAA,EACA,6FAAA;AAAA,EACA,sGAAA;AAAA,EAEA,gHAAA;AAAA,EAEA,oCAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8EAAA;AAAA,EACA,iGAAA;AAAA,EAEA,oGAAA;AAAA,EAEA,sEAAA;AAAA,EACA,wGAAA;AAAA,EAEA,8DAAA;AAAA,EACA,uDAAA;AAAA,EACA,8EAAA;AAAA,EACA,iCAAA;AAAA,EACA,4HAAA;AAAA,EAEA,gGAAA;AAAA,EAEA,mEAAA;AAAA,EACA,8FAAA;AAAA,EAEA,iFAAA;AAAA,EACA,6EAAA;AAAA,EACA,6GAAA;AAAA,EAEA;AACF,CAAA,CAAE,KAAK,IAAI;;"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const scule = require('scule');
4
+ const apiSettings = require('./api-settings.cjs');
4
5
  const cliArguments = require('./cli-arguments.cjs');
5
6
  const cliErrors = require('./cli-errors.cjs');
6
7
  const cliOutput = require('./cli-output.cjs');
@@ -9,7 +10,6 @@ const fixOption = require('./fix-option.cjs');
9
10
  const refLimits = require('./ref-limits.cjs');
10
11
 
11
12
  const REDOCLY_CONFIG_KEY = "x-openapi-ts";
12
- const FIX_SETTING = "fix";
13
13
  function redoclyApisOf(redocly) {
14
14
  return Object.entries(redocly.apis ?? {}).map(([name, api]) => {
15
15
  const settings = api[REDOCLY_CONFIG_KEY];
@@ -30,24 +30,28 @@ function apiFlags(settings) {
30
30
  return flags;
31
31
  }
32
32
  function apiFixNames(settings) {
33
- return fixOption.fixNamesOf(settings[FIX_SETTING]);
33
+ return fixOption.fixNamesOf(settings[apiSettings.FIX_SETTING]);
34
34
  }
35
35
  function configRootOf(redocly, cwd) {
36
36
  return redocly.configFile ? cliOutput.resolveLocationUrl(redocly.configFile, cwd) : cwd;
37
37
  }
38
38
  async function generateApi(run, redocly, api) {
39
- if (!api.settings?.output) {
39
+ if (!api.settings?.[apiSettings.OUTPUT_SETTING]) {
40
40
  throw cliErrors.cliError(
41
41
  "CLI_CONFIG_OUTPUT_MISSING",
42
42
  `API ${api.name} is missing an \`${REDOCLY_CONFIG_KEY}.output\` key. See ${docsLinks.MULTIPLE_SCHEMAS_DOCS_URL}`
43
43
  );
44
44
  }
45
- const output = String(api.settings.output);
45
+ for (const warning of apiSettings.unknownSettingWarnings(api.name, api.settings)) {
46
+ run.deps.logger.warn(warning);
47
+ }
48
+ const output = String(api.settings[apiSettings.OUTPUT_SETTING]);
46
49
  const configRoot = configRootOf(redocly, run.deps.cwd);
47
50
  const options = {
48
51
  ...run.args.generatorFlags,
49
52
  ...apiFlags(api.settings),
50
53
  ...refLimits.refLimitOptions(run.args, run.deps.cwd),
54
+ ...apiSettings.apiRefLimitOptions(api.name, api.settings, configRoot),
51
55
  ...fixOption.fixOption(apiFixNames(api.settings) ?? run.args.fix),
52
56
  redocly
53
57
  };