astro 7.1.3 → 7.1.4

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.
@@ -168,6 +168,17 @@ type ImageSharedProps<T> = T & {
168
168
  * ```
169
169
  */
170
170
  position?: string;
171
+ /**
172
+ * The background color to use when converting images with transparency to a format that does not support it (e.g. PNG to JPEG).
173
+ *
174
+ * The value is a string that specifies a CSS color value, e.g. `#fff`, `white`, `rgb(255, 255, 255)`.
175
+ *
176
+ * **Example**:
177
+ * ```astro
178
+ * <Image src={...} format="jpeg" background="#fff" alt="..." />
179
+ * ```
180
+ */
181
+ background?: string;
171
182
  } & ({
172
183
  /**
173
184
  * The layout type for responsive images.
@@ -66,6 +66,7 @@ async function background({
66
66
  const astroBin = resolve(dirname(require2.resolve("astro/package.json")), "bin", "astro.mjs");
67
67
  const child = spawn(process.execPath, [astroBin, ...args], {
68
68
  detached: true,
69
+ windowsHide: true,
69
70
  stdio: ["ignore", logFd, logFd],
70
71
  cwd: rootPath,
71
72
  env: { ...process.env, ASTRO_DEV_BACKGROUND: "1" }
@@ -1,6 +1,6 @@
1
1
  class BuildTimeAstroVersionProvider {
2
2
  // Injected during the build through esbuild define
3
- version = "7.1.3";
3
+ version = "7.1.4";
4
4
  }
5
5
  export {
6
6
  BuildTimeAstroVersionProvider
@@ -1,7 +1,5 @@
1
- import { posix } from "node:path";
2
- import { getDefaultClientDirectives } from "../core/client-directive/index.js";
3
- import { ASTRO_CONFIG_DEFAULTS } from "../core/config/schemas/index.js";
4
- import { validateConfig } from "../core/config/validate.js";
1
+ import { getDefaultClientDirectives } from "../core/client-directive/default.js";
2
+ import { ASTRO_CONFIG_DEFAULTS } from "../core/config/schemas/defaults.js";
5
3
  import { createKey } from "../core/encryption.js";
6
4
  import { FetchState } from "../core/fetch/fetch-state.js";
7
5
  import { AstroMiddleware } from "../core/middleware/astro-middleware.js";
@@ -14,15 +12,18 @@ import { validateSegment } from "../core/routing/segment.js";
14
12
  import { SlotString } from "../runtime/server/render/slot.js";
15
13
  import { ContainerPipeline } from "./pipeline.js";
16
14
  import { createConsoleLogger } from "../core/logger/impls/console.js";
17
- const { gfm: _, smartypants: __, ...containerMarkdownDefaults } = ASTRO_CONFIG_DEFAULTS.markdown;
18
- const CONTAINER_CONFIG_DEFAULTS = { ...ASTRO_CONFIG_DEFAULTS, markdown: containerMarkdownDefaults };
19
15
  function createManifest(manifest, renderers, middleware) {
20
16
  function middlewareInstance() {
21
17
  return {
22
18
  onRequest: middleware ?? NOOP_MIDDLEWARE_FN
23
19
  };
24
20
  }
25
- const root = new URL(import.meta.url);
21
+ let root;
22
+ try {
23
+ root = new URL(import.meta.url);
24
+ } catch {
25
+ root = new URL("file:///container/");
26
+ }
26
27
  return {
27
28
  rootDir: root,
28
29
  srcDir: manifest?.srcDir ?? new URL(ASTRO_CONFIG_DEFAULTS.srcDir, root),
@@ -81,17 +82,17 @@ class experimental_AstroContainer {
81
82
  streaming = false,
82
83
  manifest,
83
84
  renderers,
84
- resolve,
85
- astroConfig
85
+ resolve
86
86
  }) {
87
+ const ssrManifest = createManifest(manifest, renderers);
87
88
  this.#pipeline = ContainerPipeline.create({
88
89
  logger: createConsoleLogger({ level: "error" }),
89
- manifest: createManifest(manifest, renderers),
90
+ manifest: ssrManifest,
90
91
  streaming,
91
92
  renderers: renderers ?? manifest?.renderers ?? [],
92
93
  resolve: async (specifier) => {
93
94
  if (this.#withManifest) {
94
- return this.#containerResolve(specifier, astroConfig);
95
+ return this.#containerResolve(specifier, ssrManifest);
95
96
  } else if (resolve) {
96
97
  return resolve(specifier);
97
98
  }
@@ -101,10 +102,10 @@ class experimental_AstroContainer {
101
102
  this.#astroMiddleware = new AstroMiddleware(this.#pipeline);
102
103
  this.#pagesHandler = new PagesHandler(this.#pipeline);
103
104
  }
104
- async #containerResolve(specifier, astroConfig) {
105
- const found = this.#pipeline.manifest.entryModules[specifier];
105
+ async #containerResolve(specifier, manifest) {
106
+ const found = manifest.entryModules[specifier];
106
107
  if (found) {
107
- return new URL(found, astroConfig?.build.client).toString();
108
+ return new URL(found, manifest.buildClientDir).toString();
108
109
  }
109
110
  return found;
110
111
  }
@@ -115,12 +116,10 @@ class experimental_AstroContainer {
115
116
  */
116
117
  static async create(containerOptions = {}) {
117
118
  const { streaming = false, manifest, renderers = [], resolve } = containerOptions;
118
- const astroConfig = await validateConfig(CONTAINER_CONFIG_DEFAULTS, process.cwd(), "container");
119
119
  return new experimental_AstroContainer({
120
120
  streaming,
121
121
  manifest,
122
122
  renderers,
123
- astroConfig,
124
123
  resolve
125
124
  });
126
125
  }
@@ -208,10 +207,8 @@ class experimental_AstroContainer {
208
207
  // NOTE: we keep this private via TS instead via `#` so it's still available on the surface, so we can play with it.
209
208
  // @ts-expect-error @ematipico: I plan to use it for a possible integration that could help people
210
209
  static async createFromManifest(manifest) {
211
- const astroConfig = await validateConfig(CONTAINER_CONFIG_DEFAULTS, process.cwd(), "container");
212
210
  const container = new experimental_AstroContainer({
213
- manifest,
214
- astroConfig
211
+ manifest
215
212
  });
216
213
  container.#withManifest = true;
217
214
  return container;
@@ -330,7 +327,7 @@ class experimental_AstroContainer {
330
327
  this.#pipeline.insertRoute(routeData, componentInstance);
331
328
  }
332
329
  #createRoute(url, params, type) {
333
- const segments = removeLeadingForwardSlash(url.pathname).split(posix.sep).filter(Boolean).map((s) => {
330
+ const segments = removeLeadingForwardSlash(url.pathname).split("/").filter(Boolean).map((s) => {
334
331
  validateSegment(s);
335
332
  return getParts(s, url.pathname);
336
333
  });
@@ -196,7 +196,7 @@ ${contentConfig.error.message}`
196
196
  logger.info("Content config changed");
197
197
  shouldClear = true;
198
198
  }
199
- if (previousAstroVersion && previousAstroVersion !== "7.1.3") {
199
+ if (previousAstroVersion && previousAstroVersion !== "7.1.4") {
200
200
  logger.info("Astro version changed");
201
201
  shouldClear = true;
202
202
  }
@@ -204,8 +204,8 @@ ${contentConfig.error.message}`
204
204
  logger.info("Clearing content store");
205
205
  this.#store.clearAll();
206
206
  }
207
- if ("7.1.3") {
208
- this.#store.metaStore().set("astro-version", "7.1.3");
207
+ if ("7.1.4") {
208
+ this.#store.metaStore().set("astro-version", "7.1.4");
209
209
  }
210
210
  if (currentConfigDigest) {
211
211
  this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -1,7 +1,7 @@
1
1
  import { existsSync, promises as fs } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import yaml from "js-yaml";
4
- import toml from "smol-toml";
4
+ import * as toml from "smol-toml";
5
5
  import { FileGlobNotSupported, FileParserNotFound } from "../../core/errors/errors-data.js";
6
6
  import { AstroError } from "../../core/errors/index.js";
7
7
  import { posixRelative } from "../utils.js";
@@ -232,7 +232,12 @@ function glob(globOptions) {
232
232
  return;
233
233
  }
234
234
  watcher.add(filePath);
235
- const matchesGlob = (entry) => !entry.startsWith("../") && picomatch.isMatch(entry, globOptions.pattern);
235
+ const patterns = Array.isArray(globOptions.pattern) ? globOptions.pattern : [globOptions.pattern];
236
+ const positivePatterns = patterns.filter((p) => !p.startsWith("!"));
237
+ const negationPatterns = patterns.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
238
+ const matchesGlob = (entry) => !entry.startsWith("../") && picomatch.isMatch(entry, positivePatterns, {
239
+ ignore: negationPatterns.length > 0 ? negationPatterns : void 0
240
+ });
236
241
  const basePath = fileURLToPath(baseDir);
237
242
  async function onChange(changedPath) {
238
243
  const entry = posixRelative(basePath, changedPath);
@@ -10,6 +10,14 @@ export interface BuildInternals {
10
10
  * build so the client can pick up the same information and use the same chunk ids.
11
11
  */
12
12
  cssModuleToChunkIdMap: Map<string, string>;
13
+ /**
14
+ * Maps a key describing the exact set of CSS modules bundled into a chunk of the
15
+ * prerender environment to the CSS asset filename emitted for that chunk. The SSR
16
+ * environment renames its own CSS assets to these filenames when they are backed by
17
+ * the same CSS source modules, so the prerender and server builds don't emit
18
+ * duplicate stylesheets for shared layouts (#17298).
19
+ */
20
+ prerenderCssAssetByModuleKey: Map<string, string>;
13
21
  /**
14
22
  * If script is inlined, its id and inlined code is mapped here. The resolved id is
15
23
  * an URL like "/_astro/something.js" but will no longer exist as the content is now
@@ -4,6 +4,7 @@ function createBuildInternals() {
4
4
  return {
5
5
  clientInput: /* @__PURE__ */ new Set(),
6
6
  cssModuleToChunkIdMap: /* @__PURE__ */ new Map(),
7
+ prerenderCssAssetByModuleKey: /* @__PURE__ */ new Map(),
7
8
  inlinedScripts: /* @__PURE__ */ new Map(),
8
9
  entrySpecifierToBundleMap: /* @__PURE__ */ new Map(),
9
10
  pagesByKeys: /* @__PURE__ */ new Map(),
@@ -46,6 +46,20 @@ function rollupPluginAstroBuildCSS(options) {
46
46
  internals.cssModuleToChunkIdMap.set(moduleId, chunk.fileName);
47
47
  }
48
48
  }
49
+ const cssModuleIds = Object.keys(chunk.modules || {}).filter(isCSSRequest);
50
+ const importedCss = chunk.viteMetadata?.importedCss;
51
+ if (cssModuleIds.length > 0 && importedCss?.size === 1) {
52
+ const moduleKey = cssModuleIds.sort().join("\n");
53
+ const [assetFileName] = importedCss;
54
+ if (this.environment?.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender) {
55
+ internals.prerenderCssAssetByModuleKey.set(moduleKey, assetFileName);
56
+ } else {
57
+ const prerenderFileName = internals.prerenderCssAssetByModuleKey.get(moduleKey);
58
+ if (prerenderFileName && prerenderFileName !== assetFileName) {
59
+ renameBundleAsset(bundle, assetFileName, prerenderFileName);
60
+ }
61
+ }
62
+ }
49
63
  for (const [moduleId, moduleInfo] of Object.entries(chunk.modules || {})) {
50
64
  if (moduleInfo.renderedExports.length > 0) {
51
65
  const existing = internals.ssrRenderedExports?.get(moduleId);
@@ -112,6 +126,21 @@ function rollupPluginAstroBuildCSS(options) {
112
126
  for (const importedCssImport of meta.importedCss) {
113
127
  const cssToInfoRecord = pagesToCss[pageData.moduleSpecifier] ??= {};
114
128
  cssToInfoRecord[importedCssImport] = { depth: -1, order: -1 };
129
+ if (deletedCssAssets.has(importedCssImport)) {
130
+ const cssAsset = deletedCssAssets.get(importedCssImport);
131
+ if (cssAsset.type === "asset" && typeof cssAsset.source === "string" && cssAsset.source.length > 0) {
132
+ const sheet = {
133
+ type: "inline",
134
+ content: cssAsset.source
135
+ };
136
+ const alreadyAdded = pageData.styles.some(
137
+ (s) => s.sheet.type === "inline" && s.sheet.content === sheet.content
138
+ );
139
+ if (!alreadyAdded) {
140
+ pageData.styles.push({ depth: -1, order: -1, sheet });
141
+ }
142
+ }
143
+ }
115
144
  }
116
145
  }
117
146
  }
@@ -316,6 +345,21 @@ function rollupPluginAstroBuildCSS(options) {
316
345
  };
317
346
  return [cssBuildPlugin, singleCssPlugin, inlineStylesheetsPlugin];
318
347
  }
348
+ function renameBundleAsset(bundle, fromFileName, toFileName) {
349
+ const asset = bundle[fromFileName];
350
+ if (!asset || asset.type !== "asset" || bundle[toFileName]) return;
351
+ asset.fileName = toFileName;
352
+ for (const chunk of Object.values(bundle)) {
353
+ if (chunk.type !== "chunk") continue;
354
+ const meta = chunk.viteMetadata;
355
+ if (meta?.importedCss?.delete(fromFileName)) {
356
+ meta.importedCss.add(toFileName);
357
+ }
358
+ if (meta?.importedAssets?.delete(fromFileName)) {
359
+ meta.importedAssets.add(toFileName);
360
+ }
361
+ }
362
+ }
319
363
  function shouldDeleteCSSChunk(allModules, internals) {
320
364
  const componentPaths = /* @__PURE__ */ new Set();
321
365
  for (const componentPath of internals.discoveredClientOnlyComponents.keys()) {
@@ -16,73 +16,8 @@ type RemarkPlugin = ComplexifyWithUnion<_RemarkPlugin>;
16
16
  export type RemarkRehype = ComplexifyWithOmit<_RemarkRehype>;
17
17
  /** @lintignore */
18
18
  export type Smartypants = ComplexifyWithOmit<_Smartypants>;
19
- export declare const ASTRO_CONFIG_DEFAULTS: {
20
- root: string;
21
- srcDir: string;
22
- publicDir: string;
23
- outDir: string;
24
- cacheDir: string;
25
- base: string;
26
- trailingSlash: "ignore";
27
- build: {
28
- format: "directory";
29
- client: string;
30
- server: string;
31
- assets: string;
32
- serverEntry: string;
33
- redirects: true;
34
- inlineStylesheets: "auto";
35
- concurrency: number;
36
- };
37
- image: {
38
- endpoint: {
39
- entrypoint: undefined;
40
- route: "/_image";
41
- };
42
- service: {
43
- entrypoint: "astro/assets/services/sharp";
44
- config: {};
45
- };
46
- dangerouslyProcessSVG: false;
47
- responsiveStyles: false;
48
- };
49
- devToolbar: {
50
- enabled: true;
51
- };
52
- compressHTML: "jsx";
53
- server: {
54
- host: false;
55
- port: number;
56
- open: false;
57
- allowedHosts: never[];
58
- };
59
- integrations: never[];
60
- markdown: Required<Omit<import("@astrojs/internal-helpers/markdown").AstroMarkdownOptions, "image">>;
61
- vite: {};
62
- legacy: {
63
- collectionsBackwardsCompat: false;
64
- };
65
- redirects: {};
66
- security: {
67
- checkOrigin: true;
68
- allowedDomains: never[];
69
- csp: false;
70
- actionBodySizeLimit: number;
71
- serverIslandBodySizeLimit: number;
72
- };
73
- env: {
74
- schema: {};
75
- validateSecrets: false;
76
- };
77
- prerenderConflictBehavior: "warn";
78
- fetchFile: string;
79
- experimental: {
80
- clientPrerender: false;
81
- contentIntellisense: false;
82
- chromeDevtoolsWorkspace: false;
83
- collectionStorage: "single-file";
84
- };
85
- };
19
+ import { ASTRO_CONFIG_DEFAULTS } from './defaults.js';
20
+ export { ASTRO_CONFIG_DEFAULTS };
86
21
  export declare const AstroConfigSchema: z.ZodObject<{
87
22
  root: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<URL, string>>;
88
23
  srcDir: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<URL, string>>;
@@ -563,4 +498,3 @@ export declare const AstroConfigSchema: z.ZodObject<{
563
498
  }, z.core.$strip>>;
564
499
  }, z.core.$strip>;
565
500
  export type AstroConfigType = z.infer<typeof AstroConfigSchema>;
566
- export {};
@@ -1,7 +1,4 @@
1
- import {
2
- markdownConfigDefaults,
3
- syntaxHighlightDefaults
4
- } from "@astrojs/internal-helpers/markdown";
1
+ import { syntaxHighlightDefaults } from "@astrojs/internal-helpers/markdown";
5
2
  import { satteri } from "@astrojs/markdown-satteri";
6
3
  import { bundledThemes } from "shiki";
7
4
  import * as z from "zod/v4";
@@ -16,67 +13,7 @@ import {
16
13
  cspResourceEntrySchema
17
14
  } from "../../csp/config.js";
18
15
  import { SessionSchema } from "../../session/config.js";
19
- const ASTRO_CONFIG_DEFAULTS = {
20
- root: ".",
21
- srcDir: "./src",
22
- publicDir: "./public",
23
- outDir: "./dist",
24
- cacheDir: "./node_modules/.astro",
25
- base: "/",
26
- trailingSlash: "ignore",
27
- build: {
28
- format: "directory",
29
- client: "./client/",
30
- server: "./server/",
31
- assets: "_astro",
32
- serverEntry: "entry.mjs",
33
- redirects: true,
34
- inlineStylesheets: "auto",
35
- concurrency: 1
36
- },
37
- image: {
38
- endpoint: { entrypoint: void 0, route: "/_image" },
39
- service: { entrypoint: "astro/assets/services/sharp", config: {} },
40
- dangerouslyProcessSVG: false,
41
- responsiveStyles: false
42
- },
43
- devToolbar: {
44
- enabled: true
45
- },
46
- compressHTML: "jsx",
47
- server: {
48
- host: false,
49
- port: 4321,
50
- open: false,
51
- allowedHosts: []
52
- },
53
- integrations: [],
54
- markdown: markdownConfigDefaults,
55
- vite: {},
56
- legacy: {
57
- collectionsBackwardsCompat: false
58
- },
59
- redirects: {},
60
- security: {
61
- checkOrigin: true,
62
- allowedDomains: [],
63
- csp: false,
64
- actionBodySizeLimit: 1024 * 1024,
65
- serverIslandBodySizeLimit: 1024 * 1024
66
- },
67
- env: {
68
- schema: {},
69
- validateSecrets: false
70
- },
71
- prerenderConflictBehavior: "warn",
72
- fetchFile: "fetch",
73
- experimental: {
74
- clientPrerender: false,
75
- contentIntellisense: false,
76
- chromeDevtoolsWorkspace: false,
77
- collectionStorage: "single-file"
78
- }
79
- };
16
+ import { ASTRO_CONFIG_DEFAULTS } from "./defaults.js";
80
17
  const highlighterTypesSchema = z.union([z.literal("shiki"), z.literal("prism")]).default(syntaxHighlightDefaults.type);
81
18
  const quoteCharacterMapSchema = z.object({
82
19
  double: z.string(),
@@ -0,0 +1,67 @@
1
+ export declare const ASTRO_CONFIG_DEFAULTS: {
2
+ root: string;
3
+ srcDir: string;
4
+ publicDir: string;
5
+ outDir: string;
6
+ cacheDir: string;
7
+ base: string;
8
+ trailingSlash: "ignore";
9
+ build: {
10
+ format: "directory";
11
+ client: string;
12
+ server: string;
13
+ assets: string;
14
+ serverEntry: string;
15
+ redirects: true;
16
+ inlineStylesheets: "auto";
17
+ concurrency: number;
18
+ };
19
+ image: {
20
+ endpoint: {
21
+ entrypoint: undefined;
22
+ route: "/_image";
23
+ };
24
+ service: {
25
+ entrypoint: "astro/assets/services/sharp";
26
+ config: {};
27
+ };
28
+ dangerouslyProcessSVG: false;
29
+ responsiveStyles: false;
30
+ };
31
+ devToolbar: {
32
+ enabled: true;
33
+ };
34
+ compressHTML: "jsx";
35
+ server: {
36
+ host: false;
37
+ port: number;
38
+ open: false;
39
+ allowedHosts: never[];
40
+ };
41
+ integrations: never[];
42
+ markdown: Required<Omit<import("@astrojs/internal-helpers/markdown").AstroMarkdownOptions, "image">>;
43
+ vite: {};
44
+ legacy: {
45
+ collectionsBackwardsCompat: false;
46
+ };
47
+ redirects: {};
48
+ security: {
49
+ checkOrigin: true;
50
+ allowedDomains: never[];
51
+ csp: false;
52
+ actionBodySizeLimit: number;
53
+ serverIslandBodySizeLimit: number;
54
+ };
55
+ env: {
56
+ schema: {};
57
+ validateSecrets: false;
58
+ };
59
+ prerenderConflictBehavior: "warn";
60
+ fetchFile: string;
61
+ experimental: {
62
+ clientPrerender: false;
63
+ contentIntellisense: false;
64
+ chromeDevtoolsWorkspace: false;
65
+ collectionStorage: "single-file";
66
+ };
67
+ };
@@ -0,0 +1,65 @@
1
+ import { markdownConfigDefaults } from "@astrojs/internal-helpers/markdown";
2
+ const ASTRO_CONFIG_DEFAULTS = {
3
+ root: ".",
4
+ srcDir: "./src",
5
+ publicDir: "./public",
6
+ outDir: "./dist",
7
+ cacheDir: "./node_modules/.astro",
8
+ base: "/",
9
+ trailingSlash: "ignore",
10
+ build: {
11
+ format: "directory",
12
+ client: "./client/",
13
+ server: "./server/",
14
+ assets: "_astro",
15
+ serverEntry: "entry.mjs",
16
+ redirects: true,
17
+ inlineStylesheets: "auto",
18
+ concurrency: 1
19
+ },
20
+ image: {
21
+ endpoint: { entrypoint: void 0, route: "/_image" },
22
+ service: { entrypoint: "astro/assets/services/sharp", config: {} },
23
+ dangerouslyProcessSVG: false,
24
+ responsiveStyles: false
25
+ },
26
+ devToolbar: {
27
+ enabled: true
28
+ },
29
+ compressHTML: "jsx",
30
+ server: {
31
+ host: false,
32
+ port: 4321,
33
+ open: false,
34
+ allowedHosts: []
35
+ },
36
+ integrations: [],
37
+ markdown: markdownConfigDefaults,
38
+ vite: {},
39
+ legacy: {
40
+ collectionsBackwardsCompat: false
41
+ },
42
+ redirects: {},
43
+ security: {
44
+ checkOrigin: true,
45
+ allowedDomains: [],
46
+ csp: false,
47
+ actionBodySizeLimit: 1024 * 1024,
48
+ serverIslandBodySizeLimit: 1024 * 1024
49
+ },
50
+ env: {
51
+ schema: {},
52
+ validateSecrets: false
53
+ },
54
+ prerenderConflictBehavior: "warn",
55
+ fetchFile: "fetch",
56
+ experimental: {
57
+ clientPrerender: false,
58
+ contentIntellisense: false,
59
+ chromeDevtoolsWorkspace: false,
60
+ collectionStorage: "single-file"
61
+ }
62
+ };
63
+ export {
64
+ ASTRO_CONFIG_DEFAULTS
65
+ };
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
3
  import yaml from "js-yaml";
4
- import toml from "smol-toml";
4
+ import * as toml from "smol-toml";
5
5
  import { getContentPaths } from "../../content/index.js";
6
6
  import createPreferences from "../../preferences/index.js";
7
7
  import { markdownContentEntryType } from "../../vite-plugin-markdown/content-entry-type.js";
@@ -23,7 +23,7 @@ async function loadConfigWithVite({
23
23
  let server;
24
24
  try {
25
25
  const plugins = loadFallbackPlugin({ fs, root: pathToFileURL(root) });
26
- server = await createMinimalViteDevServer(plugins);
26
+ server = await createMinimalViteDevServer(plugins, root);
27
27
  if (isRunnableDevEnvironment(server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr])) {
28
28
  const environment = server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr];
29
29
  const mod = await environment.runner.import(configPath);
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "7.1.3";
1
+ const ASTRO_VERSION = "7.1.4";
2
2
  const ASTRO_GENERATOR = `Astro v${ASTRO_VERSION}`;
3
3
  const ASTRO_ERROR_HEADER = "X-Astro-Error";
4
4
  const DEFAULT_404_COMPONENT = "astro-default-404.astro";
@@ -49,7 +49,7 @@ class AstroCookies {
49
49
  name: key,
50
50
  value: DELETED_VALUE,
51
51
  expires: DELETED_EXPIRATION,
52
- // Unset `expires` to to ensure that `expires` takes precedence.
52
+ // Unset `maxAge` to ensure that `expires` takes precedence.
53
53
  maxAge: void 0
54
54
  }),
55
55
  false
@@ -5,4 +5,4 @@ import { type ViteDevServer, type Plugin } from 'vite';
5
5
  * NOTE: This is intentionally in its own module to avoid pulling `vite`'s heavy `createServer`
6
6
  * (and transitively Rollup) into every file that imports from `viteUtils.ts`.
7
7
  */
8
- export declare function createMinimalViteDevServer(plugins?: Plugin[]): Promise<ViteDevServer>;
8
+ export declare function createMinimalViteDevServer(plugins?: Plugin[], root?: string): Promise<ViteDevServer>;
@@ -1,12 +1,14 @@
1
1
  import { createServer } from "vite";
2
- async function createMinimalViteDevServer(plugins = []) {
2
+ async function createMinimalViteDevServer(plugins = [], root) {
3
3
  return await createServer({
4
+ root,
4
5
  configFile: false,
5
6
  server: { middlewareMode: true, hmr: false, watch: null, ws: false },
6
7
  optimizeDeps: { noDiscovery: true },
7
8
  clearScreen: false,
8
9
  appType: "custom",
9
10
  ssr: { external: true },
11
+ resolve: { tsconfigPaths: true },
10
12
  plugins
11
13
  });
12
14
  }
@@ -26,7 +26,7 @@ async function dev(inlineConfig) {
26
26
  await telemetry.record([]);
27
27
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
28
28
  const logger = restart.container.logger;
29
- const currentVersion = "7.1.3";
29
+ const currentVersion = "7.1.4";
30
30
  const isPrerelease = currentVersion.includes("-");
31
31
  if (!isPrerelease) {
32
32
  try {
@@ -270,7 +270,7 @@ function printHelp({
270
270
  message.push(
271
271
  linebreak(),
272
272
  ` ${bgGreen(black(` ${commandName} `))} ${green(
273
- `v${"7.1.3"}`
273
+ `v${"7.1.4"}`
274
274
  )} ${headline}`
275
275
  );
276
276
  }
@@ -1,7 +1,7 @@
1
1
  import type { SessionDriverConfig } from './types.js';
2
2
  export declare const sessionDrivers: {
3
- http: (config?: import("unstorage/drivers/http").HTTPOptions | undefined) => SessionDriverConfig;
4
3
  fs: (config?: import("unstorage/drivers/fs").FSStorageOptions | undefined) => SessionDriverConfig;
4
+ http: (config?: import("unstorage/drivers/http").HTTPOptions | undefined) => SessionDriverConfig;
5
5
  azureAppConfiguration: (config?: import("unstorage/drivers/azure-app-configuration").AzureAppConfigurationOptions | undefined) => SessionDriverConfig;
6
6
  azureCosmos: (config?: import("unstorage/drivers/azure-cosmos").AzureCosmosOptions | undefined) => SessionDriverConfig;
7
7
  azureKeyVault: (config?: import("unstorage/drivers/azure-key-vault").AzureKeyVaultOptions | undefined) => SessionDriverConfig;
@@ -20,7 +20,8 @@ async function provideSessionAsync(state, config) {
20
20
  config,
21
21
  runtimeMode: pipeline.runtimeMode,
22
22
  driverFactory,
23
- mockStorage: null
23
+ mockStorage: null,
24
+ logger: pipeline.logger
24
25
  });
25
26
  },
26
27
  finalize(session) {
@@ -1,18 +1,21 @@
1
1
  import type { RuntimeMode } from '../../types/public/config.js';
2
2
  import type { AstroCookies } from '../cookies/cookies.js';
3
+ import type { AstroLogger } from '../logger/core.js';
3
4
  import type { SessionDriverFactory } from './types.js';
4
5
  import type { SSRManifestSession } from '../app/types.js';
5
6
  import { type Storage } from 'unstorage';
6
7
  export declare const PERSIST_SYMBOL: unique symbol;
8
+ export interface AstroSessionOptions {
9
+ cookies: AstroCookies;
10
+ config: SSRManifestSession | undefined;
11
+ runtimeMode: RuntimeMode;
12
+ driverFactory: SessionDriverFactory | null;
13
+ mockStorage: Storage | null;
14
+ logger: AstroLogger;
15
+ }
7
16
  export declare class AstroSession {
8
17
  #private;
9
- constructor({ cookies, config, runtimeMode, driverFactory, mockStorage, }: {
10
- cookies: AstroCookies;
11
- config: SSRManifestSession | undefined;
12
- runtimeMode: RuntimeMode;
13
- driverFactory: SessionDriverFactory | null;
14
- mockStorage: Storage | null;
15
- });
18
+ constructor({ cookies, config, runtimeMode, driverFactory, mockStorage, logger, }: AstroSessionOptions);
16
19
  /**
17
20
  * Gets a session value. Returns `undefined` if the session or value does not exist.
18
21
  */
@@ -46,7 +46,7 @@ class AstroSession {
46
46
  // When we load the data from storage, we need to merge it with the local partial data,
47
47
  // preserving in-memory changes and deletions.
48
48
  #partial = true;
49
- // The driver factory function provided by the pipeline
49
+ #logger;
50
50
  #driverFactory;
51
51
  static #sharedStorage = /* @__PURE__ */ new Map();
52
52
  constructor({
@@ -54,8 +54,10 @@ class AstroSession {
54
54
  config,
55
55
  runtimeMode,
56
56
  driverFactory,
57
- mockStorage
57
+ mockStorage,
58
+ logger
58
59
  }) {
60
+ this.#logger = logger;
59
61
  if (!config) {
60
62
  throw new AstroError({
61
63
  ...SessionStorageInitError,
@@ -185,7 +187,8 @@ class AstroSession {
185
187
  try {
186
188
  data = await this.#ensureData();
187
189
  } catch (err) {
188
- console.error("Failed to load session data during regeneration:", err);
190
+ this.#logger.error("session", `Failed to load session data during regeneration: ${err}`);
191
+ this.#partial = false;
189
192
  }
190
193
  const oldSessionId = this.#sessionID;
191
194
  this.#sessionID = crypto.randomUUID();
@@ -195,7 +198,7 @@ class AstroSession {
195
198
  await this.#setCookie();
196
199
  if (oldSessionId && this.#storage) {
197
200
  this.#storage.removeItem(oldSessionId).catch((err) => {
198
- console.error("Failed to remove old session data:", err);
201
+ this.#logger.error("session", `Failed to remove old session ${oldSessionId}: ${err}`);
199
202
  });
200
203
  }
201
204
  }
@@ -232,7 +235,7 @@ class AstroSession {
232
235
  if (this.#toDestroy.size > 0) {
233
236
  const cleanupPromises = [...this.#toDestroy].map(
234
237
  (sessionId) => storage.removeItem(sessionId).catch((err) => {
235
- console.error("Failed to clean up session %s:", sessionId, err);
238
+ this.#logger.error("session", `Failed to remove session ${sessionId}: ${err}`);
236
239
  })
237
240
  );
238
241
  await Promise.all(cleanupPromises);
@@ -296,7 +299,7 @@ class AstroSession {
296
299
  try {
297
300
  const storedMap = unflatten(raw);
298
301
  if (!(storedMap instanceof Map)) {
299
- await this.destroy();
302
+ this.destroy();
300
303
  throw new AstroError({
301
304
  ...SessionStorageInitError,
302
305
  message: SessionStorageInitError.message(
@@ -315,7 +318,7 @@ class AstroSession {
315
318
  this.#partial = false;
316
319
  return this.#data;
317
320
  } catch (err) {
318
- await this.destroy();
321
+ this.destroy();
319
322
  if (err instanceof AstroError) {
320
323
  throw err;
321
324
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "7.1.3",
3
+ "version": "7.1.4",
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",
@@ -121,7 +121,7 @@
121
121
  "http-cache-semantics": "^4.2.0",
122
122
  "js-yaml": "^4.1.1",
123
123
  "jsonc-parser": "^3.3.1",
124
- "magic-string": "^0.30.21",
124
+ "magic-string": "^1.0.0",
125
125
  "magicast": "^0.5.2",
126
126
  "mrmime": "^2.0.1",
127
127
  "neotraverse": "^1.0.1",
@@ -147,8 +147,8 @@
147
147
  "yargs-parser": "^22.0.0",
148
148
  "zod": "^4.3.6",
149
149
  "@astrojs/internal-helpers": "0.10.1",
150
- "@astrojs/telemetry": "3.3.3",
151
- "@astrojs/markdown-satteri": "0.3.4"
150
+ "@astrojs/markdown-satteri": "0.3.4",
151
+ "@astrojs/telemetry": "3.3.3"
152
152
  },
153
153
  "optionalDependencies": {
154
154
  "sharp": "^0.34.0 || ^0.35.0"
@@ -186,7 +186,7 @@
186
186
  "typescript": "^6.0.3",
187
187
  "undici": "^7.22.0",
188
188
  "vitest": "^4.1.0",
189
- "@astrojs/check": "0.9.9",
189
+ "@astrojs/check": "0.9.10",
190
190
  "@astrojs/markdown-remark": "7.2.1",
191
191
  "astro-scripts": "0.0.14"
192
192
  },
@@ -204,7 +204,7 @@
204
204
  },
205
205
  "scripts": {
206
206
  "prebuild": "astro-scripts prebuild --to-string \"src/runtime/server/astro-island.ts\" \"src/runtime/client/{idle,load,media,only,visible}.ts\"",
207
- "build": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm && tsc -b && astro-check -- -- --root ./components",
207
+ "build": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm && tsc -b && astro-check -- -- --tsconfig ./tsconfig.components.json",
208
208
  "build:ci": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm",
209
209
  "dev": "astro-scripts dev --copy-wasm --prebuild \"src/runtime/server/astro-island.ts\" --prebuild \"src/runtime/client/{idle,load,media,only,visible}.ts\" \"src/**/*.{ts,js}\"",
210
210
  "test": "pnpm run test:unit && pnpm run test:integration && pnpm run test:types",
@@ -1,2 +0,0 @@
1
- /// <reference path="../client.d.ts" />
2
- /// <reference path="../dev-only.d.ts" />