@jskit-ai/assistant-voice 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/examples/conversation/package.json +8 -8
  2. package/package.json +1 -1
  3. package/examples/conversation/dist/assets/error-DOwCrGXH.js +0 -1
  4. package/examples/conversation/dist/assets/index-Bq1DwQwF.js +0 -90
  5. package/examples/conversation/dist/assets/index-Bw7_l3Cu.css +0 -1
  6. package/examples/conversation/dist/assets/placement-CUwf_TAl.js +0 -1
  7. package/examples/conversation/dist/assets/placementTopology-CUwf_TAl.js +0 -1
  8. package/examples/conversation/dist/index.html +0 -3
  9. package/examples/conversation/node_modules/.vite/deps/@jskit-ai_kernel_client_moduleBootstrap.js +0 -824
  10. package/examples/conversation/node_modules/.vite/deps/@jskit-ai_kernel_client_moduleBootstrap.js.map +0 -1
  11. package/examples/conversation/node_modules/.vite/deps/@mdi_js.js +0 -7450
  12. package/examples/conversation/node_modules/.vite/deps/@mdi_js.js.map +0 -1
  13. package/examples/conversation/node_modules/.vite/deps/@tanstack_vue-query.js +0 -3965
  14. package/examples/conversation/node_modules/.vite/deps/@tanstack_vue-query.js.map +0 -1
  15. package/examples/conversation/node_modules/.vite/deps/VTooltip-Nwckus73.js +0 -2311
  16. package/examples/conversation/node_modules/.vite/deps/VTooltip-Nwckus73.js.map +0 -1
  17. package/examples/conversation/node_modules/.vite/deps/_metadata.json +0 -110
  18. package/examples/conversation/node_modules/.vite/deps/defineComponent-Bx_4rnHZ.js +0 -710
  19. package/examples/conversation/node_modules/.vite/deps/defineComponent-Bx_4rnHZ.js.map +0 -1
  20. package/examples/conversation/node_modules/.vite/deps/dist-CUIjXXPV.js +0 -3878
  21. package/examples/conversation/node_modules/.vite/deps/dist-CUIjXXPV.js.map +0 -1
  22. package/examples/conversation/node_modules/.vite/deps/hotkey-parsing-B5h5TiMG.js +0 -1214
  23. package/examples/conversation/node_modules/.vite/deps/hotkey-parsing-B5h5TiMG.js.map +0 -1
  24. package/examples/conversation/node_modules/.vite/deps/icons-DPtxVIU0.js +0 -98
  25. package/examples/conversation/node_modules/.vite/deps/icons-DPtxVIU0.js.map +0 -1
  26. package/examples/conversation/node_modules/.vite/deps/json-rest-schema.js +0 -2071
  27. package/examples/conversation/node_modules/.vite/deps/json-rest-schema.js.map +0 -1
  28. package/examples/conversation/node_modules/.vite/deps/package.json +0 -3
  29. package/examples/conversation/node_modules/.vite/deps/pinia.js +0 -1453
  30. package/examples/conversation/node_modules/.vite/deps/pinia.js.map +0 -1
  31. package/examples/conversation/node_modules/.vite/deps/socket__io-client.js +0 -3899
  32. package/examples/conversation/node_modules/.vite/deps/socket__io-client.js.map +0 -1
  33. package/examples/conversation/node_modules/.vite/deps/theme-BSn2V8xv.js +0 -1301
  34. package/examples/conversation/node_modules/.vite/deps/theme-BSn2V8xv.js.map +0 -1
  35. package/examples/conversation/node_modules/.vite/deps/vue-router.js +0 -2989
  36. package/examples/conversation/node_modules/.vite/deps/vue-router.js.map +0 -1
  37. package/examples/conversation/node_modules/.vite/deps/vue.js +0 -2
  38. package/examples/conversation/node_modules/.vite/deps/vue.runtime.esm-bundler-DWdvffrK.js +0 -8890
  39. package/examples/conversation/node_modules/.vite/deps/vue.runtime.esm-bundler-DWdvffrK.js.map +0 -1
  40. package/examples/conversation/node_modules/.vite/deps/vuetify.js +0 -413
  41. package/examples/conversation/node_modules/.vite/deps/vuetify.js.map +0 -1
  42. package/examples/conversation/node_modules/.vite/deps/vuetify_components.js +0 -25370
  43. package/examples/conversation/node_modules/.vite/deps/vuetify_components.js.map +0 -1
  44. package/examples/conversation/node_modules/.vite/deps/vuetify_directives.js +0 -132
  45. package/examples/conversation/node_modules/.vite/deps/vuetify_directives.js.map +0 -1
  46. package/examples/conversation/node_modules/.vite/deps/vuetify_iconsets_mdi-svg.js +0 -70
  47. package/examples/conversation/node_modules/.vite/deps/vuetify_iconsets_mdi-svg.js.map +0 -1
