exact-mirror 0.0.1 → 0.0.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.
@@ -1,4 +1,23 @@
1
+ import { TypeCompiler, type TypeCheck } from '@sinclair/typebox/compiler';
1
2
  import type { TAnySchema } from '@sinclair/typebox';
2
3
  export declare const mergeObjectIntersection: (schema: TAnySchema) => TAnySchema;
3
- export declare const createMirror: <T extends TAnySchema>(schema: T) => ((v: T["static"]) => T["static"]);
4
+ interface Instruction {
5
+ optionals: string[];
6
+ optionalsInArray: string[][];
7
+ parentIsOptional: boolean;
8
+ array: number;
9
+ unions: TypeCheck<any>[][];
10
+ unionKeys: Record<string, 1>;
11
+ /**
12
+ * TypeCompiler is required when using Union
13
+ *
14
+ * Left as opt-in to reduce bundle size
15
+ * many end-user doesn't use Union
16
+ *
17
+ * @default undefined
18
+ */
19
+ TypeCompiler?: typeof TypeCompiler;
20
+ typeCompilerWanred?: boolean;
21
+ }
22
+ export declare const createMirror: <T extends TAnySchema>(schema: T, { TypeCompiler }?: Pick<Instruction, "TypeCompiler">) => ((v: T["static"]) => T["static"]);
4
23
  export default createMirror;
package/dist/cjs/index.js CHANGED
@@ -25,10 +25,11 @@ __export(index_exports, {
25
25
  mergeObjectIntersection: () => mergeObjectIntersection
26
26
  });
27
27
  module.exports = __toCommonJS(index_exports);
28
+ var import_compiler = require("@sinclair/typebox/compiler");
28
29
  var Kind = Symbol.for("TypeBox.Kind");
29
- var OptionalKind = Symbol.for("TypeBox.Optional");
30
30
  var isSpecialProperty = (name) => /(\ |-|\t|\n)/.test(name);
31
31
  var joinProperty = (v1, v2, isOptional = false) => {
32
+ if (typeof v2 === "number") return `${v1}[${v2}]`;
32
33
  if (isSpecialProperty(v2)) return `${v1}${isOptional ? "?." : ""}["${v2}"]`;
33
34
  return `${v1}${isOptional ? "?" : ""}.${v2}`;
34
35
  };
@@ -52,21 +53,74 @@ var mergeObjectIntersection = (schema) => {
52
53
  }
53
54
  return newSchema;
54
55
  };
