@primstack/cli 0.0.5 → 0.0.6

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,15 +1,15 @@
1
1
  # {{PROJECT_NAME}}
2
2
 
3
- A Primstack hosted project — Next.js + Primstack UI + D1 + Auth.js, deployed to Primstack hosting.
3
+ A Primstack hosted project — Next.js + Primstack UI + SQLite + Auth.js, deployed to Primstack hosting.
4
4
 
5
5
  ## Stack
6
6
 
7
- - **Framework:** Next.js 14 (App Router, edge runtime)
7
+ - **Framework:** Next.js 16 (App Router, Turbopack)
8
8
  - **Components:** @primstack/ui (60+ Radix-based React components)
9
9
  - **Styling:** Tailwind CSS + Primstack design tokens
10
- - **Database:** Cloudflare D1 via Drizzle ORM (local D1 via `setupDevPlatform` in dev)
10
+ - **Database:** SQLite via Drizzle ORM (better-sqlite3 locally)
11
11
  - **Auth:** Auth.js v5 with GitHub provider + Drizzle adapter
12
- - **Hosting:** Primstack hosting (Cloudflare Pages via `@cloudflare/next-on-pages`)
12
+ - **Hosting:** Primstack hosting
13
13
 
14
14
  ## Component Usage
15
15
 
@@ -70,15 +70,9 @@ export async function createPost(formData: FormData) {
70
70
  }
71
71
  ```
72
72
 
73
- `getDatabase()` uses the D1 binding via `getRequestContext()` in both production and local dev (via `setupDevPlatform` in `src/instrumentation.ts`).
74
-
75
73
  ## Adding a New Page
76
74
 
77
- All pages that use CF bindings (D1, env vars) must declare edge runtime:
78
-
79
75
  ```tsx
80
- export const runtime = 'edge';
81
-
82
76
  export default function MyPage() {
83
77
  return <div>Hello</div>;
84
78
  }
