@antelopejs/dms-frontend 0.3.9 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -72,7 +72,7 @@ pnpm add -g @antelopejs/core @antelopejs/dms-frontend
72
72
  ```
73
73
 
74
74
  The plugin prints through the output module of `@antelopejs/core`
75
- (`@antelopejs/core/cli`), so it needs `@antelopejs/core` 1.13.0 or later.
75
+ (`@antelopejs/core/cli`), so it needs `@antelopejs/core` 1.13.2 or later.
76
76
  `npm install -g` works too; this repository and every generated workspace use
77
77
  pnpm. Inside a package script, `ajs` resolves from `node_modules/.bin`, and the
78
78
  `dms` command it delegates to resolves the project-local plugin, so a script
@@ -134,9 +134,14 @@ missing configuration value) and 130 when stopped with Ctrl+C. `--no-color` or
134
134
  `NO_COLOR=1` turns colors off, and terminals that cannot draw Unicode, such as
135
135
  `TERM=dumb`, get ASCII symbols. `--verbose` or `ANTELOPEJS_VERBOSE` streams
136
136
  the full `pnpm` and Vite output, each line behind the name of the step, and adds
137
- the stack trace of the underlying error to a failure. `ajs --no-color dms …`,
138
- `ajs --verbose dms …` and `ajs --verbose=<channels> dms …` set those variables
139
- for the plugin.
137
+ the stack trace of the underlying error to a failure; `--verbose=<channels>`
138
+ turns all of it on too, whatever the channels. `-q`, `--quiet` or
139
+ `ANTELOPEJS_QUIET=1` prints only results, warnings and errors: no command
140
+ header, progress, summary or update notice, and of the block a ready `dev` or
141
+ `start` server prints, only its Local URL. `ajs --no-color dms …`,
142
+ `ajs --verbose dms …`, `ajs --verbose=<channels> dms …` and `ajs -q dms …` set
143
+ those variables for the plugin; the same flags are also accepted after the
144
+ command, as in `ajs dms build -q`.
140
145
 
141
146
  The CLI checks npm for a newer release at most once a day and prints a one-line
142
147
  notice on stderr, only to a terminal: as the last line of a command that
@@ -4,5 +4,5 @@ export interface CleanOptions {
4
4
  all?: boolean;
5
5
  yes?: boolean;
6
6
  }
7
- export declare function describeWorkspaces(records: WorkspaceRecord[], isTerminal: boolean): string[];
7
+ export declare function describeWorkspaces(records: WorkspaceRecord[], isTerminal: boolean, columns?: number): string[];
8
8
  export declare function runClean(options: CleanOptions): Promise<void>;
@@ -11,25 +11,30 @@ const CLEAN_ALL_COMMAND = "ajs dms clean --all";
11
11
  const YES_FLAG = "--yes";
12
12
  const COLUMN_GAP = " ";
13
13
  const ROW_INDENT = " ";
14
- function describeWorkspaces(records, isTerminal) {
14
+ function describeWorkspaces(records, isTerminal, columns) {
15
15
  const rows = records.map((record) => [
16
16
  (0, output_1.workspaceId)(record.dir, isTerminal),
17
17
  record.backendUrl,
18
18
  (0, workspaces_action_1.describeKey)(record),
19
19
  ]);
20
20
  const widths = rows[0].map((_, column) => Math.max(...rows.map((row) => row[column].length)));
21
- return rows.map((row) => row
22
- .map((cell, column) => cell.padEnd(widths[column]))
21
+ return rows.flatMap(([id, ...rest]) => (0, output_1.wrapAfter)(`${id.padEnd(widths[0])}${COLUMN_GAP}`, rest
22
+ .map((cell, column) => cell.padEnd(widths[column + 1]))
23
23
  .join(COLUMN_GAP)
24
- .trimEnd());
24
+ .trimEnd(), columns).map((line) => line.trimEnd()));
25
+ }
26
+ function writeWorkspaces(records, isTerminal, write, paint = (line) => line) {
27
+ const columns = (0, output_1.feedbackColumns)();
28
+ const width = columns === undefined ? undefined : columns - ROW_INDENT.length;
29
+ for (const line of describeWorkspaces(records, isTerminal, width)) {
30
+ write(`${ROW_INDENT}${paint(line)}`);
31
+ }
25
32
  }
26
33
  async function confirmCleanAll(records, totalBytes, options) {
27
34
  const prompter = (0, cli_1.createPrompter)({ command: CLEAN_ALL_COMMAND });
28
35
  if (!options.yes && prompter.isInteractive) {
29
36
  (0, output_1.writeFeedback)(`Remove ${(0, cli_1.pluralize)(records.length, "workspace")} (${(0, output_1.formatSize)(totalBytes)})?`);
30
- for (const line of describeWorkspaces(records, true)) {
31
- (0, output_1.writeFeedback)(`${ROW_INDENT}${line}`);
32
- }
37
+ writeWorkspaces(records, true, output_1.writeFeedback);
33
38
  }
34
39
  return prompter.confirm({
35
40
  message: "Continue?",
@@ -57,11 +62,10 @@ async function cleanAll(options) {
57
62
  ui.message("success", [
58
63
  `Removed ${(0, cli_1.pluralize)(records.length, "workspace")}`,
59
64
  `freed ${(0, output_1.formatSize)(totalBytes)}`,
60
- ].join(ui.symbols.separator), {
61
- details: options.yes
62
- ? describeWorkspaces(records, (0, output_1.isTerminalFeedback)())
63
- : [],
64
- });
65
+ ].join(ui.symbols.separator));
66
+ if (options.yes) {
67
+ writeWorkspaces(records, (0, output_1.isTerminalFeedback)(), output_1.writeInfo, ui.palette().dim);
68
+ }
65
69
  (0, workspaces_action_1.reportSkipped)(ui, skipped);
66
70
  }
67
71
  async function runClean(options) {
package/dist/help.js CHANGED
@@ -40,6 +40,7 @@ exports.ENVIRONMENT_VARIABLES = [
40
40
  ["DMS_CLIENT_BASE_URL", "Public frontend URL used in links and e-mails"],
41
41
  ["NO_COLOR", "Same as --no-color"],
42
42
  ["ANTELOPEJS_VERBOSE", "Same as --verbose"],
43
+ ["ANTELOPEJS_QUIET", "Same as -q, unless 0 or false"],
43
44
  ["NO_UPDATE_NOTIFIER, CI", "Either one turns the update check off"],
44
45
  ];
45
46
  const ENVIRONMENT_NOTES = [
package/dist/index.js CHANGED
@@ -16,7 +16,12 @@ const help_1 = require("./help");
16
16
  const output_1 = require("./output");
17
17
  const update_check_1 = require("./update-check");
18
18
  const { version } = require("../package.json");
19
- const GLOBAL_FLAGS = ["--no-color", "--verbose"];
19
+ const QUIET_FLAGS = ["-q", "--quiet"];
20
+ const GLOBAL_FLAGS = ["--no-color", ...QUIET_FLAGS];
21
+ const VERBOSE_FLAG = "--verbose";
22
+ const VERBOSE_ASSIGNMENT = `${VERBOSE_FLAG}=`;
23
+ const ALL_CHANNELS = "*";
24
+ const END_OF_OPTIONS = "--";
20
25
  const ROOT_EXAMPLES = [
21
26
  {
22
27
  description: "Inside a project started with ajs project dev",
@@ -51,8 +56,32 @@ function describeHelpFooter(width) {
51
56
  ...(0, cli_1.wrapText)(pointer, width),
52
57
  ].join("\n");
53
58
  }
59
+ function isGlobalFlag(arg) {
60
+ return GLOBAL_FLAGS.includes(arg) || arg.startsWith(VERBOSE_ASSIGNMENT);
61
+ }
54
62
  function ownArguments(args) {
55
- return args.filter((arg) => !GLOBAL_FLAGS.includes(arg));
63
+ return args.filter((arg) => !isGlobalFlag(arg));
64
+ }
65
+ function optionArguments(args) {
66
+ const end = args.indexOf(END_OF_OPTIONS);
67
+ return end === -1 ? args : args.slice(0, end);
68
+ }
69
+ function normalizeVerboseArguments(args) {
70
+ const optionCount = optionArguments(args).length;
71
+ return args.map((arg, index) => index < optionCount && arg === VERBOSE_FLAG
72
+ ? `${VERBOSE_ASSIGNMENT}${ALL_CHANNELS}`
73
+ : arg);
74
+ }
75
+ function exportOutputFlags(args) {
76
+ const options = optionArguments(args);
77
+ if (options.some((arg) => QUIET_FLAGS.includes(arg))) {
78
+ process.env.ANTELOPEJS_QUIET = "1";
79
+ }
80
+ const verbose = options.filter((arg) => arg.startsWith(VERBOSE_ASSIGNMENT));
81
+ if (verbose.length > 0) {
82
+ const channels = verbose[verbose.length - 1].slice(VERBOSE_ASSIGNMENT.length);
83
+ process.env.ANTELOPEJS_VERBOSE = channels || ALL_CHANNELS;
84
+ }
56
85
  }
57
86
  function isInvocation(args, rest) {
58
87
  const own = ownArguments(args);
@@ -79,7 +108,8 @@ const runCLI = async () => {
79
108
  .name("ajs dms")
80
109
  .version(version, "-v, --version", "Print the version")
81
110
  .option("--no-color", "Disable colors (also NO_COLOR=1)")
82
- .option("--verbose", "Show full output and stack traces (also ANTELOPEJS_VERBOSE)")
111
+ .option(`${VERBOSE_FLAG} [=channels]`, "Show full output and stack traces (also ANTELOPEJS_VERBOSE); any channels turn all of it on")
112
+ .option("-q, --quiet", "Print only results, warnings and errors (also ANTELOPEJS_QUIET=1)")
83
113
  .option("--no-update-check", "Skip the daily update check (also NO_UPDATE_NOTIFIER=1)")
84
114
  .addHelpText("before", (context) => describeVersion(version, (0, cli_1.helpTextWidth)(context)))
85
115
  .addHelpText("after", (context) => describeHelpFooter((0, cli_1.helpTextWidth)(context)));
@@ -92,7 +122,8 @@ const runCLI = async () => {
92
122
  program.addCommand((0, verify_source_1.cmdVerifySource)());
93
123
  (0, help_1.applyDmsHelp)(program);
94
124
  (0, cli_1.formatUsageErrors)(program);
95
- const args = (0, update_check_1.stripUpdateCheckFlag)(argv);
125
+ const args = normalizeVerboseArguments((0, update_check_1.stripUpdateCheckFlag)(argv));
126
+ exportOutputFlags(args);
96
127
  if (isInvocation(args, [])) {
97
128
  program.outputHelp();
98
129
  return;
@@ -1,3 +1,3 @@
1
1
  import { type Ui } from "@antelopejs/core/cli";
2
2
  import { ResolvedLayer } from "./workspace";
3
- export declare function startLayerWatchers(workspaceDir: string, layers: ResolvedLayer[], ui?: Ui, write?: (text: string) => void): () => Promise<void>;
3
+ export declare function startLayerWatchers(workspaceDir: string, layers: ResolvedLayer[], ui?: Ui, write?: (text: string) => void, isQuiet?: boolean): () => Promise<void>;
@@ -272,11 +272,14 @@ function createDerivedOutputRefresher(workspaceDir, layers, reporter) {
272
272
  },
273
273
  };
274
274
  }
275
- function startLayerWatchers(workspaceDir, layers, ui = (0, cli_1.getProcessUi)(), write = output_1.writeFeedback) {
275
+ function startLayerWatchers(workspaceDir, layers, ui = (0, cli_1.getProcessUi)(), write = output_1.writeFeedback, isQuiet = (0, cli_1.isQuietRun)()) {
276
276
  const mapPath = (0, child_output_1.createPathMapper)(workspaceDir, layers.map((layer) => ({ ...layer, sourcePath: layer.path })));
277
277
  const reporter = {
278
278
  warn: (text, options) => write((0, output_1.formatTimedMessage)("warn", text, options, ui)),
279
- succeed: (text) => write((0, output_1.formatTimedMessage)("success", text, {}, ui)),
279
+ succeed: (text) => {
280
+ if (!isQuiet)
281
+ write((0, output_1.formatTimedMessage)("success", text, {}, ui));
282
+ },
280
283
  describe: (error) => (0, output_1.failureDetails)(error, ui).map((line) => mapPath(line)),
281
284
  show: (path) => {
282
285
  const mapped = mapPath(path);
package/dist/layers.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  import { ServedWithPath } from "./manifest";
2
2
  import { ManifestModule, ResolvedLayer } from "./workspace";
3
- export declare function assertLayerPathsServed(modules: ManifestModule[], backendUrl: string, bootstrapSecret?: string): asserts modules is ServedWithPath[];
3
+ interface PathlessManifestSource {
4
+ bootstrapSecret?: string;
5
+ cache?: {
6
+ fetchedAt?: string;
7
+ };
8
+ }
9
+ export declare function assertLayerPathsServed(modules: ManifestModule[], backendUrl: string, { bootstrapSecret, cache }?: PathlessManifestSource): asserts modules is ServedWithPath[];
4
10
  export declare function assertCachedArchivesExist(modules: ManifestModule[], cacheDir: string, fetchedAt?: string): void;
5
11
  export interface LayerPackage {
6
12
  name?: unknown;
@@ -12,3 +18,4 @@ export declare function downloadAndExtractLayers(backendUrl: string, packUrl: st
12
18
  export declare function buildLayersFromCache(modules: ManifestModule[], cacheDir: string): Promise<ResolvedLayer[]>;
13
19
  export declare function getLayerSafeName(layer: ResolvedLayer): string;
14
20
  export declare function getLayerWorkspacePath(workspaceDir: string, layer: ResolvedLayer): string;
21
+ export {};
package/dist/layers.js CHANGED
@@ -51,11 +51,25 @@ const manifest_1 = require("./manifest");
51
51
  const fs_sync_1 = require("./fs-sync");
52
52
  const config_1 = require("./config");
53
53
  const output_1 = require("./output");
54
- function assertLayerPathsServed(modules, backendUrl, bootstrapSecret) {
54
+ const BUILD_FIX = "A remote or production backend never sends them: use `ajs dms build` against it";
55
+ function assertLayerPathsServed(modules, backendUrl, { bootstrapSecret, cache } = {}) {
55
56
  const pathless = modules.filter((mod) => !mod.path);
56
57
  if (pathless.length === 0)
57
58
  return;
58
59
  const count = `${pathless.length} of ${modules.length} module${modules.length === 1 ? "" : "s"}`;
60
+ if (cache) {
61
+ const fetched = cache.fetchedAt
62
+ ? ` (fetched ${(0, output_1.formatAge)(cache.fetchedAt)})`
63
+ : "";
64
+ throw new cli_1.CliError({
65
+ title: `The cached manifest of ${(0, manifest_1.displayUrl)(backendUrl)}${fetched} has no layer source paths (${count})`,
66
+ reason: "This run did not fetch it. The backend sends the paths only to callers presenting its development credential, and did not send them to the run that cached this manifest.",
67
+ fixes: [
68
+ "Run once without --offline, with the backend reachable, from the project started with `ajs project dev` or with DMS_BOOTSTRAP_SECRET set",
69
+ BUILD_FIX,
70
+ ],
71
+ });
72
+ }
59
73
  const { reason, fix } = bootstrapSecret
60
74
  ? {
61
75
  reason: "It sends them only to callers presenting its development credential, and did not accept the one this run sent.",
@@ -70,10 +84,7 @@ function assertLayerPathsServed(modules, backendUrl, bootstrapSecret) {
70
84
  throw new cli_1.CliError({
71
85
  title: `The backend at ${(0, manifest_1.displayUrl)(backendUrl)} did not send layer source paths (${count})`,
72
86
  reason,
73
- fixes: [
74
- fix,
75
- "A remote or production backend never sends them: use `ajs dms build` against it",
76
- ],
87
+ fixes: [fix, BUILD_FIX],
77
88
  });
78
89
  }
79
90
  function assertCachedArchivesExist(modules, cacheDir, fetchedAt) {
package/dist/output.d.ts CHANGED
@@ -3,7 +3,10 @@ import { CancelledError } from "./cancellation";
3
3
  export declare function exitOnBrokenPipe(stream?: NodeJS.WriteStream): void;
4
4
  export declare function isTerminalFeedback(): boolean;
5
5
  export declare function isTerminalResult(): boolean;
6
+ export declare function feedbackColumns(): number | undefined;
7
+ export declare function wrapAfter(prefix: string, text: string, columns: number | undefined, paint?: (line: string) => string): string[];
6
8
  export declare function writeFeedback(line: string): void;
9
+ export declare function writeInfo(line: string): void;
7
10
  export declare function writeHeader(command: string, context: string[], ui?: Ui): void;
8
11
  export declare function writeBlankLine(): void;
9
12
  export declare function showPath(target: string, home?: string): string;
@@ -19,13 +22,14 @@ export interface ReadyLine {
19
22
  label: string;
20
23
  value: string;
21
24
  isLink?: boolean;
25
+ isEssential?: boolean;
22
26
  }
23
27
  export interface ReadyBlock {
24
28
  title: string;
25
29
  lines: ReadyLine[];
26
30
  footer: string;
27
31
  }
28
- export declare function formatReadyBlock(block: ReadyBlock, ui?: Ui): string[];
32
+ export declare function formatReadyBlock(block: ReadyBlock, ui?: Ui, isQuiet?: boolean, columns?: number | undefined): string[];
29
33
  export declare function writeReadyBlock(block: ReadyBlock, ui?: Ui): void;
30
34
  declare const TIMED_LEVEL_COLORS: {
31
35
  readonly success: "green";
@@ -36,6 +40,7 @@ type TimedLevel = keyof typeof TIMED_LEVEL_COLORS;
36
40
  export interface TimedMessageOptions {
37
41
  details?: readonly string[];
38
42
  fixes?: readonly string[];
43
+ columns?: number;
39
44
  }
40
45
  export declare function formatTimedMessage(level: TimedLevel, text: string, options?: TimedMessageOptions, ui?: Ui, now?: Date): string;
41
46
  export {};
package/dist/output.js CHANGED
@@ -3,7 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.exitOnBrokenPipe = exitOnBrokenPipe;
4
4
  exports.isTerminalFeedback = isTerminalFeedback;
5
5
  exports.isTerminalResult = isTerminalResult;
6
+ exports.feedbackColumns = feedbackColumns;
7
+ exports.wrapAfter = wrapAfter;
6
8
  exports.writeFeedback = writeFeedback;
9
+ exports.writeInfo = writeInfo;
7
10
  exports.writeHeader = writeHeader;
8
11
  exports.writeBlankLine = writeBlankLine;
9
12
  exports.showPath = showPath;
@@ -20,6 +23,7 @@ exports.writeReadyBlock = writeReadyBlock;
20
23
  exports.formatTimedMessage = formatTimedMessage;
21
24
  const node_os_1 = require("node:os");
22
25
  const node_path_1 = require("node:path");
26
+ const node_util_1 = require("node:util");
23
27
  const cli_1 = require("@antelopejs/core/cli");
24
28
  const cancellation_1 = require("./cancellation");
25
29
  const HOME_PREFIX = "~";
@@ -33,6 +37,8 @@ const BLOCK_INDENT = " ";
33
37
  const LINK_GAP = " ";
34
38
  const LABEL_SUFFIX = ":";
35
39
  const TIME_LENGTH = 8;
40
+ const MIN_WRAP_WIDTH = 20;
41
+ const LEADING_SPACES = /^ */;
36
42
  const BYTES_PER_UNIT = 1024;
37
43
  const SIZE_UNITS = ["B", "KB", "MB", "GB", "TB"];
38
44
  const DECIMAL_SIZE_LIMIT = 10;
@@ -55,15 +61,33 @@ function isTerminalFeedback() {
55
61
  function isTerminalResult() {
56
62
  return (0, cli_1.detectCapabilities)((0, cli_1.processCapabilityContext)()).terminals.result;
57
63
  }
64
+ function feedbackColumns() {
65
+ return isTerminalFeedback() ? process.stderr.columns || undefined : undefined;
66
+ }
67
+ function wrapAfter(prefix, text, columns, paint = (line) => line) {
68
+ const indent = " ".repeat((0, node_util_1.stripVTControlCharacters)(prefix).length);
69
+ const leading = LEADING_SPACES.exec(text)?.[0] ?? "";
70
+ const lines = columns === undefined
71
+ ? [text]
72
+ : (0, cli_1.wrapText)(text.slice(leading.length), Math.max(MIN_WRAP_WIDTH, columns - indent.length - leading.length)).map((line) => `${leading}${line}`);
73
+ return lines.map((line, index) => `${index === 0 ? prefix : indent}${paint(line)}`);
74
+ }
58
75
  function writeFeedback(line) {
59
76
  (0, cli_1.getProcessTasks)().write(process.stderr, `${line}\n`);
60
77
  }
78
+ function writeInfo(line) {
79
+ if (!(0, cli_1.isQuietRun)())
80
+ writeFeedback(line);
81
+ }
61
82
  function writeHeader(command, context, ui = (0, cli_1.getProcessUi)()) {
62
83
  const title = ui.palette().bold(`ajs dms ${command}`);
63
- writeFeedback(`${title} ${context.join(ui.symbols.separator)}`);
84
+ const text = context.join(ui.symbols.separator);
85
+ for (const line of wrapAfter(`${title} `, text, feedbackColumns())) {
86
+ writeInfo(line);
87
+ }
64
88
  }
65
89
  function writeBlankLine() {
66
- writeFeedback("");
90
+ writeInfo("");
67
91
  }
68
92
  function showPath(target, home = (0, node_os_1.homedir)()) {
69
93
  if ((0, node_path_1.resolve)(target) === process.cwd())
@@ -148,32 +172,45 @@ function endInterruptedTask(task, error, stopped) {
148
172
  task.skip(stopped);
149
173
  }
150
174
  function reportStopped(stop, ui = (0, cli_1.getProcessUi)()) {
175
+ const lineStart = lineStartAfter(stop.signal);
176
+ if ((0, cli_1.isQuietRun)()) {
177
+ if (lineStart)
178
+ writeFeedback("");
179
+ return;
180
+ }
151
181
  const symbol = isUnicode(ui)
152
182
  ? STOPPED_SYMBOLS.unicode
153
183
  : STOPPED_SYMBOLS.ascii;
154
184
  const text = [stop.stopped, ...stop.context].join(ui.symbols.separator);
155
- writeFeedback(`${lineStartAfter(stop.signal)}${ui.palette().red(symbol)} ${text}`);
185
+ const symbolPrefix = `${ui.palette().red(symbol)} `;
186
+ const lines = wrapAfter(symbolPrefix, text, feedbackColumns());
187
+ writeFeedback(`${lineStart}${lines.join("\n")}`);
156
188
  }
157
- function formatReadyBlock(block, ui = (0, cli_1.getProcessUi)()) {
189
+ function formatReadyBlock(block, ui = (0, cli_1.getProcessUi)(), isQuiet = (0, cli_1.isQuietRun)(), columns = feedbackColumns()) {
158
190
  const palette = ui.palette();
159
191
  const arrow = isUnicode(ui) ? LINK_SYMBOLS.unicode : LINK_SYMBOLS.ascii;
160
- const width = Math.max(...block.lines.map(({ label }) => label.length + LABEL_SUFFIX.length));
192
+ const shown = isQuiet
193
+ ? block.lines.filter(({ isEssential }) => isEssential)
194
+ : block.lines;
195
+ const width = Math.max(...shown.map(({ label }) => label.length + LABEL_SUFFIX.length));
161
196
  const lead = (isLink) => `${BLOCK_INDENT}${isLink ? palette.cyan(arrow) : " ".repeat(arrow.length)}${LINK_GAP}`;
162
- const lines = block.lines.map(({ label, value, isLink }) => {
197
+ const lines = shown.flatMap(({ label, value, isLink }) => {
163
198
  const shownLabel = `${label}${LABEL_SUFFIX}`.padEnd(width);
164
- const shownValue = isLink ? palette.cyan(value) : value;
165
- return `${lead(isLink)}${palette.dim(shownLabel)} ${shownValue}`;
199
+ return wrapAfter(`${lead(isLink)}${palette.dim(shownLabel)} `, value, columns, isLink ? palette.cyan : undefined);
166
200
  });
201
+ if (isQuiet)
202
+ return lines;
167
203
  return [
168
- `${palette.green(ui.symbols.levels.success)} ${block.title}`,
204
+ ...wrapAfter(`${palette.green(ui.symbols.levels.success)} `, block.title, columns),
169
205
  "",
170
206
  ...lines,
171
- `${lead()}${palette.dim(block.footer)}`,
207
+ ...wrapAfter(lead(), block.footer, columns, palette.dim),
172
208
  ];
173
209
  }
174
210
  function writeReadyBlock(block, ui = (0, cli_1.getProcessUi)()) {
175
- for (const line of [...formatReadyBlock(block, ui), ""])
211
+ for (const line of formatReadyBlock(block, ui))
176
212
  writeFeedback(line);
213
+ writeInfo("");
177
214
  }
178
215
  const TIMED_LEVEL_COLORS = {
179
216
  success: "green",
@@ -184,14 +221,14 @@ function clockTime(date) {
184
221
  return date.toTimeString().slice(0, TIME_LENGTH);
185
222
  }
186
223
  function formatTimedMessage(level, text, options = {}, ui = (0, cli_1.getProcessUi)(), now = new Date()) {
187
- const { details = [], fixes = [] } = options;
224
+ const { details = [], fixes = [], columns = feedbackColumns() } = options;
188
225
  const palette = ui.palette();
189
226
  const paint = palette[TIMED_LEVEL_COLORS[level]];
190
227
  const hint = palette.cyan(ui.symbols.levels.hint);
191
228
  const indent = " ".repeat(TIME_LENGTH + 1) + BLOCK_INDENT;
192
229
  return [
193
- `${palette.dim(clockTime(now))} ${paint(ui.symbols.levels[level])} ${text}`,
194
- ...details.map((detail) => `${indent}${palette.dim(detail)}`),
195
- ...fixes.map((fix) => `${indent}${hint} ${fix}`),
230
+ ...wrapAfter(`${palette.dim(clockTime(now))} ${paint(ui.symbols.levels[level])} `, text, columns),
231
+ ...details.flatMap((detail) => wrapAfter(indent, detail, columns, palette.dim)),
232
+ ...fixes.flatMap((fix) => wrapAfter(`${indent}${hint} `, fix, columns)),
196
233
  ].join("\n");
197
234
  }
@@ -165,7 +165,12 @@ function readyLines(address, settings, interfaces, isGuestInterface) {
165
165
  const network = networkUrls(address, interfaces, isGuestInterface);
166
166
  const hidden = network.length - MAX_NETWORK_URLS;
167
167
  return [
168
- { label: "Local", value: localUrl(address), isLink: true },
168
+ {
169
+ label: "Local",
170
+ value: localUrl(address),
171
+ isLink: true,
172
+ isEssential: true,
173
+ },
169
174
  ...network.slice(0, MAX_NETWORK_URLS).map((value) => ({
170
175
  label: "Network",
171
176
  value,
@@ -14,6 +14,7 @@ export interface UpdateCheckOptions {
14
14
  fetchLatestVersion?: (packageName: string) => Promise<string | undefined>;
15
15
  ui?: Ui;
16
16
  write?: (line: string) => void;
17
+ columns?: number;
17
18
  }
18
19
  export interface UpdateNoticeOptions {
19
20
  isFollowed?: boolean;
@@ -89,6 +89,8 @@ function stripUpdateCheckFlag(argv) {
89
89
  function isUpdateCheckEnabled(argv, env) {
90
90
  if (env.CI)
91
91
  return false;
92
+ if ((0, cli_1.isQuietRun)({ argv: [...argv], env }))
93
+ return false;
92
94
  if (env.NO_UPDATE_NOTIFIER)
93
95
  return false;
94
96
  if (env.TERM === DUMB_TERMINAL)
@@ -180,11 +182,11 @@ function fetchLatestVersionFromRegistry(packageName, registryUrl = DEFAULT_REGIS
180
182
  }
181
183
  });
182
184
  }
183
- function formatNotice(currentVersion, latestVersion, ui) {
185
+ function formatNotice(currentVersion, latestVersion, ui, columns) {
184
186
  const palette = ui.palette("feedback");
185
187
  const { info, hint } = ui.symbols.levels;
186
- return (`${palette.blue(info)} ajs dms ${latestVersion} is available ` +
187
- `(you have ${currentVersion}) ${palette.cyan(`${hint} ${UPDATE_COMMAND}`)}`);
188
+ return (0, output_1.wrapAfter)(`${palette.blue(info)} `, `ajs dms ${latestVersion} is available (you have ${currentVersion}) ` +
189
+ palette.cyan(`${hint} ${UPDATE_COMMAND}`), columns);
188
190
  }
189
191
  async function isNewer(currentVersion, latestVersion) {
190
192
  if (currentVersion === latestVersion)
@@ -198,7 +200,7 @@ async function isNewer(currentVersion, latestVersion) {
198
200
  }
199
201
  function startUpdateCheck(options) {
200
202
  try {
201
- const { currentVersion, argv = process.argv.slice(2), env = process.env, isTerminal = (0, output_1.isTerminalFeedback)(), now = Date.now, cacheFile = updateCheckCacheFile(), fetchLatestVersion = fetchLatestVersionFromRegistry, ui = (0, cli_1.getProcessUi)(), write = output_1.writeFeedback, } = options;
203
+ const { currentVersion, argv = process.argv.slice(2), env = process.env, isTerminal = (0, output_1.isTerminalFeedback)(), now = Date.now, cacheFile = updateCheckCacheFile(), fetchLatestVersion = fetchLatestVersionFromRegistry, ui = (0, cli_1.getProcessUi)(), write = output_1.writeFeedback, columns = (0, output_1.feedbackColumns)(), } = options;
202
204
  if (!isTerminal || !isUpdateCheckEnabled(argv, env))
203
205
  return undefined;
204
206
  const cached = readCache(cacheFile);
@@ -228,8 +230,10 @@ function startUpdateCheck(options) {
228
230
  const known = latestVersion;
229
231
  if (!known || !(await isNewer(currentVersion, known)))
230
232
  return;
231
- const line = formatNotice(currentVersion, known, ui);
232
- for (const text of placement.isFollowed ? [line, ""] : ["", line]) {
233
+ const lines = formatNotice(currentVersion, known, ui, columns);
234
+ for (const text of placement.isFollowed
235
+ ? [...lines, ""]
236
+ : ["", ...lines]) {
233
237
  write(text);
234
238
  }
235
239
  };
@@ -228,7 +228,10 @@ async function setupWorkspace(opts) {
228
228
  const { manifest, fromCache, fetchedAt } = resolved;
229
229
  let layers;
230
230
  if (mode === "dev") {
231
- (0, layers_1.assertLayerPathsServed)(manifest.modules, backendUrl, bootstrapSecret);
231
+ (0, layers_1.assertLayerPathsServed)(manifest.modules, backendUrl, {
232
+ bootstrapSecret,
233
+ cache: fromCache ? { fetchedAt } : undefined,
234
+ });
232
235
  if (fromCache) {
233
236
  (0, manifest_1.assertCachedLayerPathsExist)(manifest.modules, fetchedAt);
234
237
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms-frontend",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "description": "Frontend-agnostic loader for AntelopeJS DMS, shipping the Vue 3 renderer (Vite, Inertia, SSR)",
5
5
  "keywords": [
6
6
  "antelope",
@@ -73,7 +73,7 @@
73
73
  "unzipper": "^0.12.3"
74
74
  },
75
75
  "devDependencies": {
76
- "@antelopejs/core": "^1.13.0",
76
+ "@antelopejs/core": "^1.13.2",
77
77
  "@antelopejs/tooling-configs": ">=0.0.7 <1.0.0",
78
78
  "@iconify/utils": "^3.1.0",
79
79
  "@iconify/vue": "^5.0.1",
@@ -101,7 +101,7 @@
101
101
  "vue-i18n": "^11.2.7"
102
102
  },
103
103
  "peerDependencies": {
104
- "@antelopejs/core": ">=1.13.0 <2"
104
+ "@antelopejs/core": ">=1.13.2 <2"
105
105
  },
106
106
  "optionalDependencies": {
107
107
  "@oxc-parser/binding-darwin-arm64": "^0.95.0",