56
+ var handleRecord = (schema, property, instruction) => {
57
+ const child = schema.patternProperties["^(.*)$"] ?? schema.patternProperties[Object.keys(schema.patternProperties)[0]];
58
+ if (!child) return property;
59
+ const i = instruction.array;
60
+ instruction.array++;
61
+ return `(()=>{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)}}return ar${i}v})()`;
62
+ };
63
+ var handleTuple = (schema, property, instruction) => {
64
+ const i = instruction.array;
65
+ instruction.array++;
66
+ const isRoot = property === "v" && !instruction.unions.length;
67
+ let v = "";
68
+ if (!isRoot) v = `(()=>{`;
69
+ v += `const ar${i}v=[`;
70
+ for (let i2 = 0; i2 < schema.length; i2++) {
71
+ if (i2 !== 0) v += ",";
72
+ v += mirror(
73
+ schema[i2],
74
+ joinProperty(property, i2, instruction.parentIsOptional),
75
+ instruction
76
+ );
77
+ }
78
+ v += `];`;
79
+ if (!isRoot) v += `return ar${i}v})()`;
80
+ return v;
81
+ };
82
+ var handleUnion = (schemas, property, instruction) => {
83
+ if (instruction.TypeCompiler === void 0) {
84
+ if (!instruction.typeCompilerWanred) {
85
+ console.warn(
86
+ new Error("TypeBox's TypeCompiler is required to use Union")
87
+ );
88
+ instruction.typeCompilerWanred = true;
89
+ }
90
+ return property;
91
+ }
92
+ instruction.unionKeys[property] = 1;
93
+ const ui = instruction.unions.length;
94
+ const typeChecks = instruction.unions[ui] = [];
95
+ let v = `(()=>{
96
+ `;
97
+ for (let i = 0; i < schemas.length; i++) {
98
+ typeChecks.push(import_compiler.TypeCompiler.Compile(schemas[i]));
99
+ v += `if(d.unions[${ui}][${i}].Check(${property})){return ${mirror(schemas[i], property, instruction)}}
100
+ `;
101
+ }
102
+ v += `return undefined})()`;
103
+ return v;
104
+ };
55
105
  var mirror = (schema, property, instruction) => {
56
106
  if (!schema) return "";
57
- const isRoot = property === "v";
58
- if (isRoot && schema.type !== "object" && schema.type !== "array")
107
+ const isRoot = property === "v" && !instruction.unions.length;
108
+ if (isRoot && schema.type !== "object" && schema.type !== "array" && !schema.anyOf)
59
109
  return `return v`;
60
110
  let v = "";
61
111
  switch (schema.type) {
62
112
  case "object":
113
+ if (schema[Kind] === "Record") {
114
+ v = handleRecord(schema, property, instruction);
115
+ break;
116
+ }
63
117
  schema = mergeObjectIntersection(schema);
64
118
  v += "{";
65
119
  if (schema.additionalProperties) v += `...${property}`;
66
120
  const keys = Object.keys(schema.properties);
67
121
  for (let i2 = 0; i2 < keys.length; i2++) {
68
122
  const key = keys[i2];
69
- let isOptional = schema.required && !schema.required.includes(key);
123
+ let isOptional = schema.required && !schema.required.includes(key) || Array.isArray(schema.properties[key].anyOf);
70
124
  const name = joinProperty(
71
125
  property,
72
126
  key,
@@ -99,12 +153,14 @@ var mirror = (schema, property, instruction) => {
99
153
  v += "}";
100
154
  break;
101
155
  case "array":
102
- const i = instruction.array;
103
- instruction.array++;
104
156
  if (schema.items.type !== "object" && schema.items.type !== "array") {
105
- v = property;
157
+ if (Array.isArray(schema.items))
158
+ v = handleTuple(schema.items, property, instruction);
159
+ else v = property;
106
160
  break;
107
161
  }
162
+ const i = instruction.array;
163
+ instruction.array++;
108
164
  if (!isRoot) v = `(()=>{`;
109
165
  v += `const ar${i}s=${property},ar${i}v=new Array(${property}.length);for(let i=0;i<ar${i}s.length;i++){const ar${i}p=ar${i}s[i];ar${i}v[i]=${mirror(schema.items, `ar${i}p`, instruction)}`;
110
166
  const optionals = instruction.optionalsInArray[i + 1];
@@ -118,7 +174,12 @@ var mirror = (schema, property, instruction) => {
118
174
  if (!isRoot) v += `return ar${i}v})()`;
119
175
  break;
120
176
  default:
177
+ if (Array.isArray(schema.anyOf)) {
178
+ v = handleUnion(schema.anyOf, property, instruction);
179
+ break;
180
+ }
121
181
  v = property;
182
+ break;
122
183
  }
123
184
  if (!isRoot) return v;
124
185
  if (schema.type === "array") return `${v}return ar0v`;
@@ -126,19 +187,33 @@ var mirror = (schema, property, instruction) => {
126
187
  `;
127
188
  for (let i = 0; i < instruction.optionals.length; i++) {
128
189
  const key = instruction.optionals[i];
129
- v += `if(${key}===undefined)delete x${key.slice(1)}
190
+ const prop = key.slice(1);
191
+ v += `if(${key}===undefined`;
192
+ if (instruction.unionKeys[key]) v += `||x${prop}===undefined`;
193
+ v += `)delete x?${prop}
130
194
  `;
131
195
  }
132
196
  return `${v}return x`;
133
197
  };
134
- var createMirror = (schema) => {
198
+ var createMirror = (schema, { TypeCompiler: TypeCompiler2 } = {}) => {
199
+ const unions = [];
135
200
  const f = mirror(schema, "v", {
136
201
  optionals: [],
137
202
  optionalsInArray: [],
138
203
  array: 0,
139
- parentIsOptional: false
204
+ parentIsOptional: false,
205
+ unions,
206
+ unionKeys: {},
207
+ TypeCompiler: TypeCompiler2
208
+ });
209
+ if (!unions.length) return Function("v", f);
210
+ const fn = `return function mirror(v){${f}}`;
211
+ return Function(
212
+ "d",
213
+ fn
214
+ )({
215
+ unions
140
216
  });
141
- return Function("v", f);
142
217
  };
143
218
  var index_default = createMirror;
144
219
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.d.ts CHANGED
@@ -1,4 +1,23 @@
1
+ import { TypeCompiler, type TypeCheck } from '@sinclair/typebox/compiler';
1
2
  import type { TAnySchema } from '@sinclair/typebox';
2
3
  export declare const mergeObjectIntersection: (schema: TAnySchema) => TAnySchema;
3
- export declare const createMirror: <T extends TAnySchema>(schema: T) => ((v: T["static"]) => T["static"]);
4
+ interface Instruction {
5
+ optionals: string[];
6
+ optionalsInArray: string[][];
7
+ parentIsOptional: boolean;
8
+ array: number;
9
+ unions: TypeCheck<any>[][];
10
+ unionKeys: Record<string, 1>;
11
+ /**
12
+ * TypeCompiler is required when using Union
13
+ *
14
+ * Left as opt-in to reduce bundle size
15
+ * many end-user doesn't use Union
16
+ *
17
+ * @default undefined
18
+ */
19
+ TypeCompiler?: typeof TypeCompiler;
20
+ typeCompilerWanred?: boolean;
21
+ }
22
+ export declare const createMirror: <T extends TAnySchema>(schema: T, { TypeCompiler }?: Pick<Instruction, "TypeCompiler">) => ((v: T["static"]) => T["static"]);
4
23
  export default createMirror;
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  // src/index.ts
2
+ import { TypeCompiler } from "@sinclair/typebox/compiler";
2
3
  var Kind = Symbol.for("TypeBox.Kind");
3
- var OptionalKind = Symbol.for("TypeBox.Optional");
4
4
  var isSpecialProperty = (name) => /(\ |-|\t|\n)/.test(name);
5
5
  var joinProperty = (v1, v2, isOptional = false) => {
6
+ if (typeof v2 === "number") return `${v1}[${v2}]`;
6
7
  if (isSpecialProperty(v2)) return `${v1}${isOptional ? "?." : ""}["${v2}"]`;
7
8
  return `${v1}${isOptional ? "?" : ""}.${v2}`;
8
9
  };
@@ -26,21 +27,74 @@ var mergeObjectIntersection = (schema) => {
26
27
  }
27
28
  return newSchema;
28
29
  };
30
+ var handleRecord = (schema, property, instruction) => {
31
+ const child = schema.patternProperties["^(.*)$"] ?? schema.patternProperties[Object.keys(schema.patternProperties)[0]];
32
+ if (!child) return property;
33
+ const i = instruction.array;
34
+ instruction.array++;
35
+ return `(()=>{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)}}return ar${i}v})()`;
36
+ };
37
+ var handleTuple = (schema, property, instruction) => {
38
+ const i = instruction.array;
39
+ instruction.array++;
40
+ const isRoot = property === "v" && !instruction.unions.length;
41
+ let v = "";
42
+ if (!isRoot) v = `(()=>{`;
43
+ v += `const ar${i}v=[`;
44
+ for (let i2 = 0; i2 < schema.length; i2++) {
45
+ if (i2 !== 0) v += ",";
46
+ v += mirror(
47
+ schema[i2],
48
+ joinProperty(property, i2, instruction.parentIsOptional),
49
+ instruction
50
+ );
51
+ }
52
+ v += `];`;
53
+ if (!isRoot) v += `return ar${i}v})()`;
54
+ return v;
55
+ };
56
+ var handleUnion = (schemas, property, instruction) => {
57
+ if (instruction.TypeCompiler === void 0) {
58
+ if (!instruction.typeCompilerWanred) {
59
+ console.warn(
60
+ new Error("TypeBox's TypeCompiler is required to use Union")
61
+ );
62
+ instruction.typeCompilerWanred = true;
63
+ }
64
+ return property;
65
+ }
66
+ instruction.unionKeys[property] = 1;
67
+ const ui = instruction.unions.length;
68
+ const typeChecks = instruction.unions[ui] = [];
69
+ let v = `(()=>{
70
+ `;
71
+ for (let i = 0; i < schemas.length; i++) {
72
+ typeChecks.push(TypeCompiler.Compile(schemas[i]));
73
+ v += `if(d.unions[${ui}][${i}].Check(${property})){return ${mirror(schemas[i], property, instruction)}}
74
+ `;
75
+ }
76
+ v += `return undefined})()`;
77
+ return v;
78
+ };
29
79
  var mirror = (schema, property, instruction) => {
30
80
  if (!schema) return "";
31
- const isRoot = property === "v";
32
- if (isRoot && schema.type !== "object" && schema.type !== "array")
81
+ const isRoot = property === "v" && !instruction.unions.length;
82
+ if (isRoot && schema.type !== "object" && schema.type !== "array" && !schema.anyOf)
33
83
  return `return v`;
34
84
  let v = "";
35
85
  switch (schema.type) {
36
86
  case "object":
87
+ if (schema[Kind] === "Record") {
88
+ v = handleRecord(schema, property, instruction);
89
+ break;
90
+ }
37
91
  schema = mergeObjectIntersection(schema);
38
92
  v += "{";
39
93
  if (schema.additionalProperties) v += `...${property}`;
40
94
  const keys = Object.keys(schema.properties);
41
95
  for (let i2 = 0; i2 < keys.length; i2++) {
42
96
  const key = keys[i2];
43
- let isOptional = schema.required && !schema.required.includes(key);
97
+ let isOptional = schema.required && !schema.required.includes(key) || Array.isArray(schema.properties[key].anyOf);
44
98
  const name = joinProperty(
45
99
  property,
46
100
  key,
@@ -73,12 +127,14 @@ var mirror = (schema, property, instruction) => {
73
127
  v += "}";
74
128
  break;
75
129
  case "array":
76
- const i = instruction.array;
77
- instruction.array++;
78
130
  if (schema.items.type !== "object" && schema.items.type !== "array") {
79
- v = property;
131
+ if (Array.isArray(schema.items))
132
+ v = handleTuple(schema.items, property, instruction);
133
+ else v = property;
80
134
  break;
81
135
  }
136
+ const i = instruction.array;
137
+ instruction.array++;
82
138
  if (!isRoot) v = `(()=>{`;
83
139
  v += `const ar${i}s=${property},ar${i}v=new Array(${property}.length);for(let i=0;i<ar${i}s.length;i++){const ar${i}p=ar${i}s[i];ar${i}v[i]=${mirror(schema.items, `ar${i}p`, instruction)}`;
84
140
  const optionals = instruction.optionalsInArray[i + 1];
@@ -92,7 +148,12 @@ var mirror = (schema, property, instruction) => {
92
148
  if (!isRoot) v += `return ar${i}v})()`;
93
149
  break;
94
150
  default:
151
+ if (Array.isArray(schema.anyOf)) {
152
+ v = handleUnion(schema.anyOf, property, instruction);
153
+ break;
154
+ }
95
155
  v = property;
156
+ break;
96
157
  }
97
158
  if (!isRoot) return v;
98
159
  if (schema.type === "array") return `${v}return ar0v`;
@@ -100,19 +161,33 @@ var mirror = (schema, property, instruction) => {
100
161
  `;
101
162
  for (let i = 0; i < instruction.optionals.length; i++) {
102
163
  const key = instruction.optionals[i];
103
- v += `if(${key}===undefined)delete x${key.slice(1)}
164
+ const prop = key.slice(1);
165
+ v += `if(${key}===undefined`;
166
+ if (instruction.unionKeys[key]) v += `||x${prop}===undefined`;
167
+ v += `)delete x?${prop}
104
168
  `;
105
169
  }
106
170
  return `${v}return x`;
107
171
  };
108
- var createMirror = (schema) => {
172
+ var createMirror = (schema, { TypeCompiler: TypeCompiler2 } = {}) => {
173
+ const unions = [];
109
174
  const f = mirror(schema, "v", {
110
175
  optionals: [],
111
176
  optionalsInArray: [],
112
177
  array: 0,
113
- parentIsOptional: false
178
+ parentIsOptional: false,
179
+ unions,
180
+ unionKeys: {},
181
+ TypeCompiler: TypeCompiler2
182
+ });
183
+ if (!unions.length) return Function("v", f);
184
+ const fn = `return function mirror(v){${f}}`;
185
+ return Function(
186
+ "d",
187
+ fn
188
+ )({
189
+ unions
114
190
  });
115
- return Function("v", f);
116
191
  };
117
192
  var index_default = createMirror;
118
193
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exact-mirror",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Mirror exact value to TypeBox/OpenAPI model",
5
5
  "license": "MIT",
6
6
  "scripts": {