@rebasepro/cli 0.0.1-canary.eae7889 → 0.1.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,96 @@
1
+ # ╔══════════════════════════════════════════════════════════════════════════════╗
2
+ # ║ Rebase Environment Configuration ║
3
+ # ║ Copy this file to .env and fill in the values ║
4
+ # ╚══════════════════════════════════════════════════════════════════════════════╝
5
+
6
+ # ── Database ──────────────────────────────────────────────────────────────────
7
+ # Database connection string (required)
8
+ # You can use PostgreSQL (postgresql://) or MongoDB (mongodb:// or mongodb+srv://).
9
+ # The backend will automatically detect the database type.
10
+ DATABASE_URL=postgresql://rebase:changeme@localhost:5432/rebase
11
+ # DATABASE_URL=mongodb://localhost:27017/rebase
12
+
13
+ # Separate admin connection string for migrations and schema operations (optional)
14
+ # Falls back to DATABASE_URL if not set
15
+ # ADMIN_CONNECTION_STRING=postgresql://postgres:your-password@localhost:5432/rebase
16
+
17
+ # Connection pool tuning (optional — sensible defaults are built-in)
18
+ # DB_POOL_MAX=20
19
+ # DB_POOL_IDLE_TIMEOUT=30000
20
+ # DB_POOL_CONNECT_TIMEOUT=10000
21
+
22
+ # ── Server ────────────────────────────────────────────────────────────────────
23
+ PORT=3001
24
+ NODE_ENV=development
25
+
26
+ # ── Logging ───────────────────────────────────────────────────────────────────
27
+ # Levels: error, warn, info, debug
28
+ LOG_LEVEL=info
29
+
30
+ # ── JWT Authentication (required) ─────────────────────────────────────────────
31
+ # Must be at least 32 characters. Generate with:
32
+ # node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
33
+ JWT_SECRET=
34
+ JWT_ACCESS_EXPIRES_IN=1h
35
+ JWT_REFRESH_EXPIRES_IN=30d
36
+
37
+ # ── Registration ──────────────────────────────────────────────────────────────
38
+ ALLOW_REGISTRATION=true
39
+
40
+ # ── Email (optional — required for password reset / verification) ─────────────
41
+ # SMTP_HOST=smtp.example.com
42
+ # SMTP_PORT=587
43
+ # SMTP_SECURE=false
44
+ # SMTP_USER=
45
+ # SMTP_PASS=
46
+ # SMTP_FROM=noreply@yourapp.com
47
+ # APP_NAME=Your App Name
48
+
49
+ # ── URLs ──────────────────────────────────────────────────────────────────────
50
+ # Canonical frontend URL (used in password-reset / verification emails)
51
+ FRONTEND_URL=http://localhost:5173
52
+
53
+ # Allowed CORS origins in production (comma-separated)
54
+ # CORS_ORIGINS=https://yourdomain.com
55
+
56
+ # ── OAuth Providers (optional — uncomment to enable) ──────────────────────────
57
+ # GOOGLE_CLIENT_ID=
58
+
59
+ # ── Frontend (Vite) ──────────────────────────────────────────────────────────
60
+ VITE_API_URL=http://localhost:3001
61
+ # VITE_GOOGLE_CLIENT_ID=
62
+
63
+ # ── Storage ───────────────────────────────────────────────────────────────────
64
+ # Set STORAGE_TYPE to choose a storage backend. Default is "local" (filesystem).
65
+ #
66
+ # Supported values: local, s3
67
+ #
68
+ # STORAGE_TYPE=local
69
+
70
+ # --- Local filesystem (default — great for dev and single-server deployments) --
71
+ # STORAGE_PATH=./uploads
72
+
73
+ # --- S3-compatible (AWS S3, Cloudflare R2, MinIO, Hetzner Object Storage, Backblaze B2) ---
74
+ # STORAGE_TYPE=s3
75
+ # S3_BUCKET=my-app-uploads
76
+ # S3_REGION=us-east-1
77
+ # S3_ACCESS_KEY_ID=
78
+ # S3_SECRET_ACCESS_KEY=
79
+ # S3_ENDPOINT= # Required for R2, MinIO, Hetzner (e.g. https://fsn1.your-objectstorage.com)
80
+ # S3_FORCE_PATH_STYLE= # Set to "true" for MinIO
81
+
82
+ # --- GCS via S3 interop (Cloud Run, GKE, etc.) ---
83
+ # Use GCS HMAC keys: https://cloud.google.com/storage/docs/interoperability
84
+ # STORAGE_TYPE=s3
85
+ # S3_BUCKET=my-gcs-bucket
86
+ # S3_ENDPOINT=https://storage.googleapis.com
87
+ # S3_ACCESS_KEY_ID=GOOG... # HMAC access key
88
+ # S3_SECRET_ACCESS_KEY=... # HMAC secret
89
+ #
90
+ # For native GCS SDK or other providers (Azure Blob, etc.), implement the
91
+ # StorageController interface and pass it directly in your backend config.
92
+
93
+ # ── Admin Service Key (optional) ──────────────────────────────────────────────
94
+ # When set, scripts authenticate with: Authorization: Bearer <key>
95
+ # Generate with: node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
96
+ # REBASE_SERVICE_KEY=
@@ -7,8 +7,8 @@ A [Rebase](https://rebase.pro) project with a PostgreSQL backend.
7
7
  ### Option 1: Docker (recommended for production)
8
8
 
9
9
  ```bash
10
- cp .env.template .env
11
- # Edit .env — set POSTGRES_PASSWORD and JWT_SECRET (see comments for generators)
10
+ cp .env.example .env
11
+ # Edit .env — set JWT_SECRET and DATABASE_URL (see comments for generators)
12
12
 
13
13
  docker compose up -d
14
14
  ```
@@ -23,7 +23,7 @@ That's it. Your app is running:
23
23
  #### Prerequisites
24
24
 
25
25
  - [Node.js](https://nodejs.org) >= 18
26
- - [pnpm](https://pnpm.io)
26
+ - [pnpm](https://pnpm.io) or [npm](https://www.npmjs.com) (v7+)
27
27
  - A PostgreSQL database
28
28
 
29
29
  #### Setup
@@ -31,13 +31,13 @@ That's it. Your app is running:
31
31
  1. Install dependencies:
32
32
 
33
33
  ```bash
34
- pnpm install
34
+ pnpm install # or: npm install
35
35
  ```
36
36
 
37
37
  2. Configure environment:
38
38
 
39
39
  ```bash
40
- cp .env.template .env
40
+ cp .env.example .env
41
41
  # Edit .env — set DATABASE_URL, JWT_SECRET
42
42
  ```
43
43
 
@@ -51,7 +51,7 @@ rebase db push
51
51
  4. Start the dev server:
52
52
 
53
53
  ```bash
54
- pnpm dev
54
+ pnpm dev # or: npm run dev
55
55
  ```
56
56
 
57
57
  Backend (Hono + PostgreSQL) on port 3001, frontend (Vite + React) on port 5173.
@@ -69,7 +69,7 @@ Backend (Hono + PostgreSQL) on port 3001, frontend (Vite + React) on port 5173.
69
69
  ├── config/ # Shared collection definitions
70
70
  │ └── collections/ # Schema-as-Code TypeScript files
71
71
  ├── docker-compose.yml # Production stack (Postgres + Backend + Frontend)
72
- ├── .env.template # Environment variable template
72
+ ├── .env.example # Environment variable reference
73
73
  └── package.json # Root workspace config
74
74
  ```
75
75
 
@@ -94,6 +94,16 @@ Call from the client SDK: `client.call("functions/hello", { name: "World" })`
94
94
 
95
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
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
+
97
107
  ## Production Deployment
98
108
 
99
109
  ```bash
@@ -1,14 +1,23 @@
1
- import "dotenv/config";
1
+ import * as dotenv from "dotenv";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
2
4
  import { defineConfig } from "drizzle-kit";
3
5
  import { tables } from "./src/schema.generated";
4
6
  import { getTableName, Table } from "drizzle-orm";
5
7
 
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+
11
+ // Load .env from the project root (single file for the entire project)
12
+ dotenv.config({ path: path.resolve(__dirname, "../.env") });
13
+
6
14
  if (!process.env.DATABASE_URL) {
7
15
  throw new Error("DATABASE_URL is not set. Make sure .env file exists in the project root and contains DATABASE_URL");
8
16
  }
9
17
 
10
- // Extract table names from the generated schema
11
- // This ensures drizzle-kit ONLY manages tables defined in the schema
18
+ // Extract table names from the generated schema.
19
+ // This ensures drizzle-kit ONLY manages tables defined in the schema.
20
+ // Any tables in the database that are NOT part of the Rebase schema are left untouched.
12
21
  const tableNames = Object.values(tables).map(table => getTableName(table as Table));
13
22
 
14
23
  export default defineConfig({
@@ -18,5 +27,16 @@ export default defineConfig({
18
27
  dbCredentials: {
19
28
  url: process.env.DATABASE_URL
20
29
  },
21
- tablesFilter: tableNames
30
+ // Only manage tables defined in the generated schema.
31
+ // Unmapped tables in the database are completely ignored.
32
+ tablesFilter: tableNames,
33
+ // Restrict drizzle-kit to the public schema only — tables in other schemas
34
+ // (e.g. extensions, custom schemas) are never touched.
35
+ schemaFilter: ["public"],
36
+ // Prevent drizzle-kit from managing roles not defined in the schema
37
+ entities: {
38
+ roles: false
39
+ },
40
+ // If PostGIS or other extensions create helper tables, ignore them
41
+ extensionsFilters: ["postgis"]
22
42
  });
@@ -10,12 +10,12 @@
10
10
  "start": "tsx src/index.ts"
11
11
  },
12
12
  "dependencies": {
13
- "{{PROJECT_NAME}}-config": "0.0.1",
13
+ "{{PROJECT_NAME}}-config": "*",
14
14
  "@rebasepro/server-core": "workspace:*",
15
15
  "@rebasepro/server-postgresql": "workspace:*",
16
16
  "drizzle-orm": "^0.44.4",
17
- "hono": "^4.2.0",
18
- "@hono/node-server": "^1.11.0",
17
+ "hono": "^4.12.10",
18
+ "@hono/node-server": "^1.19.12",
19
19
  "pg": "^8.11.3",
20
20
  "ws": "^8.16.0",
21
21
  "zod": "^3.22.4",
@@ -35,17 +35,17 @@ const postsCollection: EntityCollection = {
35
35
  {
36
36
  id: "draft",
37
37
  label: "Draft",
38
- color: "grayLight"
38
+ color: "gray"
39
39
  },
40
40
  {
41
41
  id: "review",
42
42
  label: "In Review",
43
- color: "orangeLight"
43
+ color: "orange"
44
44
  },
45
45
  {
46
46
  id: "published",
47
47
  label: "Published",
48
- color: "greenLight"
48
+ color: "green"
49
49
  }
50
50
  ]
51
51
  },
@@ -1,15 +1,15 @@
1
1
  # ─── Rebase — Production Docker Compose ──────────────────────────────
2
2
  #
3
3
  # Quick start:
4
- # cp .env.template .env # Edit with your secrets
5
- # docker compose up -d # Start everything
4
+ # cp .env.example .env # Edit with your secrets
5
+ # docker compose up -d # Start everything
6
6
  #
7
7
  # This runs:
8
8
  # 1. PostgreSQL 18 with persistent data
9
9
  # 2. Backend (Node.js / Hono) with health checks
10
10
  # 3. Frontend (nginx) serving the Vite build
11
11
  #
12
- # For development, use `pnpm dev` instead.
12
+ # For development, use `rebase dev` instead.
13
13
  # ─────────────────────────────────────────────────────────────────────
14
14
 
15
15
  services:
@@ -18,15 +18,15 @@ services:
18
18
  image: postgres:18-alpine
19
19
  restart: unless-stopped
20
20
  environment:
21
- POSTGRES_USER: ${POSTGRES_USER:-rebase}
22
- POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
23
- POSTGRES_DB: ${POSTGRES_DB:-rebase}
21
+ POSTGRES_USER: rebase
22
+ POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-changeme}
23
+ POSTGRES_DB: rebase
24
24
  ports:
25
- - "${POSTGRES_PORT:-5432}:5432"
25
+ - "5432:5432"
26
26
  volumes:
27
27
  - postgres_data:/var/lib/postgresql/data
28
28
  healthcheck:
29
- test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-rebase} -d ${POSTGRES_DB:-rebase}"]
29
+ test: ["CMD-SHELL", "pg_isready -U rebase -d rebase"]
30
30
  interval: 5s
31
31
  timeout: 5s
32
32
  retries: 10
@@ -53,38 +53,13 @@ services:
53
53
  restart: unless-stopped
54
54
  ports:
55
55
  - "${PORT:-3001}:3001"
56
+ env_file: .env
56
57
  environment:
57
- DATABASE_URL: postgresql://${POSTGRES_USER:-rebase}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-rebase}
58
- ADMIN_CONNECTION_STRING: postgresql://${POSTGRES_USER:-rebase}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-rebase}
59
- JWT_SECRET: ${JWT_SECRET:?Set JWT_SECRET in .env}
60
- JWT_ACCESS_EXPIRES_IN: ${JWT_ACCESS_EXPIRES_IN:-1h}
61
- JWT_REFRESH_EXPIRES_IN: ${JWT_REFRESH_EXPIRES_IN:-30d}
58
+ # Override DATABASE_URL to point to the Docker network service
59
+ DATABASE_URL: postgresql://rebase:${DATABASE_PASSWORD:-changeme}@db:5432/rebase
60
+ ADMIN_CONNECTION_STRING: postgresql://rebase:${DATABASE_PASSWORD:-changeme}@db:5432/rebase
62
61
  NODE_ENV: production
63
62
  PORT: "3001"
64
- ALLOW_REGISTRATION: ${ALLOW_REGISTRATION:-false}
65
- FRONTEND_URL: ${FRONTEND_URL:-http://localhost}
66
- CORS_ORIGINS: ${CORS_ORIGINS:-}
67
- # Optional Google OAuth
68
- GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}
69
- # Optional SMTP
70
- SMTP_HOST: ${SMTP_HOST:-}
71
- SMTP_PORT: ${SMTP_PORT:-}
72
- SMTP_SECURE: ${SMTP_SECURE:-}
73
- SMTP_USER: ${SMTP_USER:-}
74
- SMTP_PASS: ${SMTP_PASS:-}
75
- SMTP_FROM: ${SMTP_FROM:-}
76
- APP_NAME: ${APP_NAME:-Rebase}
77
- # Storage
78
- STORAGE_TYPE: ${STORAGE_TYPE:-local}
79
- STORAGE_PATH: ${STORAGE_PATH:-/app/backend/uploads}
80
- S3_BUCKET: ${S3_BUCKET:-}
81
- S3_REGION: ${S3_REGION:-}
82
- S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-}
83
- S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-}
84
- S3_ENDPOINT: ${S3_ENDPOINT:-}
85
- S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE:-}
86
- # Service key for scripts & server-to-server admin access
87
- REBASE_SERVICE_KEY: ${REBASE_SERVICE_KEY:-}
88
63
  depends_on:
