@macroforge/mcp-server 0.1.23 → 0.1.25
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,13 +1,13 @@
|
|
|
1
1
|
# Default
|
|
2
2
|
|
|
3
|
-
*The `Default` macro generates a static `
|
|
3
|
+
*The `Default` macro generates a static `defaultValue()` factory method that creates instances with default field values. It works like Rust's `#[derive(Default)]` trait.*
|
|
4
4
|
|
|
5
5
|
## Basic Usage
|
|
6
6
|
|
|
7
7
|
<MacroExample before={data.examples.basic.before} after={data.examples.basic.after} />
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
const config = Config.
|
|
10
|
+
const config = Config.defaultValue();
|
|
11
11
|
console.log(config.host); // ""
|
|
12
12
|
console.log(config.port); // 0
|
|
13
13
|
console.log(config.enabled); // false
|
|
@@ -15,34 +15,65 @@ console.log(config.enabled); // false
|
|
|
15
15
|
|
|
16
16
|
## Automatic Default Values
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Like Rust's `Default` trait, the macro automatically determines default values for primitive types and common collections:
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
| `string` | `""` | `String::default()`
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
| `number` | `0` | `i32::default()`
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
| `boolean` | `false` | `bool::default()`
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
| `bigint` | `0n` | `i64::default()`
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
| `T[]` / `Array<T>` | `[]` | `Vec::default()`
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
| `Map<K, V>` | `new Map()` | `HashMap::default()`
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
| `Set<T>` | `new Set()` | `HashSet::default()`
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
| `Date` | `new Date()` | —
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
| `T | null` / `T | undefined` | `null` | `Option::default()`
|
|
37
|
+
|
|
38
|
+
| Custom types | **Error** | **Error** (needs `impl Default`)
|
|
39
|
+
|
|
40
|
+
## Nullable Types (like Rust's Option)
|
|
41
|
+
|
|
42
|
+
Just like Rust's `Option<T>` defaults to `None`, nullable TypeScript types automatically default to `null`:
|
|
43
|
+
|
|
44
|
+
<MacroExample before={data.examples.nullable.before} after={data.examples.nullable.after} />
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const user = User.defaultValue();
|
|
48
|
+
console.log(user.name); // ""
|
|
49
|
+
console.log(user.email); // null (nullable type)
|
|
50
|
+
console.log(user.age); // 0
|
|
51
|
+
console.log(user.metadata); // null (nullable type)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Custom Types Require @default
|
|
55
|
+
|
|
56
|
+
Just like Rust requires `impl Default` for custom types, Macroforge requires the `@default()` decorator on fields with non-primitive types:
|
|
57
|
+
|
|
58
|
+
<MacroExample before={data.examples.customType.before} after={data.examples.customType.after} />
|
|
59
|
+
|
|
60
|
+
<p class="text-red-500 text-sm mt-2">
|
|
61
|
+
Without `@default` on custom type fields, the macro will emit an error:
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
// Error: @derive(Default) cannot determine default for non-primitive fields.
|
|
66
|
+
// Add @default(value) to: settings, permissions
|
|
67
|
+
```
|
|
37
68
|
|
|
38
69
|
## Custom Default Values
|
|
39
70
|
|
|
40
|
-
Use the `@
|
|
71
|
+
Use the `@default()` decorator to specify custom default values for any field:
|
|
41
72
|
|
|
42
73
|
<MacroExample before={data.examples.custom.before} after={data.examples.custom.after} />
|
|
43
74
|
|
|
44
75
|
```typescript
|
|
45
|
-
const config = ServerConfig.
|
|
76
|
+
const config = ServerConfig.defaultValue();
|
|
46
77
|
console.log(config.host); // "localhost"
|
|
47
78
|
console.log(config.port); // 8080
|
|
48
79
|
console.log(config.enabled); // true
|
|
@@ -51,12 +82,12 @@ console.log(config.logLevels); // ["info", "error"]
|
|
|
51
82
|
|
|
52
83
|
## Interface Support
|
|
53
84
|
|
|
54
|
-
Default also works with interfaces. For interfaces, a namespace is generated with a `
|
|
85
|
+
Default also works with interfaces. For interfaces, a namespace is generated with a `defaultValue()` function:
|
|
55
86
|
|
|
56
87
|
<MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
|
|
57
88
|
|
|
58
89
|
```typescript
|
|
59
|
-
const origin = Point.
|
|
90
|
+
const origin = Point.defaultValue();
|
|
60
91
|
console.log(origin); // { x: 0, y: 0 }
|
|
61
92
|
```
|
|
62
93
|
|
|
@@ -67,7 +98,7 @@ Default works with enums. For enums, it returns the first variant as the default
|
|
|
67
98
|
<MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
|
|
68
99
|
|
|
69
100
|
```typescript
|
|
70
|
-
const defaultStatus = Status.
|
|
101
|
+
const defaultStatus = Status.defaultValue();
|
|
71
102
|
console.log(defaultStatus); // "pending"
|
|
72
103
|
```
|
|
73
104
|
|
|
@@ -78,7 +109,7 @@ Default works with type aliases. For object types, it creates an object with def
|
|
|
78
109
|
<MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
|
|
79
110
|
|
|
80
111
|
```typescript
|
|
81
|
-
const dims = Dimensions.
|
|
112
|
+
const dims = Dimensions.defaultValue();
|
|
82
113
|
console.log(dims); // { width: 0, height: 0 }
|
|
83
114
|
```
|
|
84
115
|
|
|
@@ -86,10 +117,10 @@ console.log(dims); // { width: 0, height: 0 }
|
|
|
86
117
|
|
|
87
118
|
<InteractiveMacro code={`/** @derive(Default, Debug, Clone, PartialEq) */
|
|
88
119
|
class User {
|
|
89
|
-
/** @
|
|
120
|
+
/** @default("Anonymous") */
|
|
90
121
|
name: string;
|
|
91
122
|
|
|
92
|
-
/** @
|
|
123
|
+
/** @default(0) */
|
|
93
124
|
age: number;
|
|
94
125
|
|
|
95
126
|
constructor(name: string, age: number) {
|
|
@@ -99,7 +130,7 @@ class User {
|
|
|
99
130
|
}`} />
|
|
100
131
|
|
|
101
132
|
```typescript
|
|
102
|
-
const user1 = User.
|
|
133
|
+
const user1 = User.defaultValue();
|
|
103
134
|
const user2 = user1.clone();
|
|
104
135
|
|
|
105
136
|
console.log(user1.toString()); // User { name: "Anonymous", age: 0 }
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
| `{| content |}`
|
|
21
21
|
| Ident block: concatenates without spaces (e.g., `{|get@{name}|}` → `getUser`)
|
|
22
22
|
|
|
23
|
+
| `{> comment <}`
|
|
24
|
+
| Block comment: outputs `/* comment */`
|
|
25
|
+
|
|
26
|
+
| `{>> doc <<}`
|
|
27
|
+
| Doc comment: outputs `/** doc */` (for JSDoc)
|
|
28
|
+
|
|
23
29
|
| `@@{`
|
|
24
30
|
| Escape for literal `@{` (e.g., `"@@{foo}"` → `@{foo}`)
|
|
25
31
|
|
|
@@ -133,6 +139,73 @@ let action = "create";
|
|
|
133
139
|
ts_template! { {|@{entity}_@{action}|} } // → "user_create"
|
|
134
140
|
```
|
|
135
141
|
|
|
142
|
+
## Comments: `{> ... <}` and `{>> ... <<}`
|
|
143
|
+
|
|
144
|
+
Since Rust's tokenizer strips comments before macros see them, you can't write JSDoc comments directly. Instead, use the comment syntax to output JavaScript comments:
|
|
145
|
+
|
|
146
|
+
### Block Comments
|
|
147
|
+
|
|
148
|
+
Use `{> comment <}` for block comments:
|
|
149
|
+
|
|
150
|
+
```rust
|
|
151
|
+
let code = ts_template! {
|
|
152
|
+
{> This is a block comment <}
|
|
153
|
+
const x = 42;
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Generates:**
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
/* This is a block comment */
|
|
161
|
+
const x = 42;
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Doc Comments (JSDoc)
|
|
165
|
+
|
|
166
|
+
Use `{>> doc <<}` for JSDoc comments:
|
|
167
|
+
|
|
168
|
+
```rust
|
|
169
|
+
let code = ts_template! {
|
|
170
|
+
{>> @param {string} name - The user's name <<}
|
|
171
|
+
{>> @returns {string} A greeting message <<}
|
|
172
|
+
function greet(name: string): string {
|
|
173
|
+
return "Hello, " + name;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Generates:**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
/** @param {string} name - The user's name */
|
|
182
|
+
/** @returns {string} A greeting message */
|
|
183
|
+
function greet(name: string): string {
|
|
184
|
+
return "Hello, " + name;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Comments with Interpolation
|
|
189
|
+
|
|
190
|
+
Comments support `@{expr}` interpolation for dynamic content:
|
|
191
|
+
|
|
192
|
+
```rust
|
|
193
|
+
let param_name = "userId";
|
|
194
|
+
let param_type = "number";
|
|
195
|
+
|
|
196
|
+
let code = ts_template! {
|
|
197
|
+
{>> @param {@{param_type}} @{param_name} - The user ID <<}
|
|
198
|
+
function getUser(userId: number) {}
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Generates:**
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
/** @param {number} userId - The user ID */
|
|
206
|
+
function getUser(userId: number) {}
|
|
207
|
+
```
|
|
208
|
+
|
|
136
209
|
## String Interpolation: `"text @{expr}"`
|
|
137
210
|
|
|
138
211
|
Interpolation works automatically inside string literals - no `format!()` needed:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@macroforge/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "MCP server for Macroforge documentation and code analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"typescript": "^5.7.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"macroforge": "^0.1.
|
|
30
|
+
"macroforge": "^0.1.25"
|
|
31
31
|
},
|
|
32
32
|
"peerDependenciesMeta": {
|
|
33
33
|
"macroforge": {
|