astro 5.1.3 → 5.1.5

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 (56) hide show
  1. package/astro-jsx.d.ts +3 -1
  2. package/components/Image.astro +0 -1
  3. package/components/Picture.astro +1 -2
  4. package/components/ResponsiveImage.astro +13 -0
  5. package/components/ResponsivePicture.astro +11 -0
  6. package/dist/assets/build/generate.d.ts +1 -2
  7. package/dist/assets/build/generate.js +34 -17
  8. package/dist/assets/build/remote.d.ts +1 -1
  9. package/dist/assets/vite-plugin-assets.js +4 -3
  10. package/dist/container/index.js +2 -1
  11. package/dist/content/content-layer.d.ts +1 -1
  12. package/dist/content/content-layer.js +4 -6
  13. package/dist/content/mutable-data-store.d.ts +1 -1
  14. package/dist/content/mutable-data-store.js +21 -13
  15. package/dist/content/vite-plugin-content-virtual-mod.js +16 -13
  16. package/dist/core/app/index.js +13 -1
  17. package/dist/core/build/css-asset-name.js +1 -1
  18. package/dist/core/build/generate.js +4 -2
  19. package/dist/core/build/index.js +3 -2
  20. package/dist/core/build/static-build.js +1 -1
  21. package/dist/core/compile/compile.js +1 -2
  22. package/dist/core/compile/style.js +2 -1
  23. package/dist/core/config/schema.d.ts +49 -31
  24. package/dist/core/config/schema.js +2 -2
  25. package/dist/core/constants.js +1 -1
  26. package/dist/core/dev/container.js +2 -1
  27. package/dist/core/dev/dev.js +5 -7
  28. package/dist/core/errors/dev/utils.js +1 -1
  29. package/dist/core/messages.js +2 -2
  30. package/dist/core/middleware/sequence.js +5 -1
  31. package/dist/core/middleware/vite-plugin.js +1 -1
  32. package/dist/core/render/params-and-props.js +1 -1
  33. package/dist/core/render-context.js +17 -3
  34. package/dist/core/request.d.ts +3 -3
  35. package/dist/core/request.js +4 -2
  36. package/dist/core/routing/manifest/create.d.ts +0 -1
  37. package/dist/core/routing/manifest/create.js +2 -21
  38. package/dist/core/routing/manifest/parts.d.ts +2 -0
  39. package/dist/core/routing/manifest/parts.js +22 -0
  40. package/dist/core/routing/manifest/segment.d.ts +1 -0
  41. package/dist/core/routing/manifest/segment.js +22 -0
  42. package/dist/core/routing/rewrite.d.ts +5 -1
  43. package/dist/core/routing/rewrite.js +22 -15
  44. package/dist/core/sync/index.d.ts +4 -2
  45. package/dist/core/sync/index.js +15 -12
  46. package/dist/core/util.d.ts +2 -2
  47. package/dist/core/util.js +5 -2
  48. package/dist/env/schema.d.ts +48 -30
  49. package/dist/env/schema.js +20 -1
  50. package/dist/vite-plugin-astro/compile.js +1 -1
  51. package/dist/vite-plugin-astro-server/request.js +1 -1
  52. package/dist/vite-plugin-astro-server/route.js +1 -1
  53. package/dist/vite-plugin-markdown/content-entry-type.js +1 -6
  54. package/dist/vite-plugin-markdown/index.js +1 -1
  55. package/dist/vite-plugin-scanner/index.js +1 -2
  56. package/package.json +5 -1
@@ -1,7 +1,7 @@
1
- import { markdownConfigDefaults } from "@astrojs/markdown-remark";
2
- import { bundledThemes } from "shiki";
3
1
  import path from "node:path";
4
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
+ import { markdownConfigDefaults } from "@astrojs/markdown-remark";
4
+ import { bundledThemes } from "shiki";
5
5
  import { z } from "zod";
6
6
  import { EnvSchema } from "../../env/schema.js";
