astro 2.2.3 → 2.3.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.
@@ -1,8 +1,9 @@
1
1
  export declare const VIRTUAL_MODULE_ID = "astro:assets";
2
2
  export declare const VIRTUAL_SERVICE_ID = "virtual:image-service";
3
+ export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg"];
3
4
  /**
4
5
  * Valid formats for optimizations in our base services.
5
- * Certain formats can be imported (namely SVGs) but not optimized, so they are excluded from this list.
6
+ * Certain formats can be imported (namely SVGs) but not processed, so they are excluded from this list.
6
7
  */
7
- export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif"];
8
+ export declare const VALID_OPTIMIZABLE_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif"];
8
9
  export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg"];
@@ -14,11 +14,14 @@ const VALID_INPUT_FORMATS = [
14
14
  "png",
15
15
  "tiff",
16
16
  "webp",
17
- "gif"
17
+ "gif",
18
+ "svg"
18
19
  ];
20
+ const VALID_OPTIMIZABLE_FORMATS = ["jpeg", "jpg", "png", "tiff", "webp", "gif"];
19
21
  const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg"];
20
22
  export {
21
23
  VALID_INPUT_FORMATS,
24
+ VALID_OPTIMIZABLE_FORMATS,
22
25
  VALID_OUTPUT_FORMATS,
23
26
  VIRTUAL_MODULE_ID,
24
27
  VIRTUAL_SERVICE_ID
@@ -1,5 +1,5 @@
1
1
  import { AstroError, AstroErrorData } from "../../core/errors/index.js";
2
- import { VALID_INPUT_FORMATS } from "../consts.js";
2
+ import { VALID_OPTIMIZABLE_FORMATS } from "../consts.js";
3
3
  import { isESMImportedImage } from "../internal.js";
4
4
  function isLocalService(service) {
5
5
  if (!service) {
@@ -38,13 +38,13 @@ const baseService = {
38
38
  });
39
39
  }
40
40
  } else {
41
- if (!VALID_INPUT_FORMATS.includes(options.src.format)) {
41
+ if (!VALID_OPTIMIZABLE_FORMATS.includes(options.src.format)) {
42
42
  throw new AstroError({
43
43
  ...AstroErrorData.UnsupportedImageFormat,
44
44
  message: AstroErrorData.UnsupportedImageFormat.message(
45
45
  options.src.format,
46
46
  options.src.src,
47
- VALID_INPUT_FORMATS
47
+ VALID_OPTIMIZABLE_FORMATS
48
48
  )
49
49
  });
50
50
  }
@@ -2,7 +2,7 @@ import type { VALID_INPUT_FORMATS, VALID_OUTPUT_FORMATS } from './consts.js';
2
2
  import type { ImageService } from './services/service.js';
3
3
  export type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max' | (string & {});
4
4
  export type ImageQuality = ImageQualityPreset | number;
5
- export type ImageInputFormat = (typeof VALID_INPUT_FORMATS)[number] | 'svg';
5
+ export type ImageInputFormat = (typeof VALID_INPUT_FORMATS)[number];
6
6
  export type ImageOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {});
7
7
  declare global {
8
8
  var astroAsset: {
@@ -1,4 +1,4 @@
1
1
  import type { PluginContext } from 'rollup';
2
2
  import { z } from 'zod';
3
3
  import type { AstroSettings } from '../@types/astro.js';
4
- export declare function createImage(settings: AstroSettings, pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/utils/metadata.js").Metadata, string>;
4
+ export declare function createImage(settings: AstroSettings, pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/utils/metadata.js").Metadata | z.ZodNever, string>;
@@ -17,7 +17,7 @@ function createImage(settings, pluginContext, entryFilePath) {
17
17
  message: `Image ${imagePath} does not exist. Is the path correct?`,
18
18
  fatal: true
19
19
  });
20
- return z.NEVER;
20
+ return z.never();
21
21
  }
22
22
  return metadata;
23
23
  });
@@ -80,7 +80,12 @@ async function createContentTypesGenerator({
80
80
  }
81
81
  return { shouldGenerateTypes: true };
82
82
  }
83
- const fileType = getEntryType(fileURLToPath(event.entry), contentPaths, contentEntryExts);
83
+ const fileType = getEntryType(
84
+ fileURLToPath(event.entry),
85
+ contentPaths,
86
+ contentEntryExts,
87
+ settings.config.experimental.assets
88
+ );
84
89
  if (fileType === "ignored") {
85
90
  return { shouldGenerateTypes: false };
86
91
  }
@@ -63,7 +63,7 @@ export declare function getEntryInfo(params: Pick<ContentPaths, 'contentDir'> &
63
63
  entry: URL;
64
64
  allowFilesOutsideCollection?: true;
65
65
  }): EntryInfo;
