Skip to content

Commit f789654

Browse files
committed
Rename Bindings to Environment and add Email value
1 parent 60190b6 commit f789654

File tree

12 files changed

+596
-144
lines changed

12 files changed

+596
-144
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ async function getLoadContext(request: Request) {
4747
}
4848

4949
declare module "edgekitjs" {
50-
export interface Bindings {
51-
// Add your custom bindings here
50+
export interface Environment {
51+
// Add your custom env variables or bindings here
5252
}
5353

5454
type Schema = typeof schema;
@@ -579,21 +579,21 @@ import {
579579
} from "edgekitjs";
580580
```
581581

582-
### Override Bindings
582+
### Override Environment
583583

584-
You can override the bindings by creating a `d.ts` file in your project with this content
584+
You can override the environment by creating a `d.ts` file in your project with this content
585585

586586
```ts
587587
import "edgekitjs";
588588

589589
declare module "edgekitjs" {
590-
interface Bindings {
591-
// Add your custom bindings here
590+
interface Environment {
591+
// Add your custom env variables and bindings here
592592
}
593593
}
594594
```
595595

596-
If you're using `wrangler types` to generate the types, you can make `Bindings` extends the interface generated by `wrangler types`.
596+
If you're using `wrangler types` to generate the types, you can make `Environment` extends the interface generated by `wrangler types`.
597597

598598
### Override Database Schema
599599

docs/setup.md

Lines changed: 0 additions & 91 deletions
This file was deleted.

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export type { AI } from "./lib/ai/ai.js";
2-
export type { Bindings, DatabaseSchema } from "./lib/types.js";
2+
export type { Environment, DatabaseSchema } from "./lib/types.js";
33
export type { Cache } from "./lib/cache/cache.js";
44
export type { Env } from "./lib/env/env.js";
55
export type { FS } from "./lib/fs/fs.js";

src/lib/clients/verifier.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { afterAll, beforeAll, describe, expect, mock, test } from "bun:test";
2+
import { http, HttpResponse } from "msw";
3+
import { setupServer } from "msw/native";
4+
import { Email } from "./email.js";
5+
import { EmailVerifier } from "./verifier";
6+
7+
mock.module("@edgefirst-dev/core", () => {
8+
return {
9+
orm: mock(),
10+
env() {
11+
return {
12+
fetch(key: string) {
13+
return key;
14+
},
15+
};
16+
},
17+
};
18+
});
19+
20+
describe(EmailVerifier.name, () => {
21+
let server = setupServer();
22+
let email = Email.from("john.doe@company.com");
23+
24+
beforeAll(() => server.listen());
25+
afterAll(() => server.close());
26+
27+
test("#constructor()", () => {
28+
const client = new EmailVerifier();
29+
expect(client).toBeInstanceOf(EmailVerifier);
30+
});
31+
32+
test("#verify()", async () => {
33+
let client = new EmailVerifier();
34+
35+
server.resetHandlers(
36+
http.get(`https://verifier.meetchopra.com/verify/${email}`, () => {
37+
return HttpResponse.json({ status: true });
38+
}),
39+
);
40+
41+
expect(client.verify(email)).resolves.toBeUndefined();
42+
});
43+
44+
test("#profile() with error", async () => {
45+
let client = new EmailVerifier();
46+
47+
server.resetHandlers(
48+
http.get(`https://verifier.meetchopra.com/verify/${email}`, () => {
49+
return HttpResponse.json({
50+
status: false,
51+
error: { code: 2, message: "Disposable email address" },
52+
});
53+
}),
54+
);
55+
56+
expect(client.verify(email)).rejects.toThrowError(
57+
EmailVerifier.InvalidEmailError,
58+
);
59+
});
60+
});

