astro 1.4.4 → 1.4.6

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 (35) hide show
  1. package/config.mjs +1 -43
  2. package/dist/@types/astro.d.ts +11 -2
  3. package/dist/config/index.d.ts +7 -0
  4. package/dist/config/index.js +48 -0
  5. package/dist/core/build/static-build.js +2 -1
  6. package/dist/core/compile/compile.d.ts +0 -1
  7. package/dist/core/compile/compile.js +22 -4
  8. package/dist/core/dev/index.js +4 -1
  9. package/dist/core/fs/index.d.ts +3 -0
  10. package/dist/core/fs/index.js +79 -0
  11. package/dist/core/messages.js +2 -2
  12. package/dist/core/path.d.ts +1 -0
  13. package/dist/core/path.js +4 -0
  14. package/dist/core/render/dev/index.js +5 -4
  15. package/dist/core/render/result.js +7 -1
  16. package/dist/core/render/route-cache.d.ts +3 -2
  17. package/dist/core/render/route-cache.js +3 -2
  18. package/dist/core/util.d.ts +1 -3
  19. package/dist/core/util.js +15 -19
  20. package/dist/jsx/babel.js +7 -6
  21. package/dist/runtime/server/astro-global.js +1 -1
  22. package/dist/runtime/server/jsx.js +2 -0
  23. package/dist/runtime/server/metadata.d.ts +2 -1
  24. package/dist/runtime/server/metadata.js +6 -6
  25. package/dist/runtime/server/render/component.d.ts +2 -1
  26. package/dist/runtime/server/render/component.js +10 -4
  27. package/dist/runtime/server/render/page.js +23 -23
  28. package/dist/runtime/server/render/util.js +2 -2
  29. package/dist/vite-plugin-astro/index.js +0 -3
  30. package/dist/vite-plugin-astro-postprocess/index.js +23 -1
  31. package/dist/vite-plugin-astro-server/index.js +1 -1
  32. package/dist/vite-plugin-markdown-legacy/index.js +0 -1
  33. package/package.json +2 -2
  34. package/dist/core/render/dev/resolve.d.ts +0 -1
  35. package/dist/core/render/dev/resolve.js +0 -11