89
64
  db:
90
65
  condition: service_healthy
@@ -98,7 +73,7 @@ services:
98
73
  dockerfile: frontend/Dockerfile
99
74
  restart: unless-stopped
100
75
  ports:
101
- - "${FRONTEND_PORT:-80}:80"
76
+ - "80:80"
102
77
  depends_on:
103
78
  - backend
104
79
 
@@ -13,7 +13,7 @@
13
13
  "@rebasepro/types": "workspace:*",
14
14
  "@rebasepro/ui": "workspace:*",
15
15
  "@fontsource/jetbrains-mono": "^5.2.5",
16
- "{{PROJECT_NAME}}-config": "0.0.1",
16
+ "{{PROJECT_NAME}}-config": "*",
17
17
  "react": "^19.0.0",
18
18
  "react-dom": "^19.0.0",
19
19
  "react-router": "^7.0.0",
@@ -1,47 +1,23 @@
1
- import React, { useCallback } from "react";
1
+ import React from "react";
2
2
 
3
3
  import "@fontsource/jetbrains-mono";
4
4
  import "typeface-rubik";
5
5
 
6
- import {
7
- RebaseLoginView,
8
- useBackendUserManagement,
9
- useRebaseAuthController
10
- } from "@rebasepro/auth";
11
- import {
12
- AppBar,
13
- Drawer,
14
- Rebase,
15
- ModeControllerProvider,
16
- NotFoundPage,
17
- Scaffold,
18
- SideDialogs,
19
- RebaseRoutes,
20
- SnackbarProvider,
21
- ContentHomePage,
22
- useBuildUrlController,
23
- useBuildCollectionRegistryController,
24
- useBuildLocalConfigurationPersistence,
25
- useBuildModeController,
26
- useBuildNavigationStateController
27
- } from "@rebasepro/core";
28
- import { RebaseRoute } from "@rebasepro/admin";
29
- import { CircularProgressCenter } from "@rebasepro/ui";
30
- import { collections } from "virtual:rebase-collections";
31
- import { Route, Outlet } from "react-router-dom";
6
+ import { useRebaseAuthController, useBackendUserManagement, RebaseAuth } from "@rebasepro/auth";
7
+ import { Rebase } from "@rebasepro/core";
8
+ import { RebaseCMS, RebaseShell } from "@rebasepro/admin";
9
+ import { RebaseStudio } from "@rebasepro/studio";
32
10
  import { createRebaseClient } from "@rebasepro/client";
