Skip to content

Commit 49e9abe

Browse files
committed
Use --config, Service type, and support external DOs
1 parent d8aaaff commit 49e9abe

File tree

4 files changed

+258
-126
lines changed

4 files changed

+258
-126
lines changed

packages/wrangler/src/__tests__/type-generation.test.ts

Lines changed: 177 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as fs from "fs";
2+
import path from "path";
23
import * as TOML from "@iarna/toml";
34
import {
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(

packages/wrangler/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ export function createCLIParser(argv: string[]) {
371371
"config",
372372
(configArgv) =>
373373
configArgv["_"][0] === "dev" ||
374+
configArgv["_"][0] === "types" ||
374375
(configArgv["_"][0] === "pages" && configArgv["_"][1] === "dev")
375376
)
376377
)

packages/wrangler/src/type-generation/helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const checkTypesDiff = async (config: Config, entry: Entry) => {
4343
previousEnvInterface ?? "Env",
4444
"worker-configuration.d.ts",
4545
entry,
46+
new Map(),
4647
// don't log anything
4748
false
4849
);

0 commit comments

Comments
 (0)