typia 7.0.0-dev.20241018 → 7.0.0-dev.20241019

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 (35) hide show
  1. package/lib/factories/ProtobufFactory.js +561 -128
  2. package/lib/factories/ProtobufFactory.js.map +1 -1
  3. package/lib/programmers/helpers/ProtobufUtil.d.ts +2 -0
  4. package/lib/programmers/helpers/ProtobufUtil.js +2 -2
  5. package/lib/programmers/helpers/ProtobufUtil.js.map +1 -1
  6. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js +169 -223
  7. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js.map +1 -1
  8. package/lib/programmers/protobuf/ProtobufMessageProgrammer.d.ts +1 -1
  9. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js +48 -140
  10. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js.map +1 -1
  11. package/lib/schemas/metadata/MetadataProperty.d.ts +2 -0
  12. package/lib/schemas/metadata/MetadataProperty.js.map +1 -1
  13. package/lib/schemas/protobuf/IProtobufProperty.d.ts +5 -0
  14. package/lib/schemas/protobuf/IProtobufProperty.js +3 -0
  15. package/lib/schemas/protobuf/IProtobufProperty.js.map +1 -0
  16. package/lib/schemas/protobuf/IProtobufPropertyType.d.ts +28 -0
  17. package/lib/schemas/protobuf/IProtobufPropertyType.js +3 -0
  18. package/lib/schemas/protobuf/IProtobufPropertyType.js.map +1 -0
  19. package/lib/schemas/protobuf/IProtobufSchema.d.ts +38 -0
  20. package/lib/schemas/protobuf/IProtobufSchema.js +3 -0
  21. package/lib/schemas/protobuf/IProtobufSchema.js.map +1 -0
  22. package/lib/utils/{NameEncoder.d.ts → ProtobufNameEncoder.d.ts} +1 -1
  23. package/lib/utils/{NameEncoder.js → ProtobufNameEncoder.js} +7 -7
  24. package/lib/utils/ProtobufNameEncoder.js.map +1 -0
  25. package/package.json +1 -1
  26. package/src/factories/ProtobufFactory.ts +313 -14
  27. package/src/programmers/helpers/ProtobufUtil.ts +1 -1
  28. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +254 -315
  29. package/src/programmers/protobuf/ProtobufMessageProgrammer.ts +68 -115
  30. package/src/schemas/metadata/MetadataProperty.ts +2 -4
  31. package/src/schemas/protobuf/IProtobufProperty.ts +6 -0
  32. package/src/schemas/protobuf/IProtobufPropertyType.ts +37 -0
  33. package/src/schemas/protobuf/IProtobufSchema.ts +50 -0
  34. package/src/utils/{NameEncoder.ts → ProtobufNameEncoder.ts} +1 -1
  35. package/lib/utils/NameEncoder.js.map +0 -1
@@ -4,11 +4,15 @@ import { IMetadataTypeTag } from "../schemas/metadata/IMetadataTypeTag";
4
4
  import { Metadata } from "../schemas/metadata/Metadata";
5
5
  import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
6
6
  import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
7
+ import { IProtobufProperty } from "../schemas/protobuf/IProtobufProperty";
8
+ import { IProtobufPropertyType } from "../schemas/protobuf/IProtobufPropertyType";
9
+ import { IProtobufSchema } from "../schemas/protobuf/IProtobufSchema";
7
10
 
8
11
  import { ProtobufUtil } from "../programmers/helpers/ProtobufUtil";
9
12
 
10
13
  import { TransformerError } from "../transformers/TransformerError";
11
14
 
15
+ import { ProtobufAtomic } from "../typings/ProtobufAtomic";
12
16
  import { ValidationPipe } from "../typings/ValidationPipe";
13
17
 
14
18
  import { MetadataCollection } from "./MetadataCollection";
@@ -47,6 +51,297 @@ export namespace ProtobufFactory {
47
51
  return result.data;
48
52
  };
49
53
 
