@mandujs/mcp 0.13.0 → 0.16.0
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 +6 -7
- package/package.json +3 -2
- package/src/adapters/index.ts +20 -20
- package/src/adapters/monitor-adapter.ts +100 -100
- package/src/adapters/tool-adapter.ts +88 -88
- package/src/executor/error-handler.ts +250 -250
- package/src/executor/index.ts +22 -22
- package/src/executor/tool-executor.ts +148 -148
- package/src/hooks/config-watcher.ts +174 -174
- package/src/hooks/index.ts +23 -23
- package/src/hooks/mcp-hooks.ts +227 -227
- package/src/logging/index.ts +15 -15
- package/src/logging/mcp-transport.ts +134 -134
- package/src/registry/index.ts +13 -13
- package/src/registry/mcp-tool-registry.ts +298 -298
- package/src/resources/skills/guides.ts +1136 -1136
- package/src/resources/skills/index.ts +12 -12
- package/src/resources/skills/loader.ts +218 -218
- package/src/resources/skills/mandu-composition/SKILL.md +91 -91
- package/src/resources/skills/mandu-composition/metadata.json +13 -13
- package/src/resources/skills/mandu-composition/rules/_sections.md +26 -26
- package/src/resources/skills/mandu-composition/rules/_template.md +77 -77
- package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +146 -146
- package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +164 -164
- package/src/resources/skills/mandu-composition/rules/comp-island-event.md +161 -161
- package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +167 -167
- package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +149 -149
- package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +148 -148
- package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +150 -150
- package/src/resources/skills/mandu-deployment/SKILL.md +92 -92
- package/src/resources/skills/mandu-deployment/_sections.md +41 -41
- package/src/resources/skills/mandu-deployment/_template.md +38 -38
- package/src/resources/skills/mandu-deployment/metadata.json +13 -13
- package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +109 -109
- package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +115 -115
- package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +219 -219
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +150 -150
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +223 -223
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +152 -152
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +179 -179
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-supabase.md +323 -323
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +140 -140
- package/src/resources/skills/mandu-fs-routes/SKILL.md +82 -82
- package/src/resources/skills/mandu-fs-routes/metadata.json +12 -12
- package/src/resources/skills/mandu-fs-routes/rules/_sections.md +36 -36
- package/src/resources/skills/mandu-fs-routes/rules/_template.md +69 -69
- package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +65 -65
- package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +93 -93
- package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +55 -55
- package/src/resources/skills/mandu-guard/SKILL.md +129 -129
- package/src/resources/skills/mandu-guard/metadata.json +12 -12
- package/src/resources/skills/mandu-guard/rules/_sections.md +36 -36
- package/src/resources/skills/mandu-guard/rules/_template.md +82 -82
- package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +100 -100
- package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +76 -76
- package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +81 -81
- package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +80 -80
- package/src/resources/skills/mandu-hydration/SKILL.md +91 -91
- package/src/resources/skills/mandu-hydration/metadata.json +12 -12
- package/src/resources/skills/mandu-hydration/rules/_sections.md +31 -31
- package/src/resources/skills/mandu-hydration/rules/_template.md +72 -72
- package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +109 -109
- package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +55 -55
- package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +113 -113
- package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +68 -68
- package/src/resources/skills/mandu-performance/SKILL.md +85 -85
- package/src/resources/skills/mandu-performance/metadata.json +14 -14
- package/src/resources/skills/mandu-performance/rules/_sections.md +31 -31
- package/src/resources/skills/mandu-performance/rules/_template.md +64 -64
- package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +103 -103
- package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +95 -95
- package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +124 -124
- package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +125 -125
- package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +80 -80
- package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +145 -145
- package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +98 -98
- package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +154 -154
- package/src/resources/skills/mandu-security/SKILL.md +87 -87
- package/src/resources/skills/mandu-security/metadata.json +13 -13
- package/src/resources/skills/mandu-security/rules/_sections.md +31 -31
- package/src/resources/skills/mandu-security/rules/_template.md +74 -74
- package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +127 -127
- package/src/resources/skills/mandu-security/rules/sec-env-management.md +133 -133
- package/src/resources/skills/mandu-security/rules/sec-input-validate.md +148 -148
- package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +146 -146
- package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +138 -138
- package/src/resources/skills/mandu-slot/SKILL.md +85 -85
- package/src/resources/skills/mandu-slot/metadata.json +12 -12
- package/src/resources/skills/mandu-slot/rules/_sections.md +36 -36
- package/src/resources/skills/mandu-slot/rules/_template.md +63 -63
- package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +38 -38
- package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +56 -56
- package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +59 -59
- package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +64 -64
- package/src/resources/skills/mandu-styling/SKILL.md +154 -154
- package/src/resources/skills/mandu-styling/_sections.md +43 -43
- package/src/resources/skills/mandu-styling/_template.md +32 -32
- package/src/resources/skills/mandu-styling/metadata.json +15 -15
- package/src/resources/skills/mandu-styling/rules/style-component-compound.md +235 -235
- package/src/resources/skills/mandu-styling/rules/style-component-slots.md +255 -255
- package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +205 -205
- package/src/resources/skills/mandu-styling/rules/style-island-animations.md +272 -272
- package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +167 -167
- package/src/resources/skills/mandu-styling/rules/style-island-variants.md +221 -221
- package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +209 -209
- package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +192 -192
- package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +162 -162
- package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +164 -164
- package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +170 -170
- package/src/resources/skills/mandu-styling/rules/style-tailwind-v4-gotchas.md +179 -179
- package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +229 -229
- package/src/resources/skills/mandu-testing/SKILL.md +99 -99
- package/src/resources/skills/mandu-testing/metadata.json +13 -13
- package/src/resources/skills/mandu-testing/rules/_sections.md +26 -26
- package/src/resources/skills/mandu-testing/rules/_template.md +65 -65
- package/src/resources/skills/mandu-testing/rules/test-component-island.md +195 -195
- package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +196 -196
- package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +219 -219
- package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +192 -192
- package/src/resources/skills/mandu-ui/SKILL.md +117 -117
- package/src/resources/skills/mandu-ui/_sections.md +23 -23
- package/src/resources/skills/mandu-ui/_template.md +32 -32
- package/src/resources/skills/mandu-ui/metadata.json +13 -13
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +232 -232
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +238 -238
- package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +259 -259
- package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +258 -258
- package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +213 -213
- package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +209 -209
- package/src/resources/skills/recipes.ts +932 -932
- package/src/tools/ate.ts +129 -0
- package/src/tools/index.ts +4 -1
- package/src/tools/project.ts +334 -334
- package/src/tools/runtime.ts +497 -497
- package/src/tools/seo.ts +417 -417
- package/src/utils/withWarnings.ts +83 -83
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Always Use Mandu.filling() as Default Export
|
|
3
|
-
impact: CRITICAL
|
|
4
|
-
impactDescription: Required for slot to work
|
|
5
|
-
tags: slot, structure, filling
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Always Use Mandu.filling() as Default Export
|
|
9
|
-
|
|
10
|
-
Every slot file must export a default `Mandu.filling()` chain. This is how Mandu
|
|
11
|
-
recognizes and processes your business logic.
|
|
12
|
-
|
|
13
|
-
**Incorrect (plain function export):**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
// spec/slots/users.slot.ts
|
|
17
|
-
export default async function handler(req: Request) {
|
|
18
|
-
return Response.json({ users: [] });
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
**Correct (Mandu.filling() chain):**
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
// spec/slots/users.slot.ts
|
|
26
|
-
import { Mandu } from "@mandujs/core";
|
|
27
|
-
|
|
28
|
-
export default Mandu.filling()
|
|
29
|
-
.get((ctx) => {
|
|
30
|
-
return ctx.ok({ users: [] });
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
The `Mandu.filling()` provides:
|
|
35
|
-
- Type-safe context API
|
|
36
|
-
- Built-in error handling
|
|
37
|
-
- Guard and lifecycle hooks
|
|
38
|
-
- Consistent response format
|
|
1
|
+
---
|
|
2
|
+
title: Always Use Mandu.filling() as Default Export
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: Required for slot to work
|
|
5
|
+
tags: slot, structure, filling
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Always Use Mandu.filling() as Default Export
|
|
9
|
+
|
|
10
|
+
Every slot file must export a default `Mandu.filling()` chain. This is how Mandu
|
|
11
|
+
recognizes and processes your business logic.
|
|
12
|
+
|
|
13
|
+
**Incorrect (plain function export):**
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// spec/slots/users.slot.ts
|
|
17
|
+
export default async function handler(req: Request) {
|
|
18
|
+
return Response.json({ users: [] });
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Correct (Mandu.filling() chain):**
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// spec/slots/users.slot.ts
|
|
26
|
+
import { Mandu } from "@mandujs/core";
|
|
27
|
+
|
|
28
|
+
export default Mandu.filling()
|
|
29
|
+
.get((ctx) => {
|
|
30
|
+
return ctx.ok({ users: [] });
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The `Mandu.filling()` provides:
|
|
35
|
+
- Type-safe context API
|
|
36
|
+
- Built-in error handling
|
|
37
|
+
- Guard and lifecycle hooks
|
|
38
|
+
- Consistent response format
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Use Context Response Methods
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: Consistent API responses
|
|
5
|
-
tags: slot, context, response
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use Context Response Methods
|
|
9
|
-
|
|
10
|
-
Use `ctx.ok()`, `ctx.created()`, `ctx.error()` instead of manual Response objects.
|
|
11
|
-
These methods ensure consistent response format across your API.
|
|
12
|
-
|
|
13
|
-
**Incorrect (manual Response):**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
export default Mandu.filling()
|
|
17
|
-
.get((ctx) => {
|
|
18
|
-
return new Response(JSON.stringify({ data: [] }), {
|
|
19
|
-
headers: { "Content-Type": "application/json" }
|
|
20
|
-
});
|
|
21
|
-
})
|
|
22
|
-
.post(async (ctx) => {
|
|
23
|
-
return new Response(JSON.stringify({ error: "Bad request" }), {
|
|
24
|
-
status: 400
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**Correct (context methods):**
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
export default Mandu.filling()
|
|
33
|
-
.get((ctx) => {
|
|
34
|
-
return ctx.ok({ data: [] });
|
|
35
|
-
})
|
|
36
|
-
.post(async (ctx) => {
|
|
37
|
-
const body = await ctx.body();
|
|
38
|
-
if (!body.name) {
|
|
39
|
-
return ctx.error("name is required");
|
|
40
|
-
}
|
|
41
|
-
return ctx.created({ data: body });
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Response Methods
|
|
46
|
-
|
|
47
|
-
| Method | Status | Use Case |
|
|
48
|
-
|--------|--------|----------|
|
|
49
|
-
| `ctx.ok(data)` | 200 | Success |
|
|
50
|
-
| `ctx.created(data)` | 201 | Resource created |
|
|
51
|
-
| `ctx.noContent()` | 204 | Success, no body |
|
|
52
|
-
| `ctx.error(msg)` | 400 | Bad request |
|
|
53
|
-
| `ctx.unauthorized(msg)` | 401 | Auth required |
|
|
54
|
-
| `ctx.forbidden(msg)` | 403 | Permission denied |
|
|
55
|
-
| `ctx.notFound(msg)` | 404 | Not found |
|
|
56
|
-
| `ctx.fail(msg)` | 500 | Server error |
|
|
1
|
+
---
|
|
2
|
+
title: Use Context Response Methods
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Consistent API responses
|
|
5
|
+
tags: slot, context, response
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Context Response Methods
|
|
9
|
+
|
|
10
|
+
Use `ctx.ok()`, `ctx.created()`, `ctx.error()` instead of manual Response objects.
|
|
11
|
+
These methods ensure consistent response format across your API.
|
|
12
|
+
|
|
13
|
+
**Incorrect (manual Response):**
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
export default Mandu.filling()
|
|
17
|
+
.get((ctx) => {
|
|
18
|
+
return new Response(JSON.stringify({ data: [] }), {
|
|
19
|
+
headers: { "Content-Type": "application/json" }
|
|
20
|
+
});
|
|
21
|
+
})
|
|
22
|
+
.post(async (ctx) => {
|
|
23
|
+
return new Response(JSON.stringify({ error: "Bad request" }), {
|
|
24
|
+
status: 400
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Correct (context methods):**
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
export default Mandu.filling()
|
|
33
|
+
.get((ctx) => {
|
|
34
|
+
return ctx.ok({ data: [] });
|
|
35
|
+
})
|
|
36
|
+
.post(async (ctx) => {
|
|
37
|
+
const body = await ctx.body();
|
|
38
|
+
if (!body.name) {
|
|
39
|
+
return ctx.error("name is required");
|
|
40
|
+
}
|
|
41
|
+
return ctx.created({ data: body });
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Response Methods
|
|
46
|
+
|
|
47
|
+
| Method | Status | Use Case |
|
|
48
|
+
|--------|--------|----------|
|
|
49
|
+
| `ctx.ok(data)` | 200 | Success |
|
|
50
|
+
| `ctx.created(data)` | 201 | Resource created |
|
|
51
|
+
| `ctx.noContent()` | 204 | Success, no body |
|
|
52
|
+
| `ctx.error(msg)` | 400 | Bad request |
|
|
53
|
+
| `ctx.unauthorized(msg)` | 401 | Auth required |
|
|
54
|
+
| `ctx.forbidden(msg)` | 403 | Permission denied |
|
|
55
|
+
| `ctx.notFound(msg)` | 404 | Not found |
|
|
56
|
+
| `ctx.fail(msg)` | 500 | Server error |
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Use .guard() for Authentication
|
|
3
|
-
impact: MEDIUM
|
|
4
|
-
impactDescription: Clean auth separation
|
|
5
|
-
tags: slot, guard, authentication
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use .guard() for Authentication
|
|
9
|
-
|
|
10
|
-
Use `.guard()` to check authentication before handlers run. Return a response
|
|
11
|
-
to block the request, or return void/undefined to continue.
|
|
12
|
-
|
|
13
|
-
**Incorrect (auth check in every handler):**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
export default Mandu.filling()
|
|
17
|
-
.get((ctx) => {
|
|
18
|
-
const user = ctx.get("user");
|
|
19
|
-
if (!user) {
|
|
20
|
-
return ctx.unauthorized("Login required");
|
|
21
|
-
}
|
|
22
|
-
return ctx.ok({ data: [] });
|
|
23
|
-
})
|
|
24
|
-
.post(async (ctx) => {
|
|
25
|
-
const user = ctx.get("user");
|
|
26
|
-
if (!user) {
|
|
27
|
-
return ctx.unauthorized("Login required");
|
|
28
|
-
}
|
|
29
|
-
// ... create logic
|
|
30
|
-
});
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**Correct (single guard):**
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
export default Mandu.filling()
|
|
37
|
-
.guard((ctx) => {
|
|
38
|
-
const user = ctx.get("user");
|
|
39
|
-
if (!user) {
|
|
40
|
-
return ctx.unauthorized("Login required");
|
|
41
|
-
}
|
|
42
|
-
// void return = continue to handlers
|
|
43
|
-
})
|
|
44
|
-
.get((ctx) => {
|
|
45
|
-
const user = ctx.get("user");
|
|
46
|
-
return ctx.ok({ data: [], user });
|
|
47
|
-
})
|
|
48
|
-
.post(async (ctx) => {
|
|
49
|
-
const body = await ctx.body();
|
|
50
|
-
return ctx.created({ data: body });
|
|
51
|
-
});
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Guard Rules
|
|
55
|
-
|
|
56
|
-
1. Return response → Request blocked
|
|
57
|
-
2. Return void → Continue to handler
|
|
58
|
-
3. Guard runs before ALL HTTP method handlers
|
|
59
|
-
4. Use `.onRequest()` to set user before guard runs
|
|
1
|
+
---
|
|
2
|
+
title: Use .guard() for Authentication
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Clean auth separation
|
|
5
|
+
tags: slot, guard, authentication
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use .guard() for Authentication
|
|
9
|
+
|
|
10
|
+
Use `.guard()` to check authentication before handlers run. Return a response
|
|
11
|
+
to block the request, or return void/undefined to continue.
|
|
12
|
+
|
|
13
|
+
**Incorrect (auth check in every handler):**
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
export default Mandu.filling()
|
|
17
|
+
.get((ctx) => {
|
|
18
|
+
const user = ctx.get("user");
|
|
19
|
+
if (!user) {
|
|
20
|
+
return ctx.unauthorized("Login required");
|
|
21
|
+
}
|
|
22
|
+
return ctx.ok({ data: [] });
|
|
23
|
+
})
|
|
24
|
+
.post(async (ctx) => {
|
|
25
|
+
const user = ctx.get("user");
|
|
26
|
+
if (!user) {
|
|
27
|
+
return ctx.unauthorized("Login required");
|
|
28
|
+
}
|
|
29
|
+
// ... create logic
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Correct (single guard):**
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
export default Mandu.filling()
|
|
37
|
+
.guard((ctx) => {
|
|
38
|
+
const user = ctx.get("user");
|
|
39
|
+
if (!user) {
|
|
40
|
+
return ctx.unauthorized("Login required");
|
|
41
|
+
}
|
|
42
|
+
// void return = continue to handlers
|
|
43
|
+
})
|
|
44
|
+
.get((ctx) => {
|
|
45
|
+
const user = ctx.get("user");
|
|
46
|
+
return ctx.ok({ data: [], user });
|
|
47
|
+
})
|
|
48
|
+
.post(async (ctx) => {
|
|
49
|
+
const body = await ctx.body();
|
|
50
|
+
return ctx.created({ data: body });
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Guard Rules
|
|
55
|
+
|
|
56
|
+
1. Return response → Request blocked
|
|
57
|
+
2. Return void → Continue to handler
|
|
58
|
+
3. Guard runs before ALL HTTP method handlers
|
|
59
|
+
4. Use `.onRequest()` to set user before guard runs
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Use Appropriate HTTP Methods
|
|
3
|
-
impact: HIGH
|
|
4
|
-
impactDescription: RESTful API design
|
|
5
|
-
tags: slot, http, methods, rest
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use Appropriate HTTP Methods
|
|
9
|
-
|
|
10
|
-
Chain HTTP methods on Mandu.filling() for RESTful API design.
|
|
11
|
-
|
|
12
|
-
**Incorrect (single handler for all):**
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
export default Mandu.filling()
|
|
16
|
-
.get(async (ctx) => {
|
|
17
|
-
const method = ctx.req.method;
|
|
18
|
-
if (method === "GET") {
|
|
19
|
-
return ctx.ok({ data: [] });
|
|
20
|
-
} else if (method === "POST") {
|
|
21
|
-
const body = await ctx.body();
|
|
22
|
-
return ctx.created({ data: body });
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Correct (separate methods):**
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
export default Mandu.filling()
|
|
31
|
-
.get((ctx) => {
|
|
32
|
-
// GET /api/users - List users
|
|
33
|
-
return ctx.ok({ data: [] });
|
|
34
|
-
})
|
|
35
|
-
.post(async (ctx) => {
|
|
36
|
-
// POST /api/users - Create user
|
|
37
|
-
const body = await ctx.body<{ name: string }>();
|
|
38
|
-
return ctx.created({ data: { id: 1, ...body } });
|
|
39
|
-
})
|
|
40
|
-
.put(async (ctx) => {
|
|
41
|
-
// PUT /api/users/:id - Replace user
|
|
42
|
-
const body = await ctx.body();
|
|
43
|
-
return ctx.ok({ data: body });
|
|
44
|
-
})
|
|
45
|
-
.patch(async (ctx) => {
|
|
46
|
-
// PATCH /api/users/:id - Update user
|
|
47
|
-
const body = await ctx.body();
|
|
48
|
-
return ctx.ok({ data: body });
|
|
49
|
-
})
|
|
50
|
-
.delete((ctx) => {
|
|
51
|
-
// DELETE /api/users/:id - Delete user
|
|
52
|
-
return ctx.noContent();
|
|
53
|
-
});
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## HTTP Method Semantics
|
|
57
|
-
|
|
58
|
-
| Method | Idempotent | Use Case |
|
|
59
|
-
|--------|------------|----------|
|
|
60
|
-
| GET | Yes | Read resource |
|
|
61
|
-
| POST | No | Create resource |
|
|
62
|
-
| PUT | Yes | Replace resource |
|
|
63
|
-
| PATCH | No | Partial update |
|
|
64
|
-
| DELETE | Yes | Remove resource |
|
|
1
|
+
---
|
|
2
|
+
title: Use Appropriate HTTP Methods
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: RESTful API design
|
|
5
|
+
tags: slot, http, methods, rest
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Appropriate HTTP Methods
|
|
9
|
+
|
|
10
|
+
Chain HTTP methods on Mandu.filling() for RESTful API design.
|
|
11
|
+
|
|
12
|
+
**Incorrect (single handler for all):**
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
export default Mandu.filling()
|
|
16
|
+
.get(async (ctx) => {
|
|
17
|
+
const method = ctx.req.method;
|
|
18
|
+
if (method === "GET") {
|
|
19
|
+
return ctx.ok({ data: [] });
|
|
20
|
+
} else if (method === "POST") {
|
|
21
|
+
const body = await ctx.body();
|
|
22
|
+
return ctx.created({ data: body });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Correct (separate methods):**
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
export default Mandu.filling()
|
|
31
|
+
.get((ctx) => {
|
|
32
|
+
// GET /api/users - List users
|
|
33
|
+
return ctx.ok({ data: [] });
|
|
34
|
+
})
|
|
35
|
+
.post(async (ctx) => {
|
|
36
|
+
// POST /api/users - Create user
|
|
37
|
+
const body = await ctx.body<{ name: string }>();
|
|
38
|
+
return ctx.created({ data: { id: 1, ...body } });
|
|
39
|
+
})
|
|
40
|
+
.put(async (ctx) => {
|
|
41
|
+
// PUT /api/users/:id - Replace user
|
|
42
|
+
const body = await ctx.body();
|
|
43
|
+
return ctx.ok({ data: body });
|
|
44
|
+
})
|
|
45
|
+
.patch(async (ctx) => {
|
|
46
|
+
// PATCH /api/users/:id - Update user
|
|
47
|
+
const body = await ctx.body();
|
|
48
|
+
return ctx.ok({ data: body });
|
|
49
|
+
})
|
|
50
|
+
.delete((ctx) => {
|
|
51
|
+
// DELETE /api/users/:id - Delete user
|
|
52
|
+
return ctx.noContent();
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## HTTP Method Semantics
|
|
57
|
+
|
|
58
|
+
| Method | Idempotent | Use Case |
|
|
59
|
+
|--------|------------|----------|
|
|
60
|
+
| GET | Yes | Read resource |
|
|
61
|
+
| POST | No | Create resource |
|
|
62
|
+
| PUT | Yes | Replace resource |
|
|
63
|
+
| PATCH | No | Partial update |
|
|
64
|
+
| DELETE | Yes | Remove resource |
|