astro 1.4.3 → 1.4.5

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.
@@ -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
  /**
@@ -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.3";
52
+ const currentVersion = "1.4.5";
50
53
  if (currentVersion.includes("-")) {
51
54
  warn(options.logging, null, msg.prerelease({ currentVersion }));
52
55
  }
@@ -47,7 +47,7 @@ function serverStart({
47
47
  site,
48
48
  isRestart = false
49
49
  }) {
50
- const version = "1.4.3";
50
+ const version = "1.4.5";
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.3"}`
253
+ `v${"1.4.5"}`
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",
@@ -47,6 +47,7 @@ export declare function getLocalAddress(serverAddress: string, host: string | bo
47
47
  * through a script tag or a dynamic import as-is.
48
48
  */
49
49
  export declare function resolveIdToUrl(viteServer: ViteDevServer, id: string): Promise<string>;
50
+ export declare function resolveJsToTs(filePath: string): string;
50
51
  export declare const AggregateError: AggregateErrorConstructor | {
51
52
  new (errors: Iterable<any>, message?: string | undefined): {
52
53
  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.3";
8
+ const ASTRO_VERSION = "1.4.5";
9
9
  function isObject(value) {
10
10
  return typeof value === "object" && value != null;
11
11
  }
@@ -161,7 +161,10 @@ function getLocalAddress(serverAddress, host) {
161
161
  }
162
162
  }
163
163
  async function resolveIdToUrl(viteServer, id) {
164
- const result = await viteServer.pluginContainer.resolveId(id);
164
+ let result = await viteServer.pluginContainer.resolveId(id, void 0);
165
+ if (!result && id.endsWith(".jsx")) {
166
+ result = await viteServer.pluginContainer.resolveId(id.slice(0, -4), void 0);
167
+ }
165
168
  if (!result) {
166
169
  return VALID_ID_PREFIX + id;
167
170
  }
@@ -170,6 +173,15 @@ async function resolveIdToUrl(viteServer, id) {
170
173
  }
171
174
  return VALID_ID_PREFIX + result.id;
172
175
  }
176
+ function resolveJsToTs(filePath) {
177
+ if (filePath.endsWith(".jsx") && !fs.existsSync(filePath)) {
178
+ const tryPath = filePath.slice(0, -4) + ".tsx";
179
+ if (fs.existsSync(tryPath)) {
180
+ return tryPath;
181
+ }
182
+ }
183
+ return filePath;
184
+ }
173
185
  const AggregateError = typeof globalThis.AggregateError !== "undefined" ? globalThis.AggregateError : class extends Error {
174
186
  constructor(errors, message) {
175
187
  super(message);
@@ -197,6 +209,7 @@ export {
197
209
  removeDir,
198
210
  resolveDependency,
199
211
  resolveIdToUrl,
212
+ resolveJsToTs,
200
213
  resolvePages,
201
214
  unwrapId,
202
215
  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.3";
1
+ const ASTRO_VERSION = "1.4.5";
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,4 @@
1
- import { escapeHTML, HTMLString, markHTMLString } from "../escape.js";
1
+ import { escapeHTML, isHTMLString, markHTMLString } from "../escape.js";
2
2
  import { AstroComponent, renderAstroComponent } from "./astro.js";
3
3
  import { SlotString } from "./slot.js";
4
4
  async function* renderChild(child) {
@@ -8,7 +8,7 @@ async function* renderChild(child) {
8
8
  yield* child.instructions;
9
9
  }
10
10
  yield child;
11
- } else if (child instanceof HTMLString) {
11
+ } else if (isHTMLString(child)) {
12
12
  yield child;
13
13
  } else if (Array.isArray(child)) {
14
14
  for (const value of child) {
@@ -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.3",
3
+ "version": "1.4.5",
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
- };