@codebakers/cli 1.2.1 → 1.3.0

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.
@@ -0,0 +1,371 @@
1
+ // Next.js + Supabase + Drizzle project template
2
+
3
+ export const PACKAGE_JSON = {
4
+ name: "my-project",
5
+ version: "0.1.0",
6
+ private: true,
7
+ scripts: {
8
+ "dev": "next dev",
9
+ "build": "next build",
10
+ "start": "next start",
11
+ "lint": "next lint",
12
+ "db:generate": "drizzle-kit generate",
13
+ "db:push": "drizzle-kit push",
14
+ "db:studio": "drizzle-kit studio"
15
+ },
16
+ dependencies: {
17
+ "next": "15.1.0",
18
+ "react": "^19.0.0",
19
+ "react-dom": "^19.0.0",
20
+ "@supabase/supabase-js": "^2.47.10",
21
+ "@supabase/ssr": "^0.5.2",
22
+ "drizzle-orm": "^0.38.2",
23
+ "postgres": "^3.4.5",
24
+ "zod": "^3.24.1",
25
+ "react-hook-form": "^7.54.1",
26
+ "@hookform/resolvers": "^3.9.1",
27
+ "lucide-react": "^0.468.0",
28
+ "clsx": "^2.1.1",
29
+ "tailwind-merge": "^2.6.0"
30
+ },
31
+ devDependencies: {
32
+ "@types/node": "^22.10.2",
33
+ "@types/react": "^19.0.1",
34
+ "@types/react-dom": "^19.0.1",
35
+ "typescript": "^5.7.2",
36
+ "tailwindcss": "^3.4.17",
37
+ "postcss": "^8.4.49",
38
+ "autoprefixer": "^10.4.20",
39
+ "drizzle-kit": "^0.30.1",
40
+ "eslint": "^9.17.0",
41
+ "eslint-config-next": "15.1.0"
42
+ }
43
+ };
44
+
45
+ export const ENV_EXAMPLE = `# Supabase
46
+ NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
47
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
48
+ SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
49
+
50
+ # Database (from Supabase connection string)
51
+ DATABASE_URL=postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres
52
+ `;
53
+
54
+ export const DRIZZLE_CONFIG = `import { defineConfig } from "drizzle-kit";
55
+
56
+ export default defineConfig({
57
+ schema: "./src/db/schema.ts",
58
+ out: "./src/db/migrations",
59
+ dialect: "postgresql",
60
+ dbCredentials: {
61
+ url: process.env.DATABASE_URL!,
62
+ },
63
+ });
64
+ `;
65
+
66
+ export const DB_SCHEMA = `import { pgTable, text, timestamp, uuid, boolean } from "drizzle-orm/pg-core";
67
+
68
+ // Users table (synced with Supabase Auth)
69
+ export const users = pgTable("users", {
70
+ id: uuid("id").primaryKey().notNull(),
71
+ email: text("email").notNull().unique(),
72
+ name: text("name"),
73
+ avatarUrl: text("avatar_url"),
74
+ createdAt: timestamp("created_at").defaultNow().notNull(),
75
+ updatedAt: timestamp("updated_at").defaultNow().notNull(),
76
+ });
77
+
78
+ // Example: Add your tables here following this pattern
79
+ // export const posts = pgTable("posts", {
80
+ // id: uuid("id").primaryKey().defaultRandom(),
81
+ // title: text("title").notNull(),
82
+ // content: text("content"),
83
+ // authorId: uuid("author_id").references(() => users.id),
84
+ // published: boolean("published").default(false),
85
+ // createdAt: timestamp("created_at").defaultNow().notNull(),
86
+ // });
87
+ `;
88
+
89
+ export const DB_INDEX = `import { drizzle } from "drizzle-orm/postgres-js";
90
+ import postgres from "postgres";
91
+ import * as schema from "./schema";
92
+
93
+ const connectionString = process.env.DATABASE_URL!;
94
+
95
+ const client = postgres(connectionString, { prepare: false });
96
+ export const db = drizzle(client, { schema });
97
+
98
+ export type DB = typeof db;
99
+ `;
100
+
101
+ export const SUPABASE_SERVER = `import { createServerClient } from "@supabase/ssr";
102
+ import { cookies } from "next/headers";
103
+
104
+ export async function createClient() {
105
+ const cookieStore = await cookies();
106
+
107
+ return createServerClient(
108
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
109
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
110
+ {
111
+ cookies: {
112
+ getAll() {
113
+ return cookieStore.getAll();
114
+ },
115
+ setAll(cookiesToSet) {
116
+ try {
117
+ cookiesToSet.forEach(({ name, value, options }) =>
118
+ cookieStore.set(name, value, options)
119
+ );
120
+ } catch {
121
+ // The \`setAll\` method was called from a Server Component.
122
+ // This can be ignored if you have middleware refreshing user sessions.
123
+ }
124
+ },
125
+ },
126
+ }
127
+ );
128
+ }
129
+ `;
130
+
131
+ export const SUPABASE_CLIENT = `import { createBrowserClient } from "@supabase/ssr";
132
+
133
+ export function createClient() {
134
+ return createBrowserClient(
135
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
136
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
137
+ );
138
+ }
139
+ `;
140
+
141
+ export const SUPABASE_MIDDLEWARE = `import { createServerClient } from "@supabase/ssr";
142
+ import { NextResponse, type NextRequest } from "next/server";
143
+
144
+ export async function updateSession(request: NextRequest) {
145
+ let supabaseResponse = NextResponse.next({
146
+ request,
147
+ });
148
+
149
+ const supabase = createServerClient(
150
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
151
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
152
+ {
153
+ cookies: {
154
+ getAll() {
155
+ return request.cookies.getAll();
156
+ },
157
+ setAll(cookiesToSet) {
158
+ cookiesToSet.forEach(({ name, value }) =>
159
+ request.cookies.set(name, value)
160
+ );
161
+ supabaseResponse = NextResponse.next({
162
+ request,
163
+ });
164
+ cookiesToSet.forEach(({ name, value, options }) =>
165
+ supabaseResponse.cookies.set(name, value, options)
166
+ );
167
+ },
168
+ },
169
+ }
170
+ );
171
+
172
+ // This will refresh session if expired
173
+ await supabase.auth.getUser();
174
+
175
+ return supabaseResponse;
176
+ }
177
+ `;
178
+
179
+ export const MIDDLEWARE = `import { type NextRequest } from "next/server";
180
+ import { updateSession } from "@/lib/supabase/middleware";
181
+
182
+ export async function middleware(request: NextRequest) {
183
+ return await updateSession(request);
184
+ }
185
+
186
+ export const config = {
187
+ matcher: [
188
+ /*
189
+ * Match all request paths except for:
190
+ * - _next/static (static files)
191
+ * - _next/image (image optimization)
192
+ * - favicon.ico
193
+ * - public files
194
+ */
195
+ "/((?!_next/static|_next/image|favicon.ico|.*\\\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
196
+ ],
197
+ };
198
+ `;
199
+
200
+ export const TAILWIND_CONFIG = `import type { Config } from "tailwindcss";
201
+
202
+ const config: Config = {
203
+ content: [
204
+ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
205
+ "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
206
+ "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
207
+ ],
208
+ theme: {
209
+ extend: {},
210
+ },
211
+ plugins: [],
212
+ };
213
+ export default config;
214
+ `;
215
+
216
+ export const POSTCSS_CONFIG = `module.exports = {
217
+ plugins: {
218
+ tailwindcss: {},
219
+ autoprefixer: {},
220
+ },
221
+ };
222
+ `;
223
+
224
+ export const TSCONFIG = {
225
+ compilerOptions: {
226
+ lib: ["dom", "dom.iterable", "esnext"],
227
+ allowJs: true,
228
+ skipLibCheck: true,
229
+ strict: true,
230
+ noEmit: true,
231
+ esModuleInterop: true,
232
+ module: "esnext",
233
+ moduleResolution: "bundler",
234
+ resolveJsonModule: true,
235
+ isolatedModules: true,
236
+ jsx: "preserve",
237
+ incremental: true,
238
+ plugins: [{ name: "next" }],
239
+ paths: {
240
+ "@/*": ["./src/*"]
241
+ }
242
+ },
243
+ include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
244
+ exclude: ["node_modules"]
245
+ };
246
+
247
+ export const NEXT_CONFIG = `import type { NextConfig } from "next";
248
+
249
+ const nextConfig: NextConfig = {
250
+ /* config options here */
251
+ };
252
+
253
+ export default nextConfig;
254
+ `;
255
+
256
+ export const GLOBALS_CSS = `@tailwind base;
257
+ @tailwind components;
258
+ @tailwind utilities;
259
+
260
+ :root {
261
+ --background: #ffffff;
262
+ --foreground: #171717;
263
+ }
264
+
265
+ @media (prefers-color-scheme: dark) {
266
+ :root {
267
+ --background: #0a0a0a;
268
+ --foreground: #ededed;
269
+ }
270
+ }
271
+
272
+ body {
273
+ color: var(--foreground);
274
+ background: var(--background);
275
+ font-family: Arial, Helvetica, sans-serif;
276
+ }
277
+ `;
278
+
279
+ export const LAYOUT_TSX = `import type { Metadata } from "next";
280
+ import "./globals.css";
281
+
282
+ export const metadata: Metadata = {
283
+ title: "My App",
284
+ description: "Built with CodeBakers patterns",
285
+ };
286
+
287
+ export default function RootLayout({
288
+ children,
289
+ }: Readonly<{
290
+ children: React.ReactNode;
291
+ }>) {
292
+ return (
293
+ <html lang="en">
294
+ <body>{children}</body>
295
+ </html>
296
+ );
297
+ }
298
+ `;
299
+
300
+ export const PAGE_TSX = `export default function Home() {
301
+ return (
302
+ <main className="flex min-h-screen flex-col items-center justify-center p-24">
303
+ <h1 className="text-4xl font-bold mb-4">Welcome to Your App</h1>
304
+ <p className="text-gray-600 mb-8">Built with CodeBakers patterns</p>
305
+ <div className="flex gap-4">
306
+ <a
307
+ href="/login"
308
+ className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
309
+ >
310
+ Get Started
311
+ </a>
312
+ <a
313
+ href="/docs"
314
+ className="px-6 py-3 border border-gray-300 rounded-lg hover:bg-gray-50 transition"
315
+ >
316
+ Documentation
317
+ </a>
318
+ </div>
319
+ </main>
320
+ );
321
+ }
322
+ `;
323
+
324
+ export const UTILS_CN = `import { clsx, type ClassValue } from "clsx";
325
+ import { twMerge } from "tailwind-merge";
326
+
327
+ export function cn(...inputs: ClassValue[]) {
328
+ return twMerge(clsx(inputs));
329
+ }
330
+ `;
331
+
332
+ export const GITIGNORE = `# Dependencies
333
+ node_modules
334
+ .pnpm-debug.log*
335
+
336
+ # Next.js
337
+ .next/
338
+ out/
339
+
340
+ # Production
341
+ build
342
+ dist
343
+
344
+ # Misc
345
+ .DS_Store
346
+ *.pem
347
+
348
+ # Debug
349
+ npm-debug.log*
350
+ yarn-debug.log*
351
+ yarn-error.log*
352
+
353
+ # Local env files
354
+ .env
355
+ .env.local
356
+ .env.development.local
357
+ .env.test.local
358
+ .env.production.local
359
+
360
+ # Vercel
361
+ .vercel
362
+
363
+ # TypeScript
364
+ *.tsbuildinfo
365
+ next-env.d.ts
366
+
367
+ # IDE
368
+ .idea
369
+ .vscode/*
370
+ !.vscode/settings.json
371
+ `;