Skip to content

Commit 8d4c218

Browse files
oskardudyczoskardudycz
authored andcommitted
Made Cloudflare samples more idiomatic
The initial version was fine as it was working and using Pongo, Hono with Emmett wrappers. Still, it wasn't perfect, as it contained also a lot of boilerplate that can and should be dropped when used Pongo and Emmett wrappers idiomatically. Note, there'll be a follow up PR with changes when Pongo and Emmett gets polished some rough edges found in this usage.
1 parent 53d663a commit 8d4c218

26 files changed

Lines changed: 1513 additions & 1004 deletions

‎plan.md‎

Lines changed: 519 additions & 0 deletions
Large diffs are not rendered by default.

‎samples/cloudflare/d1/env.d.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ import 'cloudflare:workers';
33
declare module 'cloudflare:workers' {
44
interface ProvidedEnv extends CloudflareBindings {}
55
}
6+
7+
declare global {
8+
namespace Cloudflare {
9+
interface Env {
10+
MIGRATION_TOKEN?: string;
11+
}
12+
}
13+
}

‎samples/cloudflare/d1/package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"dev": "wrangler dev --var ENVIRONMENT:development",
1010
"build": "wrangler deploy --dry-run --outdir dist",
1111
"deploy": "node scripts/deploy.ts",
12-
"types:cloudflare": "wrangler types worker-configuration.d.ts --env-interface CloudflareBindings",
13-
"types:cloudflare:check": "wrangler types worker-configuration.d.ts --env-interface CloudflareBindings --check",
12+
"types:cloudflare": "wrangler types worker-configuration.d.ts --env-interface CloudflareBindings --strict-vars=false",
13+
"types:cloudflare:check": "wrangler types worker-configuration.d.ts --env-interface CloudflareBindings --strict-vars=false --check",
1414
"build:ts": "tsc -b",
1515
"build:ts:watch": "tsc -b --watch",
1616
"lint": "npm run lint:eslint && npm run lint:prettier",

‎samples/cloudflare/d1/src/index.ts‎

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,16 @@
11
import { getApplication } from '@event-driven-io/emmett-honojs';
2-
import { pongoClient, type PongoDb } from '@event-driven-io/pongo';
3-
import { d1Driver } from '@event-driven-io/pongo/cloudflare';
4-
import { Hono } from 'hono';
2+
import { env } from 'cloudflare:workers';
53
import { migrationsApi } from './migrations';
6-
import pongoConfig from './pongo.config';
7-
import { shoppingCartApi } from './shoppingCarts';
8-
9-
type Bindings = Omit<CloudflareBindings, 'ENVIRONMENT'> & {
10-
ENVIRONMENT: 'development' | 'production' | 'test';
11-
MIGRATION_TOKEN?: string;
12-
};
13-
14-
let pongoDb: PongoDb | undefined;
15-
16-
const getPongoDb = (env: Bindings): PongoDb => {
17-
pongoDb ??= pongoClient({
18-
driver: d1Driver,
19-
database: env.DB,
20-
schema: {
21-
definition: pongoConfig.schema,
22-
autoMigration:
23-
env.ENVIRONMENT === 'development' ? 'CreateOrUpdate' : 'None',
24-
},
25-
}).database;
26-
return pongoDb;
27-
};
28-
29-
const unitPrices: Readonly<Record<string, number>> = {
30-
'product-1': 1000,
31-
'product-2': 2500,
32-
};
33-
34-
const getUnitPrice = (productId: string): Promise<number> => {
35-
const unitPrice = unitPrices[productId];
36-
if (unitPrice === undefined) throw new Error('Product not found');
37-
return Promise.resolve(unitPrice);
38-
};
39-
40-
const api = new Hono<{ Bindings: Bindings }>();
41-
migrationsApi(getPongoDb)(api);
42-
shoppingCartApi(getPongoDb, getUnitPrice, () => new Date())(api);
43-
44-
const app = getApplication({ apis: [] });
45-
app.route('/', api);
46-
47-
export default app;
4+
import { pongoDb } from './pongo';
5+
import { getUnitPrice, shoppingCartApi } from './shoppingCarts';
6+
7+
export default getApplication({
8+
apis: [
9+
migrationsApi({ pongoDb, migrationToken: env.MIGRATION_TOKEN }),
10+
shoppingCartApi({
11+
pongoDb,
12+
getUnitPrice,
13+
getCurrentTime: () => new Date(),
14+
}),
15+
],
16+
});
Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
1+
import { NoContent, type WebApiSetup } from '@event-driven-io/emmett-honojs';
12
import type { PongoDb } from '@event-driven-io/pongo';
2-
import type { Hono } from 'hono';
33

4-
type MigrationBindings = {
5-
MIGRATION_TOKEN?: string;
4+
type MigrationsApiDependencies = {
5+
pongoDb: PongoDb;
6+
migrationToken?: string;
67
};
78

89
export const migrationsApi =
9-
<Bindings extends MigrationBindings>(
10-
getPongoDb: (bindings: Bindings) => PongoDb,
11-
) =>
12-
(router: Hono<{ Bindings: Bindings }>) => {
10+
({ pongoDb, migrationToken }: MigrationsApiDependencies): WebApiSetup =>
11+
(router) => {
1312
router.post('/_system/migrations', async (context) => {
14-
const migrationToken = context.env.MIGRATION_TOKEN;
1513
if (
1614
!migrationToken ||
1715
context.req.header('Authorization') !== `Bearer ${migrationToken}`
1816
)
1917
return context.body(null, 401);
2018

21-
try {
22-
await getPongoDb(context.env).schema.migrate();
23-
return context.body(null, 204);
24-
} catch {
25-
return context.body(null, 500);
26-
}
19+
await pongoDb.schema.migrate();
20+
21+
return NoContent({ context });
2722
});
2823
};

‎samples/cloudflare/d1/src/pongo.ts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { pongoClient } from '@event-driven-io/pongo';
2+
import { d1Driver } from '@event-driven-io/pongo/cloudflare';
3+
import { env } from 'cloudflare:workers';
4+
import pongoConfig from './pongo.config';
5+
6+
export const pongoDb = pongoClient({
7+
driver: d1Driver,
8+
database: env.DB,
9+
schema: {
10+
definition: pongoConfig.schema,
11+
autoMigration:
12+
env.ENVIRONMENT === 'development' ? 'CreateOrUpdate' : 'None',
13+
},
14+
errors: { throwOnOperationFailures: true },
15+
}).database;

‎samples/cloudflare/d1/src/shoppingCarts/api.e2e.spec.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { beforeAll, describe, expect, it } from 'vitest';
1010

1111
const given = ApiE2ESpecification.for({
12-
fetch: (request) => exports.default.fetch(request),
12+
getApplication: () => exports.default,
1313
});
1414

1515
describe('D1 shopping-cart Worker', () => {

0 commit comments

Comments
 (0)