@rebasepro/cli 0.0.1-canary.2 → 0.0.1-canary.4829d6e

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.
Files changed (83) hide show
  1. package/LICENSE +17 -196
  2. package/README.md +57 -33
  3. package/dist/commands/api-keys.d.ts +1 -0
  4. package/dist/commands/auth.d.ts +1 -0
  5. package/dist/commands/build.d.ts +1 -0
  6. package/dist/commands/cloud/auth.d.ts +3 -0
  7. package/dist/commands/cloud/context.d.ts +61 -0
  8. package/dist/commands/cloud/databases.d.ts +1 -0
  9. package/dist/commands/cloud/deploy.d.ts +2 -0
  10. package/dist/commands/cloud/index.d.ts +1 -0
  11. package/dist/commands/cloud/link.d.ts +5 -0
  12. package/dist/commands/cloud/orgs.d.ts +1 -0
  13. package/dist/commands/cloud/projects.d.ts +13 -0
  14. package/dist/commands/cloud/resources.d.ts +6 -0
  15. package/dist/commands/db.d.ts +1 -0
  16. package/dist/commands/dev.d.ts +1 -0
  17. package/dist/commands/doctor.d.ts +1 -0
  18. package/dist/commands/generate_sdk.d.ts +18 -0
  19. package/dist/commands/init.d.ts +40 -0
  20. package/dist/commands/schema.d.ts +1 -0
  21. package/dist/commands/skills.d.ts +1 -0
  22. package/dist/commands/start.d.ts +1 -0
  23. package/dist/index.d.ts +11 -1
  24. package/dist/index.es.js +3952 -245
  25. package/dist/index.es.js.map +1 -1
  26. package/dist/utils/package-manager.d.ts +33 -0
  27. package/dist/utils/project.d.ts +60 -0
  28. package/package.json +35 -23
  29. package/templates/overlays/baas/README.md +37 -0
  30. package/templates/overlays/baas/backend/package.json +31 -0
  31. package/templates/overlays/baas/backend/src/index.ts +172 -0
  32. package/templates/overlays/baas/backend/tsconfig.json +18 -0
  33. package/templates/overlays/baas/package.json +42 -0
  34. package/templates/overlays/baas/pnpm-workspace.yaml +9 -0
  35. package/templates/template/.cursorrules +2 -0
  36. package/templates/template/.dockerignore +28 -0
  37. package/templates/template/.env.example +120 -0
  38. package/templates/template/.github/copilot-instructions.md +2 -0
  39. package/templates/template/.windsurfrules +2 -0
  40. package/templates/template/AGENTS.md +2 -0
  41. package/templates/template/CLAUDE.md +2 -0
  42. package/templates/template/README.md +88 -21
  43. package/templates/template/ai-instructions.md +17 -0
  44. package/templates/template/backend/Dockerfile +57 -11
  45. package/templates/template/backend/functions/hello.ts +56 -0
  46. package/templates/template/backend/package.json +30 -34
  47. package/templates/template/backend/src/env.ts +23 -0
  48. package/templates/template/backend/src/index.ts +140 -100
  49. package/templates/template/backend/tsconfig.json +1 -1
  50. package/templates/template/config/collections/authors.ts +45 -0
  51. package/templates/template/config/collections/index.ts +26 -0
  52. package/templates/template/{shared → config}/collections/posts.ts +28 -10
  53. package/templates/template/config/collections/presets/blank/index.ts +3 -0
  54. package/templates/template/config/collections/presets/ecommerce/categories.ts +40 -0
  55. package/templates/template/config/collections/presets/ecommerce/index.ts +6 -0
  56. package/templates/template/config/collections/presets/ecommerce/orders.ts +66 -0
  57. package/templates/template/config/collections/presets/ecommerce/products.ts +64 -0
  58. package/templates/template/config/collections/tags.ts +25 -0
  59. package/templates/template/config/collections/users.ts +142 -0
  60. package/templates/template/{shared → config}/index.ts +1 -1
  61. package/templates/template/config/package.json +28 -0
  62. package/templates/template/docker-compose.yml +50 -14
  63. package/templates/template/frontend/Dockerfile +39 -15
  64. package/templates/template/frontend/nginx.conf +40 -0
  65. package/templates/template/frontend/package.json +13 -13
  66. package/templates/template/frontend/src/App.tsx +30 -116
  67. package/templates/template/frontend/src/index.css +15 -1
  68. package/templates/template/frontend/src/main.tsx +6 -2
  69. package/templates/template/frontend/src/virtual.d.ts +6 -0
  70. package/templates/template/frontend/tsconfig.json +3 -2
  71. package/templates/template/frontend/vite.config.ts +48 -5
  72. package/templates/template/package.json +21 -12
  73. package/templates/template/pnpm-workspace.yaml +13 -0
  74. package/templates/template/scripts/example.ts +94 -0
  75. package/dist/auth.d.ts +0 -5
  76. package/dist/index.cjs +0 -293
  77. package/dist/index.cjs.map +0 -1
  78. package/templates/template/.env.template +0 -31
  79. package/templates/template/backend/drizzle.config.ts +0 -22
  80. package/templates/template/backend/scripts/db-generate.ts +0 -60
  81. package/templates/template/shared/collections/index.ts +0 -3
  82. package/templates/template/shared/package.json +0 -28
  83. /package/templates/template/{shared → config}/tsconfig.json +0 -0
