Refactor key access and role warning in Supabase clients
The update simplifies accessing environment keys and role warnings in Supabase clients by moving them to new functions 'getSupabaseClientKeys' and 'getServiceRoleKey'. The redundancy in the code is reduced promoting clearer and more maintainable code. The '@epic-web/invariant' import has been removed from files as it is no longer needed.
This commit is contained in:
@@ -18,9 +18,7 @@ interface SessionPageProps {
|
|||||||
|
|
||||||
const LazyEmbeddedCheckout = dynamic(
|
const LazyEmbeddedCheckout = dynamic(
|
||||||
async () => {
|
async () => {
|
||||||
const { EmbeddedCheckout } = await import(
|
const { EmbeddedCheckout } = await import('@kit/billing-gateway/checkout');
|
||||||
'@kit/billing-gateway/components'
|
|
||||||
);
|
|
||||||
|
|
||||||
return EmbeddedCheckout;
|
return EmbeddedCheckout;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { invariant } from '@epic-web/invariant';
|
|
||||||
import { getServerSideSitemap } from 'next-sitemap';
|
import { getServerSideSitemap } from 'next-sitemap';
|
||||||
|
|
||||||
import { createCmsClient } from '@kit/cms';
|
import { createCmsClient } from '@kit/cms';
|
||||||
|
|
||||||
import appConfig from '~/config/app.config';
|
import appConfig from '~/config/app.config';
|
||||||
|
|
||||||
invariant(appConfig.url, 'No NEXT_PUBLIC_SITE_URL environment variable found');
|
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const urls = getSiteUrls();
|
const urls = getSiteUrls();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
export async function i18nResolver(language: string, namespace: string) {
|
export async function i18nResolver(language: string, namespace: string) {
|
||||||
const data = await import(
|
const data = await import(
|
||||||
`../../public/locales/${language}/${namespace}.json`,
|
`../../public/locales/${language}/${namespace}.json`
|
||||||
);
|
);
|
||||||
|
|
||||||
return data as Record<string, string>;
|
return data as Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
"supabase:typegen:app": "supabase gen types typescript --local > ./lib/database.types.ts"
|
"supabase:typegen:app": "supabase gen types typescript --local > ./lib/database.types.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@epic-web/invariant": "^1.0.0",
|
|
||||||
"@hookform/resolvers": "^3.3.4",
|
"@hookform/resolvers": "^3.3.4",
|
||||||
"@kit/accounts": "workspace:^",
|
"@kit/accounts": "workspace:^",
|
||||||
"@kit/admin": "workspace:^",
|
"@kit/admin": "workspace:^",
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
"./database": "./src/database.types.ts"
|
"./database": "./src/database.types.ts"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@epic-web/invariant": "^1.0.0",
|
|
||||||
"@kit/eslint-config": "workspace:*",
|
"@kit/eslint-config": "workspace:*",
|
||||||
"@kit/prettier-config": "workspace:*",
|
"@kit/prettier-config": "workspace:*",
|
||||||
"@kit/tailwind-config": "workspace:*",
|
"@kit/tailwind-config": "workspace:*",
|
||||||
@@ -38,7 +37,6 @@
|
|||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@epic-web/invariant": "^1.0.0",
|
|
||||||
"@supabase/ssr": "^0.3.0",
|
"@supabase/ssr": "^0.3.0",
|
||||||
"@supabase/supabase-js": "^2.42.0",
|
"@supabase/supabase-js": "^2.42.0",
|
||||||
"@tanstack/react-query": "^5.28.6",
|
"@tanstack/react-query": "^5.28.6",
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
import { invariant } from '@epic-web/invariant';
|
|
||||||
import { createBrowserClient } from '@supabase/ssr';
|
import { createBrowserClient } from '@supabase/ssr';
|
||||||
|
|
||||||
import { Database } from '../database.types';
|
import { Database } from '../database.types';
|
||||||
|
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name getSupabaseBrowserClient
|
* @name getSupabaseBrowserClient
|
||||||
* @description Get a Supabase client for use in the Browser
|
* @description Get a Supabase client for use in the Browser
|
||||||
*/
|
*/
|
||||||
export function getSupabaseBrowserClient<GenericSchema = Database>() {
|
export function getSupabaseBrowserClient<GenericSchema = Database>() {
|
||||||
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
const keys = getSupabaseClientKeys();
|
||||||
const SUPABASE_ANON_KEY = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
|
|
||||||
|
|
||||||
invariant(SUPABASE_URL, `Supabase URL was not provided`);
|
return createBrowserClient<GenericSchema>(keys.url, keys.anonKey);
|
||||||
invariant(SUPABASE_ANON_KEY, `Supabase Anon key was not provided`);
|
|
||||||
|
|
||||||
return createBrowserClient<GenericSchema>(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type { CookieOptions } from '@supabase/ssr';
|
|||||||
import { createServerClient } from '@supabase/ssr';
|
import { createServerClient } from '@supabase/ssr';
|
||||||
|
|
||||||
import { Database } from '../database.types';
|
import { Database } from '../database.types';
|
||||||
|
import { getServiceRoleKey } from '../get-service-role-key';
|
||||||
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,17 +21,7 @@ export function getSupabaseRouteHandlerClient<GenericSchema = Database>(
|
|||||||
const keys = getSupabaseClientKeys();
|
const keys = getSupabaseClientKeys();
|
||||||
|
|
||||||
if (params.admin) {
|
if (params.admin) {
|
||||||
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
const serviceRoleKey = getServiceRoleKey();
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
console.warn(
|
|
||||||
`[Dev Only] You are using the Supabase Service Role. Make sure it's the right call.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!serviceRoleKey) {
|
|
||||||
throw new Error('Supabase Service Role Key not provided');
|
|
||||||
}
|
|
||||||
|
|
||||||
return createServerClient<GenericSchema>(keys.url, serviceRoleKey, {
|
return createServerClient<GenericSchema>(keys.url, serviceRoleKey, {
|
||||||
auth: {
|
auth: {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { cookies } from 'next/headers';
|
|||||||
import { createServerClient } from '@supabase/ssr';
|
import { createServerClient } from '@supabase/ssr';
|
||||||
|
|
||||||
import { Database } from '../database.types';
|
import { Database } from '../database.types';
|
||||||
|
import { getServiceRoleKey } from '../get-service-role-key';
|
||||||
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
||||||
|
|
||||||
function createServerSupabaseClient() {
|
function createServerSupabaseClient() {
|
||||||
@@ -22,17 +23,7 @@ export function getSupabaseServerActionClient<
|
|||||||
const admin = params?.admin ?? false;
|
const admin = params?.admin ?? false;
|
||||||
|
|
||||||
if (admin) {
|
if (admin) {
|
||||||
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
const serviceRoleKey = getServiceRoleKey();
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
console.warn(
|
|
||||||
`[Dev Only] You are using the Supabase Service Role. Make sure it's the right call.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!serviceRoleKey) {
|
|
||||||
throw new Error('Supabase Service Role Key not provided');
|
|
||||||
}
|
|
||||||
|
|
||||||
return createServerClient<GenericSchema>(keys.url, serviceRoleKey, {
|
return createServerClient<GenericSchema>(keys.url, serviceRoleKey, {
|
||||||
auth: {
|
auth: {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { cookies } from 'next/headers';
|
|||||||
import { createServerClient } from '@supabase/ssr';
|
import { createServerClient } from '@supabase/ssr';
|
||||||
|
|
||||||
import { Database } from '../database.types';
|
import { Database } from '../database.types';
|
||||||
|
import { getServiceRoleKey } from '../get-service-role-key';
|
||||||
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,17 +20,7 @@ export function getSupabaseServerComponentClient<GenericSchema = Database>(
|
|||||||
const keys = getSupabaseClientKeys();
|
const keys = getSupabaseClientKeys();
|
||||||
|
|
||||||
if (params.admin) {
|
if (params.admin) {
|
||||||
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
const serviceRoleKey = getServiceRoleKey();
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
console.warn(
|
|
||||||
`[Dev Only] You are using the Supabase Service Role. Make sure it's the right call.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!serviceRoleKey) {
|
|
||||||
throw new Error('Supabase Service Role Key not provided');
|
|
||||||
}
|
|
||||||
|
|
||||||
return createServerClient<GenericSchema>(keys.url, serviceRoleKey, {
|
return createServerClient<GenericSchema>(keys.url, serviceRoleKey, {
|
||||||
auth: {
|
auth: {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
18
packages/supabase/src/get-service-role-key.ts
Normal file
18
packages/supabase/src/get-service-role-key.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name getServiceRoleKey
|
||||||
|
* @description Get the Supabase Service Role Key.
|
||||||
|
* ONLY USE IN SERVER-SIDE CODE. DO NOT EXPOSE THIS TO CLIENT-SIDE CODE.
|
||||||
|
*/
|
||||||
|
export function getServiceRoleKey() {
|
||||||
|
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
console.warn(
|
||||||
|
`[Dev Only] You are using the Supabase Service Role. Make sure it's the right call.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return z.string().min(1).parse(serviceRoleKey);
|
||||||
|
}
|
||||||
@@ -1,20 +1,16 @@
|
|||||||
import { invariant } from '@epic-web/invariant';
|
import { z } from 'zod';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns and validates the Supabase client keys from the environment.
|
* Returns and validates the Supabase client keys from the environment.
|
||||||
*/
|
*/
|
||||||
export function getSupabaseClientKeys() {
|
export function getSupabaseClientKeys() {
|
||||||
const env = process.env;
|
return z
|
||||||
|
.object({
|
||||||
invariant(env.NEXT_PUBLIC_SUPABASE_URL, `Supabase URL not provided`);
|
url: z.string().min(1),
|
||||||
|
anonKey: z.string().min(1),
|
||||||
invariant(
|
})
|
||||||
env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
|
.parse({
|
||||||
`Supabase Anon Key not provided`,
|
url: process.env.NEXT_PUBLIC_SUPABASE_URL,
|
||||||
);
|
anonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
|
||||||
|
});
|
||||||
return {
|
|
||||||
url: env.NEXT_PUBLIC_SUPABASE_URL,
|
|
||||||
anonKey: env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -47,9 +47,6 @@ importers:
|
|||||||
|
|
||||||
apps/web:
|
apps/web:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@epic-web/invariant':
|
|
||||||
specifier: ^1.0.0
|
|
||||||
version: 1.0.0
|
|
||||||
'@hookform/resolvers':
|
'@hookform/resolvers':
|
||||||
specifier: ^3.3.4
|
specifier: ^3.3.4
|
||||||
version: 3.3.4(react-hook-form@7.51.3)
|
version: 3.3.4(react-hook-form@7.51.3)
|
||||||
@@ -1003,9 +1000,6 @@ importers:
|
|||||||
|
|
||||||
packages/supabase:
|
packages/supabase:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@epic-web/invariant':
|
|
||||||
specifier: ^1.0.0
|
|
||||||
version: 1.0.0
|
|
||||||
'@kit/eslint-config':
|
'@kit/eslint-config':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../tooling/eslint
|
version: link:../../tooling/eslint
|
||||||
@@ -1691,9 +1685,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==}
|
resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@epic-web/invariant@1.0.0:
|
|
||||||
resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==}
|
|
||||||
|
|
||||||
/@esbuild/aix-ppc64@0.19.11:
|
/@esbuild/aix-ppc64@0.19.11:
|
||||||
resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==}
|
resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|||||||
Reference in New Issue
Block a user