Commit 90d678e4 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix: add ws package for Node 20 WebSocket support

Supabase Realtime requires WebSocket. Node 20 doesn't have native
WebSocket — install ws and pass it as transport option.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent c989cbf6
Pipeline #35 canceled with stages
...@@ -20,11 +20,13 @@ ...@@ -20,11 +20,13 @@
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"nanoid": "^5.0.9", "nanoid": "^5.0.9",
"postgres": "^3.4.5", "postgres": "^3.4.5",
"ws": "^8.21.0",
"zod": "^3.24.1" "zod": "^3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@types/jsonwebtoken": "^9.0.7", "@types/jsonwebtoken": "^9.0.7",
"@types/node": "^22.10.2", "@types/node": "^22.10.2",
"@types/ws": "^8.18.1",
"@typescript-eslint/eslint-plugin": "^8.18.0", "@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0", "@typescript-eslint/parser": "^8.18.0",
"drizzle-kit": "^0.30.1", "drizzle-kit": "^0.30.1",
...@@ -2011,6 +2013,16 @@ ...@@ -2011,6 +2013,16 @@
"undici-types": "~6.21.0" "undici-types": "~6.21.0"
} }
}, },
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.59.4", "version": "8.59.4",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.4.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.4.tgz",
...@@ -5930,6 +5942,27 @@ ...@@ -5930,6 +5942,27 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/ws": {
"version": "8.21.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/yaml": { "node_modules/yaml": {
"version": "2.9.0", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
......
...@@ -18,30 +18,32 @@ ...@@ -18,30 +18,32 @@
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"fastify": "^5.1.0",
"@fastify/cors": "^10.0.1", "@fastify/cors": "^10.0.1",
"@fastify/env": "^5.0.1",
"@fastify/helmet": "^12.0.1", "@fastify/helmet": "^12.0.1",
"@fastify/rate-limit": "^10.2.1", "@fastify/rate-limit": "^10.2.1",
"@fastify/swagger": "^9.4.2", "@fastify/swagger": "^9.4.2",
"@fastify/swagger-ui": "^5.2.1", "@fastify/swagger-ui": "^5.2.1",
"@fastify/env": "^5.0.1",
"@supabase/supabase-js": "^2.49.1", "@supabase/supabase-js": "^2.49.1",
"drizzle-orm": "^0.38.3", "drizzle-orm": "^0.38.3",
"postgres": "^3.4.5", "fastify": "^5.1.0",
"zod": "^3.24.1", "jsonwebtoken": "^9.0.2",
"nanoid": "^5.0.9", "nanoid": "^5.0.9",
"jsonwebtoken": "^9.0.2" "postgres": "^3.4.5",
"ws": "^8.21.0",
"zod": "^3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.10.2",
"@types/jsonwebtoken": "^9.0.7", "@types/jsonwebtoken": "^9.0.7",
"typescript": "^5.7.2", "@types/node": "^22.10.2",
"tsx": "^4.19.2", "@types/ws": "^8.18.1",
"vitest": "^2.1.8", "@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"drizzle-kit": "^0.30.1", "drizzle-kit": "^0.30.1",
"eslint": "^9.16.0", "eslint": "^9.16.0",
"@typescript-eslint/eslint-plugin": "^8.18.0", "tsx": "^4.19.2",
"@typescript-eslint/parser": "^8.18.0" "typescript": "^5.7.2",
"vitest": "^2.1.8"
}, },
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=20.0.0"
......
import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { createClient, SupabaseClient } from '@supabase/supabase-js';
import ws from 'ws';
import type { Env } from './env.js'; import type { Env } from './env.js';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const WebSocketTransport = ws as any;
let adminClient: SupabaseClient | null = null; let adminClient: SupabaseClient | null = null;
export function getSupabaseAdmin(env: Env): SupabaseClient { export function getSupabaseAdmin(env: Env): SupabaseClient {
...@@ -10,18 +14,27 @@ export function getSupabaseAdmin(env: Env): SupabaseClient { ...@@ -10,18 +14,27 @@ export function getSupabaseAdmin(env: Env): SupabaseClient {
autoRefreshToken: false, autoRefreshToken: false,
persistSession: false, persistSession: false,
}, },
realtime: {
transport: WebSocketTransport,
},
}); });
} }
return adminClient; return adminClient;
} }
export function getSupabaseClient(env: Env, accessToken?: string): SupabaseClient { export function getSupabaseClient(env: Env, accessToken?: string): SupabaseClient {
const opts = {
realtime: {
transport: WebSocketTransport,
},
};
if (accessToken) { if (accessToken) {
return createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY, { return createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY, {
...opts,
global: { global: {
headers: { Authorization: `Bearer ${accessToken}` }, headers: { Authorization: `Bearer ${accessToken}` },
}, },
}); });
} }
return createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY); return createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY, opts);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment