astro 2.1.9 → 2.2.1

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 (72) hide show
  1. package/client-base.d.ts +55 -5
  2. package/config.d.ts +2 -1
  3. package/dist/@types/astro.d.ts +25 -2
  4. package/dist/assets/image-endpoint.js +2 -2
  5. package/dist/assets/index.d.ts +1 -1
  6. package/dist/assets/index.js +3 -2
  7. package/dist/assets/internal.d.ts +2 -8
  8. package/dist/assets/services/service.d.ts +2 -2
  9. package/dist/assets/services/vendor/squoosh/image-pool.d.ts +2 -2
  10. package/dist/assets/services/vendor/squoosh/image.d.ts +2 -2
  11. package/dist/assets/types.d.ts +15 -9
  12. package/dist/assets/utils/emitAsset.d.ts +2 -1
  13. package/dist/assets/utils/emitAsset.js +4 -1
  14. package/dist/assets/vite-plugin-assets.js +11 -9
  15. package/dist/content/runtime-assets.d.ts +3 -7
  16. package/dist/content/runtime-assets.js +13 -20
  17. package/dist/content/template/virtual-mod.d.mts +1 -0
  18. package/dist/content/utils.d.ts +2 -6
  19. package/dist/content/utils.js +16 -56
  20. package/dist/content/vite-plugin-content-assets.js +13 -4
  21. package/dist/content/vite-plugin-content-imports.js +3 -4
  22. package/dist/content/vite-plugin-content-virtual-mod.js +1 -4
  23. package/dist/core/app/index.js +2 -0
  24. package/dist/core/build/add-rollup-input.d.ts +2 -2
  25. package/dist/core/build/generate.js +22 -6
  26. package/dist/core/build/internal.d.ts +3 -3
  27. package/dist/core/build/plugins/plugin-css.js +0 -29
  28. package/dist/core/build/plugins/plugin-internals.js +0 -7
  29. package/dist/core/build/plugins/plugin-ssr.js +12 -7
  30. package/dist/core/build/static-build.js +7 -3
  31. package/dist/core/config/schema.d.ts +12 -0
  32. package/dist/core/config/schema.js +2 -0
  33. package/dist/core/constants.js +1 -1
  34. package/dist/core/cookies/cookies.js +7 -0
  35. package/dist/core/create-vite.js +13 -0
  36. package/dist/core/dev/container.js +0 -5
  37. package/dist/core/dev/dev.js +1 -1
  38. package/dist/core/errors/errors-data.d.ts +11 -1
  39. package/dist/core/errors/errors-data.js +11 -1
  40. package/dist/core/messages.js +2 -2
  41. package/dist/core/render/dev/index.js +1 -1
  42. package/dist/core/render/dev/scripts.d.ts +1 -1
  43. package/dist/core/render/dev/scripts.js +7 -6
  44. package/dist/core/render/result.js +14 -3
  45. package/dist/core/render/ssr-element.d.ts +7 -6
  46. package/dist/core/render/ssr-element.js +28 -20
  47. package/dist/core/sync/index.js +9 -2
  48. package/dist/core/util.d.ts +1 -1
  49. package/dist/core/util.js +2 -2
  50. package/dist/runtime/server/index.d.ts +1 -1
  51. package/dist/runtime/server/index.js +2 -0
  52. package/dist/runtime/server/render/common.d.ts +1 -1
  53. package/dist/runtime/server/render/component.js +3 -3
  54. package/dist/runtime/server/render/dom.js +2 -2
  55. package/dist/runtime/server/render/index.d.ts +1 -1
  56. package/dist/runtime/server/render/index.js +2 -1
  57. package/dist/runtime/server/render/page.js +3 -2
  58. package/dist/runtime/server/render/slot.d.ts +2 -1
  59. package/dist/runtime/server/render/slot.js +21 -17
  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-integrations-container/index.d.ts +8 -0
  65. package/dist/vite-plugin-integrations-container/index.js +15 -0
  66. package/dist/vite-plugin-markdown/index.js +9 -12
  67. package/dist/vite-plugin-scanner/scan.js +17 -2
  68. package/package.json +4 -4
  69. package/src/content/template/types.d.ts +25 -10
  70. package/src/content/template/virtual-mod.mjs +7 -0
  71. package/dist/content/template/virtual-mod-assets.d.mts +0 -1
  72. package/src/content/template/virtual-mod-assets.mjs +0 -7
