@powerlines/schema 0.11.45 → 0.11.46
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/bundle.cjs +1 -1
- package/dist/bundle.d.cts +1 -1
- package/dist/bundle.d.mts +1 -1
- package/dist/bundle.mjs +1 -1
- package/dist/bundle.mjs.map +1 -1
- package/dist/codegen.cjs +28 -22
- package/dist/codegen.d.cts +11 -11
- package/dist/codegen.d.cts.map +1 -1
- package/dist/codegen.d.mts +11 -11
- package/dist/codegen.d.mts.map +1 -1
- package/dist/codegen.mjs +36 -30
- package/dist/codegen.mjs.map +1 -1
- package/dist/constants.cjs +15 -11
- package/dist/constants.d.cts +4 -3
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +4 -3
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +13 -10
- package/dist/constants.mjs.map +1 -1
- package/dist/extract.cjs +158 -20
- package/dist/extract.d.cts +55 -16
- package/dist/extract.d.cts.map +1 -1
- package/dist/extract.d.mts +55 -16
- package/dist/extract.d.mts.map +1 -1
- package/dist/extract.mjs +158 -22
- package/dist/extract.mjs.map +1 -1
- package/dist/helpers.cjs +43 -8
- package/dist/helpers.d.cts +40 -6
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.mts +40 -6
- package/dist/helpers.d.mts.map +1 -1
- package/dist/helpers.mjs +43 -10
- package/dist/helpers.mjs.map +1 -1
- package/dist/index.cjs +39 -7
- package/dist/index.d.cts +8 -8
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +7 -7
- package/dist/metadata.cjs +9 -35
- package/dist/metadata.d.cts +5 -26
- package/dist/metadata.d.cts.map +1 -1
- package/dist/metadata.d.mts +5 -26
- package/dist/metadata.d.mts.map +1 -1
- package/dist/metadata.mjs +9 -33
- package/dist/metadata.mjs.map +1 -1
- package/dist/persistence.d.cts +4 -4
- package/dist/persistence.d.cts.map +1 -1
- package/dist/persistence.d.mts +4 -4
- package/dist/persistence.d.mts.map +1 -1
- package/dist/persistence.mjs.map +1 -1
- package/dist/reflection.cjs +72 -50
- package/dist/reflection.d.cts +1 -1
- package/dist/reflection.d.cts.map +1 -1
- package/dist/reflection.d.mts +1 -1
- package/dist/reflection.d.mts.map +1 -1
- package/dist/reflection.mjs +74 -52
- package/dist/reflection.mjs.map +1 -1
- package/dist/type-checks.cjs +363 -83
- package/dist/type-checks.d.cts +138 -16
- package/dist/type-checks.d.cts.map +1 -1
- package/dist/type-checks.d.mts +138 -16
- package/dist/type-checks.d.mts.map +1 -1
- package/dist/type-checks.mjs +336 -85
- package/dist/type-checks.mjs.map +1 -1
- package/dist/types.d.cts +901 -176
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +901 -176
- package/dist/types.d.mts.map +1 -1
- package/dist/validate.mjs.map +1 -1
- package/package.json +5 -5
package/dist/extract.mjs
CHANGED
|
@@ -1,20 +1,119 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isJsonSchema, isJsonSchemaObject, isSchema, isSchemaWithSource, isUntypedInput, isUntypedSchema, isValibotSchema } from "./type-checks.mjs";
|
|
2
2
|
import { getCacheDirectory, writeSchema } from "./persistence.mjs";
|
|
3
3
|
import { reflectionToJsonSchema } from "./reflection.mjs";
|
|
4
4
|
import { resolve } from "./resolve.mjs";
|
|
5
5
|
import defu from "defu";
|
|
6
6
|
import { isSetString } from "@stryke/type-checks";
|
|
7
7
|
import { isSetObject as isSetObject$1 } from "@stryke/type-checks/is-set-object";
|
|
8
|
-
import { isStandardJsonSchema } from "@stryke/json";
|
|
9
8
|
import { isTypeDefinition } from "@powerlines/core";
|
|
10
9
|
import { rolldownPlugin } from "@powerlines/deepkit/rolldown-plugin";
|
|
11
10
|
import { isType, stringifyType } from "@powerlines/deepkit/vendor/type";
|
|
12
11
|
import { murmurhash } from "@stryke/hash";
|
|
12
|
+
import { deepClone } from "@stryke/helpers/deep-clone";
|
|
13
|
+
import { isStandardJsonSchema } from "@stryke/json";
|
|
13
14
|
import { joinPaths } from "@stryke/path/join";
|
|
14
15
|
import { extractJsonSchema, isZod3Type } from "@stryke/zod";
|
|
15
16
|
import { toJsonSchema } from "@valibot/to-json-schema";
|
|
16
17
|
|
|
17
18
|
//#region src/extract.ts
|
|
19
|
+
const SCHEMA_BUNDLE_BASE_URI = "https://powerlines.invalid/";
|
|
20
|
+
function normalizeUri(uri) {
|
|
21
|
+
return uri.endsWith("#") ? uri.slice(0, -1) : uri;
|
|
22
|
+
}
|
|
23
|
+
function stripUriFragment(uri) {
|
|
24
|
+
const hashIndex = uri.indexOf("#");
|
|
25
|
+
return hashIndex >= 0 ? uri.slice(0, hashIndex) : uri;
|
|
26
|
+
}
|
|
27
|
+
function escapeJsonPointerToken(token) {
|
|
28
|
+
return token.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
29
|
+
}
|
|
30
|
+
function toJsonPointer(path) {
|
|
31
|
+
if (path.length === 0) return "";
|
|
32
|
+
return `/${path.map((segment) => escapeJsonPointerToken(segment)).join("/")}`;
|
|
33
|
+
}
|
|
34
|
+
function resolveUri(reference, baseUri) {
|
|
35
|
+
try {
|
|
36
|
+
return normalizeUri(new URL(reference, baseUri).toString());
|
|
37
|
+
} catch {
|
|
38
|
+
return normalizeUri(reference);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function collectReferenceTargets(value, path, baseUri, uriToPointer, dynamicUriToFragment) {
|
|
42
|
+
if (!isSetObject$1(value)) return;
|
|
43
|
+
const schema = value;
|
|
44
|
+
const pointer = toJsonPointer(path);
|
|
45
|
+
const currentBaseUri = isSetString(schema.$id) ? resolveUri(schema.$id, baseUri) : baseUri;
|
|
46
|
+
const currentDocumentUri = stripUriFragment(currentBaseUri);
|
|
47
|
+
uriToPointer.set(currentBaseUri, pointer);
|
|
48
|
+
uriToPointer.set(currentDocumentUri, pointer);
|
|
49
|
+
if (isSetString(schema.$anchor)) uriToPointer.set(`${currentDocumentUri}#${schema.$anchor}`, pointer);
|
|
50
|
+
if (isSetString(schema.$dynamicAnchor)) {
|
|
51
|
+
const dynamicTarget = `${currentDocumentUri}#${schema.$dynamicAnchor}`;
|
|
52
|
+
uriToPointer.set(dynamicTarget, pointer);
|
|
53
|
+
dynamicUriToFragment.set(dynamicTarget, `#${schema.$dynamicAnchor}`);
|
|
54
|
+
}
|
|
55
|
+
for (const [key, child] of Object.entries(schema)) {
|
|
56
|
+
if (Array.isArray(child)) {
|
|
57
|
+
child.forEach((entry, index) => {
|
|
58
|
+
collectReferenceTargets(entry, [
|
|
59
|
+
...path,
|
|
60
|
+
key,
|
|
61
|
+
String(index)
|
|
62
|
+
], currentBaseUri, uriToPointer, dynamicUriToFragment);
|
|
63
|
+
});
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
collectReferenceTargets(child, [...path, key], currentBaseUri, uriToPointer, dynamicUriToFragment);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function rewriteReferenceTargets(value, path, baseUri, uriToPointer, dynamicUriToFragment) {
|
|
70
|
+
if (!isSetObject$1(value)) return;
|
|
71
|
+
const schema = value;
|
|
72
|
+
const currentBaseUri = isSetString(schema.$id) ? resolveUri(schema.$id, baseUri) : baseUri;
|
|
73
|
+
if (isSetString(schema.$ref)) {
|
|
74
|
+
const resolvedRefUri = resolveUri(schema.$ref, currentBaseUri);
|
|
75
|
+
const pointer = uriToPointer.get(resolvedRefUri) ?? uriToPointer.get(stripUriFragment(resolvedRefUri));
|
|
76
|
+
if (pointer !== void 0) schema.$ref = pointer.length > 0 ? `#${pointer}` : "#";
|
|
77
|
+
}
|
|
78
|
+
if (isSetString(schema.$dynamicRef)) {
|
|
79
|
+
const resolvedDynamicRefUri = resolveUri(schema.$dynamicRef, currentBaseUri);
|
|
80
|
+
const dynamicFragment = dynamicUriToFragment.get(resolvedDynamicRefUri);
|
|
81
|
+
if (dynamicFragment) schema.$dynamicRef = dynamicFragment;
|
|
82
|
+
else {
|
|
83
|
+
const pointer = uriToPointer.get(resolvedDynamicRefUri) ?? uriToPointer.get(stripUriFragment(resolvedDynamicRefUri));
|
|
84
|
+
if (pointer !== void 0) schema.$dynamicRef = pointer.length > 0 ? `#${pointer}` : "#";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (const [key, child] of Object.entries(schema)) {
|
|
88
|
+
if (Array.isArray(child)) {
|
|
89
|
+
child.forEach((entry, index) => {
|
|
90
|
+
rewriteReferenceTargets(entry, [
|
|
91
|
+
...path,
|
|
92
|
+
key,
|
|
93
|
+
String(index)
|
|
94
|
+
], currentBaseUri, uriToPointer, dynamicUriToFragment);
|
|
95
|
+
});
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
rewriteReferenceTargets(child, [...path, key], currentBaseUri, uriToPointer, dynamicUriToFragment);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Bundles all external references in a JSON Schema into a single schema document by collecting all reference targets and rewriting the references to point to the bundled definitions. This ensures that the resulting schema is self-contained and can be used independently without relying on external documents.
|
|
103
|
+
*
|
|
104
|
+
* @param schema - The JSON Schema to bundle references for.
|
|
105
|
+
* @returns A new JSON Schema with all references bundled and rewritten to point to the bundled definitions.
|
|
106
|
+
*/
|
|
107
|
+
function bundleReferences(schema) {
|
|
108
|
+
if (!isSetObject$1(schema)) return schema;
|
|
109
|
+
const bundledSchema = deepClone(schema);
|
|
110
|
+
const baseUri = isSetString(bundledSchema.$id) ? resolveUri(bundledSchema.$id, SCHEMA_BUNDLE_BASE_URI) : SCHEMA_BUNDLE_BASE_URI;
|
|
111
|
+
const uriToPointer = /* @__PURE__ */ new Map();
|
|
112
|
+
const dynamicUriToFragment = /* @__PURE__ */ new Map();
|
|
113
|
+
collectReferenceTargets(bundledSchema, [], baseUri, uriToPointer, dynamicUriToFragment);
|
|
114
|
+
rewriteReferenceTargets(bundledSchema, [], baseUri, uriToPointer, dynamicUriToFragment);
|
|
115
|
+
return bundledSchema;
|
|
116
|
+
}
|
|
18
117
|
function convertNestedUntypedSchema(value) {
|
|
19
118
|
if (isUntypedSchema(value)) return convertUntypedSchemaToJsonSchema(value);
|
|
20
119
|
if (isSetObject$1(value)) {
|
|
@@ -29,7 +128,7 @@ function convertNestedUntypedSchemaArray(value) {
|
|
|
29
128
|
return value.map((item) => convertNestedUntypedSchema(item));
|
|
30
129
|
}
|
|
31
130
|
function convertValibotSchemaToJsonSchema(schema) {
|
|
32
|
-
return toJsonSchema(schema, { target: "draft-
|
|
131
|
+
return toJsonSchema(schema, { target: "draft-2020-12" });
|
|
33
132
|
}
|
|
34
133
|
function convertUntypedSchemaToJsonSchema(schema) {
|
|
35
134
|
const source = schema;
|
|
@@ -97,6 +196,10 @@ function extractHash(variant, input) {
|
|
|
97
196
|
variant,
|
|
98
197
|
input
|
|
99
198
|
});
|
|
199
|
+
else if (typeof input === "boolean") return murmurhash({
|
|
200
|
+
variant,
|
|
201
|
+
input
|
|
202
|
+
});
|
|
100
203
|
else if (isSetObject$1(input)) {
|
|
101
204
|
if (isZod3Type(input)) return murmurhash({
|
|
102
205
|
variant,
|
|
@@ -130,7 +233,7 @@ function extractHash(variant, input) {
|
|
|
130
233
|
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.`);
|
|
131
234
|
}
|
|
132
235
|
/**
|
|
133
|
-
* Converts a reflected Deepkit {@link Type} into a JSON Schema (draft-
|
|
236
|
+
* Converts a reflected Deepkit {@link Type} into a JSON Schema (draft-2020-12) representation.
|
|
134
237
|
*/
|
|
135
238
|
function extractReflection(reflection) {
|
|
136
239
|
if (!isType(reflection)) return;
|
|
@@ -149,7 +252,15 @@ function extractJsonSchema$1(schema) {
|
|
|
149
252
|
if (isJsonSchema(schema)) return schema;
|
|
150
253
|
}
|
|
151
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Resolves the concrete source variant for a schema source input.
|
|
257
|
+
*
|
|
258
|
+
* @param input - The schema source input to inspect.
|
|
259
|
+
* @returns The resolved schema source variant.
|
|
260
|
+
* @throws Will throw an error when the input cannot be mapped to a supported source variant.
|
|
261
|
+
*/
|
|
152
262
|
function extractResolvedVariant(input) {
|
|
263
|
+
if (typeof input === "boolean") return "json-schema";
|
|
153
264
|
if (isSetObject$1(input)) {
|
|
154
265
|
if (isZod3Type(input)) return "zod3";
|
|
155
266
|
else if (isStandardJsonSchema(input)) return "standard-schema";
|
|
@@ -160,19 +271,41 @@ function extractResolvedVariant(input) {
|
|
|
160
271
|
}
|
|
161
272
|
throw new Error(`Failed to determine the variant of the provided schema definition input. The input must be a Zod schema, a Standard JSON Schema, a JSON Schema object, a Valibot BaseSchema, a reflected Deepkit Type object, or an Untyped schema.`);
|
|
162
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Determines the top-level input variant for schema extraction.
|
|
276
|
+
*
|
|
277
|
+
* @param input - The schema input to classify.
|
|
278
|
+
* @returns The resolved schema input variant.
|
|
279
|
+
*/
|
|
163
280
|
function extractVariant(input) {
|
|
164
281
|
if (isSetString(input) || isTypeDefinition(input)) return "type-definition";
|
|
165
282
|
return extractResolvedVariant(input);
|
|
166
283
|
}
|
|
167
|
-
|
|
168
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Extracts and normalizes a JSON Schema from a concrete schema source input.
|
|
286
|
+
*
|
|
287
|
+
* @param input - The schema source input to extract from.
|
|
288
|
+
* @param variant - Optional source variant override. When omitted, the variant is inferred from the input.
|
|
289
|
+
* @returns A promise that resolves to a bundled JSON Schema.
|
|
290
|
+
* @throws Will throw an error if no valid JSON Schema can be extracted from the input.
|
|
291
|
+
*/
|
|
292
|
+
async function extractSchema(input, variant) {
|
|
293
|
+
if (isSchemaWithSource(input)) return input.schema;
|
|
169
294
|
const resolvedVariant = variant ?? extractResolvedVariant(input);
|
|
170
295
|
let schema;
|
|
171
296
|
if (resolvedVariant === "zod3" || resolvedVariant === "json-schema" || resolvedVariant === "standard-schema" || resolvedVariant === "untyped" || resolvedVariant === "valibot") schema = extractJsonSchema$1(input);
|
|
172
297
|
else if (resolvedVariant === "reflection") schema = extractReflection(input);
|
|
173
|
-
if (schema) return schema;
|
|
298
|
+
if (schema) return bundleReferences(schema);
|
|
174
299
|
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.`);
|
|
175
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Builds source metadata for a schema input using a known source variant.
|
|
303
|
+
*
|
|
304
|
+
* @param variant - The schema source variant associated with the input.
|
|
305
|
+
* @param input - The schema source input to wrap.
|
|
306
|
+
* @returns The normalized schema source payload, including the source hash and variant.
|
|
307
|
+
* @throws Will throw an error if the provided variant is unsupported.
|
|
308
|
+
*/
|
|
176
309
|
function extractSource(variant, input) {
|
|
177
310
|
if (variant === "zod3") return {
|
|
178
311
|
hash: extractHash(variant, input),
|
|
@@ -207,7 +340,7 @@ function extractSource(variant, input) {
|
|
|
207
340
|
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.`);
|
|
208
341
|
}
|
|
209
342
|
/**
|
|
210
|
-
* Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a
|
|
343
|
+
* 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 Deepkit Type object. If the input is a type definition reference (e.g. a file path with an export), it will be resolved and bundled using Rolldown to obtain the actual schema definition before extraction.
|
|
211
344
|
*
|
|
212
345
|
* @example
|
|
213
346
|
* ```ts
|
|
@@ -221,19 +354,20 @@ function extractSource(variant, input) {
|
|
|
221
354
|
* const schema4 = await extract(context, reflectionType);
|
|
222
355
|
* ```
|
|
223
356
|
*
|
|
224
|
-
* @see https://
|
|
357
|
+
* @see https://zod.dev/
|
|
358
|
+
* @see https://valibot.dev/
|
|
225
359
|
* @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec
|
|
226
360
|
* @see https://json-schema.org/
|
|
227
361
|
* @see https://ajv.js.org/json-type-definition.html
|
|
228
362
|
* @see https://deepkit.io/en/documentation/runtime-types/reflection
|
|
229
363
|
*
|
|
230
364
|
* @param context - The context object providing access to the file system and cache path.
|
|
231
|
-
* @param input - The schema definition input to extract, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object. If the input is a string or a type definition reference, it will be resolved and bundled to obtain the actual schema definition before extraction.
|
|
232
|
-
* @param options - Optional overrides for the
|
|
365
|
+
* @param input - The schema definition input to extract, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a reflected Deepkit Type object. If the input is a string or a type definition reference, it will be resolved and bundled to obtain the actual schema definition before extraction.
|
|
366
|
+
* @param options - Optional overrides for the Rolldown configuration used during extraction. This can include custom plugins, loaders, or other build options to control how the schema definition is resolved and bundled when the input is a type definition reference.
|
|
233
367
|
* @returns A promise that resolves to the extracted and normalized schema as a JSON Schema object. The function will attempt to extract a valid JSON Schema from the provided input, and if successful, it will return the schema. If the extraction process fails or if the input is not a valid schema definition, it will throw an error indicating the failure.
|
|
234
368
|
*/
|
|
235
|
-
async function
|
|
236
|
-
if (
|
|
369
|
+
async function extractSchemaWithSource(context, input, options = {}) {
|
|
370
|
+
if (isSchemaWithSource(input)) return input;
|
|
237
371
|
if (isSchema(input)) return {
|
|
238
372
|
...input,
|
|
239
373
|
source: {
|
|
@@ -256,18 +390,19 @@ async function extractSchema(context, input, options = {}) {
|
|
|
256
390
|
"standard-schema",
|
|
257
391
|
"zod3",
|
|
258
392
|
"untyped",
|
|
393
|
+
"valibot",
|
|
259
394
|
"reflection"
|
|
260
395
|
].includes(variant)) source = extractSource(variant, input);
|
|
261
396
|
else throw new Error(`Invalid schema definition input "${variant}". The variant must be one of "type-definition", "json-schema", "standard-schema", "zod3", "untyped", or "reflection".`);
|
|
262
397
|
return {
|
|
263
398
|
variant,
|
|
264
399
|
source,
|
|
265
|
-
schema: await
|
|
400
|
+
schema: await extractSchema(source.schema, source.variant),
|
|
266
401
|
hash
|
|
267
402
|
};
|
|
268
403
|
}
|
|
269
404
|
/**
|
|
270
|
-
* Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a
|
|
405
|
+
* 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 Deepkit Type object. If the input is a type definition reference (e.g. a file path with an export), it will be resolved and bundled using Rolldown to obtain the actual schema definition before extraction.
|
|
271
406
|
*
|
|
272
407
|
* @example
|
|
273
408
|
* ```ts
|
|
@@ -281,7 +416,8 @@ async function extractSchema(context, input, options = {}) {
|
|
|
281
416
|
* const schema4 = await extract(context, reflectionType);
|
|
282
417
|
* ```
|
|
283
418
|
*
|
|
284
|
-
* @see https://
|
|
419
|
+
* @see https://zod.dev/
|
|
420
|
+
* @see https://valibot.dev/
|
|
285
421
|
* @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec
|
|
286
422
|
* @see https://json-schema.org/
|
|
287
423
|
* @see https://ajv.js.org/json-type-definition.html
|
|
@@ -290,13 +426,13 @@ async function extractSchema(context, input, options = {}) {
|
|
|
290
426
|
* @see https://www.typescriptlang.org/docs/handbook/2/types-from-types.html
|
|
291
427
|
*
|
|
292
428
|
* @param context - The context object providing access to the file system and cache path.
|
|
293
|
-
* @param input - The schema definition input to extract, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object.
|
|
294
|
-
* @param options - Optional overrides for the
|
|
429
|
+
* @param input - The schema definition input to extract, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a reflected Deepkit Type object.
|
|
430
|
+
* @param options - Optional overrides for the Rolldown configuration used during extraction.
|
|
295
431
|
* @returns A promise that resolves to the extracted and normalized schema as a JSON Schema object.
|
|
296
432
|
* @throws Will throw an error if the input is not a valid schema definition or if the extraction process fails to produce a valid schema.
|
|
297
433
|
*/
|
|
298
434
|
async function extract(context, input, options = {}) {
|
|
299
|
-
if (
|
|
435
|
+
if (isSchemaWithSource(input) || isSchema(input)) return input;
|
|
300
436
|
let result;
|
|
301
437
|
const variant = extractVariant(input);
|
|
302
438
|
const hash = extractHash(variant, input);
|
|
@@ -309,12 +445,12 @@ async function extract(context, input, options = {}) {
|
|
|
309
445
|
schema: JSON.parse(schema)
|
|
310
446
|
};
|
|
311
447
|
}
|
|
312
|
-
result ??= await
|
|
313
|
-
if (!result?.schema) 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, an untyped schema, or a reflected Deepkit Type object.`);
|
|
448
|
+
result ??= await extractSchemaWithSource(context, input, options);
|
|
449
|
+
if (!result?.schema) throw new Error(`Failed to extract a valid schema from the provided input. The input must be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a reflected Deepkit Type object.`);
|
|
314
450
|
if (context.config.skipCache !== true) await writeSchema(context, result);
|
|
315
451
|
return result;
|
|
316
452
|
}
|
|
317
453
|
|
|
318
454
|
//#endregion
|
|
319
|
-
export { extract, extractHash, extractJsonSchema$1 as extractJsonSchema, extractReflection, extractResolvedVariant, extractSchema, extractSource, extractVariant };
|
|
455
|
+
export { bundleReferences, extract, extractHash, extractJsonSchema$1 as extractJsonSchema, extractReflection, extractResolvedVariant, extractSchema, extractSchemaWithSource, extractSource, extractVariant };
|
|
320
456
|
//# sourceMappingURL=extract.mjs.map
|
package/dist/extract.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.mjs","names":["isSetObject","extractJsonSchema","extractJsonSchemaZod"],"sources":["../src/extract.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Powerlines\n\n This code was released as part of the Powerlines project. Powerlines\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/powerlines.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/powerlines\n Documentation: https://docs.stormsoftware.com/projects/powerlines\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { Context } from \"@powerlines/core\";\nimport { isTypeDefinition } from \"@powerlines/core\";\nimport { rolldownPlugin } from \"@powerlines/deepkit/rolldown-plugin\";\nimport { isType, stringifyType, Type } from \"@powerlines/deepkit/vendor/type\";\nimport { StandardJSONSchemaV1 } from \"@standard-schema/spec\";\nimport { murmurhash } from \"@stryke/hash\";\nimport { isStandardJsonSchema } from \"@stryke/json\";\nimport { joinPaths } from \"@stryke/path/join\";\nimport { isSetString } from \"@stryke/type-checks\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport {\n extractJsonSchema as extractJsonSchemaZod,\n isZod3Type\n} from \"@stryke/zod\";\nimport { toJsonSchema } from \"@valibot/to-json-schema\";\nimport defu from \"defu\";\nimport type { BuildOptions } from \"rolldown\";\nimport * as z3 from \"zod/v3\";\nimport { getCacheDirectory, writeSchema } from \"./persistence\";\nimport { reflectionToJsonSchema } from \"./reflection\";\nimport { resolve } from \"./resolve\";\nimport {\n isExtractedSchema,\n isJsonSchema,\n isJsonSchemaObject,\n isSchema,\n isUntypedInput,\n isUntypedSchema,\n isValibotSchema\n} from \"./type-checks\";\nimport {\n ExtractedSchema,\n JsonSchema,\n Schema,\n SchemaInput,\n SchemaInputVariant,\n SchemaSource,\n SchemaSourceInput,\n SchemaSourceVariant,\n TypeDefinitionReference,\n UntypedInputObject,\n UntypedSchema,\n ValibotSchema\n} from \"./types\";\n\nfunction convertNestedUntypedSchema(value: unknown): unknown {\n if (isUntypedSchema(value)) {\n return convertUntypedSchemaToJsonSchema(value);\n }\n\n if (isSetObject(value)) {\n if (isUntypedInput(value)) {\n return convertUntypedInputToJsonSchema(value);\n }\n\n const nested = value as Record<string, unknown>;\n if (\"$schema\" in nested && isUntypedSchema(nested.$schema)) {\n return convertUntypedSchemaToJsonSchema(nested.$schema);\n }\n }\n\n return value;\n}\n\nfunction convertNestedUntypedSchemaArray(value: unknown): unknown {\n if (!Array.isArray(value)) {\n return value;\n }\n\n return value.map(item => convertNestedUntypedSchema(item));\n}\n\nfunction convertValibotSchemaToJsonSchema<T = unknown>(\n schema: unknown\n): JsonSchema<T> {\n return toJsonSchema(schema as never, {\n target: \"draft-07\"\n }) as JsonSchema<T>;\n}\n\nfunction convertUntypedSchemaToJsonSchema<T = unknown>(\n schema: UntypedSchema | Record<string, unknown>\n): JsonSchema<T> {\n const source = schema as Record<string, unknown>;\n const jsonSchema: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(source)) {\n if (\n key === \"tsType\" ||\n key === \"markdownType\" ||\n key === \"tags\" ||\n key === \"args\" ||\n key === \"resolve\"\n ) {\n continue;\n }\n\n if (key === \"id\" && isSetString(value)) {\n jsonSchema.$id = value;\n continue;\n }\n\n if (\n key === \"properties\" ||\n key === \"patternProperties\" ||\n key === \"dependentSchemas\" ||\n key === \"$defs\" ||\n key === \"definitions\"\n ) {\n if (!isSetObject(value)) {\n jsonSchema[key] = value;\n continue;\n }\n\n jsonSchema[key] = Object.fromEntries(\n Object.entries(value).map(([propertyKey, propertyValue]) => [\n propertyKey,\n convertNestedUntypedSchema(propertyValue)\n ])\n );\n continue;\n }\n\n if (\n key === \"items\" ||\n key === \"contains\" ||\n key === \"if\" ||\n key === \"then\" ||\n key === \"else\" ||\n key === \"not\" ||\n key === \"propertyNames\" ||\n key === \"additionalProperties\" ||\n key === \"unevaluatedProperties\"\n ) {\n jsonSchema[key] = convertNestedUntypedSchema(value);\n continue;\n }\n\n if (key === \"oneOf\" || key === \"anyOf\" || key === \"allOf\") {\n jsonSchema[key] = convertNestedUntypedSchemaArray(value);\n continue;\n }\n\n jsonSchema[key] = value;\n }\n\n return jsonSchema as JsonSchema<T>;\n}\n\nfunction convertUntypedInputToJsonSchema<T = unknown>(\n input: UntypedInputObject\n): JsonSchema<T> {\n const inputObject = input as Record<string, unknown>;\n const base = (\n isUntypedSchema(inputObject.$schema)\n ? convertUntypedSchemaToJsonSchema<T>(inputObject.$schema)\n : {}\n ) as JsonSchema<T>;\n const properties: Record<string, JsonSchema<T>> = {};\n\n for (const [key, value] of Object.entries(inputObject)) {\n if (key.startsWith(\"$\")) {\n continue;\n }\n\n if (!isSetObject(value)) {\n continue;\n }\n\n if (isUntypedInput(value)) {\n properties[key] = convertUntypedInputToJsonSchema<T>(value);\n continue;\n }\n\n const nested = value as Record<string, unknown>;\n if (\"$schema\" in nested && isUntypedSchema(nested.$schema)) {\n properties[key] = convertUntypedSchemaToJsonSchema<T>(nested.$schema);\n continue;\n }\n\n if (isUntypedSchema(value)) {\n properties[key] = convertUntypedSchemaToJsonSchema<T>(value);\n }\n }\n\n if (!isJsonSchemaObject(base)) {\n throw new Error(\n `Failed to convert untyped input to JSON Schema. The base schema must be a valid JSON Schema object.`\n );\n }\n\n const baseProperties = isSetObject(base.properties)\n ? (base.properties as Record<string, JsonSchema<T>>)\n : {};\n const mergedProperties = {\n ...baseProperties,\n ...properties\n };\n\n return {\n ...base,\n type: base.type ?? \"object\",\n ...(Object.keys(mergedProperties).length > 0\n ? { properties: mergedProperties }\n : {})\n };\n}\n\n/**\n * Creates a hash string for a given schema definition input.\n */\nexport function extractHash<T = unknown>(\n variant: SchemaInputVariant,\n input: SchemaInput<T>\n): string {\n if (isSetString(input)) {\n return murmurhash({ variant, input });\n } else if (isSetObject(input)) {\n if (isZod3Type(input)) {\n return murmurhash({ variant, input: input._def });\n } else if (isStandardJsonSchema(input)) {\n return murmurhash({ variant, input: input[\"~standard\"] });\n } else if (isJsonSchema(input)) {\n return murmurhash({ variant, input });\n } else if (isValibotSchema(input)) {\n return murmurhash({\n variant,\n input: convertValibotSchemaToJsonSchema(input)\n });\n } else if (isUntypedInput(input)) {\n return murmurhash({\n variant,\n input: convertUntypedInputToJsonSchema(input)\n });\n } else if (isUntypedSchema(input)) {\n return murmurhash({\n variant,\n input: convertUntypedSchemaToJsonSchema(input)\n });\n } else if (isType(input)) {\n return murmurhash({ variant, input: stringifyType(input) });\n }\n }\n\n throw new Error(\n `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.`\n );\n}\n\n/**\n * Converts a reflected Deepkit {@link Type} into a JSON Schema (draft-07) representation.\n */\nexport function extractReflection<T = unknown>(\n reflection: Type\n): JsonSchema<T> | undefined {\n if (!isType(reflection)) {\n return undefined;\n }\n\n return reflectionToJsonSchema<T>(reflection);\n}\n\n/**\n * Extracts a JSON Schema from Zod, Standard Schema, Valibot, untyped, or JSON Schema inputs.\n */\nexport function extractJsonSchema<T = unknown>(\n schema: unknown\n): JsonSchema<T> | undefined {\n if (isSetObject(schema)) {\n if (isZod3Type(schema)) {\n return extractJsonSchemaZod(schema) as JsonSchema<T>;\n }\n if (isStandardJsonSchema(schema)) {\n return schema[\"~standard\"].jsonSchema.input({\n target: \"draft-2020-12\"\n }) as JsonSchema<T>;\n }\n if (isValibotSchema(schema)) {\n return convertValibotSchemaToJsonSchema<T>(schema);\n }\n if (isUntypedInput(schema)) {\n return convertUntypedInputToJsonSchema<T>(schema);\n }\n if (isUntypedSchema(schema)) {\n return convertUntypedSchemaToJsonSchema<T>(schema);\n }\n if (isJsonSchema<T>(schema)) {\n return schema;\n }\n }\n\n return undefined;\n}\n\nexport function extractResolvedVariant(\n input: SchemaSourceInput\n): SchemaSourceVariant {\n if (isSetObject(input)) {\n if (isZod3Type(input)) {\n return \"zod3\";\n } else if (isStandardJsonSchema(input)) {\n return \"standard-schema\";\n } else if (isJsonSchema(input)) {\n return \"json-schema\";\n } else if (isValibotSchema(input)) {\n return \"valibot\";\n } else if (isType(input)) {\n return \"reflection\";\n } else if (isUntypedInput(input) || isUntypedSchema(input)) {\n return \"untyped\";\n }\n }\n\n throw new Error(\n `Failed to determine the variant of the provided schema definition input. The input must be a Zod schema, a Standard JSON Schema, a JSON Schema object, a Valibot BaseSchema, a reflected Deepkit Type object, or an Untyped schema.`\n );\n}\n\nexport function extractVariant<T = unknown>(\n input: SchemaInput<T>\n): SchemaInputVariant {\n if (isSetString(input) || isTypeDefinition(input)) {\n return \"type-definition\";\n }\n\n return extractResolvedVariant(input as SchemaSourceInput);\n}\n\nasync function extractSchemaSchema<T = unknown>(\n input: SchemaSourceInput,\n variant?: SchemaInputVariant\n): Promise<JsonSchema<T>> {\n if (isExtractedSchema<T>(input)) {\n return input.schema;\n }\n\n const resolvedVariant = variant ?? extractResolvedVariant(input);\n\n let schema: JsonSchema<T> | undefined;\n if (\n resolvedVariant === \"zod3\" ||\n resolvedVariant === \"json-schema\" ||\n resolvedVariant === \"standard-schema\" ||\n resolvedVariant === \"untyped\" ||\n resolvedVariant === \"valibot\"\n ) {\n schema = extractJsonSchema<T>(input);\n } else if (resolvedVariant === \"reflection\") {\n schema = extractReflection(input as Type);\n }\n\n if (schema) {\n return schema;\n }\n\n throw new Error(\n `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.`\n );\n}\n\nexport function extractSource(\n variant: SchemaSourceVariant,\n input: SchemaSourceInput\n): SchemaSource {\n if (variant === \"zod3\") {\n return {\n hash: extractHash(variant, input),\n variant: \"zod3\",\n schema: input as z3.ZodTypeAny\n };\n } else if (variant === \"untyped\") {\n return {\n hash: extractHash(variant, input),\n variant: \"untyped\",\n schema: input as UntypedInputObject | UntypedSchema\n };\n } else if (variant === \"standard-schema\") {\n return {\n hash: extractHash(variant, input),\n variant: \"standard-schema\",\n schema: input as StandardJSONSchemaV1\n };\n } else if (variant === \"json-schema\") {\n return {\n hash: extractHash(variant, input),\n variant: \"json-schema\",\n schema: input as JsonSchema\n };\n } else if (variant === \"valibot\") {\n return {\n hash: extractHash(variant, input),\n variant: \"valibot\",\n schema: input as ValibotSchema\n };\n } else if (variant === \"reflection\") {\n return {\n hash: extractHash(variant, input),\n variant: \"reflection\",\n schema: input as Type\n };\n }\n\n throw new Error(\n `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.`\n );\n}\n\n/**\n * Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object. If the input is a type definition reference (e.g. a file path with an export), it will be resolved and bundled using ESBuild to obtain the actual schema definition before extraction.\n *\n * @example\n * ```ts\n * // Resolve a schema definition from a file path\n * const schema1 = await extract(context, \"./schemas.ts#MySchema\");\n * // Resolve a schema definition from a JSON Schema object\n * const schema2 = await extract(context, schemaObject);\n * // Resolve a schema definition from a Zod schema\n * const schema3 = await extract(context, zodSchema);\n * // Resolve a schema definition from a reflected Deepkit Type object\n * const schema4 = await extract(context, reflectionType);\n * ```\n *\n * @see https://github.com/colinhacks/zod\n * @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec\n * @see https://json-schema.org/\n * @see https://ajv.js.org/json-type-definition.html\n * @see https://deepkit.io/en/documentation/runtime-types/reflection\n *\n * @param context - The context object providing access to the file system and cache path.\n * @param input - The schema definition input to extract, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object. If the input is a string or a type definition reference, it will be resolved and bundled to obtain the actual schema definition before extraction.\n * @param options - Optional overrides for the ESBuild configuration used during extraction. This can include custom plugins, loaders, or other build options to control how the schema definition is resolved and bundled when the input is a type definition reference.\n * @returns A promise that resolves to the extracted and normalized schema as a JSON Schema object. The function will attempt to extract a valid JSON Schema from the provided input, and if successful, it will return the schema. If the extraction process fails or if the input is not a valid schema definition, it will throw an error indicating the failure.\n */\nexport async function extractSchema<T = unknown>(\n context: Context,\n input: SchemaInput,\n options: Partial<BuildOptions> = {}\n): Promise<ExtractedSchema<T>> {\n if (isExtractedSchema<T>(input)) {\n return input;\n }\n\n if (isSchema<T>(input)) {\n return {\n ...input,\n source: {\n hash: extractHash(\"json-schema\", input.schema),\n variant: \"json-schema\",\n schema: input.schema\n }\n };\n }\n\n let source: SchemaSource;\n\n const variant = extractVariant(input);\n const hash = extractHash(variant, input);\n\n if (variant === \"type-definition\") {\n const resolved = await resolve<SchemaSourceInput>(\n context,\n input as TypeDefinitionReference,\n defu(options, {\n plugins: [\n rolldownPlugin(context, {\n reflection: \"default\",\n level: \"all\"\n })\n ]\n })\n );\n\n source = extractSource(extractResolvedVariant(resolved), resolved);\n } else if (\n [\n \"json-schema\",\n \"standard-schema\",\n \"zod3\",\n \"untyped\",\n \"reflection\"\n ].includes(variant)\n ) {\n source = extractSource(variant, input as SchemaSourceInput);\n } else {\n throw new Error(\n `Invalid schema definition input \"${\n variant\n }\". The variant must be one of \"type-definition\", \"json-schema\", \"standard-schema\", \"zod3\", \"untyped\", or \"reflection\".`\n );\n }\n\n return {\n variant,\n source,\n schema: await extractSchemaSchema<T>(source.schema, source.variant),\n hash\n };\n}\n\n/**\n * Extracts a JSON Schema from a given schema definition input, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object. If the input is a type definition reference (e.g. a file path with an export), it will be resolved and bundled using ESBuild to obtain the actual schema definition before extraction.\n *\n * @example\n * ```ts\n * // Resolve a schema definition from a file path\n * const schema1 = await extract(context, \"./schemas.ts#MySchema\");\n * // Resolve a schema definition from a JSON Schema object\n * const schema2 = await extract(context, schemaObject);\n * // Resolve a schema definition from a Zod schema\n * const schema3 = await extract(context, zodSchema);\n * // Resolve a schema definition from a reflected Deepkit Type object\n * const schema4 = await extract(context, reflectionType);\n * ```\n *\n * @see https://github.com/colinhacks/zod\n * @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec\n * @see https://json-schema.org/\n * @see https://ajv.js.org/json-type-definition.html\n * @see https://deepkit.io/en/documentation/runtime-types/reflection\n * @see https://github.com/unjs/untyped\n * @see https://www.typescriptlang.org/docs/handbook/2/types-from-types.html\n *\n * @param context - The context object providing access to the file system and cache path.\n * @param input - The schema definition input to extract, which can be a Zod schema, a Standard JSON Schema, a JSON Schema object, an untyped schema, or a reflected Deepkit Type object.\n * @param options - Optional overrides for the ESBuild configuration used during extraction.\n * @returns A promise that resolves to the extracted and normalized schema as a JSON Schema object.\n * @throws Will throw an error if the input is not a valid schema definition or if the extraction process fails to produce a valid schema.\n */\nexport async function extract<T = unknown>(\n context: Context,\n input: SchemaInput,\n options: Partial<BuildOptions> = {}\n): Promise<Schema<T>> {\n if (isExtractedSchema<T>(input) || isSchema<T>(input)) {\n return input;\n }\n\n let result: Schema<T> | undefined;\n\n const variant = extractVariant(input);\n const hash = extractHash(variant, input);\n\n const cacheFilePath = joinPaths(getCacheDirectory(context), `${hash}.json`);\n if (\n context.config.skipCache !== true &&\n context.fs.existsSync(cacheFilePath)\n ) {\n const schema = await context.fs.read(cacheFilePath);\n if (schema) {\n result = {\n variant,\n hash,\n schema: JSON.parse(schema) as JsonSchema<T>\n };\n }\n }\n\n result ??= await extractSchema<T>(context, input, options);\n if (!result?.schema) {\n throw new Error(\n `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, an untyped schema, or a reflected Deepkit Type object.`\n );\n }\n\n if (context.config.skipCache !== true) {\n await writeSchema(context, result);\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extract.mjs","names":["isSetObject","extractJsonSchema","extractJsonSchemaZod"],"sources":["../src/extract.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Powerlines\n\n This code was released as part of the Powerlines project. Powerlines\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/powerlines.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/powerlines\n Documentation: https://docs.stormsoftware.com/projects/powerlines\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { Context } from \"@powerlines/core\";\nimport { isTypeDefinition } from \"@powerlines/core\";\nimport { rolldownPlugin } from \"@powerlines/deepkit/rolldown-plugin\";\nimport { isType, stringifyType, Type } from \"@powerlines/deepkit/vendor/type\";\nimport { StandardJSONSchemaV1 } from \"@standard-schema/spec\";\nimport { murmurhash } from \"@stryke/hash\";\nimport { deepClone } from \"@stryke/helpers/deep-clone\";\nimport { isStandardJsonSchema } from \"@stryke/json\";\nimport { joinPaths } from \"@stryke/path/join\";\nimport { isSetString } from \"@stryke/type-checks\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport {\n extractJsonSchema as extractJsonSchemaZod,\n isZod3Type\n} from \"@stryke/zod\";\nimport { toJsonSchema } from \"@valibot/to-json-schema\";\nimport defu from \"defu\";\nimport type { BuildOptions } from \"rolldown\";\nimport * as z3 from \"zod/v3\";\nimport { getCacheDirectory, writeSchema } from \"./persistence\";\nimport { reflectionToJsonSchema } from \"./reflection\";\nimport { resolve } from \"./resolve\";\nimport {\n isJsonSchema,\n isJsonSchemaObject,\n isSchema,\n isSchemaWithSource,\n isUntypedInput,\n isUntypedSchema,\n isValibotSchema\n} from \"./type-checks\";\nimport {\n ExtractedSchema,\n JsonSchema,\n Schema,\n SchemaInput,\n SchemaInputVariant,\n SchemaSource,\n SchemaSourceInput,\n SchemaSourceVariant,\n TypeDefinitionReference,\n UntypedInputObject,\n UntypedSchema,\n ValibotSchema\n} from \"./types\";\n\nconst SCHEMA_BUNDLE_BASE_URI = \"https://powerlines.invalid/\";\n\nfunction normalizeUri(uri: string): string {\n return uri.endsWith(\"#\") ? uri.slice(0, -1) : uri;\n}\n\nfunction stripUriFragment(uri: string): string {\n const hashIndex = uri.indexOf(\"#\");\n\n return hashIndex >= 0 ? uri.slice(0, hashIndex) : uri;\n}\n\nfunction escapeJsonPointerToken(token: string): string {\n return token.replaceAll(\"~\", \"~0\").replaceAll(\"/\", \"~1\");\n}\n\nfunction toJsonPointer(path: string[]): string {\n if (path.length === 0) {\n return \"\";\n }\n\n return `/${path.map(segment => escapeJsonPointerToken(segment)).join(\"/\")}`;\n}\n\nfunction resolveUri(reference: string, baseUri: string): string {\n try {\n return normalizeUri(new URL(reference, baseUri).toString());\n } catch {\n return normalizeUri(reference);\n }\n}\n\nfunction collectReferenceTargets(\n value: unknown,\n path: string[],\n baseUri: string,\n uriToPointer: Map<string, string>,\n dynamicUriToFragment: Map<string, string>\n): void {\n if (!isSetObject(value)) {\n return;\n }\n\n const schema = value as Record<string, unknown>;\n const pointer = toJsonPointer(path);\n\n const currentBaseUri = isSetString(schema.$id)\n ? resolveUri(schema.$id, baseUri)\n : baseUri;\n\n const currentDocumentUri = stripUriFragment(currentBaseUri);\n\n uriToPointer.set(currentBaseUri, pointer);\n uriToPointer.set(currentDocumentUri, pointer);\n\n if (isSetString(schema.$anchor)) {\n uriToPointer.set(`${currentDocumentUri}#${schema.$anchor}`, pointer);\n }\n\n if (isSetString(schema.$dynamicAnchor)) {\n const dynamicTarget = `${currentDocumentUri}#${schema.$dynamicAnchor}`;\n uriToPointer.set(dynamicTarget, pointer);\n dynamicUriToFragment.set(dynamicTarget, `#${schema.$dynamicAnchor}`);\n }\n\n for (const [key, child] of Object.entries(schema)) {\n if (Array.isArray(child)) {\n child.forEach((entry, index) => {\n collectReferenceTargets(\n entry,\n [...path, key, String(index)],\n currentBaseUri,\n uriToPointer,\n dynamicUriToFragment\n );\n });\n continue;\n }\n\n collectReferenceTargets(\n child,\n [...path, key],\n currentBaseUri,\n uriToPointer,\n dynamicUriToFragment\n );\n }\n}\n\nfunction rewriteReferenceTargets(\n value: unknown,\n path: string[],\n baseUri: string,\n uriToPointer: Map<string, string>,\n dynamicUriToFragment: Map<string, string>\n): void {\n if (!isSetObject(value)) {\n return;\n }\n\n const schema = value as Record<string, unknown>;\n\n const currentBaseUri = isSetString(schema.$id)\n ? resolveUri(schema.$id, baseUri)\n : baseUri;\n\n if (isSetString(schema.$ref)) {\n const resolvedRefUri = resolveUri(schema.$ref, currentBaseUri);\n const pointer =\n uriToPointer.get(resolvedRefUri) ??\n uriToPointer.get(stripUriFragment(resolvedRefUri));\n\n if (pointer !== undefined) {\n schema.$ref = pointer.length > 0 ? `#${pointer}` : \"#\";\n }\n }\n\n if (isSetString(schema.$dynamicRef)) {\n const resolvedDynamicRefUri = resolveUri(\n schema.$dynamicRef,\n currentBaseUri\n );\n const dynamicFragment = dynamicUriToFragment.get(resolvedDynamicRefUri);\n\n if (dynamicFragment) {\n schema.$dynamicRef = dynamicFragment;\n } else {\n const pointer =\n uriToPointer.get(resolvedDynamicRefUri) ??\n uriToPointer.get(stripUriFragment(resolvedDynamicRefUri));\n\n if (pointer !== undefined) {\n schema.$dynamicRef = pointer.length > 0 ? `#${pointer}` : \"#\";\n }\n }\n }\n\n for (const [key, child] of Object.entries(schema)) {\n if (Array.isArray(child)) {\n child.forEach((entry, index) => {\n rewriteReferenceTargets(\n entry,\n [...path, key, String(index)],\n currentBaseUri,\n uriToPointer,\n dynamicUriToFragment\n );\n });\n continue;\n }\n\n rewriteReferenceTargets(\n child,\n [...path, key],\n currentBaseUri,\n uriToPointer,\n dynamicUriToFragment\n );\n }\n}\n\n/**\n * Bundles all external references in a JSON Schema into a single schema document by collecting all reference targets and rewriting the references to point to the bundled definitions. This ensures that the resulting schema is self-contained and can be used independently without relying on external documents.\n *\n * @param schema - The JSON Schema to bundle references for.\n * @returns A new JSON Schema with all references bundled and rewritten to point to the bundled definitions.\n */\nexport function bundleReferences(schema: JsonSchema): JsonSchema {\n if (!isSetObject(schema)) {\n return schema;\n }\n\n const bundledSchema = deepClone(schema) as Record<string, unknown>;\n const baseUri = isSetString(bundledSchema.$id)\n ? resolveUri(bundledSchema.$id, SCHEMA_BUNDLE_BASE_URI)\n : SCHEMA_BUNDLE_BASE_URI;\n\n const uriToPointer = new Map<string, string>();\n const dynamicUriToFragment = new Map<string, string>();\n\n collectReferenceTargets(\n bundledSchema,\n [],\n baseUri,\n uriToPointer,\n dynamicUriToFragment\n );\n\n rewriteReferenceTargets(\n bundledSchema,\n [],\n baseUri,\n uriToPointer,\n dynamicUriToFragment\n );\n\n return bundledSchema;\n}\n\nfunction convertNestedUntypedSchema(value: unknown): unknown {\n if (isUntypedSchema(value)) {\n return convertUntypedSchemaToJsonSchema(value);\n }\n\n if (isSetObject(value)) {\n if (isUntypedInput(value)) {\n return convertUntypedInputToJsonSchema(value);\n }\n\n const nested = value as Record<string, unknown>;\n if (\"$schema\" in nested && isUntypedSchema(nested.$schema)) {\n return convertUntypedSchemaToJsonSchema(nested.$schema);\n }\n }\n\n return value;\n}\n\nfunction convertNestedUntypedSchemaArray(value: unknown): unknown {\n if (!Array.isArray(value)) {\n return value;\n }\n\n return value.map(item => convertNestedUntypedSchema(item));\n}\n\nfunction convertValibotSchemaToJsonSchema(schema: unknown): JsonSchema {\n return toJsonSchema(schema as never, {\n target: \"draft-2020-12\"\n }) as JsonSchema;\n}\n\nfunction convertUntypedSchemaToJsonSchema(\n schema: UntypedSchema | Record<string, unknown>\n): JsonSchema {\n const source = schema as Record<string, unknown>;\n const jsonSchema: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(source)) {\n if (\n key === \"tsType\" ||\n key === \"markdownType\" ||\n key === \"tags\" ||\n key === \"args\" ||\n key === \"resolve\"\n ) {\n continue;\n }\n\n if (key === \"id\" && isSetString(value)) {\n jsonSchema.$id = value;\n continue;\n }\n\n if (\n key === \"properties\" ||\n key === \"patternProperties\" ||\n key === \"dependentSchemas\" ||\n key === \"$defs\" ||\n key === \"definitions\"\n ) {\n if (!isSetObject(value)) {\n jsonSchema[key] = value;\n continue;\n }\n\n jsonSchema[key] = Object.fromEntries(\n Object.entries(value).map(([propertyKey, propertyValue]) => [\n propertyKey,\n convertNestedUntypedSchema(propertyValue)\n ])\n );\n continue;\n }\n\n if (\n key === \"items\" ||\n key === \"contains\" ||\n key === \"if\" ||\n key === \"then\" ||\n key === \"else\" ||\n key === \"not\" ||\n key === \"propertyNames\" ||\n key === \"additionalProperties\" ||\n key === \"unevaluatedProperties\"\n ) {\n jsonSchema[key] = convertNestedUntypedSchema(value);\n continue;\n }\n\n if (key === \"oneOf\" || key === \"anyOf\" || key === \"allOf\") {\n jsonSchema[key] = convertNestedUntypedSchemaArray(value);\n continue;\n }\n\n jsonSchema[key] = value;\n }\n\n return jsonSchema;\n}\n\nfunction convertUntypedInputToJsonSchema(\n input: UntypedInputObject\n): JsonSchema {\n const inputObject = input as Record<string, unknown>;\n const base = isUntypedSchema(inputObject.$schema)\n ? convertUntypedSchemaToJsonSchema(inputObject.$schema)\n : {};\n const properties: Record<string, JsonSchema> = {};\n\n for (const [key, value] of Object.entries(inputObject)) {\n if (key.startsWith(\"$\")) {\n continue;\n }\n\n if (!isSetObject(value)) {\n continue;\n }\n\n if (isUntypedInput(value)) {\n properties[key] = convertUntypedInputToJsonSchema(value);\n continue;\n }\n\n const nested = value as Record<string, unknown>;\n if (\"$schema\" in nested && isUntypedSchema(nested.$schema)) {\n properties[key] = convertUntypedSchemaToJsonSchema(nested.$schema);\n continue;\n }\n\n if (isUntypedSchema(value)) {\n properties[key] = convertUntypedSchemaToJsonSchema(value);\n }\n }\n\n if (!isJsonSchemaObject(base)) {\n throw new Error(\n `Failed to convert untyped input to JSON Schema. The base schema must be a valid JSON Schema object.`\n );\n }\n\n const baseProperties = isSetObject(base.properties) ? base.properties : {};\n const mergedProperties = {\n ...baseProperties,\n ...properties\n };\n\n return {\n ...base,\n type: base.type ?? \"object\",\n ...(Object.keys(mergedProperties).length > 0\n ? { properties: mergedProperties }\n : {})\n };\n}\n\n/**\n * Creates a hash string for a given schema definition input.\n */\nexport function extractHash(\n variant: SchemaInputVariant,\n input: SchemaInput\n): string {\n if (isSetString(input)) {\n return murmurhash({ variant, input });\n } else if (typeof input === \"boolean\") {\n return murmurhash({ variant, input });\n } else if (isSetObject(input)) {\n if (isZod3Type(input)) {\n return murmurhash({ variant, input: input._def });\n } else if (isStandardJsonSchema(input)) {\n return murmurhash({ variant, input: input[\"~standard\"] });\n } else if (isJsonSchema(input)) {\n return murmurhash({ variant, input });\n } else if (isValibotSchema(input)) {\n return murmurhash({\n variant,\n input: convertValibotSchemaToJsonSchema(input)\n });\n } else if (isUntypedInput(input)) {\n return murmurhash({\n variant,\n input: convertUntypedInputToJsonSchema(input)\n });\n } else if (isUntypedSchema(input)) {\n return murmurhash({\n variant,\n input: convertUntypedSchemaToJsonSchema(input)\n });\n } else if (isType(input)) {\n return murmurhash({ variant, input: stringifyType(input) });\n }\n }\n\n throw new Error(\n `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.`\n );\n}\n\n/**\n * Converts a reflected Deepkit {@link Type} into a JSON Schema (draft-2020-12) representation.\n */\nexport function extractReflection(reflection: Type): JsonSchema | undefined {\n if (!isType(reflection)) {\n return undefined;\n }\n\n return reflectionToJsonSchema(reflection);\n}\n\n/**\n * Extracts a JSON Schema from Zod, Standard Schema, Valibot, untyped, or JSON Schema inputs.\n */\nexport function extractJsonSchema(schema: unknown): JsonSchema | undefined {\n if (isSetObject(schema)) {\n if (isZod3Type(schema)) {\n return extractJsonSchemaZod(schema) as JsonSchema;\n }\n if (isStandardJsonSchema(schema)) {\n return schema[\"~standard\"].jsonSchema.input({\n target: \"draft-2020-12\"\n });\n }\n if (isValibotSchema(schema)) {\n return convertValibotSchemaToJsonSchema(schema);\n }\n if (isUntypedInput(schema)) {\n return convertUntypedInputToJsonSchema(schema);\n }\n if (isUntypedSchema(schema)) {\n return convertUntypedSchemaToJsonSchema(schema);\n }\n if (isJsonSchema(schema)) {\n return schema;\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolves the concrete source variant for a schema source input.\n *\n * @param input - The schema source input to inspect.\n * @returns The resolved schema source variant.\n * @throws Will throw an error when the input cannot be mapped to a supported source variant.\n */\nexport function extractResolvedVariant(\n input: SchemaSourceInput\n): SchemaSourceVariant {\n if (typeof input === \"boolean\") {\n return \"json-schema\";\n }\n\n if (isSetObject(input)) {\n if (isZod3Type(input)) {\n return \"zod3\";\n } else if (isStandardJsonSchema(input)) {\n return \"standard-schema\";\n } else if (isJsonSchema(input)) {\n return \"json-schema\";\n } else if (isValibotSchema(input)) {\n return \"valibot\";\n } else if (isType(input)) {\n return \"reflection\";\n } else if (isUntypedInput(input) || isUntypedSchema(input)) {\n return \"untyped\";\n }\n }\n\n throw new Error(\n `Failed to determine the variant of the provided schema definition input. The input must be a Zod schema, a Standard JSON Schema, a JSON Schema object, a Valibot BaseSchema, a reflected Deepkit Type object, or an Untyped schema.`\n );\n}\n\n/**\n * Determines the top-level input variant for schema extraction.\n *\n * @param input - The schema input to classify.\n * @returns The resolved schema input variant.\n */\nexport function extractVariant(input: SchemaInput): SchemaInputVariant {\n if (isSetString(input) || isTypeDefinition(input)) {\n return \"type-definition\";\n }\n\n return extractResolvedVariant(input as SchemaSourceInput);\n}\n\n/**\n * Extracts and normalizes a JSON Schema from a concrete schema source input.\n *\n * @param input - The schema source input to extract from.\n * @param variant - Optional source variant override. When omitted, the variant is inferred from the input.\n * @returns A promise that resolves to a bundled JSON Schema.\n * @throws Will throw an error if no valid JSON Schema can be extracted from the input.\n */\nexport async function extractSchema(\n input: SchemaSourceInput,\n variant?: SchemaInputVariant\n): Promise<JsonSchema> {\n if (isSchemaWithSource(input)) {\n return input.schema;\n }\n\n const resolvedVariant = variant ?? extractResolvedVariant(input);\n\n let schema: JsonSchema | undefined;\n if (\n resolvedVariant === \"zod3\" ||\n resolvedVariant === \"json-schema\" ||\n resolvedVariant === \"standard-schema\" ||\n resolvedVariant === \"untyped\" ||\n resolvedVariant === \"valibot\"\n ) {\n schema = extractJsonSchema(input);\n } else if (resolvedVariant === \"reflection\") {\n schema = extractReflection(input as Type);\n }\n\n if (schema) {\n return bundleReferences(schema);\n }\n\n throw new Error(\n `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.`\n );\n}\n\n/**\n * Builds source metadata for a schema input using a known source variant.\n *\n * @param variant - The schema source variant associated with the input.\n * @param input - The schema source input to wrap.\n * @returns The normalized schema source payload, including the source hash and variant.\n * @throws Will throw an error if the provided variant is unsupported.\n */\nexport function extractSource(\n variant: SchemaSourceVariant,\n input: SchemaSourceInput\n): SchemaSource {\n if (variant === \"zod3\") {\n return {\n hash: extractHash(variant, input),\n variant: \"zod3\",\n schema: input as z3.ZodTypeAny\n };\n } else if (variant === \"untyped\") {\n return {\n hash: extractHash(variant, input),\n variant: \"untyped\",\n schema: input as UntypedInputObject | UntypedSchema\n };\n } else if (variant === \"standard-schema\") {\n return {\n hash: extractHash(variant, input),\n variant: \"standard-schema\",\n schema: input as StandardJSONSchemaV1\n };\n } else if (variant === \"json-schema\") {\n return {\n hash: extractHash(variant, input),\n variant: \"json-schema\",\n schema: input as JsonSchema\n };\n } else if (variant === \"valibot\") {\n return {\n hash: extractHash(variant, input),\n variant: \"valibot\",\n schema: input as ValibotSchema\n };\n } else if (variant === \"reflection\") {\n return {\n hash: extractHash(variant, input),\n variant: \"reflection\",\n schema: input as Type\n };\n }\n\n throw new Error(\n `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.`\n );\n}\n\n/**\n * 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 Deepkit Type object. If the input is a type definition reference (e.g. a file path with an export), it will be resolved and bundled using Rolldown to obtain the actual schema definition before extraction.\n *\n * @example\n * ```ts\n * // Resolve a schema definition from a file path\n * const schema1 = await extract(context, \"./schemas.ts#MySchema\");\n * // Resolve a schema definition from a JSON Schema object\n * const schema2 = await extract(context, schemaObject);\n * // Resolve a schema definition from a Zod schema\n * const schema3 = await extract(context, zodSchema);\n * // Resolve a schema definition from a reflected Deepkit Type object\n * const schema4 = await extract(context, reflectionType);\n * ```\n *\n * @see https://zod.dev/\n * @see https://valibot.dev/\n * @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec\n * @see https://json-schema.org/\n * @see https://ajv.js.org/json-type-definition.html\n * @see https://deepkit.io/en/documentation/runtime-types/reflection\n *\n * @param context - The context object providing access to the file system and cache path.\n * @param input - The schema definition input to extract, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a reflected Deepkit Type object. If the input is a string or a type definition reference, it will be resolved and bundled to obtain the actual schema definition before extraction.\n * @param options - Optional overrides for the Rolldown configuration used during extraction. This can include custom plugins, loaders, or other build options to control how the schema definition is resolved and bundled when the input is a type definition reference.\n * @returns A promise that resolves to the extracted and normalized schema as a JSON Schema object. The function will attempt to extract a valid JSON Schema from the provided input, and if successful, it will return the schema. If the extraction process fails or if the input is not a valid schema definition, it will throw an error indicating the failure.\n */\nexport async function extractSchemaWithSource(\n context: Context,\n input: SchemaInput,\n options: Partial<BuildOptions> = {}\n): Promise<ExtractedSchema> {\n if (isSchemaWithSource(input)) {\n return input;\n }\n\n if (isSchema(input)) {\n return {\n ...input,\n source: {\n hash: extractHash(\"json-schema\", input.schema),\n variant: \"json-schema\",\n schema: input.schema\n }\n };\n }\n\n let source: SchemaSource;\n\n const variant = extractVariant(input);\n const hash = extractHash(variant, input);\n\n if (variant === \"type-definition\") {\n const resolved = await resolve<SchemaSourceInput>(\n context,\n input as TypeDefinitionReference,\n defu(options, {\n plugins: [\n rolldownPlugin(context, {\n reflection: \"default\",\n level: \"all\"\n })\n ]\n })\n );\n\n source = extractSource(extractResolvedVariant(resolved), resolved);\n } else if (\n [\n \"json-schema\",\n \"standard-schema\",\n \"zod3\",\n \"untyped\",\n \"valibot\",\n \"reflection\"\n ].includes(variant)\n ) {\n source = extractSource(variant, input as SchemaSourceInput);\n } else {\n throw new Error(\n `Invalid schema definition input \"${\n variant\n }\". The variant must be one of \"type-definition\", \"json-schema\", \"standard-schema\", \"zod3\", \"untyped\", or \"reflection\".`\n );\n }\n\n return {\n variant,\n source,\n schema: await extractSchema(source.schema, source.variant),\n hash\n };\n}\n\n/**\n * 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 Deepkit Type object. If the input is a type definition reference (e.g. a file path with an export), it will be resolved and bundled using Rolldown to obtain the actual schema definition before extraction.\n *\n * @example\n * ```ts\n * // Resolve a schema definition from a file path\n * const schema1 = await extract(context, \"./schemas.ts#MySchema\");\n * // Resolve a schema definition from a JSON Schema object\n * const schema2 = await extract(context, schemaObject);\n * // Resolve a schema definition from a Zod schema\n * const schema3 = await extract(context, zodSchema);\n * // Resolve a schema definition from a reflected Deepkit Type object\n * const schema4 = await extract(context, reflectionType);\n * ```\n *\n * @see https://zod.dev/\n * @see https://valibot.dev/\n * @see https://standardschema.dev/json-schema#what-schema-libraries-support-this-spec\n * @see https://json-schema.org/\n * @see https://ajv.js.org/json-type-definition.html\n * @see https://deepkit.io/en/documentation/runtime-types/reflection\n * @see https://github.com/unjs/untyped\n * @see https://www.typescriptlang.org/docs/handbook/2/types-from-types.html\n *\n * @param context - The context object providing access to the file system and cache path.\n * @param input - The schema definition input to extract, which can be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a reflected Deepkit Type object.\n * @param options - Optional overrides for the Rolldown configuration used during extraction.\n * @returns A promise that resolves to the extracted and normalized schema as a JSON Schema object.\n * @throws Will throw an error if the input is not a valid schema definition or if the extraction process fails to produce a valid schema.\n */\nexport async function extract(\n context: Context,\n input: SchemaInput,\n options: Partial<BuildOptions> = {}\n): Promise<Schema> {\n if (isSchemaWithSource(input) || isSchema(input)) {\n return input;\n }\n\n let result: Schema | undefined;\n\n const variant = extractVariant(input);\n const hash = extractHash(variant, input);\n\n const cacheFilePath = joinPaths(getCacheDirectory(context), `${hash}.json`);\n if (\n context.config.skipCache !== true &&\n context.fs.existsSync(cacheFilePath)\n ) {\n const schema = await context.fs.read(cacheFilePath);\n if (schema) {\n result = {\n variant,\n hash,\n schema: JSON.parse(schema) as JsonSchema\n };\n }\n }\n\n result ??= await extractSchemaWithSource(context, input, options);\n if (!result?.schema) {\n throw new Error(\n `Failed to extract a valid schema from the provided input. The input must be a Zod schema, a Valibot schema, any Standard JSON Schema type, a plain JSON Schema object, an untyped schema, or a reflected Deepkit Type object.`\n );\n }\n\n if (context.config.skipCache !== true) {\n await writeSchema(context, result);\n }\n\n return result;\n}\n"],"mappings":"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"}
|
package/dist/helpers.cjs
CHANGED
|
@@ -16,12 +16,18 @@ let _stryke_type_checks = require("@stryke/type-checks");
|
|
|
16
16
|
function getProperties(obj) {
|
|
17
17
|
const properties = {};
|
|
18
18
|
const schema = require_type_checks.isSchema(obj) ? obj.schema : obj;
|
|
19
|
-
if (!require_type_checks.isJsonSchemaObject(schema)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
if (!require_type_checks.isJsonSchemaObject(schema)) return properties;
|
|
20
|
+
if (!(0, _stryke_type_checks.isSetObject)(schema.properties)) return properties;
|
|
21
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
22
|
+
const propertySchema = {};
|
|
23
|
+
if (typeof value !== "boolean") Object.assign(propertySchema, value);
|
|
24
|
+
properties[key] = {
|
|
25
|
+
...propertySchema,
|
|
26
|
+
name: key,
|
|
27
|
+
required: !isPropertyOptional(schema, key),
|
|
28
|
+
default: schema.default?.[key] ?? propertySchema.default
|
|
29
|
+
};
|
|
30
|
+
}
|
|
25
31
|
return properties;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
@@ -56,8 +62,7 @@ function addProperty(obj, name, property) {
|
|
|
56
62
|
...property,
|
|
57
63
|
name
|
|
58
64
|
};
|
|
59
|
-
if (
|
|
60
|
-
else if (!schema.required.includes(name)) schema.required.push(name);
|
|
65
|
+
if (!schema.required.includes(name)) schema.required.push(name);
|
|
61
66
|
if (schema.required.length === 0) delete schema.required;
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
@@ -78,9 +83,39 @@ function mergeSchemas(...schemas) {
|
|
|
78
83
|
}
|
|
79
84
|
return result;
|
|
80
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns whether a JSON Schema fragment accepts `null`.
|
|
88
|
+
*
|
|
89
|
+
* @remarks
|
|
90
|
+
* This is true if the schema has `nullable: true` or if its `type` includes `"null"`.
|
|
91
|
+
*
|
|
92
|
+
* @param schema - The JSON Schema fragment to check.
|
|
93
|
+
* @returns `true` if the schema accepts `null`, otherwise `false`.
|
|
94
|
+
*/
|
|
95
|
+
function isSchemaNullable(schema) {
|
|
96
|
+
if (!(0, _stryke_type_checks.isSetObject)(schema)) return false;
|
|
97
|
+
if (schema.nullable === true) return true;
|
|
98
|
+
return require_metadata.readSchemaTypes(schema).includes("null");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns whether an object property is optional (not listed in `required`).
|
|
102
|
+
*
|
|
103
|
+
* @remarks
|
|
104
|
+
* In JSON Schema, object properties are optional by default unless they are listed in the `required` array of the parent schema. This function checks whether a given property name is not included in the `required` array of its parent schema, indicating that it is optional.
|
|
105
|
+
*
|
|
106
|
+
* @param parent - The parent JSON Schema object containing the property.
|
|
107
|
+
* @param propertyName - The name of the property to check for optionality.
|
|
108
|
+
* @returns `true` if the property is optional, otherwise `false`.
|
|
109
|
+
*/
|
|
110
|
+
function isPropertyOptional(parent, propertyName) {
|
|
111
|
+
if (!parent.properties?.[propertyName]) throw new Error(`The property "${propertyName}" does not exist in the parent schema.`);
|
|
112
|
+
return !(parent.required ?? []).includes(propertyName);
|
|
113
|
+
}
|
|
81
114
|
|
|
82
115
|
//#endregion
|
|
83
116
|
exports.addProperty = addProperty;
|
|
84
117
|
exports.getProperties = getProperties;
|
|
85
118
|
exports.getPropertiesList = getPropertiesList;
|
|
119
|
+
exports.isPropertyOptional = isPropertyOptional;
|
|
120
|
+
exports.isSchemaNullable = isSchemaNullable;
|
|
86
121
|
exports.mergeSchemas = mergeSchemas;
|
package/dist/helpers.d.cts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { JsonSchema,
|
|
1
|
+
import { JsonSchema, JsonSchemaObject, Schema } from "./types.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/helpers.d.ts
|
|
4
|
+
type GetPropertiesResult = JsonSchema & {
|
|
5
|
+
name: string;
|
|
6
|
+
required: boolean;
|
|
7
|
+
default?: unknown;
|
|
8
|
+
};
|
|
4
9
|
/**
|
|
5
10
|
* Extracts object properties from a JSON Schema object form.
|
|
6
11
|
*
|
|
@@ -10,7 +15,11 @@ import { JsonSchema, JsonSchemaProperty, Schema } from "./types.cjs";
|
|
|
10
15
|
* @param obj - The JSON Schema object form or a Schema wrapper to extract properties from.
|
|
11
16
|
* @returns An object mapping property names to their corresponding JSON Schema fragments, including metadata.
|
|
12
17
|
*/
|
|
13
|
-
declare function getProperties
|
|
18
|
+
declare function getProperties(obj: Schema | JsonSchemaObject): Record<string, JsonSchema & {
|
|
19
|
+
name: string;
|
|
20
|
+
required: boolean;
|
|
21
|
+
default?: unknown;
|
|
22
|
+
}>;
|
|
14
23
|
/**
|
|
15
24
|
* Returns object properties as an array.
|
|
16
25
|
*
|
|
@@ -20,7 +29,11 @@ declare function getProperties<T extends Record<string, any> = Record<string, an
|
|
|
20
29
|
* @param obj - The JSON Schema object form or a Schema wrapper to extract properties from.
|
|
21
30
|
* @returns An array of JSON Schema fragments representing the properties, each including metadata.
|
|
22
31
|
*/
|
|
23
|
-
declare function getPropertiesList
|
|
32
|
+
declare function getPropertiesList(obj: Schema | JsonSchemaObject): (JsonSchema & {
|
|
33
|
+
name: string;
|
|
34
|
+
required: boolean;
|
|
35
|
+
default?: unknown;
|
|
36
|
+
})[];
|
|
24
37
|
/**
|
|
25
38
|
* Adds a property to a JSON Schema object form.
|
|
26
39
|
*
|
|
@@ -32,7 +45,7 @@ declare function getPropertiesList<T extends Record<string, any> = Record<string
|
|
|
32
45
|
* @param property - The JSON Schema fragment representing the property's schema, including metadata.
|
|
33
46
|
* @throws Will throw an error if the provided schema is not an object form.
|
|
34
47
|
*/
|
|
35
|
-
declare function addProperty
|
|
48
|
+
declare function addProperty(obj: Schema | JsonSchemaObject, name: string, property: JsonSchema): void;
|
|
36
49
|
/**
|
|
37
50
|
* Merges multiple JSON Schema object forms into one.
|
|
38
51
|
*
|
|
@@ -42,7 +55,28 @@ declare function addProperty<T extends Record<string, any> = Record<string, any>
|
|
|
42
55
|
* @param schemas - An array of JSON Schema objects or Schema wrappers to merge.
|
|
43
56
|
* @returns A new JSON Schema object that is the result of merging all input schemas.
|
|
44
57
|
*/
|
|
45
|
-
declare function mergeSchemas
|
|
58
|
+
declare function mergeSchemas(...schemas: (JsonSchema | Schema)[]): JsonSchema;
|
|
59
|
+
/**
|
|
60
|
+
* Returns whether a JSON Schema fragment accepts `null`.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* This is true if the schema has `nullable: true` or if its `type` includes `"null"`.
|
|
64
|
+
*
|
|
65
|
+
* @param schema - The JSON Schema fragment to check.
|
|
66
|
+
* @returns `true` if the schema accepts `null`, otherwise `false`.
|
|
67
|
+
*/
|
|
68
|
+
declare function isSchemaNullable(schema?: JsonSchema): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Returns whether an object property is optional (not listed in `required`).
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* In JSON Schema, object properties are optional by default unless they are listed in the `required` array of the parent schema. This function checks whether a given property name is not included in the `required` array of its parent schema, indicating that it is optional.
|
|
74
|
+
*
|
|
75
|
+
* @param parent - The parent JSON Schema object containing the property.
|
|
76
|
+
* @param propertyName - The name of the property to check for optionality.
|
|
77
|
+
* @returns `true` if the property is optional, otherwise `false`.
|
|
78
|
+
*/
|
|
79
|
+
declare function isPropertyOptional(parent: JsonSchemaObject, propertyName: string): boolean;
|
|
46
80
|
//#endregion
|
|
47
|
-
export { addProperty, getProperties, getPropertiesList, mergeSchemas };
|
|
81
|
+
export { GetPropertiesResult, addProperty, getProperties, getPropertiesList, isPropertyOptional, isSchemaNullable, mergeSchemas };
|
|
48
82
|
//# sourceMappingURL=helpers.d.cts.map
|
package/dist/helpers.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.cts","names":[],"sources":["../src/helpers.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.cts","names":[],"sources":["../src/helpers.ts"],"mappings":";;;KAwBY,mBAAA,GAAsB,UAAU;EAC1C,IAAA;EACA,QAAA;EACA,OAAA;AAAA;;;;;;;AAAO;AAYT;;iBAAgB,aAAA,CACd,GAAA,EAAK,MAAA,GAAS,gBAAA,GACb,MAAA,SAED,UAAA;EAAe,IAAA;EAAc,QAAA;EAAmB,OAAA;AAAA;;;;;;;;;;iBA0ClC,iBAAA,CAAkB,GAAA,EAAK,MAAA,GAAS,gBAAA,IAAgB,UAAA;;;;;;;;;;;;;;;;iBAehD,WAAA,CACd,GAAA,EAAK,MAAA,GAAS,gBAAA,EACd,IAAA,UACA,QAAA,EAAU,UAAA;;;;AAHZ;;;;;;iBAgCgB,YAAA,CAAA,GAAgB,OAAA,GAAU,UAAA,GAAa,MAAA,MAAY,UAAA;;;;;;;;;AA7B7C;iBAoDN,gBAAA,CAAiB,MAAmB,GAAV,UAAU;;;;;;;;;;;iBAsBpC,kBAAA,CACd,MAAA,EAAQ,gBAAgB,EACxB,YAAA"}
|