@rebasepro/cli 0.0.1-canary.eae7889 → 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 +39 -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 +3785 -990
- 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 +11 -11
- 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 +15 -35
- 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 +26 -105
- 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 +47 -4
- package/templates/template/package.json +22 -8
- 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 -1203
- 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 -22
|
@@ -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,125 +1,46 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
|
|
3
3
|
import "@fontsource/jetbrains-mono";
|
|
4
|
-
import "
|
|
4
|
+
import "@fontsource/rubik";
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from "@rebasepro/
|
|
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 } from "@rebasepro/app";
|
|
7
|
+
import { Rebase, RebaseAuth } from "@rebasepro/app";
|
|
8
|
+
import { RebaseAdmin, RebaseShell } from "@rebasepro/admin";
|
|
9
|
+
import { ErrorBoundary } from "@rebasepro/ui";
|
|
10
|
+
import { RebaseStudio } from "@rebasepro/studio";
|
|
32
11
|
import { createRebaseClient } from "@rebasepro/client";
|
|
12
|
+
import { collections } from "virtual:rebase-collections";
|
|
33
13
|
|
|
34
14
|
// Configuration from environment
|
|
35
15
|
const API_URL = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? "http://localhost:3001" : undefined);
|
|
36
16
|
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
|
|
37
17
|
|
|
38
18
|
export function App() {
|
|
39
|
-
const modeController = useBuildModeController();
|
|
40
|
-
const userConfigPersistence = useBuildLocalConfigurationPersistence();
|
|
41
|
-
|
|
42
19
|
const rebaseClient = React.useMemo(() => createRebaseClient({
|
|
43
|
-
baseUrl: API_URL
|
|
44
|
-
|
|
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" }
|
|
24
|
+
}), []);
|
|
45
25
|
|
|
46
26
|
const authController = useRebaseAuthController({
|
|
47
27
|
client: rebaseClient,
|
|
48
28
|
googleClientId: GOOGLE_CLIENT_ID
|
|
49
29
|
});
|
|
50
30
|
|
|
51
|
-
const userManagement = useBackendUserManagement({
|
|
52
|
-
client: rebaseClient,
|
|
53
|
-
currentUser: authController.user
|
|
54
|
-
});
|
|
55
|
-
|
|
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
31
|
return (
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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>
|
|
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>
|
|
124
45
|
);
|
|
125
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
|
}
|