@power-plant/schema 0.0.35 → 0.0.37
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/codegen.cjs +1 -1
- package/dist/codegen.d.cts +1 -1
- package/dist/codegen.d.mts +1 -1
- package/dist/codegen.mjs +7 -7
- package/dist/{constants-COGt3eeW.mjs → constants-BlppSDwG.mjs} +11 -2
- package/dist/constants-BlppSDwG.mjs.map +1 -0
- package/dist/{constants-B7xonHLD.cjs → constants-CEmLvTDd.cjs} +15 -0
- package/dist/{helpers-BQD6GZyX.cjs → helpers-DbFdMcOB.cjs} +22 -2
- package/dist/{helpers-dvxktFml.mjs → helpers-_8ADIMSN.mjs} +18 -4
- package/dist/helpers-_8ADIMSN.mjs.map +1 -0
- package/dist/index.cjs +577 -170
- package/dist/index.d.cts +31 -16
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +31 -16
- package/dist/index.mjs +577 -174
- package/dist/{types-CyvYSCHO.d.mts → types-BH-Q7QrB.d.cts} +112 -9
- package/dist/types-BH-Q7QrB.d.cts.map +1 -0
- package/dist/{types-hfHmxKG0.d.cts → types-BrSNvUQg.d.mts} +112 -9
- package/dist/types-BrSNvUQg.d.mts.map +1 -0
- package/dist/valibot.cjs +1 -1
- package/dist/valibot.d.cts +1 -1
- package/dist/valibot.d.mts +1 -1
- package/dist/valibot.mjs +1 -1
- package/dist/zod.cjs +2 -2
- package/dist/zod.d.cts +1 -1
- package/dist/zod.d.mts +1 -1
- package/dist/zod.mjs +2 -2
- package/package.json +22 -19
- package/dist/constants-COGt3eeW.mjs.map +0 -1
- package/dist/helpers-dvxktFml.mjs.map +0 -1
- package/dist/types-CyvYSCHO.d.mts.map +0 -1
- package/dist/types-hfHmxKG0.d.cts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_rolldown_runtime = require('./rolldown-runtime-C_NdSu1c.cjs');
|
|
3
|
-
const require_constants = require('./constants-
|
|
4
|
-
const require_helpers = require('./helpers-
|
|
3
|
+
const require_constants = require('./constants-CEmLvTDd.cjs');
|
|
4
|
+
const require_helpers = require('./helpers-DbFdMcOB.cjs');
|
|
5
|
+
const require_codegen = require('./codegen.cjs');
|
|
5
6
|
const require_storage = require('./storage-B8aDmNpv.cjs');
|
|
6
7
|
let _stryke_type_checks_is_set_object = require("@stryke/type-checks/is-set-object");
|
|
7
8
|
let _stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string");
|
|
8
9
|
let _stryke_type_checks = require("@stryke/type-checks");
|
|
10
|
+
let _deepkit_type = require("@deepkit/type");
|
|
11
|
+
let _deepkit_type_compiler = require("@deepkit/type-compiler");
|
|
9
12
|
let _stryke_convert_extract_file_reference = require("@stryke/convert/extract-file-reference");
|
|
10
13
|
let _stryke_fs_resolve = require("@stryke/fs/resolve");
|
|
11
14
|
let _stryke_hash = require("@stryke/hash");
|
|
12
15
|
let _stryke_helpers_deep_clone = require("@stryke/helpers/deep-clone");
|
|
16
|
+
let _stryke_helpers_omit = require("@stryke/helpers/omit");
|
|
13
17
|
let _stryke_json = require("@stryke/json");
|
|
14
18
|
let _stryke_path_append = require("@stryke/path/append");
|
|
15
19
|
let _stryke_path_find = require("@stryke/path/find");
|
|
16
20
|
let _stryke_path_join = require("@stryke/path/join");
|
|
17
|
-
let _stryke_resolve_bundle = require("@stryke/resolve/bundle");
|
|
18
21
|
let _stryke_resolve_constants = require("@stryke/resolve/constants");
|
|
19
22
|
let _stryke_resolve_load = require("@stryke/resolve/load");
|
|
20
|
-
let _stryke_resolve_resolve = require("@stryke/resolve/resolve");
|
|
21
23
|
let _stryke_string_format_list = require("@stryke/string-format/list");
|
|
22
24
|
let _stryke_zod = require("@stryke/zod");
|
|
23
25
|
let _valibot_to_json_schema = require("@valibot/to-json-schema");
|
|
24
26
|
let esbuild = require("esbuild");
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
+
let jiti = require("jiti");
|
|
28
|
+
let node_fs_promises = require("node:fs/promises");
|
|
27
29
|
let typescript = require("typescript");
|
|
28
30
|
typescript = require_rolldown_runtime.__toESM(typescript, 1);
|
|
31
|
+
let defu = require("defu");
|
|
32
|
+
defu = require_rolldown_runtime.__toESM(defu, 1);
|
|
29
33
|
|
|
30
34
|
//#region src/compatibility.ts
|
|
31
35
|
const METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -129,12 +133,415 @@ function assertSchemasDoNotContradict(base, override, label = "schema") {
|
|
|
129
133
|
if (issues.length > 0) throw new Error(`The ${label} schema contradicts the generator schema:\n${issues.map((issue) => `- ${issue}`).join("\n")}`);
|
|
130
134
|
}
|
|
131
135
|
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/reflection.ts
|
|
138
|
+
/**
|
|
139
|
+
* Maps a Deepkit numeric `brand` to JSON Schema `type` and `format`.
|
|
140
|
+
*
|
|
141
|
+
* @remarks
|
|
142
|
+
* This function takes a `TypeNumberBrand` (which represents specific numeric types in Deepkit, such as `integer`, `float`, `int8`, etc.) and returns a corresponding JSON Schema fragment that includes the appropriate `type`, `format`, and any relevant keywords (like `multipleOf` for integers). If the brand is not recognized, it defaults to a generic JSON Schema for numbers.
|
|
143
|
+
*
|
|
144
|
+
* @param brand - The Deepkit numeric brand to convert.
|
|
145
|
+
* @return A JSON Schema fragment representing the numeric type corresponding to the provided brand.
|
|
146
|
+
*/
|
|
147
|
+
function numberBrandToJsonSchema(brand) {
|
|
148
|
+
switch (brand) {
|
|
149
|
+
case _deepkit_type.TypeNumberBrand.integer: return {
|
|
150
|
+
type: "integer",
|
|
151
|
+
format: "int32",
|
|
152
|
+
multipleOf: 1
|
|
153
|
+
};
|
|
154
|
+
case _deepkit_type.TypeNumberBrand.int8: return {
|
|
155
|
+
type: "integer",
|
|
156
|
+
format: "int8",
|
|
157
|
+
multipleOf: 1
|
|
158
|
+
};
|
|
159
|
+
case _deepkit_type.TypeNumberBrand.uint8: return {
|
|
160
|
+
type: "integer",
|
|
161
|
+
format: "uint8",
|
|
162
|
+
multipleOf: 1
|
|
163
|
+
};
|
|
164
|
+
case _deepkit_type.TypeNumberBrand.int16: return {
|
|
165
|
+
type: "integer",
|
|
166
|
+
format: "int16",
|
|
167
|
+
multipleOf: 1
|
|
168
|
+
};
|
|
169
|
+
case _deepkit_type.TypeNumberBrand.uint16: return {
|
|
170
|
+
type: "integer",
|
|
171
|
+
format: "uint16",
|
|
172
|
+
multipleOf: 1
|
|
173
|
+
};
|
|
174
|
+
case _deepkit_type.TypeNumberBrand.int32: return {
|
|
175
|
+
type: "integer",
|
|
176
|
+
format: "int32",
|
|
177
|
+
multipleOf: 1
|
|
178
|
+
};
|
|
179
|
+
case _deepkit_type.TypeNumberBrand.uint32: return {
|
|
180
|
+
type: "integer",
|
|
181
|
+
format: "uint32",
|
|
182
|
+
multipleOf: 1
|
|
183
|
+
};
|
|
184
|
+
case _deepkit_type.TypeNumberBrand.float:
|
|
185
|
+
case _deepkit_type.TypeNumberBrand.float32: return {
|
|
186
|
+
type: "number",
|
|
187
|
+
format: "float"
|
|
188
|
+
};
|
|
189
|
+
case _deepkit_type.TypeNumberBrand.float64: return {
|
|
190
|
+
type: "number",
|
|
191
|
+
format: "double"
|
|
192
|
+
};
|
|
193
|
+
case void 0:
|
|
194
|
+
default: return { type: "number" };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function withReflectionTags(reflection, schema) {
|
|
198
|
+
if (!(0, _stryke_type_checks.isSetObject)(schema) || !(0, _stryke_type_checks.isSetObject)(reflection?.tags)) return schema;
|
|
199
|
+
const updatedSchema = { ...schema };
|
|
200
|
+
const tags = reflection.tags;
|
|
201
|
+
if ((0, _stryke_type_checks.isSetString)(tags.title)) updatedSchema.title = tags.title;
|
|
202
|
+
if ((0, _stryke_type_checks.isSetArray)(tags.alias)) updatedSchema.alias = tags.alias;
|
|
203
|
+
if (!(0, _stryke_type_checks.isUndefined)(tags.hidden)) updatedSchema.hidden = tags.hidden;
|
|
204
|
+
if (!(0, _stryke_type_checks.isUndefined)(tags.ignore)) updatedSchema.ignore = tags.ignore;
|
|
205
|
+
if (!(0, _stryke_type_checks.isUndefined)(tags.internal)) updatedSchema.internal = tags.internal;
|
|
206
|
+
if (!(0, _stryke_type_checks.isUndefined)(tags.runtime)) updatedSchema.runtime = tags.runtime;
|
|
207
|
+
if (!(0, _stryke_type_checks.isUndefined)(tags.readonly)) updatedSchema.readOnly = tags.readonly;
|
|
208
|
+
return updatedSchema;
|
|
209
|
+
}
|
|
210
|
+
function withNullable(schema) {
|
|
211
|
+
if (!(0, _stryke_type_checks.isSetObject)(schema)) return { anyOf: [schema, {
|
|
212
|
+
type: "null",
|
|
213
|
+
default: null
|
|
214
|
+
}] };
|
|
215
|
+
const rawType = schema.type;
|
|
216
|
+
const types = Array.isArray(rawType) ? [...rawType] : rawType ? [rawType] : [];
|
|
217
|
+
if (!types.includes("null")) types.push("null");
|
|
218
|
+
return {
|
|
219
|
+
...schema,
|
|
220
|
+
type: types.length === 1 ? types[0] : types
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Converts a Deepkit type reflection into a JSON Schema (draft-07) fragment.
|
|
225
|
+
*/
|
|
226
|
+
function reflectionToJsonSchema(reflection) {
|
|
227
|
+
return reflectionToJsonSchemaInner(reflection);
|
|
228
|
+
}
|
|
229
|
+
function reflectionToJsonSchemaInner(reflection) {
|
|
230
|
+
switch (reflection.kind) {
|
|
231
|
+
case _deepkit_type.ReflectionKind.any:
|
|
232
|
+
case _deepkit_type.ReflectionKind.unknown:
|
|
233
|
+
case _deepkit_type.ReflectionKind.void:
|
|
234
|
+
case _deepkit_type.ReflectionKind.object: return withReflectionTags(reflection, { name: reflection.typeName });
|
|
235
|
+
case _deepkit_type.ReflectionKind.never: return;
|
|
236
|
+
case _deepkit_type.ReflectionKind.undefined:
|
|
237
|
+
case _deepkit_type.ReflectionKind.null: return withReflectionTags(reflection, {
|
|
238
|
+
type: "null",
|
|
239
|
+
name: reflection.typeName,
|
|
240
|
+
default: null
|
|
241
|
+
});
|
|
242
|
+
case _deepkit_type.ReflectionKind.string: return withReflectionTags(reflection, {
|
|
243
|
+
type: "string",
|
|
244
|
+
name: reflection.typeName
|
|
245
|
+
});
|
|
246
|
+
case _deepkit_type.ReflectionKind.boolean: return withReflectionTags(reflection, {
|
|
247
|
+
type: "boolean",
|
|
248
|
+
name: reflection.typeName
|
|
249
|
+
});
|
|
250
|
+
case _deepkit_type.ReflectionKind.number: return withReflectionTags(reflection, numberBrandToJsonSchema(reflection.brand));
|
|
251
|
+
case _deepkit_type.ReflectionKind.bigint: return withReflectionTags(reflection, {
|
|
252
|
+
type: "integer",
|
|
253
|
+
name: reflection.typeName,
|
|
254
|
+
format: "int64"
|
|
255
|
+
});
|
|
256
|
+
case _deepkit_type.ReflectionKind.regexp: return withReflectionTags(reflection, {
|
|
257
|
+
type: "string",
|
|
258
|
+
name: reflection.typeName,
|
|
259
|
+
format: "regex",
|
|
260
|
+
contentMediaType: "text/regex"
|
|
261
|
+
});
|
|
262
|
+
case _deepkit_type.ReflectionKind.literal: {
|
|
263
|
+
const { literal } = reflection;
|
|
264
|
+
if ((0, _stryke_type_checks.isBigInt)(literal)) return withReflectionTags(reflection, {
|
|
265
|
+
type: "integer",
|
|
266
|
+
name: reflection.typeName,
|
|
267
|
+
format: "int64",
|
|
268
|
+
const: literal
|
|
269
|
+
});
|
|
270
|
+
if ((0, _stryke_type_checks.isRegExp)(literal)) return withReflectionTags(reflection, {
|
|
271
|
+
type: "string",
|
|
272
|
+
name: reflection.typeName,
|
|
273
|
+
format: "regex",
|
|
274
|
+
const: literal.source
|
|
275
|
+
});
|
|
276
|
+
return withReflectionTags(reflection, {
|
|
277
|
+
type: require_codegen.getJsonSchemaType(literal),
|
|
278
|
+
name: reflection.typeName,
|
|
279
|
+
const: literal
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
case _deepkit_type.ReflectionKind.templateLiteral: return withReflectionTags(reflection, { type: "string" });
|
|
283
|
+
case _deepkit_type.ReflectionKind.enum: {
|
|
284
|
+
const values = reflection.values.filter((value) => (0, _stryke_type_checks.isString)(value) || (0, _stryke_type_checks.isInteger)(value) || (0, _stryke_type_checks.isBigInt)(value) || (0, _stryke_type_checks.isNumber)(value) || (0, _stryke_type_checks.isBoolean)(value) || (0, _stryke_type_checks.isNull)(value));
|
|
285
|
+
if (values.length === 0) return withReflectionTags(reflection, {
|
|
286
|
+
name: reflection.typeName,
|
|
287
|
+
description: reflection.description,
|
|
288
|
+
enum: []
|
|
289
|
+
});
|
|
290
|
+
return withReflectionTags(reflection, {
|
|
291
|
+
type: values.every((value) => (0, _stryke_type_checks.isString)(value)) ? "string" : values.every((value) => (0, _stryke_type_checks.isInteger)(value) || (0, _stryke_type_checks.isBigInt)(value)) ? "integer" : values.every((value) => (0, _stryke_type_checks.isNumber)(value)) ? "number" : values.every((value) => (0, _stryke_type_checks.isBoolean)(value)) ? "boolean" : values.every((value) => (0, _stryke_type_checks.isNull)(value)) ? "null" : values.reduce((ret, value) => {
|
|
292
|
+
const type = require_codegen.getJsonSchemaType(value);
|
|
293
|
+
if (require_helpers.isJsonSchemaPrimitiveType(type) && !ret.includes(type)) ret.push(type);
|
|
294
|
+
return ret;
|
|
295
|
+
}, []),
|
|
296
|
+
name: reflection.typeName,
|
|
297
|
+
description: reflection.description,
|
|
298
|
+
enum: values,
|
|
299
|
+
default: values.length === 1 ? values[0] : void 0
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
case _deepkit_type.ReflectionKind.array: {
|
|
303
|
+
const items = reflectionToJsonSchemaInner(reflection.type);
|
|
304
|
+
return withReflectionTags(reflection, {
|
|
305
|
+
type: "array",
|
|
306
|
+
name: reflection.typeName,
|
|
307
|
+
items: items ?? {}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
case _deepkit_type.ReflectionKind.tuple: {
|
|
311
|
+
const items = reflection.types.map((member) => reflectionToJsonSchemaInner(member.type)).filter((item) => item !== void 0);
|
|
312
|
+
if (items.length <= 1) return withReflectionTags(reflection, {
|
|
313
|
+
type: "array",
|
|
314
|
+
name: reflection.typeName,
|
|
315
|
+
items: items.length === 1 ? items[0] : {}
|
|
316
|
+
});
|
|
317
|
+
return withReflectionTags(reflection, {
|
|
318
|
+
type: "array",
|
|
319
|
+
name: reflection.typeName,
|
|
320
|
+
prefixItems: items,
|
|
321
|
+
minItems: items.length,
|
|
322
|
+
maxItems: items.length
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
case _deepkit_type.ReflectionKind.union: {
|
|
326
|
+
const branches = reflection.types.map((inner) => reflectionToJsonSchemaInner(inner)).filter((branch) => branch !== void 0);
|
|
327
|
+
if (!reflection.types.some((inner) => inner.kind === _deepkit_type.ReflectionKind.null || inner.kind === _deepkit_type.ReflectionKind.undefined)) return withReflectionTags(reflection, {
|
|
328
|
+
name: reflection.typeName,
|
|
329
|
+
anyOf: branches
|
|
330
|
+
});
|
|
331
|
+
const nonNull = branches.filter((branch) => !require_helpers.isNullOnlyJsonSchema(branch));
|
|
332
|
+
if (nonNull.length === 0) return withReflectionTags(reflection, {
|
|
333
|
+
type: "null",
|
|
334
|
+
default: null
|
|
335
|
+
});
|
|
336
|
+
if (nonNull.length === 1) {
|
|
337
|
+
const first = nonNull[0];
|
|
338
|
+
if (!(0, _stryke_type_checks.isSetObject)(first)) return withNullable(withReflectionTags(reflection, {
|
|
339
|
+
name: reflection.typeName,
|
|
340
|
+
anyOf: [first]
|
|
341
|
+
}));
|
|
342
|
+
return withNullable(withReflectionTags(reflection, {
|
|
343
|
+
name: reflection.typeName,
|
|
344
|
+
...first
|
|
345
|
+
}));
|
|
346
|
+
}
|
|
347
|
+
const enumValues = nonNull.map((branch) => (0, _stryke_type_checks.isSetObject)(branch) ? branch.const : void 0).filter((value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean");
|
|
348
|
+
if (enumValues.length === nonNull.length) return withNullable(withReflectionTags(reflection, {
|
|
349
|
+
name: reflection.typeName,
|
|
350
|
+
enum: enumValues
|
|
351
|
+
}));
|
|
352
|
+
const discriminator = tryReflectionDiscriminator(reflection.types);
|
|
353
|
+
if (discriminator && (0, _stryke_type_checks.isSetObject)(discriminator)) return withNullable(withReflectionTags(reflection, {
|
|
354
|
+
name: reflection.typeName,
|
|
355
|
+
...discriminator
|
|
356
|
+
}));
|
|
357
|
+
return withNullable(withReflectionTags(reflection, {
|
|
358
|
+
name: reflection.typeName,
|
|
359
|
+
anyOf: nonNull
|
|
360
|
+
}));
|
|
361
|
+
}
|
|
362
|
+
case _deepkit_type.ReflectionKind.intersection: {
|
|
363
|
+
const members = reflection.types.map((inner) => reflectionToJsonSchemaInner(inner)).filter((item) => item !== void 0);
|
|
364
|
+
if (members.length === 0) return;
|
|
365
|
+
if (members.length === 1) {
|
|
366
|
+
if (!(0, _stryke_type_checks.isSetObject)(members[0])) return members[0];
|
|
367
|
+
return withReflectionTags(reflection, {
|
|
368
|
+
name: reflection.typeName,
|
|
369
|
+
...members[0]
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
if (members.every(require_helpers.isJsonSchemaObject)) return withReflectionTags(reflection, {
|
|
373
|
+
name: reflection.typeName,
|
|
374
|
+
...mergeObjectSchemas(members)
|
|
375
|
+
});
|
|
376
|
+
return withReflectionTags(reflection, {
|
|
377
|
+
name: reflection.typeName,
|
|
378
|
+
allOf: members
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
case _deepkit_type.ReflectionKind.promise: return reflectionToJsonSchemaInner(reflection.type);
|
|
382
|
+
case _deepkit_type.ReflectionKind.objectLiteral: return objectReflectionToJsonSchema(reflection);
|
|
383
|
+
case _deepkit_type.ReflectionKind.class: switch (reflection.classType?.name) {
|
|
384
|
+
case "Date": return withReflectionTags(reflection, {
|
|
385
|
+
type: "string",
|
|
386
|
+
format: "date-time"
|
|
387
|
+
});
|
|
388
|
+
case "RegExp": return withReflectionTags(reflection, {
|
|
389
|
+
type: "string",
|
|
390
|
+
format: "regex"
|
|
391
|
+
});
|
|
392
|
+
case "URL": return withReflectionTags(reflection, {
|
|
393
|
+
type: "string",
|
|
394
|
+
format: "uri"
|
|
395
|
+
});
|
|
396
|
+
case "Set": {
|
|
397
|
+
const itemType = reflection.arguments?.[0];
|
|
398
|
+
return withReflectionTags(reflection, {
|
|
399
|
+
type: "array",
|
|
400
|
+
items: (itemType ? reflectionToJsonSchemaInner(itemType) : void 0) ?? {},
|
|
401
|
+
uniqueItems: true
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
case "Map": {
|
|
405
|
+
const valueType = reflection.arguments?.[1];
|
|
406
|
+
return withReflectionTags(reflection, {
|
|
407
|
+
type: "object",
|
|
408
|
+
additionalProperties: (valueType ? reflectionToJsonSchemaInner(valueType) : void 0) ?? true
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
case "Uint8Array":
|
|
412
|
+
case "Uint8ClampedArray":
|
|
413
|
+
case "Uint16Array":
|
|
414
|
+
case "Uint32Array":
|
|
415
|
+
case "Int8Array":
|
|
416
|
+
case "Int16Array":
|
|
417
|
+
case "Int32Array":
|
|
418
|
+
case "Float32Array":
|
|
419
|
+
case "Float64Array":
|
|
420
|
+
case "BigInt64Array":
|
|
421
|
+
case "BigUint64Array": return withReflectionTags(reflection, {
|
|
422
|
+
type: "string",
|
|
423
|
+
format: "byte",
|
|
424
|
+
contentEncoding: "base64"
|
|
425
|
+
});
|
|
426
|
+
case void 0:
|
|
427
|
+
default: return withReflectionTags(reflection, {
|
|
428
|
+
name: reflection.typeName,
|
|
429
|
+
description: reflection.description,
|
|
430
|
+
...objectReflectionToJsonSchema(reflection)
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
case _deepkit_type.ReflectionKind.symbol:
|
|
434
|
+
case _deepkit_type.ReflectionKind.property:
|
|
435
|
+
case _deepkit_type.ReflectionKind.method:
|
|
436
|
+
case _deepkit_type.ReflectionKind.function:
|
|
437
|
+
case _deepkit_type.ReflectionKind.parameter:
|
|
438
|
+
case _deepkit_type.ReflectionKind.typeParameter:
|
|
439
|
+
case _deepkit_type.ReflectionKind.tupleMember:
|
|
440
|
+
case _deepkit_type.ReflectionKind.enumMember:
|
|
441
|
+
case _deepkit_type.ReflectionKind.rest:
|
|
442
|
+
case _deepkit_type.ReflectionKind.indexSignature:
|
|
443
|
+
case _deepkit_type.ReflectionKind.propertySignature:
|
|
444
|
+
case _deepkit_type.ReflectionKind.methodSignature:
|
|
445
|
+
case _deepkit_type.ReflectionKind.infer:
|
|
446
|
+
case _deepkit_type.ReflectionKind.callSignature:
|
|
447
|
+
default: return;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function mergeObjectSchemas(schemas) {
|
|
451
|
+
const merged = {
|
|
452
|
+
type: "object",
|
|
453
|
+
properties: {},
|
|
454
|
+
required: []
|
|
455
|
+
};
|
|
456
|
+
for (const schema of schemas) {
|
|
457
|
+
if (schema.properties) merged.properties = (0, defu.default)(merged.properties, schema.properties);
|
|
458
|
+
if (schema.required) merged.required = Array.from(/* @__PURE__ */ new Set([...merged.required ?? [], ...schema.required]));
|
|
459
|
+
if (schema.additionalProperties !== void 0) merged.additionalProperties = schema.additionalProperties;
|
|
460
|
+
}
|
|
461
|
+
if ((merged.required?.length ?? 0) === 0) delete merged.required;
|
|
462
|
+
return merged;
|
|
463
|
+
}
|
|
464
|
+
function tryReflectionDiscriminator(types) {
|
|
465
|
+
const nonNullTypes = types.filter((t) => t.kind !== _deepkit_type.ReflectionKind.null && t.kind !== _deepkit_type.ReflectionKind.undefined);
|
|
466
|
+
const objectBranches = nonNullTypes.filter((t) => t.kind === _deepkit_type.ReflectionKind.objectLiteral || t.kind === _deepkit_type.ReflectionKind.class);
|
|
467
|
+
if (objectBranches.length < 2 || objectBranches.length !== nonNullTypes.length) return;
|
|
468
|
+
let tagKey;
|
|
469
|
+
const branches = [];
|
|
470
|
+
for (const branch of objectBranches) {
|
|
471
|
+
const literalProps = [];
|
|
472
|
+
for (const member of branch.types) if ((member.kind === _deepkit_type.ReflectionKind.property || member.kind === _deepkit_type.ReflectionKind.propertySignature) && typeof member.name === "string" && member.type.kind === _deepkit_type.ReflectionKind.literal && typeof member.type.literal === "string") literalProps.push({
|
|
473
|
+
name: member.name,
|
|
474
|
+
literal: member.type.literal
|
|
475
|
+
});
|
|
476
|
+
if (literalProps.length === 0) return;
|
|
477
|
+
const first = literalProps[0];
|
|
478
|
+
if (!tagKey) tagKey = first.name;
|
|
479
|
+
else if (tagKey !== first.name) return;
|
|
480
|
+
const body = objectReflectionToJsonSchema({
|
|
481
|
+
...branch,
|
|
482
|
+
types: branch.types.filter((member) => !((member.kind === _deepkit_type.ReflectionKind.property || member.kind === _deepkit_type.ReflectionKind.propertySignature) && member.name === tagKey))
|
|
483
|
+
});
|
|
484
|
+
if (!body || !require_helpers.isJsonSchemaObject(body)) return;
|
|
485
|
+
branches.push({
|
|
486
|
+
type: "object",
|
|
487
|
+
properties: {
|
|
488
|
+
[tagKey]: { const: first.literal },
|
|
489
|
+
...body.properties ?? {}
|
|
490
|
+
},
|
|
491
|
+
required: [tagKey, ...body.required ?? []],
|
|
492
|
+
additionalProperties: body.additionalProperties ?? false
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
if (!tagKey) return;
|
|
496
|
+
return {
|
|
497
|
+
oneOf: branches,
|
|
498
|
+
discriminator: { propertyName: tagKey }
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function objectReflectionToJsonSchema(type) {
|
|
502
|
+
const reflection = _deepkit_type.ReflectionClass.from(type);
|
|
503
|
+
const schema = {
|
|
504
|
+
type: "object",
|
|
505
|
+
name: reflection.getName(),
|
|
506
|
+
description: reflection.getDescription(),
|
|
507
|
+
properties: {},
|
|
508
|
+
required: [],
|
|
509
|
+
primaryKey: reflection.getPrimaries().map((primary) => primary.getNameAsString()),
|
|
510
|
+
...(0, _stryke_type_checks.isSetString)(reflection.databaseSchemaName) ? { databaseSchemaName: reflection.databaseSchemaName } : {},
|
|
511
|
+
...(0, _stryke_type_checks.isSetString)(reflection.getName()) ? { name: reflection.getName() } : {},
|
|
512
|
+
...(0, _stryke_type_checks.isSetString)(reflection.getDescription()) ? { description: reflection.getDescription() } : {}
|
|
513
|
+
};
|
|
514
|
+
for (const propertyReflection of reflection.getProperties()) {
|
|
515
|
+
if (propertyReflection.getKind() === _deepkit_type.ReflectionKind.indexSignature) {
|
|
516
|
+
schema.additionalProperties = reflectionToJsonSchemaInner(propertyReflection.type) ?? true;
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
let property = reflectionToJsonSchemaInner(propertyReflection.type);
|
|
520
|
+
if (!property) continue;
|
|
521
|
+
const propertySchema = (0, _stryke_type_checks.isSetObject)(property) ? property : {};
|
|
522
|
+
const groups = propertyReflection.getGroups();
|
|
523
|
+
property = {
|
|
524
|
+
...propertySchema,
|
|
525
|
+
name: propertyReflection.getNameAsString(),
|
|
526
|
+
description: propertyReflection.getDescription(),
|
|
527
|
+
readOnly: propertyReflection.isReadonly(),
|
|
528
|
+
...propertyReflection.hasDefault() ? { default: propertyReflection.getDefaultValue() } : {},
|
|
529
|
+
...(0, _stryke_type_checks.isSetArray)(groups) ? { tags: groups } : {}
|
|
530
|
+
};
|
|
531
|
+
if (propertyReflection.isNullable()) property = withNullable(property);
|
|
532
|
+
schema.properties ??= {};
|
|
533
|
+
schema.properties[propertyReflection.name] = property;
|
|
534
|
+
if (!propertyReflection.isOptional()) {
|
|
535
|
+
schema.required ??= [];
|
|
536
|
+
schema.required.push(propertyReflection.name);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return schema;
|
|
540
|
+
}
|
|
541
|
+
|
|
132
542
|
//#endregion
|
|
133
543
|
//#region src/extract.ts
|
|
134
544
|
const SCHEMA_BUNDLE_BASE_URI = "https://power-plant.invalid/";
|
|
135
|
-
function normalizePath(filePath) {
|
|
136
|
-
return filePath.replaceAll("\\", "/");
|
|
137
|
-
}
|
|
138
545
|
function isWrappedSchemaConfig(input) {
|
|
139
546
|
if (!(0, _stryke_type_checks_is_set_object.isSetObject)(input) || !("schema" in input)) return false;
|
|
140
547
|
if ("hash" in input || "variant" in input || "source" in input) return false;
|
|
@@ -337,6 +744,10 @@ function extractHash(variant, input) {
|
|
|
337
744
|
variant,
|
|
338
745
|
input: unwrappedConfig._def
|
|
339
746
|
});
|
|
747
|
+
else if ((0, _deepkit_type.isType)(unwrappedConfig)) return (0, _stryke_hash.murmurhash)({
|
|
748
|
+
variant,
|
|
749
|
+
input: (0, _deepkit_type.stringifyType)(unwrappedConfig)
|
|
750
|
+
});
|
|
340
751
|
else if ((0, _stryke_json.isStandardJsonSchema)(unwrappedConfig)) return (0, _stryke_hash.murmurhash)({
|
|
341
752
|
variant,
|
|
342
753
|
input: unwrappedConfig["~standard"]
|
|
@@ -361,6 +772,13 @@ function extractHash(variant, input) {
|
|
|
361
772
|
throw new Error(`Failed to create an input hash for the provided schema definition input. The input must be a Zod schema, a Standard JSON Schema, a JSON Schema object, a Valibot BaseSchema, or a reflected Deepkit Type object.`);
|
|
362
773
|
}
|
|
363
774
|
/**
|
|
775
|
+
* Converts a reflected Deepkit {@link Type} into a JSON Schema (draft-2020-12) representation.
|
|
776
|
+
*/
|
|
777
|
+
function extractReflection(reflection) {
|
|
778
|
+
if (!(0, _deepkit_type.isType)(reflection)) return;
|
|
779
|
+
return reflectionToJsonSchema(reflection);
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
364
782
|
* Extracts a JSON Schema from Zod, Standard Schema, Valibot, untyped, or JSON Schema inputs.
|
|
365
783
|
*
|
|
366
784
|
* @param schema - The schema input to extract a JSON Schema from.
|
|
@@ -386,6 +804,7 @@ function extractJsonSchema(schema) {
|
|
|
386
804
|
function extractResolvedVariant(input) {
|
|
387
805
|
if ((0, _stryke_type_checks_is_set_object.isSetObject)(input)) {
|
|
388
806
|
if ((0, _stryke_zod.isZod3Type)(input)) return "zod3";
|
|
807
|
+
else if ((0, _deepkit_type.isType)(input)) return "reflection";
|
|
389
808
|
else if (require_helpers.isUntypedConfigStrict(input) || require_helpers.isUntypedSchemaStrict(input)) return "untyped";
|
|
390
809
|
else if ((0, _stryke_json.isStandardJsonSchema)(input)) return "standard-schema";
|
|
391
810
|
else if (require_helpers.isJsonSchema(input)) return "json-schema";
|
|
@@ -418,6 +837,7 @@ async function extractSchema(input, variant) {
|
|
|
418
837
|
const resolvedVariant = variant ?? extractResolvedVariant(input);
|
|
419
838
|
let schema;
|
|
420
839
|
if (resolvedVariant === "zod3" || resolvedVariant === "json-schema" || resolvedVariant === "standard-schema" || resolvedVariant === "untyped" || resolvedVariant === "valibot") schema = extractJsonSchema(input);
|
|
840
|
+
else if (resolvedVariant === "reflection") schema = extractReflection(input);
|
|
421
841
|
if (schema) return bundleReferences(schema);
|
|
422
842
|
throw new Error(`Failed to extract a valid schema from the provided input. The input must be a Zod schema, a Standard JSON Schema, a JSON Schema object, a Valibot BaseSchema, an untyped schema, or a reflected Deepkit Type object.`);
|
|
423
843
|
}
|
|
@@ -455,191 +875,166 @@ function extractSource(variant, input) {
|
|
|
455
875
|
variant: "valibot",
|
|
456
876
|
schema: input
|
|
457
877
|
};
|
|
878
|
+
else if (variant === "reflection") return {
|
|
879
|
+
hash: extractHash(variant, input),
|
|
880
|
+
variant: "reflection",
|
|
881
|
+
schema: input
|
|
882
|
+
};
|
|
458
883
|
throw new Error(`Failed to extract source information from the provided input. The input must be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object.`);
|
|
459
884
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
885
|
+
const deepkitCache = new _deepkit_type_compiler.Cache();
|
|
886
|
+
function rewriteTypeOnlyImports(source) {
|
|
887
|
+
return source.replaceAll(/\bimport\s+type\s+/g, "import ").replaceAll(/\bexport\s+type\s+\*\s+from/g, "export * from").replaceAll(/\bexport\s+type\s+\{/g, "export {");
|
|
888
|
+
}
|
|
889
|
+
function resolveReflectionConfig(options) {
|
|
890
|
+
return {
|
|
891
|
+
reflection: options.reflection ?? "default",
|
|
892
|
+
exclude: options.exclude
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
function getCompilerOptions(options) {
|
|
896
|
+
const cwd = options.cwd || process.cwd();
|
|
897
|
+
const tsconfigPath = options.tsconfig ? (0, _stryke_path_append.appendPath)(options.tsconfig, cwd) : (0, _stryke_path_join.joinPaths)(cwd, "tsconfig.json");
|
|
898
|
+
try {
|
|
899
|
+
const raw = typescript.default.sys.readFile(tsconfigPath);
|
|
900
|
+
if (raw) {
|
|
901
|
+
const parsed = typescript.default.parseConfigFileTextToJson(tsconfigPath, raw);
|
|
902
|
+
if (parsed.config) return {
|
|
903
|
+
...typescript.default.parseJsonConfigFileContent(parsed.config, typescript.default.sys, (0, _stryke_path_find.findFilePath)(tsconfigPath) || cwd, {}, tsconfigPath).options,
|
|
904
|
+
noEmit: true,
|
|
905
|
+
experimentalDecorators: true,
|
|
906
|
+
emitDecoratorMetadata: true
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
} catch {}
|
|
477
910
|
return {
|
|
478
|
-
noEmit: true,
|
|
479
|
-
emitDecoratorMetadata: true,
|
|
480
|
-
experimentalDecorators: true,
|
|
481
911
|
target: typescript.default.ScriptTarget.ES2022,
|
|
482
912
|
module: typescript.default.ModuleKind.ESNext,
|
|
483
913
|
moduleResolution: typescript.default.ModuleResolutionKind.Bundler,
|
|
484
|
-
strictNullChecks:
|
|
914
|
+
strictNullChecks: true,
|
|
915
|
+
experimentalDecorators: true,
|
|
916
|
+
emitDecoratorMetadata: true,
|
|
485
917
|
skipLibCheck: true,
|
|
486
|
-
skipDefaultLibCheck: true,
|
|
487
918
|
esModuleInterop: true,
|
|
488
|
-
|
|
919
|
+
noEmit: true
|
|
489
920
|
};
|
|
490
921
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
case "jsx": return typescript.default.ScriptKind.JSX;
|
|
502
|
-
case "js":
|
|
503
|
-
case "cjs":
|
|
504
|
-
case "mjs": return typescript.default.ScriptKind.JS;
|
|
505
|
-
default: return typescript.default.ScriptKind.TS;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* Uses esbuild (with `@stryke/resolve` path resolution) to walk the module
|
|
510
|
-
* graph, capturing original TypeScript sources before types are erased.
|
|
511
|
-
*/
|
|
512
|
-
async function bundleTypeScriptSources(filePath, options) {
|
|
513
|
-
const cwd = options.cwd || process.cwd();
|
|
514
|
-
const sources = /* @__PURE__ */ new Map();
|
|
515
|
-
const result = await (0, esbuild.build)({
|
|
516
|
-
absWorkingDir: cwd,
|
|
517
|
-
entryPoints: [filePath],
|
|
518
|
-
bundle: true,
|
|
519
|
-
write: false,
|
|
520
|
-
platform: "node",
|
|
521
|
-
format: "esm",
|
|
522
|
-
logLevel: "silent",
|
|
523
|
-
packages: "external",
|
|
524
|
-
plugins: [{
|
|
525
|
-
name: "power-plant-capture-ts-sources",
|
|
526
|
-
setup(buildApi) {
|
|
527
|
-
buildApi.onLoad({ filter: /.*/ }, async (args) => {
|
|
528
|
-
if (/[/\\]node_modules[/\\]/.test(args.path)) return null;
|
|
529
|
-
try {
|
|
530
|
-
const original = await (0, _stryke_resolve_resolve.resolve)(args.path, {
|
|
531
|
-
skipBundle: true,
|
|
532
|
-
cwd,
|
|
533
|
-
fs: options.fs
|
|
534
|
-
});
|
|
535
|
-
sources.set(normalizePath(args.path), original);
|
|
536
|
-
const extension = (0, _stryke_path_find.findFileExtensionSafe)(args.path);
|
|
537
|
-
const loader = extension === "tsx" || extension === "jsx" ? extension : extension === "js" || extension === "cjs" || extension === "mjs" ? "js" : "ts";
|
|
538
|
-
return {
|
|
539
|
-
contents: rewriteTypeOnlyImports(original),
|
|
540
|
-
loader
|
|
541
|
-
};
|
|
542
|
-
} catch {
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
}, (0, _stryke_resolve_bundle.plugin)({
|
|
548
|
-
originalInput: filePath,
|
|
549
|
-
cwd,
|
|
550
|
-
fs: options.fs ?? {}
|
|
551
|
-
})]
|
|
922
|
+
function transpileWithDeepkit(code, fileName, options) {
|
|
923
|
+
const reflectionConfig = resolveReflectionConfig(options);
|
|
924
|
+
deepkitCache.tick();
|
|
925
|
+
return typescript.default.transpileModule(code, {
|
|
926
|
+
compilerOptions: getCompilerOptions(options),
|
|
927
|
+
fileName,
|
|
928
|
+
transformers: {
|
|
929
|
+
before: [(context) => new _deepkit_type_compiler.ReflectionTransformer(context, deepkitCache).withReflection(reflectionConfig)],
|
|
930
|
+
after: [(context) => new _deepkit_type_compiler.DeclarationTransformer(context, deepkitCache).withReflection(reflectionConfig)]
|
|
931
|
+
}
|
|
552
932
|
});
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
sources.set(normalizePath(filePath), fallback);
|
|
933
|
+
}
|
|
934
|
+
async function readSourceFile(path, fs) {
|
|
935
|
+
try {
|
|
936
|
+
if (fs?.promises?.readFile) return await fs.promises.readFile(path, "utf8");
|
|
937
|
+
return await (0, node_fs_promises.readFile)(path, "utf8");
|
|
938
|
+
} catch {
|
|
939
|
+
return;
|
|
561
940
|
}
|
|
562
|
-
return {
|
|
563
|
-
entryFileName: filePath,
|
|
564
|
-
sources
|
|
565
|
-
};
|
|
566
941
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
942
|
+
function createDeepkitPlugin(options) {
|
|
943
|
+
return {
|
|
944
|
+
name: "power-plant:deepkit",
|
|
945
|
+
setup(pluginBuild) {
|
|
946
|
+
pluginBuild.onLoad({ filter: /\.(m|c)?tsx?$/ }, async (args) => {
|
|
947
|
+
if (args.pluginData?.isReflected) {
|
|
948
|
+
const contents = await readSourceFile(args.path, options.fs);
|
|
949
|
+
if (!contents) return null;
|
|
950
|
+
return {
|
|
951
|
+
contents,
|
|
952
|
+
loader: "ts",
|
|
953
|
+
pluginData: { isReflected: true }
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
const raw = await readSourceFile(args.path, options.fs);
|
|
957
|
+
if (!raw) return null;
|
|
958
|
+
const result = transpileWithDeepkit(rewriteTypeOnlyImports(raw), args.path, options);
|
|
959
|
+
if (result.diagnostics?.length) {
|
|
960
|
+
const errors = result.diagnostics.filter((diagnostic) => diagnostic.category === typescript.DiagnosticCategory.Error);
|
|
961
|
+
if (errors.length > 0) {
|
|
962
|
+
const errorMessage = `Deepkit Type reflection transpilation errors: ${args.path} \n ${errors.map((diagnostic) => `-${diagnostic.file ? `${diagnostic.file.fileName}:` : ""} ${typeof diagnostic.messageText === "string" ? diagnostic.messageText : diagnostic.messageText.messageText} (at ${diagnostic.start}:${diagnostic.length})`).join("\n")}`;
|
|
963
|
+
options.logger?.error?.(errorMessage);
|
|
964
|
+
throw new Error(errorMessage);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
return {
|
|
968
|
+
contents: result.outputText,
|
|
969
|
+
loader: "ts",
|
|
970
|
+
pluginData: { isReflected: true }
|
|
971
|
+
};
|
|
972
|
+
});
|
|
586
973
|
}
|
|
587
|
-
return baseGetSourceFile(name, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
|
|
588
974
|
};
|
|
589
|
-
const program = typescript.default.createProgram([entryFileName], compilerOptions, host);
|
|
590
|
-
if (!config.skipTypeCheck) {
|
|
591
|
-
const diagnostics = typescript.default.getPreEmitDiagnostics(program);
|
|
592
|
-
if (diagnostics.length) throw new Error(`Type check error: ${diagnostics.map((diagnostic) => diagnostic.messageText.toString()).join("\n")}`);
|
|
593
|
-
}
|
|
594
|
-
return program;
|
|
595
975
|
}
|
|
596
976
|
/**
|
|
597
|
-
* Resolves a type definition to a JSON Schema.
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
* [ts-json-schema-generator](https://github.com/vega/ts-json-schema-generator)
|
|
601
|
-
* using the referenced export name as the target type when one is provided.
|
|
977
|
+
* Resolves a type definition to a JSON Schema. Bundles the TypeScript module
|
|
978
|
+
* graph with esbuild using `@deepkit/type-compiler` reflection transformers,
|
|
979
|
+
* then converts the reflected Deepkit {@link Type} via {@link reflectionToJsonSchema}.
|
|
602
980
|
*
|
|
603
981
|
* @param input - The type definition to compile. This can be either a string or a {@link FileReference} object.
|
|
604
|
-
* @param options - Optional overrides
|
|
982
|
+
* @param options - Optional overrides for reflection and file resolution.
|
|
605
983
|
* @returns A promise that resolves to the generated JSON Schema.
|
|
984
|
+
* @see https://deepkit.io/en/documentation/runtime-types/reflection
|
|
606
985
|
*/
|
|
607
986
|
async function extractTSType(input, options = {}) {
|
|
608
987
|
const fileReference = (0, _stryke_convert_extract_file_reference.extractFileReference)(input);
|
|
609
988
|
if (!fileReference) throw new Error(`Failed to extract a file reference from the provided input. The input must be a string or an object with a "file" property that specifies the file path and optional export name.`);
|
|
610
|
-
const exportName = fileReference.export ?? "
|
|
989
|
+
const exportName = fileReference.export ?? "default";
|
|
611
990
|
const resolvedPath = await (0, _stryke_fs_resolve.resolveSafe)(fileReference.file, { fs: options.fs });
|
|
612
991
|
const filePath = resolvedPath || fileReference.file;
|
|
992
|
+
const cwd = options.cwd || process.cwd();
|
|
613
993
|
try {
|
|
614
|
-
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
994
|
+
options.logger?.debug?.(`Generating JSON schema for bundled "${filePath}" using the type "${exportName}"`);
|
|
995
|
+
const result = await (0, esbuild.build)({
|
|
996
|
+
platform: "node",
|
|
997
|
+
format: "esm",
|
|
998
|
+
logLevel: "silent",
|
|
999
|
+
entryPoints: [filePath],
|
|
1000
|
+
write: false,
|
|
1001
|
+
sourcemap: false,
|
|
1002
|
+
splitting: false,
|
|
1003
|
+
treeShaking: true,
|
|
1004
|
+
bundle: true,
|
|
1005
|
+
packages: "bundle",
|
|
1006
|
+
keepNames: true,
|
|
1007
|
+
metafile: false,
|
|
1008
|
+
absWorkingDir: cwd,
|
|
1009
|
+
plugins: [createDeepkitPlugin(options)]
|
|
618
1010
|
});
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
1011
|
+
if (result.errors.length > 0) throw new Error(result.errors.map((error) => error.text).join(", "));
|
|
1012
|
+
const bundled = result.outputFiles?.filter(Boolean)[0]?.text;
|
|
1013
|
+
if (!(0, _stryke_type_checks.isSetString)(bundled)) throw new Error(`No output files generated for "${filePath}". Please check the configuration and try again.`);
|
|
1014
|
+
const evaluated = await (0, jiti.createJiti)(cwd).evalModule(bundled, {
|
|
1015
|
+
filename: filePath,
|
|
1016
|
+
ext: (0, _stryke_path_find.findFileDotExtensionSafe)(filePath) || ".ts"
|
|
1017
|
+
});
|
|
1018
|
+
let resolved = evaluated[exportName] ?? evaluated[`__Ω${exportName}`];
|
|
1019
|
+
if (resolved === void 0) throw new Error(`The export "${exportName}" could not be resolved in the "${filePath}" module. ${Object.keys(evaluated).length === 0 ? `After bundling, no exports were found in the module.` : `After bundling, the available exports were: ${Object.keys(evaluated).join(", ")}.`}`);
|
|
1020
|
+
try {
|
|
1021
|
+
const type = (0, _deepkit_type.reflect)(resolved);
|
|
1022
|
+
if ((0, _deepkit_type.isType)(type)) resolved = type;
|
|
1023
|
+
} catch {}
|
|
1024
|
+
if ((0, _deepkit_type.isType)(resolved)) {
|
|
1025
|
+
const schema = extractReflection(resolved);
|
|
1026
|
+
if (!schema) throw new Error(`Failed to convert the reflected Deepkit type for "${exportName}" to JSON Schema.`);
|
|
1027
|
+
return schema;
|
|
1028
|
+
}
|
|
1029
|
+
const schema = extractJsonSchema(resolved);
|
|
1030
|
+
if (!schema) throw new Error(`The export "${exportName}" could not be converted to a JSON Schema.`);
|
|
1031
|
+
return schema;
|
|
637
1032
|
} catch (error) {
|
|
638
1033
|
throw new Error(`Failed to generate a JSON schema for "${fileReference.file}"${resolvedPath && resolvedPath !== fileReference.file ? ` (resolved: ${resolvedPath})` : ""} using the type "${exportName}". Error: ${error.message}`);
|
|
639
1034
|
}
|
|
640
1035
|
}
|
|
641
1036
|
/**
|
|
642
|
-
* Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a {@link FileReferenceInput} to an exported TypeScript type definition or any of the previous options. If the input is a {@link FileReferenceInput} (e.g. a file path with an export), the source code will be bundled with [esbuild](esbuild.github.io) using [
|
|
1037
|
+
* Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, a Deepkit Type object, or a {@link FileReferenceInput} to an exported TypeScript type definition or any of the previous options. If the input is a {@link FileReferenceInput} (e.g. a file path with an export), the source code will be bundled with [esbuild](https://esbuild.github.io) using [@deepkit/type-compiler](https://deepkit.io/en/documentation/runtime-types/getting-started) reflection to obtain the actual schema definition before extraction.
|
|
643
1038
|
*
|
|
644
1039
|
* @example
|
|
645
1040
|
* ```ts
|
|
@@ -653,8 +1048,8 @@ async function extractTSType(input, options = {}) {
|
|
|
653
1048
|
* const schema4 = await extract(context, zodSchema);
|
|
654
1049
|
* // Resolve a schema definition from a Valibot schema
|
|
655
1050
|
* const schema5 = await extract(context, valibotSchema);
|
|
656
|
-
* // Resolve a schema definition from
|
|
657
|
-
* const schema6 = await extract(context,
|
|
1051
|
+
* // Resolve a schema definition from a reflected Deepkit Type object
|
|
1052
|
+
* const schema6 = await extract(context, reflectionType);
|
|
658
1053
|
* ```
|
|
659
1054
|
*
|
|
660
1055
|
* @see https://zod.dev/
|
|
@@ -662,7 +1057,7 @@ async function extractTSType(input, options = {}) {
|
|
|
662
1057
|
* @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec
|
|
663
1058
|
* @see https://json-schema.org/
|
|
664
1059
|
* @see https://ajv.js.org/json-type-definition.html
|
|
665
|
-
* @see https://
|
|
1060
|
+
* @see https://deepkit.io/en/documentation/runtime-types/reflection
|
|
666
1061
|
* @see https://github.com/unjs/untyped
|
|
667
1062
|
* @see https://www.typescriptlang.org/docs/handbook/2/types-from-types.html
|
|
668
1063
|
*
|
|
@@ -693,13 +1088,22 @@ async function extractSchemaWithSource(input, options = {}) {
|
|
|
693
1088
|
let fs;
|
|
694
1089
|
if (options.storage) fs = require_storage.mapStorageToFileSystem(options.storage);
|
|
695
1090
|
let resolved = await (0, _stryke_resolve_load.loadSafe)(unwrappedConfig, {
|
|
696
|
-
...options,
|
|
697
|
-
|
|
1091
|
+
...(0, _stryke_helpers_omit.omit)(options, [
|
|
1092
|
+
"storage",
|
|
1093
|
+
"logger",
|
|
1094
|
+
"tsconfig"
|
|
1095
|
+
]),
|
|
1096
|
+
fs,
|
|
1097
|
+
cwd: options.cwd ?? void 0
|
|
698
1098
|
});
|
|
699
1099
|
resolved ??= await extractTSType(unwrappedConfig, {
|
|
700
1100
|
...options,
|
|
701
1101
|
fs
|
|
702
1102
|
});
|
|
1103
|
+
try {
|
|
1104
|
+
const type = (0, _deepkit_type.reflect)(resolved);
|
|
1105
|
+
if ((0, _deepkit_type.isType)(type)) resolved = type;
|
|
1106
|
+
} catch {}
|
|
703
1107
|
const resolvedConfig = unwrapSchemaConfig(resolved);
|
|
704
1108
|
if (require_helpers.isSchemaWithSource(resolvedConfig)) source = resolvedConfig.source;
|
|
705
1109
|
else if (require_helpers.isSchema(resolvedConfig)) source = {
|
|
@@ -725,7 +1129,7 @@ async function extractSchemaWithSource(input, options = {}) {
|
|
|
725
1129
|
};
|
|
726
1130
|
}
|
|
727
1131
|
/**
|
|
728
|
-
* Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a {@link FileReferenceInput} to an exported TypeScript type definition or any of the previous options. If the input is a {@link FileReferenceInput} (e.g. a file path with an export), the source code will be bundled with [esbuild](esbuild.github.io) using [
|
|
1132
|
+
* Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, a Deepkit Type object, or a {@link FileReferenceInput} to an exported TypeScript type definition or any of the previous options. If the input is a {@link FileReferenceInput} (e.g. a file path with an export), the source code will be bundled with [esbuild](https://esbuild.github.io) using [@deepkit/type-compiler](https://deepkit.io/en/documentation/runtime-types/getting-started) reflection to obtain the actual schema definition before extraction.
|
|
729
1133
|
*
|
|
730
1134
|
* @example
|
|
731
1135
|
* ```ts
|
|
@@ -739,8 +1143,8 @@ async function extractSchemaWithSource(input, options = {}) {
|
|
|
739
1143
|
* const schema4 = await extract(context, zodSchema);
|
|
740
1144
|
* // Resolve a schema definition from a Valibot schema
|
|
741
1145
|
* const schema5 = await extract(context, valibotSchema);
|
|
742
|
-
* // Resolve a schema definition from
|
|
743
|
-
* const schema6 = await extract(context,
|
|
1146
|
+
* // Resolve a schema definition from a reflected Deepkit Type object
|
|
1147
|
+
* const schema6 = await extract(context, reflectionType);
|
|
744
1148
|
* ```
|
|
745
1149
|
*
|
|
746
1150
|
* @see https://zod.dev/
|
|
@@ -748,7 +1152,7 @@ async function extractSchemaWithSource(input, options = {}) {
|
|
|
748
1152
|
* @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec
|
|
749
1153
|
* @see https://json-schema.org/
|
|
750
1154
|
* @see https://ajv.js.org/json-type-definition.html
|
|
751
|
-
* @see https://
|
|
1155
|
+
* @see https://deepkit.io/en/documentation/runtime-types/reflection
|
|
752
1156
|
* @see https://github.com/unjs/untyped
|
|
753
1157
|
* @see https://www.typescriptlang.org/docs/handbook/2/types-from-types.html
|
|
754
1158
|
*
|
|
@@ -766,6 +1170,7 @@ async function extract(input, options = {}) {
|
|
|
766
1170
|
}
|
|
767
1171
|
|
|
768
1172
|
//#endregion
|
|
1173
|
+
exports.JSON_SCHEMA_CONSTRUCTOR_KEY = require_constants.JSON_SCHEMA_CONSTRUCTOR_KEY;
|
|
769
1174
|
exports.JSON_SCHEMA_METADATA_KEYS = require_constants.JSON_SCHEMA_METADATA_KEYS;
|
|
770
1175
|
exports.JSON_SCHEMA_PRIMITIVE_TYPES = require_constants.JSON_SCHEMA_PRIMITIVE_TYPES;
|
|
771
1176
|
exports.JSON_SCHEMA_TYPES = require_constants.JSON_SCHEMA_TYPES;
|
|
@@ -781,6 +1186,7 @@ exports.createStoragePromises = require_storage.createStoragePromises;
|
|
|
781
1186
|
exports.extract = extract;
|
|
782
1187
|
exports.extractHash = extractHash;
|
|
783
1188
|
exports.extractJsonSchema = extractJsonSchema;
|
|
1189
|
+
exports.extractReflection = extractReflection;
|
|
784
1190
|
exports.extractResolvedVariant = extractResolvedVariant;
|
|
785
1191
|
exports.extractSchema = extractSchema;
|
|
786
1192
|
exports.extractSchemaWithSource = extractSchemaWithSource;
|
|
@@ -794,6 +1200,7 @@ exports.getPrimarySchemaType = require_helpers.getPrimarySchemaType;
|
|
|
794
1200
|
exports.getProperties = require_helpers.getProperties;
|
|
795
1201
|
exports.getPropertiesList = require_helpers.getPropertiesList;
|
|
796
1202
|
exports.getProperty = require_helpers.getProperty;
|
|
1203
|
+
exports.hasJsonSchemaConstructorFlag = require_helpers.hasJsonSchemaConstructorFlag;
|
|
797
1204
|
exports.isFileReference = require_helpers.isFileReference;
|
|
798
1205
|
exports.isJsonSchema = require_helpers.isJsonSchema;
|
|
799
1206
|
exports.isJsonSchemaAllOf = require_helpers.isJsonSchemaAllOf;
|