astro 4.2.2 → 4.2.3

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.
@@ -2401,7 +2401,7 @@ export interface ClientDirectiveConfig {
2401
2401
  export interface DevToolbarApp {
2402
2402
  id: string;
2403
2403
  name: string;
2404
- icon: Icon;
2404
+ icon?: Icon;
2405
2405
  init?(canvas: ShadowRoot, eventTarget: EventTarget): void | Promise<void>;
2406
2406
  beforeTogglingOff?(canvas: ShadowRoot): boolean | Promise<boolean>;
2407
2407
  }
@@ -1,5 +1,6 @@
1
- import { createLoggerFromFlags } from "../flags.js";
1
+ import { createLoggerFromFlags, flagsToAstroInlineConfig } from "../flags.js";
2
2
  import { getPackage } from "../install-package.js";
3
+ import { resolveConfig } from "../../core/config/config.js";
3
4
  async function db({ flags }) {
4
5
  const logger = createLoggerFromFlags(flags);
5
6
  const getPackageOpts = { skipAsk: flags.yes || flags.y, cwd: flags.root };
@@ -12,8 +13,9 @@ async function db({ flags }) {
12
13
  return;
13
14
  }
14
15
  const { cli } = dbPackage;
15
- const [command, ...args] = flags._.slice(3).map((v) => v.toString());
16
- await cli(command, args);
16
+ const inlineConfig = flagsToAstroInlineConfig(flags);
17
+ const { astroConfig } = await resolveConfig(inlineConfig, "build");
18
+ await cli({ flags, config: astroConfig });
17
19
  }
18
20
  export {
19
21
  db
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "4.2.2";
1
+ const ASTRO_VERSION = "4.2.3";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -23,7 +23,7 @@ async function dev(inlineConfig) {
23
23
  base: restart.container.settings.config.base
24
24
  })
25
25
  );
26
- const currentVersion = "4.2.2";
26
+ const currentVersion = "4.2.3";
27
27
  if (currentVersion.includes("-")) {
28
28
  logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
29
29
  }
@@ -7,7 +7,7 @@ export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
7
7
  * rather than specific to a single command, function, use, etc. The label will be
8
8
  * shown in the log message to the user, so it should be relevant.
9
9
  */
10
- export type LoggerLabel = 'add' | 'build' | 'check' | 'config' | 'content' | 'deprecated' | 'markdown' | 'router' | 'types' | 'vite' | 'watch' | 'middleware' | 'preferences' | 'redirects' | 'SKIP_FORMAT';
10
+ export type LoggerLabel = 'add' | 'build' | 'check' | 'config' | 'content' | 'deprecated' | 'markdown' | 'router' | 'types' | 'vite' | 'watch' | 'middleware' | 'preferences' | 'redirects' | 'toolbar' | 'SKIP_FORMAT';
11
11
  export interface LogOptions {
12
12
  dest: LogWritable<LogMessage>;
13
13
  level: LoggerLevel;
@@ -36,7 +36,7 @@ function serverStart({
36
36
  host,
37
37
  base
38
38
  }) {
39
- const version = "4.2.2";
39
+ const version = "4.2.3";
40
40
  const localPrefix = `${dim("\u2503")} Local `;
41
41
  const networkPrefix = `${dim("\u2503")} Network `;
42
42
  const emptyPrefix = " ".repeat(11);
@@ -258,7 +258,7 @@ function printHelp({
258
258
  message.push(
259
259
  linebreak(),
260
260
  ` ${bgGreen(black(` ${commandName} `))} ${green(
261
- `v${"4.2.2"}`
261
+ `v${"4.2.3"}`
262
262
  )} ${headline}`
263
263
  );
264
264
  }
@@ -14,7 +14,7 @@ const settingsRows = [
14
14
  }
15
15
  settings.updateSetting("disableAppNotification", evt.currentTarget.checked);
16
16
  const action = evt.currentTarget.checked ? "disabled" : "enabled";
17
- settings.log(`App notification badges ${action}`);
17
+ settings.logger.verboseLog(`App notification badges ${action}`);
18
18
  }
19
19
  }
20
20
  },
@@ -27,7 +27,7 @@ const settingsRows = [
27
27
  if (evt.currentTarget instanceof HTMLInputElement) {
28
28
  settings.updateSetting("verbose", evt.currentTarget.checked);
29
29
  const action = evt.currentTarget.checked ? "enabled" : "disabled";
30
- settings.log(`Verbose logging ${action}`);
30
+ settings.logger.verboseLog(`Verbose logging ${action}`);
31
31
  }
32
32
  }
33
33
  }
