@rebasepro/cli 0.0.1-canary.e259309 → 0.0.1-canary.eb08332
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.
- package/LICENSE +17 -196
- package/README.md +57 -33
- package/dist/commands/api-keys.d.ts +1 -0
- package/dist/commands/build.d.ts +1 -0
- package/dist/commands/cloud/auth.d.ts +3 -0
- package/dist/commands/cloud/context.d.ts +61 -0
- package/dist/commands/cloud/databases.d.ts +1 -0
- package/dist/commands/cloud/deploy.d.ts +2 -0
- package/dist/commands/cloud/index.d.ts +1 -0
- package/dist/commands/cloud/link.d.ts +5 -0
- package/dist/commands/cloud/orgs.d.ts +1 -0
- package/dist/commands/cloud/projects.d.ts +13 -0
- package/dist/commands/cloud/resources.d.ts +6 -0
- package/dist/commands/generate_sdk.d.ts +1 -1
- package/dist/commands/init.d.ts +37 -0
- package/dist/commands/skills.d.ts +1 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.es.js +3781 -1089
- package/dist/index.es.js.map +1 -1
- package/dist/utils/package-manager.d.ts +33 -0
- package/dist/utils/project.d.ts +16 -1
- package/package.json +26 -23
- package/templates/overlays/baas/README.md +37 -0
- package/templates/overlays/baas/backend/package.json +31 -0
- package/templates/overlays/baas/backend/src/index.ts +172 -0
- package/templates/overlays/baas/backend/tsconfig.json +18 -0
- package/templates/overlays/baas/package.json +42 -0
- package/templates/overlays/baas/pnpm-workspace.yaml +9 -0
- package/templates/template/.cursorrules +2 -0
- package/templates/template/.dockerignore +1 -1
- package/templates/template/.env.example +120 -0
- package/templates/template/.github/copilot-instructions.md +2 -0
- package/templates/template/.windsurfrules +2 -0
- package/templates/template/AGENTS.md +2 -0
- package/templates/template/CLAUDE.md +2 -0
- package/templates/template/README.md +20 -10
- package/templates/template/ai-instructions.md +17 -0
- package/templates/template/backend/Dockerfile +5 -4
- package/templates/template/backend/functions/hello.ts +36 -32
- package/templates/template/backend/package.json +9 -9
- package/templates/template/backend/src/env.ts +13 -42
- package/templates/template/backend/src/index.ts +54 -28
- package/templates/template/config/collections/authors.ts +2 -2
- package/templates/template/config/collections/index.ts +25 -4
- package/templates/template/config/collections/posts.ts +12 -32
- package/templates/template/config/collections/presets/blank/index.ts +3 -0
- package/templates/template/config/collections/presets/ecommerce/categories.ts +40 -0
- package/templates/template/config/collections/presets/ecommerce/index.ts +6 -0
- package/templates/template/config/collections/presets/ecommerce/orders.ts +66 -0
- package/templates/template/config/collections/presets/ecommerce/products.ts +64 -0
- package/templates/template/config/collections/tags.ts +3 -5
- package/templates/template/config/collections/users.ts +142 -0
- package/templates/template/config/index.ts +1 -1
- package/templates/template/docker-compose.yml +14 -39
- package/templates/template/frontend/Dockerfile +5 -3
- package/templates/template/frontend/package.json +8 -7
- package/templates/template/frontend/src/App.tsx +22 -22
- package/templates/template/frontend/src/main.tsx +4 -0
- package/templates/template/frontend/src/virtual.d.ts +6 -0
- package/templates/template/frontend/tsconfig.json +3 -2
- package/templates/template/frontend/vite.config.ts +17 -3
- package/templates/template/package.json +18 -5
- package/templates/template/pnpm-workspace.yaml +9 -0
- package/templates/template/scripts/example.ts +5 -2
- package/dist/auth.d.ts +0 -5
- package/dist/commands/cli.test.d.ts +0 -1
- package/dist/commands/dev.test.d.ts +0 -1
- package/dist/commands/init.test.d.ts +0 -1
- package/dist/index.cjs +0 -1306
- package/dist/index.cjs.map +0 -1
- package/dist/utils/project.test.d.ts +0 -1
- package/templates/template/.env.template +0 -62
- package/templates/template/backend/drizzle.config.ts +0 -34
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CollectionConfig } from "@rebasepro/types";
|
|
2
|
+
|
|
3
|
+
const ordersCollection: CollectionConfig = {
|
|
4
|
+
name: "Orders",
|
|
5
|
+
singularName: "Order",
|
|
6
|
+
slug: "orders",
|
|
7
|
+
table: "orders",
|
|
8
|
+
icon: "Receipt",
|
|
9
|
+
properties: {
|
|
10
|
+
id: {
|
|
11
|
+
name: "ID",
|
|
12
|
+
type: "number",
|
|
13
|
+
isId: "increment"
|
|
14
|
+
},
|
|
15
|
+
customerEmail: {
|
|
16
|
+
name: "Customer Email",
|
|
17
|
+
type: "string",
|
|
18
|
+
columnName: "customer_email",
|
|
19
|
+
validation: { required: true }
|
|
20
|
+
},
|
|
21
|
+
status: {
|
|
22
|
+
name: "Status",
|
|
23
|
+
type: "string",
|
|
24
|
+
enum: [
|
|
25
|
+
{ id: "pending",
|
|
26
|
+
label: "Pending",
|
|
27
|
+
color: "gray" },
|
|
28
|
+
{ id: "processing",
|
|
29
|
+
label: "Processing",
|
|
30
|
+
color: "blue" },
|
|
31
|
+
{ id: "shipped",
|
|
32
|
+
label: "Shipped",
|
|
33
|
+
color: "orange" },
|
|
34
|
+
{ id: "delivered",
|
|
35
|
+
label: "Delivered",
|
|
36
|
+
color: "green" },
|
|
37
|
+
{ id: "cancelled",
|
|
38
|
+
label: "Cancelled",
|
|
39
|
+
color: "red" }
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
total: {
|
|
43
|
+
name: "Total",
|
|
44
|
+
type: "number",
|
|
45
|
+
validation: { required: true }
|
|
46
|
+
},
|
|
47
|
+
notes: {
|
|
48
|
+
name: "Notes",
|
|
49
|
+
type: "string",
|
|
50
|
+
ui: {
|
|
51
|
+
multiline: true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
createdAt: {
|
|
55
|
+
name: "Created At",
|
|
56
|
+
type: "date",
|
|
57
|
+
columnName: "created_at",
|
|
58
|
+
autoValue: "on_create",
|
|
59
|
+
ui: {
|
|
60
|
+
readOnly: true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default ordersCollection;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { CollectionConfig } from "@rebasepro/types";
|
|
2
|
+
import categoriesCollection from "./categories.js";
|
|
3
|
+
|
|
4
|
+
const productsCollection: CollectionConfig = {
|
|
5
|
+
name: "Products",
|
|
6
|
+
singularName: "Product",
|
|
7
|
+
slug: "products",
|
|
8
|
+
table: "products",
|
|
9
|
+
icon: "ShoppingCart",
|
|
10
|
+
properties: {
|
|
11
|
+
id: {
|
|
12
|
+
name: "ID",
|
|
13
|
+
type: "number",
|
|
14
|
+
isId: "increment"
|
|
15
|
+
},
|
|
16
|
+
name: {
|
|
17
|
+
name: "Name",
|
|
18
|
+
type: "string",
|
|
19
|
+
validation: { required: true }
|
|
20
|
+
},
|
|
21
|
+
description: {
|
|
22
|
+
name: "Description",
|
|
23
|
+
type: "string",
|
|
24
|
+
ui: {
|
|
25
|
+
markdown: true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
price: {
|
|
29
|
+
name: "Price",
|
|
30
|
+
type: "number",
|
|
31
|
+
validation: { required: true }
|
|
32
|
+
},
|
|
33
|
+
image: {
|
|
34
|
+
name: "Image",
|
|
35
|
+
type: "string",
|
|
36
|
+
storage: { storagePath: "product_images/" }
|
|
37
|
+
},
|
|
38
|
+
status: {
|
|
39
|
+
name: "Status",
|
|
40
|
+
type: "string",
|
|
41
|
+
enum: [
|
|
42
|
+
{ id: "draft",
|
|
43
|
+
label: "Draft",
|
|
44
|
+
color: "gray" },
|
|
45
|
+
{ id: "active",
|
|
46
|
+
label: "Active",
|
|
47
|
+
color: "green" },
|
|
48
|
+
{ id: "archived",
|
|
49
|
+
label: "Archived",
|
|
50
|
+
color: "orange" }
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
category: {
|
|
54
|
+
name: "Category",
|
|
55
|
+
type: "relation",
|
|
56
|
+
relationName: "category",
|
|
57
|
+
target: () => categoriesCollection,
|
|
58
|
+
cardinality: "one",
|
|
59
|
+
direction: "owning"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default productsCollection;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CollectionConfig } from "@rebasepro/types";
|
|
2
2
|
|
|
3
|
-
const tagsCollection:
|
|
3
|
+
const tagsCollection: CollectionConfig = {
|
|
4
4
|
name: "Tags",
|
|
5
5
|
singularName: "Tag",
|
|
6
6
|
slug: "tags",
|
|
@@ -10,9 +10,7 @@ const tagsCollection: EntityCollection = {
|
|
|
10
10
|
id: {
|
|
11
11
|
name: "ID",
|
|
12
12
|
type: "number",
|
|
13
|
-
|
|
14
|
-
required: true
|
|
15
|
-
}
|
|
13
|
+
isId: "increment"
|
|
16
14
|
},
|
|
17
15
|
name: {
|
|
18
16
|
name: "Tag Name",
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { CollectionConfig } from "@rebasepro/types";
|
|
2
|
+
|
|
3
|
+
const usersCollection: CollectionConfig = {
|
|
4
|
+
name: "Users",
|
|
5
|
+
singularName: "User",
|
|
6
|
+
slug: "users",
|
|
7
|
+
auth: { enabled: true },
|
|
8
|
+
table: "users",
|
|
9
|
+
schema: "rebase",
|
|
10
|
+
icon: "Users",
|
|
11
|
+
group: "Settings",
|
|
12
|
+
openEntityMode: "dialog",
|
|
13
|
+
disableDefaultActions: ["copy"],
|
|
14
|
+
securityRules: [
|
|
15
|
+
{ operation: "select",
|
|
16
|
+
roles: ["admin"] },
|
|
17
|
+
{ operations: ["insert", "update", "delete"],
|
|
18
|
+
roles: ["admin"] }
|
|
19
|
+
],
|
|
20
|
+
sort: ["createdAt", "desc"],
|
|
21
|
+
properties: {
|
|
22
|
+
id: {
|
|
23
|
+
name: "ID",
|
|
24
|
+
type: "string",
|
|
25
|
+
isId: "uuid",
|
|
26
|
+
ui: {
|
|
27
|
+
readOnly: true
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
email: {
|
|
31
|
+
name: "Email",
|
|
32
|
+
type: "string",
|
|
33
|
+
validation: {
|
|
34
|
+
required: true,
|
|
35
|
+
unique: true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
displayName: {
|
|
39
|
+
name: "Name",
|
|
40
|
+
type: "string",
|
|
41
|
+
columnName: "display_name"
|
|
42
|
+
},
|
|
43
|
+
photoURL: {
|
|
44
|
+
name: "Photo URL",
|
|
45
|
+
type: "string",
|
|
46
|
+
columnName: "photo_url",
|
|
47
|
+
ui: {
|
|
48
|
+
url: "image"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
roles: {
|
|
52
|
+
name: "Roles",
|
|
53
|
+
type: "array",
|
|
54
|
+
columnType: "text[]",
|
|
55
|
+
of: {
|
|
56
|
+
name: "Role",
|
|
57
|
+
type: "string",
|
|
58
|
+
enum: {
|
|
59
|
+
admin: "Admin",
|
|
60
|
+
editor: "Editor",
|
|
61
|
+
viewer: "Viewer"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
passwordHash: {
|
|
66
|
+
name: "Password Hash",
|
|
67
|
+
type: "string",
|
|
68
|
+
columnName: "password_hash",
|
|
69
|
+
ui: {
|
|
70
|
+
hideFromCollection: true,
|
|
71
|
+
disabled: { hidden: true }
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
emailVerified: {
|
|
75
|
+
name: "Email Verified",
|
|
76
|
+
type: "boolean",
|
|
77
|
+
columnName: "email_verified",
|
|
78
|
+
defaultValue: false,
|
|
79
|
+
ui: {
|
|
80
|
+
hideFromCollection: true,
|
|
81
|
+
disabled: { hidden: true }
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
emailVerificationToken: {
|
|
85
|
+
name: "Email Verification Token",
|
|
86
|
+
type: "string",
|
|
87
|
+
columnName: "email_verification_token",
|
|
88
|
+
ui: {
|
|
89
|
+
hideFromCollection: true,
|
|
90
|
+
disabled: { hidden: true }
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
emailVerificationSentAt: {
|
|
94
|
+
name: "Email Verification Sent At",
|
|
95
|
+
type: "date",
|
|
96
|
+
columnName: "email_verification_sent_at",
|
|
97
|
+
ui: {
|
|
98
|
+
hideFromCollection: true,
|
|
99
|
+
disabled: { hidden: true }
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
metadata: {
|
|
103
|
+
name: "Metadata",
|
|
104
|
+
type: "map",
|
|
105
|
+
keyValue: true,
|
|
106
|
+
properties: {},
|
|
107
|
+
defaultValue: {},
|
|
108
|
+
ui: {
|
|
109
|
+
hideFromCollection: true,
|
|
110
|
+
disabled: { hidden: true }
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
createdAt: {
|
|
114
|
+
name: "Created At",
|
|
115
|
+
type: "date",
|
|
116
|
+
columnName: "created_at",
|
|
117
|
+
autoValue: "on_create",
|
|
118
|
+
ui: {
|
|
119
|
+
readOnly: true
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
updatedAt: {
|
|
123
|
+
name: "Updated At",
|
|
124
|
+
type: "date",
|
|
125
|
+
columnName: "updated_at",
|
|
126
|
+
autoValue: "on_update",
|
|
127
|
+
ui: {
|
|
128
|
+
hideFromCollection: true,
|
|
129
|
+
disabled: { hidden: true }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
propertiesOrder: [
|
|
134
|
+
"id",
|
|
135
|
+
"email",
|
|
136
|
+
"displayName",
|
|
137
|
+
"roles",
|
|
138
|
+
"createdAt"
|
|
139
|
+
]
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export default usersCollection;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# ─── Rebase — Production Docker Compose ──────────────────────────────
|
|
2
2
|
#
|
|
3
3
|
# Quick start:
|
|
4
|
-
# cp .env.
|
|
5
|
-
# docker compose up -d
|
|
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 `
|
|
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:
|
|
22
|
-
POSTGRES_PASSWORD: ${
|
|
23
|
-
POSTGRES_DB:
|
|
21
|
+
POSTGRES_USER: rebase
|
|
22
|
+
POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-changeme}
|
|
23
|
+
POSTGRES_DB: rebase
|
|
24
24
|
ports:
|
|
25
|
-
- "
|
|
25
|
+
- "5432:5432"
|
|
26
26
|
volumes:
|
|
27
|
-
- postgres_data:/var/lib/postgresql
|
|
27
|
+
- postgres_data:/var/lib/postgresql
|
|
28
28
|
healthcheck:
|
|
29
|
-
test: ["CMD-SHELL", "pg_isready -U
|
|
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
|
|
58
|
-
|
|
59
|
-
|
|
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?options=-c%20search_path=public
|
|
60
|
+
ADMIN_CONNECTION_STRING: postgresql://rebase:${DATABASE_PASSWORD:-changeme}@db:5432/rebase?options=-c%20search_path=public
|
|
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
|
-
- "
|
|
76
|
+
- "80:80"
|
|
102
77
|
depends_on:
|
|
103
78
|
- backend
|
|
104
79
|
|
|
@@ -17,14 +17,16 @@ RUN apk add --no-cache python3 make g++
|
|
|
17
17
|
WORKDIR /app
|
|
18
18
|
|
|
19
19
|
# Copy workspace root files
|
|
20
|
-
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
|
20
|
+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
|
21
21
|
|
|
22
22
|
# Copy workspace packages
|
|
23
23
|
COPY frontend ./frontend
|
|
24
24
|
COPY config ./config
|
|
25
25
|
|
|
26
|
-
# Install dependencies
|
|
27
|
-
|
|
26
|
+
# Install dependencies (skip scripts to avoid @ariga/atlas binary download,
|
|
27
|
+
# which is a backend-only dependency that may fail on certain platforms)
|
|
28
|
+
RUN pnpm install --frozen-lockfile --ignore-scripts
|
|
29
|
+
RUN pnpm rebuild esbuild
|
|
28
30
|
|
|
29
31
|
# Build config first, then frontend
|
|
30
32
|
RUN pnpm --filter "*-config" run build
|
|
@@ -4,21 +4,21 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@rebasepro/
|
|
8
|
-
"@rebasepro/
|
|
9
|
-
"@rebasepro/plugin-data-enhancement": "workspace:*",
|
|
7
|
+
"@rebasepro/app": "workspace:*",
|
|
8
|
+
"@rebasepro/plugin-ai": "workspace:*",
|
|
10
9
|
"@rebasepro/client": "workspace:*",
|
|
11
10
|
"@rebasepro/admin": "workspace:*",
|
|
12
11
|
"@rebasepro/studio": "workspace:*",
|
|
13
12
|
"@rebasepro/types": "workspace:*",
|
|
14
13
|
"@rebasepro/ui": "workspace:*",
|
|
15
14
|
"@fontsource/jetbrains-mono": "^5.2.5",
|
|
16
|
-
"{{PROJECT_NAME}}-config": "
|
|
15
|
+
"{{PROJECT_NAME}}-config": "*",
|
|
17
16
|
"react": "^19.0.0",
|
|
18
17
|
"react-dom": "^19.0.0",
|
|
19
18
|
"react-router": "^7.0.0",
|
|
20
19
|
"react-router-dom": "^7.0.0",
|
|
21
|
-
"
|
|
20
|
+
"react-compiler-runtime": "^1.0.0",
|
|
21
|
+
"@fontsource/rubik": "^5.2.5"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"dev": "vite --mode development",
|
|
@@ -40,12 +40,13 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@tailwindcss/typography": "^0.5.16",
|
|
42
42
|
"@tailwindcss/vite": "^4.1.12",
|
|
43
|
+
"@types/node": "^20.19.41",
|
|
43
44
|
"@types/react": "^19.0.8",
|
|
44
45
|
"@types/react-dom": "^19.0.3",
|
|
45
|
-
"@vitejs/plugin-react": "^4.
|
|
46
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
46
47
|
"tailwindcss": "^4.1.3",
|
|
47
48
|
"typescript": "^5.9.2",
|
|
48
|
-
"vite": "^
|
|
49
|
+
"vite": "^6.4.3",
|
|
49
50
|
"vite-plugin-svgr": "^4.3.0"
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
3
|
import "@fontsource/jetbrains-mono";
|
|
4
|
-
import "
|
|
4
|
+
import "@fontsource/rubik";
|
|
5
5
|
|
|
6
|
-
import { useRebaseAuthController
|
|
7
|
-
import { Rebase } from "@rebasepro/
|
|
8
|
-
import {
|
|
6
|
+
import { useRebaseAuthController } from "@rebasepro/app";
|
|
7
|
+
import { Rebase, RebaseAuth } from "@rebasepro/app";
|
|
8
|
+
import { RebaseAdmin, RebaseShell } from "@rebasepro/admin";
|
|
9
|
+
import { ErrorBoundary } from "@rebasepro/ui";
|
|
9
10
|
import { RebaseStudio } from "@rebasepro/studio";
|
|
10
11
|
import { createRebaseClient } from "@rebasepro/client";
|
|
11
12
|
import { collections } from "virtual:rebase-collections";
|
|
@@ -16,7 +17,10 @@ const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
|
|
|
16
17
|
|
|
17
18
|
export function App() {
|
|
18
19
|
const rebaseClient = React.useMemo(() => createRebaseClient({
|
|
19
|
-
baseUrl: API_URL
|
|
20
|
+
baseUrl: API_URL,
|
|
21
|
+
// Store the refresh token in an httpOnly cookie (XSS-safe) rather than
|
|
22
|
+
// localStorage. The backend issues it via `auth.cookieAuth`.
|
|
23
|
+
auth: { authFlowMode: "cookie" }
|
|
20
24
|
}), []);
|
|
21
25
|
|
|
22
26
|
const authController = useRebaseAuthController({
|
|
@@ -24,23 +28,19 @@ export function App() {
|
|
|
24
28
|
googleClientId: GOOGLE_CLIENT_ID
|
|
25
29
|
});
|
|
26
30
|
|
|
27
|
-
const userManagement = useBackendUserManagement({
|
|
28
|
-
client: rebaseClient,
|
|
29
|
-
currentUser: authController.user
|
|
30
|
-
});
|
|
31
|
-
|
|
32
31
|
return (
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
<ErrorBoundary fullPage>
|
|
33
|
+
<Rebase
|
|
34
|
+
client={rebaseClient}
|
|
35
|
+
authController={authController}
|
|
36
|
+
>
|
|
37
|
+
<RebaseAuth />
|
|
38
|
+
<RebaseAdmin
|
|
39
|
+
collections={collections}
|
|
40
|
+
/>
|
|
41
|
+
<RebaseStudio/>
|
|
42
|
+
<RebaseShell title="Rebase"/>
|
|
43
|
+
</Rebase>
|
|
44
|
+
</ErrorBoundary>
|
|
45
45
|
);
|
|
46
46
|
}
|
|
@@ -4,6 +4,10 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
|
|
4
4
|
import { App } from "./App";
|
|
5
5
|
import "./index.css";
|
|
6
6
|
|
|
7
|
+
window.addEventListener("unhandledrejection", (event: PromiseRejectionEvent) => {
|
|
8
|
+
console.error("[Rebase] Unhandled promise rejection:", event.reason);
|
|
9
|
+
});
|
|
10
|
+
|
|
7
11
|
const router = createBrowserRouter([
|
|
8
12
|
{
|
|
9
13
|
path: "/*",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"resolveJsonModule": true,
|
|
15
15
|
"isolatedModules": true,
|
|
16
16
|
"noEmit": true,
|
|
17
|
-
"jsx": "react-jsx"
|
|
17
|
+
"jsx": "react-jsx",
|
|
18
|
+
"types": ["vite/client", "node"]
|
|
18
19
|
},
|
|
19
|
-
"include": ["
|
|
20
|
+
"include": ["src/**/*", "vite.config.ts"]
|
|
20
21
|
}
|
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
1
|
import path from "path";
|
|
3
2
|
import { defineConfig } from "vite";
|
|
4
3
|
import react from "@vitejs/plugin-react";
|
|
5
4
|
import svgr from "vite-plugin-svgr";
|
|
6
5
|
import tailwindcss from "@tailwindcss/vite";
|
|
7
|
-
import { rebaseCollectionsPlugin } from "@rebasepro/
|
|
6
|
+
import { rebaseCollectionsPlugin } from "@rebasepro/app/vitePlugin";
|
|
8
7
|
|
|
9
8
|
export default defineConfig({
|
|
9
|
+
envDir: path.resolve(__dirname, ".."),
|
|
10
|
+
// Force a single copy of React and React Router across the app and all
|
|
11
|
+
// @rebasepro/* packages. Without this, a locally `link:`ed Rebase checkout
|
|
12
|
+
// resolves its own copies of react-router, producing "multiple copies of
|
|
13
|
+
// React" and "useBlocker must be used within a data router" errors in the
|
|
14
|
+
// admin. Safe to keep for npm-installed setups too.
|
|
15
|
+
resolve: {
|
|
16
|
+
dedupe: [
|
|
17
|
+
"react",
|
|
18
|
+
"react-dom",
|
|
19
|
+
"react-router",
|
|
20
|
+
"react-router-dom",
|
|
21
|
+
"@remix-run/router"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
10
24
|
esbuild: {
|
|
11
25
|
logOverride: { "this-is-undefined-in-esm": "silent" }
|
|
12
26
|
},
|
|
@@ -19,7 +33,7 @@ export default defineConfig({
|
|
|
19
33
|
output: {
|
|
20
34
|
manualChunks(id) {
|
|
21
35
|
// Heavy vendor libraries — split into individually cached chunks
|
|
22
|
-
if (id.includes("
|
|
36
|
+
if (id.includes("exceljs")) return "vendor-exceljs";
|
|
23
37
|
if (id.includes("prosemirror")) return "vendor-prosemirror";
|
|
24
38
|
if (id.includes("monaco-editor") || id.includes("@monaco-editor")) return "vendor-monaco";
|
|
25
39
|
if (id.includes("@xyflow") || id.includes("dagre")) return "vendor-xyflow";
|
|
@@ -4,25 +4,38 @@
|
|
|
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": "
|
|
10
|
-
"start": "
|
|
14
|
+
"build": "rebase build",
|
|
15
|
+
"start": "rebase start",
|
|
11
16
|
"db:generate": "rebase db generate --collections ../config/collections",
|
|
12
17
|
"db:migrate": "rebase db migrate",
|
|
13
|
-
"
|
|
18
|
+
"schema:introspect": "rebase schema introspect",
|
|
14
19
|
"db:push": "rebase db push --collections ../config/collections",
|
|
15
|
-
"db:studio": "rebase db studio",
|
|
16
20
|
"schema:generate": "rebase schema generate --collections ../config/collections",
|
|
17
21
|
"generate:sdk": "rebase generate-sdk",
|
|
18
|
-
"
|
|
22
|
+
"skills:install": "rebase skills install",
|
|
23
|
+
"deploy": "rebase build && rebase start"
|
|
19
24
|
},
|
|
20
25
|
"devDependencies": {
|
|
21
26
|
"@rebasepro/cli": "workspace:*",
|
|
27
|
+
"@rebasepro/types": "workspace:*",
|
|
22
28
|
"concurrently": "^8.2.2",
|
|
23
29
|
"typescript": "^5.9.2"
|
|
24
30
|
},
|
|
25
31
|
"engines": {
|
|
26
32
|
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"pnpm": {
|
|
35
|
+
"onlyBuiltDependencies": [
|
|
36
|
+
"esbuild",
|
|
37
|
+
"sharp",
|
|
38
|
+
"@ariga/atlas"
|
|
39
|
+
]
|
|
27
40
|
}
|
|
28
41
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Scripts run OUTSIDE the server and need explicit authentication.
|
|
5
5
|
* Use a Service Key (set in .env as REBASE_SERVICE_KEY) to get admin
|
|
6
|
-
* access — similar to a
|
|
6
|
+
* access — similar to a Service Account credential.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
9
|
* # With local dev server running (`pnpm dev` in another terminal):
|
|
@@ -75,7 +75,10 @@ async function run() {
|
|
|
75
75
|
|
|
76
76
|
try {
|
|
77
77
|
// Example: Check backend health
|
|
78
|
-
const
|
|
78
|
+
const res = await fetch(`${baseUrl}/health`);
|
|
79
|
+
const health = res.headers.get("content-type")?.includes("application/json")
|
|
80
|
+
? await res.json()
|
|
81
|
+
: { status: res.status, text: await res.text() };
|
|
79
82
|
console.log("✅ Backend health:", health);
|
|
80
83
|
|
|
81
84
|
// Example: Fetch some data (requires auth if backend is secure-by-default)
|