@macroforge/mcp-server 0.1.65 → 0.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/docs-loader.d.ts.map +1 -1
- package/dist/tools/docs-loader.js +1 -1
- package/dist/tools/docs-loader.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +84 -85
- package/dist/tools/index.js.map +1 -1
- package/docs/BOOK.md +8 -33
- package/docs/api/api-overview.md +4 -4
- package/docs/api/expand-sync.md +3 -2
- package/docs/api/native-plugin.md +5 -2
- package/docs/api/position-mapper.md +7 -4
- package/docs/api/transform-sync.md +7 -5
- package/docs/builtin-macros/deserialize/all-options.md +7 -21
- package/docs/builtin-macros/deserialize/combining-with-serialize.md +7 -5
- package/docs/builtin-macros/deserialize/enum-support.md +8 -6
- package/docs/builtin-macros/deserialize/error-handling.md +10 -9
- package/docs/builtin-macros/deserialize/interface-support.md +9 -4
- package/docs/builtin-macros/deserialize/runtime-validation.md +10 -21
- package/docs/builtin-macros/deserialize/serde-options.md +19 -31
- package/docs/builtin-macros/deserialize/type-alias-support.md +7 -6
- package/docs/builtin-macros/macros-overview/detailed-documentation.md +9 -9
- package/docs/builtin-macros/macros-overview/enum-support.md +3 -2
- package/docs/builtin-macros/macros-overview/interface-support.md +3 -2
- package/docs/builtin-macros/macros-overview/overview.md +13 -12
- package/docs/builtin-macros/macros-overview/type-alias-support.md +3 -2
- package/docs/builtin-macros/macros-overview.md +27 -23
- package/docs/builtin-macros/partial-eq/example.md +188 -232
- package/docs/builtin-macros/partial-eq/overview.md +18 -18
- package/docs/builtin-macros/serialize/example.md +11 -3
- package/docs/builtin-macros/serialize/overview.md +12 -11
- package/docs/builtin-macros/serialize/type-specific-serialization.md +12 -12
- package/docs/concepts/architecture.md +23 -22
- package/docs/concepts/derive-system/built-in-vs-custom-macros.md +4 -3
- package/docs/concepts/derive-system/overview.md +27 -24
- package/docs/concepts/derive-system.md +31 -27
- package/docs/concepts/how-macros-work.md +23 -21
- package/docs/custom-macros/custom-overview.md +9 -8
- package/docs/custom-macros/rust-setup.md +11 -10
- package/docs/custom-macros/ts-macro-derive/accessing-field-data.md +2 -1
- package/docs/custom-macros/ts-macro-derive/adding-imports.md +2 -1
- package/docs/custom-macros/ts-macro-derive/attribute-options.md +1 -1
- package/docs/custom-macros/ts-macro-derive/complete-example.md +1 -1
- package/docs/custom-macros/ts-macro-derive/deriveinput-structure.md +1 -1
- package/docs/custom-macros/ts-macro-derive/function-signature.md +1 -1
- package/docs/custom-macros/ts-macro-derive/overview.md +3 -2
- package/docs/custom-macros/ts-macro-derive/parsing-input.md +1 -1
- package/docs/custom-macros/ts-macro-derive/returning-errors.md +1 -1
- package/docs/custom-macros/ts-macro-derive.md +7 -4
- package/docs/custom-macros/ts-quote/backtick-template-literals.md +5 -3
- package/docs/custom-macros/ts-quote/comments-and.md +3 -2
- package/docs/custom-macros/ts-quote/complete-example-json-derive-macro.md +12 -11
- package/docs/custom-macros/ts-quote/conditionals-ifif.md +1 -1
- package/docs/custom-macros/ts-quote/identifier-concatenation-content.md +5 -3
- package/docs/custom-macros/ts-quote/interpolation-expr.md +18 -11
- package/docs/custom-macros/ts-quote/iteration-for.md +1 -1
- package/docs/custom-macros/ts-quote/local-constants-let.md +1 -1
- package/docs/custom-macros/ts-quote/match-expressions-match.md +1 -1
- package/docs/custom-macros/ts-quote/overview.md +4 -2
- package/docs/custom-macros/ts-quote/pattern-matching-if-let.md +2 -2
- package/docs/custom-macros/ts-quote/pattern-matching-iflet.md +1 -1
- package/docs/custom-macros/ts-quote/quick-reference.md +24 -23
- package/docs/custom-macros/ts-quote/side-effects-do.md +6 -5
- package/docs/custom-macros/ts-quote/string-interpolation-text-expr.md +3 -3
- package/docs/custom-macros/ts-quote/string-interpolation-textexpr.md +1 -1
- package/docs/custom-macros/ts-quote/tsstream-injection-typescript.md +3 -2
- package/docs/custom-macros/ts-quote/while-loops-while.md +1 -1
- package/docs/custom-macros/ts-quote.md +30 -19
- package/docs/getting-started/first-macro.md +5 -4
- package/docs/getting-started/installation.md +20 -17
- package/docs/integration/cli.md +11 -5
- package/docs/integration/configuration.md +7 -9
- package/docs/integration/integration-overview.md +5 -5
- package/docs/integration/mcp-server.md +17 -8
- package/docs/integration/svelte-preprocessor.md +18 -14
- package/docs/integration/typescript-plugin.md +14 -12
- package/docs/integration/vite-plugin.md +13 -11
- package/docs/language-servers/ls-overview.md +18 -12
- package/docs/language-servers/svelte-ls.md +9 -11
- package/docs/language-servers/svelte.md +18 -17
- package/docs/language-servers/zed-extensions.md +14 -11
- package/docs/language-servers/zed.md +19 -13
- package/docs/roadmap/roadmap.md +8 -6
- package/package.json +5 -5
package/docs/BOOK.md
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
# Macroforge Documentation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
_TypeScript Macros - Rust-Powered Code Generation_
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
9
|
### Getting Started
|
|
10
|
+
|
|
10
11
|
- [Installation](#installation)
|
|
11
12
|
- [First Macro](#first-macro)
|
|
12
13
|
|
|
13
14
|
### Core Concepts
|
|
15
|
+
|
|
14
16
|
- [How Macros Work](#how-macros-work)
|
|
15
17
|
- [The Derive System](#the-derive-system)
|
|
16
18
|
- [Architecture](#architecture)
|
|
17
19
|
|
|
18
20
|
### Built-in Macros
|
|
21
|
+
|
|
19
22
|
- [Overview](#overview)
|
|
20
23
|
- [Debug](#debug)
|
|
21
24
|
- [Clone](#clone)
|
|
@@ -28,12 +31,14 @@
|
|
|
28
31
|
- [Deserialize](#deserialize)
|
|
29
32
|
|
|
30
33
|
### Custom Macros
|
|
34
|
+
|
|
31
35
|
- [Overview](#overview)
|
|
32
36
|
- [Rust Setup](#rust-setup)
|
|
33
37
|
- [ts_macro_derive](#ts-macro-derive)
|
|
34
38
|
- [Template Syntax](#template-syntax)
|
|
35
39
|
|
|
36
40
|
### Integration
|
|
41
|
+
|
|
37
42
|
- [Overview](#overview)
|
|
38
43
|
- [CLI](#cli)
|
|
39
44
|
- [TypeScript Plugin](#typescript-plugin)
|
|
@@ -41,11 +46,13 @@
|
|
|
41
46
|
- [Configuration](#configuration)
|
|
42
47
|
|
|
43
48
|
### Language Servers
|
|
49
|
+
|
|
44
50
|
- [Overview](#overview)
|
|
45
51
|
- [Svelte](#svelte)
|
|
46
52
|
- [Zed Extensions](#zed-extensions)
|
|
47
53
|
|
|
48
54
|
### API Reference
|
|
55
|
+
|
|
49
56
|
- [Overview](#overview)
|
|
50
57
|
- [expandSync()](#expandsync)
|
|
51
58
|
- [transformSync()](#transformsync)
|
|
@@ -56,110 +63,78 @@
|
|
|
56
63
|
|
|
57
64
|
# Getting Started
|
|
58
65
|
|
|
59
|
-
|
|
60
66
|
---
|
|
61
67
|
|
|
62
|
-
|
|
63
68
|
---
|
|
64
69
|
|
|
65
70
|
# Core Concepts
|
|
66
71
|
|
|
67
|
-
|
|
68
72
|
---
|
|
69
73
|
|
|
70
|
-
|
|
71
74
|
---
|
|
72
75
|
|
|
73
|
-
|
|
74
76
|
---
|
|
75
77
|
|
|
76
78
|
# Built-in Macros
|
|
77
79
|
|
|
78
|
-
|
|
79
80
|
---
|
|
80
81
|
|
|
81
|
-
|
|
82
82
|
---
|
|
83
83
|
|
|
84
|
-
|
|
85
84
|
---
|
|
86
85
|
|
|
87
|
-
|
|
88
86
|
---
|
|
89
87
|
|
|
90
|
-
|
|
91
88
|
---
|
|
92
89
|
|
|
93
|
-
|
|
94
90
|
---
|
|
95
91
|
|
|
96
|
-
|
|
97
92
|
---
|
|
98
93
|
|
|
99
|
-
|
|
100
94
|
---
|
|
101
95
|
|
|
102
|
-
|
|
103
96
|
---
|
|
104
97
|
|
|
105
|
-
|
|
106
98
|
---
|
|
107
99
|
|
|
108
100
|
# Custom Macros
|
|
109
101
|
|
|
110
|
-
|
|
111
102
|
---
|
|
112
103
|
|
|
113
|
-
|
|
114
104
|
---
|
|
115
105
|
|
|
116
|
-
|
|
117
106
|
---
|
|
118
107
|
|
|
119
|
-
|
|
120
108
|
---
|
|
121
109
|
|
|
122
110
|
# Integration
|
|
123
111
|
|
|
124
|
-
|
|
125
112
|
---
|
|
126
113
|
|
|
127
|
-
|
|
128
114
|
---
|
|
129
115
|
|
|
130
|
-
|
|
131
116
|
---
|
|
132
117
|
|
|
133
|
-
|
|
134
118
|
---
|
|
135
119
|
|
|
136
|
-
|
|
137
120
|
---
|
|
138
121
|
|
|
139
122
|
# Language Servers
|
|
140
123
|
|
|
141
|
-
|
|
142
124
|
---
|
|
143
125
|
|
|
144
|
-
|
|
145
126
|
---
|
|
146
127
|
|
|
147
|
-
|
|
148
128
|
---
|
|
149
129
|
|
|
150
130
|
# API Reference
|
|
151
131
|
|
|
152
|
-
|
|
153
132
|
---
|
|
154
133
|
|
|
155
|
-
|
|
156
134
|
---
|
|
157
135
|
|
|
158
|
-
|
|
159
136
|
---
|
|
160
137
|
|
|
161
|
-
|
|
162
138
|
---
|
|
163
139
|
|
|
164
|
-
|
|
165
140
|
---
|
package/docs/api/api-overview.md
CHANGED
|
@@ -66,7 +66,7 @@ if (result.diagnostics.length > 0) {
|
|
|
66
66
|
|
|
67
67
|
## Detailed Reference
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
- [`expandSync()`](../docs/api/expand-sync) - Full options and return types
|
|
70
|
+
- [`transformSync()`](../docs/api/transform-sync) - Transform with source maps
|
|
71
|
+
- [`NativePlugin`](../docs/api/native-plugin) - Caching for language servers
|
|
72
|
+
- [`PositionMapper`](../docs/api/position-mapper) - Position mapping utilities
|
package/docs/api/expand-sync.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
macroforge v0.1.48
|
|
4
4
|
|
|
5
|
-
Synchronously expands macros in TypeScript code. This is the standalone macro expansion function
|
|
5
|
+
Synchronously expands macros in TypeScript code. This is the standalone macro expansion function
|
|
6
|
+
that doesn't use caching. For cached expansion, use \[\`NativePlugin::process\_file\`\] instead.
|
|
6
7
|
|
|
7
8
|
## Signature
|
|
8
9
|
|
|
@@ -124,4 +125,4 @@ for (const diag of result.diagnostics) {
|
|
|
124
125
|
console.error(`Error at ${diag.span.start}: ${diag.message}`);
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
|
-
```
|
|
128
|
+
```
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
macroforge v0.1.48
|
|
4
4
|
|
|
5
|
-
The main plugin class for macro expansion with caching support. \`NativePlugin\` is designed to be
|
|
5
|
+
The main plugin class for macro expansion with caching support. \`NativePlugin\` is designed to be
|
|
6
|
+
instantiated once and reused across multiple file processing operations. It maintains a cache of
|
|
7
|
+
expansion results keyed by filepath and version, enabling efficient incremental processing.
|
|
6
8
|
|
|
7
9
|
## Constructor
|
|
8
10
|
|
|
@@ -121,4 +123,5 @@ class MacroforgeLanguageService {
|
|
|
121
123
|
|
|
122
124
|
## Thread Safety
|
|
123
125
|
|
|
124
|
-
The `NativePlugin` class is thread-safe and can be used from multiple async contexts. Each file is
|
|
126
|
+
The `NativePlugin` class is thread-safe and can be used from multiple async contexts. Each file is
|
|
127
|
+
processed in an isolated thread with its own stack space.
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
macroforge v0.1.48
|
|
4
4
|
|
|
5
|
-
Bidirectional position mapper for translating between original and expanded source positions. This
|
|
5
|
+
Bidirectional position mapper for translating between original and expanded source positions. This
|
|
6
|
+
mapper enables IDE features like error reporting, go-to-definition, and hover to work correctly with
|
|
7
|
+
macro-expanded code by translating positions between the original source (what the user wrote) and
|
|
8
|
+
the expanded source (what the compiler sees).
|
|
6
9
|
|
|
7
10
|
## Getting a Mapper
|
|
8
11
|
|
|
@@ -140,6 +143,6 @@ function mapError(filepath: string, expandedPos: number, message: string) {
|
|
|
140
143
|
|
|
141
144
|
Position mapping uses binary search with O(log n) complexity:
|
|
142
145
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
- Fast lookups even for large files
|
|
147
|
+
- Minimal memory overhead
|
|
148
|
+
- Thread-safe access
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
macroforge v0.1.48
|
|
4
4
|
|
|
5
|
-
Synchronously transforms TypeScript code through the macro expansion system. This is similar to
|
|
5
|
+
Synchronously transforms TypeScript code through the macro expansion system. This is similar to
|
|
6
|
+
\[\`expand\_sync\`\] but returns a \[\`TransformResult\`\] which includes source map information
|
|
7
|
+
(when available).
|
|
6
8
|
|
|
7
9
|
## Signature
|
|
8
10
|
|
|
@@ -85,8 +87,8 @@ if (result.metadata) {
|
|
|
85
87
|
|
|
86
88
|
Use `transformSync` when:
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
- Building custom integrations
|
|
91
|
+
- You need raw output without diagnostics
|
|
92
|
+
- You're implementing a build tool plugin
|
|
91
93
|
|
|
92
|
-
Use `expandSync` for most other use cases, as it provides better error handling.
|
|
94
|
+
Use `expandSync` for most other use cases, as it provides better error handling.
|
|
@@ -2,32 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
### Container Options (on class/interface)
|
|
4
4
|
|
|
5
|
-
| `rename_all`
|
|
6
|
-
| `string`
|
|
7
|
-
| Apply naming convention to all fields
|
|
5
|
+
| `rename_all` | `string` | Apply naming convention to all fields
|
|
8
6
|
|
|
9
|
-
| `deny_unknown_fields`
|
|
10
|
-
| `boolean`
|
|
11
|
-
| Throw error if JSON has unknown keys
|
|
7
|
+
| `deny_unknown_fields` | `boolean` | Throw error if JSON has unknown keys
|
|
12
8
|
|
|
13
9
|
### Field Options (on properties)
|
|
14
10
|
|
|
15
|
-
| `rename`
|
|
16
|
-
| `string`
|
|
17
|
-
| Use a different JSON key
|
|
11
|
+
| `rename` | `string` | Use a different JSON key
|
|
18
12
|
|
|
19
|
-
| `skip`
|
|
20
|
-
| `boolean`
|
|
21
|
-
| Exclude from serialization and deserialization
|
|
13
|
+
| `skip` | `boolean` | Exclude from serialization and deserialization
|
|
22
14
|
|
|
23
|
-
| `skip_deserializing`
|
|
24
|
-
| `boolean`
|
|
25
|
-
| Exclude from deserialization only
|
|
15
|
+
| `skip_deserializing` | `boolean` | Exclude from deserialization only
|
|
26
16
|
|
|
27
|
-
| `default`
|
|
28
|
-
| `boolean | string`
|
|
29
|
-
| Use TypeScript default or custom expression if missing
|
|
17
|
+
| `default` | `boolean | string` | Use TypeScript default or custom expression if missing
|
|
30
18
|
|
|
31
|
-
| `flatten`
|
|
32
|
-
| `boolean`
|
|
33
|
-
| Merge nested object fields from parent
|
|
19
|
+
| `flatten` | `boolean` | Merge nested object fields from parent
|
|
@@ -2,18 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Use both Serialize and Deserialize for complete JSON round-trip support:
|
|
4
4
|
|
|
5
|
-
<InteractiveMacro
|
|
5
|
+
<InteractiveMacro
|
|
6
|
+
code={`/** @derive(Serialize, Deserialize) */
|
|
6
7
|
/** @serde({ rename_all: "camelCase" }) */
|
|
7
8
|
class UserProfile {
|
|
8
9
|
user_name: string;
|
|
9
10
|
created_at: Date;
|
|
10
11
|
is_active: boolean;
|
|
11
|
-
}`}
|
|
12
|
+
}`}
|
|
13
|
+
/>
|
|
12
14
|
|
|
13
15
|
```typescript
|
|
14
16
|
// Create and serialize
|
|
15
17
|
const profile = new UserProfile();
|
|
16
|
-
profile.user_name =
|
|
18
|
+
profile.user_name = 'Alice';
|
|
17
19
|
profile.created_at = new Date();
|
|
18
20
|
profile.is_active = true;
|
|
19
21
|
|
|
@@ -22,6 +24,6 @@ const json = JSON.stringify(profile);
|
|
|
22
24
|
|
|
23
25
|
// Deserialize back
|
|
24
26
|
const restored = UserProfile.fromJSON(JSON.parse(json));
|
|
25
|
-
console.log(restored.user_name);
|
|
27
|
+
console.log(restored.user_name); // "Alice"
|
|
26
28
|
console.log(restored.created_at instanceof Date); // true
|
|
27
|
-
```
|
|
29
|
+
```
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
## Enum Support
|
|
2
2
|
|
|
3
|
-
Deserialize also works with enums. The `fromJSON` function validates that the input matches one of
|
|
3
|
+
Deserialize also works with enums. The `fromJSON` function validates that the input matches one of
|
|
4
|
+
the enum values:
|
|
4
5
|
|
|
5
6
|
<MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
|
|
6
7
|
|
|
7
8
|
```typescript
|
|
8
|
-
const status = Status.fromJSON(
|
|
9
|
+
const status = Status.fromJSON('active');
|
|
9
10
|
console.log(status); // Status.Active
|
|
10
11
|
|
|
11
12
|
// Invalid values throw an error
|
|
12
13
|
try {
|
|
13
|
-
|
|
14
|
+
Status.fromJSON('invalid');
|
|
14
15
|
} catch (e) {
|
|
15
|
-
|
|
16
|
+
console.log(e.message); // "Invalid Status value: invalid"
|
|
16
17
|
}
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
Works with numeric enums too:
|
|
20
21
|
|
|
21
|
-
<InteractiveMacro
|
|
22
|
+
<InteractiveMacro
|
|
23
|
+
code={`/** @derive(Deserialize) */
|
|
22
24
|
enum Priority {
|
|
23
25
|
Low = 1,
|
|
24
26
|
Medium = 2,
|
|
@@ -28,4 +30,4 @@ enum Priority {
|
|
|
28
30
|
```typescript
|
|
29
31
|
const priority = Priority.fromJSON(3);
|
|
30
32
|
console.log(priority); // Priority.High
|
|
31
|
-
```
|
|
33
|
+
```
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Handle deserialization errors gracefully:
|
|
4
4
|
|
|
5
|
-
<InteractiveMacro
|
|
5
|
+
<InteractiveMacro
|
|
6
|
+
code={`/** @derive(Deserialize) */
|
|
6
7
|
class User {
|
|
7
8
|
name: string;
|
|
8
9
|
email: string;
|
|
@@ -10,15 +11,15 @@ class User {
|
|
|
10
11
|
|
|
11
12
|
```typescript
|
|
12
13
|
function parseUser(json: unknown): User | null {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
try {
|
|
15
|
+
return User.fromJSON(json);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error('Failed to parse user:', error.message);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const user = parseUser({ name:
|
|
22
|
+
const user = parseUser({ name: 'Alice' });
|
|
22
23
|
// Logs: Failed to parse user: User.fromJSON: missing required field "email"
|
|
23
24
|
// Returns: null
|
|
24
|
-
```
|
|
25
|
+
```
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
## Interface Support
|
|
2
2
|
|
|
3
|
-
Deserialize also works with interfaces. For interfaces, a namespace is generated with `is` (type
|
|
3
|
+
Deserialize also works with interfaces. For interfaces, a namespace is generated with `is` (type
|
|
4
|
+
guard) and `fromJSON` functions:
|
|
4
5
|
|
|
5
6
|
<MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
|
|
6
7
|
|
|
7
8
|
```typescript
|
|
8
|
-
const json = {
|
|
9
|
+
const json = {
|
|
10
|
+
status: 200,
|
|
11
|
+
message: 'OK',
|
|
12
|
+
timestamp: '2024-01-15T10:30:00.000Z'
|
|
13
|
+
};
|
|
9
14
|
|
|
10
15
|
// Type guard
|
|
11
16
|
if (ApiResponse.is(json)) {
|
|
12
|
-
|
|
17
|
+
console.log(json.status); // TypeScript knows this is ApiResponse
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
// Deserialize with validation
|
|
16
21
|
const response = ApiResponse.fromJSON(json);
|
|
17
22
|
console.log(response.timestamp instanceof Date); // true
|
|
18
|
-
```
|
|
23
|
+
```
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Deserialize validates the input data and throws descriptive errors:
|
|
4
4
|
|
|
5
|
-
<InteractiveMacro
|
|
5
|
+
<InteractiveMacro
|
|
6
|
+
code={`/** @derive(Deserialize) */
|
|
6
7
|
class User {
|
|
7
8
|
name: string;
|
|
8
9
|
email: string;
|
|
@@ -10,11 +11,11 @@ class User {
|
|
|
10
11
|
|
|
11
12
|
```typescript
|
|
12
13
|
// Missing required field
|
|
13
|
-
User.fromJSON({ name:
|
|
14
|
+
User.fromJSON({ name: 'Alice' });
|
|
14
15
|
// Error: User.fromJSON: missing required field "email"
|
|
15
16
|
|
|
16
17
|
// Wrong type
|
|
17
|
-
User.fromJSON(
|
|
18
|
+
User.fromJSON('not an object');
|
|
18
19
|
// Error: User.fromJSON: expected an object, got string
|
|
19
20
|
|
|
20
21
|
// Array instead of object
|
|
@@ -26,26 +27,14 @@ User.fromJSON([1, 2, 3]);
|
|
|
26
27
|
|
|
27
28
|
Deserialize automatically converts JSON types to their TypeScript equivalents:
|
|
28
29
|
|
|
29
|
-
| string/number/boolean
|
|
30
|
-
| `string`/`number`/`boolean`
|
|
31
|
-
| Direct assignment
|
|
30
|
+
| string/number/boolean | `string`/`number`/`boolean` | Direct assignment
|
|
32
31
|
|
|
33
|
-
| ISO string
|
|
34
|
-
| `Date`
|
|
35
|
-
| `new Date(string)`
|
|
32
|
+
| ISO string | `Date` | `new Date(string)`
|
|
36
33
|
|
|
37
|
-
| array
|
|
38
|
-
| `T[]`
|
|
39
|
-
| Maps items with auto-detection
|
|
34
|
+
| array | `T[]` | Maps items with auto-detection
|
|
40
35
|
|
|
41
|
-
| object
|
|
42
|
-
| `Map<K, V>`
|
|
43
|
-
| `new Map(Object.entries())`
|
|
36
|
+
| object | `Map<K, V>` | `new Map(Object.entries())`
|
|
44
37
|
|
|
45
|
-
| array
|
|
46
|
-
| `Set<T>`
|
|
47
|
-
| `new Set(array)`
|
|
38
|
+
| array | `Set<T>` | `new Set(array)`
|
|
48
39
|
|
|
49
|
-
| object
|
|
50
|
-
| Nested class
|
|
51
|
-
| Calls `fromJSON()` if available
|
|
40
|
+
| object | Nested class | Calls `fromJSON()` if available
|
|
@@ -7,8 +7,8 @@ Use the `@serde` decorator to customize deserialization:
|
|
|
7
7
|
<MacroExample before={data.examples.rename.before} after={data.examples.rename.after} />
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
const user = User.fromJSON({ user_id:
|
|
11
|
-
console.log(user.id);
|
|
10
|
+
const user = User.fromJSON({ user_id: '123', full_name: 'Alice' });
|
|
11
|
+
console.log(user.id); // "123"
|
|
12
12
|
console.log(user.name); // "Alice"
|
|
13
13
|
```
|
|
14
14
|
|
|
@@ -17,24 +17,18 @@ console.log(user.name); // "Alice"
|
|
|
17
17
|
<MacroExample before={data.examples.default.before} after={data.examples.default.after} />
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
|
-
const config = Config.fromJSON({ host:
|
|
21
|
-
console.log(config.port);
|
|
20
|
+
const config = Config.fromJSON({ host: 'localhost' });
|
|
21
|
+
console.log(config.port); // "3000"
|
|
22
22
|
console.log(config.debug); // false
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Skipping Fields
|
|
26
26
|
|
|
27
|
-
<InteractiveMacro code={`/** @derive(Deserialize) */
|
|
28
|
-
class User {
|
|
29
|
-
name: string;
|
|
30
|
-
email: string;
|
|
27
|
+
<InteractiveMacro code={`/** @derive(Deserialize) */ class User { name: string; email: string;
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
cachedData: unknown;
|
|
29
|
+
/** @serde({ skip: true }) */ cachedData: unknown;
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
computedField: string;
|
|
37
|
-
}`} />
|
|
31
|
+
/** @serde({ skip_deserializing: true }) */ computedField: string; }`} />
|
|
38
32
|
|
|
39
33
|
<Alert type="tip" title="skip vs skip_deserializing">
|
|
40
34
|
Use `skip: true` to exclude from both serialization and deserialization.
|
|
@@ -43,41 +37,35 @@ Use `skip_deserializing: true` to only skip during deserialization.
|
|
|
43
37
|
|
|
44
38
|
### Deny Unknown Fields
|
|
45
39
|
|
|
46
|
-
<InteractiveMacro
|
|
40
|
+
<InteractiveMacro
|
|
41
|
+
code={`/** @derive(Deserialize) */
|
|
47
42
|
/** @serde({ deny_unknown_fields: true }) */
|
|
48
43
|
class StrictUser {
|
|
49
44
|
name: string;
|
|
50
45
|
email: string;
|
|
51
|
-
}`}
|
|
46
|
+
}`}
|
|
47
|
+
/>
|
|
52
48
|
|
|
53
49
|
```typescript
|
|
54
50
|
// This will throw an error
|
|
55
|
-
StrictUser.fromJSON({ name:
|
|
51
|
+
StrictUser.fromJSON({ name: 'Alice', email: 'a@b.com', extra: 'field' });
|
|
56
52
|
// Error: StrictUser.fromJSON: unknown field "extra"
|
|
57
53
|
```
|
|
58
54
|
|
|
59
55
|
### Flatten Nested Objects
|
|
60
56
|
|
|
61
|
-
<InteractiveMacro code={`/** @derive(Deserialize) */
|
|
62
|
-
class Address {
|
|
63
|
-
city: string;
|
|
64
|
-
zip: string;
|
|
65
|
-
}
|
|
57
|
+
<InteractiveMacro code={`/** @derive(Deserialize) */ class Address { city: string; zip: string; }
|
|
66
58
|
|
|
67
|
-
/** @derive(Deserialize) */
|
|
68
|
-
class User {
|
|
69
|
-
name: string;
|
|
59
|
+
/** @derive(Deserialize) */ class User { name: string;
|
|
70
60
|
|
|
71
|
-
|
|
72
|
-
address: Address;
|
|
73
|
-
}`} />
|
|
61
|
+
/** @serde({ flatten: true }) */ address: Address; }`} />
|
|
74
62
|
|
|
75
63
|
```typescript
|
|
76
64
|
// Flat JSON structure
|
|
77
65
|
const user = User.fromJSON({
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
66
|
+
name: 'Alice',
|
|
67
|
+
city: 'NYC',
|
|
68
|
+
zip: '10001'
|
|
81
69
|
});
|
|
82
70
|
console.log(user.address.city); // "NYC"
|
|
83
|
-
```
|
|
71
|
+
```
|
|
@@ -6,9 +6,9 @@ Deserialize works with type aliases. For object types, validation and type conve
|
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
8
|
const json = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
id: '123',
|
|
10
|
+
name: 'Alice',
|
|
11
|
+
createdAt: '2024-01-15T00:00:00.000Z'
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const profile = UserProfile.fromJSON(json);
|
|
@@ -17,10 +17,11 @@ console.log(profile.createdAt instanceof Date); // true
|
|
|
17
17
|
|
|
18
18
|
For union types, basic validation is applied:
|
|
19
19
|
|
|
20
|
-
<InteractiveMacro
|
|
20
|
+
<InteractiveMacro
|
|
21
|
+
code={`/** @derive(Deserialize) */
|
|
21
22
|
type ApiStatus = "loading" | "success" | "error";`} />
|
|
22
23
|
|
|
23
24
|
```typescript
|
|
24
|
-
const status = ApiStatus.fromJSON(
|
|
25
|
+
const status = ApiStatus.fromJSON('success');
|
|
25
26
|
console.log(status); // "success"
|
|
26
|
-
```
|
|
27
|
+
```
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Each macro has its own options and behaviors:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
- [**Debug**](../docs/builtin-macros/debug) - Customizable field renaming and skipping
|
|
6
|
+
- [**Clone**](../docs/builtin-macros/clone) - Deep copying for all field types
|
|
7
|
+
- [**Default**](../docs/builtin-macros/default) - Default value generation with field attributes
|
|
8
|
+
- [**Hash**](../docs/builtin-macros/hash) - Hash code generation for use in maps and sets
|
|
9
|
+
- [**PartialEq**](../docs/builtin-macros/partial-eq) - Value-based equality comparison
|
|
10
|
+
- [**Ord**](../docs/builtin-macros/ord) - Total ordering for sorting
|
|
11
|
+
- [**PartialOrd**](../docs/builtin-macros/partial-ord) - Partial ordering comparison
|
|
12
|
+
- [**Serialize**](../docs/builtin-macros/serialize) - JSON serialization with serde-style options
|
|
13
|
+
- [**Deserialize**](../docs/builtin-macros/deserialize) - JSON deserialization with validation
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## Enum Support
|
|
2
2
|
|
|
3
|
-
All built-in macros work with enums. For enums, methods are generated as functions in a namespace
|
|
3
|
+
All built-in macros work with enums. For enums, methods are generated as functions in a namespace
|
|
4
|
+
with the same name:
|
|
4
5
|
|
|
5
6
|
TypeScript
|
|
6
7
|
|
|
@@ -27,4 +28,4 @@ console.log(Status.toString(Status.Active)); // "Status.Active"
|
|
|
27
28
|
console.log(Status.equals(Status.Active, Status.Active)); // true
|
|
28
29
|
const json = Status.toJSON(Status.Pending); // "pending"
|
|
29
30
|
const parsed = Status.fromJSON("active"); // Status.Active
|
|
30
|
-
```
|
|
31
|
+
```
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## Interface Support
|
|
2
2
|
|
|
3
|
-
All built-in macros work with interfaces. For interfaces, methods are generated as functions in a
|
|
3
|
+
All built-in macros work with interfaces. For interfaces, methods are generated as functions in a
|
|
4
|
+
namespace with the same name, using `self` as the first parameter:
|
|
4
5
|
|
|
5
6
|
TypeScript
|
|
6
7
|
|
|
@@ -25,4 +26,4 @@ const point: Point = { x: 10, y: 20 };
|
|
|
25
26
|
console.log(Point.toString(point)); // "Point { x: 10, y: 20 }"
|
|
26
27
|
const copy = Point.clone(point); // { x: 10, y: 20 }
|
|
27
28
|
console.log(Point.equals(point, copy)); // true
|
|
28
|
-
```
|
|
29
|
+
```
|