astro 2.6.1 → 2.6.2

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/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import * as colors from "kleur/colors";
3
3
  import yargs from "yargs-parser";
4
- import { z } from "zod";
4
+ import { ZodError } from "zod";
5
5
  import {
6
6
  createSettings,
7
7
  openConfig,
@@ -69,15 +69,19 @@ function resolveCommand(flags) {
69
69
  }
70
70
  return "help";
71
71
  }
72
- async function handleConfigError(e, { cwd, flags, logging }) {
72
+ async function handleConfigError(e, { cmd, cwd, flags, logging }) {
73
73
  const path = await resolveConfigPath({ cwd, flags, fs });
74
- if (e instanceof Error) {
75
- if (path) {
76
- error(logging, "astro", `Unable to load ${colors.bold(path)}
74
+ error(logging, "astro", `Unable to load ${path ? colors.bold(path) : "your Astro config"}
77
75
  `);
78
- }
76
+ if (e instanceof ZodError) {
77
+ console.error(formatConfigErrorMessage(e) + "\n");
78
+ } else if (e instanceof Error) {
79
79
  console.error(formatErrorMessage(collectErrorMetadata(e)) + "\n");
80
80
  }
81
+ const telemetryPromise = telemetry.record(eventConfigError({ cmd, err: e, isFatal: true }));
82
+ await telemetryPromise.catch(
83
+ (err2) => debug("telemetry", `record() error: ${err2.message}`)
84
+ );
81
85
  }
82
86
  async function runCommand(cmd, flags) {
83
87
  var _a;
@@ -136,7 +140,7 @@ async function runCommand(cmd, flags) {
136
140
  cmd,
137
141
  logging
138
142
  }).catch(async (e) => {
139
- await handleConfigError(e, { cwd: root, flags, logging });
143
+ await handleConfigError(e, { cmd, cwd: root, flags, logging });
140
144
  return {};
141
145
  });
142
146
  if (!initialAstroConfig)
@@ -155,7 +159,7 @@ async function runCommand(cmd, flags) {
155
159
  logging,
156
160
  telemetry,
157
161
  handleConfigError(e) {
158
- handleConfigError(e, { cwd: root, flags, logging });
162
+ handleConfigError(e, { cmd, cwd: root, flags, logging });
159
163
  info(logging, "astro", "Continuing with previous valid configuration\n");
160
164
  }
161
165
  });
@@ -218,14 +222,9 @@ async function throwAndExit(cmd, err) {
218
222
  console.error(errorMessage);
219
223
  process.exit(1);
220
224
  }
221
- if (err instanceof z.ZodError) {
222
- telemetryPromise = telemetry.record(eventConfigError({ cmd, err, isFatal: true }));
223
- errorMessage = formatConfigErrorMessage(err);
224
- } else {
225
- const errorWithMetadata = collectErrorMetadata(createSafeError(err));
226
- telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true }));
227
- errorMessage = formatErrorMessage(errorWithMetadata);
228
- }
225
+ const errorWithMetadata = collectErrorMetadata(createSafeError(err));
226
+ telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true }));
227
+ errorMessage = formatErrorMessage(errorWithMetadata);
229
228
  setTimeout(exitWithErrorMessage, 400);
230
229
  await telemetryPromise.catch((err2) => debug("telemetry", `record() error: ${err2.message}`)).then(exitWithErrorMessage);
231
230
  }
@@ -55,6 +55,12 @@ const OFFICIAL_ADAPTER_TO_IMPORT_MAP = {
55
55
  node: "@astrojs/node",
56
56
  deno: "@astrojs/deno"
57
57
  };
58
+ async function getRegistry() {
59
+ var _a;
60
+ const packageManager = ((_a = await preferredPM(process.cwd())) == null ? void 0 : _a.name) || "npm";
61
+ const { stdout } = await execa(packageManager, ["config", "get", "registry"]);
62
+ return stdout || "https://registry.npmjs.org";
63
+ }
58
64
  async function add(names, { cwd, flags, logging, telemetry }) {
59
65
  var _a;
60
66
  applyPolyfill();
@@ -561,7 +567,8 @@ ${message}`
561
567
  }
562
568
  async function fetchPackageJson(scope, name, tag) {
563
569
  const packageName = `${scope ? `${scope}/` : ""}${name}`;
564
- const res = await fetch(`https://registry.npmjs.org/${packageName}/${tag}`);
570
+ const registry = await getRegistry();
571
+ const res = await fetch(`${registry}/${packageName}/${tag}`);
565
572
  if (res.status === 404) {
566
573
  return new Error();
567
574
  } else {
@@ -20,7 +20,7 @@ import { runHookBuildGenerated } from "../../integrations/index.js";
20
20
  import { isServerLikeOutput } from "../../prerender/utils.js";
21
21
  import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
22
22
  import { callEndpoint, createAPIContext, throwIfRedirectNotAllowed } from "../endpoint/index.js";
23
- import { AstroError } from "../errors/index.js";
23
+ import { AstroError, AstroErrorData } from "../errors/index.js";
24
24
  import { debug, info } from "../logger/core.js";
25
25
  import { callMiddleware } from "../middleware/callMiddleware.js";
26
26
  import {
@@ -221,7 +221,16 @@ async function getPathsForRoute(pageData, mod, opts, builtPaths) {
221
221
  throw err;
222
222
  });
223
223
  opts.routeCache.set(route, result);
224
- paths = result.staticPaths.map((staticPath) => staticPath.params && route.generate(staticPath.params)).filter((staticPath) => {
224
+ paths = result.staticPaths.map((staticPath) => {
225
+ try {
226
+ return route.generate(staticPath.params);
227
+ } catch (e) {
228
+ if (e instanceof TypeError) {
229
+ throw getInvalidRouteSegmentError(e, route, staticPath);
230
+ }
231
+ throw e;
232
+ }
233
+ }).filter((staticPath) => {
225
234
  if (!builtPaths.has(removeTrailingForwardSlash(staticPath))) {
226
235
  return true;
227
236
  }
@@ -234,6 +243,33 @@ async function getPathsForRoute(pageData, mod, opts, builtPaths) {
234
243
  }
235
244
  return paths;
236
245
  }
246
+ function getInvalidRouteSegmentError(e, route, staticPath) {
247
+ var _a, _b;
248
+ const invalidParam = (_a = e.message.match(/^Expected "([^"]+)"/)) == null ? void 0 : _a[1];
249
+ const received = invalidParam ? staticPath.params[invalidParam] : void 0;
250
+ let hint = "Learn about dynamic routes at https://docs.astro.build/en/core-concepts/routing/#dynamic-routes";
251
+ if (invalidParam && typeof received === "string") {
252
+ const matchingSegment = (_b = route.segments.find(
253
+ (segment) => {
254
+ var _a2;
255
+ return ((_a2 = segment[0]) == null ? void 0 : _a2.content) === invalidParam;
256
+ }
257
+ )) == null ? void 0 : _b[0];
258
+ const mightBeMissingSpread = (matchingSegment == null ? void 0 : matchingSegment.dynamic) && !(matchingSegment == null ? void 0 : matchingSegment.spread);
259
+ if (mightBeMissingSpread) {
260
+ hint = `If the param contains slashes, try using a rest parameter: **[...${invalidParam}]**. Learn more at https://docs.astro.build/en/core-concepts/routing/#dynamic-routes`;
261
+ }
262
+ }
263
+ return new AstroError({
264
+ ...AstroErrorData.InvalidDynamicRoute,
265
+ message: invalidParam ? AstroErrorData.InvalidDynamicRoute.message(
266
+ route.route,
267
+ JSON.stringify(invalidParam),
268
+ JSON.stringify(received)
269
+ ) : `Generated path for ${route.route} is invalid.`,
270
+ hint
271
+ });
272
+ }
237
273
  function shouldAppendForwardSlash(trailingSlash, buildFormat) {
238
274
  switch (trailingSlash) {
239
275
  case "always":
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.6.1";
1
+ const ASTRO_VERSION = "2.6.2";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -53,7 +53,7 @@ async function dev(settings, options) {
53
53
  isRestart: options.isRestart
54
54
  })
55
55
  );
56
- const currentVersion = "2.6.1";
56
+ const currentVersion = "2.6.2";
57
57
  if (currentVersion.includes("-")) {
58
58
  warn(options.logging, null, msg.prerelease({ currentVersion }));
59
59
  }
@@ -115,7 +115,7 @@ function isRedirect(statusCode) {
115
115
  return statusCode >= 300 && statusCode < 400;
116
116
  }
117
117
  function throwIfRedirectNotAllowed(response, config) {
118
- if (!isServerLikeOutput(config) && isRedirect(response.status)) {
118
+ if (!isServerLikeOutput(config) && isRedirect(response.status) && !config.experimental.redirects) {
119
119
  throw new AstroError(AstroErrorData.StaticRedirectNotAvailable);
120
120
  }
121
121
  }
@@ -655,6 +655,18 @@ export declare const AstroErrorData: {
655
655
  readonly title: "A redirect must be given a location with the `Location` header.";
656
656
  readonly code: 3037;
657
657
  };
658
+ /**
659
+ * @docs
660
+ * @see
661
+ * - [Dynamic routes](https://docs.astro.build/en/core-concepts/routing/#dynamic-routes)
662
+ * @description
663
+ * A dynamic route param is invalid. This is often caused by an `undefined` parameter or a missing [rest parameter](https://docs.astro.build/en/core-concepts/routing/#rest-parameters).
664
+ */
665
+ readonly InvalidDynamicRoute: {
666
+ readonly title: "Invalid dynamic route.";
667
+ readonly code: 3038;
668
+ readonly message: (route: string, invalidParam: string, received: string) => string;
669
+ };
658
670
  /**
659
671
  * @docs
660
672
  * @see
@@ -689,6 +689,18 @@ Expected \`${defaultExpectedValue}\` value but got \`${suffix}\`.`;
689
689
  title: "A redirect must be given a location with the `Location` header.",
690
690
  code: 3037
691
691
  },
692
+ /**
693
+ * @docs
694
+ * @see
695
+ * - [Dynamic routes](https://docs.astro.build/en/core-concepts/routing/#dynamic-routes)
696
+ * @description
697
+ * A dynamic route param is invalid. This is often caused by an `undefined` parameter or a missing [rest parameter](https://docs.astro.build/en/core-concepts/routing/#rest-parameters).
698
+ */
699
+ InvalidDynamicRoute: {
700
+ title: "Invalid dynamic route.",
701
+ code: 3038,
702
+ message: (route, invalidParam, received) => `The ${invalidParam} param for route ${route} is invalid. Received **${received}**.`
703
+ },
692
704
  // No headings here, that way Vite errors are merged with Astro ones in the docs, which makes more sense to users.
693
705
  // Vite Errors - 4xxx
694
706
  /**
@@ -47,7 +47,7 @@ function serverStart({
47
47
  base,
48
48
  isRestart = false
49
49
  }) {
50
- const version = "2.6.1";
50
+ const version = "2.6.2";
51
51
  const localPrefix = `${dim("\u2503")} Local `;
52
52
  const networkPrefix = `${dim("\u2503")} Network `;
53
53
  const emptyPrefix = " ".repeat(11);
@@ -233,7 +233,7 @@ function printHelp({
233
233
  message.push(
234
234
  linebreak(),
235
235
  ` ${bgGreen(black(` ${commandName} `))} ${green(
236
- `v${"2.6.1"}`
236
+ `v${"2.6.2"}`
237
237
  )} ${headline}`
238
238
  );
239
239
  }
@@ -1,13 +1,14 @@
1
1
  import type { AstroSettings, RouteData } from '../@types/astro';
2
- import { type DevelopmentEnvironment } from '../core/render/dev/index.js';
2
+ import { type ComponentPreload, type DevelopmentEnvironment } from '../core/render/dev/index.js';
3
3
  type GetSortedPreloadedMatchesParams = {
4
4
  env: DevelopmentEnvironment;
5
5
  matches: RouteData[];
6
6
  settings: AstroSettings;
7
7
  };
8
- export declare function getSortedPreloadedMatches({ env, matches, settings, }: GetSortedPreloadedMatchesParams): Promise<{
9
- readonly preloadedComponent: import("../core/render/dev/index.js").ComponentPreload;
10
- readonly route: RouteData;
11
- readonly filePath: URL;
12
- }[]>;
8
+ export declare function getSortedPreloadedMatches({ env, matches, settings, }: GetSortedPreloadedMatchesParams): Promise<PreloadAndSetPrerenderStatusResult[]>;
9
+ type PreloadAndSetPrerenderStatusResult = {
10
+ filePath: URL;
11
+ route: RouteData;
12
+ preloadedComponent: ComponentPreload;
13
+ };
13
14
  export {};
@@ -1,4 +1,7 @@
1
- import { preload } from "../core/render/dev/index.js";
1
+ import { RedirectComponentInstance, routeIsRedirect } from "../core/redirects/index.js";
2
+ import {
3
+ preload
4
+ } from "../core/render/dev/index.js";
2
5
  import { getPrerenderStatus } from "./metadata.js";
3
6
  async function getSortedPreloadedMatches({
4
7
  env,
@@ -19,6 +22,14 @@ async function preloadAndSetPrerenderStatus({
19
22
  const preloaded = await Promise.all(
20
23
  matches.map(async (route) => {
21
24
  const filePath = new URL(`./${route.component}`, settings.config.root);
25
+ if (routeIsRedirect(route)) {
26
+ const preloadedComponent2 = [[], RedirectComponentInstance];
27
+ return {
28
+ preloadedComponent: preloadedComponent2,
29
+ route,
30
+ filePath
31
+ };
32
+ }
22
33
  const preloadedComponent = await preload({ env, filePath });
23
34
  const prerenderStatus = getPrerenderStatus({
24
35
  filePath,
@@ -8,7 +8,7 @@ export type { AstroComponentFactory, AstroComponentInstance, ComponentSlots, Ren
8
8
  export declare function mergeSlots(...slotted: unknown[]): Record<string, () => any>;
9
9
  /** @internal Associate JSX components with a specific renderer (see /src/vite-plugin-jsx/tag.ts) */
10
10
  export declare function __astro_tag_component__(Component: unknown, rendererName: string): void;
11
- export declare function spreadAttributes(values: Record<any, any>, _name?: string, { class: scopedClassName }?: {
11
+ export declare function spreadAttributes(values?: Record<any, any>, _name?: string, { class: scopedClassName }?: {
12
12
  class?: string;
13
13
  }): any;
14
14
  export declare function defineStyleVars(defs: Record<any, any> | Record<any, any>[]): any;
@@ -59,7 +59,7 @@ function __astro_tag_component__(Component, rendererName) {
59
59
  writable: false
60
60
  });
61
61
  }
62
- function spreadAttributes(values, _name, { class: scopedClassName } = {}) {
62
+ function spreadAttributes(values = {}, _name, { class: scopedClassName } = {}) {
63
63
  let output = "";
64
64
  if (scopedClassName) {
65
65
  if (typeof values.class !== "undefined") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
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",