astro 2.8.1 → 2.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/components/Code.astro +1 -1
  2. package/dist/@types/astro.d.ts +1 -1
  3. package/dist/assets/consts.d.ts +4 -4
  4. package/dist/assets/consts.js +11 -3
  5. package/dist/assets/services/service.d.ts +1 -1
  6. package/dist/assets/services/service.js +6 -3
  7. package/dist/assets/services/sharp.js +3 -0
  8. package/dist/assets/services/squoosh.js +25 -0
  9. package/dist/assets/types.d.ts +1 -0
  10. package/dist/assets/utils/emitAsset.d.ts +2 -2
  11. package/dist/assets/utils/metadata.d.ts +1 -4
  12. package/dist/cli/add/index.d.ts +1 -2
  13. package/dist/cli/add/index.js +4 -1
  14. package/dist/cli/build/index.d.ts +8 -0
  15. package/dist/cli/build/index.js +16 -0
  16. package/dist/cli/check/index.d.ts +1 -2
  17. package/dist/cli/check/index.js +5 -1
  18. package/dist/cli/dev/index.d.ts +8 -0
  19. package/dist/cli/dev/index.js +26 -0
  20. package/dist/cli/index.js +34 -101
  21. package/dist/cli/info/index.d.ts +1 -2
  22. package/dist/cli/info/index.js +2 -2
  23. package/dist/cli/load-settings.d.ts +15 -0
  24. package/dist/cli/load-settings.js +39 -0
  25. package/dist/cli/preview/index.d.ts +8 -0
  26. package/dist/cli/preview/index.js +11 -0
  27. package/dist/cli/sync/index.d.ts +8 -0
  28. package/dist/cli/sync/index.js +13 -0
  29. package/dist/cli/throw-and-exit.d.ts +2 -0
  30. package/dist/cli/throw-and-exit.js +21 -0
  31. package/dist/content/runtime-assets.d.ts +1 -1
  32. package/dist/core/build/generate.js +8 -1
  33. package/dist/core/build/static-build.js +5 -2
  34. package/dist/core/config/config.d.ts +0 -1
  35. package/dist/core/config/config.js +27 -97
  36. package/dist/core/config/index.d.ts +1 -0
  37. package/dist/core/config/index.js +2 -0
  38. package/dist/core/config/merge.d.ts +1 -0
  39. package/dist/core/config/merge.js +50 -0
  40. package/dist/core/config/schema.js +1 -6
  41. package/dist/core/config/vite-load.d.ts +2 -10
  42. package/dist/core/config/vite-load.js +15 -28
  43. package/dist/core/constants.js +1 -1
  44. package/dist/core/dev/dev.js +1 -1
  45. package/dist/core/errors/errors-data.d.ts +1 -1
  46. package/dist/core/errors/errors-data.js +2 -2
  47. package/dist/core/messages.js +2 -2
  48. package/dist/core/routing/manifest/create.js +19 -0
  49. package/dist/events/error.js +1 -5
  50. package/dist/integrations/index.js +1 -1
  51. package/dist/runtime/server/response.js +7 -0
  52. package/package.json +1 -1
@@ -3,7 +3,7 @@ import type * as shiki from 'shiki';
3
3
  import { renderToHtml } from 'shiki';
4
4
  import { getHighlighter } from './Shiki.js';
5
5
 
