@rebasepro/cli 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,6 +35,21 @@ export declare function resolveLocalBin(projectRoot: string, binName: string): s
35
35
  * Resolve the tsx binary. Checks backend node_modules first, then root.
36
36
  */
37
37
  export declare function resolveTsx(projectRoot: string): string | null;
38
+ /**
39
+ * Validate that a resolved tsx binary actually has an intact installation.
40
+ *
41
+ * `resolveLocalBin` only checks whether `node_modules/.bin/tsx` (a symlink)
42
+ * exists. If the pnpm content-addressable store was cleaned or a previous
43
+ * install was interrupted, the symlink can exist while critical files inside
44
+ * the tsx package (e.g. `dist/preflight.cjs`) are missing — causing a
45
+ * confusing MODULE_NOT_FOUND error at runtime.
46
+ *
47
+ * This function follows the symlink, walks up to find the tsx package root
48
+ * (`package.json` with `name: "tsx"`), and verifies that `dist/preflight.cjs`
49
+ * is present. Returns `null` when the installation looks healthy, or an
50
+ * error description string when it appears corrupted.
51
+ */
52
+ export declare function validateTsxInstallation(tsxBinPath: string): string | null;
38
53
  /**
39
54
  * Require the project root or exit with a helpful error.
40
55
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebasepro/cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Developer tools for Rebase projects",
5
5
  "main": "./dist/index.es.js",
6
6
  "module": "./dist/index.es.js",
@@ -13,12 +13,6 @@
13
13
  "publishConfig": {
14
14
  "access": "public"
15
15
  },
16
- "scripts": {
17
- "test": "vitest run",
18
- "test:e2e": "vitest run --config vitest.e2e.config.ts",
19
- "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.json",
20
- "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
21
- },
22
16
  "keywords": [
23
17
  "cli",
24
18
  "create-rebase-app",
@@ -31,17 +25,17 @@
31
25
  "author": "rebase.pro",
32
26
  "license": "MIT",
33
27
  "dependencies": {
34
- "@rebasepro/agent-skills": "workspace:*",
35
- "@rebasepro/sdk-generator": "workspace:*",
36
- "@rebasepro/server-core": "workspace:*",
37
- "@rebasepro/server-postgresql": "workspace:*",
38
- "@rebasepro/types": "workspace:*",
39
28
  "arg": "^5.0.2",
40
29
  "chalk": "^5.6.2",
41
30
  "dotenv": "^17.4.2",
42
31
  "execa": "^9.6.1",
43
32
  "inquirer": "14.0.2",
44
- "jiti": "^2.7.0"
33
+ "jiti": "^2.7.0",
34
+ "@rebasepro/agent-skills": "0.8.0",
35
+ "@rebasepro/sdk-generator": "0.8.0",
36
+ "@rebasepro/server-postgresql": "0.8.0",
37
+ "@rebasepro/types": "0.8.0",
38
+ "@rebasepro/server-core": "0.8.0"
45
39
  },
46
40
  "devDependencies": {
47
41
  "@types/node": "^25.9.3",
@@ -67,10 +61,10 @@
67
61
  "url": "https://github.com/rebasepro/rebase.git",
68
62
  "directory": "packages/cli"
69
63
  },
70
- "pnpm": {
71
- "onlyBuiltDependencies": [
72
- "esbuild",
73
- "sharp"
74
- ]
64
+ "scripts": {
65
+ "test": "vitest run",
66
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
67
+ "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.json",
68
+ "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
75
69
  }
76
- }
70
+ }
@@ -14,12 +14,12 @@ ENV PATH="$PNPM_HOME:$PATH"
14
14
  RUN corepack enable
15
15
 
16
16
  # Native dependencies for bcrypt, pg, etc.
17
- RUN apk add --no-cache python3 make g++
17
+ RUN apk add --no-cache python3 make g++ curl ca-certificates
18
18
 
19
19
  WORKDIR /app
20
20
 
21
21
  # Copy workspace root files first (cache-friendly layer)
22
- COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
22
+ COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
23
23
 
24
24
  # Copy workspace packages
25
25
  COPY backend ./backend
@@ -41,6 +41,7 @@ FROM node:22-alpine AS runtime
41
41
  ENV PNPM_HOME="/pnpm"
42
42
  ENV PATH="$PNPM_HOME:$PATH"
43
43
  ENV NODE_ENV=production
44
+ ENV CI=true
44
45
 
45
46
  RUN corepack enable
46
47
 
@@ -50,7 +51,7 @@ RUN addgroup -g 1001 rebase && adduser -u 1001 -G rebase -s /bin/sh -D rebase
50
51
  WORKDIR /app
51
52
 
52
53
  # Copy only production artifacts
53
- COPY --from=builder /app/package.json /app/pnpm-lock.yaml /app/pnpm-workspace.yaml ./
54
+ COPY --from=builder /app/package.json /app/pnpm-lock.yaml /app/pnpm-workspace.yaml /app/.npmrc ./
54
55
  COPY --from=builder /app/node_modules ./node_modules
55
56
  COPY --from=builder /app/backend ./backend
56
57
  COPY --from=builder /app/config ./config
@@ -1,6 +1,4 @@
1
- import { Hono } from "hono";
2
- import type { HonoEnv } from "@rebasepro/server-core";
3
- import { rebase } from "@rebasepro/server-core";
1
+ import { defineFunction } from "@rebasepro/server-core";
4
2
 
5
3
  /**
6
4
  * Example custom function route.
@@ -12,41 +10,43 @@ import { rebase } from "@rebasepro/server-core";
12
10
  * Call from the client SDK:
13
11
  * const result = await client.call("functions/hello", { name: "World" });
14
12
  *
15
- * This is a standard Hono app use any Hono middleware,
16
- * define any HTTP methods, access the request/response directly.
13
+ * Authored with `defineFunction`, which hands you a pre-typed Hono app
14
+ * (so `c.get("user")` / `c.get("driver")` are typed) and the `rebase`
15
+ * singleton via the injected context — use any Hono middleware, define any
16
+ * HTTP methods, access the request/response directly.
17
17
  *
18
- * The `rebase` singleton gives you admin-level access to all
19
- * app-scoped services (data, auth, storage, email) from anywhere.
20
- * For request-scoped / RLS-scoped access, use c.get("user") and c.get("driver").
18
+ * `rebase` gives you admin-level access to all app-scoped services
19
+ * (data, auth, storage, email). For request-scoped / RLS-scoped access,
20
+ * use c.get("user") and c.get("driver").
21
21
  */