@@ -91,8 +85,6 @@ export default function MyPage() {
91
85
  import { auth } from '@/lib/auth';
92
86
  import { redirect } from 'next/navigation';
93
87
 
94
- export const runtime = 'edge';
95
-
96
88
  export default async function ProtectedPage() {
97
89
  const session = await auth();
98
90
  if (!session) redirect('/auth/login');
@@ -112,8 +104,6 @@ prim env set GITHUB_CLIENT_SECRET=... # GitHub OAuth secret
112
104
  prim deploy # Vars injected automatically
113
105
  ```
114
106
 
115
- D1 is bound automatically via the Primstack platform — no need to set `DATABASE_URL`.
116
-
117
107
  ## Deployment
118
108
 
119
109
  ```bash
@@ -130,10 +120,8 @@ prim deploy -m "message" # Deploy with message
130
120
  | `src/app/layout.tsx` | Root layout with ThemeProvider |
131
121
  | `src/app/page.tsx` | Home page |
132
122
  | `src/db/schema.ts` | Database schema (Drizzle) |
133
- | `src/lib/db.ts` | Database connection (D1 via getRequestContext) |
123
+ | `src/lib/db.ts` | Database connection (better-sqlite3) |
134
124
  | `src/lib/auth.ts` | Auth.js configuration + Drizzle adapter |
135
125
  | `src/middleware.ts` | Auth middleware |
136
- | `src/instrumentation.ts` | setupDevPlatform for local D1 |
137
126
  | `src/app/actions/*.ts` | Server Actions |
138
- | `wrangler.toml` | CF Pages config (D1 binding) |
139
127
  | `primstack.config.json` | Project configuration |
@@ -6,7 +6,6 @@
6
6
  "scripts": {
7
7
  "dev": "next dev --turbopack",
8
8
  "build": "next build",
9
- "preview": "npx wrangler pages dev .vercel/output/static",
10
9
  "lint": "next lint",
11
10
  "db:generate": "drizzle-kit generate",
12
11
  "db:migrate": "drizzle-kit migrate",
@@ -18,6 +17,7 @@
18
17
  "@primstack/theme": "^0.0.2",
19
18
  "@primstack/tokens": "^0.0.2",
20
19
  "@primstack/ui": "^0.0.2",
20
+ "better-sqlite3": "^11.0.0",
21
21
  "drizzle-orm": "^0.38.0",
22
22
  "next": "^16.0.0",
23
23
  "next-auth": "^5.0.0-beta.25",
@@ -25,15 +25,14 @@
25
25
  "react-dom": "^19.0.0"
26
26
  },
27
27
  "devDependencies": {
28
+ "@types/better-sqlite3": "^7.6.0",
28
29
  "@types/node": "^22.0.0",
29
30
  "@types/react": "^19.0.0",
30
31
  "@types/react-dom": "^19.0.0",
31
32
  "autoprefixer": "^10.4.0",
32
- "better-sqlite3": "^11.0.0",
33
33
  "drizzle-kit": "^0.30.0",
34
34
  "postcss": "^8.4.0",
35
35
  "tailwindcss": "^3.4.0",
36
- "typescript": "^5.7.0",
37
- "wrangler": "^4.0.0"
36
+ "typescript": "^5.7.0"
38
37
  }
39
38
  }
@@ -1,5 +1,3 @@
1
- export const runtime = 'edge';
2
-
3
1
  export function GET() {
4
2
  return Response.json({ ok: true, timestamp: Date.now() });
5
3
  }
@@ -2,8 +2,6 @@ import { signIn } from '@/lib/auth';
2
2
  import { Button } from '@primstack/ui/button';
3
3
  import { Heading, Text } from '@primstack/ui/text';
4
4
 
5
- export const runtime = 'edge';
6
-
7
5
  export default function LoginPage() {
8
6
  return (
9
7
  <div className="min-h-screen flex items-center justify-center bg-background px-4">
@@ -1,5 +1,3 @@
1
- export const runtime = 'edge';
2
-
3
1
  export default function Home() {
4
2
  return (
5
3
  <main className="flex min-h-screen flex-col items-center justify-center p-8">
@@ -1,10 +1,9 @@
1
- interface CloudflareEnv {
2
- DB: D1Database;
3
- }
4
-
5
- declare module '@cloudflare/next-on-pages' {
6
- export function getRequestContext(): {
7
- env: CloudflareEnv;
8
- ctx: ExecutionContext;
9
- };
1
+ // Environment variable declarations
2
+ declare namespace NodeJS {
3
+ interface ProcessEnv {
4
+ AUTH_SECRET: string;
5
+ GITHUB_CLIENT_ID: string;
6
+ GITHUB_CLIENT_SECRET: string;
7
+ DATABASE_URL?: string;
8
+ }
10
9
  }
@@ -4,17 +4,7 @@ import { DrizzleAdapter } from '@auth/drizzle-adapter';
4
4
  import { getDatabase } from './db';
5
5
  import { authUsers, accounts, sessions } from '../db/schema';
6
6
 
7
- /**
8
- * Auth.js v5 configuration.
9
- *
10
- * Uses the Drizzle adapter to persist users, accounts, and sessions in D1.
11
- * JWT strategy is used so middleware can validate sessions at the edge
12
- * without a DB round-trip on every request.
13
- *
14
- * NextAuth is called with a callback so the adapter is created per-request
15
- * (getDatabase() requires an active request context for getRequestContext()).
16
- */
17
- export const { handlers, signIn, signOut, auth } = NextAuth(() => ({
7
+ export const { handlers, signIn, signOut, auth } = NextAuth({
18
8
  adapter: DrizzleAdapter(getDatabase(), {
19
9
  usersTable: authUsers,
20
10
  accountsTable: accounts,
@@ -32,4 +22,4 @@ export const { handlers, signIn, signOut, auth } = NextAuth(() => ({
32
22
  pages: {
33
23
  signIn: '/auth/login',
34
24
  },
35
- }));
25
+ });
@@ -1,17 +1,24 @@
1
- import { getRequestContext } from '@cloudflare/next-on-pages';
2
- import { drizzle } from 'drizzle-orm/d1';
1
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
2
+ import Database from 'better-sqlite3';
3
3
  import * as schema from '../db/schema';
4
+ import path from 'path';
4
5
 
5
- export type AppDb = ReturnType<typeof drizzle<typeof schema>>;
6
+ export type AppDb = ReturnType<typeof getDatabase>;
7
+
8
+ let _db: AppDb | null = null;
6
9
 
7
10
  /**
8
- * Get the database for the current request.
11
+ * Get the database connection.
9
12
  *
10
- * In production: uses the D1 binding from Cloudflare Pages.
11
- * In development: uses a local D1 instance via setupDevPlatform()
12
- * (configured in src/instrumentation.ts).
13
+ * Uses better-sqlite3 with a local SQLite file.
14
+ * In production (Primstack hosting), D1 bindings are injected at deploy time.
13
15
  */
14
16
  export function getDatabase() {
15
- const d1 = getRequestContext().env.DB;
16
- return drizzle(d1, { schema });
17
+ if (!_db) {
18
+ const dbPath = process.env.DATABASE_URL || path.join(process.cwd(), 'local.db');
19
+ const sqlite = new Database(dbPath);
20
+ sqlite.pragma('journal_mode = WAL');
21
+ _db = drizzle(sqlite, { schema });
22
+ }
23
+ return _db;
17
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primstack/cli",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "CLI for Primstack component library",
5
5
  "type": "module",
6
6
  "bin": {