7
7
  import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from "../path.js";
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "5.1.3";
1
+ const ASTRO_VERSION = "5.1.5";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
4
4
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
@@ -66,7 +66,8 @@ async function createContainer({
66
66
  cleanup: true
67
67
  },
68
68
  force: inlineConfig?.force,
69
- manifest
69
+ manifest,
70
+ command: "dev"
70
71
  });
71
72
  const viteServer = await vite.createServer(viteConfig);
72
73
  const container = {
@@ -1,4 +1,4 @@
1
- import fs, { existsSync } from "node:fs";
1
+ import fs from "node:fs";
2
2
  import { performance } from "node:perf_hooks";
3
3
  import { green } from "kleur/colors";
4
4
  import { gt, major, minor, patch } from "semver";
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
22
22
  await telemetry.record([]);
23
23
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
24
24
  const logger = restart.container.logger;
25
- const currentVersion = "5.1.3";
25
+ const currentVersion = "5.1.5";
26
26
  const isPrerelease = currentVersion.includes("-");
27
27
  if (!isPrerelease) {
28
28
  try {
@@ -53,21 +53,19 @@ async function dev(inlineConfig) {
53
53
  let store;
54
54
  try {
55
55
  const dataStoreFile = getDataStoreFile(restart.container.settings, true);
56
- if (existsSync(dataStoreFile)) {
57
- store = await MutableDataStore.fromFile(dataStoreFile);
58
- }
56
+ store = await MutableDataStore.fromFile(dataStoreFile);
59
57
  } catch (err) {
60
58
  logger.error("content", err.message);
61
59
  }
62
60
  if (!store) {
63
- store = new MutableDataStore();
61
+ logger.error("content", "Failed to create data store");
64
62
  }
65
63
  await attachContentServerListeners(restart.container);
66
64
  const config = globalContentConfigObserver.get();
67
65
  if (config.status === "error") {
68
66
  logger.error("content", config.error.message);
69
67
  }
70
- if (config.status === "loaded") {
68
+ if (config.status === "loaded" && store) {
71
69
  const contentLayer = globalContentLayer.init({
72
70
  settings: restart.container.settings,
73
71
  logger,
@@ -4,8 +4,8 @@ import { fileURLToPath } from "node:url";
4
4
  import { stripVTControlCharacters } from "node:util";
5
5
  import { escape } from "html-escaper";
6
6
  import { bold, underline } from "kleur/colors";
7
- import { normalizePath } from "vite";
8
7
  import { removeLeadingForwardSlashWindows } from "../../path.js";
8
+ import { normalizePath } from "../../viteUtils.js";
9
9
  import { AggregateError } from "../errors.js";
10
10
  import { AstroErrorData } from "../index.js";
11
11
  import { codeFrame } from "../printer.js";
@@ -38,7 +38,7 @@ function serverStart({
38
38
  host,
39
39
  base
40
40
  }) {
41
- const version = "5.1.3";
41
+ const version = "5.1.5";
42
42
  const localPrefix = `${dim("\u2503")} Local `;
43
43
  const networkPrefix = `${dim("\u2503")} Network `;
44
44
  const emptyPrefix = " ".repeat(11);
@@ -276,7 +276,7 @@ function printHelp({
276
276
  message.push(
277
277
  linebreak(),
278
278
  ` ${bgGreen(black(` ${commandName} `))} ${green(
279
- `v${"5.1.3"}`
279
+ `v${"5.1.5"}`
280
280
  )} ${headline}`
281
281
  );
282
282
  }
@@ -39,7 +39,11 @@ function sequence(...handlers) {
39
39
  if (pipeline.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) {
40
40
  throw new AstroError({
41
41
  ...ForbiddenRewrite,
42
- message: ForbiddenRewrite.message(pathname, pathname, routeData.component),
42
+ message: ForbiddenRewrite.message(
43
+ handleContext.url.pathname,
44
+ pathname,
45
+ routeData.component
46
+ ),
43
47
  hint: ForbiddenRewrite.hint(routeData.component)
44
48
  });
45
49
  }
@@ -1,9 +1,9 @@
1
- import { normalizePath } from "vite";
2
1
  import { getOutputDirectory } from "../../prerender/utils.js";
3
2
  import { addRollupInput } from "../build/add-rollup-input.js";
4
3
  import { MIDDLEWARE_PATH_SEGMENT_NAME } from "../constants.js";
5
4
  import { MissingMiddlewareForInternationalization } from "../errors/errors-data.js";
6
5
  import { AstroError } from "../errors/index.js";
6
+ import { normalizePath } from "../viteUtils.js";
7
7
  const MIDDLEWARE_MODULE_ID = "\0astro-internal:middleware";
8
8
  const NOOP_MIDDLEWARE = "\0noop-middleware";
9
9
  function vitePluginMiddleware({ settings }) {
@@ -19,7 +19,7 @@ async function getProps(opts) {
19
19
  ssr: serverLike,
20
20
  base
21
21
  });
22
- const params = getParams(route, decodeURI(pathname));
22
+ const params = getParams(route, pathname);
23
23
  const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger);
24
24
  if (!matchedStaticPath && (serverLike ? route.prerender : true)) {
25
25
  throw new AstroError({
@@ -72,7 +72,7 @@ class RenderContext {
72
72
  pipeline,
73
73
  locals,
74
74
  sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware),
75
- decodeURI(pathname),
75
+ pathname,
76
76
  request,
77
77
  routeData,
78
78
  status,
@@ -137,7 +137,14 @@ class RenderContext {
137
137
  if (payload instanceof Request) {
138
138
  this.request = payload;
139
139
  } else {
140
- this.request = copyRequest(newUrl, this.request);
140
+ this.request = copyRequest(
141
+ newUrl,
142
+ this.request,
143
+ // need to send the flag of the previous routeData
144
+ routeData.prerender,
145
+ this.pipeline.logger,
146
+ this.routeData.route
147
+ );
141
148
  }
142
149
  this.isRewriting = true;
143
150
  this.url = new URL(this.request.url);
@@ -228,7 +235,14 @@ class RenderContext {
228
235
  if (reroutePayload instanceof Request) {
229
236
  this.request = reroutePayload;
230
237
  } else {
231
- this.request = copyRequest(newUrl, this.request);
238
+ this.request = copyRequest(
239
+ newUrl,
240
+ this.request,
241
+ // need to send the flag of the previous routeData
242
+ routeData.prerender,
243
+ this.pipeline.logger,
244
+ this.routeData.route
245
+ );
232
246
  }
233
247
  this.url = new URL(this.request.url);
234
248
  this.cookies = new AstroCookies(this.request);
@@ -1,13 +1,12 @@
1
1
  import type { IncomingHttpHeaders } from 'node:http';
2
2
  import type { Logger } from './logger/core.js';
3
3
  type HeaderType = Headers | Record<string, any> | IncomingHttpHeaders;
4
- type RequestBody = ArrayBuffer | Blob | ReadableStream | URLSearchParams | FormData;
5
4
  export interface CreateRequestOptions {
6
5
  url: URL | string;
7
6
  clientAddress?: string | undefined;
8
7
  headers: HeaderType;
9
8
  method?: string;
10
- body?: RequestBody | undefined;
9
+ body?: RequestInit['body'];
11
10
  logger: Logger;
12
11
  locals?: object | undefined;
13
12
  /**
@@ -19,6 +18,7 @@ export interface CreateRequestOptions {
19
18
  */
20
19
  isPrerendered?: boolean;
21
20
  routePattern: string;
21
+ init?: RequestInit;
22
22
  }
23
23
  /**
24
24
  * Used by astro internals to create a web standard request object.
@@ -27,5 +27,5 @@ export interface CreateRequestOptions {
27
27
  *
28
28
  * This is used by the static build to create fake requests for prerendering, and by the dev server to convert node requests into the standard request object.
29
29
  */
30
- export declare function createRequest({ url, headers, method, body, logger, isPrerendered, routePattern, }: CreateRequestOptions): Request;
30
+ export declare function createRequest({ url, headers, method, body, logger, isPrerendered, routePattern, init, }: CreateRequestOptions): Request;
31
31
  export {};
@@ -5,7 +5,8 @@ function createRequest({
5
5
  body = void 0,
6
6
  logger,
7
7
  isPrerendered = false,
8
- routePattern
8
+ routePattern,
9
+ init
9
10
  }) {
10
11
  const headersObj = isPrerendered ? void 0 : headers instanceof Headers ? headers : new Headers(
11
12
  // Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request.
@@ -22,7 +23,8 @@ function createRequest({
22
23
  method,
23
24
  headers: headersObj,
24
25
  // body is made available only if the request is for a page that will be on-demand rendered
25
- body: isPrerendered ? null : body
26
+ body: isPrerendered ? null : body,
27
+ ...init
26
28
  });
27
29
  if (isPrerendered) {
28
30
  let _headers = request.headers;
@@ -3,7 +3,6 @@ import type { Logger } from '../../logger/core.js';
3
3
  import nodeFs from 'node:fs';
4
4
  import type { RoutePart } from '../../../types/public/internal.js';
5
5
  export declare function getParts(part: string, file: string): RoutePart[];
6
- export declare function validateSegment(segment: string, file?: string): void;
7
6
  export interface CreateRouteManifestParams {
8
7
  /** Astro Settings object */
9
8
  settings: AstroSettings;
@@ -19,14 +19,8 @@ import { routeComparator } from "../priority.js";
19
19
  import { getRouteGenerator } from "./generator.js";
20
20
  import { getPattern } from "./pattern.js";
21
21
  import { getRoutePrerenderOption } from "./prerender.js";
22
+ import { validateSegment } from "./segment.js";
22
23
  const require2 = createRequire(import.meta.url);
23
- function countOccurrences(needle, haystack) {
24
- let count = 0;
25
- for (const hay of haystack) {
26
- if (hay === needle) count += 1;
27
- }
28
- return count;
29
- }
30
24
  const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
31
25
  const ROUTE_SPREAD = /^\.{3}.+$/;
32
26
  function getParts(part, file) {
@@ -46,18 +40,6 @@ function getParts(part, file) {
46
40
  });
47
41
  return result;
48
42
  }
49
- function validateSegment(segment, file = "") {
50
- if (!file) file = segment;
51
- if (segment.includes("][")) {
52
- throw new Error(`Invalid route ${file} \u2014 parameters must be separated`);
53
- }
54
- if (countOccurrences("[", segment) !== countOccurrences("]", segment)) {
55
- throw new Error(`Invalid route ${file} \u2014 brackets are unbalanced`);
56
- }
57
- if ((/.+\[\.\.\.[^\]]+\]/.test(segment) || /\[\.\.\.[^\]]+\].+/.test(segment)) && file.endsWith(".astro")) {
58
- throw new Error(`Invalid route ${file} \u2014 rest parameter must be a standalone segment`);
59
- }
60
- }
61
43
  function isSemanticallyEqualSegment(segmentA, segmentB) {
62
44
  if (segmentA.length !== segmentB.length) {
63
45
  return false;
@@ -529,6 +511,5 @@ function joinSegments(segments) {
529
511
  export {
530
512
  createRouteManifest,
531
513
  getParts,
532
- resolveInjectedRoute,
533
- validateSegment
514
+ resolveInjectedRoute
534
515
  };
@@ -0,0 +1,2 @@
1
+ import type { RoutePart } from '../../../types/public/index.js';
2
+ export declare function getParts(part: string, file: string): RoutePart[];
@@ -0,0 +1,22 @@
1
+ const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
2
+ const ROUTE_SPREAD = /^\.{3}.+$/;
3
+ function getParts(part, file) {
4
+ const result = [];
5
+ part.split(ROUTE_DYNAMIC_SPLIT).map((str, i) => {
6
+ if (!str) return;
7
+ const dynamic = i % 2 === 1;
8
+ const [, content] = dynamic ? /([^(]+)$/.exec(str) || [null, null] : [null, str];
9
+ if (!content || dynamic && !/^(?:\.\.\.)?[\w$]+$/.test(content)) {
10
+ throw new Error(`Invalid route ${file} \u2014 parameter name must match /^[a-zA-Z0-9_$]+$/`);
11
+ }
12
+ result.push({
13
+ content,
14
+ dynamic,
15
+ spread: dynamic && ROUTE_SPREAD.test(content)
16
+ });
17
+ });
18
+ return result;
19
+ }
20
+ export {
21
+ getParts
22
+ };
@@ -0,0 +1 @@
1
+ export declare function validateSegment(segment: string, file?: string): void;
@@ -0,0 +1,22 @@
1
+ function validateSegment(segment, file = "") {
2
+ if (!file) file = segment;
3
+ if (segment.includes("][")) {
4
+ throw new Error(`Invalid route ${file} \u2014 parameters must be separated`);
5
+ }
6
+ if (countOccurrences("[", segment) !== countOccurrences("]", segment)) {
7
+ throw new Error(`Invalid route ${file} \u2014 brackets are unbalanced`);
8
+ }
9
+ if ((/.+\[\.\.\.[^\]]+\]/.test(segment) || /\[\.\.\.[^\]]+\].+/.test(segment)) && file.endsWith(".astro")) {
10
+ throw new Error(`Invalid route ${file} \u2014 rest parameter must be a standalone segment`);
11
+ }
12
+ }
13
+ function countOccurrences(needle, haystack) {
14
+ let count = 0;
15
+ for (const hay of haystack) {
16
+ if (hay === needle) count += 1;
17
+ }
18
+ return count;
19
+ }
20
+ export {
21
+ validateSegment
22
+ };
@@ -1,6 +1,7 @@
1
1
  import type { RewritePayload } from '../../types/public/common.js';
2
2
  import type { AstroConfig } from '../../types/public/config.js';
3
3
  import type { RouteData } from '../../types/public/internal.js';
4
+ import type { Logger } from '../logger/core.js';
4
5
  export type FindRouteToRewrite = {
5
6
  payload: RewritePayload;
6
7
  routes: RouteData[];
@@ -25,7 +26,10 @@ export declare function findRouteToRewrite({ payload, routes, request, trailingS
25
26
  *
26
27
  * @param newUrl The new `URL`
27
28
  * @param oldRequest The old `Request`
29
+ * @param isPrerendered It needs to be the flag of the previous routeData, before the rewrite
30
+ * @param logger
31
+ * @param routePattern
28
32
  */
29
- export declare function copyRequest(newUrl: URL, oldRequest: Request): Request;
33
+ export declare function copyRequest(newUrl: URL, oldRequest: Request, isPrerendered: boolean, logger: Logger, routePattern: string): Request;
30
34
  export declare function setOriginPathname(request: Request, pathname: string): void;
31
35
  export declare function getOriginPathname(request: Request): string;
@@ -2,6 +2,7 @@ import { shouldAppendForwardSlash } from "../build/util.js";
2
2
  import { originPathnameSymbol } from "../constants.js";
3
3
  import { AstroError, AstroErrorData } from "../errors/index.js";
4
4
  import { appendForwardSlash, removeTrailingForwardSlash } from "../path.js";
5
+ import { createRequest } from "../request.js";
5
6
  import { DEFAULT_404_ROUTE } from "./astro-designed-error-pages.js";
6
7
  function findRouteToRewrite({
7
8
  payload,
@@ -46,26 +47,32 @@ function findRouteToRewrite({
46
47
  }
47
48
  }
48
49
  }
49
- function copyRequest(newUrl, oldRequest) {
50
+ function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) {
50
51
  if (oldRequest.bodyUsed) {
51
52
  throw new AstroError(AstroErrorData.RewriteWithBodyUsed);
52
53
  }
53
- return new Request(newUrl, {
54
+ return createRequest({
55
+ url: newUrl,
54
56
  method: oldRequest.method,
55
- headers: oldRequest.headers,
56
57
  body: oldRequest.body,
57
- referrer: oldRequest.referrer,
58
- referrerPolicy: oldRequest.referrerPolicy,
59
- mode: oldRequest.mode,
60
- credentials: oldRequest.credentials,
61
- cache: oldRequest.cache,
62
- redirect: oldRequest.redirect,
63
- integrity: oldRequest.integrity,
64
- signal: oldRequest.signal,
65
- keepalive: oldRequest.keepalive,
66
- // https://fetch.spec.whatwg.org/#dom-request-duplex
67
- // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
68
- duplex: "half"
58
+ isPrerendered,
59
+ logger,
60
+ headers: isPrerendered ? {} : oldRequest.headers,
61
+ routePattern,
62
+ init: {
63
+ referrer: oldRequest.referrer,
64
+ referrerPolicy: oldRequest.referrerPolicy,
65
+ mode: oldRequest.mode,
66
+ credentials: oldRequest.credentials,
67
+ cache: oldRequest.cache,
68
+ redirect: oldRequest.redirect,
69
+ integrity: oldRequest.integrity,
70
+ signal: oldRequest.signal,
71
+ keepalive: oldRequest.keepalive,
72
+ // https://fetch.spec.whatwg.org/#dom-request-duplex
73
+ // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
74
+ duplex: "half"
75
+ }
69
76
  });
70
77
  }
71
78
  function setOriginPathname(request, pathname) {
@@ -12,6 +12,7 @@ export type SyncOptions = {
12
12
  cleanup?: boolean;
13
13
  };
14
14
  manifest: ManifestData;
15
+ command: 'build' | 'dev' | 'sync';
15
16
  };
16
17
  export default function sync(inlineConfig: AstroInlineConfig, { fs, telemetry: _telemetry }?: {
17
18
  fs?: typeof fsMod;
@@ -20,10 +21,11 @@ export default function sync(inlineConfig: AstroInlineConfig, { fs, telemetry: _
20
21
  /**
21
22
  * Clears the content layer and content collection cache, forcing a full rebuild.
22
23
  */
23
- export declare function clearContentLayerCache({ settings, logger, fs, }: {
24
+ export declare function clearContentLayerCache({ settings, logger, fs, isDev, }: {
24
25
  settings: AstroSettings;
25
26
  logger: Logger;
26
27
  fs?: typeof fsMod;
28
+ isDev: boolean;
27
29
  }): Promise<void>;
28
30
  /**
29
31
  * Generates TypeScript types for all Astro modules. This sets up a `src/env.d.ts` file for type inferencing,
@@ -31,4 +33,4 @@ export declare function clearContentLayerCache({ settings, logger, fs, }: {
31
33
  *
32
34
  * @experimental The JavaScript API is experimental
33
35
  */
34
- export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, }: SyncOptions): Promise<void>;
36
+ export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, command, }: SyncOptions): Promise<void>;
@@ -1,10 +1,9 @@
1
- import fsMod, { existsSync } from "node:fs";
1
+ import fsMod from "node:fs";
2
2
  import { dirname, relative } from "node:path";
3
3
  import { performance } from "node:perf_hooks";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { dim } from "kleur/colors";
6
6
  import { createServer } from "vite";
7
- import { normalizePath } from "vite";
8
7
  import { CONTENT_TYPES_FILE } from "../../content/consts.js";
9
8
  import { getDataStoreFile, globalContentLayer } from "../../content/content-layer.js";
10
9
  import { createContentTypesGenerator } from "../../content/index.js";
@@ -28,6 +27,7 @@ import {
28
27
  } from "../errors/index.js";
29
28
  import { createRouteManifest } from "../routing/index.js";
30
29
  import { ensureProcessNodeEnv } from "../util.js";
30
+ import { normalizePath } from "../viteUtils.js";
31
31
  async function sync(inlineConfig, { fs, telemetry: _telemetry = false } = {}) {
32
32
  ensureProcessNodeEnv("production");
33
33
  const logger = createNodeLogger(inlineConfig);
@@ -49,15 +49,17 @@ async function sync(inlineConfig, { fs, telemetry: _telemetry = false } = {}) {
49
49
  mode: "production",
50
50
  fs,
51
51
  force: inlineConfig.force,
52
- manifest
52
+ manifest,
53
+ command: "sync"
53
54
  });
54
55
  }
55
56
  async function clearContentLayerCache({
56
57
  settings,
57
58
  logger,
58
- fs = fsMod
59
+ fs = fsMod,
60
+ isDev
59
61
  }) {
60
- const dataStore = getDataStoreFile(settings);
62
+ const dataStore = getDataStoreFile(settings, isDev);
61
63
  if (fs.existsSync(dataStore)) {
62
64
  logger.debug("content", "clearing data store");
63
65
  await fs.promises.rm(dataStore, { force: true });
@@ -71,10 +73,12 @@ async function syncInternal({
71
73
  settings,
72
74
  skip,
73
75
  force,
74
- manifest
76
+ manifest,
77
+ command
75
78
  }) {
79
+ const isDev = command === "dev";
76
80
  if (force) {
77
- await clearContentLayerCache({ settings, logger, fs });
81
+ await clearContentLayerCache({ settings, logger, fs, isDev });
78
82
  }
79
83
  const timerStart = performance.now();
80
84
  if (!skip?.content) {
@@ -82,15 +86,14 @@ async function syncInternal({
82
86
  settings.timer.start("Sync content layer");
83
87
  let store;
84
88
  try {
85
- const dataStoreFile = getDataStoreFile(settings);
86
- if (existsSync(dataStoreFile)) {
87
- store = await MutableDataStore.fromFile(dataStoreFile);
88
- }
89
+ const dataStoreFile = getDataStoreFile(settings, isDev);
90
+ store = await MutableDataStore.fromFile(dataStoreFile);
89
91
  } catch (err) {
90
92
  logger.error("content", err.message);
91
93
  }
92
94
  if (!store) {
93
- store = new MutableDataStore();
95
+ logger.error("content", "Failed to load content store");
96
+ return;
94
97
  }
95
98
  const contentLayer = globalContentLayer.init({
96
99
  settings,
@@ -1,6 +1,6 @@
1
1
  import type { AstroSettings } from '../types/astro.js';
2
2
  import type { AstroConfig } from '../types/public/config.js';
3
- import type { RouteType } from '../types/public/internal.js';
3
+ import type { RouteData } from '../types/public/internal.js';
4
4
  /** Returns true if argument is an object of any prototype/class (but not null). */
5
5
  export declare function isObject(value: unknown): value is Record<string, any>;
6
6
  /** Cross-realm compatible URL */
@@ -17,7 +17,7 @@ export declare function padMultilineString(source: string, n?: number): string;
17
17
  * Handles both "/foo" and "foo" `name` formats.
18
18
  * Handles `/404` and `/` correctly.
19
19
  */
20
- export declare function getOutputFilename(astroConfig: AstroConfig, name: string, type: RouteType): string;
20
+ export declare function getOutputFilename(astroConfig: AstroConfig, name: string, routeData: RouteData): string;
21
21
  /** is a specifier an npm package? */
22
22
  export declare function parseNpmName(spec: string): {
23
23
  scope?: string;
package/dist/core/util.js CHANGED
@@ -26,8 +26,8 @@ function padMultilineString(source, n = 2) {
26
26
  `);
27
27
  }
28
28
  const STATUS_CODE_PAGES = /* @__PURE__ */ new Set(["/404", "/500"]);
29
- function getOutputFilename(astroConfig, name, type) {
30
- if (type === "endpoint") {
29
+ function getOutputFilename(astroConfig, name, routeData) {
30
+ if (routeData.type === "endpoint") {
31
31
  return name;
32
32
  }
33
33
  if (name === "/" || name === "") {
@@ -36,6 +36,9 @@ function getOutputFilename(astroConfig, name, type) {
36
36
  if (astroConfig.build.format === "file" || STATUS_CODE_PAGES.has(name)) {
37
37
  return `${removeTrailingForwardSlash(name || "index")}.html`;
38
38
  }
39
+ if (astroConfig.build.format === "preserve" && !routeData.isIndex) {
40
+ return `${removeTrailingForwardSlash(name || "index")}.html`;
41
+ }
39
42
  return path.posix.join(name, "index.html");
40
43
  }
41
44
  function parseNpmName(spec) {