astro 4.6.4 → 4.7.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/dist/@types/astro.d.ts +48 -6
- package/dist/cli/add/index.js +1 -41
- package/dist/cli/install-package.d.ts +9 -0
- package/dist/cli/install-package.js +64 -1
- package/dist/core/build/static-build.js +4 -0
- package/dist/core/config/settings.js +3 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +1 -1
- package/dist/core/dev/dev.js +34 -2
- package/dist/core/dev/restart.js +5 -1
- package/dist/core/dev/update-check.d.ts +4 -0
- package/dist/core/dev/update-check.js +36 -0
- package/dist/core/logger/core.d.ts +1 -1
- package/dist/core/messages.d.ts +3 -0
- package/dist/core/messages.js +11 -2
- package/dist/integrations/index.d.ts +28 -0
- package/dist/integrations/index.js +40 -1
- package/dist/preferences/defaults.d.ts +9 -0
- package/dist/preferences/defaults.js +9 -0
- package/dist/preferences/index.d.ts +12 -4
- package/dist/preferences/index.js +11 -4
- package/dist/runtime/client/dev-toolbar/apps/astro.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/astro.js +3 -0
- package/dist/runtime/client/dev-toolbar/apps/audit/index.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/settings.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/xray.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/entrypoint.js +3 -2
- package/dist/runtime/client/dev-toolbar/helpers.d.ts +61 -0
- package/dist/runtime/client/dev-toolbar/helpers.js +87 -0
- package/dist/runtime/client/dev-toolbar/toolbar.d.ts +3 -2
- package/dist/runtime/client/dev-toolbar/toolbar.js +2 -1
- package/dist/toolbar/index.d.ts +2 -0
- package/dist/toolbar/index.js +6 -0
- package/dist/{vite-plugin-dev-toolbar → toolbar}/vite-plugin-dev-toolbar.js +33 -12
- package/dist/vite-plugin-astro-server/pipeline.js +1 -0
- package/package.json +3 -2
- package/tsconfigs/strictest.json +1 -3
- /package/dist/{vite-plugin-dev-toolbar → toolbar}/vite-plugin-dev-toolbar.d.ts +0 -0
package/dist/@types/astro.d.ts
CHANGED
|
@@ -14,7 +14,9 @@ import type { AstroTimer } from '../core/config/timer.js';
|
|
|
14
14
|
import type { TSConfig } from '../core/config/tsconfig.js';
|
|
15
15
|
import type { AstroCookies } from '../core/cookies/index.js';
|
|
16
16
|
import type { AstroIntegrationLogger, Logger, LoggerLevel } from '../core/logger/core.js';
|
|
17
|
+
import type { getToolbarServerCommunicationHelpers } from '../integrations/index.js';
|
|
17
18
|
import type { AstroPreferences } from '../preferences/index.js';
|
|
19
|
+
import type { ToolbarAppEventTarget, ToolbarServerHelpers } from '../runtime/client/dev-toolbar/helpers.js';
|
|
18
20
|
import type { AstroDevToolbar, DevToolbarCanvas } from '../runtime/client/dev-toolbar/toolbar.js';
|
|
19
21
|
import type { Icon } from '../runtime/client/dev-toolbar/ui-library/icons.js';
|
|
20
22
|
import type { DevToolbarBadge, DevToolbarButton, DevToolbarCard, DevToolbarHighlight, DevToolbarIcon, DevToolbarSelect, DevToolbarToggle, DevToolbarTooltip, DevToolbarWindow } from '../runtime/client/dev-toolbar/ui-library/index.js';
|
|
@@ -22,7 +24,7 @@ import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/s
|
|
|
22
24
|
import type { TransitionBeforePreparationEvent, TransitionBeforeSwapEvent } from '../transitions/events.js';
|
|
23
25
|
import type { DeepPartial, OmitIndexSignature, Simplify } from '../type-utils.js';
|
|
24
26
|
import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
|
|
25
|
-
export {
|
|
27
|
+
export type { AstroIntegrationLogger, ToolbarServerHelpers };
|
|
26
28
|
export type { MarkdownHeading, RehypePlugins, RemarkPlugins, ShikiConfig, } from '@astrojs/markdown-remark';
|
|
27
29
|
export type { ExternalImageService, ImageService, LocalImageService, } from '../assets/services/service.js';
|
|
28
30
|
export type { GetImageResult, ImageInputFormat, ImageMetadata, ImageOutputFormat, ImageQuality, ImageQualityPreset, ImageTransform, UnresolvedImageTransform, } from '../assets/types.js';
|
|
@@ -1939,7 +1941,7 @@ export interface AstroSettings {
|
|
|
1939
1941
|
* Map of directive name (e.g. `load`) to the directive script code
|
|
1940
1942
|
*/
|
|
1941
1943
|
clientDirectives: Map<string, string>;
|
|
1942
|
-
devToolbarApps: string[];
|
|
1944
|
+
devToolbarApps: (DevToolbarAppEntry | string)[];
|
|
1943
1945
|
middlewares: {
|
|
1944
1946
|
pre: string[];
|
|
1945
1947
|
post: string[];
|
|
@@ -1948,6 +1950,14 @@ export interface AstroSettings {
|
|
|
1948
1950
|
tsConfigPath: string | undefined;
|
|
1949
1951
|
watchFiles: string[];
|
|
1950
1952
|
timer: AstroTimer;
|
|
1953
|
+
/**
|
|
1954
|
+
* Latest version of Astro, will be undefined if:
|
|
1955
|
+
* - unable to check
|
|
1956
|
+
* - the user has disabled the check
|
|
1957
|
+
* - the check has not completed yet
|
|
1958
|
+
* - the user is on the latest version already
|
|
1959
|
+
*/
|
|
1960
|
+
latestAstroVersion: string | undefined;
|
|
1951
1961
|
}
|
|
1952
1962
|
export type AsyncRendererComponentFn<U> = (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<U>;
|
|
1953
1963
|
/** Generic interface for a component (Astro, Svelte, React, etc.) */
|
|
@@ -2470,7 +2480,7 @@ export interface AstroIntegration {
|
|
|
2470
2480
|
* TODO: Fully remove in Astro 5.0
|
|
2471
2481
|
*/
|
|
2472
2482
|
addDevOverlayPlugin: (entrypoint: string) => void;
|
|
2473
|
-
addDevToolbarApp: (entrypoint: string) => void;
|
|
2483
|
+
addDevToolbarApp: (entrypoint: DevToolbarAppEntry | string) => void;
|
|
2474
2484
|
addMiddleware: (mid: AstroIntegrationMiddleware) => void;
|
|
2475
2485
|
logger: AstroIntegrationLogger;
|
|
2476
2486
|
}) => void | Promise<void>;
|
|
@@ -2482,6 +2492,7 @@ export interface AstroIntegration {
|
|
|
2482
2492
|
'astro:server:setup'?: (options: {
|
|
2483
2493
|
server: vite.ViteDevServer;
|
|
2484
2494
|
logger: AstroIntegrationLogger;
|
|
2495
|
+
toolbar: ReturnType<typeof getToolbarServerCommunicationHelpers>;
|
|
2485
2496
|
}) => void | Promise<void>;
|
|
2486
2497
|
'astro:server:start'?: (options: {
|
|
2487
2498
|
address: AddressInfo;
|
|
@@ -2694,18 +2705,49 @@ export interface ClientDirectiveConfig {
|
|
|
2694
2705
|
name: string;
|
|
2695
2706
|
entrypoint: string;
|
|
2696
2707
|
}
|
|
2697
|
-
|
|
2708
|
+
type DevToolbarAppMeta = {
|
|
2698
2709
|
id: string;
|
|
2699
2710
|
name: string;
|
|
2700
2711
|
icon?: Icon;
|
|
2701
|
-
|
|
2712
|
+
};
|
|
2713
|
+
export type DevToolbarAppEntry = DevToolbarAppMeta & {
|
|
2714
|
+
entrypoint: string;
|
|
2715
|
+
};
|
|
2716
|
+
export type DevToolbarApp = {
|
|
2717
|
+
/**
|
|
2718
|
+
* @deprecated The `id`, `name`, and `icon` properties should now be defined when using `addDevToolbarApp`.
|
|
2719
|
+
*
|
|
2720
|
+
* Ex: `addDevToolbarApp({ id: 'my-app', name: 'My App', icon: '🚀', entrypoint: '/path/to/app' })`
|
|
2721
|
+
*
|
|
2722
|
+
* In the future, putting these properties directly on the app object will be removed.
|
|
2723
|
+
*/
|
|
2724
|
+
id?: string;
|
|
2725
|
+
/**
|
|
2726
|
+
* @deprecated The `id`, `name`, and `icon` properties should now be defined when using `addDevToolbarApp`.
|
|
2727
|
+
*
|
|
2728
|
+
* Ex: `addDevToolbarApp({ id: 'my-app', name: 'My App', icon: '🚀', entrypoint: '/path/to/app' })`
|
|
2729
|
+
*
|
|
2730
|
+
* In the future, putting these properties directly on the app object will be removed.
|
|
2731
|
+
*/
|
|
2732
|
+
name?: string;
|
|
2733
|
+
/**
|
|
2734
|
+
* @deprecated The `id`, `name`, and `icon` properties should now be defined when using `addDevToolbarApp`.
|
|
2735
|
+
*
|
|
2736
|
+
* Ex: `addDevToolbarApp({ id: 'my-app', name: 'My App', icon: '🚀', entrypoint: '/path/to/app' })`
|
|
2737
|
+
*
|
|
2738
|
+
* In the future, putting these properties directly on the app object will be removed.
|
|
2739
|
+
*/
|
|
2740
|
+
icon?: Icon;
|
|
2741
|
+
init?(canvas: ShadowRoot, app: ToolbarAppEventTarget, server: ToolbarServerHelpers): void | Promise<void>;
|
|
2702
2742
|
beforeTogglingOff?(canvas: ShadowRoot): boolean | Promise<boolean>;
|
|
2703
|
-
}
|
|
2743
|
+
};
|
|
2744
|
+
export type ResolvedDevToolbarApp = DevToolbarAppMeta & Omit<DevToolbarApp, 'id' | 'name' | 'icon'>;
|
|
2704
2745
|
export type DevOverlayPlugin = DevToolbarApp;
|
|
2705
2746
|
export type DevToolbarMetadata = Window & typeof globalThis & {
|
|
2706
2747
|
__astro_dev_toolbar__: {
|
|
2707
2748
|
root: string;
|
|
2708
2749
|
version: string;
|
|
2750
|
+
latestAstroVersion: AstroSettings['latestAstroVersion'];
|
|
2709
2751
|
debugInfo: string;
|
|
2710
2752
|
};
|
|
2711
2753
|
};
|
package/dist/cli/add/index.js
CHANGED
|
@@ -27,6 +27,7 @@ import { apply as applyPolyfill } from "../../core/polyfill.js";
|
|
|
27
27
|
import { ensureProcessNodeEnv, parseNpmName } from "../../core/util.js";
|
|
28
28
|
import { eventCliSession, telemetry } from "../../events/index.js";
|
|
29
29
|
import { createLoggerFromFlags, flagsToAstroInlineConfig } from "../flags.js";
|
|
30
|
+
import { fetchPackageJson, fetchPackageVersions } from "../install-package.js";
|
|
30
31
|
import { generate, parse, t, visit } from "./babel.js";
|
|
31
32
|
import { ensureImport } from "./imports.js";
|
|
32
33
|
import { wrapDefaultExport } from "./wrapper.js";
|
|
@@ -77,22 +78,6 @@ const OFFICIAL_ADAPTER_TO_IMPORT_MAP = {
|
|
|
77
78
|
cloudflare: "@astrojs/cloudflare",
|
|
78
79
|
node: "@astrojs/node"
|
|
79
80
|
};
|
|
80
|
-
let _registry;
|
|
81
|
-
async function getRegistry() {
|
|
82
|
-
if (_registry)
|
|
83
|
-
return _registry;
|
|
84
|
-
const fallback = "https://registry.npmjs.org";
|
|
85
|
-
const packageManager = (await preferredPM(process.cwd()))?.name || "npm";
|
|
86
|
-
try {
|
|
87
|
-
const { stdout } = await execa(packageManager, ["config", "get", "registry"]);
|
|
88
|
-
_registry = stdout?.trim()?.replace(/\/$/, "") || fallback;
|
|
89
|
-
if (!new URL(_registry).host)
|
|
90
|
-
_registry = fallback;
|
|
91
|
-
} catch (e) {
|
|
92
|
-
_registry = fallback;
|
|
93
|
-
}
|
|
94
|
-
return _registry;
|
|
95
|
-
}
|
|
96
81
|
async function add(names, { flags }) {
|
|
97
82
|
ensureProcessNodeEnv("production");
|
|
98
83
|
applyPolyfill();
|
|
@@ -683,31 +668,6 @@ ${message}`
|
|
|
683
668
|
}
|
|
684
669
|
}
|
|
685
670
|
}
|
|
686
|
-
async function fetchPackageJson(scope, name, tag) {
|
|
687
|
-
const packageName = `${scope ? `${scope}/` : ""}${name}`;
|
|
688
|
-
const registry = await getRegistry();
|
|
689
|
-
const res = await fetch(`${registry}/${packageName}/${tag}`);
|
|
690
|
-
if (res.status >= 200 && res.status < 300) {
|
|
691
|
-
return await res.json();
|
|
692
|
-
} else if (res.status === 404) {
|
|
693
|
-
return new Error();
|
|
694
|
-
} else {
|
|
695
|
-
return new Error(`Failed to fetch ${registry}/${packageName}/${tag} - GET ${res.status}`);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
async function fetchPackageVersions(packageName) {
|
|
699
|
-
const registry = await getRegistry();
|
|
700
|
-
const res = await fetch(`${registry}/${packageName}`, {
|
|
701
|
-
headers: { accept: "application/vnd.npm.install-v1+json" }
|
|
702
|
-
});
|
|
703
|
-
if (res.status >= 200 && res.status < 300) {
|
|
704
|
-
return await res.json().then((data) => Object.keys(data.versions));
|
|
705
|
-
} else if (res.status === 404) {
|
|
706
|
-
return new Error();
|
|
707
|
-
} else {
|
|
708
|
-
return new Error(`Failed to fetch ${registry}/${packageName} - GET ${res.status}`);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
671
|
async function validateIntegrations(integrations) {
|
|
712
672
|
const spinner = ora("Resolving packages...").start();
|
|
713
673
|
try {
|
|
@@ -5,4 +5,13 @@ type GetPackageOptions = {
|
|
|
5
5
|
cwd?: string;
|
|
6
6
|
};
|
|
7
7
|
export declare function getPackage<T>(packageName: string, logger: Logger, options: GetPackageOptions, otherDeps?: string[]): Promise<T | undefined>;
|
|
8
|
+
/**
|
|
9
|
+
* Get the command to execute and download a package (e.g. `npx`, `yarn dlx`, `pnpx`, etc.)
|
|
10
|
+
* @param packageManager - Optional package manager to use. If not provided, Astro will attempt to detect the preferred package manager.
|
|
11
|
+
* @returns The command to execute and download a package
|
|
12
|
+
*/
|
|
13
|
+
export declare function getExecCommand(packageManager?: string): Promise<string>;
|
|
14
|
+
export declare function fetchPackageJson(scope: string | undefined, name: string, tag: string): Promise<Record<string, any> | Error>;
|
|
15
|
+
export declare function fetchPackageVersions(packageName: string): Promise<string[] | Error>;
|
|
16
|
+
export declare function getRegistry(): Promise<string>;
|
|
8
17
|
export {};
|
|
@@ -5,6 +5,7 @@ import ci from "ci-info";
|
|
|
5
5
|
import { execa } from "execa";
|
|
6
6
|
import { bold, cyan, dim, magenta } from "kleur/colors";
|
|
7
7
|
import ora from "ora";
|
|
8
|
+
import preferredPM from "preferred-pm";
|
|
8
9
|
import prompts from "prompts";
|
|
9
10
|
import resolvePackage from "resolve";
|
|
10
11
|
import whichPm from "which-pm";
|
|
@@ -76,6 +77,23 @@ function getInstallCommand(packages, packageManager) {
|
|
|
76
77
|
return null;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
80
|
+
async function getExecCommand(packageManager) {
|
|
81
|
+
if (!packageManager) {
|
|
82
|
+
packageManager = (await preferredPM(process.cwd()))?.name ?? "npm";
|
|
83
|
+
}
|
|
84
|
+
switch (packageManager) {
|
|
85
|
+
case "npm":
|
|
86
|
+
return "npx";
|
|
87
|
+
case "yarn":
|
|
88
|
+
return "yarn dlx";
|
|
89
|
+
case "pnpm":
|
|
90
|
+
return "pnpx";
|
|
91
|
+
case "bun":
|
|
92
|
+
return "bunx";
|
|
93
|
+
default:
|
|
94
|
+
return "npx";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
79
97
|
async function installPackage(packageNames, options, logger) {
|
|
80
98
|
const cwd = options.cwd ?? process.cwd();
|
|
81
99
|
const packageManager = (await whichPm(cwd))?.name ?? "npm";
|
|
@@ -133,6 +151,51 @@ ${message}`
|
|
|
133
151
|
return false;
|
|
134
152
|
}
|
|
135
153
|
}
|
|
154
|
+
async function fetchPackageJson(scope, name, tag) {
|
|
155
|
+
const packageName = `${scope ? `${scope}/` : ""}${name}`;
|
|
156
|
+
const registry = await getRegistry();
|
|
157
|
+
const res = await fetch(`${registry}/${packageName}/${tag}`);
|
|
158
|
+
if (res.status >= 200 && res.status < 300) {
|
|
159
|
+
return await res.json();
|
|
160
|
+
} else if (res.status === 404) {
|
|
161
|
+
return new Error();
|
|
162
|
+
} else {
|
|
163
|
+
return new Error(`Failed to fetch ${registry}/${packageName}/${tag} - GET ${res.status}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function fetchPackageVersions(packageName) {
|
|
167
|
+
const registry = await getRegistry();
|
|
168
|
+
const res = await fetch(`${registry}/${packageName}`, {
|
|
169
|
+
headers: { accept: "application/vnd.npm.install-v1+json" }
|
|
170
|
+
});
|
|
171
|
+
if (res.status >= 200 && res.status < 300) {
|
|
172
|
+
return await res.json().then((data) => Object.keys(data.versions));
|
|
173
|
+
} else if (res.status === 404) {
|
|
174
|
+
return new Error();
|
|
175
|
+
} else {
|
|
176
|
+
return new Error(`Failed to fetch ${registry}/${packageName} - GET ${res.status}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
let _registry;
|
|
180
|
+
async function getRegistry() {
|
|
181
|
+
if (_registry)
|
|
182
|
+
return _registry;
|
|
183
|
+
const fallback = "https://registry.npmjs.org";
|
|
184
|
+
const packageManager = (await preferredPM(process.cwd()))?.name || "npm";
|
|
185
|
+
try {
|
|
186
|
+
const { stdout } = await execa(packageManager, ["config", "get", "registry"]);
|
|
187
|
+
_registry = stdout?.trim()?.replace(/\/$/, "") || fallback;
|
|
188
|
+
if (!new URL(_registry).host)
|
|
189
|
+
_registry = fallback;
|
|
190
|
+
} catch (e) {
|
|
191
|
+
_registry = fallback;
|
|
192
|
+
}
|
|
193
|
+
return _registry;
|
|
194
|
+
}
|
|
136
195
|
export {
|
|
137
|
-
|
|
196
|
+
fetchPackageJson,
|
|
197
|
+
fetchPackageVersions,
|
|
198
|
+
getExecCommand,
|
|
199
|
+
getPackage,
|
|
200
|
+
getRegistry
|
|
138
201
|
};
|
|
@@ -334,6 +334,10 @@ async function cleanServerOutput(opts, ssrOutputChunkNames, internals) {
|
|
|
334
334
|
removeEmptyDirs(out);
|
|
335
335
|
}
|
|
336
336
|
if (out.toString() !== opts.settings.config.outDir.toString()) {
|
|
337
|
+
const fileNames = await fs.promises.readdir(out);
|
|
338
|
+
await Promise.all(
|
|
339
|
+
fileNames.filter((fileName) => fileName.endsWith(".d.ts")).map((fileName) => fs.promises.rm(new URL(fileName, out)))
|
|
340
|
+
);
|
|
337
341
|
await copyFiles(out, opts.settings.config.outDir, true);
|
|
338
342
|
await fs.promises.rm(out, { recursive: true });
|
|
339
343
|
return;
|
|
@@ -92,7 +92,9 @@ function createBaseSettings(config) {
|
|
|
92
92
|
middlewares: { pre: [], post: [] },
|
|
93
93
|
watchFiles: [],
|
|
94
94
|
devToolbarApps: [],
|
|
95
|
-
timer: new AstroTimer()
|
|
95
|
+
timer: new AstroTimer(),
|
|
96
|
+
latestAstroVersion: void 0
|
|
97
|
+
// Will be set later if applicable when the dev server starts
|
|
96
98
|
};
|
|
97
99
|
}
|
|
98
100
|
async function createSettings(config, cwd) {
|
package/dist/core/constants.js
CHANGED
package/dist/core/create-vite.js
CHANGED
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
} from "../content/index.js";
|
|
13
13
|
import astroInternationalization from "../i18n/vite-plugin-i18n.js";
|
|
14
14
|
import astroPrefetch from "../prefetch/vite-plugin-prefetch.js";
|
|
15
|
+
import astroDevToolbar from "../toolbar/vite-plugin-dev-toolbar.js";
|
|
15
16
|
import astroTransitions from "../transitions/vite-plugin-transitions.js";
|
|
16
17
|
import astroPostprocessVitePlugin from "../vite-plugin-astro-postprocess/index.js";
|
|
17
18
|
import { vitePluginAstroServer } from "../vite-plugin-astro-server/index.js";
|
|
18
19
|
import astroVitePlugin from "../vite-plugin-astro/index.js";
|
|
19
20
|
import configAliasVitePlugin from "../vite-plugin-config-alias/index.js";
|
|
20
|
-
import astroDevToolbar from "../vite-plugin-dev-toolbar/vite-plugin-dev-toolbar.js";
|
|
21
21
|
import envVitePlugin from "../vite-plugin-env/index.js";
|
|
22
22
|
import vitePluginFileURL from "../vite-plugin-fileurl/index.js";
|
|
23
23
|
import astroHeadPlugin from "../vite-plugin-head/index.js";
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -1,18 +1,51 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { green } from "kleur/colors";
|
|
3
3
|
import { performance } from "perf_hooks";
|
|
4
|
+
import { gt, major, minor, patch } from "semver";
|
|
4
5
|
import { attachContentServerListeners } from "../../content/index.js";
|
|
5
6
|
import { telemetry } from "../../events/index.js";
|
|
6
7
|
import * as msg from "../messages.js";
|
|
7
8
|
import { ensureProcessNodeEnv } from "../util.js";
|
|
8
9
|
import { startContainer } from "./container.js";
|
|
9
10
|
import { createContainerWithAutomaticRestart } from "./restart.js";
|
|
11
|
+
import {
|
|
12
|
+
MAX_PATCH_DISTANCE,
|
|
13
|
+
fetchLatestAstroVersion,
|
|
14
|
+
shouldCheckForUpdates
|
|
15
|
+
} from "./update-check.js";
|
|
10
16
|
async function dev(inlineConfig) {
|
|
11
17
|
ensureProcessNodeEnv("development");
|
|
12
18
|
const devStart = performance.now();
|
|
13
19
|
await telemetry.record([]);
|
|
14
20
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
15
21
|
const logger = restart.container.logger;
|
|
22
|
+
const currentVersion = "4.7.0";
|
|
23
|
+
const isPrerelease = currentVersion.includes("-");
|
|
24
|
+
if (!isPrerelease) {
|
|
25
|
+
try {
|
|
26
|
+
shouldCheckForUpdates(restart.container.settings.preferences).then(async (shouldCheck) => {
|
|
27
|
+
if (shouldCheck) {
|
|
28
|
+
const version = await fetchLatestAstroVersion(restart.container.settings.preferences);
|
|
29
|
+
if (gt(version, currentVersion)) {
|
|
30
|
+
restart.container.settings.latestAstroVersion = version;
|
|
31
|
+
const sameMajor = major(version) === major(currentVersion);
|
|
32
|
+
const sameMinor = minor(version) === minor(currentVersion);
|
|
33
|
+
const patchDistance = patch(version) - patch(currentVersion);
|
|
34
|
+
if (sameMajor && sameMinor && patchDistance < MAX_PATCH_DISTANCE) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
logger.warn(
|
|
38
|
+
"SKIP_FORMAT",
|
|
39
|
+
msg.newVersionAvailable({
|
|
40
|
+
latestVersion: version
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
} catch (e) {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
16
49
|
const devServerAddressInfo = await startContainer(restart.container);
|
|
17
50
|
logger.info(
|
|
18
51
|
"SKIP_FORMAT",
|
|
@@ -23,8 +56,7 @@ async function dev(inlineConfig) {
|
|
|
23
56
|
base: restart.container.settings.config.base
|
|
24
57
|
})
|
|
25
58
|
);
|
|
26
|
-
|
|
27
|
-
if (currentVersion.includes("-")) {
|
|
59
|
+
if (isPrerelease) {
|
|
28
60
|
logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
|
|
29
61
|
}
|
|
30
62
|
if (restart.container.viteServer.config.server?.fs?.strict === false) {
|
package/dist/core/dev/restart.js
CHANGED
|
@@ -29,7 +29,11 @@ function shouldRestartContainer({ settings, inlineConfig, restartInFlight }, cha
|
|
|
29
29
|
shouldRestart = vite.normalizePath(inlineConfig.configFile) === vite.normalizePath(changedFile);
|
|
30
30
|
} else {
|
|
31
31
|
const normalizedChangedFile = vite.normalizePath(changedFile);
|
|
32
|
-
shouldRestart = configRE.test(normalizedChangedFile)
|
|
32
|
+
shouldRestart = configRE.test(normalizedChangedFile);
|
|
33
|
+
if (preferencesRE.test(normalizedChangedFile)) {
|
|
34
|
+
shouldRestart = settings.preferences.ignoreNextPreferenceReload ? false : true;
|
|
35
|
+
settings.preferences.ignoreNextPreferenceReload = false;
|
|
36
|
+
}
|
|
33
37
|
}
|
|
34
38
|
if (!shouldRestart && settings.watchFiles.length > 0) {
|
|
35
39
|
shouldRestart = settings.watchFiles.some(
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AstroPreferences } from '../../preferences/index.js';
|
|
2
|
+
export declare const MAX_PATCH_DISTANCE = 5;
|
|
3
|
+
export declare function fetchLatestAstroVersion(preferences: AstroPreferences | undefined): Promise<string>;
|
|
4
|
+
export declare function shouldCheckForUpdates(preferences: AstroPreferences): Promise<boolean>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import ci from "ci-info";
|
|
2
|
+
import { fetchPackageJson } from "../../cli/install-package.js";
|
|
3
|
+
const MAX_PATCH_DISTANCE = 5;
|
|
4
|
+
const CHECK_MS_INTERVAL = 10368e5;
|
|
5
|
+
let _latestVersion = void 0;
|
|
6
|
+
async function fetchLatestAstroVersion(preferences) {
|
|
7
|
+
if (_latestVersion) {
|
|
8
|
+
return _latestVersion;
|
|
9
|
+
}
|
|
10
|
+
const packageJson = await fetchPackageJson(void 0, "astro", "latest");
|
|
11
|
+
if (packageJson instanceof Error) {
|
|
12
|
+
throw packageJson;
|
|
13
|
+
}
|
|
14
|
+
const version = packageJson?.version;
|
|
15
|
+
if (!version) {
|
|
16
|
+
throw new Error("Failed to fetch latest Astro version");
|
|
17
|
+
}
|
|
18
|
+
if (preferences) {
|
|
19
|
+
await preferences.set("_variables.lastUpdateCheck", Date.now(), { reloadServer: false });
|
|
20
|
+
}
|
|
21
|
+
_latestVersion = version;
|
|
22
|
+
return version;
|
|
23
|
+
}
|
|
24
|
+
async function shouldCheckForUpdates(preferences) {
|
|
25
|
+
if (ci.isCI) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const timeSinceLastCheck = Date.now() - await preferences.get("_variables.lastUpdateCheck");
|
|
29
|
+
const hasCheckUpdatesEnabled = await preferences.get("checkUpdates.enabled");
|
|
30
|
+
return timeSinceLastCheck > CHECK_MS_INTERVAL && process.env.ASTRO_DISABLE_UPDATE_CHECK !== "true" && hasCheckUpdatesEnabled;
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
MAX_PATCH_DISTANCE,
|
|
34
|
+
fetchLatestAstroVersion,
|
|
35
|
+
shouldCheckForUpdates
|
|
36
|
+
};
|
|
@@ -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' | 'toolbar' | 'assets' | 'SKIP_FORMAT';
|
|
10
|
+
export type LoggerLabel = 'add' | 'build' | 'check' | 'config' | 'content' | 'deprecated' | 'markdown' | 'router' | 'types' | 'vite' | 'watch' | 'middleware' | 'preferences' | 'redirects' | 'toolbar' | 'assets' | 'update' | 'SKIP_FORMAT';
|
|
11
11
|
export interface LogOptions {
|
|
12
12
|
dest: LogWritable<LogMessage>;
|
|
13
13
|
level: LoggerLevel;
|
package/dist/core/messages.d.ts
CHANGED
|
@@ -23,6 +23,9 @@ export declare function serverShortcuts({ key, label }: {
|
|
|
23
23
|
key: string;
|
|
24
24
|
label: string;
|
|
25
25
|
}): string;
|
|
26
|
+
export declare function newVersionAvailable({ latestVersion }: {
|
|
27
|
+
latestVersion: string;
|
|
28
|
+
}): string;
|
|
26
29
|
export declare function telemetryNotice(): string;
|
|
27
30
|
export declare function telemetryEnabled(): string;
|
|
28
31
|
export declare function preferenceEnabled(name: string): string;
|
package/dist/core/messages.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
underline,
|
|
15
15
|
yellow
|
|
16
16
|
} from "kleur/colors";
|
|
17
|
+
import { getExecCommand } from "../cli/install-package.js";
|
|
17
18
|
import { getDocsForError, renderErrorMarkdown } from "./errors/dev/utils.js";
|
|
18
19
|
import {
|
|
19
20
|
AstroError,
|
|
@@ -36,7 +37,7 @@ function serverStart({
|
|
|
36
37
|
host,
|
|
37
38
|
base
|
|
38
39
|
}) {
|
|
39
|
-
const version = "4.
|
|
40
|
+
const version = "4.7.0";
|
|
40
41
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
41
42
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
42
43
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -69,6 +70,13 @@ function serverStart({
|
|
|
69
70
|
function serverShortcuts({ key, label }) {
|
|
70
71
|
return [dim(" Press"), key, dim("to"), label].join(" ");
|
|
71
72
|
}
|
|
73
|
+
function newVersionAvailable({ latestVersion }) {
|
|
74
|
+
const badge = bgYellow(black(` update `));
|
|
75
|
+
const headline = yellow(`\u25B6 New version of Astro available: ${latestVersion}`);
|
|
76
|
+
const execCommand = getExecCommand();
|
|
77
|
+
const details = ` Run ${cyan(`${execCommand} @astrojs/upgrade`)} to update`;
|
|
78
|
+
return ["", `${badge} ${headline}`, details, ""].join("\n");
|
|
79
|
+
}
|
|
72
80
|
function telemetryNotice() {
|
|
73
81
|
const headline = blue(`\u25B6 Astro collects anonymous usage data.`);
|
|
74
82
|
const why = " This information helps us improve Astro.";
|
|
@@ -261,7 +269,7 @@ function printHelp({
|
|
|
261
269
|
message.push(
|
|
262
270
|
linebreak(),
|
|
263
271
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
264
|
-
`v${"4.
|
|
272
|
+
`v${"4.7.0"}`
|
|
265
273
|
)} ${headline}`
|
|
266
274
|
);
|
|
267
275
|
}
|
|
@@ -291,6 +299,7 @@ export {
|
|
|
291
299
|
formatErrorMessage,
|
|
292
300
|
fsStrictWarning,
|
|
293
301
|
getNetworkLogging,
|
|
302
|
+
newVersionAvailable,
|
|
294
303
|
preferenceDefault,
|
|
295
304
|
preferenceDefaultIntro,
|
|
296
305
|
preferenceDisabled,
|
|
@@ -5,6 +5,34 @@ import type { AstroAdapter, AstroConfig, AstroSettings, RouteData } from '../@ty
|
|
|
5
5
|
import type { SerializedSSRManifest } from '../core/app/types.js';
|
|
6
6
|
import type { PageBuildData } from '../core/build/types.js';
|
|
7
7
|
import type { Logger } from '../core/logger/core.js';
|
|
8
|
+
export declare function getToolbarServerCommunicationHelpers(server: ViteDevServer): {
|
|
9
|
+
/**
|
|
10
|
+
* Send a message to the dev toolbar that an app can listen for. The payload can be any serializable data.
|
|
11
|
+
* @param event - The event name
|
|
12
|
+
* @param payload - The payload to send
|
|
13
|
+
*/
|
|
14
|
+
send: <T>(event: string, payload: T) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Receive a message from a dev toolbar app.
|
|
17
|
+
* @param event
|
|
18
|
+
* @param callback
|
|
19
|
+
*/
|
|
20
|
+
on: <T_1>(event: string, callback: (data: T_1) => void) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Fired when an app is initialized.
|
|
23
|
+
* @param appId - The id of the app that was initialized
|
|
24
|
+
* @param callback - The callback to run when the app is initialized
|
|
25
|
+
*/
|
|
26
|
+
onAppInitialized: (appId: string, callback: (data: Record<string, never>) => void) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Fired when an app is toggled on or off.
|
|
29
|
+
* @param appId - The id of the app that was toggled
|
|
30
|
+
* @param callback - The callback to run when the app is toggled
|
|
31
|
+
*/
|
|
32
|
+
onAppToggled: (appId: string, callback: (data: {
|
|
33
|
+
state: boolean;
|
|
34
|
+
}) => void) => void;
|
|
35
|
+
};
|
|
8
36
|
export declare function runHookConfigSetup({ settings, command, logger, isRestart, }: {
|
|
9
37
|
settings: AstroSettings;
|
|
10
38
|
command: 'dev' | 'build' | 'preview';
|
|
@@ -33,6 +33,43 @@ function getLogger(integration, logger) {
|
|
|
33
33
|
Loggers.set(integration, integrationLogger);
|
|
34
34
|
return integrationLogger;
|
|
35
35
|
}
|
|
36
|
+
const serverEventPrefix = "astro-dev-toolbar";
|
|
37
|
+
function getToolbarServerCommunicationHelpers(server) {
|
|
38
|
+
return {
|
|
39
|
+
/**
|
|
40
|
+
* Send a message to the dev toolbar that an app can listen for. The payload can be any serializable data.
|
|
41
|
+
* @param event - The event name
|
|
42
|
+
* @param payload - The payload to send
|
|
43
|
+
*/
|
|
44
|
+
send: (event, payload) => {
|
|
45
|
+
server.hot.send(event, payload);
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Receive a message from a dev toolbar app.
|
|
49
|
+
* @param event
|
|
50
|
+
* @param callback
|
|
51
|
+
*/
|
|
52
|
+
on: (event, callback) => {
|
|
53
|
+
server.hot.on(event, callback);
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* Fired when an app is initialized.
|
|
57
|
+
* @param appId - The id of the app that was initialized
|
|
58
|
+
* @param callback - The callback to run when the app is initialized
|
|
59
|
+
*/
|
|
60
|
+
onAppInitialized: (appId, callback) => {
|
|
61
|
+
server.hot.on(`${serverEventPrefix}:${appId}:initialized`, callback);
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Fired when an app is toggled on or off.
|
|
65
|
+
* @param appId - The id of the app that was toggled
|
|
66
|
+
* @param callback - The callback to run when the app is toggled
|
|
67
|
+
*/
|
|
68
|
+
onAppToggled: (appId, callback) => {
|
|
69
|
+
server.hot.on(`${serverEventPrefix}:${appId}:toggled`, callback);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
36
73
|
async function runHookConfigSetup({
|
|
37
74
|
settings,
|
|
38
75
|
command,
|
|
@@ -219,7 +256,8 @@ async function runHookServerSetup({
|
|
|
219
256
|
hookName: "astro:server:setup",
|
|
220
257
|
hookResult: integration.hooks["astro:server:setup"]({
|
|
221
258
|
server,
|
|
222
|
-
logger: getLogger(integration, logger)
|
|
259
|
+
logger: getLogger(integration, logger),
|
|
260
|
+
toolbar: getToolbarServerCommunicationHelpers(server)
|
|
223
261
|
}),
|
|
224
262
|
logger
|
|
225
263
|
});
|
|
@@ -384,6 +422,7 @@ function isFunctionPerRouteEnabled(adapter) {
|
|
|
384
422
|
}
|
|
385
423
|
}
|
|
386
424
|
export {
|
|
425
|
+
getToolbarServerCommunicationHelpers,
|
|
387
426
|
isFunctionPerRouteEnabled,
|
|
388
427
|
runHookBuildDone,
|
|
389
428
|
runHookBuildGenerated,
|
|
@@ -3,5 +3,14 @@ export declare const DEFAULT_PREFERENCES: {
|
|
|
3
3
|
/** Specifies whether the user has the Dev Overlay enabled */
|
|
4
4
|
enabled: boolean;
|
|
5
5
|
};
|
|
6
|
+
checkUpdates: {
|
|
7
|
+
/** Specifies whether the user has the update check enabled */
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
};
|
|
10
|
+
_variables: {
|
|
11
|
+
/** Time since last update check */
|
|
12
|
+
lastUpdateCheck: number;
|
|
13
|
+
};
|
|
6
14
|
};
|
|
7
15
|
export type Preferences = typeof DEFAULT_PREFERENCES;
|
|
16
|
+
export type PublicPreferences = Omit<Preferences, '_variables'>;
|
|
@@ -2,6 +2,15 @@ const DEFAULT_PREFERENCES = {
|
|
|
2
2
|
devToolbar: {
|
|
3
3
|
/** Specifies whether the user has the Dev Overlay enabled */
|
|
4
4
|
enabled: true
|
|
5
|
+
},
|
|
6
|
+
checkUpdates: {
|
|
7
|
+
/** Specifies whether the user has the update check enabled */
|
|
8
|
+
enabled: true
|
|
9
|
+
},
|
|
10
|
+
// Temporary variables that shouldn't be exposed to the users in the CLI, but are still useful to store in preferences
|
|
11
|
+
_variables: {
|
|
12
|
+
/** Time since last update check */
|
|
13
|
+
lastUpdateCheck: 0
|
|
5
14
|
}
|
|
6
15
|
};
|
|
7
16
|
export {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AstroConfig } from '../@types/astro.js';
|
|
2
|
-
import { type Preferences } from './defaults.js';
|
|
2
|
+
import { type Preferences, type PublicPreferences } from './defaults.js';
|
|
3
3
|
type DotKeys<T> = T extends object ? {
|
|
4
4
|
[K in keyof T]: `${Exclude<K, symbol>}${DotKeys<T[K]> extends never ? '' : `.${DotKeys<T[K]>}`}`;
|
|
5
5
|
}[keyof T] : never;
|
|
@@ -7,20 +7,28 @@ export type GetDotKey<T extends Record<string | number, any>, K extends string>
|
|
|
7
7
|
export type PreferenceLocation = 'global' | 'project';
|
|
8
8
|
export interface PreferenceOptions {
|
|
9
9
|
location?: PreferenceLocation;
|
|
10
|
+
/**
|
|
11
|
+
* If `true`, the server will be reloaded after setting the preference.
|
|
12
|
+
* If `false`, the server will not be reloaded after setting the preference.
|
|
13
|
+
*
|
|
14
|
+
* Defaults to `true`.
|
|
15
|
+
*/
|
|
16
|
+
reloadServer?: boolean;
|
|
10
17
|
}
|
|
11
18
|
type DeepPartial<T> = T extends object ? {
|
|
12
19
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
13
20
|
} : T;
|
|
14
21
|
export type PreferenceKey = DotKeys<Preferences>;
|
|
15
|
-
export interface PreferenceList extends Record<PreferenceLocation, DeepPartial<
|
|
22
|
+
export interface PreferenceList extends Record<PreferenceLocation, DeepPartial<PublicPreferences>> {
|
|
16
23
|
fromAstroConfig: DeepPartial<Preferences>;
|
|
17
|
-
defaults:
|
|
24
|
+
defaults: PublicPreferences;
|
|
18
25
|
}
|
|
19
26
|
export interface AstroPreferences {
|
|
20
27
|
get<Key extends PreferenceKey>(key: Key, opts?: PreferenceOptions): Promise<GetDotKey<Preferences, Key>>;
|
|
21
28
|
set<Key extends PreferenceKey>(key: Key, value: GetDotKey<Preferences, Key>, opts?: PreferenceOptions): Promise<void>;
|
|
22
|
-
getAll(): Promise<
|
|
29
|
+
getAll(): Promise<PublicPreferences>;
|
|
23
30
|
list(opts?: PreferenceOptions): Promise<PreferenceList>;
|
|
31
|
+
ignoreNextPreferenceReload: boolean;
|
|
24
32
|
}
|
|
25
33
|
export declare function isValidKey(key: string): key is PreferenceKey;
|
|
26
34
|
export declare function coerce(key: string, value: unknown): any;
|
|
@@ -37,30 +37,37 @@ function createPreferences(config) {
|
|
|
37
37
|
return project.get(key) ?? global.get(key) ?? dget(DEFAULT_PREFERENCES, key);
|
|
38
38
|
return stores[location].get(key);
|
|
39
39
|
},
|
|
40
|
-
async set(key, value, { location = "project" } = {}) {
|
|
40
|
+
async set(key, value, { location = "project", reloadServer = true } = {}) {
|
|
41
41
|
stores[location].set(key, value);
|
|
42
|
+
if (!reloadServer) {
|
|
43
|
+
this.ignoreNextPreferenceReload = true;
|
|
44
|
+
}
|
|
42
45
|
},
|
|
43
46
|
async getAll() {
|
|
44
|
-
|
|
47
|
+
const allPrefs = Object.assign(
|
|
45
48
|
{},
|
|
46
49
|
DEFAULT_PREFERENCES,
|
|
47
50
|
stores["global"].getAll(),
|
|
48
51
|
stores["project"].getAll()
|
|
49
52
|
);
|
|
53
|
+
const { _variables, ...prefs } = allPrefs;
|
|
54
|
+
return prefs;
|
|
50
55
|
},
|
|
51
56
|
async list() {
|
|
57
|
+
const { _variables, ...defaultPrefs } = DEFAULT_PREFERENCES;
|
|
52
58
|
return {
|
|
53
59
|
global: stores["global"].getAll(),
|
|
54
60
|
project: stores["project"].getAll(),
|
|
55
61
|
fromAstroConfig: mapFrom(DEFAULT_PREFERENCES, config),
|
|
56
|
-
defaults:
|
|
62
|
+
defaults: defaultPrefs
|
|
57
63
|
};
|
|
58
64
|
function mapFrom(defaults, astroConfig) {
|
|
59
65
|
return Object.fromEntries(
|
|
60
66
|
Object.entries(defaults).map(([key, _]) => [key, astroConfig[key]])
|
|
61
67
|
);
|
|
62
68
|
}
|
|
63
|
-
}
|
|
69
|
+
},
|
|
70
|
+
ignoreNextPreferenceReload: false
|
|
64
71
|
};
|
|
65
72
|
}
|
|
66
73
|
function getGlobalPreferenceDir() {
|
|
@@ -15,6 +15,6 @@ declare const _default: {
|
|
|
15
15
|
id: string;
|
|
16
16
|
name: string;
|
|
17
17
|
icon: "astro:logo";
|
|
18
|
-
init(canvas: ShadowRoot, eventTarget:
|
|
18
|
+
init(canvas: ShadowRoot, eventTarget: import("../helpers.js").ToolbarAppEventTarget): Promise<void>;
|
|
19
19
|
};
|
|
20
20
|
export default _default;
|
|
@@ -59,6 +59,7 @@ var astro_default = {
|
|
|
59
59
|
link: "https://astro.build/chat"
|
|
60
60
|
}
|
|
61
61
|
];
|
|
62
|
+
const hasNewerVersion = window.__astro_dev_toolbar__.latestAstroVersion;
|
|
62
63
|
const windowComponent = createWindowElement(
|
|
63
64
|
`<style>
|
|
64
65
|
#buttons-container {
|
|
@@ -301,6 +302,8 @@ var astro_default = {
|
|
|
301
302
|
<section>
|
|
302
303
|
${astroLogo}
|
|
303
304
|
<astro-dev-toolbar-badge badge-style="gray" size="large">${window.__astro_dev_toolbar__.version}</astro-dev-toolbar-badge>
|
|
305
|
+
${hasNewerVersion ? `<astro-dev-toolbar-badge badge-style="green" size="large">${window.__astro_dev_toolbar__.latestAstroVersion} available!</astro-dev-toolbar-badge>
|
|
306
|
+
` : ""}
|
|
304
307
|
</section>
|
|
305
308
|
<astro-dev-toolbar-button id="copy-debug-button">Copy debug info <astro-dev-toolbar-icon icon="copy" /></astro-dev-toolbar-button>
|
|
306
309
|
</header>
|
|
@@ -10,6 +10,6 @@ declare const _default: {
|
|
|
10
10
|
id: string;
|
|
11
11
|
name: string;
|
|
12
12
|
icon: "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 1 20 16\"><path fill=\"#fff\" d=\"M.6 2A1.1 1.1 0 0 1 1.7.9h16.6a1.1 1.1 0 1 1 0 2.2H1.6A1.1 1.1 0 0 1 .8 2Zm1.1 7.1h6a1.1 1.1 0 0 0 0-2.2h-6a1.1 1.1 0 0 0 0 2.2ZM9.3 13H1.8a1.1 1.1 0 1 0 0 2.2h7.5a1.1 1.1 0 1 0 0-2.2Zm11.3 1.9a1.1 1.1 0 0 1-1.5 0l-1.7-1.7a4.1 4.1 0 1 1 1.6-1.6l1.6 1.7a1.1 1.1 0 0 1 0 1.6Zm-5.3-3.4a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8Z\"/></svg>";
|
|
13
|
-
init(canvas: ShadowRoot, eventTarget:
|
|
13
|
+
init(canvas: ShadowRoot, eventTarget: import("../../helpers.js").ToolbarAppEventTarget): Promise<void>;
|
|
14
14
|
};
|
|
15
15
|
export default _default;
|
|
@@ -2,6 +2,6 @@ declare const _default: {
|
|
|
2
2
|
id: string;
|
|
3
3
|
name: string;
|
|
4
4
|
icon: "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"><path fill=\"#fff\" d=\"M7.9 1.5v-.4a1.1 1.1 0 0 1 2.2 0v.4a1.1 1.1 0 1 1-2.2 0Zm-6.4 8.6a1.1 1.1 0 1 0 0-2.2h-.4a1.1 1.1 0 0 0 0 2.2h.4ZM12 3.7a1.1 1.1 0 0 0 1.4-.7l.4-1.1a1.1 1.1 0 0 0-2.1-.8l-.4 1.2a1.1 1.1 0 0 0 .7 1.4Zm-9.7 7.6-1.2.4a1.1 1.1 0 1 0 .8 2.1l1-.4a1.1 1.1 0 1 0-.6-2ZM20.8 17a1.9 1.9 0 0 1 0 2.6l-1.2 1.2a1.9 1.9 0 0 1-2.6 0l-4.3-4.2-1.6 3.6a1.9 1.9 0 0 1-1.7 1.2A1.9 1.9 0 0 1 7.5 20L2.7 5a1.9 1.9 0 0 1 2.4-2.4l15 5a1.9 1.9 0 0 1 .2 3.4l-3.7 1.6 4.2 4.3ZM19 18.3 14.6 14a1.9 1.9 0 0 1 .6-3l3.2-1.5L5.1 5.1l4.3 13.3 1.5-3.2a1.9 1.9 0 0 1 3-.6l4.4 4.4.7-.7Z\"/></svg>";
|
|
5
|
-
init(canvas: ShadowRoot, eventTarget:
|
|
5
|
+
init(canvas: ShadowRoot, eventTarget: import("../helpers.js").ToolbarAppEventTarget): void;
|
|
6
6
|
};
|
|
7
7
|
export default _default;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { loadDevToolbarApps } from "astro:
|
|
1
|
+
import { loadDevToolbarApps } from "astro:toolbar:internal";
|
|
2
|
+
import { ToolbarAppEventTarget } from "./helpers.js";
|
|
2
3
|
import { settings } from "./settings.js";
|
|
3
4
|
let overlay;
|
|
4
5
|
document.addEventListener("DOMContentLoaded", async () => {
|
|
@@ -60,7 +61,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
60
61
|
info: '<svg viewBox="0 0 10 10" style="--fill:var(--fill-default);--fill-default:#3645D9;--fill-hover:#BDC3FF;"><rect width="9" height="9" x=".5" y=".5" fill="var(--fill)" stroke="#13151A" stroke-width="2" rx="1.5"/></svg>'
|
|
61
62
|
};
|
|
62
63
|
const prepareApp = (appDefinition, builtIn) => {
|
|
63
|
-
const eventTarget = new
|
|
64
|
+
const eventTarget = new ToolbarAppEventTarget();
|
|
64
65
|
const app = {
|
|
65
66
|
...appDefinition,
|
|
66
67
|
builtIn,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
type NotificationPayload = {
|
|
2
|
+
state: true;
|
|
3
|
+
level?: 'error' | 'warn' | 'info';
|
|
4
|
+
} | {
|
|
5
|
+
state: false;
|
|
6
|
+
};
|
|
7
|
+
type AppStatePayload = {
|
|
8
|
+
state: boolean;
|
|
9
|
+
};
|
|
10
|
+
type AppToggledEvent = (opts: {
|
|
11
|
+
state: boolean;
|
|
12
|
+
}) => void;
|
|
13
|
+
type ToolbarPlacementUpdatedEvent = (opts: {
|
|
14
|
+
placement: 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
15
|
+
}) => void;
|
|
16
|
+
export declare class ToolbarAppEventTarget extends EventTarget {
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Toggle the notification state of the toolbar
|
|
20
|
+
* @param options - The notification options
|
|
21
|
+
* @param options.state - The state of the notification
|
|
22
|
+
* @param options.level - The level of the notification, optional when state is false
|
|
23
|
+
*/
|
|
24
|
+
toggleNotification(options: NotificationPayload): void;
|
|
25
|
+
/**
|
|
26
|
+
* Toggle the app state on or off
|
|
27
|
+
* @param options - The app state options
|
|
28
|
+
* @param options.state - The new state of the app
|
|
29
|
+
*/
|
|
30
|
+
toggleState(options: AppStatePayload): void;
|
|
31
|
+
/**
|
|
32
|
+
* Fired when the app is toggled on or off
|
|
33
|
+
* @param callback - The callback to run when the event is fired, takes an object with the new state
|
|
34
|
+
*/
|
|
35
|
+
onToggled(callback: AppToggledEvent): void;
|
|
36
|
+
/**
|
|
37
|
+
* Fired when the toolbar placement is updated by the user
|
|
38
|
+
* @param callback - The callback to run when the event is fired, takes an object with the new placement
|
|
39
|
+
*/
|
|
40
|
+
onToolbarPlacementUpdated(callback: ToolbarPlacementUpdatedEvent): void;
|
|
41
|
+
}
|
|
42
|
+
export declare const serverHelpers: {
|
|
43
|
+
/**
|
|
44
|
+
* Send a message to the server, the payload can be any serializable data.
|
|
45
|
+
*
|
|
46
|
+
* The server can listen for this message in the `astro:server:config` hook of an Astro integration, using the `toolbar.on` method.
|
|
47
|
+
*
|
|
48
|
+
* @param event - The event name
|
|
49
|
+
* @param payload - The payload to send
|
|
50
|
+
*/
|
|
51
|
+
send: <T>(event: string, payload: T) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Receive a message from the server.
|
|
54
|
+
* @param event - The event name
|
|
55
|
+
* @param callback - The callback to run when the event is received.
|
|
56
|
+
* The payload's content will be passed to the callback as an argument
|
|
57
|
+
*/
|
|
58
|
+
on: <T_1>(event: string, callback: (data: T_1) => void) => void;
|
|
59
|
+
};
|
|
60
|
+
export type ToolbarServerHelpers = typeof serverHelpers;
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
class ToolbarAppEventTarget extends EventTarget {
|
|
2
|
+
constructor() {
|
|
3
|
+
super();
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Toggle the notification state of the toolbar
|
|
7
|
+
* @param options - The notification options
|
|
8
|
+
* @param options.state - The state of the notification
|
|
9
|
+
* @param options.level - The level of the notification, optional when state is false
|
|
10
|
+
*/
|
|
11
|
+
toggleNotification(options) {
|
|
12
|
+
this.dispatchEvent(
|
|
13
|
+
new CustomEvent("toggle-notification", {
|
|
14
|
+
detail: {
|
|
15
|
+
state: options.state,
|
|
16
|
+
level: options.state === true ? options.level : void 0
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Toggle the app state on or off
|
|
23
|
+
* @param options - The app state options
|
|
24
|
+
* @param options.state - The new state of the app
|
|
25
|
+
*/
|
|
26
|
+
toggleState(options) {
|
|
27
|
+
this.dispatchEvent(
|
|
28
|
+
new CustomEvent("app-toggled", {
|
|
29
|
+
detail: {
|
|
30
|
+
state: options.state
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fired when the app is toggled on or off
|
|
37
|
+
* @param callback - The callback to run when the event is fired, takes an object with the new state
|
|
38
|
+
*/
|
|
39
|
+
onToggled(callback) {
|
|
40
|
+
this.addEventListener("app-toggled", (evt) => {
|
|
41
|
+
if (!(evt instanceof CustomEvent))
|
|
42
|
+
return;
|
|
43
|
+
callback(evt.detail);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Fired when the toolbar placement is updated by the user
|
|
48
|
+
* @param callback - The callback to run when the event is fired, takes an object with the new placement
|
|
49
|
+
*/
|
|
50
|
+
onToolbarPlacementUpdated(callback) {
|
|
51
|
+
this.addEventListener("placement-updated", (evt) => {
|
|
52
|
+
if (!(evt instanceof CustomEvent))
|
|
53
|
+
return;
|
|
54
|
+
callback(evt.detail);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const serverHelpers = {
|
|
59
|
+
/**
|
|
60
|
+
* Send a message to the server, the payload can be any serializable data.
|
|
61
|
+
*
|
|
62
|
+
* The server can listen for this message in the `astro:server:config` hook of an Astro integration, using the `toolbar.on` method.
|
|
63
|
+
*
|
|
64
|
+
* @param event - The event name
|
|
65
|
+
* @param payload - The payload to send
|
|
66
|
+
*/
|
|
67
|
+
send: (event, payload) => {
|
|
68
|
+
if (import.meta.hot) {
|
|
69
|
+
import.meta.hot.send(event, payload);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Receive a message from the server.
|
|
74
|
+
* @param event - The event name
|
|
75
|
+
* @param callback - The callback to run when the event is received.
|
|
76
|
+
* The payload's content will be passed to the callback as an argument
|
|
77
|
+
*/
|
|
78
|
+
on: (event, callback) => {
|
|
79
|
+
if (import.meta.hot) {
|
|
80
|
+
import.meta.hot.on(event, callback);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
export {
|
|
85
|
+
ToolbarAppEventTarget,
|
|
86
|
+
serverHelpers
|
|
87
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ResolvedDevToolbarApp as DevToolbarAppDefinition } from '../../../@types/astro.js';
|
|
2
|
+
import { type ToolbarAppEventTarget } from './helpers.js';
|
|
2
3
|
import { type Icon } from './ui-library/icons.js';
|
|
3
4
|
import { type Placement } from './ui-library/window.js';
|
|
4
5
|
export type DevToolbarApp = DevToolbarAppDefinition & {
|
|
@@ -9,7 +10,7 @@ export type DevToolbarApp = DevToolbarAppDefinition & {
|
|
|
9
10
|
state: boolean;
|
|
10
11
|
level?: 'error' | 'warning' | 'info';
|
|
11
12
|
};
|
|
12
|
-
eventTarget:
|
|
13
|
+
eventTarget: ToolbarAppEventTarget;
|
|
13
14
|
};
|
|
14
15
|
export declare class AstroDevToolbar extends HTMLElement {
|
|
15
16
|
shadowRoot: ShadowRoot;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { serverHelpers } from "./helpers.js";
|
|
1
2
|
import { settings } from "./settings.js";
|
|
2
3
|
import { getIconElement, isDefinedIcon } from "./ui-library/icons.js";
|
|
3
4
|
import {} from "./ui-library/window.js";
|
|
@@ -340,7 +341,7 @@ class AstroDevToolbar extends HTMLElement {
|
|
|
340
341
|
app.status = "loading";
|
|
341
342
|
try {
|
|
342
343
|
settings.logger.verboseLog(`Initializing app ${app.id}`);
|
|
343
|
-
await app.init?.(shadowRoot, app.eventTarget);
|
|
344
|
+
await app.init?.(shadowRoot, app.eventTarget, serverHelpers);
|
|
344
345
|
app.status = "ready";
|
|
345
346
|
if (import.meta.hot) {
|
|
346
347
|
import.meta.hot.send(`${WS_EVENT_NAME}:${app.id}:initialized`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { telemetry } from "../events/index.js";
|
|
2
2
|
import { eventAppToggled } from "../events/toolbar.js";
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const PRIVATE_VIRTUAL_MODULE_ID = "astro:toolbar:internal";
|
|
4
|
+
const resolvedPrivateVirtualModuleId = "\0" + PRIVATE_VIRTUAL_MODULE_ID;
|
|
5
5
|
function astroDevToolbar({ settings, logger }) {
|
|
6
6
|
let telemetryTimeout;
|
|
7
7
|
return {
|
|
@@ -15,8 +15,8 @@ function astroDevToolbar({ settings, logger }) {
|
|
|
15
15
|
};
|
|
16
16
|
},
|
|
17
17
|
resolveId(id) {
|
|
18
|
-
if (id ===
|
|
19
|
-
return
|
|
18
|
+
if (id === PRIVATE_VIRTUAL_MODULE_ID) {
|
|
19
|
+
return resolvedPrivateVirtualModuleId;
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
configureServer(server) {
|
|
@@ -49,22 +49,43 @@ ${args.error}`
|
|
|
49
49
|
});
|
|
50
50
|
},
|
|
51
51
|
async load(id) {
|
|
52
|
-
if (id ===
|
|
52
|
+
if (id === resolvedPrivateVirtualModuleId) {
|
|
53
53
|
return `
|
|
54
54
|
export const loadDevToolbarApps = async () => {
|
|
55
55
|
return (await Promise.all([${settings.devToolbarApps.map(
|
|
56
|
-
(plugin) => `safeLoadPlugin(
|
|
56
|
+
(plugin) => `safeLoadPlugin(${JSON.stringify(
|
|
57
57
|
plugin
|
|
58
|
-
)}
|
|
59
|
-
|
|
58
|
+
)}, async () => (await import(${JSON.stringify(
|
|
59
|
+
typeof plugin === "string" ? plugin : plugin.entrypoint
|
|
60
|
+
)})).default, ${JSON.stringify(
|
|
61
|
+
typeof plugin === "string" ? plugin : plugin.entrypoint
|
|
62
|
+
)})`
|
|
63
|
+
).join(",")}]));
|
|
60
64
|
};
|
|
61
65
|
|
|
62
|
-
async function safeLoadPlugin(importEntrypoint, entrypoint) {
|
|
66
|
+
async function safeLoadPlugin(appDefinition, importEntrypoint, entrypoint) {
|
|
63
67
|
try {
|
|
64
|
-
|
|
68
|
+
let app;
|
|
69
|
+
if (typeof appDefinition === 'string') {
|
|
70
|
+
app = await importEntrypoint();
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
if (typeof app !== 'object' || !app.id || !app.name) {
|
|
73
|
+
throw new Error("Apps must default export an object with an id, and a name.");
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
app = appDefinition;
|
|
77
|
+
|
|
78
|
+
if (typeof app !== 'object' || !app.id || !app.name || !app.entrypoint) {
|
|
79
|
+
throw new Error("Apps must be an object with an id, a name and an entrypoint.");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const loadedApp = await importEntrypoint();
|
|
83
|
+
|
|
84
|
+
if (typeof loadedApp !== 'object') {
|
|
85
|
+
throw new Error("App entrypoint must default export an object.");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
app = { ...app, ...loadedApp };
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
return app;
|
|
@@ -56,6 +56,7 @@ class DevPipeline extends Pipeline {
|
|
|
56
56
|
const additionalMetadata = {
|
|
57
57
|
root: url.fileURLToPath(settings.config.root),
|
|
58
58
|
version: ASTRO_VERSION,
|
|
59
|
+
latestAstroVersion: settings.latestAstroVersion,
|
|
59
60
|
debugInfo: await getInfoOutput({ userConfig: settings.config, print: false })
|
|
60
61
|
};
|
|
61
62
|
const children = `window.__astro_dev_toolbar__ = ${JSON.stringify(additionalMetadata)}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
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",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"./client/*": "./dist/runtime/client/*",
|
|
54
54
|
"./components": "./components/index.ts",
|
|
55
55
|
"./components/*": "./components/*",
|
|
56
|
+
"./toolbar": "./dist/toolbar/index.js",
|
|
56
57
|
"./assets": "./dist/assets/index.js",
|
|
57
58
|
"./assets/utils": "./dist/assets/utils/index.js",
|
|
58
59
|
"./assets/endpoint/*": "./dist/assets/endpoint/*.js",
|
|
@@ -167,7 +168,7 @@
|
|
|
167
168
|
"@astrojs/telemetry": "3.1.0"
|
|
168
169
|
},
|
|
169
170
|
"optionalDependencies": {
|
|
170
|
-
"sharp": "^0.
|
|
171
|
+
"sharp": "^0.33.3"
|
|
171
172
|
},
|
|
172
173
|
"devDependencies": {
|
|
173
174
|
"@astrojs/check": "^0.5.10",
|
package/tsconfigs/strictest.json
CHANGED
|
@@ -19,8 +19,6 @@
|
|
|
19
19
|
// Report an error for unreachable code instead of just a warning.
|
|
20
20
|
"allowUnreachableCode": false,
|
|
21
21
|
// Report an error for unused labels instead of just a warning.
|
|
22
|
-
"allowUnusedLabels": false
|
|
23
|
-
// Disallow JavaScript files from being imported
|
|
24
|
-
"allowJs": false
|
|
22
|
+
"allowUnusedLabels": false
|
|
25
23
|
}
|
|
26
24
|
}
|
|
File without changes
|