astro 5.14.8 → 5.15.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.
Files changed (84) hide show
  1. package/components/Font.astro +7 -5
  2. package/dist/actions/runtime/virtual.js +4 -0
  3. package/dist/assets/build/generate.js +2 -2
  4. package/dist/assets/fonts/implementations/url-proxy.js +8 -1
  5. package/dist/assets/fonts/runtime.d.ts +2 -1
  6. package/dist/assets/fonts/runtime.js +36 -1
  7. package/dist/assets/fonts/types.d.ts +8 -0
  8. package/dist/assets/fonts/vite-plugin-fonts.js +2 -2
  9. package/dist/assets/utils/getAssetsPrefix.js +9 -6
  10. package/dist/cli/add/index.js +95 -18
  11. package/dist/cli/dev/index.js +2 -2
  12. package/dist/cli/docs/core/open-docs.d.ts +19 -0
  13. package/dist/cli/docs/core/open-docs.js +49 -0
  14. package/dist/cli/docs/definitions.d.ts +12 -0
  15. package/dist/cli/docs/definitions.js +0 -0
  16. package/dist/cli/docs/domains/platform.d.ts +1 -0
  17. package/dist/cli/docs/domains/platform.js +0 -0
  18. package/dist/cli/docs/infra/process-platform-provider.d.ts +2 -0
  19. package/dist/cli/docs/infra/process-platform-provider.js +11 -0
  20. package/dist/cli/docs/infra/tinyexec-command-executor.d.ts +2 -0
  21. package/dist/cli/docs/infra/tinyexec-command-executor.js +30 -0
  22. package/dist/cli/exec.d.ts +1 -0
  23. package/dist/cli/index.js +26 -13
  24. package/dist/cli/info/index.js +1 -1
  25. package/dist/cli/infra/build-time-astro-version-provider.js +2 -1
  26. package/dist/cli/infra/logger-help-display.js +2 -3
  27. package/dist/cli/infra/picocolors-text-styler.d.ts +2 -0
  28. package/dist/cli/infra/picocolors-text-styler.js +7 -0
  29. package/dist/cli/install-package.js +2 -1
  30. package/dist/cli/preferences/index.js +3 -2
  31. package/dist/cli/preview/index.js +2 -2
  32. package/dist/cli/utils/format-version.d.ts +8 -0
  33. package/dist/cli/utils/format-version.js +8 -0
  34. package/dist/content/content-layer.js +3 -3
  35. package/dist/content/loaders/glob.js +6 -6
  36. package/dist/content/server-listeners.js +6 -6
  37. package/dist/content/types-generator.js +4 -4
  38. package/dist/content/utils.js +4 -4
  39. package/dist/core/app/types.d.ts +1 -0
  40. package/dist/core/build/generate.js +2 -1
  41. package/dist/core/build/index.js +12 -9
  42. package/dist/core/build/page-data.js +1 -1
  43. package/dist/core/build/plugins/plugin-manifest.js +18 -3
  44. package/dist/core/build/static-build.js +6 -3
  45. package/dist/core/config/config.js +1 -1
  46. package/dist/core/constants.js +1 -1
  47. package/dist/core/create-vite.js +2 -0
  48. package/dist/core/dev/dev.js +3 -3
  49. package/dist/core/errors/dev/utils.js +2 -2
  50. package/dist/core/errors/overlay.js +52 -3
  51. package/dist/core/logger/core.js +7 -7
  52. package/dist/core/messages.js +14 -13
  53. package/dist/core/render/ssr-element.d.ts +3 -3
  54. package/dist/core/render/ssr-element.js +19 -12
  55. package/dist/core/render-context.js +7 -6
  56. package/dist/core/routing/manifest/create.js +2 -2
  57. package/dist/core/sync/index.js +2 -2
  58. package/dist/integrations/hooks.js +8 -6
  59. package/dist/prefetch/index.js +6 -1
  60. package/dist/runtime/client/dev-toolbar/ui-library/badge.d.ts +2 -2
  61. package/dist/runtime/client/dev-toolbar/ui-library/button.d.ts +2 -2
  62. package/dist/runtime/client/dev-toolbar/ui-library/card.d.ts +2 -2
  63. package/dist/runtime/client/dev-toolbar/ui-library/highlight.d.ts +2 -2
  64. package/dist/runtime/client/dev-toolbar/ui-library/radio-checkbox.d.ts +2 -2
  65. package/dist/runtime/client/dev-toolbar/ui-library/select.d.ts +2 -2
  66. package/dist/runtime/client/dev-toolbar/ui-library/toggle.d.ts +2 -2
  67. package/dist/runtime/server/endpoint.js +2 -2
  68. package/dist/runtime/server/render/server-islands.js +6 -1
  69. package/dist/transitions/router.js +6 -1
  70. package/dist/types/public/content.d.ts +27 -0
  71. package/dist/types/public/integrations.d.ts +15 -0
  72. package/dist/types/public/internal.d.ts +1 -0
  73. package/dist/vite-plugin-adapter-config/index.d.ts +3 -0
  74. package/dist/vite-plugin-adapter-config/index.js +33 -0
  75. package/dist/vite-plugin-astro-server/base.js +2 -2
  76. package/dist/vite-plugin-scanner/index.js +2 -2
  77. package/package.json +4 -4
  78. package/types/fonts.d.ts +3 -0
  79. package/dist/cli/docs/index.d.ts +0 -6
  80. package/dist/cli/docs/index.js +0 -18
  81. package/dist/cli/docs/open.d.ts +0 -2
  82. package/dist/cli/docs/open.js +0 -28
  83. package/dist/cli/infra/kleur-text-styler.d.ts +0 -2
  84. package/dist/cli/infra/kleur-text-styler.js +0 -7
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  import * as mod from 'virtual:astro:assets/fonts/internal';
3
+ import { filterPreloads } from 'astro/assets/fonts/runtime';
3
4
  import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
