diff --git a/.changeset/orange-icons-build.md b/.changeset/orange-icons-build.md
new file mode 100644
index 000000000000..3d128dba64fd
--- /dev/null
+++ b/.changeset/orange-icons-build.md
@@ -0,0 +1,41 @@
+---
+"@cloudflare/workers-shared": minor
+"wrangler": minor
+---
+
+feat: Create very basic Asset Server Worker and plumb it into `wrangler dev`
+
+These changes do the ground work needed in order to add Assets support for Workers in `wrangler dev`. They introduce the following components, and the following conceptual "client pipeline":
+
+
+ |
+ wrangler dev
+ | workerd
++------------------+---------------------+
+| | |
+| +-----------v--------------+ |
+| | | |
+| | NOOP Entry Worker | |
+| | | |
+| +------------+-------------+ |
+| | |
+| env.ASSET_SERVER |
+| | |
+| +------------v-------------+ |
+| | | |
+| | Asset Server Worker | |
+| | | |
+| +------------+-------------+ |
+| | |
++-------------------+--------------------+
+ |
+ v
+ "Hello world from Asset Server"
+
+
+
+Based on the above architectural diagram, this body of work implements the following:
+
+- it creates a new package called `workers-shared` that hosts the `Asset Server Worker`, and the `Router Worker`in the future
+- it scaffolds the `Asset Server Worker` in some very basic form, with basic configuration. Further behaviour implementation will follow in a subsequent PR
+- it does the ground work of plumbing ASW into Miniflare
diff --git a/fixtures/workers-with-assets/README.md b/fixtures/workers-with-assets/README.md
new file mode 100644
index 000000000000..3cddc512a6a6
--- /dev/null
+++ b/fixtures/workers-with-assets/README.md
@@ -0,0 +1,23 @@
+# workers-with-assets
+
+`workers-with-assets` is a test fixture that showcases Workers with Assets. This particular fixture sets up an assets-only Workers project.
+
+## dev
+
+To start a dev session you can run
+
+```
+wrangler dev
+```
+
+or
+
+```
+wrangler dev --experimental-assets=./public
+```
+
+## Run tests
+
+```
+npm run test
+```
diff --git a/fixtures/workers-with-assets/package.json b/fixtures/workers-with-assets/package.json
new file mode 100644
index 000000000000..771021f2e01c
--- /dev/null
+++ b/fixtures/workers-with-assets/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "assets-worker",
+ "private": true,
+ "scripts": {
+ "check:type": "tsc",
+ "dev": "npx wrangler dev",
+ "test:ci": "vitest run",
+ "test:watch": "vitest",
+ "type:tests": "tsc -p ./tests/tsconfig.json"
+ },
+ "devDependencies": {
+ "@cloudflare/workers-tsconfig": "workspace:*",
+ "@cloudflare/workers-types": "^4.20240725.0",
+ "undici": "^5.28.4",
+ "wrangler": "workspace:*"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ }
+}
diff --git a/fixtures/workers-with-assets/public/index.html b/fixtures/workers-with-assets/public/index.html
new file mode 100644
index 000000000000..de28c4adee5c
--- /dev/null
+++ b/fixtures/workers-with-assets/public/index.html
@@ -0,0 +1 @@
+
Hello Workers + Assets World!
diff --git a/fixtures/workers-with-assets/tests/index.test.ts b/fixtures/workers-with-assets/tests/index.test.ts
new file mode 100644
index 000000000000..cc0d36bb02b9
--- /dev/null
+++ b/fixtures/workers-with-assets/tests/index.test.ts
@@ -0,0 +1,26 @@
+import { resolve } from "node:path";
+import { fetch } from "undici";
+import { afterAll, beforeAll, describe, it } from "vitest";
+import { runWranglerDev } from "../../shared/src/run-wrangler-long-lived";
+
+describe("[Workers + Assets] `wrangler dev`", () => {
+ let ip: string, port: number, stop: (() => Promise) | undefined;
+
+ beforeAll(async () => {
+ ({ ip, port, stop } = await runWranglerDev(resolve(__dirname, ".."), [
+ "--port=0",
+ "--inspector-port=0",
+ ]));
+ });
+
+ afterAll(async () => {
+ await stop?.();
+ });
+
+ it("renders ", async ({ expect }) => {
+ const response = await fetch(`http://${ip}:${port}/`);
+ const text = await response.text();
+ expect(response.status).toBe(200);
+ expect(text).toContain(`Hello from Asset Server Worker 🚀`);
+ });
+});
diff --git a/fixtures/workers-with-assets/tests/tsconfig.json b/fixtures/workers-with-assets/tests/tsconfig.json
new file mode 100644
index 000000000000..d2ce7f144694
--- /dev/null
+++ b/fixtures/workers-with-assets/tests/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "@cloudflare/workers-tsconfig/tsconfig.json",
+ "compilerOptions": {
+ "types": ["node"]
+ },
+ "include": ["**/*.ts", "../../../node-types.d.ts"]
+}
diff --git a/fixtures/workers-with-assets/tsconfig.json b/fixtures/workers-with-assets/tsconfig.json
new file mode 100644
index 000000000000..874dec6ac33a
--- /dev/null
+++ b/fixtures/workers-with-assets/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "esModuleInterop": true,
+ "module": "CommonJS",
+ "lib": ["ES2020"],
+ "types": ["node"],
+ "moduleResolution": "node",
+ "noEmit": true,
+ "skipLibCheck": true
+ },
+ "include": ["tests", "../../node-types.d.ts"]
+}
diff --git a/fixtures/workers-with-assets/wrangler.toml b/fixtures/workers-with-assets/wrangler.toml
new file mode 100644
index 000000000000..74950a4d0992
--- /dev/null
+++ b/fixtures/workers-with-assets/wrangler.toml
@@ -0,0 +1,5 @@
+name = "assets-worker"
+compatibility_date = "2024-01-01"
+
+[experimental_assets]
+directory = "./public"
diff --git a/packages/workers-shared/README.md b/packages/workers-shared/README.md
new file mode 100644
index 000000000000..c42b57532b77
--- /dev/null
+++ b/packages/workers-shared/README.md
@@ -0,0 +1,13 @@
+# `@cloudflare/workers-shared`
+
+This is a package that is used at Cloudflare to power some internal features of [Cloudflare Workers](https://developers.cloudflare.com/workers/), as well as their open-source equivalents here in workers-sdk and Wrangler.
+
+## `asset-server`
+
+The Asset Server Worker.
+
+For more details please refer to the dedicated README file.
+
+> [!NOTE]
+> Since code in this package is used by the Workers infrastructure, it is important that PRs are given careful review with regards to how they could cause a failure in production.
+> Ideally, there should be comprehensive tests for changes being made to give extra confidence about the behavior.
diff --git a/packages/workers-shared/asset-server-worker/README.md b/packages/workers-shared/asset-server-worker/README.md
new file mode 100644
index 000000000000..88a6e0d953e5
--- /dev/null
+++ b/packages/workers-shared/asset-server-worker/README.md
@@ -0,0 +1,3 @@
+# `asset-server`
+
+The Asset Server is a [Cloudflare Worker](https://developers.cloudflare.com/workers/) that is responsible of serving assets for Workers deployed on the edge, that contain static assets as well.
diff --git a/packages/workers-shared/asset-server-worker/src/index.ts b/packages/workers-shared/asset-server-worker/src/index.ts
new file mode 100644
index 000000000000..3249a340c471
--- /dev/null
+++ b/packages/workers-shared/asset-server-worker/src/index.ts
@@ -0,0 +1,5 @@
+export default {
+ async fetch(request, env) {
+ return new Response("Hello from Asset Server Worker 🚀");
+ },
+};
diff --git a/packages/workers-shared/asset-server-worker/wrangler.toml b/packages/workers-shared/asset-server-worker/wrangler.toml
new file mode 100644
index 000000000000..5c312ad0e107
--- /dev/null
+++ b/packages/workers-shared/asset-server-worker/wrangler.toml
@@ -0,0 +1,12 @@
+##
+# Configuration file for the Asset Server Worker
+#
+# Please note that wrangler has a dependency on this file, and will
+# attempt to read it as part of setting up a new Miniflare instance
+# in developemnt mode. We should ensure that any configuration changes
+# to this file are persisted in wrangler as well, when necessary.
+# (see packages/wrangler/src/dev/miniflare.ts -> buildMiniflareOptions())
+##
+name = "asset-server"
+main = "src/index.ts"
+compatibility_date = "2024-07-31"
diff --git a/packages/workers-shared/package.json b/packages/workers-shared/package.json
new file mode 100644
index 000000000000..2d2c9345d715
--- /dev/null
+++ b/packages/workers-shared/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "@cloudflare/workers-shared",
+ "version": "0.0.1",
+ "description": "Package that is used at Cloudflare to power some internal features of Cloudflare Workers.",
+ "scripts": {
+ "build": "pnpm run clean && pnpm run bundle:asset-server",
+ "bundle:asset-server": "esbuild asset-server-worker/src/index.ts --format=esm --bundle --outfile=dist/asset-server-worker.mjs --sourcemap=external",
+ "clean": "rimraf dist",
+ "dev": "pnpm run clean && concurrently -n bundle:asset-server -c blue \"pnpm run bundle:asset-server --watch\""
+ },
+ "devDependencies": {
+ "concurrently": "^8.2.2",
+ "esbuild": "0.17.19",
+ "rimraf": "^6.0.1",
+ "typescript": "^5.5.4"
+ }
+}
diff --git a/packages/workers-shared/turbo.json b/packages/workers-shared/turbo.json
new file mode 100644
index 000000000000..1a6c74c9def8
--- /dev/null
+++ b/packages/workers-shared/turbo.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "http://turbo.build/schema.json",
+ "extends": ["//"],
+ "pipeline": {
+ "build": {
+ "outputs": ["dist/**"]
+ }
+ }
+}
diff --git a/packages/wrangler/package.json b/packages/wrangler/package.json
index 00b374bc3c02..d48326f63234 100644
--- a/packages/wrangler/package.json
+++ b/packages/wrangler/package.json
@@ -92,6 +92,7 @@
"@cloudflare/eslint-config-worker": "workspace:*",
"@cloudflare/pages-shared": "workspace:^",
"@cloudflare/types": "^6.18.4",
+ "@cloudflare/workers-shared": "workspace:*",
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20240725.0",
"@cspotcode/source-map-support": "0.8.1",
diff --git a/packages/wrangler/scripts/deps.ts b/packages/wrangler/scripts/deps.ts
index 4c6ed1409263..874df64b2740 100644
--- a/packages/wrangler/scripts/deps.ts
+++ b/packages/wrangler/scripts/deps.ts
@@ -22,6 +22,7 @@ export const EXTERNAL_DEPENDENCIES = [
// and read when we are bundling the worker application
"unenv",
"workerd/worker.mjs",
+ "@cloudflare/workers-shared",
];
const pathToPackageJson = path.resolve(__dirname, "..", "package.json");
diff --git a/packages/wrangler/src/__tests__/deploy.test.ts b/packages/wrangler/src/__tests__/deploy.test.ts
index 0928001eb071..6a1109ee44e5 100644
--- a/packages/wrangler/src/__tests__/deploy.test.ts
+++ b/packages/wrangler/src/__tests__/deploy.test.ts
@@ -4363,7 +4363,7 @@ addEventListener('fetch', event => {});`
});
writeWorkerSource();
mockUploadWorkerRequest({
- expectedMainModule: "no-op-worker.js",
+ expectedMainModule: "no-op-assets-worker.js",
});
mockSubDomainRequest();
await runWrangler("deploy");
diff --git a/packages/wrangler/src/__tests__/dev.test.tsx b/packages/wrangler/src/__tests__/dev.test.tsx
index 1a96ed5c64c5..c0e9376e07cf 100644
--- a/packages/wrangler/src/__tests__/dev.test.tsx
+++ b/packages/wrangler/src/__tests__/dev.test.tsx
@@ -1303,7 +1303,7 @@ describe("wrangler dev", () => {
await expect(
runWrangler("dev --legacy-assets abc --site xyz")
).rejects.toThrowErrorMatchingInlineSnapshot(
- `[Error: Cannot use Assets and Workers Sites in the same Worker.]`
+ `[Error: Cannot use Legacy Assets and Workers Sites in the same Worker.]`
);
});
@@ -1318,7 +1318,7 @@ describe("wrangler dev", () => {
await expect(
runWrangler("dev --legacy-assets abc")
).rejects.toThrowErrorMatchingInlineSnapshot(
- `[Error: Cannot use Assets and Workers Sites in the same Worker.]`
+ `[Error: Cannot use Legacy Assets and Workers Sites in the same Worker.]`
);
});
@@ -1331,7 +1331,7 @@ describe("wrangler dev", () => {
await expect(
runWrangler("dev --site xyz")
).rejects.toThrowErrorMatchingInlineSnapshot(
- `[Error: Cannot use Assets and Workers Sites in the same Worker.]`
+ `[Error: Cannot use Legacy Assets and Workers Sites in the same Worker.]`
);
});
@@ -1347,7 +1347,7 @@ describe("wrangler dev", () => {
await expect(
runWrangler("dev --legacy-assets abc")
).rejects.toThrowErrorMatchingInlineSnapshot(
- `[Error: Cannot use Assets and Workers Sites in the same Worker.]`
+ `[Error: Cannot use Legacy Assets and Workers Sites in the same Worker.]`
);
});
@@ -1441,11 +1441,11 @@ describe("wrangler dev", () => {
await expect(
runWrangler("dev")
).rejects.toThrowErrorMatchingInlineSnapshot(
- `[Error: Cannot use Assets and Workers Sites in the same Worker.]`
+ `[Error: Cannot use Experimental Assets and Workers Sites in the same Worker.]`
);
});
- it("should error if --experimental-assets and config.site are used together", async () => {
+ it("should error if config.site and --experimental-assets are used together", async () => {
writeWranglerToml({
main: "./index.js",
site: {
@@ -1457,7 +1457,74 @@ describe("wrangler dev", () => {
await expect(
runWrangler("dev --experimental-assets assets")
).rejects.toThrowErrorMatchingInlineSnapshot(
- `[Error: Cannot use Assets and Workers Sites in the same Worker.]`
+ `[Error: Cannot use Experimental Assets and Workers Sites in the same Worker.]`
+ );
+ });
+
+ it("should error if config.experimental_assets and config.legacy_assets are used together", async () => {
+ writeWranglerToml({
+ main: "./index.js",
+ experimental_assets: { directory: "assets" },
+ legacy_assets: {
+ bucket: "xyz",
+ include: [],
+ exclude: [],
+ browser_TTL: undefined,
+ serve_single_page_app: true,
+ },
+ });
+ fs.writeFileSync("index.js", `export default {};`);
+ fs.openSync("assets", "w");
+ await expect(
+ runWrangler("dev")
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
+ `[Error: Cannot use Legacy Assets and Experimental Assets in the same Worker.]`
+ );
+ });
+
+ it("should error if --experimental-assets and --legacy-assets are used together", async () => {
+ fs.writeFileSync("index.js", `export default {};`);
+ fs.openSync("assets", "w");
+ await expect(
+ runWrangler("dev --experimental-assets assets --legacy-assets assets")
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
+ `[Error: Cannot use Legacy Assets and Experimental Assets in the same Worker.]`
+ );
+ });
+
+ it("should error if --experimental-assets and config.legacy_assets are used together", async () => {
+ writeWranglerToml({
+ main: "./index.js",
+ legacy_assets: {
+ bucket: "xyz",
+ include: [],
+ exclude: [],
+ browser_TTL: undefined,
+ serve_single_page_app: true,
+ },
+ });
+ fs.writeFileSync("index.js", `export default {};`);
+ fs.openSync("assets", "w");
+ await expect(
+ runWrangler("dev --experimental-assets assets")
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
+ `[Error: Cannot use Legacy Assets and Experimental Assets in the same Worker.]`
+ );
+ });
+
+ it("should error if config.experimental_assets and --legacy-assets are used together", async () => {
+ writeWranglerToml({
+ main: "./index.js",
+ experimental_assets: {
+ directory: "xyz",
+ },
+ });
+ fs.writeFileSync("index.js", `export default {};`);
+ fs.openSync("xyz", "w");
+ await expect(
+ runWrangler("dev --legacy-assets xyz")
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
+ `[Error: Cannot use Legacy Assets and Experimental Assets in the same Worker.]`
);
});
@@ -1475,7 +1542,7 @@ describe("wrangler dev", () => {
);
});
- it("should error if directory specified by 'experimental_assets' configuration key does not exist", async () => {
+ it("should error if directory specified by '[experimental_assets]' configuration key does not exist", async () => {
writeWranglerToml({
main: "./index.js",
experimental_assets: {
diff --git a/packages/wrangler/src/api/dev.ts b/packages/wrangler/src/api/dev.ts
index a9dde89e61d1..dc43a863c6a8 100644
--- a/packages/wrangler/src/api/dev.ts
+++ b/packages/wrangler/src/api/dev.ts
@@ -189,7 +189,7 @@ export async function unstable_dev(
localProtocol: options?.localProtocol,
httpsKeyPath: options?.httpsKeyPath,
httpsCertPath: options?.httpsCertPath,
- experimentalAssets: options?.experimentalAssets,
+ experimentalAssets: undefined,
legacyAssets: options?.legacyAssets,
site: options?.site, // Root folder of static assets for Workers Sites
siteInclude: options?.siteInclude, // Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded.
diff --git a/packages/wrangler/src/api/startDevWorker/ConfigController.ts b/packages/wrangler/src/api/startDevWorker/ConfigController.ts
index 6ec2e5b75f40..874f505da207 100644
--- a/packages/wrangler/src/api/startDevWorker/ConfigController.ts
+++ b/packages/wrangler/src/api/startDevWorker/ConfigController.ts
@@ -204,6 +204,10 @@ async function resolveConfig(
legacyAssets: Boolean(legacyAssets),
script: input.entrypoint,
moduleRoot: input.build?.moduleRoot,
+ // getEntry only needs to know if experimental_assets was specified.
+ // The actualy value is not relevant here, which is why not passing
+ // the entire ExperimentalAssets object is fine.
+ experimentalAssets: input?.experimental?.assets?.directory,
},
config,
"dev"
@@ -257,6 +261,9 @@ async function resolveConfig(
capnp: input.unsafe?.capnp ?? unsafe?.capnp,
metadata: input.unsafe?.metadata ?? unsafe?.metadata,
},
+ experimental: {
+ assets: input?.experimental?.assets,
+ },
} satisfies StartDevWorkerOptions;
if (resolved.legacy.legacyAssets && resolved.legacy.site) {
diff --git a/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts b/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts
index 1fc406fc233e..22bd9aab3bed 100644
--- a/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts
+++ b/packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts
@@ -100,6 +100,7 @@ async function convertToConfigBundle(
includePatterns: event.config.legacy?.site?.include ?? [],
}
: undefined,
+ experimentalAssets: event.config.experimental?.assets,
initialPort: undefined,
initialIp: "127.0.0.1",
rules: [],
diff --git a/packages/wrangler/src/api/startDevWorker/types.ts b/packages/wrangler/src/api/startDevWorker/types.ts
index aa45767a92b3..9f8c0ecd0b0c 100644
--- a/packages/wrangler/src/api/startDevWorker/types.ts
+++ b/packages/wrangler/src/api/startDevWorker/types.ts
@@ -1,6 +1,7 @@
import type { Config } from "../../config";
import type {
CustomDomainRoute,
+ ExperimentalAssets,
Rule,
ZoneIdRoute,
ZoneNameRoute,
@@ -161,6 +162,9 @@ export interface StartDevWorkerInput {
enableServiceEnvironments?: boolean;
};
unsafe?: Omit;
+ experimental?: {
+ assets?: Omit;
+ };
}
export type StartDevWorkerOptions = StartDevWorkerInput & {
@@ -258,7 +262,8 @@ export type Binding =
| ({ type: "dispatch_namespace" } & Omit)
| ({ type: "mtls_certificate" } & Omit)
| ({ type: "logfwdr" } & Omit)
- | { type: `unsafe_${string}` };
+ | { type: `unsafe_${string}` }
+ | { type: "assets" };
export type ServiceFetch = (request: Request) => Promise | Response;
diff --git a/packages/wrangler/src/deployment-bundle/entry.ts b/packages/wrangler/src/deployment-bundle/entry.ts
index 8eef2c9e8088..3fe5d022efa9 100644
--- a/packages/wrangler/src/deployment-bundle/entry.ts
+++ b/packages/wrangler/src/deployment-bundle/entry.ts
@@ -38,13 +38,14 @@ export async function getEntry(
format?: CfScriptFormat | undefined;
legacyAssets?: string | undefined | boolean;
moduleRoot?: string;
- experimentalAssets?: string;
+ experimentalAssets?: string | undefined;
},
config: Config,
command: "dev" | "deploy" | "versions upload" | "types"
): Promise {
let file: string;
let directory = process.cwd();
+
if (args.script) {
// If the script name comes from the command line it is relative to the current working directory.
file = path.resolve(args.script);
@@ -55,13 +56,10 @@ export async function getEntry(
? path.resolve(config.site?.["entry-point"])
: // site.entry-point could be a directory
path.resolve(config.site?.["entry-point"], "index.js");
- } else if (
- args.legacyAssets ||
- config.legacy_assets ||
- args.experimentalAssets ||
- config.experimental_assets
- ) {
+ } else if (args.legacyAssets || config.legacy_assets) {
file = path.resolve(getBasePath(), "templates/no-op-worker.js");
+ } else if (args.experimentalAssets || config.experimental_assets) {
+ file = path.resolve(getBasePath(), "templates/no-op-assets-worker.ts");
} else {
throw new UserError(
`Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler ${command} path/to/script\`) or the \`main\` config field.`
diff --git a/packages/wrangler/src/dev.tsx b/packages/wrangler/src/dev.tsx
index 2fa09c157275..286833ef6bdf 100644
--- a/packages/wrangler/src/dev.tsx
+++ b/packages/wrangler/src/dev.tsx
@@ -562,6 +562,7 @@ export async function startDev(args: StartDevOptions) {
"--local is no longer required and will be removed in a future version.\n`wrangler dev` now uses the local Cloudflare Workers runtime by default. 🎉"
);
}
+
if (args.experimentalLocal) {
logger.warn(
"--experimental-local is no longer required and will be removed in a future version.\n`wrangler dev` now uses the local Cloudflare Workers runtime by default. 🎉"
@@ -574,6 +575,7 @@ export async function startDev(args: StartDevOptions) {
"Passing --inspect is unnecessary, now you can always connect to devtools."
);
}
+
if (args.experimentalPublic) {
throw new UserError(
"The --experimental-public field has been deprecated, try --legacy-assets instead."
@@ -594,6 +596,21 @@ export async function startDev(args: StartDevOptions) {
);
}
+ const experimentalAssets = processExperimentalAssetsArg(args, config);
+ if (experimentalAssets) {
+ args.forceLocal = true;
+ }
+
+ /*
+ * - `config.legacy_assets` conflates `legacy_assets` and `assets`
+ * - `args.legacyAssets` conflates `legacy-assets` and `assets`
+ */
+ if ((args.legacyAssets || config.legacy_assets) && experimentalAssets) {
+ throw new UserError(
+ "Cannot use Legacy Assets and Experimental Assets in the same Worker."
+ );
+ }
+
const projectRoot = configPath && path.dirname(configPath);
const devEnv = new DevEnv();
@@ -770,6 +787,9 @@ export async function startDev(args: StartDevOptions) {
legacyAssets: (configParam) => configParam.legacy_assets,
enableServiceEnvironments: !(args.legacyEnv ?? true),
},
+ experimental: {
+ assets: experimentalAssets,
+ },
} satisfies StartDevWorkerInput);
void metrics.sendMetricsEvent(
@@ -803,11 +823,6 @@ export async function startDev(args: StartDevOptions) {
});
}
- const experimentalAssets = processExperimentalAssetsArg(args, config);
- if (experimentalAssets) {
- args.forceLocal = true;
- }
-
const {
entry,
upstreamProtocol,
@@ -882,6 +897,7 @@ export async function startDev(args: StartDevOptions) {
}
legacyAssetPaths={legacyAssetPaths}
legacyAssetsConfig={configParam.legacy_assets}
+ experimentalAssets={experimentalAssets}
initialPort={
args.port ?? configParam.dev.port ?? (await getLocalPort())
}
@@ -1044,6 +1060,7 @@ export async function startApiDev(args: StartDevOptions) {
args.accountId ?? configParam.account_id ?? getAccountFromCache()?.id,
legacyAssetPaths: legacyAssetPaths,
legacyAssetsConfig: configParam.legacy_assets,
+ experimentalAssets: undefined,
//port can be 0, which means to use a random port
initialPort: args.port ?? configParam.dev.port ?? (await getLocalPort()),
initialIp: args.ip ?? configParam.dev.ip,
@@ -1181,6 +1198,28 @@ export async function validateDevServerSettings(
args: StartDevOptions,
config: Config
) {
+ /*
+ * - `args.legacyAssets` conflates `legacy-assets` and `assets`
+ * - `config.legacy_assets` conflates `legacy_assets` and `assets`
+ */
+ if (
+ (args.legacyAssets || config.legacy_assets) &&
+ (args.site || config.site)
+ ) {
+ throw new UserError(
+ "Cannot use Legacy Assets and Workers Sites in the same Worker."
+ );
+ }
+
+ if (
+ (args.experimentalAssets || config.experimental_assets) &&
+ (args.site || config.site)
+ ) {
+ throw new UserError(
+ "Cannot use Experimental Assets and Workers Sites in the same Worker."
+ );
+ }
+
const entry = await getEntry(
{
legacyAssets: args.legacyAssets,
@@ -1231,18 +1270,6 @@ export async function validateDevServerSettings(
);
}
- if (
- (args.legacyAssets ||
- config.legacy_assets ||
- args.experimentalAssets ||
- config.experimental_assets) &&
- (args.site || config.site)
- ) {
- throw new UserError(
- "Cannot use Assets and Workers Sites in the same Worker."
- );
- }
-
const upstreamProtocol =
args.upstreamProtocol ?? config.dev.upstream_protocol;
if (upstreamProtocol === "http" && args.remote) {
diff --git a/packages/wrangler/src/dev/dev.tsx b/packages/wrangler/src/dev/dev.tsx
index a6da138b7e56..0c7dcceac2a7 100644
--- a/packages/wrangler/src/dev/dev.tsx
+++ b/packages/wrangler/src/dev/dev.tsx
@@ -42,7 +42,7 @@ import type {
Trigger,
} from "../api";
import type { Config } from "../config";
-import type { Route } from "../config/environment";
+import type { ExperimentalAssets, Route } from "../config/environment";
import type { Entry } from "../deployment-bundle/entry";
import type { NodeJSCompatMode } from "../deployment-bundle/node-compat";
import type { CfModule, CfWorkerInit } from "../deployment-bundle/worker";
@@ -233,6 +233,7 @@ export type DevProps = {
isWorkersSite: boolean;
legacyAssetPaths: LegacyAssetPaths | undefined;
legacyAssetsConfig: Config["legacy_assets"];
+ experimentalAssets: ExperimentalAssets | undefined;
compatibilityDate: string;
compatibilityFlags: string[] | undefined;
usageModel: "bundled" | "unbound" | undefined;
@@ -479,6 +480,9 @@ function DevSession(props: DevSessionProps) {
capnp: props.bindings.unsafe?.capnp,
metadata: props.bindings.unsafe?.metadata,
},
+ experimental: {
+ assets: props.experimentalAssets,
+ },
} satisfies StartDevWorkerOptions;
}, [
props.routes,
@@ -493,6 +497,7 @@ function DevSession(props: DevSessionProps) {
props.isWorkersSite,
props.local,
props.legacyAssetsConfig,
+ props.experimentalAssets,
props.processEntrypoint,
props.additionalModules,
props.env,
@@ -684,6 +689,7 @@ function DevSession(props: DevSessionProps) {
bindings={props.bindings}
workerDefinitions={workerDefinitions}
legacyAssetPaths={props.legacyAssetPaths}
+ experimentalAssets={props.experimentalAssets}
initialPort={undefined} // hard-code for userworker, DevEnv-ProxyWorker now uses this prop value
initialIp={"127.0.0.1"} // hard-code for userworker, DevEnv-ProxyWorker now uses this prop value
rules={props.rules}
diff --git a/packages/wrangler/src/dev/local.tsx b/packages/wrangler/src/dev/local.tsx
index 612ce77b4459..66e428bc32bf 100644
--- a/packages/wrangler/src/dev/local.tsx
+++ b/packages/wrangler/src/dev/local.tsx
@@ -7,6 +7,7 @@ import { logger } from "../logger";
import { DEFAULT_WORKER_NAME, MiniflareServer } from "./miniflare";
import type { ProxyData } from "../api";
import type { Config } from "../config";
+import type { ExperimentalAssets } from "../config/environment";
import type {
CfDurableObject,
CfScriptFormat,
@@ -31,6 +32,7 @@ export interface LocalProps {
bindings: CfWorkerInit["bindings"];
workerDefinitions: WorkerRegistry | undefined;
legacyAssetPaths: LegacyAssetPaths | undefined;
+ experimentalAssets: ExperimentalAssets | undefined;
initialPort: number | undefined;
initialIp: string;
rules: Config["rules"];
@@ -90,6 +92,7 @@ export async function localPropsToConfigBundle(
bindings: props.bindings,
workerDefinitions: props.workerDefinitions,
legacyAssetPaths: props.legacyAssetPaths,
+ experimentalAssets: props.experimentalAssets,
initialPort: props.initialPort,
initialIp: props.initialIp,
rules: props.rules,
diff --git a/packages/wrangler/src/dev/miniflare.ts b/packages/wrangler/src/dev/miniflare.ts
index c3bb37498900..674cc8fd5404 100644
--- a/packages/wrangler/src/dev/miniflare.ts
+++ b/packages/wrangler/src/dev/miniflare.ts
@@ -1,6 +1,6 @@
import assert from "node:assert";
import { randomUUID } from "node:crypto";
-import path from "node:path";
+import path, { dirname } from "node:path";
import * as esmLexer from "es-module-lexer";
import {
CoreHeaders,
@@ -16,6 +16,7 @@ import {
EXTERNAL_AI_WORKER_NAME,
EXTERNAL_AI_WORKER_SCRIPT,
} from "../ai/fetcher";
+import { readConfig } from "../config";
import { ModuleTypeToRuleType } from "../deployment-bundle/module-collection";
import { withSourceURLs } from "../deployment-bundle/source-url";
import { UserError } from "../errors";
@@ -24,6 +25,7 @@ import { getSourceMappedString } from "../sourcemap";
import { updateCheck } from "../update-check";
import type { ServiceFetch } from "../api";
import type { Config } from "../config";
+import type { ExperimentalAssets } from "../config/environment";
import type {
CfD1Database,
CfDurableObject,
@@ -172,6 +174,7 @@ export interface ConfigBundle {
bindings: CfWorkerInit["bindings"];
workerDefinitions: WorkerRegistry | undefined;
legacyAssetPaths: LegacyAssetPaths | undefined;
+ experimentalAssets: ExperimentalAssets | undefined;
initialPort: Port;
initialIp: string;
rules: Config["rules"];
@@ -374,7 +377,7 @@ type MiniflareBindingsConfig = Pick<
| "services"
| "serviceBindings"
> &
- Partial>;
+ Partial>;
// TODO(someday): would be nice to type these methods more, can we export types for
// each plugin options schema and use those
@@ -408,7 +411,9 @@ export function buildMiniflareBindingOptions(config: MiniflareBindingsConfig): {
// Setup service bindings to external services
const serviceBindings: NonNullable = {
...config.serviceBindings,
+ ...(config.experimentalAssets ? { ASSET_SERVER: "asset-server" } : {}),
};
+
const notFoundServices = new Set();
for (const service of config.services ?? []) {
if (service.service === config.name) {
@@ -837,6 +842,43 @@ export async function buildMiniflareOptions(
}
}
+ const assetServerModulePath = require.resolve(
+ "@cloudflare/workers-shared/dist/asset-server-worker.mjs"
+ );
+ const assetServerConfigPath = require.resolve(
+ "@cloudflare/workers-shared/asset-server-worker/wrangler.toml"
+ );
+ let assetServerConfig: Config | undefined;
+
+ try {
+ assetServerConfig = readConfig(assetServerConfigPath, {});
+ } catch (err) {
+ throw new UserError(
+ "Failed to read the Asset Server Worker configuration file.\n" + `${err}`
+ );
+ }
+
+ const assetServerWorker: WorkerOptions | undefined = config.experimentalAssets
+ ? {
+ name: assetServerConfig?.name,
+ compatibilityDate: assetServerConfig?.compatibility_date,
+ compatibilityFlags: assetServerConfig?.compatibility_flags,
+ modulesRoot: dirname(assetServerModulePath),
+ modules: [
+ {
+ type: "ESModule",
+ path: assetServerModulePath,
+ },
+ ],
+ unsafeDirectSockets: [
+ {
+ host: "127.0.0.1",
+ port: 0,
+ },
+ ],
+ }
+ : undefined;
+
const upstream =
typeof config.localUpstream === "string"
? `${config.upstreamProtocol}://${config.localUpstream}`
@@ -879,6 +921,9 @@ export async function buildMiniflareOptions(
proxy: true,
})),
},
+ ...(config.experimentalAssets
+ ? [assetServerWorker as WorkerOptions]
+ : []),
...externalWorkers,
],
};
@@ -947,9 +992,11 @@ export class MiniflareServer extends TypedEventTarget {
config,
this.#proxyToUserWorkerAuthenticationSecret
);
+
if (opts?.signal?.aborted) {
return;
}
+
if (this.#mf === undefined) {
this.#mf = new Miniflare(options);
} else {
@@ -981,6 +1028,7 @@ export class MiniflareServer extends TypedEventTarget {
this.dispatchEvent(new ErrorEvent("error", { error }));
}
}
+
onBundleUpdate(config: ConfigBundle, opts?: Abortable): Promise {
return this.#mutex.runWith(() => this.#onBundleUpdate(config, opts));
}
diff --git a/packages/wrangler/src/dev/start-server.ts b/packages/wrangler/src/dev/start-server.ts
index 831ecc523f1e..92ca4e693b58 100644
--- a/packages/wrangler/src/dev/start-server.ts
+++ b/packages/wrangler/src/dev/start-server.ts
@@ -266,6 +266,7 @@ export async function startDevServer(
compatibilityFlags: props.compatibilityFlags,
bindings: props.bindings,
legacyAssetPaths: props.legacyAssetPaths,
+ experimentalAssets: props.experimentalAssets,
initialPort: undefined, // hard-code for userworker, DevEnv-ProxyWorker now uses this prop value
initialIp: "127.0.0.1", // hard-code for userworker, DevEnv-ProxyWorker now uses this prop value
rules: props.rules,
diff --git a/packages/wrangler/templates/no-op-assets-worker.ts b/packages/wrangler/templates/no-op-assets-worker.ts
new file mode 100644
index 000000000000..7f9a0636d0dc
--- /dev/null
+++ b/packages/wrangler/templates/no-op-assets-worker.ts
@@ -0,0 +1,33 @@
+/**
+ * This Worker is used as a default entry-point for Assets-only
+ * Workers. It proxies the request directly on to the Asset Sever
+ * Worker service binding.
+ *
+ * In an Assets-only Workers world, we want to enable users
+ * to deploy a Worker with Assets without ever having to provide
+ * a User Worker.
+ *
+ * ```bash
+ * wrangler dev --experimental-assets dist
+ * wrangler deploy --experimental-assets dist
+ * ```
+ *
+ * ```toml
+ * name = "assets-only-worker"
+ * compatibility_date = "2024-01-01"
+ * ```
+ *
+ * Without a user-defined Worker, which usually serves as the entry
+ * point in the bundling process, wrangler needs to default to some
+ * other entry-point Worker for all intents and purposes. This is what
+ * this Worker is.
+ */
+type Env = {
+ ASSET_SERVER: Fetcher;
+};
+
+export default {
+ async fetch(request: Request, env: Env) {
+ return env.ASSET_SERVER.fetch(request);
+ },
+};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 59bfcecec8bd..0870a2a4c89b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -668,6 +668,21 @@ importers:
fixtures/workers-chat-demo: {}
+ fixtures/workers-with-assets:
+ devDependencies:
+ '@cloudflare/workers-tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/workers-tsconfig
+ '@cloudflare/workers-types':
+ specifier: ^4.20240725.0
+ version: 4.20240725.0
+ undici:
+ specifier: ^5.28.4
+ version: 5.28.4
+ wrangler:
+ specifier: workspace:*
+ version: link:../../packages/wrangler
+
packages/cli:
devDependencies:
'@clack/core':
@@ -684,10 +699,10 @@ importers:
version: link:../workers-tsconfig
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.0
- version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/parser':
specifier: ^6.9.0
- version: 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(eslint@8.57.0)(typescript@5.5.4)
chalk:
specifier: ^5.2.0
version: 5.3.0
@@ -759,10 +774,10 @@ importers:
version: 17.0.24
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.0
- version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/parser':
specifier: ^6.9.0
- version: 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(eslint@8.57.0)(typescript@5.5.4)
chalk:
specifier: ^5.2.0
version: 5.2.0
@@ -816,7 +831,7 @@ importers:
version: 5.28.4
vite-tsconfig-paths:
specifier: ^4.0.8
- version: 4.2.0(typescript@5.5.2)(vite@5.0.12(@types/node@20.8.3))
+ version: 4.2.0(typescript@5.5.4)(vite@5.0.12(@types/node@20.8.3))
which-pm-runs:
specifier: ^1.1.0
version: 1.1.0
@@ -870,7 +885,7 @@ importers:
dependencies:
'@typescript-eslint/parser':
specifier: ^6.9.0
- version: 6.10.0(eslint@8.49.0)(typescript@5.5.2)
+ version: 6.10.0(eslint@8.49.0)(typescript@5.5.4)
eslint:
specifier: ^8.49.0
version: 8.49.0
@@ -879,7 +894,7 @@ importers:
version: 2.0.10(eslint@8.49.0)
eslint-plugin-import:
specifier: 2.26.x
- version: 2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)
+ version: 2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)
eslint-plugin-no-only-tests:
specifier: ^3.1.0
version: 3.1.0
@@ -891,11 +906,11 @@ importers:
version: 4.6.0(eslint@8.49.0)
eslint-plugin-unused-imports:
specifier: ^3.0.0
- version: 3.0.0(@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)
+ version: 3.0.0(@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)
devDependencies:
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.0
- version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)(typescript@5.5.2)
+ version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)(typescript@5.5.4)
packages/format-errors:
devDependencies:
@@ -1032,10 +1047,10 @@ importers:
version: 8.5.10
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.0
- version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/parser':
specifier: ^6.9.0
- version: 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(eslint@8.57.0)(typescript@5.5.4)
ava:
specifier: ^6.0.1
version: 6.1.1(@ava/typescript@4.1.0)(encoding@0.1.13)
@@ -1065,7 +1080,7 @@ importers:
version: 4.1.0(eslint@8.57.0)
eslint-plugin-import:
specifier: 2.26.x
- version: 2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)
+ version: 2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)
eslint-plugin-prettier:
specifier: ^5.0.1
version: 5.0.1(eslint-config-prettier@9.0.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5)
@@ -1419,10 +1434,10 @@ importers:
version: 9.0.4
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.0
- version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/parser':
specifier: ^6.9.0
- version: 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(eslint@8.57.0)(typescript@5.5.4)
'@vitejs/plugin-react':
specifier: ^4.0.1
version: 4.0.4(vite@5.0.12(@types/node@20.12.12))
@@ -1448,6 +1463,21 @@ importers:
specifier: workspace:^
version: link:../wrangler
+ packages/workers-shared:
+ devDependencies:
+ concurrently:
+ specifier: ^8.2.2
+ version: 8.2.2
+ esbuild:
+ specifier: 0.17.19
+ version: 0.17.19
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
+ typescript:
+ specifier: ^5.5.4
+ version: 5.5.4
+
packages/workers-tsconfig: {}
packages/workers.new:
@@ -1544,6 +1574,9 @@ importers:
'@cloudflare/types':
specifier: ^6.18.4
version: 6.18.4(react@18.2.0)
+ '@cloudflare/workers-shared':
+ specifier: workspace:*
+ version: link:../workers-shared
'@cloudflare/workers-tsconfig':
specifier: workspace:*
version: link:../workers-tsconfig
@@ -1711,7 +1744,7 @@ importers:
version: 9.3.1
msw:
specifier: ^2.3.0
- version: 2.3.0(typescript@5.5.2)
+ version: 2.3.0(typescript@5.5.4)
open:
specifier: ^8.4.0
version: 8.4.0
@@ -1810,10 +1843,10 @@ importers:
version: link:../packages/workers-tsconfig
'@typescript-eslint/eslint-plugin':
specifier: ^6.9.0
- version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/parser':
specifier: ^6.9.0
- version: 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ version: 6.10.0(eslint@8.57.0)(typescript@5.5.4)
find-up:
specifier: ^6.3.0
version: 6.3.0
@@ -5443,6 +5476,11 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
@@ -5988,6 +6026,10 @@ packages:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
+ jackspeak@4.0.1:
+ resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==}
+ engines: {node: 20 || >=22}
+
javascript-time-ago@2.5.7:
resolution: {integrity: sha512-EGvh6K4hpJz0S0aZinbW2EfXDqT/JBB84HfMOFDTzGg7yjpjql9feSgtlG1JQ6b6/NkIxl+PoKSUTEMsatTuTg==}
@@ -6226,6 +6268,10 @@ packages:
resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==}
engines: {node: 14 || >=16.14}
+ lru-cache@11.0.0:
+ resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==}
+ engines: {node: 20 || >=22}
+
lru-cache@4.1.5:
resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
@@ -6368,6 +6414,10 @@ packages:
engines: {node: '>=16.13'}
hasBin: true
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.0.8:
resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==}
@@ -6405,6 +6455,10 @@ packages:
resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==}
engines: {node: '>=16 || 14 >=14.17'}
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
@@ -6766,6 +6820,9 @@ packages:
resolution: {integrity: sha512-GYTTew2slBcYdvRHqjhwaaydVMvn/qrGC323+nKclYioNSLTDUM/lGgtGTgyHVtYcozb+XkE8CNhwcraOmZ9Mg==}
engines: {node: '>=18'}
+ package-json-from-dist@1.0.0:
+ resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
+
package-json@8.1.1:
resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==}
engines: {node: '>=14.16'}
@@ -6855,6 +6912,10 @@ packages:
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
engines: {node: '>=16 || 14 >=14.17'}
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
path-to-regexp@0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
@@ -7402,6 +7463,11 @@ packages:
engines: {node: '>=14'}
hasBin: true
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
roarr@7.11.0:
resolution: {integrity: sha512-DKiMaEYHoOZ0JyD4Ohr5KRnqybQ162s3ZL/WNO9oy6EUszYvpp0eLYJErc/U4NI96HYnHsbROhFaH4LYuJPnDg==}
engines: {node: '>=12.0'}
@@ -8132,6 +8198,11 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ typescript@5.5.4:
+ resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
ufo@1.5.3:
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
@@ -10796,13 +10867,13 @@ snapshots:
'@types/yoga-layout@1.9.2': {}
- '@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)(typescript@5.5.2)':
+ '@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)(typescript@5.5.4)':
dependencies:
'@eslint-community/regexpp': 4.10.1
- '@typescript-eslint/parser': 6.10.0(eslint@8.49.0)(typescript@5.5.2)
+ '@typescript-eslint/parser': 6.10.0(eslint@8.49.0)(typescript@5.5.4)
'@typescript-eslint/scope-manager': 6.10.0
- '@typescript-eslint/type-utils': 6.10.0(eslint@8.49.0)(typescript@5.5.2)
- '@typescript-eslint/utils': 6.10.0(eslint@8.49.0)(typescript@5.5.2)
+ '@typescript-eslint/type-utils': 6.10.0(eslint@8.49.0)(typescript@5.5.4)
+ '@typescript-eslint/utils': 6.10.0(eslint@8.49.0)(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 6.10.0
debug: 4.3.5(supports-color@9.2.2)
eslint: 8.49.0
@@ -10810,19 +10881,19 @@ snapshots:
ignore: 5.3.1
natural-compare: 1.4.0
semver: 7.5.4
- ts-api-utils: 1.0.3(typescript@5.5.2)
+ ts-api-utils: 1.0.3(typescript@5.5.4)
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)':
+ '@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)':
dependencies:
'@eslint-community/regexpp': 4.10.1
- '@typescript-eslint/parser': 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ '@typescript-eslint/parser': 6.10.0(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/scope-manager': 6.10.0
- '@typescript-eslint/type-utils': 6.10.0(eslint@8.57.0)(typescript@5.5.2)
- '@typescript-eslint/utils': 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ '@typescript-eslint/type-utils': 6.10.0(eslint@8.57.0)(typescript@5.5.4)
+ '@typescript-eslint/utils': 6.10.0(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 6.10.0
debug: 4.3.5(supports-color@9.2.2)
eslint: 8.57.0
@@ -10830,35 +10901,35 @@ snapshots:
ignore: 5.3.1
natural-compare: 1.4.0
semver: 7.5.4
- ts-api-utils: 1.0.3(typescript@5.5.2)
+ ts-api-utils: 1.0.3(typescript@5.5.4)
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2)':
+ '@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4)':
dependencies:
'@typescript-eslint/scope-manager': 6.10.0
'@typescript-eslint/types': 6.10.0
- '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.2)
+ '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 6.10.0
debug: 4.3.5(supports-color@9.2.2)
eslint: 8.49.0
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2)':
+ '@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4)':
dependencies:
'@typescript-eslint/scope-manager': 6.10.0
'@typescript-eslint/types': 6.10.0
- '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.2)
+ '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 6.10.0
debug: 4.3.5(supports-color@9.2.2)
eslint: 8.57.0
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
@@ -10867,33 +10938,33 @@ snapshots:
'@typescript-eslint/types': 6.10.0
'@typescript-eslint/visitor-keys': 6.10.0
- '@typescript-eslint/type-utils@6.10.0(eslint@8.49.0)(typescript@5.5.2)':
+ '@typescript-eslint/type-utils@6.10.0(eslint@8.49.0)(typescript@5.5.4)':
dependencies:
- '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.2)
- '@typescript-eslint/utils': 6.10.0(eslint@8.49.0)(typescript@5.5.2)
+ '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.4)
+ '@typescript-eslint/utils': 6.10.0(eslint@8.49.0)(typescript@5.5.4)
debug: 4.3.5(supports-color@9.2.2)
eslint: 8.49.0
- ts-api-utils: 1.0.3(typescript@5.5.2)
+ ts-api-utils: 1.0.3(typescript@5.5.4)
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/type-utils@6.10.0(eslint@8.57.0)(typescript@5.5.2)':
+ '@typescript-eslint/type-utils@6.10.0(eslint@8.57.0)(typescript@5.5.4)':
dependencies:
- '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.2)
- '@typescript-eslint/utils': 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.4)
+ '@typescript-eslint/utils': 6.10.0(eslint@8.57.0)(typescript@5.5.4)
debug: 4.3.5(supports-color@9.2.2)
eslint: 8.57.0
- ts-api-utils: 1.0.3(typescript@5.5.2)
+ ts-api-utils: 1.0.3(typescript@5.5.4)
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@6.10.0': {}
- '@typescript-eslint/typescript-estree@6.10.0(typescript@5.5.2)':
+ '@typescript-eslint/typescript-estree@6.10.0(typescript@5.5.4)':
dependencies:
'@typescript-eslint/types': 6.10.0
'@typescript-eslint/visitor-keys': 6.10.0
@@ -10901,34 +10972,34 @@ snapshots:
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.4
- ts-api-utils: 1.0.3(typescript@5.5.2)
+ ts-api-utils: 1.0.3(typescript@5.5.4)
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@6.10.0(eslint@8.49.0)(typescript@5.5.2)':
+ '@typescript-eslint/utils@6.10.0(eslint@8.49.0)(typescript@5.5.4)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
'@types/json-schema': 7.0.13
'@types/semver': 7.5.1
'@typescript-eslint/scope-manager': 6.10.0
'@typescript-eslint/types': 6.10.0
- '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.2)
+ '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.4)
eslint: 8.49.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
- '@typescript-eslint/utils@6.10.0(eslint@8.57.0)(typescript@5.5.2)':
+ '@typescript-eslint/utils@6.10.0(eslint@8.57.0)(typescript@5.5.4)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.13
'@types/semver': 7.5.1
'@typescript-eslint/scope-manager': 6.10.0
'@typescript-eslint/types': 6.10.0
- '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.2)
+ '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.5.4)
eslint: 8.57.0
semver: 7.5.4
transitivePeerDependencies:
@@ -12375,21 +12446,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.7)(eslint@8.49.0):
+ eslint-module-utils@2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint@8.49.0):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 6.10.0(eslint@8.49.0)(typescript@5.5.2)
+ '@typescript-eslint/parser': 6.10.0(eslint@8.49.0)(typescript@5.5.4)
eslint: 8.49.0
eslint-import-resolver-node: 0.3.7
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.7)(eslint@8.57.0):
+ eslint-module-utils@2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ '@typescript-eslint/parser': 6.10.0(eslint@8.57.0)(typescript@5.5.4)
eslint: 8.57.0
eslint-import-resolver-node: 0.3.7
transitivePeerDependencies:
@@ -12401,7 +12472,7 @@ snapshots:
eslint-utils: 2.1.0
regexpp: 3.2.0
- eslint-plugin-import@2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0):
+ eslint-plugin-import@2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0):
dependencies:
array-includes: 3.1.6
array.prototype.flat: 1.3.1
@@ -12409,7 +12480,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.49.0
eslint-import-resolver-node: 0.3.7
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.7)(eslint@8.49.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint@8.49.0)
has: 1.0.3
is-core-module: 2.13.0
is-glob: 4.0.3
@@ -12418,13 +12489,13 @@ snapshots:
resolve: 1.22.2
tsconfig-paths: 3.14.1
optionalDependencies:
- '@typescript-eslint/parser': 6.10.0(eslint@8.49.0)(typescript@5.5.2)
+ '@typescript-eslint/parser': 6.10.0(eslint@8.49.0)(typescript@5.5.4)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-import@2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0):
+ eslint-plugin-import@2.26.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0):
dependencies:
array-includes: 3.1.6
array.prototype.flat: 1.3.1
@@ -12432,7 +12503,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.7
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.7)(eslint@8.57.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.7)(eslint@8.57.0)
has: 1.0.3
is-core-module: 2.13.0
is-glob: 4.0.3
@@ -12441,7 +12512,7 @@ snapshots:
resolve: 1.22.2
tsconfig-paths: 3.14.1
optionalDependencies:
- '@typescript-eslint/parser': 6.10.0(eslint@8.57.0)(typescript@5.5.2)
+ '@typescript-eslint/parser': 6.10.0(eslint@8.57.0)(typescript@5.5.4)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -12495,12 +12566,12 @@ snapshots:
dotenv: 16.0.3
eslint: 8.49.0
- eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0):
+ eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0):
dependencies:
eslint: 8.49.0
eslint-rule-composer: 0.3.0
optionalDependencies:
- '@typescript-eslint/eslint-plugin': 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.2))(eslint@8.49.0)(typescript@5.5.2)
+ '@typescript-eslint/eslint-plugin': 6.10.0(@typescript-eslint/parser@6.10.0(eslint@8.49.0)(typescript@5.5.4))(eslint@8.49.0)(typescript@5.5.4)
eslint-rule-composer@0.3.0: {}
@@ -13066,6 +13137,15 @@ snapshots:
minipass: 6.0.2
path-scurry: 1.10.1
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.1.1
+ jackspeak: 4.0.1
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 2.0.0
+
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -13639,6 +13719,12 @@ snapshots:
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
+ jackspeak@4.0.1:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
javascript-time-ago@2.5.7:
dependencies:
relative-time-format: 1.1.4
@@ -13862,6 +13948,8 @@ snapshots:
lru-cache@10.1.0: {}
+ lru-cache@11.0.0: {}
+
lru-cache@4.1.5:
dependencies:
pseudomap: 1.0.2
@@ -13992,6 +14080,10 @@ snapshots:
- supports-color
- utf-8-validate
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.0.8:
dependencies:
brace-expansion: 1.1.11
@@ -14030,6 +14122,8 @@ snapshots:
minipass@6.0.2: {}
+ minipass@7.1.2: {}
+
minizlib@2.1.2:
dependencies:
minipass: 3.3.6
@@ -14069,7 +14163,7 @@ snapshots:
ms@2.1.3: {}
- msw@2.3.0(typescript@5.5.2):
+ msw@2.3.0(typescript@5.5.4):
dependencies:
'@bundled-es-modules/cookie': 2.0.0
'@bundled-es-modules/statuses': 1.0.1
@@ -14089,7 +14183,7 @@ snapshots:
type-fest: 4.18.2
yargs: 17.7.2
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
mustache@4.2.0: {}
@@ -14425,6 +14519,8 @@ snapshots:
find-up-simple: 1.0.0
load-json-file: 7.0.1
+ package-json-from-dist@1.0.0: {}
+
package-json@8.1.1:
dependencies:
got: 12.6.1
@@ -14513,6 +14609,11 @@ snapshots:
lru-cache: 10.1.0
minipass: 6.0.2
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.0
+ minipass: 7.1.2
+
path-to-regexp@0.1.7: {}
path-to-regexp@6.2.0: {}
@@ -15073,6 +15174,11 @@ snapshots:
dependencies:
glob: 10.3.10
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.0
+
roarr@7.11.0:
dependencies:
boolean: 3.2.0
@@ -15658,9 +15764,9 @@ snapshots:
trim-newlines@3.0.1: {}
- ts-api-utils@1.0.3(typescript@5.5.2):
+ ts-api-utils@1.0.3(typescript@5.5.4):
dependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
ts-dedent@2.2.0: {}
@@ -15697,9 +15803,9 @@ snapshots:
lodash: 4.17.21
prettier: 2.7.1
- tsconfck@2.1.1(typescript@5.5.2):
+ tsconfck@2.1.1(typescript@5.5.4):
optionalDependencies:
- typescript: 5.5.2
+ typescript: 5.5.4
tsconfig-paths@3.14.1:
dependencies:
@@ -15846,6 +15952,8 @@ snapshots:
typescript@5.5.2: {}
+ typescript@5.5.4: {}
+
ufo@1.5.3: {}
uglify-js@3.17.4:
@@ -16028,11 +16136,11 @@ snapshots:
connect-history-api-fallback: 1.6.0
vite: 5.0.12(@types/node@20.12.12)
- vite-tsconfig-paths@4.2.0(typescript@5.5.2)(vite@5.0.12(@types/node@20.8.3)):
+ vite-tsconfig-paths@4.2.0(typescript@5.5.4)(vite@5.0.12(@types/node@20.8.3)):
dependencies:
debug: 4.3.4(supports-color@9.2.2)
globrex: 0.1.2
- tsconfck: 2.1.1(typescript@5.5.2)
+ tsconfck: 2.1.1(typescript@5.5.4)
optionalDependencies:
vite: 5.0.12(@types/node@20.8.3)
transitivePeerDependencies: