@macroforge/mcp-server 0.1.17 → 0.1.21

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.
@@ -4,37 +4,14 @@
4
4
 
5
5
  ## Basic Usage
6
6
 
7
- ```typescript
8
- /** @derive(Serialize) */
9
- class User {
10
- name: string;
11
- age: number;
12
- createdAt: Date;
13
-
14
- constructor(name: string, age: number) {
15
- this.name = name;
16
- this.age = age;
17
- this.createdAt = new Date();
18
- }
19
- }
7
+ <MacroExample before={data.examples.basic.before} after={data.examples.basic.after} />
20
8
 
9
+ ```typescript
21
10
  const user = new User("Alice", 30);
22
11
  console.log(JSON.stringify(user));
23
12
  // {"name":"Alice","age":30,"createdAt":"2024-01-15T10:30:00.000Z"}
24
13
  ```
25
14
 
26
- ## Generated Code
27
-
28
- ```typescript
29
- toJSON(): Record<string, unknown> {
30
- const result: Record<string, unknown> = {};
31
- result["name"] = this.name;
32
- result["age"] = this.age;
33
- result["createdAt"] = this.createdAt.toISOString();
34
- return result;
35
- }
36
- ```
37
-
38
15
  ## Automatic Type Handling
39
16
 
40
17
  Serialize automatically handles various TypeScript types:
@@ -57,32 +34,15 @@ Serialize automatically handles various TypeScript types:
57
34
  | Nested objects
58
35
  | Calls `toJSON()` if available
59
36
 
60
- ```typescript
61
- /** @derive(Serialize) */
62
- class DataContainer {
63
- items: string[];
64
- metadata: Map<string, number>;
65
- tags: Set<string>;
66
- nested: User;
67
- }
68
- ```
69
-
70
37
  ## Serde Options
71
38
 
72
39
  Use the `@serde` decorator for fine-grained control over serialization:
73
40
 
74
41
  ### Renaming Fields
75
42
 
76
- ```typescript
77
- /** @derive(Serialize) */
78
- class User {
79
- /** @serde({ rename: "user_id" }) */
80
- id: string;
81
-
82
- /** @serde({ rename: "full_name" }) */
83
- name: string;
84
- }
43
+ <MacroExample before={data.examples.rename.before} after={data.examples.rename.after} />
85
44
 
45
+ ```typescript
86
46
  const user = new User();
87
47
  user.id = "123";
88
48
  user.name = "Alice";
@@ -92,19 +52,7 @@ console.log(JSON.stringify(user));
92
52
 
93
53
  ### Skipping Fields
94
54
 
95
- ```typescript
96
- /** @derive(Serialize) */
97
- class User {
98
- name: string;
99
- email: string;
100
-
101
- /** @serde({ skip: true }) */
102
- password: string;
103
-
104
- /** @serde({ skip_serializing: true }) */
105
- internalId: string;
106
- }
107
- ```
55
+ <MacroExample before={data.examples.skip.before} after={data.examples.skip.after} />
108
56
 
109
57
  <Alert type="tip" title="skip vs skip_serializing">
110
58
  Use `skip: true` to exclude from both serialization and deserialization.
@@ -115,15 +63,13 @@ Use `skip_serializing: true` to only skip during serialization.
115
63
 
116
64
  Apply a naming convention to all fields at the container level:
117
65
 
118
- ```typescript
119
- /** @derive(Serialize) */
66
+ <InteractiveMacro code={`/** @derive(Serialize) */
120
67
  /** @serde({ rename_all: "camelCase" }) */
121
68
  class ApiResponse {
122
- user_name: string; // becomes "userName"
123
- created_at: Date; // becomes "createdAt"
124
- is_active: boolean; // becomes "isActive"
125
- }
126
- ```
69
+ user_name: string;
70
+ created_at: Date;
71
+ is_active: boolean;
72
+ }`} />
127
73
 
128
74
  Supported conventions:
129
75
 
@@ -139,8 +85,7 @@ Supported conventions:
139
85
 
140
86
  ### Flattening Nested Objects
141
87
 
142
- ```typescript
143
- /** @derive(Serialize) */
88
+ <InteractiveMacro code={`/** @derive(Serialize) */
144
89
  class Address {
145
90
  city: string;
146
91
  zip: string;
@@ -152,8 +97,9 @@ class User {
152
97
 
153
98
  /** @serde({ flatten: true }) */
154
99
  address: Address;
155
- }
100
+ }`} />
156
101
 