4
5
 
5
6
  // TODO: remove check when fonts are stabilized
@@ -12,7 +13,7 @@ interface Props {
12
13
  /** The `cssVariable` registered in your Astro configuration. */
13
14
  cssVariable: import('astro:assets').CssVariable;
14
15
  /** Whether it should output [preload links](https://web.dev/learn/performance/optimize-web-fonts#preload) or not. */
15
- preload?: boolean;
16
+ preload?: import('astro:assets').FontPreloadFilter;
16
17
  }
17
18
 
18
19
  const { cssVariable, preload = false } = Astro.props as Props;
@@ -23,12 +24,13 @@ if (!data) {
23
24
  message: AstroErrorData.FontFamilyNotFound.message(cssVariable),
24
25
  });
25
26
  }
27
+
28
+ const filteredPreloadData = filterPreloads(data.preloadData, preload);
26
29
  ---
27
30
 
28
31
  <style set:html={data.css}></style>
29
32
  {
30
- preload &&
31
- data.preloadData.map(({ url, type }) => (
32
- <link rel="preload" href={url} as="font" type={`font/${type}`} crossorigin />
33
- ))
33
+ filteredPreloadData?.map(({ url, type }) => (
34
+ <link rel="preload" href={url} as="font" type={`font/${type}`} crossorigin />
35
+ ))
34
36
  }
@@ -1,4 +1,5 @@
1
1
  import { shouldAppendTrailingSlash } from "virtual:astro:actions/options";
