Skip to content

Commit

Permalink
Add support for new bindings to wrangler types (#5089)
Browse files Browse the repository at this point in the history
* Add support for new bindings to `wrangler types`

* Actually Workers AI is also Fetcher

* Add test

* Add changeset

* Format changelog

* Use `unknown` for AI binding

* Make bindings config type validation stricter

* Fix typecheck failure as discussed
  • Loading branch information
DaniFoldi authored Mar 6, 2024
1 parent bb3db47 commit 5b85dc9
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 3 deletions.
46 changes: 46 additions & 0 deletions .changeset/curvy-ghosts-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
"wrangler": patch
---

fix: include all currently existing bindings in `wrangler types`

Add support for Email Send, Vectorize, Hyperdrive, mTLS, Browser Rendering and Workers AI bindings in `wrangler types`

For example, from the following `wrangler.toml` setup:

```toml
[browser]
binding = "BROWSER"

[ai]
binding = "AI"

[[send_email]]
name = "SEND_EMAIL"

[[vectorize]]
binding = "VECTORIZE"
index_name = "VECTORIZE_NAME"

[[hyperdrive]]
binding = "HYPERDRIVE"
id = "HYPERDRIVE_ID"

[[mtls_certificates]]
binding = "MTLS"
certificate_id = "MTLS_CERTIFICATE_ID"
```

Previously, nothing would have been included in the generated Environment.
Now, the following will be generated:

```ts
interface Env {
SEND_EMAIL: SendEmail;
VECTORIZE: VectorizeIndex;
HYPERDRIVE: Hyperdrive;
MTLS: Fetcher;
BROWSER: Fetcher;
AI: Fetcher;
}
```
26 changes: 24 additions & 2 deletions packages/wrangler/src/__tests__/type-generation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { dedent } from "../utils/dedent";
import { mockConsoleMethods } from "./helpers/mock-console";
import { runInTempDir } from "./helpers/run-in-tmp";
import { runWrangler } from "./helpers/run-wrangler";
import type { Config } from "../config";
import type { EnvironmentNonInheritable } from "../config/environment";

const bindingsConfigMock: Partial<Config> = {
const bindingsConfigMock: Omit<
EnvironmentNonInheritable,
"define" | "tail_consumers" | "constellation" | "cloudchamber"
> &
Record<string, unknown> = {
kv_namespaces: [{ binding: "TEST_KV_NAMESPACE", id: "1234" }],
vars: {
SOMETHING: "asdasdfasdf",
Expand Down Expand Up @@ -62,6 +66,18 @@ const bindingsConfigMock: Partial<Config> = {
dispatch_namespaces: [
{ binding: "NAMESPACE_BINDING", namespace: "NAMESPACE_ID" },
],
send_email: [{ name: "SEND_EMAIL_BINDING" }],
vectorize: [{ binding: "VECTORIZE_BINDING", index_name: "VECTORIZE_NAME" }],
hyperdrive: [{ binding: "HYPERDRIVE_BINDING", id: "HYPERDRIVE_ID" }],
mtls_certificates: [
{ binding: "MTLS_BINDING", certificate_id: "MTLS_CERTIFICATE_ID" },
],
browser: {
binding: "BROWSER_BINDING",
},
ai: {
binding: "AI_BINDING",
},
logfwdr: {
bindings: [{ name: "LOGFWDR_BINDING", destination: "LOGFWDR_DESTINATION" }],
},
Expand Down Expand Up @@ -201,6 +217,12 @@ describe("generateTypes()", () => {
SOME_TEXT_BLOB2: string;
testing_unsafe: any;
TEST_QUEUE_BINDING: Queue;
SEND_EMAIL_BINDING: SendEmail;
VECTORIZE_BINDING: VectorizeIndex;
HYPERDRIVE_BINDING: Hyperdrive;
MTLS_BINDING: Fetcher;
BROWSER_BINDING: Fetcher;
AI_BINDING: unknown;
}
declare module \\"*.txt\\" {
const value: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/src/config/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ export type DurableObjectBindings = {
* If any of these fields are defined at the top-level then they should also be specifically defined
* for each named environment.
*/
interface EnvironmentNonInheritable {
export interface EnvironmentNonInheritable {
/**
* A map of values to substitute when deploying your worker.
*
Expand Down
41 changes: 41 additions & 0 deletions packages/wrangler/src/type-generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ export async function typesHandler(
rules: config.rules,
queues: config.queues,
constellation: config.constellation,
send_email: config.send_email,
vectorize: config.vectorize,
hyperdrive: config.hyperdrive,
mtls_certificates: config.mtls_certificates,
browser: config.browser,
ai: config.ai,
secrets,
};

Expand Down Expand Up @@ -240,6 +246,41 @@ async function generateTypes(
}
}

if (configToDTS.send_email) {
for (const sendEmail of configToDTS.send_email) {
envTypeStructure.push(`${sendEmail.name}: SendEmail;`);
}
}

if (configToDTS.vectorize) {
for (const vectorize of configToDTS.vectorize) {
envTypeStructure.push(`${vectorize.binding}: VectorizeIndex;`);
}
}

if (configToDTS.hyperdrive) {
for (const hyperdrive of configToDTS.hyperdrive) {
envTypeStructure.push(`${hyperdrive.binding}: Hyperdrive;`);
}
}

if (configToDTS.mtls_certificates) {
for (const mtlsCertificate of configToDTS.mtls_certificates) {
envTypeStructure.push(`${mtlsCertificate.binding}: Fetcher;`);
}
}

if (configToDTS.browser) {
// The BrowserWorker type in @cloudflare/puppeteer is of type
// { fetch: typeof fetch }, but workers-types doesn't include it
// and Fetcher is valid for the purposes of handing it to puppeteer
envTypeStructure.push(`${configToDTS.browser.binding}: Fetcher;`);
}

if (configToDTS.ai) {
envTypeStructure.push(`${configToDTS.ai.binding}: unknown;`);
}

const modulesTypeStructure: string[] = [];
if (configToDTS.rules) {
const moduleTypeMap = {
Expand Down

0 comments on commit 5b85dc9

Please sign in to comment.