@antelopejs/dms-frontend 0.7.1 → 0.8.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 +13 -41
- package/dist/commands/build.js +9 -15
- package/dist/commands/dev-action.js +5 -1
- package/dist/commands/start-action.d.ts +2 -0
- package/dist/commands/start-action.js +36 -49
- package/dist/commands/start.js +8 -6
- package/dist/config.d.ts +2 -0
- package/dist/config.js +6 -0
- package/dist/derived-outputs.js +2 -2
- package/dist/fs-sync.d.ts +1 -0
- package/dist/fs-sync.js +6 -0
- package/dist/help.js +8 -4
- package/dist/index.js +4 -6
- package/dist/layer-watch.js +4 -0
- package/dist/layers.d.ts +1 -3
- package/dist/layers.js +1 -95
- package/dist/manifest.d.ts +8 -8
- package/dist/manifest.js +15 -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 +2 -2
- package/dist/private-values.js +1 -6
- package/dist/project-modules.d.ts +46 -0
- package/dist/project-modules.js +233 -0
- package/dist/workspace-setup.d.ts +3 -7
- package/dist/workspace-setup.js +41 -62
- package/dist/workspace.d.ts +2 -4
- package/dist/workspace.js +1 -1
- package/package.json +5 -7
- package/skills/dms-frontend/SKILL.md +2 -2
- package/templates/vue/client-chunking.mjs +61 -0
- package/templates/vue/email-renderer.ts +6 -1
- package/templates/vue/frontend-build-loader.ts +1 -1
- package/templates/vue/frontend-module.ts +24 -0
- package/templates/vue/main.ts +11 -2
- package/templates/vue/package.json +2 -2
- 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 +22 -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/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/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 +84 -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 +59 -49
- package/templates/vue/ssr-renderer.ts +19 -1
- package/templates/vue/vite.config.ts +72 -46
- 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/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, "__");
|
package/dist/manifest.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare class ManifestRefusedError extends CliError {
|
|
|
18
18
|
}
|
|
19
19
|
export declare function describeManifestVersion(version: unknown): CliProblem;
|
|
20
20
|
export declare class BackendResponseError extends CliError {
|
|
21
|
+
readonly status: number;
|
|
21
22
|
constructor(subject: string, url: string | URL, response: Pick<Response, "status" | "statusText">);
|
|
22
23
|
}
|
|
23
24
|
export declare class NoCachedManifestError extends CliError {
|
|
@@ -29,19 +30,18 @@ export interface ManifestCacheEntry {
|
|
|
29
30
|
fetchedAt: string;
|
|
30
31
|
}
|
|
31
32
|
export declare function readCachedManifest(workspaceDir: string): ManifestCacheEntry | undefined;
|
|
32
|
-
export declare function writeCachedManifest(workspaceDir: string, manifest: Manifest,
|
|
33
|
-
export type
|
|
34
|
-
export
|
|
33
|
+
export declare function writeCachedManifest(workspaceDir: string, manifest: Manifest, fetchedAt?: string): void;
|
|
34
|
+
export type ManifestCacheUse = "fallback" | "offline";
|
|
35
|
+
export interface ManifestRequest {
|
|
36
|
+
clientUrl?: string;
|
|
37
|
+
bootstrapSecret?: string;
|
|
38
|
+
}
|
|
35
39
|
export interface ResolvedManifest {
|
|
36
40
|
manifest: Manifest;
|
|
37
41
|
fromCache: boolean;
|
|
38
42
|
fetchedAt?: string;
|
|
39
43
|
}
|
|
40
|
-
export declare function resolveManifest(workspaceDir: string, backendUrl: string, cacheUse: ManifestCacheUse, { clientUrl, bootstrapSecret
|
|
41
|
-
clientUrl?: string;
|
|
42
|
-
bootstrapSecret?: string;
|
|
43
|
-
privateValues?: PrivateValues;
|
|
44
|
-
}): Promise<ResolvedManifest>;
|
|
44
|
+
export declare function resolveManifest(workspaceDir: string, backendUrl: string, cacheUse: ManifestCacheUse, { clientUrl, bootstrapSecret }?: ManifestRequest): Promise<ResolvedManifest>;
|
|
45
45
|
export declare function assertCachedLayerPathsExist(modules: ServedWithPath[], fetchedAt?: string): void;
|
|
46
46
|
export type ServedWithPath = ManifestModule & {
|
|
47
47
|
path: string;
|
package/dist/manifest.js
CHANGED
|
@@ -14,7 +14,6 @@ const node_fs_1 = require("node:fs");
|
|
|
14
14
|
const node_path_1 = require("node:path");
|
|
15
15
|
const cli_1 = require("@antelopejs/core/cli");
|
|
16
16
|
const config_1 = require("./config");
|
|
17
|
-
const private_values_1 = require("./private-values");
|
|
18
17
|
const output_1 = require("./output");
|
|
19
18
|
const workspace_1 = require("./workspace");
|
|
20
19
|
class ManifestUnauthorizedError extends cli_1.CliError {
|
|
@@ -162,6 +161,7 @@ class BackendResponseError extends cli_1.CliError {
|
|
|
162
161
|
};
|
|
163
162
|
super(problem);
|
|
164
163
|
this.name = "BackendResponseError";
|
|
164
|
+
this.status = status;
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
exports.BackendResponseError = BackendResponseError;
|
|
@@ -194,10 +194,7 @@ async function fetchManifest(backendUrl, clientUrl, bootstrapSecret) {
|
|
|
194
194
|
if (incompatible.length) {
|
|
195
195
|
throw new ManifestRefusedError(`Frontend manifest contains incompatible renderer modules: ${incompatible.map((module) => module.name).join(", ")}`);
|
|
196
196
|
}
|
|
197
|
-
const resolved = {
|
|
198
|
-
pack: manifest.archive,
|
|
199
|
-
modules: manifest.modules,
|
|
200
|
-
};
|
|
197
|
+
const resolved = { modules: manifest.modules };
|
|
201
198
|
if (manifest.settling)
|
|
202
199
|
resolved.settling = true;
|
|
203
200
|
return resolved;
|
|
@@ -217,19 +214,15 @@ function readCachedManifest(workspaceDir) {
|
|
|
217
214
|
return undefined;
|
|
218
215
|
}
|
|
219
216
|
}
|
|
220
|
-
function writeCachedManifest(workspaceDir, manifest,
|
|
217
|
+
function writeCachedManifest(workspaceDir, manifest, fetchedAt = new Date().toISOString()) {
|
|
221
218
|
const entry = { manifest, fetchedAt };
|
|
222
|
-
|
|
223
|
-
write((0, node_path_1.join)(workspaceDir, MANIFEST_CACHE_FILE), `${JSON.stringify(entry, null, 2)}\n`);
|
|
219
|
+
(0, config_1.writeSecretBearingFile)((0, node_path_1.join)(workspaceDir, MANIFEST_CACHE_FILE), `${JSON.stringify(entry, null, 2)}\n`);
|
|
224
220
|
}
|
|
225
|
-
async function resolveManifest(workspaceDir, backendUrl, cacheUse, { clientUrl, bootstrapSecret
|
|
221
|
+
async function resolveManifest(workspaceDir, backendUrl, cacheUse, { clientUrl, bootstrapSecret } = {}) {
|
|
226
222
|
if (cacheUse !== "offline") {
|
|
227
223
|
try {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
? served
|
|
231
|
-
: { ...served, modules: (0, private_values_1.withoutPrivateValues)(served.modules) };
|
|
232
|
-
writeCachedManifest(workspaceDir, manifest, privateValues);
|
|
224
|
+
const manifest = await fetchManifest(backendUrl, clientUrl, bootstrapSecret);
|
|
225
|
+
writeCachedManifest(workspaceDir, manifest);
|
|
233
226
|
return { manifest, fromCache: false };
|
|
234
227
|
}
|
|
235
228
|
catch (err) {
|
|
@@ -240,37 +233,20 @@ async function resolveManifest(workspaceDir, backendUrl, cacheUse, { clientUrl,
|
|
|
240
233
|
const cached = readCachedManifest(workspaceDir);
|
|
241
234
|
if (!cached)
|
|
242
235
|
throw err;
|
|
243
|
-
|
|
244
|
-
throw cacheNotUsed(err, backendUrl, cached);
|
|
245
|
-
return fromCachedEntry(workspaceDir, cached, privateValues);
|
|
236
|
+
return fromCachedEntry(cached);
|
|
246
237
|
}
|
|
247
238
|
}
|
|
248
239
|
const cached = readCachedManifest(workspaceDir);
|
|
249
240
|
if (!cached)
|
|
250
241
|
throw new NoCachedManifestError();
|
|
251
|
-
return fromCachedEntry(
|
|
252
|
-
}
|
|
253
|
-
function cacheNotUsed(failure, backendUrl, cached) {
|
|
254
|
-
const problem = failure instanceof cli_1.CliError
|
|
255
|
-
? failure.problem
|
|
256
|
-
: { title: errorMessage(failure) };
|
|
257
|
-
const cache = `A manifest${(0, output_1.cachedAge)(cached.fetchedAt)} exists; a build uses it only with --offline.`;
|
|
258
|
-
return new cli_1.CliError({
|
|
259
|
-
...problem,
|
|
260
|
-
reason: problem.reason ? `${problem.reason} ${cache}` : cache,
|
|
261
|
-
fixes: [
|
|
262
|
-
...(problem.fixes ?? []),
|
|
263
|
-
`Or build from the cache on purpose: ajs dms build -b ${displayUrl(backendUrl)} --offline`,
|
|
264
|
-
],
|
|
265
|
-
}, { cause: failure });
|
|
242
|
+
return fromCachedEntry(cached);
|
|
266
243
|
}
|
|
267
|
-
function fromCachedEntry(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
return { manifest, fromCache: true, fetchedAt: cached.fetchedAt };
|
|
244
|
+
function fromCachedEntry(cached) {
|
|
245
|
+
return {
|
|
246
|
+
manifest: cached.manifest,
|
|
247
|
+
fromCache: true,
|
|
248
|
+
fetchedAt: cached.fetchedAt,
|
|
249
|
+
};
|
|
274
250
|
}
|
|
275
251
|
function assertCachedLayerPathsExist(modules, fetchedAt) {
|
|
276
252
|
const missing = modules.filter((mod) => !(0, node_fs_1.existsSync)(mod.path));
|
package/dist/materialize.js
CHANGED
|
@@ -70,6 +70,12 @@ function copyLayerSource(src, dest) {
|
|
|
70
70
|
filter: (srcPath) => !(0, fs_sync_1.isBlocklistedCopyPath)(src, srcPath),
|
|
71
71
|
});
|
|
72
72
|
sanitizeLayerPackage((0, node_path_1.join)(dest, "package.json"));
|
|
73
|
+
sanitizeBuildDeclaration((0, node_path_1.join)(dest, config_1.FRONTEND_BUILD_ENTRY));
|
|
74
|
+
}
|
|
75
|
+
function sanitizeBuildDeclaration(file) {
|
|
76
|
+
if (!(0, node_fs_1.existsSync)(file))
|
|
77
|
+
return;
|
|
78
|
+
(0, fs_sync_1.applyContent)((0, fs_sync_1.sanitizedBuildDeclaration)((0, node_fs_1.readFileSync)(file, "utf-8")), file);
|
|
73
79
|
}
|
|
74
80
|
function sanitizeLayerPackage(pkgPath) {
|
|
75
81
|
if (!(0, node_fs_1.existsSync)(pkgPath))
|
package/dist/module-set.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type ManifestModule } from "./workspace";
|
|
2
2
|
export declare const MODULE_SET_POLL_INTERVAL_MS = 3000;
|
|
3
|
+
export declare const OWN_RELEASE: {
|
|
4
|
+
version: string;
|
|
5
|
+
};
|
|
3
6
|
export type ModuleSetMember = Pick<ManifestModule, "name" | "path" | "priority" | "publicEndpoints" | "backendProxies">;
|
|
4
7
|
export type BootstrapSecretSource = () => string | undefined;
|
|
5
8
|
export interface ModuleSetFollowOptions {
|
|
@@ -13,15 +16,14 @@ export interface ModuleSetFollowOptions {
|
|
|
13
16
|
}
|
|
14
17
|
export declare function moduleSetFingerprint(modules: readonly ModuleSetMember[]): string;
|
|
15
18
|
export declare function followModuleSet(options: ModuleSetFollowOptions): () => void;
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export declare function compareWithBackend(backendUrl: string, builtDigest: string, digestOf: (modules: readonly ManifestModule[]) => string, bootstrapSecret?: string): Promise<BuildDrift>;
|
|
19
|
+
export interface ServedModule {
|
|
20
|
+
name: string;
|
|
21
|
+
version?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ReadyRetry {
|
|
24
|
+
firstDelayMs: number;
|
|
25
|
+
maxDelayMs: number;
|
|
26
|
+
timeoutMs: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function reportFrontendReady(backendUrl: string, modules: readonly ServedModule[], bootstrapSecret?: string): Promise<boolean>;
|
|
29
|
+
export declare function reportFrontendReadyOnceAnswered(backendUrl: string, modules: readonly ServedModule[], bootstrapSecret?: string, retry?: ReadyRetry): Promise<boolean>;
|
package/dist/module-set.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MODULE_SET_POLL_INTERVAL_MS = void 0;
|
|
3
|
+
exports.OWN_RELEASE = exports.MODULE_SET_POLL_INTERVAL_MS = void 0;
|
|
4
4
|
exports.moduleSetFingerprint = moduleSetFingerprint;
|
|
5
5
|
exports.followModuleSet = followModuleSet;
|
|
6
6
|
exports.reportFrontendReady = reportFrontendReady;
|
|
7
|
-
exports.
|
|
7
|
+
exports.reportFrontendReadyOnceAnswered = reportFrontendReadyOnceAnswered;
|
|
8
|
+
const promises_1 = require("node:timers/promises");
|
|
8
9
|
const manifest_1 = require("./manifest");
|
|
9
10
|
const workspace_1 = require("./workspace");
|
|
10
11
|
exports.MODULE_SET_POLL_INTERVAL_MS = 3000;
|
|
11
12
|
const READY_ENDPOINT = "/dms/frontend/ready";
|
|
12
13
|
const READY_TIMEOUT_MS = 5000;
|
|
13
14
|
const JSON_CONTENT_TYPE = "application/json";
|
|
14
|
-
|
|
15
|
+
exports.OWN_RELEASE = require("../package.json");
|
|
15
16
|
function moduleSetFingerprint(modules) {
|
|
16
17
|
return JSON.stringify([...modules]
|
|
17
18
|
.sort((left, right) => left.name.localeCompare(right.name))
|
|
@@ -63,40 +64,47 @@ function followModuleSet(options) {
|
|
|
63
64
|
clearTimeout(timer);
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
+
const READY_WAKE_TIMEOUT_MS = 90_000;
|
|
68
|
+
const READY_FIRST_RETRY_MS = 2_000;
|
|
69
|
+
const READY_MAX_RETRY_MS = 60_000;
|
|
70
|
+
const SERVER_ERROR = 500;
|
|
71
|
+
const DEFAULT_READY_RETRY = {
|
|
72
|
+
firstDelayMs: READY_FIRST_RETRY_MS,
|
|
73
|
+
maxDelayMs: READY_MAX_RETRY_MS,
|
|
74
|
+
timeoutMs: READY_WAKE_TIMEOUT_MS,
|
|
75
|
+
};
|
|
76
|
+
async function postReadyReport(backendUrl, modules, bootstrapSecret, timeoutMs) {
|
|
77
|
+
const response = await fetch((0, manifest_1.backendEndpoint)(backendUrl, READY_ENDPOINT), {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: {
|
|
80
|
+
...(0, workspace_1.bootstrapHeaders)(bootstrapSecret),
|
|
81
|
+
"content-type": JSON_CONTENT_TYPE,
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({ modules, version: exports.OWN_RELEASE.version }),
|
|
84
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
85
|
+
});
|
|
86
|
+
await response.body?.cancel();
|
|
87
|
+
return response;
|
|
88
|
+
}
|
|
89
|
+
async function reportFrontendReady(backendUrl, modules, bootstrapSecret) {
|
|
67
90
|
try {
|
|
68
|
-
const response = await
|
|
69
|
-
method: "POST",
|
|
70
|
-
headers: {
|
|
71
|
-
...(0, workspace_1.bootstrapHeaders)(bootstrapSecret),
|
|
72
|
-
"content-type": JSON_CONTENT_TYPE,
|
|
73
|
-
},
|
|
74
|
-
body: JSON.stringify({
|
|
75
|
-
modules: moduleNames,
|
|
76
|
-
version: OWN_RELEASE.version,
|
|
77
|
-
}),
|
|
78
|
-
signal: AbortSignal.timeout(READY_TIMEOUT_MS),
|
|
79
|
-
});
|
|
91
|
+
const response = await postReadyReport(backendUrl, modules, bootstrapSecret, READY_TIMEOUT_MS);
|
|
80
92
|
return response.ok;
|
|
81
93
|
}
|
|
82
94
|
catch {
|
|
83
95
|
return false;
|
|
84
96
|
}
|
|
85
97
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
status: "unknown",
|
|
99
|
-
reason: error instanceof Error ? error.message : String(error),
|
|
100
|
-
};
|
|
98
|
+
async function reportFrontendReadyOnceAnswered(backendUrl, modules, bootstrapSecret, retry = DEFAULT_READY_RETRY) {
|
|
99
|
+
for (let delayMs = retry.firstDelayMs;;) {
|
|
100
|
+
try {
|
|
101
|
+
const response = await postReadyReport(backendUrl, modules, bootstrapSecret, retry.timeoutMs);
|
|
102
|
+
if (response.status < SERVER_ERROR)
|
|
103
|
+
return response.ok;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
}
|
|
107
|
+
await (0, promises_1.setTimeout)(delayMs, undefined, { ref: false });
|
|
108
|
+
delayMs = Math.min(retry.maxDelayMs, delayMs * 2);
|
|
101
109
|
}
|
|
102
110
|
}
|
package/dist/private-values.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { FrontendModuleOptions
|
|
2
|
-
export declare function
|
|
1
|
+
import type { FrontendModuleOptions } from "./workspace";
|
|
2
|
+
export declare function emptiedOptions(options: FrontendModuleOptions): FrontendModuleOptions;
|
|
3
3
|
export declare const PRIVATE_OPTIONS_VARIABLE = "DMS_PRIVATE_OPTIONS";
|
|
4
4
|
export interface UnfilledPrivateValue {
|
|
5
5
|
module: string;
|
package/dist/private-values.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PRIVATE_OPTIONS_VARIABLE = void 0;
|
|
4
|
-
exports.
|
|
4
|
+
exports.emptiedOptions = emptiedOptions;
|
|
5
5
|
exports.parsePrivateOptions = parsePrivateOptions;
|
|
6
6
|
exports.unfilledPrivateValues = unfilledPrivateValues;
|
|
7
7
|
const config_1 = require("./config");
|
|
@@ -17,11 +17,6 @@ function emptied(value) {
|
|
|
17
17
|
function emptiedOptions(options) {
|
|
18
18
|
return Object.fromEntries(Object.entries(options).map(([key, value]) => [key, emptied(value)]));
|
|
19
19
|
}
|
|
20
|
-
function withoutPrivateValues(modules) {
|
|
21
|
-
return modules.map((module) => module.privateOptions
|
|
22
|
-
? { ...module, privateOptions: emptiedOptions(module.privateOptions) }
|
|
23
|
-
: { ...module });
|
|
24
|
-
}
|
|
25
20
|
exports.PRIVATE_OPTIONS_VARIABLE = "DMS_PRIVATE_OPTIONS";
|
|
26
21
|
function isOptions(value) {
|
|
27
22
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BackendProxyDeclaration, FrontendModuleOptions, PublicEndpointDeclaration, ResolvedLayer } from "./workspace";
|
|
2
|
+
export declare const FRONTEND_DECLARATION_FIELD = "dmsFrontend";
|
|
3
|
+
export interface FrontendRegistration {
|
|
4
|
+
name: string;
|
|
5
|
+
sourcePath: string;
|
|
6
|
+
renderer: {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
};
|
|
10
|
+
priority?: number;
|
|
11
|
+
configKey?: string;
|
|
12
|
+
options?: FrontendModuleOptions;
|
|
13
|
+
privateOptions?: FrontendModuleOptions;
|
|
14
|
+
authEstablishEndpoints?: string[];
|
|
15
|
+
publicEndpoints?: PublicEndpointDeclaration[];
|
|
16
|
+
backendProxies?: BackendProxyDeclaration[];
|
|
17
|
+
}
|
|
18
|
+
export interface FrontendModuleContext {
|
|
19
|
+
dev: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ModuleSource {
|
|
22
|
+
type: string;
|
|
23
|
+
path?: string;
|
|
24
|
+
package?: string;
|
|
25
|
+
}
|
|
26
|
+
interface ProjectModule {
|
|
27
|
+
source: ModuleSource;
|
|
28
|
+
config: unknown;
|
|
29
|
+
}
|
|
30
|
+
interface ProjectConfig {
|
|
31
|
+
cacheFolder: string;
|
|
32
|
+
modules: Record<string, ProjectModule>;
|
|
33
|
+
}
|
|
34
|
+
export interface ProjectFrontendModule {
|
|
35
|
+
layer: ResolvedLayer;
|
|
36
|
+
version?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ProjectModulesOptions {
|
|
39
|
+
projectDir: string;
|
|
40
|
+
environment: string;
|
|
41
|
+
dev?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function loadProjectConfig(projectDir: string, environment: string): Promise<ProjectConfig>;
|
|
44
|
+
export declare function readShippingVersion(sourcePath: string): string | undefined;
|
|
45
|
+
export declare function readProjectFrontendModules(options: ProjectModulesOptions): Promise<ProjectFrontendModule[]>;
|
|
46
|
+
export {};
|