@macroforge/mcp-server 0.1.42 → 0.1.49

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 (71) hide show
  1. package/LICENSE +22 -0
  2. package/docs/BOOK.md +165 -0
  3. package/docs/api/api-overview.md +67 -48
  4. package/docs/api/expand-sync.md +88 -53
  5. package/docs/api/native-plugin.md +121 -71
  6. package/docs/api/position-mapper.md +115 -55
  7. package/docs/api/transform-sync.md +86 -60
  8. package/docs/builtin-macros/clone.md +0 -20
  9. package/docs/builtin-macros/debug.md +0 -23
  10. package/docs/builtin-macros/default.md +1 -40
  11. package/docs/builtin-macros/deserialize/example.md +8 -1416
  12. package/docs/builtin-macros/deserialize.md +8 -1416
  13. package/docs/builtin-macros/hash.md +0 -42
  14. package/docs/builtin-macros/macros-overview/detailed-documentation.md +13 -0
  15. package/docs/builtin-macros/macros-overview/enum-support.md +30 -0
  16. package/docs/builtin-macros/macros-overview/interface-support.md +28 -0
  17. package/docs/builtin-macros/macros-overview/overview.md +36 -0
  18. package/docs/builtin-macros/macros-overview/type-alias-support.md +62 -0
  19. package/docs/builtin-macros/macros-overview.md +171 -130
  20. package/docs/builtin-macros/ord.md +0 -25
  21. package/docs/builtin-macros/partial-eq.md +0 -84
  22. package/docs/builtin-macros/partial-ord.md +2 -32
  23. package/docs/builtin-macros/serialize.md +2 -62
  24. package/docs/concepts/architecture.md +125 -48
  25. package/docs/concepts/derive-system/built-in-vs-custom-macros.md +13 -0
  26. package/docs/concepts/derive-system/overview.md +200 -0
  27. package/docs/concepts/derive-system.md +157 -104
  28. package/docs/concepts/how-macros-work.md +98 -47
  29. package/docs/custom-macros/custom-overview.md +79 -57
  30. package/docs/custom-macros/rust-setup.md +138 -99
  31. package/docs/custom-macros/ts-macro-derive/accessing-field-data.md +40 -31
  32. package/docs/custom-macros/ts-macro-derive/adding-imports.md +14 -11
  33. package/docs/custom-macros/ts-macro-derive/attribute-options.md +20 -25
  34. package/docs/custom-macros/ts-macro-derive/complete-example.md +40 -38
  35. package/docs/custom-macros/ts-macro-derive/deriveinput-structure.md +49 -47
  36. package/docs/custom-macros/ts-macro-derive/function-signature.md +12 -0
  37. package/docs/custom-macros/ts-macro-derive/overview.md +9 -7
  38. package/docs/custom-macros/ts-macro-derive/parsing-input.md +20 -18
  39. package/docs/custom-macros/ts-macro-derive/returning-errors.md +15 -13
  40. package/docs/custom-macros/ts-macro-derive.md +322 -228
  41. package/docs/custom-macros/ts-quote/backtick-template-literals.md +19 -7
  42. package/docs/custom-macros/ts-quote/comments-and.md +56 -22
  43. package/docs/custom-macros/ts-quote/complete-example-json-derive-macro.md +89 -98
  44. package/docs/custom-macros/ts-quote/conditionals-ifif.md +35 -29
  45. package/docs/custom-macros/ts-quote/identifier-concatenation-content.md +30 -22
  46. package/docs/custom-macros/ts-quote/iteration-for.md +48 -40
  47. package/docs/custom-macros/ts-quote/local-constants-let.md +23 -21
  48. package/docs/custom-macros/ts-quote/match-expressions-match.md +46 -38
  49. package/docs/custom-macros/ts-quote/overview.md +5 -10
  50. package/docs/custom-macros/ts-quote/pattern-matching-iflet.md +39 -0
  51. package/docs/custom-macros/ts-quote/quick-reference.md +50 -129
  52. package/docs/custom-macros/ts-quote/side-effects-do.md +13 -78
  53. package/docs/custom-macros/ts-quote/string-interpolation-textexpr.md +36 -0
  54. package/docs/custom-macros/ts-quote/tsstream-injection-typescript.md +43 -35
  55. package/docs/custom-macros/ts-quote/while-loops-while.md +31 -23
  56. package/docs/custom-macros/ts-quote.md +800 -520
  57. package/docs/getting-started/first-macro.md +98 -71
  58. package/docs/getting-started/installation.md +109 -65
  59. package/docs/integration/cli.md +214 -105
  60. package/docs/integration/configuration.md +115 -72
  61. package/docs/integration/integration-overview.md +55 -18
  62. package/docs/integration/mcp-server.md +84 -43
  63. package/docs/integration/svelte-preprocessor.md +183 -126
  64. package/docs/integration/typescript-plugin.md +101 -53
  65. package/docs/integration/vite-plugin.md +116 -76
  66. package/docs/language-servers/ls-overview.md +37 -21
  67. package/docs/language-servers/svelte.md +69 -38
  68. package/docs/language-servers/zed.md +81 -44
  69. package/docs/roadmap/roadmap.md +75 -53
  70. package/docs/sections.json +333 -44
  71. package/package.json +27 -28
