@rebasepro/cli 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/LICENSE +17 -196
  2. package/dist/index.cjs +158 -44
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.es.js +142 -28
  5. package/dist/index.es.js.map +1 -1
  6. package/package.json +13 -11
  7. package/templates/template/.cursorrules +2 -0
  8. package/templates/template/.env.example +7 -0
  9. package/templates/template/.github/copilot-instructions.md +2 -0
  10. package/templates/template/.windsurfrules +2 -0
  11. package/templates/template/README.md +2 -2
  12. package/templates/template/ai-instructions.md +14 -0
  13. package/templates/template/backend/Dockerfile +1 -1
  14. package/templates/template/backend/drizzle.config.ts +11 -5
  15. package/templates/template/backend/package.json +4 -3
  16. package/templates/template/backend/src/env.ts +2 -43
  17. package/templates/template/backend/src/index.ts +10 -12
  18. package/templates/template/config/collections/index.ts +6 -4
  19. package/templates/template/config/collections/posts.ts +3 -17
  20. package/templates/template/config/collections/roles.ts +72 -0
  21. package/templates/template/config/collections/users.ts +141 -0
  22. package/templates/template/config/index.ts +1 -1
  23. package/templates/template/config/package.json +2 -1
  24. package/templates/template/docker-compose.yml +1 -1
  25. package/templates/template/frontend/package.json +3 -1
  26. package/templates/template/frontend/src/App.tsx +3 -3
  27. package/templates/template/frontend/src/virtual.d.ts +6 -0
  28. package/templates/template/frontend/tsconfig.json +3 -2
  29. package/templates/template/frontend/vite.config.ts +1 -1
  30. package/templates/template/pnpm-workspace.yaml +6 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebasepro/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Developer tools for Rebase projects",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.es.js",
@@ -26,20 +26,21 @@
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
28
  "arg": "^5.0.2",
29
- "chalk": "^4.1.2",
30
- "dotenv": "^16.0.0",
31
- "execa": "^4.1.0",
29
+ "chalk": "^5.6.2",
30
+ "dotenv": "^16.6.1",
31
+ "execa": "^9.6.1",
32
32
  "inquirer": "12.11.1",
33
- "ncp": "^2.0.0",
34
- "pnpm": "^9.0.0",
35
- "@rebasepro/sdk-generator": "0.1.0",
36
- "@rebasepro/types": "0.1.0",
37
- "@rebasepro/server-core": "0.1.0"
33
+ "jiti": "^2.7.0",
34
+ "@rebasepro/sdk-generator": "0.2.1",
35
+ "@rebasepro/server-core": "0.2.1",
36
+ "@rebasepro/types": "0.2.1"
38
37
  },
39
38
  "devDependencies": {
40
- "@types/node": "^20.19.17",
39
+ "@types/node": "^20.19.41",
40
+ "@types/pg": "^8.20.0",
41
+ "pg": "^8.21.0",
41
42
  "typescript": "^5.9.3",
42
- "vite": "^7.2.4",
43
+ "vite": "^7.3.3",
43
44
  "vitest": "4.1.5"
44
45
  },