102
+ ```typescript
157
103
  const user = new User();
158
104
  user.name = "Alice";
159
105
  user.address = { city: "NYC", zip: "10001" };
@@ -191,25 +137,9 @@ console.log(JSON.stringify(user));
191
137
 
192
138
  Serialize also works with interfaces. For interfaces, a namespace is generated with a `toJSON` function:
193
139
 
194
- ```typescript
195
- /** @derive(Serialize) */
196
- interface ApiResponse {
197
- status: number;
198
- message: string;
199
- timestamp: Date;
200
- }
201
-
202
- // Generated:
203
- // export namespace ApiResponse {
204
- // export function toJSON(self: ApiResponse): Record<string, unknown> {
205
- // const result: Record<string, unknown> = {};
206
- // result["status"] = self.status;
207
- // result["message"] = self.message;
208
- // result["timestamp"] = self.timestamp.toISOString();
209
- // return result;
210
- // }
211
- // }
140
+ <MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
212
141
 
142
+ ```typescript
213
143
  const response: ApiResponse = {
214
144
  status: 200,
215
145
  message: "OK",
@@ -224,35 +154,23 @@ console.log(JSON.stringify(ApiResponse.toJSON(response)));
224
154
 
225
155
  Serialize also works with enums. The `toJSON` function returns the underlying enum value (string or number):
226
156
 
227
- ```typescript
228
- /** @derive(Serialize) */
229
- enum Status {
230
- Active = "active",
231
- Inactive = "inactive",
232
- Pending = "pending",
233
- }
234
-
235
- // Generated:
236
- // export namespace Status {
237
- // export function toJSON(value: Status): string | number {
238
- // return value;
239
- // }
240
- // }
157
+ <MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
241
158
 
159
+ ```typescript
242
160
  console.log(Status.toJSON(Status.Active)); // "active"
243
161
  console.log(Status.toJSON(Status.Pending)); // "pending"
244
162
  ```
245
163
 
246
164
  Works with numeric enums too:
247
165
 
248
- ```typescript
249
- /** @derive(Serialize) */
166
+ <InteractiveMacro code={`/** @derive(Serialize) */
250
167
  enum Priority {
251
168
  Low = 1,
252
169
  Medium = 2,
253
170
  High = 3,
254
- }
171
+ }`} />
255
172
 
173
+ ```typescript
256
174
  console.log(Priority.toJSON(Priority.High)); // 3
257
175
  ```
258
176
 
@@ -260,25 +178,9 @@ console.log(Priority.toJSON(Priority.High)); // 3
260
178
 
261
179
  Serialize works with type aliases. For object types, fields are serialized with full type handling:
262
180
 
263
- ```typescript
264
- /** @derive(Serialize) */
265
- type UserProfile = {
266
- id: string;
267
- name: string;
268
- createdAt: Date;
269
- };
270
-
271
- // Generated:
272
- // export namespace UserProfile {
273
- // export function toJSON(value: UserProfile): Record<string, unknown> {
274
- // const result: Record<string, unknown> = {};
275
- // result["id"] = value.id;
276
- // result["name"] = value.name;
277
- // result["createdAt"] = value.createdAt.toISOString();
278
- // return result;
279
- // }
280
- // }
181
+ <MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
281
182
 
183
+ ```typescript
282
184
  const profile: UserProfile = {
283
185
  id: "123",
284
186
  name: "Alice",
@@ -291,10 +193,10 @@ console.log(JSON.stringify(UserProfile.toJSON(profile)));
291
193
 
292
194
  For union types, the value is returned directly:
293
195
 
294
- ```typescript
295
- /** @derive(Serialize) */
296
- type ApiStatus = "loading" | "success" | "error";
196
+ <InteractiveMacro code={`/** @derive(Serialize) */
197
+ type ApiStatus = "loading" | "success" | "error";`} />
297
198
 
199
+ ```typescript
298
200
  console.log(ApiStatus.toJSON("success")); // "success"
299
201
  ```
300
202
 
@@ -302,13 +204,13 @@ console.log(ApiStatus.toJSON("success")); // "success"
302
204
 
