@rebasepro/cli 0.6.0 → 0.7.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.
Files changed (51) hide show
  1. package/README.md +0 -1
  2. package/dist/commands/api-keys.d.ts +1 -0
  3. package/dist/commands/generate_sdk.d.ts +1 -1
  4. package/dist/commands/init.d.ts +13 -0
  5. package/dist/index.es.js +463 -105
  6. package/dist/index.es.js.map +1 -1
  7. package/package.json +22 -18
  8. package/templates/template/backend/package.json +0 -1
  9. package/templates/template/backend/src/index.ts +1 -1
  10. package/templates/template/config/collections/posts.ts +1 -3
  11. package/templates/template/config/collections/tags.ts +1 -3
  12. package/templates/template/config/collections/users.ts +1 -4
  13. package/templates/template/package.json +0 -1
  14. package/templates/template/scripts/example.ts +4 -1
  15. package/dist/index.cjs +0 -1948
  16. package/dist/index.cjs.map +0 -1
  17. package/skills/rebase-api/SKILL.md +0 -662
  18. package/skills/rebase-api/references/.gitkeep +0 -3
  19. package/skills/rebase-auth/SKILL.md +0 -1143
  20. package/skills/rebase-auth/references/.gitkeep +0 -3
  21. package/skills/rebase-backend-postgres/SKILL.md +0 -633
  22. package/skills/rebase-backend-postgres/references/.gitkeep +0 -3
  23. package/skills/rebase-basics/SKILL.md +0 -749
  24. package/skills/rebase-basics/references/.gitkeep +0 -3
  25. package/skills/rebase-collections/SKILL.md +0 -1328
  26. package/skills/rebase-collections/references/.gitkeep +0 -3
  27. package/skills/rebase-cron-jobs/SKILL.md +0 -699
  28. package/skills/rebase-cron-jobs/references/.gitkeep +0 -1
  29. package/skills/rebase-custom-functions/SKILL.md +0 -233
  30. package/skills/rebase-deployment/SKILL.md +0 -583
  31. package/skills/rebase-deployment/references/.gitkeep +0 -3
  32. package/skills/rebase-design-language/SKILL.md +0 -664
  33. package/skills/rebase-email/SKILL.md +0 -701
  34. package/skills/rebase-email/references/.gitkeep +0 -1
  35. package/skills/rebase-entity-history/SKILL.md +0 -485
  36. package/skills/rebase-entity-history/references/.gitkeep +0 -1
  37. package/skills/rebase-local-env-setup/SKILL.md +0 -189
  38. package/skills/rebase-local-env-setup/references/.gitkeep +0 -3
  39. package/skills/rebase-realtime/SKILL.md +0 -755
  40. package/skills/rebase-realtime/references/.gitkeep +0 -3
  41. package/skills/rebase-sdk/SKILL.md +0 -594
  42. package/skills/rebase-sdk/references/.gitkeep +0 -0
  43. package/skills/rebase-storage/SKILL.md +0 -765
  44. package/skills/rebase-storage/references/.gitkeep +0 -3
  45. package/skills/rebase-studio/SKILL.md +0 -746
  46. package/skills/rebase-studio/references/.gitkeep +0 -3
  47. package/skills/rebase-ui-components/SKILL.md +0 -1411
  48. package/skills/rebase-ui-components/references/.gitkeep +0 -3
  49. package/skills/rebase-webhooks/SKILL.md +0 -623
  50. package/skills/rebase-webhooks/references/.gitkeep +0 -1
  51. package/templates/template/backend/drizzle.config.ts +0 -51