package/config.mjs CHANGED
@@ -1,43 +1 @@
1
- export function defineConfig(config) {
2
- return config;
3
- }
4
-
5
- export function getViteConfig(inlineConfig) {
6
- // Return an async Vite config getter which exposes a resolved `mode` and `command`
7
- return async ({ mode, command }) => {
8
- // Vite `command` is `serve | build`, but Astro uses `dev | build`
9
- const cmd = command === 'serve' ? 'dev' : command;
10
-
11
- // Use dynamic import to avoid pulling in deps unless used
12
- const [
13
- { mergeConfig },
14
- { nodeLogDestination },
15
- { openConfig },
16
- { createVite },
17
- { runHookConfigSetup, runHookConfigDone },
18
- ] = await Promise.all([
19
- import('vite'),
20
- import('./dist/core/logger/node.js'),
21
- import('./dist/core/config.js'),
22
- import('./dist/core/create-vite.js'),
23
- import('./dist/integrations/index.js'),
24
- ]);
25
- const logging = {
26
- dest: nodeLogDestination,
27
- level: 'info',
28
- };
29
- const { astroConfig: config } = await openConfig({
30
- cmd,
31
- logging,
32
- });
33
- await runHookConfigSetup({ config, command: cmd });
34
- const viteConfig = await createVite(
35
- {
36
- mode,
37
- },
38
- { astroConfig: config, logging: logging, mode }
39
- );
40
- await runHookConfigDone({ config });
41
- return mergeConfig(viteConfig, inlineConfig);
42
- };
43
- }
1
+ export { defineConfig, getViteConfig } from './dist/config/index.js';
@@ -69,7 +69,7 @@ export interface BuildConfig {
69
69
  *
70
70
  * [Astro reference](https://docs.astro.build/reference/api-reference/#astro-global)
71
71
  */
72
- export interface AstroGlobal extends AstroGlobalPartial {
72
+ export interface AstroGlobal<Props extends Record<string, any> = Record<string, any>> extends AstroGlobalPartial {
73
73
  /**
74
74
  * Canonical URL of the current page.
75
75
  * @deprecated Use `Astro.url` instead.
@@ -125,7 +125,7 @@ export interface AstroGlobal extends AstroGlobalPartial {
125
125
  *
126
126
  * [Astro reference](https://docs.astro.build/en/core-concepts/astro-components/#component-props)
127
127
  */
128
- props: Record<string, number | string | any>;
128
+ props: Props;
129
129
  /** Information about the current request. This is a standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object
130
130
  *
131
131
  * For example, to get a URL object of the current URL, you can use:
@@ -391,6 +391,15 @@ export interface AstroUserConfig {
391
391
  * base: '/docs'
392
392
  * }
393
393
  * ```
394
+ *
395
+ * When using this option, you should mind that all of your imports will be affected. In this example, all of the imports including static resources and codes should add a prefix `/docs/`.
396
+ *
397
+ * For example, if you want to use a image in your Astro component, you need to change it from '/someimg.png' into '/docs/someimg.png'.
398
+ *
399
+ * ```astro
400
+ * <!-- <img src="/someimg.png"> is not correct. -->
401
+ * <img src="/docs/someimg.png">
402
+ * ```
394
403
  */
395
404
  base?: string;
396
405
  /**
@@ -0,0 +1,7 @@
1
+ import type { UserConfig } from 'vite';
2
+ import type { AstroUserConfig } from '../@types/astro';
3
+ export declare function defineConfig(config: AstroUserConfig): AstroUserConfig;
4
+ export declare function getViteConfig(inlineConfig: UserConfig): ({ mode, command }: {
5
+ mode: string;
6
+ command: 'serve' | 'build';
7
+ }) => Promise<Record<string, any>>;
@@ -0,0 +1,48 @@
1
+ function defineConfig(config) {
2
+ return config;
3
+ }
4
+ function getViteConfig(inlineConfig) {
5
+ return async ({ mode, command }) => {
6
+ const cmd = command === "serve" ? "dev" : command;
7
+ const [
8
+ { mergeConfig },
9
+ { nodeLogDestination },
10
+ { openConfig, createSettings, loadTSConfig },
11
+ { createVite },
12
+ { runHookConfigSetup, runHookConfigDone }
13
+ ] = await Promise.all([
14
+ import("vite"),
15
+ import("../core/logger/node.js"),
16
+ import("../core/config/index.js"),
17
+ import("../core/create-vite.js"),
18
+ import("../integrations/index.js")
19
+ ]);
20
+ const logging = {
21
+ dest: nodeLogDestination,
22
+ level: "info"
23
+ };
24
+ const { astroConfig: config } = await openConfig({
25
+ cmd,
26
+ logging
27
+ });
28
+ const initialTsConfig = loadTSConfig(inlineConfig.root);
29
+ const settings = createSettings({
30
+ config,
31
+ tsConfig: initialTsConfig == null ? void 0 : initialTsConfig.config,
32
+ tsConfigPath: initialTsConfig == null ? void 0 : initialTsConfig.path
33
+ });
34
+ await runHookConfigSetup({ settings, command: cmd, logging });
35
+ const viteConfig = await createVite(
36
+ {
37
+ mode
38
+ },
39
+ { settings, logging, mode }
40
+ );
41
+ await runHookConfigDone({ settings, logging });
42
+ return mergeConfig(viteConfig, inlineConfig);
43
+ };
44
+ }
45
+ export {
46
+ defineConfig,
47
+ getViteConfig
48
+ };
@@ -5,8 +5,9 @@ import path from "path";
5
5
  import { fileURLToPath } from "url";
6
6
  import * as vite from "vite";
7
7
  import { createBuildInternals } from "../../core/build/internal.js";
8
+ import { emptyDir, removeDir } from "../../core/fs/index.js";
8
9
  import { prependForwardSlash } from "../../core/path.js";
9
- import { emptyDir, isModeServerWithNoAdapter, removeDir } from "../../core/util.js";
10
+ import { isModeServerWithNoAdapter } from "../../core/util.js";
10
11
  import { runHookBuildSetup } from "../../integrations/index.js";
11
12
  import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
12
13
  import { info } from "../logger/core.js";
@@ -8,7 +8,6 @@ declare type CompileResult = TransformResult & {
8
8
  export interface CompileProps {
9
9
  config: AstroConfig;
10
10
  filename: string;
11
- moduleId: string;
12
11
  source: string;
13
12
  transformStyle: TransformStyle;
14
13
  }
@@ -1,13 +1,13 @@
1
+ import path from "path";
1
2
  import { transform } from "@astrojs/compiler";
2
3
  import { AstroErrorCodes } from "../errors.js";
3
- import { prependForwardSlash } from "../path.js";
4
- import { AggregateError, viteID } from "../util.js";
4
+ import { prependForwardSlash, removeLeadingForwardSlashWindows } from "../path.js";
5
+ import { AggregateError, resolveJsToTs, viteID } from "../util.js";
5
6
  import { createStylePreprocessor } from "./style.js";
6
7
  const configCache = /* @__PURE__ */ new WeakMap();
7
8
  async function compile({
8
9
  config,
9
10
  filename,
10
- moduleId,
11
11
  source,
12
12
  transformStyle
13
13
  }) {
@@ -15,7 +15,7 @@ async function compile({
15
15
  let cssDeps = /* @__PURE__ */ new Set();
16
16
  let cssTransformErrors = [];
17
17
  const transformResult = await transform(source, {
18
- pathname: `/@fs${prependForwardSlash(moduleId)}`,
18
+ pathname: prependForwardSlash(filename),
19
19
  projectRoot: config.root.toString(),
20
20
  site: (_a = config.site) == null ? void 0 : _a.toString(),
21
21
  sourcefile: filename,
@@ -54,6 +54,24 @@ async function compile({
54
54
  value: source
55
55
  }
56
56
  });
57
+ for (const c of compileResult.clientOnlyComponents) {
58
+ c.resolvedPath = removeLeadingForwardSlashWindows(c.resolvedPath);
59
+ if (c.specifier.endsWith(".jsx") && !c.resolvedPath.endsWith(".jsx")) {
60
+ c.resolvedPath += ".jsx";
61
+ }
62
+ if (path.isAbsolute(c.resolvedPath)) {
63
+ c.resolvedPath = resolveJsToTs(c.resolvedPath);
64
+ }
65
+ }
66
+ for (const c of compileResult.hydratedComponents) {
67
+ c.resolvedPath = removeLeadingForwardSlashWindows(c.resolvedPath);
68
+ if (c.specifier.endsWith(".jsx") && !c.resolvedPath.endsWith(".jsx")) {
69
+ c.resolvedPath += ".jsx";
70
+ }
71
+ if (path.isAbsolute(c.resolvedPath)) {
72
+ c.resolvedPath = resolveJsToTs(c.resolvedPath);
73
+ }
74
+ }
57
75
  return compileResult;
58
76
  }
59
77
  function isCached(config, filename) {
@@ -26,6 +26,9 @@ async function dev(settings, options) {
26
26
  server: { host },
27
27
  optimizeDeps: {
28
28
  include: rendererClientEntries
29
+ },
30
+ define: {
31
+ "import.meta.env.BASE_URL": settings.config.base ? `'${settings.config.base}'` : "undefined"
29
32
  }
30
33
  },
31
34
  { settings, logging: options.logging, mode: "dev" }
@@ -46,7 +49,7 @@ async function dev(settings, options) {
46
49
  isRestart
47
50
  })
48
51
  );
49
- const currentVersion = "1.4.4";
52
+ const currentVersion = "1.4.6";
50
53
  if (currentVersion.includes("-")) {
51
54
  warn(options.logging, null, msg.prerelease({ currentVersion }));
52
55
  }
@@ -0,0 +1,3 @@
1
+ /** An fs utility, similar to `rimraf` or `rm -rf` */
2
+ export declare function removeDir(_dir: URL): void;
3
+ export declare function emptyDir(_dir: URL, skip?: Set<string>): void;
@@ -0,0 +1,79 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ const isWindows = process.platform === "win32";
5
+ function removeDir(_dir) {
6
+ const dir = fileURLToPath(_dir);
7
+ fs.rmSync(dir, { recursive: true, force: true, maxRetries: 3 });
8
+ }
9
+ function emptyDir(_dir, skip) {
10
+ const dir = fileURLToPath(_dir);
11
+ if (!fs.existsSync(dir))
12
+ return void 0;
13
+ for (const file of fs.readdirSync(dir)) {
14
+ if (skip == null ? void 0 : skip.has(file)) {
15
+ continue;
16
+ }
17
+ const p = path.resolve(dir, file);
18
+ const rmOptions = { recursive: true, force: true, maxRetries: 3 };
19
+ try {
20
+ fs.rmSync(p, rmOptions);
21
+ } catch (er) {
22
+ if (er.code === "ENOENT") {
23
+ return;
24
+ }
25
+ if (er.code === "EPERM" && isWindows) {
26
+ fixWinEPERMSync(p, rmOptions, er);
27
+ }
28
+ }
29
+ }
30
+ }
31
+ /**
32
+ * https://github.com/isaacs/rimraf/blob/8c10fb8d685d5cc35708e0ffc4dac9ec5dd5b444/rimraf.js#L183
33
+ * @license ISC
34
+ * The ISC License
35
+ *
36
+ * Copyright (c) Isaac Z. Schlueter and Contributors
37
+ *
38
+ * Permission to use, copy, modify, and/or distribute this software for any
39
+ purpose with or without fee is hereby granted, provided that the above
40
+ copyright notice and this permission notice appear in all copies.
41
+ *
42
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
43
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
44
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
45
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
47
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
48
+ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
49
+ */
50
+ const fixWinEPERMSync = (p, options, er) => {
51
+ try {
52
+ fs.chmodSync(p, 438);
53
+ } catch (er2) {
54
+ if (er2.code === "ENOENT") {
55
+ return;
56
+ } else {
57
+ throw er;
58
+ }
59
+ }
60
+ let stats;
61
+ try {
62
+ stats = fs.statSync(p);
63
+ } catch (er3) {
64
+ if (er3.code === "ENOENT") {
65
+ return;
66
+ } else {
67
+ throw er;
68
+ }
69
+ }
70
+ if (stats.isDirectory()) {
71
+ fs.rmdirSync(p, options);
72
+ } else {
73
+ fs.unlinkSync(p);
74
+ }
75
+ };
76
+ export {
77
+ emptyDir,
78
+ removeDir
79
+ };
@@ -47,7 +47,7 @@ function serverStart({
47
47
  site,
48
48
  isRestart = false
49
49
  }) {
50
- const version = "1.4.4";
50
+ const version = "1.4.6";
51
51
  const rootPath = site ? site.pathname : "/";
52
52
  const localPrefix = `${dim("\u2503")} Local `;
53
53
  const networkPrefix = `${dim("\u2503")} Network `;
@@ -250,7 +250,7 @@ function printHelp({
250
250
  message.push(
251
251
  linebreak(),
252
252
  ` ${bgGreen(black(` ${commandName} `))} ${green(
253
- `v${"1.4.4"}`
253
+ `v${"1.4.6"}`
254
254
  )} ${headline}`
255
255
  );
256
256
  }
@@ -3,6 +3,7 @@ export declare function appendForwardSlash(path: string): string;
3
3
  export declare function prependForwardSlash(path: string): string;
4
4
  export declare function removeTrailingForwardSlash(path: string): string;
5
5
  export declare function removeLeadingForwardSlash(path: string): string;
6
+ export declare function removeLeadingForwardSlashWindows(path: string): string;
6
7
  export declare function trimSlashes(path: string): string;
7
8
  export declare function startsWithForwardSlash(path: string): boolean;
8
9
  export declare function startsWithDotDotSlash(path: string): boolean;
package/dist/core/path.js CHANGED
@@ -13,6 +13,9 @@ function removeTrailingForwardSlash(path) {
13
13
  function removeLeadingForwardSlash(path) {
14
14
  return path.startsWith("/") ? path.substring(1) : path;
15
15
  }
16
+ function removeLeadingForwardSlashWindows(path) {
17
+ return path.startsWith("/") && path[2] === ":" ? path.substring(1) : path;
18
+ }
16
19
  function trimSlashes(path) {
17
20
  return path.replace(/^\/|\/$/g, "");
18
21
  }
@@ -51,6 +54,7 @@ export {
51
54
  prependForwardSlash,
52
55
  removeFileExtension,
53
56
  removeLeadingForwardSlash,
57
+ removeLeadingForwardSlashWindows,
54
58
  removeTrailingForwardSlash,
55
59
  startsWithDotDotSlash,
56
60
  startsWithDotSlash,
@@ -4,7 +4,6 @@ import { isPage, resolveIdToUrl } from "../../util.js";
4
4
  import { render as coreRender } from "../core.js";
5
5
  import { collectMdMetadata } from "../util.js";
6
6
  import { getStylesForURL } from "./css.js";
7
- import { resolveClientDevPath } from "./resolve.js";
8
7
  import { getScriptsForURL } from "./scripts.js";
9
8
  const svelteStylesRE = /svelte\?svelte&type=style/;
10
9
  async function loadRenderer(viteServer, renderer) {
@@ -111,10 +110,12 @@ async function render(renderers, mod, ssrOpts) {
111
110
  pathname,
112
111
  scripts,
113
112
  async resolve(s) {
114
- if (s.startsWith("/@fs")) {
115
- return resolveClientDevPath(s);
113
+ const url = await resolveIdToUrl(viteServer, s);
114
+ if (url.startsWith("/@fs") && url.endsWith(".jsx")) {
115
+ return url.slice(0, -4);
116
+ } else {
117
+ return url;
116
118
  }
117
- return await resolveIdToUrl(viteServer, s);
118
119
  },
119
120
  renderers,
120
121
  request,
@@ -19,6 +19,7 @@ var __privateSet = (obj, member, value, setter) => {
19
19
  var _cache, _result, _slots, _loggingOpts;
20
20
  import { bold } from "kleur/colors";
21
21
  import { renderSlot } from "../../runtime/server/index.js";
22
+ import { renderJSX } from "../../runtime/server/jsx.js";
22
23
  import { AstroCookies } from "../cookies/index.js";
23
24
  import { warn } from "../logger/core.js";
24
25
  import { isScriptRequest } from "./script.js";
@@ -80,7 +81,6 @@ Please update the name of this slot.`
80
81
  return void 0;
81
82
  if (!cacheable) {
82
83
  const component = await __privateGet(this, _slots)[name]();
83
- const expression = getFunctionExpression(component);
84
84
  if (!Array.isArray(args)) {
85
85
  warn(
86
86
  __privateGet(this, _loggingOpts),
@@ -88,12 +88,18 @@ Please update the name of this slot.`
88
88
  `Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])`
89
89
  );
90
90
  } else {
91
+ const expression = getFunctionExpression(component);
91
92
  if (expression) {
92
93
  const slot = expression(...args);
93
94
  return await renderSlot(__privateGet(this, _result), slot).then(
94
95
  (res) => res != null ? String(res) : res
95
96
  );
96
97
  }
98
+ if (typeof component === "function") {
99
+ return await renderJSX(__privateGet(this, _result), component(...args)).then(
100
+ (res) => res != null ? String(res) : res
101
+ );
102
+ }
97
103
  }
98
104
  }
99
105
  const content = await renderSlot(__privateGet(this, _result), __privateGet(this, _slots)[name]).then(
@@ -1,4 +1,4 @@
1
- import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResultKeyed, Params, RouteData } from '../../@types/astro';
1
+ import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResultKeyed, Params, RouteData, RuntimeMode } from '../../@types/astro';
2
2
  import { LogOptions } from '../logger/core.js';
3
3
  interface CallGetStaticPathsOptions {
4
4
  mod: ComponentInstance;
@@ -19,7 +19,8 @@ export interface RouteCacheEntry {
19
19
  export declare class RouteCache {
20
20
  private logging;
21
21
  private cache;
22
- constructor(logging: LogOptions);
22
+ private mode;
23
+ constructor(logging: LogOptions, mode?: RuntimeMode);
23
24
  /** Clear the cache. */
24
25
  clearAll(): void;
25
26
  set(route: RouteData, entry: RouteCacheEntry): void;
@@ -39,15 +39,16 @@ async function callGetStaticPaths({
39
39
  };
40
40
  }
41
41
  class RouteCache {
42
- constructor(logging) {
42
+ constructor(logging, mode = "production") {
43
43
  this.cache = {};
44
44
  this.logging = logging;
45
+ this.mode = mode;
45
46
  }
46
47
  clearAll() {
47
48
  this.cache = {};
48
49
  }
49
50
  set(route, entry) {
50
- if (this.cache[route.component]) {
51
+ if (this.mode === "production" && this.cache[route.component]) {
51
52
  warn(
52
53
  this.logging,
53
54
  "routeCache",
@@ -33,9 +33,6 @@ export declare function resolveDependency(dep: string, projectRoot: URL): string
33
33
  export declare function viteID(filePath: URL): string;
34
34
  export declare const VALID_ID_PREFIX = "/@id/";
35
35
  export declare function unwrapId(id: string): string;
36
- /** An fs utility, similar to `rimraf` or `rm -rf` */
37
- export declare function removeDir(_dir: URL): void;
38
- export declare function emptyDir(_dir: URL, skip?: Set<string>): void;
39
36
  export declare function resolvePages(config: AstroConfig): URL;
40
37
  export declare function isPage(file: URL, settings: AstroSettings): boolean;
41
38
  export declare function isModeServerWithNoAdapter(settings: AstroSettings): boolean;
@@ -47,6 +44,7 @@ export declare function getLocalAddress(serverAddress: string, host: string | bo
47
44
  * through a script tag or a dynamic import as-is.
48
45
  */
49
46
  export declare function resolveIdToUrl(viteServer: ViteDevServer, id: string): Promise<string>;
47
+ export declare function resolveJsToTs(filePath: string): string;
50
48
  export declare const AggregateError: AggregateErrorConstructor | {
51
49
  new (errors: Iterable<any>, message?: string | undefined): {
52
50
  errors: Array<any>;
package/dist/core/util.js CHANGED
@@ -5,7 +5,7 @@ import resolve from "resolve";
5
5
  import slash from "slash";
6
6
  import { fileURLToPath, pathToFileURL } from "url";
7
7
  import { prependForwardSlash, removeTrailingForwardSlash } from "./path.js";
8
- const ASTRO_VERSION = "1.4.4";
8
+ const ASTRO_VERSION = "1.4.6";
9
9
  function isObject(value) {
10
10
  return typeof value === "object" && value != null;
11
11
  }
@@ -93,21 +93,6 @@ const VALID_ID_PREFIX = `/@id/`;
93
93
  function unwrapId(id) {
94
94
  return id.startsWith(VALID_ID_PREFIX) ? id.slice(VALID_ID_PREFIX.length) : id;
95
95
  }
96
- function removeDir(_dir) {
97
- const dir = fileURLToPath(_dir);
98
- fs.rmSync(dir, { recursive: true, force: true, maxRetries: 3 });
99
- }
100
- function emptyDir(_dir, skip) {
101
- const dir = fileURLToPath(_dir);
102
- if (!fs.existsSync(dir))
103
- return void 0;
104
- for (const file of fs.readdirSync(dir)) {
105
- if (skip == null ? void 0 : skip.has(file)) {
106
- continue;
107
- }
108
- fs.rmSync(path.resolve(dir, file), { recursive: true, force: true, maxRetries: 3 });
109
- }
110
- }
111
96
  function resolvePages(config) {
112
97
  return new URL("./pages", config.srcDir);
113
98
  }
@@ -161,7 +146,10 @@ function getLocalAddress(serverAddress, host) {
161
146
  }
162
147
  }
163
148
  async function resolveIdToUrl(viteServer, id) {
164
- const result = await viteServer.pluginContainer.resolveId(id);
149
+ let result = await viteServer.pluginContainer.resolveId(id, void 0);
150
+ if (!result && id.endsWith(".jsx")) {
151
+ result = await viteServer.pluginContainer.resolveId(id.slice(0, -4), void 0);
152
+ }
165
153
  if (!result) {
166
154
  return VALID_ID_PREFIX + id;
167
155
  }
@@ -170,6 +158,15 @@ async function resolveIdToUrl(viteServer, id) {
170
158
  }
171
159
  return VALID_ID_PREFIX + result.id;
172
160
  }
161
+ function resolveJsToTs(filePath) {
162
+ if (filePath.endsWith(".jsx") && !fs.existsSync(filePath)) {
163
+ const tryPath = filePath.slice(0, -4) + ".tsx";
164
+ if (fs.existsSync(tryPath)) {
165
+ return tryPath;
166
+ }
167
+ }
168
+ return filePath;
169
+ }
173
170
  const AggregateError = typeof globalThis.AggregateError !== "undefined" ? globalThis.AggregateError : class extends Error {
174
171
  constructor(errors, message) {
175
172
  super(message);
@@ -185,7 +182,6 @@ export {
185
182
  codeFrame,
186
183
  createSafeError,
187
184
  emoji,
188
- emptyDir,
189
185
  getLocalAddress,
190
186
  getOutputFilename,
191
187
  isModeServerWithNoAdapter,
@@ -194,9 +190,9 @@ export {
194
190
  padMultilineString,
195
191
  parseNpmName,
196
192
  relativeToSrcDir,
197
- removeDir,
198
193
  resolveDependency,
199
194
  resolveIdToUrl,
195
+ resolveJsToTs,
200
196
  resolvePages,
201
197
  unwrapId,
202
198
  viteID
package/dist/jsx/babel.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as t from "@babel/types";
2
- import { pathToFileURL } from "node:url";
3
- import { resolveClientDevPath } from "../core/render/dev/resolve.js";
2
+ import npath from "path";
3
+ import { normalizePath } from "vite";
4
+ import { resolveJsToTs } from "../core/util.js";
4
5
  import { HydrationDirectiveProps } from "../runtime/server/hydration.js";
5
6
  const ClientOnlyPlaceholder = "astro-client-only";
6
7
  function isComponent(tagName) {
@@ -195,8 +196,8 @@ function astroJSX() {
195
196
  if (meta) {
196
197
  let resolvedPath;
197
198
  if (meta.path.startsWith(".")) {
198
- const fileURL = pathToFileURL(state.filename);
199
- resolvedPath = resolveClientDevPath(`/@fs${new URL(meta.path, fileURL).pathname}`);
199
+ resolvedPath = normalizePath(npath.resolve(npath.dirname(state.filename), meta.path));
200
+ resolvedPath = resolveJsToTs(resolvedPath);
200
201
  } else {
201
202
  resolvedPath = meta.path;
202
203
  }
@@ -271,8 +272,8 @@ function astroJSX() {
271
272
  }
272
273
  let resolvedPath;
273
274
  if (meta.path.startsWith(".")) {
274
- const fileURL = pathToFileURL(state.filename);
275
- resolvedPath = resolveClientDevPath(`/@fs${new URL(meta.path, fileURL).pathname}`);
275
+ resolvedPath = normalizePath(npath.resolve(npath.dirname(state.filename), meta.path));
276
+ resolvedPath = resolveJsToTs(resolvedPath);
276
277
  } else {
277
278
  resolvedPath = meta.path;
278
279
  }
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "1.4.4";
1
+ const ASTRO_VERSION = "1.4.6";
2
2
  function createDeprecatedFetchContentFn() {
3
3
  return () => {
4
4
  throw new Error("Deprecated: Astro.fetchContent() has been replaced with Astro.glob().");
@@ -22,6 +22,8 @@ async function renderJSX(result, vnode) {
22
22
  return vnode;
23
23
  case typeof vnode === "string":
24
24
  return markHTMLString(escapeHTML(vnode));
25
+ case typeof vnode === "function":
26
+ return vnode;
25
27
  case (!vnode && vnode !== 0):
26
28
  return "";
27
29
  case Array.isArray(vnode):
@@ -10,12 +10,13 @@ interface CreateMetadataOptions {
10
10
  hoisted: any[];
11
11
  }
12
12
  export declare class Metadata {
13
- mockURL: URL;
13
+ filePath: string;
14
14
  modules: ModuleInfo[];
15
15
  hoisted: any[];
16
16
  hydratedComponents: any[];
17
17
  clientOnlyComponents: any[];
18
18
  hydrationDirectives: Set<string>;
19
+ private mockURL;
19
20
  private metadataCache;
20
21
  constructor(filePathname: string, opts: CreateMetadataOptions);
21
22
  resolvePath(specifier: string): string;
@@ -1,3 +1,4 @@
1
+ import { removeLeadingForwardSlashWindows } from "../../core/path.js";
1
2
  class Metadata {
2
3
  constructor(filePathname, opts) {
3
4
  this.modules = opts.modules;
@@ -5,18 +6,17 @@ class Metadata {
5
6
  this.hydratedComponents = opts.hydratedComponents;
6
7
  this.clientOnlyComponents = opts.clientOnlyComponents;
7
8
  this.hydrationDirectives = opts.hydrationDirectives;
9
+ this.filePath = removeLeadingForwardSlashWindows(filePathname);
8
10
  this.mockURL = new URL(filePathname, "http://example.com");
9
11
  this.metadataCache = /* @__PURE__ */ new Map();
10
12
  }
11
13
  resolvePath(specifier) {
12
14
  if (specifier.startsWith(".")) {
13
- const resolved = new URL(specifier, this.mockURL).pathname;
14
- if (resolved.startsWith("/@fs") && resolved.endsWith(".jsx")) {
15
- return resolved.slice(0, resolved.length - 4);
16
- }
17
- return resolved;
15
+ const url = new URL(specifier, this.mockURL);
16
+ return removeLeadingForwardSlashWindows(decodeURI(url.pathname));
17
+ } else {
18
+ return specifier;
18
19
  }
19
- return specifier;
20
20
  }
21
21
  getPath(Component) {
22
22
  const metadata = this.getComponentMetadata(Component);
@@ -1,4 +1,5 @@
1
1
  import type { SSRResult } from '../../../@types/astro';
2
2
  import type { RenderInstruction } from './types.js';
3
3
  import { HTMLBytes } from '../escape.js';
4
- export declare function renderComponent(result: SSRResult, displayName: string, Component: unknown, _props: Record<string | number, any>, slots?: any): Promise<string | AsyncIterable<string | HTMLBytes | RenderInstruction>>;
4
+ export declare type ComponentIterable = AsyncIterable<string | HTMLBytes | RenderInstruction>;
5
+ export declare function renderComponent(result: SSRResult, displayName: string, Component: unknown, _props: Record<string | number, any>, slots?: any): Promise<ComponentIterable>;
@@ -205,10 +205,16 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
205
205
  }
206
206
  }
207
207
  if (!hydration) {
208
- if (isPage || (renderer == null ? void 0 : renderer.name) === "astro:jsx") {
209
- return html;
210
- }
211
- return markHTMLString(html.replace(/\<\/?astro-slot\>/g, ""));
208
+ return async function* () {
209
+ if (slotInstructions) {
210
+ yield* slotInstructions;
211
+ }
212
+ if (isPage || (renderer == null ? void 0 : renderer.name) === "astro:jsx") {
213
+ yield html;
214
+ } else {
215
+ yield markHTMLString(html.replace(/\<\/?astro-slot\>/g, ""));
216
+ }
217
+ }();
212
218
  }
213
219
  const astroId = shorthash(
214
220
  `<!--${metadata.componentExport.value}:${metadata.componentUrl}-->
@@ -8,6 +8,24 @@ const needsHeadRenderingSymbol = Symbol.for("astro.needsHeadRendering");
8
8
  function nonAstroPageNeedsHeadInjection(pageComponent) {
9
9
  return needsHeadRenderingSymbol in pageComponent && !!pageComponent[needsHeadRenderingSymbol];
10
10
  }
11
+ async function iterableToHTMLBytes(result, iterable, onDocTypeInjection) {
12
+ const parts = new HTMLParts();
13
+ let i = 0;
14
+ for await (const chunk of iterable) {
15
+ if (isHTMLString(chunk)) {
16
+ if (i === 0) {
17
+ if (!/<!doctype html/i.test(String(chunk))) {
18
+ parts.append("<!DOCTYPE html>\n", result);
19
+ if (onDocTypeInjection) {
20
+ await onDocTypeInjection(parts);
21
+ }
22
+ }
23
+ }
24
+ }
25
+ parts.append(chunk, result);
26
+ }
27
+ return parts.toArrayBuffer();
28
+ }
11
29
  async function renderPage(result, componentFactory, props, children, streaming) {
12
30
  if (!isAstroComponentFactory(componentFactory)) {
13
31
  const pageProps = { ...props ?? {}, "server:root": true };
@@ -18,18 +36,13 @@ async function renderPage(result, componentFactory, props, children, streaming)
18
36
  pageProps,
19
37
  null
20
38
  );
21
- let html = output.toString();
22
- if (!/<!doctype html/i.test(html)) {
23
- let rest = html;
24
- html = `<!DOCTYPE html>`;
39
+ const bytes = await iterableToHTMLBytes(result, output, async (parts) => {
25
40
  if (nonAstroPageNeedsHeadInjection(componentFactory)) {
26
41
  for await (let chunk of maybeRenderHead(result)) {
27
- html += chunk;
42
+ parts.append(chunk, result);
28
43
  }
29
44
  }
30
- html += rest;
31
- }
32
- const bytes = encoder.encode(html);
45
+ });
33
46
  return new Response(bytes, {
34
47
  headers: new Headers([
35
48
  ["Content-Type", "text/html; charset=utf-8"],
@@ -57,7 +70,7 @@ async function renderPage(result, componentFactory, props, children, streaming)
57
70
  }
58
71
  }
59
72
  }
60
- let bytes = chunkToByteArray(result, chunk);
73
+ const bytes = chunkToByteArray(result, chunk);
61
74
  controller.enqueue(bytes);
62
75
  i++;
63
76
  }
@@ -70,20 +83,7 @@ async function renderPage(result, componentFactory, props, children, streaming)
70
83
  }
71
84
  });
72
85
  } else {
73
- let parts = new HTMLParts();
74
- let i = 0;
75
- for await (const chunk of iterable) {
76
- if (isHTMLString(chunk)) {
77
- if (i === 0) {
78
- if (!/<!doctype html/i.test(String(chunk))) {
79
- parts.append("<!DOCTYPE html>\n", result);
80
- }
81
- }
82
- }
83
- parts.append(chunk, result);
84
- i++;
85
- }
86
- body = parts.toArrayBuffer();
86
+ body = await iterableToHTMLBytes(result, iterable);
87
87
  headers.set("Content-Length", body.byteLength.toString());
88
88
  }
89
89
  let response = createResponse(body, { ...init, headers });
@@ -44,14 +44,14 @@ Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the
44
44
  return "";
45
45
  }
46
46
  if (key === "class:list") {
47
- const listValue = toAttributeString(serializeListValue(value));
47
+ const listValue = toAttributeString(serializeListValue(value), shouldEscape);
48
48
  if (listValue === "") {
49
49
  return "";
50
50
  }
51
51
  return markHTMLString(` ${key.slice(0, -5)}="${listValue}"`);
52
52
  }
53
53
  if (key === "style" && !(value instanceof HTMLString) && typeof value === "object") {
54
- return markHTMLString(` ${key}="${toStyleString(value)}"`);
54
+ return markHTMLString(` ${key}="${toAttributeString(toStyleString(value), shouldEscape)}"`);
55
55
  }
56
56
  if (key === "className") {
57
57
  return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`);
@@ -94,7 +94,6 @@ function astro({ settings, logging }) {
94
94
  const compileProps = {
95
95
  config,
96
96
  filename,
97
- moduleId: id,
98
97
  source,
99
98
  transformStyle: createTransformStyles(styleTransformer, filename, Boolean(opts == null ? void 0 : opts.ssr), this)
100
99
  };
@@ -183,7 +182,6 @@ File: ${filename}`
183
182
  const compileProps = {
184
183
  config,
185
184
  filename,
186
- moduleId: id,
187
185
  source,
188
186
  transformStyle: createTransformStyles(styleTransformer, filename, Boolean(opts == null ? void 0 : opts.ssr), this)
189
187
  };
@@ -282,7 +280,6 @@ ${source}
282
280
  const compileProps = {
283
281
  config,
284
282
  filename: context.file,
285
- moduleId: context.file,
286
283
  source: await context.read(),
287
284
  transformStyle: createTransformStyles(styleTransformer, context.file, true)
288
285
  };
@@ -1,6 +1,10 @@
1
1
  import { parse as babelParser } from "@babel/parser";
2
+ import npath from "path";
2
3
  import { parse, print, types, visit } from "recast";
4
+ import { removeLeadingForwardSlashWindows } from "../core/path.js";
5
+ import { resolveJsToTs } from "../core/util.js";
3
6
  const ASTRO_GLOB_REGEX = /Astro2?\s*\.\s*glob\s*\(/;
7
+ const CLIENT_COMPONENT_PATH_REGEX = /['"]client:component-path['"]:/;
4
8
  const validAstroGlobalNames = /* @__PURE__ */ new Set(["Astro", "Astro2"]);
5
9
  function astro(_opts) {
6
10
  return {
@@ -9,7 +13,7 @@ function astro(_opts) {
9
13
  if (!id.endsWith(".astro") && !id.endsWith(".md")) {
10
14
  return null;
11
15
  }
12
- if (!ASTRO_GLOB_REGEX.test(code)) {
16
+ if (!ASTRO_GLOB_REGEX.test(code) && !CLIENT_COMPONENT_PATH_REGEX.test(code)) {
13
17
  return null;
14
18
  }
15
19
  const ast = parse(code, {
@@ -45,6 +49,24 @@ function astro(_opts) {
45
49
  }
46
50
  );
47
51
  return false;
52
+ },
53
+ visitObjectProperty: function(path) {
54
+ if (!types.namedTypes.StringLiteral.check(path.node.key) || path.node.key.value !== "client:component-path" || !types.namedTypes.StringLiteral.check(path.node.value)) {
55
+ this.traverse(path);
56
+ return;
57
+ }
58
+ const valuePath = path.get("value");
59
+ let value = valuePath.value.value;
60
+ value = removeLeadingForwardSlashWindows(value);
61
+ if (code.includes(npath.basename(value) + ".jsx")) {
62
+ value += ".jsx";
63
+ }
64
+ value = resolveJsToTs(value);
65
+ valuePath.replace({
66
+ type: "StringLiteral",
67
+ value
68
+ });
69
+ return false;
48
70
  }
49
71
  });
50
72
  const result = print(ast);
@@ -315,7 +315,7 @@ function createPlugin({ settings, logging }) {
315
315
  return {
316
316
  name: "astro:server",
317
317
  configureServer(viteServer) {
318
- let routeCache = new RouteCache(logging);
318
+ let routeCache = new RouteCache(logging, "development");
319
319
  let manifest = createRouteManifest({ settings }, logging);
320
320
  function rebuildManifest(needsManifestRebuild, file) {
321
321
  routeCache.clearAll();
@@ -164,7 +164,6 @@ ${astroResult}
164
164
  const compileProps = {
165
165
  config,
166
166
  filename,
167
- moduleId: id,
168
167
  source: astroResult,
169
168
  transformStyle: createTransformStyles(
170
169
  styleTransformer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
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",
@@ -82,7 +82,7 @@
82
82
  "vendor"
83
83
  ],
84
84
  "dependencies": {
85
- "@astrojs/compiler": "^0.25.0",
85
+ "@astrojs/compiler": "^0.26.0",
86
86
  "@astrojs/language-server": "^0.26.2",
87
87
  "@astrojs/markdown-remark": "^1.1.3",
88
88
  "@astrojs/telemetry": "^1.0.1",
@@ -1 +0,0 @@
1
- export declare function resolveClientDevPath(id: string): string;
@@ -1,11 +0,0 @@
1
- function resolveClientDevPath(id) {
2
- if (id.startsWith("/@fs")) {
3
- if (id.endsWith(".jsx")) {
4
- return id.slice(0, id.length - 4);
5
- }
6
- }
7
- return id;
8
- }
9
- export {
10
- resolveClientDevPath
11
- };