astro 2.1.8 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/config.d.ts +2 -1
  2. package/dist/@types/astro.d.ts +36 -9
  3. package/dist/assets/image-endpoint.js +2 -2
  4. package/dist/assets/index.d.ts +1 -1
  5. package/dist/assets/index.js +3 -2
  6. package/dist/assets/internal.d.ts +9 -9
  7. package/dist/assets/internal.js +10 -1
  8. package/dist/assets/services/service.d.ts +2 -2
  9. package/dist/assets/services/service.js +6 -0
  10. package/dist/assets/services/vendor/squoosh/copy-wasm.d.ts +1 -0
  11. package/dist/assets/services/vendor/squoosh/copy-wasm.js +19 -6
  12. package/dist/assets/services/vendor/squoosh/image-pool.d.ts +2 -2
  13. package/dist/assets/services/vendor/squoosh/image.d.ts +2 -2
  14. package/dist/assets/types.d.ts +19 -10
  15. package/dist/assets/utils/emitAsset.d.ts +2 -1
  16. package/dist/assets/utils/emitAsset.js +4 -1
  17. package/dist/assets/utils/transformToPath.d.ts +2 -1
  18. package/dist/assets/utils/transformToPath.js +7 -3
  19. package/dist/assets/vite-plugin-assets.js +21 -19
  20. package/dist/cli/index.js +1 -1
  21. package/dist/content/runtime-assets.d.ts +3 -7
  22. package/dist/content/runtime-assets.js +20 -16
  23. package/dist/content/template/virtual-mod.d.mts +1 -0
  24. package/dist/content/utils.d.ts +2 -6
  25. package/dist/content/utils.js +16 -56
  26. package/dist/content/vite-plugin-content-assets.js +13 -4
  27. package/dist/content/vite-plugin-content-imports.js +3 -4
  28. package/dist/content/vite-plugin-content-virtual-mod.js +1 -4
  29. package/dist/core/app/index.js +2 -0
  30. package/dist/core/build/add-rollup-input.d.ts +2 -2
  31. package/dist/core/build/generate.js +27 -7
  32. package/dist/core/build/internal.d.ts +3 -3
  33. package/dist/core/build/plugins/plugin-css.js +0 -29
  34. package/dist/core/build/plugins/plugin-internals.js +0 -7
  35. package/dist/core/build/plugins/plugin-ssr.js +12 -7
  36. package/dist/core/build/static-build.js +7 -3
  37. package/dist/core/config/schema.d.ts +12 -0
  38. package/dist/core/config/schema.js +2 -0
  39. package/dist/core/constants.js +1 -1
  40. package/dist/core/cookies/cookies.js +7 -0
  41. package/dist/core/create-vite.js +11 -2
  42. package/dist/core/dev/container.js +0 -3
  43. package/dist/core/dev/dev.js +1 -1
  44. package/dist/core/errors/dev/utils.js +6 -2
  45. package/dist/core/errors/errors-data.d.ts +76 -3
  46. package/dist/core/errors/errors-data.js +76 -3
  47. package/dist/core/errors/overlay.js +8 -6
  48. package/dist/core/messages.js +2 -2
  49. package/dist/core/render/dev/index.js +1 -1
  50. package/dist/core/render/dev/scripts.d.ts +1 -1
  51. package/dist/core/render/dev/scripts.js +7 -6
  52. package/dist/core/render/paginate.js +15 -8
  53. package/dist/core/render/result.js +6 -0
  54. package/dist/core/render/ssr-element.d.ts +7 -6
  55. package/dist/core/render/ssr-element.js +28 -20
  56. package/dist/core/sync/index.js +9 -2
  57. package/dist/core/util.d.ts +1 -1
  58. package/dist/core/util.js +2 -2
  59. package/dist/runtime/server/render/common.d.ts +1 -1
  60. package/dist/vite-plugin-astro-server/response.d.ts +1 -1
  61. package/dist/vite-plugin-astro-server/response.js +2 -1
  62. package/dist/vite-plugin-astro-server/route.js +1 -1
  63. package/dist/vite-plugin-env/index.js +9 -0
  64. package/dist/vite-plugin-markdown/index.js +31 -14
  65. package/package.json +3 -3
  66. package/src/content/template/types.d.ts +23 -3
  67. package/src/content/template/virtual-mod.mjs +7 -0
  68. package/dist/content/template/virtual-mod-assets.d.mts +0 -1
  69. package/dist/vite-plugin-integrations-container/index.d.ts +0 -8
  70. package/dist/vite-plugin-integrations-container/index.js +0 -15
  71. package/src/content/template/virtual-mod-assets.mjs +0 -7
@@ -5,10 +5,10 @@ import path from "node:path";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
6
  import { normalizePath } from "vite";
7
7
  import { z } from "zod";