54
+ /**
55
+ * @internal
56
+ */
57
+ export const emplaceObject = (object: MetadataObjectType): void => {
58
+ for (const p of object.properties) emplaceProperty(p);
59
+ const properties: IProtobufProperty[] = object.properties
60
+ .map((p) => p.of_protobuf_)
61
+ .filter((p) => p !== undefined);
62
+ const unique: Set<number> = new Set(
63
+ properties
64
+ .filter((p) => p !== undefined)
65
+ .filter((p) => p.fixed === true)
66
+ .map((p) => p.union.map((u) => u.index))
67
+ .flat(),
68
+ );
69
+ let index: number = 1;
70
+ properties.forEach((schema) => {
71
+ if (schema.fixed === true)
72
+ index = Math.max(
73
+ index,
74
+ Math.max(...schema.union.map((u) => u.index)) + 1,
75
+ );
76
+ else {
77
+ for (const u of schema.union) {
78
+ while (unique.has(index) === true) ++index;
79
+ u.index = index;
80
+ unique.add(index);
81
+ }
82
+ ++index;
83
+ }
84
+ });
85
+ };
86
+
87
+ const emplaceProperty = (prop: MetadataProperty): void => {
88
+ const union: IProtobufPropertyType[] = [];
89
+ for (const native of prop.value.natives)
90
+ if (native.name === "Uint8Array")
91
+ union.push({
92
+ type: "bytes",
93
+ index: ProtobufUtil.getSequence(native.tags[0] ?? [])!,
94
+ });
95
+ union.push(...emplaceAtomic(prop.value).values());
96
+ for (const array of prop.value.arrays)
97
+ union.push({
98
+ type: "array",
99
+ array: array.type,
100
+ value: emplaceSchema(
101
+ array.type.value,
102
+ ) as IProtobufSchema.IArray["value"],
103
+ index: ProtobufUtil.getSequence(array.tags[0] ?? [])!,
104
+ });
105
+ for (const obj of prop.value.objects)
106
+ if (isDynamicObject(obj.type))
107
+ union.push({
108
+ type: "map",
109
+ map: obj.type,
110
+ key: emplaceSchema(
111
+ obj.type.properties[0]!.key,
112
+ ) as IProtobufSchema.IMap["key"],
113
+ value: emplaceSchema(
114
+ obj.type.properties[0]!.value,
115
+ ) as IProtobufSchema.IMap["value"],
116
+ index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
117
+ });
118
+ else
119
+ union.push({
120
+ type: "object",
121
+ object: obj.type,
122
+ index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
123
+ });
124
+ for (const map of prop.value.maps)
125
+ union.push({
126
+ type: "map",
127
+ map,
128
+ key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
129
+ value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
130
+ index: ProtobufUtil.getSequence(map.tags[0] ?? [])!,
131
+ });
132
+ prop.of_protobuf_ = {
133
+ union,
134
+ fixed: union.every((p) => p.index !== null),
135
+ };
136
+ };
137
+
138
+ const emplaceSchema = (metadata: Metadata): IProtobufSchema => {
139
+ for (const native of metadata.natives)
140
+ if (native.name === "Uint8Array")
141
+ return {
142
+ type: "bytes",
143
+ };
144
+ const atomic = emplaceAtomic(metadata);
145
+ if (atomic.size) return atomic.values().next().value!;
146
+ for (const array of metadata.arrays)
147
+ return {
148
+ type: "array",
149
+ array: array.type,
150
+ value: emplaceSchema(
151
+ array.type.value,
152
+ ) as IProtobufSchema.IArray["value"],
153
+ };
154
+ for (const obj of metadata.objects)
155
+ if (isDynamicObject(obj.type))
156
+ return {
157
+ type: "map",
158
+ map: obj.type,
159
+ key: emplaceSchema(
160
+ obj.type.properties[0]!.key,
161
+ ) as IProtobufSchema.IMap["key"],
162
+ value: emplaceSchema(
163
+ obj.type.properties[0]!.value,
164
+ ) as IProtobufSchema.IMap["value"],
165
+ };
166
+ else
167
+ return {
168
+ type: "object",
169
+ object: obj.type,
170
+ };
171
+ for (const map of metadata.maps)
172
+ return {
173
+ type: "map",
174
+ map,
175
+ key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
176
+ value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
177
+ };
178
+ throw new Error(
179
+ "Error on ProtobufFactory.emplaceSchema(): any type detected.",
180
+ );
181
+ };
182
+
183
+ const emplaceAtomic = (
184
+ meta: Metadata,
185
+ ): Map<ProtobufAtomic, IProtobufPropertyType> => {
186
+ const map: Map<ProtobufAtomic, IProtobufPropertyType> = new Map();
187
+
188
+ // CONSTANTS
189
+ for (const c of meta.constants)
190
+ if (c.type === "boolean")
191
+ map.set("bool", {
192
+ type: "bool",
193
+ index: getSequence(c.values[0]?.tags[0] ?? [])!,
194
+ });
195
+ else if (c.type === "bigint") {
196
+ const init: ProtobufAtomic.BigNumeric = getBigintType(
197
+ c.values.map((v) => BigInt(v.value)),
198
+ );
199
+ for (const value of c.values)
200
+ emplaceBigint({
201
+ map,
202
+ tags: value.tags,
203
+ init,
204
+ });
205
+ } else if (c.type === "number") {
206
+ const init: ProtobufAtomic.Numeric = getNumberType(
207
+ c.values.map((v) => v.value) as number[],
208
+ );
209
+ for (const value of c.values)
210
+ emplaceNumber({
211
+ map,
212
+ tags: value.tags,
213
+ init,
214
+ });
215
+ } else if (c.type === "string")
216
+ map.set("string", {
217
+ type: "string",
218
+ index: getSequence(c.values[0]?.tags[0] ?? [])!,
219
+ });
220
+
221
+ // TEMPLATE
222
+ if (meta.templates.length)
223
+ map.set("string", {
224
+ type: "string",
225
+ index: getSequence(meta.templates[0]?.tags[0] ?? [])!,
226
+ });
227
+
228
+ // ATOMICS
229
+ for (const atomic of meta.atomics)
230
+ if (atomic.type === "boolean")
231
+ map.set("bool", {
232
+ type: "bool",
233
+ index: getSequence(atomic.tags[0] ?? [])!,
234
+ });
235
+ else if (atomic.type === "bigint")
236
+ emplaceBigint({
237
+ map,
238
+ tags: atomic.tags,
239
+ init: "int64",
240
+ });
241
+ else if (atomic.type === "number")
242
+ emplaceNumber({
243
+ map,
244
+ tags: atomic.tags,
245
+ init: "double",
246
+ });
247
+ else if (atomic.type === "string")
248
+ map.set("string", {
249
+ type: "string",
250
+ index: getSequence(atomic.tags[0] ?? [])!,
251
+ });
252
+
253
+ // SORTING IF REQUIRED
254
+ if (map.size && map.values().next().value!.index === null)
255
+ return new Map(
256
+ Array.from(map).sort((x, y) => ProtobufUtil.compare(x[0], y[0])),
257
+ );
258
+ return map;
259
+ };
260
+
261
+ const emplaceBigint = (next: {
262
+ map: Map<ProtobufAtomic, IProtobufPropertyType>;
263
+ tags: IMetadataTypeTag[][];
264
+ init: ProtobufAtomic.BigNumeric;
265
+ }): void => {
266
+ if (next.tags.length === 0) {
267
+ next.map.set(next.init, {
268
+ type: "bigint",
269
+ name: next.init,
270
+ index: null!,
271
+ });
272
+ return;
273
+ }
274
+ for (const row of next.tags) {
275
+ const value: ProtobufAtomic.BigNumeric =
276
+ row.find(
277
+ (tag) =>
278
+ tag.kind === "type" &&
279
+ (tag.value === "int64" || tag.value === "uint64"),
280
+ )?.value ?? next.init;
281
+ next.map.set(next.init, {
282
+ type: "bigint",
283
+ name: value,
284
+ index: ProtobufUtil.getSequence(row)!,
285
+ });
286
+ }
287
+ };
288
+
289
+ const emplaceNumber = (next: {
290
+ map: Map<ProtobufAtomic, IProtobufPropertyType>;
291
+ tags: IMetadataTypeTag[][];
292
+ init: ProtobufAtomic.Numeric;
293
+ }): void => {
294
+ if (next.tags.length === 0) {
295
+ next.map.set(next.init, {
296
+ type: "number",
297
+ name: next.init,
298
+ index: null!,
299
+ });
300
+ return;
301
+ }
302
+ for (const row of next.tags) {
303
+ const value: ProtobufAtomic.Numeric =
304
+ row.find(
305
+ (tag) =>
306
+ tag.kind === "type" &&
307
+ (tag.value === "int32" ||
308
+ tag.value === "uint32" ||
309
+ tag.value === "int64" ||
310
+ tag.value === "uint64" ||
311
+ tag.value === "float" ||
312
+ tag.value === "double"),
313
+ )?.value ?? next.init;
314
+ next.map.set(value, {
315
+ type: "number",
316
+ name: value,
317
+ index: ProtobufUtil.getSequence(row)!,
318
+ });
319
+ }
320
+ };
321
+
322
+ const getBigintType = (values: bigint[]): ProtobufAtomic.BigNumeric =>
323
+ values.some((v) => v < 0) ? "int64" : "uint64";
324
+
325
+ const getNumberType = (values: number[]): ProtobufAtomic.Numeric =>
326
+ values.every((v) => Math.floor(v) === v)
327
+ ? values.every((v) => -2147483648 <= v && v <= 2147483647)
328
+ ? "int32"
329
+ : "int64"
330
+ : "double";
331
+
332
+ const getSequence = (tags: IMetadataTypeTag[]): number | null => {
333
+ const sequence = tags.find(
334
+ (t) =>
335
+ t.kind === "sequence" &&
336
+ typeof (t.schema as any)?.["x-protobuf-sequence"] === "number",
337
+ );
338
+ if (sequence === undefined) return null;
339
+ const value: number = Number(
340
+ (sequence.schema as any)["x-protobuf-sequence"],
341
+ );
342
+ return Number.isNaN(value) ? null : value;
343
+ };
344
+
50
345
  /* -----------------------------------------------------------
51
346
  VALIDATORS
52
347
  ----------------------------------------------------------- */
