@macroforge/mcp-server 0.1.30 → 0.1.31

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.
@@ -1,83 +1,131 @@
1
1
  ## Quick Reference
2
2
 
3
3
  | `@{expr}`
4
- | Interpolate a Rust expression (adds space after)
5
-
6
- | `{| content |}`
7
- | Ident block: concatenates without spaces (e.g., `{|get@{name}|}` → `getUser`)
8
-
9
- | `&#123;> comment <&#125;`
10
- | Block comment: outputs `/* comment */`
11
-
12
- | `&#123;>> doc <<&#125;`
13
- | Doc comment: outputs `/** doc */` (for JSDoc)
14
-
15
- | `@@&#123;`
16
- | Escape for literal `@&#123;` (e.g., `"@@&#123;foo&#125;"` → `@&#123;foo&#125;`)
17
-
18
- | `"text @&#123;expr&#125;"`
19
- | String interpolation (auto-detected)
20
-
21
- | `"'^template $&#123;js&#125;^'"`
22
- | JS backtick template literal (outputs ``template $&#123;js&#125;``)
23
-
24
- | `&#123;#if cond&#125;...&#123;/if&#125;`
25
- | Conditional block
26
-
27
- | `&#123;#if cond&#125;...&#123;:else&#125;...&#123;/if&#125;`
28
- | Conditional with else
29
-
30
- | `&#123;#if a&#125;...&#123;:else if b&#125;...&#123;:else&#125;...&#123;/if&#125;`
31
- | Full if/else-if/else chain
32
-
33
- | `&#123;#if let pattern = expr&#125;...&#123;/if&#125;`
34
- | Pattern matching if-let
35
-
36
- | `&#123;#match expr&#125;&#123;:case pattern&#125;...&#123;/match&#125;`
37
- | Match expression with case arms
38
-
39
- | `&#123;#for item in list&#125;...&#123;/for&#125;`
40
- | Iterate over a collection
41
-
42
- | `&#123;#while cond&#125;...&#123;/while&#125;`
43
- | While loop
44
-
45
- | `&#123;#while let pattern = expr&#125;...&#123;/while&#125;`
46
- | While-let pattern matching loop
47
-
48
- | `&#123;$let name = expr&#125;`
49
- | Define a local constant
50
-
51
- | `&#123;$let mut name = expr&#125;`
52
- | Define a mutable local variable
53
-
54
- | `&#123;$do expr&#125;`
55
- | Execute a side-effectful expression
56
-
57
- | `&#123;$typescript stream&#125;`
58
- | Inject a TsStream, preserving its source and runtime_patches (imports)
59
-
60
- **Note:** A single `@` not followed by `&#123;` passes through unchanged (e.g., `email@domain.com` works as expected).
61
-
62
- ## Interpolation: `@&#123;expr&#125;`
63
-
64
- Insert Rust expressions into the generated TypeScript:
65
-
66
- ```rust
67
- let class_name = "User";
68
- let method = "toString";
69
-
70
- let code = ts_template! {
71
- @{class_name}.prototype.@{method} = function() {
72
- return "User instance";
73
- };
74
- };
75
- ```
76
-
77
- **Generates:**
78
-
79
- ```typescript
80
- User.prototype.toString = function () {
81
- return "User instance";
82
- };
83
- ```
4
+ | Interpolate a Rust expression (adds space after)
5
+
6
+
7
+
8
+ | `&#123;| content |&#125;`
9
+ | Ident block: concatenates without spaces (e.g., <code
10
+ >&#123;|get@&#123;name&#125;|&#125;</code
11
+ >
12
+ `getUser`)</td
13
+ >
14
+
15
+
16
+
17
+ <td>`&#123;> "comment" <&#125;`
18
+ | Block comment: outputs `/* comment */` (string preserves
19
+ whitespace)</td
20
+ >
21
+
22
+
23
+
24
+ <td>`&#123;>> "doc" <<&#125;`
25
+ | Doc comment: outputs `/** doc */` (string preserves whitespace)</td
26
+ >
27
+
28
+
29
+
30
+ <td>`@@&#123;`
31
+ | Escape for literal `@&#123;` (e.g.,
32
+ `"@@&#123;foo&#125;"`
33
+ `@&#123;foo&#125;`)</td
34
+ >
35
+
36
+
37
+
38
+ <td>`"text @&#123;expr&#125;"`
39
+ | String interpolation (auto-detected)
40
+
41
+
42
+
43
+ | `"'^template $&#123;js&#125;^'"`
44
+ | JS backtick template literal (outputs <code
45
+ >`template $&#123;js&#125;`</code
46
+ >)</td
47
+ >
48
+
49
+
50
+
51
+ <td>`&#123;#if cond&#125;...&#123;/if&#125;`
52
+ | Conditional block
53
+
54
+
55
+
56
+ | <code
57
+ >&#123;#if cond&#125;...&#123;:else&#125;...&#123;/if&#125;</code
58
+ ></td
59
+ >
60
+ <td>Conditional with else
61
+
62
+
63
+
64
+ | <code
65
+ >&#123;#if a&#125;...&#123;:else if
66
+ b&#125;...&#123;:else&#125;...&#123;/if&#125;</code
67
+ ></td
68
+ >
69
+ <td>Full if/else-if/else chain
70
+
71
+
72
+
73
+ | <code
74
+ >&#123;#if let pattern = expr&#125;...&#123;/if&#125;</code
75
+ ></td
76
+ >
77
+ <td>Pattern matching if-let
78
+
79
+
80
+
81
+ | <code
82
+ >&#123;#match expr&#125;&#123;:case
83
+ pattern&#125;...&#123;/match&#125;</code
84
+ ></td
85
+ >
86
+ <td>Match expression with case arms
87
+
88
+
89
+
90
+ | <code>&#123;#for item in list&#125;...&#123;/for&#125;</code
91
+ ></td
92
+ >
93
+ <td>Iterate over a collection
94
+
95
+
96
+
97
+ | `&#123;#while cond&#125;...&#123;/while&#125;`
98
+ | While loop
99
+
100
+
101
+
102
+ | <code
103
+ >&#123;#while let pattern = expr&#125;...&#123;/while&#125;</code
104
+ ></td
105
+ >
106
+ <td>While-let pattern matching loop
107
+
108
+
109
+
110
+ | `&#123;$let name = expr&#125;`
111
+ | Define a local constant
112
+
113
+
114
+
115
+ | `&#123;$let mut name = expr&#125;`
116
+ | Define a mutable local variable
117
+
118
+
119
+
120
+ | `&#123;$do expr&#125;`
121
+ | Execute a side-effectful expression
122
+
123
+
124
+
125
+ | `&#123;$typescript stream&#125;`
126
+ <td
127
+ >Inject a TsStream, preserving its source and runtime_patches
128
+ (imports)</td
129
+ >
130
+
131
+ **Note:** A single `@` not followed by `&#123;` passes through unchanged (e.g., `email@domain.com` works as expected).
@@ -16,8 +16,72 @@ Common uses for `&#123;$do&#125;`:
16
16
 
17
17
  - Incrementing counters: `&#123;$do i += 1&#125;`
18
18
 
19
- - Building collections: `&#123;$do vec.push(item)&#125;`
19
+ - Building collections: `&#123;$do vec.push(item)&#125;`
20
20
 
21
- - Setting flags: `&#123;$do found = true&#125;`
21
+ - Setting flags: `&#123;$do found = true&#125;`
22
22
 
23
- - Any mutating operation
23
+ - Any mutating operation
24
+
25
+ <h2 id="typescript-injection">
26
+ TsStream Injection: `&#123;$typescript&#125;`
27
+ </h2>
28
+
29
+ Inject another TsStream into your template, preserving both its source code and runtime patches (like imports added via `add_import()`):
30
+
31
+ ```rust
32
+ // Create a helper method with its own import
33
+ let mut helper = body! {
34
+ validateEmail(email: string): boolean {
35
+ return Result.ok(true);
36
+ }
37
+ };
38
+ helper.add_import("Result", "macroforge/utils");
39
+
40
+ // Inject the helper into the main template
41
+ let result = body! {
42
+ {$typescript helper}
43
+
44
+ process(data: Record<string, unknown>): void {
45
+ // ...
46
+ }
47
+ };
48
+ // result now includes helper's source AND its Result import
49
+ ```
50
+
51
+ This is essential for composing multiple macro outputs while preserving imports and patches:
52
+
53
+ ```rust
54
+ let extra_methods = if include_validation {
55
+ Some(body! {
56
+ validate(): boolean { return true; }
57
+ })
58
+ } else {
59
+ None
60
+ };
61
+
62
+ body! {
63
+ mainMethod(): void {}
64
+
65
+ {#if let Some(methods) = extra_methods}
66
+ {$typescript methods}
67
+ {/if}
68
+ }
69
+ ```
70
+
71
+ ## Escape Syntax
72
+
73
+ If you need a literal `@&#123;` in your output (not interpolation), use `@@&#123;`:
74
+
75
+ ```rust
76
+ ts_template! {
77
+ // This outputs a literal @{foo}
78
+ const example = "Use @@{foo} for templates";
79
+ }
80
+ ```
81
+
82
+ **Generates:**
83
+
84
+ ```typescript
85
+ // This outputs a literal @{foo}
86
+ const example = "Use @{foo} for templates";
87
+ ```
@@ -9,7 +9,7 @@ let mut helper = body! {
9
9
  return Result.ok(true);
10
10
  }
11
11
  };
