diff --git a/.changeset/async-read-config.md b/.changeset/async-read-config.md new file mode 100644 index 000000000000..dd73aae87d90 --- /dev/null +++ b/.changeset/async-read-config.md @@ -0,0 +1,13 @@ +--- +"wrangler": minor +"@cloudflare/workers-utils": minor +--- + +Add new async config reading APIs to support future code-based config files. + +- `unstable_readConfigAsync` - Async version of `unstable_readConfig` that will support code-based config files (`.ts`, `.js`) +- `experimental_readRawConfigAsync` - Async version of `experimental_readRawConfig` + +The existing sync APIs (`unstable_readConfig`, `experimental_readRawConfig`) continue to work unchanged for data file formats (`.toml`, `.json`, `.jsonc`). + +In Wrangler v5, the sync APIs will be removed and the async APIs will become the default. diff --git a/packages/vite-plugin-cloudflare/playground/bindings/__tests__/shortcuts.spec.ts b/packages/vite-plugin-cloudflare/playground/bindings/__tests__/shortcuts.spec.ts index e7961fbcf395..494bdbc78540 100644 --- a/packages/vite-plugin-cloudflare/playground/bindings/__tests__/shortcuts.spec.ts +++ b/packages/vite-plugin-cloudflare/playground/bindings/__tests__/shortcuts.spec.ts @@ -28,14 +28,14 @@ describe.skipIf(!satisfiesViteVersion("7.2.7"))("shortcuts", () => { process.stdin.isTTY = false; }); - test("display binding shortcut hint", () => { + test("display binding shortcut hint", async () => { // Set up the shortcut wrapper (after stubs are in place from beforeAll) const mockContext = new PluginContext({ hasShownWorkerConfigWarnings: false, isRestartingDevServer: false, }); mockContext.setResolvedPluginConfig( - resolvePluginConfig( + await resolvePluginConfig( { configPath: path.resolve(__dirname, "../wrangler.jsonc"), }, @@ -63,7 +63,7 @@ describe.skipIf(!satisfiesViteVersion("7.2.7"))("shortcuts", () => { "press b + enter to list configured Cloudflare bindings" ); }); - test("prints bindings with a single Worker", () => { + test("prints bindings with a single Worker", async () => { // Create a test server with a spy on bindCLIShortcuts const mockBindCLIShortcuts = vi.spyOn(viteServer, "bindCLIShortcuts"); // Create mock plugin context @@ -73,7 +73,7 @@ describe.skipIf(!satisfiesViteVersion("7.2.7"))("shortcuts", () => { }); mockContext.setResolvedPluginConfig( - resolvePluginConfig( + await resolvePluginConfig( { configPath: path.resolve(__dirname, "../wrangler.jsonc"), }, @@ -119,7 +119,7 @@ describe.skipIf(!satisfiesViteVersion("7.2.7"))("shortcuts", () => { `); }); - test("prints bindings with multi Workers", () => { + test("prints bindings with multi Workers", async () => { // Create a test server with a spy on bindCLIShortcuts const mockBindCLIShortcuts = vi.spyOn(viteServer, "bindCLIShortcuts"); // Create mock plugin context @@ -129,7 +129,7 @@ describe.skipIf(!satisfiesViteVersion("7.2.7"))("shortcuts", () => { }); mockContext.setResolvedPluginConfig( - resolvePluginConfig( + await resolvePluginConfig( { configPath: path.resolve(__dirname, "../wrangler.jsonc"), auxiliaryWorkers: [ diff --git a/packages/vite-plugin-cloudflare/src/__tests__/get-worker-config.spec.ts b/packages/vite-plugin-cloudflare/src/__tests__/get-worker-config.spec.ts index af127b2b584b..4f117ce746c2 100644 --- a/packages/vite-plugin-cloudflare/src/__tests__/get-worker-config.spec.ts +++ b/packages/vite-plugin-cloudflare/src/__tests__/get-worker-config.spec.ts @@ -6,8 +6,8 @@ import { } from "../workers-configs"; describe("readWorkerConfigFromFile", () => { - test("should return a simple raw config", () => { - const { raw } = readWorkerConfigFromFile( + test("should return a simple raw config", async () => { + const { raw } = await readWorkerConfigFromFile( fileURLToPath(new URL("fixtures/simple-wrangler.jsonc", import.meta.url)), undefined ); @@ -34,8 +34,8 @@ describe("readWorkerConfigFromFile", () => { expect(raw.tsconfig).toBeUndefined(); }); - test("should return a simple config without non-applicable fields", () => { - const { config } = readWorkerConfigFromFile( + test("should return a simple config without non-applicable fields", async () => { + const { config } = await readWorkerConfigFromFile( fileURLToPath(new URL("fixtures/simple-wrangler.jsonc", import.meta.url)), undefined ); @@ -44,8 +44,8 @@ describe("readWorkerConfigFromFile", () => { expect("preserve_file_names" in config).toBeFalsy(); }); - test("should not return any non-applicable config when there isn't any", () => { - const { nonApplicable } = readWorkerConfigFromFile( + test("should not return any non-applicable config when there isn't any", async () => { + const { nonApplicable } = await readWorkerConfigFromFile( fileURLToPath(new URL("fixtures/simple-wrangler.jsonc", import.meta.url)), undefined ); @@ -55,8 +55,8 @@ describe("readWorkerConfigFromFile", () => { }); }); - test("should read a simple wrangler config file", () => { - const { config, nonApplicable } = readWorkerConfigFromFile( + test("should read a simple wrangler config file", async () => { + const { config, nonApplicable } = await readWorkerConfigFromFile( fileURLToPath(new URL("fixtures/simple-wrangler.jsonc", import.meta.url)), undefined ); @@ -84,8 +84,8 @@ describe("readWorkerConfigFromFile", () => { }); }); - test("should collect non applicable configs", () => { - const { config, raw, nonApplicable } = readWorkerConfigFromFile( + test("should collect non applicable configs", async () => { + const { config, raw, nonApplicable } = await readWorkerConfigFromFile( fileURLToPath( new URL( "fixtures/wrangler-with-fields-to-ignore.jsonc", @@ -159,11 +159,11 @@ describe("readWorkerConfigFromFile", () => { }); describe("resolveWorkerType", () => { - test("should throw if the provided main config doesn't point to an existing file", () => { + test("should throw if the provided main config doesn't point to an existing file", async () => { const configPath = fileURLToPath( new URL("fixtures/non-existing-main-wrangler.jsonc", import.meta.url) ); - const { config, raw, nonApplicable } = readWorkerConfigFromFile( + const { config, raw, nonApplicable } = await readWorkerConfigFromFile( configPath, undefined ); diff --git a/packages/vite-plugin-cloudflare/src/__tests__/resolve-plugin-config.spec.ts b/packages/vite-plugin-cloudflare/src/__tests__/resolve-plugin-config.spec.ts index 559eb09f2005..4c2970f61c23 100644 --- a/packages/vite-plugin-cloudflare/src/__tests__/resolve-plugin-config.spec.ts +++ b/packages/vite-plugin-cloudflare/src/__tests__/resolve-plugin-config.spec.ts @@ -38,7 +38,7 @@ describe("resolvePluginConfig - auxiliary workers", () => { return configPath; } - test("should resolve auxiliary worker from config file", () => { + test("should resolve auxiliary worker from config file", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); // Create auxiliary worker config @@ -60,16 +60,16 @@ describe("resolvePluginConfig - auxiliary workers", () => { auxiliaryWorkers: [{ configPath: auxConfigPath }], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); expect(result.environmentNameToWorkerMap.get("aux_worker")).toBeDefined(); }); - test("should resolve inline auxiliary worker with config object", () => { + test("should resolve inline auxiliary worker with config object", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); // Create the inline worker's main file fs.writeFileSync(path.join(tempDir, "src/aux.ts"), "export default {}"); @@ -86,11 +86,11 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("inline_aux_worker"); @@ -100,7 +100,7 @@ describe("resolvePluginConfig - auxiliary workers", () => { expect(auxWorker?.config.main).toBe(path.join(tempDir, "src/aux.ts")); }); - test("should resolve inline auxiliary worker with config function", () => { + test("should resolve inline auxiliary worker with config function", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); // Create the inline worker's main file fs.writeFileSync(path.join(tempDir, "src/fn-aux.ts"), "export default {}"); @@ -117,18 +117,18 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("fn_aux_worker"); expect(auxWorker).toBeDefined(); expect(auxWorker?.config.name).toBe("fn-aux-worker"); }); - test("should auto-populate topLevelName from name if not set", () => { + test("should auto-populate topLevelName from name if not set", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); // Create the inline worker's main file fs.writeFileSync(path.join(tempDir, "src/aux.ts"), "export default {}"); @@ -145,11 +145,11 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("my_aux_worker"); expect(auxWorker).toBeDefined(); @@ -157,7 +157,7 @@ describe("resolvePluginConfig - auxiliary workers", () => { expect(auxWorker?.config.topLevelName).toBe("my-aux-worker"); }); - test("should apply config to file-based auxiliary worker", () => { + test("should apply config to file-based auxiliary worker", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); // Create auxiliary worker config with initial values @@ -186,11 +186,11 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("aux_worker"); expect(auxWorker).toBeDefined(); @@ -200,7 +200,7 @@ describe("resolvePluginConfig - auxiliary workers", () => { expect(auxWorker?.config.name).toBe("aux-worker"); }); - test("should pass entryWorkerConfig as second parameter to auxiliary worker config function", () => { + test("should pass entryWorkerConfig as second parameter to auxiliary worker config function", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); fs.writeFileSync(path.join(tempDir, "src/aux.ts"), "export default {}"); @@ -227,11 +227,11 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("aux_worker"); expect(auxWorker).toBeDefined(); @@ -240,7 +240,7 @@ describe("resolvePluginConfig - auxiliary workers", () => { expect(auxWorker?.config.compatibility_date).toBe("2024-01-01"); }); - test("should allow auxiliary worker to inherit entry worker compatibility_flags", () => { + test("should allow auxiliary worker to inherit entry worker compatibility_flags", async () => { // Create entry worker with compatibility_flags const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( @@ -271,11 +271,11 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("aux_worker"); expect(auxWorker).toBeDefined(); @@ -284,7 +284,7 @@ describe("resolvePluginConfig - auxiliary workers", () => { ); }); - test("should throw if inline auxiliary worker is missing required fields", () => { + test("should throw if inline auxiliary worker is missing required fields", async () => { const entryConfigPath = createEntryWorkerConfig(tempDir); const pluginConfig: PluginConfig = { @@ -298,9 +298,9 @@ describe("resolvePluginConfig - auxiliary workers", () => { ], }; - expect(() => + await expect( resolvePluginConfig(pluginConfig, { root: tempDir }, viteEnv) - ).toThrow(); + ).rejects.toThrow(); }); }); @@ -317,7 +317,7 @@ describe("resolvePluginConfig - entry worker config()", () => { const viteEnv = { mode: "development", command: "serve" as const }; - test("should convert assets-only worker to worker with server logic when config() adds main", () => { + test("should convert assets-only worker to worker with server logic when config() adds main", async () => { // Create a config file without main (assets-only) const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( @@ -340,11 +340,11 @@ describe("resolvePluginConfig - entry worker config()", () => { }, }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; // Should now be a worker with server logic, not assets-only expect(result.type).toBe("workers"); const entryWorker = result.environmentNameToWorkerMap.get( @@ -354,7 +354,7 @@ describe("resolvePluginConfig - entry worker config()", () => { expect(entryWorker?.config.main).toMatch(/index\.ts$/); }); - test("should allow config() function to add main field", () => { + test("should allow config() function to add main field", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -374,11 +374,11 @@ describe("resolvePluginConfig - entry worker config()", () => { }), }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const entryWorker = result.environmentNameToWorkerMap.get( result.entryWorkerEnvironmentName @@ -386,7 +386,7 @@ describe("resolvePluginConfig - entry worker config()", () => { expect(entryWorker).toBeDefined(); }); - test("should remain assets-only when config() does not add main", () => { + test("should remain assets-only when config() does not add main", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -403,7 +403,7 @@ describe("resolvePluginConfig - entry worker config()", () => { }, }; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -430,10 +430,10 @@ describe("resolvePluginConfig - zero-config mode", () => { const viteEnv = { mode: "development", command: "serve" as const }; - test("should return an assets-only config when no wrangler config exists", () => { + test("should return an assets-only config when no wrangler config exists", async () => { const pluginConfig: PluginConfig = {}; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -442,7 +442,7 @@ describe("resolvePluginConfig - zero-config mode", () => { expect(result.type).toBe("assets-only"); }); - test("should derive worker name from package.json name", () => { + test("should derive worker name from package.json name", async () => { fs.writeFileSync( path.join(tempDir, "package.json"), JSON.stringify({ name: "my-awesome-app" }) @@ -450,7 +450,7 @@ describe("resolvePluginConfig - zero-config mode", () => { const pluginConfig: PluginConfig = {}; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -462,7 +462,7 @@ describe("resolvePluginConfig - zero-config mode", () => { expect(assetsOnlyResult.config.topLevelName).toBe("my-awesome-app"); }); - test("should normalize invalid worker names from package.json", () => { + test("should normalize invalid worker names from package.json", async () => { fs.writeFileSync( path.join(tempDir, "package.json"), JSON.stringify({ name: "@scope/my_package_name" }) @@ -470,7 +470,7 @@ describe("resolvePluginConfig - zero-config mode", () => { const pluginConfig: PluginConfig = {}; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -482,7 +482,7 @@ describe("resolvePluginConfig - zero-config mode", () => { expect(assetsOnlyResult.config.name).toBe("scope-my-package-name"); }); - test("should fall back to directory name when package.json has no name", () => { + test("should fall back to directory name when package.json has no name", async () => { const namedDir = path.join(tempDir, "my-test-project"); fs.mkdirSync(namedDir); fs.writeFileSync( @@ -492,7 +492,7 @@ describe("resolvePluginConfig - zero-config mode", () => { const pluginConfig: PluginConfig = {}; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: namedDir }, viteEnv @@ -503,13 +503,13 @@ describe("resolvePluginConfig - zero-config mode", () => { expect(assetsOnlyResult.config.name).toBe("my-test-project"); }); - test("should fall back to directory name when no package.json exists", () => { + test("should fall back to directory name when no package.json exists", async () => { const namedDir = path.join(tempDir, "another-project"); fs.mkdirSync(namedDir); const pluginConfig: PluginConfig = {}; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: namedDir }, viteEnv @@ -520,10 +520,10 @@ describe("resolvePluginConfig - zero-config mode", () => { expect(assetsOnlyResult.config.name).toBe("another-project"); }); - test("should set a compatibility date in zero-config mode", () => { + test("should set a compatibility date in zero-config mode", async () => { const pluginConfig: PluginConfig = {}; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -536,7 +536,7 @@ describe("resolvePluginConfig - zero-config mode", () => { ); }); - test("should allow config() to add main in zero-config mode", () => { + test("should allow config() to add main in zero-config mode", async () => { fs.writeFileSync( path.join(tempDir, "package.json"), JSON.stringify({ name: "my-worker" }) @@ -550,11 +550,11 @@ describe("resolvePluginConfig - zero-config mode", () => { }, }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const entryWorker = result.environmentNameToWorkerMap.get( result.entryWorkerEnvironmentName @@ -577,7 +577,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { const viteEnv = { mode: "development", command: "serve" as const }; - test("should accept Wrangler config file with only name, filling in compatibility_date from defaults", () => { + test("should accept Wrangler config file with only name, filling in compatibility_date from defaults", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -591,7 +591,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { configPath, }; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -606,7 +606,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { ); }); - test("should accept Wrangler config file missing name when config() provides it", () => { + test("should accept Wrangler config file missing name when config() provides it", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -623,7 +623,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { }, }; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -634,7 +634,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { expect(assetsOnlyResult.config.name).toBe("configured-worker"); }); - test("should accept Wrangler config file missing compatibility_date when config() provides it", () => { + test("should accept Wrangler config file missing compatibility_date when config() provides it", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -651,7 +651,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { }, }; - const result = resolvePluginConfig( + const result = await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv @@ -662,7 +662,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { expect(assetsOnlyResult.config.compatibility_date).toBe("2025-06-01"); }); - test("should accept minimal Wrangler config file when all required fields come from config()", () => { + test("should accept minimal Wrangler config file when all required fields come from config()", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -684,11 +684,11 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { }, }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const entryWorker = result.environmentNameToWorkerMap.get( result.entryWorkerEnvironmentName @@ -699,7 +699,7 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { expect(entryWorker?.config.compatibility_flags).toContain("nodejs_compat"); }); - test("should accept auxiliary worker Wrangler config file missing fields when config() provides them", () => { + test("should accept auxiliary worker Wrangler config file missing fields when config() provides them", async () => { // Create entry worker config const entryConfigPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( @@ -738,11 +738,11 @@ describe("resolvePluginConfig - defaults fill in missing fields", () => { ], }; - const result = resolvePluginConfig( + const result = (await resolvePluginConfig( pluginConfig, { root: tempDir }, viteEnv - ) as WorkersResolvedConfig; + )) as WorkersResolvedConfig; expect(result.type).toBe("workers"); const auxWorker = result.environmentNameToWorkerMap.get("aux_from_config"); expect(auxWorker).toBeDefined(); @@ -765,7 +765,7 @@ describe("resolvePluginConfig - environment name validation", () => { const viteEnv = { mode: "development", command: "serve" as const }; - test("throws when environment name is 'client'", () => { + test("throws when environment name is 'client'", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -779,12 +779,12 @@ describe("resolvePluginConfig - environment name validation", () => { viteEnvironment: { name: "client" }, }; - expect(() => + await expect( resolvePluginConfig(pluginConfig, { root: tempDir }, viteEnv) - ).toThrow('"client" is a reserved Vite environment name'); + ).rejects.toThrow('"client" is a reserved Vite environment name'); }); - test("throws when child environment duplicates parent", () => { + test("throws when child environment duplicates parent", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -798,12 +798,12 @@ describe("resolvePluginConfig - environment name validation", () => { viteEnvironment: { childEnvironments: ["entry_worker"] }, }; - expect(() => + await expect( resolvePluginConfig(pluginConfig, { root: tempDir }, viteEnv) - ).toThrow('Duplicate Vite environment name: "entry_worker"'); + ).rejects.toThrow('Duplicate Vite environment name: "entry_worker"'); }); - test("throws when child environments duplicate each other", () => { + test("throws when child environments duplicate each other", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -817,12 +817,12 @@ describe("resolvePluginConfig - environment name validation", () => { viteEnvironment: { childEnvironments: ["child", "child"] }, }; - expect(() => + await expect( resolvePluginConfig(pluginConfig, { root: tempDir }, viteEnv) - ).toThrow('Duplicate Vite environment name: "child"'); + ).rejects.toThrow('Duplicate Vite environment name: "child"'); }); - test("throws when auxiliary Worker duplicates entry Worker", () => { + test("throws when auxiliary Worker duplicates entry Worker", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -849,12 +849,12 @@ describe("resolvePluginConfig - environment name validation", () => { ], }; - expect(() => + await expect( resolvePluginConfig(pluginConfig, { root: tempDir }, viteEnv) - ).toThrow('Duplicate Vite environment name: "entry_worker"'); + ).rejects.toThrow('Duplicate Vite environment name: "entry_worker"'); }); - test("throws when auxiliary Worker child duplicates entry Worker", () => { + test("throws when auxiliary Worker child duplicates entry Worker", async () => { const configPath = path.join(tempDir, "wrangler.jsonc"); fs.writeFileSync( configPath, @@ -881,8 +881,8 @@ describe("resolvePluginConfig - environment name validation", () => { ], }; - expect(() => + await expect( resolvePluginConfig(pluginConfig, { root: tempDir }, viteEnv) - ).toThrow('Duplicate Vite environment name: "entry_worker"'); + ).rejects.toThrow('Duplicate Vite environment name: "entry_worker"'); }); }); diff --git a/packages/vite-plugin-cloudflare/src/deploy-config.ts b/packages/vite-plugin-cloudflare/src/deploy-config.ts index b8ca61299383..9ff743cd2ec9 100644 --- a/packages/vite-plugin-cloudflare/src/deploy-config.ts +++ b/packages/vite-plugin-cloudflare/src/deploy-config.ts @@ -7,6 +7,7 @@ import type { WorkersResolvedConfig, } from "./plugin-config"; import type * as vite from "vite"; +import type { Unstable_Config } from "wrangler"; interface DeployConfig { configPath: string; @@ -17,22 +18,26 @@ function getDeployConfigPath(root: string) { return path.resolve(root, ".wrangler", "deploy", "config.json"); } -export function getWorkerConfigs(root: string) { +export async function getWorkerConfigs( + root: string +): Promise { const deployConfigPath = getDeployConfigPath(root); const deployConfig = JSON.parse( fs.readFileSync(deployConfigPath, "utf-8") ) as DeployConfig; - return [ - { configPath: deployConfig.configPath }, - ...deployConfig.auxiliaryWorkers, - ].map(({ configPath }) => { - const resolvedConfigPath = path.resolve( - path.dirname(deployConfigPath), - configPath - ); - return wrangler.unstable_readConfig({ config: resolvedConfigPath }); - }); + return Promise.all( + [ + { configPath: deployConfig.configPath }, + ...deployConfig.auxiliaryWorkers, + ].map(async ({ configPath }) => { + const resolvedConfigPath = path.resolve( + path.dirname(deployConfigPath), + configPath + ); + return wrangler.unstable_readConfig({ config: resolvedConfigPath }); + }) + ); } function getRelativePathToWorkerConfig( diff --git a/packages/vite-plugin-cloudflare/src/index.ts b/packages/vite-plugin-cloudflare/src/index.ts index eb7839e7d72c..9ed0f159c4fe 100644 --- a/packages/vite-plugin-cloudflare/src/index.ts +++ b/packages/vite-plugin-cloudflare/src/index.ts @@ -50,9 +50,9 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] { { name: "vite-plugin-cloudflare", sharedDuringBuild: true, - config(userConfig, env) { + async config(userConfig, env) { ctx.setResolvedPluginConfig( - resolvePluginConfig(pluginConfig, userConfig, env) + await resolvePluginConfig(pluginConfig, userConfig, env) ); }, async configureServer(viteDevServer) { diff --git a/packages/vite-plugin-cloudflare/src/miniflare-options.ts b/packages/vite-plugin-cloudflare/src/miniflare-options.ts index 1ab84bb2d622..44b5af8ae3f9 100644 --- a/packages/vite-plugin-cloudflare/src/miniflare-options.ts +++ b/packages/vite-plugin-cloudflare/src/miniflare-options.ts @@ -293,7 +293,7 @@ export async function getDevMiniflareOptions( } const miniflareWorkerOptions = - wrangler.unstable_getMiniflareWorkerOptions( + await wrangler.unstable_getMiniflareWorkerOptions( { ...worker.config, assets: undefined, @@ -583,12 +583,16 @@ export async function getPreviewMiniflareOptions( } const miniflareWorkerOptions = - wrangler.unstable_getMiniflareWorkerOptions(workerConfig, undefined, { - remoteProxyConnectionString: - remoteProxySessionData?.session?.remoteProxyConnectionString, - - containerBuildId, - }); + await wrangler.unstable_getMiniflareWorkerOptions( + workerConfig, + undefined, + { + remoteProxyConnectionString: + remoteProxySessionData?.session?.remoteProxyConnectionString, + + containerBuildId, + } + ); const { externalWorkers } = miniflareWorkerOptions; diff --git a/packages/vite-plugin-cloudflare/src/plugin-config.ts b/packages/vite-plugin-cloudflare/src/plugin-config.ts index c672e47dba29..632d4a71994c 100644 --- a/packages/vite-plugin-cloudflare/src/plugin-config.ts +++ b/packages/vite-plugin-cloudflare/src/plugin-config.ts @@ -188,7 +188,7 @@ export function customizeWorkerConfig( /** * Resolves the config for a single worker, applying defaults, file config, and config(). */ -function resolveWorkerConfig( +async function resolveWorkerConfig( options: { root: string; configPath: string | undefined; @@ -201,7 +201,7 @@ function resolveWorkerConfig( } | { configCustomizer: WorkerConfigCustomizer | undefined } ) -): WorkerResolvedConfig { +): Promise { const isEntryWorker = !("entryWorkerConfig" in options); let workerConfig: WorkerConfig; let raw: Unstable_Config; @@ -213,7 +213,7 @@ function resolveWorkerConfig( raw, config: workerConfig, nonApplicable, - } = readWorkerConfigFromFile(options.configPath, options.env, { + } = await readWorkerConfigFromFile(options.configPath, options.env, { visitedConfigPaths: options.visitedConfigPaths, })); } else { @@ -261,11 +261,11 @@ function resolveWorkerConfig( }); } -export function resolvePluginConfig( +export async function resolvePluginConfig( pluginConfig: PluginConfig, userConfig: vite.UserConfig, viteEnv: vite.ConfigEnv -): ResolvedPluginConfig { +): Promise { const shared = { persistState: pluginConfig.persistState ?? true, inspectorPort: pluginConfig.inspectorPort, @@ -287,7 +287,7 @@ export function resolvePluginConfig( ...shared, remoteBindings: pluginConfig.remoteBindings ?? true, type: "preview", - workers: getWorkerConfigs(root), + workers: await getWorkerConfigs(root), }; } @@ -299,7 +299,7 @@ export function resolvePluginConfig( ); // Build entry worker config: defaults → file config → config() - const entryWorkerResolvedConfig = resolveWorkerConfig({ + const entryWorkerResolvedConfig = await resolveWorkerConfig({ root, configPath, env: prefixedEnv.CLOUDFLARE_ENV, @@ -368,7 +368,7 @@ export function resolvePluginConfig( ); // Build auxiliary worker config: defaults → file config → config() - const workerResolvedConfig = resolveWorkerConfig({ + const workerResolvedConfig = await resolveWorkerConfig({ root, configPath: workerConfigPath, env: cloudflareEnv, diff --git a/packages/vite-plugin-cloudflare/src/workers-configs.ts b/packages/vite-plugin-cloudflare/src/workers-configs.ts index 76e25b9acfc8..10a6d2272d95 100644 --- a/packages/vite-plugin-cloudflare/src/workers-configs.ts +++ b/packages/vite-plugin-cloudflare/src/workers-configs.ts @@ -109,20 +109,20 @@ const nullableNonApplicable = [ "tsconfig", ] as const; -function readWorkerConfig( +async function readWorkerConfig( configPath: string, env: string | undefined -): { +): Promise<{ raw: RawWorkerConfig; config: WorkerConfig; nonApplicable: NonApplicableConfigMap; -} { +}> { const nonApplicable: NonApplicableConfigMap = { replacedByVite: new Set(), notRelevant: new Set(), }; const config: Optional = - wrangler.unstable_readConfig( + await wrangler.unstable_readConfig( { config: configPath, env }, // Preserve the original `main` value so that Vite can resolve it { preserveOriginalMain: true } @@ -280,22 +280,22 @@ function missingFieldErrorMessage( /** * Reads and sanitizes a worker config from a wrangler config file. */ -export function readWorkerConfigFromFile( +export async function readWorkerConfigFromFile( configPath: string, env: string | undefined, opts?: { visitedConfigPaths?: Set; } -): { +): Promise<{ raw: RawWorkerConfig; config: WorkerConfig; nonApplicable: NonApplicableConfigMap; -} { +}> { if (opts?.visitedConfigPaths?.has(configPath)) { throw new Error(`Duplicate Wrangler config path found: ${configPath}`); } - const result = readWorkerConfig(configPath, env); + const result = await readWorkerConfig(configPath, env); opts?.visitedConfigPaths?.add(configPath); diff --git a/packages/vitest-pool-workers/src/pool/config.ts b/packages/vitest-pool-workers/src/pool/config.ts index ca42a70ff8fb..d208eea3a427 100644 --- a/packages/vitest-pool-workers/src/pool/config.ts +++ b/packages/vitest-pool-workers/src/pool/config.ts @@ -294,7 +294,7 @@ async function parseCustomPoolOptions( } const { workerOptions, externalWorkers, define, main } = - wrangler.unstable_getMiniflareWorkerOptions( + await wrangler.unstable_getMiniflareWorkerOptions( configPath, options.wrangler.environment, { @@ -313,6 +313,9 @@ async function parseCustomPoolOptions( const hasAIOrVectorizeBindings = wrappedBindings.some((binding) => { return ( typeof binding === "object" && + binding !== null && + "scriptName" in binding && + typeof binding.scriptName === "string" && (binding.scriptName.includes("__WRANGLER_EXTERNAL_VECTORIZE_WORKER") || binding.scriptName.includes("__WRANGLER_EXTERNAL_AI_WORKER")) ); diff --git a/packages/vitest-pool-workers/src/pool/index.ts b/packages/vitest-pool-workers/src/pool/index.ts index e4ecf1ac68d2..6a534824df7a 100644 --- a/packages/vitest-pool-workers/src/pool/index.ts +++ b/packages/vitest-pool-workers/src/pool/index.ts @@ -302,13 +302,13 @@ function getDurableObjectClasses(worker: SourcelessWorkerOptions): Set { return result; } -function getWranglerWorkerName( +async function getWranglerWorkerName( relativeWranglerConfigPath?: string -): string | undefined { +): Promise { if (!relativeWranglerConfigPath) { return undefined; } - const wranglerConfigObject = experimental_readRawConfig({ + const wranglerConfigObject = await experimental_readRawConfig({ config: relativeWranglerConfigPath, }); return wranglerConfigObject.rawConfig.name; @@ -332,10 +332,10 @@ function updateWorkflowsScriptNames( /** * Gets a set of class names for Workflows defined in the SELF Worker. */ -function getWorkflowClasses( +async function getWorkflowClasses( worker: SourcelessWorkerOptions, relativeWranglerConfigPath: string | undefined -): Set { +): Promise> { // TODO(someday): may need to extend this to take into account other workers // if doing multi-worker tests across workspace projects // TODO(someday): may want to validate class names are valid identifiers? @@ -349,7 +349,7 @@ function getWorkflowClasses( let workerName: string | undefined; // If the designator's scriptName matches its own Worker name, // use that as the worker name, otherwise use the vitest worker's name - const wranglerWorkerName = getWranglerWorkerName( + const wranglerWorkerName = await getWranglerWorkerName( relativeWranglerConfigPath ); if (wranglerWorkerName && designator.scriptName === wranglerWorkerName) { @@ -472,7 +472,7 @@ async function buildProjectWorkerOptions( runnerWorker.durableObjects ??= {}; const durableObjectClassNames = getDurableObjectClasses(runnerWorker); - const workflowClassNames = getWorkflowClasses( + const workflowClassNames = await getWorkflowClasses( runnerWorker, relativeWranglerConfigPath ); @@ -728,7 +728,7 @@ async function buildProjectMiniflareOptions( // --> multiple instances each with single runner worker // Set Workflows scriptName to the runner worker name if it matches the Wrangler worker name - const wranglerWorkerName = getWranglerWorkerName( + const wranglerWorkerName = await getWranglerWorkerName( project.options.wrangler?.configPath ); updateWorkflowsScriptNames(runnerWorker, wranglerWorkerName); @@ -753,7 +753,7 @@ async function buildProjectMiniflareOptions( testWorker.bindings[SELF_NAME_BINDING] = testWorker.name; // Set Workflows scriptName to the test worker name if it matches the Wrangler worker name - const wranglerWorkerName = getWranglerWorkerName( + const wranglerWorkerName = await getWranglerWorkerName( project.options.wrangler?.configPath ); updateWorkflowsScriptNames(testWorker, wranglerWorkerName); diff --git a/packages/workers-utils/src/config/index.ts b/packages/workers-utils/src/config/index.ts index 8b5f4c92c64d..dfe5330da4f1 100644 --- a/packages/workers-utils/src/config/index.ts +++ b/packages/workers-utils/src/config/index.ts @@ -120,16 +120,24 @@ const parseRawConfigFile = (configPath: string): RawConfig => { return {}; }; -export const experimental_readRawConfig = ( - args: ReadConfigCommandArgs, - options: ReadConfigOptions = {} -): { +export type ReadRawConfigResult = { rawConfig: RawConfig; configPath: string | undefined; userConfigPath: string | undefined; deployConfigPath: string | undefined; redirected: boolean; -} => { +}; + +/** + * Synchronously read the raw Wrangler configuration from a data file (toml, json, jsonc). + * + * This function only supports data file formats. For code-based config files, + * use `unstable_readRawConfigAsync` instead. + */ +export const experimental_readRawConfig = ( + args: ReadConfigCommandArgs, + options: ReadConfigOptions = {} +): ReadRawConfigResult => { // Load the configuration from disk if available const { configPath, userConfigPath, deployConfigPath, redirected } = resolveWranglerConfigPath(args, options); @@ -144,3 +152,18 @@ export const experimental_readRawConfig = ( redirected, }; }; + +/** + * Asynchronously read the raw Wrangler configuration. + * + * This function supports both data file formats (toml, json, jsonc) and + * will support code-based config files (ts, js, mjs) in the future. + * + * In Wrangler v5, this will become the default and be renamed to `experimental_readRawConfig`. + */ +export const experimental_readRawConfigAsync = async ( + args: ReadConfigCommandArgs, + options: ReadConfigOptions = {} +): Promise => { + return experimental_readRawConfig(args, options); +}; diff --git a/packages/workers-utils/src/index.ts b/packages/workers-utils/src/index.ts index adfcb1e9633a..fb56616ab513 100644 --- a/packages/workers-utils/src/index.ts +++ b/packages/workers-utils/src/index.ts @@ -16,6 +16,8 @@ export { configFormat, configFileName, experimental_readRawConfig, + experimental_readRawConfigAsync, + type ReadRawConfigResult, } from "./config"; export { experimental_patchConfig, diff --git a/packages/wrangler/src/__tests__/config/configuration.test.ts b/packages/wrangler/src/__tests__/config/configuration.test.ts index 1c0080e3fe0f..d7b27c743cc4 100644 --- a/packages/wrangler/src/__tests__/config/configuration.test.ts +++ b/packages/wrangler/src/__tests__/config/configuration.test.ts @@ -7,12 +7,12 @@ import { runInTempDir } from "../helpers/run-in-tmp"; describe("readConfig()", () => { runInTempDir(); - it("should not error if a python entrypoint is used with the right compatibility_flag", () => { + it("should not error if a python entrypoint is used with the right compatibility_flag", async () => { writeWranglerConfig({ main: "index.py", compatibility_flags: ["python_workers"], }); - const config = readConfig({ config: "wrangler.toml" }); + const config = await readConfig({ config: "wrangler.toml" }); expect(config.rules).toMatchInlineSnapshot(` Array [ Object { @@ -24,18 +24,15 @@ describe("readConfig()", () => { ] `); }); - it("should error if a python entrypoint is used without the right compatibility_flag", () => { + it("should error if a python entrypoint is used without the right compatibility_flag", async () => { writeWranglerConfig({ main: "index.py", }); - try { - readConfig({ config: "wrangler.toml" }); - expect.fail(); - } catch (e) { - expect(e).toMatchInlineSnapshot( - `[Error: The \`python_workers\` compatibility flag is required to use Python.]` - ); - } + await expect(() => + readConfig({ config: "wrangler.toml" }) + ).toThrowErrorMatchingInlineSnapshot( + `[Error: The \`python_workers\` compatibility flag is required to use Python.]` + ); }); }); @@ -44,14 +41,14 @@ describe("experimental_readRawConfig()", () => { `with %s config files`, (configType) => { runInTempDir(); - it(`should find a ${configType} config file given a specific path`, () => { + it(`should find a ${configType} config file given a specific path`, async () => { fs.mkdirSync("../folder", { recursive: true }); writeWranglerConfig( { name: "config-one" }, `../folder/config.${configType}` ); - const result = experimental_readRawConfig({ + const result = await experimental_readRawConfig({ config: `../folder/config.${configType}`, }); expect(result.rawConfig).toEqual( @@ -61,7 +58,7 @@ describe("experimental_readRawConfig()", () => { ); }); - it("should find a config file given a specific script", () => { + it("should find a config file given a specific script", async () => { fs.mkdirSync("./path/to", { recursive: true }); writeWranglerConfig( { name: "config-one" }, @@ -74,7 +71,7 @@ describe("experimental_readRawConfig()", () => { `../folder/wrangler.${configType}` ); - let result = experimental_readRawConfig({ + let result = await experimental_readRawConfig({ script: "./path/to/index.js", }); expect(result.rawConfig).toEqual( @@ -83,7 +80,7 @@ describe("experimental_readRawConfig()", () => { }) ); - result = experimental_readRawConfig({ + result = await experimental_readRawConfig({ script: "../folder/index.js", }); expect(result.rawConfig).toEqual( @@ -99,7 +96,7 @@ describe("experimental_readRawConfig()", () => { describe("BOM (Byte Order Marker) handling", () => { runInTempDir(); - it("should remove UTF-8 BOM from TOML config files", () => { + it("should remove UTF-8 BOM from TOML config files", async () => { const configContent = `name = "test-worker" compatibility_date = "2022-01-12"`; @@ -111,12 +108,12 @@ compatibility_date = "2022-01-12"`; ]) ); - const config = readConfig({ config: "wrangler.toml" }); + const config = await readConfig({ config: "wrangler.toml" }); expect(config.name).toBe("test-worker"); expect(config.compatibility_date).toBe("2022-01-12"); }); - it("should remove UTF-8 BOM from JSON config files", () => { + it("should remove UTF-8 BOM from JSON config files", async () => { const configContent = `{ "name": "test-worker", "compatibility_date": "2022-01-12" @@ -130,55 +127,55 @@ compatibility_date = "2022-01-12"`; ]) ); - const config = readConfig({ config: "wrangler.json" }); + const config = await readConfig({ config: "wrangler.json" }); expect(config.name).toBe("test-worker"); expect(config.compatibility_date).toBe("2022-01-12"); }); - it("should error on UTF-16 BE BOM", () => { + it("should error on UTF-16 BE BOM", async () => { const bomBytes = Buffer.from([0xfe, 0xff]); const configContent = Buffer.from('{"name": "test"}', "utf-8"); fs.writeFileSync("wrangler.json", Buffer.concat([bomBytes, configContent])); - expect(() => readConfig({ config: "wrangler.json" })).toThrow( + await expect(() => readConfig({ config: "wrangler.json" })).toThrow( "Configuration file contains UTF-16 BE byte order marker" ); }); - it("should error on UTF-16 LE BOM", () => { + it("should error on UTF-16 LE BOM", async () => { const bomBytes = Buffer.from([0xff, 0xfe]); const configContent = Buffer.from('{"name": "test"}', "utf-8"); fs.writeFileSync("wrangler.json", Buffer.concat([bomBytes, configContent])); - expect(() => readConfig({ config: "wrangler.json" })).toThrow( + await expect(() => readConfig({ config: "wrangler.json" })).toThrow( "Configuration file contains UTF-16 LE byte order marker" ); }); - it("should error on UTF-32 BE BOM", () => { + it("should error on UTF-32 BE BOM", async () => { const bomBytes = Buffer.from([0x00, 0x00, 0xfe, 0xff]); const configContent = Buffer.from('{"name": "test"}', "utf-8"); fs.writeFileSync("wrangler.json", Buffer.concat([bomBytes, configContent])); - expect(() => readConfig({ config: "wrangler.json" })).toThrow( + await expect(() => readConfig({ config: "wrangler.json" })).toThrow( "Configuration file contains UTF-32 BE byte order marker" ); }); - it("should error on UTF-32 LE BOM", () => { + it("should error on UTF-32 LE BOM", async () => { const bomBytes = Buffer.from([0xff, 0xfe, 0x00, 0x00]); const configContent = Buffer.from('{"name": "test"}', "utf-8"); fs.writeFileSync("wrangler.json", Buffer.concat([bomBytes, configContent])); - expect(() => readConfig({ config: "wrangler.json" })).toThrow( + await expect(() => readConfig({ config: "wrangler.json" })).toThrow( "Configuration file contains UTF-32 LE byte order marker" ); }); - it("should handle files without BOM normally", () => { + it("should handle files without BOM normally", async () => { writeWranglerConfig({ name: "no-bom-test" }); - const config = readConfig({ config: "wrangler.toml" }); + const config = await readConfig({ config: "wrangler.toml" }); expect(config.name).toBe("no-bom-test"); }); }); diff --git a/packages/wrangler/src/__tests__/dev.test.ts b/packages/wrangler/src/__tests__/dev.test.ts index 93fdb867a027..e139908f811f 100644 --- a/packages/wrangler/src/__tests__/dev.test.ts +++ b/packages/wrangler/src/__tests__/dev.test.ts @@ -1916,7 +1916,7 @@ describe.sequential("wrangler dev", () => { await expect( runWrangler("dev --site") ).rejects.toThrowErrorMatchingInlineSnapshot( - `[Error: Not enough arguments following: site]` + `[YError: Not enough arguments following: site]` ); }); diff --git a/packages/wrangler/src/__tests__/init.test.ts b/packages/wrangler/src/__tests__/init.test.ts index 81da3fd6b60e..581c7d979fca 100644 --- a/packages/wrangler/src/__tests__/init.test.ts +++ b/packages/wrangler/src/__tests__/init.test.ts @@ -1267,7 +1267,7 @@ describe("init", () => { await expect( runWrangler("init --from-dash") ).rejects.toMatchInlineSnapshot( - `[Error: Not enough arguments following: from-dash]` + `[YError: Not enough arguments following: from-dash]` ); checkFiles({ items: { diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 68ee9e5de5f1..f51e4a1da941 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -6,7 +6,7 @@ import { } from "@cloudflare/workers-utils"; import { kCurrentWorker, Miniflare } from "miniflare"; import { getAssetsOptions, NonExistentAssetsDirError } from "../../../assets"; -import { readConfig } from "../../../config"; +import { readConfig, readConfigAsync } from "../../../config"; import { partitionDurableObjectBindings } from "../../../deployment-bundle/entry"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; import { getBindings } from "../../../dev"; @@ -42,6 +42,7 @@ import type { export { getVarsForDev as unstable_getVarsForDev } from "../../../dev/dev-vars"; export { readConfig as unstable_readConfig }; +export { readConfigAsync as unstable_readConfigAsync }; export { getDurableObjectClassNameToUseSQLiteMap as unstable_getDurableObjectClassNameToUseSQLiteMap }; /** @@ -151,7 +152,7 @@ export async function getPlatformProxy< ): Promise> { const env = options.environment; - const config = readConfig({ + const config = await readConfigAsync({ config: options.configPath, env, }); @@ -360,7 +361,7 @@ export function unstable_getMiniflareWorkerOptions( }; containerBuildId?: string; } -): Unstable_MiniflareWorkerOptions; +): Promise; export function unstable_getMiniflareWorkerOptions( config: Config, env?: string, @@ -372,8 +373,8 @@ export function unstable_getMiniflareWorkerOptions( }; containerBuildId?: string; } -): Unstable_MiniflareWorkerOptions; -export function unstable_getMiniflareWorkerOptions( +): Promise; +export async function unstable_getMiniflareWorkerOptions( configOrConfigPath: string | Config, env?: string, options?: { @@ -385,10 +386,10 @@ export function unstable_getMiniflareWorkerOptions( }; containerBuildId?: string; } -): Unstable_MiniflareWorkerOptions { +): Promise { const config = typeof configOrConfigPath === "string" - ? readConfig({ config: configOrConfigPath, env }) + ? await readConfigAsync({ config: configOrConfigPath, env }) : configOrConfigPath; const modulesRules: ModuleRule[] = config.rules diff --git a/packages/wrangler/src/api/pages/deploy.ts b/packages/wrangler/src/api/pages/deploy.ts index f5721e7c1dad..95c52f670994 100644 --- a/packages/wrangler/src/api/pages/deploy.ts +++ b/packages/wrangler/src/api/pages/deploy.ts @@ -164,7 +164,7 @@ export async function deploy({ let config: Config | undefined; try { - config = readPagesConfig( + config = await readPagesConfig( { ...args, env }, { useRedirectIfAvailable: true } ); diff --git a/packages/wrangler/src/api/remoteBindings/index.ts b/packages/wrangler/src/api/remoteBindings/index.ts index a7df42d1a6a9..f1afd97725af 100644 --- a/packages/wrangler/src/api/remoteBindings/index.ts +++ b/packages/wrangler/src/api/remoteBindings/index.ts @@ -79,7 +79,7 @@ export async function maybeStartOrUpdateRemoteProxySession( let config: Config | undefined; if ("path" in wranglerOrWorkerConfigObject) { const wranglerConfigObject = wranglerOrWorkerConfigObject; - config = readConfig({ + config = await readConfig({ config: wranglerConfigObject.path, env: wranglerConfigObject.environment, }); diff --git a/packages/wrangler/src/api/startDevWorker/ConfigController.ts b/packages/wrangler/src/api/startDevWorker/ConfigController.ts index bf579aabf0c7..27335552845d 100644 --- a/packages/wrangler/src/api/startDevWorker/ConfigController.ts +++ b/packages/wrangler/src/api/startDevWorker/ConfigController.ts @@ -590,7 +590,7 @@ export class ConfigController extends Controller { const signal = this.#abortController.signal; this.latestInput = input; try { - const fileConfig = readConfig( + const fileConfig = await readConfig( { script: input.entrypoint, config: input.config, diff --git a/packages/wrangler/src/cloudchamber/common.ts b/packages/wrangler/src/cloudchamber/common.ts index 6476f04f1358..1beebf7b7343 100644 --- a/packages/wrangler/src/cloudchamber/common.ts +++ b/packages/wrangler/src/cloudchamber/common.ts @@ -114,7 +114,7 @@ export function handleFailure< : "open beta"; logger.warn(constructStatusMessage(command, commandStatus)); } - const config = readConfig(args); + const config = await readConfig(args); await fillOpenAPIConfiguration(config, scope); await cb(args, config); }; diff --git a/packages/wrangler/src/config/index.ts b/packages/wrangler/src/config/index.ts index 9befacd2cddb..a6ac1203c09e 100644 --- a/packages/wrangler/src/config/index.ts +++ b/packages/wrangler/src/config/index.ts @@ -3,6 +3,7 @@ import path from "node:path"; import { configFileName, experimental_readRawConfig, + experimental_readRawConfigAsync, FatalError, isPagesConfig, normalizeAndValidateConfig, @@ -16,6 +17,7 @@ import type { Config, NormalizeAndValidateConfigArgs, RawConfig, + ReadRawConfigResult, ResolveConfigPathOptions, } from "@cloudflare/workers-utils"; @@ -49,19 +51,19 @@ export type ConfigBindingOptions = Pick< >; /** - * Get the Wrangler configuration; read it from the give `configPath` if available. + * Convert the result of experimental_readRawConfig into a Config shape that can be used across the codebase */ -export function readConfig( +function convertRawConfigToConfig( args: ReadConfigCommandArgs, - options: ReadConfigOptions = {} -): Config { - const { + options: ReadConfigOptions = {}, + { rawConfig, configPath, userConfigPath, deployConfigPath, redirected, - } = experimental_readRawConfig(args, options); + }: ReturnType +): Config { if (redirected) { assert(configPath, "Redirected config found without a configPath"); assert( @@ -94,6 +96,36 @@ export function readConfig( return config; } +/** + * Synchronously get the Wrangler configuration from a data file (toml, json, jsonc). + * + * This function only supports data file formats. For code-based config files, + * use `unstable_readConfigAsync` instead. + */ +export function readConfig( + args: ReadConfigCommandArgs, + options: ReadConfigOptions = {} +): Config { + const raw = experimental_readRawConfig(args, options); + return convertRawConfigToConfig(args, options, raw); +} + +/** + * Asynchronously get the Wrangler configuration. + * + * This function supports both data file formats (toml, json, jsonc) and + * will support code-based config files (ts, js, mjs) in the future. + * + * In Wrangler v5, this will become the default `readConfig`. + */ +export async function readConfigAsync( + args: ReadConfigCommandArgs, + options: ReadConfigOptions = {} +): Promise { + const raw = await experimental_readRawConfigAsync(args, options); + return convertRawConfigToConfig(args, options, raw); +} + export function readPagesConfig( args: ReadConfigCommandArgs, options: ReadConfigOptions = {} diff --git a/packages/wrangler/src/core/register-yargs-command.ts b/packages/wrangler/src/core/register-yargs-command.ts index 517ef62494d3..502469662c5c 100644 --- a/packages/wrangler/src/core/register-yargs-command.ts +++ b/packages/wrangler/src/core/register-yargs-command.ts @@ -165,10 +165,10 @@ function createHandler(def: CommandDefinition, commandName: string) { AUTOCREATE_RESOURCES: args.experimentalAutoCreate, }; - await run(experimentalFlags, () => { + await run(experimentalFlags, async () => { const config = def.behaviour?.provideConfig ?? true - ? readConfig(args, { + ? await readConfig(args, { hideWarnings: !(def.behaviour?.printConfigWarnings ?? true), useRedirectIfAvailable: def.behaviour?.useConfigRedirectIfAvailable, @@ -177,7 +177,7 @@ function createHandler(def: CommandDefinition, commandName: string) { if (def.behaviour?.warnIfMultipleEnvsConfiguredButNoneSpecified) { if (!("env" in args) && config.configPath) { - const { rawConfig } = experimental_readRawConfig( + const { rawConfig } = await experimental_readRawConfig( { config: config.configPath, }, diff --git a/packages/wrangler/src/deploy/index.ts b/packages/wrangler/src/deploy/index.ts index 535fe6eb37d6..845d8b49240f 100644 --- a/packages/wrangler/src/deploy/index.ts +++ b/packages/wrangler/src/deploy/index.ts @@ -292,7 +292,7 @@ export const deployCommand = createCommand({ autoConfigSummary = await runAutoConfig(details); // If autoconfig worked, there should now be a new config file, and so we need to read config again - config = readConfig(args, { + config = await readConfig(args, { hideWarnings: false, useRedirectIfAvailable: true, }); diff --git a/packages/wrangler/src/deployments.ts b/packages/wrangler/src/deployments.ts index 1074c99f1102..33edbd9b02c0 100644 --- a/packages/wrangler/src/deployments.ts +++ b/packages/wrangler/src/deployments.ts @@ -348,7 +348,7 @@ export async function commonDeploymentCMDSetup( yargs: ArgumentsCamelCase ) { await printWranglerBanner(); - const config = readConfig(yargs); + const config = await readConfig(yargs); const accountId = await requireAuth(config); const scriptName = getScriptName( { name: yargs.name as string, env: undefined }, diff --git a/packages/wrangler/src/index.ts b/packages/wrangler/src/index.ts index 12684a58e541..4770859993f6 100644 --- a/packages/wrangler/src/index.ts +++ b/packages/wrangler/src/index.ts @@ -1761,7 +1761,7 @@ export async function main(argv: string[]): Promise { let dispatcher: ReturnType | undefined; // Register Yargs middleware to record command as Sentry breadcrumb let recordedCommand = false; - const wranglerWithMiddleware = wrangler.middleware((args) => { + const wranglerWithMiddleware = wrangler.middleware(async (args) => { // Update logger level, before we do any logging if (Object.keys(LOGGER_LEVELS).includes(args.logLevel as string)) { logger.loggerLevel = args.logLevel as LoggerLevel; @@ -1778,7 +1778,7 @@ export async function main(argv: string[]): Promise { // key to fetch) or flags try { - const { rawConfig, configPath } = experimental_readRawConfig(args); + const { rawConfig, configPath } = await experimental_readRawConfig(args); dispatcher = getMetricsDispatcher({ sendMetrics: rawConfig.send_metrics, hasAssets: !!rawConfig.assets?.directory, diff --git a/packages/wrangler/src/kv/index.ts b/packages/wrangler/src/kv/index.ts index c5d02a22e49a..4232746387aa 100644 --- a/packages/wrangler/src/kv/index.ts +++ b/packages/wrangler/src/kv/index.ts @@ -99,7 +99,7 @@ export const kvNamespaceCreateCommand = createCommand({ }, positionalArgs: ["namespace"], async handler(args, { sdk }) { - const config = readConfig(args); + const config = await readConfig(args); const environment = args.env ? `${args.env}-` : ""; const preview = args.preview ? "_preview" : ""; const title = `${environment}${args.namespace}${preview}`; @@ -219,7 +219,7 @@ export const kvNamespaceDeleteCommand = createCommand({ }, async handler(args) { - const config = readConfig(args); + const config = await readConfig(args); printResourceLocation("remote"); let id; try { @@ -317,7 +317,7 @@ export const kvNamespaceRenameCommand = createCommand({ }, async handler(args) { - const config = readConfig(args); + const config = await readConfig(args); printResourceLocation("remote"); const accountId = await requireAuth(config); @@ -435,7 +435,7 @@ export const kvKeyPutCommand = createCommand({ async handler({ key, ttl, expiration, metadata, ...args }) { const localMode = isLocal(args); - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); // One of `args.path` and `args.value` must be defined const value = args.path @@ -547,7 +547,7 @@ export const kvKeyListCommand = createCommand({ async handler({ prefix, ...args }) { const localMode = isLocal(args); // TODO: support for limit+cursor (pagination) - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); let result: NamespaceKeyInfo[]; @@ -645,7 +645,7 @@ export const kvKeyGetCommand = createCommand({ }, async handler({ key, ...args }) { const localMode = isLocal(args); - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); let bufferKVValue; @@ -744,7 +744,7 @@ export const kvKeyDeleteCommand = createCommand({ async handler({ key, ...args }) { const localMode = isLocal(args); - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); logger.log(`Deleting the key "${key}" on namespace ${namespaceId}.`); @@ -793,7 +793,7 @@ export const kvBulkGetCommand = createCommand({ async handler({ filename, ...args }) { const localMode = isLocal(args); - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); const content = parseJSON(readFileSync(filename), filename) as ( @@ -892,7 +892,7 @@ export const kvBulkPutCommand = createCommand({ // This could be made more efficient with a streaming parser/uploader // but we'll do that in the future if needed. - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); const content = parseJSON(readFileSync(filename), filename); @@ -1016,7 +1016,7 @@ export const kvBulkDeleteCommand = createCommand({ async handler({ filename, ...args }) { const localMode = isLocal(args); - const config = readConfig(args); + const config = await readConfig(args); const namespaceId = await getKVNamespaceId(args, config, localMode); if (!args.force) { diff --git a/packages/wrangler/src/pages/build-env.ts b/packages/wrangler/src/pages/build-env.ts index 4e74944b08fe..a21a1e7b4d38 100644 --- a/packages/wrangler/src/pages/build-env.ts +++ b/packages/wrangler/src/pages/build-env.ts @@ -64,7 +64,7 @@ export const pagesFunctionsBuildEnvCommand = createCommand({ pages_build_output_dir: string; }; try { - config = readPagesConfig({ + config = await readPagesConfig({ ...args, config: configPath, // eslint-disable-next-line turbo/no-undeclared-env-vars diff --git a/packages/wrangler/src/pages/build.ts b/packages/wrangler/src/pages/build.ts index 4382eaeed30d..2690db2b3559 100644 --- a/packages/wrangler/src/pages/build.ts +++ b/packages/wrangler/src/pages/build.ts @@ -382,7 +382,7 @@ async function maybeReadPagesConfig( return undefined; } try { - const config = readPagesConfig({ + const config = await readPagesConfig({ ...args, config: configPath, // eslint-disable-next-line turbo/no-undeclared-env-vars diff --git a/packages/wrangler/src/pages/deploy.ts b/packages/wrangler/src/pages/deploy.ts index 04482b1b9b52..de2d362b8501 100644 --- a/packages/wrangler/src/pages/deploy.ts +++ b/packages/wrangler/src/pages/deploy.ts @@ -149,7 +149,11 @@ export const pagesDeployCommand = createCommand({ * need for now. We will perform a second config file read later * in `/api/pages/deploy`, that will get the environment specific config */ - config = readPagesConfig({ ...args, config: configPath, env: undefined }); + config = await readPagesConfig({ + ...args, + config: configPath, + env: undefined, + }); } catch (err) { if ( !( diff --git a/packages/wrangler/src/pages/deployment-tails.ts b/packages/wrangler/src/pages/deployment-tails.ts index cd1a85e57c10..3cf3de6d5876 100644 --- a/packages/wrangler/src/pages/deployment-tails.ts +++ b/packages/wrangler/src/pages/deployment-tails.ts @@ -140,7 +140,7 @@ export const pagesDeploymentTailCommand = createCommand({ ); } - const config = readConfig(args); + const config = await readConfig(args); const pagesConfig = getConfigCache( PAGES_CONFIG_CACHE_FILENAME ); diff --git a/packages/wrangler/src/pages/dev.ts b/packages/wrangler/src/pages/dev.ts index 2d65decbcb75..e51d500541bc 100644 --- a/packages/wrangler/src/pages/dev.ts +++ b/packages/wrangler/src/pages/dev.ts @@ -286,7 +286,7 @@ export const pagesDevCommand = createCommand({ // for `dev` we always use the top-level config, which means we need // to read the config file with `env` set to `undefined` - const config = readConfig( + const config = await readConfig( { ...args, env: undefined, config: undefined }, { useRedirectIfAvailable: true } ); diff --git a/packages/wrangler/src/pages/secret/index.ts b/packages/wrangler/src/pages/secret/index.ts index 60daf1d25193..84ba97e4ac02 100644 --- a/packages/wrangler/src/pages/secret/index.ts +++ b/packages/wrangler/src/pages/secret/index.ts @@ -51,7 +51,7 @@ async function pagesProject( * return the top-level config. This contains all the information we * need. */ - config = readPagesConfig({ config: configPath, env: undefined }); + config = await readPagesConfig({ config: configPath, env: undefined }); } catch (err) { if ( !( diff --git a/packages/wrangler/src/pubsub/pubsub-commands.ts b/packages/wrangler/src/pubsub/pubsub-commands.ts index 7f934cb7a1d8..a60dedcb1022 100644 --- a/packages/wrangler/src/pubsub/pubsub-commands.ts +++ b/packages/wrangler/src/pubsub/pubsub-commands.ts @@ -40,7 +40,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); const namespace: pubsub.PubSubNamespace = { @@ -65,7 +65,7 @@ export function pubSubCommands( return yargs.epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); logger.log(await pubsub.listPubSubNamespaces(config, accountId)); @@ -87,7 +87,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); if ( @@ -121,7 +121,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); logger.log( @@ -174,7 +174,7 @@ export function pubSubCommands( }) .epilogue(pubsub.pubSubBetaWarning), async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); const broker: pubsub.PubSubBroker = { @@ -244,7 +244,7 @@ export function pubSubCommands( }) .epilogue(pubsub.pubSubBetaWarning), async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); const broker: pubsub.PubSubBrokerUpdate = {}; @@ -299,7 +299,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); logger.log( @@ -331,7 +331,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); if ( @@ -372,7 +372,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); logger.log( @@ -432,7 +432,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); let parsedExpiration: number | undefined; @@ -493,7 +493,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); const numTokens = args.jti.length; @@ -542,7 +542,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); const numTokens = args.jti.length; @@ -584,7 +584,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); logger.log(`Listing previously revoked tokens for ${args.name}...`); @@ -621,7 +621,7 @@ export function pubSubCommands( .epilogue(pubsub.pubSubBetaWarning); }, async (args) => { - const config = readConfig(args); + const config = await readConfig(args); const accountId = await requireAuth(config); logger.log( diff --git a/packages/wrangler/src/r2/object.ts b/packages/wrangler/src/r2/object.ts index 014384fce387..9ad7fcc1123d 100644 --- a/packages/wrangler/src/r2/object.ts +++ b/packages/wrangler/src/r2/object.ts @@ -424,7 +424,7 @@ export const r2ObjectDeleteCommand = createCommand({ const localMode = isLocal(args); const { objectPath, jurisdiction } = args; - const config = readConfig(args); + const config = await readConfig(args); const { bucket, key } = validateAndReturnBucketAndKey(objectPath); let fullBucketName = bucket; if (jurisdiction !== undefined) { diff --git a/packages/wrangler/src/type-generation/index.ts b/packages/wrangler/src/type-generation/index.ts index 3d3f4692f199..18c3b0374fa9 100644 --- a/packages/wrangler/src/type-generation/index.ts +++ b/packages/wrangler/src/type-generation/index.ts @@ -138,12 +138,12 @@ export const typesCommand = createCommand({ let config: Config; const secondaryConfigs: Config[] = []; if (Array.isArray(args.config)) { - config = readConfig({ ...args, config: args.config[0] }); + config = await readConfig({ ...args, config: args.config[0] }); for (const configPath of args.config.slice(1)) { - secondaryConfigs.push(readConfig({ config: configPath })); + secondaryConfigs.push(await readConfig({ config: configPath })); } } else { - config = readConfig(args); + config = await readConfig(args); } const { envInterface, path: outputPath } = args; @@ -378,7 +378,7 @@ export async function generateEnvTypes( ); } - const { rawConfig } = experimental_readRawConfig(collectionArgs); + const { rawConfig } = await experimental_readRawConfig(collectionArgs); const hasEnvironments = !!rawConfig.env && Object.keys(rawConfig.env).length > 0; @@ -436,12 +436,14 @@ async function generateSimpleEnvTypes( ): Promise<{ envHeader?: string; envTypes?: string }> { const stringKeys = new Array(); - const collectedBindings = collectCoreBindings(collectionArgs); - const collectedDurableObjects = collectAllDurableObjects(collectionArgs); - const collectedServices = collectAllServices(collectionArgs); - const collectedUnsafeBindings = collectAllUnsafeBindings(collectionArgs); - const collectedVars = collectAllVars(collectionArgs); - const collectedWorkflows = collectAllWorkflows(collectionArgs); + const collectedBindings = await collectCoreBindings(collectionArgs); + const collectedDurableObjects = + await collectAllDurableObjects(collectionArgs); + const collectedServices = await collectAllServices(collectionArgs); + const collectedUnsafeBindings = + await collectAllUnsafeBindings(collectionArgs); + const collectedVars = await collectAllVars(collectionArgs); + const collectedWorkflows = await collectAllWorkflows(collectionArgs); const entrypointFormat = entrypoint?.format ?? "modules"; const fullOutputPath = resolve(outputPath); @@ -718,7 +720,7 @@ async function generatePerEnvironmentTypes( secrets: Record = {}, log = true ): Promise<{ envHeader?: string; envTypes?: string }> { - const { rawConfig } = experimental_readRawConfig(collectionArgs); + const { rawConfig } = await experimental_readRawConfig(collectionArgs); const envNames = Object.keys(rawConfig.env ?? {}); validateEnvInterfaceNames(envNames); @@ -726,13 +728,15 @@ async function generatePerEnvironmentTypes( const entrypointFormat = entrypoint?.format ?? "modules"; const fullOutputPath = resolve(outputPath); - const bindingsPerEnv = collectCoreBindingsPerEnvironment(collectionArgs); - const varsPerEnv = collectVarsPerEnvironment(collectionArgs); + const bindingsPerEnv = + await collectCoreBindingsPerEnvironment(collectionArgs); + const varsPerEnv = await collectVarsPerEnvironment(collectionArgs); const durableObjectsPerEnv = - collectDurableObjectsPerEnvironment(collectionArgs); - const servicesPerEnv = collectServicesPerEnvironment(collectionArgs); - const workflowsPerEnv = collectWorkflowsPerEnvironment(collectionArgs); - const unsafePerEnv = collectUnsafeBindingsPerEnvironment(collectionArgs); + await collectDurableObjectsPerEnvironment(collectionArgs); + const servicesPerEnv = await collectServicesPerEnvironment(collectionArgs); + const workflowsPerEnv = await collectWorkflowsPerEnvironment(collectionArgs); + const unsafePerEnv = + await collectUnsafeBindingsPerEnvironment(collectionArgs); // Track all binding names and their types across all environments for aggregation const aggregatedBindings = new Map< @@ -1310,9 +1314,9 @@ function getEnvConfig( * * @returns an object which keys are the variable names and values are arrays containing all the computed types for such variables */ -function collectAllVars( +async function collectAllVars( args: Partial<(typeof typesCommand)["args"]> -): Record { +): Promise> { const varsInfo: Record> = {}; // Collects onto the `varsInfo` object the vars and values for a specific environment @@ -1343,7 +1347,7 @@ function collectAllVars( }); } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); if (args.env) { const envConfig = getEnvConfig(args.env, rawConfig); @@ -1416,9 +1420,9 @@ interface CollectedBinding { * * @throws {UserError} If a binding name exists with different types across environments */ -function collectCoreBindings( +async function collectCoreBindings( args: Partial<(typeof typesCommand)["args"]> -): Array { +): Promise> { const bindingsMap = new Map(); function addBinding( @@ -1806,7 +1810,7 @@ function collectCoreBindings( } } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); if (args.env) { const envConfig = getEnvConfig(args.env, rawConfig); @@ -1830,13 +1834,15 @@ function collectCoreBindings( * * @returns An array of collected Durable Object bindings with their names, class name & possible script name. */ -function collectAllDurableObjects( +async function collectAllDurableObjects( args: Partial<(typeof typesCommand)["args"]> -): Array<{ - class_name: string; - name: string; - script_name?: string; -}> { +): Promise< + Array<{ + class_name: string; + name: string; + script_name?: string; + }> +> { const durableObjectsMap = new Map< string, { @@ -1878,7 +1884,7 @@ function collectAllDurableObjects( } } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); if (args.env) { const envConfig = getEnvConfig(args.env, rawConfig); @@ -1902,13 +1908,15 @@ function collectAllDurableObjects( * * @returns An array of collected service bindings with their binding, service & possible entrypoint. */ -function collectAllServices( +async function collectAllServices( args: Partial<(typeof typesCommand)["args"]> -): Array<{ - binding: string; - service: string; - entrypoint?: string; -}> { +): Promise< + Array<{ + binding: string; + service: string; + entrypoint?: string; + }> +> { const servicesMap = new Map< string, { @@ -1950,7 +1958,7 @@ function collectAllServices( } } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); if (args.env) { const envConfig = getEnvConfig(args.env, rawConfig); @@ -1974,14 +1982,16 @@ function collectAllServices( * * @returns An array of collected workflow bindings with their names, class name, binding and possible script name. */ -function collectAllWorkflows( +async function collectAllWorkflows( args: Partial<(typeof typesCommand)["args"]> -): Array<{ - binding: string; - name: string; - class_name: string; - script_name?: string; -}> { +): Promise< + Array<{ + binding: string; + name: string; + class_name: string; + script_name?: string; + }> +> { const workflowsMap = new Map< string, { @@ -2025,7 +2035,7 @@ function collectAllWorkflows( } } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); if (args.env) { const envConfig = getEnvConfig(args.env, rawConfig); @@ -2047,12 +2057,14 @@ function collectAllWorkflows( * * @returns An array of collected unsafe bindings with their names and type. */ -function collectAllUnsafeBindings( +async function collectAllUnsafeBindings( args: Partial<(typeof typesCommand)["args"]> -): Array<{ - name: string; - type: string; -}> { +): Promise< + Array<{ + name: string; + type: string; + }> +> { const unsafeMap = new Map< string, { @@ -2092,7 +2104,7 @@ function collectAllUnsafeBindings( } } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); if (args.env) { const envConfig = getEnvConfig(args.env, rawConfig); @@ -2127,9 +2139,9 @@ interface PerEnvBinding { * * @returns A map of environment name to an object of var names to their type values */ -function collectVarsPerEnvironment( +async function collectVarsPerEnvironment( args: Partial<(typeof typesCommand)["args"]> -): Map> { +): Promise>> { const result = new Map>(); function collectVars(vars: RawEnvironment["vars"]): Record { @@ -2163,7 +2175,7 @@ function collectVarsPerEnvironment( ); } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); // Collect top-level vars const topLevelVars = collectVars(rawConfig.vars); @@ -2194,9 +2206,9 @@ function collectVarsPerEnvironment( * * @returns A map of environment name to array of bindings */ -function collectCoreBindingsPerEnvironment( +async function collectCoreBindingsPerEnvironment( args: Partial<(typeof typesCommand)["args"]> -): Map> { +): Promise>> { const result = new Map>(); function collectEnvironmentBindings( @@ -2624,7 +2636,7 @@ function collectCoreBindingsPerEnvironment( return bindings; } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); const topLevelBindings = collectEnvironmentBindings( rawConfig, @@ -2651,15 +2663,17 @@ function collectCoreBindingsPerEnvironment( * * @returns A map of environment name to array of DO bindings */ -function collectDurableObjectsPerEnvironment( +async function collectDurableObjectsPerEnvironment( args: Partial<(typeof typesCommand)["args"]> -): Map< - string, - Array<{ - class_name: string; - name: string; - script_name?: string; - }> +): Promise< + Map< + string, + Array<{ + class_name: string; + name: string; + script_name?: string; + }> + > > { const result = new Map< string, @@ -2706,7 +2720,7 @@ function collectDurableObjectsPerEnvironment( return durableObjects; } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); const topLevelDOs = collectEnvironmentDOs(rawConfig, TOP_LEVEL_ENV_NAME); if (topLevelDOs.length > 0) { @@ -2730,15 +2744,17 @@ function collectDurableObjectsPerEnvironment( * * @returns A map of environment name to array of service bindings */ -function collectServicesPerEnvironment( +async function collectServicesPerEnvironment( args: Partial<(typeof typesCommand)["args"]> -): Map< - string, - Array<{ - binding: string; - entrypoint?: string; - service: string; - }> +): Promise< + Map< + string, + Array<{ + binding: string; + entrypoint?: string; + service: string; + }> + > > { const result = new Map< string, @@ -2789,7 +2805,7 @@ function collectServicesPerEnvironment( return services; } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); const topLevelServices = collectEnvironmentServices( rawConfig, @@ -2816,16 +2832,18 @@ function collectServicesPerEnvironment( * * @returns A map of environment name to array of workflow bindings */ -function collectWorkflowsPerEnvironment( +async function collectWorkflowsPerEnvironment( args: Partial<(typeof typesCommand)["args"]> -): Map< - string, - Array<{ - binding: string; - class_name: string; - name: string; - script_name?: string; - }> +): Promise< + Map< + string, + Array<{ + binding: string; + class_name: string; + name: string; + script_name?: string; + }> + > > { const result = new Map< string, @@ -2880,7 +2898,7 @@ function collectWorkflowsPerEnvironment( return workflows; } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); const topLevelWorkflows = collectEnvironmentWorkflows( rawConfig, @@ -2907,14 +2925,16 @@ function collectWorkflowsPerEnvironment( * * @returns A map of environment name to array of unsafe bindings */ -function collectUnsafeBindingsPerEnvironment( +async function collectUnsafeBindingsPerEnvironment( args: Partial<(typeof typesCommand)["args"]> -): Map< - string, - Array<{ - name: string; - type: string; - }> +): Promise< + Map< + string, + Array<{ + name: string; + type: string; + }> + > > { const result = new Map< string, @@ -2961,7 +2981,7 @@ function collectUnsafeBindingsPerEnvironment( return unsafeBindings; } - const { rawConfig } = experimental_readRawConfig(args); + const { rawConfig } = await experimental_readRawConfig(args); const topLevelUnsafe = collectEnvironmentUnsafe( rawConfig,