66
- export declare function getEntryType(entryPath: string, paths: Pick<ContentPaths, 'config' | 'contentDir'>, contentFileExts: string[]): 'content' | 'config' | 'ignored' | 'unsupported';
66
+ export declare function getEntryType(entryPath: string, paths: Pick<ContentPaths, 'config' | 'contentDir'>, contentFileExts: string[], experimentalAssets: boolean): 'content' | 'config' | 'ignored' | 'unsupported';
67
67
  /**
68
68
  * Match YAML exception handling from Astro core errors
69
69
  * @see 'astro/src/core/errors.ts'
@@ -5,6 +5,7 @@ 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 { VALID_INPUT_FORMATS } from "../assets/consts.js";
8
9
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
9
10
  import { CONTENT_TYPES_FILE } from "./consts.js";
10
11
  import { errorMap } from "./error-map.js";
@@ -113,10 +114,10 @@ function getEntryInfo({
113
114
  };
114
115
  return res;
115
116
  }
116
- function getEntryType(entryPath, paths, contentFileExts) {
117
+ function getEntryType(entryPath, paths, contentFileExts, experimentalAssets) {
117
118
  const { ext, base } = path.parse(entryPath);
118
119
  const fileUrl = pathToFileURL(entryPath);
119
- if (hasUnderscoreBelowContentDirectoryPath(fileUrl, paths.contentDir) || isOnIgnoreList(base)) {
120
+ if (hasUnderscoreBelowContentDirectoryPath(fileUrl, paths.contentDir) || isOnIgnoreList(base) || experimentalAssets && isImageAsset(ext)) {
120
121
  return "ignored";
121
122
  } else if (contentFileExts.includes(ext)) {
122
123
  return "content";
@@ -129,6 +130,9 @@ function getEntryType(entryPath, paths, contentFileExts) {
129
130
  function isOnIgnoreList(fileName) {
130
131
  return [".DS_Store"].includes(fileName);
131
132
  }
133
+ function isImageAsset(fileExt) {
134
+ return VALID_INPUT_FORMATS.includes(fileExt.slice(1));
135
+ }
132
136
  function hasUnderscoreBelowContentDirectoryPath(fileUrl, contentDir) {
133
137
  const parts = fileUrl.pathname.replace(contentDir.pathname, "").split("/");
134
138
  for (const part of parts) {
@@ -68,7 +68,12 @@ function astroContentImportPlugin({
68
68
  },
69
69
  configureServer(viteServer) {
70
70
  viteServer.watcher.on("all", async (event, entry) => {
71
- if (CHOKIDAR_MODIFIED_EVENTS.includes(event) && getEntryType(entry, contentPaths, contentEntryExts) === "config") {
71
+ if (CHOKIDAR_MODIFIED_EVENTS.includes(event) && getEntryType(
72
+ entry,
73
+ contentPaths,
74
+ contentEntryExts,
75
+ settings.config.experimental.assets
76
+ ) === "config") {
72
77
  for (const modUrl of viteServer.moduleGraph.urlToModuleMap.keys()) {
73
78
  if (isContentFlagImport(modUrl) || Boolean(getContentRendererByViteId(modUrl, settings))) {
74
79
  const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl);
@@ -3,6 +3,7 @@ import * as eslexer from "es-module-lexer";
3
3
  import glob from "fast-glob";
4
4
  import fs from "fs";
5
5
  import { bgGreen, bgMagenta, black, dim } from "kleur/colors";
6
+ import path from "path";
6
7
  import { fileURLToPath } from "url";
7
8
  import * as vite from "vite";
8
9
  import {
@@ -292,11 +293,13 @@ async function ssrMoveAssets(opts) {
292
293
  cwd: fileURLToPath(serverAssets)
293
294
  });
294
295
  if (files.length > 0) {
295
- await fs.promises.mkdir(clientAssets, { recursive: true });
296
296
  await Promise.all(
297
297
  files.map(async (filename) => {
298
298
  const currentUrl = new URL(filename, appendForwardSlash(serverAssets.toString()));
299
299
  const clientUrl = new URL(filename, appendForwardSlash(clientAssets.toString()));
300
+ const dir = new URL(path.parse(clientUrl.href).dir);
301
+ if (!fs.existsSync(dir))
302
+ await fs.promises.mkdir(dir, { recursive: true });
300
303
  return fs.promises.rename(currentUrl, clientUrl);
301
304
  })
302
305
  );
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.2.3";
1
+ const ASTRO_VERSION = "2.3.0";
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.2.3";
56
+ const currentVersion = "2.3.0";
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.2.3";
50
+ const version = "2.3.0";
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.2.3"}`
236
+ `v${"2.3.0"}`
237
237
  )} ${headline}`
238
238
  );
239
239
  }
@@ -1,11 +1,6 @@
1
+ import { type Plugin as VitePlugin } from 'vite';
1
2
  import type { AstroSettings } from '../@types/astro';
2
- import type * as vite from 'vite';
3
- /** Result of successfully parsed tsconfig.json or jsconfig.json. */
4
- export declare interface Alias {
5
- find: RegExp;
6
- replacement: string;
7
- }
8
3
  /** Returns a Vite plugin used to alias paths from tsconfig.json and jsconfig.json. */