303
205
  Use both Serialize and Deserialize for complete JSON round-trip support:
304
206
 
305
- ```typescript
306
- /** @derive(Serialize, Deserialize) */
207
+ <InteractiveMacro code={`/** @derive(Serialize, Deserialize) */
307
208
  class User {
308
209
  name: string;
309
210
  createdAt: Date;
310
- }
211
+ }`} />
311
212
 
213
+ ```typescript
312
214
  // Serialize
313
215
  const user = new User();
314
216
  user.name = "Alice";
@@ -4,21 +4,12 @@
4
4
 
5
5
  ## Overview
6
6
 
7
- ```text
8
- ┌─────────────────────────────────────────────────────────┐
9
- │ Node.js / Vite │
10
- ├─────────────────────────────────────────────────────────┤
11
- │ NAPI-RS Bindings │
12
- ├─────────────────────────────────────────────────────────┤
13
- │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │
14
- │ │ ts_syn │ │ ts_quote │ │ts_macro_derive│ │
15
- │ │ (parsing) │ │ (templating) │ │ (proc-macro) │ │
16
- │ └─────────────┘ └──────────────┘ └───────────────┘ │
17
- ├─────────────────────────────────────────────────────────┤
18
- │ SWC Core │
19
- │ (TypeScript parsing & codegen) │
20
- └─────────────────────────────────────────────────────────┘
21
- ```
7
+ <ArchitectureDiagram layers={[
8
+ { title: "Node.js / Vite" },
9
+ { title: "NAPI-RS Bindings" },
10
+ { title: "Macro Crates", items: ["macroforge_ts_syn", "macroforge_ts_quote", "macroforge_ts_macros"] },
11
+ { title: "SWC Core", items: ["TypeScript parsing & codegen"] }
12
+ ]} />
22
13
 
23
14
  ## Core Components
24
15
 
@@ -32,7 +23,7 @@ The foundation layer provides:
32
23
 
33
24
  - Code generation (AST → source code)
34
25
 
35
- ### ts_syn
26
+ ### macroforge_ts_syn
36
27
 
37
28
  A Rust crate that provides:
38
29
 
@@ -42,7 +33,7 @@ A Rust crate that provides:
42
33
 
43
34
  - Derive input structures (class fields, decorators, etc.)
44
35
 
45
- ### ts_quote
36
+ ### macroforge_ts_quote
46
37
 
47
38
  Template-based code generation similar to Rust's `quote!`:
48
39
 
@@ -52,7 +43,7 @@ Template-based code generation similar to Rust's `quote!`:
52
43
 
53
44
  - Control flow: `{"{#for}"}`, `{"{#if}"}`, `{"{$let}"}`
54
45
 
55
- ### ts_macro_derive
46
+ ### macroforge_ts_macros
56
47
 
57
48
  The procedural macro attribute for defining derive macros:
58
49
 
@@ -74,33 +65,16 @@ Bridges Rust and Node.js:
74
65
 
75
66
  ## Data Flow
76
67
 
77
- ```text
78
- 1. Source Code (TypeScript with @derive)
79
-
80
-
81
- 2. NAPI-RS receives JavaScript string
82
-
83
-
84
- 3. SWC parses to AST
85
-
86
-
87
- 4. Macro expander finds @derive decorators
88
-
89
-
90
- 5. For each macro:
91
- │ a. Extract class/interface data
92
- │ b. Run macro function
93
- │ c. Generate new AST nodes
94
-
95
-
96
- 6. Merge generated nodes into AST
97
-
98
-
99
- 7. SWC generates source code
100
-
101
-
102
- 8. Return to JavaScript with source mapping
103
- ```
68
+ <Flowchart steps={[
69
+ { title: "1. Source Code", description: "TypeScript with @derive" },
70
+ { title: "2. NAPI-RS", description: "receives JavaScript string" },
71
+ { title: "3. SWC Parser", description: "parses to AST" },
72
+ { title: "4. Macro Expander", description: "finds @derive decorators" },
73
+ { title: "5. For Each Macro", description: "extract data, run macro, generate AST nodes" },
74
+ { title: "6. Merge", description: "generated nodes into AST" },
75
+ { title: "7. SWC Codegen", description: "generates source code" },
76
+ { title: "8. Return", description: "to JavaScript with source mapping" }
77
+ ]} />
104
78
 
