kofi-stack-template-generator 2.0.17 → 2.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
 
2
- > kofi-stack-template-generator@2.0.17 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
2
+ > kofi-stack-template-generator@2.0.19 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
3
3
  > pnpm run prebuild && tsup src/index.ts --format esm --dts
4
4
 
5
5
 
6
- > kofi-stack-template-generator@2.0.17 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
6
+ > kofi-stack-template-generator@2.0.19 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
7
7
  > node scripts/generate-templates.js
8
8
 
9
9
  Generating templates.generated.ts...
@@ -13,8 +13,8 @@ CLI Using tsconfig: tsconfig.json
13
13
  CLI tsup v8.5.1
14
14
  CLI Target: es2022
15
15
  ESM Build start
16
- ESM dist/index.js 99.29 KB
17
- ESM ⚡️ Build success in 12ms
16
+ ESM dist/index.js 99.49 KB
17
+ ESM ⚡️ Build success in 16ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 411ms
19
+ DTS ⚡️ Build success in 425ms
20
20
  DTS dist/index.d.ts 2.96 KB
package/dist/index.js CHANGED
@@ -270,12 +270,12 @@ var EMBEDDED_TEMPLATES = {
270
270
  "convex": "^1.25.0",
271
271
  "@convex-dev/auth": "^0.0.90",
272
272
  "@auth/core": "^0.37.0",
273
- "@convex-dev/resend": "^0.1.0"{{#if (eq integrations.uploads 'convex-fs')}},
274
- "@convex-dev/convex-fs": "^0.1.0"{{/if}}{{#if (eq integrations.uploads 'r2')}},
275
- "@convex-dev/cloudflare-r2": "^0.1.0"{{/if}}{{#if (eq integrations.payments 'stripe')}},
273
+ "@convex-dev/resend": "^0.2.0"{{#if (eq integrations.uploads 'convex-fs')}},
274
+ "convex-fs": "^0.2.0"{{/if}}{{#if (eq integrations.uploads 'r2')}},
275
+ "@convex-dev/r2": "^0.8.0"{{/if}}{{#if (eq integrations.payments 'stripe')}},
276
276
  "@convex-dev/stripe": "^0.1.0"{{/if}}{{#if (eq integrations.payments 'polar')}},
277
- "@convex-dev/polar": "^0.1.0"{{/if}}{{#if (includes addons 'rate-limiting')}},
278
- "@convex-dev/rate-limiter": "^0.1.0"{{/if}}
277
+ "@convex-dev/polar": "^0.7.0"{{/if}}{{#if (includes addons 'rate-limiting')}},
278
+ "@convex-dev/rate-limiter": "^0.3.0"{{/if}}
279
279
  },
280
280
  "devDependencies": {
281
281
  "typescript": "^5.0.0"
@@ -571,7 +571,7 @@ export default function RootLayout({
571
571
  "marketing/payload/src/globals/index.ts.hbs": "export { SiteSettings } from './SiteSettings'\nexport { Navigation } from './Navigation'\n",
572
572
  "marketing/payload/src/payload.config.ts.hbs": "import path from 'path'\nimport { fileURLToPath } from 'url'\nimport { buildConfig } from 'payload'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { s3Storage } from '@payloadcms/storage-s3'\nimport { seoPlugin } from '@payloadcms/plugin-seo'\n\nimport { Pages } from './collections/Pages'\nimport { Media } from './collections/Media'\nimport { Users } from './collections/Users'\nimport { Posts } from './collections/Posts'\nimport { SiteSettings } from './globals/SiteSettings'\nimport { Navigation } from './globals/Navigation'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nexport default buildConfig({\n admin: {\n user: Users.slug,\n importMap: {\n baseDir: path.resolve(__dirname),\n },\n },\n db: postgresAdapter({\n pool: {\n connectionString: process.env.DATABASE_URL,\n },\n }),\n editor: lexicalEditor(),\n collections: [Users, Media, Pages, Posts],\n globals: [SiteSettings, Navigation],\n plugins: [\n s3Storage({\n collections: {\n media: true,\n },\n bucket: process.env.S3_BUCKET!,\n config: {\n credentials: {\n accessKeyId: process.env.S3_ACCESS_KEY_ID!,\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,\n },\n region: process.env.S3_REGION!,\n endpoint: process.env.S3_ENDPOINT!,\n forcePathStyle: true,\n },\n }),\n seoPlugin({\n collections: ['pages', 'posts'],\n uploadsCollection: 'media',\n generateTitle: ({ doc }) => `${doc?.title ?? ''} | {{projectName}}`,\n generateDescription: ({ doc }) => doc?.excerpt ?? '',\n }),\n ],\n secret: process.env.PAYLOAD_SECRET!,\n typescript: {\n outputFile: path.resolve(__dirname, 'payload-types.ts'),\n },\n})\n",
573
573
  "marketing/payload/tsconfig.json.hbs": '{\n "compilerOptions": {\n "target": "ES2017",\n "lib": ["dom", "dom.iterable", "esnext"],\n "allowJs": true,\n "skipLibCheck": true,\n "strict": true,\n "noEmit": true,\n "esModuleInterop": true,\n "module": "esnext",\n "moduleResolution": "bundler",\n "resolveJsonModule": true,\n "isolatedModules": true,\n "jsx": "react-jsx",\n "incremental": true,\n "plugins": [{ "name": "next" }],\n "paths": {\n "@/*": ["./src/*"]\n }\n },\n "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],\n "exclude": ["node_modules"]\n}\n',
574
- "monorepo/package.json.hbs": '{\n "name": "{{projectName}}",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "node scripts/dev.mjs",\n "dev:all": "turbo dev",\n "dev:web": "turbo -F @repo/web dev",\n "dev:backend": "turbo -F @repo/backend dev",\n "dev:setup": "turbo -F @repo/backend dev:setup",\n "build": "turbo build",\n "lint": "turbo lint",\n "lint:fix": "turbo lint:fix",\n "format": "turbo format",\n "typecheck": "turbo typecheck",\n "test": "turbo test",\n "test:e2e": "turbo test:e2e",\n "clean": "turbo clean && rm -rf node_modules",\n "prepare": "husky"\n },\n "devDependencies": {\n "turbo": "^2.0.0",\n "husky": "^9.0.0",\n "lint-staged": "^15.0.0"\n },\n "packageManager": "pnpm@9.0.0",\n "lint-staged": {\n "*.{js,ts,jsx,tsx}": ["biome check --apply"],\n "*.{json,md}": ["biome format --write"]\n }\n}\n',
574
+ "monorepo/package.json.hbs": '{\n "name": "{{projectName}}",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "node scripts/dev.mjs",\n "dev:all": "turbo dev",\n "dev:web": "turbo -F @repo/web dev",\n "dev:backend": "turbo -F @repo/backend dev",\n "dev:setup": "pnpm --filter @repo/backend dev:setup",\n "build": "turbo build",\n "lint": "turbo lint",\n "lint:fix": "turbo lint:fix",\n "format": "turbo format",\n "typecheck": "turbo typecheck",\n "test": "turbo test",\n "test:e2e": "turbo test:e2e",\n "clean": "turbo clean && rm -rf node_modules",\n "prepare": "husky"\n },\n "devDependencies": {\n "turbo": "^2.0.0",\n "husky": "^9.0.0",\n "lint-staged": "^15.0.0"\n },\n "packageManager": "pnpm@9.0.0",\n "lint-staged": {\n "*.{js,ts,jsx,tsx}": ["biome check --apply"],\n "*.{json,md}": ["biome format --write"]\n }\n}\n',
575
575
  "monorepo/pnpm-workspace.yaml.hbs": 'packages:\n - "apps/*"\n - "packages/*"\n',
576
576
  "monorepo/turbo.json.hbs": '{\n "$schema": "https://turbo.build/schema.json",\n "ui": "tui",\n "tasks": {\n "build": {\n "dependsOn": ["^build"],\n "inputs": ["$TURBO_DEFAULT$", ".env*"],\n "outputs": [".next/**", "!.next/cache/**", "dist/**"]\n },\n "lint": {\n "dependsOn": ["^lint"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "lint:fix": {\n "dependsOn": ["^lint:fix"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "format": {\n "dependsOn": ["^format"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "typecheck": {\n "dependsOn": ["^typecheck"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "dev": {\n "cache": false,\n "persistent": true\n },\n "dev:setup": {\n "cache": false,\n "interactive": true\n },\n "test": {\n "dependsOn": ["^build"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "test:e2e": {\n "dependsOn": ["build"],\n "inputs": ["$TURBO_DEFAULT$"]\n },\n "clean": {\n "cache": false\n }\n }\n}\n',
577
577
  "packages/config-biome/biome.json.hbs": '{\n "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",\n "extends": ["../../biome.json"]\n}\n',
@@ -1255,7 +1255,34 @@ export function DashboardLayout({ children, title = 'Dashboard' }: DashboardLayo
1255
1255
  "web/src/components/providers/convex-provider.tsx.hbs": "'use client'\n\nimport { ConvexAuthNextjsProvider } from '@convex-dev/auth/nextjs'\nimport { ConvexReactClient } from 'convex/react'\n\nconst convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!)\n\nexport function ConvexClientProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <ConvexAuthNextjsProvider client={convex}>\n {children}\n </ConvexAuthNextjsProvider>\n )\n}\n",
1256
1256
  "web/src/lib/auth.ts.hbs": "'use client'\n\nimport { useConvexAuth, useQuery } from 'convex/react'\nimport { useAuthActions } from '@convex-dev/auth/react'\nimport { api } from '{{#if (eq structure 'monorepo')}}@repo/backend/convex/_generated/api{{else}}../../convex/_generated/api{{/if}}'\n\nexport function useAuth() {\n const { isAuthenticated, isLoading } = useConvexAuth()\n const { signIn, signOut } = useAuthActions()\n const user = useQuery(api.users.viewer)\n\n return {\n isAuthenticated,\n isLoading,\n user,\n signIn: (provider: 'github' | 'google') => {\n void signIn(provider)\n },\n signInWithPassword: async (email: string, password: string, flow: 'signIn' | 'signUp' = 'signIn', name?: string) => {\n const formData = new FormData()\n formData.append('email', email)\n formData.append('password', password)\n formData.append('flow', flow)\n if (name) {\n formData.append('name', name)\n }\n await signIn('password', formData)\n },\n signOut: () => {\n void signOut()\n },\n }\n}\n",
1257
1257
  "web/src/lib/utils.ts.hbs": "import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
1258
- "web/src/proxy.ts.hbs": "import {\n convexAuthNextjsProxy,\n createRouteMatcher,\n nextjsProxyRedirect,\n} from '@convex-dev/auth/nextjs/server'\n\nconst isPublicRoute = createRouteMatcher(['/sign-in', '/sign-up'])\n\nexport default convexAuthNextjsProxy(async (request, { convexAuth }) => {\n const isAuthenticated = await convexAuth.isAuthenticated()\n\n // Redirect unauthenticated users to /sign-up\n if (!isPublicRoute(request) && !isAuthenticated) {\n return nextjsProxyRedirect(request, '/sign-up')\n }\n\n // Redirect authenticated users from auth pages to / (dashboard)\n if (isPublicRoute(request) && isAuthenticated) {\n return nextjsProxyRedirect(request, '/')\n }\n})\n",
1258
+ "web/src/proxy.ts.hbs": `import {
1259
+ convexAuthNextjsMiddleware,
1260
+ createRouteMatcher,
1261
+ nextjsMiddlewareRedirect,
1262
+ } from '@convex-dev/auth/nextjs/server'
1263
+
1264
+ const isPublicRoute = createRouteMatcher(['/sign-in', '/sign-up'])
1265
+
1266
+ // Next.js 16 uses proxy.ts (renamed from middleware.ts)
1267
+ // @convex-dev/auth still uses "middleware" naming in exports
1268
+ export default convexAuthNextjsMiddleware(async (request, { convexAuth }) => {
1269
+ const isAuthenticated = await convexAuth.isAuthenticated()
1270
+
1271
+ // Redirect unauthenticated users to /sign-up
1272
+ if (!isPublicRoute(request) && !isAuthenticated) {
1273
+ return nextjsMiddlewareRedirect(request, '/sign-up')
1274
+ }
1275
+
1276
+ // Redirect authenticated users from auth pages to / (dashboard)
1277
+ if (isPublicRoute(request) && isAuthenticated) {
1278
+ return nextjsMiddlewareRedirect(request, '/')
1279
+ }
1280
+ })
1281
+
1282
+ export const config = {
1283
+ matcher: ['/((?!.*\\\\..*|_next).*)', '/', '/(api|trpc)(.*)'],
1284
+ }
1285
+ `,
1259
1286
  "web/tsconfig.json.hbs": '{\n "compilerOptions": {\n "target": "ES2017",\n "lib": ["dom", "dom.iterable", "esnext"],\n "allowJs": true,\n "skipLibCheck": true,\n "strict": true,\n "noEmit": true,\n "esModuleInterop": true,\n "module": "esnext",\n "moduleResolution": "bundler",\n "resolveJsonModule": true,\n "isolatedModules": true,\n "jsx": "react-jsx",\n "incremental": true,\n "plugins": [{ "name": "next" }],\n "paths": {\n "@/*": ["./src/*"]\n }\n },\n "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],\n "exclude": ["node_modules"]\n}\n'
1260
1287
  };
1261
1288
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kofi-stack-template-generator",
3
- "version": "2.0.17",
3
+ "version": "2.0.19",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -10,6 +10,12 @@
10
10
  "types": "./dist/index.d.ts"
11
11
  }
12
12
  },
13
+ "scripts": {
14
+ "build": "pnpm run prebuild && tsup src/index.ts --format esm --dts",
15
+ "dev": "tsup src/index.ts --format esm --dts --watch",
16
+ "prebuild": "node scripts/generate-templates.js",
17
+ "typecheck": "tsc --noEmit"
18
+ },
13
19
  "dependencies": {
14
20
  "kofi-stack-types": "^2.0.3",
15
21
  "handlebars": "^4.7.8",
@@ -19,11 +25,5 @@
19
25
  "@types/node": "^20.0.0",
20
26
  "tsup": "^8.0.0",
21
27
  "typescript": "^5.0.0"
22
- },
23
- "scripts": {
24
- "build": "pnpm run prebuild && tsup src/index.ts --format esm --dts",
25
- "dev": "tsup src/index.ts --format esm --dts --watch",
26
- "prebuild": "node scripts/generate-templates.js",
27
- "typecheck": "tsc --noEmit"
28
28
  }
29
- }
29
+ }
@@ -1,6 +1,6 @@
1
1
  // Auto-generated file. Do not edit manually.
2
2
  // Run 'pnpm prebuild' to regenerate.
3
- // Generated: 2026-01-14T01:39:16.805Z
3
+ // Generated: 2026-01-14T02:00:59.812Z
4
4
  // Template count: 86
5
5
 
6
6
  export const EMBEDDED_TEMPLATES: Record<string, string> = {
@@ -11,7 +11,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
11
11
  "convex/convex/http.ts.hbs": "import { httpRouter } from 'convex/server'\nimport { auth } from './auth'\n\nconst http = httpRouter()\n\nauth.addHttpRoutes(http)\n\nexport default http\n",
12
12
  "convex/convex/schema.ts.hbs": "import { defineSchema, defineTable } from 'convex/server'\nimport { authTables } from '@convex-dev/auth/server'\nimport { v } from 'convex/values'\n\nexport default defineSchema({\n ...authTables,\n // Add your custom tables here\n // Example:\n // posts: defineTable({\n // title: v.string(),\n // content: v.string(),\n // authorId: v.id('users'),\n // createdAt: v.number(),\n // }).index('by_author', ['authorId']),\n})\n",
13
13
  "convex/convex/users.ts.hbs": "import { query } from './_generated/server'\nimport { auth } from './auth'\n\nexport const current = query({\n args: {},\n handler: async (ctx) => {\n const userId = await auth.getUserId(ctx)\n if (!userId) return null\n\n const user = await ctx.db.get(userId)\n return user\n },\n})\n\n// Alias for current user - used by dashboard components\nexport const viewer = query({\n args: {},\n handler: async (ctx) => {\n const userId = await auth.getUserId(ctx)\n if (!userId) return null\n\n const user = await ctx.db.get(userId)\n return user\n },\n})\n",
14
- "convex/package.json.hbs": "{{#if (eq structure 'monorepo')}}{\n \"name\": \"@repo/backend\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"main\": \"./convex/_generated/api.js\",\n \"types\": \"./convex/_generated/api.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./convex/_generated/api.js\",\n \"types\": \"./convex/_generated/api.d.ts\"\n }\n },\n \"scripts\": {\n \"dev\": \"convex dev\",\n \"dev:setup\": \"convex dev --configure --until-success\",\n \"deploy\": \"convex deploy\"\n },\n \"dependencies\": {\n \"convex\": \"^1.25.0\",\n \"@convex-dev/auth\": \"^0.0.90\",\n \"@auth/core\": \"^0.37.0\",\n \"@convex-dev/resend\": \"^0.1.0\"{{#if (eq integrations.uploads 'convex-fs')}},\n \"@convex-dev/convex-fs\": \"^0.1.0\"{{/if}}{{#if (eq integrations.uploads 'r2')}},\n \"@convex-dev/cloudflare-r2\": \"^0.1.0\"{{/if}}{{#if (eq integrations.payments 'stripe')}},\n \"@convex-dev/stripe\": \"^0.1.0\"{{/if}}{{#if (eq integrations.payments 'polar')}},\n \"@convex-dev/polar\": \"^0.1.0\"{{/if}}{{#if (includes addons 'rate-limiting')}},\n \"@convex-dev/rate-limiter\": \"^0.1.0\"{{/if}}\n },\n \"devDependencies\": {\n \"typescript\": \"^5.0.0\"\n }\n}{{/if}}\n",
14
+ "convex/package.json.hbs": "{{#if (eq structure 'monorepo')}}{\n \"name\": \"@repo/backend\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"main\": \"./convex/_generated/api.js\",\n \"types\": \"./convex/_generated/api.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./convex/_generated/api.js\",\n \"types\": \"./convex/_generated/api.d.ts\"\n }\n },\n \"scripts\": {\n \"dev\": \"convex dev\",\n \"dev:setup\": \"convex dev --configure --until-success\",\n \"deploy\": \"convex deploy\"\n },\n \"dependencies\": {\n \"convex\": \"^1.25.0\",\n \"@convex-dev/auth\": \"^0.0.90\",\n \"@auth/core\": \"^0.37.0\",\n \"@convex-dev/resend\": \"^0.2.0\"{{#if (eq integrations.uploads 'convex-fs')}},\n \"convex-fs\": \"^0.2.0\"{{/if}}{{#if (eq integrations.uploads 'r2')}},\n \"@convex-dev/r2\": \"^0.8.0\"{{/if}}{{#if (eq integrations.payments 'stripe')}},\n \"@convex-dev/stripe\": \"^0.1.0\"{{/if}}{{#if (eq integrations.payments 'polar')}},\n \"@convex-dev/polar\": \"^0.7.0\"{{/if}}{{#if (includes addons 'rate-limiting')}},\n \"@convex-dev/rate-limiter\": \"^0.3.0\"{{/if}}\n },\n \"devDependencies\": {\n \"typescript\": \"^5.0.0\"\n }\n}{{/if}}\n",
15
15
  "convex/tsconfig.json.hbs": "{{#if (eq structure 'monorepo')}}{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"noEmit\": true,\n \"outDir\": \"dist\"\n },\n \"include\": [\"convex/**/*.ts\"],\n \"exclude\": [\"node_modules\"]\n}{{/if}}\n",
16
16
  "integrations/posthog/src/components/providers/posthog-provider.tsx.hbs": "'use client'\n\nimport posthog from 'posthog-js'\nimport { PostHogProvider as PHProvider } from 'posthog-js/react'\nimport { useEffect } from 'react'\n\nexport function PostHogProvider({ children }: { children: React.ReactNode }) {\n useEffect(() => {\n posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {\n api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com',\n person_profiles: 'identified_only',\n capture_pageview: false, // We capture pageviews manually\n })\n }, [])\n\n return <PHProvider client={posthog}>{children}</PHProvider>\n}\n",
17
17
  "marketing/nextjs/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n transpilePackages: ['@repo/ui'],\n}\n\nexport default nextConfig\n",
@@ -58,7 +58,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
58
58
  "marketing/payload/src/globals/index.ts.hbs": "export { SiteSettings } from './SiteSettings'\nexport { Navigation } from './Navigation'\n",
59
59
  "marketing/payload/src/payload.config.ts.hbs": "import path from 'path'\nimport { fileURLToPath } from 'url'\nimport { buildConfig } from 'payload'\nimport { postgresAdapter } from '@payloadcms/db-postgres'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { s3Storage } from '@payloadcms/storage-s3'\nimport { seoPlugin } from '@payloadcms/plugin-seo'\n\nimport { Pages } from './collections/Pages'\nimport { Media } from './collections/Media'\nimport { Users } from './collections/Users'\nimport { Posts } from './collections/Posts'\nimport { SiteSettings } from './globals/SiteSettings'\nimport { Navigation } from './globals/Navigation'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nexport default buildConfig({\n admin: {\n user: Users.slug,\n importMap: {\n baseDir: path.resolve(__dirname),\n },\n },\n db: postgresAdapter({\n pool: {\n connectionString: process.env.DATABASE_URL,\n },\n }),\n editor: lexicalEditor(),\n collections: [Users, Media, Pages, Posts],\n globals: [SiteSettings, Navigation],\n plugins: [\n s3Storage({\n collections: {\n media: true,\n },\n bucket: process.env.S3_BUCKET!,\n config: {\n credentials: {\n accessKeyId: process.env.S3_ACCESS_KEY_ID!,\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,\n },\n region: process.env.S3_REGION!,\n endpoint: process.env.S3_ENDPOINT!,\n forcePathStyle: true,\n },\n }),\n seoPlugin({\n collections: ['pages', 'posts'],\n uploadsCollection: 'media',\n generateTitle: ({ doc }) => `${doc?.title ?? ''} | {{projectName}}`,\n generateDescription: ({ doc }) => doc?.excerpt ?? '',\n }),\n ],\n secret: process.env.PAYLOAD_SECRET!,\n typescript: {\n outputFile: path.resolve(__dirname, 'payload-types.ts'),\n },\n})\n",
60
60
  "marketing/payload/tsconfig.json.hbs": "{\n \"compilerOptions\": {\n \"target\": \"ES2017\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"jsx\": \"react-jsx\",\n \"incremental\": true,\n \"plugins\": [{ \"name\": \"next\" }],\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\", \".next/dev/types/**/*.ts\"],\n \"exclude\": [\"node_modules\"]\n}\n",
61
- "monorepo/package.json.hbs": "{\n \"name\": \"{{projectName}}\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"node scripts/dev.mjs\",\n \"dev:all\": \"turbo dev\",\n \"dev:web\": \"turbo -F @repo/web dev\",\n \"dev:backend\": \"turbo -F @repo/backend dev\",\n \"dev:setup\": \"turbo -F @repo/backend dev:setup\",\n \"build\": \"turbo build\",\n \"lint\": \"turbo lint\",\n \"lint:fix\": \"turbo lint:fix\",\n \"format\": \"turbo format\",\n \"typecheck\": \"turbo typecheck\",\n \"test\": \"turbo test\",\n \"test:e2e\": \"turbo test:e2e\",\n \"clean\": \"turbo clean && rm -rf node_modules\",\n \"prepare\": \"husky\"\n },\n \"devDependencies\": {\n \"turbo\": \"^2.0.0\",\n \"husky\": \"^9.0.0\",\n \"lint-staged\": \"^15.0.0\"\n },\n \"packageManager\": \"pnpm@9.0.0\",\n \"lint-staged\": {\n \"*.{js,ts,jsx,tsx}\": [\"biome check --apply\"],\n \"*.{json,md}\": [\"biome format --write\"]\n }\n}\n",
61
+ "monorepo/package.json.hbs": "{\n \"name\": \"{{projectName}}\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"node scripts/dev.mjs\",\n \"dev:all\": \"turbo dev\",\n \"dev:web\": \"turbo -F @repo/web dev\",\n \"dev:backend\": \"turbo -F @repo/backend dev\",\n \"dev:setup\": \"pnpm --filter @repo/backend dev:setup\",\n \"build\": \"turbo build\",\n \"lint\": \"turbo lint\",\n \"lint:fix\": \"turbo lint:fix\",\n \"format\": \"turbo format\",\n \"typecheck\": \"turbo typecheck\",\n \"test\": \"turbo test\",\n \"test:e2e\": \"turbo test:e2e\",\n \"clean\": \"turbo clean && rm -rf node_modules\",\n \"prepare\": \"husky\"\n },\n \"devDependencies\": {\n \"turbo\": \"^2.0.0\",\n \"husky\": \"^9.0.0\",\n \"lint-staged\": \"^15.0.0\"\n },\n \"packageManager\": \"pnpm@9.0.0\",\n \"lint-staged\": {\n \"*.{js,ts,jsx,tsx}\": [\"biome check --apply\"],\n \"*.{json,md}\": [\"biome format --write\"]\n }\n}\n",
62
62
  "monorepo/pnpm-workspace.yaml.hbs": "packages:\n - \"apps/*\"\n - \"packages/*\"\n",
63
63
  "monorepo/turbo.json.hbs": "{\n \"$schema\": \"https://turbo.build/schema.json\",\n \"ui\": \"tui\",\n \"tasks\": {\n \"build\": {\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n \"outputs\": [\".next/**\", \"!.next/cache/**\", \"dist/**\"]\n },\n \"lint\": {\n \"dependsOn\": [\"^lint\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"lint:fix\": {\n \"dependsOn\": [\"^lint:fix\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"format\": {\n \"dependsOn\": [\"^format\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"typecheck\": {\n \"dependsOn\": [\"^typecheck\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"dev\": {\n \"cache\": false,\n \"persistent\": true\n },\n \"dev:setup\": {\n \"cache\": false,\n \"interactive\": true\n },\n \"test\": {\n \"dependsOn\": [\"^build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"test:e2e\": {\n \"dependsOn\": [\"build\"],\n \"inputs\": [\"$TURBO_DEFAULT$\"]\n },\n \"clean\": {\n \"cache\": false\n }\n }\n}\n",
64
64
  "packages/config-biome/biome.json.hbs": "{\n \"$schema\": \"https://biomejs.dev/schemas/1.9.4/schema.json\",\n \"extends\": [\"../../biome.json\"]\n}\n",
@@ -88,6 +88,6 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
88
88
  "web/src/components/providers/convex-provider.tsx.hbs": "'use client'\n\nimport { ConvexAuthNextjsProvider } from '@convex-dev/auth/nextjs'\nimport { ConvexReactClient } from 'convex/react'\n\nconst convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!)\n\nexport function ConvexClientProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <ConvexAuthNextjsProvider client={convex}>\n {children}\n </ConvexAuthNextjsProvider>\n )\n}\n",
89
89
  "web/src/lib/auth.ts.hbs": "'use client'\n\nimport { useConvexAuth, useQuery } from 'convex/react'\nimport { useAuthActions } from '@convex-dev/auth/react'\nimport { api } from '{{#if (eq structure 'monorepo')}}@repo/backend/convex/_generated/api{{else}}../../convex/_generated/api{{/if}}'\n\nexport function useAuth() {\n const { isAuthenticated, isLoading } = useConvexAuth()\n const { signIn, signOut } = useAuthActions()\n const user = useQuery(api.users.viewer)\n\n return {\n isAuthenticated,\n isLoading,\n user,\n signIn: (provider: 'github' | 'google') => {\n void signIn(provider)\n },\n signInWithPassword: async (email: string, password: string, flow: 'signIn' | 'signUp' = 'signIn', name?: string) => {\n const formData = new FormData()\n formData.append('email', email)\n formData.append('password', password)\n formData.append('flow', flow)\n if (name) {\n formData.append('name', name)\n }\n await signIn('password', formData)\n },\n signOut: () => {\n void signOut()\n },\n }\n}\n",
90
90
  "web/src/lib/utils.ts.hbs": "import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n",
91
- "web/src/proxy.ts.hbs": "import {\n convexAuthNextjsProxy,\n createRouteMatcher,\n nextjsProxyRedirect,\n} from '@convex-dev/auth/nextjs/server'\n\nconst isPublicRoute = createRouteMatcher(['/sign-in', '/sign-up'])\n\nexport default convexAuthNextjsProxy(async (request, { convexAuth }) => {\n const isAuthenticated = await convexAuth.isAuthenticated()\n\n // Redirect unauthenticated users to /sign-up\n if (!isPublicRoute(request) && !isAuthenticated) {\n return nextjsProxyRedirect(request, '/sign-up')\n }\n\n // Redirect authenticated users from auth pages to / (dashboard)\n if (isPublicRoute(request) && isAuthenticated) {\n return nextjsProxyRedirect(request, '/')\n }\n})\n",
91
+ "web/src/proxy.ts.hbs": "import {\n convexAuthNextjsMiddleware,\n createRouteMatcher,\n nextjsMiddlewareRedirect,\n} from '@convex-dev/auth/nextjs/server'\n\nconst isPublicRoute = createRouteMatcher(['/sign-in', '/sign-up'])\n\n// Next.js 16 uses proxy.ts (renamed from middleware.ts)\n// @convex-dev/auth still uses \"middleware\" naming in exports\nexport default convexAuthNextjsMiddleware(async (request, { convexAuth }) => {\n const isAuthenticated = await convexAuth.isAuthenticated()\n\n // Redirect unauthenticated users to /sign-up\n if (!isPublicRoute(request) && !isAuthenticated) {\n return nextjsMiddlewareRedirect(request, '/sign-up')\n }\n\n // Redirect authenticated users from auth pages to / (dashboard)\n if (isPublicRoute(request) && isAuthenticated) {\n return nextjsMiddlewareRedirect(request, '/')\n }\n})\n\nexport const config = {\n matcher: ['/((?!.*\\\\..*|_next).*)', '/', '/(api|trpc)(.*)'],\n}\n",
92
92
  "web/tsconfig.json.hbs": "{\n \"compilerOptions\": {\n \"target\": \"ES2017\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"jsx\": \"react-jsx\",\n \"incremental\": true,\n \"plugins\": [{ \"name\": \"next\" }],\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\", \".next/dev/types/**/*.ts\"],\n \"exclude\": [\"node_modules\"]\n}\n"
93
93
  }
@@ -20,12 +20,12 @@
20
20
  "convex": "^1.25.0",
21
21
  "@convex-dev/auth": "^0.0.90",
22
22
  "@auth/core": "^0.37.0",
23
- "@convex-dev/resend": "^0.1.0"{{#if (eq integrations.uploads 'convex-fs')}},
24
- "@convex-dev/convex-fs": "^0.1.0"{{/if}}{{#if (eq integrations.uploads 'r2')}},
25
- "@convex-dev/cloudflare-r2": "^0.1.0"{{/if}}{{#if (eq integrations.payments 'stripe')}},
23
+ "@convex-dev/resend": "^0.2.0"{{#if (eq integrations.uploads 'convex-fs')}},
24
+ "convex-fs": "^0.2.0"{{/if}}{{#if (eq integrations.uploads 'r2')}},
25
+ "@convex-dev/r2": "^0.8.0"{{/if}}{{#if (eq integrations.payments 'stripe')}},
26
26
  "@convex-dev/stripe": "^0.1.0"{{/if}}{{#if (eq integrations.payments 'polar')}},
27
- "@convex-dev/polar": "^0.1.0"{{/if}}{{#if (includes addons 'rate-limiting')}},
28
- "@convex-dev/rate-limiter": "^0.1.0"{{/if}}
27
+ "@convex-dev/polar": "^0.7.0"{{/if}}{{#if (includes addons 'rate-limiting')}},
28
+ "@convex-dev/rate-limiter": "^0.3.0"{{/if}}
29
29
  },
30
30
  "devDependencies": {
31
31
  "typescript": "^5.0.0"
@@ -7,7 +7,7 @@
7
7
  "dev:all": "turbo dev",
8
8
  "dev:web": "turbo -F @repo/web dev",
9
9
  "dev:backend": "turbo -F @repo/backend dev",
10
- "dev:setup": "turbo -F @repo/backend dev:setup",
10
+ "dev:setup": "pnpm --filter @repo/backend dev:setup",
11
11
  "build": "turbo build",
12
12
  "lint": "turbo lint",
13
13
  "lint:fix": "turbo lint:fix",
@@ -1,21 +1,27 @@
1
1
  import {
2
- convexAuthNextjsProxy,
2
+ convexAuthNextjsMiddleware,
3
3
  createRouteMatcher,
4
- nextjsProxyRedirect,
4
+ nextjsMiddlewareRedirect,
5
5
  } from '@convex-dev/auth/nextjs/server'
6
6
 
7
7
  const isPublicRoute = createRouteMatcher(['/sign-in', '/sign-up'])
8
8
 
9
- export default convexAuthNextjsProxy(async (request, { convexAuth }) => {
9
+ // Next.js 16 uses proxy.ts (renamed from middleware.ts)
10
+ // @convex-dev/auth still uses "middleware" naming in exports
11
+ export default convexAuthNextjsMiddleware(async (request, { convexAuth }) => {
10
12
  const isAuthenticated = await convexAuth.isAuthenticated()
11
13
 
12
14
  // Redirect unauthenticated users to /sign-up
13
15
  if (!isPublicRoute(request) && !isAuthenticated) {
14
- return nextjsProxyRedirect(request, '/sign-up')
16
+ return nextjsMiddlewareRedirect(request, '/sign-up')
15
17
  }
16
18
 
17
19
  // Redirect authenticated users from auth pages to / (dashboard)
18
20
  if (isPublicRoute(request) && isAuthenticated) {
19
- return nextjsProxyRedirect(request, '/')
21
+ return nextjsMiddlewareRedirect(request, '/')
20
22
  }
21
23
  })
24
+
25
+ export const config = {
26
+ matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'],
27
+ }