diff --git a/.changeset/long-starfishes-raise.md b/.changeset/long-starfishes-raise.md
new file mode 100644
index 000000000000..e081aedbe839
--- /dev/null
+++ b/.changeset/long-starfishes-raise.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix middleware for API endpoints that use `Response`, and log a warning for endpoints that don't use `Response`.
diff --git a/.changeset/pretty-planets-wink.md b/.changeset/pretty-planets-wink.md
new file mode 100644
index 000000000000..23208f833dab
--- /dev/null
+++ b/.changeset/pretty-planets-wink.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/vercel': minor
+---
+
+Add `edge-light` and `worker` import condition for worker bundling
diff --git a/.changeset/tall-eyes-vanish.md b/.changeset/tall-eyes-vanish.md
new file mode 100644
index 000000000000..06b7f62696a2
--- /dev/null
+++ b/.changeset/tall-eyes-vanish.md
@@ -0,0 +1,51 @@
+---
+'astro': minor
+---
+
+Integrations can add new `client:` directives through the `astro:config:setup` hook's `addClientDirective()` API. To enable this API, the user needs to set `experimental.customClientDirectives` to `true` in their config.
+
+```js
+import { defineConfig } from 'astro/config';
+import onClickDirective from 'astro-click-directive';
+
+export default defineConfig({
+ integrations: [onClickDirective()],
+ experimental: {
+ customClientDirectives: true
+ }
+});
+```
+
+```js
+export default function onClickDirective() {
+ return {
+ hooks: {
+ 'astro:config:setup': ({ addClientDirective }) => {
+ addClientDirective({
+ name: 'click',
+ entrypoint: 'astro-click-directive/click.js'
+ });
+ },
+ }
+ }
+}
+```
+
+```astro
+
+```
+
+The client directive file (e.g. `astro-click-directive/click.js`) should export a function of type `ClientDirective`:
+
+```ts
+import type { ClientDirective } from 'astro'
+
+const clickDirective: ClientDirective = (load, opts, el) => {
+ window.addEventListener('click', async () => {
+ const hydrate = await load()
+ await hydrate()
+ }, { once: true })
+}
+
+export default clickDirective
+```
diff --git a/.changeset/young-impalas-boil.md b/.changeset/young-impalas-boil.md
new file mode 100644
index 000000000000..bfcb25107e59
--- /dev/null
+++ b/.changeset/young-impalas-boil.md
@@ -0,0 +1,26 @@
+---
+'@astrojs/cloudflare': patch
+'@astrojs/turbolinks': patch
+'@astrojs/partytown': patch
+'@astrojs/alpinejs': patch
+'@astrojs/prefetch': patch
+'@astrojs/tailwind': patch
+'@astrojs/markdoc': patch
+'@astrojs/netlify': patch
+'@astrojs/preact': patch
+'@astrojs/svelte': patch
+'@astrojs/vercel': patch
+'@astrojs/react': patch
+'@astrojs/solid-js': patch
+'@astrojs/markdown-component': patch
+'@astrojs/deno': patch
+'@astrojs/node': patch
+'@astrojs/lit': patch
+'@astrojs/mdx': patch
+'@astrojs/vue': patch
+'@astrojs/markdown-remark': patch
+'@astrojs/prism': patch
+'@astrojs/rss': patch
+---
+
+Specify `"files"` field to only publish necessary files
diff --git a/packages/astro-prism/package.json b/packages/astro-prism/package.json
index acbb3dd7de13..abf05dffb2bd 100644
--- a/packages/astro-prism/package.json
+++ b/packages/astro-prism/package.json
@@ -23,6 +23,10 @@
"./Prism.astro": "./Prism.astro",
"./dist/highlighter": "./dist/highlighter.js"
},
+ "files": [
+ "dist",
+ "Prism.astro"
+ ],
"keywords": [
"astro",
"astro-component"
diff --git a/packages/astro-rss/package.json b/packages/astro-rss/package.json
index 52051b32db27..4151647d0cbc 100644
--- a/packages/astro-rss/package.json
+++ b/packages/astro-rss/package.json
@@ -17,6 +17,9 @@
".": "./dist/index.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/astro/astro-jsx.d.ts b/packages/astro/astro-jsx.d.ts
index 9f89b8dd066d..93888c826f7f 100644
--- a/packages/astro/astro-jsx.d.ts
+++ b/packages/astro/astro-jsx.d.ts
@@ -18,12 +18,16 @@ declare namespace astroHTML.JSX {
children: {};
}
- interface IntrinsicAttributes extends AstroBuiltinProps, AstroBuiltinAttributes {
+ interface IntrinsicAttributes
+ extends AstroBuiltinProps,
+ AstroBuiltinAttributes,
+ AstroClientDirectives {
slot?: string;
children?: Children;
}
type AstroBuiltinProps = import('./dist/@types/astro.js').AstroBuiltinProps;
+ type AstroClientDirectives = import('./dist/@types/astro.js').AstroClientDirectives;
type AstroBuiltinAttributes = import('./dist/@types/astro.js').AstroBuiltinAttributes;
type AstroDefineVarsAttribute = import('./dist/@types/astro.js').AstroDefineVarsAttribute;
type AstroScriptAttributes = import('./dist/@types/astro.js').AstroScriptAttributes &
diff --git a/packages/astro/e2e/custom-client-directives.test.js b/packages/astro/e2e/custom-client-directives.test.js
new file mode 100644
index 000000000000..fec5ef9a1104
--- /dev/null
+++ b/packages/astro/e2e/custom-client-directives.test.js
@@ -0,0 +1,92 @@
+import { expect } from '@playwright/test';
+import { testFactory, waitForHydrate } from './test-utils.js';
+import testAdapter from '../test/test-adapter.js';
+
+const test = testFactory({
+ root: './fixtures/custom-client-directives/',
+});
+
+test.describe('Custom Client Directives - dev', () => {
+ let devServer;
+
+ test.beforeAll(async ({ astro }) => {
+ devServer = await astro.startDevServer();
+ });
+
+ test.afterAll(async () => {
+ await devServer.stop();
+ });
+
+ testClientDirectivesShared();
+});
+
+test.describe('Custom Client Directives - build static', () => {
+ let previewServer;
+
+ test.beforeAll(async ({ astro }) => {
+ await astro.build();
+ previewServer = await astro.preview();
+ });
+
+ test.afterAll(async () => {
+ await previewServer.stop();
+ });
+
+ testClientDirectivesShared();
+});
+
+test.describe('Custom Client Directives - build server', () => {
+ let previewServer;
+
+ test.beforeAll(async ({ astro }) => {
+ await astro.build({
+ adapter: testAdapter(),
+ });
+ previewServer = await astro.preview();
+ });
+
+ test.afterAll(async () => {
+ await previewServer.stop();
+ });
+
+ testClientDirectivesShared();
+});
+
+function testClientDirectivesShared() {
+ test('client:click should work', async ({ astro, page }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ const incrementBtn = page.locator('#client-click .increment');
+ const counterValue = page.locator('#client-click pre');
+
+ await expect(counterValue).toHaveText('0');
+
+ // Component only hydrates on first click
+ await Promise.all([waitForHydrate(page, counterValue), incrementBtn.click()]);
+
+ // Since first click only triggers hydration, this should stay 0
+ await expect(counterValue).toHaveText('0');
+ await incrementBtn.click();
+ // Hydrated, this should be 1
+ await expect(counterValue).toHaveText('1');
+ });
+
+ test('client:password should work', async ({ astro, page }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ const incrementBtn = page.locator('#client-password .increment');
+ const counterValue = page.locator('#client-password pre');
+
+ await expect(counterValue).toHaveText('0');
+ await incrementBtn.click();
+ // Not hydrated, so this should stay 0
+ await expect(counterValue).toHaveText('0');
+
+ // Type super cool password to activate password!
+ await Promise.all([waitForHydrate(page, counterValue), page.keyboard.type('hunter2')]);
+
+ await incrementBtn.click();
+ // Hydrated, this should be 1
+ await expect(counterValue).toHaveText('1');
+ });
+}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/astro.config.mjs b/packages/astro/e2e/fixtures/custom-client-directives/astro.config.mjs
new file mode 100644
index 000000000000..451c7ddd8ad3
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/astro.config.mjs
@@ -0,0 +1,38 @@
+import { defineConfig } from 'astro/config';
+import react from "@astrojs/react";
+import { fileURLToPath } from 'url';
+
+export default defineConfig({
+ integrations: [astroClientClickDirective(), astroClientPasswordDirective(), react()],
+ experimental: {
+ customClientDirectives: true
+ }
+});
+
+function astroClientClickDirective() {
+ return {
+ name: 'astro-client-click',
+ hooks: {
+ 'astro:config:setup': (opts) => {
+ opts.addClientDirective({
+ name: 'click',
+ entrypoint: fileURLToPath(new URL('./client-click.js', import.meta.url))
+ });
+ }
+ }
+ };
+}
+
+function astroClientPasswordDirective() {
+ return {
+ name: 'astro-client-click',
+ hooks: {
+ 'astro:config:setup': (opts) => {
+ opts.addClientDirective({
+ name: 'password',
+ entrypoint: fileURLToPath(new URL('./client-password.js', import.meta.url))
+ });
+ }
+ }
+ };
+}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/client-click.js b/packages/astro/e2e/fixtures/custom-client-directives/client-click.js
new file mode 100644
index 000000000000..a2866be78258
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/client-click.js
@@ -0,0 +1,7 @@
+// Hydrate on first click on the window
+export default (load) => {
+ window.addEventListener('click', async () => {
+ const hydrate = await load()
+ await hydrate()
+ }, { once: true })
+}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/client-password.js b/packages/astro/e2e/fixtures/custom-client-directives/client-password.js
new file mode 100644
index 000000000000..36a4939340f7
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/client-password.js
@@ -0,0 +1,21 @@
+// Hydrate when the user types the correct password
+export default (load, options) => {
+ const password = options.value
+ let consecutiveMatch = 0
+
+ const handleKeydown = async (e) => {
+ if (e.key === password[consecutiveMatch]) {
+ consecutiveMatch++
+ } else {
+ consecutiveMatch = 0
+ }
+
+ if (consecutiveMatch === password.length) {
+ window.removeEventListener('keydown', handleKeydown)
+ const hydrate = await load()
+ await hydrate()
+ }
+ }
+
+ window.addEventListener('keydown', handleKeydown)
+}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/package.json b/packages/astro/e2e/fixtures/custom-client-directives/package.json
new file mode 100644
index 000000000000..ee1d8ec533c6
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@test/custom-client-directives",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/react": "workspace:*",
+ "astro": "workspace:*",
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ }
+}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/src/client-directives-types.d.ts b/packages/astro/e2e/fixtures/custom-client-directives/src/client-directives-types.d.ts
new file mode 100644
index 000000000000..07399f7bb09c
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/src/client-directives-types.d.ts
@@ -0,0 +1,9 @@
+declare module 'astro' {
+ interface AstroClientDirectives {
+ 'client:click'?: boolean
+ 'client:password'?: string
+ }
+}
+
+// Make d.ts a module to similate common packaging setups where the entry `index.d.ts` would augment the types
+export {}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/src/components/Counter.jsx b/packages/astro/e2e/fixtures/custom-client-directives/src/components/Counter.jsx
new file mode 100644
index 000000000000..9d2212b0cae8
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/src/components/Counter.jsx
@@ -0,0 +1,18 @@
+import React, { useState } from 'react';
+
+export default function Counter({ children, count: initialCount = 0, id }) {
+ const [count, setCount] = useState(initialCount);
+ const add = () => setCount((i) => i + 1);
+ const subtract = () => setCount((i) => i - 1);
+
+ return (
+ <>
+
+ {children}
+ >
+ );
+}
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/src/pages/index.astro b/packages/astro/e2e/fixtures/custom-client-directives/src/pages/index.astro
new file mode 100644
index 000000000000..05c28b109e1c
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/src/pages/index.astro
@@ -0,0 +1,10 @@
+---
+import Counter from '../components/Counter.jsx';
+---
+
+
+
+ client:click
+ client:password
+
+
\ No newline at end of file
diff --git a/packages/astro/e2e/fixtures/custom-client-directives/tsconfig.json b/packages/astro/e2e/fixtures/custom-client-directives/tsconfig.json
new file mode 100644
index 000000000000..59a562e0e58b
--- /dev/null
+++ b/packages/astro/e2e/fixtures/custom-client-directives/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ // preserveSymlinks set to true so the augmented `declare module 'astro'` works.
+ // This is only needed because we link Astro locally.
+ "preserveSymlinks": true
+ },
+ "include": ["./src/**/*"]
+}
\ No newline at end of file
diff --git a/packages/astro/e2e/test-utils.js b/packages/astro/e2e/test-utils.js
index 88daa8eec282..a11ba868b625 100644
--- a/packages/astro/e2e/test-utils.js
+++ b/packages/astro/e2e/test-utils.js
@@ -55,7 +55,6 @@ export async function getErrorOverlayContent(page) {
}
/**
- * @param {import('@playwright/test').Locator} el
* @returns {Promise}
*/
export async function getColor(el) {
diff --git a/packages/astro/package.json b/packages/astro/package.json
index 5fd28d282eb6..56d9ed1028e6 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -137,6 +137,7 @@
"devalue": "^4.2.0",
"diff": "^5.1.0",
"es-module-lexer": "^1.1.0",
+ "esbuild": "^0.17.18",
"estree-walker": "3.0.0",
"execa": "^6.1.0",
"fast-glob": "^3.2.11",
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index b0b0f4e9fbca..19606b0703d1 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -55,6 +55,10 @@ export interface AstroBuiltinProps {
'client:only'?: boolean | string;
}
+// Allow users to extend this for astro-jsx.d.ts
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface AstroClientDirectives {}
+
export interface AstroBuiltinAttributes {
'class:list'?:
| Record
@@ -1076,6 +1080,28 @@ export interface AstroUserConfig {
*/
inlineStylesheets?: 'always' | 'auto' | 'never';
+ /**
+ * @docs
+ * @name experimental.customClientDirectives
+ * @type {boolean}
+ * @default `false`
+ * @version 2.5.0
+ * @description
+ * Allow integrations to use the [experimental `addClientDirective` API](/en/reference/integrations-reference/#addclientdirective-option) in the `astro:config:setup` hook
+ * to add custom client directives in Astro files.
+ *
+ * To enable this feature, set `experimental.customClientDirectives` to `true` in your Astro config:
+ *
+ * ```js
+ * {
+ * experimental: {
+ * customClientDirectives: true,
+ * },
+ * }
+ * ```
+ */
+ customClientDirectives?: boolean;
+
/**
* @docs
* @name experimental.middleware
@@ -1245,6 +1271,10 @@ export interface AstroSettings {
stage: InjectedScriptStage;
content: string;
}[];
+ /**
+ * Map of directive name (e.g. `load`) to the directive script code
+ */
+ clientDirectives: Map;
tsConfig: TsConfigJson | undefined;
tsConfigPath: string | undefined;
watchFiles: string[];
@@ -1693,6 +1723,7 @@ export interface AstroIntegration {
addWatchFile: (path: URL | string) => void;
injectScript: (stage: InjectedScriptStage, content: string) => void;
injectRoute: (injectRoute: InjectedRoute) => void;
+ addClientDirective: (directive: ClientDirectiveConfig) => void;
// TODO: Add support for `injectElement()` for full HTML element injection, not just scripts.
// This may require some refactoring of `scripts`, `styles`, and `links` into something
// more generalized. Consider the SSR use-case as well.
@@ -1789,6 +1820,7 @@ export interface SSRMetadata {
hasDirectives: Set;
hasRenderedHead: boolean;
headInTree: boolean;
+ clientDirectives: Map;
}
/**
@@ -1854,3 +1886,29 @@ export type CreatePreviewServer = (
export interface PreviewModule {
default: CreatePreviewServer;
}
+
+/* Client Directives */
+type DirectiveHydrate = () => Promise;
+type DirectiveLoad = () => Promise;
+
+type DirectiveOptions = {
+ /**
+ * The component displayName
+ */
+ name: string;
+ /**
+ * The attribute value provided
+ */
+ value: string;
+};
+
+export type ClientDirective = (
+ load: DirectiveLoad,
+ options: DirectiveOptions,
+ el: HTMLElement
+) => void;
+
+export interface ClientDirectiveConfig {
+ name: string;
+ entrypoint: string;
+}
diff --git a/packages/astro/src/core/app/common.ts b/packages/astro/src/core/app/common.ts
index 6fd13d9b9086..58898b2fe51f 100644
--- a/packages/astro/src/core/app/common.ts
+++ b/packages/astro/src/core/app/common.ts
@@ -15,11 +15,13 @@ export function deserializeManifest(serializedManifest: SerializedSSRManifest):
const assets = new Set(serializedManifest.assets);
const componentMetadata = new Map(serializedManifest.componentMetadata);
+ const clientDirectives = new Map(serializedManifest.clientDirectives);
return {
...serializedManifest,
assets,
componentMetadata,
+ clientDirectives,
routes,
};
}
diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts
index d7d4241d20d4..546d45975f21 100644
--- a/packages/astro/src/core/app/index.ts
+++ b/packages/astro/src/core/app/index.ts
@@ -10,7 +10,7 @@ import type { RouteInfo, SSRManifest as Manifest } from './types';
import mime from 'mime';
import { attachToResponse, getSetCookiesFromResponse } from '../cookies/index.js';
-import { call as callEndpoint, createAPIContext } from '../endpoint/index.js';
+import { callEndpoint, createAPIContext } from '../endpoint/index.js';
import { consoleLogDestination } from '../logger/console.js';
import { error, type LogOptions } from '../logger/core.js';
import { callMiddleware } from '../middleware/callMiddleware.js';
@@ -65,6 +65,7 @@ export class App {
markdown: manifest.markdown,
mode: 'production',
renderers: manifest.renderers,
+ clientDirectives: manifest.clientDirectives,
async resolve(specifier: string) {
if (!(specifier in manifest.entryModules)) {
throw new Error(`Unable to resolve [${specifier}]`);
@@ -224,6 +225,7 @@ export class App {
let response;
if (onRequest) {
response = await callMiddleware(
+ this.#env.logging,
onRequest as MiddlewareResponseHandler,
apiContext,
() => {
diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts
index ab6a50b9c946..89c5bad37a4d 100644
--- a/packages/astro/src/core/app/types.ts
+++ b/packages/astro/src/core/app/types.ts
@@ -41,16 +41,24 @@ export interface SSRManifest {
markdown: MarkdownRenderingOptions;
pageMap: Map;
renderers: SSRLoadedRenderer[];
+ /**
+ * Map of directive name (e.g. `load`) to the directive script code
+ */
+ clientDirectives: Map;
entryModules: Record;
assets: Set;
componentMetadata: SSRResult['componentMetadata'];
middleware?: AstroMiddlewareInstance;
}
-export type SerializedSSRManifest = Omit & {
+export type SerializedSSRManifest = Omit<
+ SSRManifest,
+ 'routes' | 'assets' | 'componentMetadata' | 'clientDirectives'
+> & {
routes: SerializedRouteInfo[];
assets: string[];
componentMetadata: [string, SSRComponentMetadata][];
+ clientDirectives: [string, string][];
};
export type AdapterCreateExports = (
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index 4763762f5fb2..2c59218937f7 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -28,11 +28,7 @@ import {
} from '../../core/path.js';
import { runHookBuildGenerated } from '../../integrations/index.js';
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
-import {
- call as callEndpoint,
- createAPIContext,
- throwIfRedirectNotAllowed,
-} from '../endpoint/index.js';
+import { callEndpoint, createAPIContext, throwIfRedirectNotAllowed } from '../endpoint/index.js';
import { AstroError } from '../errors/index.js';
import { debug, info } from '../logger/core.js';
import { callMiddleware } from '../middleware/callMiddleware.js';
@@ -422,6 +418,7 @@ async function generatePath(
markdown: settings.config.markdown,
mode: opts.mode,
renderers,
+ clientDirectives: settings.clientDirectives,
async resolve(specifier: string) {
const hashedFilePath = internals.entrySpecifierToBundleMap.get(specifier);
if (typeof hashedFilePath !== 'string') {
@@ -496,6 +493,7 @@ async function generatePath(
const onRequest = middleware?.onRequest;
if (onRequest) {
response = await callMiddleware(
+ env.logging,
onRequest as MiddlewareResponseHandler,
apiContext,
() => {
diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts
index 1c7ce8252b90..34967cdf3ff2 100644
--- a/packages/astro/src/core/build/plugins/plugin-ssr.ts
+++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts
@@ -237,6 +237,7 @@ function buildManifest(
pageMap: null as any,
componentMetadata: Array.from(internals.componentMetadata),
renderers: [],
+ clientDirectives: Array.from(settings.clientDirectives),
entryModules,
assets: staticFiles.map(prefixAssetPath),
};
diff --git a/packages/astro/src/core/client-directive/build.ts b/packages/astro/src/core/client-directive/build.ts
new file mode 100644
index 000000000000..591c0c4372d2
--- /dev/null
+++ b/packages/astro/src/core/client-directive/build.ts
@@ -0,0 +1,33 @@
+import { build } from 'esbuild';
+
+/**
+ * Build a client directive entrypoint into code that can directly run in a ``;
+ return `${ISLAND_STYLES}`;
case 'directive':
- return ``;
+ return ``;
}
return '';
}
diff --git a/packages/astro/test/fixtures/middleware-dev/src/middleware.js b/packages/astro/test/fixtures/middleware-dev/src/middleware.js
index 89b0365437e0..c8b440239e19 100644
--- a/packages/astro/test/fixtures/middleware-dev/src/middleware.js
+++ b/packages/astro/test/fixtures/middleware-dev/src/middleware.js
@@ -11,6 +11,13 @@ const first = defineMiddleware(async (context, next) => {
return new Response(null, {
status: 500,
});
+ } else if (context.request.url.includes('/api/endpoint')) {
+ const response = await next();
+ const object = await response.json();
+ object.name = 'REDACTED';
+ return new Response(JSON.stringify(object), {
+ headers: response.headers,
+ });
} else {
context.locals.name = 'bar';
}
diff --git a/packages/astro/test/fixtures/middleware-dev/src/pages/api/endpoint.js b/packages/astro/test/fixtures/middleware-dev/src/pages/api/endpoint.js
new file mode 100644
index 000000000000..dadff6edb77d
--- /dev/null
+++ b/packages/astro/test/fixtures/middleware-dev/src/pages/api/endpoint.js
@@ -0,0 +1,10 @@
+export function get() {
+ const object = {
+ name: 'Endpoint!!',
+ };
+ return new Response(JSON.stringify(object), {
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+}
diff --git a/packages/astro/test/middleware.test.js b/packages/astro/test/middleware.test.js
index 7a1d6843ebbf..8e2e0dd0af80 100644
--- a/packages/astro/test/middleware.test.js
+++ b/packages/astro/test/middleware.test.js
@@ -197,6 +197,22 @@ describe('Middleware API in PROD mode, SSR', () => {
const $ = cheerio.load(html);
expect($('title').html()).to.not.equal('MiddlewareNoDataReturned');
});
+
+ it('should correctly work for API endpoints that return a Response object', async () => {
+ const app = await fixture.loadTestAdapterApp();
+ const request = new Request('http://example.com/api/endpoint');
+ const response = await app.render(request);
+ expect(response.status).to.equal(200);
+ expect(response.headers.get('Content-Type')).to.equal('application/json');
+ });
+
+ it('should correctly manipulate the response coming from API endpoints (not simple)', async () => {
+ const app = await fixture.loadTestAdapterApp();
+ const request = new Request('http://example.com/api/endpoint');
+ const response = await app.render(request);
+ const text = await response.text();
+ expect(text.includes('REDACTED')).to.be.true;
+ });
});
describe('Middleware with tailwind', () => {
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index f933a13ada33..e26ab8c6d508 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -127,12 +127,21 @@ export async function loadFixture(inlineConfig) {
if (inlineConfig.base && !inlineConfig.base.endsWith('/')) {
config.base = inlineConfig.base + '/';
}
- let settings = createSettings(config, fileURLToPath(cwd));
- if (config.integrations.find((integration) => integration.name === '@astrojs/mdx')) {
- // Enable default JSX integration. It needs to come first, so unshift rather than push!
- const { default: jsxRenderer } = await import('astro/jsx/renderer.js');
- settings.renderers.unshift(jsxRenderer);
- }
+
+ /**
+ * The dev/build/sync/check commands run integrations' `astro:config:setup` hook that could mutate
+ * the `AstroSettings`. This function helps to create a fresh settings object that is used by the
+ * command functions below to prevent tests from polluting each other.
+ */
+ const getSettings = async () => {
+ let settings = createSettings(config, fileURLToPath(cwd));
+ if (config.integrations.find((integration) => integration.name === '@astrojs/mdx')) {
+ // Enable default JSX integration. It needs to come first, so unshift rather than push!
+ const { default: jsxRenderer } = await import('astro/jsx/renderer.js');
+ settings.renderers.unshift(jsxRenderer);
+ }
+ return settings;
+ };
/** @type {import('@astrojs/telemetry').AstroTelemetry} */
const telemetry = {
@@ -170,17 +179,17 @@ export async function loadFixture(inlineConfig) {
let devServer;
return {
- build: (opts = {}) => {
+ build: async (opts = {}) => {
process.env.NODE_ENV = 'production';
- return build(settings, { logging, telemetry, ...opts });
+ return build(await getSettings(), { logging, telemetry, ...opts });
},
- sync: (opts) => sync(settings, { logging, fs, ...opts }),
+ sync: async (opts) => sync(await getSettings(), { logging, fs, ...opts }),
check: async (opts) => {
- return await check(settings, { logging, ...opts });
+ return await check(await getSettings(), { logging, ...opts });
},
startDevServer: async (opts = {}) => {
process.env.NODE_ENV = 'development';
- devServer = await dev(settings, { logging, telemetry, ...opts });
+ devServer = await dev(await getSettings(), { logging, telemetry, ...opts });
config.server.host = parseAddressToHost(devServer.address.address); // update host
config.server.port = devServer.address.port; // update port
return devServer;
@@ -202,7 +211,7 @@ export async function loadFixture(inlineConfig) {
},
preview: async (opts = {}) => {
process.env.NODE_ENV = 'production';
- const previewServer = await preview(settings, {
+ const previewServer = await preview(await getSettings(), {
logging,
telemetry,
...opts,
diff --git a/packages/integrations/alpinejs/package.json b/packages/integrations/alpinejs/package.json
index fcb61e9158ba..bba68e333324 100644
--- a/packages/integrations/alpinejs/package.json
+++ b/packages/integrations/alpinejs/package.json
@@ -24,6 +24,9 @@
".": "./dist/index.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/cloudflare/package.json b/packages/integrations/cloudflare/package.json
index baa8efad8318..4991ee196a4f 100644
--- a/packages/integrations/cloudflare/package.json
+++ b/packages/integrations/cloudflare/package.json
@@ -27,6 +27,10 @@
"./server.directory.js": "./dist/server.directory.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "runtime.d.ts"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/deno/package.json b/packages/integrations/deno/package.json
index 68da19493e19..e6c6f3ab0508 100644
--- a/packages/integrations/deno/package.json
+++ b/packages/integrations/deno/package.json
@@ -23,6 +23,9 @@
"./__deno_imports.js": "./dist/__deno_imports.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/image/.npmignore b/packages/integrations/image/.npmignore
deleted file mode 100644
index 65e3ba2edadd..000000000000
--- a/packages/integrations/image/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-test/
diff --git a/packages/integrations/lit/package.json b/packages/integrations/lit/package.json
index 596b6de5b996..44f7626ecb9c 100644
--- a/packages/integrations/lit/package.json
+++ b/packages/integrations/lit/package.json
@@ -27,6 +27,14 @@
"./hydration-support.js": "./hydration-support.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "client-shim.js",
+ "client-shim.min.js",
+ "hydration-support.js",
+ "server.js",
+ "server-shim.js"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json
index 5eb65e0d47d1..b048ba2e9496 100644
--- a/packages/integrations/markdoc/package.json
+++ b/packages/integrations/markdoc/package.json
@@ -26,6 +26,11 @@
"./experimental-assets-config": "./dist/experimental-assets-config.js",
"./package.json": "./package.json"
},
+ "files": [
+ "components",
+ "dist",
+ "template"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json
index 659e8b9a1fbd..40d9d32c38a3 100644
--- a/packages/integrations/mdx/package.json
+++ b/packages/integrations/mdx/package.json
@@ -22,6 +22,10 @@
".": "./dist/index.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "template"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/netlify/.npmignore b/packages/integrations/netlify/.npmignore
deleted file mode 100644
index 65e3ba2edadd..000000000000
--- a/packages/integrations/netlify/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-test/
diff --git a/packages/integrations/netlify/package.json b/packages/integrations/netlify/package.json
index b4c3cc72ee46..d30e44c90951 100644
--- a/packages/integrations/netlify/package.json
+++ b/packages/integrations/netlify/package.json
@@ -25,6 +25,9 @@
"./netlify-edge-functions.js": "./dist/netlify-edge-functions.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/node/package.json b/packages/integrations/node/package.json
index de72fb89c799..152e281e81db 100644
--- a/packages/integrations/node/package.json
+++ b/packages/integrations/node/package.json
@@ -23,6 +23,9 @@
"./preview.js": "./dist/preview.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/partytown/package.json b/packages/integrations/partytown/package.json
index 139c4e9344f1..549730f9ee10 100644
--- a/packages/integrations/partytown/package.json
+++ b/packages/integrations/partytown/package.json
@@ -23,6 +23,9 @@
".": "./dist/index.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/preact/package.json b/packages/integrations/preact/package.json
index 37598d18d865..ccff0a95e6e6 100644
--- a/packages/integrations/preact/package.json
+++ b/packages/integrations/preact/package.json
@@ -26,6 +26,9 @@
"./server.js": "./dist/server.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/prefetch/package.json b/packages/integrations/prefetch/package.json
index 178214ad972a..7c7bc7ea6989 100644
--- a/packages/integrations/prefetch/package.json
+++ b/packages/integrations/prefetch/package.json
@@ -23,6 +23,9 @@
"./client.js": "./dist/client.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json
index 318c4bc2731a..8947f6b161c1 100644
--- a/packages/integrations/react/package.json
+++ b/packages/integrations/react/package.json
@@ -28,6 +28,16 @@
"./package.json": "./package.json",
"./jsx-runtime": "./jsx-runtime.js"
},
+ "files": [
+ "dist",
+ "client.js",
+ "client-v17.js",
+ "context.js",
+ "jsx-runtime.js",
+ "server.js",
+ "server-v17.js",
+ "static-html.js"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/solid/package.json b/packages/integrations/solid/package.json
index 5adec5a2b806..5d9a23698893 100644
--- a/packages/integrations/solid/package.json
+++ b/packages/integrations/solid/package.json
@@ -26,6 +26,9 @@
"./server.js": "./dist/server.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json
index 78d3a8f8187c..6abc3e9d624d 100644
--- a/packages/integrations/svelte/package.json
+++ b/packages/integrations/svelte/package.json
@@ -27,6 +27,11 @@
"./server.js": "./server.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "client.js",
+ "server.js"
+ ],
"scripts": {
"build": "astro-scripts build \"src/index.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist",
diff --git a/packages/integrations/tailwind/package.json b/packages/integrations/tailwind/package.json
index 876c5f9eb69c..43c76a5b6fa0 100644
--- a/packages/integrations/tailwind/package.json
+++ b/packages/integrations/tailwind/package.json
@@ -22,6 +22,10 @@
"./base.css": "./base.css",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "base.css"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/turbolinks/package.json b/packages/integrations/turbolinks/package.json
index e888a5a4724d..d7505030c7c8 100644
--- a/packages/integrations/turbolinks/package.json
+++ b/packages/integrations/turbolinks/package.json
@@ -23,6 +23,10 @@
"./client.js": "./client.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "client.js"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json
index 0f5f7a9eac90..d3dc5a6d8217 100644
--- a/packages/integrations/vercel/package.json
+++ b/packages/integrations/vercel/package.json
@@ -40,6 +40,9 @@
]
}
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
diff --git a/packages/integrations/vercel/src/edge/adapter.ts b/packages/integrations/vercel/src/edge/adapter.ts
index 5f9f81f2155b..3c2d39116e95 100644
--- a/packages/integrations/vercel/src/edge/adapter.ts
+++ b/packages/integrations/vercel/src/edge/adapter.ts
@@ -119,6 +119,8 @@ export default function vercelEdge({
await esbuild.build({
target: 'es2020',
platform: 'browser',
+ // https://runtime-keys.proposal.wintercg.org/#edge-light
+ conditions: ['edge-light', 'worker', 'browser'],
entryPoints: [entryPath],
outfile: entryPath,
allowOverwrite: true,
diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json
index a336714447bb..6de8c2ad2cbf 100644
--- a/packages/integrations/vue/package.json
+++ b/packages/integrations/vue/package.json
@@ -27,6 +27,12 @@
"./server.js": "./server.js",
"./package.json": "./package.json"
},
+ "files": [
+ "dist",
+ "client.js",
+ "server.js",
+ "static-html.js"
+ ],
"scripts": {
"build": "astro-scripts build \"src/index.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist",
diff --git a/packages/markdown/component/package.json b/packages/markdown/component/package.json
index 2eee2c3dddf8..5cfcfdc7ea07 100644
--- a/packages/markdown/component/package.json
+++ b/packages/markdown/component/package.json
@@ -18,6 +18,9 @@
"astro": "./Markdown.astro"
}
},
+ "files": [
+ "Markdown.astro"
+ ],
"scripts": {
"test": "mocha --exit --timeout 20000"
},
diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json
index bf9d4262d2b6..b4a0ae4cebfa 100644
--- a/packages/markdown/remark/package.json
+++ b/packages/markdown/remark/package.json
@@ -16,6 +16,9 @@
".": "./dist/index.js",
"./dist/internal.js": "./dist/internal.js"
},
+ "files": [
+ "dist"
+ ],
"scripts": {
"prepublish": "pnpm build",
"build": "astro-scripts build \"src/**/*.ts\" && tsc -p tsconfig.json",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d12dd2eea977..6cea88c27df1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -603,6 +603,9 @@ importers:
es-module-lexer:
specifier: ^1.1.0
version: 1.1.1
+ esbuild:
+ specifier: ^0.17.18
+ version: 0.17.18
estree-walker:
specifier: 3.0.0
version: 3.0.0
@@ -941,6 +944,21 @@ importers:
specifier: workspace:*
version: link:../../..
+ packages/astro/e2e/fixtures/custom-client-directives:
+ dependencies:
+ '@astrojs/react':
+ specifier: workspace:*
+ version: link:../../../../integrations/react
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+ react:
+ specifier: ^18.0.0
+ version: 18.2.0
+ react-dom:
+ specifier: ^18.0.0
+ version: 18.2.0(react@18.2.0)
+
packages/astro/e2e/fixtures/error-cyclic:
dependencies:
'@astrojs/preact':
@@ -7403,6 +7421,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/android-arm64@0.17.18:
+ resolution: {integrity: sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
/@esbuild/android-arm@0.15.18:
resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==}
engines: {node: '>=12'}
@@ -7420,6 +7446,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/android-arm@0.17.18:
+ resolution: {integrity: sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
/@esbuild/android-x64@0.17.12:
resolution: {integrity: sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==}
engines: {node: '>=12'}
@@ -7428,6 +7462,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/android-x64@0.17.18:
+ resolution: {integrity: sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
/@esbuild/darwin-arm64@0.17.12:
resolution: {integrity: sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==}
engines: {node: '>=12'}
@@ -7436,6 +7478,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/darwin-arm64@0.17.18:
+ resolution: {integrity: sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
/@esbuild/darwin-x64@0.17.12:
resolution: {integrity: sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==}
engines: {node: '>=12'}
@@ -7444,6 +7494,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/darwin-x64@0.17.18:
+ resolution: {integrity: sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
/@esbuild/freebsd-arm64@0.17.12:
resolution: {integrity: sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==}
engines: {node: '>=12'}
@@ -7452,6 +7510,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/freebsd-arm64@0.17.18:
+ resolution: {integrity: sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/freebsd-x64@0.17.12:
resolution: {integrity: sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==}
engines: {node: '>=12'}
@@ -7460,6 +7526,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/freebsd-x64@0.17.18:
+ resolution: {integrity: sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-arm64@0.17.12:
resolution: {integrity: sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==}
engines: {node: '>=12'}
@@ -7468,6 +7542,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-arm64@0.17.18:
+ resolution: {integrity: sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-arm@0.17.12:
resolution: {integrity: sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==}
engines: {node: '>=12'}
@@ -7476,6 +7558,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-arm@0.17.18:
+ resolution: {integrity: sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-ia32@0.17.12:
resolution: {integrity: sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==}
engines: {node: '>=12'}
@@ -7484,6 +7574,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-ia32@0.17.18:
+ resolution: {integrity: sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-loong64@0.15.18:
resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==}
engines: {node: '>=12'}
@@ -7501,6 +7599,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-loong64@0.17.18:
+ resolution: {integrity: sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-mips64el@0.17.12:
resolution: {integrity: sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==}
engines: {node: '>=12'}
@@ -7509,6 +7615,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-mips64el@0.17.18:
+ resolution: {integrity: sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-ppc64@0.17.12:
resolution: {integrity: sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==}
engines: {node: '>=12'}
@@ -7517,6 +7631,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-ppc64@0.17.18:
+ resolution: {integrity: sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-riscv64@0.17.12:
resolution: {integrity: sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==}
engines: {node: '>=12'}
@@ -7525,6 +7647,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-riscv64@0.17.18:
+ resolution: {integrity: sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-s390x@0.17.12:
resolution: {integrity: sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==}
engines: {node: '>=12'}
@@ -7533,6 +7663,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-s390x@0.17.18:
+ resolution: {integrity: sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-x64@0.17.12:
resolution: {integrity: sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==}
engines: {node: '>=12'}
@@ -7541,6 +7679,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-x64@0.17.18:
+ resolution: {integrity: sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/netbsd-x64@0.17.12:
resolution: {integrity: sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==}
engines: {node: '>=12'}
@@ -7549,6 +7695,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/netbsd-x64@0.17.18:
+ resolution: {integrity: sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/openbsd-x64@0.17.12:
resolution: {integrity: sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==}
engines: {node: '>=12'}
@@ -7557,6 +7711,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/openbsd-x64@0.17.18:
+ resolution: {integrity: sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/sunos-x64@0.17.12:
resolution: {integrity: sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==}
engines: {node: '>=12'}
@@ -7565,6 +7727,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/sunos-x64@0.17.18:
+ resolution: {integrity: sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ optional: true
+
/@esbuild/win32-arm64@0.17.12:
resolution: {integrity: sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==}
engines: {node: '>=12'}
@@ -7573,6 +7743,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/win32-arm64@0.17.18:
+ resolution: {integrity: sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@esbuild/win32-ia32@0.17.12:
resolution: {integrity: sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==}
engines: {node: '>=12'}
@@ -7581,6 +7759,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/win32-ia32@0.17.18:
+ resolution: {integrity: sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@esbuild/win32-x64@0.17.12:
resolution: {integrity: sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==}
engines: {node: '>=12'}
@@ -7589,6 +7775,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/win32-x64@0.17.18:
+ resolution: {integrity: sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@eslint-community/eslint-utils@4.4.0(eslint@8.38.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -11338,6 +11532,35 @@ packages:
'@esbuild/win32-ia32': 0.17.12
'@esbuild/win32-x64': 0.17.12
+ /esbuild@0.17.18:
+ resolution: {integrity: sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.17.18
+ '@esbuild/android-arm64': 0.17.18
+ '@esbuild/android-x64': 0.17.18
+ '@esbuild/darwin-arm64': 0.17.18
+ '@esbuild/darwin-x64': 0.17.18
+ '@esbuild/freebsd-arm64': 0.17.18
+ '@esbuild/freebsd-x64': 0.17.18
+ '@esbuild/linux-arm': 0.17.18
+ '@esbuild/linux-arm64': 0.17.18
+ '@esbuild/linux-ia32': 0.17.18
+ '@esbuild/linux-loong64': 0.17.18
+ '@esbuild/linux-mips64el': 0.17.18
+ '@esbuild/linux-ppc64': 0.17.18
+ '@esbuild/linux-riscv64': 0.17.18
+ '@esbuild/linux-s390x': 0.17.18
+ '@esbuild/linux-x64': 0.17.18
+ '@esbuild/netbsd-x64': 0.17.18
+ '@esbuild/openbsd-x64': 0.17.18
+ '@esbuild/sunos-x64': 0.17.18
+ '@esbuild/win32-arm64': 0.17.18
+ '@esbuild/win32-ia32': 0.17.18
+ '@esbuild/win32-x64': 0.17.18
+
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
@@ -17395,7 +17618,7 @@ packages:
optional: true
dependencies:
'@types/node': 18.16.3
- esbuild: 0.17.12
+ esbuild: 0.17.18
postcss: 8.4.23
rollup: 3.21.8
sass: 1.52.2
diff --git a/scripts/cmd/prebuild.js b/scripts/cmd/prebuild.js
index bb8220eef165..99208a29f257 100644
--- a/scripts/cmd/prebuild.js
+++ b/scripts/cmd/prebuild.js
@@ -1,4 +1,5 @@
import esbuild from 'esbuild';
+import { red } from 'kleur/colors';
import glob from 'tiny-glob';
import fs from 'fs';
import path from 'path';
@@ -39,11 +40,40 @@ export default async function prebuild(...args) {
}
async function prebuildFile(filepath) {
- const tscode = await fs.promises.readFile(filepath, 'utf-8');
- const esbuildresult = await esbuild.transform(tscode, {
- loader: 'ts',
+ let tscode = await fs.promises.readFile(filepath, 'utf-8');
+ // If we're bundling a client directive, modify the code to match `packages/astro/src/core/client-directive/build.ts`.
+ // If updating this code, make sure to also update that file.
+ if (filepath.includes(`runtime${path.sep}client`)) {
+ // `export default xxxDirective` is a convention used in the current client directives that we use
+ // to make sure we bundle this right. We'll error below if this convention isn't followed.
+ const newTscode = tscode.replace(
+ /export default (.*?)Directive/,
+ (_, name) =>
+ `(self.Astro || (self.Astro = {})).${name} = ${name}Directive;window.dispatchEvent(new Event('astro:${name}'))`
+ );
+ if (newTscode === tscode) {
+ console.error(
+ red(
+ `${filepath} doesn't follow the \`export default xxxDirective\` convention. The prebuilt output may be wrong. ` +
+ `For more information, check out ${fileURLToPath(import.meta.url)}`
+ )
+ );
+ }
+ tscode = newTscode;
+ }
+ const esbuildresult = await esbuild.build({
+ stdin: {
+ contents: tscode,
+ resolveDir: path.dirname(filepath),
+ loader: 'ts',
+ sourcefile: filepath,
+ },
+ format: 'iife',
minify,
+ bundle: true,
+ write: false,
});
+ const code = esbuildresult.outputFiles[0].text.trim();
const rootURL = new URL('../../', import.meta.url);
const rel = path.relative(fileURLToPath(rootURL), filepath);
const mod = `/**
@@ -52,7 +82,7 @@ export default async function prebuild(...args) {
* to generate this file.
*/
-export default \`${escapeTemplateLiterals(esbuildresult.code.trim())}\`;`;
+export default \`${escapeTemplateLiterals(code)}\`;`;
const url = getPrebuildURL(filepath);
await fs.promises.writeFile(url, mod, 'utf-8');
}