@antelopejs/dms-frontend 0.3.8 → 0.3.9
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 +82 -23
- package/dist/cancellation.d.ts +8 -0
- package/dist/cancellation.js +23 -0
- package/dist/child-output.d.ts +45 -0
- package/dist/child-output.js +183 -0
- package/dist/commands/build-action.d.ts +21 -0
- package/dist/commands/build-action.js +144 -0
- package/dist/commands/build.js +54 -62
- package/dist/commands/clean-action.d.ts +8 -0
- package/dist/commands/clean-action.js +97 -0
- package/dist/commands/clean.js +52 -39
- package/dist/commands/dev-action.d.ts +8 -0
- package/dist/commands/dev-action.js +120 -0
- package/dist/commands/dev.js +55 -115
- package/dist/commands/prepare-action.d.ts +8 -0
- package/dist/commands/prepare-action.js +73 -0
- package/dist/commands/prepare.js +55 -54
- package/dist/commands/start-action.d.ts +5 -0
- package/dist/commands/start-action.js +77 -0
- package/dist/commands/start.js +48 -48
- package/dist/commands/verify-source-action.d.ts +10 -0
- package/dist/commands/verify-source-action.js +104 -0
- package/dist/commands/verify-source.d.ts +0 -1
- package/dist/commands/verify-source.js +53 -31
- package/dist/commands/workspace-task.d.ts +2 -0
- package/dist/commands/workspace-task.js +26 -0
- package/dist/commands/workspaces-action.d.ts +25 -0
- package/dist/commands/workspaces-action.js +71 -0
- package/dist/commands/workspaces.d.ts +2 -0
- package/dist/commands/workspaces.js +60 -0
- package/dist/common.d.ts +1 -0
- package/dist/common.js +1 -0
- package/dist/config.d.ts +13 -4
- package/dist/config.js +115 -18
- package/dist/derived-outputs.d.ts +6 -1
- package/dist/derived-outputs.js +12 -3
- package/dist/discovery.d.ts +2 -1
- package/dist/discovery.js +28 -11
- package/dist/env-file.js +5 -2
- package/dist/help.d.ts +5 -0
- package/dist/help.js +70 -0
- package/dist/index.js +98 -38
- package/dist/layer-watch.d.ts +2 -1
- package/dist/layer-watch.js +129 -26
- package/dist/layers.d.ts +2 -2
- package/dist/layers.js +71 -23
- package/dist/manifest-secrets.d.ts +3 -2
- package/dist/manifest-secrets.js +25 -21
- package/dist/manifest.d.ts +22 -5
- package/dist/manifest.js +184 -28
- package/dist/materialize.js +2 -1
- package/dist/output.d.ts +41 -0
- package/dist/output.js +197 -0
- package/dist/ports.d.ts +2 -0
- package/dist/ports.js +23 -13
- package/dist/renderer-range.d.ts +3 -1
- package/dist/renderer-range.js +49 -17
- package/dist/server-process.d.ts +39 -0
- package/dist/server-process.js +221 -0
- package/dist/typecheck-output.d.ts +13 -0
- package/dist/typecheck-output.js +87 -0
- package/dist/update-check.d.ts +14 -2
- package/dist/update-check.js +95 -29
- package/dist/verify-source-result.d.ts +11 -0
- package/dist/verify-source-result.js +17 -0
- package/dist/verify-source-runner.js +266 -131
- package/dist/vite-output.d.ts +14 -0
- package/dist/vite-output.js +99 -0
- package/dist/workspace-setup.d.ts +17 -3
- package/dist/workspace-setup.js +119 -35
- package/dist/workspace.d.ts +8 -2
- package/dist/workspace.js +47 -12
- package/package.json +4 -12
- package/templates/vue/package.json +4 -0
- package/templates/vue/server/cli-report.mjs +91 -0
- package/templates/vue/server.mjs +18 -15
- package/templates/vue/vite.config.ts +8 -1
- package/templates/vue/vite.email.config.ts +5 -1
- package/dist/utils/cli-ui.d.ts +0 -27
- package/dist/utils/cli-ui.js +0 -178
package/dist/index.js
CHANGED
|
@@ -1,63 +1,123 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const
|
|
4
|
+
const cli_1 = require("@antelopejs/core/cli");
|
|
8
5
|
const commander_1 = require("commander");
|
|
6
|
+
const cancellation_1 = require("./cancellation");
|
|
9
7
|
const build_1 = require("./commands/build");
|
|
10
8
|
const clean_1 = require("./commands/clean");
|
|
11
9
|
const dev_1 = require("./commands/dev");
|
|
12
10
|
const prepare_1 = require("./commands/prepare");
|
|
13
11
|
const start_1 = require("./commands/start");
|
|
14
12
|
const verify_source_1 = require("./commands/verify-source");
|
|
13
|
+
const workspaces_1 = require("./commands/workspaces");
|
|
15
14
|
const env_file_1 = require("./env-file");
|
|
15
|
+
const help_1 = require("./help");
|
|
16
|
+
const output_1 = require("./output");
|
|
16
17
|
const update_check_1 = require("./update-check");
|
|
17
|
-
const cli_ui_1 = require("./utils/cli-ui");
|
|
18
18
|
const { version } = require("../package.json");
|
|
19
|
+
const GLOBAL_FLAGS = ["--no-color", "--verbose"];
|
|
20
|
+
const ROOT_EXAMPLES = [
|
|
21
|
+
{
|
|
22
|
+
description: "Inside a project started with ajs project dev",
|
|
23
|
+
command: "ajs dms dev",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
description: "Build for production, then serve the build",
|
|
27
|
+
command: "ajs dms build -b https://dms.example.com",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
description: "Serve it on another port",
|
|
31
|
+
command: "ajs dms start -b https://dms.example.com -p 3001",
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
function describeVersion(version, width) {
|
|
35
|
+
const name = `ajs dms ${version}`;
|
|
36
|
+
const line = [
|
|
37
|
+
(0, cli_1.unbreakable)(name),
|
|
38
|
+
"DMS frontend for AntelopeJS (Vue 3, Vite, Inertia)",
|
|
39
|
+
].join((0, cli_1.getProcessUi)().symbols.separator);
|
|
40
|
+
const [first, ...rest] = (0, cli_1.wrapText)(line, width);
|
|
41
|
+
const title = first.replace(name, (0, cli_1.getProcessPalette)("result").bold(name));
|
|
42
|
+
return `${[title, ...rest].join("\n")}\n`;
|
|
43
|
+
}
|
|
44
|
+
function describeHelpFooter(width) {
|
|
45
|
+
const pointer = `Run ${(0, cli_1.unbreakable)("ajs dms <command> --help")} for its options and examples, and ` +
|
|
46
|
+
`${(0, cli_1.unbreakable)(`ajs dms help ${help_1.ENVIRONMENT_TOPIC}`)} for the variables read from the environment.`;
|
|
47
|
+
return [
|
|
48
|
+
"",
|
|
49
|
+
(0, cli_1.formatExamples)(ROOT_EXAMPLES, width),
|
|
50
|
+
"",
|
|
51
|
+
...(0, cli_1.wrapText)(pointer, width),
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
54
|
+
function ownArguments(args) {
|
|
55
|
+
return args.filter((arg) => !GLOBAL_FLAGS.includes(arg));
|
|
56
|
+
}
|
|
57
|
+
function isInvocation(args, rest) {
|
|
58
|
+
const own = ownArguments(args);
|
|
59
|
+
return own.length === rest.length && own.every((arg, i) => arg === rest[i]);
|
|
60
|
+
}
|
|
61
|
+
function unknownHelpSubject(program, args) {
|
|
62
|
+
const [first, subject, ...rest] = ownArguments(args);
|
|
63
|
+
if (first !== "help" || subject === undefined || rest.length > 0) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const known = [
|
|
67
|
+
...program.commands.map((command) => command.name()),
|
|
68
|
+
"help",
|
|
69
|
+
help_1.ENVIRONMENT_TOPIC,
|
|
70
|
+
];
|
|
71
|
+
return known.includes(subject) ? undefined : subject;
|
|
72
|
+
}
|
|
19
73
|
const runCLI = async () => {
|
|
74
|
+
(0, output_1.exitOnBrokenPipe)();
|
|
20
75
|
(0, env_file_1.loadProjectEnv)();
|
|
21
76
|
const argv = process.argv.slice(2);
|
|
22
|
-
|
|
23
|
-
if (process.argv.length <= 2) {
|
|
24
|
-
(0, cli_ui_1.displayBanner)("Antelope DMS");
|
|
25
|
-
console.log(chalk_1.default.dim(` Frontend Loader for AntelopeJS DMS - v${version}\n`));
|
|
26
|
-
}
|
|
77
|
+
(0, update_check_1.startProcessUpdateCheck)({ currentVersion: version, argv });
|
|
27
78
|
const program = new commander_1.Command()
|
|
28
79
|
.name("ajs dms")
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
.
|
|
32
|
-
.option("--no-update-check", "Skip the daily check
|
|
33
|
-
.
|
|
34
|
-
.addHelpText("after",
|
|
35
|
-
Environment:
|
|
36
|
-
Every command reads ${env_file_1.ENV_FILE_NAMES.join(" then ")} from the current directory before parsing
|
|
37
|
-
its options, so DMS_API_BASE_URL, DMS_BOOTSTRAP_SECRET, DMS_SESSION_SECRET and
|
|
38
|
-
the other variables below can live in the project's .env. A variable already
|
|
39
|
-
set in the environment always wins over a file, and .env.local wins over .env.
|
|
40
|
-
The generated workspace never loads a .env of its own.
|
|
41
|
-
'dev' generates an ephemeral 32-byte DMS_SESSION_SECRET when it is absent;
|
|
42
|
-
restarting dev invalidates its sessions. 'build' and 'start' require a
|
|
43
|
-
configured secret of at least 32 characters.
|
|
44
|
-
|
|
45
|
-
Workspaces:
|
|
46
|
-
Each canonical backend URL gets its own workspace under
|
|
47
|
-
~/.antelopejs/dms-frontend. 'dev' without -b is the exception: it keys the
|
|
48
|
-
workspace on the antelope project directory instead, so a backend that lands
|
|
49
|
-
on a different port between runs keeps its node_modules and manifest cache.
|
|
50
|
-
Pass -b to 'dev' to share one workspace with 'build' and 'start'.`);
|
|
80
|
+
.version(version, "-v, --version", "Print the version")
|
|
81
|
+
.option("--no-color", "Disable colors (also NO_COLOR=1)")
|
|
82
|
+
.option("--verbose", "Show full output and stack traces (also ANTELOPEJS_VERBOSE)")
|
|
83
|
+
.option("--no-update-check", "Skip the daily update check (also NO_UPDATE_NOTIFIER=1)")
|
|
84
|
+
.addHelpText("before", (context) => describeVersion(version, (0, cli_1.helpTextWidth)(context)))
|
|
85
|
+
.addHelpText("after", (context) => describeHelpFooter((0, cli_1.helpTextWidth)(context)));
|
|
51
86
|
program.addCommand((0, dev_1.cmdDev)());
|
|
52
87
|
program.addCommand((0, build_1.cmdBuild)());
|
|
53
88
|
program.addCommand((0, start_1.cmdStart)());
|
|
54
89
|
program.addCommand((0, prepare_1.cmdPrepare)());
|
|
90
|
+
program.addCommand((0, workspaces_1.cmdWorkspaces)());
|
|
55
91
|
program.addCommand((0, clean_1.cmdClean)());
|
|
56
92
|
program.addCommand((0, verify_source_1.cmdVerifySource)());
|
|
57
|
-
|
|
93
|
+
(0, help_1.applyDmsHelp)(program);
|
|
94
|
+
(0, cli_1.formatUsageErrors)(program);
|
|
95
|
+
const args = (0, update_check_1.stripUpdateCheckFlag)(argv);
|
|
96
|
+
if (isInvocation(args, [])) {
|
|
97
|
+
program.outputHelp();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (isInvocation(args, ["help", help_1.ENVIRONMENT_TOPIC])) {
|
|
101
|
+
(0, cli_1.getProcessUi)().value((0, help_1.formatEnvironmentHelp)());
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const helpSubject = unknownHelpSubject(program, args);
|
|
105
|
+
if (helpSubject !== undefined) {
|
|
106
|
+
program.error(`error: unknown command '${helpSubject}'`, {
|
|
107
|
+
code: "commander.unknownCommand",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
await program.parseAsync(args, { from: "user" });
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
if (!(err instanceof cancellation_1.CancelledError))
|
|
115
|
+
throw err;
|
|
116
|
+
(0, output_1.reportStopped)(err);
|
|
117
|
+
process.exitCode = err.exitCode;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (!process.exitCode)
|
|
121
|
+
await (0, update_check_1.reportAvailableUpdate)();
|
|
58
122
|
};
|
|
59
|
-
|
|
60
|
-
runCLI().catch((err) => {
|
|
61
|
-
console.error(chalk_1.default.red("Error:"), err.message || err);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
123
|
+
void (0, cli_1.runWithErrorBoundary)(runCLI, { verbose: (0, cli_1.isVerboseRun)() }).then(() => process.exit());
|
package/dist/layer-watch.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
import { type Ui } from "@antelopejs/core/cli";
|
|
1
2
|
import { ResolvedLayer } from "./workspace";
|
|
2
|
-
export declare function startLayerWatchers(workspaceDir: string, layers: ResolvedLayer[]): () => Promise<void>;
|
|
3
|
+
export declare function startLayerWatchers(workspaceDir: string, layers: ResolvedLayer[], ui?: Ui, write?: (text: string) => void): () => Promise<void>;
|
package/dist/layer-watch.js
CHANGED
|
@@ -6,25 +6,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.startLayerWatchers = startLayerWatchers;
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = require("node:path");
|
|
9
|
+
const cli_1 = require("@antelopejs/core/cli");
|
|
9
10
|
const chokidar_1 = __importDefault(require("chokidar"));
|
|
11
|
+
const child_output_1 = require("./child-output");
|
|
10
12
|
const layers_1 = require("./layers");
|
|
11
13
|
const derived_outputs_1 = require("./derived-outputs");
|
|
14
|
+
const output_1 = require("./output");
|
|
12
15
|
const fs_sync_1 = require("./fs-sync");
|
|
13
16
|
const WATCH_DEBOUNCE_MS = 80;
|
|
14
17
|
const DERIVED_REFRESH_DEBOUNCE_MS = 100;
|
|
15
|
-
function
|
|
18
|
+
function capitalize(text) {
|
|
19
|
+
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
20
|
+
}
|
|
21
|
+
function createSyncFailures(src, reporter) {
|
|
22
|
+
const failed = new Set();
|
|
23
|
+
const show = (rel) => reporter.show((0, node_path_1.join)(src, rel));
|
|
24
|
+
return {
|
|
25
|
+
fail(rel, err) {
|
|
26
|
+
failed.add(rel);
|
|
27
|
+
reporter.warn(`${show(rel)} not copied to the workspace`, {
|
|
28
|
+
details: [
|
|
29
|
+
...reporter.describe(err),
|
|
30
|
+
"The dev server keeps its previous version until the next save.",
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
applied(rel) {
|
|
35
|
+
if (failed.delete(rel))
|
|
36
|
+
reporter.succeed(`${show(rel)} copied to the workspace`);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function createLayerSync(src, dest, onFlushed, reporter) {
|
|
16
41
|
const fileUpserts = new Set();
|
|
17
42
|
const fileDeletes = new Set();
|
|
18
43
|
const dirCreates = new Set();
|
|
19
44
|
const dirDeletes = new Set();
|
|
45
|
+
const failures = createSyncFailures(src, reporter);
|
|
20
46
|
let timer = null;
|
|
21
47
|
const toRel = (p) => {
|
|
22
48
|
const r = (0, node_path_1.relative)(src, p);
|
|
23
49
|
return r ? r : null;
|
|
24
50
|
};
|
|
25
|
-
const warnFailure = (rel, err) => {
|
|
26
|
-
console.warn(`[ajs-dms] layer sync skipped ${rel}:`, err);
|
|
27
|
-
};
|
|
28
51
|
const flush = () => {
|
|
29
52
|
timer = null;
|
|
30
53
|
const touched = [
|
|
@@ -36,9 +59,10 @@ function createLayerSync(src, dest, onFlushed) {
|
|
|
36
59
|
for (const rel of [...dirCreates].sort((a, b) => a.length - b.length)) {
|
|
37
60
|
try {
|
|
38
61
|
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(dest, rel), { recursive: true });
|
|
62
|
+
failures.applied(rel);
|
|
39
63
|
}
|
|
40
64
|
catch (err) {
|
|
41
|
-
|
|
65
|
+
failures.fail(rel, err);
|
|
42
66
|
}
|
|
43
67
|
}
|
|
44
68
|
dirCreates.clear();
|
|
@@ -54,9 +78,10 @@ function createLayerSync(src, dest, onFlushed) {
|
|
|
54
78
|
else {
|
|
55
79
|
(0, fs_sync_1.applyFile)(srcPath, destPath);
|
|
56
80
|
}
|
|
81
|
+
failures.applied(rel);
|
|
57
82
|
}
|
|
58
83
|
catch (err) {
|
|
59
|
-
|
|
84
|
+
failures.fail(rel, err);
|
|
60
85
|
}
|
|
61
86
|
}
|
|
62
87
|
fileUpserts.clear();
|
|
@@ -67,9 +92,10 @@ function createLayerSync(src, dest, onFlushed) {
|
|
|
67
92
|
const destPath = (0, node_path_1.join)(dest, rel);
|
|
68
93
|
if ((0, node_fs_1.existsSync)(destPath))
|
|
69
94
|
(0, node_fs_1.rmSync)(destPath, { force: true });
|
|
95
|
+
failures.applied(rel);
|
|
70
96
|
}
|
|
71
97
|
catch (err) {
|
|
72
|
-
|
|
98
|
+
failures.fail(rel, err);
|
|
73
99
|
}
|
|
74
100
|
}
|
|
75
101
|
fileDeletes.clear();
|
|
@@ -80,9 +106,10 @@ function createLayerSync(src, dest, onFlushed) {
|
|
|
80
106
|
const destPath = (0, node_path_1.join)(dest, rel);
|
|
81
107
|
if ((0, node_fs_1.existsSync)(destPath))
|
|
82
108
|
(0, node_fs_1.rmSync)(destPath, { recursive: true, force: true });
|
|
109
|
+
failures.applied(rel);
|
|
83
110
|
}
|
|
84
111
|
catch (err) {
|
|
85
|
-
|
|
112
|
+
failures.fail(rel, err);
|
|
86
113
|
}
|
|
87
114
|
}
|
|
88
115
|
dirDeletes.clear();
|
|
@@ -133,40 +160,106 @@ function createLayerSync(src, dest, onFlushed) {
|
|
|
133
160
|
},
|
|
134
161
|
};
|
|
135
162
|
}
|
|
136
|
-
function
|
|
137
|
-
const
|
|
163
|
+
function describeOutputFailure(output, err, reporter) {
|
|
164
|
+
const kept = `The dev server keeps the previous ${output.name} until the file is fixed.`;
|
|
165
|
+
if (err instanceof derived_outputs_1.InvalidLocaleFileError) {
|
|
166
|
+
const file = reporter.show(err.path);
|
|
167
|
+
return {
|
|
168
|
+
text: `${file} is not a valid locale file`,
|
|
169
|
+
options: { details: [err.reason, kept] },
|
|
170
|
+
fixed: [`${file} fixed`, `${output.name} regenerated`].join((0, cli_1.getProcessUi)().symbols.separator),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
text: `${capitalize(output.name)} not regenerated`,
|
|
175
|
+
options: { details: [...reporter.describe(err), kept] },
|
|
176
|
+
fixed: `${capitalize(output.name)} regenerated`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function describeLayerDirectories(paths, reporter) {
|
|
180
|
+
const layers = [...new Set(paths)].filter((path) => !paths.some((other) => other.startsWith(`${path}${node_path_1.sep}`)));
|
|
181
|
+
const shown = layers.map((path) => reporter.show(path));
|
|
182
|
+
if (shown.length !== 1)
|
|
183
|
+
return `Layer directories added or removed: ${shown.join(", ")}`;
|
|
184
|
+
return (0, node_fs_1.existsSync)(layers[0])
|
|
185
|
+
? `New layer directory ${shown[0]}`
|
|
186
|
+
: `Layer directory ${shown[0]} removed`;
|
|
187
|
+
}
|
|
188
|
+
function createDerivedOutputRefresher(workspaceDir, layers, reporter) {
|
|
189
|
+
const pending = new Map();
|
|
190
|
+
const failures = new Map();
|
|
191
|
+
let hasRestartNotice = false;
|
|
138
192
|
let timer = null;
|
|
139
|
-
const
|
|
193
|
+
const fail = (key, failure) => {
|
|
194
|
+
failures.set(key, failure);
|
|
195
|
+
reporter.warn(failure.text, failure.options);
|
|
196
|
+
};
|
|
197
|
+
const recover = (key) => {
|
|
198
|
+
const failure = failures.get(key);
|
|
199
|
+
if (!failure)
|
|
200
|
+
return;
|
|
201
|
+
failures.delete(key);
|
|
202
|
+
reporter.succeed(failure.fixed);
|
|
203
|
+
};
|
|
204
|
+
const noticeRestart = (output, paths) => {
|
|
205
|
+
if (!output.restartHint || hasRestartNotice)
|
|
206
|
+
return;
|
|
207
|
+
hasRestartNotice = true;
|
|
208
|
+
reporter.warn(describeLayerDirectories(paths, reporter), {
|
|
209
|
+
fixes: [output.restartHint],
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
const regenerate = (output, paths, registry) => {
|
|
140
213
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
214
|
+
const isChanged = output.write(workspaceDir, registry);
|
|
215
|
+
recover(output);
|
|
216
|
+
if (isChanged)
|
|
217
|
+
noticeRestart(output, paths);
|
|
143
218
|
}
|
|
144
219
|
catch (err) {
|
|
145
|
-
|
|
220
|
+
fail(output, describeOutputFailure(output, err, reporter));
|
|
146
221
|
}
|
|
147
222
|
};
|
|
148
223
|
const refresh = () => {
|
|
149
224
|
timer = null;
|
|
150
|
-
const outputs = derived_outputs_1.DERIVED_OUTPUTS.filter((output) => pending.has(output));
|
|
225
|
+
const outputs = derived_outputs_1.DERIVED_OUTPUTS.filter((output) => pending.has(output)).map((output) => [output, pending.get(output) ?? []]);
|
|
151
226
|
pending.clear();
|
|
152
227
|
let registry;
|
|
153
228
|
try {
|
|
154
229
|
registry = (0, derived_outputs_1.createFrontendModuleRegistry)(workspaceDir, layers);
|
|
230
|
+
recover("registry");
|
|
155
231
|
}
|
|
156
232
|
catch (err) {
|
|
157
|
-
|
|
233
|
+
fail("registry", {
|
|
234
|
+
text: "Derived files not regenerated",
|
|
235
|
+
options: {
|
|
236
|
+
details: [
|
|
237
|
+
...reporter.describe(err),
|
|
238
|
+
"The dev server keeps the previous ones until the module is fixed.",
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
fixed: "Derived files regenerated",
|
|
242
|
+
});
|
|
158
243
|
return;
|
|
159
244
|
}
|
|
160
|
-
for (const output of outputs)
|
|
161
|
-
regenerate(output, registry);
|
|
245
|
+
for (const [output, paths] of outputs)
|
|
246
|
+
regenerate(output, paths, registry);
|
|
162
247
|
};
|
|
163
248
|
return {
|
|
164
|
-
schedule(paths) {
|
|
165
|
-
|
|
166
|
-
|
|
249
|
+
schedule(src, paths) {
|
|
250
|
+
let isAffected = false;
|
|
251
|
+
for (const output of derived_outputs_1.DERIVED_OUTPUTS) {
|
|
252
|
+
const affected = paths.filter((path) => output.affects(path));
|
|
253
|
+
if (affected.length === 0)
|
|
254
|
+
continue;
|
|
255
|
+
isAffected = true;
|
|
256
|
+
pending.set(output, [
|
|
257
|
+
...(pending.get(output) ?? []),
|
|
258
|
+
...affected.map((path) => (0, node_path_1.join)(src, path)),
|
|
259
|
+
]);
|
|
260
|
+
}
|
|
261
|
+
if (!isAffected)
|
|
167
262
|
return;
|
|
168
|
-
for (const output of affected)
|
|
169
|
-
pending.add(output);
|
|
170
263
|
if (timer)
|
|
171
264
|
clearTimeout(timer);
|
|
172
265
|
timer = setTimeout(refresh, DERIVED_REFRESH_DEBOUNCE_MS);
|
|
@@ -179,16 +272,26 @@ function createDerivedOutputRefresher(workspaceDir, layers) {
|
|
|
179
272
|
},
|
|
180
273
|
};
|
|
181
274
|
}
|
|
182
|
-
function startLayerWatchers(workspaceDir, layers) {
|
|
275
|
+
function startLayerWatchers(workspaceDir, layers, ui = (0, cli_1.getProcessUi)(), write = output_1.writeFeedback) {
|
|
276
|
+
const mapPath = (0, child_output_1.createPathMapper)(workspaceDir, layers.map((layer) => ({ ...layer, sourcePath: layer.path })));
|
|
277
|
+
const reporter = {
|
|
278
|
+
warn: (text, options) => write((0, output_1.formatTimedMessage)("warn", text, options, ui)),
|
|
279
|
+
succeed: (text) => write((0, output_1.formatTimedMessage)("success", text, {}, ui)),
|
|
280
|
+
describe: (error) => (0, output_1.failureDetails)(error, ui).map((line) => mapPath(line)),
|
|
281
|
+
show: (path) => {
|
|
282
|
+
const mapped = mapPath(path);
|
|
283
|
+
return mapped === path ? (0, output_1.showPath)(path) : mapped;
|
|
284
|
+
},
|
|
285
|
+
};
|
|
183
286
|
const watchers = [];
|
|
184
287
|
const syncs = [];
|
|
185
|
-
const refresher = createDerivedOutputRefresher(workspaceDir, layers);
|
|
288
|
+
const refresher = createDerivedOutputRefresher(workspaceDir, layers, reporter);
|
|
186
289
|
for (const layer of layers) {
|
|
187
290
|
if (!layer.packageName)
|
|
188
291
|
continue;
|
|
189
292
|
const dest = (0, layers_1.getLayerWorkspacePath)(workspaceDir, layer);
|
|
190
293
|
const src = layer.path;
|
|
191
|
-
const sync = createLayerSync(src, dest, (paths) => refresher.schedule(paths));
|
|
294
|
+
const sync = createLayerSync(src, dest, (paths) => refresher.schedule(src, paths), reporter);
|
|
192
295
|
syncs.push(sync);
|
|
193
296
|
const watcher = chokidar_1.default.watch(src, {
|
|
194
297
|
ignoreInitial: true,
|
package/dist/layers.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ServedWithPath } from "./manifest";
|
|
2
2
|
import { ManifestModule, ResolvedLayer } from "./workspace";
|
|
3
|
-
export declare function assertLayerPathsServed(modules: ManifestModule[]): asserts modules is ServedWithPath[];
|
|
3
|
+
export declare function assertLayerPathsServed(modules: ManifestModule[], backendUrl: string, bootstrapSecret?: string): asserts modules is ServedWithPath[];
|
|
4
4
|
export declare function assertCachedArchivesExist(modules: ManifestModule[], cacheDir: string, fetchedAt?: string): void;
|
|
5
5
|
export interface LayerPackage {
|
|
6
6
|
name?: unknown;
|
|
7
7
|
engines?: Record<string, unknown>;
|
|
8
8
|
}
|
|
9
9
|
export declare function readLayerPackage(layerPath: string): LayerPackage | undefined;
|
|
10
|
-
export declare function buildLayersFromPaths(modules:
|
|
10
|
+
export declare function buildLayersFromPaths(modules: ServedWithPath[]): ResolvedLayer[];
|
|
11
11
|
export declare function downloadAndExtractLayers(backendUrl: string, packUrl: string, cacheDir: string, force: boolean, bootstrapSecret?: string): Promise<void>;
|
|
12
12
|
export declare function buildLayersFromCache(modules: ManifestModule[], cacheDir: string): Promise<ResolvedLayer[]>;
|
|
13
13
|
export declare function getLayerSafeName(layer: ResolvedLayer): string;
|
package/dist/layers.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.assertLayerPathsServed = assertLayerPathsServed;
|
|
4
37
|
exports.assertCachedArchivesExist = assertCachedArchivesExist;
|
|
@@ -13,30 +46,46 @@ const promises_1 = require("node:fs/promises");
|
|
|
13
46
|
const node_path_1 = require("node:path");
|
|
14
47
|
const node_stream_1 = require("node:stream");
|
|
15
48
|
const consumers_1 = require("node:stream/consumers");
|
|
16
|
-
const
|
|
49
|
+
const cli_1 = require("@antelopejs/core/cli");
|
|
17
50
|
const manifest_1 = require("./manifest");
|
|
18
|
-
const workspace_1 = require("./workspace");
|
|
19
51
|
const fs_sync_1 = require("./fs-sync");
|
|
20
52
|
const config_1 = require("./config");
|
|
21
|
-
|
|
53
|
+
const output_1 = require("./output");
|
|
54
|
+
function assertLayerPathsServed(modules, backendUrl, bootstrapSecret) {
|
|
22
55
|
const pathless = modules.filter((mod) => !mod.path);
|
|
23
56
|
if (pathless.length === 0)
|
|
24
57
|
return;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
58
|
+
const count = `${pathless.length} of ${modules.length} module${modules.length === 1 ? "" : "s"}`;
|
|
59
|
+
const { reason, fix } = bootstrapSecret
|
|
60
|
+
? {
|
|
61
|
+
reason: "It sends them only to callers presenting its development credential, and did not accept the one this run sent.",
|
|
62
|
+
fix: "Run the command from the antelope project started with `ajs project dev`, without DMS_BOOTSTRAP_SECRET or --bootstrap-secret, so the credential is read from .antelope/dms-dev.json",
|
|
63
|
+
}
|
|
64
|
+
: {
|
|
65
|
+
reason: "It sends them only to callers presenting its development credential, and this run sent none: " +
|
|
66
|
+
"no DMS_BOOTSTRAP_SECRET or --bootstrap-secret, and no project started with `ajs project dev` " +
|
|
67
|
+
"serving this backend was found from the current directory, so no .antelope/dms-dev.json was read.",
|
|
68
|
+
fix: "Run the command from that project, or set DMS_BOOTSTRAP_SECRET to the backend's credential",
|
|
69
|
+
};
|
|
70
|
+
throw new cli_1.CliError({
|
|
71
|
+
title: `The backend at ${(0, manifest_1.displayUrl)(backendUrl)} did not send layer source paths (${count})`,
|
|
72
|
+
reason,
|
|
73
|
+
fixes: [
|
|
74
|
+
fix,
|
|
75
|
+
"A remote or production backend never sends them: use `ajs dms build` against it",
|
|
76
|
+
],
|
|
77
|
+
});
|
|
31
78
|
}
|
|
32
79
|
function assertCachedArchivesExist(modules, cacheDir, fetchedAt) {
|
|
33
80
|
const present = new Set((0, node_fs_1.readdirSync)(cacheDir));
|
|
34
81
|
const missing = modules.filter((mod) => !present.has(mod.archiveName));
|
|
35
82
|
if (missing.length === 0)
|
|
36
83
|
return;
|
|
37
|
-
throw new
|
|
38
|
-
missing
|
|
39
|
-
"
|
|
84
|
+
throw new cli_1.CliError({
|
|
85
|
+
title: `The cached layers archive is missing entries listed in the manifest${fetchedAt ? ` (fetched ${(0, output_1.formatAge)(fetchedAt)})` : ""}`,
|
|
86
|
+
fixes: ["Run once with the backend reachable to download the layers again"],
|
|
87
|
+
details: missing.map((mod) => `${mod.name}: ${mod.archiveName}`),
|
|
88
|
+
});
|
|
40
89
|
}
|
|
41
90
|
function sortModulesByPriority(modules) {
|
|
42
91
|
return [...modules].sort((a, b) => b.priority - a.priority);
|
|
@@ -59,6 +108,7 @@ function readLayerPackageName(layerPath) {
|
|
|
59
108
|
function resolveLayer(layerPath, mod) {
|
|
60
109
|
return {
|
|
61
110
|
path: layerPath,
|
|
111
|
+
sourcePath: mod.path,
|
|
62
112
|
packageName: readLayerPackageName(layerPath),
|
|
63
113
|
priority: mod.priority,
|
|
64
114
|
configKey: mod.configKey,
|
|
@@ -67,34 +117,32 @@ function resolveLayer(layerPath, mod) {
|
|
|
67
117
|
};
|
|
68
118
|
}
|
|
69
119
|
function buildLayersFromPaths(modules) {
|
|
70
|
-
assertLayerPathsServed(modules);
|
|
71
120
|
return sortModulesByPriority(modules).map((mod) => resolveLayer(mod.path, mod));
|
|
72
121
|
}
|
|
73
122
|
async function downloadAndExtractLayers(backendUrl, packUrl, cacheDir, force, bootstrapSecret) {
|
|
74
|
-
const url =
|
|
75
|
-
const response = await
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if ((0, workspace_1.isUnauthorized)(response.status)) {
|
|
79
|
-
throw new manifest_1.ManifestUnauthorizedError(url, response.status);
|
|
123
|
+
const url = (0, manifest_1.backendEndpoint)(backendUrl, packUrl);
|
|
124
|
+
const response = await (0, manifest_1.fetchFromBackend)(backendUrl, url, bootstrapSecret);
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
throw new manifest_1.BackendResponseError("the layers archive", url, response);
|
|
80
127
|
}
|
|
81
|
-
if (!response.
|
|
82
|
-
throw new Error(
|
|
128
|
+
if (!response.body) {
|
|
129
|
+
throw new Error(`The layers archive from ${(0, manifest_1.displayUrl)(url)} came without a body`);
|
|
83
130
|
}
|
|
84
131
|
const modulesBlob = await (0, consumers_1.buffer)(node_stream_1.Readable.fromWeb(response.body));
|
|
132
|
+
const { Open } = await Promise.resolve().then(() => __importStar(require("unzipper")));
|
|
85
133
|
const cacheExists = (0, node_fs_1.existsSync)(cacheDir);
|
|
86
134
|
if (force || !cacheExists) {
|
|
87
135
|
if (cacheExists) {
|
|
88
136
|
(0, node_fs_1.rmSync)(cacheDir, { recursive: true, force: true });
|
|
89
137
|
}
|
|
90
|
-
await (await
|
|
138
|
+
await (await Open.buffer(modulesBlob)).extract({ path: cacheDir });
|
|
91
139
|
return;
|
|
92
140
|
}
|
|
93
141
|
const tempDir = `${cacheDir}_temp`;
|
|
94
142
|
if ((0, node_fs_1.existsSync)(tempDir)) {
|
|
95
143
|
(0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
|
|
96
144
|
}
|
|
97
|
-
await (await
|
|
145
|
+
await (await Open.buffer(modulesBlob)).extract({ path: tempDir });
|
|
98
146
|
const tempEntries = (0, node_fs_1.readdirSync)(tempDir);
|
|
99
147
|
for (const entry of tempEntries) {
|
|
100
148
|
(0, fs_sync_1.syncDirectories)((0, node_path_1.join)(tempDir, entry), (0, node_path_1.join)(cacheDir, entry));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Ui } from "@antelopejs/core/cli";
|
|
1
2
|
import type { ManifestModule } from "./workspace";
|
|
2
3
|
export declare const MANIFEST_SECRET_ENV: {
|
|
3
4
|
readonly DMS_HTML_RENDER_SECRET: readonly ["htmlRender", "serviceSecret"];
|
|
@@ -26,6 +27,6 @@ export interface ResolvedManifestSecrets {
|
|
|
26
27
|
export declare function collectManifestSecrets(modules: readonly ManifestModule[]): ManifestSecrets;
|
|
27
28
|
export declare function resolveManifestSecrets(secrets: ManifestSecrets, env?: NodeJS.ProcessEnv): ResolvedManifestSecrets;
|
|
28
29
|
export declare function formatSecretConflicts(conflicts: readonly ManifestSecretConflict[]): string[];
|
|
29
|
-
export declare function
|
|
30
|
-
export declare function reportManifestSecrets(resolved: ResolvedManifestSecrets,
|
|
30
|
+
export declare function describeSecretSources(sources: ResolvedManifestSecrets["sources"], manifestLabel?: string): string | undefined;
|
|
31
|
+
export declare function reportManifestSecrets(resolved: ResolvedManifestSecrets, fix: (count: number) => string, ui?: Ui): void;
|
|
31
32
|
export {};
|