@mandujs/core 0.54.10 → 0.54.11
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/package.json +200 -200
- package/scripts/postinstall-lock.ts +153 -153
- package/src/a11y/run-audit.ts +15 -15
- package/src/agent/__tests__/context.test.ts +17 -65
- package/src/agent/context.ts +535 -535
- package/src/agent/index.ts +6 -6
- package/src/agent/plan.ts +282 -282
- package/src/agent/repair.ts +171 -171
- package/src/agent/sync.ts +200 -200
- package/src/agent/types.ts +10 -18
- package/src/agent/verify.ts +17 -115
- package/src/brain/doctor/analyzer.ts +7 -7
- package/src/bundler/__tests__/build-runner.ts +81 -62
- package/src/bundler/__tests__/cold-start.test.ts +60 -60
- package/src/bundler/__tests__/css.test.ts +20 -20
- package/src/bundler/analyzer.ts +15 -15
- package/src/bundler/build.test.ts +120 -88
- package/src/bundler/build.ts +511 -511
- package/src/bundler/css.ts +42 -42
- package/src/bundler/manifest-schema.ts +21 -21
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +13 -13
- package/src/bundler/plugins/block-generated-imports.ts +13 -13
- package/src/bundler/types.ts +31 -31
- package/src/client/island.ts +79 -79
- package/src/config/validate.ts +1 -1
- package/src/deploy/inference/context.ts +82 -82
- package/src/devtools/client/components/panel/islands-panel.tsx +16 -16
- package/src/devtools/client/components/panel/panel-container.tsx +1 -1
- package/src/error/formatter.ts +22 -31
- package/src/filling/context.ts +17 -17
- package/src/generator/generate.ts +30 -30
- package/src/generator/index.ts +3 -3
- package/src/generator/templates.test.ts +66 -65
- package/src/generator/templates.ts +210 -210
- package/src/guard/check.ts +9 -9
- package/src/guard/config-guard.ts +13 -13
- package/src/guard/fs-routes-policy.ts +51 -51
- package/src/guard/index.ts +11 -11
- package/src/index.ts +3 -3
- package/src/kitchen/api/file-api.ts +11 -11
- package/src/report/index.ts +1 -1
- package/src/resource/__tests__/generator.test.ts +6 -6
- package/src/resource/__tests__/schema.test.ts +14 -14
- package/src/resource/ddl/__tests__/emit.test.ts +165 -165
- package/src/resource/ddl/emit.ts +146 -146
- package/src/resource/generator-schema.ts +11 -11
- package/src/resource/generators/slot.ts +72 -72
- package/src/resource/schema.ts +21 -21
- package/src/router/client-entry.test.ts +192 -140
- package/src/router/client-entry.ts +516 -486
- package/src/router/fs-routes.ts +16 -16
- package/src/router/fs-scanner.ts +16 -28
- package/src/runtime/__tests__/devtools-adapter.test.ts +68 -68
- package/src/runtime/__tests__/observability-lifecycle.test.ts +103 -103
- package/src/runtime/__tests__/page-render-response.test.ts +103 -103
- package/src/runtime/__tests__/request-middleware.test.ts +70 -70
- package/src/runtime/devtools-adapter.ts +68 -68
- package/src/runtime/escape.ts +34 -34
- package/src/runtime/observability-lifecycle.ts +290 -290
- package/src/runtime/page-render-response.ts +106 -106
- package/src/runtime/request-middleware.ts +31 -31
- package/src/runtime/server.ts +243 -243
- package/src/runtime/ssr.ts +59 -59
- package/src/runtime/static-files.ts +289 -289
- package/src/runtime/streaming-ssr.ts +22 -22
- package/src/watcher/__tests__/watcher.test.ts +59 -59
- package/src/watcher/watcher.ts +61 -61
|
@@ -1,140 +1,192 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import {
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { mkdir, mkdtemp, rm, writeFile } from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import {
|
|
5
|
+
findClientComponentImports,
|
|
6
|
+
findRouteLevelClientComponentImport,
|
|
7
|
+
findRouteLevelClientComponentImports,
|
|
8
|
+
resolveRouteLevelClientEntryPath,
|
|
9
|
+
} from "./client-entry";
|
|
10
|
+
|
|
11
|
+
describe("findClientComponentImports", () => {
|
|
12
|
+
it("detects named .client imports for diagnostics", () => {
|
|
13
|
+
const imports = findClientComponentImports(`
|
|
14
|
+
import { LoginForm, SubmitButton as Button } from "@/client/widgets/login-form/LoginForm.client";
|
|
15
|
+
import Header from "./Header.client.tsx";
|
|
16
|
+
`);
|
|
17
|
+
|
|
18
|
+
expect(imports).toEqual([
|
|
19
|
+
{
|
|
20
|
+
module: "@/client/widgets/login-form/LoginForm.client",
|
|
21
|
+
kind: "named",
|
|
22
|
+
names: ["LoginForm", "Button"],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
module: "./Header.client.tsx",
|
|
26
|
+
kind: "default",
|
|
27
|
+
names: ["Header"],
|
|
28
|
+
},
|
|
29
|
+
]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("detects a default-imported client component when the page returns only that component", () => {
|
|
33
|
+
const routeClient = findRouteLevelClientComponentImport(`
|
|
34
|
+
import LoginPage from "@/client/pages/login/LoginPage.client";
|
|
35
|
+
|
|
36
|
+
export const metadata = { title: "Login" };
|
|
37
|
+
|
|
38
|
+
export default function Page() {
|
|
39
|
+
return <LoginPage />;
|
|
40
|
+
}
|
|
41
|
+
`);
|
|
42
|
+
|
|
43
|
+
expect(routeClient).toEqual({
|
|
44
|
+
module: "@/client/pages/login/LoginPage.client",
|
|
45
|
+
localName: "LoginPage",
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("promotes a fragment wrapper with head-only elements and a bare client component", () => {
|
|
50
|
+
const routeClient = findRouteLevelClientComponentImport(`
|
|
51
|
+
import HomeApp from "@/client/pages/home/HomeApp.client";
|
|
52
|
+
|
|
53
|
+
export default function HomePage() {
|
|
54
|
+
return <>
|
|
55
|
+
<meta name="description" content="home" />
|
|
56
|
+
<HomeApp />
|
|
57
|
+
</>;
|
|
58
|
+
}
|
|
59
|
+
`);
|
|
60
|
+
|
|
61
|
+
expect(routeClient).toEqual({
|
|
62
|
+
module: "@/client/pages/home/HomeApp.client",
|
|
63
|
+
localName: "HomeApp",
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("detects a named-imported client component when the page returns only that component", () => {
|
|
68
|
+
const routeClient = findRouteLevelClientComponentImport(`
|
|
69
|
+
import { NotificationsPage } from "@/client/pages/notifications/NotificationsPage.client";
|
|
70
|
+
|
|
71
|
+
export default function Page() {
|
|
72
|
+
return <NotificationsPage />;
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
75
|
+
|
|
76
|
+
expect(routeClient).toEqual({
|
|
77
|
+
module: "@/client/pages/notifications/NotificationsPage.client",
|
|
78
|
+
localName: "NotificationsPage",
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("promotes embedded client imports inside a larger server page", () => {
|
|
83
|
+
const routeClient = findRouteLevelClientComponentImport(`
|
|
84
|
+
import HomeApp from "@/client/pages/home/HomeApp.client";
|
|
85
|
+
|
|
86
|
+
export default function HomePage() {
|
|
87
|
+
return <>
|
|
88
|
+
<header>Server shell</header>
|
|
89
|
+
<HomeApp />
|
|
90
|
+
</>;
|
|
91
|
+
}
|
|
92
|
+
`);
|
|
93
|
+
|
|
94
|
+
expect(routeClient).toEqual({
|
|
95
|
+
module: "@/client/pages/home/HomeApp.client",
|
|
96
|
+
localName: "HomeApp",
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("promotes client imports when the page wrapper passes props", () => {
|
|
101
|
+
const routeClient = findRouteLevelClientComponentImport(`
|
|
102
|
+
import PledgePage from "@/client/pages/pledges/PledgePage.client";
|
|
103
|
+
|
|
104
|
+
export default function Page({ params }) {
|
|
105
|
+
return <PledgePage id={params.id} />;
|
|
106
|
+
}
|
|
107
|
+
`);
|
|
108
|
+
|
|
109
|
+
expect(routeClient).toEqual({
|
|
110
|
+
module: "@/client/pages/pledges/PledgePage.client",
|
|
111
|
+
localName: "PledgePage",
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("detects multiple rendered client imports in a server shell", () => {
|
|
116
|
+
const routeClients = findRouteLevelClientComponentImports(`
|
|
117
|
+
import { CommentsSection } from "@/client/widgets/comments-section/CommentsSection.client";
|
|
118
|
+
import { PledgeActions } from "@/client/widgets/pledge-actions/PledgeActions.client";
|
|
119
|
+
|
|
120
|
+
export default async function PledgePage({ params }) {
|
|
121
|
+
const pledge = await Promise.resolve(params.id);
|
|
122
|
+
return (
|
|
123
|
+
<main>
|
|
124
|
+
<article>{pledge}</article>
|
|
125
|
+
<PledgeActions pledgeId={params.id} />
|
|
126
|
+
<CommentsSection pledgeId={params.id} />
|
|
127
|
+
</main>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
`);
|
|
131
|
+
|
|
132
|
+
expect(routeClients).toEqual([
|
|
133
|
+
{
|
|
134
|
+
module: "@/client/widgets/comments-section/CommentsSection.client",
|
|
135
|
+
localName: "CommentsSection",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
module: "@/client/widgets/pledge-actions/PledgeActions.client",
|
|
139
|
+
localName: "PledgeActions",
|
|
140
|
+
},
|
|
141
|
+
]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("detects rendered component imports without a .client filename suffix", () => {
|
|
145
|
+
const routeClient = findRouteLevelClientComponentImport(`
|
|
146
|
+
import { PledgeForm } from "@/client/widgets/pledge-form/PledgeForm";
|
|
147
|
+
|
|
148
|
+
export default async function NewPledgePage() {
|
|
149
|
+
return <main><PledgeForm parties={[]} candidates={[]} /></main>;
|
|
150
|
+
}
|
|
151
|
+
`);
|
|
152
|
+
|
|
153
|
+
expect(routeClient).toEqual({
|
|
154
|
+
module: "@/client/widgets/pledge-form/PledgeForm",
|
|
155
|
+
localName: "PledgeForm",
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("resolves a route-level client entry by reading a use client target without .client in the path", async () => {
|
|
160
|
+
const rootDir = await mkdtemp(path.join(import.meta.dir, ".tmp-client-entry-"));
|
|
161
|
+
try {
|
|
162
|
+
await mkdir(path.join(rootDir, "app", "pledges", "new"), { recursive: true });
|
|
163
|
+
await mkdir(path.join(rootDir, "src", "client", "widgets", "pledge-form"), { recursive: true });
|
|
164
|
+
|
|
165
|
+
const pageSource = `
|
|
166
|
+
import { PledgeForm } from "@/client/widgets/pledge-form/PledgeForm";
|
|
167
|
+
|
|
168
|
+
export default async function NewPledgePage() {
|
|
169
|
+
return <main><PledgeForm parties={[]} candidates={[]} /></main>;
|
|
170
|
+
}
|
|
171
|
+
`;
|
|
172
|
+
await writeFile(path.join(rootDir, "app", "pledges", "new", "page.tsx"), pageSource);
|
|
173
|
+
await writeFile(
|
|
174
|
+
path.join(rootDir, "src", "client", "widgets", "pledge-form", "PledgeForm.tsx"),
|
|
175
|
+
`"use client";
|
|
176
|
+
export function PledgeForm() {
|
|
177
|
+
return <form />;
|
|
178
|
+
}`,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const resolved = await resolveRouteLevelClientEntryPath(
|
|
182
|
+
rootDir,
|
|
183
|
+
"app/pledges/new/page.tsx",
|
|
184
|
+
pageSource,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
expect(resolved).toBe("src/client/widgets/pledge-form/PledgeForm.tsx");
|
|
188
|
+
} finally {
|
|
189
|
+
await rm(rootDir, { recursive: true, force: true });
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|