astro 2.3.2 → 2.3.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.
package/client-base.d.ts CHANGED
@@ -3,7 +3,26 @@
3
3
  declare module 'astro:assets' {
4
4
  // Exporting things one by one is a bit cumbersome, not sure if there's a better way - erika, 2023-02-03
5
5
  type AstroAssets = {
6
- getImage: typeof import('./dist/assets/index.js').getImage;
6
+ // getImage's type here is different from the internal function since the Vite module implicitly pass the service config
7
+ /**
8
+ * Get an optimized image and the necessary attributes to render it.
9
+ *
10
+ * **Example**
11
+ * ```astro
12
+ * ---
13
+ * import { getImage } from 'astro:assets';
14
+ * import originalImage from '../assets/image.png';
15
+ *
16
+ * const optimizedImage = await getImage({src: originalImage, width: 1280 });
17
+ * ---
18
+ * <img src={optimizedImage.src} {...optimizedImage.attributes} />
19
+ * ```
20
+ *
21
+ * This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
22
+ */
23
+ getImage: (
24
+ options: import('./dist/assets/types.js').ImageTransform
25
+ ) => Promise<import('./dist/assets/types.js').GetImageResult>;
7
26
  getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService;
8
27
  Image: typeof import('./components/Image.astro').default;
9
28
  };
@@ -289,6 +289,10 @@ type ServerConfig = {
289
289
  export interface ViteUserConfig extends vite.UserConfig {
290
290
  ssr?: vite.SSROptions;
291
291
  }
292
+ export interface ImageServiceConfig {
293
+ entrypoint: 'astro/assets/services/sharp' | 'astro/assets/services/squoosh' | (string & {});
294
+ config?: Record<string, any>;
295
+ }
292
296
  /**
293
297
  * Astro User Config
294
298
  * Docs: https://docs.astro.build/reference/configuration-reference/
@@ -686,25 +690,26 @@ export interface AstroUserConfig {
686
690
  /**
687
691
  * @docs
688
692
  * @name image.service (Experimental)
689
- * @type {'astro/assets/services/sharp' | 'astro/assets/services/squoosh' | string}
690
- * @default `'astro/assets/services/squoosh'`
693
+ * @type {{entrypoint: 'astro/assets/services/sharp' | 'astro/assets/services/squoosh' | string, config: Record<string, any>}}
694
+ * @default `{entrypoint: 'astro/assets/services/squoosh', config?: {}}`
691
695
  * @version 2.1.0
692
696
  * @description
693
697
  * Set which image service is used for Astro’s experimental assets support.
694
698
  *
695
- * The value should be a module specifier for the image service to use:
696
- * either one of Astro’s two built-in services, or a third-party implementation.
699
+ * The value should be an object with an entrypoint for the image service to use and optionally, a config object to pass to the service.
700
+ *
701
+ * The service entrypoint can be either one of the included services, or a third-party package.
697
702
  *
698
703
  * ```js
699
704
  * {
700
705
  * image: {
701
706
  * // Example: Enable the Sharp-based image service
702
- * service: 'astro/assets/services/sharp',
707
+ * service: { entrypoint: 'astro/assets/services/sharp' },
703
708
  * },
704
709
  * }
705
710
  * ```
706
711
  */
707
- service: 'astro/assets/services/sharp' | 'astro/assets/services/squoosh' | (string & {});
712
+ service: ImageServiceConfig;
708
713
  };
709
714
  /**
710
715
  * @docs
@@ -3,6 +3,7 @@ import { isRemotePath } from "../core/path.js";
3
3
  import { getConfiguredImageService } from "./internal.js";
4
4
  import { isLocalService } from "./services/service.js";
5
5
  import { etag } from "./utils/etag.js";
6
+ import { imageServiceConfig } from "astro:assets";
6
7
  async function loadRemoteImage(src) {
7
8
  try {
8
9
  const res = await fetch(src);
@@ -21,7 +22,7 @@ const get = async ({ request }) => {
21
22
  throw new Error("Configured image service is not a local service");
22
23
  }
23
24
  const url = new URL(request.url);
24
- const transform = await imageService.parseURL(url);
25
+ const transform = await imageService.parseURL(url, imageServiceConfig);
25
26
  if (!transform || !transform.src) {
26
27
  throw new Error("Incorrect transform returned by `parseURL`");
27
28
  }
@@ -31,7 +32,11 @@ const get = async ({ request }) => {
31
32
  if (!inputBuffer) {
32
33
  return new Response("Not Found", { status: 404 });
33
34
  }
34
- const { data, format } = await imageService.transform(inputBuffer, transform);
35
+ const { data, format } = await imageService.transform(
36
+ inputBuffer,
37
+ transform,
38
+ imageServiceConfig
39
+ );
35
40
  return new Response(data, {
36
41
  status: 200,
37
42
  headers: {
@@ -1,5 +1,8 @@
1
+ import type { ImageServiceConfig } from '../@types/astro.js';
1
2
  export { getConfiguredImageService, getImage } from './internal.js';
2
3
  export { baseService, isLocalService } from './services/service.js';
3
4
  export { type LocalImageProps, type RemoteImageProps } from './types.js';
4
5
  export { emitESMImage } from './utils/emitAsset.js';
5
6
  export { imageMetadata } from './utils/metadata.js';
7
+ export declare function sharpImageService(): ImageServiceConfig;
8
+ export declare function squooshImageService(): ImageServiceConfig;
@@ -3,11 +3,25 @@ import { baseService, isLocalService } from "./services/service.js";
3
3
  import {} from "./types.js";
4
4
  import { emitESMImage } from "./utils/emitAsset.js";
5
5
  import { imageMetadata } from "./utils/metadata.js";
6
+ function sharpImageService() {
7
+ return {
8
+ entrypoint: "astro/assets/services/sharp",
9
+ config: {}
10
+ };
11
+ }
12
+ function squooshImageService() {
13
+ return {
14
+ entrypoint: "astro/assets/services/squoosh",
15
+ config: {}
16
+ };
17
+ }
6
18
  export {
7
19
  baseService,
8
20
  emitESMImage,
9
21
  getConfiguredImageService,
10
22
  getImage,
11
23
  imageMetadata,
12
- isLocalService
24
+ isLocalService,
25
+ sharpImageService,
26
+ squooshImageService
13
27
  };
@@ -3,23 +3,7 @@ import { type ImageService } from './services/service.js';
3
3
  import type { GetImageResult, ImageMetadata, ImageTransform } from './types.js';
4
4
  export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
5
5
  export declare function getConfiguredImageService(): Promise<ImageService>;
6
- /**
7
- * Get an optimized image and the necessary attributes to render it.
8
- *
9
- * **Example**
10
- * ```astro
11
- * ---
12
- * import { getImage } from 'astro:assets';
13
- * import originalImage from '../assets/image.png';
14
- *
15
- * const optimizedImage = await getImage({src: originalImage, width: 1280 });
16
- * ---
17
- * <img src={optimizedImage.src} {...optimizedImage.attributes} />
18
- * ```
19
- *
20
- * This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
21
- */
22
- export declare function getImage(options: ImageTransform): Promise<GetImageResult>;
6
+ export declare function getImage(options: ImageTransform, serviceConfig: Record<string, any>): Promise<GetImageResult>;
23
7
  export declare function getStaticImageList(): Iterable<[
24
8
  string,
25
9
  {
@@ -24,7 +24,7 @@ async function getConfiguredImageService() {
24
24
  }
25
25
  return globalThis.astroAsset.imageService;
26
26
  }
27
- async function getImage(options) {
27
+ async function getImage(options, serviceConfig) {
28
28
  if (!options || typeof options !== "object") {
29
29
  throw new AstroError({
30
30
  ...AstroErrorData.ExpectedImageOptions,
@@ -32,8 +32,8 @@ async function getImage(options) {
32
32
  });
33
33
  }
34
34
  const service = await getConfiguredImageService();
35
- const validatedOptions = service.validateOptions ? service.validateOptions(options) : options;
36
- let imageURL = service.getURL(validatedOptions);
35
+ const validatedOptions = service.validateOptions ? service.validateOptions(options, serviceConfig) : options;
36
+ let imageURL = service.getURL(validatedOptions, serviceConfig);
37
37
  if (isLocalService(service) && globalThis.astroAsset.addStaticImage) {
38
38
  imageURL = globalThis.astroAsset.addStaticImage(validatedOptions);
39
39
  }
@@ -41,7 +41,7 @@ async function getImage(options) {
41
41
  rawOptions: options,
42
42
  options: validatedOptions,
43
43
  src: imageURL,
44
- attributes: service.getHTMLAttributes !== void 0 ? service.getHTMLAttributes(validatedOptions) : {}
44
+ attributes: service.getHTMLAttributes !== void 0 ? service.getHTMLAttributes(validatedOptions, serviceConfig) : {}
45
45
  };
46
46
  }
47
47
  function getStaticImageList() {
@@ -73,7 +73,11 @@ async function generateImage(buildOpts, options, filepath) {
73
73
  serverRoot
74
74
  )
75
75
  );
76
- const resultData = await imageService.transform(fileData, { ...options, src: originalImagePath });
76
+ const resultData = await imageService.transform(
77
+ fileData,
78
+ { ...options, src: originalImagePath },
79
+ buildOpts.settings.config.image.service.config
80
+ );
77
81
  const finalFileURL = new URL("." + filepath, clientRoot);
78
82
  const finalFolderURL = new URL("./", finalFileURL);
79
83
  await fs.promises.mkdir(finalFolderURL, { recursive: true });
@@ -12,14 +12,14 @@ interface SharedServiceProps {
12
12
  * For external services, this should point to the URL your images are coming from, for instance, `/_vercel/image`
13
13
  *
14
14
  */
15
- getURL: (options: ImageTransform) => string;
15
+ getURL: (options: ImageTransform, serviceConfig: Record<string, any>) => string;
16
16
  /**
17
17
  * Return any additional HTML attributes separate from `src` that your service requires to show the image properly.
18
18
  *
19
19
  * For example, you might want to return the `width` and `height` to avoid CLS, or a particular `class` or `style`.
20
20
  * In most cases, you'll want to return directly what your user supplied you, minus the attributes that were used to generate the image.
21
21
  */
22
- getHTMLAttributes?: (options: ImageTransform) => Record<string, any>;
22
+ getHTMLAttributes?: (options: ImageTransform, serviceConfig: Record<string, any>) => Record<string, any>;
23
23
  /**
24
24
  * Validate and return the options passed by the user.
25
25
  *
@@ -28,7 +28,7 @@ interface SharedServiceProps {
28
28
  *
29
29
  * This method should returns options, and can be used to set defaults (ex: a default output format to be used if the user didn't specify one.)
30
30
  */
31
- validateOptions?: (options: ImageTransform) => ImageTransform;
31
+ validateOptions?: (options: ImageTransform, serviceConfig: Record<string, any>) => ImageTransform;
32
32
  }
33
33
  export type ExternalImageService = SharedServiceProps;
34
34
  type LocalImageTransform = {
@@ -41,12 +41,12 @@ export interface LocalImageService extends SharedServiceProps {
41
41
  *
42
42
  * In most cases, this will get query parameters using, for example, `params.get('width')` and return those.
43
43
  */
44
- parseURL: (url: URL) => LocalImageTransform | undefined;
44
+ parseURL: (url: URL, serviceConfig: Record<string, any>) => LocalImageTransform | undefined;
45
45
  /**
46
46
  * Performs the image transformations on the input image and returns both the binary data and
47
47
  * final image format of the optimized image.
48
48
  */
49
- transform: (inputBuffer: Buffer, transform: LocalImageTransform) => Promise<{
49
+ transform: (inputBuffer: Buffer, transform: LocalImageTransform, serviceConfig: Record<string, any>) => Promise<{
50
50
  data: Buffer;
51
51
  format: ImageOutputFormat;
52
52
  }>;
@@ -31,7 +31,7 @@ function assets({
31
31
  ]);
32
32
  const adapterName = (_a = settings.config.adapter) == null ? void 0 : _a.name;
33
33
  if (["astro/assets/services/sharp", "astro/assets/services/squoosh"].includes(
34
- settings.config.image.service
34
+ settings.config.image.service.entrypoint
35
35
  ) && adapterName && UNSUPPORTED_ADAPTERS.has(adapterName)) {
36
36
  error(
37
37
  logging,
@@ -59,7 +59,7 @@ function assets({
59
59
  },
60
60
  async resolveId(id) {
61
61
  if (id === VIRTUAL_SERVICE_ID) {
62
- return await this.resolve(settings.config.image.service);
62
+ return await this.resolve(settings.config.image.service.entrypoint);
63
63
  }
64
64
  if (id === VIRTUAL_MODULE_ID) {
65
65
  return resolvedVirtualModuleId;
@@ -68,8 +68,12 @@ function assets({
68
68
  load(id) {
69
69
  if (id === resolvedVirtualModuleId) {
70
70
  return `
71
- export { getImage, getConfiguredImageService, isLocalService } from "astro/assets";
71
+ export { getConfiguredImageService, isLocalService } from "astro/assets";
72
+ import { getImage as getImageInternal } from "astro/assets";
72
73
  export { default as Image } from "astro/components/Image.astro";
74
+
75
+ export const imageServiceConfig = ${JSON.stringify(settings.config.image.service.config)};
76
+ export const getImage = async (options) => await getImageInternal(options, imageServiceConfig);
73
77
  `;
74
78
  }
75
79
  },
@@ -95,14 +99,21 @@ function assets({
95
99
  return next();
96
100
  }
97
101
  }
98
- const transform = await globalThis.astroAsset.imageService.parseURL(url);
102
+ const transform = await globalThis.astroAsset.imageService.parseURL(
103
+ url,
104
+ settings.config.image.service.config
105
+ );
99
106
  if (transform === void 0) {
100
107
  error(logging, "image", `Failed to parse transform for ${url}`);
101
108
  }
102
109
  let data = file;
103
110
  let format = meta.format;
104
111
  if (transform) {
105
- const result = await globalThis.astroAsset.imageService.transform(file, transform);
112
+ const result = await globalThis.astroAsset.imageService.transform(
113
+ file,
114
+ transform,
115
+ settings.config.image.service.config
116
+ );
106
117
  data = result.data;
107
118
  format = result.format;
108
119
  }
@@ -122,7 +133,7 @@ function assets({
122
133
  if (!globalThis.astroAsset.staticImages) {
123
134
  globalThis.astroAsset.staticImages = /* @__PURE__ */ new Map();
124
135
  }
125
- const hash = hashTransform(options, settings.config.image.service);
136
+ const hash = hashTransform(options, settings.config.image.service.entrypoint);
126
137
  let filePath;
127
138
  if (globalThis.astroAsset.staticImages.has(hash)) {
128
139
  filePath = globalThis.astroAsset.staticImages.get(hash).path;
@@ -90,7 +90,7 @@ function astroContentImportPlugin({
90
90
  if (settings.contentEntryTypes.some((t) => t.getRenderModule)) {
91
91
  plugins.push({
92
92
  name: "astro:content-render-imports",
93
- async load(viteId) {
93
+ async transform(_, viteId) {
94
94
  const contentRenderer = getContentRendererByViteId(viteId, settings);
95
95
  if (!contentRenderer)
96
96
  return;
@@ -28,12 +28,7 @@ import { createRequest } from "../request.js";
28
28
  import { matchRoute } from "../routing/match.js";
29
29
  import { getOutputFilename } from "../util.js";
30
30
  import { getOutDirWithinCwd, getOutFile, getOutFolder } from "./common.js";
31
- import {
32
- eachPageData,
33
- eachPrerenderedPageData,
34
- getPageDataByComponent,
35
- sortedCSS
36
- } from "./internal.js";
31
+ import { eachPageData, getPageDataByComponent, sortedCSS } from "./internal.js";
37
32
  import { getTimeStat } from "./util.js";
38
33
  function shouldSkipDraft(pageModule, settings) {
39
34
  var _a;
@@ -73,8 +68,9 @@ ${bgGreen(black(` ${verb} static routes `))}`);
73
68
  const ssrEntry = await import(ssrEntryURL.toString());
74
69
  const builtPaths = /* @__PURE__ */ new Set();
75
70
  if (ssr) {
76
- for (const pageData of eachPrerenderedPageData(internals)) {
77
- await generatePage(opts, internals, pageData, ssrEntry, builtPaths);
71
+ for (const pageData of eachPageData(internals)) {
72
+ if (pageData.route.prerender)
73
+ await generatePage(opts, internals, pageData, ssrEntry, builtPaths);
78
74
  }
79
75
  } else {
80
76
  for (const pageData of eachPageData(internals)) {
@@ -77,8 +77,6 @@ export declare function getPageDataByViteID(internals: BuildInternals, viteid: V
77
77
  export declare function hasPageDataByViteID(internals: BuildInternals, viteid: ViteID): boolean;
78
78
  export declare function eachPageData(internals: BuildInternals): Generator<PageBuildData, void, undefined>;
79
79
  export declare function hasPrerenderedPages(internals: BuildInternals): boolean;
80
- export declare function eachPrerenderedPageData(internals: BuildInternals): Generator<PageBuildData, void, unknown>;
81
- export declare function eachServerPageData(internals: BuildInternals): Generator<PageBuildData, void, unknown>;
82
80
  /**
83
81
  * Sort a page's CSS by depth. A higher depth means that the CSS comes from shared subcomponents.
84
82
  * A lower depth means it comes directly from the top-level page.
@@ -83,30 +83,13 @@ function* eachPageData(internals) {
83
83
  yield* internals.pagesByComponent.values();
84
84
  }
85
85
  function hasPrerenderedPages(internals) {
86
- var _a;
87
- for (const id of internals.pagesByViteID.keys()) {
88
- if ((_a = internals.pageOptionsByPage.get(id)) == null ? void 0 : _a.prerender) {
86
+ for (const pageData of eachPageData(internals)) {
87
+ if (pageData.route.prerender) {
89
88
  return true;
90
89
  }
91
90
  }
92
91
  return false;
93
92
  }
94
- function* eachPrerenderedPageData(internals) {
95
- var _a;
96
- for (const [id, pageData] of internals.pagesByViteID.entries()) {
97
- if ((_a = internals.pageOptionsByPage.get(id)) == null ? void 0 : _a.prerender) {
98
- yield pageData;
99
- }
100
- }
101
- }
102
- function* eachServerPageData(internals) {
103
- var _a;
104
- for (const [id, pageData] of internals.pagesByViteID.entries()) {
105
- if (!((_a = internals.pageOptionsByPage.get(id)) == null ? void 0 : _a.prerender)) {
106
- yield pageData;
107
- }
108
- }
109
- }
110
93
  function sortedCSS(pageData) {
111
94
  return Array.from(pageData.css).sort((a, b) => {
112
95
  let depthA = a[1].depth, depthB = b[1].depth, orderA = a[1].order, orderB = b[1].order;
@@ -146,8 +129,6 @@ function* getPageDatasByHoistedScriptId(internals, id) {
146
129
  export {
147
130
  createBuildInternals,
148
131
  eachPageData,
149
- eachPrerenderedPageData,
150
- eachServerPageData,
151
132
  getPageDataByComponent,
152
133
  getPageDataByViteID,
153
134
  getPageDatasByChunk,
@@ -1,6 +1,7 @@
1
1
  import type { Plugin as VitePlugin } from 'vite';
2
2
  import type { BuildInternals } from '../internal.js';
3
3
  import type { AstroBuildPlugin } from '../plugin.js';
4
+ export declare const astroEntryPrefix = "\0astro-entry:";
4
5
  /**
5
6
  * When adding hydrated or client:only components as Rollup inputs, sometimes we're not using all
6
7
  * of the export names, e.g. `import { Counter } from './ManyComponents.jsx'`. This plugin proxies
@@ -68,6 +68,7 @@ function pluginComponentEntry(internals) {
68
68
  };
69
69
  }
70
70
  export {
71
+ astroEntryPrefix,
71
72
  normalizeEntryId,
72
73
  pluginComponentEntry,
73
74
  vitePluginComponentEntry
@@ -7,7 +7,7 @@ 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";
10
- import { eachPrerenderedPageData, eachServerPageData, sortedCSS } from "../internal.js";
10
+ import { eachPageData, sortedCSS } from "../internal.js";
11
11
  const virtualModuleId = "@astrojs-ssr-virtual-entry";
12
12
  const resolvedVirtualModuleId = "\0" + virtualModuleId;
13
13
  const manifestReplace = "@@ASTRO_MANIFEST_REPLACE@@";
@@ -111,7 +111,9 @@ function buildManifest(opts, internals, staticFiles) {
111
111
  return prependForwardSlash(joinPaths(settings.config.base, pth));
112
112
  }
113
113
  };
114
- for (const pageData of eachPrerenderedPageData(internals)) {
114
+ for (const pageData of eachPageData(internals)) {
115
+ if (!pageData.route.prerender)
116
+ continue;
115
117
  if (!pageData.route.pathname)
116
118
  continue;
117
119
  const outFolder = getOutFolder(
@@ -134,7 +136,9 @@ function buildManifest(opts, internals, staticFiles) {
134
136
  });
135
137
  staticFiles.push(file);
136
138
  }
137
- for (const pageData of eachServerPageData(internals)) {
139
+ for (const pageData of eachPageData(internals)) {
140
+ if (pageData.route.prerender)
141
+ continue;
138
142
  const scripts = [];
139
143
  if (pageData.hoistedScript) {
140
144
  const hoistedValue = pageData.hoistedScript.value;
@@ -8,7 +8,7 @@ import { fileURLToPath } from "url";
8
8
  import * as vite from "vite";
9
9
  import {
10
10
  createBuildInternals,
11
- eachPrerenderedPageData
11
+ eachPageData
12
12
  } from "../../core/build/internal.js";
13
13
  import { emptyDir, removeEmptyDirs } from "../../core/fs/index.js";
14
14
  import { appendForwardSlash, prependForwardSlash } from "../../core/path.js";
@@ -219,8 +219,9 @@ async function runPostBuildHooks(container, ssrReturn, clientReturn) {
219
219
  }
220
220
  async function cleanStaticOutput(opts, internals) {
221
221
  const allStaticFiles = /* @__PURE__ */ new Set();
222
- for (const pageData of eachPrerenderedPageData(internals)) {
223
- allStaticFiles.add(internals.pageToBundleMap.get(pageData.moduleSpecifier));
222
+ for (const pageData of eachPageData(internals)) {
223
+ if (pageData.route.prerender)
224
+ allStaticFiles.add(internals.pageToBundleMap.get(pageData.moduleSpecifier));
224
225
  }
225
226
  const ssr = opts.settings.config.output === "server";
226
227
  const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.settings.config.outDir);
@@ -80,11 +80,26 @@ export declare const AstroConfigSchema: z.ZodObject<{
80
80
  port: number;
81
81
  }, unknown>;
82
82
  image: z.ZodDefault<z.ZodObject<{
83
- service: z.ZodUnion<[z.ZodLiteral<"astro/assets/services/sharp">, z.ZodLiteral<"astro/assets/services/squoosh">, z.ZodString]>;
83
+ service: z.ZodObject<{
84
+ entrypoint: z.ZodUnion<[z.ZodLiteral<"astro/assets/services/sharp">, z.ZodLiteral<"astro/assets/services/squoosh">, z.ZodString]>;
85
+ config: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
86
+ }, "strip", z.ZodTypeAny, {
87
+ entrypoint: string;
88
+ config: Record<string, any>;
89
+ }, {
90
+ config?: Record<string, any> | undefined;
91
+ entrypoint: string;
92
+ }>;
84
93
  }, "strip", z.ZodTypeAny, {
85
- service: string;
94
+ service: {
95
+ entrypoint: string;
96
+ config: Record<string, any>;
97
+ };
86
98
  }, {
87
- service: string;
99
+ service: {
100
+ config?: Record<string, any> | undefined;
101
+ entrypoint: string;
102
+ };
88
103
  }>>;
89
104
  markdown: z.ZodDefault<z.ZodObject<{
90
105
  drafts: z.ZodDefault<z.ZodBoolean>;
@@ -189,7 +204,10 @@ export declare const AstroConfigSchema: z.ZodObject<{
189
204
  serverEntry: string;
190
205
  };
191
206
  image: {
192
- service: string;
207
+ service: {
208
+ entrypoint: string;
209
+ config: Record<string, any>;
210
+ };
193
211
  };
194
212
  vite: ViteUserConfig;
195
213
  experimental: {
@@ -234,7 +252,10 @@ export declare const AstroConfigSchema: z.ZodObject<{
234
252
  serverEntry?: string | undefined;
235
253
  } | undefined;
236
254
  image?: {
237
- service: string;
255
+ service: {
256
+ config?: Record<string, any> | undefined;
257
+ entrypoint: string;
258
+ };
238
259
  } | undefined;
239
260
  vite?: ViteUserConfig | undefined;
240
261
  experimental?: {
@@ -319,11 +340,26 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
319
340
  hooks: {};
320
341
  }[], unknown>;
321
342
  image: z.ZodDefault<z.ZodObject<{
322
- service: z.ZodUnion<[z.ZodLiteral<"astro/assets/services/sharp">, z.ZodLiteral<"astro/assets/services/squoosh">, z.ZodString]>;
343
+ service: z.ZodObject<{
344
+ entrypoint: z.ZodUnion<[z.ZodLiteral<"astro/assets/services/sharp">, z.ZodLiteral<"astro/assets/services/squoosh">, z.ZodString]>;
345
+ config: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
346
+ }, "strip", z.ZodTypeAny, {
347
+ entrypoint: string;
348
+ config: Record<string, any>;
349
+ }, {
350
+ config?: Record<string, any> | undefined;
351
+ entrypoint: string;
352
+ }>;
323
353
  }, "strip", z.ZodTypeAny, {
324
- service: string;
354
+ service: {
355
+ entrypoint: string;
356
+ config: Record<string, any>;
357
+ };
325
358
  }, {
326
- service: string;
359
+ service: {
360
+ config?: Record<string, any> | undefined;
361
+ entrypoint: string;
362
+ };
327
363
  }>>;
328
364
  vite: z.ZodDefault<z.ZodType<ViteUserConfig, z.ZodTypeDef, ViteUserConfig>>;
329
365
  experimental: z.ZodDefault<z.ZodOptional<z.ZodObject<{
@@ -432,7 +468,10 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
432
468
  serverEntry: string;
433
469
  };
434
470
  image: {
435
- service: string;
471
+ service: {
472
+ entrypoint: string;
473
+ config: Record<string, any>;
474
+ };
436
475
  };
437
476
  vite: ViteUserConfig;
438
477
  experimental: {
@@ -477,7 +516,10 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
477
516
  serverEntry?: string | undefined;
478
517
  } | undefined;
479
518
  image?: {
480
- service: string;
519
+ service: {
520
+ config?: Record<string, any> | undefined;
521
+ entrypoint: string;
522
+ };
481
523
  } | undefined;
482
524
  vite?: ViteUserConfig | undefined;
483
525
  experimental?: {
@@ -531,7 +573,10 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
531
573
  serverEntry: string;
532
574
  };
533
575
  image: {
534
- service: string;
576
+ service: {
577
+ entrypoint: string;
578
+ config: Record<string, any>;
579
+ };
535
580
  };
536
581
  vite: ViteUserConfig;
537
582
  experimental: {
@@ -576,7 +621,10 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
576
621
  serverEntry?: string | undefined;
577
622
  } | undefined;
578
623
  image?: {
579
- service: string;
624
+ service: {
625
+ config?: Record<string, any> | undefined;
626
+ entrypoint: string;
627
+ };
580
628
  } | undefined;
581
629
  vite?: ViteUserConfig | undefined;
582
630
  experimental?: {
@@ -71,13 +71,16 @@ const AstroConfigSchema = z.object({
71
71
  }).optional().default({})
72
72
  ),
73
73
  image: z.object({
74
- service: z.union([
75
- z.literal("astro/assets/services/sharp"),
76
- z.literal("astro/assets/services/squoosh"),
77
- z.string()
78
- ])
74
+ service: z.object({
75
+ entrypoint: z.union([
76
+ z.literal("astro/assets/services/sharp"),
77
+ z.literal("astro/assets/services/squoosh"),
78
+ z.string()
79
+ ]),
80
+ config: z.record(z.any()).default({})
81
+ })
79
82
  }).default({
80
- service: "astro/assets/services/squoosh"
83
+ service: { entrypoint: "astro/assets/services/squoosh", config: {} }
81
84
  }),
82
85
  markdown: z.object({
83
86
  drafts: z.boolean().default(false),
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.3.2";
1
+ const ASTRO_VERSION = "2.3.4";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -53,7 +53,7 @@ async function dev(settings, options) {
53
53
  isRestart: options.isRestart
54
54
  })
55
55
  );
56
- const currentVersion = "2.3.2";
56
+ const currentVersion = "2.3.4";
57
57
  if (currentVersion.includes("-")) {
58
58
  warn(options.logging, null, msg.prerelease({ currentVersion }));
59
59
  }
@@ -47,7 +47,7 @@ function serverStart({
47
47
  base,
48
48
  isRestart = false
49
49
  }) {
50
- const version = "2.3.2";
50
+ const version = "2.3.4";
51
51
  const localPrefix = `${dim("\u2503")} Local `;
52
52
  const networkPrefix = `${dim("\u2503")} Network `;
53
53
  const emptyPrefix = " ".repeat(11);
@@ -233,7 +233,7 @@ function printHelp({
233
233
  message.push(
234
234
  linebreak(),
235
235
  ` ${bgGreen(black(` ${commandName} `))} ${green(
236
- `v${"2.3.2"}`
236
+ `v${"2.3.4"}`
237
237
  )} ${headline}`
238
238
  );
239
239
  }
package/dist/core/path.js CHANGED
@@ -40,7 +40,15 @@ function isString(path) {
40
40
  return typeof path === "string" || path instanceof String;
41
41
  }
42
42
  function joinPaths(...paths) {
43
- return paths.filter(isString).map(trimSlashes).join("/");
43
+ return paths.filter(isString).map((path, i) => {
44
+ if (i === 0) {
45
+ return removeTrailingForwardSlash(path);
46
+ } else if (i === paths.length - 1) {
47
+ return removeLeadingForwardSlash(path);
48
+ } else {
49
+ return trimSlashes(path);
50
+ }
51
+ }).join("/");
44
52
  }
45
53
  function removeFileExtension(path) {
46
54
  let idx = path.lastIndexOf(".");
@@ -208,7 +208,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
208
208
  if (isPage || (renderer == null ? void 0 : renderer.name) === "astro:jsx") {
209
209
  yield html;
210
210
  } else if (html && html.length > 0) {
211
- yield markHTMLString(html.replace(/\<\/?astro-slot\>/g, ""));
211
+ yield markHTMLString(html.replace(/\<\/?astro-slot\b[^>]*>/g, ""));
212
212
  } else {
213
213
  yield "";
214
214
  }
@@ -4,18 +4,15 @@ import { call as callEndpoint } from "../core/endpoint/dev/index.js";
4
4
  import { throwIfRedirectNotAllowed } from "../core/endpoint/index.js";
5
5
  import { AstroErrorData } from "../core/errors/index.js";
6
6
  import { warn } from "../core/logger/core.js";
7
- import { appendForwardSlash } from "../core/path.js";
8
7
  import { preload, renderPage } from "../core/render/dev/index.js";
9
8
  import { getParamsAndProps, GetParamsAndPropsError } from "../core/render/index.js";
10
9
  import { createRequest } from "../core/request.js";
11
10
  import { matchAllRoutes } from "../core/routing/index.js";
12
- import { resolvePages } from "../core/util.js";
13
11
  import { log404 } from "./common.js";
14
12
  import { handle404Response, writeSSRResult, writeWebResponse } from "./response.js";
15
- function getCustom404Route({ config }, manifest) {
16
- const relPages = resolvePages(config).href.replace(config.root.href, "");
17
- const pattern = new RegExp(`${appendForwardSlash(relPages)}404.(astro|md)`);
18
- return manifest.routes.find((r) => r.component.match(pattern));
13
+ function getCustom404Route(manifest) {
14
+ const route404 = /^\/404\/?$/;
15
+ return manifest.routes.find((r) => route404.test(r.route));
19
16
  }
20
17
  async function matchRoute(pathname, env, manifest) {
21
18
  const { logging, settings, routeCache } = env;
@@ -59,7 +56,7 @@ ${AstroErrorData.NoMatchingStaticPathFound.hint(possibleRoutes)}`
59
56
  );
60
57
  }
61
58
  log404(logging, pathname);
62
- const custom404 = getCustom404Route(settings, manifest);
59
+ const custom404 = getCustom404Route(manifest);
63
60
  if (custom404) {
64
61
  const filePath = new URL(`./${custom404.component}`, settings.config.root);
65
62
  const preloadedComponent = await preload({ env, filePath });
@@ -15,7 +15,12 @@ function getPrivateEnv(viteConfig, astroConfig) {
15
15
  for (const key in fullEnv) {
16
16
  if (envPrefixes.every((prefix) => !key.startsWith(prefix))) {
17
17
  if (typeof process.env[key] !== "undefined") {
18
- privateEnv[key] = `process.env.${key}`;
18
+ const value = process.env[key];
19
+ if (value === "0" || value === "1" || value === "true" || value === "false") {
20
+ privateEnv[key] = value;
21
+ } else {
22
+ privateEnv[key] = `process.env.${key}`;
23
+ }
19
24
  } else {
20
25
  privateEnv[key] = JSON.stringify(fullEnv[key]);
21
26
  }
@@ -5,6 +5,7 @@ import babel from "@babel/core";
5
5
  import * as colors from "kleur/colors";
6
6
  import path from "path";
7
7
  import { CONTENT_FLAG, PROPAGATED_ASSET_FLAG } from "../content/index.js";
8
+ import { astroEntryPrefix } from "../core/build/plugins/plugin-component-entry.js";
8
9
  import { error } from "../core/logger/core.js";
9
10
  import { removeQueryString } from "../core/path.js";
10
11
  import { detectImportSource } from "./import-source.js";
@@ -104,7 +105,7 @@ function jsx({ settings, logging }) {
104
105
  },
105
106
  async transform(code, id, opts) {
106
107
  const ssr = Boolean(opts == null ? void 0 : opts.ssr);
107
- if (SPECIAL_QUERY_REGEX.test(id)) {
108
+ if (SPECIAL_QUERY_REGEX.test(id) || id.startsWith(astroEntryPrefix)) {
108
109
  return null;
109
110
  }
110
111
  id = removeQueryString(id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "2.3.2",
3
+ "version": "2.3.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",
@@ -93,11 +93,11 @@
93
93
  "src/content/template"
94
94
  ],
95
95
  "dependencies": {
96
- "@astrojs/compiler": "^1.3.1",
97
- "@astrojs/language-server": "^0.28.3",
96
+ "@astrojs/compiler": "^1.3.2",
97
+ "@astrojs/language-server": "^1.0.0",
98
98
  "@astrojs/markdown-remark": "^2.1.4",
99
- "@astrojs/telemetry": "^2.1.0",
100
- "@astrojs/webapi": "^2.1.0",
99
+ "@astrojs/telemetry": "^2.1.1",
100
+ "@astrojs/webapi": "^2.1.1",
101
101
  "@babel/core": "^7.18.2",
102
102
  "@babel/generator": "^7.18.2",
103
103
  "@babel/parser": "^7.18.4",
@@ -168,7 +168,6 @@
168
168
  "@types/rimraf": "^3.0.2",
169
169
  "@types/send": "^0.17.1",
170
170
  "@types/server-destroy": "^1.0.1",
171
- "@types/sharp": "^0.31.1",
172
171
  "@types/unist": "^2.0.6",
173
172
  "chai": "^4.3.6",
174
173
  "cheerio": "^1.0.0-rc.11",
@@ -182,14 +181,14 @@
182
181
  "remark-code-titles": "^0.1.2",
183
182
  "rollup": "^3.9.0",
184
183
  "sass": "^1.52.2",
185
- "sharp": "^0.31.3",
184
+ "sharp": "^0.32.1",
186
185
  "srcset-parse": "^1.1.0",
187
- "undici": "^5.20.0",
186
+ "undici": "^5.22.0",
188
187
  "unified": "^10.1.2",
189
188
  "astro-scripts": "0.0.14"
190
189
  },
191
190
  "peerDependencies": {
192
- "sharp": "^0.31.3"
191
+ "sharp": ">=0.31.0"
193
192
  },
194
193
  "peerDependenciesMeta": {
195
194
  "sharp": {