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 : [ ] ,
@@ -143,7 +149,19 @@ const bindingsConfigMock: Omit<
143149 database_id : "1234" ,
144150 } ,
145151 ] ,
146- services : [ { binding : "SERVICE_BINDING" , service : "SERVICE_NAME" } ] ,
152+ services : [
153+ { binding : "SERVICE_BINDING" , service : "service_name" } ,
154+ {
155+ binding : "OTHER_SERVICE_BINDING" ,
156+ service : "service_name_2" ,
157+ entrypoint : "FakeEntrypoint" ,
158+ } ,
159+ {
160+ binding : "OTHER_SERVICE_BINDING_ENTRYPOINT" ,
161+ service : "service_name_2" ,
162+ entrypoint : "RealEntrypoint" ,
163+ } ,
164+ ] ,
147165 analytics_engine_datasets : [
148166 {
149167 binding : "AE_DATASET_BINDING" ,
@@ -415,9 +433,12 @@ describe("generate types", () => {
415433 DURABLE_RE_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableReexport>;
416434 DURABLE_NO_EXPORT: DurableObjectNamespace /* DurableNoexport */;
417435 DURABLE_EXTERNAL: DurableObjectNamespace /* DurableExternal from external-worker */;
436+ REAL_DURABLE_EXTERNAL: DurableObjectNamespace /* RealDurableExternal from service_name_2 */;
418437 R2_BUCKET_BINDING: R2Bucket;
419438 D1_TESTING_SOMETHING: D1Database;
420- SERVICE_BINDING: Fetcher;
439+ SERVICE_BINDING: Fetcher /* service_name */;
440+ OTHER_SERVICE_BINDING: Fetcher /* entrypoint FakeEntrypoint from service_name_2 */;
441+ OTHER_SERVICE_BINDING_ENTRYPOINT: Fetcher /* entrypoint RealEntrypoint from service_name_2 */;
421442 AE_DATASET_BINDING: AnalyticsEngineDataset;
422443 NAMESPACE_BINDING: DispatchNamespace;
423444 LOGFWDR_SCHEMA: any;
@@ -504,9 +525,12 @@ describe("generate types", () => {
504525 DURABLE_RE_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableReexport>;
505526 DURABLE_NO_EXPORT: DurableObjectNamespace /* DurableNoexport */;
506527 DURABLE_EXTERNAL: DurableObjectNamespace /* DurableExternal from external-worker */;
528+ REAL_DURABLE_EXTERNAL: DurableObjectNamespace /* RealDurableExternal from service_name_2 */;
507529 R2_BUCKET_BINDING: R2Bucket;
508530 D1_TESTING_SOMETHING: D1Database;
509- SERVICE_BINDING: Fetcher;
531+ SERVICE_BINDING: Fetcher /* service_name */;
532+ OTHER_SERVICE_BINDING: Fetcher /* entrypoint FakeEntrypoint from service_name_2 */;
533+ OTHER_SERVICE_BINDING_ENTRYPOINT: Fetcher /* entrypoint RealEntrypoint from service_name_2 */;
510534 AE_DATASET_BINDING: AnalyticsEngineDataset;
511535 NAMESPACE_BINDING: DispatchNamespace;
512536 LOGFWDR_SCHEMA: any;
@@ -556,6 +580,156 @@ describe("generate types", () => {
556580 ` ) ;
557581 } ) ;
558582
583+ it ( "should handle multiple worker configs" , async ( ) => {
584+ fs . mkdirSync ( "a" ) ;
585+
586+ fs . writeFileSync (
587+ "./a/index.ts" ,
588+ `import { DurableObject } from 'cloudflare:workers';
589+ export default { async fetch () {} };
590+ export class DurableDirect extends DurableObject {}
591+ export { DurableReexport } from './durable-2.js';
592+ // This should not be picked up, because it's external:
593+ export class DurableExternal extends DurableObject {}`
594+ ) ;
595+ fs . writeFileSync (
596+ "./a/wrangler.toml" ,
597+ TOML . stringify ( {
598+ compatibility_date : "2022-01-12" ,
599+ compatibility_flags : [
600+ "nodejs_compat" ,
601+ "nodejs_compat_populate_process_env" ,
602+ ] ,
603+ name : "test-name" ,
604+ main : "./index.ts" ,
605+ ...bindingsConfigMock ,
606+ unsafe : bindingsConfigMock . unsafe ?? { } ,
607+ } as unknown as TOML . JsonMap ) ,
608+ "utf-8"
609+ ) ;
610+ fs . mkdirSync ( "b" ) ;
611+
612+ fs . writeFileSync ( "./b/index.ts" , `export default { async fetch () {} };` ) ;
613+ fs . writeFileSync (
614+ "./b/wrangler.toml" ,
615+ TOML . stringify ( {
616+ compatibility_date : "2022-01-12" ,
617+ compatibility_flags : [
618+ "nodejs_compat" ,
619+ "nodejs_compat_populate_process_env" ,
620+ ] ,
621+ name : "service_name" ,
622+ main : "./index.ts" ,
623+ ...bindingsConfigMock ,
624+ unsafe : bindingsConfigMock . unsafe ?? { } ,
625+ } as unknown as TOML . JsonMap ) ,
626+ "utf-8"
627+ ) ;
628+
629+ fs . mkdirSync ( "c" ) ;
630+
631+ fs . writeFileSync (
632+ "./c/index.ts" ,
633+ `import { DurableObject, WorkerEntrypoint } from 'cloudflare:workers';
634+ export default { async fetch () {} };
635+
636+ export class RealDurableExternal extends DurableObject {}
637+
638+ export class RealEntrypoint extends WorkerEntrypoint {}
639+ `
640+ ) ;
641+ fs . writeFileSync (
642+ "./c/wrangler.toml" ,
643+ TOML . stringify ( {
644+ compatibility_date : "2022-01-12" ,
645+ compatibility_flags : [
646+ "nodejs_compat" ,
647+ "nodejs_compat_populate_process_env" ,
648+ ] ,
649+ name : "service_name_2" ,
650+ main : "./index.ts" ,
651+ ...bindingsConfigMock ,
652+ unsafe : bindingsConfigMock . unsafe ?? { } ,
653+ } as unknown as TOML . JsonMap ) ,
654+ "utf-8"
655+ ) ;
656+ fs . writeFileSync ( "./a/.dev.vars" , "SECRET=test" , "utf-8" ) ;
657+
658+ await runWrangler (
659+ "types --include-runtime=false -c a/wrangler.toml -c b/wrangler.toml -c c/wrangler.toml --path a/worker-configuration.d.ts"
660+ ) ;
661+ expect ( std . out ) . toMatchInlineSnapshot ( `
662+ "- Found Worker 'service_name' at 'b/index.ts' (b/wrangler.toml)
663+ - Found Worker 'service_name_2' at 'c/index.ts' (c/wrangler.toml)
664+ Generating project types...
665+
666+ declare namespace Cloudflare {
667+ interface Env {
668+ TEST_KV_NAMESPACE: KVNamespace;
669+ SOMETHING: \\"asdasdfasdf\\";
670+ ANOTHER: \\"thing\\";
671+ \\"some-other-var\\": \\"some-other-value\\";
672+ OBJECT_VAR: {\\"enterprise\\":\\"1701-D\\",\\"activeDuty\\":true,\\"captian\\":\\"Picard\\"};
673+ SECRET: string;
674+ DURABLE_DIRECT_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableDirect>;
675+ DURABLE_RE_EXPORT: DurableObjectNamespace<import(\\"./index\\").DurableReexport>;
676+ DURABLE_NO_EXPORT: DurableObjectNamespace /* DurableNoexport */;
677+ DURABLE_EXTERNAL: DurableObjectNamespace /* DurableExternal from external-worker */;
678+ REAL_DURABLE_EXTERNAL: DurableObjectNamespace<import(\\"../c/index\\").RealDurableExternal>;
679+ R2_BUCKET_BINDING: R2Bucket;
680+ D1_TESTING_SOMETHING: D1Database;
681+ SERVICE_BINDING: Service<import(\\"../b/index\\").default>;
682+ OTHER_SERVICE_BINDING: Fetcher /* entrypoint FakeEntrypoint from service_name_2 */;
683+ OTHER_SERVICE_BINDING_ENTRYPOINT: Service<import(\\"../c/index\\").RealEntrypoint>;
684+ AE_DATASET_BINDING: AnalyticsEngineDataset;
685+ NAMESPACE_BINDING: DispatchNamespace;
686+ LOGFWDR_SCHEMA: any;
687+ SOME_DATA_BLOB1: ArrayBuffer;
688+ SOME_DATA_BLOB2: ArrayBuffer;
689+ SOME_TEXT_BLOB1: string;
690+ SOME_TEXT_BLOB2: string;
691+ testing_unsafe: any;
692+ UNSAFE_RATELIMIT: RateLimit;
693+ TEST_QUEUE_BINDING: Queue;
694+ SEND_EMAIL_BINDING: SendEmail;
695+ VECTORIZE_BINDING: VectorizeIndex;
696+ HYPERDRIVE_BINDING: Hyperdrive;
697+ MTLS_BINDING: Fetcher;
698+ BROWSER_BINDING: Fetcher;
699+ AI_BINDING: Ai;
700+ IMAGES_BINDING: ImagesBinding;
701+ VERSION_METADATA_BINDING: { id: string; tag: string };
702+ ASSETS_BINDING: Fetcher;
703+ PIPELINE: import(\\"cloudflare:pipelines\\").Pipeline<import(\\"cloudflare:pipelines\\").PipelineRecord>;
704+ }
705+ }
706+ interface Env extends Cloudflare.Env {}
707+ type StringifyValues<EnvType extends Record<string, unknown>> = {
708+ [Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
709+ };
710+ declare namespace NodeJS {
711+ interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, \\"SOMETHING\\" | \\"ANOTHER\\" | \\"some-other-var\\" | \\"OBJECT_VAR\\" | \\"SECRET\\">> {}
712+ }
713+ declare module \\"*.txt\\" {
714+ const value: string;
715+ export default value;
716+ }
717+ declare module \\"*.webp\\" {
718+ const value: ArrayBuffer;
719+ export default value;
720+ }
721+ declare module \\"*.wasm\\" {
722+ const value: WebAssembly.Module;
723+ export default value;
724+ }
725+ ────────────────────────────────────────────────────────────
726+ ✨ Types written to a/worker-configuration.d.ts
727+
728+ 📣 Remember to rerun 'wrangler types' after you change your wrangler.toml file.
729+ "
730+ ` ) ;
731+ } ) ;
732+
559733 it ( "should create a DTS file at the location that the command is executed from" , async ( ) => {
560734 fs . writeFileSync ( "./index.ts" , "export default { async fetch () {} };" ) ;
561735 fs . writeFileSync (
0 commit comments