@@ -70,15 +365,13 @@ export namespace ProtobufFactory {
70
365
  }
71
366
  if (explore.object !== null && visited.has(explore.object) === false) {
72
367
  visited.add(explore.object);
73
- validateRegularObject({
368
+ validateObject({
74
369
  object: explore.object,
75
370
  errors,
76
371
  });
77
- for (const p of explore.object.properties)
78
- validateRegularProperty({
79
- value: p.value,
80
- errors,
81
- });
372
+ try {
373
+ emplaceObject(explore.object);
374
+ } catch {}
82
375
  }
83
376
 
84
377
  //----
@@ -259,10 +552,16 @@ export namespace ProtobufFactory {
259
552
  /* -----------------------------------------------------------
260
553
  SEQUENE VALIDATOR
261
554
  ----------------------------------------------------------- */
262
- const validateRegularObject = (next: {
555
+ const validateObject = (next: {
263
556
  object: MetadataObjectType;
264
557
  errors: string[];
265
558
  }): void => {
559
+ for (const property of next.object.properties)
560
+ validateProperty({
561
+ metadata: property.value,
562
+ errors: next.errors,
563
+ });
564
+
266
565
  const entire: Map<number, string> = new Map();
267
566
  const visitProperty = (p: MetadataProperty) => {
268
567
  const local: Set<number> = new Set();
@@ -289,8 +588,8 @@ export namespace ProtobufFactory {
289
588
  for (const p of next.object.properties) visitProperty(p);
290
589
  };
291
590
 
292
- const validateRegularProperty = (next: {
293
- value: Metadata;
591
+ const validateProperty = (next: {
592
+ metadata: Metadata;
294
593
  errors: string[];
295
594
  }): void => {
296
595
  let expected: number = 0;
@@ -316,29 +615,29 @@ export namespace ProtobufFactory {
316
615
  }),
317
616
  validateStringSequence,
318
617
  ])
319
- validator({ metadata: next.value, errors: next.errors, add });
320
- for (const array of next.value.arrays)
618
+ validator({ metadata: next.metadata, errors: next.errors, add });
619
+ for (const array of next.metadata.arrays)
321
620
  validateInstanceSequence({
322
621
  type: "array",
323
622
  tags: array.tags,
324
623
  errors: next.errors,
325
624
  add,
326
625
  });
327
- for (const object of next.value.objects)
626
+ for (const object of next.metadata.objects)
328
627
  validateInstanceSequence({
329
628
  type: "object",
330
629
  tags: object.tags,
331
630
  errors: next.errors,
332
631
  add,
333
632
  });
334
- for (const map of next.value.maps)
633
+ for (const map of next.metadata.maps)
335
634
  validateInstanceSequence({
336
635
  type: "map",
337
636
  tags: map.tags,
338
637
  errors: next.errors,
339
638
  add,
340
639
  });
341
- for (const native of next.value.natives)
640
+ for (const native of next.metadata.natives)
342
641
  if (native.name === "Uint8Array")
343
642
  validateInstanceSequence({
344
643
  type: "Uint8Array",
@@ -156,7 +156,7 @@ export namespace ProtobufUtil {
156
156
  for (const [key, value] of entries) map.set(key, value);
157
157
  };
158
158
 
159
- const compare = (x: ProtobufAtomic, y: ProtobufAtomic): number =>
159
+ export const compare = (x: ProtobufAtomic, y: ProtobufAtomic): number =>
160
160
  ATOMIC_ORDER.get(x)! - ATOMIC_ORDER.get(y)!;
161
161
  }
162
162