src/lib/clients/verifier.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { APIClient } from "@edgefirst-dev/api-client";
2+
import { ObjectParser } from "@edgefirst-dev/data/parser";
3+
4+
import { env } from "../storage/accessors.js";
5+
import type { Email } from "../values/email.js";
6+
7+
export class EmailVerifier extends APIClient {
8+
constructor() {
9+
super(new URL("https://verifier.meetchopra.com"));
10+
}
11+
12+
override async before(request: Request) {
13+
let url = new URL(request.url);
14+
let apiKey = env().fetch("VERIFIER_API_KEY");
15+
if (apiKey) url.searchParams.append("token", apiKey);
16+
return new Request(url.toString(), request);
17+
}
18+
19+
public async verify(value: Email) {
20+
let response = await this.get(`/verify/${value.toString()}`);
21+
22+
let result = await response.json();
23+
24+
let parser = new ObjectParser(result);
25+
26+
if (parser.boolean("status")) return;
27+
let error = parser.object("error");
28+
29+
throw new EmailVerifier.InvalidEmailError(
30+
error.number("code"),
31+
error.string("message"),
32+
);
33+
}
34+
}
35+
36+
export namespace EmailVerifier {
37+
/**
38+
* The `InvalidEmailError` is thrown when an email fails verification by the
39+
* external API.
40+
*/
41+
export class InvalidEmailError extends Error {
42+
override name = "InvalidEmailError";
43+
44+
/**
45+
* Constructs an `InvalidEmailError` with a specific error code and message.
46+
*
47+
* @param code - The error code returned by the API.
48+
* @param message - The error message returned by the API.
49+
*/
50+
constructor(
51+
public code: number,
52+
message: string,
53+
) {
54+
super(message);
55+
}
56+
}
57+
}

src/lib/env/env.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
import { describe, expect, test } from "bun:test";
22

33
import { EdgeEnvKeyError } from "../errors.js";
4-
import { Bindings } from "../types.js";
4+
import { Environment } from "../types.js";
55
import { Env } from "./env.js";
66

77
describe(Env.name, () => {
8-
let bindings = { KEY: "value" } as unknown as Bindings;
8+
let environment = { KEY: "value" } as unknown as Environment;
99

1010
test("#constructor", () => {
11-
let env = new Env(bindings);
11+
let env = new Env(environment);
1212
expect(env).toBeInstanceOf(Env);
1313
});
1414

15-
test("#constructor with missing bindings", () => {
15+
test("#constructor with missing environment", () => {
1616
// @ts-expect-error - Testing invalid input
1717
expect(() => new Env(undefined)).toThrow();
1818
});
1919

2020
test("#fetch", () => {
21-
let env = new Env(bindings);
21+
let env = new Env(environment);
2222
expect(env.fetch("KEY")).toBe("value");
2323
});
2424

2525
test("#fetch with fallback", () => {
26-
let env = new Env(bindings);
26+
let env = new Env(environment);
2727
expect(env.fetch("OPTIONAL", "fallback")).toBe("fallback");
2828
});
2929

3030
test("#fetch with missing", () => {
31-
let env = new Env(bindings);
31+
let env = new Env(environment);
3232
expect(() => env.fetch("OPTIONAL")).toThrow(EdgeEnvKeyError);
3333
});
3434
});
3535

36-
// Overwrite Bindings on this file
36+
// Overwrite Environment on this file
3737
declare module "../types.js" {
38-
interface Bindings {
38+
interface Environment {
3939
KEY: string;
4040
OPTIONAL?: string;
4141
}

src/lib/env/env.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { EdgeContextError, EdgeEnvKeyError } from "../errors.js";
2-
import type { Bindings } from "../types.js";
2+
import type { Environment } from "../types.js";
33

44
/**
55
* Access environment variables in your Edge-first application.
66
*/
77
export class Env {
8-
constructor(protected bindings: Bindings) {
9-
if (!bindings) throw new EdgeContextError("env().fetch");
8+
constructor(protected env: Environment) {
9+
if (!env) throw new EdgeContextError("env().fetch");
1010
}
1111

1212
/**
@@ -17,11 +17,11 @@ export class Env {
1717
* @param fallback An optional fallback value to return if the key is not found.
1818
* @returns
1919
*/
20-
fetch<Key extends keyof Bindings>(
20+
fetch<Key extends keyof Environment>(
2121
key: Key,
22-
fallback?: Bindings[Key],
23-
): Bindings[Key] {
24-
let data = this.bindings[key];
22+
fallback?: Environment[Key],
23+
): Environment[Key] {
24+
let data = this.env[key];
2525
if (data) return data;
2626

2727
if (fallback) return fallback;

0 commit comments

Comments
 (0)