2
+ import { internalFetchHeaders } from "virtual:astro:adapter-config/client";
2
3
  import {
3
4
  ACTION_QUERY_PARAMS,
4
5
  ActionError,
@@ -73,6 +74,9 @@ async function handleAction(param, path, context) {
73
74
  }
74
75
  const headers = new Headers();
75
76
  headers.set("Accept", "application/json");
77
+ for (const [key, value] of Object.entries(internalFetchHeaders)) {
78
+ headers.set(key, value);
79
+ }
76
80
  let body = param;
77
81
  if (!(body instanceof FormData)) {
78
82
  try {
@@ -1,6 +1,6 @@
1
1
  import fs, { readFileSync } from "node:fs";
2
2
  import { basename } from "node:path/posix";
3
- import { dim, green } from "kleur/colors";
3
+ import colors from "picocolors";
4
4
  import { getOutDirWithinCwd } from "../../core/build/common.js";
5
5
  import { getTimeStat } from "../../core/build/util.js";
6
6
  import { AstroError } from "../../core/errors/errors.js";
@@ -74,7 +74,7 @@ async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
74
74
  const count = `(${env.count.current}/${env.count.total})`;
75
75
  env.logger.info(
76
76
  null,
77
- ` ${green("\u25B6")} ${filepath} ${dim(statsText)} ${dim(timeIncrease)} ${dim(count)}`
77
+ ` ${colors.green("\u25B6")} ${filepath} ${colors.dim(statsText)} ${colors.dim(timeIncrease)} ${colors.dim(count)}`
78
78
  );
79
79
  env.count.current++;
80
80
  }
@@ -1,3 +1,4 @@
1
+ import { renderFontWeight } from "../utils.js";
1
2
  function createUrlProxy({
2
3
  hashResolver,
3
4
  dataCollector,
@@ -11,7 +12,13 @@ function createUrlProxy({
11
12
  dataCollector.collect({
12
13
  url: originalUrl,
13
14
  hash,
14
- preload: collectPreload ? { url, type } : null,
15
+ preload: collectPreload ? {
16
+ url,
17
+ type,
18
+ weight: renderFontWeight(data.weight),
19
+ style: data.style,
20
+ subset: data.subset
21
+ } : null,
15
22
  data,
16
23
  init
17
24
  });
@@ -1,4 +1,5 @@
1
- import type { ConsumableMap } from './types.js';
1
+ import type { ConsumableMap, PreloadData, PreloadFilter } from './types.js';
2
2
  export declare function createGetFontData({ consumableMap }: {
3
3
  consumableMap?: ConsumableMap;
4
4
  }): (cssVariable: string) => import("./types.js").FontData[];
5
+ export declare function filterPreloads(data: Array<PreloadData>, preload: PreloadFilter): Array<PreloadData> | null;
@@ -14,6 +14,41 @@ function createGetFontData({ consumableMap }) {
14
14
  return data;
15
15
  };
16
16
  }
17
+ function filterPreloads(data, preload) {
18
+ if (!preload) {
19
+ return null;
20
+ }
21
+ if (preload === true) {
22
+ return data;
23
+ }
24
+ return data.filter(
25
+ ({ weight, style, subset }) => preload.some((p) => {
26
+ if (p.weight !== void 0 && weight !== void 0 && !checkWeight(p.weight.toString(), weight)) {
27
+ return false;
28
+ }
29
+ if (p.style !== void 0 && p.style !== style) {
30
+ return false;
31
+ }
32
+ if (p.subset !== void 0 && p.subset !== subset) {
33
+ return false;
34
+ }
35
+ return true;
36
+ })
37
+ );
38
+ }
39
+ function checkWeight(input, target) {
40
+ const trimmedInput = input.trim();
41
+ if (trimmedInput.includes(" ")) {
42
+ return trimmedInput === target;
43
+ }
44
+ if (target.includes(" ")) {
45
+ const [a, b] = target.split(" ");
46
+ const parsedInput = Number.parseInt(input);
47
+ return parsedInput >= Number.parseInt(a) && parsedInput <= Number.parseInt(b);
48
+ }
49
+ return input === target;
50
+ }
17
51
  export {
18
- createGetFontData
52
+ createGetFontData,
53
+ filterPreloads
19
54
  };
@@ -44,6 +44,9 @@ export interface PreloadData {
44
44
  * A font type, eg. woff2, woff, ttf...
45
45
  */
46
46
  type: FontType;
47
+ weight: string | undefined;
48
+ style: string | undefined;
49
+ subset: string | undefined;
47
50
  }
48
51
  export type FontFaceMetrics = Pick<Font, 'ascent' | 'descent' | 'lineGap' | 'unitsPerEm' | 'xWidthAvg'>;
49
52
  export type GenericFallbackName = (typeof GENERIC_FALLBACK_NAMES)[number];
@@ -87,4 +90,9 @@ export interface FontData {
87
90
  */
88
91
  export type ConsumableMap = Map<string, Array<FontData>>;
89
92
  export type Style = z.output<typeof styleSchema>;
93
+ export type PreloadFilter = boolean | Array<{
94
+ weight?: string | number;
95
+ style?: string;
96
+ subset?: string;
97
+ }>;
90
98
  export {};
@@ -2,7 +2,7 @@ import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { isAbsolute } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { bold } from "kleur/colors";
5
+ import colors from "picocolors";
6
6
  import { getAlgorithm, shouldTrackCspHashes } from "../../core/csp/common.js";
7
7
  import { generateCspDigest } from "../../core/encryption.js";
8
8
  import { collectErrorMetadata } from "../../core/errors/dev/utils.js";
@@ -140,7 +140,7 @@ function fontsPlugin({ settings, sync, logger }) {
140
140
  });
141
141
  },
142
142
  defaults: DEFAULTS,
143
- bold,
143
+ bold: colors.bold,
144
144
  stringMatcher
145
145
  });
146
146
  fontFileDataMap = res.fontFileDataMap;
@@ -1,11 +1,14 @@
1
1
  function getAssetsPrefix(fileExtension, assetsPrefix) {
2
- if (!assetsPrefix) return "";
3
- if (typeof assetsPrefix === "string") return assetsPrefix;
4
- const dotLessFileExtension = fileExtension.slice(1);
5
- if (assetsPrefix[dotLessFileExtension]) {
6
- return assetsPrefix[dotLessFileExtension];
2
+ let prefix = "";
3
+ if (!assetsPrefix) {
4
+ prefix = "";
5
+ } else if (typeof assetsPrefix === "string") {
6
+ prefix = assetsPrefix;
7
+ } else {
8
+ const dotLessFileExtension = fileExtension.slice(1);
9
+ prefix = assetsPrefix[dotLessFileExtension] || assetsPrefix.fallback;
7
10
  }
8
- return assetsPrefix.fallback;
11
+ return prefix;
9
12
  }
10
13
  export {
11
14
  getAssetsPrefix
@@ -3,10 +3,10 @@ import path from "node:path";
3
3
  import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import boxen from "boxen";
5
5
  import { diffWords } from "diff";
6
- import { bold, cyan, dim, green, magenta, red, yellow } from "kleur/colors";
7
6
  import { builders, generateCode, loadFile } from "magicast";
8
7
  import { getDefaultExportOptions } from "magicast/helpers";
9
8
  import { detect, resolveCommand } from "package-manager-detector";
9
+ import colors from "picocolors";
10
10
  import prompts from "prompts";
11
11
  import maxSatisfying from "semver/ranges/max-satisfying.js";
12
12
  import yoctoSpinner from "yocto-spinner";
@@ -30,6 +30,7 @@ import { eventCliSession, telemetry } from "../../events/index.js";
30
30
  import { exec } from "../exec.js";
31
31
  import { createLoggerFromFlags, flagsToAstroInlineConfig } from "../flags.js";
32
32
  import { fetchPackageJson, fetchPackageVersions } from "../install-package.js";
33
+ const { bold, cyan, dim, green, magenta, red, yellow } = colors;
33
34
  const ALIASES = /* @__PURE__ */ new Map([
34
35
  ["solid", "solid-js"],
35
36
  ["tailwindcss", "tailwind"]
@@ -61,7 +62,25 @@ export default defineDb({
61
62
  export default async function seed() {
62
63
  // TODO
63
64
  }
64
- `
65
+ `,
66
+ CLOUDFLARE_WRANGLER_CONFIG: (name) => `{
67
+ "main": "dist/_worker.js/index.js",
68
+ "name": ${JSON.stringify(name)},
69
+ "compatibility_date": ${JSON.stringify((/* @__PURE__ */ new Date()).toISOString().slice(0, 10))},
70
+ "compatibility_flags": [
71
+ "nodejs_compat",
72
+ "global_fetch_strictly_public"
73
+ ],
74
+ "assets": {
75
+ "binding": "ASSETS",
76
+ "directory": "./dist"
77
+ },
78
+ "observability": {
79
+ "enabled": true
80
+ }
81
+ }`,
82
+ CLOUDFLARE_ASSETSIGNORE: `_worker.js
83
+ _routes.json`
65
84
  };
66
85
  const OFFICIAL_ADAPTER_TO_IMPORT_MAP = {
67
86
  netlify: "@astrojs/netlify",
@@ -122,8 +141,79 @@ async function add(names, { flags }) {
122
141
  const rootPath = resolveRoot(cwd);
123
142
  const root = pathToFileURL(rootPath);
124
143
  root.href = appendForwardSlash(root.href);
144
+ const rawConfigPath = await resolveConfigPath({
145
+ root: rootPath,
146
+ configFile: inlineConfig.configFile,
147
+ fs: fsMod
148
+ });
149
+ let configURL = rawConfigPath ? pathToFileURL(rawConfigPath) : void 0;
150
+ if (configURL) {
151
+ logger.debug("add", `Found config at ${configURL}`);
152
+ } else {
153
+ logger.info("add", `Unable to locate a config file, generating one for you.`);
154
+ configURL = new URL("./astro.config.mjs", root);
155
+ await fs.writeFile(fileURLToPath(configURL), STUBS.ASTRO_CONFIG, { encoding: "utf-8" });
156
+ }
157
+ let packageJson = { type: "unknown" };
158
+ async function getPackageJson() {
159
+ if (packageJson.type === "exists") {
160
+ return packageJson.data;
161
+ }
162
+ if (packageJson.type === "does-not-exist") {
163
+ return null;
164
+ }
165
+ const pkgURL = new URL("./package.json", configURL);
166
+ if (existsSync(pkgURL)) {
167
+ packageJson = {
168
+ type: "exists",
169
+ data: await fs.readFile(fileURLToPath(pkgURL)).then((res) => JSON.parse(res.toString()))
170
+ };
171
+ return packageJson.data;
172
+ }
173
+ packageJson = { type: "does-not-exist" };
174
+ return null;
175
+ }
125
176
  switch (installResult) {
126
177
  case 1 /* updated */: {
178
+ if (integrations.find((integration) => integration.id === "cloudflare")) {
179
+ const wranglerConfigURL = new URL("./wrangler.jsonc", configURL);
180
+ if (!existsSync(wranglerConfigURL)) {
181
+ logger.info(
182
+ "SKIP_FORMAT",
183
+ `
184
+ ${magenta(`Astro will scaffold ${green("./wrangler.jsonc")}.`)}
185
+ `
186
+ );
187
+ if (await askToContinue({ flags })) {
188
+ const data = await getPackageJson();
189
+ await fs.writeFile(
190
+ wranglerConfigURL,
191
+ STUBS.CLOUDFLARE_WRANGLER_CONFIG(data?.name ?? "example"),
192
+ "utf-8"
193
+ );
194
+ }
195
+ } else {
196
+ logger.debug("add", "Using existing wrangler configuration");
197
+ }
198
+ const dir = new URL(userConfig.publicDir ?? "./public/", root);
199
+ const assetsignore = new URL("./.assetsignore", dir);
200
+ if (!existsSync(assetsignore)) {
201
+ logger.info(
202
+ "SKIP_FORMAT",
203
+ `
204
+ ${magenta(`Astro will scaffold ${green("./public/.assetsignore")}.`)}
205
+ `
206
+ );
207
+ if (await askToContinue({ flags })) {
208
+ if (!existsSync(dir)) {
209
+ await fs.mkdir(dir);
210
+ }
211
+ await fs.writeFile(assetsignore, STUBS.CLOUDFLARE_ASSETSIGNORE, "utf-8");
212
+ }
213
+ } else {
214
+ logger.debug("add", `Using existing .assetsignore`);
215
+ }
216
+ }
127
217
  if (integrations.find((integration) => integration.id === "tailwind")) {
128
218
  const dir = new URL("./styles/", new URL(userConfig.srcDir ?? "./src/", root));
129
219
  const styles = new URL("./global.css", dir);
@@ -219,19 +309,6 @@ async function add(names, { flags }) {
219
309
  case 0 /* none */:
220
310
  break;
221
311
  }
222
- const rawConfigPath = await resolveConfigPath({
223
- root: rootPath,
224
- configFile: inlineConfig.configFile,
225
- fs: fsMod
226
- });
227
- let configURL = rawConfigPath ? pathToFileURL(rawConfigPath) : void 0;
228
- if (configURL) {
229
- logger.debug("add", `Found config at ${configURL}`);
230
- } else {
231
- logger.info("add", `Unable to locate a config file, generating one for you.`);
232
- configURL = new URL("./astro.config.mjs", root);
233
- await fs.writeFile(fileURLToPath(configURL), STUBS.ASTRO_CONFIG, { encoding: "utf-8" });
234
- }
235
312
  let mod;
236
313
  try {
237
314
  mod = await loadFile(fileURLToPath(configURL));
@@ -294,9 +371,9 @@ async function add(names, { flags }) {
294
371
  break;
295
372
  }
296
373
  case 0 /* none */: {
297
- const pkgURL = new URL("./package.json", configURL);
298
- if (existsSync(fileURLToPath(pkgURL))) {
299
- const { dependencies = {}, devDependencies = {} } = await fs.readFile(fileURLToPath(pkgURL)).then((res) => JSON.parse(res.toString()));
374
+ const data = await getPackageJson();
375
+ if (data) {
376
+ const { dependencies = {}, devDependencies = {} } = data;
300
377
  const deps = Object.keys(Object.assign(dependencies, devDependencies));
301
378
  const missingDeps = integrations.filter(
302
379
  (integration) => !deps.includes(integration.packageName)
@@ -1,4 +1,4 @@
1
- import { cyan } from "kleur/colors";
1
+ import colors from "picocolors";
2
2
  import devServer from "../../core/dev/index.js";
3
3
  import { printHelp } from "../../core/messages.js";
4
4
  import { flagsToAstroInlineConfig } from "../flags.js";
@@ -22,7 +22,7 @@ async function dev({ flags }) {
22
22
  ["--help (-h)", "See all available flags."]
23
23
  ]
24
24
  },
25
- description: `Check ${cyan(
25
+ description: `Check ${colors.cyan(
26
26
  "https://docs.astro.build/en/reference/cli-reference/#astro-dev"
27
27
  )} for more information.`
28
28
  });
@@ -0,0 +1,19 @@
1
+ import type { Logger } from '../../../core/logger/core.js';
2
+ import type { CommandExecutor, PlatformProvider } from '../definitions.js';
3
+ interface Options {
4
+ url: string;
5
+ platformProvider: PlatformProvider;
6
+ logger: Logger;
7
+ commandExecutor: CommandExecutor;
8
+ }
9
+ export declare const openDocsCommand: {
10
+ help: {
11
+ commandName: string;
12
+ tables: {
13
+ Flags: [string, string][];
14
+ };
15
+ description: string;
16
+ };
17
+ run({ url, platformProvider, logger, commandExecutor }: Options): Promise<void>;
18
+ };
19
+ export {};
@@ -0,0 +1,49 @@
1
+ import { defineCommand } from "../../domain/command.js";
2
+ function getExecInputForPlatform(platform) {
3
+ switch (platform) {
4
+ case "android":
5
+ case "linux":
6
+ return ["xdg-open"];
7
+ case "darwin":
8
+ return ["open"];
9
+ case "win32":
10
+ return ["cmd", ["/c", "start"]];
11
+ case "gitpod":
12
+ return ["/ide/bin/remote-cli/gitpod-code", ["--openExternal"]];
13
+ case "aix":
14
+ case "freebsd":
15
+ case "haiku":
16
+ case "openbsd":
17
+ case "sunos":
18
+ case "cygwin":
19
+ case "netbsd":
20
+ default:
21
+ return null;
22
+ }
23
+ }
24
+ const openDocsCommand = defineCommand({
25
+ help: {
26
+ commandName: "astro docs",
27
+ tables: {
28
+ Flags: [["--help (-h)", "See all available flags."]]
29
+ },
30
+ description: `Launches the Astro Docs website directly from the terminal.`
31
+ },
32
+ async run({ url, platformProvider, logger, commandExecutor }) {
33
+ const platform = platformProvider.get();
34
+ const input = getExecInputForPlatform(platform);
35
+ if (!input) {
36
+ logger.error(
37
+ "SKIP_FORMAT",
38
+ `It looks like your platform ("${platform}") isn't supported!
39
+ To view Astro's docs, please visit ${url}`
40
+ );
41
+ return;
42
+ }
43
+ const [command, args = []] = input;
44
+ await commandExecutor.execute(command, [...args, encodeURI(url)]);
45
+ }
46
+ });
47
+ export {
48
+ openDocsCommand
49
+ };
@@ -0,0 +1,12 @@
1
+ import type { Platform } from './domains/platform.js';
2
+ export interface PlatformProvider {
3
+ get: () => Platform;
4
+ }
5
+ export interface CommandExecutor {
6
+ execute: (command: string, args?: Array<string>, options?: {
7
+ cwd?: string;
8
+ env: Record<string, string | undefined>;
9
+ }) => Promise<{
10
+ stdout: string;
11
+ }>;
12
+ }
File without changes
@@ -0,0 +1 @@
1
+ export type Platform = NodeJS.Platform | 'gitpod';
File without changes
@@ -0,0 +1,2 @@
1
+ import type { PlatformProvider } from '../definitions.js';
2
+ export declare function createProcessPlatformProvider(): PlatformProvider;
@@ -0,0 +1,11 @@
1
+ function createProcessPlatformProvider() {
2
+ const platform = Boolean(process.env.GITPOD_REPO_ROOT) ? "gitpod" : process.platform;
3
+ return {
4
+ get() {
5
+ return platform;
6
+ }
7
+ };
8
+ }
9
+ export {
10
+ createProcessPlatformProvider
11
+ };
@@ -0,0 +1,2 @@
1
+ import type { CommandExecutor } from '../definitions.js';
2
+ export declare function createTinyexecCommandExecutor(): CommandExecutor;
@@ -0,0 +1,30 @@
1
+ import { NonZeroExitError, x } from "tinyexec";
2
+ function createTinyexecCommandExecutor() {
3
+ return {
4
+ async execute(command, args, options) {
5
+ return await x(command, args, {
6
+ throwOnError: true,
7
+ nodeOptions: {
8
+ cwd: options?.cwd,
9
+ env: options?.env
10
+ }
11
+ }).then(
12
+ (o) => o,
13
+ (e) => {
14
+ if (e instanceof NonZeroExitError) {
15
+ const fullCommand = args?.length ? `${command} ${args.map((a) => a.includes(" ") ? `"${a}"` : a).join(" ")}` : command;
16
+ const message = `The command \`${fullCommand}\` exited with code ${e.exitCode}`;
17
+ const newError = new Error(message, e.cause ? { cause: e.cause } : void 0);
18
+ newError.stderr = e.output?.stderr;
19
+ newError.stdout = e.output?.stdout;
20
+ throw newError;
21
+ }
22
+ throw e;
23
+ }
24
+ );
25
+ }
26
+ };
27
+ }
28
+ export {
29
+ createTinyexecCommandExecutor
30
+ };
@@ -1,5 +1,6 @@
1
1
  import { type Options } from 'tinyexec';
2
2
  /**
3
3
  * Improve tinyexec error logging and set `throwOnError` to `true` by default
4
+ * @deprecated use CommandExecutor instead
4
5
  */
5
6
  export declare function exec(command: string, args?: string[], options?: Partial<Options>): PromiseLike<import("tinyexec").Output>;
package/dist/cli/index.js CHANGED
@@ -1,10 +1,4 @@
1
- import * as colors from "kleur/colors";
2
1
  import yargs from "yargs-parser";
3
- import { ASTRO_VERSION } from "../core/constants.js";
4
- function printVersion() {
5
- console.log();
6
- console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${ASTRO_VERSION}`)}`);
7
- }
8
2
  function resolveCommand(flags) {
9
3
  const cmd = flags._[2];
10
4
  if (flags.version) return "version";
@@ -34,19 +28,19 @@ function resolveCommand(flags) {
34
28
  async function runCommand(cmd, flags) {
35
29
  const [
36
30
  { createLoggerFromFlags },
37
- { createKleurTextStyler },
31
+ { createPicocolorsTextStyler },
38
32
  { createBuildTimeAstroVersionProvider },
39
33
  { createLoggerHelpDisplay },
40
34
  { createCliCommandRunner }
41
35
  ] = await Promise.all([
42
36
  import("./flags.js"),
43
- import("./infra/kleur-text-styler.js"),
37
+ import("./infra/picocolors-text-styler.js"),
44
38
  import("./infra/build-time-astro-version-provider.js"),
45
39
  import("./infra/logger-help-display.js"),
46
40
  import("./infra/cli-command-runner.js")
47
41
  ]);
48
42
  const logger = createLoggerFromFlags(flags);
49
- const textStyler = createKleurTextStyler();
43
+ const textStyler = createPicocolorsTextStyler();
50
44
  const astroVersionProvider = createBuildTimeAstroVersionProvider();
51
45
  const helpDisplay = createLoggerHelpDisplay({
52
46
  logger,
@@ -62,8 +56,13 @@ async function runCommand(cmd, flags) {
62
56
  helpDisplay.show(DEFAULT_HELP_PAYLOAD);
63
57
  return;
64
58
  }
59
+ /** Display --version flag */
65
60
  case "version": {
66
- printVersion();
61
+ const { formatVersion } = await import("./utils/format-version.js");
62
+ logger.info(
63
+ "SKIP_FORMAT",
64
+ formatVersion({ name: "astro", textStyler, astroVersionProvider })
65
+ );
67
66
  return;
68
67
  }
69
68
  case "info": {
@@ -80,9 +79,23 @@ async function runCommand(cmd, flags) {
80
79
  return await runner.run(createKeyCommand, { logger, keyGenerator });
81
80
  }
82
81
  case "docs": {
83
- const { docs } = await import("./docs/index.js");
84
- await docs({ flags });
85
- return;
82
+ const [
83
+ { createTinyexecCommandExecutor },
84
+ { createProcessPlatformProvider },
85
+ { openDocsCommand }
86
+ ] = await Promise.all([
87
+ import("./docs/infra/tinyexec-command-executor.js"),
88
+ import("./docs/infra/process-platform-provider.js"),
89
+ import("./docs/core/open-docs.js")
90
+ ]);
91
+ const commandExecutor = createTinyexecCommandExecutor();
92
+ const platformProvider = createProcessPlatformProvider();
93
+ return await runner.run(openDocsCommand, {
94
+ url: "https://docs.astro.build/",
95
+ logger,
96
+ commandExecutor,
97
+ platformProvider
98
+ });
86
99
  }
87
100
  case "telemetry": {
88
101
  const { update } = await import("./telemetry/index.js");
@@ -1,6 +1,6 @@
1
1
  import { spawn, spawnSync } from "node:child_process";
2
2
  import { arch, platform } from "node:os";
3
- import * as colors from "kleur/colors";
3
+ import colors from "picocolors";
4
4
  import prompts from "prompts";
5
5
  import { resolveConfig } from "../../core/config/index.js";
6
6
  import { ASTRO_VERSION } from "../../core/constants.js";
@@ -1,7 +1,8 @@
1
1
  function createBuildTimeAstroVersionProvider() {
2
+ const version = "5.15.0";
2
3
  return {
3
4
  getVersion() {
4
- return "5.14.8";
5
+ return version;
5
6
  }
6
7
  };
7
8
  }
@@ -1,3 +1,4 @@
1
+ import { formatVersion } from "../utils/format-version.js";
1
2
  function createLoggerHelpDisplay({
2
3
  logger,
3
4
  flags,
@@ -29,9 +30,7 @@ function createLoggerHelpDisplay({
29
30
  if (headline) {
30
31
  message.push(
31
32
  linebreak(),
32
- ` ${textStyler.bgGreen(textStyler.black(` ${commandName} `))} ${textStyler.green(
33
- `v${astroVersionProvider.getVersion()}`
34
- )} ${headline}`
33
+ `${formatVersion({ name: commandName, textStyler, astroVersionProvider })} ${headline}`
35
34
  );
36
35
  }
37
36
  if (usage) {
@@ -0,0 +1,2 @@
1
+ import type { TextStyler } from '../definitions.js';
2
+ export declare function createPicocolorsTextStyler(): TextStyler;
@@ -0,0 +1,7 @@
1
+ import colors from "picocolors";
2
+ function createPicocolorsTextStyler() {
3
+ return colors;
4
+ }
5
+ export {
6
+ createPicocolorsTextStyler
7
+ };