@antelopejs/dms-frontend 0.7.1 → 0.9.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 +4 -4
- package/dist/commands/build-action.d.ts +8 -5
- package/dist/commands/build-action.js +16 -41
- package/dist/commands/build.js +9 -15
- package/dist/commands/dev-action.d.ts +2 -0
- package/dist/commands/dev-action.js +14 -3
- package/dist/commands/dev.js +3 -1
- package/dist/commands/start-action.d.ts +2 -0
- package/dist/commands/start-action.js +65 -47
- package/dist/commands/start.js +8 -6
- package/dist/common.d.ts +1 -0
- package/dist/common.js +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +9 -0
- package/dist/derived-outputs.d.ts +1 -5
- package/dist/derived-outputs.js +48 -35
- package/dist/dev-modules.d.ts +5 -0
- package/dist/dev-modules.js +88 -0
- package/dist/entry-weight.d.ts +24 -0
- package/dist/entry-weight.js +86 -0
- package/dist/fs-sync.d.ts +1 -0
- package/dist/fs-sync.js +6 -0
- package/dist/help.js +12 -4
- package/dist/index.js +4 -6
- package/dist/layer-watch.js +7 -2
- package/dist/layers.d.ts +2 -3
- package/dist/layers.js +1 -95
- package/dist/locale-files.d.ts +6 -0
- package/dist/locale-files.js +75 -0
- package/dist/manifest.d.ts +8 -8
- package/dist/manifest.js +17 -39
- package/dist/materialize.js +6 -0
- package/dist/module-set.d.ts +14 -12
- package/dist/module-set.js +39 -31
- package/dist/private-values.d.ts +3 -2
- package/dist/private-values.js +16 -5
- package/dist/project-modules-child.d.ts +13 -0
- package/dist/project-modules-child.js +26 -0
- package/dist/project-modules.d.ts +47 -0
- package/dist/project-modules.js +268 -0
- package/dist/workspace-setup.d.ts +3 -7
- package/dist/workspace-setup.js +79 -62
- package/dist/workspace.d.ts +8 -4
- package/dist/workspace.js +1 -1
- package/package.json +13 -8
- package/skills/dms-frontend/SKILL.md +2 -2
- package/templates/vue/app-runtime.ts +8 -1
- package/templates/vue/client-chunking.mjs +61 -0
- package/templates/vue/email-renderer.ts +6 -1
- package/templates/vue/entry-weight.mjs +132 -0
- package/templates/vue/frontend-build-loader.ts +1 -1
- package/templates/vue/frontend-module.ts +168 -1
- package/templates/vue/gitignore +1 -0
- package/templates/vue/main.ts +32 -2
- package/templates/vue/network-error.ts +3 -1
- package/templates/vue/package.json +3 -3
- package/templates/vue/patches/@vueuse__core@14.4.0.patch +24 -0
- package/templates/vue/pnpm-workspace.yaml +5 -0
- package/templates/vue/prepare-types.mjs +2 -7
- package/templates/vue/public-options.ts +19 -0
- package/templates/vue/server/auth/backend.mjs +20 -3
- package/templates/vue/server/auth/client-ip.mjs +64 -22
- package/templates/vue/server/auth/session.mjs +4 -11
- package/templates/vue/server/backend-proxies.mjs +13 -2
- package/templates/vue/server/backend-response.mjs +2 -13
- package/templates/vue/server/cli-report.mjs +42 -18
- package/templates/vue/server/client-manifest.mjs +34 -58
- package/templates/vue/server/dev-private-files.mjs +1 -1
- package/templates/vue/server/dev-styles.mjs +16 -5
- package/templates/vue/server/homepage.mjs +4 -1
- package/templates/vue/server/in-place-render.mjs +110 -0
- package/templates/vue/server/module-event.mjs +23 -8
- package/templates/vue/server/module-server.mjs +4 -4
- package/templates/vue/server/module-testing.mjs +5 -3
- package/templates/vue/server/page-props.mjs +10 -0
- package/templates/vue/server/proxy-compression.mjs +15 -8
- package/templates/vue/server/proxy-headers.mjs +12 -1
- package/templates/vue/server/proxy-redirects.mjs +66 -0
- package/templates/vue/server/proxy-transfers.mjs +110 -0
- package/templates/vue/server/public-endpoints.mjs +2 -2
- package/templates/vue/server/public-options.mjs +49 -0
- package/templates/vue/server/request-routing.mjs +20 -0
- package/templates/vue/server/web-body.mjs +24 -0
- package/templates/vue/server-module.ts +19 -7
- package/templates/vue/server.mjs +98 -78
- package/templates/vue/sfc-global-types.mjs +119 -0
- package/templates/vue/ssr-renderer.ts +27 -1
- package/templates/vue/ui-kbd.mjs +45 -0
- package/templates/vue/vite.config.ts +104 -47
- package/templates/vue/vite.email.config.ts +6 -3
- package/templates/vue/vite.server.config.ts +5 -2
- package/dist/commands/snapshot-action.d.ts +0 -6
- package/dist/commands/snapshot-action.js +0 -53
- package/dist/commands/snapshot.d.ts +0 -2
- package/dist/commands/snapshot.js +0 -55
- package/dist/snapshot.d.ts +0 -25
- package/dist/snapshot.js +0 -90
- package/templates/vue/server/backend-wake.mjs +0 -129
package/dist/derived-outputs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DERIVED_OUTPUTS =
|
|
3
|
+
exports.DERIVED_OUTPUTS = void 0;
|
|
4
4
|
exports.createFrontendModuleRegistry = createFrontendModuleRegistry;
|
|
5
5
|
exports.affectsLocaleMessages = affectsLocaleMessages;
|
|
6
6
|
exports.writeLocaleMessages = writeLocaleMessages;
|
|
@@ -8,9 +8,11 @@ const node_fs_1 = require("node:fs");
|
|
|
8
8
|
const node_path_1 = require("node:path");
|
|
9
9
|
const config_1 = require("./config");
|
|
10
10
|
const app_configs_1 = require("./app-configs");
|
|
11
|
+
const locale_files_1 = require("./locale-files");
|
|
11
12
|
const asset_roots_1 = require("./asset-roots");
|
|
12
13
|
const layer_aliases_1 = require("./layer-aliases");
|
|
13
14
|
const layers_1 = require("./layers");
|
|
15
|
+
const project_modules_1 = require("./project-modules");
|
|
14
16
|
const fs_sync_1 = require("./fs-sync");
|
|
15
17
|
const GENERATED_MODULE_ID = /^[A-Za-z0-9_-]+$/;
|
|
16
18
|
function validateFrontendModuleRegistry(registry, workspaceDir) {
|
|
@@ -42,6 +44,7 @@ function createFrontendModuleRegistry(workspaceDir, layers) {
|
|
|
42
44
|
id: (0, layers_1.getLayerSafeName)(layer),
|
|
43
45
|
name: layer.name ?? layer.packageName,
|
|
44
46
|
packageName: layer.packageName,
|
|
47
|
+
version: (0, project_modules_1.readShippingVersion)(layer.sourcePath ?? layer.path),
|
|
45
48
|
root: (0, layers_1.getLayerWorkspacePath)(workspaceDir, layer),
|
|
46
49
|
priority: layer.priority ?? 0,
|
|
47
50
|
entry: (0, node_fs_1.existsSync)(sourceEntry) ? config_1.FRONTEND_MODULE_ENTRY : undefined,
|
|
@@ -72,7 +75,7 @@ function writeFrontendModuleLoader(workspaceDir, registry) {
|
|
|
72
75
|
.map((module, index) => `import module${index} from "@frontend/${module.id}/${module.entry}";`)
|
|
73
76
|
.join("\n");
|
|
74
77
|
const registrations = modules
|
|
75
|
-
.map((module, index) => `{ name: ${JSON.stringify(module.name)}, module: module${index}, options: { public: ${JSON.stringify(module.options)} } }`)
|
|
78
|
+
.map((module, index) => `{ id: ${JSON.stringify(module.id)}, name: ${JSON.stringify(module.name)}, module: module${index}, options: { public: ${JSON.stringify(module.options)} } }`)
|
|
76
79
|
.join(", ");
|
|
77
80
|
const content = `${imports}\n\nimport type { DmsFrontendModuleRegistration } from "./frontend-module";\n\nexport const frontendModules: DmsFrontendModuleRegistration[] = [${registrations}];\n`;
|
|
78
81
|
return (0, fs_sync_1.applyContent)(content, (0, node_path_1.join)(workspaceDir, "frontend-modules.generated.ts"));
|
|
@@ -85,7 +88,7 @@ function writeFrontendBuildLoader(workspaceDir, registry) {
|
|
|
85
88
|
const declarations = modules
|
|
86
89
|
.map((module, index) => `{ id: ${JSON.stringify(module.id)}, setup: build${index} }`)
|
|
87
90
|
.join(", ");
|
|
88
|
-
const content = `${imports}\n\nimport type { FrontendBuildDeclaration } from "./frontend-build-loader";\n\nexport const frontendBuilds: FrontendBuildDeclaration[] = [${declarations}];\n`;
|
|
91
|
+
const content = `${imports}\n\nimport type { FrontendBuildDeclaration } from "./frontend-build-loader.ts";\n\nexport const frontendBuilds: FrontendBuildDeclaration[] = [${declarations}];\n`;
|
|
89
92
|
return (0, fs_sync_1.applyContent)(content, (0, node_path_1.join)(workspaceDir, "frontend-builds.generated.ts"));
|
|
90
93
|
}
|
|
91
94
|
function writeServerModuleLoader(workspaceDir, registry) {
|
|
@@ -148,24 +151,6 @@ function mergeLocaleMessages(source, existing) {
|
|
|
148
151
|
return merged;
|
|
149
152
|
}
|
|
150
153
|
const LOCALE_DIRECTORY = "i18n/locales";
|
|
151
|
-
class InvalidLocaleFileError extends Error {
|
|
152
|
-
constructor(path, reason) {
|
|
153
|
-
super(`Invalid locale file ${path}: ${reason}`);
|
|
154
|
-
this.path = path;
|
|
155
|
-
this.reason = reason;
|
|
156
|
-
this.name = "InvalidLocaleFileError";
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
exports.InvalidLocaleFileError = InvalidLocaleFileError;
|
|
160
|
-
function readLocaleFile(path) {
|
|
161
|
-
try {
|
|
162
|
-
return JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
166
|
-
throw new InvalidLocaleFileError(path, reason);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
154
|
function readLocaleMessages(assets, registry) {
|
|
170
155
|
const roots = new Map(registry.modules.map((module) => [module.id, module.root]));
|
|
171
156
|
const messages = {};
|
|
@@ -174,7 +159,7 @@ function readLocaleMessages(assets, registry) {
|
|
|
174
159
|
const root = roots.get(asset.moduleId);
|
|
175
160
|
if (!locale || !root)
|
|
176
161
|
continue;
|
|
177
|
-
const value = readLocaleFile((0, node_path_1.join)(root, asset.relativePath));
|
|
162
|
+
const value = (0, locale_files_1.readLocaleFile)((0, node_path_1.join)(root, asset.relativePath));
|
|
178
163
|
messages[locale] = mergeLocaleMessages(value, messages[locale] ?? {});
|
|
179
164
|
}
|
|
180
165
|
return messages;
|
|
@@ -182,13 +167,28 @@ function readLocaleMessages(assets, registry) {
|
|
|
182
167
|
function affectsLocaleMessages(relativePath) {
|
|
183
168
|
return (0, asset_roots_1.affectsAssetDirectory)(LOCALE_DIRECTORY, relativePath);
|
|
184
169
|
}
|
|
170
|
+
const FALLBACK_LOCALE = "en";
|
|
171
|
+
const RENDERER_TRANSLATED_KEYS = ["error.network"];
|
|
172
|
+
function withoutMessage(messages, key) {
|
|
173
|
+
const [head, ...rest] = key.split(".");
|
|
174
|
+
if (!(head in messages))
|
|
175
|
+
return messages;
|
|
176
|
+
const { [head]: value, ...others } = messages;
|
|
177
|
+
if (!rest.length)
|
|
178
|
+
return others;
|
|
179
|
+
if (!isRecord(value))
|
|
180
|
+
return messages;
|
|
181
|
+
const remaining = withoutMessage(value, rest.join("."));
|
|
182
|
+
return Object.keys(remaining).length
|
|
183
|
+
? { ...others, [head]: remaining }
|
|
184
|
+
: others;
|
|
185
|
+
}
|
|
185
186
|
function localeModuleSource(supportedLocales) {
|
|
186
|
-
const loaders = supportedLocales
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
type LocaleMessages = Record<string, unknown>;
|
|
187
|
+
const loaders = supportedLocales.map((locale) => ` ${JSON.stringify(locale)}: () => import(${JSON.stringify(`./locales.generated/${locale}`)}),`);
|
|
188
|
+
const fallback = supportedLocales.includes(FALLBACK_LOCALE)
|
|
189
|
+
? FALLBACK_LOCALE
|
|
190
|
+
: supportedLocales[0];
|
|
191
|
+
return `type LocaleMessages = Record<string, unknown>;
|
|
192
192
|
type LocaleLoader = () => Promise<{ default: LocaleMessages }>;
|
|
193
193
|
interface LocaleMessagesTarget {
|
|
194
194
|
setLocaleMessage(locale: string, messages: LocaleMessages): void;
|
|
@@ -200,13 +200,13 @@ interface LocaleState {
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
export const supportedLocales = ${JSON.stringify(supportedLocales)};
|
|
203
|
+
const fallbackLocale: string | undefined = ${JSON.stringify(fallback)};
|
|
203
204
|
const localeLoaders: Record<string, LocaleLoader> = {
|
|
204
|
-
"en": async () => ({ default: defaultMessages }),
|
|
205
205
|
${loaders.join("\n")}
|
|
206
206
|
};
|
|
207
207
|
const shared: LocaleState | undefined = import.meta.hot?.data.state;
|
|
208
208
|
const state: LocaleState = shared ?? {
|
|
209
|
-
messages: {
|
|
209
|
+
messages: {},
|
|
210
210
|
targets: new Set(),
|
|
211
211
|
version: 0,
|
|
212
212
|
};
|
|
@@ -216,11 +216,20 @@ async function readLocaleMessages(locale: string): Promise<LocaleMessages> {
|
|
|
216
216
|
return (await localeLoaders[locale]()).default;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
|
|
219
|
+
/**
|
|
220
|
+
* The catalog that serves \`locale\`: its own when the application has one,
|
|
221
|
+
* else the fallback locale's.
|
|
222
|
+
*/
|
|
223
|
+
export function catalogLocale(locale: string): string | undefined {
|
|
220
224
|
const normalized = locale.slice(0, 2);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
225
|
+
return normalized in localeLoaders ? normalized : fallbackLocale;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export async function loadLocaleMessages(locale: string): Promise<LocaleMessages> {
|
|
229
|
+
const catalog = catalogLocale(locale);
|
|
230
|
+
if (!catalog) return {};
|
|
231
|
+
localeMessages[catalog] ??= await readLocaleMessages(catalog);
|
|
232
|
+
return localeMessages[catalog];
|
|
224
233
|
}
|
|
225
234
|
|
|
226
235
|
/** Development only: applies every regenerated catalog to \`target\`. */
|
|
@@ -262,10 +271,14 @@ function writeLocaleMessages(workspaceDir, registry) {
|
|
|
262
271
|
changed = (0, fs_sync_1.applyContent)(content, path) || changed;
|
|
263
272
|
};
|
|
264
273
|
(0, node_fs_1.mkdirSync)(outputDir, { recursive: true });
|
|
274
|
+
const fallback = RENDERER_TRANSLATED_KEYS.reduce(withoutMessage, messages[FALLBACK_LOCALE] ?? {});
|
|
265
275
|
for (const [locale, value] of Object.entries(messages)) {
|
|
266
276
|
const catalog = JSON.stringify(value);
|
|
277
|
+
const complete = locale === FALLBACK_LOCALE
|
|
278
|
+
? catalog
|
|
279
|
+
: JSON.stringify(mergeLocaleMessages(fallback, value));
|
|
267
280
|
apply(catalog, (0, node_path_1.join)(outputDir, `${locale}.json`));
|
|
268
|
-
apply(`const messages = ${
|
|
281
|
+
apply(`const messages = ${complete};\nexport default messages;\n`, (0, node_path_1.join)(outputDir, `${locale}.ts`));
|
|
269
282
|
outputs.add(`${locale}.json`).add(`${locale}.ts`);
|
|
270
283
|
}
|
|
271
284
|
const supportedLocales = Object.keys(messages);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ProjectFrontendModule, ProjectModulesOptions } from "./project-modules";
|
|
2
|
+
import type { Manifest, ResolvedLayer } from "./workspace";
|
|
3
|
+
export declare function readProjectModulesFresh(options: ProjectModulesOptions): Promise<ProjectFrontendModule[]>;
|
|
4
|
+
export declare function warnModuleDrift(layers: readonly ResolvedLayer[], manifest: Manifest): void;
|
|
5
|
+
export declare function withBackendValues(modules: readonly ProjectFrontendModule[], manifest: Manifest): ResolvedLayer[];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readProjectModulesFresh = readProjectModulesFresh;
|
|
4
|
+
exports.warnModuleDrift = warnModuleDrift;
|
|
5
|
+
exports.withBackendValues = withBackendValues;
|
|
6
|
+
const node_child_process_1 = require("node:child_process");
|
|
7
|
+
const cli_1 = require("@antelopejs/core/cli");
|
|
8
|
+
const private_values_1 = require("./private-values");
|
|
9
|
+
function readProjectModulesFresh(options) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const child = (0, node_child_process_1.fork)(require.resolve("./project-modules-child"), [], {
|
|
12
|
+
stdio: ["ignore", "inherit", "inherit", "ipc"],
|
|
13
|
+
});
|
|
14
|
+
let reply;
|
|
15
|
+
child.once("message", (message) => {
|
|
16
|
+
reply = message;
|
|
17
|
+
});
|
|
18
|
+
child.once("error", reject);
|
|
19
|
+
child.once("exit", (code, signal) => {
|
|
20
|
+
if (!reply) {
|
|
21
|
+
reject(new Error(`Reading the project's modules stopped (${signal ?? `exit code ${code}`})`));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const ui = (0, cli_1.getProcessUi)();
|
|
25
|
+
for (const message of reply.messages)
|
|
26
|
+
ui.message(...message);
|
|
27
|
+
if ("modules" in reply)
|
|
28
|
+
resolve(reply.modules);
|
|
29
|
+
else if ("problem" in reply)
|
|
30
|
+
reject(new cli_1.CliError(reply.problem));
|
|
31
|
+
else
|
|
32
|
+
reject(new Error(reply.failure));
|
|
33
|
+
});
|
|
34
|
+
child.send(options);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const URL_BOUNDARY = "(?=[/?#]|$)";
|
|
38
|
+
function escapeRegExp(value) {
|
|
39
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
40
|
+
}
|
|
41
|
+
function rewriteOrigins(options, rewrites) {
|
|
42
|
+
if (rewrites.length === 0)
|
|
43
|
+
return options;
|
|
44
|
+
const replacements = new Map(rewrites.map(({ from, to }) => [from, to]));
|
|
45
|
+
const alternation = [...replacements.keys()]
|
|
46
|
+
.sort((left, right) => right.length - left.length)
|
|
47
|
+
.map(escapeRegExp)
|
|
48
|
+
.join("|");
|
|
49
|
+
const pattern = new RegExp(`(?:${alternation})${URL_BOUNDARY}`, "g");
|
|
50
|
+
const rewrite = (value) => {
|
|
51
|
+
if (typeof value === "string")
|
|
52
|
+
return value.replace(pattern, (match) => replacements.get(match) ?? match);
|
|
53
|
+
if (Array.isArray(value))
|
|
54
|
+
return value.map(rewrite);
|
|
55
|
+
if (value !== null && typeof value === "object")
|
|
56
|
+
return rewriteObject(value);
|
|
57
|
+
return value;
|
|
58
|
+
};
|
|
59
|
+
const rewriteObject = (value) => Object.fromEntries(Object.entries(value).map(([key, item]) => [key, rewrite(item)]));
|
|
60
|
+
return rewriteObject(options);
|
|
61
|
+
}
|
|
62
|
+
function warnModuleDrift(layers, manifest) {
|
|
63
|
+
const served = new Set(layers.map((layer) => layer.name ?? ""));
|
|
64
|
+
const registered = new Set(manifest.modules.map((module) => module.name));
|
|
65
|
+
const ui = (0, cli_1.getProcessUi)();
|
|
66
|
+
for (const name of served) {
|
|
67
|
+
if (!registered.has(name))
|
|
68
|
+
ui.message("warn", `${name} is served from the project, but the backend does not register it`, {
|
|
69
|
+
detail: "Its frontendModule returns a registration the running backend did not add: check the module's configuration and startup",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
for (const name of registered) {
|
|
73
|
+
if (!served.has(name))
|
|
74
|
+
ui.message("warn", `${name} is registered by the backend, but not in the project: its pages are left out`, {
|
|
75
|
+
detail: `A build leaves it out too. Declare its frontendModule (dmsFrontend in its package.json), or add the module to antelope.config.ts`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function withBackendValues(modules, manifest) {
|
|
80
|
+
const registered = new Map(manifest.modules.map((module) => [module.name, module]));
|
|
81
|
+
return modules.map(({ layer }) => ({
|
|
82
|
+
...layer,
|
|
83
|
+
options: layer.options &&
|
|
84
|
+
rewriteOrigins(layer.options, manifest.originRewrites ?? []),
|
|
85
|
+
privateOptions: layer.privateOptions &&
|
|
86
|
+
(0, private_values_1.filledOptions)(layer.privateOptions, registered.get(layer.name ?? "")?.privateOptions),
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const ENTRY_WEIGHT_VARIABLE = "DMS_ENTRY_WEIGHT_WARNING";
|
|
2
|
+
export declare const DEFAULT_ENTRY_WEIGHT_WARNING_KB = 50;
|
|
3
|
+
export interface EntryShare {
|
|
4
|
+
owner: string;
|
|
5
|
+
bytes: number;
|
|
6
|
+
brotli: number;
|
|
7
|
+
}
|
|
8
|
+
export interface EntryWeight {
|
|
9
|
+
bytes: number;
|
|
10
|
+
brotli: number;
|
|
11
|
+
shares: EntryShare[];
|
|
12
|
+
}
|
|
13
|
+
export declare function readEntryWeight(workspaceDir: string): EntryWeight | undefined;
|
|
14
|
+
export declare function entryWeightThreshold(env: NodeJS.ProcessEnv): number;
|
|
15
|
+
export declare function heavyEntryModules(weight: EntryWeight, threshold: number): EntryShare[];
|
|
16
|
+
export declare function describeEntryShares(weight: EntryWeight): string[];
|
|
17
|
+
interface ReportUi {
|
|
18
|
+
message(level: "info" | "warn", text: string, options?: {
|
|
19
|
+
detail?: string;
|
|
20
|
+
details?: string[];
|
|
21
|
+
}): void;
|
|
22
|
+
}
|
|
23
|
+
export declare function reportEntryWeight(ui: ReportUi, workspaceDir: string, env: NodeJS.ProcessEnv): void;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_ENTRY_WEIGHT_WARNING_KB = exports.ENTRY_WEIGHT_VARIABLE = void 0;
|
|
4
|
+
exports.readEntryWeight = readEntryWeight;
|
|
5
|
+
exports.entryWeightThreshold = entryWeightThreshold;
|
|
6
|
+
exports.heavyEntryModules = heavyEntryModules;
|
|
7
|
+
exports.describeEntryShares = describeEntryShares;
|
|
8
|
+
exports.reportEntryWeight = reportEntryWeight;
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const node_path_1 = require("node:path");
|
|
11
|
+
const node_zlib_1 = require("node:zlib");
|
|
12
|
+
const cli_1 = require("@antelopejs/core/cli");
|
|
13
|
+
const output_1 = require("./output");
|
|
14
|
+
exports.ENTRY_WEIGHT_VARIABLE = "DMS_ENTRY_WEIGHT_WARNING";
|
|
15
|
+
exports.DEFAULT_ENTRY_WEIGHT_WARNING_KB = 50;
|
|
16
|
+
const ENTRY_WEIGHT_FILE = (0, node_path_1.join)("dist", "client", ".vite", "entry-weight.json");
|
|
17
|
+
const SHARED_OWNER = "shared";
|
|
18
|
+
const TRANSLATIONS_OWNER = "translations";
|
|
19
|
+
const NON_MODULE_OWNERS = new Set([SHARED_OWNER, TRANSLATIONS_OWNER]);
|
|
20
|
+
const BYTES_PER_KB = 1024;
|
|
21
|
+
function brotliSize(file) {
|
|
22
|
+
const compressed = `${file}.br`;
|
|
23
|
+
if ((0, node_fs_1.existsSync)(compressed))
|
|
24
|
+
return (0, node_fs_1.statSync)(compressed).size;
|
|
25
|
+
return (0, node_zlib_1.brotliCompressSync)((0, node_fs_1.readFileSync)(file), {
|
|
26
|
+
params: { [node_zlib_1.constants.BROTLI_PARAM_QUALITY]: node_zlib_1.constants.BROTLI_MAX_QUALITY },
|
|
27
|
+
}).length;
|
|
28
|
+
}
|
|
29
|
+
function readEntryWeight(workspaceDir) {
|
|
30
|
+
const path = (0, node_path_1.join)(workspaceDir, ENTRY_WEIGHT_FILE);
|
|
31
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
32
|
+
return undefined;
|
|
33
|
+
const recorded = JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
34
|
+
const brotli = recorded.files.reduce((sum, file) => sum + brotliSize((0, node_path_1.join)(workspaceDir, "dist", "client", file)), 0);
|
|
35
|
+
const ratio = recorded.bytes ? brotli / recorded.bytes : 0;
|
|
36
|
+
const shares = Object.entries(recorded.owners)
|
|
37
|
+
.map(([owner, bytes]) => ({
|
|
38
|
+
owner,
|
|
39
|
+
bytes,
|
|
40
|
+
brotli: Math.round(bytes * ratio),
|
|
41
|
+
}))
|
|
42
|
+
.sort((left, right) => right.bytes - left.bytes);
|
|
43
|
+
return { bytes: recorded.bytes, brotli, shares };
|
|
44
|
+
}
|
|
45
|
+
function entryWeightThreshold(env) {
|
|
46
|
+
const value = env[exports.ENTRY_WEIGHT_VARIABLE]?.trim();
|
|
47
|
+
if (!value)
|
|
48
|
+
return exports.DEFAULT_ENTRY_WEIGHT_WARNING_KB * BYTES_PER_KB;
|
|
49
|
+
const kilobytes = Number(value);
|
|
50
|
+
if (!Number.isFinite(kilobytes) || kilobytes < 0)
|
|
51
|
+
throw new cli_1.CliError({
|
|
52
|
+
title: `${exports.ENTRY_WEIGHT_VARIABLE} is not a size`,
|
|
53
|
+
reason: `It is ${JSON.stringify(value)}; it takes a number of KB of Brotli.`,
|
|
54
|
+
fixes: [
|
|
55
|
+
`Set ${exports.ENTRY_WEIGHT_VARIABLE}=${exports.DEFAULT_ENTRY_WEIGHT_WARNING_KB}, or 0 to turn the warning off`,
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
return kilobytes * BYTES_PER_KB;
|
|
59
|
+
}
|
|
60
|
+
function heavyEntryModules(weight, threshold) {
|
|
61
|
+
if (threshold <= 0)
|
|
62
|
+
return [];
|
|
63
|
+
return weight.shares.filter((share) => !NON_MODULE_OWNERS.has(share.owner) && share.brotli > threshold);
|
|
64
|
+
}
|
|
65
|
+
function describeEntryShares(weight) {
|
|
66
|
+
return weight.shares.map((share) => `${share.owner} ${(0, output_1.formatSize)(share.brotli)} (${(0, output_1.formatSize)(share.bytes)})`);
|
|
67
|
+
}
|
|
68
|
+
function reportEntryWeight(ui, workspaceDir, env) {
|
|
69
|
+
const threshold = entryWeightThreshold(env);
|
|
70
|
+
const weight = readEntryWeight(workspaceDir);
|
|
71
|
+
if (!weight)
|
|
72
|
+
return;
|
|
73
|
+
ui.message("info", `Client entry ${(0, output_1.formatSize)(weight.brotli)} Brotli (${(0, output_1.formatSize)(weight.bytes)}), loaded first by every page`, { details: describeEntryShares(weight) });
|
|
74
|
+
const heavy = heavyEntryModules(weight, threshold);
|
|
75
|
+
heavy.forEach((share, index) => {
|
|
76
|
+
const isLast = index === heavy.length - 1;
|
|
77
|
+
ui.message("warn", `${share.owner} adds ${(0, output_1.formatSize)(share.brotli)} Brotli to the client entry`, {
|
|
78
|
+
details: isLast
|
|
79
|
+
? [
|
|
80
|
+
"What a module's dms.frontend.ts and its plugins import is loaded by every page: render a component they only show on some pages by its registered name or with defineAsyncComponent",
|
|
81
|
+
`The threshold is ${(0, output_1.formatSize)(threshold)} (${exports.ENTRY_WEIGHT_VARIABLE}, in KB; 0 turns the warning off)`,
|
|
82
|
+
]
|
|
83
|
+
: [],
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
package/dist/fs-sync.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare function stripExtendedLengthPrefix(p: string): string;
|
|
|
2
2
|
export declare function toPosixPath(path: string, separator?: string): string;
|
|
3
3
|
export declare function isBlocklistedCopyPath(src: string, srcPath: string): boolean;
|
|
4
4
|
export declare function sanitizedPackageContent(raw: string): string;
|
|
5
|
+
export declare function sanitizedBuildDeclaration(raw: string): string;
|
|
5
6
|
export declare function filesIdentical(srcPath: string, destPath: string): boolean;
|
|
6
7
|
export declare function applyContent(content: string, destPath: string): boolean;
|
|
7
8
|
export declare function applyFile(srcPath: string, destPath: string): boolean;
|
package/dist/fs-sync.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.stripExtendedLengthPrefix = stripExtendedLengthPrefix;
|
|
|
7
7
|
exports.toPosixPath = toPosixPath;
|
|
8
8
|
exports.isBlocklistedCopyPath = isBlocklistedCopyPath;
|
|
9
9
|
exports.sanitizedPackageContent = sanitizedPackageContent;
|
|
10
|
+
exports.sanitizedBuildDeclaration = sanitizedBuildDeclaration;
|
|
10
11
|
exports.filesIdentical = filesIdentical;
|
|
11
12
|
exports.applyContent = applyContent;
|
|
12
13
|
exports.applyFile = applyFile;
|
|
@@ -39,6 +40,11 @@ function sanitizedPackageContent(raw) {
|
|
|
39
40
|
}
|
|
40
41
|
return `${JSON.stringify(pkg, null, 2)}\n`;
|
|
41
42
|
}
|
|
43
|
+
const BUILD_HELPER_IMPORT = /(["'])#dms\/frontend-build\1/g;
|
|
44
|
+
const BUILD_HELPER_FROM_MODULE_ROOT = "../../frontend-build.ts";
|
|
45
|
+
function sanitizedBuildDeclaration(raw) {
|
|
46
|
+
return raw.replace(BUILD_HELPER_IMPORT, (_, quote) => `${quote}${BUILD_HELPER_FROM_MODULE_ROOT}${quote}`);
|
|
47
|
+
}
|
|
42
48
|
function filesIdentical(srcPath, destPath) {
|
|
43
49
|
if (!(0, node_fs_1.existsSync)(destPath))
|
|
44
50
|
return false;
|
package/dist/help.js
CHANGED
|
@@ -15,7 +15,15 @@ exports.ENVIRONMENT_VARIABLES = [
|
|
|
15
15
|
],
|
|
16
16
|
["DMS_OFFLINE", "Same as --offline, unless 0, false, no or off"],
|
|
17
17
|
["DMS_WORKSPACE_DIR", "Same as build and start --workspace"],
|
|
18
|
+
[
|
|
19
|
+
"ANTELOPEJS_LAUNCH_ENV",
|
|
20
|
+
"AntelopeJS environment dev, build and start evaluate the project in, same as -e",
|
|
21
|
+
],
|
|
18
22
|
["DMS_PREPARE_STRICT", "Same as prepare --strict, read like DMS_OFFLINE"],
|
|
23
|
+
[
|
|
24
|
+
"DMS_ENTRY_WEIGHT_WARNING",
|
|
25
|
+
"KB of Brotli a module may add to the client entry before build warns (default: 50; 0: never)",
|
|
26
|
+
],
|
|
19
27
|
["PORT", "Same as -p"],
|
|
20
28
|
[
|
|
21
29
|
"HOST",
|
|
@@ -29,6 +37,10 @@ exports.ENVIRONMENT_VARIABLES = [
|
|
|
29
37
|
"NODE_ENV",
|
|
30
38
|
"Build of Vue and its libraries the server loads (default: development in dev, production in start)",
|
|
31
39
|
],
|
|
40
|
+
[
|
|
41
|
+
"DMS_CLIENT_IP_HEADER",
|
|
42
|
+
"Header the hosting platform overwrites with the client's address, e.g. X-Client-IP (default: none)",
|
|
43
|
+
],
|
|
32
44
|
[
|
|
33
45
|
"DMS_TRUSTED_PROXY_HOPS",
|
|
34
46
|
"Trusted reverse-proxy hops, counted from the right (default: 0)",
|
|
@@ -61,10 +73,6 @@ exports.ENVIRONMENT_VARIABLES = [
|
|
|
61
73
|
"DMS_BACKEND_PROXIES",
|
|
62
74
|
"More backend prefixes the server proxies, as a JSON array of { path, auth? }",
|
|
63
75
|
],
|
|
64
|
-
[
|
|
65
|
-
"DMS_BACKEND_WAKE_BUDGET_MS",
|
|
66
|
-
"How long a GET or HEAD waits out a waking or starting backend's 503, in ms (default: 30000; 0: never)",
|
|
67
|
-
],
|
|
68
76
|
["DMS_CLIENT_BASE_URL", "Public frontend URL used in links and e-mails"],
|
|
69
77
|
["NO_COLOR", "Same as --no-color"],
|
|
70
78
|
["ANTELOPEJS_VERBOSE", "Same as --verbose"],
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,6 @@ const build_1 = require("./commands/build");
|
|
|
8
8
|
const clean_1 = require("./commands/clean");
|
|
9
9
|
const dev_1 = require("./commands/dev");
|
|
10
10
|
const prepare_1 = require("./commands/prepare");
|
|
11
|
-
const snapshot_1 = require("./commands/snapshot");
|
|
12
11
|
const start_1 = require("./commands/start");
|
|
13
12
|
const verify_source_1 = require("./commands/verify-source");
|
|
14
13
|
const workspaces_1 = require("./commands/workspaces");
|
|
@@ -29,12 +28,12 @@ const ROOT_EXAMPLES = [
|
|
|
29
28
|
command: "ajs dms dev",
|
|
30
29
|
},
|
|
31
30
|
{
|
|
32
|
-
description: "Build for production,
|
|
33
|
-
command: "ajs dms build
|
|
31
|
+
description: "Build for production from the project root, without a backend",
|
|
32
|
+
command: "ajs dms build",
|
|
34
33
|
},
|
|
35
34
|
{
|
|
36
|
-
description: "Serve
|
|
37
|
-
command: "ajs dms start -b https://
|
|
35
|
+
description: "Serve the build against its backend, on another port",
|
|
36
|
+
command: "ajs dms start -b https://api.example.com -p 3001",
|
|
38
37
|
},
|
|
39
38
|
];
|
|
40
39
|
function describeVersion(version, width) {
|
|
@@ -117,7 +116,6 @@ const runCLI = async () => {
|
|
|
117
116
|
program.addCommand((0, dev_1.cmdDev)());
|
|
118
117
|
program.addCommand((0, build_1.cmdBuild)());
|
|
119
118
|
program.addCommand((0, start_1.cmdStart)());
|
|
120
|
-
program.addCommand((0, snapshot_1.cmdSnapshot)());
|
|
121
119
|
program.addCommand((0, prepare_1.cmdPrepare)());
|
|
122
120
|
program.addCommand((0, workspaces_1.cmdWorkspaces)());
|
|
123
121
|
program.addCommand((0, clean_1.cmdClean)());
|
package/dist/layer-watch.js
CHANGED
|
@@ -9,8 +9,10 @@ const node_path_1 = require("node:path");
|
|
|
9
9
|
const cli_1 = require("@antelopejs/core/cli");
|
|
10
10
|
const chokidar_1 = __importDefault(require("chokidar"));
|
|
11
11
|
const child_output_1 = require("./child-output");
|
|
12
|
+
const config_1 = require("./config");
|
|
12
13
|
const layers_1 = require("./layers");
|
|
13
14
|
const derived_outputs_1 = require("./derived-outputs");
|
|
15
|
+
const locale_files_1 = require("./locale-files");
|
|
14
16
|
const output_1 = require("./output");
|
|
15
17
|
const fs_sync_1 = require("./fs-sync");
|
|
16
18
|
const WATCH_DEBOUNCE_MS = 80;
|
|
@@ -62,6 +64,9 @@ function createLayerSync(src, dest, reporter, onStaged) {
|
|
|
62
64
|
if (rel === "package.json") {
|
|
63
65
|
(0, fs_sync_1.applyContent)((0, fs_sync_1.sanitizedPackageContent)((0, node_fs_1.readFileSync)(srcPath, "utf-8")), destPath);
|
|
64
66
|
}
|
|
67
|
+
else if (rel === config_1.FRONTEND_BUILD_ENTRY) {
|
|
68
|
+
(0, fs_sync_1.applyContent)((0, fs_sync_1.sanitizedBuildDeclaration)((0, node_fs_1.readFileSync)(srcPath, "utf-8")), destPath);
|
|
69
|
+
}
|
|
65
70
|
else {
|
|
66
71
|
(0, fs_sync_1.applyFile)(srcPath, destPath);
|
|
67
72
|
}
|
|
@@ -124,11 +129,11 @@ function createLayerSync(src, dest, reporter, onStaged) {
|
|
|
124
129
|
}
|
|
125
130
|
function describeOutputFailure(output, err, reporter) {
|
|
126
131
|
const kept = `The dev server keeps the previous ${output.name} until the file is fixed.`;
|
|
127
|
-
if (err instanceof
|
|
132
|
+
if (err instanceof locale_files_1.InvalidLocaleFileError) {
|
|
128
133
|
const file = reporter.show(err.path);
|
|
129
134
|
return {
|
|
130
135
|
text: `${file} is not a valid locale file`,
|
|
131
|
-
options: { details: [err.reason, kept] },
|
|
136
|
+
options: { details: [...err.reason.split("\n"), kept] },
|
|
132
137
|
fixed: [`${file} fixed`, `${output.name} regenerated`].join((0, cli_1.getProcessUi)().symbols.separator),
|
|
133
138
|
};
|
|
134
139
|
}
|
package/dist/layers.d.ts
CHANGED
|
@@ -7,15 +7,14 @@ interface PathlessManifestSource {
|
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
9
|
export declare function assertLayerPathsServed(modules: ManifestModule[], backendUrl: string, { bootstrapSecret, cache }?: PathlessManifestSource): asserts modules is ServedWithPath[];
|
|
10
|
-
export declare function assertCachedArchivesExist(modules: ManifestModule[], cacheDir: string, fetchedAt?: string): void;
|
|
11
10
|
export interface LayerPackage {
|
|
12
11
|
name?: unknown;
|
|
13
12
|
engines?: Record<string, unknown>;
|
|
13
|
+
dmsFrontend?: unknown;
|
|
14
|
+
antelopeJs?: unknown;
|
|
14
15
|
}
|
|
15
16
|
export declare function readLayerPackage(layerPath: string): LayerPackage | undefined;
|
|
16
17
|
export declare function buildLayersFromPaths(modules: ServedWithPath[]): ResolvedLayer[];
|
|
17
|
-
export declare function downloadAndExtractLayers(backendUrl: string, packUrl: string, cacheDir: string, force: boolean, bootstrapSecret?: string): Promise<void>;
|
|
18
|
-
export declare function buildLayersFromCache(modules: ManifestModule[], cacheDir: string): Promise<ResolvedLayer[]>;
|
|
19
18
|
export declare function getLayerSafeName(layer: ResolvedLayer): string;
|
|
20
19
|
export declare function getLayerWorkspacePath(workspaceDir: string, layer: ResolvedLayer): string;
|
|
21
20
|
export {};
|
package/dist/layers.js
CHANGED
|
@@ -1,57 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.assertLayerPathsServed = assertLayerPathsServed;
|
|
37
|
-
exports.assertCachedArchivesExist = assertCachedArchivesExist;
|
|
38
4
|
exports.readLayerPackage = readLayerPackage;
|
|
39
5
|
exports.buildLayersFromPaths = buildLayersFromPaths;
|
|
40
|
-
exports.downloadAndExtractLayers = downloadAndExtractLayers;
|
|
41
|
-
exports.buildLayersFromCache = buildLayersFromCache;
|
|
42
6
|
exports.getLayerSafeName = getLayerSafeName;
|
|
43
7
|
exports.getLayerWorkspacePath = getLayerWorkspacePath;
|
|
44
8
|
const node_fs_1 = require("node:fs");
|
|
45
|
-
const promises_1 = require("node:fs/promises");
|
|
46
9
|
const node_path_1 = require("node:path");
|
|
47
|
-
const node_stream_1 = require("node:stream");
|
|
48
|
-
const consumers_1 = require("node:stream/consumers");
|
|
49
10
|
const cli_1 = require("@antelopejs/core/cli");
|
|
50
11
|
const manifest_1 = require("./manifest");
|
|
51
|
-
const fs_sync_1 = require("./fs-sync");
|
|
52
12
|
const config_1 = require("./config");
|
|
53
13
|
const output_1 = require("./output");
|
|
54
|
-
const BUILD_FIX = "A remote or production backend never sends them:
|
|
14
|
+
const BUILD_FIX = "A remote or production backend never sends them: build the frontend from the project instead, with `ajs dms build`";
|
|
55
15
|
function assertLayerPathsServed(modules, backendUrl, { bootstrapSecret, cache } = {}) {
|
|
56
16
|
const pathless = modules.filter((mod) => !mod.path);
|
|
57
17
|
if (pathless.length === 0)
|
|
@@ -87,17 +47,6 @@ function assertLayerPathsServed(modules, backendUrl, { bootstrapSecret, cache }
|
|
|
87
47
|
fixes: [fix, BUILD_FIX],
|
|
88
48
|
});
|
|
89
49
|
}
|
|
90
|
-
function assertCachedArchivesExist(modules, cacheDir, fetchedAt) {
|
|
91
|
-
const present = new Set((0, node_fs_1.readdirSync)(cacheDir));
|
|
92
|
-
const missing = modules.filter((mod) => !present.has(mod.archiveName));
|
|
93
|
-
if (missing.length === 0)
|
|
94
|
-
return;
|
|
95
|
-
throw new cli_1.CliError({
|
|
96
|
-
title: `The cached layers archive is missing entries listed in the manifest${fetchedAt ? ` (fetched ${(0, output_1.formatAge)(fetchedAt)})` : ""}`,
|
|
97
|
-
fixes: ["Run once with the backend reachable to download the layers again"],
|
|
98
|
-
details: missing.map((mod) => `${mod.name}: ${mod.archiveName}`),
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
50
|
function sortModulesByPriority(modules) {
|
|
102
51
|
return [...modules].sort((a, b) => b.priority - a.priority);
|
|
103
52
|
}
|
|
@@ -134,49 +83,6 @@ function resolveLayer(layerPath, mod) {
|
|
|
134
83
|
function buildLayersFromPaths(modules) {
|
|
135
84
|
return sortModulesByPriority(modules).map((mod) => resolveLayer(mod.path, mod));
|
|
136
85
|
}
|
|
137
|
-
async function downloadAndExtractLayers(backendUrl, packUrl, cacheDir, force, bootstrapSecret) {
|
|
138
|
-
const url = (0, manifest_1.backendEndpoint)(backendUrl, packUrl);
|
|
139
|
-
const response = await (0, manifest_1.fetchFromBackend)(backendUrl, url, bootstrapSecret);
|
|
140
|
-
if (!response.ok) {
|
|
141
|
-
throw new manifest_1.BackendResponseError("the layers archive", url, response);
|
|
142
|
-
}
|
|
143
|
-
if (!response.body) {
|
|
144
|
-
throw new Error(`The layers archive from ${(0, manifest_1.displayUrl)(url)} came without a body`);
|
|
145
|
-
}
|
|
146
|
-
const modulesBlob = await (0, consumers_1.buffer)(node_stream_1.Readable.fromWeb(response.body));
|
|
147
|
-
const { Open } = await Promise.resolve().then(() => __importStar(require("unzipper")));
|
|
148
|
-
const cacheExists = (0, node_fs_1.existsSync)(cacheDir);
|
|
149
|
-
if (force || !cacheExists) {
|
|
150
|
-
if (cacheExists) {
|
|
151
|
-
(0, node_fs_1.rmSync)(cacheDir, { recursive: true, force: true });
|
|
152
|
-
}
|
|
153
|
-
await (await Open.buffer(modulesBlob)).extract({ path: cacheDir });
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const tempDir = `${cacheDir}_temp`;
|
|
157
|
-
if ((0, node_fs_1.existsSync)(tempDir)) {
|
|
158
|
-
(0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
|
|
159
|
-
}
|
|
160
|
-
await (await Open.buffer(modulesBlob)).extract({ path: tempDir });
|
|
161
|
-
const tempEntries = (0, node_fs_1.readdirSync)(tempDir);
|
|
162
|
-
for (const entry of tempEntries) {
|
|
163
|
-
(0, fs_sync_1.syncDirectories)((0, node_path_1.join)(tempDir, entry), (0, node_path_1.join)(cacheDir, entry));
|
|
164
|
-
}
|
|
165
|
-
(0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
|
|
166
|
-
}
|
|
167
|
-
async function buildLayersFromCache(modules, cacheDir) {
|
|
168
|
-
if (!(0, node_fs_1.existsSync)(cacheDir))
|
|
169
|
-
return [];
|
|
170
|
-
const layerFiles = await (0, promises_1.readdir)(cacheDir);
|
|
171
|
-
const layers = [];
|
|
172
|
-
for (const mod of sortModulesByPriority(modules)) {
|
|
173
|
-
if (!layerFiles.includes(mod.archiveName))
|
|
174
|
-
continue;
|
|
175
|
-
const layerPath = (0, node_path_1.join)(cacheDir, mod.archiveName);
|
|
176
|
-
layers.push(resolveLayer(layerPath, mod));
|
|
177
|
-
}
|
|
178
|
-
return layers;
|
|
179
|
-
}
|
|
180
86
|
function getLayerSafeName(layer) {
|
|
181
87
|
if (layer.packageName) {
|
|
182
88
|
return layer.packageName.replace(/^@/, "").replace(/\//g, "__");
|