astro 2.0.10 → 2.0.12

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.
@@ -8,8 +8,8 @@ import { fileURLToPath, pathToFileURL } from "url";
8
8
  import { printDiagnostic } from "./print.js";
9
9
  async function check(settings, { logging }) {
10
10
  console.log(bold("astro check"));
11
- const { sync } = await import("../sync/index.js");
12
- const syncRet = await sync(settings, { logging, fs });
11
+ const { syncCli } = await import("../../core/sync/index.js");
12
+ const syncRet = await syncCli(settings, { logging, fs });
13
13
  if (syncRet === 1)
14
14
  return syncRet;
15
15
  const root = settings.config.root;
package/dist/cli/index.js CHANGED
@@ -161,8 +161,8 @@ async function runCommand(cmd, flags) {
161
161
  return process.exit(ret);
162
162
  }
163
163
  case "sync": {
164
- const { sync } = await import("./sync/index.js");
165
- const ret = await sync(settings, { logging, fs });
164
+ const { syncCli } = await import("../core/sync/index.js");
165
+ const ret = await syncCli(settings, { logging, fs });
166
166
  return process.exit(ret);
167
167
  }
168
168
  case "preview": {
@@ -1,6 +1,8 @@
1
- import { cyan } from "kleur/colors";
2
- import { pathToFileURL } from "node:url";
3
- import { info } from "../core/logger/core.js";
1
+ import { bold, cyan } from "kleur/colors";
2
+ import path from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { loadTSConfig } from "../core/config/tsconfig.js";
5
+ import { info, warn } from "../core/logger/core.js";
4
6
  import { appendForwardSlash } from "../core/path.js";
5
7
  import { createContentTypesGenerator } from "./types-generator.js";
6
8
  import { getContentPaths, globalContentConfigObserver } from "./utils.js";
@@ -10,7 +12,10 @@ async function attachContentServerListeners({
10
12
  logging,
11
13
  settings
12
14
  }) {
13
- const contentPaths = getContentPaths(settings.config);
15
+ const contentPaths = getContentPaths(settings.config, fs);
16
+ const maybeTsConfigStats = getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings });
17
+ if (maybeTsConfigStats)
18
+ warnAllowJsIsFalse({ ...maybeTsConfigStats, logging });
14
19
  if (fs.existsSync(contentPaths.contentDir)) {
15
20
  info(
16
21
  logging,
@@ -60,6 +65,45 @@ async function attachContentServerListeners({
60
65
  );
61
66
  }
62
67
  }
68
+ function warnAllowJsIsFalse({
69
+ logging,
70
+ tsConfigFileName,
71
+ contentConfigFileName
72
+ }) {
73
+ if (!["info", "warn"].includes(logging.level))
74
+ warn(
75
+ logging,
76
+ "content",
77
+ `Make sure you have the ${bold("allowJs")} compiler option set to ${bold(
78
+ "true"
79
+ )} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold(
80
+ contentConfigFileName
81
+ )} file.
82
+ See ${bold("https://www.typescriptlang.org/tsconfig#allowJs")} for more information.
83
+ `
84
+ );
85
+ }
86
+ function getTSConfigStatsWhenAllowJsFalse({
87
+ contentPaths,
88
+ settings
89
+ }) {
90
+ var _a, _b;
91
+ const isContentConfigJsFile = [".js", ".mjs"].some(
92
+ (ext) => contentPaths.config.url.pathname.endsWith(ext)
93
+ );
94
+ if (!isContentConfigJsFile)
95
+ return;
96
+ const inputConfig = loadTSConfig(fileURLToPath(settings.config.root), false);
97
+ const tsConfigFileName = inputConfig.exists && inputConfig.path.split(path.sep).pop();
98
+ if (!tsConfigFileName)
99
+ return;
100
+ const contentConfigFileName = contentPaths.config.url.pathname.split(path.sep).pop();
101
+ const allowJSOption = (_b = (_a = inputConfig == null ? void 0 : inputConfig.config) == null ? void 0 : _a.compilerOptions) == null ? void 0 : _b.allowJs;
102
+ const hasAllowJs = allowJSOption === true || tsConfigFileName === "jsconfig.json" && allowJSOption !== false;
103
+ if (hasAllowJs)
104
+ return;
105
+ return { tsConfigFileName, contentConfigFileName };
106
+ }
63
107
  export {
64
108
  attachContentServerListeners
65
109
  };
@@ -26,7 +26,7 @@ async function createContentTypesGenerator({
26
26
  viteServer
27
27
  }) {
28
28
  const contentTypes = {};
29
- const contentPaths = getContentPaths(settings.config);
29
+ const contentPaths = getContentPaths(settings.config, fs);
30
30
  let events = [];
31
31
  let debounceTimeout;
32
32
  const contentTypesBase = await fs.promises.readFile(contentPaths.typesTemplate, "utf-8");
@@ -34,7 +34,7 @@ async function createContentTypesGenerator({
34
34
  if (!fs.existsSync(contentPaths.contentDir)) {
35
35
  return { typesGenerated: false, reason: "no-content-dir" };
36
36
  }
37
- events.push(handleEvent({ name: "add", entry: contentPaths.config }, { logLevel: "warn" }));
37
+ events.push(handleEvent({ name: "add", entry: contentPaths.config.url }, { logLevel: "warn" }));
38
38
  const globResult = await glob("**", {
39
39
  cwd: fileURLToPath(contentPaths.contentDir),
40
40
  fs: {
@@ -43,7 +43,7 @@ async function createContentTypesGenerator({
43
43
  }
44
44
  });
45
45
  const entries = globResult.map((e) => new URL(e, contentPaths.contentDir)).filter(
46
- (e) => !e.href.startsWith(contentPaths.config.href)
46
+ (e) => !e.href.startsWith(contentPaths.config.url.href)
47
47
  );
48
48
  for (const entry of entries) {
49
49
  events.push(handleEvent({ name: "add", entry }, { logLevel: "warn" }));
@@ -263,7 +263,7 @@ async function writeContentFiles({
263
263
  fs.mkdirSync(contentPaths.cacheDir, { recursive: true });
264
264
  }
265
265
  let configPathRelativeToCacheDir = normalizePath(
266
- path.relative(contentPaths.cacheDir.pathname, contentPaths.config.pathname)
266
+ path.relative(contentPaths.cacheDir.pathname, contentPaths.config.url.pathname)
267
267
  );
268
268
  if (!isRelativePath(configPathRelativeToCacheDir))
269
269
  configPathRelativeToCacheDir = "./" + configPathRelativeToCacheDir;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import matter from 'gray-matter';
3
- import type fsMod from 'node:fs';
3
+ import fsMod from 'node:fs';
4
4
  import { ViteDevServer } from 'vite';
5
5
  import { z } from 'zod';
6
6
  import { AstroConfig, AstroSettings } from '../@types/astro.js';
@@ -103,7 +103,10 @@ export type ContentPaths = {
103
103
  cacheDir: URL;
104
104
  typesTemplate: URL;
105
105
  virtualModTemplate: URL;
106
- config: URL;
106
+ config: {
107
+ exists: boolean;
108
+ url: URL;
109
+ };
107
110
  };
108
- export declare function getContentPaths({ srcDir, root, }: Pick<AstroConfig, 'root' | 'srcDir'>): ContentPaths;
111
+ export declare function getContentPaths({ srcDir, root }: Pick<AstroConfig, 'root' | 'srcDir'>, fs?: typeof fsMod): ContentPaths;
109
112
  export {};
@@ -1,11 +1,11 @@
1
1
  import { slug as githubSlug } from "github-slugger";
2
2
  import matter from "gray-matter";
3
+ import fsMod from "node:fs";
3
4
  import path from "node:path";
4
5
  import { fileURLToPath, pathToFileURL } from "node:url";
5
6
  import { normalizePath } from "vite";
6
7
  import { z } from "zod";
7
8
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
8
- import { appendForwardSlash } from "../core/path.js";
9
9
  import { contentFileExts, CONTENT_TYPES_FILE } from "./consts.js";
10
10
  const collectionConfigParser = z.object({
11
11
  schema: z.any().optional()
@@ -104,22 +104,20 @@ function getEntryInfo({
104
104
  return res;
105
105
  }
106
106
  function getEntryType(entryPath, paths) {
107
- const { dir: rawDir, ext, base } = path.parse(entryPath);
108
- const dir = appendForwardSlash(pathToFileURL(rawDir).href);
109
- const fileUrl = new URL(base, dir);
110
- if (hasUnderscoreInPath(fileUrl) || isOnIgnoreList(fileUrl)) {
107
+ const { ext, base } = path.parse(entryPath);
108
+ const fileUrl = pathToFileURL(entryPath);
109
+ if (hasUnderscoreInPath(fileUrl) || isOnIgnoreList(base)) {
111
110
  return "ignored";
112
111
  } else if (contentFileExts.includes(ext)) {
113
112
  return "content";
114
- } else if (fileUrl.href === paths.config.href) {
113
+ } else if (fileUrl.href === paths.config.url.href) {
115
114
  return "config";
116
115
  } else {
117
116
  return "unsupported";
118
117
  }
119
118
  }
120
- function isOnIgnoreList(fileUrl) {
121
- const { base } = path.parse(fileURLToPath(fileUrl));
122
- return [".DS_Store"].includes(base);
119
+ function isOnIgnoreList(fileName) {
120
+ return [".DS_Store"].includes(fileName);
123
121
  }
124
122
  function hasUnderscoreInPath(fileUrl) {
125
123
  const parts = fileUrl.pathname.split("/");
@@ -172,13 +170,13 @@ async function loadContentConfig({
172
170
  settings,
173
171
  viteServer
174
172
  }) {
175
- const contentPaths = getContentPaths(settings.config);
173
+ const contentPaths = getContentPaths(settings.config, fs);
176
174
  let unparsedConfig;
177
- if (!fs.existsSync(contentPaths.config)) {
175
+ if (!contentPaths.config.exists) {
178
176
  return void 0;
179
177
  }
180
178
  try {
181
- const configPathname = fileURLToPath(contentPaths.config);
179
+ const configPathname = fileURLToPath(contentPaths.config.url);
182
180
  unparsedConfig = await viteServer.ssrLoadModule(configPathname);
183
181
  } catch (e) {
184
182
  throw e;
@@ -212,19 +210,28 @@ function contentObservable(initialCtx) {
212
210
  subscribe
213
211
  };
214
212
  }
215
- function getContentPaths({
216
- srcDir,
217
- root
218
- }) {
213
+ function getContentPaths({ srcDir, root }, fs = fsMod) {
214
+ const configStats = search(fs, srcDir);
219
215
  const templateDir = new URL("../../src/content/template/", import.meta.url);
220
216
  return {
221
217
  cacheDir: new URL(".astro/", root),
222
218
  contentDir: new URL("./content/", srcDir),
223
219
  typesTemplate: new URL("types.d.ts", templateDir),
224
220
  virtualModTemplate: new URL("virtual-mod.mjs", templateDir),
225
- config: new URL("./content/config.ts", srcDir)
221
+ config: configStats
226
222
  };
227
223
  }
224
+ function search(fs, srcDir) {
225
+ const paths = ["config.mjs", "config.js", "config.ts"].map(
226
+ (p) => new URL(`./content/${p}`, srcDir)
227
+ );
228
+ for (const file of paths) {
229
+ if (fs.existsSync(file)) {
230
+ return { exists: true, url: file };
231
+ }
232
+ }
233
+ return { exists: false, url: paths[0] };
234
+ }
228
235
  export {
229
236
  NoCollectionError,
230
237
  collectionConfigParser,
@@ -21,7 +21,7 @@ function astroContentImportPlugin({
21
21
  fs,
22
22
  settings
23
23
  }) {
24
- const contentPaths = getContentPaths(settings.config);
24
+ const contentPaths = getContentPaths(settings.config, fs);
25
25
  return {
26
26
  name: "astro:content-imports",
27
27
  async load(id) {
@@ -54,7 +54,7 @@ class AstroBuilder {
54
54
  { settings: this.settings, logging, mode: "build" }
55
55
  );
56
56
  await runHookConfigDone({ settings: this.settings, logging });
57
- const { sync } = await import("../../cli/sync/index.js");
57
+ const { sync } = await import("../sync/index.js");
58
58
  const syncRet = await sync(this.settings, { logging, fs });
59
59
  if (syncRet !== 0) {
60
60
  return process.exit(syncRet);
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.0.10";
1
+ const ASTRO_VERSION = "2.0.12";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -5,7 +5,7 @@ import * as msg from "../messages.js";
5
5
  import { startContainer } from "./container.js";
6
6
  import { createContainerWithAutomaticRestart } from "./restart.js";
7
7
  async function dev(settings, options) {
8
- var _a, _b;
8
+ var _a, _b, _c;
9
9
  const devStart = performance.now();
10
10
  await options.telemetry.record([]);
11
11
  const restart = await createContainerWithAutomaticRestart({
@@ -14,6 +14,7 @@ async function dev(settings, options) {
14
14
  beforeRestart: () => console.clear(),
15
15
  params: {
16
16
  settings,
17
+ root: (_a = options.flags) == null ? void 0 : _a.root,
17
18
  logging: options.logging,
18
19
  isRestart: options.isRestart
19
20
  }
@@ -30,11 +31,11 @@ async function dev(settings, options) {
30
31
  isRestart: options.isRestart
31
32
  })
32
33
  );
33
- const currentVersion = "2.0.10";
34
+ const currentVersion = "2.0.12";
34
35
  if (currentVersion.includes("-")) {
35
36
  warn(options.logging, null, msg.prerelease({ currentVersion }));
36
37
  }
37
- if (((_b = (_a = restart.container.viteConfig.server) == null ? void 0 : _a.fs) == null ? void 0 : _b.strict) === false) {
38
+ if (((_c = (_b = restart.container.viteConfig.server) == null ? void 0 : _b.fs) == null ? void 0 : _c.strict) === false) {
38
39
  warn(options.logging, null, msg.fsStrictWarning());
39
40
  }
40
41
  await attachContentServerListeners(restart.container);
@@ -47,7 +47,7 @@ function serverStart({
47
47
  base,
48
48
  isRestart = false
49
49
  }) {
50
- const version = "2.0.10";
50
+ const version = "2.0.12";
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.0.10"}`
236
+ `v${"2.0.12"}`
237
237
  )} ${headline}`
238
238
  );
239
239
  }
@@ -14,7 +14,7 @@ function createDevelopmentEnvironment(settings, logging, loader) {
14
14
  },
15
15
  mode,
16
16
  renderers: [],
17
- resolve: createResolve(loader),
17
+ resolve: createResolve(loader, settings.config.root),
18
18
  routeCache: new RouteCache(logging, mode),
19
19
  site: settings.config.site,
20
20
  ssr: settings.config.output === "server",
@@ -1,2 +1,2 @@
1
1
  import type { ModuleLoader } from '../../module-loader/index';
2
- export declare function createResolve(loader: ModuleLoader): (s: string) => Promise<string>;
2
+ export declare function createResolve(loader: ModuleLoader, root: URL): (s: string) => Promise<string>;
@@ -1,8 +1,8 @@
1
1
  import { resolveIdToUrl } from "../../util.js";
2
- function createResolve(loader) {
2
+ function createResolve(loader, root) {
3
3
  return async function(s) {
4
- const url = await resolveIdToUrl(loader, s);
5
- if (url.startsWith("/@fs") && url.endsWith(".jsx")) {
4
+ const url = await resolveIdToUrl(loader, s, root);
5
+ if (url.startsWith("/") && url.endsWith(".jsx")) {
6
6
  return url.slice(0, -4);
7
7
  } else {
8
8
  return url;
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ import type fsMod from 'node:fs';
3
+ import type { AstroSettings } from '../../@types/astro';
4
+ import { LogOptions } from '../logger/core.js';
5
+ type ProcessExit = 0 | 1;
6
+ export declare function syncCli(settings: AstroSettings, { logging, fs }: {
7
+ logging: LogOptions;
8
+ fs: typeof fsMod;
9
+ }): Promise<ProcessExit>;
10
+ export declare function sync(settings: AstroSettings, { logging, fs }: {
11
+ logging: LogOptions;
12
+ fs: typeof fsMod;
13
+ }): Promise<ProcessExit>;
14
+ export {};
@@ -3,11 +3,20 @@ import { performance } from "node:perf_hooks";
3
3
  import { createServer } from "vite";
4
4
  import { createContentTypesGenerator } from "../../content/index.js";
5
5
  import { globalContentConfigObserver } from "../../content/utils.js";
6
- import { getTimeStat } from "../../core/build/util.js";
7
- import { createVite } from "../../core/create-vite.js";
8
- import { AstroError, AstroErrorData } from "../../core/errors/index.js";
9
- import { info } from "../../core/logger/core.js";
6
+ import { runHookConfigSetup } from "../../integrations/index.js";
10
7
  import { setUpEnvTs } from "../../vite-plugin-inject-env-ts/index.js";
8
+ import { getTimeStat } from "../build/util.js";
9
+ import { createVite } from "../create-vite.js";
10
+ import { AstroError, AstroErrorData } from "../errors/index.js";
11
+ import { info } from "../logger/core.js";
12
+ async function syncCli(settings, { logging, fs }) {
13
+ const resolvedSettings = await runHookConfigSetup({
14
+ settings,
15
+ logging,
16
+ command: "build"
17
+ });
18
+ return sync(resolvedSettings, { logging, fs });
19
+ }
11
20
  async function sync(settings, { logging, fs }) {
12
21
  const timerStart = performance.now();
13
22
  const tempViteServer = await createServer(
@@ -51,5 +60,6 @@ async function sync(settings, { logging, fs }) {
51
60
  return 0;
52
61
  }
53
62
  export {
54
- sync
63
+ sync,
64
+ syncCli
55
65
  };
@@ -42,7 +42,7 @@ export declare function emoji(char: string, fallback: string): string;
42
42
  * Simulate Vite's resolve and import analysis so we can import the id as an URL
43
43
  * through a script tag or a dynamic import as-is.
44
44
  */
45
- export declare function resolveIdToUrl(loader: ModuleLoader, id: string): Promise<string>;
45
+ export declare function resolveIdToUrl(loader: ModuleLoader, id: string, root?: URL): Promise<string>;
46
46
  export declare function resolveJsToTs(filePath: string): string;
47
47
  /**
48
48
  * Resolve the hydration paths so that it can be imported in the client
package/dist/core/util.js CHANGED
@@ -117,7 +117,7 @@ function relativeToSrcDir(config, idOrUrl) {
117
117
  function emoji(char, fallback) {
118
118
  return process.platform !== "win32" ? char : fallback;
119
119
  }
120
- async function resolveIdToUrl(loader, id) {
120
+ async function resolveIdToUrl(loader, id, root) {
121
121
  let resultId = await loader.resolveId(id, void 0);
122
122
  if (!resultId && id.endsWith(".jsx")) {
123
123
  resultId = await loader.resolveId(id.slice(0, -4), void 0);
@@ -126,7 +126,12 @@ async function resolveIdToUrl(loader, id) {
126
126
  return VALID_ID_PREFIX + id;
127
127
  }
128
128
  if (path.isAbsolute(resultId)) {
129
- return "/@fs" + prependForwardSlash(resultId);
129
+ const normalizedRoot = root && normalizePath(fileURLToPath(root));
130
+ if (normalizedRoot && resultId.startsWith(normalizedRoot)) {
131
+ return resultId.slice(normalizedRoot.length - 1);
132
+ } else {
133
+ return "/@fs" + prependForwardSlash(resultId);
134
+ }
130
135
  }
131
136
  return VALID_ID_PREFIX + resultId;
132
137
  }
@@ -50,12 +50,19 @@ function stringifyChunk(result, chunk) {
50
50
  }
51
51
  break;
52
52
  }
53
- case ScopeFlags.Slot: {
53
+ case ScopeFlags.Slot:
54
+ case ScopeFlags.Slot | ScopeFlags.HeadBuffer: {
54
55
  if (hasScopeFlag(result, ScopeFlags.RenderSlot)) {
55
56
  return "";
56
57
  }
57
58
  break;
58
59
  }
60
+ case ScopeFlags.HeadBuffer: {
61
+ if (hasScopeFlag(result, ScopeFlags.JSX | ScopeFlags.HeadBuffer)) {
62
+ return "";
63
+ }
64
+ break;
65
+ }
59
66
  case ScopeFlags.RenderSlot | ScopeFlags.Astro:
60
67
  case ScopeFlags.RenderSlot | ScopeFlags.Astro | ScopeFlags.JSX:
61
68
  case ScopeFlags.RenderSlot | ScopeFlags.Astro | ScopeFlags.JSX | ScopeFlags.HeadBuffer: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "2.0.10",
3
+ "version": "2.0.12",
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",
@@ -1,8 +0,0 @@
1
- /// <reference types="node" />
2
- import type fsMod from 'node:fs';
3
- import type { AstroSettings } from '../../@types/astro';
4
- import { LogOptions } from '../../core/logger/core.js';
5
- export declare function sync(settings: AstroSettings, { logging, fs }: {
6
- logging: LogOptions;
7
- fs: typeof fsMod;
8
- }): Promise<0 | 1>;