12
- helper.add_import("Result", "macroforge/result");
12
+ helper.add_import("Result", "macroforge/utils");
13
13
 
14
14
  // Inject the helper into the main template
15
15
  let result = body! {
@@ -45,37 +45,4 @@ let code = ts_template! {
45
45
  result.@{next_field.name} = this.@{next_field.name};
46
46
  {/while}
47
47
  };
48
- ```
49
-
50
- ## Local Constants: `&#123;$let&#125;`
51
-
52
- Define local variables within the template scope:
53
-
54
- ```rust
55
- let items = vec![("user", "User"), ("post", "Post")];
56
-
57
- let code = ts_template! {
58
- {#for (key, class_name) in items}
59
- {$let upper = class_name.to_uppercase()}
60
- console.log("Processing @{upper}");
61
- const @{key} = new @{class_name}();
62
- {/for}
63
- };
64
- ```
65
-
66
- This is useful for computing derived values inside loops without cluttering the Rust code.
67
-
68
- ## Mutable Variables: `&#123;$let mut&#125;`
69
-
70
- When you need to modify a variable within the template (e.g., in a `while` loop), use `&#123;$let mut&#125;`:
71
-
72
- ```rust
73
- let code = ts_template! {
74
- {$let mut count = 0}
75
- {#for item in items}
76
- console.log("Item @{count}: @{item}");
77
- {$do count += 1}
78
- {/for}
79
- console.log("Total: @{count}");
80
- };
81
48
  ```