@@ -1,9 +1,13 @@
1
- import { renderSlot, stringifyChunk } from "../../runtime/server/index.js";
1
+ import {
2
+ renderSlotToString,
3
+ stringifyChunk
4
+ } from "../../runtime/server/index.js";
2
5
  import { renderJSX } from "../../runtime/server/jsx.js";
3
6
  import { AstroCookies } from "../cookies/index.js";
4
7
  import { AstroError, AstroErrorData } from "../errors/index.js";
5
8
  import { warn } from "../logger/core.js";
6
9
  const clientAddressSymbol = Symbol.for("astro.clientAddress");
10
+ const responseSentSymbol = Symbol.for("astro.responseSent");
7
11
  function onlyAvailableInSSR(name) {
8
12
  return function _onlyAvailableInSSR() {
9
13
  switch (name) {
@@ -66,7 +70,9 @@ class Slots {
66
70
  const expression = getFunctionExpression(component);
67
71
  if (expression) {
68
72
  const slot = () => expression(...args);
69
- return await renderSlot(result, slot).then((res) => res != null ? String(res) : res);
73
+ return await renderSlotToString(result, slot).then(
74
+ (res) => res != null ? String(res) : res
75
+ );
70
76
  }
71
77
  if (typeof component === "function") {
72
78
  return await renderJSX(result, component(...args)).then(
@@ -74,7 +80,7 @@ class Slots {
74
80
  );
75
81
  }
76
82
  }
77
- const content = await renderSlot(result, this.#slots[name]);
83
+ const content = await renderSlotToString(result, this.#slots[name]);
78
84
  const outHTML = stringifyChunk(result, content);
79
85
  return outHTML;
80
86
  }
@@ -138,6 +144,11 @@ function createResult(args) {
138
144
  request,
139
145
  url,
140
146
  redirect: args.ssr ? (path, status) => {
147
+ if (request[responseSentSymbol]) {
148
+ throw new AstroError({
149
+ ...AstroErrorData.ResponseSentError
150
+ });
151
+ }
141
152
  return new Response(null, {
142
153
  status: status || 302,
143
154
  headers: {
@@ -1,13 +1,14 @@
1
1
  import type { SSRElement } from '../../@types/astro';
2
- export declare function createLinkStylesheetElement(href: string, base?: string): SSRElement;
3
- export declare function createLinkStylesheetElementSet(hrefs: string[], base?: string): Set<SSRElement>;
2
+ export declare function createAssetLink(href: string, base?: string, assetsPrefix?: string): string;
3
+ export declare function createLinkStylesheetElement(href: string, base?: string, assetsPrefix?: string): SSRElement;
4
+ export declare function createLinkStylesheetElementSet(hrefs: string[], base?: string, assetsPrefix?: string): Set<SSRElement>;
4
5
  export declare function createModuleScriptElement(script: {
5
6
  type: 'inline' | 'external';
6
7
  value: string;
7
- }, base?: string): SSRElement;
8
- export declare function createModuleScriptElementWithSrc(src: string, site?: string): SSRElement;
9
- export declare function createModuleScriptElementWithSrcSet(srces: string[], site?: string): Set<SSRElement>;
8
+ }, base?: string, assetsPrefix?: string): SSRElement;
9
+ export declare function createModuleScriptElementWithSrc(src: string, base?: string, assetsPrefix?: string): SSRElement;
10
+ export declare function createModuleScriptElementWithSrcSet(srces: string[], site?: string, assetsPrefix?: string): Set<SSRElement>;
10
11
  export declare function createModuleScriptsSet(scripts: {
11
12
  type: 'inline' | 'external';
12
13
  value: string;
13
- }[], base?: string): Set<SSRElement>;
14
+ }[], base?: string, assetsPrefix?: string): Set<SSRElement>;
@@ -1,28 +1,31 @@
1
1
  import slashify from "slash";
2
- import { appendForwardSlash, removeLeadingForwardSlash } from "../../core/path.js";
3
- function getRootPath(base) {
4
- return appendForwardSlash(new URL(base || "/", "http://localhost/").pathname);
5
- }
6
- function joinToRoot(href, base) {
7
- const rootPath = getRootPath(base);
8
- const normalizedHref = slashify(href);
9
- return appendForwardSlash(rootPath) + removeLeadingForwardSlash(normalizedHref);
2
+ import { joinPaths, prependForwardSlash } from "../../core/path.js";
3
+ function createAssetLink(href, base, assetsPrefix) {
4
+ if (assetsPrefix) {
5
+ return joinPaths(assetsPrefix, slashify(href));
6
+ } else if (base) {
7
+ return prependForwardSlash(joinPaths(base, slashify(href)));
8
+ } else {
9
+ return href;
10
+ }
10
11
  }
11
- function createLinkStylesheetElement(href, base) {
12
+ function createLinkStylesheetElement(href, base, assetsPrefix) {
12
13
  return {
13
14
  props: {
14
15
  rel: "stylesheet",
15
- href: joinToRoot(href, base)
16
+ href: createAssetLink(href, base, assetsPrefix)
16
17
  },
17
18
  children: ""
18
19
  };
19
20
  }
20
- function createLinkStylesheetElementSet(hrefs, base) {
21
- return new Set(hrefs.map((href) => createLinkStylesheetElement(href, base)));
21
+ function createLinkStylesheetElementSet(hrefs, base, assetsPrefix) {
22
+ return new Set(
23
+ hrefs.map((href) => createLinkStylesheetElement(href, base, assetsPrefix))
24
+ );
22
25
  }
23
- function createModuleScriptElement(script, base) {
26
+ function createModuleScriptElement(script, base, assetsPrefix) {
24
27
  if (script.type === "external") {
25
- return createModuleScriptElementWithSrc(script.value, base);
28
+ return createModuleScriptElementWithSrc(script.value, base, assetsPrefix);
26
29
  } else {
27
30
  return {
28
31
  props: {
@@ -32,22 +35,27 @@ function createModuleScriptElement(script, base) {
32
35
  };
33
36
  }
34
37
  }
35
- function createModuleScriptElementWithSrc(src, site) {
38
+ function createModuleScriptElementWithSrc(src, base, assetsPrefix) {
36
39
  return {
37
40
  props: {
38
41
  type: "module",
39
- src: joinToRoot(src, site)
42
+ src: createAssetLink(src, base, assetsPrefix)
40
43
  },
41
44
  children: ""
42
45
  };
43
46
  }
44
- function createModuleScriptElementWithSrcSet(srces, site) {
45
- return new Set(srces.map((src) => createModuleScriptElementWithSrc(src, site)));
47
+ function createModuleScriptElementWithSrcSet(srces, site, assetsPrefix) {
48
+ return new Set(
49
+ srces.map((src) => createModuleScriptElementWithSrc(src, site, assetsPrefix))
50
+ );
46
51
  }
47
- function createModuleScriptsSet(scripts, base) {
48
- return new Set(scripts.map((script) => createModuleScriptElement(script, base)));
52
+ function createModuleScriptsSet(scripts, base, assetsPrefix) {
53
+ return new Set(
54
+ scripts.map((script) => createModuleScriptElement(script, base, assetsPrefix))
55
+ );
49
56
  }
50
57
  export {
58
+ createAssetLink,
51
59
  createLinkStylesheetElement,
52
60
  createLinkStylesheetElementSet,
53
61
  createModuleScriptElement,
@@ -7,7 +7,7 @@ import { runHookConfigSetup } from "../../integrations/index.js";
7
7
  import { setUpEnvTs } from "../../vite-plugin-inject-env-ts/index.js";
8
8
  import { getTimeStat } from "../build/util.js";
9
9
  import { createVite } from "../create-vite.js";
10
- import { AstroError, AstroErrorData } from "../errors/index.js";
10
+ import { AstroError, AstroErrorData, createSafeError } from "../errors/index.js";
11
11
  import { info } from "../logger/core.js";
12
12
  import { printHelp } from "../messages.js";
13
13
  async function syncCli(settings, { logging, fs, flags }) {
@@ -64,7 +64,14 @@ async function sync(settings, { logging, fs }) {
64
64
  }
65
65
  }
66
66
  } catch (e) {
67
- throw new AstroError(AstroErrorData.GenerateContentTypesError);
67
+ const safeError = createSafeError(e);
68
+ throw new AstroError(
69
+ {
70
+ ...AstroErrorData.GenerateContentTypesError,
71
+ message: AstroErrorData.GenerateContentTypesError.message(safeError.message)
72
+ },
73
+ { cause: e }
74
+ );
68
75
  } finally {
69
76
  await tempViteServer.close();
70
77
  }
@@ -37,7 +37,7 @@ export declare function isPage(file: URL, settings: AstroSettings): boolean;
37
37
  export declare function isEndpoint(file: URL, settings: AstroSettings): boolean;
38
38
  export declare function isModeServerWithNoAdapter(settings: AstroSettings): boolean;
39
39
  export declare function relativeToSrcDir(config: AstroConfig, idOrUrl: URL | string): string;
40
- export declare function rootRelativePath(config: AstroConfig, idOrUrl: URL | string): string;
40
+ export declare function rootRelativePath(root: URL, idOrUrl: URL | string): string;
41
41
  export declare function emoji(char: string, fallback: string): string;
42
42
  /**
43
43
  * Simulate Vite's resolve and import analysis so we can import the id as an URL
package/dist/core/util.js CHANGED
@@ -114,14 +114,14 @@ function relativeToSrcDir(config, idOrUrl) {
114
114
  }
115
115
  return id.slice(slash(fileURLToPath(config.srcDir)).length);
116
116
  }
117
- function rootRelativePath(config, idOrUrl) {
117
+ function rootRelativePath(root, idOrUrl) {
118
118
  let id;
119
119
  if (typeof idOrUrl !== "string") {
120
120
  id = unwrapId(viteID(idOrUrl));
121
121
  } else {
122
122
  id = idOrUrl;
123
123
  }
124
- return prependForwardSlash(id.slice(normalizePath(fileURLToPath(config.root)).length));
124
+ return prependForwardSlash(id.slice(normalizePath(fileURLToPath(root)).length));
125
125
  }
126
126
  function emoji(char, fallback) {
127
127
  return process.platform !== "win32" ? char : fallback;
@@ -3,7 +3,7 @@ export { createAstro } from './astro-global.js';
3
3
  export { renderEndpoint } from './endpoint.js';
4
4
  export { escapeHTML, HTMLBytes, HTMLString, markHTMLString, unescapeHTML } from './escape.js';
5
5
  export { renderJSX } from './jsx.js';
6
- export { addAttribute, createHeadAndContent, defineScriptVars, Fragment, maybeRenderHead, renderAstroTemplateResult as renderAstroComponent, renderComponent, renderComponentToIterable, Renderer as Renderer, renderHead, renderHTMLElement, renderPage, renderScriptElement, renderSlot, renderStyleElement, renderTemplate as render, renderTemplate, renderToString, renderUniqueStylesheet, stringifyChunk, voidElementNames, } from './render/index.js';
6
+ export { addAttribute, createHeadAndContent, defineScriptVars, Fragment, maybeRenderHead, renderAstroTemplateResult as renderAstroComponent, renderComponent, renderComponentToIterable, Renderer as Renderer, renderHead, renderHTMLElement, renderPage, renderScriptElement, renderSlot, renderSlotToString, renderStyleElement, renderTemplate as render, renderTemplate, renderToString, renderUniqueStylesheet, stringifyChunk, voidElementNames, } from './render/index.js';
7
7
  export type { AstroComponentFactory, AstroComponentInstance, ComponentSlots, RenderInstruction, } from './render/index.js';
8
8
  export declare function mergeSlots(...slotted: unknown[]): Record<string, () => any>;
9
9
  /** @internal Associate JSX components with a specific renderer (see /src/vite-plugin-jsx/tag.ts) */
@@ -18,6 +18,7 @@ import {
18
18
  renderPage,
19
19
  renderScriptElement,
20
20
  renderSlot,
21
+ renderSlotToString,
21
22
  renderStyleElement,
22
23
  renderTemplate,
23
24
  renderTemplate as renderTemplate2,
@@ -107,6 +108,7 @@ export {
107
108
  renderPage,
108
109
  renderScriptElement,
109
110
  renderSlot,
111
+ renderSlotToString,
110
112
  renderStyleElement,
111
113
  renderTemplate2 as renderTemplate,
112
114
  renderToString,
@@ -6,7 +6,7 @@ export declare const Fragment: unique symbol;
6
6
  export declare const Renderer: unique symbol;
7
7
  export declare const encoder: TextEncoder;
8
8
  export declare const decoder: TextDecoder;
9
- export declare function stringifyChunk(result: SSRResult, chunk: string | SlotString | RenderInstruction): any;
9
+ export declare function stringifyChunk(result: SSRResult, chunk: string | SlotString | RenderInstruction): string;
10
10
  export declare class HTMLParts {
11
11
  parts: string;
12
12
  constructor();
@@ -13,7 +13,7 @@ import {
13
13
  } from "./astro/index.js";
14
14
  import { Fragment, Renderer, stringifyChunk } from "./common.js";
15
15
  import { componentIsHTMLElement, renderHTMLElement } from "./dom.js";
16
- import { renderSlot, renderSlots } from "./slot.js";
16
+ import { renderSlots, renderSlotToString } from "./slot.js";
17
17
  import { formatList, internalSpreadAttributes, renderElement, voidElementNames } from "./util.js";
18
18
  const rendererAliases = /* @__PURE__ */ new Map([["solid", "solid-js"]]);
19
19
  function guessRenderers(componentUrl) {
@@ -166,7 +166,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
166
166
  }
167
167
  } else {
168
168
  if (metadata.hydrate === "only") {
169
- html = await renderSlot(result, slots == null ? void 0 : slots.fallback);
169
+ html = await renderSlotToString(result, slots == null ? void 0 : slots.fallback);
170
170
  } else {
171
171
  ({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call(
172
172
  { result },
@@ -261,7 +261,7 @@ function sanitizeElementName(tag) {
261
261
  return tag.trim().split(unsafe)[0].trim();
262
262
  }
263
263
  async function renderFragmentComponent(result, slots = {}) {
264
- const children = await renderSlot(result, slots == null ? void 0 : slots.default);
264
+ const children = await renderSlotToString(result, slots == null ? void 0 : slots.default);
265
265
  if (children == null) {
266
266
  return children;
267
267
  }
@@ -1,5 +1,5 @@
1
1
  import { markHTMLString } from "../escape.js";
2
- import { renderSlot } from "./slot.js";
2
+ import { renderSlotToString } from "./slot.js";
3
3
  import { toAttributeString } from "./util.js";
4
4
  function componentIsHTMLElement(Component) {
5
5
  return typeof HTMLElement !== "undefined" && HTMLElement.isPrototypeOf(Component);
@@ -11,7 +11,7 @@ async function renderHTMLElement(result, constructor, props, slots) {
11
11
  attrHTML += ` ${attr}="${toAttributeString(await props[attr])}"`;
12
12
  }
13
13
  return markHTMLString(
14
- `<${name}${attrHTML}>${await renderSlot(result, slots == null ? void 0 : slots.default)}</${name}>`
14
+ `<${name}${attrHTML}>${await renderSlotToString(result, slots == null ? void 0 : slots.default)}</${name}>`
15
15
  );
16
16
  }
17
17
  function getHTMLElementName(constructor) {
@@ -5,7 +5,7 @@ export { renderComponent, renderComponentToIterable } from './component.js';
5
5
  export { renderHTMLElement } from './dom.js';
6
6
  export { maybeRenderHead, renderHead } from './head.js';
7
7
  export { renderPage } from './page.js';
8
- export { renderSlot, type ComponentSlots } from './slot.js';
8
+ export { renderSlot, renderSlotToString, type ComponentSlots } from './slot.js';
9
9
  export { renderScriptElement, renderStyleElement, renderUniqueStylesheet } from './tags.js';
10
10
  export type { RenderInstruction } from './types';
11
11
  export { addAttribute, defineScriptVars, voidElementNames } from './util.js';
@@ -9,7 +9,7 @@ import { renderComponent, renderComponentToIterable } from "./component.js";
9
9
  import { renderHTMLElement } from "./dom.js";
10
10
  import { maybeRenderHead, renderHead } from "./head.js";
11
11
  import { renderPage } from "./page.js";
12
- import { renderSlot } from "./slot.js";
12
+ import { renderSlot, renderSlotToString } from "./slot.js";
13
13
  import { renderScriptElement, renderStyleElement, renderUniqueStylesheet } from "./tags.js";
14
14
  import { addAttribute, defineScriptVars, voidElementNames } from "./util.js";
15
15
  export {
@@ -27,6 +27,7 @@ export {
27
27
  renderPage,
28
28
  renderScriptElement,
29
29
  renderSlot,
30
+ renderSlotToString,
30
31
  renderStyleElement,
31
32
  renderTemplate,
32
33
  renderToString,
@@ -48,8 +48,9 @@ async function bufferHeadContent(result) {
48
48
  }
49
49
  }
50
50
  async function renderPage(result, componentFactory, props, children, streaming, route) {
51
- var _a;
51
+ var _a, _b;
52
52
  if (!isAstroComponentFactory(componentFactory)) {
53
+ result._metadata.headInTree = ((_a = result.componentMetadata.get(componentFactory.moduleId)) == null ? void 0 : _a.containsHead) ?? false;
53
54
  const pageProps = { ...props ?? {}, "server:root": true };
54
55
  let output;
55
56
  let head = "";
@@ -91,7 +92,7 @@ async function renderPage(result, componentFactory, props, children, streaming,
91
92
  ])
92
93
  });
93
94
  }
94
- result._metadata.headInTree = ((_a = result.componentMetadata.get(componentFactory.moduleId)) == null ? void 0 : _a.containsHead) ?? false;
95
+ result._metadata.headInTree = ((_b = result.componentMetadata.get(componentFactory.moduleId)) == null ? void 0 : _b.containsHead) ?? false;
95
96
  const factoryReturnValue = await componentFactory(result, props, children);
96
97
  const factoryIsHeadAndContent = isHeadAndContent(factoryReturnValue);
97
98
  if (isRenderTemplateResult(factoryReturnValue) || factoryIsHeadAndContent) {
@@ -12,7 +12,8 @@ export declare class SlotString extends HTMLString {
12
12
  constructor(content: string, instructions: null | RenderInstruction[]);
13
13
  }
14
14
  export declare function isSlotString(str: string): str is any;
15
- export declare function renderSlot(result: SSRResult, slotted: ComponentSlotValue | RenderTemplateResult, fallback?: ComponentSlotValue | RenderTemplateResult): Promise<string>;
15
+ export declare function renderSlot(result: SSRResult, slotted: ComponentSlotValue | RenderTemplateResult, fallback?: ComponentSlotValue | RenderTemplateResult): AsyncGenerator<any, void, undefined>;
16
+ export declare function renderSlotToString(result: SSRResult, slotted: ComponentSlotValue | RenderTemplateResult, fallback?: ComponentSlotValue | RenderTemplateResult): Promise<string>;
16
17
  interface RenderSlotsResult {
17
18
  slotInstructions: null | RenderInstruction[];
18
19
  children: Record<string, string>;
@@ -12,27 +12,30 @@ slotString;
12
12
  function isSlotString(str) {
13
13
  return !!str[slotString];
14
14
  }
15
- async function renderSlot(result, slotted, fallback) {
15
+ async function* renderSlot(result, slotted, fallback) {
16
16
  if (slotted) {
17
17
  let iterator = renderChild(typeof slotted === "function" ? slotted(result) : slotted);
18
- let content = "";
19
- let instructions = null;
20
- for await (const chunk of iterator) {
21
- if (typeof chunk.type === "string") {
22
- if (instructions === null) {
23
- instructions = [];
24
- }
25
- instructions.push(chunk);
26
- } else {
27
- content += chunk;
28
- }
29
- }
30
- return markHTMLString(new SlotString(content, instructions));
18
+ yield* iterator;
31
19
  }
32
20
  if (fallback) {
33
- return renderSlot(result, fallback);
21
+ yield* renderSlot(result, fallback);
22
+ }
23
+ }
24
+ async function renderSlotToString(result, slotted, fallback) {
25
+ let content = "";
26
+ let instructions = null;
27
+ let iterator = renderSlot(result, slotted, fallback);
28
+ for await (const chunk of iterator) {
29
+ if (typeof chunk.type === "string") {
30
+ if (instructions === null) {
31
+ instructions = [];
32
+ }
33
+ instructions.push(chunk);
34
+ } else {
35
+ content += chunk;
36
+ }
34
37
  }
35
- return "";
38
+ return markHTMLString(new SlotString(content, instructions));
36
39
  }
37
40
  async function renderSlots(result, slots = {}) {
38
41
  let slotInstructions = null;
@@ -40,7 +43,7 @@ async function renderSlots(result, slots = {}) {
40
43
  if (slots) {
41
44
  await Promise.all(
42
45
  Object.entries(slots).map(
43
- ([key, value]) => renderSlot(result, value).then((output) => {
46
+ ([key, value]) => renderSlotToString(result, value).then((output) => {
44
47
  if (output.instructions) {
45
48
  if (slotInstructions === null) {
46
49
  slotInstructions = [];
@@ -58,5 +61,6 @@ export {
58
61
  SlotString,
59
62
  isSlotString,
60
63
  renderSlot,
64
+ renderSlotToString,
61
65
  renderSlots
62
66
  };
@@ -6,4 +6,4 @@ export declare function handle404Response(origin: string, req: http.IncomingMess
6
6
  export declare function handle500Response(loader: ModuleLoader, res: http.ServerResponse, err: ErrorWithMetadata): Promise<void>;
7
7
  export declare function writeHtmlResponse(res: http.ServerResponse, statusCode: number, html: string): void;
8
8
  export declare function writeWebResponse(res: http.ServerResponse, webResponse: Response): Promise<void>;
9
- export declare function writeSSRResult(webResponse: Response, res: http.ServerResponse): Promise<void>;
9
+ export declare function writeSSRResult(webRequest: Request, webResponse: Response, res: http.ServerResponse): Promise<void>;
@@ -76,7 +76,8 @@ async function writeWebResponse(res, webResponse) {
76
76
  }
77
77
  res.end();
78
78
  }
79
- async function writeSSRResult(webResponse, res) {
79
+ async function writeSSRResult(webRequest, webResponse, res) {
80
+ Reflect.set(webRequest, Symbol.for("astro.responseSent"), true);
80
81
  return writeWebResponse(res, webResponse);
81
82
  }
82
83
  export {
@@ -151,7 +151,7 @@ async function handleRoute(matchedRoute, url, pathname, body, origin, env, manif
151
151
  } else {
152
152
  const result = await renderPage(options);
153
153
  throwIfRedirectNotAllowed(result, config);
154
- return await writeSSRResult(result, res);
154
+ return await writeSSRResult(request, result, res);
155
155
  }
156
156
  }
157
157
  export {
@@ -24,6 +24,7 @@ function getPrivateEnv(viteConfig, astroConfig) {
24
24
  privateEnv.SITE = astroConfig.site ? JSON.stringify(astroConfig.site) : "undefined";
25
25
  privateEnv.SSR = JSON.stringify(true);
26
26
  privateEnv.BASE_URL = astroConfig.base ? JSON.stringify(astroConfig.base) : "undefined";
27
+ privateEnv.ASSETS_PREFIX = astroConfig.build.assetsPrefix ? JSON.stringify(astroConfig.build.assetsPrefix) : "undefined";
27
28
  return privateEnv;
28
29
  }
29
30
  function getReferencedPrivateKeys(source, privateEnv) {
@@ -42,6 +43,14 @@ function envVitePlugin({ settings }) {
42
43
  return {
43
44
  name: "astro:vite-plugin-env",
44
45
  enforce: "pre",
46
+ config() {
47
+ return {
48
+ define: {
49
+ "import.meta.env.BASE_URL": astroConfig.base ? JSON.stringify(astroConfig.base) : "undefined",
50
+ "import.meta.env.ASSETS_PREFIX": astroConfig.build.assetsPrefix ? JSON.stringify(astroConfig.build.assetsPrefix) : "undefined"
51
+ }
52
+ };
53
+ },
45
54
  configResolved(resolvedConfig) {
46
55
  viteConfig = resolvedConfig;
47
56
  },
@@ -0,0 +1,8 @@
1
+ import type { Plugin as VitePlugin } from 'vite';
2
+ import type { AstroSettings } from '../@types/astro.js';
3
+ import type { LogOptions } from '../core/logger/core.js';
4
+ /** Connect Astro integrations into Vite, as needed. */
5
+ export default function astroIntegrationsContainerPlugin({ settings, logging, }: {
6
+ settings: AstroSettings;
7
+ logging: LogOptions;
8
+ }): VitePlugin;
@@ -0,0 +1,15 @@
1
+ import { runHookServerSetup } from "../integrations/index.js";
2
+ function astroIntegrationsContainerPlugin({
3
+ settings,
4
+ logging
5
+ }) {
6
+ return {
7
+ name: "astro:integration-container",
8
+ configureServer(server) {
9
+ runHookServerSetup({ config: settings.config, server, logging });
10
+ }
11
+ };
12
+ }
13
+ export {
14
+ astroIntegrationsContainerPlugin as default
15
+ };
@@ -54,6 +54,7 @@ function markdown({ settings, logging }) {
54
54
  // passing to the transform hook. This lets us get the truly raw value
55
55
  // to escape "import.meta.env" ourselves.
56
56
  async load(id) {
57
+ var _a;
57
58
  if (isMarkdownFile(id)) {
58
59
  const { fileId, fileUrl } = getFileInfo(id, settings.config);
59
60
  const rawFile = await fs.promises.readFile(fileId, "utf-8");
@@ -67,17 +68,13 @@ function markdown({ settings, logging }) {
67
68
  let html = renderResult.code;
68
69
  const { headings } = renderResult.metadata;
69
70
  let imagePaths = [];
70
- if (settings.config.experimental.assets) {
71
- let paths = renderResult.vfile.data.imagePaths ?? [];
72
- imagePaths = await Promise.all(
73
- paths.map(async (imagePath) => {
74
- var _a;
75
- return {
76
- raw: imagePath,
77
- resolved: ((_a = await this.resolve(imagePath, id)) == null ? void 0 : _a.id) ?? path.join(path.dirname(id), imagePath)
78
- };
79
- })
80
- );
71
+ if (settings.config.experimental.assets && renderResult.vfile.data.imagePaths) {
72
+ for (let imagePath of renderResult.vfile.data.imagePaths.values()) {
73
+ imagePaths.push({
74
+ raw: imagePath,
75
+ resolved: ((_a = await this.resolve(imagePath, id)) == null ? void 0 : _a.id) ?? path.join(path.dirname(id), imagePath)
76
+ });
77
+ }
81
78
  }
82
79
  const astroData = safelyGetAstroData(renderResult.vfile.data);
83
80
  if (astroData instanceof InvalidAstroDataError) {
@@ -102,7 +99,7 @@ function markdown({ settings, logging }) {
102
99
 
103
100
  export const images = {
104
101
  ${imagePaths.map(
105
- (entry) => `'${entry.raw}': await getImageSafely((await import("${entry.raw}")).default, "${entry.raw}", "${rootRelativePath(settings.config, entry.resolved)}")`
102
+ (entry) => `'${entry.raw}': await getImageSafely((await import("${entry.raw}")).default, "${entry.raw}", "${rootRelativePath(settings.config.root, entry.resolved)}")`
106
103
  )}
107
104
  }
108
105
 
@@ -8,6 +8,21 @@ function includesExport(code) {
8
8
  }
9
9
  return false;
10
10
  }
11
+ function isQuoted(value) {
12
+ return (value[0] === '"' || value[0] === "'") && value[value.length - 1] === value[0];
13
+ }
14
+ function isTruthy(value) {
15
+ if (isQuoted(value)) {
16
+ value = value.slice(1, -1);
17
+ }
18
+ return value === "true" || value === "1";
19
+ }
20
+ function isFalsy(value) {
21
+ if (isQuoted(value)) {
22
+ value = value.slice(1, -1);
23
+ }
24
+ return value === "false" || value === "0";
25
+ }
11
26
  let didInit = false;
12
27
  async function scan(code, id) {
13
28
  if (!includesExport(code))
@@ -23,14 +38,14 @@ async function scan(code, id) {
23
38
  if (BOOLEAN_EXPORTS.has(name)) {
24
39
  const prefix = code.slice(0, endOfLocalName).split("export").pop().trim().replace("prerender", "").trim();
25
40
  const suffix = code.slice(endOfLocalName).trim().replace(/\=/, "").trim().split(/[;\n]/)[0];
26
- if (prefix !== "const" || !(suffix === "true" || suffix === "false")) {
41
+ if (prefix !== "const" || !(isTruthy(suffix) || isFalsy(suffix))) {
27
42
  throw new AstroError({
28
43
  ...AstroErrorData.InvalidPrerenderExport,
29
44
  message: AstroErrorData.InvalidPrerenderExport.message(prefix, suffix),
30
45
  location: { file: id }
31
46
  });
32
47
  } else {
33
- pageOptions[name] = suffix === "true";
48
+ pageOptions[name] = isTruthy(suffix);
34
49
  }
35
50
  }
36
51
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "2.1.9",
3
+ "version": "2.2.1",
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",
@@ -93,9 +93,9 @@
93
93
  "src/content/template"
94
94
  ],
95
95
  "dependencies": {
96
- "@astrojs/compiler": "^1.3.0",
96
+ "@astrojs/compiler": "^1.3.1",
97
97
  "@astrojs/language-server": "^0.28.3",
98
- "@astrojs/markdown-remark": "^2.1.2",
98
+ "@astrojs/markdown-remark": "^2.1.3",
99
99
  "@astrojs/telemetry": "^2.1.0",
100
100
  "@astrojs/webapi": "^2.1.0",
101
101
  "@babel/core": "^7.18.2",
@@ -142,7 +142,7 @@
142
142
  "typescript": "*",
143
143
  "unist-util-visit": "^4.1.0",
144
144
  "vfile": "^5.3.2",
145
- "vite": "^4.1.2",
145
+ "vite": "^4.2.1",
146
146
  "vitefu": "^0.2.4",
147
147
  "yargs-parser": "^21.0.1",
148
148
  "zod": "^3.17.3"