Skip to content

Commit e045ebd

Browse files
barckcodeclaude
andcommitted
Migrate env access from Astro.locals.runtime.env to cloudflare:workers
Astro v6 removed locals.runtime.env in favor of the cloudflare:workers module import. Updated all 15 source files and 2 test files to use `import { env } from 'cloudflare:workers'` pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3e00aca commit e045ebd

17 files changed

Lines changed: 38 additions & 39 deletions

File tree

src/env.d.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ type RuntimeEnv = {
1616
CRON_SECRET: string;
1717
};
1818

19+
declare module 'cloudflare:workers' {
20+
const env: RuntimeEnv;
21+
export { env };
22+
}
23+
1924
declare namespace App {
2025
interface Locals {
21-
runtime: {
22-
env: RuntimeEnv;
23-
};
2426
member?: typeof import('../db/schema').members.$inferSelect;
2527
}
2628
}

src/middleware.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { defineMiddleware } from 'astro:middleware';
2+
import { env } from 'cloudflare:workers';
23
import { getDb } from './lib/db';
34
import { validateSession, clearSessionCookie } from './lib/auth';
45

@@ -15,7 +16,6 @@ export const onRequest = defineMiddleware(async (context, next) => {
1516
return context.redirect('/login');
1617
}
1718

18-
const env = context.locals.runtime.env;
1919
const db = getDb(env.DB);
2020

2121
const result = await validateSession(sessionId, db);

src/pages/api/auth/discord/link.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { APIContext } from 'astro';
2+
import { env } from 'cloudflare:workers';
23
import { buildOAuthUrl, generateOAuthState } from '../../../../lib/discord';
34

45
export async function GET(context: APIContext) {
@@ -7,7 +8,6 @@ export async function GET(context: APIContext) {
78
return context.redirect('/login');
89
}
910

10-
const env = context.locals.runtime.env;
1111
const baseUrl = env.PUBLIC_URL || context.url.origin;
1212
const redirectUri = `${baseUrl}/auth/discord/callback`;
1313

src/pages/api/auth/logout.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { APIContext } from 'astro';
2+
import { env } from 'cloudflare:workers';
23
import { getDb } from '../../../lib/db';
34
import { destroySession, clearSessionCookie, verifyCsrfOrigin } from '../../../lib/auth';
45

56
export async function POST(context: APIContext) {
6-
const env = context.locals.runtime.env;
77
const allowedOrigin = env.PUBLIC_URL || context.url.origin;
88

99
if (!verifyCsrfOrigin(context.request, allowedOrigin)) {

src/pages/api/auth/magic-link.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { APIContext } from 'astro';
2+
import { env } from 'cloudflare:workers';
23
import { eq, and, gte } from 'drizzle-orm';
34
import { getDb } from '../../../lib/db';
45
import { createMagicToken, cleanupExpiredTokens, verifyCsrfOrigin } from '../../../lib/auth';
@@ -8,7 +9,6 @@ import { magicTokens } from '../../../../db/schema';
89
const MAX_ACTIVE_TOKENS_PER_EMAIL = 3;
910

1011
export async function POST(context: APIContext) {
11-
const env = context.locals.runtime.env;
1212
const allowedOrigin = env.PUBLIC_URL || context.url.origin;
1313

1414
if (!verifyCsrfOrigin(context.request, allowedOrigin)) {

src/pages/api/benefits/[id].ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { APIContext } from 'astro';
2+
import { env } from 'cloudflare:workers';
23
import { eq, and } from 'drizzle-orm';
34
import { getDb } from '../../../lib/db';
45
import { validateSession } from '../../../lib/auth';
@@ -10,7 +11,6 @@ export async function GET(context: APIContext) {
1011
return new Response('Unauthorized', { status: 401 });
1112
}
1213

13-
const env = context.locals.runtime.env;
1414
const db = getDb(env.DB);
1515

1616
const result = await validateSession(sessionId, db);

src/pages/api/benefits/benefits.test.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { describe, it, expect, vi, beforeEach } from 'vitest';
22

33
// Mock dependencies
4+
vi.mock('cloudflare:workers', () => ({
5+
env: {
6+
DB: {},
7+
PUBLIC_URL: 'https://nan.builders',
8+
},
9+
}));
10+
411
vi.mock('../../../lib/db', () => ({
512
getDb: vi.fn(),
613
}));
@@ -56,15 +63,7 @@ function createMockContext(overrides: Record<string, any> = {}): any {
5663
url: new URL(overrides.url ?? 'https://nan.builders/api/benefits'),
5764
request: overrides.request ?? new Request('https://nan.builders/api/benefits'),
5865
params: overrides.params ?? {},
59-
locals: {
60-
runtime: {
61-
env: {
62-
DB: {},
63-
PUBLIC_URL: 'https://nan.builders',
64-
...(overrides.env ?? {}),
65-
},
66-
},
67-
},
66+
locals: {},
6867
};
6968
}
7069

src/pages/api/benefits/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { APIContext } from 'astro';
2+
import { env } from 'cloudflare:workers';
23
import { eq, desc } from 'drizzle-orm';
34
import { nanoid } from 'nanoid';
45
import { getDb } from '../../../lib/db';
@@ -11,7 +12,6 @@ export async function GET(context: APIContext) {
1112
return new Response('Unauthorized', { status: 401 });
1213
}
1314

14-
const env = context.locals.runtime.env;
1515
const db = getDb(env.DB);
1616

1717
const result = await validateSession(sessionId, db);
@@ -34,7 +34,6 @@ export async function GET(context: APIContext) {
3434
const VALID_BENEFIT_TYPES = ['infrastructure', 'tool_access'];
3535

3636
export async function POST(context: APIContext) {
37-
const env = context.locals.runtime.env;
3837
const allowedOrigin = env.PUBLIC_URL || context.url.origin;
3938

4039
if (!verifyCsrfOrigin(context.request, allowedOrigin)) {

src/pages/api/checkout/create.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { APIContext } from 'astro';
2+
import { env } from 'cloudflare:workers';
23
import { getDb } from '../../../lib/db';
34
import { validateSession, verifyCsrfOrigin } from '../../../lib/auth';
45
import {
@@ -9,7 +10,6 @@ import {
910
} from '../../../lib/stripe';
1011

1112
export async function POST(context: APIContext) {
12-
const env = context.locals.runtime.env;
1313
const allowedOrigin = env.PUBLIC_URL || context.url.origin;
1414

1515
if (!verifyCsrfOrigin(context.request, allowedOrigin)) {

src/pages/api/cron/discord-reminder.test.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ const mockUpdate = vi.fn();
66
const mockSet = vi.fn();
77
const mockWhere = vi.fn();
88

9+
vi.mock('cloudflare:workers', () => ({
10+
env: {
11+
DB: {},
12+
CRON_SECRET: 'test-secret',
13+
RESEND_API_KEY: 're_test',
14+
PUBLIC_URL: 'https://nan.builders',
15+
},
16+
}));
17+
918
vi.mock('../../../lib/email', () => ({
1019
sendDiscordReminder: (...args: unknown[]) => mockSendDiscordReminder(...args),
1120
}));
@@ -38,16 +47,6 @@ vi.mock('../../../../db/schema', () => ({
3847

3948
function createContext(authHeader?: string) {
4049
return {
41-
locals: {
42-
runtime: {
43-
env: {
44-
DB: {},
45-
CRON_SECRET: 'test-secret',
46-
RESEND_API_KEY: 're_test',
47-
PUBLIC_URL: 'https://nan.builders',
48-
},
49-
},
50-
},
5150
request: {
5251
headers: new Headers(authHeader ? { authorization: authHeader } : {}),
5352
},

0 commit comments

Comments
 (0)