UNPKG

@pubflow/nextjs

Version:

Next.js adapter for Pubflow framework

254 lines (201 loc) 5.8 kB
# @pubflow/nextjs Next.js adapter for the Pubflow framework. ## Overview `@pubflow/nextjs` provides Next.js-specific implementations and utilities for the Pubflow framework, including: - Server-side rendering (SSR) support - API route handlers - Next.js-specific storage adapter - Integration with Next.js routing ## Installation ```bash # Install the core package and Next.js adapter npm install @pubflow/core @pubflow/nextjs # Optional: Install Zod for schema validation npm install zod ``` ## Schema Validation Pubflow recommends defining schemas at the application level, not in the adapter. This allows for better reusability and separation of concerns. ```tsx // lib/schemas/user.ts import { z } from 'zod'; // Schema for complete user entity export const userSchema = z.object({ id: z.string().uuid().optional(), name: z.string().min(2, 'Name must be at least 2 characters'), email: z.string().email('Invalid email address'), role: z.enum(['user', 'admin'], 'Role must be either user or admin') }); // Schema for creating a user export const createUserSchema = userSchema.omit({ id: true }); // Schema for updating a user export const updateUserSchema = userSchema .partial() .extend({ id: z.string().uuid() }); // TypeScript types inferred from schemas export type User = z.infer<typeof userSchema>; export type CreateUser = z.infer<typeof createUserSchema>; export type UpdateUser = z.infer<typeof updateUserSchema>; ``` These schemas can then be used with Pubflow's CRUD operations: ```tsx import { useBridgeCrud } from '@pubflow/nextjs'; import { userSchema, createUserSchema, updateUserSchema } from '../lib/schemas/user'; function UsersPage() { const { items: users, createItem, updateItem, deleteItem, validationErrors } = useBridgeCrud({ entityConfig: { endpoint: 'users' }, schemas: { entity: userSchema, create: createUserSchema, update: updateUserSchema } }); // Component implementation... } ``` ## Persistent Cache Pubflow Next.js adapter supports persistent caching to improve performance and offline experience: ```jsx import { PubflowProvider, createPersistentCache } from '@pubflow/nextjs'; function MyApp({ Component, pageProps }) { // Create a persistent cache provider const persistentCacheProvider = createPersistentCache({ prefix: 'my_nextjs_app_cache', ttl: 24 * 60 * 60 * 1000, // 24 hours }); return ( <PubflowProvider config={{ baseUrl: 'https://api.example.com', bridgeBasePath: '/bridge', authBasePath: '/auth' }} persistentCache={{ enabled: true, provider: persistentCacheProvider }} > <Component {...pageProps} /> </PubflowProvider> ); } export default MyApp; ``` For more information, see the persistent cache documentation. ## Usage ### Provider Setup ```tsx // pages/_app.tsx import { AppProps } from 'next/app'; import { PubflowProvider } from '@pubflow/nextjs'; function MyApp({ Component, pageProps }: AppProps) { return ( <PubflowProvider config={{ baseUrl: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8787', bridgeBasePath: '/bridge', authBasePath: '/auth' }} loginRedirectPath="/login" publicPaths={['/login', '/register', '/forgot-password']} > <Component {...pageProps} /> </PubflowProvider> ); } export default MyApp; ``` ### Server-Side Authentication ```tsx // pages/profile.tsx import { GetServerSideProps } from 'next'; import { withPubflowSSR, useAuth } from '@pubflow/nextjs'; export const getServerSideProps: GetServerSideProps = withPubflowSSR( async (context, api, auth) => { // Check if user is authenticated const { isValid } = await auth.validateSession(); if (!isValid) { return { redirect: { destination: '/login', permanent: false, }, }; } // Get user data const user = await auth.getCurrentUser(); return { props: { user, }, }; } ); function ProfilePage({ user }) { const { logout } = useAuth(); return ( <div> <h1>Profile</h1> <p>Name: {user.name}</p> <p>Email: {user.email}</p> <button onClick={logout}>Logout</button> </div> ); } export default ProfilePage; ``` ### API Routes ```tsx // pages/api/custom.ts import { NextApiRequest, NextApiResponse } from 'next'; import { withPubflow } from '@pubflow/nextjs'; export default withPubflow(async (req, res, api) => { // Check method if (req.method !== 'GET') { return res.status(405).json({ error: 'Method not allowed' }); } try { // Make API request const response = await api.get('/some/endpoint'); // Return response return res.status(200).json(response.data); } catch (error) { return res.status(500).json({ error: 'Internal server error' }); } }); ``` ### Protected Routes with useServerAuth ```tsx // pages/dashboard.tsx import { useServerAuth } from '@pubflow/nextjs'; function DashboardPage() { // This hook will automatically redirect to login if not authenticated const { user, isAuthenticated, isLoading } = useServerAuth({ loginRedirectPath: '/login', allowedTypes: ['admin', 'manager'] }); if (isLoading) { return <div>Loading...</div>; } return ( <div> <h1>Dashboard</h1> <p>Welcome, {user.name}!</p> </div> ); } export default DashboardPage; ``` ## License AGPL-3.0-or-later