105
79
  ## Performance Characteristics
106
80
 
@@ -117,19 +91,14 @@ Bridges Rust and Node.js:
117
91
  For custom macro development, `macroforge_ts` re-exports everything you need:
118
92
 
119
93
  ```rust
120
- // All available via macroforge_ts::*
121
- pub extern crate ts_syn; // AST types, parsing
122
- pub extern crate ts_quote; // Code generation templates
123
- pub extern crate ts_macro_derive; // #[ts_macro_derive] attribute
124
- pub extern crate inventory; // Macro registration
125
- pub extern crate serde_json; // Serialization
126
- pub extern crate napi; // Node.js bindings
127
- pub extern crate napi_derive; // NAPI proc-macros
128
-
129
- // SWC modules
130
- pub use ts_syn::swc_core;
131
- pub use ts_syn::swc_common;
132
- pub use ts_syn::swc_ecma_ast;
94
+ // Convenient re-exports for macro development
95
+ use macroforge_ts::macros::{ts_macro_derive, body, ts_template, above, below, signature};
96
+ use macroforge_ts::ts_syn::{Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input};
97
+
98
+ // Also available: raw crate access and SWC modules
99
+ use macroforge_ts::swc_core;
100
+ use macroforge_ts::swc_common;
101
+ use macroforge_ts::swc_ecma_ast;
133
102
  ```
134
103
 
135
104
  ## Next Steps
@@ -10,13 +10,10 @@ Macroforge uses JSDoc comments for all macro annotations. This ensures compatibi
10
10
 
11
11
  The `@derive` decorator triggers macro expansion on a class or interface:
12
12
 
13
- ```typescript
14
- /** @derive(MacroName) */
15
- class MyClass { }
16
-
17
- /** @derive(Debug, Clone, PartialEq) */
18
- class AnotherClass { }
19
- ```
13
+ <InteractiveMacro code={`/** @derive(Debug) */
14
+ class MyClass {
15
+ value: string;
16
+ }`} />
20
17
 
21
18
  Syntax rules:
22
19
 
@@ -28,16 +25,11 @@ Syntax rules:
28
25
 
29
26
  - Multiple `@derive` statements can be stacked
30
27
 
31
- ```typescript
32
- // Single derive with multiple macros
33
- /** @derive(Debug, Clone) */
34
- class User { }
35
-
36
- // Multiple derive statements (equivalent)
37
- /** @derive(Debug) */
38
- /** @derive(Clone) */
39
- class User { }
40
- ```
28
+ <InteractiveMacro code={`/** @derive(Debug, Clone) */
29
+ class User {
30
+ name: string;
31
+ email: string;
32
+ }`} />
41
33
 
42
34
  ### The import macro Statement
43
35
 
@@ -68,36 +60,15 @@ class User {
68
60
  }
