From 7b29d09577e0c8a020be5c00953677bf4825889d Mon Sep 17 00:00:00 2001 From: Maurice Putz <55104311+Shooteger@users.noreply.github.com> Date: Fri, 3 Oct 2025 23:46:11 +0700 Subject: [PATCH 1/6] Update module.ts --- src/module.ts | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/module.ts b/src/module.ts index d369c88a..c34a9005 100644 --- a/src/module.ts +++ b/src/module.ts @@ -47,6 +47,7 @@ export interface ModuleOptions { * @docs https://supabase.com/blog/jwt-signing-keys */ secretKey: string + /** * Redirect automatically to login page if user is not authenticated * @default `true` @@ -181,11 +182,27 @@ export default defineNuxtModule({ logger.warn('Missing supabase url, set it either in `nuxt.config.ts` or via env variable') } else { - // Use the default storage key as defined by the supabase-js client if no cookiePrefix is set. - // Source: https://github.com/supabase/supabase-js/blob/3316f2426d7c2e5babaab7ddc17c30bfa189f500/src/SupabaseClient.ts#L86 - const defaultStorageKey = `sb-${new URL(finalUrl).hostname.split('.')[0]}-auth-token` - const currentPrefix = nuxt.options.runtimeConfig.public.supabase.cookiePrefix - nuxt.options.runtimeConfig.public.supabase.cookiePrefix = currentPrefix || defaultStorageKey + try { + // Use the default storage key as defined by the supabase-js client if no cookiePrefix is set. + // Source: https://github.com/supabase/supabase-js/blob/3316f2426d7c2e5babaab7ddc17c30bfa189f500/src/SupabaseClient.ts#L86 + const defaultStorageKey = `sb-${new URL(finalUrl).hostname.split('.')[0]}-auth-token` + const currentPrefix = nuxt.options.runtimeConfig.public.supabase.cookiePrefix + nuxt.options.runtimeConfig.public.supabase.cookiePrefix = currentPrefix || defaultStorageKey + } + catch (error) { + logger.error( + `Invalid Supabase URL: "${finalUrl}". ` + + `Please provide a valid URL (e.g., https://example.supabase.co or http://localhost:5432)`, error) + + // Use fallback prefix + const currentPrefix = nuxt.options.runtimeConfig.public.supabase.cookiePrefix + nuxt.options.runtimeConfig.public.supabase.cookiePrefix = currentPrefix || 'sb-auth-token' + + // Fail build in production + if (!nuxt.options.dev) { + throw new Error('Invalid Supabase URL configuration') + } + } } // Warn if the key isn't set. @@ -266,13 +283,23 @@ export default defineNuxtModule({ filename: 'types/supabase-database.d.ts', getContents: async () => { if (options.types) { - // resolvePath is used to minify user input error. - const path = await resolvePath(options.types) - const typesPath = await resolvePath('~~/.nuxt/types/') // this is the default path for nuxt types - - if (fs.existsSync(path)) { - // Make the path relative to the "types" directory. - return `export * from '${relative(typesPath, path)}'` + try { + const path = await resolvePath(options.types) + const typesPath = await resolvePath('~~/.nuxt/types/') + + if (fs.existsSync(path)) { + return `export * from '${relative(typesPath, path)}'` + } + else { + // Add warning if configured but not found + logger.warn( + `Database types configured at "${options.types}" but file not found. ` + + `Using "Database = unknown".`, + ) + } + } + catch (error) { + logger.error(`Failed to load Supabase database types from "${options.types}":`, error) } } From fa0f6caaded3239bc67a7757f329a8c0e57f016c Mon Sep 17 00:00:00 2001 From: Maurice Putz <55104311+Shooteger@users.noreply.github.com> Date: Fri, 3 Oct 2025 23:59:20 +0700 Subject: [PATCH 2/6] Update fetch-retry.ts --- src/runtime/utils/fetch-retry.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/runtime/utils/fetch-retry.ts b/src/runtime/utils/fetch-retry.ts index 149ce713..a406953f 100644 --- a/src/runtime/utils/fetch-retry.ts +++ b/src/runtime/utils/fetch-retry.ts @@ -14,6 +14,9 @@ export async function fetchWithRetry(req: RequestInfo | URL, init?: RequestInit) throw error } console.warn(`Retrying fetch attempt ${attempt + 1} for request: ${req}`) + + // Small incremental delay before retry + await new Promise(resolve => setTimeout(resolve, 100 * attempt)) } } throw new Error('Unreachable code') From 46ba05582d5bcd1ad58e6ec095d4293dcfa4bf54 Mon Sep 17 00:00:00 2001 From: Maurice Putz <55104311+Shooteger@users.noreply.github.com> Date: Sat, 4 Oct 2025 00:07:39 +0700 Subject: [PATCH 3/6] Update auth-redirect.ts --- src/runtime/plugins/auth-redirect.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/runtime/plugins/auth-redirect.ts b/src/runtime/plugins/auth-redirect.ts index 172f959b..71a934d7 100644 --- a/src/runtime/plugins/auth-redirect.ts +++ b/src/runtime/plugins/auth-redirect.ts @@ -4,6 +4,14 @@ import type { Plugin } from '#app' import { defineNuxtPlugin, addRouteMiddleware, defineNuxtRouteMiddleware, useRuntimeConfig, navigateTo } from '#imports' import type { RouteLocationNormalized } from '#vue-router' +function matchesAnyPattern(path: string, patterns: (string | undefined)[]): boolean { + return patterns.some((pattern) => { + if (!pattern) return false + const regex = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`) + return regex.test(path) + }) +} + export default defineNuxtPlugin({ name: 'auth-redirect', setup() { @@ -15,21 +23,16 @@ export default defineNuxtPlugin({ // Redirect only on included routes (if defined) if (include && include.length > 0) { - const isIncluded = include.some((path: string) => { - const regex = new RegExp(`^${path.replace(/\*/g, '.*')}$`) - return regex.test(to.path) - }) - if (!isIncluded) { + if (!matchesAnyPattern(to.path, include)) { return } } // Do not redirect on login route, callback route and excluded routes - const isExcluded = [...exclude ?? [], login, callback]?.some((path) => { - const regex = new RegExp(`^${path.replace(/\*/g, '.*')}$`) - return regex.test(to.path) - }) - if (isExcluded) return + const excludePatterns = [login, callback, ...(exclude ?? [])] + if (matchesAnyPattern(to.path, excludePatterns)) { + return + } const session = useSupabaseSession() if (!session.value) { From c11d503057414ea58925889372c68e456c67a03e Mon Sep 17 00:00:00 2001 From: Maurice Putz <55104311+Shooteger@users.noreply.github.com> Date: Sat, 4 Oct 2025 00:16:59 +0700 Subject: [PATCH 4/6] Update serverSupabaseServiceRole.ts --- src/runtime/server/services/serverSupabaseServiceRole.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/runtime/server/services/serverSupabaseServiceRole.ts b/src/runtime/server/services/serverSupabaseServiceRole.ts index 64221288..0eb506b2 100644 --- a/src/runtime/server/services/serverSupabaseServiceRole.ts +++ b/src/runtime/server/services/serverSupabaseServiceRole.ts @@ -1,5 +1,6 @@ import type { SupabaseClient } from '@supabase/supabase-js' import { createClient } from '@supabase/supabase-js' +import { fetchWithRetry } from '../../utils/fetch-retry' import type { H3Event } from 'h3' import { useRuntimeConfig } from '#imports' // @ts-expect-error - `#supabase/database` is a runtime alias @@ -27,6 +28,9 @@ export const serverSupabaseServiceRole: (event: H3Event) => Supaba persistSession: false, autoRefreshToken: false, }, + global: { + fetch: fetchWithRetry, + }, }) } From 4ff325365cb3ce071f5e2dba9131d6da38c1d0a9 Mon Sep 17 00:00:00 2001 From: Maurice Putz <55104311+Shooteger@users.noreply.github.com> Date: Sat, 4 Oct 2025 00:42:26 +0700 Subject: [PATCH 5/6] Update module.ts --- src/module.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/module.ts b/src/module.ts index c34a9005..55a3b305 100644 --- a/src/module.ts +++ b/src/module.ts @@ -284,14 +284,15 @@ export default defineNuxtModule({ getContents: async () => { if (options.types) { try { + // resolvePath is used to minify user input error. const path = await resolvePath(options.types) - const typesPath = await resolvePath('~~/.nuxt/types/') + const typesPath = await resolvePath('~~/.nuxt/types/') // this is the default path for nuxt types if (fs.existsSync(path)) { + // Make the path relative to the "types" directory. return `export * from '${relative(typesPath, path)}'` } else { - // Add warning if configured but not found logger.warn( `Database types configured at "${options.types}" but file not found. ` + `Using "Database = unknown".`, From c4a3a58a22f9eca84ca5e2f76b5af98924e6c466 Mon Sep 17 00:00:00 2001 From: Baptiste Leproux Date: Wed, 8 Oct 2025 14:37:53 +0200 Subject: [PATCH 6/6] move types in `app` folder --- playground/{ => app}/types/database.types.ts | 0 src/module.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename playground/{ => app}/types/database.types.ts (100%) diff --git a/playground/types/database.types.ts b/playground/app/types/database.types.ts similarity index 100% rename from playground/types/database.types.ts rename to playground/app/types/database.types.ts diff --git a/src/module.ts b/src/module.ts index 55a3b305..43fc4739 100644 --- a/src/module.ts +++ b/src/module.ts @@ -294,7 +294,7 @@ export default defineNuxtModule({ } else { logger.warn( - `Database types configured at "${options.types}" but file not found. ` + `Database types configured at "${options.types}" but file not found at "${path}". ` + `Using "Database = unknown".`, ) }