@@ -1,2071 +0,0 @@
1
- //#region ../../../../node_modules/json-rest-schema/src/utils/object-helpers.js
2
- /**
3
- * @file Shared object-shape helpers.
4
- */
5
- function isPlainObject(value) {
6
- if (value === null || typeof value !== "object") return false;
7
- const prototype = Object.getPrototypeOf(value);
8
- return prototype === Object.prototype || prototype === null || isEmptyNullPrototypeRecord(prototype);
9
- }
10
- function isEmptyNullPrototypeRecord(value) {
11
- return value !== null && typeof value === "object" && Object.getPrototypeOf(value) === null && Reflect.ownKeys(value).length === 0;
12
- }
13
- //#endregion
14
- //#region ../../../../node_modules/json-rest-schema/src/core/nested-contract.js
15
- function isSchemaLike(value) {
16
- return value !== null && typeof value === "object" && isPlainObject(value.structure) && isPlainObject(value.operations) && typeof value.validateWith === "function" && typeof value.toJsonSchema === "function" && typeof value.cleanup === "function";
17
- }
18
- function resolveArrayItemsConfig(fieldPath, definition) {
19
- if (!Object.hasOwn(definition, "items")) return null;
20
- const { items } = definition;
21
- if (isSchemaLike(items)) return {
22
- kind: "schema",
23
- schema: items
24
- };
25
- if (!isPlainObject(items) || typeof items.type !== "string") throw new Error(`Array field "${fieldPath}" must define items as either a Schema instance or a field definition object.`);
26
- return {
27
- kind: "definition",
28
- definition: items
29
- };
30
- }
31
- function resolveObjectValuesConfig(fieldPath, definition) {
32
- if (!Object.hasOwn(definition, "values")) return null;
33
- const { values } = definition;
34
- if (isSchemaLike(values)) return {
35
- kind: "schema",
36
- schema: values
37
- };
38
- if (!isPlainObject(values) || typeof values.type !== "string") throw new Error(`Object field "${fieldPath}" must define values as either a Schema instance or a field definition object.`);
39
- return {
40
- kind: "definition",
41
- definition: values
42
- };
43
- }
44
- function resolveObjectFieldMode(fieldPath, definition) {
45
- const hasNestedSchema = Object.hasOwn(definition, "schema");
46
- const hasValues = Object.hasOwn(definition, "values");
47
- const hasAdditionalProperties = Object.hasOwn(definition, "additionalProperties");
48
- if (hasNestedSchema && hasValues) throw new Error(`Object field "${fieldPath}" cannot define both schema and values.`);
49
- if (hasAdditionalProperties && definition.additionalProperties !== true) throw new Error(`Object field "${fieldPath}" only supports additionalProperties: true.`);
50
- if (hasValues && definition.additionalProperties === true) throw new Error(`Object field "${fieldPath}" cannot define both values and additionalProperties: true.`);
51
- if (hasNestedSchema) {
52
- if (!isSchemaLike(definition.schema)) throw new Error(`Object field "${fieldPath}" must define schema as a Schema instance.`);
53
- return {
54
- kind: "nested",
55
- schema: definition.schema,
56
- allowAdditionalProperties: definition.additionalProperties === true
57
- };
58
- }
59
- if (hasValues) return {
60
- kind: "map",
61
- valuesConfig: resolveObjectValuesConfig(fieldPath, definition)
62
- };
63
- if (definition.additionalProperties === true) return { kind: "opaque" };
64
- return { kind: "plain" };
65
- }
66
- //#endregion
67
- //#region ../../../../node_modules/json-rest-schema/src/core/definition-helpers.js
68
- /**
69
- * @file Shared schema-definition predicates used by runtime and transport code.
70
- */
71
- function isNumericDefinition(definition) {
72
- return definition?.type === "number" || definition?.type === "integer" || definition?.type === "epochMilliseconds" || definition?.type === "epochSeconds";
73
- }
74
- //#endregion
75
- //#region ../../../../node_modules/json-rest-schema/src/core/temporal.js
76
- /**
77
- * @file Shared validation contracts for JSON-native temporal values.
78
- */
79
- var EPOCH_MILLISECONDS_LIMIT = 864e13;
80
- var EPOCH_SECONDS_LIMIT = 864e10;
81
- var EPOCH_INTEGER_STRING_PATTERN = "^(?:0|-?[1-9]\\d*)$";
82
- var YEAR_PATTERN = "\\d{4}";
83
- var MONTH_PATTERN = "0[1-9]|1[0-2]";
84
- var DAY_PATTERN = "0[1-9]|[12]\\d|3[01]";
85
- var HOUR_PATTERN = "[01]\\d|2[0-3]";
86
- var MINUTE_OR_SECOND_PATTERN = "[0-5]\\d";
87
- var HOUR_MINUTE_PATTERN = `(?:${HOUR_PATTERN}):${MINUTE_OR_SECOND_PATTERN}`;
88
- var TIME_ZONE_PATTERN = `(?:Z|[+-](?:${HOUR_PATTERN}):${MINUTE_OR_SECOND_PATTERN})`;
89
- var CAPTURED_DATE_PATTERN = `(${YEAR_PATTERN})-(${MONTH_PATTERN})-(${DAY_PATTERN})`;
90
- var JSON_SCHEMA_DATE_PATTERN = `${YEAR_PATTERN}-(?:${MONTH_PATTERN})-(?:${DAY_PATTERN})`;
91
- var DATE_JSON_SCHEMA_PATTERN = `^${JSON_SCHEMA_DATE_PATTERN}$`;
92
- var DATE_PATTERN = new RegExp(`^${CAPTURED_DATE_PATTERN}$`);
93
- var TIME_PATTERN = new RegExp(`^${HOUR_MINUTE_PATTERN}(?::${MINUTE_OR_SECOND_PATTERN}(?:\\.(\\d+))?)?$`);
94
- var DATE_TIME_PATTERN = new RegExp(`^${CAPTURED_DATE_PATTERN}T${HOUR_MINUTE_PATTERN}:${MINUTE_OR_SECOND_PATTERN}(?:\\.(\\d+))?${TIME_ZONE_PATTERN}$`);
95
- var EPOCH_INTEGER_STRING = new RegExp(EPOCH_INTEGER_STRING_PATTERN);
96
- var DAYS_PER_MONTH = [
97
- 31,
98
- 28,
99
- 31,
100
- 30,
101
- 31,
102
- 30,
103
- 31,
104
- 31,
105
- 30,
106
- 31,
107
- 30,
108
- 31
109
- ];
110
- function isLeapYear(year) {
111
- return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
112
- }
113
- function daysInMonth(year, month) {
114
- if (month === 2) return isLeapYear(year) ? 29 : 28;
115
- return DAYS_PER_MONTH[month - 1];
116
- }
117
- function isValidCalendarDateParts(yearText, monthText, dayText) {
118
- const year = Number(yearText);
119
- const month = Number(monthText);
120
- const day = Number(dayText);
121
- return month >= 1 && month <= 12 && day >= 1 && day <= daysInMonth(year, month);
122
- }
123
- function resolveTemporalPrecision(definition, fieldName) {
124
- const precision = definition.temporalPrecision;
125
- if (precision === void 0) return void 0;
126
- if (!Number.isInteger(precision) || precision < 0) throw new Error(`temporalPrecision for "${fieldName}" must be a non-negative integer.`);
127
- return precision;
128
- }
129
- function hasAllowedFractionalPrecision(fraction, temporalPrecision) {
130
- if (fraction === void 0) return true;
131
- return temporalPrecision === void 0 || fraction.length <= temporalPrecision;
132
- }
133
- function isValidDate(value) {
134
- if (typeof value !== "string") return false;
135
- const match = DATE_PATTERN.exec(value);
136
- return match !== null && isValidCalendarDateParts(match[1], match[2], match[3]);
137
- }
138
- function isValidTime(value, temporalPrecision) {
139
- if (typeof value !== "string") return false;
140
- const match = TIME_PATTERN.exec(value);
141
- return match !== null && hasAllowedFractionalPrecision(match[1], temporalPrecision);
142
- }
143
- function isValidDateTime(value, temporalPrecision) {
144
- if (typeof value !== "string") return false;
145
- const match = DATE_TIME_PATTERN.exec(value);
146
- if (match === null) return false;
147
- return isValidCalendarDateParts(match[1], match[2], match[3]) && hasAllowedFractionalPrecision(match[4], temporalPrecision);
148
- }
149
- function fractionalPattern(temporalPrecision) {
150
- if (temporalPrecision === void 0) return "(?:\\.\\d+)?";
151
- if (temporalPrecision === 0) return "";
152
- return `(?:\\.\\d{1,${temporalPrecision}})?`;
153
- }
154
- function timeJsonSchemaPattern(definition, fieldName) {
155
- return `^${HOUR_MINUTE_PATTERN}(?::${MINUTE_OR_SECOND_PATTERN}${fractionalPattern(resolveTemporalPrecision(definition, fieldName))})?$`;
156
- }
157
- function dateTimeJsonSchemaPattern(definition, fieldName) {
158
- return `^${JSON_SCHEMA_DATE_PATTERN}T${HOUR_MINUTE_PATTERN}:${MINUTE_OR_SECOND_PATTERN}${fractionalPattern(resolveTemporalPrecision(definition, fieldName))}${TIME_ZONE_PATTERN}$`;
159
- }
160
- function castEpochInteger(value, limit) {
161
- let integerValue;
162
- if (typeof value === "number") integerValue = value;
163
- else if (typeof value === "string" && EPOCH_INTEGER_STRING.test(value)) integerValue = Number(value);
164
- else return null;
165
- if (!Number.isSafeInteger(integerValue) || integerValue < -limit || integerValue > limit) return null;
166
- return integerValue === 0 ? 0 : integerValue;
167
- }
168
- //#endregion
169
- //#region ../../../../node_modules/json-rest-schema/src/utils/path-helpers.js
170
- /**
171
- * @file Shared dotted-path helpers for schema errors and UI adapters.
172
- */
173
- var UNSAFE_PATH_SEGMENTS = /* @__PURE__ */ new Set([
174
- "__proto__",
175
- "prototype",
176
- "constructor"
177
- ]);
178
- function isObjectLike(value) {
179
- return value !== null && typeof value === "object";
180
- }
181
- function isNumericSegment(segment) {
182
- return /^[0-9]+$/.test(segment);
183
- }
184
- function setOwnProperty(target, key, value) {
185
- Object.defineProperty(target, key, {
186
- value,
187
- enumerable: true,
188
- configurable: true,
189
- writable: true
190
- });
191
- }
192
- function assertSafePathSegment(segment, helperName) {
193
- if (UNSAFE_PATH_SEGMENTS.has(segment)) throw new Error(`${helperName}() received unsafe path segment "${segment}".`);
194
- }
195
- function normalizeFieldPath(path) {
196
- if (typeof path !== "string") return path;
197
- return path.replace(/\[(.+?)\]/g, ".$1").replace(/^\.+/, "").replace(/\.+/g, ".").replace(/\.$/, "");
198
- }
199
- function buildPathSegments$1(path, helperName, { normalize = false, allowEmpty = false } = {}) {
200
- const normalizedPath = normalize ? normalizeFieldPath(path) : path;
201
- if (typeof normalizedPath !== "string" || normalizedPath.trim() === "") {
202
- if (allowEmpty && normalizedPath === "") return [];
203
- throw new Error(`${helperName}() expects a non-empty dotted path string.`);
204
- }
205
- const segments = normalizedPath.split(".");
206
- if (segments.some((segment) => segment === "")) throw new Error(`${helperName}() received an invalid path "${normalizedPath}".`);
207
- for (const segment of segments) assertSafePathSegment(segment, helperName);
208
- return segments;
209
- }
210
- function joinPath$1(basePath, pathSegment) {
211
- return basePath === "" ? String(pathSegment) : `${basePath}.${String(pathSegment)}`;
212
- }
213
- //#endregion
214
- //#region ../../../../node_modules/json-rest-schema/src/core/transport-schema.js
215
- var JSON_SCHEMA_DRAFT_07 = "http://json-schema.org/draft-07/schema#";
216
- var JSON_REST_EXTENSION_KEY = "x-json-rest-schema";
217
- var NON_NULL_JSON_TYPES = [
218
- "object",
219
- "array",
220
- "string",
221
- "number",
222
- "boolean"
223
- ];
224
- var EXPORT_CONTEXT_KEY = Symbol("json-rest-schema.exportContext");
225
- var BOOLEAN_TRUE_VALUES = [
226
- "true",
227
- "1",
228
- "yes",
229
- "y",
230
- "on"
231
- ];
232
- var BOOLEAN_FALSE_VALUES = [
233
- "false",
234
- "0",
235
- "no",
236
- "n",
237
- "off"
238
- ];
239
- function epochIntegerSchema(limit) {
240
- return { anyOf: [{
241
- type: "integer",
242
- minimum: -limit,
243
- maximum: limit
244
- }, {
245
- type: "string",
246
- pattern: EPOCH_INTEGER_STRING_PATTERN
247
- }] };
248
- }
249
- function extensionMetadataFragment(section, values) {
250
- return { [JSON_REST_EXTENSION_KEY]: { [section]: values } };
251
- }
252
- var BUILTIN_TYPE_EXPORTERS = {
253
- none: () => ({ type: NON_NULL_JSON_TYPES }),
254
- blob: () => ({ type: NON_NULL_JSON_TYPES }),
255
- serialize: () => ({ type: NON_NULL_JSON_TYPES }),
256
- object: () => ({ type: "object" }),
257
- array: () => ({ type: "array" }),
258
- file: () => ({ type: "string" }),
259
- string: () => ({ type: "string" }),
260
- number: () => ({ type: ["number", "string"] }),
261
- integer: () => ({ type: ["integer", "string"] }),
262
- epochMilliseconds: () => epochIntegerSchema(EPOCH_MILLISECONDS_LIMIT),
263
- epochSeconds: () => epochIntegerSchema(EPOCH_SECONDS_LIMIT),
264
- dateTime: ({ definition, fieldName }) => ({
265
- type: "string",
266
- format: "date-time",
267
- pattern: dateTimeJsonSchemaPattern(definition, fieldName)
268
- }),
269
- date: () => ({
270
- type: "string",
271
- format: "date",
272
- pattern: DATE_JSON_SCHEMA_PATTERN
273
- }),
274
- time: ({ definition, fieldName }) => ({
275
- type: "string",
276
- pattern: timeJsonSchemaPattern(definition, fieldName)
277
- }),
278
- boolean: ({ definition }) => {
279
- if (definition.strictBoolean === true) return { type: "boolean" };
280
- const trueValues = /* @__PURE__ */ new Set([...BOOLEAN_TRUE_VALUES, String(definition.stringTrueWhen || "true").trim().toLowerCase()]);
281
- return { anyOf: [
282
- { type: "boolean" },
283
- {
284
- type: "number",
285
- enum: [0, 1]
286
- },
287
- {
288
- type: "string",
289
- enum: [.../* @__PURE__ */ new Set([...BOOLEAN_FALSE_VALUES, String(definition.stringFalseWhen || "false").trim().toLowerCase()]), ...trueValues]
290
- }
291
- ] };
292
- },
293
- id: () => ({
294
- type: ["integer", "string"],
295
- minimum: 1,
296
- pattern: "^[1-9][0-9]*$"
297
- })
298
- };
299
- var BUILTIN_VALIDATOR_EXPORTERS = {
300
- minLength: ({ definition, parameterValue }) => definition.type === "string" ? { minLength: parameterValue } : null,
301
- maxLength: ({ definition, parameterValue }) => definition.type === "string" ? { maxLength: parameterValue } : null,
302
- min: ({ definition, parameterValue }) => isNumericDefinition(definition) ? { minimum: parameterValue } : null,
303
- max: ({ definition, parameterValue }) => isNumericDefinition(definition) ? { maximum: parameterValue } : null,
304
- pattern: ({ definition, parameterValue }) => definition.type === "string" ? { pattern: parameterValue instanceof RegExp ? parameterValue.source : parameterValue } : null,
305
- enum: ({ parameterValue }) => ({ enum: parameterValue }),
306
- notEmpty: ({ parameterValue, definition }) => {
307
- if (!parameterValue) return null;
308
- if (definition.type === "array") return null;
309
- return { minLength: 1 };
310
- },
311
- uppercase: ({ parameterValue }) => parameterValue ? extensionMetadataFragment("transforms", { uppercase: true }) : null,
312
- lowercase: ({ parameterValue }) => parameterValue ? extensionMetadataFragment("transforms", { lowercase: true }) : null,
313
- length: ({ parameterValue }) => extensionMetadataFragment("transforms", { length: parameterValue }),
314
- unsigned: ({ parameterValue }) => parameterValue ? extensionMetadataFragment("metadata", { unsigned: true }) : null,
315
- precision: ({ parameterValue }) => extensionMetadataFragment("metadata", { precision: parameterValue }),
316
- scale: ({ parameterValue }) => extensionMetadataFragment("metadata", { scale: parameterValue }),
317
- temporalPrecision: ({ parameterValue }) => extensionMetadataFragment("metadata", { temporalPrecision: parameterValue }),
318
- strictBoolean: () => null,
319
- required: () => null,
320
- nullable: () => null,
321
- nullOnEmpty: () => null,
322
- defaultTo: () => null
323
- };
324
- function mergePlainObjects(target, source) {
325
- for (const key of Object.keys(source)) {
326
- const sourceValue = source[key];
327
- const targetValue = target[key];
328
- if (sourceValue && targetValue && typeof sourceValue === "object" && typeof targetValue === "object" && !Array.isArray(sourceValue) && !Array.isArray(targetValue)) {
329
- mergePlainObjects(targetValue, sourceValue);
330
- continue;
331
- }
332
- target[key] = sourceValue;
333
- }
334
- }
335
- function mergeSchemaFragment(target, fragment) {
336
- if (!fragment || typeof fragment !== "object" || Array.isArray(fragment)) throw new Error("JSON Schema export hooks must return an object or null.");
337
- for (const key of Object.keys(fragment)) {
338
- if (key === JSON_REST_EXTENSION_KEY && target[key] && typeof target[key] === "object" && typeof fragment[key] === "object" && !Array.isArray(target[key]) && !Array.isArray(fragment[key])) {
339
- mergePlainObjects(target[key], fragment[key]);
340
- continue;
341
- }
342
- target[key] = fragment[key];
343
- }
344
- }
345
- function buildAnyOfSchema(baseSchema, alternatives) {
346
- const finalAlternatives = [...Array.isArray(baseSchema.anyOf) && Object.keys(baseSchema).length === 1 ? baseSchema.anyOf : [baseSchema], ...alternatives];
347
- if (finalAlternatives.length === 1) return baseSchema;
348
- return { anyOf: finalAlternatives };
349
- }
350
- function getTypeExporter(schema, definition) {
351
- if (!Object.hasOwn(schema.types, definition.type)) throw new Error(`No casting function for type: ${definition.type}`);
352
- const handler = schema.types[definition.type];
353
- if (typeof handler.toJsonSchema === "function") return handler.toJsonSchema;
354
- const exporter = BUILTIN_TYPE_EXPORTERS[definition.type];
355
- if (!exporter) throw new Error(`Type '${definition.type}' cannot be exported to JSON Schema without a toJsonSchema hook.`);
356
- return exporter;
357
- }
358
- function getValidatorExporter(schema, parameterName, fieldName) {
359
- if (!Object.hasOwn(schema.validators, parameterName)) return null;
360
- const handler = schema.validators[parameterName];
361
- if (typeof handler.toJsonSchema === "function") return handler.toJsonSchema;
362
- const exporter = BUILTIN_VALIDATOR_EXPORTERS[parameterName];
363
- if (exporter) return exporter;
364
- throw new Error(`Validator '${parameterName}' on field '${fieldName}' cannot be exported to JSON Schema without a toJsonSchema hook.`);
365
- }
366
- function normalizeMode(mode) {
367
- if (mode === void 0) return "create";
368
- if ([
369
- "create",
370
- "replace",
371
- "patch"
372
- ].includes(mode)) return mode;
373
- throw new Error(`Unsupported JSON Schema export mode '${mode}'. Expected 'create', 'replace', or 'patch'.`);
374
- }
375
- function resolveOperationName(schema, options = {}) {
376
- if (options.mode !== void 0 && options.operation !== void 0) {
377
- const normalizedMode = normalizeMode(options.mode);
378
- if (normalizedMode !== options.operation) throw new Error(`Conflicting JSON Schema export options: mode '${normalizedMode}' does not match operation '${options.operation}'.`);
379
- }
380
- if (options.operation !== void 0) {
381
- if (!Object.hasOwn(schema.operations, options.operation)) throw new Error(`Unknown JSON Schema export operation '${options.operation}'.`);
382
- return options.operation;
383
- }
384
- return normalizeMode(options.mode);
385
- }
386
- function resolveExportOperation(schema, options = {}) {
387
- if (options.operationName !== void 0 && options.operationDescriptor !== void 0) return {
388
- operationName: options.operationName,
389
- operation: options.operationDescriptor
390
- };
391
- const operationName = resolveOperationName(schema, options);
392
- return {
393
- operationName,
394
- operation: schema.operations[operationName]
395
- };
396
- }
397
- function createExportOptions(options = {}) {
398
- const exportOptions = { ...options };
399
- Object.defineProperty(exportOptions, EXPORT_CONTEXT_KEY, {
400
- value: {
401
- definitions: {},
402
- nodes: [],
403
- nextDefinitionId: 1,
404
- rootNode: null
405
- },
406
- enumerable: false
407
- });
408
- return exportOptions;
409
- }
410
- function getExportContext(options = {}) {
411
- if (options[EXPORT_CONTEXT_KEY]) return options[EXPORT_CONTEXT_KEY];
412
- return {
413
- definitions: {},
414
- nodes: [],
415
- nextDefinitionId: 1,
416
- rootNode: null
417
- };
418
- }
419
- function sanitizeDefinitionNamePart(value) {
420
- return String(value).replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "operation";
421
- }
422
- function isReferenceOnlySchema(schema) {
423
- return isPlainObject(schema) && Object.keys(schema).length === 1 && typeof schema.$ref === "string";
424
- }
425
- function wrapReferenceSchema(schema) {
426
- if (!isReferenceOnlySchema(schema)) return schema;
427
- return { allOf: [schema] };
428
- }
429
- function findExportNode(exportContext, schema, operationName, operation, additionalProperties) {
430
- return exportContext.nodes.find((node) => node.schema === schema && node.operationName === operationName && node.operation === operation && node.additionalProperties === additionalProperties) || null;
431
- }
432
- function createDefinitionName(exportContext, operationName) {
433
- const suffix = sanitizeDefinitionNamePart(operationName);
434
- const definitionName = `SchemaNode_${exportContext.nextDefinitionId}_${suffix}`;
435
- exportContext.nextDefinitionId += 1;
436
- return definitionName;
437
- }
438
- function getOrCreateExportNode(schema, options, operationName, operation, additionalProperties, { root = false } = {}) {
439
- const exportContext = getExportContext(options);
440
- const existingNode = findExportNode(exportContext, schema, operationName, operation, additionalProperties);
441
- if (existingNode) {
442
- if (root) {
443
- existingNode.pointer = "#";
444
- exportContext.rootNode = existingNode;
445
- }
446
- return existingNode;
447
- }
448
- const node = {
449
- schema,
450
- operationName,
451
- operation,
452
- additionalProperties,
453
- status: "new",
454
- definitionName: root ? null : createDefinitionName(exportContext, operationName),
455
- pointer: root ? "#" : null
456
- };
457
- if (!root) node.pointer = `#/definitions/${node.definitionName}`;
458
- else exportContext.rootNode = node;
459
- exportContext.nodes.push(node);
460
- return node;
461
- }
462
- function buildExportNodeSchema(node, options) {
463
- if (node.status === "built") return { $ref: node.pointer };
464
- if (node.status === "building") return { $ref: node.pointer };
465
- const exportContext = getExportContext(options);
466
- node.status = "building";
467
- if (node.pointer !== "#") exportContext.definitions[node.definitionName] = {};
468
- const objectSchema = buildSchemaObjectFragment(node.schema, options, node.operationName, node.operation, node.additionalProperties);
469
- node.status = "built";
470
- if (node.pointer === "#") return objectSchema;
471
- exportContext.definitions[node.definitionName] = objectSchema;
472
- return { $ref: node.pointer };
473
- }
474
- function buildSchemaReference(schema, options, operationName, operation, additionalProperties = false) {
475
- const exportContext = getExportContext(options);
476
- const node = getOrCreateExportNode(schema, options, operationName, operation, additionalProperties);
477
- if (exportContext.rootNode === node) return { $ref: "#" };
478
- return buildExportNodeSchema(node, options);
479
- }
480
- function createFieldSchemaState(schema, { referenceBacked = false } = {}) {
481
- return {
482
- schema,
483
- referenceBacked
484
- };
485
- }
486
- function buildSchemaObjectFragment(schema, options, operationName, operation, additionalProperties = false) {
487
- const properties = {};
488
- const required = [];
489
- for (const [fieldName, definition] of Object.entries(schema.structure)) {
490
- setOwnProperty(properties, fieldName, buildFieldSchema(schema, fieldName, definition, options, operationName, operation));
491
- if (operation.enforceRequired && definition.required === true) required.push(fieldName);
492
- }
493
- const objectSchema = {
494
- type: "object",
495
- properties,
496
- additionalProperties
497
- };
498
- if (required.length > 0) objectSchema.required = required;
499
- return objectSchema;
500
- }
501
- function buildArrayItemsSchema(schema, fieldName, definition, options, operationName, operation) {
502
- const itemsConfig = resolveArrayItemsConfig(fieldName, definition);
503
- if (!itemsConfig) return null;
504
- if (itemsConfig.kind === "schema") return {
505
- ...wrapReferenceSchema(buildSchemaReference(itemsConfig.schema, options, "replace", itemsConfig.schema.operations.replace, false)),
506
- [JSON_REST_EXTENSION_KEY]: { castType: "object" }
507
- };
508
- const itemOperationName = definition.items.type === "object" && Object.hasOwn(definition.items, "schema") ? "replace" : operationName;
509
- const itemOperation = itemOperationName === "replace" ? schema.operations.replace : operation;
510
- return buildFieldSchema(schema, `${fieldName}[]`, definition.items, options, itemOperationName, itemOperation);
511
- }
512
- function buildObjectValuesSchema(schema, fieldName, definition, options, operationName, operation) {
513
- const valuesConfig = resolveObjectValuesConfig(fieldName, definition);
514
- if (!valuesConfig) return null;
515
- if (valuesConfig.kind === "schema") return {
516
- ...wrapReferenceSchema(buildSchemaReference(valuesConfig.schema, options, "replace", valuesConfig.schema.operations.replace, false)),
517
- [JSON_REST_EXTENSION_KEY]: { castType: "object" }
518
- };
519
- const valueOperationName = valuesConfig.definition.type === "object" && Object.hasOwn(valuesConfig.definition, "schema") ? "replace" : operationName;
520
- const valueOperation = valueOperationName === "replace" ? schema.operations.replace : operation;
521
- return buildFieldSchema(schema, `${fieldName}.*`, valuesConfig.definition, options, valueOperationName, valueOperation);
522
- }
523
- function buildBaseFieldSchema(schema, fieldName, definition, options, operationName, operation) {
524
- if (definition.type === "object") {
525
- const objectMode = resolveObjectFieldMode(fieldName, definition);
526
- if (objectMode.kind === "nested") return createFieldSchemaState(buildSchemaReference(objectMode.schema, options, operationName, operation, objectMode.allowAdditionalProperties === true), { referenceBacked: true });
527
- if (objectMode.kind === "opaque") return createFieldSchemaState({
528
- type: "object",
529
- additionalProperties: true
530
- });
531
- if (objectMode.kind === "map") return createFieldSchemaState({
532
- type: "object",
533
- additionalProperties: buildObjectValuesSchema(schema, fieldName, definition, options, operationName, operation)
534
- });
535
- }
536
- const baseSchema = getTypeExporter(schema, definition)({
537
- schema,
538
- fieldName,
539
- definition,
540
- operation: operationName,
541
- mode: operationName,
542
- options
543
- });
544
- if (!baseSchema || typeof baseSchema !== "object" || Array.isArray(baseSchema)) throw new Error(`Type '${definition.type}' on field '${fieldName}' returned an invalid JSON Schema fragment.`);
545
- if (definition.type === "array") {
546
- const itemsSchema = buildArrayItemsSchema(schema, fieldName, definition, options, operationName, operation);
547
- if (itemsSchema) return createFieldSchemaState({
548
- ...baseSchema,
549
- items: itemsSchema
550
- }, { referenceBacked: isReferenceOnlySchema(baseSchema) });
551
- }
552
- return createFieldSchemaState(baseSchema, { referenceBacked: isReferenceOnlySchema(baseSchema) });
553
- }
554
- function buildFieldSchema(schema, fieldName, definition, options, operationName, operation) {
555
- const exportContext = {
556
- schema,
557
- fieldName,
558
- definition,
559
- operation: operationName,
560
- mode: operationName,
561
- options
562
- };
563
- const baseFieldSchemaState = buildBaseFieldSchema(schema, fieldName, definition, options, operationName, operation);
564
- const workingSchema = baseFieldSchemaState.referenceBacked ? wrapReferenceSchema(baseFieldSchemaState.schema) : { ...baseFieldSchemaState.schema };
565
- const extensionMetadata = { castType: definition.type };
566
- for (const parameterName of Object.keys(definition)) {
567
- if (parameterName === "type") continue;
568
- if (!Object.hasOwn(schema.validators, parameterName)) continue;
569
- const exporter = getValidatorExporter(schema, parameterName, fieldName);
570
- if (!exporter) continue;
571
- const fragment = exporter({
572
- ...exportContext,
573
- parameterName,
574
- parameterValue: definition[parameterName],
575
- fieldSchema: { ...workingSchema }
576
- });
577
- if (!fragment) continue;
578
- mergeSchemaFragment(workingSchema, fragment);
579
- }
580
- if (workingSchema[JSON_REST_EXTENSION_KEY]) {
581
- mergePlainObjects(extensionMetadata, workingSchema[JSON_REST_EXTENSION_KEY]);
582
- delete workingSchema[JSON_REST_EXTENSION_KEY];
583
- }
584
- const alternatives = [];
585
- if (definition.nullable === true) alternatives.push({ type: "null" });
586
- if (definition.nullOnEmpty === true) alternatives.push({ const: "" });
587
- const finalSchema = wrapReferenceSchema(buildAnyOfSchema(workingSchema, alternatives));
588
- if (definition.defaultTo !== void 0 && operation.applyDefaults) {
589
- if (typeof definition.defaultTo !== "function") {
590
- const defaultResult = schema._normalizeDefault(definition, definition.defaultTo, {
591
- fieldPath: fieldName,
592
- currentObject: {},
593
- containerKey: fieldName,
594
- objectBeforeCast: {},
595
- options: {},
596
- settings: schema._buildOperationSettings(operationName, operation, {})
597
- });
598
- if (Object.keys(defaultResult.errors).length > 0) {
599
- const firstError = Object.values(defaultResult.errors)[0];
600
- throw new Error(`defaultTo for "${fieldName}" is invalid (${firstError.code}).`);
601
- }
602
- finalSchema.default = defaultResult.value;
603
- } else extensionMetadata.defaults = { providedByFunction: true };
604
- }
605
- finalSchema[JSON_REST_EXTENSION_KEY] = extensionMetadata;
606
- return finalSchema;
607
- }
608
- function buildJsonSchema(schema, options = {}) {
609
- const exportOptions = createExportOptions(options);
610
- const { operationName, operation } = resolveExportOperation(schema, exportOptions);
611
- const additionalProperties = exportOptions.additionalProperties === void 0 ? false : exportOptions.additionalProperties;
612
- const exportContext = getExportContext(exportOptions);
613
- const transportSchema = {
614
- $schema: JSON_SCHEMA_DRAFT_07,
615
- ...buildExportNodeSchema(getOrCreateExportNode(schema, exportOptions, operationName, operation, additionalProperties, { root: true }), exportOptions)
616
- };
617
- if (Object.keys(exportContext.definitions).length > 0) transportSchema.definitions = exportContext.definitions;
618
- return transportSchema;
619
- }
620
- //#endregion
621
- //#region ../../../../node_modules/json-rest-schema/src/core/Schema.js
622
- /**
623
- * @file Defines the Schema class, which contains the core validation engine.
624
- */
625
- /**
626
- * @typedef {object} ValidationError
627
- * @property {string} field - The name of the field that failed validation.
628
- * @property {string} code - A stable, machine-readable error code (e.g., 'MIN_LENGTH').
629
- * @property {string} message - The human-readable error message.
630
- * @property {object} [params] - A key-value object with context about the error (e.g., { min: 3, actual: 2 }).
631
- */
632
- /**
633
- * @typedef {object} ValidationContext
634
- * @property {Schema} schema - The current schema instance.
635
- * @property {object} definition - The schema definition for the specific field.
636
- * @property {any} value - The current value of the field being processed.
637
- * @property {string} fieldName - The name of the field.
638
- * @property {object} object - The full object being validated (with modifications).
639
- * @property {object} objectBeforeCast - The original, unmodified input object.
640
- * @property {any} valueBeforeCast - The original value of the field.
641
- * @property {object} options - The global validation options.
642
- * @property {string} mode - The active validation contract. Preserved as a compatibility alias for `operation`.
643
- * @property {string} operation - The active validation contract name.
644
- * @property {boolean} fieldPresent - Whether the field was explicitly present in the input object.
645
- * @property {{nullable: boolean, nullOnEmpty: boolean}} computedOptions - Calculated options.
646
- * @property {string} [parameterName] - The name of the validator parameter being processed.
647
- * @property {any} [parameterValue] - The value of the validator parameter.
648
- * @property {function(): void} throwTypeError - Throws a standardized type casting error.
649
- * @property {function(string, string, object=): void} throwParamError - Throws a standardized parameter validation error.
650
- */
651
- function isThenable$1(value) {
652
- return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
653
- }
654
- function isSchemaInstance(value) {
655
- return value instanceof Schema;
656
- }
657
- function createSelectionNode() {
658
- return {
659
- self: false,
660
- children: {}
661
- };
662
- }
663
- function hasSelectionChildren(selectionNode) {
664
- return Object.keys(selectionNode.children).length > 0;
665
- }
666
- function joinPath(basePath, pathSegment) {
667
- return `${basePath}.${String(pathSegment)}`;
668
- }
669
- function buildFieldPath(basePath, fieldName) {
670
- return basePath === "" ? String(fieldName) : joinPath(basePath, fieldName);
671
- }
672
- function stripPathPrefix(path, prefix) {
673
- if (path === prefix) return "";
674
- const prefixWithDot = `${prefix}.`;
675
- if (!path.startsWith(prefixWithDot)) return null;
676
- return path.slice(prefixWithDot.length);
677
- }
678
- function prefixErrorMap(errors, prefix) {
679
- const prefixedErrors = {};
680
- for (const error of Object.values(errors)) {
681
- const field = joinPath(prefix, error.field);
682
- setOwnProperty(prefixedErrors, field, {
683
- ...error,
684
- field
685
- });
686
- }
687
- return prefixedErrors;
688
- }
689
- function buildPathSegments(path) {
690
- return buildPathSegments$1(path, "validatePath");
691
- }
692
- function buildSelectionTree(paths) {
693
- const selectionTree = {};
694
- for (const path of paths) {
695
- const segments = buildPathSegments(path);
696
- let currentTree = selectionTree;
697
- for (let index = 0; index < segments.length; index++) {
698
- const segment = segments[index];
699
- if (!Object.hasOwn(currentTree, segment)) setOwnProperty(currentTree, segment, createSelectionNode());
700
- if (index === segments.length - 1) currentTree[segment].self = true;
701
- currentTree = currentTree[segment].children;
702
- }
703
- }
704
- return selectionTree;
705
- }
706
- function getValueAtPath(value, pathSegments) {
707
- let currentValue = value;
708
- for (const segment of pathSegments) {
709
- if (currentValue === null || currentValue === void 0) return void 0;
710
- if (typeof currentValue !== "object") return void 0;
711
- if (!Object.hasOwn(currentValue, segment)) return void 0;
712
- currentValue = currentValue[segment];
713
- }
714
- return currentValue;
715
- }
716
- function hasSelectedValue(value) {
717
- if (value === null) return true;
718
- if (Array.isArray(value)) return Object.keys(value).length > 0;
719
- if (isPlainObject(value)) return Object.keys(value).length > 0;
720
- return value !== void 0;
721
- }
722
- function sortSelectionKeys(keys) {
723
- return [...keys].sort((left, right) => {
724
- const leftIsIndex = /^[0-9]+$/.test(left);
725
- const rightIsIndex = /^[0-9]+$/.test(right);
726
- if (leftIsIndex && rightIsIndex) return Number(left) - Number(right);
727
- if (leftIsIndex) return -1;
728
- if (rightIsIndex) return 1;
729
- return left.localeCompare(right);
730
- });
731
- }
732
- function isNumericPathSegment(segment) {
733
- return /^[0-9]+$/.test(segment);
734
- }
735
- function cloneSchemaIntrospectionSnapshot(schema, seen = /* @__PURE__ */ new WeakMap()) {
736
- if (seen.has(schema)) return seen.get(schema);
737
- const snapshot = Object.create(Schema.prototype);
738
- seen.set(schema, snapshot);
739
- snapshot.structure = null;
740
- snapshot.types = schema.types;
741
- snapshot.validators = schema.validators;
742
- snapshot.operations = schema.operations;
743
- snapshot.structure = freezeIntrospectionValue(cloneIntrospectionValue(schema.structure, seen));
744
- snapshot._installOperationMethods();
745
- return Object.freeze(snapshot);
746
- }
747
- function cloneIntrospectionValue(value, seen = /* @__PURE__ */ new WeakMap()) {
748
- if (value === null || typeof value !== "object") return value;
749
- if (isSchemaInstance(value)) return cloneSchemaIntrospectionSnapshot(value, seen);
750
- if (value instanceof Date) return new Date(value.getTime());
751
- if (value instanceof RegExp) {
752
- const cloned = new RegExp(value.source, value.flags);
753
- cloned.lastIndex = value.lastIndex;
754
- return cloned;
755
- }
756
- if (seen.has(value)) return seen.get(value);
757
- if (Array.isArray(value)) {
758
- const cloned = [];
759
- seen.set(value, cloned);
760
- for (const item of value) cloned.push(cloneIntrospectionValue(item, seen));
761
- return cloned;
762
- }
763
- if (!isPlainObject(value)) return value;
764
- const cloned = {};
765
- seen.set(value, cloned);
766
- for (const [key, entry] of Object.entries(value)) setOwnProperty(cloned, key, cloneIntrospectionValue(entry, seen));
767
- return cloned;
768
- }
769
- function freezeIntrospectionValue(value, seen = /* @__PURE__ */ new WeakSet()) {
770
- if (value === null || typeof value !== "object" || seen.has(value) || isSchemaInstance(value)) return value;
771
- seen.add(value);
772
- if (Array.isArray(value)) for (const item of value) freezeIntrospectionValue(item, seen);
773
- else for (const key of Reflect.ownKeys(value)) freezeIntrospectionValue(value[key], seen);
774
- return Object.freeze(value);
775
- }
776
- function createIntrospectionSnapshot(value) {
777
- return freezeIntrospectionValue(cloneIntrospectionValue(value));
778
- }
779
- function resolveDefinitionFromSchemaPath(schema, pathSegments, basePath = "") {
780
- if (!isSchemaInstance(schema)) return null;
781
- if (!Array.isArray(pathSegments) || pathSegments.length < 1) return null;
782
- const [fieldName, ...rest] = pathSegments;
783
- if (!Object.hasOwn(schema.structure, fieldName)) return null;
784
- const definition = schema.structure[fieldName];
785
- if (rest.length < 1) return definition;
786
- return resolveNestedDefinitionAtPath(schema, definition, rest, buildFieldPath(basePath, fieldName));
787
- }
788
- function resolveNestedDefinitionAtPath(schema, definition, pathSegments, fieldPath) {
789
- if (definition?.type === "object") {
790
- const objectMode = schema._resolveObjectFieldMode(fieldPath, definition);
791
- if (objectMode.kind !== "nested") return null;
792
- return resolveDefinitionFromSchemaPath(objectMode.schema, pathSegments, fieldPath);
793
- }
794
- if (definition?.type === "array") {
795
- const itemsConfig = schema._resolveArrayItemsConfig(fieldPath, definition);
796
- if (!itemsConfig || pathSegments.length < 1) return null;
797
- const [indexSegment, ...rest] = pathSegments;
798
- if (!isNumericPathSegment(indexSegment)) return null;
799
- const itemPath = joinPath(fieldPath, indexSegment);
800
- if (itemsConfig.kind === "schema") {
801
- if (rest.length < 1) return null;
802
- return resolveDefinitionFromSchemaPath(itemsConfig.schema, rest, itemPath);
803
- }
804
- if (rest.length < 1) return itemsConfig.definition;
805
- return resolveNestedDefinitionAtPath(schema, itemsConfig.definition, rest, itemPath);
806
- }
807
- return null;
808
- }
809
- function buildNestedOptions(options, prefix) {
810
- const nestedOptions = { ...options };
811
- if (Array.isArray(options.skipFields)) {
812
- const skipFields = options.skipFields.map((fieldPath) => stripPathPrefix(fieldPath, prefix)).filter((fieldPath) => fieldPath !== null && fieldPath !== "");
813
- if (skipFields.length > 0) nestedOptions.skipFields = skipFields;
814
- else delete nestedOptions.skipFields;
815
- }
816
- if (isPlainObject(options.skipParams)) {
817
- const skipParams = {};
818
- for (const [fieldPath, parameters] of Object.entries(options.skipParams)) {
819
- const nestedFieldPath = stripPathPrefix(fieldPath, prefix);
820
- if (nestedFieldPath === null || nestedFieldPath === "") continue;
821
- setOwnProperty(skipParams, nestedFieldPath, parameters);
822
- }
823
- if (Object.keys(skipParams).length > 0) nestedOptions.skipParams = skipParams;
824
- else delete nestedOptions.skipParams;
825
- }
826
- return nestedOptions;
827
- }
828
- var DEFAULT_OPERATIONS = Object.freeze({
829
- create: Object.freeze({
830
- targetFields: "schema",
831
- enforceRequired: true,
832
- applyDefaults: true,
833
- outputFields: "validated",
834
- rejectExplicitUndefined: true
835
- }),
836
- replace: Object.freeze({
837
- targetFields: "schema",
838
- enforceRequired: true,
839
- applyDefaults: true,
840
- outputFields: "validated",
841
- rejectExplicitUndefined: true
842
- }),
843
- patch: Object.freeze({
844
- targetFields: "input",
845
- enforceRequired: false,
846
- applyDefaults: false,
847
- outputFields: "input",
848
- rejectExplicitUndefined: true
849
- })
850
- });
851
- function validateOperationOption(operationName, descriptor, key, allowedValues) {
852
- const value = descriptor[key];
853
- if (!allowedValues.includes(value)) throw new Error(`Operation "${operationName}" must define ${key} as one of: ${allowedValues.join(", ")}.`);
854
- }
855
- function validateBooleanOperationOption(operationName, descriptor, key, required = true) {
856
- const value = descriptor[key];
857
- if (value === void 0 && !required) return;
858
- if (typeof value !== "boolean") throw new Error(`Operation "${operationName}" must define ${key} as a boolean.`);
859
- }
860
- function normalizeOperationDescriptor(operationName, descriptor) {
861
- if (typeof descriptor !== "object" || descriptor === null || Array.isArray(descriptor)) throw new Error(`Operation "${operationName}" must be an object.`);
862
- validateOperationOption(operationName, descriptor, "targetFields", ["schema", "input"]);
863
- validateBooleanOperationOption(operationName, descriptor, "enforceRequired");
864
- validateBooleanOperationOption(operationName, descriptor, "applyDefaults");
865
- validateOperationOption(operationName, descriptor, "outputFields", ["validated", "input"]);
866
- validateBooleanOperationOption(operationName, descriptor, "rejectExplicitUndefined", false);
867
- return Object.freeze({
868
- targetFields: descriptor.targetFields,
869
- enforceRequired: descriptor.enforceRequired,
870
- applyDefaults: descriptor.applyDefaults,
871
- outputFields: descriptor.outputFields,
872
- rejectExplicitUndefined: descriptor.rejectExplicitUndefined === void 0 ? true : descriptor.rejectExplicitUndefined
873
- });
874
- }
875
- function normalizeOperations(operations = {}) {
876
- if (typeof operations !== "object" || operations === null || Array.isArray(operations)) throw new Error("Schema operations must be an object.");
877
- const normalizedOperations = Object.create(null);
878
- for (const [operationName, descriptor] of Object.entries(DEFAULT_OPERATIONS)) setOwnProperty(normalizedOperations, operationName, descriptor);
879
- for (const [operationName, descriptor] of Object.entries(operations)) setOwnProperty(normalizedOperations, operationName, normalizeOperationDescriptor(operationName, descriptor));
880
- return Object.freeze(normalizedOperations);
881
- }
882
- function freezeOwnMap(source) {
883
- const map = Object.create(null);
884
- for (const [key, value] of Object.entries(source)) setOwnProperty(map, key, value);
885
- return Object.freeze(map);
886
- }
887
- function cloneValidationOptions(options) {
888
- const validationOptions = { ...options };
889
- delete validationOptions.operation;
890
- delete validationOptions.mode;
891
- return validationOptions;
892
- }
893
- /**
894
- * Represents an instance of a schema that can validate objects against a structure.
895
- * This class is instantiated by the createSchema factory function.
896
- */
897
- var Schema = class {
898
- /**
899
- * @param {object} structure The schema definition.
900
- * @param {object} types The globally registered type handlers.
901
- * @param {object} validators The globally registered validator handlers.
902
- * @param {object} [operations={}] Per-schema operation descriptors.
903
- */
904
- constructor(structure, types, validators, operations = {}) {
905
- this.structure = structure;
906
- this.types = freezeOwnMap(types);
907
- this.validators = freezeOwnMap(validators);
908
- this.operations = normalizeOperations(operations);
909
- this._installOperationMethods();
910
- }
911
- /** @private */
912
- _typeError(field) {
913
- return this._paramError(field, "TYPE_CAST_FAILED", "Value could not be cast to the required type.");
914
- }
915
- /** @private */
916
- _paramError(field, code, message, params = {}) {
917
- const e = new Error(message);
918
- e.errorObject = {
919
- field,
920
- code,
921
- message,
922
- params
923
- };
924
- return e;
925
- }
926
- /** @private */
927
- _paramToBeSkipped(parameterName, skipParams, fieldName) {
928
- if (typeof skipParams !== "object" || skipParams === null) return false;
929
- if (Array.isArray(skipParams[fieldName]) && skipParams[fieldName].includes(parameterName)) return true;
930
- return false;
931
- }
932
- /** @private */
933
- _fieldToBeSkipped(fieldPath, options) {
934
- return Array.isArray(options.skipFields) && options.skipFields.includes(fieldPath);
935
- }
936
- /** @private */
937
- _mergeErrors(target, source) {
938
- for (const [fieldPath, error] of Object.entries(source)) setOwnProperty(target, fieldPath, error);
939
- }
940
- /** @private */
941
- _singleErrorMap(error) {
942
- const errors = {};
943
- setOwnProperty(errors, error.field, error);
944
- return errors;
945
- }
946
- /** @private */
947
- _assertSupportedOptions(options = {}) {
948
- if (Object.hasOwn(options, "onlyObjectValues")) throw new Error("Unsupported validation option `onlyObjectValues`. Call `patch()` directly.");
949
- if (Object.hasOwn(options, "mode")) throw new Error("Unsupported validation option `mode`. Call `validateWith()` or an operation method directly.");
950
- if (Object.hasOwn(options, "operation")) throw new Error("Unsupported validation option `operation`. Call `validateWith()` or an operation method directly.");
951
- }
952
- /** @private */
953
- _buildOperationSettings(operationName, operation, object) {
954
- return {
955
- operationName,
956
- operation,
957
- targetFieldNames: operation.targetFields === "input" ? Object.keys(object) : Object.keys(this.structure),
958
- outputFieldNames: operation.outputFields === "input" ? Object.keys(object) : Object.keys(this.structure),
959
- enforceRequired: operation.enforceRequired,
960
- applyDefaults: operation.applyDefaults,
961
- rejectExplicitUndefined: operation.rejectExplicitUndefined,
962
- defaultedFields: /* @__PURE__ */ new Set(),
963
- isFieldPresent: (fieldName) => Object.hasOwn(object, fieldName)
964
- };
965
- }
966
- /** @private */
967
- _assertPlainObjectInput(methodName, object) {
968
- if (!isPlainObject(object)) throw new Error(`${methodName}() expects a plain object input.`);
969
- }
970
- /** @private */
971
- _resolvePathValidationRequest(options = {}) {
972
- const operationName = options.operation ?? options.mode ?? "patch";
973
- if (Object.hasOwn(options, "operation") && Object.hasOwn(options, "mode") && options.operation !== options.mode) throw new Error("Path validation options `operation` and `mode` must match when both are provided.");
974
- if (!Object.hasOwn(this.operations, operationName)) throw new Error(`Unknown operation "${operationName}".`);
975
- return {
976
- operationName,
977
- operation: this.operations[operationName],
978
- validationOptions: cloneValidationOptions(options)
979
- };
980
- }
981
- /** @private */
982
- _buildOperationResult(object, workingObject, settings) {
983
- const validatedObject = {};
984
- for (const fieldName of settings.outputFieldNames) {
985
- if (!Object.hasOwn(this.structure, fieldName)) continue;
986
- const fieldPresent = settings.isFieldPresent(fieldName);
987
- if (!(workingObject[fieldName] !== void 0 || fieldPresent && object[fieldName] === null || settings.defaultedFields.has(fieldName))) continue;
988
- if (!fieldPresent && !settings.defaultedFields.has(fieldName)) continue;
989
- setOwnProperty(validatedObject, fieldName, workingObject[fieldName]);
990
- }
991
- return validatedObject;
992
- }
993
- /** @private */
994
- _resolveObjectFieldMode(fieldPath, definition) {
995
- return resolveObjectFieldMode(fieldPath, definition);
996
- }
997
- /** @private */
998
- _resolveArrayItemsConfig(fieldPath, definition) {
999
- return resolveArrayItemsConfig(fieldPath, definition);
1000
- }
1001
- /** @private */
1002
- _resolveObjectValuesConfig(fieldPath, definition) {
1003
- return resolveObjectValuesConfig(fieldPath, definition);
1004
- }
1005
- /** @private */
1006
- _buildArrayItemSettings(definition, settings) {
1007
- if (definition.type === "object" && Object.hasOwn(definition, "schema")) return {
1008
- ...settings,
1009
- operationName: "replace",
1010
- operation: this.operations.replace
1011
- };
1012
- return settings;
1013
- }
1014
- /** @private */
1015
- _castValue(definition, rawValue, fieldPath, currentObject, containerKey, objectBeforeCast, options, settings) {
1016
- const nullable = definition.nullable === true || options.nullable === true;
1017
- const nullOnEmpty = definition.nullOnEmpty === true || options.nullOnEmpty === true;
1018
- if (!Object.hasOwn(this.types, definition.type)) throw new Error(`No casting function for type: ${definition.type}`);
1019
- const typeHandler = this.types[definition.type];
1020
- if (rawValue === null) {
1021
- if (nullable) {
1022
- setOwnProperty(currentObject, containerKey, null);
1023
- return {
1024
- errors: {},
1025
- shouldContinue: false
1026
- };
1027
- }
1028
- return {
1029
- errors: this._singleErrorMap({
1030
- field: fieldPath,
1031
- code: "NOT_NULLABLE",
1032
- message: "Field cannot be null",
1033
- params: {}
1034
- }),
1035
- shouldContinue: false
1036
- };
1037
- }
1038
- if (rawValue === "" && nullOnEmpty) {
1039
- setOwnProperty(currentObject, containerKey, null);
1040
- return {
1041
- errors: {},
1042
- shouldContinue: false
1043
- };
1044
- }
1045
- /** @type {ValidationContext} */
1046
- const context = {
1047
- schema: this,
1048
- definition,
1049
- value: rawValue,
1050
- fieldName: fieldPath,
1051
- object: currentObject,
1052
- objectBeforeCast,
1053
- valueBeforeCast: rawValue,
1054
- options,
1055
- mode: settings.operationName,
1056
- operation: settings.operationName,
1057
- fieldPresent: true,
1058
- computedOptions: {
1059
- nullable: nullable || nullOnEmpty,
1060
- nullOnEmpty
1061
- },
1062
- throwTypeError: () => {
1063
- throw this._typeError(fieldPath);
1064
- },
1065
- throwParamError: (code, message, params) => {
1066
- throw this._paramError(fieldPath, code, message, params);
1067
- }
1068
- };
1069
- try {
1070
- const castResult = typeHandler(context);
1071
- if (isThenable$1(castResult)) throw new Error(`Type handler for "${definition.type}" must be synchronous.`);
1072
- if (castResult !== void 0) {
1073
- setOwnProperty(currentObject, containerKey, castResult);
1074
- context.value = castResult;
1075
- }
1076
- } catch (e) {
1077
- if (e.errorObject) return {
1078
- errors: this._singleErrorMap(e.errorObject),
1079
- shouldContinue: false
1080
- };
1081
- throw e;
1082
- }
1083
- return {
1084
- errors: {},
1085
- context,
1086
- shouldContinue: true
1087
- };
1088
- }
1089
- /** @private */
1090
- _runFieldValidators(definition, fieldPath, currentObject, containerKey, context, options) {
1091
- for (const paramName of Object.keys(definition)) {
1092
- if (paramName === "type") continue;
1093
- if (this._paramToBeSkipped(paramName, options.skipParams, fieldPath)) continue;
1094
- if (!Object.hasOwn(this.validators, paramName)) continue;
1095
- const validatorHandler = this.validators[paramName];
1096
- try {
1097
- context.parameterName = paramName;
1098
- context.parameterValue = definition[paramName];
1099
- const validatorResult = validatorHandler(context);
1100
- if (isThenable$1(validatorResult)) throw new Error(`Validator handler for "${paramName}" must be synchronous.`);
1101
- if (validatorResult !== void 0) {
1102
- setOwnProperty(currentObject, containerKey, validatorResult);
1103
- context.value = validatorResult;
1104
- }
1105
- } catch (e) {
1106
- if (e.errorObject) return this._singleErrorMap(e.errorObject);
1107
- throw e;
1108
- }
1109
- }
1110
- return {};
1111
- }
1112
- /** @private */
1113
- _normalizeAndValidateValue(definition, rawValue, fieldPath, currentObject, containerKey, objectBeforeCast, options, settings) {
1114
- const castResult = this._castValue(definition, rawValue, fieldPath, currentObject, containerKey, objectBeforeCast, options, settings);
1115
- if (Object.keys(castResult.errors).length > 0) return castResult.errors;
1116
- if (!castResult.shouldContinue) return {};
1117
- const { context } = castResult;
1118
- const nestedErrors = this._validateNestedValue(definition, fieldPath, currentObject, containerKey, options, settings);
1119
- if (Object.keys(nestedErrors).length > 0) return nestedErrors;
1120
- context.value = currentObject[containerKey];
1121
- return this._runFieldValidators(definition, fieldPath, currentObject, containerKey, context, options);
1122
- }
1123
- /** @private */
1124
- _normalizeDefault(definition, defaultValue, { fieldPath, currentObject, containerKey, objectBeforeCast, options, settings }) {
1125
- const defaultObject = { ...currentObject };
1126
- setOwnProperty(defaultObject, containerKey, defaultValue);
1127
- return {
1128
- errors: this._normalizeAndValidateValue(definition, defaultValue, fieldPath, defaultObject, containerKey, objectBeforeCast, options, settings),
1129
- value: defaultObject[containerKey]
1130
- };
1131
- }
1132
- /** @private */
1133
- _validateNestedValue(definition, fieldPath, currentObject, containerKey, options, settings) {
1134
- if (definition.type === "object") {
1135
- const objectMode = this._resolveObjectFieldMode(fieldPath, definition);
1136
- if (objectMode.kind === "nested") return this._validateNestedObjectSchema(objectMode, fieldPath, currentObject, containerKey, options, settings);
1137
- if (objectMode.kind === "map") return this._validateObjectValues(fieldPath, currentObject, containerKey, objectMode.valuesConfig, options, settings);
1138
- return {};
1139
- }
1140
- if (definition.type !== "array") return {};
1141
- const itemsConfig = this._resolveArrayItemsConfig(fieldPath, definition);
1142
- if (!itemsConfig) return {};
1143
- return this._validateArrayItems(fieldPath, currentObject, containerKey, itemsConfig, options, settings);
1144
- }
1145
- /** @private */
1146
- _validateNestedObjectSchema(objectMode, fieldPath, currentObject, containerKey, options, settings) {
1147
- const sourceObject = currentObject[containerKey];
1148
- const nestedInput = objectMode.allowAdditionalProperties ? this._extractKnownObjectFields(sourceObject, objectMode.schema) : sourceObject;
1149
- const nestedResult = objectMode.schema._validateWithOperation(settings.operationName, settings.operation, nestedInput, buildNestedOptions(options, fieldPath));
1150
- setOwnProperty(currentObject, containerKey, objectMode.allowAdditionalProperties ? this._mergeKnownAndPassthroughObjectFields(sourceObject, objectMode.schema, nestedResult.validatedObject) : nestedResult.validatedObject);
1151
- return prefixErrorMap(nestedResult.errors, fieldPath);
1152
- }
1153
- /** @private */
1154
- _extractKnownObjectFields(sourceObject, nestedSchema) {
1155
- const knownObject = {};
1156
- for (const [key, value] of Object.entries(sourceObject)) if (Object.hasOwn(nestedSchema.structure, key)) setOwnProperty(knownObject, key, value);
1157
- return knownObject;
1158
- }
1159
- /** @private */
1160
- _mergeKnownAndPassthroughObjectFields(sourceObject, nestedSchema, validatedObject) {
1161
- const mergedObject = {};
1162
- for (const key of Object.keys(sourceObject)) {
1163
- if (!Object.hasOwn(nestedSchema.structure, key)) {
1164
- setOwnProperty(mergedObject, key, sourceObject[key]);
1165
- continue;
1166
- }
1167
- if (Object.hasOwn(validatedObject, key)) setOwnProperty(mergedObject, key, validatedObject[key]);
1168
- }
1169
- for (const [key, value] of Object.entries(validatedObject)) if (!Object.hasOwn(mergedObject, key)) setOwnProperty(mergedObject, key, value);
1170
- return mergedObject;
1171
- }
1172
- /** @private */
1173
- _validateObjectValues(fieldPath, currentObject, containerKey, valuesConfig, options, settings) {
1174
- const originalEntries = currentObject[containerKey];
1175
- const normalizedEntries = { ...originalEntries };
1176
- const errors = {};
1177
- setOwnProperty(currentObject, containerKey, normalizedEntries);
1178
- for (const key of Object.keys(originalEntries)) {
1179
- const valuePath = joinPath(fieldPath, key);
1180
- if (this._fieldToBeSkipped(valuePath, options)) continue;
1181
- const rawValue = normalizedEntries[key];
1182
- if (rawValue === void 0) {
1183
- if (settings.rejectExplicitUndefined) this._mergeErrors(errors, this._singleErrorMap(this._typeError(valuePath).errorObject));
1184
- else delete normalizedEntries[key];
1185
- continue;
1186
- }
1187
- if (valuesConfig.kind === "schema") {
1188
- const valueResult = valuesConfig.schema._validateWithOperation("replace", valuesConfig.schema.operations.replace, rawValue, buildNestedOptions(options, valuePath));
1189
- setOwnProperty(normalizedEntries, key, valueResult.validatedObject);
1190
- this._mergeErrors(errors, prefixErrorMap(valueResult.errors, valuePath));
1191
- continue;
1192
- }
1193
- const valueErrors = this._normalizeAndValidateValue(valuesConfig.definition, rawValue, valuePath, normalizedEntries, key, originalEntries, options, this._buildArrayItemSettings(valuesConfig.definition, settings));
1194
- this._mergeErrors(errors, valueErrors);
1195
- }
1196
- return errors;
1197
- }
1198
- /** @private */
1199
- _validateArrayItems(fieldPath, currentObject, containerKey, itemsConfig, options, settings) {
1200
- const originalItems = currentObject[containerKey];
1201
- const normalizedItems = originalItems.slice();
1202
- const errors = {};
1203
- setOwnProperty(currentObject, containerKey, normalizedItems);
1204
- for (let index = 0; index < normalizedItems.length; index++) {
1205
- const itemPath = joinPath(fieldPath, index);
1206
- if (this._fieldToBeSkipped(itemPath, options)) continue;
1207
- if (!Object.hasOwn(originalItems, index) || normalizedItems[index] === void 0) {
1208
- if (settings.rejectExplicitUndefined) this._mergeErrors(errors, this._singleErrorMap(this._typeError(itemPath).errorObject));
1209
- else delete normalizedItems[index];
1210
- continue;
1211
- }
1212
- if (itemsConfig.kind === "schema") {
1213
- const itemResult = itemsConfig.schema._validateWithOperation("replace", itemsConfig.schema.operations.replace, normalizedItems[index], buildNestedOptions(options, itemPath));
1214
- setOwnProperty(normalizedItems, index, itemResult.validatedObject);
1215
- this._mergeErrors(errors, prefixErrorMap(itemResult.errors, itemPath));
1216
- continue;
1217
- }
1218
- const itemErrors = this._normalizeAndValidateValue(itemsConfig.definition, normalizedItems[index], itemPath, normalizedItems, index, originalItems, options, this._buildArrayItemSettings(itemsConfig.definition, settings));
1219
- this._mergeErrors(errors, itemErrors);
1220
- }
1221
- return errors;
1222
- }
1223
- /**
1224
- * Processes a single field through the entire validation pipeline (pre-checks, casting, validators).
1225
- * This is the heart of the validation logic for an individual field.
1226
- * @private
1227
- * @param {string} fieldName - The name of the field to validate.
1228
- * @param {object} object - The original input object.
1229
- * @param {object} validatedObject - The object being built with validated data.
1230
- * @param {object} options - The global validation options.
1231
- * @param {object} settings - Mode-specific validation settings.
1232
- * @returns {ValidationError|null} An error object if validation fails, otherwise null.
1233
- */
1234
- _validateField(fieldName, object, validatedObject, options, settings) {
1235
- if (!Object.hasOwn(this.structure, fieldName)) return {};
1236
- const definition = this.structure[fieldName];
1237
- if (this._fieldToBeSkipped(fieldName, options)) return {};
1238
- const fieldPresent = settings.isFieldPresent(fieldName);
1239
- const rawValue = object[fieldName];
1240
- const valueMissing = rawValue === void 0;
1241
- if (settings.enforceRequired && definition.required && (!fieldPresent || valueMissing)) {
1242
- if (!this._paramToBeSkipped("required", options.skipParams, fieldName)) return this._singleErrorMap({
1243
- field: fieldName,
1244
- code: "REQUIRED",
1245
- message: "Field is required",
1246
- params: {}
1247
- });
1248
- }
1249
- if (!fieldPresent) return {};
1250
- if (valueMissing) {
1251
- if (settings.rejectExplicitUndefined) return this._singleErrorMap(this._typeError(fieldName).errorObject);
1252
- return {};
1253
- }
1254
- return this._normalizeAndValidateValue(definition, rawValue, fieldName, validatedObject, fieldName, object, options, settings);
1255
- }
1256
- /** @private */
1257
- _validateWithOperation(operationName, operation, object, options) {
1258
- this._assertSupportedOptions(options);
1259
- const errors = {};
1260
- const workingObject = { ...object };
1261
- const settings = this._buildOperationSettings(operationName, operation, object);
1262
- for (const fieldName of Object.keys(object)) if (!Object.hasOwn(this.structure, fieldName)) setOwnProperty(errors, fieldName, {
1263
- field: fieldName,
1264
- code: "FIELD_NOT_ALLOWED",
1265
- message: "Field not allowed",
1266
- params: {}
1267
- });
1268
- for (const fieldName of settings.targetFieldNames) {
1269
- const fieldErrors = this._validateField(fieldName, object, workingObject, options, settings);
1270
- this._mergeErrors(errors, fieldErrors);
1271
- }
1272
- if (settings.applyDefaults) for (const fieldName of Object.keys(this.structure)) {
1273
- if (settings.isFieldPresent(fieldName)) continue;
1274
- if (this.structure[fieldName].defaultTo !== void 0) {
1275
- const definition = this.structure[fieldName];
1276
- const defaultValue = typeof definition.defaultTo === "function" ? definition.defaultTo() : definition.defaultTo;
1277
- const defaultResult = this._normalizeDefault(definition, defaultValue, {
1278
- fieldPath: fieldName,
1279
- currentObject: workingObject,
1280
- containerKey: fieldName,
1281
- objectBeforeCast: object,
1282
- options,
1283
- settings
1284
- });
1285
- this._mergeErrors(errors, defaultResult.errors);
1286
- if (Object.keys(defaultResult.errors).length > 0) continue;
1287
- setOwnProperty(workingObject, fieldName, defaultResult.value);
1288
- settings.defaultedFields.add(fieldName);
1289
- }
1290
- }
1291
- return {
1292
- validatedObject: this._buildOperationResult(object, workingObject, settings),
1293
- errors
1294
- };
1295
- }
1296
- /** @private */
1297
- _validateSelectedTree(selectionTree, object, options, settings, basePath = "") {
1298
- const errors = {};
1299
- const validatedObject = {};
1300
- for (const fieldName of sortSelectionKeys(Object.keys(selectionTree))) {
1301
- const fieldPath = buildFieldPath(basePath, fieldName);
1302
- if (!Object.hasOwn(this.structure, fieldName)) throw new Error(`Unknown schema path "${fieldPath}".`);
1303
- const fieldErrors = this._validateSelectedField(fieldName, selectionTree[fieldName], object, validatedObject, options, settings, fieldPath);
1304
- this._mergeErrors(errors, fieldErrors);
1305
- }
1306
- return {
1307
- validatedObject,
1308
- errors
1309
- };
1310
- }
1311
- /** @private */
1312
- _validateSelectedField(fieldName, selectionNode, object, validatedObject, options, settings, fieldPath) {
1313
- if (!Object.hasOwn(this.structure, fieldName)) return {};
1314
- const definition = this.structure[fieldName];
1315
- const exactSelected = selectionNode.self === true;
1316
- const hasChildren = hasSelectionChildren(selectionNode);
1317
- if (this._fieldToBeSkipped(fieldPath, options)) return {};
1318
- const fieldPresent = Object.hasOwn(object, fieldName);
1319
- const rawValue = object[fieldName];
1320
- const errors = {};
1321
- if (!fieldPresent) {
1322
- if (exactSelected && settings.enforceRequired && definition.required && !this._paramToBeSkipped("required", options.skipParams, fieldPath)) this._mergeErrors(errors, this._singleErrorMap({
1323
- field: fieldPath,
1324
- code: "REQUIRED",
1325
- message: "Field is required",
1326
- params: {}
1327
- }));
1328
- if (exactSelected && settings.applyDefaults && definition.defaultTo !== void 0) {
1329
- const defaultValue = typeof definition.defaultTo === "function" ? definition.defaultTo() : definition.defaultTo;
1330
- const defaultResult = this._normalizeDefault(definition, defaultValue, {
1331
- fieldPath,
1332
- currentObject: validatedObject,
1333
- containerKey: fieldName,
1334
- objectBeforeCast: object,
1335
- options,
1336
- settings
1337
- });
1338
- this._mergeErrors(errors, defaultResult.errors);
1339
- if (Object.keys(defaultResult.errors).length === 0) setOwnProperty(validatedObject, fieldName, defaultResult.value);
1340
- }
1341
- return errors;
1342
- }
1343
- if (rawValue === void 0) {
1344
- if (exactSelected && settings.rejectExplicitUndefined) return this._singleErrorMap(this._typeError(fieldPath).errorObject);
1345
- return {};
1346
- }
1347
- const currentObject = { [fieldName]: rawValue };
1348
- if (exactSelected) {
1349
- const fieldErrors = this._normalizeAndValidateValue(definition, rawValue, fieldPath, currentObject, fieldName, object, options, settings);
1350
- if (Object.hasOwn(currentObject, fieldName) && currentObject[fieldName] !== void 0) setOwnProperty(validatedObject, fieldName, currentObject[fieldName]);
1351
- else if (currentObject[fieldName] === null) setOwnProperty(validatedObject, fieldName, null);
1352
- return fieldErrors;
1353
- }
1354
- if (!hasChildren) return {};
1355
- const castResult = this._castValue(definition, rawValue, fieldPath, currentObject, fieldName, object, options, settings);
1356
- if (Object.keys(castResult.errors).length > 0) return castResult.errors;
1357
- if (!castResult.shouldContinue) return {};
1358
- const nestedResult = this._validateSelectedDescendants(definition, selectionNode.children, fieldPath, currentObject, fieldName, options, settings);
1359
- if (hasSelectedValue(currentObject[fieldName])) setOwnProperty(validatedObject, fieldName, currentObject[fieldName]);
1360
- return nestedResult;
1361
- }
1362
- /** @private */
1363
- _validateSelectedDescendants(definition, selectionTree, fieldPath, currentObject, containerKey, options, settings) {
1364
- if (definition.type === "object") {
1365
- const objectMode = this._resolveObjectFieldMode(fieldPath, definition);
1366
- if (objectMode.kind !== "nested") throw new Error(`Schema path "${fieldPath}" does not support nested field selection.`);
1367
- const nestedValue = currentObject[containerKey];
1368
- if (!isPlainObject(nestedValue)) return {};
1369
- const nestedResult = objectMode.schema._validateSelectedTree(selectionTree, nestedValue, buildNestedOptions(options, fieldPath), {
1370
- ...settings,
1371
- defaultedFields: /* @__PURE__ */ new Set()
1372
- });
1373
- setOwnProperty(currentObject, containerKey, nestedResult.validatedObject);
1374
- return prefixErrorMap(nestedResult.errors, fieldPath);
1375
- }
1376
- if (definition.type === "array") {
1377
- const itemsConfig = this._resolveArrayItemsConfig(fieldPath, definition);
1378
- if (!itemsConfig) throw new Error(`Schema path "${fieldPath}" does not define array items for nested selection.`);
1379
- return this._validateSelectedArrayItems(fieldPath, currentObject, containerKey, itemsConfig, selectionTree, options, settings);
1380
- }
1381
- throw new Error(`Schema path "${fieldPath}" does not support nested field selection.`);
1382
- }
1383
- /** @private */
1384
- _validateSelectedArrayItems(fieldPath, currentObject, containerKey, itemsConfig, selectionTree, options, settings) {
1385
- const normalizedItems = [];
1386
- const sourceItems = currentObject[containerKey];
1387
- const errors = {};
1388
- setOwnProperty(currentObject, containerKey, normalizedItems);
1389
- for (const indexKey of sortSelectionKeys(Object.keys(selectionTree))) {
1390
- if (!/^[0-9]+$/.test(indexKey)) throw new Error(`Schema path "${joinPath(fieldPath, indexKey)}" is invalid because array segments must use numeric indexes.`);
1391
- const index = Number(indexKey);
1392
- const itemPath = joinPath(fieldPath, index);
1393
- const selectionNode = selectionTree[indexKey];
1394
- const exactSelected = selectionNode.self === true;
1395
- const hasChildren = hasSelectionChildren(selectionNode);
1396
- if (this._fieldToBeSkipped(itemPath, options)) continue;
1397
- if (!Object.hasOwn(sourceItems, index)) {
1398
- if (exactSelected && settings.rejectExplicitUndefined) setOwnProperty(errors, itemPath, this._typeError(itemPath).errorObject);
1399
- continue;
1400
- }
1401
- const rawValue = sourceItems[index];
1402
- if (rawValue === void 0) {
1403
- if (exactSelected && settings.rejectExplicitUndefined) setOwnProperty(errors, itemPath, this._typeError(itemPath).errorObject);
1404
- continue;
1405
- }
1406
- if (itemsConfig.kind === "schema") {
1407
- if (exactSelected) {
1408
- const itemResult = itemsConfig.schema._validateWithOperation("replace", itemsConfig.schema.operations.replace, rawValue, buildNestedOptions(options, itemPath));
1409
- if (hasSelectedValue(itemResult.validatedObject)) setOwnProperty(normalizedItems, index, itemResult.validatedObject);
1410
- this._mergeErrors(errors, prefixErrorMap(itemResult.errors, itemPath));
1411
- continue;
1412
- }
1413
- if (!hasChildren) continue;
1414
- const itemResult = itemsConfig.schema._validateSelectedTree(selectionNode.children, rawValue, buildNestedOptions(options, itemPath), {
1415
- ...settings,
1416
- operationName: "replace",
1417
- operation: itemsConfig.schema.operations.replace,
1418
- defaultedFields: /* @__PURE__ */ new Set()
1419
- });
1420
- if (hasSelectedValue(itemResult.validatedObject)) setOwnProperty(normalizedItems, index, itemResult.validatedObject);
1421
- this._mergeErrors(errors, prefixErrorMap(itemResult.errors, itemPath));
1422
- continue;
1423
- }
1424
- const itemSettings = this._buildArrayItemSettings(itemsConfig.definition, settings);
1425
- const itemHolder = [rawValue];
1426
- if (exactSelected) {
1427
- const itemErrors = this._normalizeAndValidateValue(itemsConfig.definition, rawValue, itemPath, itemHolder, 0, sourceItems, options, itemSettings);
1428
- if (Object.hasOwn(itemHolder, 0) && itemHolder[0] !== void 0) setOwnProperty(normalizedItems, index, itemHolder[0]);
1429
- else if (itemHolder[0] === null) setOwnProperty(normalizedItems, index, null);
1430
- this._mergeErrors(errors, itemErrors);
1431
- continue;
1432
- }
1433
- if (!hasChildren) continue;
1434
- const castResult = this._castValue(itemsConfig.definition, rawValue, itemPath, itemHolder, 0, sourceItems, options, itemSettings);
1435
- if (Object.keys(castResult.errors).length > 0) {
1436
- this._mergeErrors(errors, castResult.errors);
1437
- continue;
1438
- }
1439
- if (!castResult.shouldContinue) continue;
1440
- const itemErrors = this._validateSelectedDescendants(itemsConfig.definition, selectionNode.children, itemPath, itemHolder, 0, options, itemSettings);
1441
- if (hasSelectedValue(itemHolder[0])) setOwnProperty(normalizedItems, index, itemHolder[0]);
1442
- this._mergeErrors(errors, itemErrors);
1443
- }
1444
- return errors;
1445
- }
1446
- /**
1447
- * Validates an object with a named operation contract.
1448
- * @param {string} operationName - The operation contract to use.
1449
- * @param {object} object - The input object to validate.
1450
- * @param {object} [options={}] - Validation options.
1451
- * @returns {{validatedObject: object, errors: Object.<string, ValidationError>}}
1452
- */
1453
- validateWith(operationName, object, options = {}) {
1454
- if (!Object.hasOwn(this.operations, operationName)) throw new Error(`Unknown operation "${operationName}".`);
1455
- const operation = this.operations[operationName];
1456
- this._assertPlainObjectInput(operationName, object);
1457
- return this._validateWithOperation(operationName, operation, object, options);
1458
- }
1459
- /**
1460
- * Validates a single schema path against the selected operation.
1461
- * Defaults to `patch` semantics when no operation is specified.
1462
- * @param {string} path - A dotted schema path such as `email` or `workspace.slug`.
1463
- * @param {object} object - The input object to validate.
1464
- * @param {{operation?: string, mode?: string}} [options={}] - Path validation options.
1465
- * @returns {{validatedValue: any, errors: Object.<string, ValidationError>}}
1466
- */
1467
- validateAt(path, object, options = {}) {
1468
- this._assertPlainObjectInput("validateAt", object);
1469
- const pathSegments = buildPathSegments(path);
1470
- const { operationName, operation, validationOptions } = this._resolvePathValidationRequest(options);
1471
- const result = this._validateSelectedTree(buildSelectionTree([path]), object, validationOptions, this._buildOperationSettings(operationName, operation, object));
1472
- return {
1473
- validatedValue: getValueAtPath(result.validatedObject, pathSegments),
1474
- errors: result.errors
1475
- };
1476
- }
1477
- /**
1478
- * Validates a selected set of schema paths against the chosen operation.
1479
- * Defaults to `patch` semantics when no operation is specified.
1480
- * @param {string[]} paths - A list of dotted schema paths.
1481
- * @param {object} object - The input object to validate.
1482
- * @param {{operation?: string, mode?: string}} [options={}] - Path validation options.
1483
- * @returns {{validatedObject: object, errors: Object.<string, ValidationError>}}
1484
- */
1485
- validatePaths(paths, object, options = {}) {
1486
- this._assertPlainObjectInput("validatePaths", object);
1487
- if (!Array.isArray(paths) || paths.length === 0) throw new Error("validatePaths() expects a non-empty array of schema paths.");
1488
- const { operationName, operation, validationOptions } = this._resolvePathValidationRequest(options);
1489
- return this._validateSelectedTree(buildSelectionTree(paths), object, validationOptions, this._buildOperationSettings(operationName, operation, object));
1490
- }
1491
- /**
1492
- * Installs operation aliases such as `create`, `replace`, `patch`, or user-defined operations.
1493
- * @private
1494
- */
1495
- _installOperationMethods() {
1496
- for (const operationName of Object.keys(this.operations)) {
1497
- if (operationName in this) throw new Error(`Operation name "${operationName}" is reserved and cannot be used as a schema method.`);
1498
- this[operationName] = (object, options = {}) => this.validateWith(operationName, object, options);
1499
- }
1500
- }
1501
- /**
1502
- * Exports the schema as a transport-facing JSON Schema object.
1503
- * @param {{operation?: string, mode?: 'create'|'replace'|'patch', additionalProperties?: boolean}} [options={}] - Export options.
1504
- * @returns {object} A draft-07 JSON Schema object.
1505
- */
1506
- toJsonSchema(options = {}) {
1507
- return buildJsonSchema(this, options);
1508
- }
1509
- /**
1510
- * Returns a frozen snapshot map of the schema's top-level field definitions.
1511
- * @returns {object}
1512
- */
1513
- getFieldDefinitions() {
1514
- return createIntrospectionSnapshot(this.structure);
1515
- }
1516
- /**
1517
- * Resolves a field definition by dotted path. Array items use numeric segments such as `roles.0.id`.
1518
- * Returns a frozen snapshot, or `null` when the path does not resolve to a field definition.
1519
- * @param {string} path
1520
- * @returns {object|null}
1521
- */
1522
- getFieldDefinition(path) {
1523
- if (typeof path !== "string" || path.trim() === "") throw new Error("Field path must be a non-empty string.");
1524
- const definition = resolveDefinitionFromSchemaPath(this, buildPathSegments(path.trim()));
1525
- return definition === null ? null : createIntrospectionSnapshot(definition);
1526
- }
1527
- /**
1528
- * Resolves the `messages` object for a field definition by dotted path.
1529
- * Returns a frozen snapshot, or an empty frozen object when no messages exist.
1530
- * @param {string} path
1531
- * @returns {object}
1532
- */
1533
- getFieldMessages(path) {
1534
- const definition = this.getFieldDefinition(path);
1535
- if (!definition || typeof definition.messages !== "object" || definition.messages === null) return Object.freeze({});
1536
- return createIntrospectionSnapshot(definition.messages);
1537
- }
1538
- /**
1539
- * Utility to filter an object, keeping only fields that have a specific parameter.
1540
- * @param {object} object - The object to clean.
1541
- * @param {string} parameterName - The schema parameter to look for.
1542
- * @returns {object} A new object with only the matching fields.
1543
- */
1544
- cleanup(object, parameterName) {
1545
- const newObject = {};
1546
- for (const k of Object.keys(object)) if (Object.hasOwn(this.structure, k) && this.structure[k][parameterName]) setOwnProperty(newObject, k, object[k]);
1547
- return newObject;
1548
- }
1549
- };
1550
- //#endregion
1551
- //#region ../../../../node_modules/flatted/esm/index.js
1552
- var { parse: $parse, stringify: $stringify } = JSON;
1553
- var { keys } = Object;
1554
- var Primitive = String;
1555
- var primitive = "string";
1556
- var object = "object";
1557
- var noop = (_, value) => value;
1558
- var set = (known, input, value) => {
1559
- const index = Primitive(input.push(value) - 1);
1560
- known.set(value, index);
1561
- return index;
1562
- };
1563
- /**
1564
- * Converts a JS value into a specialized flatted string.
1565
- * @param {any} value
1566
- * @param {((this: any, key: string, value: any) => any) | (string | number)[] | null | undefined} [replacer]
1567
- * @param {string | number | undefined} [space]
1568
- * @returns {string}
1569
- */
1570
- var stringify = (value, replacer, space) => {
1571
- const $ = replacer && typeof replacer === object ? (k, v) => k === "" || -1 < replacer.indexOf(k) ? v : void 0 : replacer || noop;
1572
- const known = /* @__PURE__ */ new Map();
1573
- const input = [];
1574
- const output = [];
1575
- let i = +set(known, input, $.call({ "": value }, "", value));
1576
- let firstRun = !i;
1577
- while (i < input.length) {
1578
- firstRun = true;
1579
- output[i] = $stringify(input[i++], replace, space);
1580
- }
1581
- return "[" + output.join(",") + "]";
1582
- function replace(key, value) {
1583
- if (firstRun) {
1584
- firstRun = !firstRun;
1585
- return value;
1586
- }
1587
- const after = $.call(this, key, value);
1588
- switch (typeof after) {
1589
- case object: if (after === null) return after;
1590
- case primitive: return known.get(after) || set(known, input, after);
1591
- }
1592
- return after;
1593
- }
1594
- };
1595
- //#endregion
1596
- //#region ../../../../node_modules/json-rest-schema/src/core/CorePlugin.js
1597
- /**
1598
- * @file Contains all the built-in type and validator handlers for the schema library.
1599
- */
1600
- /**
1601
- * @typedef {import('./Schema.js').ValidationContext} ValidationContext
1602
- */
1603
- var DEFAULT_BOOLEAN_TRUE_VALUES = /* @__PURE__ */ new Set([
1604
- "true",
1605
- "1",
1606
- "yes",
1607
- "y",
1608
- "on"
1609
- ]);
1610
- var DEFAULT_BOOLEAN_FALSE_VALUES = /* @__PURE__ */ new Set([
1611
- "false",
1612
- "0",
1613
- "no",
1614
- "n",
1615
- "off"
1616
- ]);
1617
- function isThenable(value) {
1618
- return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
1619
- }
1620
- function normalizeFiniteNumberInput(value) {
1621
- if (typeof value === "number") return Number.isFinite(value) ? value : null;
1622
- if (typeof value === "bigint") {
1623
- const numberValue = Number(value);
1624
- return Number.isSafeInteger(numberValue) ? numberValue : null;
1625
- }
1626
- if (typeof value === "string") {
1627
- const trimmed = value.trim();
1628
- if (trimmed === "") return null;
1629
- const numberValue = Number(trimmed);
1630
- return Number.isFinite(numberValue) ? numberValue : null;
1631
- }
1632
- return null;
1633
- }
1634
- function deepEqual(left, right) {
1635
- if (Object.is(left, right)) return true;
1636
- if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();
1637
- if (left instanceof RegExp && right instanceof RegExp) return left.source === right.source && left.flags === right.flags;
1638
- if (Array.isArray(left) || Array.isArray(right)) {
1639
- if (!Array.isArray(left) || !Array.isArray(right)) return false;
1640
- if (left.length !== right.length) return false;
1641
- for (let index = 0; index < left.length; index++) if (!deepEqual(left[index], right[index])) return false;
1642
- return true;
1643
- }
1644
- if (left === null || right === null || typeof left !== "object" || typeof right !== "object") return false;
1645
- if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;
1646
- const leftKeys = Object.keys(left);
1647
- const rightKeys = Object.keys(right);
1648
- if (leftKeys.length !== rightKeys.length) return false;
1649
- for (const key of leftKeys) {
1650
- if (!Object.hasOwn(right, key)) return false;
1651
- if (!deepEqual(left[key], right[key])) return false;
1652
- }
1653
- return true;
1654
- }
1655
- /**
1656
- * The CorePlugin provides the default set of types and validators.
1657
- */
1658
- var CorePlugin = {
1659
- /**
1660
- * Installs the core types and validators.
1661
- * @param {{addType: Function, addValidator: Function}} api - An object containing registration functions.
1662
- */
1663
- install(api) {
1664
- const { addType, addValidator } = api;
1665
- addType("none", (context) => context.value);
1666
- addType("file", (context) => {
1667
- const val = context.value;
1668
- if (val === void 0 || val === null) context.throwTypeError();
1669
- const valType = typeof val;
1670
- if (valType === "string" || valType === "number" || valType === "boolean") {
1671
- const s = val.toString();
1672
- return context.definition.noTrim ? s : s.trim();
1673
- }
1674
- context.throwTypeError();
1675
- });
1676
- addType("string", (context) => {
1677
- const val = context.value;
1678
- if (val === void 0 || val === null) return "";
1679
- const valType = typeof val;
1680
- if (valType === "string" || valType === "number" || valType === "boolean") {
1681
- const s = val.toString();
1682
- return context.definition.noTrim ? s : s.trim();
1683
- }
1684
- context.throwTypeError();
1685
- });
1686
- addType("blob", (context) => context.value);
1687
- addType("number", (context) => {
1688
- const numberValue = normalizeFiniteNumberInput(context.value);
1689
- if (numberValue === null) context.throwTypeError();
1690
- return numberValue;
1691
- });
1692
- addType("integer", (context) => {
1693
- const numberValue = normalizeFiniteNumberInput(context.value);
1694
- if (numberValue === null || !Number.isInteger(numberValue)) context.throwTypeError();
1695
- return numberValue;
1696
- });
1697
- addType("epochMilliseconds", (context) => {
1698
- const epochMilliseconds = castEpochInteger(context.value, EPOCH_MILLISECONDS_LIMIT);
1699
- if (epochMilliseconds === null) context.throwTypeError();
1700
- return epochMilliseconds;
1701
- });
1702
- addType("epochSeconds", (context) => {
1703
- const epochSeconds = castEpochInteger(context.value, EPOCH_SECONDS_LIMIT);
1704
- if (epochSeconds === null) context.throwTypeError();
1705
- return epochSeconds;
1706
- });
1707
- addType("dateTime", (context) => {
1708
- const temporalPrecision = resolveTemporalPrecision(context.definition, context.fieldName);
1709
- if (!isValidDateTime(context.value, temporalPrecision)) context.throwTypeError();
1710
- return context.value;
1711
- });
1712
- addType("date", (context) => {
1713
- if (!isValidDate(context.value)) context.throwTypeError();
1714
- return context.value;
1715
- });
1716
- addType("time", (context) => {
1717
- const temporalPrecision = resolveTemporalPrecision(context.definition, context.fieldName);
1718
- if (!isValidTime(context.value, temporalPrecision)) context.throwTypeError();
1719
- return context.value;
1720
- });
1721
- addType("array", (context) => {
1722
- if (context.definition.type === "array" && !Array.isArray(context.value)) return [context.value];
1723
- return context.value;
1724
- });
1725
- addType("object", (context) => {
1726
- if (!isPlainObject(context.value)) context.throwTypeError();
1727
- return context.value;
1728
- });
1729
- addType("serialize", (context) => {
1730
- try {
1731
- return JSON.stringify(context.value);
1732
- } catch (e) {
1733
- try {
1734
- return stringify(context.value);
1735
- } catch (e2) {
1736
- context.throwTypeError();
1737
- }
1738
- }
1739
- });
1740
- addType("boolean", (context) => {
1741
- if (typeof context.value === "boolean") return context.value;
1742
- if (typeof context.value === "number") {
1743
- if (context.value === 1) return true;
1744
- if (context.value === 0) return false;
1745
- context.throwTypeError();
1746
- }
1747
- if (typeof context.value === "bigint") {
1748
- if (context.value === 1n) return true;
1749
- if (context.value === 0n) return false;
1750
- context.throwTypeError();
1751
- }
1752
- if (typeof context.value === "string") {
1753
- const falseVal = String(context.definition.stringFalseWhen || "false").trim().toLowerCase();
1754
- const trueVal = String(context.definition.stringTrueWhen || "true").trim().toLowerCase();
1755
- const lowerValue = context.value.trim().toLowerCase();
1756
- const falseValues = /* @__PURE__ */ new Set([...DEFAULT_BOOLEAN_FALSE_VALUES, falseVal]);
1757
- const trueValues = /* @__PURE__ */ new Set([...DEFAULT_BOOLEAN_TRUE_VALUES, trueVal]);
1758
- if (falseValues.has(lowerValue)) return false;
1759
- if (trueValues.has(lowerValue)) return true;
1760
- }
1761
- context.throwTypeError();
1762
- });
1763
- addType("id", (context) => {
1764
- if (typeof context.value === "number") {
1765
- if (Number.isSafeInteger(context.value) && context.value > 0) return context.value;
1766
- context.throwTypeError();
1767
- }
1768
- if (typeof context.value === "bigint") {
1769
- if (context.value > 0n && context.value <= BigInt(Number.MAX_SAFE_INTEGER)) return Number(context.value);
1770
- context.throwTypeError();
1771
- }
1772
- if (typeof context.value === "string") {
1773
- const trimmed = context.value.trim();
1774
- if (!/^[1-9][0-9]*$/.test(trimmed)) context.throwTypeError();
1775
- const numberValue = Number(trimmed);
1776
- if (!Number.isSafeInteger(numberValue)) context.throwTypeError();
1777
- return numberValue;
1778
- }
1779
- context.throwTypeError();
1780
- });
1781
- addValidator("minLength", (context) => {
1782
- if (context.value === void 0) return;
1783
- if (context.definition.type === "string" && context.value.toString && context.value.toString().length < context.parameterValue) context.throwParamError("MIN_LENGTH", `Length must be at least ${context.parameterValue} characters.`, {
1784
- min: context.parameterValue,
1785
- actual: context.value.toString().length
1786
- });
1787
- });
1788
- addValidator("min", (context) => {
1789
- if (context.value === void 0) return;
1790
- if (isNumericDefinition(context.definition) && typeof context.value === "number" && context.value < context.parameterValue) context.throwParamError("MIN_VALUE", `Value must be at least ${context.parameterValue}.`, {
1791
- min: context.parameterValue,
1792
- actual: context.value
1793
- });
1794
- });
1795
- addValidator("maxLength", (context) => {
1796
- if (context.value === void 0) return;
1797
- if (context.definition.type === "string" && context.value.toString && context.value.toString().length > context.parameterValue) context.throwParamError("MAX_LENGTH", `Length must be no more than ${context.parameterValue} characters.`, {
1798
- max: context.parameterValue,
1799
- actual: context.value.toString().length
1800
- });
1801
- });
1802
- addValidator("max", (context) => {
1803
- if (context.value === void 0) return;
1804
- if (isNumericDefinition(context.definition) && typeof context.value === "number" && context.value > context.parameterValue) context.throwParamError("MAX_VALUE", `Value must be no more than ${context.parameterValue}.`, {
1805
- max: context.parameterValue,
1806
- actual: context.value
1807
- });
1808
- });
1809
- addValidator("enum", (context) => {
1810
- if (!Array.isArray(context.parameterValue)) throw new Error(`Enum for ${context.fieldName} must be an array.`);
1811
- if (!context.parameterValue.some((allowedValue) => deepEqual(allowedValue, context.value))) context.throwParamError("ENUM_VALUE", "Value must match one of the allowed enum values.", { allowed: context.parameterValue });
1812
- });
1813
- addValidator("pattern", (context) => {
1814
- if (context.value === void 0) return;
1815
- if (context.definition.type !== "string" || typeof context.value !== "string") return;
1816
- const patternValue = context.parameterValue;
1817
- const matcher = patternValue instanceof RegExp ? new RegExp(patternValue.source, patternValue.flags) : typeof patternValue === "string" ? new RegExp(patternValue) : null;
1818
- if (!matcher) throw new Error(`Pattern for ${context.fieldName} must be a string or RegExp.`);
1819
- if (!matcher.test(context.value)) context.throwParamError("PATTERN", "Value does not match the required pattern.", { pattern: matcher.source });
1820
- });
1821
- addValidator("strictBoolean", (context) => {
1822
- if (!context.parameterValue) return;
1823
- if (context.definition.type !== "boolean") throw new Error(`strictBoolean can only be used on boolean fields (${context.fieldName}).`);
1824
- if (typeof context.valueBeforeCast !== "boolean") context.throwParamError("STRICT_BOOLEAN", "Value must be a boolean.");
1825
- });
1826
- addValidator("validator", (context) => {
1827
- if (typeof context.parameterValue !== "function") throw new Error(`Validator for ${context.fieldName} must be a function.`);
1828
- const r = context.parameterValue(context.value, context.object, context);
1829
- if (isThenable(r)) throw new Error(`Custom validator for "${context.fieldName}" must be synchronous.`);
1830
- if (typeof r === "string") context.throwParamError("CUSTOM_VALIDATOR_FAILED", r);
1831
- });
1832
- addValidator("uppercase", (context) => {
1833
- if (typeof context.value === "string") return context.value.toUpperCase();
1834
- });
1835
- addValidator("lowercase", (context) => {
1836
- if (typeof context.value === "string") return context.value.toLowerCase();
1837
- });
1838
- addValidator("length", (context) => {
1839
- if (typeof context.value === "string") return context.value.substr(0, context.parameterValue);
1840
- else if (Number.isInteger(Number(context.valueBeforeCast)) && String(context.valueBeforeCast).length > context.parameterValue) context.throwParamError("RANGE_EXCEEDED", "Numeric value is out of the allowed character range.", {
1841
- max: context.parameterValue,
1842
- actual: String(context.valueBeforeCast).length
1843
- });
1844
- });
1845
- addValidator("notEmpty", (context) => {
1846
- if (context.parameterValue && typeof context.value === "string" && context.value === "") context.throwParamError("NOT_EMPTY", "Field cannot be empty.");
1847
- });
1848
- addValidator("required", () => {});
1849
- addValidator("unsigned", () => {});
1850
- addValidator("precision", () => {});
1851
- addValidator("scale", () => {});
1852
- addValidator("temporalPrecision", (context) => {
1853
- if (context.definition.type !== "time" && context.definition.type !== "dateTime") throw new Error(`temporalPrecision can only be used on time or dateTime fields (${context.fieldName}).`);
1854
- });
1855
- addValidator("nullable", () => {});
1856
- addValidator("nullOnEmpty", () => {});
1857
- addValidator("defaultTo", () => {});
1858
- } };
1859
- //#endregion
1860
- //#region ../../../../node_modules/json-rest-schema/src/utils/error-helpers.js
1861
- /**
1862
- * @file Small helper utilities for working with the flat dotted-path error map.
1863
- */
1864
- function isValidationErrorObject(value) {
1865
- return isObjectLike(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string" && Object.hasOwn(value, "params");
1866
- }
1867
- function flattenNestedErrorsInto(nestedValue, currentPath, flatErrors) {
1868
- if (!isObjectLike(nestedValue)) throw new Error(`flattenErrors() found an invalid nested error value at "${currentPath}".`);
1869
- if (isValidationErrorObject(nestedValue)) {
1870
- if (currentPath === "") throw new Error("flattenErrors() cannot flatten a root-level error object without a path.");
1871
- buildPathSegments$1(currentPath, "flattenErrors");
1872
- setOwnProperty(flatErrors, currentPath, nestedValue);
1873
- return;
1874
- }
1875
- const entries = Array.isArray(nestedValue) ? Object.entries(nestedValue) : Object.entries(nestedValue).sort(([left], [right]) => left.localeCompare(right));
1876
- for (const [segment, childValue] of entries) flattenNestedErrorsInto(childValue, joinPath$1(currentPath, segment), flatErrors);
1877
- }
1878
- /**
1879
- * Reads one error object from a flat dotted-path error map.
1880
- * @param {Object.<string, object>} errors
1881
- * @param {string} path
1882
- * @returns {object|undefined}
1883
- */
1884
- function getError(errors, path) {
1885
- buildPathSegments$1(path, "getError");
1886
- if (!isObjectLike(errors)) return void 0;
1887
- return Object.hasOwn(errors, path) ? errors[path] : void 0;
1888
- }
1889
- /**
1890
- * Checks whether a flat dotted-path error map contains a specific path.
1891
- * @param {Object.<string, object>} errors
1892
- * @param {string} path
1893
- * @returns {boolean}
1894
- */
1895
- function hasError(errors, path) {
1896
- return getError(errors, path) !== void 0;
1897
- }
1898
- /**
1899
- * Converts a flat dotted-path error map into a nested object/array structure.
1900
- * @param {Object.<string, object>} errors
1901
- * @returns {object}
1902
- */
1903
- function nestErrors(errors) {
1904
- if (!isObjectLike(errors)) return {};
1905
- const nestedErrors = {};
1906
- for (const [path, error] of Object.entries(errors)) {
1907
- const segments = buildPathSegments$1(path, "nestErrors");
1908
- let currentNode = nestedErrors;
1909
- for (let index = 0; index < segments.length; index++) {
1910
- const segment = segments[index];
1911
- if (index === segments.length - 1) {
1912
- setOwnProperty(currentNode, segment, error);
1913
- continue;
1914
- }
1915
- const hasExistingNode = Object.hasOwn(currentNode, segment);
1916
- const existingNode = hasExistingNode ? currentNode[segment] : void 0;
1917
- if (hasExistingNode && (!isObjectLike(existingNode) || isValidationErrorObject(existingNode))) throw new Error(`nestErrors() cannot nest conflicting path "${path}".`);
1918
- if (!hasExistingNode) {
1919
- const nextSegment = segments[index + 1];
1920
- setOwnProperty(currentNode, segment, isNumericSegment(nextSegment) ? [] : {});
1921
- }
1922
- currentNode = currentNode[segment];
1923
- }
1924
- }
1925
- return nestedErrors;
1926
- }
1927
- /**
1928
- * Converts a nested object/array error structure into the flat dotted-path map.
1929
- * @param {object} nestedErrors
1930
- * @returns {Object.<string, object>}
1931
- */
1932
- function flattenErrors(nestedErrors) {
1933
- if (!isObjectLike(nestedErrors)) return {};
1934
- const flatErrors = {};
1935
- flattenNestedErrorsInto(nestedErrors, "", flatErrors);
1936
- return flatErrors;
1937
- }
1938
- //#endregion
1939
- //#region ../../../../node_modules/json-rest-schema/src/index.js
1940
- /**
1941
- * @file Main entry point for the schema library.
1942
- * Assembles and exports the `createSchema` factory function and related utilities.
1943
- */
1944
- var factoryTypesBySource = /* @__PURE__ */ new WeakMap();
1945
- var factoryValidatorsBySource = /* @__PURE__ */ new WeakMap();
1946
- var registryMetadataSymbol = Symbol.for("json-rest-schema.registry-metadata");
1947
- function registerTypeHandler(types, name, handler) {
1948
- if (typeof handler !== "function") throw new Error(`Type handler for '${name}' must be a function.`);
1949
- setOwnProperty(types, name, handler);
1950
- }
1951
- function registerValidatorHandler(validators, name, handler) {
1952
- if (typeof handler !== "function") throw new Error(`Validator handler for '${name}' must be a function.`);
1953
- setOwnProperty(validators, name, handler);
1954
- }
1955
- function createHandlerRegistry(source = {}) {
1956
- const registry = Object.create(null);
1957
- for (const [name, handler] of Object.entries(source)) setOwnProperty(registry, name, handler);
1958
- return registry;
1959
- }
1960
- function installPlugin(plugin, api) {
1961
- if (typeof plugin.install !== "function") throw new Error("Plugin must have an install method.");
1962
- plugin.install(api);
1963
- }
1964
- function attachRegistryMetadata(target, types, validators) {
1965
- factoryTypesBySource.set(target, types);
1966
- factoryValidatorsBySource.set(target, validators);
1967
- Object.defineProperty(target, registryMetadataSymbol, {
1968
- value: Object.freeze({
1969
- getTypes: () => types,
1970
- getValidators: () => validators
1971
- }),
1972
- enumerable: false,
1973
- configurable: false,
1974
- writable: false
1975
- });
1976
- }
1977
- function extractRegistryMetadata(source) {
1978
- if (!source || typeof source !== "object" && typeof source !== "function") return null;
1979
- const types = factoryTypesBySource.get(source);
1980
- const validators = factoryValidatorsBySource.get(source);
1981
- if (types && validators) return {
1982
- types,
1983
- validators
1984
- };
1985
- const symbolMetadata = source[registryMetadataSymbol];
1986
- if (symbolMetadata && typeof symbolMetadata.getTypes === "function" && typeof symbolMetadata.getValidators === "function") return {
1987
- types: symbolMetadata.getTypes(),
1988
- validators: symbolMetadata.getValidators()
1989
- };
1990
- if (typeof source === "object" && source.types && typeof source.types === "object" && source.validators && typeof source.validators === "object" && typeof source.create === "function" && typeof source.replace === "function" && typeof source.patch === "function" && typeof source.toJsonSchema === "function") return {
1991
- types: source.types,
1992
- validators: source.validators
1993
- };
1994
- return null;
1995
- }
1996
- function normalizeFactorySources(sources) {
1997
- if (sources.length === 1 && Array.isArray(sources[0])) return sources[0];
1998
- return sources;
1999
- }
2000
- function areEquivalentHandlers(left, right) {
2001
- return left === right;
2002
- }
2003
- function mergeRegistryHandlers(target, source, kind) {
2004
- for (const [name, handler] of Object.entries(source)) {
2005
- if (Object.hasOwn(target, name) && !areEquivalentHandlers(target[name], handler)) throw new Error(`Cannot merge schema factories with conflicting ${kind} "${name}".`);
2006
- setOwnProperty(target, name, handler);
2007
- }
2008
- }
2009
- function resolveMergedRegistries(fallbackTypes, fallbackValidators, sources) {
2010
- const normalizedSources = normalizeFactorySources(sources).filter(Boolean);
2011
- if (normalizedSources.length < 1) return {
2012
- types: createHandlerRegistry(fallbackTypes),
2013
- validators: createHandlerRegistry(fallbackValidators)
2014
- };
2015
- const mergedTypes = Object.create(null);
2016
- const mergedValidators = Object.create(null);
2017
- for (const source of normalizedSources) {
2018
- const metadata = extractRegistryMetadata(source);
2019
- if (!metadata) throw new Error("Factory sources must be schema instances or schema factories created by json-rest-schema.");
2020
- mergeRegistryHandlers(mergedTypes, metadata.types, "type");
2021
- mergeRegistryHandlers(mergedValidators, metadata.validators, "validator");
2022
- }
2023
- return {
2024
- types: mergedTypes,
2025
- validators: mergedValidators
2026
- };
2027
- }
2028
- function createSchemaFactory({ types = {}, validators = {}, installCore = true } = {}) {
2029
- const factoryTypes = createHandlerRegistry(types);
2030
- const factoryValidators = createHandlerRegistry(validators);
2031
- const factory = (structure, options = {}) => {
2032
- const schema = new Schema(structure, factoryTypes, factoryValidators, options.operations);
2033
- attachRegistryMetadata(schema, factoryTypes, factoryValidators);
2034
- return schema;
2035
- };
2036
- attachRegistryMetadata(factory, factoryTypes, factoryValidators);
2037
- factory.addType = (name, handler) => {
2038
- registerTypeHandler(factoryTypes, name, handler);
2039
- };
2040
- factory.addValidator = (name, handler) => {
2041
- registerValidatorHandler(factoryValidators, name, handler);
2042
- };
2043
- factory.use = (plugin) => {
2044
- installPlugin(plugin, {
2045
- addType: factory.addType,
2046
- addValidator: factory.addValidator
2047
- });
2048
- };
2049
- factory.createFactory = (...sources) => {
2050
- const mergedRegistries = resolveMergedRegistries(factoryTypes, factoryValidators, sources);
2051
- return createSchemaFactory({
2052
- types: mergedRegistries.types,
2053
- validators: mergedRegistries.validators,
2054
- installCore: false
2055
- });
2056
- };
2057
- if (installCore) factory.use(CorePlugin);
2058
- return factory;
2059
- }
2060
- var createSchema = createSchemaFactory({ installCore: true });
2061
- function addType(name, handler) {
2062
- createSchema.addType(name, handler);
2063
- }
2064
- function addValidator(name, handler) {
2065
- createSchema.addValidator(name, handler);
2066
- }
2067
- function use(plugin) {
2068
- createSchema.use(plugin);
2069
- }
2070
- //#endregion
2071
- export { addType, addValidator, createSchema, createSchemaFactory, flattenErrors, getError, hasError, nestErrors, use };