69
61
  ```
70
62
 
71
- >
72
- > Built-in macros (Debug, Clone, Default, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize) do not require an import statement.
63
+ <Alert type="note" title="Built-in macros">
64
+ Built-in macros (Debug, Clone, Default, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize) do not require an import statement.
65
+ </Alert>
73
66
 
74
67
  ### Field Attributes
75
68
 
76
69
  Macros can define field-level attributes to customize behavior per field:
77
70
 
78
- ```typescript
79
- /** @attributeName(options) */
80
- ```
81
-
82
- The attribute name and available options depend on the macro. Common patterns:
83
-
84
- ```typescript
85
- /** @derive(Debug, Serialize) */
86
- class User {
87
- /** @debug({ rename: "userId" }) */
88
- /** @serde({ rename: "user_id" }) */
89
- id: number;
90
-
91
- name: string;
92
-
93
- /** @debug({ skip: true }) */
94
- /** @serde({ skip: true }) */
95
- password: string;
96
-
97
- /** @serde({ flatten: true }) */
98
- metadata: Record<string, unknown>;
99
- }
100
- ```
71
+ <MacroExample before={data.examples.fieldAttributes.before} after={data.examples.fieldAttributes.after} />
101
72
 
102
73
  Syntax rules:
103
74
 
@@ -149,10 +120,11 @@ The derive system works on:
149
120
 
150
121
  - **Classes**: The primary target for derive macros
151
122
 
152
- - **Interfaces**: Some macros can generate companion functions
123
+ - **Interfaces**: Macros generate companion namespace functions
124
+
125
+ - **Enums**: Macros generate namespace functions for enum values
153
126
 
154
- > **Warning:**
155
- > Enums are not currently supported by the derive system.
127
+ - **Type aliases**: Both object types and union types are supported
156
128
 
157
129
  ## Built-in vs Custom Macros
158
130
 
@@ -14,22 +14,7 @@ Unlike runtime solutions that use reflection or proxies, Macroforge expands macr
14
14
 
15
15
  4. **Output**: The transformed TypeScript is written out, ready for normal compilation
16
16
 
17
- ```typescript
18
- // Your source code
19
- /** @derive(Debug) */
20
- class User {
21
- name: string;
22
- }
23
-
24
- // After macro expansion
25
- class User {
26
- name: string;
27
-
28
- toString(): string {
29
- return \`User { name: \${this.name} }\`;
30
- }
31
- }
32
- ```
17
+ <MacroExample before={data.examples.basic.before} after={data.examples.basic.after} />
33
18
 
34
19
  ## Zero Runtime Overhead
35
20
 
@@ -55,43 +40,19 @@ Macroforge tracks the relationship between your source code and the expanded out
55
40
 
56
41
  - IDE features like "go to definition" work as expected
57
42
 
58
- > **Note:**
59
- > The TypeScript plugin uses source mapping to show errors at the `@derive` decorator position, not in the generated code.
43
+ <Alert type="info" title="Error positioning">
44
+ The TypeScript plugin uses source mapping to show errors at the `@derive` decorator position, not in the generated code.
45
+ </Alert>
60
46
 
61
47
  ## Execution Flow
62
48
 
63
- ```text
64
- ┌─────────────────────────────────────────────────────────┐
65
- │ Your Source Code │
66
- │ (with @derive decorators) │
67
- └───────────────────────┬─────────────────────────────────┘
68
-
69
-
70
- ┌─────────────────────────────────────────────────────────┐
71
- │ SWC Parser │
72
- │ (TypeScript → AST) │
73
- └───────────────────────┬─────────────────────────────────┘
74
-
75
-
76
- ┌─────────────────────────────────────────────────────────┐
77
- │ Macro Expansion Engine │
78
- │ - Finds @derive decorators │
79
- │ - Runs registered macros │
80
- │ - Generates new AST nodes │
81
- └───────────────────────┬─────────────────────────────────┘
82
-
83
-
84
- ┌─────────────────────────────────────────────────────────┐
85
- │ Code Generator │
86
- │ (AST → TypeScript) │
87
- └───────────────────────┬─────────────────────────────────┘
88
-
89
-
90
- ┌─────────────────────────────────────────────────────────┐
91
- │ Expanded TypeScript │
92
- │ (ready for normal compilation) │
93
- └─────────────────────────────────────────────────────────┘
94
- ```
49
+ <Flowchart steps={[
50
+ { title: "Your Source Code", description: "with @derive decorators" },
51
+ { title: "SWC Parser", description: "TypeScript → AST" },
52
+ { title: "Macro Expansion Engine", description: "Finds @derive decorators, runs macros, generates new AST nodes" },
53
+ { title: "Code Generator", description: "AST → TypeScript" },
54
+ { title: "Expanded TypeScript", description: "ready for normal compilation" }
55
+ ]} />
95
56
 
96
57
  ## Integration Points
97
58
 
@@ -10,15 +10,14 @@ Custom macros are written in Rust and compiled to native Node.js addons. The pro
10
10
 
11
11
  2. Defining macro functions with `#[ts_macro_derive]`
12
12
 
13
- 3. Using `ts_quote` to generate TypeScript code
13
+ 3. Using `macroforge_ts_quote` to generate TypeScript code
14
14
 
15
15
  4. Building and publishing as an npm package
16
16
 
17
17
  ## Quick Example
18
18
 
19
19
  ```rust
20
- use macroforge_ts::ts_macro_derive::ts_macro_derive;
21
- use macroforge_ts::ts_quote::body;
20
+ use macroforge_ts::macros::{ts_macro_derive, body};
22
21
  use macroforge_ts::ts_syn::{Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input};
23
22
 
24
23
  #[ts_macro_derive(
@@ -79,6 +78,6 @@ Follow these guides to create your own macros:
79
78
 
80
79
  - [Set up a Rust macro crate]({base}/docs/custom-macros/rust-setup)
81
80
 
82
- - [Use the ts_macro_derive attribute]({base}/docs/custom-macros/ts-macro-derive)
81
+ - [Learn the #[ts_macro_derive] attribute]({base}/docs/custom-macros/ts-macro-derive)
83
82
 
84
- - [Learn the ts_quote template syntax]({base}/docs/custom-macros/ts-quote)
83
+ - [Learn the template syntax]({base}/docs/custom-macros/ts-quote)
@@ -61,8 +61,7 @@ fn main() {
61
61
 
62
62
  `src/lib.rs`
63
63
  ```rust
64
- use macroforge_ts::ts_macro_derive::ts_macro_derive;
65
- use macroforge_ts::ts_quote::body;
64
+ use macroforge_ts::macros::{ts_macro_derive, body};
66
65
  use macroforge_ts::ts_syn::{
67
66
  Data, DeriveInput, MacroforgeError, TsStream, parse_ts_macro_input,
68
67
  };
@@ -141,6 +140,6 @@ npm run build
141
140
 
142
141
  ## Next Steps
143
142
 
144
- - [Learn the ts_macro_derive attribute]({base}/docs/custom-macros/ts-macro-derive)
143
+ - [Learn the #[ts_macro_derive] attribute]({base}/docs/custom-macros/ts-macro-derive)
145
144
 
146
- - [Master the ts_quote template syntax]({base}/docs/custom-macros/ts-quote)
145
+ - [Master the template syntax]({base}/docs/custom-macros/ts-quote)
@@ -5,7 +5,7 @@
5
5
  ## Basic Syntax
6
6
 
7
7
  ```rust
8
- use macroforge_ts::ts_macro_derive::ts_macro_derive;
8
+ use macroforge_ts::macros::ts_macro_derive;
9
9
  use macroforge_ts::ts_syn::{TsStream, MacroforgeError};
10
10
 
11
11
  #[ts_macro_derive(MacroName)]
@@ -70,7 +70,7 @@ pub fn my_macro(mut input: TsStream) -> Result<TsStream, MacroforgeError>
70
70
  Use `parse_ts_macro_input!` to convert the token stream:
71
71
 
72
72
  ```rust
73
- use macroforge_ts::ts_syn::{DeriveInput, Data, parse_ts_macro_input};
73
+ use macroforge_ts::ts_syn::{Data, DeriveInput, parse_ts_macro_input};
74
74
 
75
75
  #[ts_macro_derive(MyMacro)]
76
76
  pub fn my_macro(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
@@ -256,8 +256,7 @@ pub fn class_only(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
256
256
  ## Complete Example
257
257
 
258
258
  ```rust
259
- use macroforge_ts::ts_macro_derive::ts_macro_derive;
260
- use macroforge_ts::ts_quote::body;
259
+ use macroforge_ts::macros::{ts_macro_derive, body};
261
260
  use macroforge_ts::ts_syn::{
262
261
  Data, DeriveInput, FieldIR, MacroforgeError, TsStream, parse_ts_macro_input,
263
262
  };
@@ -304,4 +303,4 @@ pub fn derive_validate(mut input: TsStream) -> Result<TsStream, MacroforgeError>
304
303
 
305
304
  ## Next Steps
306
305
 
307
- - [Learn the ts_quote template syntax]({base}/docs/custom-macros/ts-quote)
306
+ - [Learn the template syntax]({base}/docs/custom-macros/ts-quote)
@@ -1,6 +1,6 @@
1
- # Template Syntax (ts_quote)
1
+ # Template Syntax
2
2
 
3
- *The `ts_quote` crate provides template-based code generation for TypeScript. The `ts_template!` macro uses Rust-inspired syntax for control flow and interpolation, making it easy to generate complex TypeScript code.*
3
+ *The `macroforge_ts_quote` crate provides template-based code generation for TypeScript. The `ts_template!` macro uses Rust-inspired syntax for control flow and interpolation, making it easy to generate complex TypeScript code.*
4
4
 
5
5
  ## Available Macros
6
6