11
+ import { collections } from "virtual:rebase-collections";
33
12
 
34
13
  // Configuration from environment
35
14
  const API_URL = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? "http://localhost:3001" : undefined);
36
15
  const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
37
16
 
38
17
  export function App() {
39
- const modeController = useBuildModeController();
40
- const userConfigPersistence = useBuildLocalConfigurationPersistence();
41
-
42
18
  const rebaseClient = React.useMemo(() => createRebaseClient({
43
19
  baseUrl: API_URL
44
- }), [API_URL]);
20
+ }), []);
45
21
 
46
22
  const authController = useRebaseAuthController({
47
23
  client: rebaseClient,
@@ -53,73 +29,18 @@ export function App() {
53
29
  currentUser: authController.user
54
30
  });
55
31
 
56
- const collectionsBuilder = useCallback(() => {
57
- return [...collections];
58
- }, []);
59
-
60
- const collectionRegistryController = useBuildCollectionRegistryController({ userConfigPersistence });
61
- const urlController = useBuildUrlController({
62
- basePath: "/",
63
- baseCollectionPath: "/c",
64
- collectionRegistryController
65
- });
66
-
67
- const navigationStateController = useBuildNavigationStateController({
68
- collections: collectionsBuilder,
69
- authController,
70
- data: rebaseClient.data,
71
- collectionRegistryController,
72
- urlController,
73
- userManagement
74
- });
75
-
76
32
  return (
77
- <SnackbarProvider>
78
- <ModeControllerProvider value={modeController}>
79
- <Rebase
80
- client={rebaseClient}
81
- apiUrl={API_URL}
82
- collectionRegistryController={collectionRegistryController}
83
- urlController={urlController}
84
- navigationStateController={navigationStateController}
85
- authController={authController}
86
- userConfigPersistence={userConfigPersistence}
87
- storageSource={rebaseClient.storage}
88
- >
89
- {({ loading }) => {
90
- if (loading || authController.initialLoading) {
91
- return <CircularProgressCenter/>;
92
- }
93
-
94
- if (!authController.user) {
95
- return (
96
- <RebaseLoginView
97
- authController={authController}
98
- googleEnabled={!!GOOGLE_CLIENT_ID}
99
- googleClientId={GOOGLE_CLIENT_ID}
100
- />
101
- );
102
- }
103
-
104
- return (
105
- <RebaseRoutes>
106
- <Route element={
107
- <Scaffold autoOpenDrawer={false}>
108
- <AppBar/>
109
- <Drawer/>
110
- <Outlet/>
111
- <SideDialogs/>
112
- </Scaffold>
113
- }>
114
- <Route path={"/"} element={<ContentHomePage/>}/>
115
- <Route path={"/c/*"} element={<RebaseRoute/>}/>
116
- <Route path={"*"} element={<NotFoundPage/>}/>
117
- </Route>
118
- </RebaseRoutes>
119
- );
120
- }}
121
- </Rebase>
122
- </ModeControllerProvider>
123
- </SnackbarProvider>
33
+ <Rebase
34
+ client={rebaseClient}
35
+ authController={authController}
36
+ userManagement={userManagement}
37
+ >
38
+ <RebaseAuth />
39
+ <RebaseCMS
40
+ collections={collections}
41
+ />
42
+ <RebaseStudio/>
43
+ <RebaseShell title="Rebase"/>
44
+ </Rebase>
124
45
  );
125
46
  }