45
46
  "files": [
@@ -61,6 +62,7 @@
61
62
  "gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6",
62
63
  "scripts": {
63
64
  "test": "vitest run",
65
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
64
66
  "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.json",
65
67
  "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
66
68
  }
@@ -0,0 +1,2 @@
1
+ # Rebase AI Rules
2
+ Please refer to and follow the instructions defined in [ai-instructions.md](./ai-instructions.md).
@@ -22,6 +22,8 @@ DATABASE_URL=postgresql://rebase:changeme@localhost:5432/rebase
22
22
  # ── Server ────────────────────────────────────────────────────────────────────
23
23
  PORT=3001
24
24
  NODE_ENV=development
25
+ # Allow connecting to localhost / 127.0.0.1 in production mode (for local testing of prod builds)
26
+ # ALLOW_LOCALHOST_IN_PRODUCTION=false
25
27
 
26
28
  # ── Logging ───────────────────────────────────────────────────────────────────
27
29
  # Levels: error, warn, info, debug
@@ -94,3 +96,8 @@ VITE_API_URL=http://localhost:3001
94
96
  # When set, scripts authenticate with: Authorization: Bearer <key>
95
97
  # Generate with: node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
96
98
  # REBASE_SERVICE_KEY=
99
+
100
+ # Disable switching to database-level roles (e.g. 'admin') for Studio SQL execution (optional)
101
+ # Falls back to false. Useful for databases with application-only roles or managed setups.
102
+ # DISABLE_DB_ROLE_SWITCHING=true
103
+
@@ -0,0 +1,2 @@
1
+ # Rebase AI Rules
2
+ Please refer to and follow the instructions defined in [ai-instructions.md](../ai-instructions.md).
@@ -0,0 +1,2 @@
1
+ # Rebase AI Rules
2
+ Please refer to and follow the instructions defined in [ai-instructions.md](./ai-instructions.md).
@@ -44,8 +44,8 @@ cp .env.example .env
44
44
  3. Generate schema and push to database:
45
45
 
46
46
  ```bash
47
- rebase schema generate
48
- rebase db push
47
+ pnpm run schema:generate # or: npm run schema:generate
48
+ pnpm run db:push # or: npm run db:push
49
49
  ```
50
50
 
51
51
  4. Start the dev server:
@@ -0,0 +1,14 @@
1
+ # Rebase AI Coding Rules
2
+
3
+ For the most up-to-date, comprehensive guidelines, architecture details, SDK APIs, and troubleshooting guides, please refer to the official Rebase LLM documentation:
4
+ 👉 https://rebase.pro/llms.txt
5
+
6
+ If you are running in an agentic environment (like Antigravity or a Gemini CLI extension), the assistant will automatically load the active Rebase agent skills.
7
+
8
+ ## Core Tenets (Quick Reference)
9
+
10
+ 1. **Schema-as-Code**: Always define or edit collections in `config/collections/` (e.g., `config/collections/posts.ts`). Never modify generated Drizzle schemas or PostgreSQL tables manually.
11
+ 2. **Two-Step Migrations**:
12
+ - Step 1: Run `rebase schema generate` to compile collections to the Drizzle schema.
13
+ - Step 2: Run `rebase db push` (development) or `rebase db generate && rebase db migrate` (production) to apply schema changes to the database.
14
+ 3. **Use the SDK**: Always use the Rebase SDK (`rebase.data.<slug>`) to fetch or modify data. Bypassing it with raw SQL or direct Drizzle/PG queries circumvents model validations, lifecycle hooks, and Row-Level Security (RLS).
@@ -33,7 +33,7 @@ RUN pnpm --filter "*-config" run build
33
33
  RUN pnpm --filter "*-backend" run build
34
34
 
35
35
  # Prune dev dependencies for a smaller runtime
36
- RUN pnpm install --frozen-lockfile --prod
36
+ RUN CI=true pnpm install --frozen-lockfile --prod
37
37
 
38
38
  # ── Stage 2: Production Runtime ──────────────────────────────────────
39
39
  FROM node:22-alpine AS runtime
@@ -3,7 +3,8 @@ import path from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  import { defineConfig } from "drizzle-kit";
5
5
  import { tables } from "./src/schema.generated";
6
- import { getTableName, Table } from "drizzle-orm";
6
+ import { getTableName } from "drizzle-orm";
7
+ import { getTableConfig, PgTable } from "drizzle-orm/pg-core";
7
8
 
8
9
  const __filename = fileURLToPath(import.meta.url);
9
10
  const __dirname = path.dirname(__filename);
@@ -18,7 +19,13 @@ if (!process.env.DATABASE_URL) {
18
19
  // Extract table names from the generated schema.
19
20
  // This ensures drizzle-kit ONLY manages tables defined in the schema.
20
21
  // Any tables in the database that are NOT part of the Rebase schema are left untouched.
21
- const tableNames = Object.values(tables).map(table => getTableName(table as Table));
22
+ const tableNames = Object.values(tables).map(table => getTableName(table as PgTable));
23
+
24
+ // Dynamically extract all schemas defined in the generated tables to ensure Drizzle Kit manages them.
25
+ const schemas = Array.from(new Set(
26
+ Object.values(tables)
27
+ .map(table => getTableConfig(table as PgTable).schema || "public")
28
+ ));
22
29
 
23
30
  export default defineConfig({
24
31
  schema: "./src/schema.generated.ts",
@@ -30,9 +37,8 @@ export default defineConfig({
30
37
  // Only manage tables defined in the generated schema.
31
38
  // Unmapped tables in the database are completely ignored.
32
39
  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"],
40
+ // Restrict drizzle-kit to the schemas defined in our collections
41
+ schemaFilter: schemas.length > 0 ? schemas : ["public"],
36
42
  // Prevent drizzle-kit from managing roles not defined in the schema
37
43
  entities: {
38
44
  roles: false
@@ -6,19 +6,20 @@
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "dev": "tsx watch --watch=\"../config/**/*\" src/index.ts",
9
- "build": "tsc --noEmit",
10
- "start": "tsx src/index.ts"
9
+ "build": "rebase schema generate --collections ../config/collections && tsc",
10
+ "start": "node dist/backend/src/index.js"
11
11
  },
12
12
  "dependencies": {
13
13
  "{{PROJECT_NAME}}-config": "*",
14
14
  "@rebasepro/server-core": "workspace:*",
15
15
  "@rebasepro/server-postgresql": "workspace:*",
16
+ "@rebasepro/admin": "workspace:*",
16
17
  "drizzle-orm": "^0.44.4",
17
18
  "hono": "^4.12.10",
18
19
  "@hono/node-server": "^1.19.12",
19
20
  "pg": "^8.11.3",
20
21
  "ws": "^8.16.0",
21
- "zod": "^3.22.4",
22
+ "react-compiler-runtime": "^1.0.0",
22
23
  "dotenv": "^16.0.0"
23
24
  },
24
25
  "devDependencies": {
@@ -1,52 +1,11 @@
1
- import { z } from "zod";
2
1
  import * as dotenv from "dotenv";
3
2
  import path from "path";
4
3
  import { fileURLToPath } from "url";
4
+ import { loadEnv } from "@rebasepro/server-core";
5
5
 
6
6
  const __filename = fileURLToPath(import.meta.url);
7
7
  const __dirname = path.dirname(__filename);
8
8
 
9
9
  dotenv.config({ path: path.resolve(__dirname, "../../.env") });
10
10
 
11
- const envSchema = z.object({
12
- NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
13
- PORT: z.string().default("3001").transform(Number),
14
- DATABASE_URL: z.string().url("DATABASE_URL must be a valid URL"),
15
- ADMIN_CONNECTION_STRING: z.string().url().optional(),
16
- JWT_SECRET: z.string().min(32, "JWT_SECRET must be at least 32 characters long"),
17
- JWT_ACCESS_EXPIRES_IN: z.string().default("1h"),
18
- JWT_REFRESH_EXPIRES_IN: z.string().default("30d"),
19
- GOOGLE_CLIENT_ID: z.string().optional(),
20
- ALLOW_REGISTRATION: z.enum(["true", "false", ""]).default("false").transform(v => v === "true"),
21
- CORS_ORIGINS: z.string().optional(),
22
- FRONTEND_URL: z.string().optional(),
23
- DB_POOL_MAX: z.string().default("20").transform(Number),
24
- DB_POOL_IDLE_TIMEOUT: z.string().default("30000").transform(Number),
25
- DB_POOL_CONNECT_TIMEOUT: z.string().default("10000").transform(Number),
26
- FORCE_LOCAL_STORAGE: z.enum(["true", "false", ""]).optional().transform(v => v === "true"),
27
- STORAGE_TYPE: z.enum(["local", "s3"]).default("local"),
28
- STORAGE_PATH: z.string().optional(),
29
- S3_BUCKET: z.string().optional(),
30
- S3_REGION: z.string().optional(),
31
- S3_ACCESS_KEY_ID: z.string().optional(),
32
- S3_SECRET_ACCESS_KEY: z.string().optional(),
33
- S3_ENDPOINT: z.string().url().optional(),
34
- S3_FORCE_PATH_STYLE: z.enum(["true", "false", ""]).optional().transform(v => v === "true"),
35
- /**
36
- * Service key for admin-level script / server-to-server authentication.
37
- * When set, scripts can send `Authorization: Bearer <key>` to get admin access.
38
- * Generate with: node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
39
- */
40
- REBASE_SERVICE_KEY: z.string().min(32, "REBASE_SERVICE_KEY must be at least 32 characters").optional()
41
- }).superRefine((data, ctx) => {
42
- if (data.NODE_ENV === "production" && !data.CORS_ORIGINS && !data.FRONTEND_URL) {
43
- ctx.addIssue({
44
- code: z.ZodIssueCode.custom,
45
- message: "CORS_ORIGINS or FRONTEND_URL must be set in production to secure the API.",
46
- path: ["CORS_ORIGINS"]
47
- });
48
- }
49
- });
50
-
51
- // Parse and export
52
- export const env = envSchema.parse(process.env);
11
+ export const env = loadEnv();
@@ -13,15 +13,15 @@ import {
13
13
  cleanupDevPortFile,
14
14
  logger
15
15
  } from "@rebasepro/server-core";
16
- import { createPostgresDatabaseConnection, createPostgresBootstrapper } from "@rebasepro/server-postgresql";
17
- import { enums, relations, tables } from "./schema.generated";
18
- import { env } from "./env";
16
+ import { createPostgresDatabaseConnection, createPostgresAdapter } from "@rebasepro/server-postgresql";
17
+ import { enums, relations, tables } from "./schema.generated.js";
18
+ import { env } from "./env.js";
19
19
 
20
20
  const __filename = fileURLToPath(import.meta.url);
21
21
  const __dirname = path.dirname(__filename);
22
22
 
23
23
  // ─── App ─────────────────────────────────────────────────────────────
24
- const app = new Hono<HonoEnv>();
24
+ const app: Hono<HonoEnv> = new Hono<HonoEnv>();
25
25
 
26
26
  const isProduction = env.NODE_ENV === "production";
27
27
  const allowedOrigins = isProduction
@@ -54,16 +54,14 @@ async function startServer() {
54
54
  functionsDir: path.resolve(__dirname, "../functions"),
55
55
  server,
56
56
  app,
57
- bootstrappers: [
58
- createPostgresBootstrapper({
59
- connection: db,
60
- schema: { tables,
57
+ database: createPostgresAdapter({
58
+ connection: db,
59
+ schema: { tables,
61
60
  enums,
62
61
  relations },
63
- adminConnectionString: env.ADMIN_CONNECTION_STRING || databaseUrl,
64
- connectionString
65
- })
66
- ],
62
+ adminConnectionString: env.ADMIN_CONNECTION_STRING || databaseUrl,
63
+ connectionString
64
+ }),
67
65
  auth: {
68
66
  jwtSecret,
69
67
  accessExpiresIn: env.JWT_ACCESS_EXPIRES_IN,
@@ -1,5 +1,7 @@
1
- import postsCollection from "./posts";
2
- import authorsCollection from "./authors";
3
- import tagsCollection from "./tags";
1
+ import postsCollection from "./posts.js";
2
+ import authorsCollection from "./authors.js";
3
+ import tagsCollection from "./tags.js";
4
+ import usersCollection from "./users.js";
5
+ import rolesCollection from "./roles.js";
4
6
 
5
- export const collections = [postsCollection, authorsCollection, tagsCollection];
7
+ export const collections = [postsCollection, authorsCollection, tagsCollection, usersCollection, rolesCollection];
@@ -1,6 +1,6 @@
1
1
  import { EntityCollection } from "@rebasepro/types";
2
- import authorsCollection from "./authors";
3
- import tagsCollection from "./tags";
2
+ import authorsCollection from "./authors.js";
3
+ import tagsCollection from "./tags.js";
4
4
 
5
5
  const postsCollection: EntityCollection = {
6
6
  name: "Posts",
@@ -71,21 +71,7 @@ const postsCollection: EntityCollection = {
71
71
  target: () => tagsCollection
72
72
  }
73
73
  }
74
- },
75
- relations: [
76
- {
77
- relationName: "author",
78
- target: () => authorsCollection,
79
- cardinality: "one",
80
- direction: "owning"
81
- },
82
- {
83
- relationName: "tags",
84
- target: () => tagsCollection,
85
- cardinality: "many",
86
- direction: "owning"
87
- }
88
- ]
74
+ }
89
75
  };
90
76
 
91
77
  export default postsCollection;
@@ -0,0 +1,72 @@
1
+ import { PostgresCollection, EntityCollection } from "@rebasepro/types";
2
+
3
+ const rolesCollection: PostgresCollection = {
4
+ name: "Roles",
5
+ singularName: "Role",
6
+ slug: "roles",
7
+ table: "roles",
8
+ schema: "rebase",
9
+ icon: "Shield",
10
+ group: "Settings",
11
+ properties: {
12
+ id: {
13
+ name: "ID",
14
+ type: "string",
15
+ isId: "manual",
16
+ validation: {
17
+ required: true
18
+ }
19
+ },
20
+ name: {
21
+ name: "Name",
22
+ type: "string",
23
+ validation: {
24
+ required: true
25
+ }
26
+ },
27
+ isAdmin: {
28
+ name: "Is Admin",
29
+ type: "boolean",
30
+ columnName: "is_admin",
31
+ defaultValue: false
32
+ },
33
+ defaultPermissions: {
34
+ name: "Default Permissions",
35
+ type: "map",
36
+ columnName: "default_permissions",
37
+ properties: {
38
+ read: { name: "Read", type: "boolean" },
39
+ create: { name: "Create", type: "boolean" },
40
+ edit: { name: "Edit", type: "boolean" },
41
+ delete: { name: "Delete", type: "boolean" }
42
+ }
43
+ },
44
+ collectionPermissions: {
45
+ name: "Collection Permissions",
46
+ type: "map",
47
+ columnName: "collection_permissions"
48
+ },
49
+ config: {
50
+ name: "Config",
51
+ type: "map",
52
+ columnName: "config",
53
+ properties: {
54
+ createCollections: { name: "Create Collections", type: "boolean" },
55
+ editCollections: { name: "Edit Collections", type: "string" },
56
+ deleteCollections: { name: "Delete Collections", type: "string" }
57
+ }
58
+ }
59
+ }
60
+ };
61
+
62
+ rolesCollection.securityRules = [
63
+ {
64
+ name: "roles_public_access",
65
+ mode: "permissive",
66
+ operation: "all",
67
+ pgRoles: ["public"],
68
+ using: "true"
69
+ }
70
+ ];
71
+
72
+ export default rolesCollection;
@@ -0,0 +1,141 @@
1
+ import { EntityCollection } from "@rebasepro/types";
2
+ import { resetPasswordAction, deleteEntityAction, RolesFilterSelect, UserRolesSelectField } from "@rebasepro/admin";
3
+ import rolesCollection from "./roles.js";
4
+
5
+ const usersCollection: EntityCollection = {
6
+ name: "Users",
7
+ singularName: "User",
8
+ slug: "users",
9
+ table: "users",
10
+ schema: "rebase",
11
+ icon: "Users",
12
+ group: "Settings",
13
+ openEntityMode: "dialog",
14
+ disableDefaultActions: ["copy"],
15
+ Actions: [RolesFilterSelect],
16
+ entityActions: [
17
+ resetPasswordAction,
18
+ {
19
+ ...deleteEntityAction,
20
+ collapsed: false
21
+ }
22
+ ],
23
+ sort: ["createdAt", "desc"],
24
+ properties: {
25
+ id: {
26
+ name: "ID",
27
+ type: "string",
28
+ isId: "uuid",
29
+ ui: {
30
+ readOnly: true
31
+ }
32
+ },
33
+ email: {
34
+ name: "Email",
35
+ type: "string",
36
+ validation: {
37
+ required: true,
38
+ unique: true
39
+ }
40
+ },
41
+ displayName: {
42
+ name: "Name",
43
+ type: "string",
44
+ validation: {
45
+ required: true
46
+ }
47
+ },
48
+ photoURL: {
49
+ name: "Photo URL",
50
+ type: "string",
51
+ url: "image"
52
+ },
53
+ roles: {
54
+ name: "Roles",
55
+ type: "relation",
56
+ target: () => rolesCollection,
57
+ cardinality: "many",
58
+ direction: "owning",
59
+ through: {
60
+ table: "user_roles",
61
+ sourceColumn: "user_id",
62
+ targetColumn: "role_id"
63
+ },
64
+ ui: {
65
+ Field: UserRolesSelectField
66
+ }
67
+ },
68
+ passwordHash: {
69
+ name: "Password Hash",
70
+ type: "string",
71
+ columnName: "password_hash",
72
+ ui: {
73
+ hideFromCollection: true,
74
+ disabled: { hidden: true }
75
+ }
76
+ },
77
+ emailVerified: {
78
+ name: "Email Verified",
79
+ type: "boolean",
80
+ columnName: "email_verified",
81
+ defaultValue: false,
82
+ ui: {
83
+ hideFromCollection: true,
84
+ disabled: { hidden: true }
85
+ }
86
+ },
87
+ emailVerificationToken: {
88
+ name: "Email Verification Token",
89
+ type: "string",
90
+ columnName: "email_verification_token",
91
+ ui: {
92
+ hideFromCollection: true,
93
+ disabled: { hidden: true }
94
+ }
95
+ },
96
+ emailVerificationSentAt: {
97
+ name: "Email Verification Sent At",
98
+ type: "date",
99
+ columnName: "email_verification_sent_at",
100
+ ui: {
101
+ hideFromCollection: true,
102
+ disabled: { hidden: true }
103
+ }
104
+ },
105
+ metadata: {
106
+ name: "Metadata",
107
+ type: "map",
108
+ defaultValue: {},
109
+ ui: {
110
+ hideFromCollection: true,
111
+ disabled: { hidden: true }
112
+ }
113
+ },
114
+ createdAt: {
115
+ name: "Created At",
116
+ type: "date",
117
+ ui: {
118
+ readOnly: true
119
+ }
120
+ },
121
+ updatedAt: {
122
+ name: "Updated At",
123
+ type: "date",
124
+ columnName: "updated_at",
125
+ autoValue: "on_update",
126
+ ui: {
127
+ hideFromCollection: true,
128
+ disabled: { hidden: true }
129
+ }
130
+ }
131
+ },
132
+ propertiesOrder: [
133
+ "id",
134
+ "email",
135
+ "displayName",
136
+ "roles",
137
+ "createdAt"
138
+ ]
139
+ };
140
+
141
+ export default usersCollection;
@@ -3,4 +3,4 @@
3
3
  * Collections defined here are used by both the frontend and backend
4
4
  */
5
5
 
6
- export { collections } from "./collections";
6
+ export { collections } from "./collections/index.js";
@@ -12,7 +12,8 @@
12
12
  "clean": "rm -rf dist"
13
13
  },
14
14
  "dependencies": {
15
- "@rebasepro/types": "workspace:*"
15
+ "@rebasepro/types": "workspace:*",
16
+ "@rebasepro/admin": "workspace:*"
16
17
  },
17
18
  "devDependencies": {
18
19
  "typescript": "^5.9.2"
@@ -15,7 +15,7 @@
15
15
  services:
16
16
  # ── PostgreSQL ───────────────────────────────────────────────────────
17
17
  db:
18
- image: postgres:18-alpine
18
+ image: postgres:16-alpine
19
19
  restart: unless-stopped
20
20
  environment:
21
21
  POSTGRES_USER: rebase
@@ -18,7 +18,8 @@
18
18
  "react-dom": "^19.0.0",
19
19
  "react-router": "^7.0.0",
20
20
  "react-router-dom": "^7.0.0",
21
- "typeface-rubik": "^1.1.13"
21
+ "react-compiler-runtime": "^1.0.0",
22
+ "@fontsource/rubik": "^5.2.5"
22
23
  },
23
24
  "scripts": {
24
25
  "dev": "vite --mode development",
@@ -40,6 +41,7 @@
40
41
  "devDependencies": {
41
42
  "@tailwindcss/typography": "^0.5.16",
42
43
  "@tailwindcss/vite": "^4.1.12",
44
+ "@types/node": "^20.19.41",
43
45
  "@types/react": "^19.0.8",
44
46
  "@types/react-dom": "^19.0.3",
45
47
  "@vitejs/plugin-react": "^4.3.4",
@@ -1,10 +1,10 @@
1
1
  import React from "react";
2
2
 
3
3
  import "@fontsource/jetbrains-mono";
4
- import "typeface-rubik";
4
+ import "@fontsource/rubik";
5
5
 
6
- import { useRebaseAuthController, useBackendUserManagement, RebaseAuth } from "@rebasepro/auth";
7
- import { Rebase } from "@rebasepro/core";
6
+ import { useRebaseAuthController, useBackendUserManagement } from "@rebasepro/auth";
7
+ import { Rebase, RebaseAuth } from "@rebasepro/core";
8
8
  import { RebaseCMS, RebaseShell } from "@rebasepro/admin";
9
9
  import { RebaseStudio } from "@rebasepro/studio";
10
10
  import { createRebaseClient } from "@rebasepro/client";
@@ -0,0 +1,6 @@
1
+ /// <reference types="vite/client" />
2
+ /// <reference types="vite-plugin-svgr/client" />
3
+
4
+ declare module "virtual:rebase-collections" {
5
+ export const collections: any[];
6
+ }
@@ -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": ["./src", "./vite.config.ts"]
20
+ "include": ["src/**/*", "vite.config.ts"]
20
21
  }
@@ -20,7 +20,7 @@ export default defineConfig({
20
20
  output: {
21
21
  manualChunks(id) {
22
22
  // Heavy vendor libraries — split into individually cached chunks
23
- if (id.includes("xlsx")) return "vendor-xlsx";
23
+ if (id.includes("exceljs")) return "vendor-exceljs";
24
24
  if (id.includes("prosemirror")) return "vendor-prosemirror";
25
25
  if (id.includes("monaco-editor") || id.includes("@monaco-editor")) return "vendor-monaco";
26
26
  if (id.includes("@xyflow") || id.includes("dagre")) return "vendor-xyflow";
@@ -2,3 +2,9 @@ packages:
2
2
  - "frontend"
3
3
  - "backend"
4
4
  - "config"
5
+ linkWorkspacePackages: true
6
+ blockExoticSubdeps: false
7
+ minimumReleaseAge: 0
8
+ allowBuilds:
9
+ esbuild: true
10
+