quicktype-core 23.3.20 → 23.3.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/input/io/NodeIO.d.ts +1 -1
- package/dist/input/io/NodeIO.js +44 -1
- package/dist/language/TypeScriptZod/TypeScriptZodRenderer.d.ts +20 -0
- package/dist/language/TypeScriptZod/TypeScriptZodRenderer.js +110 -3
- package/package.json +2 -2
- package/dist/input/io/$fetch.ci.d.ts +0 -1
- package/dist/input/io/$fetch.ci.js +0 -6
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Readable } from "readable-stream";
|
|
2
2
|
export declare function readableFromFileOrURL(fileOrURL: string, httpHeaders?: string[]): Promise<Readable>;
|
|
3
3
|
export declare function readFromFileOrURL(fileOrURL: string, httpHeaders?: string[]): Promise<string>;
|
package/dist/input/io/NodeIO.js
CHANGED
|
@@ -41,6 +41,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
41
41
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
45
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
46
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
47
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
48
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
49
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
50
|
+
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
51
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
52
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
53
|
+
function fulfill(value) { resume("next", value); }
|
|
54
|
+
function reject(value) { resume("throw", value); }
|
|
55
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
56
|
+
};
|
|
44
57
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
58
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
59
|
};
|
|
@@ -52,6 +65,7 @@ const path = __importStar(require("path"));
|
|
|
52
65
|
const ts_necessities_1 = require("@glideapps/ts-necessities");
|
|
53
66
|
const browser_or_node_1 = require("browser-or-node");
|
|
54
67
|
const is_url_1 = __importDefault(require("is-url"));
|
|
68
|
+
const readable_stream_1 = require("readable-stream");
|
|
55
69
|
const Messages_1 = require("../../Messages");
|
|
56
70
|
const Support_1 = require("../../support/Support");
|
|
57
71
|
const get_stream_1 = require("./get-stream");
|
|
@@ -73,6 +87,35 @@ function parseHeaders(httpHeaders) {
|
|
|
73
87
|
return result;
|
|
74
88
|
}, {});
|
|
75
89
|
}
|
|
90
|
+
function webStreamChunks(stream) {
|
|
91
|
+
return __asyncGenerator(this, arguments, function* webStreamChunks_1() {
|
|
92
|
+
const reader = stream.getReader();
|
|
93
|
+
try {
|
|
94
|
+
for (;;) {
|
|
95
|
+
const { done, value } = yield __await(reader.read());
|
|
96
|
+
if (done)
|
|
97
|
+
return yield __await(void 0);
|
|
98
|
+
yield yield __await((0, ts_necessities_1.defined)(value));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
reader.releaseLock();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// readable-stream implements Readable.from (it can't do Readable.fromWeb),
|
|
107
|
+
// but @types/readable-stream doesn't declare it, hence this cast.
|
|
108
|
+
const ReadableWithFrom = readable_stream_1.Readable;
|
|
109
|
+
function readableFromResponseBody(body) {
|
|
110
|
+
// Native fetch (Node >= 18, browsers) returns a WHATWG ReadableStream,
|
|
111
|
+
// which lacks the Node stream API that our consumers rely on, so we have
|
|
112
|
+
// to wrap it. The cross-fetch fallback (node-fetch) already returns a
|
|
113
|
+
// Node stream, which we pass through unchanged.
|
|
114
|
+
if (typeof body.getReader === "function") {
|
|
115
|
+
return ReadableWithFrom.from(webStreamChunks(body), { objectMode: false });
|
|
116
|
+
}
|
|
117
|
+
return body;
|
|
118
|
+
}
|
|
76
119
|
function resolveSymbolicLink(filePath) {
|
|
77
120
|
if (!fs.lstatSync(filePath).isSymbolicLink()) {
|
|
78
121
|
return filePath;
|
|
@@ -90,7 +133,7 @@ function readableFromFileOrURL(fileOrURL, httpHeaders) {
|
|
|
90
133
|
const response = yield (0, _fetch_1.fetch)(fileOrURL, {
|
|
91
134
|
headers: parseHeaders(httpHeaders),
|
|
92
135
|
});
|
|
93
|
-
return (0, ts_necessities_1.defined)(response.body);
|
|
136
|
+
return readableFromResponseBody((0, ts_necessities_1.defined)(response.body));
|
|
94
137
|
}
|
|
95
138
|
if (browser_or_node_1.isNode) {
|
|
96
139
|
if (fileOrURL === "-") {
|
|
@@ -8,6 +8,10 @@ import { type ClassProperty, type EnumType, ObjectType, type Type } from "../../
|
|
|
8
8
|
import type { typeScriptZodOptions } from "./language";
|
|
9
9
|
export declare class TypeScriptZodRenderer extends ConvenienceRenderer {
|
|
10
10
|
protected readonly _options: OptionValues<typeof typeScriptZodOptions>;
|
|
11
|
+
/** TypeRefs of object types that participate in a reference cycle.
|
|
12
|
+
* These must be emitted as z.lazy() schemas with an explicit type
|
|
13
|
+
* annotation, since zod cannot infer recursive types. */
|
|
14
|
+
private _recursiveTypeRefs;
|
|
11
15
|
constructor(targetLanguage: TargetLanguage, renderContext: RenderContext, _options: OptionValues<typeof typeScriptZodOptions>);
|
|
12
16
|
protected forbiddenNamesForGlobalNamespace(): string[];
|
|
13
17
|
protected nameStyle(original: string, upper: boolean): string;
|
|
@@ -19,7 +23,23 @@ export declare class TypeScriptZodRenderer extends ConvenienceRenderer {
|
|
|
19
23
|
protected emitImports(): void;
|
|
20
24
|
protected typeMapTypeForProperty(p: ClassProperty): Sourcelike;
|
|
21
25
|
protected typeMapTypeFor(t: Type, required?: boolean): Sourcelike;
|
|
26
|
+
/** TypeScript type for `t`, used to annotate recursive schemas for
|
|
27
|
+
* which zod cannot infer the type.
|
|
28
|
+
*
|
|
29
|
+
* This intentionally duplicates neither `typeMapTypeFor` above nor
|
|
30
|
+
* `sourceFor` in the plain TypeScript renderer
|
|
31
|
+
* (`TypeScriptFlowBaseRenderer`): it must mirror exactly what
|
|
32
|
+
* `z.infer` would derive from the schemas emitted by
|
|
33
|
+
* `typeMapTypeFor` (e.g. `z.coerce.date()` implies `Date`), while
|
|
34
|
+
* `sourceFor` is shaped by ts/flow-specific options like
|
|
35
|
+
* `preferConstValues` and `declareUnions` that don't exist here. */
|
|
36
|
+
protected underlyingTypeFor(t: Type): Sourcelike;
|
|
37
|
+
protected isRecursive(t: ObjectType): boolean;
|
|
22
38
|
protected emitObject(name: Name, t: ObjectType): void;
|
|
39
|
+
/** Emit a recursive object type. zod cannot infer recursive types, so
|
|
40
|
+
* the type is declared explicitly and the schema is wrapped in
|
|
41
|
+
* z.lazy() with a z.ZodType annotation. */
|
|
42
|
+
protected emitLazyObject(name: Name, t: ObjectType): void;
|
|
23
43
|
protected emitEnum(e: EnumType, enumName: Name): void;
|
|
24
44
|
/** Static function that extracts underlying type refs for types that form part of the
|
|
25
45
|
* definition of the passed type - used to ensure that these appear in generated source
|
|
@@ -14,6 +14,10 @@ class TypeScriptZodRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
14
14
|
constructor(targetLanguage, renderContext, _options) {
|
|
15
15
|
super(targetLanguage, renderContext);
|
|
16
16
|
this._options = _options;
|
|
17
|
+
/** TypeRefs of object types that participate in a reference cycle.
|
|
18
|
+
* These must be emitted as z.lazy() schemas with an explicit type
|
|
19
|
+
* annotation, since zod cannot infer recursive types. */
|
|
20
|
+
this._recursiveTypeRefs = new Set();
|
|
17
21
|
}
|
|
18
22
|
forbiddenNamesForGlobalNamespace() {
|
|
19
23
|
return ["Class", "Date", "Object", "String", "Array", "JSON", "Error"];
|
|
@@ -72,7 +76,46 @@ class TypeScriptZodRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
72
76
|
}
|
|
73
77
|
return match;
|
|
74
78
|
}
|
|
79
|
+
/** TypeScript type for `t`, used to annotate recursive schemas for
|
|
80
|
+
* which zod cannot infer the type.
|
|
81
|
+
*
|
|
82
|
+
* This intentionally duplicates neither `typeMapTypeFor` above nor
|
|
83
|
+
* `sourceFor` in the plain TypeScript renderer
|
|
84
|
+
* (`TypeScriptFlowBaseRenderer`): it must mirror exactly what
|
|
85
|
+
* `z.infer` would derive from the schemas emitted by
|
|
86
|
+
* `typeMapTypeFor` (e.g. `z.coerce.date()` implies `Date`), while
|
|
87
|
+
* `sourceFor` is shaped by ts/flow-specific options like
|
|
88
|
+
* `preferConstValues` and `declareUnions` that don't exist here. */
|
|
89
|
+
underlyingTypeFor(t) {
|
|
90
|
+
if (["class", "object", "enum"].includes(t.kind)) {
|
|
91
|
+
return this.nameForNamedType(t);
|
|
92
|
+
}
|
|
93
|
+
return (0, TypeUtils_1.matchType)(t, (_anyType) => "any", (_nullType) => "null", (_boolType) => "boolean", (_integerType) => "number", (_doubleType) => "number", (_stringType) => "string", (arrayType) => [
|
|
94
|
+
"Array<",
|
|
95
|
+
this.underlyingTypeFor(arrayType.items),
|
|
96
|
+
">",
|
|
97
|
+
], (_classType) => (0, Support_1.panic)("Should already be handled."), (mapType) => [
|
|
98
|
+
"Record<string, ",
|
|
99
|
+
this.underlyingTypeFor(mapType.values),
|
|
100
|
+
">",
|
|
101
|
+
], (_enumType) => (0, Support_1.panic)("Should already be handled."), (unionType) => {
|
|
102
|
+
const children = Array.from(unionType.getChildren()).map((type) => this.underlyingTypeFor(type));
|
|
103
|
+
return (0, collection_utils_1.arrayIntercalate)(" | ", children);
|
|
104
|
+
}, (_transformedStringType) => {
|
|
105
|
+
if (_transformedStringType.kind === "date-time") {
|
|
106
|
+
return "Date";
|
|
107
|
+
}
|
|
108
|
+
return "string";
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
isRecursive(t) {
|
|
112
|
+
return this._recursiveTypeRefs.has(t.typeRef);
|
|
113
|
+
}
|
|
75
114
|
emitObject(name, t) {
|
|
115
|
+
if (this.isRecursive(t)) {
|
|
116
|
+
this.emitLazyObject(name, t);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
76
119
|
this.ensureBlankLine();
|
|
77
120
|
this.emitLine("\nexport const ", name, "Schema = ", "z.object({");
|
|
78
121
|
this.indent(() => {
|
|
@@ -85,6 +128,35 @@ class TypeScriptZodRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
85
128
|
this.emitLine("export type ", name, " = z.infer<typeof ", name, "Schema>;");
|
|
86
129
|
}
|
|
87
130
|
}
|
|
131
|
+
/** Emit a recursive object type. zod cannot infer recursive types, so
|
|
132
|
+
* the type is declared explicitly and the schema is wrapped in
|
|
133
|
+
* z.lazy() with a z.ZodType annotation. */
|
|
134
|
+
emitLazyObject(name, t) {
|
|
135
|
+
this.ensureBlankLine();
|
|
136
|
+
if (this._options.justSchema) {
|
|
137
|
+
this.emitLine("\nexport const ", name, "Schema: z.ZodType<any> = z.lazy(() =>");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.emitLine("\nexport type ", name, " = {");
|
|
141
|
+
this.indent(() => {
|
|
142
|
+
this.forEachClassProperty(t, "none", (_, jsonName, property) => {
|
|
143
|
+
this.emitLine(`"${(0, Strings_1.utf16StringEscape)(jsonName)}"`, property.isOptional ? "?" : "", ": ", this.underlyingTypeFor(property.type), ";");
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
this.emitLine("};");
|
|
147
|
+
this.emitLine("export const ", name, "Schema: z.ZodType<", name, "> = z.lazy(() =>");
|
|
148
|
+
}
|
|
149
|
+
this.indent(() => {
|
|
150
|
+
this.emitLine("z.object({");
|
|
151
|
+
this.indent(() => {
|
|
152
|
+
this.forEachClassProperty(t, "none", (_, jsonName, property) => {
|
|
153
|
+
this.emitLine(`"${(0, Strings_1.utf16StringEscape)(jsonName)}"`, ": ", this.typeMapTypeForProperty(property), ",");
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
this.emitLine("})");
|
|
157
|
+
});
|
|
158
|
+
this.emitLine(");");
|
|
159
|
+
}
|
|
88
160
|
emitEnum(e, enumName) {
|
|
89
161
|
this.ensureBlankLine();
|
|
90
162
|
this.emitDescription(this.descriptionForType(e));
|
|
@@ -164,10 +236,44 @@ class TypeScriptZodRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
164
236
|
});
|
|
165
237
|
mapChildTypeRefs.push(childTypeRefs);
|
|
166
238
|
});
|
|
239
|
+
// Find types that participate in a reference cycle: types from
|
|
240
|
+
// which we can get back to the same type by following child type
|
|
241
|
+
// references. Those can never be topologically ordered.
|
|
242
|
+
const indexForTypeRef = new Map();
|
|
243
|
+
mapTypeRef.forEach((typeRef, index) => indexForTypeRef.set(typeRef, index));
|
|
244
|
+
this._recursiveTypeRefs = new Set();
|
|
245
|
+
mapType.forEach((_, startIndex) => {
|
|
246
|
+
const visited = new Set();
|
|
247
|
+
const stack = [...mapChildTypeRefs[startIndex]];
|
|
248
|
+
while (stack.length > 0) {
|
|
249
|
+
const childRef = stack.pop();
|
|
250
|
+
const childIndex = indexForTypeRef.get(childRef);
|
|
251
|
+
if (childIndex === undefined)
|
|
252
|
+
continue;
|
|
253
|
+
if (childIndex === startIndex) {
|
|
254
|
+
this._recursiveTypeRefs.add(mapTypeRef[startIndex]);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
if (visited.has(childIndex))
|
|
258
|
+
continue;
|
|
259
|
+
visited.add(childIndex);
|
|
260
|
+
stack.push(...mapChildTypeRefs[childIndex]);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
167
263
|
// Items to process on this pass
|
|
168
264
|
let indices = [];
|
|
169
265
|
mapType.forEach((_, index) => {
|
|
170
|
-
|
|
266
|
+
if (this._recursiveTypeRefs.has(mapTypeRef[index])) {
|
|
267
|
+
// Recursive types are emitted first: they are wrapped in
|
|
268
|
+
// z.lazy(), so all their references to other schemas are
|
|
269
|
+
// deferred until parse time and don't constrain the
|
|
270
|
+
// output order, while other schemas can reference them
|
|
271
|
+
// directly.
|
|
272
|
+
order.push(index);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
indices.push(index);
|
|
276
|
+
}
|
|
171
277
|
});
|
|
172
278
|
// items to process on the next pass
|
|
173
279
|
let deferredIndices = [];
|
|
@@ -214,8 +320,9 @@ class TypeScriptZodRenderer extends ConvenienceRenderer_1.ConvenienceRenderer {
|
|
|
214
320
|
deferredIndices = [];
|
|
215
321
|
passNum++;
|
|
216
322
|
if (passNum > MAX_PASSES) {
|
|
217
|
-
// giving up
|
|
218
|
-
|
|
323
|
+
// giving up: emit the stuck items anyway rather than
|
|
324
|
+
// silently dropping them
|
|
325
|
+
order.push(...indices);
|
|
219
326
|
console.warn("Exceeded maximum number of passes when determining output order, output may contain forward references");
|
|
220
327
|
}
|
|
221
328
|
} while (indices.length > 0 && passNum <= MAX_PASSES);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quicktype-core",
|
|
3
|
-
"version": "23.3.
|
|
3
|
+
"version": "23.3.22",
|
|
4
4
|
"description": "The quicktype engine as a library",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"repository": "https://github.com/glideapps/quicktype",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"clean": "rm -rf dist node_modules *~",
|
|
11
|
-
"build": "
|
|
11
|
+
"build": "tsc"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@glideapps/ts-necessities": "2.2.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const fetch: any;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fetch = void 0;
|
|
4
|
-
// No logging here: this module runs at import time, and anything written to
|
|
5
|
-
// stdout corrupts redirected CLI output (issue #2874).
|
|
6
|
-
exports.fetch = require("cross-fetch").default;
|