@rebasepro/cli 0.0.1-canary.2 → 0.0.1-canary.4829d6e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -196
- package/README.md +57 -33
- package/dist/commands/api-keys.d.ts +1 -0
- package/dist/commands/auth.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/db.d.ts +1 -0
- package/dist/commands/dev.d.ts +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/generate_sdk.d.ts +18 -0
- package/dist/commands/init.d.ts +40 -0
- package/dist/commands/schema.d.ts +1 -0
- package/dist/commands/skills.d.ts +1 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.es.js +3952 -245
- package/dist/index.es.js.map +1 -1
- package/dist/utils/package-manager.d.ts +33 -0
- package/dist/utils/project.d.ts +60 -0
- package/package.json +35 -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 +28 -0
- 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 +88 -21
- package/templates/template/ai-instructions.md +17 -0
- package/templates/template/backend/Dockerfile +57 -11
- package/templates/template/backend/functions/hello.ts +56 -0
- package/templates/template/backend/package.json +30 -34
- package/templates/template/backend/src/env.ts +23 -0
- package/templates/template/backend/src/index.ts +140 -100
- package/templates/template/backend/tsconfig.json +1 -1
- package/templates/template/config/collections/authors.ts +45 -0
- package/templates/template/config/collections/index.ts +26 -0
- package/templates/template/{shared → config}/collections/posts.ts +28 -10
- 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 +25 -0
- package/templates/template/config/collections/users.ts +142 -0
- package/templates/template/{shared → config}/index.ts +1 -1
- package/templates/template/config/package.json +28 -0
- package/templates/template/docker-compose.yml +50 -14
- package/templates/template/frontend/Dockerfile +39 -15
- package/templates/template/frontend/nginx.conf +40 -0
- package/templates/template/frontend/package.json +13 -13
- package/templates/template/frontend/src/App.tsx +30 -116
- package/templates/template/frontend/src/index.css +15 -1
- package/templates/template/frontend/src/main.tsx +6 -2
- 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 +48 -5
- package/templates/template/package.json +21 -12
- package/templates/template/pnpm-workspace.yaml +13 -0
- package/templates/template/scripts/example.ts +94 -0
- package/dist/auth.d.ts +0 -5
- package/dist/index.cjs +0 -293
- package/dist/index.cjs.map +0 -1
- package/templates/template/.env.template +0 -31
- package/templates/template/backend/drizzle.config.ts +0 -22
- package/templates/template/backend/scripts/db-generate.ts +0 -60
- package/templates/template/shared/collections/index.ts +0 -3
- package/templates/template/shared/package.json +0 -28
- /package/templates/template/{shared → config}/tsconfig.json +0 -0
|
@@ -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;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}-config",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared collections for frontend and backend",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"private": true,
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"clean": "rm -rf dist"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@rebasepro/types": "workspace:*"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.9.2"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,48 +1,84 @@
|
|
|
1
|
-
|
|
1
|
+
# ─── Rebase — Production Docker Compose ──────────────────────────────
|
|
2
|
+
#
|
|
3
|
+
# Quick start:
|
|
4
|
+
# cp .env.example .env # Edit with your secrets
|
|
5
|
+
# docker compose up -d # Start everything
|
|
6
|
+
#
|
|
7
|
+
# This runs:
|
|
8
|
+
# 1. PostgreSQL 18 with persistent data
|
|
9
|
+
# 2. Backend (Node.js / Hono) with health checks
|
|
10
|
+
# 3. Frontend (nginx) serving the Vite build
|
|
11
|
+
#
|
|
12
|
+
# For development, use `rebase dev` instead.
|
|
13
|
+
# ─────────────────────────────────────────────────────────────────────
|
|
2
14
|
|
|
3
15
|
services:
|
|
16
|
+
# ── PostgreSQL ───────────────────────────────────────────────────────
|
|
4
17
|
db:
|
|
5
18
|
image: postgres:18-alpine
|
|
19
|
+
restart: unless-stopped
|
|
6
20
|
environment:
|
|
7
21
|
POSTGRES_USER: rebase
|
|
8
|
-
POSTGRES_PASSWORD: ${
|
|
22
|
+
POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-changeme}
|
|
9
23
|
POSTGRES_DB: rebase
|
|
10
24
|
ports:
|
|
11
25
|
- "5432:5432"
|
|
12
26
|
volumes:
|
|
13
|
-
- postgres_data:/var/lib/postgresql
|
|
27
|
+
- postgres_data:/var/lib/postgresql
|
|
14
28
|
healthcheck:
|
|
15
|
-
test: ["CMD-SHELL", "pg_isready -U rebase"]
|
|
29
|
+
test: ["CMD-SHELL", "pg_isready -U rebase -d rebase"]
|
|
16
30
|
interval: 5s
|
|
17
31
|
timeout: 5s
|
|
18
|
-
retries:
|
|
32
|
+
retries: 10
|
|
33
|
+
start_period: 10s
|
|
34
|
+
# Production tuning (adjust for your workload)
|
|
35
|
+
command:
|
|
36
|
+
- "postgres"
|
|
37
|
+
- "-c"
|
|
38
|
+
- "shared_buffers=256MB"
|
|
39
|
+
- "-c"
|
|
40
|
+
- "max_connections=100"
|
|
41
|
+
- "-c"
|
|
42
|
+
- "work_mem=4MB"
|
|
43
|
+
- "-c"
|
|
44
|
+
- "effective_cache_size=768MB"
|
|
45
|
+
- "-c"
|
|
46
|
+
- "log_min_duration_statement=1000"
|
|
19
47
|
|
|
48
|
+
# ── Backend ──────────────────────────────────────────────────────────
|
|
20
49
|
backend:
|
|
21
|
-
build:
|
|
50
|
+
build:
|
|
22
51
|
context: .
|
|
23
52
|
dockerfile: backend/Dockerfile
|
|
53
|
+
restart: unless-stopped
|
|
24
54
|
ports:
|
|
25
|
-
- "3001:3001"
|
|
55
|
+
- "${PORT:-3001}:3001"
|
|
56
|
+
env_file: .env
|
|
26
57
|
environment:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
61
|
+
NODE_ENV: production
|
|
62
|
+
PORT: "3001"
|
|
30
63
|
depends_on:
|
|
31
64
|
db:
|
|
32
65
|
condition: service_healthy
|
|
33
66
|
volumes:
|
|
34
|
-
-
|
|
67
|
+
- uploads:/app/backend/uploads
|
|
35
68
|
|
|
69
|
+
# ── Frontend ─────────────────────────────────────────────────────────
|
|
36
70
|
frontend:
|
|
37
71
|
build:
|
|
38
72
|
context: .
|
|
39
73
|
dockerfile: frontend/Dockerfile
|
|
74
|
+
restart: unless-stopped
|
|
40
75
|
ports:
|
|
41
|
-
- "
|
|
42
|
-
environment:
|
|
43
|
-
- VITE_API_URL=http://localhost:3001
|
|
76
|
+
- "80:80"
|
|
44
77
|
depends_on:
|
|
45
78
|
- backend
|
|
46
79
|
|
|
47
80
|
volumes:
|
|
48
81
|
postgres_data:
|
|
82
|
+
driver: local
|
|
83
|
+
uploads:
|
|
84
|
+
driver: local
|
|
@@ -1,28 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
# ─── Multi-stage production Dockerfile for the Rebase frontend ────────
|
|
2
|
+
# Builds the Vite app, then serves via nginx for proper caching/compression.
|
|
3
|
+
#
|
|
4
|
+
# Build context: the project root (where pnpm-workspace.yaml lives)
|
|
5
|
+
# Usage:
|
|
6
|
+
# docker build -t my-app-frontend -f frontend/Dockerfile .
|
|
7
|
+
|
|
8
|
+
# ── Stage 1: Install + Build ─────────────────────────────────────────
|
|
9
|
+
FROM node:24-alpine AS builder
|
|
10
|
+
|
|
2
11
|
ENV PNPM_HOME="/pnpm"
|
|
3
12
|
ENV PATH="$PNPM_HOME:$PATH"
|
|
4
13
|
RUN corepack enable
|
|
14
|
+
|
|
5
15
|
RUN apk add --no-cache python3 make g++
|
|
6
16
|
|
|
7
17
|
WORKDIR /app
|
|
8
18
|
|
|
9
|
-
# Copy root
|
|
10
|
-
COPY package.json ./
|
|
19
|
+
# Copy workspace root files
|
|
20
|
+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
|
11
21
|
|
|
12
|
-
# Copy
|
|
22
|
+
# Copy workspace packages
|
|
13
23
|
COPY frontend ./frontend
|
|
14
|
-
COPY
|
|
24
|
+
COPY config ./config
|
|
25
|
+
|
|
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
|
|
30
|
+
|
|
31
|
+
# Build config first, then frontend
|
|
32
|
+
RUN pnpm --filter "*-config" run build
|
|
33
|
+
RUN pnpm --filter "*-frontend" run build
|
|
34
|
+
|
|
35
|
+
# ── Stage 2: Serve with nginx ────────────────────────────────────────
|
|
36
|
+
FROM nginx:1.27-alpine AS runtime
|
|
37
|
+
|
|
38
|
+
# Remove default nginx page
|
|
39
|
+
RUN rm -rf /usr/share/nginx/html/*
|
|
40
|
+
|
|
41
|
+
# Copy built assets
|
|
42
|
+
COPY --from=builder /app/frontend/dist /usr/share/nginx/html
|
|
15
43
|
|
|
16
|
-
#
|
|
17
|
-
|
|
44
|
+
# Custom nginx config for SPA routing + compression
|
|
45
|
+
COPY frontend/nginx.conf /etc/nginx/conf.d/default.conf
|
|
18
46
|
|
|
19
|
-
|
|
20
|
-
RUN pnpm run build:shared
|
|
21
|
-
RUN pnpm run build:frontend
|
|
47
|
+
EXPOSE 80
|
|
22
48
|
|
|
23
|
-
|
|
24
|
-
|
|
49
|
+
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
|
50
|
+
CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1
|
|
25
51
|
|
|
26
|
-
|
|
27
|
-
EXPOSE 5173
|
|
28
|
-
CMD ["serve", "-s", "dist", "-l", "5173"]
|
|
52
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
server {
|
|
2
|
+
listen 80;
|
|
3
|
+
server_name _;
|
|
4
|
+
|
|
5
|
+
root /usr/share/nginx/html;
|
|
6
|
+
index index.html;
|
|
7
|
+
|
|
8
|
+
# Gzip compression
|
|
9
|
+
gzip on;
|
|
10
|
+
gzip_vary on;
|
|
11
|
+
gzip_proxied any;
|
|
12
|
+
gzip_comp_level 6;
|
|
13
|
+
gzip_min_length 256;
|
|
14
|
+
gzip_types
|
|
15
|
+
text/plain
|
|
16
|
+
text/css
|
|
17
|
+
text/javascript
|
|
18
|
+
application/javascript
|
|
19
|
+
application/json
|
|
20
|
+
application/xml
|
|
21
|
+
image/svg+xml
|
|
22
|
+
font/woff2;
|
|
23
|
+
|
|
24
|
+
# Cache static assets aggressively (hashed filenames from Vite)
|
|
25
|
+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
26
|
+
expires 1y;
|
|
27
|
+
add_header Cache-Control "public, immutable";
|
|
28
|
+
try_files $uri =404;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# SPA fallback: serve index.html for all non-file routes
|
|
32
|
+
location / {
|
|
33
|
+
try_files $uri $uri/ /index.html;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Security headers
|
|
37
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
38
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
39
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
40
|
+
}
|
|
@@ -4,22 +4,21 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@rebasepro/
|
|
8
|
-
"@rebasepro/
|
|
9
|
-
"@rebasepro/
|
|
10
|
-
"@rebasepro/
|
|
11
|
-
"@rebasepro/
|
|
12
|
-
"@rebasepro/
|
|
13
|
-
"@rebasepro/
|
|
14
|
-
"@rebasepro/types": "^4.0.0",
|
|
15
|
-
"@rebasepro/ui": "^4.0.0",
|
|
7
|
+
"@rebasepro/app": "workspace:*",
|
|
8
|
+
"@rebasepro/plugin-ai": "workspace:*",
|
|
9
|
+
"@rebasepro/client": "workspace:*",
|
|
10
|
+
"@rebasepro/admin": "workspace:*",
|
|
11
|
+
"@rebasepro/studio": "workspace:*",
|
|
12
|
+
"@rebasepro/types": "workspace:*",
|
|
13
|
+
"@rebasepro/ui": "workspace:*",
|
|
16
14
|
"@fontsource/jetbrains-mono": "^5.2.5",
|
|
17
|
-
"{{PROJECT_NAME}}-
|
|
15
|
+
"{{PROJECT_NAME}}-config": "*",
|
|
18
16
|
"react": "^19.0.0",
|
|
19
17
|
"react-dom": "^19.0.0",
|
|
20
18
|
"react-router": "^7.0.0",
|
|
21
19
|
"react-router-dom": "^7.0.0",
|
|
22
|
-
"
|
|
20
|
+
"react-compiler-runtime": "^1.0.0",
|
|
21
|
+
"@fontsource/rubik": "^5.2.5"
|
|
23
22
|
},
|
|
24
23
|
"scripts": {
|
|
25
24
|
"dev": "vite --mode development",
|
|
@@ -41,12 +40,13 @@
|
|
|
41
40
|
"devDependencies": {
|
|
42
41
|
"@tailwindcss/typography": "^0.5.16",
|
|
43
42
|
"@tailwindcss/vite": "^4.1.12",
|
|
43
|
+
"@types/node": "^20.19.41",
|
|
44
44
|
"@types/react": "^19.0.8",
|
|
45
45
|
"@types/react-dom": "^19.0.3",
|
|
46
|
-
"@vitejs/plugin-react": "^4.
|
|
46
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
47
47
|
"tailwindcss": "^4.1.3",
|
|
48
48
|
"typescript": "^5.9.2",
|
|
49
|
-
"vite": "^
|
|
49
|
+
"vite": "^6.4.3",
|
|
50
50
|
"vite-plugin-svgr": "^4.3.0"
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -1,132 +1,46 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
|
|
3
3
|
import "@fontsource/jetbrains-mono";
|
|
4
|
-
import "
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from "@rebasepro/
|
|
11
|
-
import {
|
|
12
|
-
AppBar,
|
|
13
|
-
CircularProgressCenter,
|
|
14
|
-
Drawer,
|
|
15
|
-
Rebase,
|
|
16
|
-
RebaseRoute,
|
|
17
|
-
ModeControllerProvider,
|
|
18
|
-
NotFoundPage,
|
|
19
|
-
Scaffold,
|
|
20
|
-
SideDialogs,
|
|
21
|
-
RebaseRoutes,
|
|
22
|
-
SnackbarProvider,
|
|
23
|
-
ContentHomePage,
|
|
24
|
-
useBackendStorageSource,
|
|
25
|
-
useBuildCMSUrlController,
|
|
26
|
-
useBuildCollectionRegistryController,
|
|
27
|
-
useBuildLocalConfigurationPersistence,
|
|
28
|
-
useBuildModeController,
|
|
29
|
-
useBuildNavigationStateController
|
|
30
|
-
} from "@rebasepro/core";
|
|
31
|
-
import { usePostgresClientDataSource } from "@rebasepro/postgresql";
|
|
4
|
+
import "@fontsource/rubik";
|
|
5
|
+
|
|
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";
|
|
11
|
+
import { createRebaseClient } from "@rebasepro/client";
|
|
32
12
|
import { collections } from "virtual:rebase-collections";
|
|
33
|
-
import { Route, Outlet } from "react-router-dom";
|
|
34
13
|
|
|
35
14
|
// Configuration from environment
|
|
36
|
-
const API_URL = import.meta.env.VITE_API_URL || "http://localhost:3001";
|
|
15
|
+
const API_URL = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? "http://localhost:3001" : undefined);
|
|
37
16
|
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
|
|
38
17
|
|
|
39
18
|
export function App() {
|
|
40
|
-
const
|
|
41
|
-
|
|
19
|
+
const rebaseClient = React.useMemo(() => createRebaseClient({
|
|
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
|
+
}), []);
|
|
42
25
|
|
|
43
26
|
const authController = useRebaseAuthController({
|
|
44
|
-
|
|
27
|
+
client: rebaseClient,
|
|
45
28
|
googleClientId: GOOGLE_CLIENT_ID
|
|
46
29
|
});
|
|
47
30
|
|
|
48
|
-
const storageSource = useBackendStorageSource({
|
|
49
|
-
apiUrl: API_URL,
|
|
50
|
-
getAuthToken: authController.getAuthToken
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const userManagement = useBackendUserManagement({
|
|
54
|
-
apiUrl: API_URL,
|
|
55
|
-
getAuthToken: authController.getAuthToken,
|
|
56
|
-
currentUser: authController.user
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const postgresDelegate = usePostgresClientDataSource({
|
|
60
|
-
websocketUrl: API_URL.replace(/^http/, "ws"),
|
|
61
|
-
getAuthToken: authController.initialLoading ? undefined : authController.getAuthToken
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const collectionsBuilder = useCallback(() => {
|
|
65
|
-
return [...collections];
|
|
66
|
-
}, []);
|
|
67
|
-
|
|
68
|
-
const collectionRegistryController = useBuildCollectionRegistryController({ userConfigPersistence });
|
|
69
|
-
const cmsUrlController = useBuildCMSUrlController({
|
|
70
|
-
basePath: "/",
|
|
71
|
-
baseCollectionPath: "/c",
|
|
72
|
-
collectionRegistryController
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const navigationStateController = useBuildNavigationStateController({
|
|
76
|
-
collections: collectionsBuilder,
|
|
77
|
-
authController,
|
|
78
|
-
dataSource: postgresDelegate,
|
|
79
|
-
collectionRegistryController,
|
|
80
|
-
cmsUrlController,
|
|
81
|
-
userManagement
|
|
82
|
-
});
|
|
83
|
-
|
|
84
31
|
return (
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return <CircularProgressCenter />;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!authController.user) {
|
|
102
|
-
return (
|
|
103
|
-
<RebaseLoginView
|
|
104
|
-
authController={authController}
|
|
105
|
-
googleEnabled={!!GOOGLE_CLIENT_ID}
|
|
106
|
-
googleClientId={GOOGLE_CLIENT_ID}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<RebaseRoutes>
|
|
113
|
-
<Route element={
|
|
114
|
-
<Scaffold autoOpenDrawer={false}>
|
|
115
|
-
<AppBar />
|
|
116
|
-
<Drawer />
|
|
117
|
-
<Outlet />
|
|
118
|
-
<SideDialogs />
|
|
119
|
-
</Scaffold>
|
|
120
|
-
}>
|
|
121
|
-
<Route path={"/"} element={<ContentHomePage />} />
|
|
122
|
-
<Route path={"/c/*"} element={<RebaseRoute />} />
|
|
123
|
-
<Route path={"*"} element={<NotFoundPage />} />
|
|
124
|
-
</Route>
|
|
125
|
-
</RebaseRoutes>
|
|
126
|
-
);
|
|
127
|
-
}}
|
|
128
|
-
</Rebase>
|
|
129
|
-
</ModeControllerProvider>
|
|
130
|
-
</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>
|
|
131
45
|
);
|
|
132
46
|
}
|
|
@@ -1,2 +1,16 @@
|
|
|
1
1
|
@import "tailwindcss";
|
|
2
|
-
@import "@rebasepro/ui/index.css";
|
|
2
|
+
@import "@rebasepro/ui/index.css" layer(base);
|
|
3
|
+
|
|
4
|
+
@source "../node_modules/@rebasepro";
|
|
5
|
+
|
|
6
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
7
|
+
|
|
8
|
+
@layer utilities {
|
|
9
|
+
body {
|
|
10
|
+
@apply w-full min-h-screen bg-surface-50 dark:bg-surface-900 flex flex-col items-center justify-center;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
a {
|
|
14
|
+
@apply text-primary dark:text-primary;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -4,15 +4,19 @@ 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: "/*",
|
|
10
|
-
element: <App
|
|
14
|
+
element: <App/>
|
|
11
15
|
}
|
|
12
16
|
]);
|
|
13
17
|
|
|
14
18
|
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
|
15
19
|
<React.StrictMode>
|
|
16
|
-
<RouterProvider router={router}
|
|
20
|
+
<RouterProvider router={router}/>
|
|
17
21
|
</React.StrictMode>
|
|
18
22
|
);
|
|
@@ -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
|
}
|