@@ -1,749 +0,0 @@
1
- ---
2
- name: rebase-basics
3
- description: Core principles, workflow, and maintenance for using Rebase. Use this for all Rebase CLI tasks, project setup, MCP server usage, and general development. Make sure to ALWAYS use this skill whenever you are trying to use Rebase, even if not explicitly asked.
4
- ---
5
-
6
- # Prerequisites
7
-
8
- Please complete these setup steps before proceeding, and remember your progress to avoid repeating them in future interactions.
9
-
10
- 1. **Local Environment Setup:** Verify the environment is properly set up:
11
- - Run `node --version` to check Node.js is installed (v20+ required).
12
- - Run `pnpm --version` to check pnpm is installed. If not, install it: `npm install -g pnpm`.
13
- - Verify PostgreSQL is available: `psql --version` or confirm Docker is running with a Postgres container.
14
- - If any of these checks fail, use the `rebase-local-env-setup` skill to get the environment ready.
15
-
16
- 2. **Authentication:**
17
- Ensure you are logged in to Rebase Cloud for MCP server access. Run `rebase login`. This opens a browser for Google OAuth.
18
- - Tokens are stored at `~/.rebase/tokens.json` and shared between CLI and MCP server.
19
- - If the browser fails to open, check the CLI output for a manual URL.
20
-
21
- 3. **Active Project:**
22
- Most Rebase tasks require a project context.
23
- - For Rebase Cloud: Run `rebase login` and select your project via the MCP `list_projects` tool.
24
- - For self-hosted: Ensure your `.env` file in the project root contains a valid `DATABASE_URL`.
25
-
26
- # Rebase Usage Principles
27
-
28
- Please adhere to these principles when working with Rebase, as they ensure reliability and consistency:
29
-
30
- 1. **Use pnpm exclusively:** Rebase uses pnpm as its package manager. Never use `npm` or `yarn`. All commands should use `pnpm run`, `pnpm install`, `pnpm add`, etc.
31
-
32
- 2. **Never convert to `any`:** TypeScript strictness is critical. Never use `as any` type assertions. Use proper typing, `unknown`, or explicit type narrowing instead.
33
-
34
- 3. **Follow the Schema-as-Code approach:** Schemas are defined as standalone TypeScript files. The visual Studio generates TypeScript via AST manipulation — it does NOT run raw SQL. Always define collections in code first.
35
-
36
- 4. **Use the two-step migration workflow:**
37
- - `rebase schema generate` — converts collection definitions to Drizzle ORM schema
38
- - `rebase db push` (development) or `rebase db generate && rebase db migrate` (production)
39
-
40
- 5. **Use Rebase MCP Server tools when available:** For data operations, user management, and collection browsing, prefer the MCP tools (`list_documents`, `get_document`, `create_document`, etc.) over writing manual API calls.
41
-
42
- 6. **Respect the monorepo structure:** See the [Package Reference](#package-reference) section below for the full list of packages and when to use each.
43
-
44
- 7. **Never deploy unless explicitly asked:** Agents should never run `rebase deploy`, `firebase deploy`, `gcloud deploy`, or any command that pushes code to live infrastructure unless the user explicitly asks you to deploy in the current conversation. Provide the exact command and let the user run it themselves if they prefer.
45
-
46
- 8. **Scripting and Data Tasks:** Default to using the Rebase SDK (`@rebasepro/client` or `@rebasepro/server-core`) to write scripts or tasks for manipulating data. For standalone scripts running locally, you can dynamically read the active backend URL from the `.rebase-dev-url` temp file automatically created by the dev server. For internal server-side backend tasks, use the global `import { rebase } from "@rebasepro/server-core"` singleton. For calling custom backend functions from the frontend, use `client.functions.invoke('name', payload)` — NEVER manually construct `/api/functions/` URLs or extract auth tokens from `localStorage`. NEVER default to using raw `psql` queries or raw REST API calls (`fetch`/`curl`) unless explicitly instructed or the SDK lacks the functionality.
47
-
48
- # Project Structure
49
-
50
- ## Scaffolded Project Structure (CLI)
51
-
52
- When you initialize a Rebase project via the CLI (`rebase init`), the generated project structure contains:
53
-
54
- ```
55
- <project-root>/
56
- ├── frontend/ # React frontend (Vite)
57
- ├── backend/ # Hono backend server
58
- │ └── src/
59
- │ ├── index.ts # Server entry point
60
- │ └── schema.generated.ts # Auto-generated Drizzle schema
61
- ├── config/ # Application configuration
62
- │ └── collections/ # TypeScript collection files (one per collection)
63
- │ └── index.ts # Barrel export of all collections
64
- ├── .env # Environment variables (generated from .env.example)
65
- ├── .env.example # Template with placeholder secrets
66
- ├── docker-compose.yml # PostgreSQL container (when no custom DB provided)
67
- ├── drizzle.config.ts # Drizzle ORM configuration
68
- ├── pnpm-workspace.yaml # pnpm workspace definition
69
- └── package.json # Root workspace package.json
70
- ```
71
-
72
- ### Key Files
73
-
74
- | File | Purpose |
75
- |------|---------|
76
- | `.env` | Environment variables — secrets, DATABASE_URL, JWT_SECRET |
77
- | `config/collections/*.ts` | Collection definitions (schema-as-code) |
78
- | `backend/src/index.ts` | Server entry point — calls `initializeRebaseBackend()` |
79
- | `backend/src/schema.generated.ts` | Auto-generated by `rebase schema generate` — DO NOT edit manually |
80
- | `.rebase-dev-port` | Written by `rebase dev` — stores the resolved backend port |
81
- | `.rebase-dev-url` | Written by `rebase dev` — stores `http://localhost:<port>` for scripts |
82
-
83
- ## Framework Monorepo Structure
84
-
85
- For development of the Rebase framework itself, the repository is organized as a modular monorepo:
86
-
87
- ```
88
- rebase/
89
- ├── app/ # Example application (scaffolded structure above)
90
- │ ├── frontend/ # React frontend (Vite)
91
- │ ├── backend/ # Hono backend server
92
- │ └── config/ # Application configuration
93
- │ └── collections/ # TypeScript collection files (one per collection)
94
- ├── packages/
95
- │ ├── server-core/ # @rebasepro/server-core
96
- │ ├── server-postgresql/ # @rebasepro/server-postgresql
97
- │ ├── server-mongodb/ # @rebasepro/server-mongodb
98
- │ ├── core/ # @rebasepro/core
99
- │ ├── types/ # @rebasepro/types
100
- │ ├── ui/ # @rebasepro/ui
101
- │ ├── admin/ # @rebasepro/admin
102
- │ ├── studio/ # @rebasepro/studio
103
- │ ├── auth/ # @rebasepro/auth
104
- │ ├── cli/ # @rebasepro/cli
105
- │ ├── client/ # @rebasepro/client
106
- │ ├── client-firebase/ # @rebasepro/client-firebase
107
- │ ├── client-postgresql/ # @rebasepro/client-postgresql
108
- │ ├── common/ # @rebasepro/common
109
- │ ├── formex/ # @rebasepro/formex
110
- │ ├── mcp-server/ # @rebasepro/mcp-server
111
- │ ├── sdk-generator/ # @rebasepro/sdk-generator
112
- │ ├── schema-inference/ # @rebasepro/schema-inference
113
- │ ├── plugin-data-enhancement/ # @rebasepro/plugin-data-enhancement
114
- │ └── utils/ # @rebasepro/utils
115
- ├── pnpm-workspace.yaml
116
- ├── lerna.json
117
- └── package.json
118
- ```
119
-
120
- ## Package Reference
121
-
122
- | Package | Purpose | When to use |
123
- |---------|---------|-------------|
124
- | `@rebasepro/server-core` | Hono server coordinator, API generation, auth middleware, storage, email, cron, custom functions | Backend entry point — every Rebase backend imports this |
125
- | `@rebasepro/server-postgresql` | PostgreSQL bootstrapper and Drizzle ORM data driver | Backend setup when using PostgreSQL |
126
- | `@rebasepro/server-mongodb` | MongoDB bootstrapper and data driver | Backend setup when using MongoDB |
127
- | `@rebasepro/core` | Core framework, types, hooks, and React components | Frontend — React integration, hooks, providers |
128
- | `@rebasepro/types` | Shared TypeScript type definitions (`PostgresCollection`, `EntityCollection`, `RebaseClient`, etc.) | Type imports across all packages |
129
- | `@rebasepro/ui` | Standalone component library (Tailwind CSS v4 + Radix) | Building custom views in Studio or standalone UI |
130
- | `@rebasepro/admin` | CMS frontend application | The Studio admin panel frontend |
131
- | `@rebasepro/studio` | Admin panel, collection editor, visual schema editor | Studio-specific features and customization |
132
- | `@rebasepro/auth` | Authentication module (client-side) | Frontend auth flows, login forms |
133
- | `@rebasepro/client` | Client SDK for consuming the Rebase API | Any client-side or script-side data operations |
134
- | `@rebasepro/client-firebase` | Firebase client adapter | When connecting to a Firebase backend |
135
- | `@rebasepro/client-postgresql` | PostgreSQL client adapter | When connecting directly to PostgreSQL from client |
136
- | `@rebasepro/common` | Shared utilities, `defaultUsersCollection` | Shared constants and default collection exports |
137
- | `@rebasepro/formex` | Form engine | Building dynamic forms from collection schemas |
138
- | `@rebasepro/mcp-server` | AI agent MCP tools | The MCP server that agents use |
139
- | `@rebasepro/sdk-generator` | Typed SDK generation from collection definitions | Used by `rebase generate-sdk` command |
140
- | `@rebasepro/schema-inference` | Auto-infer schema from data / database introspection | Used by `rebase schema introspect` |
141
- | `@rebasepro/plugin-data-enhancement` | AI-powered data autofill | Studio plugin for auto-completing fields |
142
- | `@rebasepro/cli` | CLI tool | The `rebase` CLI binary |
143
- | `@rebasepro/utils` | Utility functions | Low-level shared helpers |
144
-
145
- # CLI Commands
146
-
147
- ## Global Options
148
-
149
- | Option | Description |
150
- |--------|-------------|
151
- | `--version`, `-v` | Show CLI version number |
152
- | `--help`, `-h` | Show help message |
153
-
154
- ## Full Command Reference
155
-
156
- ### Project Lifecycle
157
-
158
- | Command | Description |
159
- |---------|-------------|
160
- | `rebase init [name]` | Scaffold a new Rebase project interactively |
161
- | `rebase dev` | Start development server (backend + frontend concurrently) |
162
- | `rebase build` | Build all workspace packages for production |
163
- | `rebase start` | Start the backend server in production mode |
164
-
165
- ### `rebase init` Options
166
-
167
- | Option | Alias | Description |
168
- |--------|-------|-------------|
169
- | `--git` | `-g` | Initialize a git repository |
170
- | `--install` | `-i` | Install dependencies with the detected PM |
171
- | `--database-url` | — | PostgreSQL connection string (skip prompt) |
172
- | `--introspect` | — | Auto-introspect the database after init |
173
- | `--yes` | `-y` | Non-interactive mode (use all defaults) |
174
-
175
- ```bash
176
- # Interactive mode
177
- rebase init my-app
178
-
179
- # Non-interactive — scaffold with a remote database and introspect it
180
- rebase init my-app --yes --database-url "postgresql://user:pass@host:5432/db" --introspect --install
181
- ```
182
-
183
- ### `rebase dev` Options
184
-
185
- | Option | Alias | Description |
186
- |--------|-------|-------------|
187
- | `--backend-only` | `-b` | Only start the backend server |
188
- | `--frontend-only` | `-f` | Only start the frontend server |
189
- | `--port` | `-p` | Set the backend port (default: deterministic per-project hash) |
190
- | `--generate` | `-g` | Auto-regenerate schema + SDK on startup and file changes |
191
-
192
- > **IMPORTANT FOR AGENTS:** Each project automatically receives a **unique default port** derived from its directory path (range 3001–3999), preventing collisions when running multiple Rebase instances. The resolved port is saved to `.rebase-dev-port` for affinity across restarts. The backend URL is saved to `.rebase-dev-url` so scripts can read it. The frontend receives `VITE_API_URL` automatically.
193
-
194
- **Port resolution order:**
195
- 1. Explicit `--port` flag (highest priority)
196
- 2. `PORT` environment variable
197
- 3. Previously saved port from `.rebase-dev-port` (port affinity)
198
- 4. Deterministic hash from project path (unique per project)
199
-
200
- **Auto-generation:** Disabled by default. Enable with `--generate` or by setting `REBASE_AUTO_GENERATE=true` / `REBASE_GENERATE=true` in your environment. When enabled, the CLI:
201
- - Runs `schema generate` + `generate-sdk` once on startup
202
- - Watches `config/collections/` for file changes and regenerates automatically
203
-
204
- ```bash
205
- # Start everything (default)
206
- rebase dev
207
-
208
- # Backend only on a specific port
209
- rebase dev --backend-only --port 3005
210
-
211
- # With auto-generation of schema/SDK on collection file changes
212
- rebase dev --generate
213
- ```
214
-
215
- ### `rebase build`
216
-
217
- Runs the build script across all workspace packages using the detected package manager (pnpm or npm). No options.
218
-
219
- ```bash
220
- rebase build
221
- ```
222
-
223
- ### `rebase start`
224
-
225
- Starts the backend server in production mode. Automatically sets `DOTENV_CONFIG_PATH` if a `.env` file is found. No options.
226
-
227
- ```bash
228
- rebase start
229
- ```
230
-
231
- ### Schema Commands
232
-
233
- | Command | Description |
234
- |---------|-------------|
235
- | `rebase schema generate` | Generate Drizzle schema from collection definitions |
236
- | `rebase schema introspect` | Introspect a live database → generate Rebase collection files |
237
- | `rebase schema --help` | Show schema command help |
238
-
239
- > **IMPORTANT FOR AGENTS:** Schema commands are delegated to the active database driver plugin (e.g. `@rebasepro/server-postgresql`). The plugin must be installed in `backend/package.json` or the command will fail with `Could not detect an active database plugin`.
240
-
241
- #### `schema generate` Options
242
-
243
- | Option | Alias | Description |
244
- |--------|-------|-------------|
245
- | `--collections` | `-c` | Path to collections directory |
246
- | `--output` | `-o` | Output path for generated schema |
247
- | `--watch` | `-w` | Watch for changes and regenerate automatically |
248
-
249
- #### `schema introspect` Options
250
-
251
- | Option | Alias | Description |
252
- |--------|-------|-------------|
253
- | `--output` | `-o` | Output directory for generated collection files |
254
-
255
- ### Database Commands
256
-
257
- | Command | Description |
258
- |---------|-------------|
259
- | `rebase db push` | Apply schema directly to database (development only) |
260
- | `rebase db generate` | Generate SQL migration files |
261
- | `rebase db migrate` | Run pending SQL migrations |
262
- | `rebase db studio` | Open Drizzle Studio (visual database browser) |
263
- | `rebase db branch` | Database branching (create, list, delete, info) |
264
- | `rebase db --help` | Show database command help |
265
-
266
- > **IMPORTANT FOR AGENTS:** Like schema commands, database commands are delegated to the active database driver plugin. The plugin provides the actual implementation.
267
-
268
- ```bash
269
- # Development workflow (fast, no migration files)
270
- rebase schema generate && rebase db push
271
-
272
- # Production workflow (versioned migrations)
273
- rebase schema generate
274
- rebase db generate
275
- rebase db migrate
276
-
277
- # Create a database branch
278
- rebase db branch create feature_auth
279
- ```
280
-
281
- ### SDK Generation
282
-
283
- | Command | Description |
284
- |---------|-------------|
285
- | `rebase generate-sdk` | Generate a typed JS/TS SDK from collection definitions |
286
-
287
- | Option | Alias | Default | Description |
288
- |--------|-------|---------|-------------|
289
- | `--collections-dir` | `-c` | `./config/collections` | Path to collections directory |
290
- | `--output` | `-o` | `./generated/sdk` | Output path for generated SDK |
291
-
292
- The SDK generator uses `jiti` for dynamic TypeScript import of collection files. It will look for an `index.ts` barrel export in the collections directory. If no index file is found, it falls back to scanning individual `.ts`/`.js` files.
293
-
294
- ```bash
295
- rebase generate-sdk --collections-dir ./config/collections --output ./generated/sdk
296
- ```
297
-
298
- ### Auth Commands
299
-
300
- | Command | Description |
301
- |---------|-------------|
302
- | `rebase auth reset-password` | Reset a user's password directly in the database |
303
- | `rebase auth --help` | Show auth command help |
304
-
305
- | Option | Alias | Default | Description |
306
- |--------|-------|---------|-------------|
307
- | `--email` | `-e` | (required — or pass as positional arg) | User's email address |
308
- | `--password` | `-p` | `NewPassword123!` | New password |
309
-
310
- ```bash
311
- # With flags
312
- rebase auth reset-password --email user@example.com --password MyNewPass!
313
-
314
- # Positional args
315
- rebase auth reset-password user@example.com MyNewPass!
316
- ```
317
-
318
- ### Diagnostics
319
-
320
- | Command | Description |
321
- |---------|-------------|
322
- | `rebase doctor` | Detect three-way schema drift between collections, Drizzle schema, and live DB |
323
-
324
- > **IMPORTANT FOR AGENTS:** `rebase doctor` compares collection definitions, the generated Drizzle schema (`schema.generated.ts`), and the actual PostgreSQL database. Run it after any manual DB changes or when suspecting schema drift.
325
-
326
- # Environment Variables
327
-
328
- ## `loadEnv()` Function
329
-
330
- Rebase provides `loadEnv()` from `@rebasepro/server-core` to validate and load environment variables with Zod. Call it **after** your `.env` file has been loaded (e.g. via `dotenv.config()`). It does NOT load `.env` files itself.
331
-
332
- ### Behavior
333
-
334
- - **Auto-generates** ephemeral `JWT_SECRET` and `REBASE_SERVICE_KEY` in non-production mode so developers can start without manual setup
335
- - **Blocks** auto-generated secrets in production (fails validation)
336
- - Returns a fully typed, validated env object
337
-
338
- ### Signature
339
-
340
- ```typescript
341
- import { loadEnv } from "@rebasepro/server-core";
342
-
343
- // Basic — just Rebase env vars:
344
- export const env = loadEnv();
345
-
346
- // Extended — add your own typed vars:
347
- import { z } from "zod";
348
- export const env = loadEnv({
349
- extend: z.object({
350
- SMTP_HOST: z.string().optional(),
351
- SMTP_PORT: z.string().default("587").transform(Number),
352
- STRIPE_SECRET_KEY: z.string(),
353
- })
354
- });
355
- // env.SMTP_HOST → string | undefined (fully typed)
356
- // env.STRIPE_SECRET_KEY → string (validated, required)
357
- ```
358
-
359
- ### Function Overloads
360
-
361
- ```typescript
362
- function loadEnv(): RebaseEnv;
363
- function loadEnv<E extends z.AnyZodObject>(options: { extend: E }): RebaseEnv & z.infer<E>;
364
- ```
365
-
366
- When `extend` is provided, the base `rebaseEnvSchema` is merged (`.merge()`) with your custom Zod object, so all fields are validated together in a single pass.
367
-
368
- ### Complete Environment Variable Reference
369
-
370
- | Variable | Type | Default | Required | Description |
371
- |----------|------|---------|----------|-------------|
372
- | `NODE_ENV` | `"development" \| "production" \| "test"` | `"development"` | No | Environment mode |
373
- | `PORT` | `string` → `number` | `"3001"` | No | Server port |
374
- | `DATABASE_URL` | `string` (URL) | — | **Yes** | PostgreSQL connection string |
375
- | `DATABASE_DIRECT_URL` | `string` (URL) | — | No | Direct connection (bypasses pooler) |
376
- | `DATABASE_READ_URL` | `string` (URL) | — | No | Read replica connection |
377
- | `ADMIN_CONNECTION_STRING` | `string` (URL) | — | No | Admin-level DB connection |
378
- | `JWT_SECRET` | `string` (≥32 chars) | Auto-generated in dev | **Yes** (prod) | JWT signing secret |
379
- | `JWT_ACCESS_EXPIRES_IN` | `string` | `"1h"` | No | Access token TTL |
380
- | `JWT_REFRESH_EXPIRES_IN` | `string` | `"30d"` | No | Refresh token TTL |
381
- | `REBASE_SERVICE_KEY` | `string` | Auto-generated in dev | No | Static key for server-to-server auth |
382
- | `GOOGLE_CLIENT_ID` | `string` | — | No | Google OAuth client ID |
383
- | `GOOGLE_CLIENT_SECRET` | `string` | — | No | Google OAuth client secret |
384
- | `ALLOW_REGISTRATION` | `"true" \| "false"` | `"false"` | No | Allow public user registration |
385
- | `ALLOW_LOCALHOST_IN_PRODUCTION` | `"true" \| "false"` | — | No | Skip localhost URL checks in production |
386
- | `CORS_ORIGINS` | `string` | — | **Yes** (prod) | Allowed CORS origins (comma-separated) |
387
- | `FRONTEND_URL` | `string` | — | Prod alt | Alternative to CORS_ORIGINS for single frontend |
388
- | `DB_POOL_MAX` | `string` → `number` | `"20"` | No | Max database pool connections |
389
- | `DB_POOL_IDLE_TIMEOUT` | `string` → `number` | `"30000"` | No | Pool idle timeout (ms) |
390
- | `DB_POOL_CONNECT_TIMEOUT` | `string` → `number` | `"10000"` | No | Pool connect timeout (ms) |
391
- | `STORAGE_TYPE` | `"local" \| "s3"` | `"local"` | No | File storage backend type |
392
- | `STORAGE_PATH` | `string` | — | No | Local storage directory path |
393
- | `FORCE_LOCAL_STORAGE` | `"true" \| "false"` | — | No | Force local storage even in production |
394
- | `S3_BUCKET` | `string` | — | When S3 | S3 bucket name |
395
- | `S3_REGION` | `string` | — | When S3 | S3 region |
396
- | `S3_ACCESS_KEY_ID` | `string` | — | When S3 | S3 access key |
397
- | `S3_SECRET_ACCESS_KEY` | `string` | — | When S3 | S3 secret key |
398
- | `S3_ENDPOINT` | `string` (URL) | — | No | Custom S3 endpoint (MinIO, R2, etc.) |
399
- | `S3_FORCE_PATH_STYLE` | `"true" \| "false"` | — | No | Use path-style S3 URLs |
400
-
401
- ### Production Validations
402
-
403
- `loadEnv()` enforces these rules when `NODE_ENV=production`:
404
-
405
- 1. `CORS_ORIGINS` or `FRONTEND_URL` **must** be set
406
- 2. `JWT_SECRET` and `REBASE_SERVICE_KEY` **must** be explicitly set (auto-generation disabled)
407
- 3. No environment variable may contain a localhost/loopback URL (unless `ALLOW_LOCALHOST_IN_PRODUCTION=true`)
408
-
409
- ### Auto-Generated Dev Secrets
410
-
411
- In non-production mode, `loadEnv()` automatically generates cryptographically secure random values for `JWT_SECRET` and `REBASE_SERVICE_KEY` using `crypto.randomBytes(48).toString("hex")` when they are not set. This means:
412
-
413
- - **Developers can start immediately** without creating a `.env` file
414
- - **Existing JWT tokens are invalidated on every server restart** because the secret changes
415
- - A console warning is emitted: `⚠️ Auto-generated secrets for: JWT_SECRET, REBASE_SERVICE_KEY...`
416
- - To persist sessions across restarts, set these values explicitly in `.env`
417
-
418
- # Backend Configuration
419
-
420
- ## `initializeRebaseBackend()`
421
-
422
- The main entry point for initializing a Rebase backend server. Returns a `RebaseBackendInstance` with access to drivers, auth, storage, and lifecycle methods.
423
-
424
- ### `RebaseBackendConfig` — Full Interface
425
-
426
- ```typescript
427
- import { initializeRebaseBackend, RebaseBackendConfig } from "@rebasepro/server-core";
428
- ```
429
-
430
- | Property | Type | Default | Description |
431
- |----------|------|---------|-------------|
432
- | `server` | `Server` (Node `http.Server`) | — | **Required.** The HTTP server instance |
433
- | `app` | `Hono<HonoEnv>` | — | **Required.** The Hono application instance |
434
- | `collections` | `EntityCollection[]` | `[]` | Inline collection definitions |
435
- | `collectionsDir` | `string` | — | Directory to auto-discover collection files (used if `collections` is empty) |
436
- | `basePath` | `string` | `"/api"` | Base path for all API routes |
437
- | `database` | `DatabaseAdapter` | — | Database adapter (takes precedence over `bootstrappers`) |
438
- | `bootstrappers` | `BackendBootstrapper[]` | `[]` | Database bootstrappers (legacy — prefer `database`) |
439
- | `auth` | `RebaseAuthConfig \| AuthAdapter` | — | Authentication config or pluggable adapter |
440
- | `storage` | `BackendStorageConfig \| StorageController \| Record<string, ...>` | — | File storage configuration |
441
- | `history` | `unknown` | — | Entity history/audit-log configuration |
442
- | `defaultSecurityRules` | `SecurityRule[]` | — | Default RLS rules for collections without their own |
443
- | `enableSwagger` | `boolean` | `true` | Enable OpenAPI spec at `/api/docs` and Swagger UI at `/api/swagger` (dev only) |
444
- | `functionsDir` | `string` | — | Directory for auto-discovered custom function handlers |
445
- | `cronsDir` | `string` | — | Directory for auto-discovered cron job handlers |
446
- | `cronPersistence` | `boolean` | `true` | Persist cron job execution logs to the database |
447
- | `maxBodySize` | `number` | `10485760` (10 MB) | Max request body size in bytes. Set `0` to disable |
448
- | `csrf` | `{ origin: string \| string[] \| ((origin: string) => boolean) }` | — | CSRF protection (opt-in, disabled by default) |
449
- | `hooks` | `BackendHooks` | — | Backend-level hooks for intercepting admin data at the API boundary |
450
- | `logging` | `{ level?: "error" \| "warn" \| "info" \| "debug" }` | `"info"` | Log level configuration |
451
-
452
- > **IMPORTANT FOR AGENTS:** `maxBodySize` applies to all API routes under `basePath`. Storage upload routes have their **own** limit derived from the storage config's `maxFileSize` property (default: 50 MB), which overrides the global limit.
453
-
454
- ### `RebaseAuthConfig` — Authentication Options
455
-
456
- | Property | Type | Default | Description |
457
- |----------|------|---------|-------------|
458
- | `collection` | `EntityCollection` | `defaultUsersCollection` | The collection used for auth users |
459
- | `jwtSecret` | `string` | — | JWT signing secret (≥32 chars) |
460
- | `accessExpiresIn` | `string` | `"1h"` | Access token TTL |
461
- | `refreshExpiresIn` | `string` | `"30d"` | Refresh token TTL |
462
- | `requireAuth` | `boolean` | `true` | Require authentication for data routes |
463
- | `allowRegistration` | `boolean` | `false` | Allow public user registration |
464
- | `serviceKey` | `string` | — | Static secret for server-to-server auth (≥32 chars) |
465
- | `defaultRole` | `string` | — | Role assigned to new users on registration |
466
- | `email` | `EmailConfig` | — | SMTP email configuration |
467
- | `hooks` | `AuthHooks` | — | Override auth behavior (password hashing, validation, etc.) |
468
- | `providers` | `OAuthProvider[]` | — | Custom OAuth providers |
469
-
470
- #### Built-in OAuth Providers
471
-
472
- | Property | Required Fields | Description |
473
- |----------|----------------|-------------|
474
- | `google` | `clientId`, `clientSecret?` | Google OAuth (supports ID token without secret) |
475
- | `github` | `clientId`, `clientSecret` | GitHub OAuth |
476
- | `linkedin` | `clientId`, `clientSecret` | LinkedIn OAuth |
477
- | `microsoft` | `clientId`, `clientSecret`, `tenantId?` | Microsoft/Azure AD OAuth |
478
- | `apple` | `clientId`, `teamId`, `keyId`, `privateKey` | Apple Sign In |
479
- | `facebook` | `clientId`, `clientSecret` | Facebook OAuth |
480
- | `twitter` | `clientId`, `clientSecret` | Twitter/X OAuth |
481
- | `discord` | `clientId`, `clientSecret` | Discord OAuth |
482
- | `gitlab` | `clientId`, `clientSecret`, `baseUrl?` | GitLab OAuth (supports self-hosted) |
483
- | `bitbucket` | `clientId`, `clientSecret` | Bitbucket OAuth |
484
- | `slack` | `clientId`, `clientSecret` | Slack OAuth |
485
- | `spotify` | `clientId`, `clientSecret` | Spotify OAuth |
486
-
487
- ### `RebaseBackendInstance` — Return Value
488
-
489
- | Property / Method | Type | Description |
490
- |-------------------|------|-------------|
491
- | `driver` | `DataDriver` | The default data driver |
492
- | `driverRegistry` | `DriverRegistry` | Registry of all initialized drivers |
493
- | `realtimeService` | `RealtimeProvider` | Default realtime provider |
494
- | `realtimeServices` | `Record<string, RealtimeProvider>` | All realtime providers |
495
- | `auth` | `BootstrappedAuth \| undefined` | Bootstrapped auth result |
496
- | `storageRegistry` | `StorageRegistry \| undefined` | All storage backends |
497
- | `storageController` | `StorageController \| undefined` | Default storage controller |
498
- | `collectionRegistry` | `BackendCollectionRegistry` | Registry of all active collections |
499
- | `cronScheduler` | `CronScheduler \| undefined` | The cron job scheduler (if configured) |
500
- | `healthCheck()` | `() => Promise<HealthCheckResult>` | Deep health check (verifies DB connectivity, returns latency) |
501
- | `shutdown(timeoutMs?)` | `(timeoutMs?: number) => Promise<void>` | Graceful shutdown (stops cron, destroys realtime, drains HTTP, default 15s timeout) |
502
-
503
- ### Shutdown Behavior
504
-
505
- When `shutdown()` is called, it performs these steps in order:
506
-
507
- 1. **Stops the cron scheduler** (if configured)
508
- 2. **Destroys realtime services** (LISTEN clients, debounce timers, subscriptions) — this happens **before** pool close to prevent timer callbacks firing against a closed pool
509
- 3. **Closes the HTTP server** (stops accepting, drains in-flight requests)
510
- 4. **Force-resolves** after `timeoutMs` (default 15000ms). Pass `0` to disable the force timer (useful in tests)
511
-
512
- ### Minimal Backend Example
513
-
514
- ```typescript
515
- import { Hono } from "hono";
516
- import { serve } from "@hono/node-server";
517
- import { initializeRebaseBackend, loadEnv } from "@rebasepro/server-core";
518
- import { createPostgresAdapter } from "@rebasepro/server-postgresql";
519
- import { defaultUsersCollection } from "@rebasepro/common";
520
- import collections from "../config/collections";
521
- import dotenv from "dotenv";
522
-
523
- dotenv.config({ path: "../../.env" });
524
- const env = loadEnv();
525
-
526
- const app = new Hono();
527
- const server = serve({ fetch: app.fetch, port: env.PORT });
528
-
529
- await initializeRebaseBackend({
530
- app,
531
- server,
532
- database: createPostgresAdapter({
533
- connectionString: env.DATABASE_URL,
534
- }),
535
- collections: [...collections, defaultUsersCollection],
536
- collectionsDir: "../config/collections",
537
- functionsDir: "./src/functions",
538
- cronsDir: "./src/crons",
539
- auth: {
540
- collection: defaultUsersCollection,
541
- jwtSecret: env.JWT_SECRET,
542
- serviceKey: env.REBASE_SERVICE_KEY,
543
- allowRegistration: env.ALLOW_REGISTRATION,
544
- google: env.GOOGLE_CLIENT_ID
545
- ? { clientId: env.GOOGLE_CLIENT_ID }
546
- : undefined,
547
- },
548
- storage: { type: env.STORAGE_TYPE },
549
- defaultSecurityRules: [
550
- { operation: "select", access: "public" },
551
- { operations: ["insert", "update", "delete"], roles: ["admin"] },
552
- ],
553
- });
554
-
555
- console.log(`Server running at http://localhost:${env.PORT}`);
556
- ```
557
-
558
- # The `rebase` Singleton
559
-
560
- After `initializeRebaseBackend()` completes, a server-side singleton is available:
561
-
562
- ```typescript
563
- import { rebase } from "@rebasepro/server-core";
564
- ```
565
-
566
- > **WARNING FOR AGENTS:** The singleton is a **lazy proxy** — accessing it at module import time (top-level) will throw. Only use it inside request handlers, cron jobs, hooks, or functions that run after the server has started.
567
-
568
- ### How It Works
569
-
570
- The singleton is a JavaScript `Proxy` object. Any property access on `rebase.*` is intercepted:
571
- - If the server **has** been initialized (`_initRebase()` called by `initializeRebaseBackend()`), the access is forwarded to the internal `RebaseClient` instance.
572
- - If the server **has not** been initialized yet, a descriptive error is thrown: `"rebase.<prop>: server not initialized yet"`.
573
- - The proxy is **read-only** — attempting to assign `rebase.anything = value` throws.
574
-
575
- The underlying client uses an internal `app.request()` fetch (no network hop) and authenticates with the `serviceKey`, giving it **admin-level access** (bypasses RLS).
576
-
577
- ### What It Exposes
578
-
579
- The `rebase` singleton implements the `RebaseClient` interface:
580
-
581
- | Property | Type | Description |
582
- |----------|------|-------------|
583
- | `rebase.data` | `RebaseData` | Admin-level data access (bypasses RLS). Use `rebase.data.<slug>.find()`, `.findOne()`, `.create()`, `.update()`, `.delete()` |
584
- | `rebase.auth` | `AuthClient` | Authentication operations |
585
- | `rebase.storage` | `StorageSource \| undefined` | File storage operations |
586
- | `rebase.email` | `EmailService \| undefined` | Send emails via SMTP (only when email is configured) |
587
- | `rebase.admin` | `AdminAPI \| undefined` | User management API |
588
- | `rebase.sql` | `(query: string) => Promise<Record[]> \| undefined` | Raw SQL execution (only for SQL databases) |
589
- | `rebase.baseUrl` | `string \| undefined` | The base HTTP URL of the backend |
590
-
591
- ### Usage Examples
592
-
593
- ```typescript
594
- import { rebase } from "@rebasepro/server-core";
595
-
596
- // In a cron job, custom function, or hook:
597
-
598
- // Data operations (admin-level, no RLS)
599
- const posts = await rebase.data.posts.find({ limit: 10 });
600
- await rebase.data.orders.create({ status: "pending", total: 99.99 });
601
-
602
- // Send an email
603
- await rebase.email?.send({
604
- to: "admin@company.com",
605
- subject: "Daily Report",
606
- html: "<p>Today's summary...</p>",
607
- });
608
-
609
- // Execute raw SQL
610
- if (rebase.sql) {
611
- const rows = await rebase.sql("SELECT count(*) FROM orders WHERE status = 'pending'");
612
- }
613
- ```
614
-
615
- ### Testing
616
-
617
- ```typescript
618
- import { _setRebaseMock, _resetRebaseMock } from "@rebasepro/server-core";
619
-
620
- // Only works when NODE_ENV=test
621
- beforeEach(() => {
622
- _setRebaseMock({
623
- data: mockDataLayer,
624
- email: mockEmailService,
625
- });
626
- });
627
- afterEach(() => _resetRebaseMock());
628
- ```
629
-
630
- > **IMPORTANT FOR AGENTS:** `_setRebaseMock()` and `_resetRebaseMock()` throw if `NODE_ENV !== "test"`. This prevents accidental use in production.
631
-
632
- # MCP Server Tools
633
-
634
- The Rebase MCP server provides these tools for AI agents. Use the MCP tool calling convention (`call_mcp_tool` with server name `rebase`):
635
-
636
- ### Dev Server Management
637
-
638
- | Tool | Description | Parameters |
639
- |------|-------------|------------|
640
- | `rebase_dev_start` | Start the Rebase dev server (frontend + backend). Returns immediately — use `rebase_dev_logs` to check output | — |
641
- | `rebase_dev_stop` | Stop the running Rebase dev server | — |
642
- | `rebase_dev_logs` | Read recent output from the running dev server | `lines?: number` (default 50) |
643
-
644
- ### Schema & Database
645
-
646
- | Tool | Description | Parameters |
647
- |------|-------------|------------|
648
- | `rebase_schema_generate` | Generate Drizzle schema from collection definitions. Run after adding or modifying collection files | — |
649
- | `rebase_schema_introspect` | Introspect the live database and generate Rebase collection definitions from existing tables | — |
650
- | `rebase_db_push` | Apply the current Drizzle schema directly to the database (development shortcut, skips migration files) | — |
651
- | `rebase_db_generate` | Generate SQL migration files from schema changes (compares current Drizzle schema against the last snapshot) | — |
652
- | `rebase_db_migrate` | Run all pending SQL migrations against the database | — |
653
-
654
- ### SDK
655
-
656
- | Tool | Description | Parameters |
657
- |------|-------------|------------|
658
- | `rebase_generate_sdk` | Generate a fully-typed JS/TS SDK from collection definitions | — |
659
-
660
- ### Document Operations
661
-
662
- | Tool | Description | Parameters |
663
- |------|-------------|------------|
664
- | `list_documents` | List documents from a collection with optional filtering, sorting, pagination | `collection` (required), `where?: object`, `orderBy?: string`, `limit?: number` (default 25), `offset?: number` |
665
- | `get_document` | Get a single document by ID | `collection` (required), `id` (required) |
666
- | `create_document` | Create a new document in a collection | `collection` (required), `data` (required) |
667
- | `update_document` | Update an existing document | `collection` (required), `id` (required), `data` (required) |
668
- | `delete_document` | Delete a document from a collection | `collection` (required), `id` (required) |
669
-
670
- ### User Management
671
-
672
- | Tool | Description | Parameters |
673
- |------|-------------|------------|
674
- | `list_users` | List all users registered in the backend, including their roles | — |
675
- | `create_user` | Create a new user | `email` (required), `displayName?: string`, `password?: string`, `roles?: string[]` |
676
- | `update_user` | Update an existing user (email, display name, roles) | `userId` (required), `email?: string`, `displayName?: string`, `roles?: string[]` |
677
- | `delete_user` | Delete a user from the backend | `userId` (required) |
678
- | `list_roles` | List all roles defined in the backend | — |
679
-
680
- ### Filtering with `list_documents`
681
-
682
- The `where` parameter accepts a filter object with PostgREST-style operators:
683
-
684
- ```json
685
- {
686
- "collection": "products",
687
- "where": {
688
- "status": "eq.active",
689
- "price": "gte.100",
690
- "category": "eq.electronics"
691
- },
692
- "orderBy": "price:desc",
693
- "limit": 10
694
- }
695
- ```
696
-
697
- # Common Issues
698
-
699
- ### Database & Connection
700
-
701
- - **`DATABASE_URL is not set`:** Ensure `.env` exists in the project root with `DATABASE_URL=postgresql://user:password@localhost:5432/rebase`
702
- - **`DATABASE_URL must be a valid URL`:** The value must be a proper PostgreSQL URL including protocol (`postgresql://`). Check for missing or malformed values.
703
- - **Connection refused on port 5432:** PostgreSQL is not running. Start it with `docker compose up -d db` or verify your local Postgres service.
704
- - **`CORS_ORIGINS or FRONTEND_URL must be set in production`:** In `NODE_ENV=production`, set `CORS_ORIGINS=https://yourapp.com` or `FRONTEND_URL=https://yourapp.com` in `.env`.
705
- - **Localhost URL blocked in production:** `loadEnv()` rejects localhost/loopback URLs in production. Set `ALLOW_LOCALHOST_IN_PRODUCTION=true` to override (not recommended).
706
-
707
- ### JWT & Authentication
708
-
709
- - **`JWT_SECRET must be at least 32 characters long`:** Generate one with `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"` and set it in `.env`.
710
- - **`JWT_SECRET must be explicitly set in production`:** Auto-generated dev secrets are blocked in production. Set the value explicitly in `.env`.
711
- - **Tokens invalidated on restart:** In development, `JWT_SECRET` is auto-generated ephemerally. Set it explicitly in `.env` for persistent sessions across restarts.
712
- - **`REBASE_SERVICE_KEY is too short`:** Must be ≥32 characters. Generate with `node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"`.
713
-
714
- ### Port Conflicts
715
-
716
- - **Port already in use:** `rebase dev` auto-selects a unique port per project (3001–3999). If a conflict occurs, use `--port <number>` to specify an explicit port: `rebase dev --port 3010`.
717
- - **Frontend connecting to wrong backend:** Delete `.rebase-dev-port` to reset port affinity, then restart with `rebase dev`.
718
-
719
- ### Schema Drift
720
-
721
- - **Schema out of sync:** Run `rebase doctor` to detect three-way drift between collections, generated Drizzle schema, and the live database.
722
- - **`schema.generated.ts` is stale:** Run `rebase schema generate` to regenerate it from your collection definitions.
723
- - **Migrations pending:** Run `rebase db migrate` to apply outstanding migration files.
724
- - **Column type mismatch after manual DB edit:** Never edit the database manually. Always modify collection files → `rebase schema generate` → `rebase db push` (dev) or `rebase db generate && rebase db migrate` (prod).
725
-
726
- ### CLI & Tooling
727
-
728
- - **pnpm not found:** Install with `npm install -g pnpm`.
729
- - **Node.js version mismatch:** Rebase requires Node.js v20+. Use `nvm install 20 && nvm use 20`.
730
- - **`Could not find tsx binary`:** Install tsx in your project: `pnpm add -D tsx`.
731
- - **`Could not detect an active database plugin`:** Ensure `@rebasepro/server-postgresql` (or another driver) is listed in `backend/package.json` dependencies.
732
- - **`No bootstrappers or database adapter provided`:** The `initializeRebaseBackend()` call is missing the `database` (or `bootstrappers`) property. See the backend configuration section above.
733
- - **`Could not find CLI entry point for <plugin>`:** The database driver plugin's CLI script is missing or not found. Reinstall the plugin: `pnpm add @rebasepro/server-postgresql`.
734
-
735
- ### Singleton Errors
736
-
737
- - **`rebase.<prop>: server not initialized yet`:** You are accessing the `rebase` singleton at module import time or before `initializeRebaseBackend()` has completed. Move the access inside a handler, hook, or function body.
738
- - **`Cannot set rebase.<prop> directly`:** The singleton is read-only. You cannot assign properties to it.
739
- - **`_setRebaseMock can only be called in a test environment`:** Set `NODE_ENV=test` before calling `_setRebaseMock()`.
740
-
741
- ### Storage
742
-
743
- - **`Storage backend "default" uses local filesystem in production`:** A warning is emitted when using `type: "local"` with `NODE_ENV=production`. Files will be lost on container restart. Configure S3-compatible storage or a custom `StorageController`.
744
- - **`File too large`:** The storage upload endpoint has its own body limit (default 50 MB), separate from the global `maxBodySize` (default 10 MB). Configure `maxFileSize` in your storage config to increase it.
745
-
746
- # References
747
-
748
- - **Documentation:** [rebase.pro/docs](https://rebase.pro/docs)
749
- - **GitHub:** [github.com/rebasepro/rebase](https://github.com/rebasepro/rebase)