Open-next Cloudflare / Docker / Setup (#248)

* Add Cloudflare generator with Wrangler and OpenNext support

This update introduces a new Cloudflare generator to streamline configuration and deployment via Wrangler and OpenNext. It registers the necessary templates, modifies project files, and adds Cloudflare-specific scripts and dependencies to the package.json. Additionally, .hbs files are updated in .prettierignore for formatting consistency.

* Add GitHub username prompt and improve setup scripts

Introduce a prompt for GitHub username to personalize project setup. Enhance the setup scripts by adding PNPM verification, configuring `upstream` remote, and removing the `origin` remote. Adjust health check and error handling for better reliability.

* Add Dockerfile generator to turbo generators

Introduced a new generator to create Dockerfile configurations for standalone Next.js applications. This includes modifying `next.config.mjs` for standalone output, updating dependencies in `package.json`, and adding a Dockerfile template. The generator is now registered in the turbo setup.

* Add console-based logger implementation. This is required for edge environments such as Cloudflare.

* Remove deprecated Supabase client utilities

The `server-actions-client`, `route-handler-client`, and `server-component-client` utilities have been removed in favor of `getSupabaseServerClient`. This simplifies and consolidates the API, ensuring consistency across server-side usage. Version bumped to 2.9.0 to reflect breaking changes.
This commit is contained in:
Giancarlo Buomprisco
2025-04-29 09:12:08 +07:00
committed by GitHub
parent 76bfeddd32
commit 4cfb4f936f
20 changed files with 441 additions and 230 deletions

View File

@@ -0,0 +1,9 @@
const Logger = {
info: console.info,
error: console.error,
warn: console.warn,
debug: console.debug,
fatal: console.error,
}
export { Logger };

View File

@@ -2,8 +2,9 @@ import { createRegistry } from '../registry';
import { Logger as LoggerInstance } from './logger';
// Define the type for the logger provider. Currently supporting 'pino'.
type LoggerProvider = 'pino';
type LoggerProvider = 'pino' | 'console';
// Use pino as the default logger provider
const LOGGER = (process.env.LOGGER ?? 'pino') as LoggerProvider;
// Create a registry for logger implementations
@@ -16,6 +17,13 @@ loggerRegistry.register('pino', async () => {
return PinoLogger;
});
// Register the 'console' logger implementation
loggerRegistry.register('console', async () => {
const { Logger: ConsoleLogger } = await import('./impl/console');
return ConsoleLogger;
});
/**
* @name getLogger
* @description Retrieves the logger implementation based on the LOGGER environment variable using the registry API.

View File

@@ -13,9 +13,6 @@
"./server-client": "./src/clients/server-client.ts",
"./server-admin-client": "./src/clients/server-admin-client.ts",
"./middleware-client": "./src/clients/middleware-client.ts",
"./server-actions-client": "./src/clients/server-actions-client.ts",
"./route-handler-client": "./src/clients/route-handler-client.ts",
"./server-component-client": "./src/clients/server-component-client.ts",
"./browser-client": "./src/clients/browser-client.ts",
"./check-requires-mfa": "./src/check-requires-mfa.ts",
"./require-user": "./src/require-user.ts",

View File

@@ -1,65 +0,0 @@
import 'server-only';
import { cookies } from 'next/headers';
import { createClient } from '@supabase/supabase-js';
import type { CookieOptions } from '@supabase/ssr';
import { createServerClient } from '@supabase/ssr';
import { Database } from '../database.types';
import {
getServiceRoleKey,
warnServiceRoleKeyUsage,
} from '../get-service-role-key';
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
const serviceRoleKey = getServiceRoleKey();
const keys = getSupabaseClientKeys();
/**
* @name getSupabaseRouteHandlerClient
* @deprecated Use `getSupabaseServerClient` instead.
* @description Get a Supabase client for use in the Route Handler Routes
*/
export function getSupabaseRouteHandlerClient<GenericSchema = Database>(
params = {
admin: false,
},
) {
if (params.admin) {
warnServiceRoleKeyUsage();
return createClient<GenericSchema>(keys.url, serviceRoleKey, {
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
});
}
return createServerClient<GenericSchema>(keys.url, keys.anonKey, {
cookies: getCookiesStrategy(),
});
}
function getCookiesStrategy() {
return {
set: async (name: string, value: string, options: CookieOptions) => {
const cookieStore = await cookies();
cookieStore.set({ name, value, ...options });
},
get: async (name: string) => {
const cookieStore = await cookies();
return cookieStore.get(name)?.value;
},
remove: async (name: string, options: CookieOptions) => {
const cookieStore = await cookies();
cookieStore.set({ name, value: '', ...options });
},
};
}

View File

@@ -1,76 +0,0 @@
import 'server-only';
import { cookies } from 'next/headers';
import { createClient } from '@supabase/supabase-js';
import { createServerClient } from '@supabase/ssr';
import { Database } from '../database.types';
import {
getServiceRoleKey,
warnServiceRoleKeyUsage,
} from '../get-service-role-key';
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
const keys = getSupabaseClientKeys();
const serviceRoleKey = getServiceRoleKey();
function createServerSupabaseClient<
GenericSchema extends Database = Database,
>() {
return createServerClient<GenericSchema>(keys.url, keys.anonKey, {
cookies: getCookiesStrategy(),
});
}
/**
* @name getSupabaseServerComponentClient
* @deprecated Use `getSupabaseServerClient` instead.
* @param params
*/
export function getSupabaseServerActionClient<
GenericSchema extends Database = Database,
>(params?: { admin: boolean }) {
const keys = getSupabaseClientKeys();
const admin = params?.admin ?? false;
if (admin) {
warnServiceRoleKeyUsage();
return createClient<GenericSchema>(keys.url, serviceRoleKey, {
auth: {
persistSession: false,
detectSessionInUrl: false,
autoRefreshToken: false,
},
});
}
return createServerSupabaseClient();
}
function getCookiesStrategy() {
return {
get: async (name: string) => {
const cookieStore = await cookies();
const cookie = cookieStore.get(name);
return cookie?.value;
},
set: async (name: string, value: string, options: object) => {
const cookieStore = await cookies();
cookieStore.set({ name, value, ...options });
},
remove: async (name: string, options: object) => {
const cookieStore = await cookies();
cookieStore.set({
name,
value: '',
...options,
});
},
};
}

View File

@@ -1,53 +0,0 @@
import 'server-only';
import { cookies } from 'next/headers';
import { createClient } from '@supabase/supabase-js';
import { createServerClient } from '@supabase/ssr';
import { Database } from '../database.types';
import {
getServiceRoleKey,
warnServiceRoleKeyUsage,
} from '../get-service-role-key';
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
const serviceRoleKey = getServiceRoleKey();
const keys = getSupabaseClientKeys();
/**
* @name getSupabaseServerComponentClient
* @description Get a Supabase client for use in the Server Components
*/
export function getSupabaseServerComponentClient<GenericSchema = Database>(
params = {
admin: false,
},
) {
if (params.admin) {
warnServiceRoleKeyUsage();
return createClient<GenericSchema>(keys.url, serviceRoleKey, {
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
});
}
return createServerClient<GenericSchema>(keys.url, keys.anonKey, {
cookies: getCookiesStrategy(),
});
}
function getCookiesStrategy() {
return {
get: async (name: string) => {
const cookieStore = await cookies();
return cookieStore.get(name)?.value;
},
};
}