@@ -173,7 +173,7 @@ document.addEventListener("DOMContentLoaded", async () => {
173
173
  button.setAttribute("data-app-id", app.id);
174
174
  const iconContainer = document.createElement("div");
175
175
  const iconElement = document.createElement("template");
176
- iconElement.innerHTML = getAppIcon(app.icon);
176
+ iconElement.innerHTML = app.icon ? getAppIcon(app.icon) : "?";
177
177
  iconContainer.append(iconElement.content.cloneNode(true));
178
178
  const notification = document.createElement("div");
179
179
  notification.classList.add("notification");
@@ -9,5 +9,8 @@ export declare const defaultSettings: {
9
9
  export declare const settings: {
10
10
  readonly config: Settings;
11
11
  updateSetting: (key: keyof Settings, value: boolean) => void;
12
- log: (message: string) => void;
12
+ logger: {
13
+ log: (message: string) => void;
14
+ verboseLog: (message: string) => void;
15
+ };
13
16
  };
@@ -30,7 +30,14 @@ function getSettings() {
30
30
  return _settings;
31
31
  },
32
32
  updateSetting,
33
- log
33
+ logger: {
34
+ log,
35
+ verboseLog: (message) => {
36
+ if (_settings.verbose) {
37
+ log(message);
38
+ }
39
+ }
40
+ }
34
41
  };
35
42
  }
36
43
  export {
@@ -28,6 +28,7 @@ export declare class AstroDevToolbar extends HTMLElement {
28
28
  getAppTemplate(app: DevToolbarApp): string;
29
29
  getAppById(id: string): DevToolbarApp | undefined;
30
30
  getAppCanvasById(id: string): HTMLElement | null;
31
+ getAppButtonById(id: string): HTMLElement | null;
31
32
  toggleAppStatus(app: DevToolbarApp): Promise<void>;
32
33
  setAppStatus(app: DevToolbarApp, newStatus: boolean): Promise<boolean>;
33
34
  isHidden(): boolean;
@@ -109,6 +109,11 @@ class AstroDevToolbar extends HTMLElement {
109
109
  outline-offset: -3px;
110
110
  }
111
111
 
112
+ #dev-bar #bar-container .item[data-app-error]:hover, #dev-bar #bar-container .item[data-app-error]:focus-visible {
113
+ cursor: not-allowed;
114
+ background: #ff252520;
115
+ }
116
+
112
117
  #dev-bar .item:first-of-type {
113
118
  border-top-left-radius: 9999px;
114
119
  border-bottom-left-radius: 9999px;
@@ -149,6 +154,10 @@ class AstroDevToolbar extends HTMLElement {
149
154
  border-top: 5px solid #343841;
150
155
  }
151
156
 
157
+ #dev-bar .item[data-app-error] .icon {
158
+ opacity: 0.35;
159
+ }
160
+
152
161
  #dev-bar .item:hover .item-tooltip, #dev-bar .item:not(.active):focus-visible .item-tooltip {
153
162
  transition: opacity 0.2s ease-in-out 200ms;
154
163
  opacity: 1;
@@ -229,8 +238,7 @@ class AstroDevToolbar extends HTMLElement {
229
238
  this.devToolbarContainer = this.shadowRoot.querySelector("#dev-toolbar-root");
230
239
  this.attachEvents();
231
240
  this.apps.forEach(async (app) => {
232
- if (settings.config.verbose)
233
- console.log(`Creating app canvas for ${app.id}`);
241
+ settings.logger.verboseLog(`Creating app canvas for ${app.id}`);
234
242
  const appCanvas = document.createElement("astro-dev-toolbar-app-canvas");
235
243
  appCanvas.dataset.appId = app.id;
236
244
  this.shadowRoot?.append(appCanvas);
@@ -311,8 +319,7 @@ class AstroDevToolbar extends HTMLElement {
311
319
  const shadowRoot = this.getAppCanvasById(app.id).shadowRoot;
312
320
  app.status = "loading";
313
321
  try {
314
- if (settings.config.verbose)
315
- console.info(`Initializing app ${app.id}`);
322
+ settings.logger.verboseLog(`Initializing app ${app.id}`);
316
323
  await app.init?.(shadowRoot, app.eventTarget);
317
324
  app.status = "ready";
318
325
  if (import.meta.hot) {
@@ -322,11 +329,23 @@ class AstroDevToolbar extends HTMLElement {
322
329
  } catch (e) {
323
330
  console.error(`Failed to init app ${app.id}, error: ${e}`);
324
331
  app.status = "error";
332
+ if (import.meta.hot) {
333
+ import.meta.hot.send("astro:devtoolbar:error:init", {
334
+ app,
335
+ error: e instanceof Error ? e.stack : e
336
+ });
337
+ }
338
+ const appButton = this.getAppButtonById(app.id);
339
+ const appTooltip = appButton?.querySelector(".item-tooltip");
340
+ if (appButton && appTooltip) {
341
+ appButton.toggleAttribute("data-app-error", true);
342
+ appTooltip.innerText = `Error initializing ${app.name}`;
343
+ }
325
344
  }
326
345
  }
327
346
  getAppTemplate(app) {
328
347
  return `<button class="item" data-app-id="${app.id}">
329
- <div class="icon">${getAppIcon(app.icon)}<div class="notification"></div></div>
348
+ <div class="icon">${app.icon ? getAppIcon(app.icon) : "?"}<div class="notification"></div></div>
330
349
  <span class="item-tooltip">${app.name}</span>
331
350
  </button>`;
332
351
  }
@@ -338,6 +357,9 @@ class AstroDevToolbar extends HTMLElement {
338
357
  `astro-dev-toolbar-app-canvas[data-app-id="${id}"]`
339
358
  );
340
359
  }
360
+ getAppButtonById(id) {
361
+ return this.shadowRoot.querySelector(`[data-app-id="${id}"]`);
362
+ }
341
363
  async toggleAppStatus(app) {
342
364
  const activeApp = this.getActiveApp();
343
365
  if (activeApp) {
@@ -361,7 +383,7 @@ class AstroDevToolbar extends HTMLElement {
361
383
  return false;
362
384
  }
363
385
  app.active = newStatus ?? !app.active;
364
- const mainBarButton = this.shadowRoot.querySelector(`[data-app-id="${app.id}"]`);
386
+ const mainBarButton = this.getAppButtonById(app.id);
365
387
  const moreBarButton = this.getAppCanvasById("astro:more")?.shadowRoot?.querySelector(
366
388
  `[data-app-id="${app.id}"]`
367
389
  );
@@ -1,3 +1,3 @@
1
1
  import type * as vite from 'vite';
2
2
  import type { AstroPluginOptions } from '../@types/astro.js';
3
- export default function astroDevToolbar({ settings }: AstroPluginOptions): vite.Plugin;
3
+ export default function astroDevToolbar({ settings, logger }: AstroPluginOptions): vite.Plugin;
@@ -1,6 +1,6 @@
1
1
  const VIRTUAL_MODULE_ID = "astro:dev-toolbar";
2
2
  const resolvedVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
3
- function astroDevToolbar({ settings }) {
3
+ function astroDevToolbar({ settings, logger }) {
4
4
  return {
5
5
  name: "astro:dev-toolbar",
6
6
  config() {
@@ -16,12 +16,49 @@ function astroDevToolbar({ settings }) {
16
16
  return resolvedVirtualModuleId;
17
17
  }
18
18
  },
19
+ configureServer(server) {
20
+ server.ws.on("astro:devtoolbar:error:load", (args) => {
21
+ logger.error(
22
+ "toolbar",
23
+ `Failed to load dev toolbar app from ${args.entrypoint}: ${args.error}`
24
+ );
25
+ });
26
+ server.ws.on("astro:devtoolbar:error:init", (args) => {
27
+ logger.error(
28
+ "toolbar",
29
+ `Failed to initialize dev toolbar app ${args.app.name} (${args.app.id}):
30
+ ${args.error}`
31
+ );
32
+ });
33
+ },
19
34
  async load(id) {
20
35
  if (id === resolvedVirtualModuleId) {
21
36
  return `
22
37
  export const loadDevToolbarApps = async () => {
23
- return [${settings.devToolbarApps.map((plugin) => `(await import(${JSON.stringify(plugin)})).default`).join(",")}];
38
+ return (await Promise.all([${settings.devToolbarApps.map((plugin) => `safeLoadPlugin(${JSON.stringify(plugin)})`).join(",")}])).filter(app => app);
24
39
  };
40
+
41
+ async function safeLoadPlugin(entrypoint) {
42
+ try {
43
+ const app = (await import(/* @vite-ignore */ entrypoint)).default;
44
+
45
+ if (typeof app !== 'object' || !app.id || !app.name) {
46
+ throw new Error("Apps must default export an object with an id, and a name.");
47
+ }
48
+
49
+ return app;
50
+ } catch (err) {
51
+ console.error(\`Failed to load dev toolbar app from \${entrypoint}: \${err.message}\`);
52
+
53
+ if (import.meta.hot) {
54
+ import.meta.hot.send('astro:devtoolbar:error:load', { entrypoint: entrypoint, error: err.message })
55
+ }
56
+
57
+ return undefined;
58
+ }
59
+
60
+ return undefined;
61
+ }
25
62
  `;
26
63
  }
27
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "4.2.2",
3
+ "version": "4.2.3",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",