@@ -17,34 +17,6 @@ class User {
17
17
  ```
18
18
 
19
19
  ```typescript after
20
- class User {
21
- id: number;
22
-
23
- email: string;
24
-
25
- name: string;
26
-
27
- age?: number;
28
- }
29
- ```
30
-
31
- Generated output:
32
-
33
- ```typescript
34
- class User {
35
- id: number;
36
-
37
- email: string;
38
-
39
- name: string;
40
-
41
- age?: number;
42
- }
43
- ```
44
-
45
- Generated output:
46
-
47
- ```typescript
48
20
  import { DeserializeContext } from 'macroforge/serde';
49
21
  import { DeserializeError } from 'macroforge/serde';
50
22
  import type { DeserializeOptions } from 'macroforge/serde';
@@ -81,7 +53,7 @@ class User {
81
53
  */
82
54
  static deserialize(
83
55
  input: unknown,
84
- opts?: DeserializeOptions
56
+ opts?: @{DESERIALIZE_OPTIONS}
85
57
  ): Result<
86
58
  User,
87
59
  Array<{
@@ -93,9 +65,9 @@ class User {
93
65
  // Auto-detect: if string, parse as JSON first
94
66
  const data = typeof input === 'string' ? JSON.parse(input) : input;
95
67
 
96
- const ctx = DeserializeContext.create();
68
+ const ctx = @{DESERIALIZE_CONTEXT}.create();
97
69
  const resultOrRef = User.deserializeWithContext(data, ctx);
98
- if (PendingRef.is(resultOrRef)) {
70
+ if (@{PENDING_REF}.is(resultOrRef)) {
99
71
  return Result.err([
100
72
  {
101
73
  field: '_root',
@@ -109,7 +81,7 @@ class User {
109
81
  }
110
82
  return Result.ok(resultOrRef);
111
83
  } catch (e) {
112
- if (e instanceof DeserializeError) {
84
+ if (e instanceof @{DESERIALIZE_ERROR}) {
113
85
  return Result.err(e.errors);
114
86
  }
115
87
  const message = e instanceof Error ? e.message : String(e);
@@ -123,12 +95,12 @@ class User {
123
95
  }
124
96
 
125
97
  /** @internal */
126
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
98
+ static deserializeWithContext(value: any, ctx: @{DESERIALIZE_CONTEXT}): User | @{PENDING_REF} {
127
99
  if (value?.__ref !== undefined) {
128
100
  return ctx.getOrDefer(value.__ref);
129
101
  }
130
102
  if (typeof value !== 'object' || value === null || Array.isArray(value)) {
131
- throw new DeserializeError([
103
+ throw new @{DESERIALIZE_ERROR}([
132
104
  {
133
105
  field: '_root',
134
106
  message: 'User.deserializeWithContext: expected an object'
@@ -162,7 +134,7 @@ class User {
162
134
  });
163
135
  }
164
136
  if (errors.length > 0) {
165
- throw new DeserializeError(errors);
137
+ throw new @{DESERIALIZE_ERROR}(errors);
166
138
  }
167
139
  const instance = Object.create(User.prototype) as User;
168
140
  if (obj.__id !== undefined) {
@@ -188,1386 +160,7 @@ class User {
188
160
  instance.age = __raw_age;
189
161
  }
190
162
  if (errors.length > 0) {
191
- throw new DeserializeError(errors);
192
- }
193
- return instance;
194
- }
195
-
196
- static validateField<K extends keyof User>(
197
- field: K,
198
- value: User[K]
199
- ): Array<{
200
- field: string;
201
- message: string;
202
- }> {
203
- return [];
204
- }
205
-
206
- static validateFields(partial: Partial<User>): Array<{
207
- field: string;
208
- message: string;
209
- }> {
210
- return [];
211
- }
212
-
213
- static hasShape(obj: unknown): boolean {
214
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
215
- return false;
216
- }
217
- const o = obj as Record<string, unknown>;
218
- return 'id' in o && 'email' in o;
219
- }
220
-
221
- static is(obj: unknown): obj is User {
222
- if (obj instanceof User) {
223
- return true;
224
- }
225
- if (!User.hasShape(obj)) {
226
- return false;
227
- }
228
- const result = User.deserialize(obj);
229
- return Result.isOk(result);
230
- }
231
- }
232
-
233
- // Usage:
234
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
235
- if (Result.isOk(result)) {
236
- const user = result.value;
237
- } else {
238
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
239
- }
240
- ```
241
-
242
- Generated output:
243
-
244
- ```typescript
245
- import { DeserializeContext } from 'macroforge/serde';
246
- import { DeserializeError } from 'macroforge/serde';
247
- import type { DeserializeOptions } from 'macroforge/serde';
248
- import { PendingRef } from 'macroforge/serde';
249
-
250
- /** @serde({ denyUnknownFields: true }) */
251
- class User {
252
- id: number;
253
-
254
- email: string;
255
-
256
- name: string;
257
-
258
- age?: number;
259
-
260
- constructor(props: {
261
- id: number;
262
- email: string;
263
- name?: string;
264
- age?: number;
265
- }) {
266
- this.id = props.id;
267
- this.email = props.email;
268
- this.name = props.name as string;
269
- this.age = props.age as number;
270
- }
271
-
272
- /**
273
- * Deserializes input to an instance of this class.
274
- * Automatically detects whether input is a JSON string or object.
275
- * @param input - JSON string or object to deserialize
276
- * @param opts - Optional deserialization options
277
- * @returns Result containing the deserialized instance or validation errors
278
- */
279
- static deserialize(
280
- input: unknown,
281
- opts?: DeserializeOptions
282
- ): Result<
283
- User,
284
- Array<{
285
- field: string;
286
- message: string;
287
- }>
288
- > {
289
- try {
290
- // Auto-detect: if string, parse as JSON first
291
- const data = typeof input === 'string' ? JSON.parse(input) : input;
292
-
293
- const ctx = DeserializeContext.create();
294
- const resultOrRef = User.deserializeWithContext(data, ctx);
295
- if (PendingRef.is(resultOrRef)) {
296
- return Result.err([
297
- {
298
- field: '_root',
299
- message: 'User.deserialize: root cannot be a forward reference'
300
- }
301
- ]);
302
- }
303
- ctx.applyPatches();
304
- if (opts?.freeze) {
305
- ctx.freezeAll();
306
- }
307
- return Result.ok(resultOrRef);
308
- } catch (e) {
309
- if (e instanceof DeserializeError) {
310
- return Result.err(e.errors);
311
- }
312
- const message = e instanceof Error ? e.message : String(e);
313
- return Result.err([
314
- {
315
- field: '_root',
316
- message
317
- }
318
- ]);
319
- }
320
- }
321
-
322
- /** @internal */
323
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
324
- if (value?.__ref !== undefined) {
325
- return ctx.getOrDefer(value.__ref);
326
- }
327
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
328
- throw new DeserializeError([
329
- {
330
- field: '_root',
331
- message: 'User.deserializeWithContext: expected an object'
332
- }
333
- ]);
334
- }
335
- const obj = value as Record<string, unknown>;
336
- const errors: Array<{
337
- field: string;
338
- message: string;
339
- }> = [];
340
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
341
- for (const key of Object.keys(obj)) {
342
- if (!knownKeys.has(key)) {
343
- errors.push({
344
- field: key,
345
- message: 'unknown field'
346
- });
347
- }
348
- }
349
- if (!('id' in obj)) {
350
- errors.push({
351
- field: 'id',
352
- message: 'missing required field'
353
- });
354
- }
355
- if (!('email' in obj)) {
356
- errors.push({
357
- field: 'email',
358
- message: 'missing required field'
359
- });
360
- }
361
- if (errors.length > 0) {
362
- throw new DeserializeError(errors);
363
- }
364
- const instance = Object.create(User.prototype) as User;
365
- if (obj.__id !== undefined) {
366
- ctx.register(obj.__id as number, instance);
367
- }
368
- ctx.trackForFreeze(instance);
369
- {
370
- const __raw_id = obj['id'] as number;
371
- instance.id = __raw_id;
372
- }
373
- {
374
- const __raw_email = obj['email'] as string;
375
- instance.email = __raw_email;
376
- }
377
- if ('name' in obj && obj['name'] !== undefined) {
378
- const __raw_name = obj['name'] as string;
379
- instance.name = __raw_name;
380
- } else {
381
- instance.name = 'guest';
382
- }
383
- if ('age' in obj && obj['age'] !== undefined) {
384
- const __raw_age = obj['age'] as number;
385
- instance.age = __raw_age;
386
- }
387
- if (errors.length > 0) {
388
- throw new DeserializeError(errors);
389
- }
390
- return instance;
391
- }
392
-
393
- static validateField<K extends keyof User>(
394
- field: K,
395
- value: User[K]
396
- ): Array<{
397
- field: string;
398
- message: string;
399
- }> {
400
- return [];
401
- }
402
-
403
- static validateFields(partial: Partial<User>): Array<{
404
- field: string;
405
- message: string;
406
- }> {
407
- return [];
408
- }
409
-
410
- static hasShape(obj: unknown): boolean {
411
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
412
- return false;
413
- }
414
- const o = obj as Record<string, unknown>;
415
- return 'id' in o && 'email' in o;
416
- }
417
-
418
- static is(obj: unknown): obj is User {
419
- if (obj instanceof User) {
420
- return true;
421
- }
422
- if (!User.hasShape(obj)) {
423
- return false;
424
- }
425
- const result = User.deserialize(obj);
426
- return Result.isOk(result);
427
- }
428
- }
429
-
430
- // Usage:
431
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
432
- if (Result.isOk(result)) {
433
- const user = result.value;
434
- } else {
435
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
436
- }
437
- ```
438
-
439
- Generated output:
440
-
441
- ```typescript
442
- import { DeserializeContext } from 'macroforge/serde';
443
- import { DeserializeError } from 'macroforge/serde';
444
- import type { DeserializeOptions } from 'macroforge/serde';
445
- import { PendingRef } from 'macroforge/serde';
446
-
447
- /** @serde({ denyUnknownFields: true }) */
448
- class User {
449
- id: number;
450
-
451
- email: string;
452
-
453
- name: string;
454
-
455
- age?: number;
456
-
457
- constructor(props: {
458
- id: number;
459
- email: string;
460
- name?: string;
461
- age?: number;
462
- }) {
463
- this.id = props.id;
464
- this.email = props.email;
465
- this.name = props.name as string;
466
- this.age = props.age as number;
467
- }
468
-
469
- /**
470
- * Deserializes input to an instance of this class.
471
- * Automatically detects whether input is a JSON string or object.
472
- * @param input - JSON string or object to deserialize
473
- * @param opts - Optional deserialization options
474
- * @returns Result containing the deserialized instance or validation errors
475
- */
476
- static deserialize(
477
- input: unknown,
478
- opts?: DeserializeOptions
479
- ): Result<
480
- User,
481
- Array<{
482
- field: string;
483
- message: string;
484
- }>
485
- > {
486
- try {
487
- // Auto-detect: if string, parse as JSON first
488
- const data = typeof input === 'string' ? JSON.parse(input) : input;
489
-
490
- const ctx = DeserializeContext.create();
491
- const resultOrRef = User.deserializeWithContext(data, ctx);
492
- if (PendingRef.is(resultOrRef)) {
493
- return Result.err([
494
- {
495
- field: '_root',
496
- message: 'User.deserialize: root cannot be a forward reference'
497
- }
498
- ]);
499
- }
500
- ctx.applyPatches();
501
- if (opts?.freeze) {
502
- ctx.freezeAll();
503
- }
504
- return Result.ok(resultOrRef);
505
- } catch (e) {
506
- if (e instanceof DeserializeError) {
507
- return Result.err(e.errors);
508
- }
509
- const message = e instanceof Error ? e.message : String(e);
510
- return Result.err([
511
- {
512
- field: '_root',
513
- message
514
- }
515
- ]);
516
- }
517
- }
518
-
519
- /** @internal */
520
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
521
- if (value?.__ref !== undefined) {
522
- return ctx.getOrDefer(value.__ref);
523
- }
524
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
525
- throw new DeserializeError([
526
- {
527
- field: '_root',
528
- message: 'User.deserializeWithContext: expected an object'
529
- }
530
- ]);
531
- }
532
- const obj = value as Record<string, unknown>;
533
- const errors: Array<{
534
- field: string;
535
- message: string;
536
- }> = [];
537
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
538
- for (const key of Object.keys(obj)) {
539
- if (!knownKeys.has(key)) {
540
- errors.push({
541
- field: key,
542
- message: 'unknown field'
543
- });
544
- }
545
- }
546
- if (!('id' in obj)) {
547
- errors.push({
548
- field: 'id',
549
- message: 'missing required field'
550
- });
551
- }
552
- if (!('email' in obj)) {
553
- errors.push({
554
- field: 'email',
555
- message: 'missing required field'
556
- });
557
- }
558
- if (errors.length > 0) {
559
- throw new DeserializeError(errors);
560
- }
561
- const instance = Object.create(User.prototype) as User;
562
- if (obj.__id !== undefined) {
563
- ctx.register(obj.__id as number, instance);
564
- }
565
- ctx.trackForFreeze(instance);
566
- {
567
- const __raw_id = obj['id'] as number;
568
- instance.id = __raw_id;
569
- }
570
- {
571
- const __raw_email = obj['email'] as string;
572
- instance.email = __raw_email;
573
- }
574
- if ('name' in obj && obj['name'] !== undefined) {
575
- const __raw_name = obj['name'] as string;
576
- instance.name = __raw_name;
577
- } else {
578
- instance.name = "guest";
579
- }
580
- if ('age' in obj && obj['age'] !== undefined) {
581
- const __raw_age = obj['age'] as number;
582
- instance.age = __raw_age;
583
- }
584
- if (errors.length > 0) {
585
- throw new DeserializeError(errors);
586
- }
587
- return instance;
588
- }
589
-
590
- static validateField<K extends keyof User>(
591
- field: K,
592
- value: User[K]
593
- ): Array<{
594
- field: string;
595
- message: string;
596
- }> {
597
- return [];
598
- }
599
-
600
- static validateFields(partial: Partial<User>): Array<{
601
- field: string;
602
- message: string;
603
- }> {
604
- return [];
605
- }
606
-
607
- static hasShape(obj: unknown): boolean {
608
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
609
- return false;
610
- }
611
- const o = obj as Record<string, unknown>;
612
- return 'id' in o && 'email' in o;
613
- }
614
-
615
- static is(obj: unknown): obj is User {
616
- if (obj instanceof User) {
617
- return true;
618
- }
619
- if (!User.hasShape(obj)) {
620
- return false;
621
- }
622
- const result = User.deserialize(obj);
623
- return Result.isOk(result);
624
- }
625
- }
626
-
627
- // Usage:
628
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
629
- if (Result.isOk(result)) {
630
- const user = result.value;
631
- } else {
632
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
633
- }
634
- ```
635
-
636
- Generated output:
637
-
638
- ```typescript
639
- import { DeserializeContext } from 'macroforge/serde';
640
- import { DeserializeError } from 'macroforge/serde';
641
- import type { DeserializeOptions } from 'macroforge/serde';
642
- import { PendingRef } from 'macroforge/serde';
643
-
644
- /** @serde({ denyUnknownFields: true }) */
645
- class User {
646
- id: number;
647
-
648
- email: string;
649
-
650
- name: string;
651
-
652
- age?: number;
653
-
654
- constructor(props: {
655
- id: number;
656
- email: string;
657
- name?: string;
658
- age?: number;
659
- }) {
660
- this.id = props.id;
661
- this.email = props.email;
662
- this.name = props.name as string;
663
- this.age = props.age as number;
664
- }
665
-
666
- /**
667
- * Deserializes input to an instance of this class.
668
- * Automatically detects whether input is a JSON string or object.
669
- * @param input - JSON string or object to deserialize
670
- * @param opts - Optional deserialization options
671
- * @returns Result containing the deserialized instance or validation errors
672
- */
673
- static deserialize(
674
- input: unknown,
675
- opts?: DeserializeOptions
676
- ): Result<
677
- User,
678
- Array<{
679
- field: string;
680
- message: string;
681
- }>
682
- > {
683
- try {
684
- // Auto-detect: if string, parse as JSON first
685
- const data = typeof input === 'string' ? JSON.parse(input) : input;
686
-
687
- const ctx = DeserializeContext.create();
688
- const resultOrRef = User.deserializeWithContext(data, ctx);
689
- if (PendingRef.is(resultOrRef)) {
690
- return Result.err([
691
- {
692
- field: '_root',
693
- message: 'User.deserialize: root cannot be a forward reference'
694
- }
695
- ]);
696
- }
697
- ctx.applyPatches();
698
- if (opts?.freeze) {
699
- ctx.freezeAll();
700
- }
701
- return Result.ok(resultOrRef);
702
- } catch (e) {
703
- if (e instanceof DeserializeError) {
704
- return Result.err(e.errors);
705
- }
706
- const message = e instanceof Error ? e.message : String(e);
707
- return Result.err([
708
- {
709
- field: '_root',
710
- message
711
- }
712
- ]);
713
- }
714
- }
715
-
716
- /** @internal */
717
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
718
- if (value?.__ref !== undefined) {
719
- return ctx.getOrDefer(value.__ref);
720
- }
721
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
722
- throw new DeserializeError([
723
- {
724
- field: '_root',
725
- message: 'User.deserializeWithContext: expected an object'
726
- }
727
- ]);
728
- }
729
- const obj = value as Record<string, unknown>;
730
- const errors: Array<{
731
- field: string;
732
- message: string;
733
- }> = [];
734
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
735
- for (const key of Object.keys(obj)) {
736
- if (!knownKeys.has(key)) {
737
- errors.push({
738
- field: key,
739
- message: 'unknown field'
740
- });
741
- }
742
- }
743
- if (!('id' in obj)) {
744
- errors.push({
745
- field: 'id',
746
- message: 'missing required field'
747
- });
748
- }
749
- if (!('email' in obj)) {
750
- errors.push({
751
- field: 'email',
752
- message: 'missing required field'
753
- });
754
- }
755
- if (errors.length > 0) {
756
- throw new DeserializeError(errors);
757
- }
758
- const instance = Object.create(User.prototype) as User;
759
- if (obj.__id !== undefined) {
760
- ctx.register(obj.__id as number, instance);
761
- }
762
- ctx.trackForFreeze(instance);
763
- {
764
- const __raw_id = obj['id'] as number;
765
- instance.id = __raw_id;
766
- }
767
- {
768
- const __raw_email = obj['email'] as string;
769
- instance.email = __raw_email;
770
- }
771
- if ('name' in obj && obj['name'] !== undefined) {
772
- const __raw_name = obj['name'] as string;
773
- instance.name = __raw_name;
774
- } else {
775
- instance.name = 'guest';
776
- }
777
- if ('age' in obj && obj['age'] !== undefined) {
778
- const __raw_age = obj['age'] as number;
779
- instance.age = __raw_age;
780
- }
781
- if (errors.length > 0) {
782
- throw new DeserializeError(errors);
783
- }
784
- return instance;
785
- }
786
-
787
- static validateField<K extends keyof User>(
788
- field: K,
789
- value: User[K]
790
- ): Array<{
791
- field: string;
792
- message: string;
793
- }> {
794
- return [];
795
- }
796
-
797
- static validateFields(partial: Partial<User>): Array<{
798
- field: string;
799
- message: string;
800
- }> {
801
- return [];
802
- }
803
-
804
- static hasShape(obj: unknown): boolean {
805
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
806
- return false;
807
- }
808
- const o = obj as Record<string, unknown>;
809
- return 'id' in o && 'email' in o;
810
- }
811
-
812
- static is(obj: unknown): obj is User {
813
- if (obj instanceof User) {
814
- return true;
815
- }
816
- if (!User.hasShape(obj)) {
817
- return false;
818
- }
819
- const result = User.deserialize(obj);
820
- return Result.isOk(result);
821
- }
822
- }
823
-
824
- // Usage:
825
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
826
- if (Result.isOk(result)) {
827
- const user = result.value;
828
- } else {
829
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
830
- }
831
- ```
832
-
833
- Generated output:
834
-
835
- ```typescript
836
- import { DeserializeContext } from 'macroforge/serde';
837
- import { DeserializeError } from 'macroforge/serde';
838
- import type { DeserializeOptions } from 'macroforge/serde';
839
- import { PendingRef } from 'macroforge/serde';
840
-
841
- /** @serde({ denyUnknownFields: true }) */
842
- class User {
843
- id: number;
844
-
845
- email: string;
846
-
847
- name: string;
848
-
849
- age?: number;
850
-
851
- constructor(props: {
852
- id: number;
853
- email: string;
854
- name?: string;
855
- age?: number;
856
- }) {
857
- this.id = props.id;
858
- this.email = props.email;
859
- this.name = props.name as string;
860
- this.age = props.age as number;
861
- }
862
-
863
- /**
864
- * Deserializes input to an instance of this class.
865
- * Automatically detects whether input is a JSON string or object.
866
- * @param input - JSON string or object to deserialize
867
- * @param opts - Optional deserialization options
868
- * @returns Result containing the deserialized instance or validation errors
869
- */
870
- static deserialize(
871
- input: unknown,
872
- opts?: DeserializeOptions
873
- ): Result<
874
- User,
875
- Array<{
876
- field: string;
877
- message: string;
878
- }>
879
- > {
880
- try {
881
- // Auto-detect: if string, parse as JSON first
882
- const data = typeof input === 'string' ? JSON.parse(input) : input;
883
-
884
- const ctx = DeserializeContext.create();
885
- const resultOrRef = User.deserializeWithContext(data, ctx);
886
- if (PendingRef.is(resultOrRef)) {
887
- return Result.err([
888
- {
889
- field: '_root',
890
- message: 'User.deserialize: root cannot be a forward reference'
891
- }
892
- ]);
893
- }
894
- ctx.applyPatches();
895
- if (opts?.freeze) {
896
- ctx.freezeAll();
897
- }
898
- return Result.ok(resultOrRef);
899
- } catch (e) {
900
- if (e instanceof DeserializeError) {
901
- return Result.err(e.errors);
902
- }
903
- const message = e instanceof Error ? e.message : String(e);
904
- return Result.err([
905
- {
906
- field: '_root',
907
- message
908
- }
909
- ]);
910
- }
911
- }
912
-
913
- /** @internal */
914
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
915
- if (value?.__ref !== undefined) {
916
- return ctx.getOrDefer(value.__ref);
917
- }
918
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
919
- throw new DeserializeError([
920
- {
921
- field: '_root',
922
- message: 'User.deserializeWithContext: expected an object'
923
- }
924
- ]);
925
- }
926
- const obj = value as Record<string, unknown>;
927
- const errors: Array<{
928
- field: string;
929
- message: string;
930
- }> = [];
931
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
932
- for (const key of Object.keys(obj)) {
933
- if (!knownKeys.has(key)) {
934
- errors.push({
935
- field: key,
936
- message: 'unknown field'
937
- });
938
- }
939
- }
940
- if (!('id' in obj)) {
941
- errors.push({
942
- field: 'id',
943
- message: 'missing required field'
944
- });
945
- }
946
- if (!('email' in obj)) {
947
- errors.push({
948
- field: 'email',
949
- message: 'missing required field'
950
- });
951
- }
952
- if (errors.length > 0) {
953
- throw new DeserializeError(errors);
954
- }
955
- const instance = Object.create(User.prototype) as User;
956
- if (obj.__id !== undefined) {
957
- ctx.register(obj.__id as number, instance);
958
- }
959
- ctx.trackForFreeze(instance);
960
- {
961
- const __raw_id = obj['id'] as number;
962
- instance.id = __raw_id;
963
- }
964
- {
965
- const __raw_email = obj['email'] as string;
966
- instance.email = __raw_email;
967
- }
968
- if ('name' in obj && obj['name'] !== undefined) {
969
- const __raw_name = obj['name'] as string;
970
- instance.name = __raw_name;
971
- } else {
972
- instance.name = "guest";
973
- }
974
- if ('age' in obj && obj['age'] !== undefined) {
975
- const __raw_age = obj['age'] as number;
976
- instance.age = __raw_age;
977
- }
978
- if (errors.length > 0) {
979
- throw new DeserializeError(errors);
980
- }
981
- return instance;
982
- }
983
-
984
- static validateField<K extends keyof User>(
985
- field: K,
986
- value: User[K]
987
- ): Array<{
988
- field: string;
989
- message: string;
990
- }> {
991
- return [];
992
- }
993
-
994
- static validateFields(partial: Partial<User>): Array<{
995
- field: string;
996
- message: string;
997
- }> {
998
- return [];
999
- }
1000
-
1001
- static hasShape(obj: unknown): boolean {
1002
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
1003
- return false;
1004
- }
1005
- const o = obj as Record<string, unknown>;
1006
- return 'id' in o && 'email' in o;
1007
- }
1008
-
1009
- static is(obj: unknown): obj is User {
1010
- if (obj instanceof User) {
1011
- return true;
1012
- }
1013
- if (!User.hasShape(obj)) {
1014
- return false;
1015
- }
1016
- const result = User.deserialize(obj);
1017
- return Result.isOk(result);
1018
- }
1019
- }
1020
-
1021
- // Usage:
1022
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
1023
- if (Result.isOk(result)) {
1024
- const user = result.value;
1025
- } else {
1026
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
1027
- }
1028
- ```
1029
-
1030
- Generated output:
1031
-
1032
- ```typescript
1033
- import { DeserializeContext } from 'macroforge/serde';
1034
- import { DeserializeError } from 'macroforge/serde';
1035
- import type { DeserializeOptions } from 'macroforge/serde';
1036
- import { PendingRef } from 'macroforge/serde';
1037
-
1038
- /** @serde({ denyUnknownFields: true }) */
1039
- class User {
1040
- id: number;
1041
-
1042
- email: string;
1043
-
1044
- name: string;
1045
-
1046
- age?: number;
1047
-
1048
- constructor(props: {
1049
- id: number;
1050
- email: string;
1051
- name?: string;
1052
- age?: number;
1053
- }) {
1054
- this.id = props.id;
1055
- this.email = props.email;
1056
- this.name = props.name as string;
1057
- this.age = props.age as number;
1058
- }
1059
-
1060
- /**
1061
- * Deserializes input to an instance of this class.
1062
- * Automatically detects whether input is a JSON string or object.
1063
- * @param input - JSON string or object to deserialize
1064
- * @param opts - Optional deserialization options
1065
- * @returns Result containing the deserialized instance or validation errors
1066
- */
1067
- static deserialize(
1068
- input: unknown,
1069
- opts?: DeserializeOptions
1070
- ): Result<
1071
- User,
1072
- Array<{
1073
- field: string;
1074
- message: string;
1075
- }>
1076
- > {
1077
- try {
1078
- // Auto-detect: if string, parse as JSON first
1079
- const data = typeof input === 'string' ? JSON.parse(input) : input;
1080
-
1081
- const ctx = DeserializeContext.create();
1082
- const resultOrRef = User.deserializeWithContext(data, ctx);
1083
- if (PendingRef.is(resultOrRef)) {
1084
- return Result.err([
1085
- {
1086
- field: '_root',
1087
- message: 'User.deserialize: root cannot be a forward reference'
1088
- }
1089
- ]);
1090
- }
1091
- ctx.applyPatches();
1092
- if (opts?.freeze) {
1093
- ctx.freezeAll();
1094
- }
1095
- return Result.ok(resultOrRef);
1096
- } catch (e) {
1097
- if (e instanceof DeserializeError) {
1098
- return Result.err(e.errors);
1099
- }
1100
- const message = e instanceof Error ? e.message : String(e);
1101
- return Result.err([
1102
- {
1103
- field: '_root',
1104
- message
1105
- }
1106
- ]);
1107
- }
1108
- }
1109
-
1110
- /** @internal */
1111
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
1112
- if (value?.__ref !== undefined) {
1113
- return ctx.getOrDefer(value.__ref);
1114
- }
1115
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
1116
- throw new DeserializeError([
1117
- {
1118
- field: '_root',
1119
- message: 'User.deserializeWithContext: expected an object'
1120
- }
1121
- ]);
1122
- }
1123
- const obj = value as Record<string, unknown>;
1124
- const errors: Array<{
1125
- field: string;
1126
- message: string;
1127
- }> = [];
1128
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
1129
- for (const key of Object.keys(obj)) {
1130
- if (!knownKeys.has(key)) {
1131
- errors.push({
1132
- field: key,
1133
- message: 'unknown field'
1134
- });
1135
- }
1136
- }
1137
- if (!('id' in obj)) {
1138
- errors.push({
1139
- field: 'id',
1140
- message: 'missing required field'
1141
- });
1142
- }
1143
- if (!('email' in obj)) {
1144
- errors.push({
1145
- field: 'email',
1146
- message: 'missing required field'
1147
- });
1148
- }
1149
- if (errors.length > 0) {
1150
- throw new DeserializeError(errors);
1151
- }
1152
- const instance = Object.create(User.prototype) as User;
1153
- if (obj.__id !== undefined) {
1154
- ctx.register(obj.__id as number, instance);
1155
- }
1156
- ctx.trackForFreeze(instance);
1157
- {
1158
- const __raw_id = obj['id'] as number;
1159
- instance.id = __raw_id;
1160
- }
1161
- {
1162
- const __raw_email = obj['email'] as string;
1163
- instance.email = __raw_email;
1164
- }
1165
- if ('name' in obj && obj['name'] !== undefined) {
1166
- const __raw_name = obj['name'] as string;
1167
- instance.name = __raw_name;
1168
- } else {
1169
- instance.name = 'guest';
1170
- }
1171
- if ('age' in obj && obj['age'] !== undefined) {
1172
- const __raw_age = obj['age'] as number;
1173
- instance.age = __raw_age;
1174
- }
1175
- if (errors.length > 0) {
1176
- throw new DeserializeError(errors);
1177
- }
1178
- return instance;
1179
- }
1180
-
1181
- static validateField<K extends keyof User>(
1182
- field: K,
1183
- value: User[K]
1184
- ): Array<{
1185
- field: string;
1186
- message: string;
1187
- }> {
1188
- return [];
1189
- }
1190
-
1191
- static validateFields(partial: Partial<User>): Array<{
1192
- field: string;
1193
- message: string;
1194
- }> {
1195
- return [];
1196
- }
1197
-
1198
- static hasShape(obj: unknown): boolean {
1199
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
1200
- return false;
1201
- }
1202
- const o = obj as Record<string, unknown>;
1203
- return 'id' in o && 'email' in o;
1204
- }
1205
-
1206
- static is(obj: unknown): obj is User {
1207
- if (obj instanceof User) {
1208
- return true;
1209
- }
1210
- if (!User.hasShape(obj)) {
1211
- return false;
1212
- }
1213
- const result = User.deserialize(obj);
1214
- return Result.isOk(result);
1215
- }
1216
- }
1217
-
1218
- // Usage:
1219
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
1220
- if (Result.isOk(result)) {
1221
- const user = result.value;
1222
- } else {
1223
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
1224
- }
1225
- ```
1226
-
1227
- Generated output:
1228
-
1229
- ```typescript
1230
- import { DeserializeContext } from 'macroforge/serde';
1231
- import { DeserializeError } from 'macroforge/serde';
1232
- import type { DeserializeOptions } from 'macroforge/serde';
1233
- import { PendingRef } from 'macroforge/serde';
1234
-
1235
- /** @serde({ denyUnknownFields: true }) */
1236
- class User {
1237
- id: number;
1238
-
1239
- email: string;
1240
-
1241
- name: string;
1242
-
1243
- age?: number;
1244
-
1245
- constructor(props: {
1246
- id: number;
1247
- email: string;
1248
- name?: string;
1249
- age?: number;
1250
- }) {
1251
- this.id = props.id;
1252
- this.email = props.email;
1253
- this.name = props.name as string;
1254
- this.age = props.age as number;
1255
- }
1256
-
1257
- /**
1258
- * Deserializes input to an instance of this class.
1259
- * Automatically detects whether input is a JSON string or object.
1260
- * @param input - JSON string or object to deserialize
1261
- * @param opts - Optional deserialization options
1262
- * @returns Result containing the deserialized instance or validation errors
1263
- */
1264
- static deserialize(
1265
- input: unknown,
1266
- opts?: DeserializeOptions
1267
- ): Result<
1268
- User,
1269
- Array<{
1270
- field: string;
1271
- message: string;
1272
- }>
1273
- > {
1274
- try {
1275
- // Auto-detect: if string, parse as JSON first
1276
- const data = typeof input === 'string' ? JSON.parse(input) : input;
1277
-
1278
- const ctx = DeserializeContext.create();
1279
- const resultOrRef = User.deserializeWithContext(data, ctx);
1280
- if (PendingRef.is(resultOrRef)) {
1281
- return Result.err([
1282
- {
1283
- field: '_root',
1284
- message: 'User.deserialize: root cannot be a forward reference'
1285
- }
1286
- ]);
1287
- }
1288
- ctx.applyPatches();
1289
- if (opts?.freeze) {
1290
- ctx.freezeAll();
1291
- }
1292
- return Result.ok(resultOrRef);
1293
- } catch (e) {
1294
- if (e instanceof DeserializeError) {
1295
- return Result.err(e.errors);
1296
- }
1297
- const message = e instanceof Error ? e.message : String(e);
1298
- return Result.err([
1299
- {
1300
- field: '_root',
1301
- message
1302
- }
1303
- ]);
1304
- }
1305
- }
1306
-
1307
- /** @internal */
1308
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
1309
- if (value?.__ref !== undefined) {
1310
- return ctx.getOrDefer(value.__ref);
1311
- }
1312
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
1313
- throw new DeserializeError([
1314
- {
1315
- field: '_root',
1316
- message: 'User.deserializeWithContext: expected an object'
1317
- }
1318
- ]);
1319
- }
1320
- const obj = value as Record<string, unknown>;
1321
- const errors: Array<{
1322
- field: string;
1323
- message: string;
1324
- }> = [];
1325
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
1326
- for (const key of Object.keys(obj)) {
1327
- if (!knownKeys.has(key)) {
1328
- errors.push({
1329
- field: key,
1330
- message: 'unknown field'
1331
- });
1332
- }
1333
- }
1334
- if (!('id' in obj)) {
1335
- errors.push({
1336
- field: 'id',
1337
- message: 'missing required field'
1338
- });
1339
- }
1340
- if (!('email' in obj)) {
1341
- errors.push({
1342
- field: 'email',
1343
- message: 'missing required field'
1344
- });
1345
- }
1346
- if (errors.length > 0) {
1347
- throw new DeserializeError(errors);
1348
- }
1349
- const instance = Object.create(User.prototype) as User;
1350
- if (obj.__id !== undefined) {
1351
- ctx.register(obj.__id as number, instance);
1352
- }
1353
- ctx.trackForFreeze(instance);
1354
- {
1355
- const __raw_id = obj['id'] as number;
1356
- instance.id = __raw_id;
1357
- }
1358
- {
1359
- const __raw_email = obj['email'] as string;
1360
- instance.email = __raw_email;
1361
- }
1362
- if ('name' in obj && obj['name'] !== undefined) {
1363
- const __raw_name = obj['name'] as string;
1364
- instance.name = __raw_name;
1365
- } else {
1366
- instance.name = 'guest';
1367
- }
1368
- if ('age' in obj && obj['age'] !== undefined) {
1369
- const __raw_age = obj['age'] as number;
1370
- instance.age = __raw_age;
1371
- }
1372
- if (errors.length > 0) {
1373
- throw new DeserializeError(errors);
1374
- }
1375
- return instance;
1376
- }
1377
-
1378
- static validateField<K extends keyof User>(
1379
- field: K,
1380
- value: User[K]
1381
- ): Array<{
1382
- field: string;
1383
- message: string;
1384
- }> {
1385
- return [];
1386
- }
1387
-
1388
- static validateFields(partial: Partial<User>): Array<{
1389
- field: string;
1390
- message: string;
1391
- }> {
1392
- return [];
1393
- }
1394
-
1395
- static hasShape(obj: unknown): boolean {
1396
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
1397
- return false;
1398
- }
1399
- const o = obj as Record<string, unknown>;
1400
- return 'id' in o && 'email' in o;
1401
- }
1402
-
1403
- static is(obj: unknown): obj is User {
1404
- if (obj instanceof User) {
1405
- return true;
1406
- }
1407
- if (!User.hasShape(obj)) {
1408
- return false;
1409
- }
1410
- const result = User.deserialize(obj);
1411
- return Result.isOk(result);
1412
- }
1413
- }
1414
-
1415
- // Usage:
1416
- const result = User.deserialize('{"id":1,"email":"test@example.com"}');
1417
- if (Result.isOk(result)) {
1418
- const user = result.value;
1419
- } else {
1420
- console.error(result.error); // [{ field: "email", message: "must be a valid email" }]
1421
- }
1422
- ```
1423
-
1424
- Generated output:
1425
-
1426
- ```typescript
1427
- import { DeserializeContext } from 'macroforge/serde';
1428
- import { DeserializeError } from 'macroforge/serde';
1429
- import type { DeserializeOptions } from 'macroforge/serde';
1430
- import { PendingRef } from 'macroforge/serde';
1431
-
1432
- /** @serde({ denyUnknownFields: true }) */
1433
- class User {
1434
- id: number;
1435
-
1436
- email: string;
1437
-
1438
- name: string;
1439
-
1440
- age?: number;
1441
-
1442
- constructor(props: {
1443
- id: number;
1444
- email: string;
1445
- name?: string;
1446
- age?: number;
1447
- }) {
1448
- this.id = props.id;
1449
- this.email = props.email;
1450
- this.name = props.name as string;
1451
- this.age = props.age as number;
1452
- }
1453
-
1454
- /**
1455
- * Deserializes input to an instance of this class.
1456
- * Automatically detects whether input is a JSON string or object.
1457
- * @param input - JSON string or object to deserialize
1458
- * @param opts - Optional deserialization options
1459
- * @returns Result containing the deserialized instance or validation errors
1460
- */
1461
- static deserialize(
1462
- input: unknown,
1463
- opts?: DeserializeOptions
1464
- ): Result<
1465
- User,
1466
- Array<{
1467
- field: string;
1468
- message: string;
1469
- }>
1470
- > {
1471
- try {
1472
- // Auto-detect: if string, parse as JSON first
1473
- const data = typeof input === 'string' ? JSON.parse(input) : input;
1474
-
1475
- const ctx = DeserializeContext.create();
1476
- const resultOrRef = User.deserializeWithContext(data, ctx);
1477
- if (PendingRef.is(resultOrRef)) {
1478
- return Result.err([
1479
- {
1480
- field: '_root',
1481
- message: 'User.deserialize: root cannot be a forward reference'
1482
- }
1483
- ]);
1484
- }
1485
- ctx.applyPatches();
1486
- if (opts?.freeze) {
1487
- ctx.freezeAll();
1488
- }
1489
- return Result.ok(resultOrRef);
1490
- } catch (e) {
1491
- if (e instanceof DeserializeError) {
1492
- return Result.err(e.errors);
1493
- }
1494
- const message = e instanceof Error ? e.message : String(e);
1495
- return Result.err([
1496
- {
1497
- field: '_root',
1498
- message
1499
- }
1500
- ]);
1501
- }
1502
- }
1503
-
1504
- /** @internal */
1505
- static deserializeWithContext(value: any, ctx: DeserializeContext): User | PendingRef {
1506
- if (value?.__ref !== undefined) {
1507
- return ctx.getOrDefer(value.__ref);
1508
- }
1509
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
1510
- throw new DeserializeError([
1511
- {
1512
- field: '_root',
1513
- message: 'User.deserializeWithContext: expected an object'
1514
- }
1515
- ]);
1516
- }
1517
- const obj = value as Record<string, unknown>;
1518
- const errors: Array<{
1519
- field: string;
1520
- message: string;
1521
- }> = [];
1522
- const knownKeys = new Set(['__type', '__id', '__ref', 'id', 'email', 'name', 'age']);
1523
- for (const key of Object.keys(obj)) {
1524
- if (!knownKeys.has(key)) {
1525
- errors.push({
1526
- field: key,
1527
- message: 'unknown field'
1528
- });
1529
- }
1530
- }
1531
- if (!('id' in obj)) {
1532
- errors.push({
1533
- field: 'id',
1534
- message: 'missing required field'
1535
- });
1536
- }
1537
- if (!('email' in obj)) {
1538
- errors.push({
1539
- field: 'email',
1540
- message: 'missing required field'
1541
- });
1542
- }
1543
- if (errors.length > 0) {
1544
- throw new DeserializeError(errors);
1545
- }
1546
- const instance = Object.create(User.prototype) as User;
1547
- if (obj.__id !== undefined) {
1548
- ctx.register(obj.__id as number, instance);
1549
- }
1550
- ctx.trackForFreeze(instance);
1551
- {
1552
- const __raw_id = obj['id'] as number;
1553
- instance.id = __raw_id;
1554
- }
1555
- {
1556
- const __raw_email = obj['email'] as string;
1557
- instance.email = __raw_email;
1558
- }
1559
- if ('name' in obj && obj['name'] !== undefined) {
1560
- const __raw_name = obj['name'] as string;
1561
- instance.name = __raw_name;
1562
- } else {
1563
- instance.name = 'guest';
1564
- }
1565
- if ('age' in obj && obj['age'] !== undefined) {
1566
- const __raw_age = obj['age'] as number;
1567
- instance.age = __raw_age;
1568
- }
1569
- if (errors.length > 0) {
1570
- throw new DeserializeError(errors);
163
+ throw new @{DESERIALIZE_ERROR}(errors);
1571
164
  }
1572
165
  return instance;
1573
166
  }
@@ -1621,5 +214,4 @@ if (Result.isOk(result)) {
1621
214
  ## Required Imports
1622
215
 
1623
216
  The generated code automatically imports:
1624
- - `Result` from `macroforge/utils`
1625
217
  - `DeserializeContext`, `DeserializeError`, `PendingRef` from `macroforge/serde`