@gabrielbryk/json-schema-to-zod 2.10.0 → 2.11.0

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 (138) hide show
  1. package/AGENTS.md +44 -0
  2. package/CHANGELOG.md +35 -0
  3. package/README.md +6 -33
  4. package/check-types-lift.sh +23 -0
  5. package/check-types.sh +20 -0
  6. package/dist/{esm/cli.js → cli.js} +0 -6
  7. package/dist/{esm/core → core}/analyzeSchema.js +4 -5
  8. package/dist/core/emitZod.js +263 -0
  9. package/dist/{esm/generators → generators}/generateBundle.js +225 -67
  10. package/dist/{esm/index.js → index.js} +6 -0
  11. package/dist/jsonSchemaToZod.js +17 -0
  12. package/dist/parsers/parseAllOf.js +125 -0
  13. package/dist/parsers/parseAnyOf.js +28 -0
  14. package/dist/{esm/parsers → parsers}/parseArray.js +27 -11
  15. package/dist/parsers/parseBoolean.js +4 -0
  16. package/dist/parsers/parseConst.js +22 -0
  17. package/dist/parsers/parseEnum.js +35 -0
  18. package/dist/{esm/parsers → parsers}/parseIfThenElse.js +11 -7
  19. package/dist/parsers/parseMultipleType.js +10 -0
  20. package/dist/parsers/parseNot.js +14 -0
  21. package/dist/parsers/parseNull.js +4 -0
  22. package/dist/parsers/parseNullable.js +12 -0
  23. package/dist/{esm/parsers → parsers}/parseNumber.js +4 -1
  24. package/dist/{esm/parsers → parsers}/parseObject.js +168 -29
  25. package/dist/parsers/parseOneOf.js +365 -0
  26. package/dist/{esm/parsers → parsers}/parseSchema.js +56 -110
  27. package/dist/parsers/parseSimpleDiscriminatedOneOf.js +24 -0
  28. package/dist/{esm/parsers → parsers}/parseString.js +29 -18
  29. package/dist/types/Types.d.ts +32 -4
  30. package/dist/types/core/analyzeSchema.d.ts +3 -2
  31. package/dist/types/generators/generateBundle.d.ts +0 -2
  32. package/dist/types/index.d.ts +6 -0
  33. package/dist/types/parsers/parseAllOf.d.ts +2 -2
  34. package/dist/types/parsers/parseAnyOf.d.ts +2 -2
  35. package/dist/types/parsers/parseArray.d.ts +2 -2
  36. package/dist/types/parsers/parseBoolean.d.ts +2 -1
  37. package/dist/types/parsers/parseConst.d.ts +2 -2
  38. package/dist/types/parsers/parseDefault.d.ts +2 -2
  39. package/dist/types/parsers/parseEnum.d.ts +2 -2
  40. package/dist/types/parsers/parseIfThenElse.d.ts +2 -2
  41. package/dist/types/parsers/parseMultipleType.d.ts +2 -2
  42. package/dist/types/parsers/parseNot.d.ts +2 -2
  43. package/dist/types/parsers/parseNull.d.ts +2 -1
  44. package/dist/types/parsers/parseNullable.d.ts +2 -2
  45. package/dist/types/parsers/parseNumber.d.ts +2 -2
  46. package/dist/types/parsers/parseObject.d.ts +2 -2
  47. package/dist/types/parsers/parseOneOf.d.ts +2 -2
  48. package/dist/types/parsers/parseSchema.d.ts +2 -2
  49. package/dist/types/parsers/parseSimpleDiscriminatedOneOf.d.ts +2 -2
  50. package/dist/types/parsers/parseString.d.ts +2 -2
  51. package/dist/types/utils/anyOrUnknown.d.ts +5 -4
  52. package/dist/types/utils/esmEmitter.d.ts +29 -0
  53. package/dist/types/utils/extractInlineObject.d.ts +15 -0
  54. package/dist/types/utils/liftInlineObjects.d.ts +21 -0
  55. package/dist/types/utils/namingService.d.ts +21 -0
  56. package/dist/types/utils/resolveRef.d.ts +7 -0
  57. package/dist/types/utils/schemaRepresentation.d.ts +71 -0
  58. package/dist/utils/anyOrUnknown.js +13 -0
  59. package/dist/{esm/utils → utils}/buildRefRegistry.js +4 -0
  60. package/dist/utils/esmEmitter.js +87 -0
  61. package/dist/utils/extractInlineObject.js +119 -0
  62. package/dist/utils/liftInlineObjects.js +476 -0
  63. package/dist/utils/namingService.js +58 -0
  64. package/dist/utils/resolveRef.js +92 -0
  65. package/dist/utils/schemaRepresentation.js +569 -0
  66. package/docs/IMPROVEMENT-PLAN.md +243 -0
  67. package/docs/ZOD-V4-RECURSIVE-TYPE-LIMITATIONS.md +292 -0
  68. package/docs/proposals/bundle-refactor.md +1 -1
  69. package/docs/proposals/discriminated-union-with-default.md +248 -0
  70. package/docs/proposals/inline-object-lifting.md +77 -0
  71. package/eslint.config.js +4 -2
  72. package/jest.config.mjs +19 -0
  73. package/package.json +17 -20
  74. package/scripts/generateWorkflowSchema.ts +0 -1
  75. package/dist/cjs/Types.js +0 -2
  76. package/dist/cjs/cli.js +0 -70
  77. package/dist/cjs/core/analyzeSchema.js +0 -62
  78. package/dist/cjs/core/emitZod.js +0 -141
  79. package/dist/cjs/generators/generateBundle.js +0 -365
  80. package/dist/cjs/index.js +0 -50
  81. package/dist/cjs/jsonSchemaToZod.js +0 -10
  82. package/dist/cjs/package.json +0 -1
  83. package/dist/cjs/parsers/parseAllOf.js +0 -46
  84. package/dist/cjs/parsers/parseAnyOf.js +0 -18
  85. package/dist/cjs/parsers/parseArray.js +0 -90
  86. package/dist/cjs/parsers/parseBoolean.js +0 -5
  87. package/dist/cjs/parsers/parseConst.js +0 -7
  88. package/dist/cjs/parsers/parseDefault.js +0 -8
  89. package/dist/cjs/parsers/parseEnum.js +0 -21
  90. package/dist/cjs/parsers/parseIfThenElse.js +0 -35
  91. package/dist/cjs/parsers/parseMultipleType.js +0 -10
  92. package/dist/cjs/parsers/parseNot.js +0 -12
  93. package/dist/cjs/parsers/parseNull.js +0 -5
  94. package/dist/cjs/parsers/parseNullable.js +0 -12
  95. package/dist/cjs/parsers/parseNumber.js +0 -116
  96. package/dist/cjs/parsers/parseObject.js +0 -315
  97. package/dist/cjs/parsers/parseOneOf.js +0 -53
  98. package/dist/cjs/parsers/parseSchema.js +0 -411
  99. package/dist/cjs/parsers/parseSimpleDiscriminatedOneOf.js +0 -21
  100. package/dist/cjs/parsers/parseString.js +0 -317
  101. package/dist/cjs/utils/anyOrUnknown.js +0 -14
  102. package/dist/cjs/utils/buildRefRegistry.js +0 -56
  103. package/dist/cjs/utils/cliTools.js +0 -108
  104. package/dist/cjs/utils/cycles.js +0 -113
  105. package/dist/cjs/utils/half.js +0 -7
  106. package/dist/cjs/utils/jsdocs.js +0 -20
  107. package/dist/cjs/utils/omit.js +0 -11
  108. package/dist/cjs/utils/resolveUri.js +0 -16
  109. package/dist/cjs/utils/withMessage.js +0 -21
  110. package/dist/cjs/zodToJsonSchema.js +0 -89
  111. package/dist/esm/core/emitZod.js +0 -137
  112. package/dist/esm/jsonSchemaToZod.js +0 -6
  113. package/dist/esm/package.json +0 -1
  114. package/dist/esm/parsers/parseAllOf.js +0 -43
  115. package/dist/esm/parsers/parseAnyOf.js +0 -14
  116. package/dist/esm/parsers/parseBoolean.js +0 -1
  117. package/dist/esm/parsers/parseConst.js +0 -3
  118. package/dist/esm/parsers/parseEnum.js +0 -17
  119. package/dist/esm/parsers/parseMultipleType.js +0 -6
  120. package/dist/esm/parsers/parseNot.js +0 -8
  121. package/dist/esm/parsers/parseNull.js +0 -1
  122. package/dist/esm/parsers/parseNullable.js +0 -8
  123. package/dist/esm/parsers/parseOneOf.js +0 -49
  124. package/dist/esm/parsers/parseSimpleDiscriminatedOneOf.js +0 -17
  125. package/dist/esm/utils/anyOrUnknown.js +0 -10
  126. package/jest.config.cjs +0 -4
  127. package/postcjs.cjs +0 -1
  128. package/postesm.cjs +0 -1
  129. /package/dist/{esm/Types.js → Types.js} +0 -0
  130. /package/dist/{esm/parsers → parsers}/parseDefault.js +0 -0
  131. /package/dist/{esm/utils → utils}/cliTools.js +0 -0
  132. /package/dist/{esm/utils → utils}/cycles.js +0 -0
  133. /package/dist/{esm/utils → utils}/half.js +0 -0
  134. /package/dist/{esm/utils → utils}/jsdocs.js +0 -0
  135. /package/dist/{esm/utils → utils}/omit.js +0 -0
  136. /package/dist/{esm/utils → utils}/resolveUri.js +0 -0
  137. /package/dist/{esm/utils → utils}/withMessage.js +0 -0
  138. /package/dist/{esm/zodToJsonSchema.js → zodToJsonSchema.js} +0 -0
