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