@@ -7,14 +7,44 @@ import tailwindcss from "@tailwindcss/vite";
7
7
  import { rebaseCollectionsPlugin } from "@rebasepro/core/vitePlugin";
8
8
 
9
9
  export default defineConfig({
10
+ envDir: path.resolve(__dirname, ".."),
10
11
  esbuild: {
11
12
  logOverride: { "this-is-undefined-in-esm": "silent" }
12
13
  },
13
14
  build: {
14
15
  minify: true,
15
- outDir: "./build",
16
+ outDir: "./dist",
16
17
  target: "ESNEXT",
17
- sourcemap: true
18
+ sourcemap: true,
19
+ rollupOptions: {
20
+ output: {
21
+ manualChunks(id) {
22
+ // Heavy vendor libraries — split into individually cached chunks
23
+ if (id.includes("xlsx")) return "vendor-xlsx";
24
+ if (id.includes("prosemirror")) return "vendor-prosemirror";
25
+ if (id.includes("monaco-editor") || id.includes("@monaco-editor")) return "vendor-monaco";
26
+ if (id.includes("@xyflow") || id.includes("dagre")) return "vendor-xyflow";
27
+ if (id.includes("@dnd-kit")) return "vendor-dnd";
28
+ if (id.includes("prism-react-renderer")) return "vendor-prism";
29
+ if (id.includes("markdown-it")) return "vendor-markdown";
30
+ if (id.includes("react-dropzone")) return "vendor-dropzone";
31
+ if (id.includes("date-fns")) return "vendor-datefns";
32
+ if (id.includes("fuse.js")) return "vendor-fuse";
33
+ if (id.includes("node_modules/react-dom/")) return "vendor-react-dom";
34
+ if (id.includes("node_modules/react-router") || id.includes("node_modules/@remix-run")) return "vendor-react-router";
35
+ if (id.includes("node_modules/@radix-ui/")) return "vendor-radix";
36
+ if (id.includes("node_modules/framer-motion/")) return "vendor-framer-motion";
37
+ if (id.includes("node_modules/zod/")) return "vendor-zod";
38
+ if (id.includes("node_modules/i18next") || id.includes("node_modules/react-i18next")) return "vendor-i18next";
39
+ if (id.includes("node_modules/@floating-ui/")) return "vendor-floating-ui";
40
+ if (id.includes("node_modules/tailwind-merge/")) return "vendor-tailwind-merge";
41
+ if (id.includes("node_modules/notistack/")) return "vendor-notistack";
42
+ if (id.includes("node_modules/lucide-react/")) return "vendor-lucide-react";
43
+
44
+ return undefined;
45
+ }
46
+ }
47
+ }
18
48
  },
19
49
  optimizeDeps: { include: ["react/jsx-runtime"] },
20
50
  plugins: [
@@ -4,17 +4,23 @@
4
4
  "description": "Rebase application with PostgreSQL backend",
5
5
  "private": true,
6
6
  "type": "module",
7
+ "workspaces": [
8
+ "frontend",
9
+ "backend",
10
+ "config"
11
+ ],
7
12
  "scripts": {
8
13
  "dev": "rebase dev",
9
- "build": "pnpm -r run build",
10
- "start": "pnpm --filter \"*-backend\" start",
11
- "db:generate": "rebase db generate",
14
+ "build": "rebase build",
15
+ "start": "rebase start",
16
+ "db:generate": "rebase db generate --collections ../config/collections",
12
17
  "db:migrate": "rebase db migrate",
13
- "db:pull": "rebase db pull",
14
- "db:push": "rebase db push",
18
+ "schema:introspect": "rebase schema introspect",
19
+ "db:push": "rebase db push --collections ../config/collections",
15
20
  "db:studio": "rebase db studio",
16
- "schema:generate": "rebase schema generate",
17
- "generate:sdk": "rebase generate-sdk"
21
+ "schema:generate": "rebase schema generate --collections ../config/collections",
22
+ "generate:sdk": "rebase generate-sdk",
23
+ "deploy": "rebase build && rebase start"
18
24
  },
19
25
  "devDependencies": {
20
26
  "@rebasepro/cli": "workspace:*",
@@ -1,62 +0,0 @@
1
- # ─── Rebase Environment Configuration ────────────────────────────────
2
- # Copy this file to .env and fill in your values:
3
- # cp .env.template .env
4
-
5
- # ── Database ─────────────────────────────────────────────────────────
6
- # Used by Docker Compose AND the backend
7
- POSTGRES_USER=rebase
8
- POSTGRES_PASSWORD= # REQUIRED — generate with: openssl rand -base64 32
9
- POSTGRES_DB=rebase
10
- POSTGRES_PORT=5432
11
-
12
- # For local dev (without Docker):
13
- DATABASE_URL=postgresql://rebase:${POSTGRES_PASSWORD}@localhost:5432/rebase
14
-
15
- # ── Server ───────────────────────────────────────────────────────────
16
- PORT=3001
17
- NODE_ENV=development
18
-
19
- # ── Authentication ───────────────────────────────────────────────────
20
- JWT_SECRET= # REQUIRED — generate with: openssl rand -base64 64
21
- JWT_ACCESS_EXPIRES_IN=1h
22
- JWT_REFRESH_EXPIRES_IN=30d
23
- ALLOW_REGISTRATION=true
24
-
25
- # Admin service key for scripts & server-to-server calls (optional).
26
- # When set, scripts authenticate with: Authorization: Bearer <key>
27
- # REBASE_SERVICE_KEY= # generate with: node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
28
-
29
- # ── Frontend ─────────────────────────────────────────────────────────
30
- FRONTEND_PORT=80
31
- VITE_API_URL=http://localhost:3001
32
-
33
- # Canonical frontend URL (used in password-reset / verification emails)
34
- FRONTEND_URL=http://localhost
35
-
36
- # Allowed CORS origins in production (comma-separated)
37
- # CORS_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
38
-
39
- # ── Google OAuth (optional) ──────────────────────────────────────────
40
- # GOOGLE_CLIENT_ID=your-google-client-id
41
- # VITE_GOOGLE_CLIENT_ID=your-google-client-id
42
-
43
- # ── Email / SMTP (optional — enables password reset emails) ──────────
44
- # SMTP_HOST=smtp.example.com
45
- # SMTP_PORT=587
46
- # SMTP_SECURE=false
47
- # SMTP_USER=your-smtp-username
48
- # SMTP_PASS=your-smtp-password
49
- # SMTP_FROM=noreply@yourapp.com
50
- # APP_NAME=My Rebase App
51
-
52
- # ── Storage ──────────────────────────────────────────────────────────
53
- # STORAGE_TYPE=local # Options: "local" or "s3"
54
- # STORAGE_PATH=./uploads # Path for "local" storage
55
-
56
- # S3 Configuration (Required if STORAGE_TYPE=s3)
57
- # S3_BUCKET=my-rebase-bucket
58
- # S3_REGION=us-east-1
59
- # S3_ACCESS_KEY_ID=your-access-key
60
- # S3_SECRET_ACCESS_KEY=your-secret-key
61
- # S3_ENDPOINT=https://s3.us-east-1.amazonaws.com # Optional, used for MinIO or Cloudflare R2
62
- # S3_FORCE_PATH_STYLE=false # Set to true for MinIO