8
- import { emitESMImage } from "../assets/utils/emitAsset.js";
9
8
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
10
9
  import { CONTENT_TYPES_FILE } from "./consts.js";
11
10
  import { errorMap } from "./error-map.js";
11
+ import { createImage } from "./runtime-assets.js";
12
12
  const collectionConfigParser = z.object({
13
13
  schema: z.any().optional()
14
14
  });
@@ -25,22 +25,6 @@ const contentConfigParser = z.object({
25
25
  const msg = {
26
26
  collectionConfigMissing: (collection) => `${collection} does not have a config. We suggest adding one for type safety!`
27
27
  };
28
- async function patchAssets(frontmatterEntry, watchMode, fileEmitter, astroSettings) {
29
- for (const key of Object.keys(frontmatterEntry)) {
30
- if (typeof frontmatterEntry[key] === "object" && frontmatterEntry[key] !== null) {
31
- if (frontmatterEntry[key]["__astro_asset"]) {
32
- frontmatterEntry[key] = await emitESMImage(
33
- frontmatterEntry[key].src,
34
- watchMode,
35
- fileEmitter,
36
- astroSettings
37
- );
38
- } else {
39
- await patchAssets(frontmatterEntry[key], watchMode, fileEmitter, astroSettings);
40
- }
41
- }
42
- }
43
- }
44
28
  function getEntrySlug({
45
29
  id,
46
30
  collection,
@@ -56,50 +40,27 @@ function getEntrySlug({
56
40
  });
57
41
  }
58
42
  }
59
- async function getEntryData(entry, collectionConfig, resolver) {
43
+ async function getEntryData(entry, collectionConfig, pluginContext, settings) {
60
44
  let { slug, ...data } = entry.unvalidatedData;
61
- if (collectionConfig.schema) {
62
- if (typeof collectionConfig.schema === "object" && !("safeParseAsync" in collectionConfig.schema)) {
63
- throw new AstroError({
64
- title: "Invalid content collection config",
65
- message: `New: Content collection schemas must be Zod objects. Update your collection config to use \`schema: z.object({...})\` instead of \`schema: {...}\`.`,
66
- hint: "See https://docs.astro.build/en/reference/api-reference/#definecollection for an example.",
67
- code: 99999
68
- });
45
+ let schema = collectionConfig.schema;
46
+ if (typeof schema === "function") {
47
+ if (!settings.config.experimental.assets) {
48
+ throw new Error(
49
+ "The function shape for schema can only be used when `experimental.assets` is enabled."
50
+ );
69
51
  }
70
- if (typeof collectionConfig.schema === "object" && "shape" in collectionConfig.schema && collectionConfig.schema.shape.slug) {
52
+ schema = schema({
53
+ image: createImage(settings, pluginContext, entry._internal.filePath)
54
+ });
55
+ }
56
+ if (schema) {
57
+ if (typeof schema === "object" && "shape" in schema && schema.shape.slug) {
71
58
  throw new AstroError({
72
59
  ...AstroErrorData.ContentSchemaContainsSlugError,
73
60
  message: AstroErrorData.ContentSchemaContainsSlugError.message(entry.collection)
74
61
  });
75
62
  }
76
- async function preprocessAssetPaths(object) {
77
- if (typeof object !== "object" || object === null)
78
- return;
79
- for (let [schemaName, schema] of Object.entries(object)) {
80
- if (schema._def.description === "__image") {
81
- object[schemaName] = z.preprocess(
82
- async (value) => {
83
- var _a;
84
- if (!value || typeof value !== "string")
85
- return value;
86
- return (_a = await resolver(value)) == null ? void 0 : _a.id;
87
- },
88
- schema,
89
- { description: void 0 }
90
- );
91
- } else if ("shape" in schema) {
92
- await preprocessAssetPaths(schema.shape);
93
- } else if ("unwrap" in schema) {
94
- const unwrapped = schema.unwrap().shape;
95
- if (unwrapped) {
96
- await preprocessAssetPaths(unwrapped);
97
- }
98
- }
99
- }
100
- }
101
- await preprocessAssetPaths(collectionConfig.schema.shape);
102
- const parsed = await collectionConfig.schema.safeParseAsync(entry.unvalidatedData, {
63
+ const parsed = await schema.safeParseAsync(entry.unvalidatedData, {
103
64
  errorMap
104
65
  });
105
66
  if (parsed.success) {
@@ -288,6 +249,5 @@ export {
288
249
  globalContentConfigObserver,
289
250
  loadContentConfig,
290
251
  msg,
291
- parseFrontmatter,
292
- patchAssets
252
+ parseFrontmatter
293
253
  };
@@ -1,9 +1,8 @@
1
- import npath from "node:path";
2
1
  import { pathToFileURL } from "url";
3
2
  import { moduleIsTopLevelPage, walkParentInfos } from "../core/build/graph.js";
4
3
  import { getPageDataByViteID } from "../core/build/internal.js";
5
4
  import { createViteLoader } from "../core/module-loader/vite.js";
6
- import { prependForwardSlash } from "../core/path.js";
5
+ import { joinPaths, prependForwardSlash } from "../core/path.js";
7
6
  import { getStylesForURL } from "../core/render/dev/css.js";
8
7
  import { getScriptsForURL } from "../core/render/dev/scripts.js";
9
8
  import {
@@ -59,7 +58,11 @@ function astroContentAssetPropagationPlugin({
59
58
  devModuleLoader,
60
59
  "development"
61
60
  );
62
- const hoistedScripts = await getScriptsForURL(pathToFileURL(basePath), devModuleLoader);
61
+ const hoistedScripts = await getScriptsForURL(
62
+ pathToFileURL(basePath),
63
+ settings.config.root,
64
+ devModuleLoader
65
+ );
63
66
  return {
64
67
  code: code.replace(JSON.stringify(LINKS_PLACEHOLDER), JSON.stringify([...urls])).replace(JSON.stringify(STYLES_PLACEHOLDER), JSON.stringify([...stylesMap.values()])).replace(JSON.stringify(SCRIPTS_PLACEHOLDER), JSON.stringify([...hoistedScripts]))
65
68
  };
@@ -87,7 +90,13 @@ function astroConfigBuildPlugin(options, internals) {
87
90
  "build:post": ({ ssrOutputs, clientOutputs, mutate }) => {
88
91
  var _a, _b;
89
92
  const outputs = ssrOutputs.flatMap((o) => o.output);
90
- const prependBase = (src) => prependForwardSlash(npath.posix.join(options.settings.config.base, src));
93
+ const prependBase = (src) => {
94
+ if (options.settings.config.build.assetsPrefix) {
95
+ return joinPaths(options.settings.config.build.assetsPrefix, src);
96
+ } else {
97
+ return prependForwardSlash(joinPaths(options.settings.config.base, src));
98
+ }
99
+ };
91
100
  for (const chunk of outputs) {
92
101
  if (chunk.type === "chunk" && (chunk.code.includes(LINKS_PLACEHOLDER) || chunk.code.includes(SCRIPTS_PLACEHOLDER))) {
93
102
  let entryCSS = /* @__PURE__ */ new Set();
@@ -13,8 +13,7 @@ import {
13
13
  getEntrySlug,
14
14
  getEntryType,
15
15
  globalContentConfigObserver,
16
- NoCollectionError,
17
- patchAssets
16
+ NoCollectionError
18
17
  } from "./utils.js";
19
18
  function isContentFlagImport(viteId, contentEntryExts) {
20
19
  const { searchParams, pathname } = new URL(viteId, "file://");
@@ -164,9 +163,9 @@ export const _internal = {
164
163
  let data = collectionConfig ? await getEntryData(
165
164
  { id, collection, slug, _internal, unvalidatedData },
166
165
  collectionConfig,
167
- (idToResolve) => pluginContext.resolve(idToResolve, fileId)
166
+ pluginContext,
167
+ settings
168
168
  ) : unvalidatedData;
169
- await patchAssets(data, pluginContext.meta.watchMode, pluginContext.emitFile, settings);
170
169
  const contentEntryModule = {
171
170
  id,
172
171
  slug,
@@ -16,16 +16,13 @@ function astroContentVirtualModPlugin({
16
16
  )
17
17
  );
18
18
  const contentEntryExts = getContentEntryExts(settings);
19
- const assetsDir = settings.config.experimental.assets ? contentPaths.assetsDir.toString() : "undefined";
20
19
  const extGlob = contentEntryExts.length === 1 ? (
21
20
  // Wrapping {...} breaks when there is only one extension
22
21
  contentEntryExts[0]
23
22
  ) : `{${contentEntryExts.join(",")}}`;
24
23
  const entryGlob = `${relContentDir}**/*${extGlob}`;
25
24
  const virtualModContents = fsMod.readFileSync(contentPaths.virtualModTemplate, "utf-8").replace("@@CONTENT_DIR@@", relContentDir).replace("@@ENTRY_GLOB_PATH@@", entryGlob).replace("@@RENDER_ENTRY_GLOB_PATH@@", entryGlob);
26
- const virtualAssetsModContents = fsMod.readFileSync(contentPaths.virtualAssetsModTemplate, "utf-8").replace("@@ASSETS_DIR@@", assetsDir);
27
25
  const astroContentVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
28
- const allContents = settings.config.experimental.assets ? virtualModContents + virtualAssetsModContents : virtualModContents;
29
26
  return {
30
27
  name: "astro-content-virtual-mod-plugin",
31
28
  enforce: "pre",
@@ -37,7 +34,7 @@ function astroContentVirtualModPlugin({
37
34
  load(id) {
38
35
  if (id === astroContentVirtualModuleId) {
39
36
  return {
40
- code: allContents
37
+ code: virtualModContents
41
38
  };
42
39
  }
43
40
  }
@@ -18,6 +18,7 @@ import { matchRoute } from "../routing/match.js";
18
18
  import { deserializeManifest } from "./common.js";
19
19
  const pagesVirtualModuleId = "@astrojs-pages-virtual-entry";
20
20
  const resolvedPagesVirtualModuleId = "\0" + pagesVirtualModuleId;
21
+ const responseSentSymbol = Symbol.for("astro.responseSent");
21
22
  class App {
22
23
  #env;
23
24
  #manifest;
@@ -168,6 +169,7 @@ class App {
168
169
  status
169
170
  });
170
171
  const response = await renderPage(mod, ctx, this.#env);
172
+ Reflect.set(request, responseSentSymbol, true);
171
173
  return response;
172
174
  } catch (err) {
173
175
  error(this.#logging, "ssr", err.stack || err.message || String(err));
@@ -1,2 +1,2 @@
1
- import type { InputOptions } from 'rollup';
2
- export declare function addRollupInput(inputOptions: InputOptions, newInputs: string[]): InputOptions;
1
+ import type { Rollup } from 'vite';
2
+ export declare function addRollupInput(inputOptions: Rollup.InputOptions, newInputs: string[]): Rollup.InputOptions;
@@ -1,12 +1,12 @@
1
1
  import fs from "fs";
2
2
  import * as colors from "kleur/colors";
3
3
  import { bgGreen, black, cyan, dim, green, magenta } from "kleur/colors";
4
- import npath from "path";
5
4
  import { fileURLToPath } from "url";
6
5
  import {
7
6
  generateImage as generateImageInternal,
8
7
  getStaticImageList
9
8
  } from "../../assets/internal.js";
9
+ import { deleteWasmFiles } from "../../assets/services/vendor/squoosh/copy-wasm.js";
10
10
  import { hasPrerenderedPages } from "../../core/build/internal.js";
11
11
  import {
12
12
  prependForwardSlash,
@@ -20,7 +20,11 @@ import { AstroError } from "../errors/index.js";
20
20
  import { debug, info } from "../logger/core.js";
21
21
  import { createEnvironment, createRenderContext, renderPage } from "../render/index.js";
22
22
  import { callGetStaticPaths } from "../render/route-cache.js";
23
- import { createLinkStylesheetElementSet, createModuleScriptsSet } from "../render/ssr-element.js";
23
+ import {
24
+ createAssetLink,
25
+ createLinkStylesheetElementSet,
26
+ createModuleScriptsSet
27
+ } from "../render/ssr-element.js";
24
28
  import { createRequest } from "../request.js";
25
29
  import { matchRoute } from "../routing/match.js";
26
30
  import { getOutputFilename } from "../util.js";
@@ -82,7 +86,10 @@ ${bgGreen(black(` ${verb} static routes `))}`);
82
86
  info(opts.logging, null, `
83
87
  ${bgGreen(black(` generating optimized images `))}`);
84
88
  for (const imageData of getStaticImageList()) {
85
- await generateImage(opts, imageData[0], imageData[1]);
89
+ await generateImage(opts, imageData[1].options, imageData[1].path);
90
+ }
91
+ if (opts.settings.config.image.service === "astro/assets/services/squoosh" && opts.settings.config.output === "static") {
92
+ await deleteWasmFiles(new URL("./chunks", opts.settings.config.outDir));
86
93
  }
87
94
  delete globalThis.astroAsset.addStaticImage;
88
95
  }
@@ -234,17 +241,26 @@ async function generatePath(pathname, opts, gopts) {
234
241
  addPageName(pathname, opts);
235
242
  }
236
243
  debug("build", `Generating: ${pathname}`);
237
- const links = createLinkStylesheetElementSet(linkIds, settings.config.base);
244
+ const links = createLinkStylesheetElementSet(
245
+ linkIds,
246
+ settings.config.base,
247
+ settings.config.build.assetsPrefix
248
+ );
238
249
  const scripts = createModuleScriptsSet(
239
250
  hoistedScripts ? [hoistedScripts] : [],
240
- settings.config.base
251
+ settings.config.base,
252
+ settings.config.build.assetsPrefix
241
253
  );
242
254
  if (settings.scripts.some((script) => script.stage === "page")) {
243
255
  const hashedFilePath = internals.entrySpecifierToBundleMap.get(PAGE_SCRIPT_ID);
244
256
  if (typeof hashedFilePath !== "string") {
245
257
  throw new Error(`Cannot find the built path for ${PAGE_SCRIPT_ID}`);
246
258
  }
247
- const src = prependForwardSlash(npath.posix.join(settings.config.base, hashedFilePath));
259
+ const src = createAssetLink(
260
+ hashedFilePath,
261
+ settings.config.base,
262
+ settings.config.build.assetsPrefix
263
+ );
248
264
  scripts.add({
249
265
  props: { type: "module", src },
250
266
  children: ""
@@ -280,7 +296,11 @@ async function generatePath(pathname, opts, gopts) {
280
296
  }
281
297
  throw new Error(`Cannot find the built path for ${specifier}`);
282
298
  }
283
- return prependForwardSlash(npath.posix.join(settings.config.base, hashedFilePath));
299
+ return createAssetLink(
300
+ hashedFilePath,
301
+ settings.config.base,
302
+ settings.config.build.assetsPrefix
303
+ );
284
304
  },
285
305
  routeCache,
286
306
  site: settings.config.site ? new URL(settings.config.base, settings.config.site).toString() : settings.config.site,
@@ -1,4 +1,4 @@
1
- import type { OutputChunk, RenderedChunk } from 'rollup';
1
+ import type { Rollup } from 'vite';
2
2
  import type { PageBuildData, ViteID } from './types';
3
3
  import type { SSRResult } from '../../@types/astro';
4
4
  import type { PageOptions } from '../../vite-plugin-astro/types';
@@ -57,7 +57,7 @@ export interface BuildInternals {
57
57
  */
58
58
  discoveredScripts: Set<string>;
59
59
  staticFiles: Set<string>;
60
- ssrEntryChunk?: OutputChunk;
60
+ ssrEntryChunk?: Rollup.OutputChunk;
61
61
  componentMetadata: SSRResult['componentMetadata'];
62
62
  }
63
63
  /**
@@ -70,7 +70,7 @@ export declare function trackPageData(internals: BuildInternals, component: stri
70
70
  * Tracks client-only components to the pages they are associated with.
71
71
  */
72
72
  export declare function trackClientOnlyPageDatas(internals: BuildInternals, pageData: PageBuildData, clientOnlys: string[]): void;
73
- export declare function getPageDatasByChunk(internals: BuildInternals, chunk: RenderedChunk): Generator<PageBuildData, void, unknown>;
73
+ export declare function getPageDatasByChunk(internals: BuildInternals, chunk: Rollup.RenderedChunk): Generator<PageBuildData, void, unknown>;
74
74
  export declare function getPageDatasByClientOnlyID(internals: BuildInternals, viteid: ViteID): Generator<PageBuildData, void, unknown>;
75
75
  export declare function getPageDataByComponent(internals: BuildInternals, component: string): PageBuildData | undefined;
76
76
  export declare function getPageDataByViteID(internals: BuildInternals, viteid: ViteID): PageBuildData | undefined;
@@ -1,6 +1,5 @@
1
1
  import * as crypto from "node:crypto";
2
2
  import * as npath from "node:path";
3
- import { transformWithEsbuild } from "vite";
4
3
  import { isBuildableCSSRequest } from "../../render/dev/util.js";
5
4
  import { PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
6
5
  import * as assetName from "../css-asset-name.js";
@@ -166,34 +165,6 @@ function rollupPluginAstroBuildCSS(options) {
166
165
  }
167
166
  }
168
167
  }
169
- },
170
- {
171
- name: "astro:rollup-plugin-build-css-minify",
172
- enforce: "post",
173
- async generateBundle(_outputOptions, bundle) {
174
- var _a, _b, _c;
175
- if (options.target === "server") {
176
- for (const [, output] of Object.entries(bundle)) {
177
- if (output.type === "asset") {
178
- if (((_a = output.name) == null ? void 0 : _a.endsWith(".css")) && typeof output.source === "string") {
179
- const cssTarget = (_b = settings.config.vite.build) == null ? void 0 : _b.cssTarget;
180
- const minify = ((_c = settings.config.vite.build) == null ? void 0 : _c.minify) !== false;
181
- const { code: minifiedCSS } = await transformWithEsbuild(
182
- output.source,
183
- output.name,
184
- {
185
- loader: "css",
186
- minify,
187
- target: cssTarget || void 0,
188
- sourcemap: false
189
- }
190
- );
191
- output.source = minifiedCSS;
192
- }
193
- }
194
- }
195
- }
196
- }
197
168
  }
198
169
  ];
199
170
  }
@@ -16,13 +16,6 @@ function vitePluginInternals(input, internals) {
16
16
  };
17
17
  return extra;
18
18
  },
19
- configResolved(resolvedConfig) {
20
- const plugins = resolvedConfig.plugins;
21
- const viteAsset = plugins.find((p) => p.name === "vite:asset");
22
- if (viteAsset) {
23
- delete viteAsset.generateBundle;
24
- }
25
- },
26
19
  async generateBundle(_options, bundle) {
27
20
  const promises = [];
28
21
  const mapping = /* @__PURE__ */ new Map();
@@ -3,7 +3,7 @@ import { fileURLToPath } from "url";
3
3
  import { runHookBuildSsr } from "../../../integrations/index.js";
4
4
  import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../../vite-plugin-scripts/index.js";
5
5
  import { pagesVirtualModuleId } from "../../app/index.js";
6
- import { removeLeadingForwardSlash, removeTrailingForwardSlash } from "../../path.js";
6
+ import { joinPaths, prependForwardSlash } from "../../path.js";
7
7
  import { serializeRouteData } from "../../routing/index.js";
8
8
  import { addRollupInput } from "../add-rollup-input.js";
9
9
  import { getOutFile, getOutFolder } from "../common.js";
@@ -104,8 +104,13 @@ function buildManifest(opts, internals, staticFiles) {
104
104
  if (settings.scripts.some((script) => script.stage === "page")) {
105
105
  staticFiles.push(entryModules[PAGE_SCRIPT_ID]);
106
106
  }
107
- const bareBase = removeTrailingForwardSlash(removeLeadingForwardSlash(settings.config.base));
108
- const joinBase = (pth) => bareBase ? bareBase + "/" + pth : pth;
107
+ const prefixAssetPath = (pth) => {
108
+ if (settings.config.build.assetsPrefix) {
109
+ return joinPaths(settings.config.build.assetsPrefix, pth);
110
+ } else {
111
+ return prependForwardSlash(joinPaths(settings.config.base, pth));
112
+ }
113
+ };
109
114
  for (const pageData of eachPrerenderedPageData(internals)) {
110
115
  if (!pageData.route.pathname)
111
116
  continue;
@@ -133,7 +138,7 @@ function buildManifest(opts, internals, staticFiles) {
133
138
  const scripts = [];
134
139
  if (pageData.hoistedScript) {
135
140
  const hoistedValue = pageData.hoistedScript.value;
136
- const value = hoistedValue.endsWith(".js") ? joinBase(hoistedValue) : hoistedValue;
141
+ const value = hoistedValue.endsWith(".js") ? prefixAssetPath(hoistedValue) : hoistedValue;
137
142
  scripts.unshift(
138
143
  Object.assign({}, pageData.hoistedScript, {
139
144
  value
@@ -144,10 +149,10 @@ function buildManifest(opts, internals, staticFiles) {
144
149
  const src = entryModules[PAGE_SCRIPT_ID];
145
150
  scripts.push({
146
151
  type: "external",
147
- value: joinBase(src)
152
+ value: prefixAssetPath(src)
148
153
  });
149
154
  }
150
- const links = sortedCSS(pageData).map((pth) => joinBase(pth));
155
+ const links = sortedCSS(pageData).map((pth) => prefixAssetPath(pth));
151
156
  routes.push({
152
157
  file: "",
153
158
  links,
@@ -171,7 +176,7 @@ function buildManifest(opts, internals, staticFiles) {
171
176
  componentMetadata: Array.from(internals.componentMetadata),
172
177
  renderers: [],
173
178
  entryModules,
174
- assets: staticFiles.map((s) => settings.config.base + s)
179
+ assets: staticFiles.map(prefixAssetPath)
175
180
  };
176
181
  return ssrManifest;
177
182
  }
@@ -94,7 +94,7 @@ ${bgMagenta(black(" finalizing server assets "))}
94
94
  }
95
95
  }
96
96
  async function ssrBuild(opts, internals, input, container) {
97
- var _a, _b, _c;
97
+ var _a, _b, _c, _d, _e;
98
98
  const { settings, viteConfig } = opts;
99
99
  const ssr = settings.config.output === "server";
100
100
  const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(settings.config.outDir);
@@ -105,13 +105,16 @@ async function ssrBuild(opts, internals, input, container) {
105
105
  logLevel: opts.viteConfig.logLevel ?? "error",
106
106
  build: {
107
107
  target: "esnext",
108
+ // Vite defaults cssMinify to false in SSR by default, but we want to minify it
109
+ // as the CSS generated are used and served to the client.
110
+ cssMinify: ((_a = viteConfig.build) == null ? void 0 : _a.minify) == null ? true : !!((_b = viteConfig.build) == null ? void 0 : _b.minify),
108
111
  ...viteConfig.build,
109
112
  emptyOutDir: false,
110
113
  manifest: false,
111
114
  outDir: fileURLToPath(out),
112
115
  copyPublicDir: !ssr,
113
116
  rollupOptions: {
114
- ...(_a = viteConfig.build) == null ? void 0 : _a.rollupOptions,
117
+ ...(_c = viteConfig.build) == null ? void 0 : _c.rollupOptions,
115
118
  input: [],
116
119
  output: {
117
120
  format: "esm",
@@ -119,7 +122,7 @@ async function ssrBuild(opts, internals, input, container) {
119
122
  // We need to keep these separate
120
123
  chunkFileNames: `chunks/[name].[hash].mjs`,
121
124
  assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
122
- ...(_c = (_b = viteConfig.build) == null ? void 0 : _b.rollupOptions) == null ? void 0 : _c.output,
125
+ ...(_e = (_d = viteConfig.build) == null ? void 0 : _d.rollupOptions) == null ? void 0 : _e.output,
123
126
  entryFileNames(chunkInfo) {
124
127
  if (chunkInfo.facadeModuleId === resolvedPagesVirtualModuleId) {
125
128
  return opts.buildConfig.serverEntry;
@@ -130,6 +133,7 @@ async function ssrBuild(opts, internals, input, container) {
130
133
  }
131
134
  },
132
135
  ssr: true,
136
+ ssrEmitAssets: true,
133
137
  // improve build performance
134
138
  minify: false,
135
139
  modulePreload: { polyfill: false },
@@ -41,8 +41,10 @@ export declare const AstroConfigSchema: z.ZodObject<{
41
41
  client: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, URL, string | undefined>;
42
42
  server: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, URL, string | undefined>;
43
43
  assets: z.ZodDefault<z.ZodOptional<z.ZodString>>;
44
+ assetsPrefix: z.ZodOptional<z.ZodString>;
44
45
  serverEntry: z.ZodDefault<z.ZodOptional<z.ZodString>>;
45
46
  }, "strip", z.ZodTypeAny, {
47
+ assetsPrefix?: string | undefined;
46
48
  assets: string;
47
49
  server: URL;
48
50
  format: "file" | "directory";
@@ -53,6 +55,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
53
55
  server?: string | undefined;
54
56
  format?: "file" | "directory" | undefined;
55
57
  client?: string | undefined;
58
+ assetsPrefix?: string | undefined;
56
59
  serverEntry?: string | undefined;
57
60
  }>>>;
58
61
  server: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodObject<{
@@ -178,6 +181,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
178
181
  hooks: {};
179
182
  }[];
180
183
  build: {
184
+ assetsPrefix?: string | undefined;
181
185
  assets: string;
182
186
  server: URL;
183
187
  format: "file" | "directory";
@@ -226,6 +230,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
226
230
  server?: string | undefined;
227
231
  format?: "file" | "directory" | undefined;
228
232
  client?: string | undefined;
233
+ assetsPrefix?: string | undefined;
229
234
  serverEntry?: string | undefined;
230
235
  } | undefined;
231
236
  image?: {
@@ -338,8 +343,10 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
338
343
  client: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, URL, string | undefined>;
339
344
  server: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, URL, string | undefined>;
340
345
  assets: z.ZodDefault<z.ZodOptional<z.ZodString>>;
346
+ assetsPrefix: z.ZodOptional<z.ZodString>;
341
347
  serverEntry: z.ZodDefault<z.ZodOptional<z.ZodString>>;
342
348
  }, "strip", z.ZodTypeAny, {
349
+ assetsPrefix?: string | undefined;
343
350
  assets: string;
344
351
  server: URL;
345
352
  format: "file" | "directory";
@@ -350,6 +357,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
350
357
  server?: string | undefined;
351
358
  format?: "file" | "directory" | undefined;
352
359
  client?: string | undefined;
360
+ assetsPrefix?: string | undefined;
353
361
  serverEntry?: string | undefined;
354
362
  }>>>;
355
363
  server: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodObject<{
@@ -416,6 +424,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
416
424
  hooks: {};
417
425
  }[];
418
426
  build: {
427
+ assetsPrefix?: string | undefined;
419
428
  assets: string;
420
429
  server: URL;
421
430
  format: "file" | "directory";
@@ -464,6 +473,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
464
473
  server?: string | undefined;
465
474
  format?: "file" | "directory" | undefined;
466
475
  client?: string | undefined;
476
+ assetsPrefix?: string | undefined;
467
477
  serverEntry?: string | undefined;
468
478
  } | undefined;
469
479
  image?: {
@@ -513,6 +523,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
513
523
  hooks: {};
514
524
  }[];
515
525
  build: {
526
+ assetsPrefix?: string | undefined;
516
527
  assets: string;
517
528
  server: URL;
518
529
  format: "file" | "directory";
@@ -561,6 +572,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
561
572
  server?: string | undefined;
562
573
  format?: "file" | "directory" | undefined;
563
574
  client?: string | undefined;
575
+ assetsPrefix?: string | undefined;
564
576
  serverEntry?: string | undefined;
565
577
  } | undefined;
566
578
  image?: {
@@ -54,6 +54,7 @@ const AstroConfigSchema = z.object({
54
54
  client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => new URL(val)),
55
55
  server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => new URL(val)),
56
56
  assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
57
+ assetsPrefix: z.string().optional(),
57
58
  serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry)
58
59
  }).optional().default({}),
59
60
  server: z.preprocess(
@@ -119,6 +120,7 @@ function createRelativeSchema(cmd, fileProtocolRoot) {
119
120
  client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => new URL(val, fileProtocolRoot)),
120
121
  server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => new URL(val, fileProtocolRoot)),
121
122
  assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
123
+ assetsPrefix: z.string().optional(),
122
124
  serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry)
123
125
  }).optional().default({}),
124
126
  server: z.preprocess(
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.1.8";
1
+ const ASTRO_VERSION = "2.2.0";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -1,6 +1,8 @@
1
1
  import { parse, serialize } from "cookie";
2
+ import { AstroError, AstroErrorData } from "../errors/index.js";
2
3
  const DELETED_EXPIRATION = /* @__PURE__ */ new Date(0);
3
4
  const DELETED_VALUE = "deleted";
5
+ const responseSentSymbol = Symbol.for("astro.responseSent");
4
6
  class AstroCookie {
5
7
  constructor(value) {
6
8
  this.value = value;
@@ -117,6 +119,11 @@ class AstroCookies {
117
119
  serialize(key, serializedValue, serializeOptions),
118
120
  true
119
121
  ]);
122
+ if (this.#request[responseSentSymbol]) {
123
+ throw new AstroError({
124
+ ...AstroErrorData.ResponseSentError
125
+ });
126
+ }
120
127
  }
121
128
  /**
122
129
  * Astro.cookies.header() returns an iterator for the cookies that have previously
@@ -16,7 +16,6 @@ import envVitePlugin from "../vite-plugin-env/index.js";
16
16
  import astroHeadPlugin from "../vite-plugin-head/index.js";
17
17
  import htmlVitePlugin from "../vite-plugin-html/index.js";
18
18
  import { astroInjectEnvTsPlugin } from "../vite-plugin-inject-env-ts/index.js";
19
- import astroIntegrationsContainerPlugin from "../vite-plugin-integrations-container/index.js";
20
19
  import jsxVitePlugin from "../vite-plugin-jsx/index.js";
21
20
  import astroLoadFallbackPlugin from "../vite-plugin-load-fallback/index.js";
22
21
  import markdownVitePlugin from "../vite-plugin-markdown/index.js";
@@ -24,6 +23,7 @@ import astroScannerPlugin from "../vite-plugin-scanner/index.js";
24
23
  import astroScriptsPlugin from "../vite-plugin-scripts/index.js";
25
24
  import astroScriptsPageSSRPlugin from "../vite-plugin-scripts/page-ssr.js";
26
25
  import { vitePluginSSRManifest } from "../vite-plugin-ssr-manifest/index.js";
26
+ import { joinPaths } from "./path.js";
27
27
  const ALWAYS_NOEXTERNAL = [
28
28
  // This is only because Vite's native ESM doesn't resolve "exports" correctly.
29
29
  "astro",
@@ -93,7 +93,6 @@ async function createVite(commandConfig, { settings, logging, mode, command, fs
93
93
  htmlVitePlugin(),
94
94
  jsxVitePlugin({ settings, logging }),
95
95
  astroPostprocessVitePlugin({ settings }),
96
- astroIntegrationsContainerPlugin({ settings, logging }),
97
96
  astroScriptsPageSSRPlugin({ settings }),
98
97
  astroHeadPlugin({ settings }),
99
98
  astroScannerPlugin({ settings }),
@@ -145,6 +144,16 @@ async function createVite(commandConfig, { settings, logging, mode, command, fs
145
144
  external: [...mode === "dev" ? ONLY_DEV_EXTERNAL : [], ...astroPkgsConfig.ssr.external]
146
145
  }
147
146
  };
147
+ const assetsPrefix = settings.config.build.assetsPrefix;
148
+ if (assetsPrefix) {
149
+ commonConfig.experimental = {
150
+ renderBuiltUrl(filename, { type }) {
151
+ if (type === "asset") {
152
+ return joinPaths(assetsPrefix, filename);
153
+ }
154
+ }
155
+ };
156
+ }
148
157
  let result = commonConfig;
149
158
  if (command && ((_b = settings.config.vite) == null ? void 0 : _b.plugins)) {
150
159
  let { plugins, ...rest } = settings.config.vite;
@@ -42,9 +42,6 @@ async function createContainer(params = {}) {
42
42
  server: { host, headers, open },
43
43
  optimizeDeps: {
44
44
  include: rendererClientEntries
45
- },
46
- define: {
47
- "import.meta.env.BASE_URL": settings.config.base ? JSON.stringify(settings.config.base) : "undefined"
48
45
  }
49
46
  },
50
47
  { settings, logging, mode: "dev", command: "dev", fs }