History

refactor(cloud): export shared web and server env

Rhys Sullivan committed 7 months ago

Commit d3fede21 parent 9c5e8bf5 files · +40 −18Browse files

Unified · Split

5 files
  1. apps/cloud/src/api.ts +3 −3
  2. apps/cloud/src/auth/handlers.ts +2 −2
  3. apps/cloud/src/auth/workos.ts +4 −4
  4. apps/cloud/src/env.ts +27 −5
  5. apps/cloud/src/services/db.ts +4 −4
apps/cloud/src/api.ts+3−3
@@ -31,7 +31,7 @@ import { CloudAuthHandlers, CloudAuthPublicHandlers } from "./auth/handlers"; · 30 unmodified lines
3131 import { WorkOSAuth } from "./auth/workos";
3232 import { DbService } from "./services/db";
3333 import { createTeamExecutor } from "./services/executor";
34−import { env } from "./env";
34+import { server } from "./env";
3535
3636 const ProtectedCloudApi = addGroup(OpenApiGroup)
3737 .add(McpGroup)
@@ -105,7 +105,7 @@ const COOKIE_OPTIONS = { · 67 unmodified lines
105105 httpOnly: true,
106106 sameSite: "lax" as const,
107107 maxAge: 60 * 60 * 24 * 7,
108− secure: env.NODE_ENV === "production",
108+ secure: server.NODE_ENV === "production",
109109 };
110110
111111 const resolveAuth = (request: Request) =>
@@ -152,7 +152,7 @@ const resolveExecutor = (teamId: string) => · 40 unmodified lines
152152 const users = yield* UserStoreService;
153153 const team = yield* users.use((store) => store.getTeam(teamId));
154154 const teamName = team?.name ?? "Unknown Team";
155− const encryptionKey = env.ENCRYPTION_KEY;
155+ const encryptionKey = server.ENCRYPTION_KEY;
156156 return yield* createTeamExecutor(teamId, teamName, encryptionKey);
157157 });
158158
apps/cloud/src/auth/handlers.ts+2−2
@@ -6,14 +6,14 @@ import { addGroup } from "@executor/api"; · 5 unmodified lines
66 import { AUTH_PATHS, CloudAuthApi, CloudAuthPublicApi } from "./api";
77 import { AuthContext, UserStoreService } from "./context";
88 import { WorkOSAuth } from "./workos";
9−import { env } from "../env";
9+import { server } from "../env";
1010
1111 const COOKIE_OPTIONS = {
1212 path: "/",
1313 httpOnly: true,
1414 sameSite: "lax" as const,
1515 maxAge: 60 * 60 * 24 * 7,
16− secure: env.NODE_ENV === "production",
16+ secure: server.NODE_ENV === "production",
1717 };
1818
1919 // ---------------------------------------------------------------------------
apps/cloud/src/auth/workos.ts+4−4
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 import { Context, Effect, Layer } from "effect";
66 import { WorkOS } from "@workos-inc/node";
77 import { WorkOSError } from "./errors";
8−import { env } from "../env";
8+import { server } from "../env";
99
1010 const COOKIE_NAME = "wos-session";
1111
@@ -15,9 +15,9 @@ const COOKIE_NAME = "wos-session"; · 3 unmodified lines
1515
1616
1717 const make = Effect.gen(function* () {
18− const apiKey = env.WORKOS_API_KEY;
19− const clientId = env.WORKOS_CLIENT_ID;
20− const cookiePassword = env.WORKOS_COOKIE_PASSWORD;
18+ const apiKey = server.WORKOS_API_KEY;
19+ const clientId = server.WORKOS_CLIENT_ID;
20+ const cookiePassword = server.WORKOS_COOKIE_PASSWORD;
2121
2222 if (!cookiePassword || cookiePassword.length < 32) {
2323 return yield* Effect.die(new Error("WORKOS_COOKIE_PASSWORD must be at least 32 characters"));
apps/cloud/src/env.ts+27−5
@@ -1,6 +1,6 @@
11 import { createEnv, Env } from "@executor/env";
22
3−const server = {
3+const sharedShape = {
44 NODE_ENV: Env.literalOr(
55 "NODE_ENV",
66 "development",
@@ -8,6 +8,9 @@ const server = { · 1 unmodified line
88 "test",
99 "production",
1010 ),
11+};
12+
13+const serverShape = {
1114 DATABASE_URL: Env.stringOr("DATABASE_URL", ""),
1215 PGLITE_DATA_DIR: Env.stringOr("PGLITE_DATA_DIR", ".pglite"),
1316 ENCRYPTION_KEY: Env.stringOr(
@@ -19,8 +22,11 @@ const server = { · 5 unmodified lines
1922 WORKOS_COOKIE_PASSWORD: Env.string("WORKOS_COOKIE_PASSWORD"),
2023 };
2124
22−type CloudEnv = Readonly<{
25+type SharedEnv = Readonly<{
2326 NODE_ENV: "development" | "test" | "production";
27+}>;
28+
29+type ServerEnv = SharedEnv & Readonly<{
2430 DATABASE_URL: string;
2531 PGLITE_DATA_DIR: string;
2632 ENCRYPTION_KEY: string;
@@ -29,8 +35,24 @@ type CloudEnv = Readonly<{ · 2 unmodified lines
2935 WORKOS_COOKIE_PASSWORD: string;
3036 }>;
3137
32−export const env = createEnv<undefined, typeof server>({
33− server,
38+type WebEnv = Readonly<Record<string, never>>;
39+
40+export const shared = createEnv({
41+ server: sharedShape,
42+ runtimeEnv: process.env,
43+ emptyStringAsUndefined: true,
44+}) as SharedEnv;
45+
46+export const web = createEnv({
47+ clientPrefix: "PUBLIC_",
48+ client: {},
49+ runtimeEnv: process.env,
50+ emptyStringAsUndefined: true,
51+}) as WebEnv;
52+
53+export const server = createEnv({
54+ server: serverShape,
55+ extends: [shared],
3456 runtimeEnv: process.env,
3557 emptyStringAsUndefined: true,
36−}) as CloudEnv;
58+}) as ServerEnv;
apps/cloud/src/services/db.ts+4−4
@@ -7,7 +7,7 @@ import { resolve } from "node:path"; · 6 unmodified lines
77 import * as sharedSchema from "@executor/storage-postgres/schema";
88 import * as cloudSchema from "./schema";
99 import type { DrizzleDb } from "@executor/storage-postgres";
10−import { env } from "../env";
10+import { server } from "../env";
1111
1212 const schema = { ...sharedSchema, ...cloudSchema };
1313
@@ -24,11 +24,11 @@ type DbResource = { · 10 unmodified lines
2424 };
2525
2626 const createDbResource = async (): Promise<DbResource> => {
27− if (env.DATABASE_URL) {
27+ if (server.DATABASE_URL) {
2828 const { drizzle } = await import("drizzle-orm/node-postgres");
2929 const { migrate } = await import("drizzle-orm/node-postgres/migrator");
3030 const { Pool } = await import("pg");
31− const pool = new Pool({ connectionString: env.DATABASE_URL });
31+ const pool = new Pool({ connectionString: server.DATABASE_URL });
3232 const db = drizzle(pool, { schema }) as DrizzleDb;
3333 await migrate(db as any, { migrationsFolder: MIGRATIONS_DIR });
3434 return {
@@ -40,7 +40,7 @@ const createDbResource = async (): Promise<DbResource> => { · 5 unmodified lines
4040 const { PGlite } = await import("@electric-sql/pglite");
4141 const { drizzle } = await import("drizzle-orm/pglite");
4242 const { migrate } = await import("drizzle-orm/pglite/migrator");
43− const dataDir = env.PGLITE_DATA_DIR;
43+ const dataDir = server.PGLITE_DATA_DIR;
4444 const client = new PGlite(dataDir);
4545 const db = drizzle(client, { schema }) as DrizzleDb;
4646 await migrate(db, { migrationsFolder: MIGRATIONS_DIR });