11import * as fs from "fs" ;
2+ import path from "path" ;
23import * as TOML from "@iarna/toml" ;
34import {
45 constructTSModuleGlob ,
@@ -126,6 +127,11 @@ const bindingsConfigMock: Omit<
126127 class_name : "DurableExternal" ,
127128 script_name : "external-worker" ,
128129 } ,
130+ {
131+ name : "REAL_DURABLE_EXTERNAL" ,
132+ class_name : "RealDurableExternal" ,
133+ script_name : "service_name_2" ,
134+ } ,
129135 ] ,
130136 } ,
131137 workflows : [ ] ,
@@ -150,7 +156,19 @@ const bindingsConfigMock: Omit<
150156 secret_name : "secret_name" ,
151157 } ,
152158 ] ,
153- services : [ { binding : "SERVICE_BINDING" , service : "SERVICE_NAME" } ] ,
159+ services : [
160+ { binding : "SERVICE_BINDING" , service : "service_name" } ,
161+ {
162+ binding : "OTHER_SERVICE_BINDING" ,
163+ service : "service_name_2" ,
164+ entrypoint : "FakeEntrypoint" ,
165+ } ,
166+ {
167+ binding : "OTHER_SERVICE_BINDING_ENTRYPOINT" ,
168+ service : "service_name_2" ,
169+ entrypoint : "RealEntrypoint" ,
170+ } ,
171+ ] ,
154172 analytics_engine_datasets : [
155173 {
156174 binding : "AE_DATASET_BINDING" ,
@@ -422,10 +440,13 @@ describe("generate types", () => {
422440 DURABLE_RE_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableReexport>;
423441 DURABLE_NO_EXPORT: DurableObjectNamespace /* DurableNoexport */;
424442 DURABLE_EXTERNAL: DurableObjectNamespace /* DurableExternal from external-worker */;
443+ REAL_DURABLE_EXTERNAL: DurableObjectNamespace /* RealDurableExternal from service_name_2 */;
425444 R2_BUCKET_BINDING: R2Bucket;
426445 D1_TESTING_SOMETHING: D1Database;
427446 SECRET: SecretsStoreSecret;
428- SERVICE_BINDING: Fetcher;
447+ SERVICE_BINDING: Fetcher /* service_name */;
448+ OTHER_SERVICE_BINDING: Fetcher /* entrypoint FakeEntrypoint from service_name_2 */;
449+ OTHER_SERVICE_BINDING_ENTRYPOINT: Fetcher /* entrypoint RealEntrypoint from service_name_2 */;
429450 AE_DATASET_BINDING: AnalyticsEngineDataset;
430451 NAMESPACE_BINDING: DispatchNamespace;
431452 LOGFWDR_SCHEMA: any;
@@ -512,10 +533,13 @@ describe("generate types", () => {
512533 DURABLE_RE_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableReexport>;
513534 DURABLE_NO_EXPORT: DurableObjectNamespace /* DurableNoexport */;
514535 DURABLE_EXTERNAL: DurableObjectNamespace /* DurableExternal from external-worker */;
536+ REAL_DURABLE_EXTERNAL: DurableObjectNamespace /* RealDurableExternal from service_name_2 */;
515537 R2_BUCKET_BINDING: R2Bucket;
516538 D1_TESTING_SOMETHING: D1Database;
517539 SECRET: SecretsStoreSecret;
518- SERVICE_BINDING: Fetcher;
540+ SERVICE_BINDING: Fetcher /* service_name */;
541+ OTHER_SERVICE_BINDING: Fetcher /* entrypoint FakeEntrypoint from service_name_2 */;
542+ OTHER_SERVICE_BINDING_ENTRYPOINT: Fetcher /* entrypoint RealEntrypoint from service_name_2 */;
519543 AE_DATASET_BINDING: AnalyticsEngineDataset;
520544 NAMESPACE_BINDING: DispatchNamespace;
521545 LOGFWDR_SCHEMA: any;
@@ -565,6 +589,156 @@ describe("generate types", () => {
565589 ` ) ;
566590 } ) ;
567591
592+ it ( "should handle multiple worker configs" , async ( ) => {
593+ fs . mkdirSync ( "a" ) ;
594+
595+ fs . writeFileSync (
596+ "./a/index.ts" ,
597+ `import { DurableObject } from 'cloudflare:workers';
598+ export default { async fetch () {} };
599+ export class DurableDirect extends DurableObject {}
600+ export { DurableReexport } from './durable-2.js';
601+ // This should not be picked up, because it's external:
602+ export class DurableExternal extends DurableObject {}`
603+ ) ;
604+ fs . writeFileSync (
605+ "./a/wrangler.toml" ,
606+ TOML . stringify ( {
607+ compatibility_date : "2022-01-12" ,
608+ compatibility_flags : [
609+ "nodejs_compat" ,
610+ "nodejs_compat_populate_process_env" ,
611+ ] ,
612+ name : "test-name" ,
613+ main : "./index.ts" ,
614+ ...bindingsConfigMock ,
615+ unsafe : bindingsConfigMock . unsafe ?? { } ,
616+ } as unknown as TOML . JsonMap ) ,
617+ "utf-8"
618+ ) ;
619+ fs . mkdirSync ( "b" ) ;
620+
621+ fs . writeFileSync ( "./b/index.ts" , `export default { async fetch () {} };` ) ;
622+ fs . writeFileSync (
623+ "./b/wrangler.toml" ,
624+ TOML . stringify ( {
625+ compatibility_date : "2022-01-12" ,
626+ compatibility_flags : [
627+ "nodejs_compat" ,
628+ "nodejs_compat_populate_process_env" ,
629+ ] ,
630+ name : "service_name" ,
631+ main : "./index.ts" ,
632+ ...bindingsConfigMock ,
633+ unsafe : bindingsConfigMock . unsafe ?? { } ,
634+ } as unknown as TOML . JsonMap ) ,
635+ "utf-8"
636+ ) ;
637+
638+ fs . mkdirSync ( "c" ) ;
639+
640+ fs . writeFileSync (
641+ "./c/index.ts" ,
642+ `import { DurableObject, WorkerEntrypoint } from 'cloudflare:workers';
643+ export default { async fetch () {} };
644+
645+ export class RealDurableExternal extends DurableObject {}
646+
647+ export class RealEntrypoint extends WorkerEntrypoint {}
648+ `
649+ ) ;
650+ fs . writeFileSync (
651+ "./c/wrangler.toml" ,
652+ TOML . stringify ( {
653+ compatibility_date : "2022-01-12" ,
654+ compatibility_flags : [
655+ "nodejs_compat" ,
656+ "nodejs_compat_populate_process_env" ,
657+ ] ,
658+ name : "service_name_2" ,
659+ main : "./index.ts" ,
660+ ...bindingsConfigMock ,
661+ unsafe : bindingsConfigMock . unsafe ?? { } ,
662+ } as unknown as TOML . JsonMap ) ,
663+ "utf-8"
664+ ) ;
665+ fs . writeFileSync ( "./a/.dev.vars" , "SECRET=test" , "utf-8" ) ;
666+
667+ await runWrangler (
668+ "types --include-runtime=false -c a/wrangler.toml -c b/wrangler.toml -c c/wrangler.toml --path a/worker-configuration.d.ts"
669+ ) ;
670+ expect ( std . out ) . toMatchInlineSnapshot ( `
671+ "- Found Worker 'service_name' at 'b/index.ts' (b/wrangler.toml)
672+ - Found Worker 'service_name_2' at 'c/index.ts' (c/wrangler.toml)
673+ Generating project types...
674+
675+ declare namespace Cloudflare {
676+ interface Env {
677+ TEST_KV_NAMESPACE: KVNamespace;
678+ SOMETHING: \\"asdasdfasdf\\";
679+ ANOTHER: \\"thing\\";
680+ \\"some-other-var\\": \\"some-other-value\\";
681+ OBJECT_VAR: {\\"enterprise\\":\\"1701-D\\",\\"activeDuty\\":true,\\"captian\\":\\"Picard\\"};
682+ SECRET: string;
683+ DURABLE_DIRECT_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableDirect>;
684+ DURABLE_RE_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableReexport>;
685+ DURABLE_NO_EXPORT: DurableObjectNamespace /* DurableNoexport */;
686+ DURABLE_EXTERNAL: DurableObjectNamespace /* DurableExternal from external-worker */;
687+ REAL_DURABLE_EXTERNAL: DurableObjectNamespace<import(\\"../c/index\\").RealDurableExternal>;
688+ R2_BUCKET_BINDING: R2Bucket;
689+ D1_TESTING_SOMETHING: D1Database;
690+ SERVICE_BINDING: Service<import(\\"../b/index\\").default>;
691+ OTHER_SERVICE_BINDING: Fetcher /* entrypoint FakeEntrypoint from service_name_2 */;
692+ OTHER_SERVICE_BINDING_ENTRYPOINT: Service<import(\\"../c/index\\").RealEntrypoint>;
693+ AE_DATASET_BINDING: AnalyticsEngineDataset;
694+ NAMESPACE_BINDING: DispatchNamespace;
695+ LOGFWDR_SCHEMA: any;
696+ SOME_DATA_BLOB1: ArrayBuffer;
697+ SOME_DATA_BLOB2: ArrayBuffer;
698+ SOME_TEXT_BLOB1: string;
699+ SOME_TEXT_BLOB2: string;
700+ testing_unsafe: any;
701+ UNSAFE_RATELIMIT: RateLimit;
702+ TEST_QUEUE_BINDING: Queue;
703+ SEND_EMAIL_BINDING: SendEmail;
704+ VECTORIZE_BINDING: VectorizeIndex;
705+ HYPERDRIVE_BINDING: Hyperdrive;
706+ MTLS_BINDING: Fetcher;
707+ BROWSER_BINDING: Fetcher;
708+ AI_BINDING: Ai;
709+ IMAGES_BINDING: ImagesBinding;
710+ VERSION_METADATA_BINDING: { id: string; tag: string };
711+ ASSETS_BINDING: Fetcher;
712+ PIPELINE: import(\\"cloudflare:pipelines\\").Pipeline<import(\\"cloudflare:pipelines\\").PipelineRecord>;
713+ }
714+ }
715+ interface Env extends Cloudflare.Env {}
716+ type StringifyValues<EnvType extends Record<string, unknown>> = {
717+ [Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
718+ };
719+ declare namespace NodeJS {
720+ interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, \\"SOMETHING\\" | \\"ANOTHER\\" | \\"some-other-var\\" | \\"OBJECT_VAR\\" | \\"SECRET\\">> {}
721+ }
722+ declare module \\"*.txt\\" {
723+ const value: string;
724+ export default value;
725+ }
726+ declare module \\"*.webp\\" {
727+ const value: ArrayBuffer;
728+ export default value;
729+ }
730+ declare module \\"*.wasm\\" {
731+ const value: WebAssembly.Module;
732+ export default value;
733+ }
734+ ────────────────────────────────────────────────────────────
735+ ✨ Types written to a/worker-configuration.d.ts
736+
737+ 📣 Remember to rerun 'wrangler types' after you change your wrangler.toml file.
738+ "
739+ ` ) ;
740+ } ) ;
741+
568742 it ( "should create a DTS file at the location that the command is executed from" , async ( ) => {
569743 fs . writeFileSync ( "./index.ts" , "export default { async fetch () {} };" ) ;
570744 fs . writeFileSync (
0 commit comments