6
- export interface Props {
6
+ interface Props {
7
7
  /** The code to highlight. Required. */
8
8
  code: string;
9
9
  /**
@@ -788,7 +788,7 @@ export interface AstroUserConfig {
788
788
  * @docs
789
789
  * @name build.excludeMiddleware
790
790
  * @type {boolean}
791
- * @default {false}
791
+ * @default `false`
792
792
  * @version 2.8.0
793
793
  * @description
794
794
  * Defines whether or not any SSR middleware code will be bundled when built.
@@ -2,8 +2,8 @@ export declare const VIRTUAL_MODULE_ID = "astro:assets";
2
2
  export declare const VIRTUAL_SERVICE_ID = "virtual:image-service";
3
3
  export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg"];
4
4
  /**
5
- * Valid formats for optimizations in our base services.
6
- * Certain formats can be imported (namely SVGs) but not processed, so they are excluded from this list.
5
+ * Valid formats that our base services support.
6
+ * Certain formats can be imported (namely SVGs) but will not be processed.
7
7
  */
8
- export declare const VALID_OPTIMIZABLE_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif"];
9
- export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg"];
8
+ export declare const VALID_SUPPORTED_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg"];
9
+ export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg", "svg"];
@@ -17,12 +17,20 @@ const VALID_INPUT_FORMATS = [
17
17
  "gif",
18
18
  "svg"
19
19
  ];
20
- const VALID_OPTIMIZABLE_FORMATS = ["jpeg", "jpg", "png", "tiff", "webp", "gif"];
21
- const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg"];
20
+ const VALID_SUPPORTED_FORMATS = [
21
+ "jpeg",
22
+ "jpg",
23
+ "png",
24
+ "tiff",
25
+ "webp",
26
+ "gif",
27
+ "svg"
28
+ ];
29
+ const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg", "svg"];
22
30
  export {
23
31
  VALID_INPUT_FORMATS,
24
- VALID_OPTIMIZABLE_FORMATS,
25
32
  VALID_OUTPUT_FORMATS,
33
+ VALID_SUPPORTED_FORMATS,
26
34
  VIRTUAL_MODULE_ID,
27
35
  VIRTUAL_SERVICE_ID
28
36
  };
@@ -31,7 +31,7 @@ interface SharedServiceProps {
31
31
  validateOptions?: (options: ImageTransform, serviceConfig: Record<string, any>) => ImageTransform;
32
32
  }
33
33
  export type ExternalImageService = SharedServiceProps;
34
- type LocalImageTransform = {
34
+ export type LocalImageTransform = {
35
35
  src: string;
36
36
  [key: string]: any;
37
37
  };
@@ -1,6 +1,6 @@
1
1
  import { AstroError, AstroErrorData } from "../../core/errors/index.js";
2
2
  import { joinPaths } from "../../core/path.js";
3
- import { VALID_OPTIMIZABLE_FORMATS } from "../consts.js";
3
+ import { VALID_SUPPORTED_FORMATS } from "../consts.js";
4
4
  import { isESMImportedImage } from "../internal.js";
5
5
  function isLocalService(service) {
6
6
  if (!service) {
@@ -45,16 +45,19 @@ const baseService = {
45
45
  });
46
46
  }
47
47
  } else {
48
- if (!VALID_OPTIMIZABLE_FORMATS.includes(options.src.format)) {
48
+ if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) {
49
49
  throw new AstroError({
50
50
  ...AstroErrorData.UnsupportedImageFormat,
51
51
  message: AstroErrorData.UnsupportedImageFormat.message(
52
52
  options.src.format,
53
53
  options.src.src,
54
- VALID_OPTIMIZABLE_FORMATS
54
+ VALID_SUPPORTED_FORMATS
55
55
  )
56
56
  });
57
57
  }
58
+ if (options.src.format === "svg") {
59
+ options.format = "svg";
60
+ }
58
61
  }
59
62
  if (!options.format) {
60
63
  options.format = "webp";
@@ -27,7 +27,10 @@ const sharpService = {
27
27
  if (!sharp)
28
28
  sharp = await loadSharp();
29
29
  const transform = transformOptions;
30
+ if (transform.format === "svg")
31
+ return { data: inputBuffer, format: "svg" };
30
32
  let result = sharp(inputBuffer, { failOnError: false, pages: -1 });
33
+ result.rotate();
31
34
  if (transform.height && !transform.width) {
32
35
  result.resize({ height: transform.height });
33
36
  } else if (transform.width) {
@@ -1,3 +1,4 @@
1
+ import { imageMetadata } from "../utils/metadata.js";
1
2
  import {
2
3
  baseService,
3
4
  parseQuality
@@ -17,6 +18,24 @@ const qualityTable = {
17
18
  webp: baseQuality
18
19
  // Squoosh's PNG encoder does not support a quality setting, so we can skip that here
19
20
  };
21
+ async function getRotationForEXIF(transform, inputBuffer) {
22
+ const filePath = transform.src.slice("/@fs".length);
23
+ const filePathURL = new URL("." + filePath, "file:");
24
+ const meta = await imageMetadata(filePathURL, inputBuffer);
25
+ if (!meta)
26
+ return void 0;
27
+ switch (meta.orientation) {
28
+ case 3:
29
+ case 4:
30
+ return { type: "rotate", numRotations: 2 };
31
+ case 5:
32
+ case 6:
33
+ return { type: "rotate", numRotations: 1 };
34
+ case 7:
35
+ case 8:
36
+ return { type: "rotate", numRotations: 3 };
37
+ }
38
+ }
20
39
  const service = {
21
40
  validateOptions: baseService.validateOptions,
22
41
  getURL: baseService.getURL,
@@ -25,7 +44,13 @@ const service = {
25
44
  async transform(inputBuffer, transformOptions) {
26
45
  const transform = transformOptions;
27
46
  let format = transform.format;
47
+ if (format === "svg")
48
+ return { data: inputBuffer, format: "svg" };
28
49
  const operations = [];
50
+ const rotation = await getRotationForEXIF(transform, inputBuffer);
51
+ if (rotation) {
52
+ operations.push(rotation);
53
+ }
29
54
  if (transform.height && !transform.width) {
30
55
  operations.push({
31
56
  type: "resize",
@@ -22,6 +22,7 @@ export interface ImageMetadata {
22
22
  width: number;
23
23
  height: number;
24
24
  format: ImageInputFormat;
25
+ orientation?: number;
25
26
  }
26
27
  /**
27
28
  * Options accepted by the image transformation service.
@@ -1,2 +1,2 @@
1
- import { type Metadata } from './metadata.js';
2
- export declare function emitESMImage(id: string | undefined, watchMode: boolean, fileEmitter: any): Promise<Metadata | undefined>;
1
+ import type { ImageMetadata } from '../types.js';
2
+ export declare function emitESMImage(id: string | undefined, watchMode: boolean, fileEmitter: any): Promise<ImageMetadata | undefined>;
@@ -1,6 +1,3 @@
1
1
  /// <reference types="node" />
2
2
  import type { ImageMetadata } from '../types.js';
3
- export interface Metadata extends ImageMetadata {
4
- orientation?: number;
5
- }
6
- export declare function imageMetadata(src: URL | string, data?: Buffer): Promise<Metadata | undefined>;
3
+ export declare function imageMetadata(src: URL | string, data?: Buffer): Promise<ImageMetadata | undefined>;
@@ -3,7 +3,6 @@ import { type LogOptions } from '../../core/logger/core.js';
3
3
  interface AddOptions {
4
4
  logging: LogOptions;
5
5
  flags: yargs.Arguments;
6
- cwd?: string;
7
6
  }
8
7
  interface IntegrationInfo {
9
8
  id: string;
@@ -11,6 +10,6 @@ interface IntegrationInfo {
11
10
  dependencies: [name: string, version: string][];
12
11
  type: 'integration' | 'adapter';
13
12
  }
14
- export declare function add(names: string[], { cwd, flags, logging }: AddOptions): Promise<void>;
13
+ export declare function add(names: string[], { flags, logging }: AddOptions): Promise<void>;
15
14
  export declare function validateIntegrations(integrations: string[]): Promise<IntegrationInfo[]>;
16
15
  export {};
@@ -20,6 +20,7 @@ import { printHelp } from "../../core/messages.js";
20
20
  import { appendForwardSlash } from "../../core/path.js";
21
21
  import { apply as applyPolyfill } from "../../core/polyfill.js";
22
22
  import { parseNpmName } from "../../core/util.js";
23
+ import { eventCliSession, telemetry } from "../../events/index.js";
23
24
  import { generate, parse, t, visit } from "./babel.js";
24
25
  import { ensureImport } from "./imports.js";
25
26
  import { wrapDefaultExport } from "./wrapper.js";
@@ -65,8 +66,9 @@ async function getRegistry() {
65
66
  return "https://registry.npmjs.org";
66
67
  }
67
68
  }
68
- async function add(names, { cwd, flags, logging }) {
69
+ async function add(names, { flags, logging }) {
69
70
  var _a;
71
+ telemetry.record(eventCliSession("add"));
70
72
  applyPolyfill();
71
73
  if (flags.help || names.length === 0) {
72
74
  printHelp({
@@ -106,6 +108,7 @@ async function add(names, { cwd, flags, logging }) {
106
108
  });
107
109
  return;
108
110
  }
111
+ const cwd = flags.root;
109
112
  const integrationNames = names.map((name) => ALIASES.has(name) ? ALIASES.get(name) : name);
110
113
  const integrations = await validateIntegrations(integrationNames);
111
114
  let installResult = await tryToInstallIntegrations({ integrations, cwd, flags, logging });
@@ -0,0 +1,8 @@
1
+ import type yargs from 'yargs-parser';
2
+ import type { LogOptions } from '../../core/logger/core.js';
3
+ interface BuildOptions {
4
+ flags: yargs.Arguments;
5
+ logging: LogOptions;
6
+ }
7
+ export declare function build({ flags, logging }: BuildOptions): Promise<void>;
8
+ export {};
@@ -0,0 +1,16 @@
1
+ import _build from "../../core/build/index.js";
2
+ import { loadSettings } from "../load-settings.js";
3
+ async function build({ flags, logging }) {
4
+ const settings = await loadSettings({ cmd: "build", flags, logging });
5
+ if (!settings)
6
+ return;
7
+ await _build(settings, {
8
+ flags,
9
+ logging,
10
+ teardownCompiler: true,
11
+ mode: flags.mode
12
+ });
13
+ }
14
+ export {
15
+ build
16
+ };
@@ -41,12 +41,11 @@ export declare enum CheckResult {
41
41
  *
42
42
  * Every time an astro files is modified, content collections are also generated.
43
43
  *
44
- * @param {AstroSettings} settings
45
44
  * @param {CheckPayload} options Options passed {@link AstroChecker}
46
45
  * @param {Flags} options.flags Flags coming from the CLI
47
46
  * @param {LogOptions} options.logging Logging options
48
47
  */
49
- export declare function check(settings: AstroSettings, { logging, flags }: CheckPayload): Promise<AstroChecker | undefined>;
48
+ export declare function check({ logging, flags }: CheckPayload): Promise<AstroChecker | undefined>;
50
49
  type CheckerConstructor = {
51
50
  diagnosticChecker: AstroCheck;
52
51
  isWatchMode: boolean;
@@ -11,6 +11,7 @@ import ora from "ora";
11
11
  import { fileURLToPath, pathToFileURL } from "url";
12
12
  import { debug, info } from "../../core/logger/core.js";
13
13
  import { printHelp } from "../../core/messages.js";
14
+ import { loadSettings } from "../load-settings.js";
14
15
  import { printDiagnostic } from "./print.js";
15
16
  var CheckResult = /* @__PURE__ */ ((CheckResult2) => {
16
17
  CheckResult2[CheckResult2["ExitWithSuccess"] = 0] = "ExitWithSuccess";
@@ -19,7 +20,7 @@ var CheckResult = /* @__PURE__ */ ((CheckResult2) => {
19
20
  return CheckResult2;
20
21
  })(CheckResult || {});
21
22
  const ASTRO_GLOB_PATTERN = "**/*.astro";
22
- async function check(settings, { logging, flags }) {
23
+ async function check({ logging, flags }) {
23
24
  if (flags.help || flags.h) {
24
25
  printHelp({
25
26
  commandName: "astro check",
@@ -34,6 +35,9 @@ async function check(settings, { logging, flags }) {
34
35
  });
35
36
  return;
36
37
  }
38
+ const settings = await loadSettings({ cmd: "check", flags, logging });
39
+ if (!settings)
40
+ return;
37
41
  const checkFlags = parseFlags(flags);
38
42
  if (checkFlags.watch) {
39
43
  info(logging, "check", "Checking files in watch mode");
@@ -0,0 +1,8 @@
1
+ import type yargs from 'yargs-parser';
2
+ import { type LogOptions } from '../../core/logger/core.js';
3
+ interface DevOptions {
4
+ flags: yargs.Arguments;
5
+ logging: LogOptions;
6
+ }
7
+ export declare function dev({ flags, logging }: DevOptions): Promise<import("../../core/dev/dev.js").DevServer | undefined>;
8
+ export {};
@@ -0,0 +1,26 @@
1
+ import fs from "fs";
2
+ import { resolveConfigPath, resolveFlags } from "../../core/config/index.js";
3
+ import devServer from "../../core/dev/index.js";
4
+ import { info } from "../../core/logger/core.js";
5
+ import { handleConfigError, loadSettings } from "../load-settings.js";
6
+ async function dev({ flags, logging }) {
7
+ const settings = await loadSettings({ cmd: "dev", flags, logging });
8
+ if (!settings)
9
+ return;
10
+ const root = flags.root;
11
+ const configFlag = resolveFlags(flags).config;
12
+ const configFlagPath = configFlag ? await resolveConfigPath({ cwd: root, flags, fs }) : void 0;
13
+ return await devServer(settings, {
14
+ configFlag,
15
+ configFlagPath,
16
+ flags,
17
+ logging,
18
+ handleConfigError(e) {
19
+ handleConfigError(e, { cmd: "dev", cwd: root, flags, logging });
20
+ info(logging, "astro", "Continuing with previous valid configuration\n");
21
+ }
22
+ });
23
+ }
24
+ export {
25
+ dev
26
+ };
package/dist/cli/index.js CHANGED
@@ -1,22 +1,8 @@
1
- import fs from "fs";
2
1
  import * as colors from "kleur/colors";
3
2
  import yargs from "yargs-parser";
4
- import { ZodError } from "zod";
5
- import {
6
- createSettings,
7
- openConfig,
8
- resolveConfigPath,
9
- resolveFlags
10
- } from "../core/config/index.js";
11
3
  import { ASTRO_VERSION } from "../core/constants.js";
12
- import { collectErrorMetadata } from "../core/errors/dev/index.js";
13
- import { createSafeError } from "../core/errors/index.js";
14
- import { debug, error, info } from "../core/logger/core.js";
15
- import { enableVerboseLogging, nodeLogDestination } from "../core/logger/node.js";
16
- import { formatConfigErrorMessage, formatErrorMessage, printHelp } from "../core/messages.js";
17
- import * as event from "../events/index.js";
18
- import { eventConfigError, eventError, telemetry } from "../events/index.js";
19
- function printAstroHelp() {
4
+ async function printAstroHelp() {
5
+ const { printHelp } = await import("../core/messages.js");
20
6
  printHelp({
21
7
  commandName: "astro",
22
8
  usage: "[command] [...flags]",
@@ -70,37 +56,21 @@ function resolveCommand(flags) {
70
56
  }
71
57
  return "help";
72
58
  }
73
- async function handleConfigError(e, { cmd, cwd, flags, logging }) {
74
- const path = await resolveConfigPath({ cwd, flags, fs });
75
- error(logging, "astro", `Unable to load ${path ? colors.bold(path) : "your Astro config"}
76
- `);
77
- if (e instanceof ZodError) {
78
- console.error(formatConfigErrorMessage(e) + "\n");
79
- } else if (e instanceof Error) {
80
- console.error(formatErrorMessage(collectErrorMetadata(e)) + "\n");
81
- }
82
- const telemetryPromise = telemetry.record(eventConfigError({ cmd, err: e, isFatal: true }));
83
- await telemetryPromise.catch(
84
- (err2) => debug("telemetry", `record() error: ${err2.message}`)
85
- );
86
- }
87
59
  async function runCommand(cmd, flags) {
88
60
  var _a;
89
- const root = flags.root;
90
61
  switch (cmd) {
91
62
  case "help":
92
- printAstroHelp();
63
+ await printAstroHelp();
93
64
  return;
94
65
  case "version":
95
66
  printVersion();
96
67
  return;
97
68
  case "info": {
98
69
  const { printInfo } = await import("./info/index.js");
99
- await printInfo({ cwd: root, flags });
70
+ await printInfo({ flags });
100
71
  return;
101
72
  }
102
73
  case "docs": {
103
- telemetry.record(event.eventCliSession(cmd));
104
74
  const { docs } = await import("./docs/index.js");
105
75
  await docs({ flags });
106
76
  return;
@@ -112,6 +82,7 @@ async function runCommand(cmd, flags) {
112
82
  return;
113
83
  }
114
84
  }
85
+ const { enableVerboseLogging, nodeLogDestination } = await import("../core/logger/node.js");
115
86
  const logging = {
116
87
  dest: nodeLogDestination,
117
88
  level: "info"
@@ -122,83 +93,57 @@ async function runCommand(cmd, flags) {
122
93
  } else if (flags.silent) {
123
94
  logging.level = "silent";
124
95
  }
96
+ if (!process.env.NODE_ENV) {
97
+ process.env.NODE_ENV = cmd === "dev" ? "development" : "production";
98
+ }
125
99
  switch (cmd) {
126
100
  case "add": {
127
- telemetry.record(event.eventCliSession(cmd));
128
101
  const { add } = await import("./add/index.js");
129
102
  const packages = flags._.slice(3);
130
- await add(packages, { cwd: root, flags, logging });
103
+ await add(packages, { flags, logging });
131
104
  return;
132
105
  }
133
- }
134
- if (!process.env.NODE_ENV) {
135
- process.env.NODE_ENV = cmd === "dev" ? "development" : "production";
136
- }
137
- let { astroConfig: initialAstroConfig, userConfig: initialUserConfig } = await openConfig({
138
- cwd: root,
139
- flags,
140
- cmd
141
- }).catch(async (e) => {
142
- await handleConfigError(e, { cmd, cwd: root, flags, logging });
143
- return {};
144
- });
145
- if (!initialAstroConfig)
146
- return;
147
- telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags));
148
- let settings = createSettings(initialAstroConfig, root);
149
- switch (cmd) {
150
106
  case "dev": {
151
- const { default: devServer } = await import("../core/dev/index.js");
152
- const configFlag = resolveFlags(flags).config;
153
- const configFlagPath = configFlag ? await resolveConfigPath({ cwd: root, flags, fs }) : void 0;
154
- await devServer(settings, {
155
- configFlag,
156
- configFlagPath,
157
- flags,
158
- logging,
159
- handleConfigError(e) {
160
- handleConfigError(e, { cmd, cwd: root, flags, logging });
161
- info(logging, "astro", "Continuing with previous valid configuration\n");
162
- }
163
- });
164
- return await new Promise(() => {
165
- });
107
+ const { dev } = await import("./dev/index.js");
108
+ const server = await dev({ flags, logging });
109
+ if (server) {
110
+ return await new Promise(() => {
111
+ });
112
+ }
113
+ return;
166
114
  }
167
115
  case "build": {
168
- const { default: build } = await import("../core/build/index.js");
169
- return await build(settings, {
170
- flags,
171
- logging,
172
- teardownCompiler: true,
173
- mode: flags.mode
174
- });
116
+ const { build } = await import("./build/index.js");
117
+ await build({ flags, logging });
118
+ return;
119
+ }
120
+ case "preview": {
121
+ const { preview } = await import("./preview/index.js");
122
+ const server = await preview({ flags, logging });
123
+ if (server) {
124
+ return await server.closed();
125
+ }
126
+ return;
175
127
  }
176
128
  case "check": {
177
129
  const { check } = await import("./check/index.js");
178
- const checkServer = await check(settings, { flags, logging });
130
+ const checkServer = await check({ flags, logging });
179
131
  if (checkServer) {
180
132
  if (checkServer.isWatchMode) {
181
133
  await checkServer.watch();
182
134
  return await new Promise(() => {
183
135
  });
184
136
  } else {
185
- let checkResult = await checkServer.check();
137
+ const checkResult = await checkServer.check();
186
138
  return process.exit(checkResult);
187
139
  }
188
140
  }
141
+ return;
189
142
  }
190
143
  case "sync": {
191
- const { syncCli } = await import("../core/sync/index.js");
192
- const result = await syncCli(settings, { logging, fs, flags });
193
- return process.exit(result);
194
- }
195
- case "preview": {
196
- const { default: preview } = await import("../core/preview/index.js");
197
- const server = await preview(settings, { logging, flags });
198
- if (server) {
199
- return await server.closed();
200
- }
201
- return;
144
+ const { sync } = await import("./sync/index.js");
145
+ const exitCode = await sync({ flags, logging });
146
+ return process.exit(exitCode);
202
147
  }
203
148
  }
204
149
  throw new Error(`Error running ${cmd} -- no command found.`);
@@ -209,22 +154,10 @@ async function cli(args) {
209
154
  try {
210
155
  await runCommand(cmd, flags);
211
156
  } catch (err) {
157
+ const { throwAndExit } = await import("./throw-and-exit.js");
212
158
  await throwAndExit(cmd, err);
213
159
  }
214
160
  }
215
- async function throwAndExit(cmd, err) {
216
- let telemetryPromise;
217
- let errorMessage;
218
- function exitWithErrorMessage() {
219
- console.error(errorMessage);
220
- process.exit(1);
221
- }
222
- const errorWithMetadata = collectErrorMetadata(createSafeError(err));
223
- telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true }));
224
- errorMessage = formatErrorMessage(errorWithMetadata);
225
- setTimeout(exitWithErrorMessage, 400);
226
- await telemetryPromise.catch((err2) => debug("telemetry", `record() error: ${err2.message}`)).then(exitWithErrorMessage);
227
- }
228
161
  export {
229
162
  cli
230
163
  };
@@ -1,7 +1,6 @@
1
1
  import type yargs from 'yargs-parser';
2
2
  interface InfoOptions {
3
- cwd?: string;
4
3
  flags: yargs.Arguments;
5
4
  }
6
- export declare function printInfo({ cwd, flags }: InfoOptions): Promise<void>;
5
+ export declare function printInfo({ flags }: InfoOptions): Promise<void>;
7
6
  export {};
@@ -3,7 +3,7 @@ import { arch, platform } from "node:os";
3
3
  import whichPm from "which-pm";
4
4
  import { openConfig } from "../../core/config/index.js";
5
5
  import { ASTRO_VERSION } from "../../core/constants.js";
6
- async function printInfo({ cwd, flags }) {
6
+ async function printInfo({ flags }) {
7
7
  var _a;
8
8
  const packageManager = await whichPm(process.cwd());
9
9
  let adapter = "Couldn't determine.";
@@ -15,7 +15,7 @@ async function printInfo({ cwd, flags }) {
15
15
  }
16
16
  try {
17
17
  const { userConfig } = await openConfig({
18
- cwd,
18
+ cwd: flags.root,
19
19
  flags,
20
20
  cmd: "info"
21
21
  });
@@ -0,0 +1,15 @@
1
+ import type { Arguments as Flags } from 'yargs-parser';
2
+ import { type LogOptions } from '../core/logger/core.js';
3
+ interface LoadSettingsOptions {
4
+ cmd: string;
5
+ flags: Flags;
6
+ logging: LogOptions;
7
+ }
8
+ export declare function loadSettings({ cmd, flags, logging }: LoadSettingsOptions): Promise<import("../@types/astro.js").AstroSettings | undefined>;
9
+ export declare function handleConfigError(e: any, { cmd, cwd, flags, logging }: {
10
+ cmd: string;
11
+ cwd?: string;
12
+ flags?: Flags;
13
+ logging: LogOptions;
14
+ }): Promise<void>;
15
+ export {};
@@ -0,0 +1,39 @@
1
+ import fs from "fs";
2
+ import * as colors from "kleur/colors";
3
+ import { ZodError } from "zod";
4
+ import { createSettings, openConfig, resolveConfigPath } from "../core/config/index.js";
5
+ import { collectErrorMetadata } from "../core/errors/dev/index.js";
6
+ import { error } from "../core/logger/core.js";
7
+ import { formatConfigErrorMessage, formatErrorMessage } from "../core/messages.js";
8
+ import * as event from "../events/index.js";
9
+ import { eventConfigError, telemetry } from "../events/index.js";
10
+ async function loadSettings({ cmd, flags, logging }) {
11
+ const root = flags.root;
12
+ const { astroConfig: initialAstroConfig, userConfig: initialUserConfig } = await openConfig({
13
+ cwd: root,
14
+ flags,
15
+ cmd
16
+ }).catch(async (e) => {
17
+ await handleConfigError(e, { cmd, cwd: root, flags, logging });
18
+ return {};
19
+ });
20
+ if (!initialAstroConfig)
21
+ return;
22
+ telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags));
23
+ return createSettings(initialAstroConfig, root);
24
+ }
25
+ async function handleConfigError(e, { cmd, cwd, flags, logging }) {
26
+ const path = await resolveConfigPath({ cwd, flags, fs });
27
+ error(logging, "astro", `Unable to load ${path ? colors.bold(path) : "your Astro config"}
28
+ `);
29
+ if (e instanceof ZodError) {
30
+ console.error(formatConfigErrorMessage(e) + "\n");
31
+ telemetry.record(eventConfigError({ cmd, err: e, isFatal: true }));
32
+ } else if (e instanceof Error) {
33
+ console.error(formatErrorMessage(collectErrorMetadata(e)) + "\n");
34
+ }
35
+ }
36
+ export {
37
+ handleConfigError,
38
+ loadSettings
39
+ };
@@ -0,0 +1,8 @@
1
+ import type yargs from 'yargs-parser';
2
+ import type { LogOptions } from '../../core/logger/core.js';
3
+ interface PreviewOptions {
4
+ flags: yargs.Arguments;
5
+ logging: LogOptions;
6
+ }
7
+ export declare function preview({ flags, logging }: PreviewOptions): Promise<import("../../@types/astro.js").PreviewServer | undefined>;
8
+ export {};
@@ -0,0 +1,11 @@
1
+ import previewServer from "../../core/preview/index.js";
2
+ import { loadSettings } from "../load-settings.js";
3
+ async function preview({ flags, logging }) {
4
+ const settings = await loadSettings({ cmd: "preview", flags, logging });
5
+ if (!settings)
6
+ return;
7
+ return await previewServer(settings, { flags, logging });
8
+ }
9
+ export {
10
+ preview
11
+ };
@@ -0,0 +1,8 @@
1
+ import type yargs from 'yargs-parser';
2
+ import type { LogOptions } from '../../core/logger/core.js';
3
+ interface SyncOptions {
4
+ flags: yargs.Arguments;
5
+ logging: LogOptions;
6
+ }
7
+ export declare function sync({ flags, logging }: SyncOptions): Promise<import("../../core/sync/index.js").ProcessExit | undefined>;
8
+ export {};
@@ -0,0 +1,13 @@
1
+ import fs from "fs";
2
+ import { syncCli } from "../../core/sync/index.js";
3
+ import { loadSettings } from "../load-settings.js";
4
+ async function sync({ flags, logging }) {
5
+ const settings = await loadSettings({ cmd: "sync", flags, logging });
6
+ if (!settings)
7
+ return;
8
+ const exitCode = await syncCli(settings, { logging, fs, flags });
9
+ return exitCode;
10
+ }
11
+ export {
12
+ sync
13
+ };
@@ -0,0 +1,2 @@
1
+ /** Display error and exit */
2
+ export declare function throwAndExit(cmd: string, err: unknown): Promise<void>;
@@ -0,0 +1,21 @@
1
+ import { collectErrorMetadata } from "../core/errors/dev/index.js";
2
+ import { createSafeError } from "../core/errors/index.js";
3
+ import { debug } from "../core/logger/core.js";
4
+ import { formatErrorMessage } from "../core/messages.js";
5
+ import { eventError, telemetry } from "../events/index.js";
6
+ async function throwAndExit(cmd, err) {
7
+ let telemetryPromise;
8
+ let errorMessage;
9
+ function exitWithErrorMessage() {
10
+ console.error(errorMessage);
11
+ process.exit(1);
12
+ }
13
+ const errorWithMetadata = collectErrorMetadata(createSafeError(err));
14
+ telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true }));
15
+ errorMessage = formatErrorMessage(errorWithMetadata);
16
+ setTimeout(exitWithErrorMessage, 400);
17
+ await telemetryPromise.catch((err2) => debug("telemetry", `record() error: ${err2.message}`)).then(exitWithErrorMessage);
18
+ }
19
+ export {
20
+ throwAndExit
21
+ };
@@ -1,3 +1,3 @@
1
1
  import type { PluginContext } from 'rollup';
2
2
  import { z } from 'zod';
3
- export declare function createImage(pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/utils/metadata.js").Metadata | z.ZodNever, string>;
3
+ export declare function createImage(pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/types.js").ImageMetadata | z.ZodNever, string>;
@@ -461,9 +461,16 @@ async function generatePath(pathname, opts, gopts, manifest, onRequest) {
461
461
  return;
462
462
  }
463
463
  const location = getRedirectLocationOrThrow(response.headers);
464
+ const fromPath = new URL(renderContext.request.url).pathname;
465
+ const delay = response.status === 302 ? 2 : 0;
464
466
  body = `<!doctype html>
465
467
  <title>Redirecting to: ${location}</title>
466
- <meta http-equiv="refresh" content="0;url=${location}" />`;
468
+ <meta http-equiv="refresh" content="${delay};url=${location}">
469
+ <meta name="robots" content="noindex">
470
+ <link rel="canonical" href="${location}">
471
+ <body>
472
+ <a href="${location}">Redirecting from <code>${fromPath}</code> to <code>${location}</code></a>
473
+ </body>`;
467
474
  if (pageData.route.type !== "redirect") {
468
475
  pageData.route.redirect = location;
469
476
  }
@@ -19,6 +19,7 @@ import { isServerLikeOutput } from "../../prerender/utils.js";
19
19
  import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
20
20
  import { AstroError, AstroErrorData } from "../errors/index.js";
21
21
  import { info } from "../logger/core.js";
22
+ import { routeIsRedirect } from "../redirects/index.js";
22
23
  import { getOutDirWithinCwd } from "./common.js";
23
24
  import { generatePages } from "./generate.js";
24
25
  import { trackPageData } from "./internal.js";
@@ -43,8 +44,10 @@ async function viteBuild(opts) {
43
44
  const astroModuleURL = new URL("./" + component, settings.config.root);
44
45
  const astroModuleId = prependForwardSlash(component);
45
46
  trackPageData(internals, component, pageData, astroModuleId, astroModuleURL);
46
- pageInput.add(astroModuleId);
47
- facadeIdToPageDataMap.set(fileURLToPath(astroModuleURL), pageData);
47
+ if (!routeIsRedirect(pageData.route)) {
48
+ pageInput.add(astroModuleId);
49
+ facadeIdToPageDataMap.set(fileURLToPath(astroModuleURL), pageData);
50
+ }
48
51
  }
49
52
  if (((_c = (_b = (_a = settings.config) == null ? void 0 : _a.vite) == null ? void 0 : _b.build) == null ? void 0 : _c.emptyOutDir) !== false) {
50
53
  emptyDir(settings.config.outDir, new Set(".git"));
@@ -37,5 +37,4 @@ export declare function openConfig(configOptions: LoadConfigOptions): Promise<Op
37
37
  /** Attempt to resolve an Astro configuration object. Normalize, validate, and return. */
38
38
  export declare function resolveConfig(userConfig: AstroUserConfig, root: string, flags: CLIFlags | undefined, cmd: string): Promise<AstroConfig>;
39
39
  export declare function createDefaultDevConfig(userConfig?: AstroUserConfig, root?: string): Promise<AstroConfig>;
40
- export declare function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot?: boolean): Record<string, any>;
41
40
  export {};
@@ -2,9 +2,8 @@ import fs from "fs";
2
2
  import * as colors from "kleur/colors";
3
3
  import path from "path";
4
4
  import { fileURLToPath, pathToFileURL } from "url";
5
- import { mergeConfig as mergeViteConfig } from "vite";
6
5
  import { AstroError, AstroErrorData } from "../errors/index.js";
7
- import { arraify, isObject, isURL } from "../util.js";
6
+ import { mergeConfig } from "./merge.js";
8
7
  import { createRelativeSchema } from "./schema.js";
9
8
  import { loadConfigWithVite } from "./vite-load.js";
10
9
  const LEGACY_ASTRO_CONFIG_KEYS = /* @__PURE__ */ new Set([
@@ -86,25 +85,18 @@ function resolveRoot(cwd) {
86
85
  return cwd ? path.resolve(cwd) : process.cwd();
87
86
  }
88
87
  function mergeCLIFlags(astroConfig, flags) {
89
- astroConfig.server = astroConfig.server || {};
90
- astroConfig.markdown = astroConfig.markdown || {};
91
- astroConfig.experimental = astroConfig.experimental || {};
92
- if (typeof flags.site === "string")
93
- astroConfig.site = flags.site;
94
- if (typeof flags.base === "string")
95
- astroConfig.base = flags.base;
96
- if (typeof flags.drafts === "boolean")
97
- astroConfig.markdown.drafts = flags.drafts;
98
- if (typeof flags.port === "number") {
99
- astroConfig.server.port = flags.port;
100
- }
101
- if (typeof flags.host === "string" || typeof flags.host === "boolean") {
102
- astroConfig.server.host = flags.host;
103
- }
104
- if (typeof flags.open === "boolean") {
105
- astroConfig.server.open = flags.open;
106
- }
107
- return astroConfig;
88
+ return mergeConfig(astroConfig, {
89
+ site: flags.site,
90
+ base: flags.base,
91
+ markdown: {
92
+ drafts: flags.drafts
93
+ },
94
+ server: {
95
+ port: flags.port,
96
+ host: flags.host,
97
+ open: flags.open
98
+ }
99
+ });
108
100
  }
109
101
  async function search(fsMod, root) {
110
102
  const paths = [
@@ -142,11 +134,7 @@ async function resolveConfigPath(configOptions) {
142
134
  async function openConfig(configOptions) {
143
135
  const root = resolveRoot(configOptions.cwd);
144
136
  const flags = resolveFlags(configOptions.flags || {});
145
- let userConfig = {};
146
- const config = await tryLoadConfig(configOptions, root);
147
- if (config) {
148
- userConfig = config.value;
149
- }
137
+ const userConfig = await loadConfig(configOptions, root);
150
138
  const astroConfig = await resolveConfig(userConfig, root, flags, configOptions.cmd);
151
139
  return {
152
140
  astroConfig,
@@ -155,42 +143,20 @@ async function openConfig(configOptions) {
155
143
  root
156
144
  };
157
145
  }
158
- async function tryLoadConfig(configOptions, root) {
146
+ async function loadConfig(configOptions, root) {
159
147
  const fsMod = configOptions.fsMod ?? fs;
160
- let finallyCleanup = async () => {
161
- };
162
- try {
163
- let configPath = await resolveConfigPath({
164
- cwd: configOptions.cwd,
165
- flags: configOptions.flags,
166
- fs: fsMod
167
- });
168
- if (!configPath)
169
- return void 0;
170
- if (configOptions.isRestart) {
171
- const tempConfigPath = path.join(
172
- root,
173
- `.temp.${Date.now()}.config${path.extname(configPath)}`
174
- );
175
- const currentConfigContent = await fsMod.promises.readFile(configPath, "utf-8");
176
- await fs.promises.writeFile(tempConfigPath, currentConfigContent);
177
- finallyCleanup = async () => {
178
- try {
179
- await fs.promises.unlink(tempConfigPath);
180
- } catch {
181
- }
182
- };
183
- configPath = tempConfigPath;
184
- }
185
- const config = await loadConfigWithVite({
186
- configPath,
187
- fs: fsMod,
188
- root
189
- });
190
- return config;
191
- } finally {
192
- await finallyCleanup();
193
- }
148
+ const configPath = await resolveConfigPath({
149
+ cwd: configOptions.cwd,
150
+ flags: configOptions.flags,
151
+ fs: fsMod
152
+ });
153
+ if (!configPath)
154
+ return {};
155
+ return await loadConfigWithVite({
156
+ configPath,
157
+ fs: fsMod,
158
+ root
159
+ });
194
160
  }
195
161
  async function resolveConfig(userConfig, root, flags = {}, cmd) {
196
162
  const mergedConfig = mergeCLIFlags(userConfig, flags);
@@ -200,45 +166,9 @@ async function resolveConfig(userConfig, root, flags = {}, cmd) {
200
166
  function createDefaultDevConfig(userConfig = {}, root = process.cwd()) {
201
167
  return resolveConfig(userConfig, root, void 0, "dev");
202
168
  }
203
- function mergeConfigRecursively(defaults, overrides, rootPath) {
204
- const merged = { ...defaults };
205
- for (const key in overrides) {
206
- const value = overrides[key];
207
- if (value == null) {
208
- continue;
209
- }
210
- const existing = merged[key];
211
- if (existing == null) {
212
- merged[key] = value;
213
- continue;
214
- }
215
- if (key === "vite" && rootPath === "") {
216
- merged[key] = mergeViteConfig(existing, value);
217
- continue;
218
- }
219
- if (Array.isArray(existing) || Array.isArray(value)) {
220
- merged[key] = [...arraify(existing ?? []), ...arraify(value ?? [])];
221
- continue;
222
- }
223
- if (isURL(existing) && isURL(value)) {
224
- merged[key] = value;
225
- continue;
226
- }
227
- if (isObject(existing) && isObject(value)) {
228
- merged[key] = mergeConfigRecursively(existing, value, rootPath ? `${rootPath}.${key}` : key);
229
- continue;
230
- }
231
- merged[key] = value;
232
- }
233
- return merged;
234
- }
235
- function mergeConfig(defaults, overrides, isRoot = true) {
236
- return mergeConfigRecursively(defaults, overrides, isRoot ? "" : ".");
237
- }
238
169
  export {
239
170
  LEGACY_ASTRO_CONFIG_KEYS,
240
171
  createDefaultDevConfig,
241
- mergeConfig,
242
172
  openConfig,
243
173
  resolveConfig,
244
174
  resolveConfigPath,
@@ -1,4 +1,5 @@
1
1
  export { createDefaultDevConfig, openConfig, resolveConfigPath, resolveFlags, resolveRoot, validateConfig, } from './config.js';
2
+ export { mergeConfig } from './merge.js';
2
3
  export type { AstroConfigSchema } from './schema';
3
4
  export { createDefaultDevSettings, createSettings } from './settings.js';
4
5
  export { loadTSConfig, updateTSConfigForFramework } from './tsconfig.js';
@@ -6,6 +6,7 @@ import {
6
6
  resolveRoot,
7
7
  validateConfig
8
8
  } from "./config.js";
9
+ import { mergeConfig } from "./merge.js";
9
10
  import { createDefaultDevSettings, createSettings } from "./settings.js";
10
11
  import { loadTSConfig, updateTSConfigForFramework } from "./tsconfig.js";
11
12
  export {
@@ -13,6 +14,7 @@ export {
13
14
  createDefaultDevSettings,
14
15
  createSettings,
15
16
  loadTSConfig,
17
+ mergeConfig,
16
18
  openConfig,
17
19
  resolveConfigPath,
18
20
  resolveFlags,
@@ -0,0 +1 @@
1
+ export declare function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot?: boolean): Record<string, any>;
@@ -0,0 +1,50 @@
1
+ import { mergeConfig as mergeViteConfig } from "vite";
2
+ import { arraify, isObject, isURL } from "../util.js";
3
+ function mergeConfigRecursively(defaults, overrides, rootPath) {
4
+ const merged = { ...defaults };
5
+ for (const key in overrides) {
6
+ const value = overrides[key];
7
+ if (value == null) {
8
+ continue;
9
+ }
10
+ const existing = merged[key];
11
+ if (existing == null) {
12
+ merged[key] = value;
13
+ continue;
14
+ }
15
+ if (key === "vite" && rootPath === "") {
16
+ merged[key] = mergeViteConfig(existing, value);
17
+ continue;
18
+ }
19
+ if (key === "server" && rootPath === "") {
20
+ if (typeof existing === "function" || typeof value === "function") {
21
+ merged[key] = (...args) => {
22
+ const existingConfig = typeof existing === "function" ? existing(...args) : existing;
23
+ const valueConfig = typeof value === "function" ? value(...args) : value;
24
+ return mergeConfigRecursively(existingConfig, valueConfig, key);
25
+ };
26
+ continue;
27
+ }
28
+ }
29
+ if (Array.isArray(existing) || Array.isArray(value)) {
30
+ merged[key] = [...arraify(existing ?? []), ...arraify(value ?? [])];
31
+ continue;
32
+ }
33
+ if (isURL(existing) && isURL(value)) {
34
+ merged[key] = value;
35
+ continue;
36
+ }
37
+ if (isObject(existing) && isObject(value)) {
38
+ merged[key] = mergeConfigRecursively(existing, value, rootPath ? `${rootPath}.${key}` : key);
39
+ continue;
40
+ }
41
+ merged[key] = value;
42
+ }
43
+ return merged;
44
+ }
45
+ function mergeConfig(defaults, overrides, isRoot = true) {
46
+ return mergeConfigRecursively(defaults, overrides, isRoot ? "" : ".");
47
+ }
48
+ export {
49
+ mergeConfig
50
+ };
@@ -171,12 +171,7 @@ function createRelativeSchema(cmd, fileProtocolRoot) {
171
171
  // preprocess
172
172
  (val) => {
173
173
  if (typeof val === "function") {
174
- const result = val({ command: cmd === "dev" ? "dev" : "preview" });
175
- if (val.port)
176
- result.port = val.port;
177
- if (val.host)
178
- result.host = val.host;
179
- return result;
174
+ return val({ command: cmd === "dev" ? "dev" : "preview" });
180
175
  } else {
181
176
  return val;
182
177
  }
@@ -1,17 +1,9 @@
1
1
  /// <reference types="node" />
2
2
  import type fsType from 'fs';
3
- import * as vite from 'vite';
4
- export interface ViteLoader {
5
- root: string;
6
- viteServer: vite.ViteDevServer;
7
- }
8
3
  interface LoadConfigWithViteOptions {
9
4
  root: string;
10
- configPath: string | undefined;
5
+ configPath: string;
11
6
  fs: typeof fsType;
12
7
  }
13
- export declare function loadConfigWithVite({ configPath, fs, root, }: LoadConfigWithViteOptions): Promise<{
14
- value: Record<string, any>;
15
- filePath?: string;
16
- }>;
8
+ export declare function loadConfigWithVite({ configPath, fs, root, }: LoadConfigWithViteOptions): Promise<Record<string, any>>;
17
9
  export {};
@@ -1,8 +1,9 @@
1
1
  import { pathToFileURL } from "url";
2
- import * as vite from "vite";
2
+ import { createServer } from "vite";
3
3
  import loadFallbackPlugin from "../../vite-plugin-load-fallback/index.js";
4
- async function createViteLoader(root, fs) {
5
- const viteServer = await vite.createServer({
4
+ import { debug } from "../logger/core.js";
5
+ async function createViteServer(root, fs) {
6
+ const viteServer = await createServer({
6
7
  server: { middlewareMode: true, hmr: false, watch: { ignored: ["**"] } },
7
8
  optimizeDeps: { disabled: true },
8
9
  clearScreen: false,
@@ -22,43 +23,29 @@ async function createViteLoader(root, fs) {
22
23
  },
23
24
  plugins: [loadFallbackPlugin({ fs, root: pathToFileURL(root) })]
24
25
  });
25
- return {
26
- root,
27
- viteServer
28
- };
26
+ return viteServer;
29
27
  }
30
28
  async function loadConfigWithVite({
31
29
  configPath,
32
30
  fs,
33
31
  root
34
32
  }) {
35
- if (!configPath) {
36
- return {
37
- value: {},
38
- filePath: void 0
39
- };
40
- }
41
33
  if (/\.[cm]?js$/.test(configPath)) {
42
34
  try {
43
- const config = await import(pathToFileURL(configPath).toString());
44
- return {
45
- value: config.default ?? {},
46
- filePath: configPath
47
- };
48
- } catch {
35
+ const config = await import(pathToFileURL(configPath).toString() + "?t=" + Date.now());
36
+ return config.default ?? {};
37
+ } catch (e) {
38
+ debug("Failed to load config with Node", e);
49
39
  }
50
40
  }
51
- let loader;
41
+ let server;
52
42
  try {
53
- loader = await createViteLoader(root, fs);
54
- const mod = await loader.viteServer.ssrLoadModule(configPath);
55
- return {
56
- value: mod.default ?? {},
57
- filePath: configPath
58
- };
43
+ server = await createViteServer(root, fs);
44
+ const mod = await server.ssrLoadModule(configPath, { fixStacktrace: true });
45
+ return mod.default ?? {};
59
46
  } finally {
60
- if (loader) {
61
- await loader.viteServer.close();
47
+ if (server) {
48
+ await server.close();
62
49
  }
63
50
  }
64
51
  }
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.8.1";
1
+ const ASTRO_VERSION = "2.8.3";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -54,7 +54,7 @@ async function dev(settings, options) {
54
54
  isRestart: options.isRestart
55
55
  })
56
56
  );
57
- const currentVersion = "2.8.1";
57
+ const currentVersion = "2.8.3";
58
58
  if (currentVersion.includes("-")) {
59
59
  warn(options.logging, null, msg.prerelease({ currentVersion }));
60
60
  }
@@ -438,7 +438,7 @@ export declare const AstroErrorData: {
438
438
  readonly UnsupportedImageFormat: {
439
439
  readonly title: "Unsupported image format";
440
440
  readonly message: (format: string, imagePath: string, supportedFormats: readonly string[]) => string;
441
- readonly hint: "If you do not need optimization, using an `img` tag directly instead of the `Image` component might be what you're looking for.";
441
+ readonly hint: "Using an `img` tag directly instead of the `Image` component might be what you're looking for.";
442
442
  };
443
443
  /**
444
444
  * @docs
@@ -452,8 +452,8 @@ Expected \`${defaultExpectedValue}\` value but got \`${suffix}\`.`;
452
452
  title: "Unsupported image format",
453
453
  message: (format, imagePath, supportedFormats) => `Received unsupported format \`${format}\` from \`${imagePath}\`. Currently only ${supportedFormats.join(
454
454
  ", "
455
- )} are supported for optimization.`,
456
- hint: "If you do not need optimization, using an `img` tag directly instead of the `Image` component might be what you're looking for."
455
+ )} are supported by our image services.`,
456
+ hint: "Using an `img` tag directly instead of the `Image` component might be what you're looking for."
457
457
  },
458
458
  /**
459
459
  * @docs
@@ -47,7 +47,7 @@ function serverStart({
47
47
  base,
48
48
  isRestart = false
49
49
  }) {
50
- const version = "2.8.1";
50
+ const version = "2.8.3";
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.8.1"}`
236
+ `v${"2.8.3"}`
237
237
  )} ${headline}`
238
238
  );
239
239
  }
@@ -313,6 +313,25 @@ This route collides with: "${collision.component}".`
313
313
  redirect: to,
314
314
  redirectRoute: routes.find((r) => r.route === to)
315
315
  };
316
+ const lastSegmentIsDynamic = (r) => {
317
+ var _a2, _b;
318
+ return !!((_b = (_a2 = r.segments.at(-1)) == null ? void 0 : _a2.at(-1)) == null ? void 0 : _b.dynamic);
319
+ };
320
+ const redirBase = path.posix.dirname(route);
321
+ const dynamicRedir = lastSegmentIsDynamic(routeData);
322
+ let i = 0;
323
+ for (const existingRoute of routes) {
324
+ if (existingRoute.route === route) {
325
+ routes.splice(i + 1, 0, routeData);
326
+ return;
327
+ }
328
+ const base = path.posix.dirname(existingRoute.route);
329
+ if (base === redirBase && !dynamicRedir && lastSegmentIsDynamic(existingRoute)) {
330
+ routes.splice(i, 0, routeData);
331
+ return;
332
+ }
333
+ i++;
334
+ }
316
335
  routes.push(routeData);
317
336
  });
318
337
  return {
@@ -33,11 +33,7 @@ function eventError({
33
33
  plugin: err.plugin,
34
34
  cliCommand: cmd,
35
35
  isFatal,
36
- anonymousMessageHint: (
37
- // https://github.com/typescript-eslint/typescript-eslint/issues/4820
38
- // eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- errorData may be false
39
- errorData && errorData.message ? getSafeErrorMessage(errorData.message) : anonymizeErrorMessage(err.message)
40
- )
36
+ anonymousMessageHint: errorData && errorData.message ? getSafeErrorMessage(errorData.message) : anonymizeErrorMessage(err.message)
41
37
  };
42
38
  return [{ eventName: EVENT_ERROR, payload }];
43
39
  }
@@ -2,7 +2,7 @@ import { bold } from "kleur/colors";
2
2
  import fs from "node:fs";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { buildClientDirectiveEntrypoint } from "../core/client-directive/index.js";
5
- import { mergeConfig } from "../core/config/config.js";
5
+ import { mergeConfig } from "../core/config/index.js";
6
6
  import { info } from "../core/logger/core.js";
7
7
  import { isServerLikeOutput } from "../prerender/utils.js";
8
8
  async function withTakingALongTimeMsg({
@@ -45,6 +45,13 @@ function createResponseClass() {
45
45
  }
46
46
  return super.arrayBuffer();
47
47
  }
48
+ clone() {
49
+ return new StreamingCompatibleResponse(this.#body, {
50
+ status: this.status,
51
+ statusText: this.statusText,
52
+ headers: this.headers
53
+ });
54
+ }
48
55
  };
49
56
  return StreamingCompatibleResponse;
50
57
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",