@@ -1,317 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseString = void 0;
4
- const withMessage_js_1 = require("../utils/withMessage.js");
5
- const parseSchema_js_1 = require("./parseSchema.js");
6
- const parseString = (schema, refs) => {
7
- const formatError = schema.errorMessage?.format;
8
- const refContext = ensureRefs(refs);
9
- const topLevelFormatMap = {
10
- email: "z.email",
11
- ipv4: "z.ipv4",
12
- ipv6: "z.ipv6",
13
- uri: "z.url",
14
- uuid: "z.uuid",
15
- cuid: "z.cuid",
16
- cuid2: "z.cuid2",
17
- nanoid: "z.nanoid",
18
- ulid: "z.ulid",
19
- jwt: "z.jwt",
20
- e164: "z.e164",
21
- base64url: "z.base64url",
22
- base64: "z.base64",
23
- emoji: "z.emoji",
24
- "idn-email": "z.email",
25
- };
26
- const formatFn = schema.format && topLevelFormatMap[schema.format];
27
- const formatParam = formatError !== undefined ? `{ error: ${JSON.stringify(formatError)} }` : "";
28
- let r = formatFn ? `${formatFn}(${formatParam})` : "z.string()";
29
- const formatHandled = Boolean(formatFn);
30
- let formatWasHandled = formatHandled;
31
- if (!formatHandled) {
32
- r += (0, withMessage_js_1.withMessage)(schema, "format", ({ value }) => {
33
- switch (value) {
34
- case "email":
35
- formatWasHandled = true;
36
- return {
37
- opener: ".email(",
38
- closer: ")",
39
- messagePrefix: "{ error: ",
40
- messageCloser: " })",
41
- };
42
- case "ip":
43
- formatWasHandled = true;
44
- return {
45
- opener: ".ip(",
46
- closer: ")",
47
- messagePrefix: "{ error: ",
48
- messageCloser: " })",
49
- };
50
- case "ipv4":
51
- formatWasHandled = true;
52
- return {
53
- opener: '.ip({ version: "v4"',
54
- closer: " })",
55
- messagePrefix: ", error: ",
56
- messageCloser: " })",
57
- };
58
- case "ipv6":
59
- formatWasHandled = true;
60
- return {
61
- opener: '.ip({ version: "v6"',
62
- closer: " })",
63
- messagePrefix: ", error: ",
64
- messageCloser: " })",
65
- };
66
- case "uri":
67
- formatWasHandled = true;
68
- return {
69
- opener: ".url(",
70
- closer: ")",
71
- messagePrefix: "{ error: ",
72
- messageCloser: " })",
73
- };
74
- case "uuid":
75
- formatWasHandled = true;
76
- return {
77
- opener: ".uuid(",
78
- closer: ")",
79
- messagePrefix: "{ error: ",
80
- messageCloser: " })",
81
- };
82
- case "cuid":
83
- formatWasHandled = true;
84
- return {
85
- opener: ".cuid(",
86
- closer: ")",
87
- messagePrefix: "{ error: ",
88
- messageCloser: " })",
89
- };
90
- case "cuid2":
91
- formatWasHandled = true;
92
- return {
93
- opener: ".cuid2(",
94
- closer: ")",
95
- messagePrefix: "{ error: ",
96
- messageCloser: " })",
97
- };
98
- case "nanoid":
99
- formatWasHandled = true;
100
- return {
101
- opener: ".nanoid(",
102
- closer: ")",
103
- messagePrefix: "{ error: ",
104
- messageCloser: " })",
105
- };
106
- case "ulid":
107
- formatWasHandled = true;
108
- return {
109
- opener: ".ulid(",
110
- closer: ")",
111
- messagePrefix: "{ error: ",
112
- messageCloser: " })",
113
- };
114
- case "jwt":
115
- formatWasHandled = true;
116
- return {
117
- opener: ".jwt(",
118
- closer: ")",
119
- messagePrefix: "{ error: ",
120
- messageCloser: " })",
121
- };
122
- case "e164":
123
- formatWasHandled = true;
124
- return {
125
- opener: ".e164(",
126
- closer: ")",
127
- messagePrefix: "{ error: ",
128
- messageCloser: " })",
129
- };
130
- case "base64url":
131
- formatWasHandled = true;
132
- return {
133
- opener: ".base64url(",
134
- closer: ")",
135
- messagePrefix: "{ error: ",
136
- messageCloser: " })",
137
- };
138
- case "emoji":
139
- formatWasHandled = true;
140
- return {
141
- opener: ".emoji(",
142
- closer: ")",
143
- messagePrefix: "{ error: ",
144
- messageCloser: " })",
145
- };
146
- case "date-time":
147
- formatWasHandled = true;
148
- return {
149
- opener: ".datetime({ offset: true",
150
- closer: " })",
151
- messagePrefix: ", error: ",
152
- messageCloser: " })",
153
- };
154
- case "time":
155
- formatWasHandled = true;
156
- return {
157
- opener: ".time(",
158
- closer: ")",
159
- messagePrefix: "{ error: ",
160
- messageCloser: " })",
161
- };
162
- case "date":
163
- formatWasHandled = true;
164
- return {
165
- opener: ".date(",
166
- closer: ")",
167
- messagePrefix: "{ error: ",
168
- messageCloser: " })",
169
- };
170
- case "binary":
171
- formatWasHandled = true;
172
- return {
173
- opener: ".base64(",
174
- closer: ")",
175
- messagePrefix: "{ error: ",
176
- messageCloser: " })",
177
- };
178
- case "duration":
179
- formatWasHandled = true;
180
- return {
181
- opener: ".duration(",
182
- closer: ")",
183
- messagePrefix: "{ error: ",
184
- messageCloser: " })",
185
- };
186
- case "hostname":
187
- case "idn-hostname":
188
- formatWasHandled = true;
189
- return {
190
- opener: ".refine((val) => { if (typeof val !== \"string\" || val.length === 0 || val.length > 253) return false; return val.split(\".\").every((label) => label.length > 0 && label.length <= 63 && /^[A-Za-z0-9-]+$/.test(label) && label[0] !== \"-\" && label[label.length - 1] !== \"-\"); }",
191
- closer: ")",
192
- messagePrefix: ", { error: ",
193
- messageCloser: " })",
194
- };
195
- case "idn-email":
196
- formatWasHandled = true;
197
- return {
198
- opener: ".email(",
199
- closer: ")",
200
- messagePrefix: "{ error: ",
201
- messageCloser: " })",
202
- };
203
- case "uri-reference":
204
- case "iri":
205
- case "iri-reference":
206
- formatWasHandled = true;
207
- return {
208
- opener: '.refine((val) => { try { new URL(val, "http://example.com"); return true; } catch { return false; } }',
209
- closer: ")",
210
- messagePrefix: ", { error: ",
211
- messageCloser: " })",
212
- };
213
- case "json-pointer":
214
- formatWasHandled = true;
215
- return {
216
- opener: ".refine((val) => typeof val === \"string\" && /^(?:\\/(?:[^/~]|~[01])*)*$/.test(val)",
217
- closer: ")",
218
- messagePrefix: ", { error: ",
219
- messageCloser: " })",
220
- };
221
- case "relative-json-pointer":
222
- formatWasHandled = true;
223
- return {
224
- opener: ".refine((val) => typeof val === \"string\" && /^(?:0|[1-9][0-9]*)(?:#|(?:\\/(?:[^/~]|~[01])*))*$/.test(val)",
225
- closer: ")",
226
- messagePrefix: ", { error: ",
227
- messageCloser: " })",
228
- };
229
- case "uri-template":
230
- formatWasHandled = true;
231
- return {
232
- opener: ".refine((val) => { if (typeof val !== \"string\") return false; const opens = (val.match(/\\{/g) || []).length; const closes = (val.match(/\\}/g) || []).length; return opens === closes; }",
233
- closer: ")",
234
- messagePrefix: ", { error: ",
235
- messageCloser: " })",
236
- };
237
- case "regex":
238
- formatWasHandled = true;
239
- return {
240
- opener: ".refine((val) => { try { new RegExp(val); return true; } catch { return false; } }",
241
- closer: ")",
242
- messagePrefix: ", { error: ",
243
- messageCloser: " })",
244
- };
245
- }
246
- });
247
- }
248
- if (schema.format && !formatWasHandled) {
249
- refContext.onUnknownFormat?.(schema.format, refContext.path);
250
- }
251
- r += (0, withMessage_js_1.withMessage)(schema, "pattern", ({ json }) => ({
252
- opener: `.regex(new RegExp(${json})`,
253
- closer: ")",
254
- messagePrefix: ", { error: ",
255
- messageCloser: " })",
256
- }));
257
- r += (0, withMessage_js_1.withMessage)(schema, "minLength", ({ json }) => ({
258
- opener: `.min(${json}`,
259
- closer: ")",
260
- messagePrefix: ", { error: ",
261
- messageCloser: " })",
262
- }));
263
- r += (0, withMessage_js_1.withMessage)(schema, "maxLength", ({ json }) => ({
264
- opener: `.max(${json}`,
265
- closer: ")",
266
- messagePrefix: ", { error: ",
267
- messageCloser: " })",
268
- }));
269
- r += (0, withMessage_js_1.withMessage)(schema, "contentEncoding", ({ value }) => {
270
- if (value === "base64") {
271
- return {
272
- opener: ".base64(",
273
- closer: ")",
274
- messagePrefix: "{ error: ",
275
- messageCloser: " })",
276
- };
277
- }
278
- });
279
- const contentMediaType = (0, withMessage_js_1.withMessage)(schema, "contentMediaType", ({ value }) => {
280
- if (value === "application/json") {
281
- return {
282
- opener: '.transform((str, ctx) => { try { return JSON.parse(str); } catch (err) { ctx.addIssue({ code: "custom", message: "Invalid JSON" }); }}',
283
- closer: ")",
284
- messagePrefix: ", { error: ",
285
- messageCloser: " })",
286
- };
287
- }
288
- });
289
- if (contentMediaType != "") {
290
- r += contentMediaType;
291
- r += (0, withMessage_js_1.withMessage)(schema, "contentSchema", ({ value }) => {
292
- if (value && typeof value === "object") {
293
- return {
294
- opener: `.pipe(${(0, parseSchema_js_1.parseSchema)(value, refContext)}`,
295
- closer: ")",
296
- messagePrefix: ", { error: ",
297
- messageCloser: " })",
298
- };
299
- }
300
- });
301
- }
302
- return r;
303
- };
304
- exports.parseString = parseString;
305
- function ensureRefs(refs) {
306
- if (refs)
307
- return refs;
308
- return {
309
- path: [],
310
- seen: new Map(),
311
- declarations: new Map(),
312
- dependencies: new Map(),
313
- inProgress: new Set(),
314
- refNameByPointer: new Map(),
315
- usedNames: new Set(),
316
- };
317
- }
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.anyOrUnknown = void 0;
4
- /**
5
- * Returns "z.unknown()" if the useUnknown option is enabled, otherwise "z.any()".
6
- * This helper is used throughout the library for fallback cases.
7
- *
8
- * @param refs - The refs object containing options
9
- * @returns The appropriate Zod schema string
10
- */
11
- const anyOrUnknown = (refs) => {
12
- return refs?.useUnknown ? "z.unknown()" : "z.any()";
13
- };
14
- exports.anyOrUnknown = anyOrUnknown;
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildRefRegistry = void 0;
4
- const resolveUri_js_1 = require("./resolveUri.js");
5
- const buildRefRegistry = (schema, rootBaseUri = "root:///") => {
6
- const registry = new Map();
7
- const walk = (node, baseUri, path) => {
8
- if (typeof node !== "object" || node === null)
9
- return;
10
- const obj = node;
11
- const nextBase = obj.$id ? (0, resolveUri_js_1.resolveUri)(baseUri, obj.$id) : baseUri;
12
- // Legacy recursive anchor
13
- if (obj.$recursiveAnchor === true) {
14
- const name = "__recursive__";
15
- registry.set(`${nextBase}#${name}`, {
16
- schema: node,
17
- path,
18
- baseUri: nextBase,
19
- dynamic: true,
20
- anchor: name,
21
- });
22
- }
23
- // Register base entry
24
- registry.set(nextBase, { schema: node, path, baseUri: nextBase });
25
- if (typeof obj.$anchor === "string") {
26
- registry.set(`${nextBase}#${obj.$anchor}`, {
27
- schema: node,
28
- path,
29
- baseUri: nextBase,
30
- anchor: obj.$anchor,
31
- });
32
- }
33
- if (typeof obj.$dynamicAnchor === "string") {
34
- const name = obj.$dynamicAnchor;
35
- registry.set(`${nextBase}#${name}`, {
36
- schema: node,
37
- path,
38
- baseUri: nextBase,
39
- dynamic: true,
40
- anchor: name,
41
- });
42
- }
43
- for (const key in obj) {
44
- const value = obj[key];
45
- if (Array.isArray(value)) {
46
- value.forEach((v, i) => walk(v, nextBase, [...path, key, i]));
47
- }
48
- else if (typeof value === "object" && value !== null) {
49
- walk(value, nextBase, [...path, key]);
50
- }
51
- }
52
- };
53
- walk(schema, rootBaseUri, []);
54
- return { registry, rootBaseUri };
55
- };
56
- exports.buildRefRegistry = buildRefRegistry;
@@ -1,108 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseArgs = parseArgs;
4
- exports.parseOrReadJSON = parseOrReadJSON;
5
- exports.readPipe = readPipe;
6
- exports.printParams = printParams;
7
- const fs_1 = require("fs");
8
- function parseArgs(params, args, help) {
9
- const result = {};
10
- if (help) {
11
- let index = args.indexOf("--help");
12
- if (index === -1) {
13
- index = args.indexOf("-h");
14
- }
15
- if (index !== -1) {
16
- printParams({
17
- ...params,
18
- help: {
19
- shorthand: "h",
20
- description: typeof help === "string" ? help : "Display this message :)",
21
- },
22
- });
23
- process.exit(0);
24
- }
25
- }
26
- for (const name in params) {
27
- const { shorthand, required, value } = params[name];
28
- let index = args.indexOf("--" + name);
29
- if (index === -1 && shorthand) {
30
- index = args.indexOf("-" + shorthand);
31
- }
32
- if (index === -1) {
33
- if (required || required === "") {
34
- throw new Error(typeof required === "string" && required !== ""
35
- ? required
36
- : `Missing required argument ${name}`);
37
- }
38
- result[name] = false;
39
- continue;
40
- }
41
- if (value) {
42
- const val = args[index + 1];
43
- if (val === undefined) {
44
- throw new Error(`Expected a value for argument ${name}`);
45
- }
46
- if (value === "number") {
47
- const asNumber = Number(val);
48
- if (isNaN(asNumber)) {
49
- throw new Error(`Value of argument ${name} must be a valid number`);
50
- }
51
- result[name] = asNumber;
52
- continue;
53
- }
54
- if (Array.isArray(value) && !value.includes(val)) {
55
- throw new Error(`Value of argument ${name} must be one of ${value}`);
56
- }
57
- result[name] = val;
58
- }
59
- else {
60
- result[name] = true;
61
- }
62
- }
63
- return result;
64
- }
65
- function parseOrReadJSON(jsonOrPath) {
66
- jsonOrPath = jsonOrPath.trim();
67
- if (jsonOrPath.length < 255 &&
68
- (0, fs_1.statSync)(jsonOrPath, { throwIfNoEntry: false })?.isFile()) {
69
- jsonOrPath = (0, fs_1.readFileSync)(jsonOrPath, "utf-8");
70
- }
71
- return JSON.parse(jsonOrPath);
72
- }
73
- function readPipe() {
74
- return new Promise((resolve, reject) => {
75
- let buf = "";
76
- process.stdin
77
- .setEncoding("utf-8")
78
- .on("end", () => resolve(buf))
79
- .on("error", reject)
80
- .on("readable", () => {
81
- let chunk;
82
- while ((chunk = process.stdin.read()) != null) {
83
- buf += chunk;
84
- }
85
- });
86
- });
87
- }
88
- function printParams(params) {
89
- const longest = Object.keys(params).reduce((l, c) => (c.length > l ? c.length : l), 5);
90
- const header = "Name " + " ".repeat(longest - 2) + "Short Description";
91
- console.log(header);
92
- for (const name in params) {
93
- let { shorthand, description } = params[name];
94
- if (shorthand) {
95
- shorthand = " -" + shorthand;
96
- }
97
- else {
98
- shorthand = " ";
99
- }
100
- if (description) {
101
- description = " " + description;
102
- }
103
- else {
104
- description = "";
105
- }
106
- console.log("--" + name + " ".repeat(longest - name.length) + shorthand + description);
107
- }
108
- }
@@ -1,113 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.computeScc = exports.detectCycles = exports.findRefDependencies = void 0;
4
- const findRefDependencies = (schema, validDefNames) => {
5
- const deps = new Set();
6
- function traverse(obj) {
7
- if (obj === null || typeof obj !== "object")
8
- return;
9
- if (Array.isArray(obj)) {
10
- obj.forEach(traverse);
11
- return;
12
- }
13
- const record = obj;
14
- if (typeof record["$ref"] === "string") {
15
- const ref = record["$ref"];
16
- const match = ref.match(/^#\/(?:\$defs|definitions)\/(.+)$/);
17
- if (match && validDefNames.includes(match[1])) {
18
- deps.add(match[1]);
19
- }
20
- }
21
- for (const value of Object.values(record)) {
22
- traverse(value);
23
- }
24
- }
25
- traverse(schema);
26
- return deps;
27
- };
28
- exports.findRefDependencies = findRefDependencies;
29
- const detectCycles = (defNames, deps) => {
30
- const cycleNodes = new Set();
31
- const visited = new Set();
32
- const recursionStack = new Set();
33
- function dfs(node, path) {
34
- if (recursionStack.has(node)) {
35
- const cycleStart = path.indexOf(node);
36
- for (let i = cycleStart; i < path.length; i++) {
37
- cycleNodes.add(path[i]);
38
- }
39
- cycleNodes.add(node);
40
- return;
41
- }
42
- if (visited.has(node))
43
- return;
44
- visited.add(node);
45
- recursionStack.add(node);
46
- const targets = deps.get(node);
47
- if (targets) {
48
- for (const dep of targets) {
49
- dfs(dep, [...path, node]);
50
- }
51
- }
52
- recursionStack.delete(node);
53
- }
54
- for (const defName of defNames) {
55
- if (!visited.has(defName))
56
- dfs(defName, []);
57
- }
58
- return cycleNodes;
59
- };
60
- exports.detectCycles = detectCycles;
61
- const computeScc = (defNames, deps) => {
62
- // Tarjan's algorithm, keeps mapping for quick "is this ref in my cycle?"
63
- const index = new Map();
64
- const lowlink = new Map();
65
- const stack = [];
66
- const onStack = new Set();
67
- const componentByName = new Map();
68
- const cycleMembers = new Set();
69
- let currentIndex = 0;
70
- let componentId = 0;
71
- const strongConnect = (v) => {
72
- index.set(v, currentIndex);
73
- lowlink.set(v, currentIndex);
74
- currentIndex += 1;
75
- stack.push(v);
76
- onStack.add(v);
77
- const neighbors = deps.get(v);
78
- if (neighbors) {
79
- for (const w of neighbors) {
80
- if (!index.has(w)) {
81
- strongConnect(w);
82
- lowlink.set(v, Math.min(lowlink.get(v), lowlink.get(w)));
83
- }
84
- else if (onStack.has(w)) {
85
- lowlink.set(v, Math.min(lowlink.get(v), index.get(w)));
86
- }
87
- }
88
- }
89
- if (lowlink.get(v) === index.get(v)) {
90
- const component = [];
91
- let w;
92
- do {
93
- w = stack.pop();
94
- if (w === undefined)
95
- break;
96
- onStack.delete(w);
97
- component.push(w);
98
- componentByName.set(w, componentId);
99
- } while (w !== v);
100
- if (component.length > 1) {
101
- component.forEach((name) => cycleMembers.add(name));
102
- }
103
- componentId += 1;
104
- }
105
- };
106
- for (const name of defNames) {
107
- if (!index.has(name)) {
108
- strongConnect(name);
109
- }
110
- }
111
- return { cycleMembers, componentByName };
112
- };
113
- exports.computeScc = computeScc;
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.half = void 0;
4
- const half = (arr) => {
5
- return [arr.slice(0, arr.length / 2), arr.slice(arr.length / 2)];
6
- };
7
- exports.half = half;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addJsdocs = exports.expandJsdocs = void 0;
4
- const expandJsdocs = (jsdocs) => {
5
- const lines = jsdocs.split("\n");
6
- const result = lines.length === 1
7
- ? lines[0]
8
- : `\n${lines.map(x => `* ${x}`)
9
- .join("\n")}\n`;
10
- return `/**${result}*/\n`;
11
- };
12
- exports.expandJsdocs = expandJsdocs;
13
- const addJsdocs = (schema, parsed) => {
14
- const description = schema.description;
15
- if (!description) {
16
- return parsed;
17
- }
18
- return `\n${(0, exports.expandJsdocs)(description)}${parsed}`;
19
- };
20
- exports.addJsdocs = addJsdocs;
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.omit = void 0;
4
- const omit = (obj, ...keys) => Object.keys(obj).reduce((acc, key) => {
5
- const typedKey = key;
6
- if (!keys.includes(typedKey)) {
7
- acc[typedKey] = obj[typedKey];
8
- }
9
- return acc;
10
- }, {});
11
- exports.omit = omit;
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveUri = void 0;
4
- const resolveUri = (base, ref) => {
5
- try {
6
- // If ref is absolute, new URL will accept it; otherwise resolves against base
7
- return new URL(ref, base).toString();
8
- }
9
- catch {
10
- // Fallback: simple concatenation to avoid throwing; keep ref as-is
11
- if (ref.startsWith("#"))
12
- return `${base}${ref}`;
13
- return ref;
14
- }
15
- };
16
- exports.resolveUri = resolveUri;