@@ -2,58 +2,125 @@
2
2
 
3
3
  A [Rebase](https://rebase.pro) project with a PostgreSQL backend.
4
4
 
5
- ## Getting Started
5
+ ## Quick Start
6
6
 
7
- ### Prerequisites
7
+ ### Option 1: Docker (recommended for production)
8
+
9
+ ```bash
10
+ cp .env.example .env
11
+ # Edit .env — set JWT_SECRET and DATABASE_URL (see comments for generators)
12
+
13
+ docker compose up -d
14
+ ```
15
+
16
+ That's it. Your app is running:
17
+ - **Frontend**: http://localhost (port 80)
18
+ - **Backend API**: http://localhost:3001
19
+ - **PostgreSQL**: localhost:5432
20
+
21
+ ### Option 2: Local Development
22
+
23
+ #### Prerequisites
8
24
 
9
25
  - [Node.js](https://nodejs.org) >= 18
10
- - [pnpm](https://pnpm.io)
11
- - A PostgreSQL database
26
+ - [pnpm](https://pnpm.io) or [npm](https://www.npmjs.com) (v7+)
27
+ - A PostgreSQL database (you can start the included database container via `docker compose up -d db`)
12
28
 
13
- ### Setup
29
+ #### Setup
14
30
 
15
31
  1. Install dependencies:
16
32
 
17
33
  ```bash
18
- pnpm install
34
+ pnpm install # or: npm install
19
35
  ```
20
36
 
21
- 2. Configure your database — edit `.env` and set `DATABASE_URL`:
37
+ 2. Configure environment:
22
38
 
23
- ```
24
- DATABASE_URL=postgresql://postgres:password@localhost:5432/mydb
39
+ ```bash
40
+ cp .env.example .env
41
+ # Edit .env — set DATABASE_URL, JWT_SECRET
25
42
  ```
26
43
 
27
- 3. Generate and run database migrations:
44
+ 3. Generate schema and push to database:
28
45
 
29
46
  ```bash
30
- pnpm db:generate
31
- pnpm db:migrate
47
+ pnpm run schema:generate # or: npm run schema:generate
48
+ pnpm run db:push # or: npm run db:push
32
49
  ```
33
50
 
34
51
  4. Start the dev server:
35
52
 
36
53
  ```bash
37
- pnpm dev
54
+ pnpm dev # or: npm run dev
38
55
  ```
39
56
 
40
- This starts both the backend (Express + PostgreSQL on port 3001) and the frontend (Vite + React on port 5173) concurrently.
57
+ Backend (Hono + PostgreSQL) on port 3001, frontend (Vite + React) on port 5173.
41
58
 
42
59
  ## Project Structure
43
60
 
44
61
  ```
45
- ├── frontend/ # React frontend (Vite)
46
- ├── backend/ # Express backend with PostgreSQL
47
- ├── shared/ # Shared collection definitions
48
- ├── .env # Environment variables
49
- └── package.json # Root workspace config
62
+ ├── frontend/ # React frontend (Vite)
63
+ ├── Dockerfile # Production build nginx
64
+ │ └── nginx.conf # SPA routing + compression
65
+ ├── backend/ # Hono backend with PostgreSQL
66
+ │ ├── Dockerfile # Multi-stage production build
67
+ │ ├── functions/ # Custom API endpoints (auto-discovered)
68
+ │ └── src/
69
+ ├── config/ # Shared collection definitions
70
+ │ └── collections/ # Schema-as-Code TypeScript files
71
+ ├── docker-compose.yml # Production stack (Postgres + Backend + Frontend)
72
+ ├── .env.example # Environment variable reference
73
+ └── package.json # Root workspace config
74
+ ```
75
+
76
+ ### Custom Functions
77
+
78
+ Drop a Hono app in `backend/functions/` and it's auto-mounted at `/api/functions/<name>`:
79
+
80
+ ```typescript
81
+ // backend/functions/hello.ts
82
+ import { Hono } from "hono";
83
+ const app = new Hono();
84
+ app.post("/", async (c) => {
85
+ const body = await c.req.json();
86
+ return c.json({ message: `Hello, ${body.name}!` });
87
+ });
88
+ export default app;
50
89
  ```
51
90
 
91
+ Call from the client SDK: `client.call("functions/hello", { name: "World" })`
92
+
52
93
  ### Shared Collections
53
94
 
54
- Collections are defined once in `shared/collections/` and used by both the frontend and backend. This ensures your schema stays in sync across the stack.
95
+ Collections are defined once in `config/collections/` and used by both the frontend and backend. This ensures your schema stays in sync across the stack.
96
+
97
+ ## Environment Configuration
98
+
99
+ All configuration is managed through a single `.env` file in the project root. Both the backend and frontend read from this file:
100
+
101
+ - **Backend**: loads via `dotenv` from `../../.env` (relative to `backend/src/`)
102
+ - **Frontend**: Vite reads `VITE_*` variables via `envDir` pointing to the project root
103
+ - **Scripts**: load via `dotenv` from the project root
104
+
105
+ Copy `.env.example` to `.env` to get started. See the comments in `.env.example` for details on each variable.
106
+
107
+ ## Production Deployment
108
+
109
+ ```bash
110
+ # Build and start
111
+ docker compose up -d --build
112
+
113
+ # View logs
114
+ docker compose logs -f backend
115
+
116
+ # Stop
117
+ docker compose down
118
+
119
+ # Stop and remove data
120
+ docker compose down -v
121
+ ```
55
122
 
56
123
  ## Documentation
57
124
 
58
125
  - [Rebase Docs](https://rebase.pro/docs)
59
- - [GitHub](https://github.com/rebaseco/rebase)
126
+ - [GitHub](https://github.com/rebasepro/rebase)
@@ -0,0 +1,17 @@
1
+ # Rebase AI Coding Rules
2
+
3
+ Rebase provides agent skills for AI coding assistants (Cursor, Claude Code, Windsurf, Gemini CLI, Antigravity, and more) with detailed guidelines, architecture, SDK APIs, and troubleshooting guides.
4
+
5
+ To install skills for your environment, run:
6
+
7
+ ```
8
+ rebase skills install
9
+ ```
10
+
11
+ ## Core Tenets (Quick Reference)
12
+
13
+ 1. **Schema-as-Code**: Always define or edit collections in `config/collections/` (e.g., `config/collections/posts.ts`). Never modify generated Drizzle schemas or PostgreSQL tables manually.
14
+ 2. **Two-Step Migrations**:
15
+ - Step 1: Run `rebase schema generate` to compile collections to the Drizzle schema.
16
+ - Step 2: Run `rebase db push` (development) or `rebase db generate && rebase db migrate` (production) to apply schema changes to the database.
17
+ 3. **Use the SDK**: Always use the Rebase SDK (`rebase.data.<slug>`) to fetch or modify data. Bypassing it with raw SQL or direct Drizzle/PG queries circumvents model validations, lifecycle hooks, and Row-Level Security (RLS).
@@ -1,25 +1,71 @@
1
- FROM node:24-alpine AS base
1
+ # ─── Multi-stage production Dockerfile for the Rebase backend ─────────
2
+ # Produces a minimal image (~150MB) with only the runtime needed.
3
+ #
4
+ # Build context: the project root (where pnpm-workspace.yaml lives)
5
+ # Usage:
6
+ # docker build -t my-app-backend -f backend/Dockerfile .
7
+ # docker run -p 3001:3001 --env-file .env my-app-backend
8
+
9
+ # ── Stage 1: Install + Build ─────────────────────────────────────────
10
+ FROM node:22-alpine AS builder
11
+
2
12
  ENV PNPM_HOME="/pnpm"
3
13
  ENV PATH="$PNPM_HOME:$PATH"
4
14
  RUN corepack enable
5
- RUN apk add --no-cache python3 make g++
15
+
16
+ # Native dependencies for bcrypt, pg, etc.
17
+ RUN apk add --no-cache python3 make g++ curl ca-certificates
6
18
 
7
19
  WORKDIR /app
8
20
 
9
- # Copy root configurations
10
- COPY package.json ./
21
+ # Copy workspace root files first (cache-friendly layer)
22
+ COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
11
23
 
12
- # Copy internal workspaces
24
+ # Copy workspace packages
13
25
  COPY backend ./backend
14
- COPY shared ./shared
26
+ COPY config ./config
27
+
28
+ # Install all deps (including devDependencies for build)
29
+ RUN pnpm install --frozen-lockfile
30
+
31
+ # Build config first, then backend
32
+ RUN pnpm --filter "*-config" run build
33
+ RUN pnpm --filter "*-backend" run build
34
+
35
+ # Prune dev dependencies for a smaller runtime
36
+ RUN CI=true pnpm install --frozen-lockfile --prod
37
+
38
+ # ── Stage 2: Production Runtime ──────────────────────────────────────
39
+ FROM node:22-alpine AS runtime
40
+
41
+ ENV PNPM_HOME="/pnpm"
42
+ ENV PATH="$PNPM_HOME:$PATH"
43
+ ENV NODE_ENV=production
44
+ ENV CI=true
45
+
46
+ RUN corepack enable
15
47
 
16
- # Install dependencies
17
- RUN pnpm install
48
+ # Security: run as non-root
49
+ RUN addgroup -g 1001 rebase && adduser -u 1001 -G rebase -s /bin/sh -D rebase
50
+
51
+ WORKDIR /app
18
52
 
19
- # Build shared and backend
20
- RUN pnpm run build:shared
21
- RUN pnpm run build:backend
53
+ # Copy only production artifacts
54
+ COPY --from=builder /app/package.json /app/pnpm-lock.yaml /app/pnpm-workspace.yaml /app/.npmrc ./
55
+ COPY --from=builder /app/node_modules ./node_modules
56
+ COPY --from=builder /app/backend ./backend
57
+ COPY --from=builder /app/config ./config
58
+
59
+ # Create uploads directory
60
+ RUN mkdir -p /app/backend/uploads && chown -R rebase:rebase /app
61
+
62
+ USER rebase
22
63
 
23
64
  WORKDIR /app/backend
24
65
  EXPOSE 3001
66
+
67
+ # Health check for orchestrators (Docker Compose, ECS, k8s)
68
+ HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=10s \
69
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1
70
+
25
71
  CMD ["pnpm", "start"]
@@ -0,0 +1,56 @@
1
+ import { defineFunction } from "@rebasepro/server";
2
+
3
+ /**
4
+ * Example custom function route.
5
+ *
6
+ * This file is auto-discovered by Rebase and mounted at:
7
+ * POST /api/functions/hello
8
+ * GET /api/functions/hello
9
+ *
10
+ * Call from the client SDK:
11
+ * const result = await client.call("functions/hello", { name: "World" });
12
+ *
13
+ * Authored with `defineFunction`, which hands you a pre-typed Hono app
14
+ * (so `c.get("user")` / `c.get("driver")` are typed) and the `rebase`
15
+ * singleton via the injected context — use any Hono middleware, define any
16
+ * HTTP methods, access the request/response directly.
17
+ *
18
+ * `rebase.dataAsAdmin` gives you admin-level access to your data and
19
+ * **bypasses RLS** — use it only for trusted admin work. For request-scoped /
20
+ * RLS-scoped data access, use c.get("user") and c.get("driver"), which carry
21
+ * the caller's identity. (`rebase` also exposes auth, storage, email.)
22
+ */
23
+ export default defineFunction((app, { rebase }) => {
24
+ void rebase; // available for dataAsAdmin/auth/storage/email — see commented usage below
25
+
26
+ app.post("/", async (c) => {
27
+ const body = await c.req.json().catch(() => ({}));
28
+ const user = c.get("user");
29
+
30
+ const userId = (user && typeof user === "object" && "userId" in user)
31
+ ? user.userId
32
+ : "anonymous";
33
+
34
+ // Access any Rebase service via the injected `rebase`:
35
+ // await rebase.email.send({
36
+ // to: "admin@example.com",
37
+ // subject: "Function called",
38
+ // html: `<p>Hello from ${userId}!</p>`,
39
+ // });
40
+ //
41
+ // Admin-scoped data (bypasses RLS — trusted work only):
42
+ // const authors = await rebase.dataAsAdmin.authors.find({ limit: 5 });
43
+ // For user-scoped data (RLS applies), use the request-scoped driver
44
+ // (c.get("driver")), which carries the caller's identity.
45
+
46
+ return c.json({
47
+ message: `Hello, ${body.name || "World"}!`,
48
+ user: userId
49
+ });
50
+ });
51
+
52
+ app.get("/", (c) => {
53
+ return c.json({ status: "ok",
54
+ endpoint: "hello" });
55
+ });
56
+ });
@@ -1,36 +1,32 @@
1
1
  {
2
- "name": "{{PROJECT_NAME}}-backend",
3
- "version": "1.0.0",
4
- "description": "Rebase backend with PostgreSQL",
5
- "main": "src/index.ts",
6
- "type": "module",
7
- "scripts": {
8
- "dev": "tsx watch --watch=\"../shared/**/*\" src/index.ts",
9
- "build": "tsc --noEmit",
10
- "start": "tsx src/index.ts",
11
- "generate:schema": "tsx node_modules/@rebasepro/backend/src/generate-drizzle-schema.ts --collections=../shared/collections --output=src/schema.generated.ts",
12
- "db:generate": "pnpm generate:schema && tsx scripts/db-generate.ts",
13
- "db:migrate": "DOTENV_CONFIG_PATH=../.env drizzle-kit migrate",
14
- "db:push": "DOTENV_CONFIG_PATH=../.env drizzle-kit push",
15
- "db:studio": "DOTENV_CONFIG_PATH=../.env drizzle-kit studio"
16
- },
17
- "dependencies": {
18
- "{{PROJECT_NAME}}-shared": "workspace:*",
19
- "@rebasepro/backend": "^4.0.0",
20
- "cors": "^2.8.5",
21
- "drizzle-orm": "^0.44.4",
22
- "express": "^5.1.0",
23
- "pg": "^8.11.3",
24
- "ws": "^8.16.0",
25
- "zod": "^3.22.4",
26
- "dotenv": "^16.0.0"
27
- },
28
- "devDependencies": {
29
- "@types/pg": "^8.6.5",
30
- "@types/node": "^20.10.5",
31
- "@types/ws": "^8.5.10",
32
- "drizzle-kit": "^0.31.4",
33
- "tsx": "^4.20.6",
34
- "typescript": "^5.9.2"
35
- }
2
+ "name": "{{PROJECT_NAME}}-backend",
3
+ "version": "1.0.0",
4
+ "description": "Rebase backend with PostgreSQL",
5
+ "main": "src/index.ts",
6
+ "type": "module",
7
+ "scripts": {
8
+ "dev": "tsx watch --watch=\"../config/**/*\" src/index.ts",
9
+ "build": "rebase schema generate --collections ../config/collections && tsc",
10
+ "start": "node dist/backend/src/index.js"
11
+ },
12
+ "dependencies": {
13
+ "{{PROJECT_NAME}}-config": "*",
14
+ "@rebasepro/server": "workspace:*",
15
+ "@rebasepro/server-postgres": "workspace:*",
16
+ "@rebasepro/types": "workspace:*",
17
+ "drizzle-orm": "^0.45.2",
18
+ "hono": "^4.12.10",
19
+ "@hono/node-server": "^1.19.12",
20
+ "pg": "^8.11.3",
21
+ "ws": "^8.16.0",
22
+ "dotenv": "^16.0.0",
23
+ "zod": "^4.4.3"
24
+ },
25
+ "devDependencies": {
26
+ "@types/pg": "^8.6.5",
27
+ "@types/node": "^20.10.5",
28
+ "@types/ws": "^8.5.10",
29
+ "tsx": "^4.20.6",
30
+ "typescript": "^5.9.2"
31
+ }
36
32
  }
@@ -0,0 +1,23 @@
1
+ import * as dotenv from "dotenv";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { loadEnv } from "@rebasepro/server";
5
+ import { z } from "zod";
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ dotenv.config({ path: path.resolve(__dirname, "../../.env") });
11
+
12
+ export const env = loadEnv({
13
+ extend: z.object({
14
+ SMTP_HOST: z.string().optional(),
15
+ SMTP_PORT: z.string().default("587").transform(Number),
16
+ SMTP_SECURE: z.enum(["true", "false", ""]).default("false").transform(v => v === "true"),
17
+ SMTP_USER: z.string().optional(),
18
+ SMTP_PASS: z.string().optional(),
19
+ SMTP_FROM: z.string().optional(),
20
+ SMTP_NAME: z.string().optional(),
21
+ APP_NAME: z.string().default("Rebase")
22
+ })
23
+ });