22
- const app = new Hono<HonoEnv>();
22
+ export default defineFunction((app, { rebase }) => {
23
+ void rebase; // available for data/auth/storage/email — see commented usage below
23
24
 
24
- app.post("/", async (c) => {
25
- const body = await c.req.json().catch(() => ({}));
26
- const user = c.get("user");
25
+ app.post("/", async (c) => {
26
+ const body = await c.req.json().catch(() => ({}));
27
+ const user = c.get("user");
27
28
 
28
- const userId = (user && typeof user === "object" && "userId" in user)
29
- ? user.userId
30
- : "anonymous";
29
+ const userId = (user && typeof user === "object" && "userId" in user)
30
+ ? user.userId
31
+ : "anonymous";
31
32
 
32
- // Access any Rebase service just import and use:
33
- // await rebase.email?.send({
34
- // to: "admin@example.com",
35
- // subject: "Function called",
36
- // html: `<p>Hello from ${userId}!</p>`,
37
- // });
38
- //
39
- // const authors = await rebase.data.authors.find({ limit: 5 });
33
+ // Access any Rebase service via the injected `rebase`:
34
+ // await rebase.email?.send({
35
+ // to: "admin@example.com",
36
+ // subject: "Function called",
37
+ // html: `<p>Hello from ${userId}!</p>`,
38
+ // });
39
+ //
40
+ // const authors = await rebase.data.authors.find({ limit: 5 });
40
41
 
41
- return c.json({
42
- message: `Hello, ${body.name || "World"}!`,
43
- user: userId
42
+ return c.json({
43
+ message: `Hello, ${body.name || "World"}!`,
44
+ user: userId
45
+ });
44
46
  });
45
- });
46
47
 
47
- app.get("/", (c) => {
48
- return c.json({ status: "ok",
49
- endpoint: "hello" });
48
+ app.get("/", (c) => {
49
+ return c.json({ status: "ok",
50
+ endpoint: "hello" });
51
+ });
50
52
  });
51
-
52
- export default app;
@@ -14,6 +14,7 @@
14
14
  "@rebasepro/server-core": "workspace:*",
15
15
  "@rebasepro/server-postgresql": "workspace:*",
16
16
  "@rebasepro/admin": "workspace:*",
17
+ "@rebasepro/types": "workspace:*",
17
18
  "drizzle-orm": "^0.45.2",
18
19
  "hono": "^4.12.10",
19
20
  "@hono/node-server": "^1.19.12",
@@ -91,7 +91,6 @@ relations },
91
91
  google: env.GOOGLE_CLIENT_ID
92
92
  ? { clientId: env.GOOGLE_CLIENT_ID }
93
93
  : undefined,
94
- seedDefaultRoles: true,
95
94
  allowRegistration: env.ALLOW_REGISTRATION,
96
95
  email: env.SMTP_HOST
97
96
  ? {
@@ -24,7 +24,9 @@ const postsCollection: EntityCollection = {
24
24
  content: {
25
25
  name: "Content",
26
26
  type: "string",
27
- markdown: true
27
+ ui: {
28
+ markdown: true
29
+ }
28
30
  },
29
31
  status: {
30
32
  name: "Status",
@@ -25,7 +25,9 @@ const categoriesCollection: EntityCollection = {
25
25
  description: {
26
26
  name: "Description",
27
27
  type: "string",
28
- multiline: true
28
+ ui: {
29
+ multiline: true
30
+ }
29
31
  },
30
32
  icon: {
31
33
  name: "Icon",
@@ -47,7 +47,9 @@ color: "red" }
47
47
  notes: {
48
48
  name: "Notes",
49
49
  type: "string",
50
- multiline: true
50
+ ui: {
51
+ multiline: true
52
+ }
51
53
  },
52
54
  createdAt: {
53
55
  name: "Created At",
@@ -21,7 +21,9 @@ const productsCollection: EntityCollection = {
21
21
  description: {
22
22
  name: "Description",
23
23
  type: "string",
24
- markdown: true
24
+ ui: {
25
+ markdown: true
26
+ }
25
27
  },
26
28
  price: {
27
29
  name: "Price",
@@ -44,7 +44,9 @@ roles: ["admin"] }
44
44
  name: "Photo URL",
45
45
  type: "string",
46
46
  columnName: "photo_url",
47
- url: "image"
47
+ ui: {
48
+ url: "image"
49
+ }
48
50
  },
49
51
  roles: {
50
52
  name: "Roles",
@@ -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
- RUN pnpm install --frozen-lockfile
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
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@rebasepro/cli": "workspace:*",
27
+ "@rebasepro/types": "workspace:*",
27
28
  "concurrently": "^8.2.2",
28
29
  "typescript": "^5.9.2"
29
30
  },
@@ -33,7 +34,8 @@
33
34
  "pnpm": {
34
35
  "onlyBuiltDependencies": [
35
36
  "esbuild",
36
- "sharp"
37
+ "sharp",
38
+ "@ariga/atlas"
37
39
  ]
38
40
  }
39
41
  }
@@ -7,5 +7,7 @@ blockExoticSubdeps: false
7
7
  minimumReleaseAge: 0
8
8
  allowBuilds:
9
9
  esbuild: true
10
+ sharp: true
11
+ "@ariga/atlas": true
10
12
  "{{PROJECT_NAME}}-config": true
11
13
 
@@ -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 Firebase Service Account credential.
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):