9
4
  export default function configAliasVitePlugin({ settings, }: {
10
5
  settings: AstroSettings;
11
- }): vite.PluginOption;
6
+ }): VitePlugin | null;
@@ -1,66 +1,91 @@
1
- import * as path from "path";
2
- const normalize = (pathname) => String(pathname).split(path.sep).join(path.posix.sep);
1
+ import path from "path";
2
+ import { normalizePath } from "vite";
3
3
  const getConfigAlias = (settings) => {
4
- const config = settings.tsConfig;
5
- const configPath = settings.tsConfigPath;
6
- if (!config || !configPath)
4
+ const { tsConfig, tsConfigPath } = settings;
5
+ if (!tsConfig || !tsConfigPath || !tsConfig.compilerOptions)
7
6
  return null;
8
- const compilerOptions = Object(config.compilerOptions);
9
- if (!compilerOptions.baseUrl)
7
+ const { baseUrl, paths } = tsConfig.compilerOptions;
8
+ if (!baseUrl || !paths)
10
9
  return null;
11
- const baseUrl = path.posix.resolve(
12
- path.posix.dirname(normalize(configPath).replace(/^\/?/, "/")),
13
- normalize(compilerOptions.baseUrl)
14
- );
10
+ const resolvedBaseUrl = path.resolve(path.dirname(tsConfigPath), baseUrl);
15
11
  const aliases = [];
16
- for (let [alias, values] of Object.entries(
17
- Object(compilerOptions.paths)
18
- )) {
19
- values = [].concat(values);
12
+ for (const [alias, values] of Object.entries(paths)) {
20
13
  const find = new RegExp(
21
14
  `^${[...alias].map(
22
15
  (segment) => segment === "*" ? "(.+)" : segment.replace(/[\\^$*+?.()|[\]{}]/, "\\$&")
23
16
  ).join("")}$`
24
17
  );
25
18
  let matchId = 0;
26
- for (let value of values) {
27
- const replacement = [...path.posix.resolve(baseUrl, value)].map((segment) => segment === "*" ? `$${++matchId}` : segment === "$" ? "$$" : segment).join("");
19
+ for (const value of values) {
20
+ const replacement = [...normalizePath(path.resolve(resolvedBaseUrl, value))].map((segment) => segment === "*" ? `$${++matchId}` : segment === "$" ? "$$" : segment).join("");
28
21
  aliases.push({ find, replacement });
29
22
  }
30
23
  }
31
24
  aliases.push({
32
- find: /^(?!\.*\/)(.+)$/,
33
- replacement: `${[...baseUrl].map((segment) => segment === "$" ? "$$" : segment).join("")}/$1`
25
+ find: /^(?!\.*\/|\w:)(.+)$/,
26
+ replacement: `${[...normalizePath(resolvedBaseUrl)].map((segment) => segment === "$" ? "$$" : segment).join("")}/$1`
34
27
  });
35
28
  return aliases;
36
29
  };
37
30
  function configAliasVitePlugin({
38
31
  settings
39
32
  }) {
40
- const { config } = settings;
41
33
  const configAlias = getConfigAlias(settings);
42
34
  if (!configAlias)
43
- return {};
44
- return {
35
+ return null;
36
+ const plugin = {
45
37
  name: "astro:tsconfig-alias",
46
38
  enforce: "pre",
47
- async resolveId(sourceId, importer, options) {
48
- const resolvedId = await this.resolve(sourceId, importer, { skipSelf: true, ...options });
49
- if (resolvedId)
50
- return resolvedId;
39
+ configResolved(config) {
40
+ patchCreateResolver(config, plugin);
41
+ },
42
+ async resolveId(id, importer, options) {
43
+ if (isVirtualId(id))
44
+ return;
51
45
  for (const alias of configAlias) {
52
- if (alias.find.test(sourceId)) {
53
- const aliasedSourceId = sourceId.replace(alias.find, alias.replacement);
54
- const resolvedAliasedId = await this.resolve(aliasedSourceId, importer, {
55
- skipSelf: true,
56
- ...options
57
- });
58
- if (resolvedAliasedId)
59
- return resolvedAliasedId;
46
+ if (alias.find.test(id)) {
47
+ const updatedId = id.replace(alias.find, alias.replacement);
48
+ const resolved = await this.resolve(updatedId, importer, { skipSelf: true, ...options });
49
+ if (resolved)
50
+ return resolved;
60
51
  }
61
52
  }
62
53
  }
63
54
  };
55
+ return plugin;
56
+ }
57
+ function patchCreateResolver(config, prePlugin) {
58
+ const _createResolver = config.createResolver;
59
+ config.createResolver = function(...args1) {
60
+ const resolver = _createResolver.apply(config, args1);
61
+ return async function(...args2) {
62
+ const id = args2[0];
63
+ const importer = args2[1];
64
+ const ssr = args2[3];
65
+ if (importer == null ? void 0 : importer.includes("node_modules")) {
66
+ return resolver.apply(_createResolver, args2);
67
+ }
68
+ const fakePluginContext = {
69
+ resolve: (_id, _importer) => resolver(_id, _importer, false, ssr)
70
+ };
71
+ const fakeResolveIdOpts = {
72
+ assertions: {},
73
+ isEntry: false,
74
+ ssr
75
+ };
76
+ const resolved = await prePlugin.resolveId.apply(fakePluginContext, [
77
+ id,
78
+ importer,
79
+ fakeResolveIdOpts
80
+ ]);
81
+ if (resolved)
82
+ return resolved;
83
+ return resolver.apply(_createResolver, args2);
84
+ };
85
+ };
86
+ }
87
+ function isVirtualId(id) {
88
+ return id.includes("\0") || id.startsWith("virtual:") || id.startsWith("astro:");
64
89
  }
65
90
  export {
66
91
  configAliasVitePlugin as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "2.2.3",
3
+ "version": "2.3.0",
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",
@@ -95,7 +95,7 @@
95
95
  "dependencies": {
96
96
  "@astrojs/compiler": "^1.3.1",
97
97
  "@astrojs/language-server": "^0.28.3",
98
- "@astrojs/markdown-remark": "^2.1.3",
98
+ "@astrojs/markdown-remark": "^2.1.4",
99
99
  "@astrojs/telemetry": "^2.1.0",
100
100
  "@astrojs/webapi": "^2.1.0",
101
101
  "@babel/core": "^7.18.2",
@@ -145,7 +145,7 @@
145
145
  "vite": "^4.2.1",
146
146
  "vitefu": "^0.2.4",
147
147
  "yargs-parser": "^21.0.1",
148
- "zod": "^3.17.3"
148
+ "zod": "^3.20.6"
149
149
  },
150
150
  "devDependencies": {
151
151
  "@playwright/test": "^1.29.2",
@@ -170,7 +170,6 @@
170
170
  "@types/server-destroy": "^1.0.1",
171
171
  "@types/sharp": "^0.31.1",
172
172
  "@types/unist": "^2.0.6",
173
- "astro-scripts": "0.0.14",
174
173
  "chai": "^4.3.6",
175
174
  "cheerio": "^1.0.0-rc.11",
176
175
  "eol": "^0.9.1",
@@ -186,7 +185,8 @@
186
185
  "sharp": "^0.31.3",
187
186
  "srcset-parse": "^1.1.0",
188
187
  "undici": "^5.20.0",
189
- "unified": "^10.1.2"
188
+ "unified": "^10.1.2",
189
+ "astro-scripts": "0.0.14"
190
190
  },
191
191
  "peerDependencies": {
192
192
  "sharp": "^0.31.3"