exact-mirror 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,467 +1,362 @@
1
- // src/index.ts
2
- var Kind = "~kind";
3
- var Hint = "~hint";
4
- var isSpecialProperty = (name) => /(\ |-|\t|\n|\.|\[|\]|\{|\})/.test(name) || !isNaN(+name[0]);
5
- var joinProperty = (v1, v2, isOptional = false) => {
6
- if (typeof v2 === "number") return `${v1}[${v2}]`;
7
- if (isSpecialProperty(v2)) return `${v1}${isOptional ? "?." : ""}["${v2}"]`;
8
- return `${v1}${isOptional ? "?" : ""}.${v2}`;
1
+ //#region src/index.ts
2
+ const Kind = "~kind";
3
+ const Hint = "~hint";
4
+ const Codec = "~codec";
5
+ const isSpecialProperty = (name) => !/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
6
+ const joinProperty = (v1, v2, isOptional = false) => {
7
+ if (typeof v2 === "number") return `${v1}[${v2}]`;
8
+ if (isSpecialProperty(v2)) return `${v1}${isOptional ? "?." : ""}[${JSON.stringify(v2)}]`;
9
+ return `${v1}${isOptional ? "?" : ""}.${v2}`;
9
10
  };
10
- var encodeProperty = (v) => isSpecialProperty(v) ? `"${v}"` : v;
11
- var sanitize = (key, sanitize2 = 0, schema) => {
12
- if (schema.type !== "string" || schema.const || schema.trusted) return key;
13
- let hof = "";
14
- for (let i = sanitize2 - 1; i >= 0; i--) hof += `d.h${i}(`;
15
- return hof + key + ")".repeat(sanitize2);
11
+ const encodeProperty = (v) => isSpecialProperty(v) ? JSON.stringify(v) : v;
12
+ const sanitize = (key, sanitize = 0, schema) => {
13
+ if (schema.type !== "string" || schema.const || schema.trusted) return key;
14
+ let hof = "";
15
+ for (let i = sanitize - 1; i >= 0; i--) hof += `d.h${i}(`;
16
+ return hof + key + ")".repeat(sanitize);
16
17
  };
17
- var mergeObjectIntersection = (schema) => {
18
- if (!schema.allOf || Kind in schema && (schema[Kind] !== "Intersect" || schema.type !== "object"))
19
- return schema;
20
- const { allOf, ...newSchema } = schema;
21
- newSchema.properties = {};
22
- if (Kind in newSchema) newSchema[Kind] = "Object";
23
- for (const type of allOf) {
24
- if (type.type !== "object") continue;
25
- const { properties, required, type: _, [Kind]: __, ...rest } = type;
26
- if (required)
27
- newSchema.required = newSchema.required ? newSchema.required.concat(required) : required;
28
- Object.assign(newSchema, rest);
29
- for (const property in type.properties)
30
- newSchema.properties[property] = mergeObjectIntersection(
31
- type.properties[property]
32
- );
33
- }
34
- return newSchema;
18
+ const mergeObjectIntersection = (schema) => {
19
+ if (!schema.allOf || Kind in schema && (schema[Kind] !== "Intersect" || schema.type !== "object")) return schema;
20
+ const { allOf, ...newSchema } = schema;
21
+ newSchema.properties = {};
22
+ if (Kind in newSchema) newSchema[Kind] = "Object";
23
+ for (const type of allOf) {
24
+ if (type.type !== "object") continue;
25
+ const { properties, required, type: _, [Kind]: __, ...rest } = type;
26
+ if (required) newSchema.required = newSchema.required ? newSchema.required.concat(required) : required;
27
+ Object.assign(newSchema, rest);
28
+ for (const property in type.properties) newSchema.properties[property] = mergeObjectIntersection(type.properties[property]);
29
+ }
30
+ return newSchema;
35
31
  };
36
- var handleRecord = (schema, property, instruction) => {
37
- const child = schema.patternProperties["^(.*)$"] ?? schema.patternProperties[Object.keys(schema.patternProperties)[0]];
38
- if (!child) return property;
39
- const i = instruction.array;
40
- instruction.array++;
41
- let v = `(()=>{const ar${i}s=Object.keys(${property}),ar${i}v={};for(let i=0;i<ar${i}s.length;i++){const ar${i}p=${property}[ar${i}s[i]];ar${i}v[ar${i}s[i]]=${mirror(child, `ar${i}p`, instruction)}`;
42
- const optionals = instruction.optionalsInArray[i + 1];
43
- if (optionals) {
44
- for (let oi = 0; oi < optionals.length; oi++) {
45
- const target = `ar${i}v[ar${i}s[i]]${optionals[oi]}`;
46
- v += `;if(${target}===undefined)delete ${target}`;
47
- }
48
- instruction.optionalsInArray[i + 1] = [];
49
- }
50
- v += `}return ar${i}v})()`;
51
- return v;
32
+ const handleRecord = (schema, property, instruction) => {
33
+ const child = schema.patternProperties["^(.*)$"] ?? schema.patternProperties[Object.keys(schema.patternProperties)[0]];
34
+ if (!child) return property;
35
+ const i = instruction.array;
36
+ instruction.array++;
37
+ let v = `(()=>{const ar${i}s=Object.keys(${property}),ar${i}v={};for(let i=0;i<ar${i}s.length;i++){const ar${i}p=${property}[ar${i}s[i]];ar${i}v[ar${i}s[i]]=${mirror(child, `ar${i}p`, instruction)}`;
38
+ const optionals = instruction.optionalsInArray[i + 1];
39
+ if (optionals) {
40
+ for (let oi = 0; oi < optionals.length; oi++) {
41
+ const target = `ar${i}v[ar${i}s[i]]${optionals[oi]}`;
42
+ v += `;if(${target}===undefined)delete ${target}`;
43
+ }
44
+ instruction.optionalsInArray[i + 1] = [];
45
+ }
46
+ v += `}return ar${i}v})()`;
47
+ return v;
52
48
  };
53
- var handleTuple = (schema, property, instruction) => {
54
- const i = instruction.array;
55
- instruction.array++;
56
- const isRoot = property === "v" && !instruction.fromUnion;
57
- let v = "";
58
- if (!isRoot) v = `(()=>{`;
59
- v += `const ar${i}v=[`;
60
- for (let i2 = 0; i2 < schema.length; i2++) {
61
- if (i2 !== 0) v += ",";
62
- v += mirror(
63
- schema[i2],
64
- joinProperty(
65
- property,
66
- i2,
67
- instruction.parentIsOptional || instruction.fromUnion
68
- ),
69
- instruction
70
- );
71
- }
72
- v += `];`;
73
- if (!isRoot) v += `return ar${i}v})()`;
74
- return v;
49
+ const handleTuple = (schema, property, instruction) => {
50
+ const i = instruction.array;
51
+ instruction.array++;
52
+ const isRoot = property === "v" && !instruction.fromUnion;
53
+ let v = "";
54
+ if (!isRoot) v = `(()=>{`;
55
+ v += `const ar${i}v=[`;
56
+ for (let i = 0; i < schema.length; i++) {
57
+ if (i !== 0) v += ",";
58
+ v += mirror(schema[i], joinProperty(property, i, instruction.parentIsOptional || instruction.fromUnion), instruction);
59
+ }
60
+ v += `];`;
61
+ if (!isRoot) v += `return ar${i}v})()`;
62
+ return v;
75
63
  };
76
64
  function deepClone(source, weak = /* @__PURE__ */ new WeakMap()) {
77
- if (source === null || typeof source !== "object" || typeof source === "function")
78
- return source;
79
- if (weak.has(source)) return weak.get(source);
80
- if (Array.isArray(source)) {
81
- const copy = new Array(source.length);
82
- weak.set(source, copy);
83
- for (let i = 0; i < source.length; i++)
84
- copy[i] = deepClone(source[i], weak);
85
- return copy;
86
- }
87
- if (typeof source === "object") {
88
- const keys = Object.keys(source).concat(
89
- Object.getOwnPropertySymbols(source)
90
- );
91
- const cloned = {};
92
- for (const key of keys)
93
- cloned[key] = deepClone(source[key], weak);
94
- return cloned;
95
- }
96
- return source;
65
+ if (source === null || typeof source !== "object" || typeof source === "function") return source;
66
+ if (weak.has(source)) return weak.get(source);
67
+ if (Array.isArray(source)) {
68
+ const copy = new Array(source.length);
69
+ weak.set(source, copy);
70
+ for (let i = 0; i < source.length; i++) copy[i] = deepClone(source[i], weak);
71
+ return copy;
72
+ }
73
+ const keys = Object.keys(source).concat(Object.getOwnPropertySymbols(source));
74
+ const cloned = Object.create(null);
75
+ weak.set(source, cloned);
76
+ for (const key of keys) cloned[key] = deepClone(source[key], weak);
77
+ return cloned;
97
78
  }
98
- var handleCyclic = (schema, property, instruction) => {
99
- const defs = schema.$defs;
100
- let group = instruction.cyclic.groups.get(defs);
101
- if (!group) {
102
- group = { defs, names: {} };
103
- instruction.cyclic.groups.set(defs, group);
104
- for (const name in defs)
105
- group.names[name] = `cy${instruction.cyclic.count++}`;
106
- for (const name in defs)
107
- instruction.cyclic.fns.push(
108
- `function ${group.names[name]}(v){${mirror(defs[name], "v", {
109
- ...instruction,
110
- cyclicDefs: group,
111
- fromUnion: false,
112
- parentIsOptional: false,
113
- optionals: [],
114
- optionalsInArray: [],
115
- unionKeys: {},
116
- array: 0,
117
- recursion: 0
118
- })}}`
119
- );
120
- }
121
- const fn = group.names[schema.$ref];
122
- if (!fn)
123
- throw new Error(
124
- `[exact-mirror] cyclic reference "${schema.$ref}" is not found in $defs`
125
- );
126
- return `(${property}==null?${property}:${fn}(${property}))`;
79
+ const handleCyclic = (schema, property, instruction) => {
80
+ const defs = schema.$defs;
81
+ let group = instruction.cyclic.groups.get(defs);
82
+ if (!group) {
83
+ group = {
84
+ defs,
85
+ names: {}
86
+ };
87
+ instruction.cyclic.groups.set(defs, group);
88
+ for (const name in defs) group.names[name] = `cy${instruction.cyclic.count++}`;
89
+ for (const name in defs) instruction.cyclic.fns.push(`function ${group.names[name]}(v){${mirror(defs[name], "v", {
90
+ ...instruction,
91
+ cyclicDefs: group,
92
+ fromUnion: false,
93
+ parentIsOptional: false,
94
+ optionals: [],
95
+ optionalsInArray: [],
96
+ unionKeys: {},
97
+ array: 0,
98
+ recursion: 0
99
+ })}}`);
100
+ }
101
+ const fn = group.names[schema.$ref];
102
+ if (!fn) throw new Error(`[exact-mirror] cyclic reference "${schema.$ref}" is not found in $defs`);
103
+ return `(${property}==null?${property}:${fn}(${property}))`;
127
104
  };
128
- var withDefs = (type, group) => {
129
- if (Kind in type) {
130
- if (type[Kind] === "Cyclic") return type;
131
- if (type[Kind] === "Ref" && type.$ref in group.defs)
132
- return Object.defineProperty(
133
- { $defs: group.defs, $ref: type.$ref },
134
- Kind,
135
- { value: "Cyclic" }
136
- );
137
- }
138
- let entry = "~check";
139
- while (entry in group.defs) entry += "~";
140
- const def = Object.create(
141
- Object.getPrototypeOf(type),
142
- Object.getOwnPropertyDescriptors(type)
143
- );
144
- def.$id = entry;
145
- return Object.defineProperty(
146
- { $defs: { ...group.defs, [entry]: def }, $ref: entry },
147
- Kind,
148
- { value: "Cyclic" }
149
- );
105
+ const withDefs = (type, group) => {
106
+ if (Kind in type) {
107
+ if (type[Kind] === "Cyclic") return type;
108
+ if (type[Kind] === "Ref" && type.$ref in group.defs) return Object.defineProperty({
109
+ $defs: group.defs,
110
+ $ref: type.$ref
111
+ }, Kind, { value: "Cyclic" });
112
+ }
113
+ let entry = "~check";
114
+ while (entry in group.defs) entry += "~";
115
+ const def = Object.create(Object.getPrototypeOf(type), Object.getOwnPropertyDescriptors(type));
116
+ def.$id = entry;
117
+ return Object.defineProperty({
118
+ $defs: {
119
+ ...group.defs,
120
+ [entry]: def
121
+ },
122
+ $ref: entry
123
+ }, Kind, { value: "Cyclic" });
150
124
  };
151
- var handleUnion = (schemas, property, instruction) => {
152
- if (instruction.Compile === void 0) {
153
- if (!instruction.typeCompilerWanred) {
154
- console.warn(
155
- new Error(
156
- "[exact-mirror] TypeBox's TypeCompiler is required to use Union"
157
- )
158
- );
159
- instruction.typeCompilerWanred = true;
160
- }
161
- return property;
162
- }
163
- instruction.unionKeys[property] = 1;
164
- const ui = instruction.unions.length;
165
- const typeChecks = instruction.unions[ui] = [];
166
- let v = `(()=>{
167
- `;
168
- const unwrapRef = (type) => {
169
- if (!(Kind in type) || !type.$ref) return type;
170
- if (type[Kind] === "This")
171
- return deepClone(instruction.definitions[type.$ref]);
172
- return type;
173
- };
174
- let cleanThenCheck = "";
175
- for (let i = 0; i < schemas.length; i++) {
176
- let type = unwrapRef(schemas[i]);
177
- if (Array.isArray(type.anyOf))
178
- for (let i2 = 0; i2 < type.anyOf.length; i2++)
179
- type.anyOf[i2] = unwrapRef(type.anyOf[i2]);
180
- else if (type.items) {
181
- if (Array.isArray(type.items))
182
- for (let i2 = 0; i2 < type.items.length; i2++)
183
- type.items[i2] = unwrapRef(type.items[i2]);
184
- else type.items = unwrapRef(type.items);
185
- }
186
- typeChecks.push(
187
- instruction.Compile(
188
- instruction.cyclicDefs ? withDefs(type, instruction.cyclicDefs) : type
189
- )
190
- );
191
- v += `if(d.unions[${ui}][${i}].Check(${property})){return ${mirror(
192
- type,
193
- property,
194
- {
195
- ...instruction,
196
- recursion: instruction.recursion + 1,
197
- parentIsOptional: true,
198
- fromUnion: true
199
- }
200
- )}}
201
- `;
202
- cleanThenCheck += (i ? "" : "let ") + "tmp=" + mirror(type, property, {
203
- ...instruction,
204
- recursion: instruction.recursion + 1,
205
- parentIsOptional: true,
206
- fromUnion: true
207
- }) + `
208
- if(d.unions[${ui}][${i}].Check(tmp))return tmp
209
- `;
210
- }
211
- if (cleanThenCheck) v += cleanThenCheck;
212
- v += `return ${instruction.removeUnknownUnionType ? "undefined" : property}`;
213
- return v + `})()`;
125
+ const handleUnion = (schemas, property, instruction) => {
126
+ if (instruction.Compile === void 0) {
127
+ if (!instruction.typeCompilerWanred) {
128
+ console.warn(/* @__PURE__ */ new Error("[exact-mirror] TypeBox's TypeCompiler is required to use Union"));
129
+ instruction.typeCompilerWanred = true;
130
+ }
131
+ return property;
132
+ }
133
+ instruction.unionKeys[property] = 1;
134
+ const ui = instruction.unions.length;
135
+ const typeChecks = instruction.unions[ui] = [];
136
+ let v = `(()=>{\n`;
137
+ const unwrapRef = (type) => {
138
+ if (!(Kind in type) || !type.$ref) return type;
139
+ if (type[Kind] === "This") return deepClone(instruction.definitions[type.$ref]);
140
+ return type;
141
+ };
142
+ let cleanThenCheck = "";
143
+ for (let i = 0; i < schemas.length; i++) {
144
+ let type = unwrapRef(schemas[i]);
145
+ if (Array.isArray(type.anyOf)) for (let i = 0; i < type.anyOf.length; i++) type.anyOf[i] = unwrapRef(type.anyOf[i]);
146
+ else if (type.items) if (Array.isArray(type.items)) for (let i = 0; i < type.items.length; i++) type.items[i] = unwrapRef(type.items[i]);
147
+ else type.items = unwrapRef(type.items);
148
+ typeChecks.push(instruction.Compile(instruction.cyclicDefs ? withDefs(type, instruction.cyclicDefs) : type));
149
+ v += `if(d.unions[${ui}][${i}].Check(${property})){return ${mirror(type, property, {
150
+ ...instruction,
151
+ recursion: instruction.recursion + 1,
152
+ parentIsOptional: true,
153
+ fromUnion: true
154
+ })}}\n`;
155
+ cleanThenCheck += (i ? "" : "let ") + "tmp=" + mirror(type, property, {
156
+ ...instruction,
157
+ recursion: instruction.recursion + 1,
158
+ parentIsOptional: true,
159
+ fromUnion: true
160
+ }) + `\nif(d.unions[${ui}][${i}].Check(tmp))return tmp\n`;
161
+ }
162
+ if (cleanThenCheck) v += cleanThenCheck;
163
+ v += `return ${instruction.removeUnknownUnionType ? "undefined" : property}`;
164
+ return v + `})()`;
214
165
  };
215
- var mirror = (schema, property, instruction) => {
216
- if (!schema) return "";
217
- const isRoot = property === "v" && !instruction.fromUnion;
218
- const optionalsLength = instruction.optionals.length;
219
- try {
220
- if (Kind in schema && schema[Kind] === "Cyclic") {
221
- const call = handleCyclic(schema, property, instruction);
222
- return isRoot ? `return ${call}` : call;
223
- }
224
- return mirrorNode(schema, property, instruction);
225
- } catch (error) {
226
- instruction.optionals.length = optionalsLength;
227
- console.warn(
228
- new Error(
229
- "[exact-mirror] failed to generate mirror for a schema node, the node is passed through as-is. Please report this issue to https://github.com/elysiajs/exact-mirror/issues"
230
- ),
231
- error
232
- );
233
- return isRoot ? "return v" : property;
234
- }
166
+ const mirror = (schema, property, instruction) => {
167
+ if (!schema) return "";
168
+ const isRoot = property === "v" && !instruction.fromUnion;
169
+ const optionalsLength = instruction.optionals.length;
170
+ try {
171
+ if (instruction.transform && Codec in schema) {
172
+ const codec = schema[Codec][instruction.transform];
173
+ let ci = instruction.codecs.indexOf(codec);
174
+ if (ci === -1) ci = instruction.codecs.push(codec) - 1;
175
+ const body = mirrorNode(schema, `d.codecs[${ci}](${property})`, instruction);
176
+ return isRoot ? `return ${body}` : body;
177
+ }
178
+ if (Kind in schema && schema[Kind] === "Cyclic") {
179
+ const call = handleCyclic(schema, property, instruction);
180
+ return isRoot ? `return ${call}` : call;
181
+ }
182
+ return mirrorNode(schema, property, instruction);
183
+ } catch (error) {
184
+ instruction.optionals.length = optionalsLength;
185
+ console.warn(/* @__PURE__ */ new Error("[exact-mirror] failed to generate mirror for a schema node, the node is passed through as-is. Please report this issue to https://github.com/elysiajs/exact-mirror/issues"), error);
186
+ return isRoot ? "return v" : property;
187
+ }
235
188
  };
236
- var mirrorNode = (schema, property, instruction) => {
237
- const isRoot = property === "v" && !instruction.fromUnion;
238
- if (instruction.cyclicDefs && Kind in schema && schema[Kind] === "Ref" && schema.$ref && schema.$ref in instruction.cyclicDefs.names) {
239
- const call = `(${property}==null?${property}:${instruction.cyclicDefs.names[schema.$ref]}(${property}))`;
240
- return isRoot ? `return ${call}` : call;
241
- }
242
- if (isRoot && schema.type !== "object" && schema.type !== "array" && !schema.anyOf)
243
- return `return ${sanitize("v", instruction.sanitize?.length, schema)}`;
244
- if (instruction.recursion >= instruction.recursionLimit) return property;
245
- let v = "";
246
- if (schema.$id && Hint in schema)
247
- instruction.definitions[schema.$id] = schema;
248
- switch (schema.type) {
249
- case "object":
250
- if (schema[Kind] === "Record") {
251
- v = handleRecord(schema, property, instruction);
252
- break;
253
- }
254
- schema = mergeObjectIntersection(schema);
255
- if (!schema.properties) {
256
- v = property;
257
- break;
258
- }
259
- v += "{";
260
- if (schema.additionalProperties) v += `...${property},`;
261
- const keys = Object.keys(schema.properties);
262
- for (let i2 = 0; i2 < keys.length; i2++) {
263
- const key = keys[i2];
264
- let isOptional = (
265
- // all fields are optional
266
- !schema.required || // field is explicitly required
267
- schema.required && !schema.required.includes(key) || Array.isArray(schema.properties[key].anyOf)
268
- );
269
- const name = joinProperty(
270
- property,
271
- key,
272
- // If parent is a union, any property could be undefined
273
- instruction.parentIsOptional || instruction.fromUnion
274
- );
275
- if (isOptional) {
276
- const index = instruction.array;
277
- if (property.startsWith("ar")) {
278
- const dotIndex = name.indexOf(".");
279
- let refName;
280
- if (dotIndex >= 0) {
281
- refName = name.slice(dotIndex);
282
- } else {
283
- refName = name.slice(property.length);
284
- }
285
- if (refName.startsWith("?.")) {
286
- if (refName.charAt(2) === "[") {
287
- refName = refName.slice(2);
288
- } else {
289
- refName = refName.slice(1);
290
- }
291
- }
292
- const array = instruction.optionalsInArray;
293
- if (array[index]) {
294
- array[index].push(refName);
295
- } else {
296
- array[index] = [refName];
297
- }
298
- } else {
299
- instruction.optionals.push(name);
300
- }
301
- }
302
- const child = schema.properties[key];
303
- if (i2 !== 0) v += ",";
304
- v += `${encodeProperty(key)}:${isOptional ? `${name}===undefined?undefined:` : ""}${mirror(
305
- child,
306
- name,
307
- {
308
- ...instruction,
309
- recursion: instruction.recursion + 1,
310
- parentIsOptional: isOptional
311
- }
312
- )}`;
313
- }
314
- v += "}";
315
- break;
316
- case "array":
317
- if (!schema.items) {
318
- v = property;
319
- break;
320
- }
321
- if (
322
- // @ts-expect-error
323
- schema.items.type !== "object" && // @ts-expect-error
324
- schema.items.type !== "array"
325
- ) {
326
- const cyclicItems = instruction.cyclicDefs !== void 0 && !Array.isArray(schema.items) && Kind in schema.items && schema.items[Kind] === "Ref" && schema.items.$ref !== void 0 && schema.items.$ref in instruction.cyclicDefs.names;
327
- if (Array.isArray(schema.items)) {
328
- v = handleTuple(schema.items, property, instruction);
329
- break;
330
- } else if (!cyclicItems) {
331
- if (isRoot && !Array.isArray(schema.items.anyOf))
332
- return "return v";
333
- else if (Kind in schema.items && schema.items.$ref && (schema.items[Kind] === "Ref" || schema.items[Kind] === "This"))
334
- v = mirror(
335
- deepClone(
336
- instruction.definitions[schema.items.$ref]
337
- ),
338
- property,
339
- {
340
- ...instruction,
341
- parentIsOptional: true,
342
- recursion: instruction.recursion + 1
343
- }
344
- );
345
- else if (!Array.isArray(schema.items.anyOf)) {
346
- v = property;
347
- break;
348
- }
349
- }
350
- }
351
- const i = instruction.array;
352
- instruction.array++;
353
- let reference = property;
354
- if (isRoot) v = `const ar${i}v=new Array(${property}.length);`;
355
- else {
356
- reference = `ar${i}s`;
357
- v = `((${reference})=>{const ar${i}v=new Array(${reference}.length);`;
358
- }
359
- v += `for(let i=0;i<${reference}.length;i++){const ar${i}p=${reference}[i];ar${i}v[i]=${mirror(schema.items, `ar${i}p`, instruction)}`;
360
- const optionals = instruction.optionalsInArray[i + 1];
361
- if (optionals) {
362
- for (let oi = 0; oi < optionals.length; oi++) {
363
- const target = `ar${i}v[i]${optionals[oi]}`;
364
- v += `;if(${target}===undefined)delete ${target}`;
365
- }
366
- instruction.optionalsInArray[i + 1] = [];
367
- }
368
- v += `}`;
369
- if (!isRoot) v += `return ar${i}v})(${property})`;
370
- break;
371
- default:
372
- if (schema.$ref && schema.$ref in instruction.definitions)
373
- return mirror(
374
- instruction.definitions[schema.$ref],
375
- property,
376
- instruction
377
- );
378
- if (Array.isArray(schema.anyOf)) {
379
- v = handleUnion(schema.anyOf, property, instruction);
380
- break;
381
- }
382
- v = sanitize(property, instruction.sanitize?.length, schema);
383
- break;
384
- }
385
- if (!isRoot) return v;
386
- if (schema.type === "array") {
387
- v = `${v}const x=ar0v;`;
388
- } else {
389
- v = `const x=${v}
390
- `;
391
- }
392
- for (let i = 0; i < instruction.optionals.length; i++) {
393
- const key = instruction.optionals[i];
394
- const prop = key.slice(1);
395
- v += `if(${key}===undefined`;
396
- if (instruction.unionKeys[key]) v += `||x${prop}===undefined`;
397
- const shouldQuestion = prop.charCodeAt(0) !== 63 && schema.type !== "array";
398
- v += `)delete x${shouldQuestion ? prop.charCodeAt(0) === 91 ? "?." : "?" : ""}${prop}
399
- `;
400
- }
401
- return `${v}return x`;
189
+ const mirrorNode = (schema, property, instruction) => {
190
+ const isRoot = property === "v" && !instruction.fromUnion;
191
+ if (instruction.cyclicDefs && Kind in schema && schema[Kind] === "Ref" && schema.$ref && schema.$ref in instruction.cyclicDefs.names) {
192
+ const call = `(${property}==null?${property}:${instruction.cyclicDefs.names[schema.$ref]}(${property}))`;
193
+ return isRoot ? `return ${call}` : call;
194
+ }
195
+ if (isRoot && schema.type !== "object" && schema.type !== "array" && !schema.anyOf) return `return ${sanitize("v", instruction.sanitize?.length, schema)}`;
196
+ if (instruction.recursion >= instruction.recursionLimit) return property;
197
+ let v = "";
198
+ if (schema.$id && Hint in schema) instruction.definitions[schema.$id] = schema;
199
+ switch (schema.type) {
200
+ case "object":
201
+ if (schema[Kind] === "Record") {
202
+ v = handleRecord(schema, property, instruction);
203
+ break;
204
+ }
205
+ schema = mergeObjectIntersection(schema);
206
+ if (!schema.properties) {
207
+ v = property;
208
+ break;
209
+ }
210
+ v += "{";
211
+ if (schema.additionalProperties) v += `...${property},`;
212
+ const keys = Object.keys(schema.properties);
213
+ for (let i = 0; i < keys.length; i++) {
214
+ const key = keys[i];
215
+ let isOptional = !schema.required || schema.required && !schema.required.includes(key) || Array.isArray(schema.properties[key].anyOf);
216
+ const name = joinProperty(property, key, instruction.parentIsOptional || instruction.fromUnion);
217
+ if (isOptional) {
218
+ const index = instruction.array;
219
+ if (property.startsWith("ar")) {
220
+ const dotIndex = name.indexOf(".");
221
+ let refName;
222
+ if (dotIndex >= 0) refName = name.slice(dotIndex);
223
+ else refName = name.slice(property.length);
224
+ const array = instruction.optionalsInArray;
225
+ if (array[index]) array[index].push(refName);
226
+ else array[index] = [refName];
227
+ } else instruction.optionals.push(name);
228
+ }
229
+ const child = schema.properties[key];
230
+ if (i !== 0) v += ",";
231
+ v += `${encodeProperty(key)}:${isOptional ? `${name}===undefined?undefined:` : ""}${mirror(child, name, {
232
+ ...instruction,
233
+ recursion: instruction.recursion + 1,
234
+ parentIsOptional: isOptional
235
+ })}`;
236
+ }
237
+ v += "}";
238
+ break;
239
+ case "array":
240
+ if (!schema.items) {
241
+ v = property;
242
+ break;
243
+ }
244
+ if (schema.items.type !== "object" && schema.items.type !== "array") {
245
+ const cyclicItems = instruction.cyclicDefs !== void 0 && !Array.isArray(schema.items) && Kind in schema.items && schema.items[Kind] === "Ref" && schema.items.$ref !== void 0 && schema.items.$ref in instruction.cyclicDefs.names;
246
+ const codecItems = instruction.transform !== void 0 && !Array.isArray(schema.items) && Codec in schema.items;
247
+ if (Array.isArray(schema.items)) {
248
+ v = handleTuple(schema.items, property, instruction);
249
+ break;
250
+ } else if (!cyclicItems && !codecItems) {
251
+ if (isRoot && !Array.isArray(schema.items.anyOf)) return "return v";
252
+ else if (Kind in schema.items && schema.items.$ref && (schema.items[Kind] === "Ref" || schema.items[Kind] === "This")) v = mirror(deepClone(instruction.definitions[schema.items.$ref]), property, {
253
+ ...instruction,
254
+ parentIsOptional: true,
255
+ recursion: instruction.recursion + 1
256
+ });
257
+ else if (!Array.isArray(schema.items.anyOf)) {
258
+ v = property;
259
+ break;
260
+ }
261
+ }
262
+ }
263
+ const i = instruction.array;
264
+ instruction.array++;
265
+ let reference = property;
266
+ if (isRoot) v = `const ar${i}v=new Array(${property}.length);`;
267
+ else {
268
+ reference = `ar${i}s`;
269
+ v = `((${reference})=>{const ar${i}v=new Array(${reference}.length);`;
270
+ }
271
+ v += `for(let i=0;i<${reference}.length;i++){const ar${i}p=${reference}[i];ar${i}v[i]=${mirror(schema.items, `ar${i}p`, instruction)}`;
272
+ const optionals = instruction.optionalsInArray[i + 1];
273
+ if (optionals) {
274
+ for (let oi = 0; oi < optionals.length; oi++) {
275
+ const target = `ar${i}v[i]${optionals[oi]}`;
276
+ v += `;if(${target}===undefined)delete ${target}`;
277
+ }
278
+ instruction.optionalsInArray[i + 1] = [];
279
+ }
280
+ v += `}`;
281
+ if (!isRoot) v += `return ar${i}v})(${property})`;
282
+ break;
283
+ default:
284
+ if (schema.$ref && schema.$ref in instruction.definitions) return mirror(instruction.definitions[schema.$ref], property, instruction);
285
+ if (Array.isArray(schema.anyOf)) {
286
+ v = handleUnion(schema.anyOf, property, instruction);
287
+ break;
288
+ }
289
+ v = sanitize(property, instruction.sanitize?.length, schema);
290
+ break;
291
+ }
292
+ if (!isRoot) return v;
293
+ if (schema.type === "array") v = `${v}const x=ar0v;`;
294
+ else v = `const x=${v}\n`;
295
+ for (let i = 0; i < instruction.optionals.length; i++) {
296
+ const key = instruction.optionals[i];
297
+ const prop = key.slice(1);
298
+ v += `if(${key}===undefined`;
299
+ if (instruction.unionKeys[key]) v += `||x${prop}===undefined`;
300
+ const shouldQuestion = prop.charCodeAt(0) !== 63 && schema.type !== "array";
301
+ v += `)delete x${shouldQuestion ? prop.charCodeAt(0) === 91 ? "?." : "?" : ""}${prop}\n`;
302
+ }
303
+ return `${v}return x`;
402
304
  };
403
- var createMirror = (schema, {
404
- Compile,
405
- modules,
406
- definitions,
407
- sanitize: sanitize2,
408
- recursionLimit = 8,
409
- removeUnknownUnionType = false,
410
- emit
411
- } = {}) => {
412
- const unions = [];
413
- const cyclic = { groups: /* @__PURE__ */ new Map(), fns: [], count: 0 };
414
- if (typeof sanitize2 === "function") sanitize2 = [sanitize2];
415
- const f = mirror(schema, "v", {
416
- optionals: [],
417
- optionalsInArray: [],
418
- array: 0,
419
- parentIsOptional: false,
420
- unions,
421
- unionKeys: {},
422
- Compile,
423
- modules,
424
- // @ts-ignore private property
425
- definitions: definitions ?? modules?.$defs ?? {},
426
- cyclic,
427
- sanitize: sanitize2,
428
- recursion: 0,
429
- recursionLimit,
430
- removeUnknownUnionType
431
- });
432
- const fns = cyclic.fns.length ? cyclic.fns.join("\n") + "\n" : "";
433
- if (!unions.length && !sanitize2?.length) {
434
- if (emit) return { source: fns + f, externals: void 0 };
435
- return Function("v", fns + f);
436
- }
437
- let hof;
438
- if (sanitize2?.length) {
439
- hof = {};
440
- for (let i = 0; i < sanitize2.length; i++) hof[`h${i}`] = sanitize2[i];
441
- }
442
- const source = `${fns}return function mirror(v){${f}}`;
443
- if (emit)
444
- return {
445
- source,
446
- externals: {
447
- unions,
448
- hof
449
- }
450
- };
451
- return Function(
452
- "d",
453
- source
454
- )(
455
- hof ? unions ? {
456
- unions,
457
- ...hof
458
- } : hof : unions ? { unions } : void 0
459
- );
460
- };
461
- var index_default = createMirror;
462
- export {
463
- createMirror,
464
- deepClone,
465
- index_default as default,
466
- mergeObjectIntersection
305
+ const createMirror = (schema, { Compile, modules, definitions, sanitize, recursionLimit = 8, removeUnknownUnionType = false, emit, decode, encode } = Object.create(null)) => {
306
+ const unions = [];
307
+ const codecs = [];
308
+ const cyclic = {
309
+ groups: /* @__PURE__ */ new Map(),
310
+ fns: [],
311
+ count: 0
312
+ };
313
+ if (typeof sanitize === "function") sanitize = [sanitize];
314
+ const f = mirror(schema, "v", {
315
+ optionals: [],
316
+ optionalsInArray: [],
317
+ array: 0,
318
+ parentIsOptional: false,
319
+ unions,
320
+ unionKeys: Object.create(null),
321
+ Compile,
322
+ modules,
323
+ definitions: definitions ?? modules?.$defs ?? Object.create(null),
324
+ cyclic,
325
+ sanitize,
326
+ recursion: 0,
327
+ recursionLimit,
328
+ removeUnknownUnionType,
329
+ transform: decode ? "decode" : encode ? "encode" : void 0,
330
+ codecs
331
+ });
332
+ const fns = cyclic.fns.length ? cyclic.fns.join("\n") + "\n" : "";
333
+ if (!unions.length && !sanitize?.length && !codecs.length) {
334
+ if (emit) return {
335
+ source: fns + f,
336
+ externals: void 0
337
+ };
338
+ return Function("v", fns + f);
339
+ }
340
+ let hof;
341
+ if (sanitize?.length) {
342
+ hof = Object.create(null);
343
+ for (let i = 0; i < sanitize.length; i++) hof[`h${i}`] = sanitize[i];
344
+ }
345
+ const source = `${fns}return function mirror(v){${f}}`;
346
+ if (emit) return {
347
+ source,
348
+ externals: {
349
+ unions,
350
+ codecs: codecs.length ? codecs : void 0,
351
+ hof
352
+ }
353
+ };
354
+ const d = Object.create(null);
355
+ if (unions.length) d.unions = unions;
356
+ if (codecs.length) d.codecs = codecs;
357
+ if (hof) Object.assign(d, hof);
358
+ return Function("d", source)(d);
467
359
  };
360
+
361
+ //#endregion
362
+ export { createMirror, createMirror as default, deepClone, mergeObjectIntersection };