@macroforge/mcp-server 0.1.33 → 0.1.35
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 +68 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/docs-loader.d.ts +133 -5
- package/dist/tools/docs-loader.d.ts.map +1 -1
- package/dist/tools/docs-loader.js +131 -15
- package/dist/tools/docs-loader.js.map +1 -1
- package/dist/tools/index.d.ts +48 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +163 -14
- package/dist/tools/index.js.map +1 -1
- package/docs/api/api-overview.md +24 -46
- package/docs/api/expand-sync.md +24 -51
- package/docs/api/native-plugin.md +24 -56
- package/docs/api/position-mapper.md +34 -76
- package/docs/api/transform-sync.md +27 -59
- package/docs/builtin-macros/clone.md +45 -104
- package/docs/builtin-macros/debug.md +33 -104
- package/docs/builtin-macros/default.md +78 -114
- package/docs/builtin-macros/deserialize.md +93 -273
- package/docs/builtin-macros/hash.md +58 -100
- package/docs/builtin-macros/macros-overview.md +42 -103
- package/docs/builtin-macros/ord.md +65 -133
- package/docs/builtin-macros/partial-eq.md +53 -179
- package/docs/builtin-macros/partial-ord.md +67 -159
- package/docs/builtin-macros/serialize.md +64 -194
- package/docs/concepts/architecture.md +40 -99
- package/docs/concepts/derive-system.md +129 -125
- package/docs/concepts/how-macros-work.md +52 -84
- package/docs/custom-macros/custom-overview.md +17 -39
- package/docs/custom-macros/rust-setup.md +22 -55
- package/docs/custom-macros/ts-macro-derive.md +43 -107
- package/docs/custom-macros/ts-quote.md +177 -507
- package/docs/getting-started/first-macro.md +108 -33
- package/docs/getting-started/installation.md +32 -73
- package/docs/integration/cli.md +70 -156
- package/docs/integration/configuration.md +32 -75
- package/docs/integration/integration-overview.md +16 -55
- package/docs/integration/mcp-server.md +30 -69
- package/docs/integration/svelte-preprocessor.md +60 -83
- package/docs/integration/typescript-plugin.md +32 -74
- package/docs/integration/vite-plugin.md +30 -79
- package/docs/language-servers/ls-overview.md +22 -46
- package/docs/language-servers/svelte.md +30 -69
- package/docs/language-servers/zed.md +34 -72
- package/docs/roadmap/roadmap.md +54 -130
- package/docs/sections.json +3 -262
- package/package.json +2 -2
|
@@ -1,55 +1,37 @@
|
|
|
1
1
|
# The Derive System
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
The `@derive` decorator triggers macro expansion on a class or interface:
|
|
12
|
-
|
|
13
|
-
<InteractiveMacro code={`/** @derive(Debug) */
|
|
2
|
+
*The derive system is inspired by Rust's derive macros. It allows you to automatically implement common patterns by annotating your classes with `@derive`.*
|
|
3
|
+
## Syntax Reference
|
|
4
|
+
Macroforge uses JSDoc comments for all macro annotations. This ensures compatibility with standard TypeScript tooling.
|
|
5
|
+
### The @derive Statement
|
|
6
|
+
The `@derive` decorator triggers macro expansion on a class or interface:
|
|
7
|
+
**Source:**
|
|
8
|
+
```
|
|
9
|
+
/** @derive(Debug) */
|
|
14
10
|
class MyClass {
|
|
15
11
|
value: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- Multiple `@derive` statements can be stacked
|
|
27
|
-
|
|
28
|
-
<InteractiveMacro code={`/** @derive(Debug, Clone) */
|
|
12
|
+
}
|
|
13
|
+
``` Syntax rules:
|
|
14
|
+
- Must be inside a JSDoc comment (`/** */`)
|
|
15
|
+
- Must appear immediately before the class/interface declaration
|
|
16
|
+
- Multiple macros can be comma-separated: `@derive(A, B, C)`
|
|
17
|
+
- Multiple `@derive` statements can be stacked
|
|
18
|
+
**Source:**
|
|
19
|
+
```
|
|
20
|
+
/** @derive(Debug, Clone) */
|
|
29
21
|
class User {
|
|
30
22
|
name: string;
|
|
31
23
|
email: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
To use macros from external packages, you must declare them with `import macro`:
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
24
|
+
}
|
|
25
|
+
``` ### The import macro Statement
|
|
26
|
+
To use macros from external packages, you must declare them with `import macro`:
|
|
27
|
+
```
|
|
39
28
|
/** import macro { MacroName } from "package-name"; */
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
- Can appear anywhere in the file (typically at the top)
|
|
47
|
-
|
|
48
|
-
- Multiple macros can be imported: `import macro { A, B } from "pkg";`
|
|
49
|
-
|
|
50
|
-
- Multiple import statements can be used for different packages
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
29
|
+
``` Syntax rules:
|
|
30
|
+
- Must be inside a JSDoc comment (`/** */`)
|
|
31
|
+
- Can appear anywhere in the file (typically at the top)
|
|
32
|
+
- Multiple macros can be imported: `import macro { A, B } from "pkg";`
|
|
33
|
+
- Multiple import statements can be used for different packages
|
|
34
|
+
```
|
|
53
35
|
/** import macro { JSON, Validate } from "@my/macros"; */
|
|
54
36
|
/** import macro { Builder } from "@other/macros"; */
|
|
55
37
|
|
|
@@ -58,88 +40,110 @@ class User {
|
|
|
58
40
|
name: string;
|
|
59
41
|
email: string;
|
|
60
42
|
}
|
|
43
|
+
``` **Built-in macros Built-in macros (Debug, Clone, Default, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize) do not require an import statement. ### Field Attributes
|
|
44
|
+
Macros can define field-level attributes to customize behavior per field:
|
|
45
|
+
****Before:**
|
|
61
46
|
```
|
|
47
|
+
/** @derive(Debug, Serialize) */
|
|
48
|
+
class User {
|
|
49
|
+
/** @debug({ rename: "userId" }) */
|
|
50
|
+
/** @serde({ rename: "user_id" }) */
|
|
51
|
+
id: number;
|
|
62
52
|
|
|
63
|
-
|
|
64
|
-
Built-in macros (Debug, Clone, Default, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize) do not require an import statement.
|
|
65
|
-
</Alert>
|
|
66
|
-
|
|
67
|
-
### Field Attributes
|
|
68
|
-
|
|
69
|
-
Macros can define field-level attributes to customize behavior per field:
|
|
70
|
-
|
|
71
|
-
<MacroExample before={data.examples.fieldAttributes.before} after={data.examples.fieldAttributes.after} />
|
|
72
|
-
|
|
73
|
-
Syntax rules:
|
|
74
|
-
|
|
75
|
-
- Must be inside a JSDoc comment immediately before the field
|
|
76
|
-
|
|
77
|
-
- Options use object literal syntax: `@attr({ key: value })`
|
|
78
|
-
|
|
79
|
-
- Boolean options: `@attr({ skip: true })`
|
|
80
|
-
|
|
81
|
-
- String options: `@attr({ rename: "newName" })`
|
|
82
|
-
|
|
83
|
-
- Multiple attributes can be on separate lines or combined
|
|
84
|
-
|
|
85
|
-
Common field attributes by macro:
|
|
86
|
-
|
|
87
|
-
| Debug
|
|
88
|
-
| `@debug`
|
|
89
|
-
| `skip`, `rename`
|
|
90
|
-
|
|
91
|
-
| Clone
|
|
92
|
-
| `@clone`
|
|
93
|
-
| `skip`, `clone_with`
|
|
94
|
-
|
|
95
|
-
| Serialize/Deserialize
|
|
96
|
-
| `@serde`
|
|
97
|
-
| `skip`, `rename`, `flatten`, `default`
|
|
98
|
-
|
|
99
|
-
| Hash
|
|
100
|
-
| `@hash`
|
|
101
|
-
| `skip`
|
|
102
|
-
|
|
103
|
-
| PartialEq/Ord
|
|
104
|
-
| `@eq`, `@ord`
|
|
105
|
-
| `skip`
|
|
106
|
-
|
|
107
|
-
## How It Works
|
|
108
|
-
|
|
109
|
-
1. **Declaration**: You write `@derive(MacroName)` before a class
|
|
110
|
-
|
|
111
|
-
2. **Discovery**: Macroforge finds all derive decorators in your code
|
|
112
|
-
|
|
113
|
-
3. **Expansion**: Each named macro receives the class AST and generates code
|
|
114
|
-
|
|
115
|
-
4. **Injection**: Generated methods/properties are added to the class
|
|
116
|
-
|
|
117
|
-
## What Can Be Derived
|
|
118
|
-
|
|
119
|
-
The derive system works on:
|
|
120
|
-
|
|
121
|
-
- **Classes**: The primary target for derive macros
|
|
122
|
-
|
|
123
|
-
- **Interfaces**: Macros generate companion namespace functions
|
|
124
|
-
|
|
125
|
-
- **Enums**: Macros generate namespace functions for enum values
|
|
126
|
-
|
|
127
|
-
- **Type aliases**: Both object types and union types are supported
|
|
128
|
-
|
|
129
|
-
## Built-in vs Custom Macros
|
|
130
|
-
|
|
131
|
-
Macroforge comes with built-in macros that work out of the box. You can also create custom macros in Rust and use them via the `import macro` statement.
|
|
132
|
-
|
|
133
|
-
| Built-in
|
|
134
|
-
| No
|
|
135
|
-
| Debug, Clone, Default, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize
|
|
136
|
-
|
|
137
|
-
| Custom
|
|
138
|
-
| Yes
|
|
139
|
-
| Any macro from an external package
|
|
53
|
+
name: string;
|
|
140
54
|
|
|
141
|
-
|
|
55
|
+
/** @debug({ skip: true }) */
|
|
56
|
+
/** @serde({ skip: true }) */
|
|
57
|
+
password: string;
|
|
142
58
|
|
|
143
|
-
|
|
59
|
+
/** @serde({ flatten: true }) */
|
|
60
|
+
metadata: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
**After:**
|
|
64
|
+
```
|
|
65
|
+
import { SerializeContext } from 'macroforge/serde';
|
|
144
66
|
|
|
145
|
-
|
|
67
|
+
class User {
|
|
68
|
+
id: number;
|
|
69
|
+
|
|
70
|
+
name: string;
|
|
71
|
+
|
|
72
|
+
password: string;
|
|
73
|
+
|
|
74
|
+
metadata: Record<string, unknown>;
|
|
75
|
+
|
|
76
|
+
toString(): string {
|
|
77
|
+
const parts: string[] = [];
|
|
78
|
+
parts.push('userId: ' + this.id);
|
|
79
|
+
parts.push('name: ' + this.name);
|
|
80
|
+
parts.push('metadata: ' + this.metadata);
|
|
81
|
+
return 'User { ' + parts.join(', ') + ' }';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
toStringifiedJSON(): string {
|
|
85
|
+
const ctx = SerializeContext.create();
|
|
86
|
+
return JSON.stringify(this.__serialize(ctx));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
toObject(): Record<string, unknown> {
|
|
90
|
+
const ctx = SerializeContext.create();
|
|
91
|
+
return this.__serialize(ctx);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
__serialize(ctx: SerializeContext): Record<string, unknown> {
|
|
95
|
+
const existingId = ctx.getId(this);
|
|
96
|
+
if (existingId !== undefined) {
|
|
97
|
+
return {
|
|
98
|
+
__ref: existingId
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const __id = ctx.register(this);
|
|
102
|
+
const result: Record<string, unknown> = {
|
|
103
|
+
__type: 'User',
|
|
104
|
+
__id
|
|
105
|
+
};
|
|
106
|
+
result['user_id'] = this.id;
|
|
107
|
+
result['name'] = this.name;
|
|
108
|
+
{
|
|
109
|
+
const __flattened = __serializeRecord<string, unknown>(this.metadata, ctx);
|
|
110
|
+
const { __type: _, __id: __, ...rest } = __flattened as any;
|
|
111
|
+
Object.assign(result, rest);
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
``` Syntax rules:
|
|
117
|
+
- Must be inside a JSDoc comment immediately before the field
|
|
118
|
+
- Options use object literal syntax: `@attr({ key: value })`
|
|
119
|
+
- Boolean options: `@attr({ skip: true })`
|
|
120
|
+
- String options: `@attr({ rename: "newName" })`
|
|
121
|
+
- Multiple attributes can be on separate lines or combined
|
|
122
|
+
Common field attributes by macro:
|
|
123
|
+
| Macro | Attribute | Options |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| Debug | `@debug` | `skip`, `rename` |
|
|
126
|
+
| Clone | `@clone` | `skip`, `clone_with` |
|
|
127
|
+
| Serialize/Deserialize | `@serde` | `skip`, `rename`, `flatten`, `default` |
|
|
128
|
+
| Hash | `@hash` | `skip` |
|
|
129
|
+
| PartialEq/Ord | `@eq`, `@ord` | `skip` |
|
|
130
|
+
## How It Works
|
|
131
|
+
1. **Declaration**: You write `@derive(MacroName)` before a class
|
|
132
|
+
2. **Discovery**: Macroforge finds all derive decorators in your code
|
|
133
|
+
3. **Expansion**: Each named macro receives the class AST and generates code
|
|
134
|
+
4. **Injection**: Generated methods/properties are added to the class
|
|
135
|
+
## What Can Be Derived
|
|
136
|
+
The derive system works on:
|
|
137
|
+
- **Classes**: The primary target for derive macros
|
|
138
|
+
- **Interfaces**: Macros generate companion namespace functions
|
|
139
|
+
- **Enums**: Macros generate namespace functions for enum values
|
|
140
|
+
- **Type aliases**: Both object types and union types are supported
|
|
141
|
+
## Built-in vs Custom Macros
|
|
142
|
+
Macroforge comes with built-in macros that work out of the box. You can also create custom macros in Rust and use them via the `import macro` statement.
|
|
143
|
+
| Type | Import Required | Examples |
|
|
144
|
+
| --- | --- | --- |
|
|
145
|
+
| Built-in | No | Debug, Clone, Default, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize |
|
|
146
|
+
| Custom | Yes | Any macro from an external package |
|
|
147
|
+
## Next Steps
|
|
148
|
+
- [Explore built-in macros](../../docs/builtin-macros)
|
|
149
|
+
- [Create custom macros](../../docs/custom-macros)
|
|
@@ -1,85 +1,53 @@
|
|
|
1
1
|
# How Macros Work
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Macroforge tracks the relationship between your source code and the expanded output. This means:
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{ title: "Expanded TypeScript", description: "ready for normal compilation" }
|
|
55
|
-
]} />
|
|
56
|
-
|
|
57
|
-
## Integration Points
|
|
58
|
-
|
|
59
|
-
Macroforge integrates at two key points:
|
|
60
|
-
|
|
61
|
-
### IDE (TypeScript Plugin)
|
|
62
|
-
|
|
63
|
-
The TypeScript plugin intercepts language server calls to provide:
|
|
64
|
-
|
|
65
|
-
- Diagnostics that reference your source, not expanded code
|
|
66
|
-
|
|
67
|
-
- Completions for generated methods
|
|
68
|
-
|
|
69
|
-
- Hover information showing what macros generate
|
|
70
|
-
|
|
71
|
-
### Build (Vite Plugin)
|
|
72
|
-
|
|
73
|
-
The Vite plugin runs macro expansion during the build process:
|
|
74
|
-
|
|
75
|
-
- Transforms files before they reach the TypeScript compiler
|
|
76
|
-
|
|
77
|
-
- Generates type declaration files (.d.ts)
|
|
78
|
-
|
|
79
|
-
- Produces metadata for debugging
|
|
80
|
-
|
|
81
|
-
## Next Steps
|
|
82
|
-
|
|
83
|
-
- [Learn about the derive system]({base}/docs/concepts/derive-system)
|
|
84
|
-
|
|
85
|
-
- [Explore the architecture]({base}/docs/concepts/architecture)
|
|
2
|
+
*Macroforge performs compile-time code generation by parsing your TypeScript, expanding macros, and outputting transformed code. This happens before your code runs, resulting in zero runtime overhead.*
|
|
3
|
+
## Compile-Time Expansion
|
|
4
|
+
Unlike runtime solutions that use reflection or proxies, Macroforge expands macros at compile time:
|
|
5
|
+
1. **Parse**: Your TypeScript code is parsed into an AST using SWC
|
|
6
|
+
2. **Find**: Macroforge finds `@derive` decorators and their associated items
|
|
7
|
+
3. **Expand**: Each macro generates new code based on the class structure
|
|
8
|
+
4. **Output**: The transformed TypeScript is written out, ready for normal compilation
|
|
9
|
+
**Before:**
|
|
10
|
+
```
|
|
11
|
+
/** @derive(Debug) */
|
|
12
|
+
class User {
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
**After:**
|
|
17
|
+
```
|
|
18
|
+
class User {
|
|
19
|
+
name: string;
|
|
20
|
+
|
|
21
|
+
toString(): string {
|
|
22
|
+
const parts: string[] = [];
|
|
23
|
+
parts.push('name: ' + this.name);
|
|
24
|
+
return 'User { ' + parts.join(', ') + ' }';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
``` ## Zero Runtime Overhead
|
|
28
|
+
Because code generation happens at compile time, there's no:
|
|
29
|
+
- Runtime reflection or metadata
|
|
30
|
+
- Proxy objects or wrappers
|
|
31
|
+
- Additional dependencies in your bundle
|
|
32
|
+
- Performance cost at runtime
|
|
33
|
+
The generated code is plain TypeScript that compiles to efficient JavaScript.
|
|
34
|
+
## Source Mapping
|
|
35
|
+
Macroforge tracks the relationship between your source code and the expanded output. This means:
|
|
36
|
+
- Errors in generated code point back to your source
|
|
37
|
+
- Debugging works correctly
|
|
38
|
+
- IDE features like "go to definition" work as expected
|
|
39
|
+
> with @derive decorators <div class="font-semibold text-foreground">SWC Parser TypeScript → AST <div class="font-semibold text-foreground">Macro Expansion Engine Finds @derive decorators, runs macros, generates new AST nodes <div class="font-semibold text-foreground">Code Generator AST → TypeScript <div class="font-semibold text-foreground">Expanded TypeScript ready for normal compilation ## Integration Points
|
|
40
|
+
Macroforge integrates at two key points:
|
|
41
|
+
### IDE (TypeScript Plugin)
|
|
42
|
+
The TypeScript plugin intercepts language server calls to provide:
|
|
43
|
+
- Diagnostics that reference your source, not expanded code
|
|
44
|
+
- Completions for generated methods
|
|
45
|
+
- Hover information showing what macros generate
|
|
46
|
+
### Build (Vite Plugin)
|
|
47
|
+
The Vite plugin runs macro expansion during the build process:
|
|
48
|
+
- Transforms files before they reach the TypeScript compiler
|
|
49
|
+
- Generates type declaration files (.d.ts)
|
|
50
|
+
- Produces metadata for debugging
|
|
51
|
+
## Next Steps
|
|
52
|
+
- [Learn about the derive system](../docs/concepts/derive-system)
|
|
53
|
+
- [Explore the architecture](../docs/concepts/architecture)
|
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
# Custom Macros
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
2. Defining macro functions with `#[ts_macro_derive]`
|
|
12
|
-
|
|
13
|
-
3. Using `macroforge_ts_quote` to generate TypeScript code
|
|
14
|
-
|
|
15
|
-
4. Building and publishing as an npm package
|
|
16
|
-
|
|
17
|
-
## Quick Example
|
|
18
|
-
|
|
19
|
-
```rust
|
|
2
|
+
*Macroforge allows you to create custom derive macros in Rust. Your macros have full access to the class AST and can generate any TypeScript code.*
|
|
3
|
+
## Overview
|
|
4
|
+
Custom macros are written in Rust and compiled to native Node.js addons. The process involves:
|
|
5
|
+
1. Creating a Rust crate with NAPI bindings
|
|
6
|
+
2. Defining macro functions with `#[ts_macro_derive]`
|
|
7
|
+
3. Using `macroforge_ts_quote` to generate TypeScript code
|
|
8
|
+
4. Building and publishing as an npm package
|
|
9
|
+
## Quick Example
|
|
10
|
+
```
|
|
20
11
|
use macroforge_ts::macros::{ts_macro_derive, body};
|
|
21
12
|
use macroforge_ts::ts_syn::{Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input};
|
|
22
13
|
|
|
@@ -45,13 +36,9 @@ pub fn derive_json(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
|
|
|
45
36
|
)),
|
|
46
37
|
}
|
|
47
38
|
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Once your macro package is published, users can import and use it:
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
39
|
+
``` ## Using Custom Macros
|
|
40
|
+
Once your macro package is published, users can import and use it:
|
|
41
|
+
```
|
|
55
42
|
/** import macro { JSON } from "@my/macros"; */
|
|
56
43
|
|
|
57
44
|
/** @derive(JSON) */
|
|
@@ -67,17 +54,8 @@ class User {
|
|
|
67
54
|
|
|
68
55
|
const user = new User("Alice", 30);
|
|
69
56
|
console.log(user.toJSON()); // { name: "Alice", age: 30 }
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
## Getting Started
|
|
76
|
-
|
|
77
|
-
Follow these guides to create your own macros:
|
|
78
|
-
|
|
79
|
-
- [Set up a Rust macro crate]({base}/docs/custom-macros/rust-setup)
|
|
80
|
-
|
|
81
|
-
- [Learn the #[ts_macro_derive] attribute]({base}/docs/custom-macros/ts-macro-derive)
|
|
82
|
-
|
|
83
|
-
- [Learn the template syntax]({base}/docs/custom-macros/ts-quote)
|
|
57
|
+
``` > **Note:** The import macro comment tells Macroforge which package provides the macro. ## Getting Started
|
|
58
|
+
Follow these guides to create your own macros:
|
|
59
|
+
- [Set up a Rust macro crate](../docs/custom-macros/rust-setup)
|
|
60
|
+
- [Learn the #[ts_macro_derive] attribute](../docs/custom-macros/ts-macro-derive)
|
|
61
|
+
- [Learn the template syntax](../docs/custom-macros/ts-quote)
|
|
@@ -1,32 +1,20 @@
|
|
|
1
1
|
# Rust Setup
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Node.js 24 or later
|
|
10
|
-
|
|
11
|
-
- NAPI-RS CLI: `cargo install macroforge_ts`
|
|
12
|
-
|
|
13
|
-
## Create the Project
|
|
14
|
-
|
|
15
|
-
```bash
|
|
2
|
+
*Create a new Rust crate that will contain your custom macros. This crate compiles to a native Node.js addon.*
|
|
3
|
+
## Prerequisites
|
|
4
|
+
- Rust toolchain (1.88 or later)
|
|
5
|
+
- Node.js 24 or later
|
|
6
|
+
- NAPI-RS CLI: `cargo install macroforge_ts`
|
|
7
|
+
## Create the Project
|
|
8
|
+
```
|
|
16
9
|
# Create a new directory
|
|
17
10
|
mkdir my-macros
|
|
18
11
|
cd my-macros
|
|
19
12
|
|
|
20
13
|
# Initialize with NAPI-RS
|
|
21
14
|
napi new --platform --name my-macros
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Update your `Cargo.toml` with the required dependencies:
|
|
27
|
-
|
|
28
|
-
`Cargo.toml`
|
|
29
|
-
```toml
|
|
15
|
+
``` ## Configure Cargo.toml
|
|
16
|
+
Update your `Cargo.toml` with the required dependencies:
|
|
17
|
+
```
|
|
30
18
|
[package]
|
|
31
19
|
name = "my-macros"
|
|
32
20
|
version = "0.1.0"
|
|
@@ -46,21 +34,13 @@ napi-build = "2"
|
|
|
46
34
|
[profile.release]
|
|
47
35
|
lto = true
|
|
48
36
|
strip = true
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Create build.rs
|
|
52
|
-
|
|
53
|
-
`build.rs`
|
|
54
|
-
```rust
|
|
37
|
+
``` ## Create build.rs
|
|
38
|
+
```
|
|
55
39
|
fn main() {
|
|
56
40
|
napi_build::setup();
|
|
57
41
|
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Create src/lib.rs
|
|
61
|
-
|
|
62
|
-
`src/lib.rs`
|
|
63
|
-
```rust
|
|
42
|
+
``` ## Create src/lib.rs
|
|
43
|
+
```
|
|
64
44
|
use macroforge_ts::macros::{ts_macro_derive, body};
|
|
65
45
|
use macroforge_ts::ts_syn::{
|
|
66
46
|
Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input,
|
|
@@ -91,12 +71,8 @@ pub fn derive_json(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
|
|
|
91
71
|
)),
|
|
92
72
|
}
|
|
93
73
|
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Create package.json
|
|
97
|
-
|
|
98
|
-
`package.json`
|
|
99
|
-
```json
|
|
74
|
+
``` ## Create package.json
|
|
75
|
+
```
|
|
100
76
|
{
|
|
101
77
|
"name": "@my-org/macros",
|
|
102
78
|
"version": "0.1.0",
|
|
@@ -121,11 +97,8 @@ pub fn derive_json(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
|
|
|
121
97
|
"@napi-rs/cli": "^3.0.0-alpha.0"
|
|
122
98
|
}
|
|
123
99
|
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Build the Package
|
|
127
|
-
|
|
128
|
-
```bash
|
|
100
|
+
``` ## Build the Package
|
|
101
|
+
```
|
|
129
102
|
# Build the native addon
|
|
130
103
|
npm run build
|
|
131
104
|
|
|
@@ -133,13 +106,7 @@ npm run build
|
|
|
133
106
|
# - index.js (JavaScript bindings)
|
|
134
107
|
# - index.d.ts (TypeScript types)
|
|
135
108
|
# - *.node (native binary)
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
## Next Steps
|
|
142
|
-
|
|
143
|
-
- <a href="{base}/docs/custom-macros/ts-macro-derive" >Learn the #[ts_macro_derive] attribute</a >
|
|
144
|
-
|
|
145
|
-
- <a href="{base}/docs/custom-macros/ts-quote" >Master the template syntax</a >
|
|
109
|
+
``` **Tip For cross-platform builds, use GitHub Actions with the NAPI-RS CI template. ## Next Steps
|
|
110
|
+
- [Learn the #[ts_macro_derive] attribute](../../docs/custom-macros/ts-macro-derive)
|
|
111
|
+
- [Master the template syntax](../../docs/custom-macros/ts-quote)
|
|
112
|
+
**
|