@antelopejs/dms-frontend 0.9.3 → 0.10.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 +18 -24
- package/dist/commands/build-action.js +3 -2
- package/dist/commands/dev-action.js +2 -1
- package/dist/commands/prepare-action.js +1 -1
- package/dist/commands/start-action.js +3 -24
- package/dist/commands/workspace-task.js +2 -1
- package/dist/derived-outputs.js +3 -3
- package/dist/discovery.js +17 -6
- package/dist/entry-weight.js +15 -0
- package/dist/fs-sync.js +7 -4
- package/dist/index.js +2 -1
- package/dist/internal/built-workspace.d.ts +4 -0
- package/dist/internal/built-workspace.js +43 -0
- package/dist/internal/ensure.d.ts +1 -0
- package/dist/internal/ensure.js +8 -0
- package/dist/internal/locale-catalogs.d.ts +8 -3
- package/dist/internal/locale-catalogs.js +16 -6
- package/dist/internal/manifest-decoder.d.ts +7 -0
- package/dist/internal/manifest-decoder.js +81 -0
- package/dist/internal/own-release.d.ts +5 -0
- package/dist/internal/own-release.js +20 -0
- package/dist/internal/plain-object.d.ts +1 -0
- package/dist/internal/plain-object.js +6 -0
- package/dist/internal/text-list.d.ts +1 -0
- package/dist/internal/text-list.js +10 -0
- package/dist/internal/vite-manifest.d.ts +6 -0
- package/dist/internal/vite-manifest.js +24 -0
- package/dist/layer-watch.js +25 -24
- package/dist/layers.d.ts +1 -1
- package/dist/layers.js +3 -1
- package/dist/locale-files.d.ts +2 -1
- package/dist/locale-files.js +4 -0
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.js +44 -31
- package/dist/materialize.js +6 -2
- package/dist/module-set.js +2 -1
- package/dist/node-options.d.ts +1 -0
- package/dist/node-options.js +8 -0
- package/dist/output.d.ts +15 -9
- package/dist/output.js +30 -18
- package/dist/private-values.d.ts +1 -1
- package/dist/private-values.js +5 -3
- package/dist/project-modules.js +13 -8
- package/dist/renderer-range.js +5 -3
- package/dist/server-process.js +1 -1
- package/dist/verify-source-build.js +10 -2
- package/dist/verify-source-client-bundle.d.ts +1 -0
- package/dist/verify-source-client-bundle.js +30 -0
- package/dist/verify-source-runner.js +44 -60
- package/dist/verify-source-sources.js +49 -11
- package/dist/workspace-setup.js +1 -1
- package/package.json +6 -4
- package/skills/dms-frontend/SKILL.md +1 -1
- package/templates/vue/app-runtime.ts +2 -9
- package/templates/vue/client-server-guard.mjs +16 -0
- package/templates/vue/compress-assets.mjs +9 -1
- package/templates/vue/entry-weight.mjs +22 -0
- package/templates/vue/frontend-module.ts +1 -0
- package/templates/vue/frontend-runtime/module-registration.ts +2 -2
- package/templates/vue/frontend-runtime/state.ts +2 -2
- package/templates/vue/frontend-runtime/types.ts +8 -2
- package/templates/vue/head-order.mjs +7 -0
- package/templates/vue/icon-scan.mjs +4 -0
- package/templates/vue/server/auth/backend.mjs +41 -4
- package/templates/vue/server/auth/client-ip.mjs +52 -4
- package/templates/vue/server/auth/establish-endpoints.mjs +10 -6
- package/templates/vue/server/auth/session.mjs +81 -2
- package/templates/vue/server/auth-hooks.mjs +15 -5
- package/templates/vue/server/backend-proxies.mjs +65 -9
- package/templates/vue/server/backend-request.mjs +61 -0
- package/templates/vue/server/backend-response.mjs +23 -6
- package/templates/vue/server/built-files.mjs +7 -0
- package/templates/vue/server/cli-report.mjs +53 -11
- package/templates/vue/server/client-manifest.mjs +23 -1
- package/templates/vue/server/content.mjs +18 -1
- package/templates/vue/server/dev-private-files.mjs +17 -1
- package/templates/vue/server/dev-styles.mjs +38 -0
- package/templates/vue/server/email.mjs +9 -3
- package/templates/vue/server/favicon.mjs +3 -0
- package/templates/vue/server/generated-files.mjs +211 -0
- package/templates/vue/server/homepage.mjs +21 -9
- package/templates/vue/server/html-tag.mjs +4 -0
- package/templates/vue/server/icons.mjs +80 -7
- package/templates/vue/server/in-place-render.mjs +35 -0
- package/templates/vue/server/inertia.mjs +61 -2
- package/templates/vue/server/module-event.mjs +98 -17
- package/templates/vue/server/module-route-types.mjs +78 -0
- package/templates/vue/server/module-routes.mjs +138 -31
- package/templates/vue/server/module-server.mjs +98 -27
- package/templates/vue/server/module-testing.mjs +14 -5
- package/templates/vue/server/page-props.mjs +92 -2
- package/templates/vue/server/page-redirects.mjs +37 -0
- package/templates/vue/server/path-patterns.mjs +13 -1
- package/templates/vue/server/proxy-compression.mjs +22 -0
- package/templates/vue/server/proxy-headers.mjs +11 -1
- package/templates/vue/server/proxy-redirects.mjs +20 -5
- package/templates/vue/server/proxy-request.mjs +57 -0
- package/templates/vue/server/proxy-transfers.mjs +33 -5
- package/templates/vue/server/public-endpoints.mjs +138 -23
- package/templates/vue/server/public-options.mjs +20 -6
- package/templates/vue/server/request-failure.mjs +23 -0
- package/templates/vue/server/request-routing.mjs +26 -9
- package/templates/vue/server/request-target.mjs +9 -3
- package/templates/vue/server/route-rules.mjs +39 -15
- package/templates/vue/server/ssr-module.mjs +32 -0
- package/templates/vue/server/static-files.mjs +24 -1
- package/templates/vue/server/type-guards.mjs +71 -0
- package/templates/vue/server/vite-errors.mjs +32 -5
- package/templates/vue/server/web-body.mjs +3 -0
- package/templates/vue/server-module.ts +10 -1
- package/templates/vue/server.mjs +132 -148
- package/templates/vue/sfc-global-types.mjs +112 -13
- package/templates/vue/ssr-renderer.ts +2 -2
- package/templates/vue/ui-inertia-page.mjs +16 -1
- package/templates/vue/ui-kbd.mjs +2 -1
- package/templates/vue/ui-request-state.mjs +2 -1
package/dist/server-process.js
CHANGED
|
@@ -73,7 +73,7 @@ function readListenError(message) {
|
|
|
73
73
|
function readStartError(message) {
|
|
74
74
|
if (!isServerMessage(message) || message.type !== START_ERROR_MESSAGE)
|
|
75
75
|
return undefined;
|
|
76
|
-
const
|
|
76
|
+
const location = message.location;
|
|
77
77
|
const isLocated = hasFile(location);
|
|
78
78
|
return {
|
|
79
79
|
message: String(message.message),
|
|
@@ -8,6 +8,8 @@ const cli_1 = require("@antelopejs/core/cli");
|
|
|
8
8
|
const child_output_1 = require("./child-output");
|
|
9
9
|
const build_action_1 = require("./commands/build-action");
|
|
10
10
|
const common_1 = require("./common");
|
|
11
|
+
const text_list_1 = require("./internal/text-list");
|
|
12
|
+
const plain_object_1 = require("./internal/plain-object");
|
|
11
13
|
const typecheck_output_1 = require("./typecheck-output");
|
|
12
14
|
const verify_source_result_1 = require("./verify-source-result");
|
|
13
15
|
const vite_output_1 = require("./vite-output");
|
|
@@ -39,8 +41,14 @@ const TYPECHECK_CONFIG = "tsconfig.verify.json";
|
|
|
39
41
|
function snapshotTypeDeclarations(workspace) {
|
|
40
42
|
(0, node_fs_1.cpSync)((0, node_path_1.join)(workspace, AUTO_IMPORTS_DECLARATIONS), (0, node_path_1.join)(workspace, AUTO_IMPORTS_SNAPSHOT));
|
|
41
43
|
const config = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(workspace, "tsconfig.json"), "utf8"));
|
|
42
|
-
|
|
43
|
-
if (!config.
|
|
44
|
+
const listed = (0, plain_object_1.isPlainObject)(config) ? (config.files ?? []) : undefined;
|
|
45
|
+
if (!(0, plain_object_1.isPlainObject)(config) || !(0, text_list_1.isTextList)(listed))
|
|
46
|
+
throw new cli_1.CliError({
|
|
47
|
+
title: "The workspace tsconfig.json does not list its files as paths",
|
|
48
|
+
});
|
|
49
|
+
const files = listed.map((file) => file === AUTO_IMPORTS_DECLARATIONS ? AUTO_IMPORTS_SNAPSHOT : file);
|
|
50
|
+
config.files = files;
|
|
51
|
+
if (!files.includes(AUTO_IMPORTS_SNAPSHOT))
|
|
44
52
|
throw new cli_1.CliError({
|
|
45
53
|
title: `The workspace tsconfig.json does not list ${AUTO_IMPORTS_DECLARATIONS}`,
|
|
46
54
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function checkClientBundle(workspace: string): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkClientBundle = checkClientBundle;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const ensure_1 = require("./internal/ensure");
|
|
7
|
+
const vite_manifest_1 = require("./internal/vite-manifest");
|
|
8
|
+
const LAZY_LIBRARIES = [
|
|
9
|
+
{ name: "ApexCharts", pattern: /ApexCharts/ },
|
|
10
|
+
{ name: "Tiptap", pattern: /tiptap/i },
|
|
11
|
+
];
|
|
12
|
+
const RUNTIME_MARKERS = ["auth/login", "DefaultLayout", "error.500.title"];
|
|
13
|
+
function checkClientBundle(workspace) {
|
|
14
|
+
const clientRoot = (0, node_path_1.join)(workspace, "dist", "client");
|
|
15
|
+
const manifest = (0, vite_manifest_1.parseViteManifest)((0, node_fs_1.readFileSync)((0, node_path_1.join)(clientRoot, ".vite", "manifest.json"), "utf8"), "client build manifest");
|
|
16
|
+
const mainEntry = manifest.find((entry) => entry.isEntry);
|
|
17
|
+
(0, ensure_1.ensure)(mainEntry !== undefined, "The Vite manifest names no entry chunk");
|
|
18
|
+
const mainJavascript = (0, node_fs_1.readFileSync)((0, node_path_1.join)(clientRoot, mainEntry.file), "utf8");
|
|
19
|
+
const javascript = (0, node_fs_1.readdirSync)((0, node_path_1.join)(clientRoot, "assets"))
|
|
20
|
+
.filter((file) => file.endsWith(".js"))
|
|
21
|
+
.map((file) => (0, node_fs_1.readFileSync)((0, node_path_1.join)(clientRoot, "assets", file), "utf8"))
|
|
22
|
+
.join("\n");
|
|
23
|
+
for (const { name, pattern } of LAZY_LIBRARIES) {
|
|
24
|
+
(0, ensure_1.ensure)(!pattern.test(mainJavascript), `The main chunk bundles ${name}`, "It must stay in a lazily loaded chunk.");
|
|
25
|
+
(0, ensure_1.ensure)(pattern.test(javascript), `No client chunk bundles ${name}`);
|
|
26
|
+
}
|
|
27
|
+
(0, ensure_1.ensure)(manifest.some((chunk) => chunk.src?.endsWith("/kpi/KpiCard.vue")), "DmsKpiCard is not reachable at runtime");
|
|
28
|
+
for (const marker of RUNTIME_MARKERS)
|
|
29
|
+
(0, ensure_1.ensure)(javascript.includes(marker), `${marker} is not reachable at runtime`);
|
|
30
|
+
}
|
|
@@ -37,32 +37,27 @@ const node_fs_1 = require("node:fs");
|
|
|
37
37
|
const node_path_1 = require("node:path");
|
|
38
38
|
const cli_1 = require("@antelopejs/core/cli");
|
|
39
39
|
const child_output_1 = require("./child-output");
|
|
40
|
+
const ensure_1 = require("./internal/ensure");
|
|
41
|
+
const guards_1 = require("./internal/guards");
|
|
42
|
+
const plain_object_1 = require("./internal/plain-object");
|
|
43
|
+
const vite_manifest_1 = require("./internal/vite-manifest");
|
|
40
44
|
const common_1 = require("./common");
|
|
41
45
|
const output_1 = require("./output");
|
|
42
46
|
const temporary_workspace_1 = require("./temporary-workspace");
|
|
47
|
+
const verify_source_client_bundle_1 = require("./verify-source-client-bundle");
|
|
43
48
|
const verify_source_build_1 = require("./verify-source-build");
|
|
44
49
|
const verify_source_result_1 = require("./verify-source-result");
|
|
45
50
|
const verify_source_sources_1 = require("./verify-source-sources");
|
|
46
51
|
const vite_output_1 = require("./vite-output");
|
|
47
52
|
const EMAIL_BUILD_SIZE_CEILING_BYTES = 256 * 1024;
|
|
48
53
|
const NON_EMAIL_RUNTIME_PATTERN = /DisplayRichText|ApexCharts|Tiptap|FlowCanvas|app\/.*table|components\/table/i;
|
|
49
|
-
const LAZY_LIBRARIES = [
|
|
50
|
-
{ name: "ApexCharts", pattern: /ApexCharts/ },
|
|
51
|
-
{ name: "Tiptap", pattern: /tiptap/i },
|
|
52
|
-
];
|
|
53
|
-
const RUNTIME_MARKERS = ["auth/login", "DefaultLayout", "error.500.title"];
|
|
54
|
-
function readJson(path) {
|
|
55
|
-
return JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
56
|
-
}
|
|
57
|
-
function ensure(condition, title, reason) {
|
|
58
|
-
if (!condition)
|
|
59
|
-
throw new cli_1.CliError({ title, reason });
|
|
60
|
-
}
|
|
61
54
|
function removeDevelopmentDependencies(root) {
|
|
62
55
|
const packagePath = (0, node_path_1.join)(root, "package.json");
|
|
63
56
|
if (!(0, node_fs_1.existsSync)(packagePath))
|
|
64
57
|
return;
|
|
65
|
-
const packageData =
|
|
58
|
+
const packageData = JSON.parse((0, node_fs_1.readFileSync)(packagePath, "utf8"));
|
|
59
|
+
if (!(0, plain_object_1.isPlainObject)(packageData))
|
|
60
|
+
return;
|
|
66
61
|
delete packageData.devDependencies;
|
|
67
62
|
(0, node_fs_1.writeFileSync)(packagePath, `${JSON.stringify(packageData, null, 2)}\n`);
|
|
68
63
|
}
|
|
@@ -82,10 +77,14 @@ function materializeWorkspace(workspace, layers, localPackages) {
|
|
|
82
77
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(workspace, "dms-main.css"), '@import "tailwindcss";\n@import "@nuxt/ui";\n');
|
|
83
78
|
(0, common_1.writeWorkspacePackageJson)(workspace, layers);
|
|
84
79
|
const packagePath = (0, node_path_1.join)(workspace, "package.json");
|
|
85
|
-
const workspacePackage =
|
|
80
|
+
const workspacePackage = JSON.parse((0, node_fs_1.readFileSync)(packagePath, "utf8"));
|
|
81
|
+
(0, ensure_1.ensure)((0, plain_object_1.isPlainObject)(workspacePackage), "The workspace package.json is not a JSON object");
|
|
86
82
|
workspacePackage.pnpm = {
|
|
87
83
|
overrides: {
|
|
88
|
-
...Object.fromEntries(layers.map((layer) => [
|
|
84
|
+
...Object.fromEntries(layers.map((layer) => [
|
|
85
|
+
String(layer.packageName),
|
|
86
|
+
"workspace:*",
|
|
87
|
+
])),
|
|
89
88
|
...Object.fromEntries(Object.entries(localPackages).map(([name, path]) => [
|
|
90
89
|
name,
|
|
91
90
|
`link:${(0, node_path_1.resolve)(path)}`,
|
|
@@ -94,33 +93,15 @@ function materializeWorkspace(workspace, layers, localPackages) {
|
|
|
94
93
|
};
|
|
95
94
|
(0, node_fs_1.writeFileSync)(packagePath, `${JSON.stringify(workspacePackage, null, 2)}\n`);
|
|
96
95
|
}
|
|
97
|
-
function checkClientBundle(workspace) {
|
|
98
|
-
const clientRoot = (0, node_path_1.join)(workspace, "dist", "client");
|
|
99
|
-
const manifest = readJson((0, node_path_1.join)(clientRoot, ".vite", "manifest.json"));
|
|
100
|
-
const mainEntry = Object.values(manifest).find((entry) => entry.isEntry);
|
|
101
|
-
ensure(mainEntry !== undefined, "The Vite manifest names no entry chunk");
|
|
102
|
-
const mainJavascript = (0, node_fs_1.readFileSync)((0, node_path_1.join)(clientRoot, mainEntry.file), "utf8");
|
|
103
|
-
const javascript = (0, node_fs_1.readdirSync)((0, node_path_1.join)(clientRoot, "assets"))
|
|
104
|
-
.filter((file) => file.endsWith(".js"))
|
|
105
|
-
.map((file) => (0, node_fs_1.readFileSync)((0, node_path_1.join)(clientRoot, "assets", file), "utf8"))
|
|
106
|
-
.join("\n");
|
|
107
|
-
for (const { name, pattern } of LAZY_LIBRARIES) {
|
|
108
|
-
ensure(!pattern.test(mainJavascript), `The main chunk bundles ${name}`, "It must stay in a lazily loaded chunk.");
|
|
109
|
-
ensure(pattern.test(javascript), `No client chunk bundles ${name}`);
|
|
110
|
-
}
|
|
111
|
-
ensure(Object.keys(manifest).some((source) => source.endsWith("/kpi/KpiCard.vue")), "DmsKpiCard is not reachable at runtime");
|
|
112
|
-
for (const marker of RUNTIME_MARKERS)
|
|
113
|
-
ensure(javascript.includes(marker), `${marker} is not reachable at runtime`);
|
|
114
|
-
}
|
|
115
96
|
async function checkServerModulesBundle(workspace) {
|
|
116
97
|
const root = (0, node_path_1.join)(workspace, "dist", "server-modules");
|
|
117
98
|
const javascript = (0, node_fs_1.readdirSync)(root, { recursive: true, encoding: "utf8" })
|
|
118
99
|
.filter((file) => file.endsWith(".js"))
|
|
119
100
|
.map((file) => (0, node_fs_1.readFileSync)((0, node_path_1.join)(root, file), "utf8"))
|
|
120
101
|
.join("\n");
|
|
121
|
-
ensure(!/\.vue["'?]|createApp\(|DefaultLayout/.test(javascript), "The server modules bundle loads application code", "A dms.server.ts imports server code only, never .vue files or dms.frontend.ts.");
|
|
122
|
-
const
|
|
123
|
-
ensure(Array.isArray(serverModules), "The server modules bundle exports none");
|
|
102
|
+
(0, ensure_1.ensure)(!/\.vue["'?]|createApp\(|DefaultLayout/.test(javascript), "The server modules bundle loads application code", "A dms.server.ts imports server code only, never .vue files or dms.frontend.ts.");
|
|
103
|
+
const serverModules = (await Promise.resolve(`${(0, node_path_1.join)(root, "server-modules.generated.js")}`).then(s => __importStar(require(s)))).serverModules;
|
|
104
|
+
(0, ensure_1.ensure)(Array.isArray(serverModules), "The server modules bundle exports none");
|
|
124
105
|
return `${(0, cli_1.pluralize)(serverModules.length, "server module")}, ${(0, output_1.formatSize)(Buffer.byteLength(javascript))} JS`;
|
|
125
106
|
}
|
|
126
107
|
const EMAIL_CASES = [
|
|
@@ -177,19 +158,19 @@ const EMAIL_CASES = [
|
|
|
177
158
|
];
|
|
178
159
|
const BROWSER_ONLY_REASON = "It must not load rich text, charts, tables or flows.";
|
|
179
160
|
function checkLayoutEmail(html) {
|
|
180
|
-
ensure(/<meta charset="utf-8"/.test(html), "EmailLayout declares no UTF-8 charset");
|
|
181
|
-
ensure(/images\/antelope-logo\/light\.svg/.test(html), "EmailLayout renders no logo");
|
|
182
|
-
ensure(!/<h1[^>]*\bas=/.test(html), "EmailLayout leaks an `as` attribute onto its heading");
|
|
161
|
+
(0, ensure_1.ensure)(/<meta charset="utf-8"/.test(html), "EmailLayout declares no UTF-8 charset");
|
|
162
|
+
(0, ensure_1.ensure)(/images\/antelope-logo\/light\.svg/.test(html), "EmailLayout renders no logo");
|
|
163
|
+
(0, ensure_1.ensure)(!/<h1[^>]*\bas=/.test(html), "EmailLayout leaks an `as` attribute onto its heading");
|
|
183
164
|
}
|
|
184
165
|
async function checkEmailContracts(workspace) {
|
|
185
166
|
const emailRoot = (0, node_path_1.join)(workspace, "dist", "server");
|
|
186
167
|
const emailManifestContent = (0, node_fs_1.readFileSync)((0, node_path_1.join)(emailRoot, ".vite", "manifest.json"), "utf8");
|
|
187
|
-
ensure(!NON_EMAIL_RUNTIME_PATTERN.test(emailManifestContent), "The e-mail manifest references browser-only modules", BROWSER_ONLY_REASON);
|
|
188
|
-
const emailManifest =
|
|
168
|
+
(0, ensure_1.ensure)(!NON_EMAIL_RUNTIME_PATTERN.test(emailManifestContent), "The e-mail manifest references browser-only modules", BROWSER_ONLY_REASON);
|
|
169
|
+
const emailManifest = (0, vite_manifest_1.parseViteManifest)(emailManifestContent, "e-mail build manifest");
|
|
189
170
|
const emailJavascriptFiles = [
|
|
190
171
|
...new Set([
|
|
191
172
|
"email-renderer.js",
|
|
192
|
-
...
|
|
173
|
+
...emailManifest
|
|
193
174
|
.map((entry) => entry.file)
|
|
194
175
|
.filter((file) => file.endsWith(".js")),
|
|
195
176
|
]),
|
|
@@ -197,18 +178,18 @@ async function checkEmailContracts(workspace) {
|
|
|
197
178
|
const emailJavascript = emailJavascriptFiles
|
|
198
179
|
.map((file) => (0, node_fs_1.readFileSync)((0, node_path_1.join)(emailRoot, file), "utf8"))
|
|
199
180
|
.join("\n");
|
|
200
|
-
ensure(!NON_EMAIL_RUNTIME_PATTERN.test(emailJavascript), "The e-mail bundle loads browser-only modules", BROWSER_ONLY_REASON);
|
|
181
|
+
(0, ensure_1.ensure)(!NON_EMAIL_RUNTIME_PATTERN.test(emailJavascript), "The e-mail bundle loads browser-only modules", BROWSER_ONLY_REASON);
|
|
201
182
|
const emailBuildSize = Buffer.byteLength(emailJavascript);
|
|
202
183
|
const emailLocaleBytes = (0, node_fs_1.readdirSync)((0, node_path_1.join)(emailRoot, "locales")).reduce((total, file) => total + (0, node_fs_1.readFileSync)((0, node_path_1.join)(emailRoot, "locales", file)).byteLength, 0);
|
|
203
184
|
const limit = (0, output_1.formatSize)(EMAIL_BUILD_SIZE_CEILING_BYTES);
|
|
204
|
-
ensure(emailBuildSize <= EMAIL_BUILD_SIZE_CEILING_BYTES, `The e-mail bundle is ${(0, output_1.formatSize)(emailBuildSize)} of JavaScript`, `The limit is ${limit}.`);
|
|
185
|
+
(0, ensure_1.ensure)(emailBuildSize <= EMAIL_BUILD_SIZE_CEILING_BYTES, `The e-mail bundle is ${(0, output_1.formatSize)(emailBuildSize)} of JavaScript`, `The limit is ${limit}.`);
|
|
205
186
|
const { renderEmail } = await Promise.resolve(`${(0, node_path_1.join)(emailRoot, "email-renderer.js")}`).then(s => __importStar(require(s)));
|
|
206
187
|
for (const emailCase of EMAIL_CASES) {
|
|
207
188
|
const html = await renderEmail(emailCase.name, emailCase.props);
|
|
208
|
-
ensure(html.startsWith("<!doctype html>"), `${emailCase.name} does not render a full HTML document`);
|
|
189
|
+
(0, ensure_1.ensure)((0, guards_1.isText)(html) && html.startsWith("<!doctype html>"), `${emailCase.name} does not render a full HTML document`);
|
|
209
190
|
if (emailCase.name === "EmailLayout")
|
|
210
191
|
checkLayoutEmail(html);
|
|
211
|
-
ensure(html.includes(emailCase.marker), `${emailCase.name} does not render its props`, `Its HTML lacks ${emailCase.marker}.`);
|
|
192
|
+
(0, ensure_1.ensure)(html.includes(emailCase.marker), `${emailCase.name} does not render its props`, `Its HTML lacks ${emailCase.marker}.`);
|
|
212
193
|
}
|
|
213
194
|
return [
|
|
214
195
|
"E-mail contracts hold",
|
|
@@ -219,18 +200,6 @@ async function checkEmailContracts(workspace) {
|
|
|
219
200
|
}
|
|
220
201
|
const LINE_BREAK = /\r?\n/;
|
|
221
202
|
const STACK_TRACE_HINT = "Run with --verbose for the full trace.";
|
|
222
|
-
function describeError(error, isVerbose) {
|
|
223
|
-
if (error instanceof cli_1.CliError)
|
|
224
|
-
return error.problem;
|
|
225
|
-
if (!(error instanceof Error))
|
|
226
|
-
return { title: String(error) };
|
|
227
|
-
const [title] = error.message.split(LINE_BREAK);
|
|
228
|
-
const stack = (error.stack ?? "").split(LINE_BREAK);
|
|
229
|
-
return {
|
|
230
|
-
title: title || error.name,
|
|
231
|
-
details: isVerbose ? stack : [STACK_TRACE_HINT],
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
203
|
async function verifySources() {
|
|
235
204
|
const options = (0, verify_source_sources_1.readSourceOptions)();
|
|
236
205
|
const { layers, coreLayer } = (0, verify_source_sources_1.readSources)(options);
|
|
@@ -251,7 +220,7 @@ async function verifySources() {
|
|
|
251
220
|
await (0, common_1.installDeps)(workspace, context.mapLine, ["--ignore-scripts"]);
|
|
252
221
|
await (0, verify_source_build_1.prepareTypes)(context);
|
|
253
222
|
await (0, verify_source_build_1.buildAndTypeCheck)(context);
|
|
254
|
-
await tasks.run("Checking the client bundle", async () => checkClientBundle(workspace), { done: "Client bundle checked", failed: "Client bundle check failed" });
|
|
223
|
+
await tasks.run("Checking the client bundle", async () => (0, verify_source_client_bundle_1.checkClientBundle)(workspace), { done: "Client bundle checked", failed: "Client bundle check failed" });
|
|
255
224
|
await tasks.run("Checking the e-mail contracts", async () => checkEmailContracts(workspace), { done: (line) => line, failed: "E-mail contracts failed" });
|
|
256
225
|
await tasks.run("Checking the server modules", async () => checkServerModulesBundle(workspace), { done: (line) => line, failed: "Server modules check failed" });
|
|
257
226
|
return { ok: true, modules: layers.length };
|
|
@@ -276,7 +245,22 @@ async function main() {
|
|
|
276
245
|
process.exitCode = error.exitCode;
|
|
277
246
|
return;
|
|
278
247
|
}
|
|
279
|
-
|
|
248
|
+
let problem;
|
|
249
|
+
if (error instanceof cli_1.CliError) {
|
|
250
|
+
problem = error.problem;
|
|
251
|
+
}
|
|
252
|
+
else if (error instanceof Error) {
|
|
253
|
+
const [title] = error.message.split(LINE_BREAK);
|
|
254
|
+
const stack = (error.stack ?? "").split(LINE_BREAK);
|
|
255
|
+
problem = {
|
|
256
|
+
title: title || error.name,
|
|
257
|
+
details: (0, cli_1.isVerboseRun)() ? stack : [STACK_TRACE_HINT],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
problem = { title: String(error) };
|
|
262
|
+
}
|
|
263
|
+
result = { ok: false, problem };
|
|
280
264
|
}
|
|
281
265
|
if (process.send) {
|
|
282
266
|
process.exitCode = result.ok ? 0 : 1;
|
|
@@ -5,18 +5,20 @@ exports.readSources = readSources;
|
|
|
5
5
|
const node_fs_1 = require("node:fs");
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const common_1 = require("./common");
|
|
8
|
+
const guards_1 = require("./internal/guards");
|
|
9
|
+
const plain_object_1 = require("./internal/plain-object");
|
|
8
10
|
const output_1 = require("./output");
|
|
9
11
|
const verify_source_result_1 = require("./verify-source-result");
|
|
10
12
|
const DMS_PACKAGE = "@antelopejs/dms";
|
|
11
13
|
const DMS_CORE_LAYER_PACKAGE = "@antelopejs/dms-frontend-vue";
|
|
12
14
|
const CORE_LAYER_DIRECTORY = "frontend-vue";
|
|
13
15
|
const FRONTEND_ENTRY = "dms.frontend.ts";
|
|
14
|
-
const ADD_DEV_DEPENDENCY =
|
|
15
|
-
pnpm
|
|
16
|
-
npm
|
|
17
|
-
yarn
|
|
18
|
-
bun
|
|
19
|
-
|
|
16
|
+
const ADD_DEV_DEPENDENCY = new Map([
|
|
17
|
+
["pnpm", "pnpm add -D"],
|
|
18
|
+
["npm", "npm install -D"],
|
|
19
|
+
["yarn", "yarn add -D"],
|
|
20
|
+
["bun", "bun add -d"],
|
|
21
|
+
]);
|
|
20
22
|
const LOCKFILES = [
|
|
21
23
|
["pnpm-lock.yaml", "pnpm"],
|
|
22
24
|
["package-lock.json", "npm"],
|
|
@@ -24,16 +26,46 @@ const LOCKFILES = [
|
|
|
24
26
|
["bun.lock", "bun"],
|
|
25
27
|
["bun.lockb", "bun"],
|
|
26
28
|
];
|
|
29
|
+
function malformedVariable(variable, expected) {
|
|
30
|
+
return new common_1.UsageError({
|
|
31
|
+
title: `${variable} is not ${expected}`,
|
|
32
|
+
reason: `\`ajs dms verify-source\` starts the runner with ${variable} set to ${expected}.`,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function readTextList(variable) {
|
|
36
|
+
const value = JSON.parse(process.env[variable] ?? "[]");
|
|
37
|
+
if (Array.isArray(value) && value.every(guards_1.isText))
|
|
38
|
+
return value;
|
|
39
|
+
throw malformedVariable(variable, "a JSON list of paths");
|
|
40
|
+
}
|
|
41
|
+
function readTextRecord(variable) {
|
|
42
|
+
const value = JSON.parse(process.env[variable] ?? "{}");
|
|
43
|
+
if ((0, plain_object_1.isPlainObject)(value)) {
|
|
44
|
+
const entries = Object.entries(value);
|
|
45
|
+
if (entries.every((entry) => (0, guards_1.isText)(entry[1]))) {
|
|
46
|
+
return Object.fromEntries(entries);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw malformedVariable(variable, "a JSON record of paths by package name");
|
|
50
|
+
}
|
|
27
51
|
function readSourceOptions() {
|
|
28
52
|
return {
|
|
29
53
|
projectDir: process.cwd(),
|
|
30
54
|
layerSource: process.env.DMS_LAYER_SOURCE || undefined,
|
|
31
|
-
moduleSources:
|
|
32
|
-
localPackages:
|
|
55
|
+
moduleSources: readTextList("DMS_MODULE_SOURCES"),
|
|
56
|
+
localPackages: readTextRecord("DMS_LOCAL_PACKAGES"),
|
|
33
57
|
};
|
|
34
58
|
}
|
|
35
59
|
function readManifest(packagePath) {
|
|
36
|
-
|
|
60
|
+
const parsed = JSON.parse((0, node_fs_1.readFileSync)(packagePath, "utf8"));
|
|
61
|
+
if (!(0, plain_object_1.isPlainObject)(parsed))
|
|
62
|
+
return {};
|
|
63
|
+
const { name, version, packageManager } = parsed;
|
|
64
|
+
return {
|
|
65
|
+
name: (0, guards_1.isText)(name) ? name : undefined,
|
|
66
|
+
version: (0, guards_1.isText)(version) ? version : undefined,
|
|
67
|
+
packageManager: (0, guards_1.isText)(packageManager) ? packageManager : undefined,
|
|
68
|
+
};
|
|
37
69
|
}
|
|
38
70
|
function readLayer(root) {
|
|
39
71
|
const packagePath = (0, node_path_1.join)(root, "package.json");
|
|
@@ -68,7 +100,7 @@ function packageManager(projectDir) {
|
|
|
68
100
|
const packagePath = (0, node_path_1.join)(directory, "package.json");
|
|
69
101
|
if ((0, node_fs_1.existsSync)(packagePath)) {
|
|
70
102
|
const [name] = (readManifest(packagePath).packageManager ?? "").split("@");
|
|
71
|
-
if (name && ADD_DEV_DEPENDENCY
|
|
103
|
+
if (name && ADD_DEV_DEPENDENCY.has(name))
|
|
72
104
|
return name;
|
|
73
105
|
const lockfile = LOCKFILES.find(([file]) => (0, node_fs_1.existsSync)((0, node_path_1.join)(directory, file)));
|
|
74
106
|
if (lockfile)
|
|
@@ -79,7 +111,7 @@ function packageManager(projectDir) {
|
|
|
79
111
|
}
|
|
80
112
|
}
|
|
81
113
|
function addDmsCommand(projectDir, version = "") {
|
|
82
|
-
return `${ADD_DEV_DEPENDENCY
|
|
114
|
+
return `${ADD_DEV_DEPENDENCY.get(packageManager(projectDir))} ${DMS_PACKAGE}${version}`;
|
|
83
115
|
}
|
|
84
116
|
function describeDirectory(directory) {
|
|
85
117
|
return (0, node_path_1.resolve)(directory) === process.cwd()
|
|
@@ -107,6 +139,12 @@ function installedCoreLayer(projectDir) {
|
|
|
107
139
|
],
|
|
108
140
|
});
|
|
109
141
|
const { version } = readManifest(packagePath);
|
|
142
|
+
if (version === undefined)
|
|
143
|
+
throw new common_1.UsageError({
|
|
144
|
+
title: `${DMS_PACKAGE} has no text "version" in its package.json`,
|
|
145
|
+
reason: `${(0, output_1.showPath)(packagePath)} has no "version" that is text, and the verification names the installed ${DMS_PACKAGE} by it.`,
|
|
146
|
+
fixes: [`Reinstall it: ${addDmsCommand(projectDir, "@latest")}`],
|
|
147
|
+
});
|
|
110
148
|
const root = (0, node_path_1.join)((0, node_path_1.dirname)(packagePath), CORE_LAYER_DIRECTORY);
|
|
111
149
|
const layer = (0, node_fs_1.existsSync)((0, node_path_1.join)(root, "package.json"))
|
|
112
150
|
? readLayer(root)
|
package/dist/workspace-setup.js
CHANGED
|
@@ -95,7 +95,7 @@ async function installDeps(workspaceDir, mapLine, extraArgs = []) {
|
|
|
95
95
|
task.succeed(progress.doneLabel);
|
|
96
96
|
}
|
|
97
97
|
catch (error) {
|
|
98
|
-
(0, output_1.endInterruptedTask)(task, error, "Dependency install stopped");
|
|
98
|
+
(0, output_1.endInterruptedTask)(task, error instanceof cancellation_1.CancelledError ? error : undefined, "Dependency install stopped");
|
|
99
99
|
throw error;
|
|
100
100
|
}
|
|
101
101
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antelopejs/dms-frontend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Frontend-agnostic loader for AntelopeJS DMS, shipping the Vue 3 renderer (Vite, Inertia, SSR)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antelope",
|
|
@@ -76,9 +76,7 @@
|
|
|
76
76
|
"prepare": "if git rev-parse --is-inside-work-tree >/dev/null 2>&1 && command -v lefthook >/dev/null 2>&1; then lefthook install; fi",
|
|
77
77
|
"checks": "antelopejs-checks",
|
|
78
78
|
"size": "antelopejs-check-size",
|
|
79
|
-
"ratchet": "antelopejs-ratchet",
|
|
80
79
|
"sync": "antelopejs-sync",
|
|
81
|
-
"ratchet:update": "antelopejs-ratchet --update",
|
|
82
80
|
"sync:check": "antelopejs-sync --check",
|
|
83
81
|
"format:check": "oxfmt --check .",
|
|
84
82
|
"suppressions": "antelopejs-suppressions",
|
|
@@ -92,7 +90,8 @@
|
|
|
92
90
|
"semver": "^7.7.4"
|
|
93
91
|
},
|
|
94
92
|
"devDependencies": {
|
|
95
|
-
"@antelopejs/core": "^1.
|
|
93
|
+
"@antelopejs/core": "^1.20.0",
|
|
94
|
+
"@antelopejs/interface-dms": "^0.10.0",
|
|
96
95
|
"@antelopejs/tooling-configs": "^0.2.17",
|
|
97
96
|
"@iconify/utils": "^3.1.0",
|
|
98
97
|
"@iconify/vue": "^5.0.1",
|
|
@@ -141,6 +140,9 @@
|
|
|
141
140
|
}
|
|
142
141
|
},
|
|
143
142
|
"antelopeJs": {
|
|
143
|
+
"docs": {
|
|
144
|
+
"standard": true
|
|
145
|
+
},
|
|
144
146
|
"skills": [
|
|
145
147
|
"./skills"
|
|
146
148
|
]
|
|
@@ -40,7 +40,7 @@ tags: [frontend, cli, renderer, vue, inertia, ssr, deployment, dms-module]
|
|
|
40
40
|
|
|
41
41
|
| Task | Page |
|
|
42
42
|
| --- | --- |
|
|
43
|
-
|
|
|
43
|
+
| Where to read the renderer releases a DMS release runs on | `/docs/frontend/introduction#compatibility` |
|
|
44
44
|
| One command in depth | `/docs/frontend/cli/<command>` |
|
|
45
45
|
| Variables and secrets | `/docs/frontend/configuration` |
|
|
46
46
|
| Module files and SDK | `/docs/frontend/frontend-modules/anatomy`, then `server-routes`, `sessions-and-sign-in`, `route-rules`, `emails` |
|
|
@@ -9,7 +9,6 @@ import { useHead } from "@unhead/vue";
|
|
|
9
9
|
import type { VueHeadClient } from "@unhead/vue/types";
|
|
10
10
|
import type { IconifyIcon } from "@iconify/vue";
|
|
11
11
|
import { parse } from "devalue";
|
|
12
|
-
import type { FetchOptions } from "ofetch";
|
|
13
12
|
import {
|
|
14
13
|
type App,
|
|
15
14
|
type Component,
|
|
@@ -28,6 +27,7 @@ import {
|
|
|
28
27
|
type DmsLocaleLoader,
|
|
29
28
|
type DmsPageProps,
|
|
30
29
|
type DmsPayload,
|
|
30
|
+
type DmsServerFetch,
|
|
31
31
|
type DmsUser,
|
|
32
32
|
createDmsFrontendRuntime,
|
|
33
33
|
dmsPageSuspenseProps,
|
|
@@ -107,11 +107,6 @@ export interface DmsConfiguredApp {
|
|
|
107
107
|
runtime: ReturnType<typeof createDmsFrontendRuntime>;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
export type DmsServerFetch = (
|
|
111
|
-
request: string,
|
|
112
|
-
options?: FetchOptions,
|
|
113
|
-
) => Promise<unknown>;
|
|
114
|
-
|
|
115
110
|
export const DMS_PAYLOAD_ID = "dms-payload";
|
|
116
111
|
export const SSR_ASYNC_COMPONENTS_ID = "dms-ssr-async-components";
|
|
117
112
|
const DEFAULT_LOCALE = "en";
|
|
@@ -156,9 +151,7 @@ drawLoadedIconsAtOnce();
|
|
|
156
151
|
function createBrowserRuntime(
|
|
157
152
|
serverFetch?: DmsServerFetch,
|
|
158
153
|
): DmsConfiguredApp["runtime"] {
|
|
159
|
-
const runtime = createDmsFrontendRuntime(
|
|
160
|
-
serverFetch as typeof import("ofetch").ofetch,
|
|
161
|
-
);
|
|
154
|
+
const runtime = createDmsFrontendRuntime(serverFetch);
|
|
162
155
|
// Nothing when the server did not render the page: no hydration then.
|
|
163
156
|
const payload = readServerRendered<DmsPayload | undefined>(
|
|
164
157
|
DMS_PAYLOAD_ID,
|
|
@@ -2,11 +2,20 @@ import { relative, sep } from "node:path";
|
|
|
2
2
|
|
|
3
3
|
const SERVER_ENTRY = /(?:^|[\\/])dms\.server\.[cm]?[jt]sx?$/;
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} id
|
|
7
|
+
* @returns {string}
|
|
8
|
+
*/
|
|
5
9
|
function stripQuery(id) {
|
|
6
10
|
const query = id.indexOf("?");
|
|
7
11
|
return query === -1 ? id : id.slice(0, query);
|
|
8
12
|
}
|
|
9
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @param {string} file
|
|
16
|
+
* @param {readonly string[]} moduleRoots
|
|
17
|
+
* @returns {boolean}
|
|
18
|
+
*/
|
|
10
19
|
function insideModuleServerDirectory(file, moduleRoots) {
|
|
11
20
|
return moduleRoots.some((root) => {
|
|
12
21
|
const path = relative(root, file);
|
|
@@ -20,6 +29,10 @@ function insideModuleServerDirectory(file, moduleRoots) {
|
|
|
20
29
|
* Whether `id`, a resolved module id, is server code: a module's server entry
|
|
21
30
|
* (`dms.server.*`) or a file under a `server/` directory of a module. Installed
|
|
22
31
|
* packages never are: `node_modules` has its own `server` directories.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} id
|
|
34
|
+
* @param {readonly string[]} moduleRoots
|
|
35
|
+
* @returns {boolean}
|
|
23
36
|
*/
|
|
24
37
|
export function isServerSource(id, moduleRoots) {
|
|
25
38
|
if (id.startsWith("\0")) return false;
|
|
@@ -44,6 +57,9 @@ export function isServerSource(id, moduleRoots) {
|
|
|
44
57
|
* import; the guard sits in the module graph instead, where every resolved file
|
|
45
58
|
* passes. Kept beside vite.config.ts rather than inside it so the plugin can be
|
|
46
59
|
* exercised on its own, the way head-order.mjs is.
|
|
60
|
+
*
|
|
61
|
+
* @param {readonly string[]} moduleRoots
|
|
62
|
+
* @returns {import("vite").Plugin}
|
|
47
63
|
*/
|
|
48
64
|
export function rejectServerSourcesInClient(moduleRoots) {
|
|
49
65
|
let ssrBuild = false;
|
|
@@ -16,10 +16,14 @@ const MINIMUM_SIZE_BYTES = 1_024;
|
|
|
16
16
|
const compressBrotli = promisify(brotliCompress);
|
|
17
17
|
const compressGzip = promisify(gzip);
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} directory
|
|
21
|
+
* @returns {Promise<string[]>}
|
|
22
|
+
*/
|
|
19
23
|
async function assetFiles(directory) {
|
|
20
24
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
21
25
|
const files = await Promise.all(
|
|
22
|
-
entries.map((entry) => {
|
|
26
|
+
entries.map(async (entry) => {
|
|
23
27
|
const path = join(directory, entry.name);
|
|
24
28
|
return entry.isDirectory() ? assetFiles(path) : [path];
|
|
25
29
|
}),
|
|
@@ -27,6 +31,10 @@ async function assetFiles(directory) {
|
|
|
27
31
|
return files.flat();
|
|
28
32
|
}
|
|
29
33
|
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} path
|
|
36
|
+
* @returns {Promise<void>}
|
|
37
|
+
*/
|
|
30
38
|
async function compressAsset(path) {
|
|
31
39
|
if (!COMPRESSIBLE_EXTENSIONS.has(extname(path))) return;
|
|
32
40
|
const content = await readFile(path);
|
|
@@ -10,11 +10,20 @@ export const TRANSLATIONS_OWNER = "translations";
|
|
|
10
10
|
|
|
11
11
|
const LOCALE_CATALOG = /[\\/]locales\.generated[\\/]/;
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @param {string} id
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
13
17
|
function stripQuery(id) {
|
|
14
18
|
const query = id.indexOf("?");
|
|
15
19
|
return query === -1 ? id : id.slice(0, query);
|
|
16
20
|
}
|
|
17
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} root
|
|
24
|
+
* @param {string} file
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
*/
|
|
18
27
|
function isInside(root, file) {
|
|
19
28
|
const path = relative(root, file);
|
|
20
29
|
return Boolean(path) && !path.startsWith("..") && !path.startsWith(sep);
|
|
@@ -26,7 +35,9 @@ function isInside(root, file) {
|
|
|
26
35
|
* what every page shares (the renderer's runtime, the UI and icon libraries,
|
|
27
36
|
* an installed package).
|
|
28
37
|
*
|
|
38
|
+
* @param {string} id
|
|
29
39
|
* @param {{ root: string, name?: string, packageName?: string, id: string }[]} modules
|
|
40
|
+
* @returns {string}
|
|
30
41
|
*/
|
|
31
42
|
export function entryOwner(id, modules) {
|
|
32
43
|
if (id.startsWith("\0")) return SHARED_OWNER;
|
|
@@ -42,13 +53,18 @@ export function entryOwner(id, modules) {
|
|
|
42
53
|
/**
|
|
43
54
|
* The files a page loads before its first line runs: the entry chunks and
|
|
44
55
|
* their static imports, transitively, by file name.
|
|
56
|
+
*
|
|
57
|
+
* @param {import("vite").Rollup.OutputBundle} bundle
|
|
58
|
+
* @returns {(import("vite").Rollup.OutputChunk | undefined)[]}
|
|
45
59
|
*/
|
|
46
60
|
function entryClosure(bundle) {
|
|
47
61
|
const chunks = Object.values(bundle).filter(
|
|
48
62
|
(output) => output.type === "chunk",
|
|
49
63
|
);
|
|
50
64
|
const byName = new Map(chunks.map((chunk) => [chunk.fileName, chunk]));
|
|
65
|
+
/** @type {Set<string>} */
|
|
51
66
|
const seen = new Set();
|
|
67
|
+
/** @param {import("vite").Rollup.OutputChunk | undefined} chunk */
|
|
52
68
|
const visit = (chunk) => {
|
|
53
69
|
if (!chunk || seen.has(chunk.fileName)) return;
|
|
54
70
|
seen.add(chunk.fileName);
|
|
@@ -64,10 +80,13 @@ function entryClosure(bundle) {
|
|
|
64
80
|
* rendered for each (`renderedLength`, before minification): an estimate that
|
|
65
81
|
* needs nothing the bundle does not already hold.
|
|
66
82
|
*
|
|
83
|
+
* @param {import("vite").Rollup.OutputBundle} bundle
|
|
84
|
+
* @param {{ root: string, name?: string, packageName?: string, id: string }[]} modules
|
|
67
85
|
* @returns {{ files: string[], bytes: number, owners: Record<string, number> }}
|
|
68
86
|
*/
|
|
69
87
|
export function attributeEntry(bundle, modules) {
|
|
70
88
|
const files = entryClosure(bundle);
|
|
89
|
+
/** @type {Record<string, number>} */
|
|
71
90
|
const owners = {};
|
|
72
91
|
let bytes = 0;
|
|
73
92
|
for (const chunk of files) {
|
|
@@ -109,6 +128,9 @@ export function attributeEntry(bundle, modules) {
|
|
|
109
128
|
*
|
|
110
129
|
* The weight is recorded once the bundle is written: plugins that generate the
|
|
111
130
|
* bundle after this one still rewrite the chunks' code.
|
|
131
|
+
*
|
|
132
|
+
* @param {{ root: string, name?: string, packageName?: string, id: string }[]} modules
|
|
133
|
+
* @returns {import("vite").Plugin}
|
|
112
134
|
*/
|
|
113
135
|
export function recordEntryWeight(modules) {
|
|
114
136
|
let ssrBuild = false;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { usePage } from "@inertiajs/vue3";
|
|
2
|
-
import { ofetch } from "ofetch";
|
|
3
2
|
import {
|
|
4
3
|
type Component,
|
|
5
4
|
type EffectScope,
|
|
@@ -19,6 +18,7 @@ import {
|
|
|
19
18
|
type DmsPluginRegistrationOptions,
|
|
20
19
|
type DmsPluginSetup,
|
|
21
20
|
type DmsRoute,
|
|
21
|
+
type DmsServerFetch,
|
|
22
22
|
type DmsSharedPagePayload,
|
|
23
23
|
type RouteLocationRaw,
|
|
24
24
|
} from "./types";
|
|
@@ -212,7 +212,7 @@ export interface DmsFrontendRuntime {
|
|
|
212
212
|
/** Whether to warn about what a development render does wrong. */
|
|
213
213
|
devWarnings?: boolean;
|
|
214
214
|
runtimeHooks: Map<string, DmsRuntimeHook[]>;
|
|
215
|
-
serverFetch?:
|
|
215
|
+
serverFetch?: DmsServerFetch;
|
|
216
216
|
currentError: Ref<Error | null>;
|
|
217
217
|
route: DmsRoute;
|
|
218
218
|
currentRoutePattern?: string;
|