-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadmin.ts
More file actions
104 lines (98 loc) · 3.38 KB
/
Copy pathadmin.ts
File metadata and controls
104 lines (98 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import 'server-only';
import { createClient, type SupabaseClient } from '@supabase/supabase-js';
import { getSupabaseServiceRoleKey, getSupabaseUrl } from '@/lib/supabase/env';
export function createSupabaseAdminClient() {
const url = getSupabaseUrl();
const serviceKey = getSupabaseServiceRoleKey();
const hasValidUrl = (() => {
if (!url) return false;
try {
new URL(url);
return true;
} catch {
return false;
}
})();
if (!hasValidUrl || !serviceKey) {
// Allow graceful fallback during Next.js build phase (prerender analysis)
// and in test environments. In production runtime, throw immediately.
const isBuildPhase = process.env.NEXT_PHASE === 'phase-production-build';
if (process.env.NODE_ENV !== 'test' && !isBuildPhase) {
throw new Error(
'[Supabase] Cannot create admin client — SUPABASE_SERVICE_ROLE_KEY is missing or invalid. ' +
'Check environment configuration.',
);
}
return createFallbackAdminClient();
}
try {
return createClient(url, serviceKey, {
auth: {
persistSession: false,
},
});
} catch (error) {
if (process.env.NODE_ENV !== 'test') {
throw new Error(
`[Supabase] Failed to initialize admin client: ${error instanceof Error ? error.message : String(error)}`,
);
}
return createFallbackAdminClient();
}
}
function createFallbackAdminClient() {
const error = { message: 'Supabase admin client is not configured.' };
const emptyResult: { data: unknown; error: { message: string } } = {
data: null,
error,
};
const emptyListResult: { data: unknown[]; error: { message: string } } = {
data: [],
error,
};
const buildQuery = (
result: { data: unknown; error: { message: string } } = emptyListResult,
): Record<string, unknown> => {
const builder: Record<string, unknown> = {
select: () => buildQuery(emptyListResult),
insert: () => buildQuery(emptyResult),
update: () => buildQuery(emptyResult),
delete: () => buildQuery(emptyResult),
upsert: () => buildQuery(emptyResult),
eq: () => builder,
match: () => builder,
in: () => builder,
not: () => builder,
gt: () => builder,
gte: () => builder,
lt: () => builder,
lte: () => builder,
order: () => builder,
limit: () => builder,
single: () => Promise.resolve(emptyResult),
maybeSingle: () => Promise.resolve(emptyResult),
then: (resolve: (value: typeof result) => void) =>
Promise.resolve(result).then(resolve),
catch: (reject: (reason?: unknown) => void) =>
Promise.resolve(result).catch(reject),
finally: (callback: () => void) =>
Promise.resolve(result).finally(callback),
};
return builder;
};
return {
from: () => buildQuery(),
rpc: async () => emptyResult,
auth: {
admin: {
listUsers: async () => ({ data: { users: [], total: 0 }, error }),
getUserById: async () => ({ data: { user: null }, error }),
createUser: async () => ({ data: { user: null }, error }),
deleteUser: async () => ({ data: { user: null }, error }),
updateUserById: async () => ({ data: { user: null }, error }),
inviteUserByEmail: async () => ({ data: { user: null }, error }),
generateLink: async () => ({ data: null, error }),
},
},
} as unknown as SupabaseClient;
}