@rebasepro/cli 0.5.0 → 0.6.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.
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/skills.d.ts +1 -0
- package/dist/index.es.js +1631 -1308
- package/dist/index.es.js.map +1 -1
- package/dist/utils/package-manager.d.ts +2 -0
- package/package.json +17 -16
- package/skills/rebase-admin/SKILL.md +710 -0
- package/skills/rebase-api/SKILL.md +662 -0
- package/skills/rebase-api/references/.gitkeep +3 -0
- package/skills/rebase-auth/SKILL.md +1143 -0
- package/skills/rebase-auth/references/.gitkeep +3 -0
- package/skills/rebase-backend-postgres/SKILL.md +633 -0
- package/skills/rebase-backend-postgres/references/.gitkeep +3 -0
- package/skills/rebase-basics/SKILL.md +749 -0
- package/skills/rebase-basics/references/.gitkeep +3 -0
- package/skills/rebase-collections/SKILL.md +1328 -0
- package/skills/rebase-collections/references/.gitkeep +3 -0
- package/skills/rebase-cron-jobs/SKILL.md +699 -0
- package/skills/rebase-cron-jobs/references/.gitkeep +1 -0
- package/skills/rebase-custom-functions/SKILL.md +233 -0
- package/skills/rebase-deployment/SKILL.md +885 -0
- package/skills/rebase-deployment/references/.gitkeep +3 -0
- package/skills/rebase-design-language/SKILL.md +692 -0
- package/skills/rebase-email/SKILL.md +701 -0
- package/skills/rebase-email/references/.gitkeep +1 -0
- package/skills/rebase-entity-history/SKILL.md +485 -0
- package/skills/rebase-entity-history/references/.gitkeep +1 -0
- package/skills/rebase-local-env-setup/SKILL.md +189 -0
- package/skills/rebase-local-env-setup/references/.gitkeep +3 -0
- package/skills/rebase-realtime/SKILL.md +755 -0
- package/skills/rebase-realtime/references/.gitkeep +3 -0
- package/skills/rebase-sdk/SKILL.md +594 -0
- package/skills/rebase-sdk/references/.gitkeep +0 -0
- package/skills/rebase-storage/SKILL.md +765 -0
- package/skills/rebase-storage/references/.gitkeep +3 -0
- package/skills/rebase-studio/SKILL.md +746 -0
- package/skills/rebase-studio/references/.gitkeep +3 -0
- package/skills/rebase-ui-components/SKILL.md +1488 -0
- package/skills/rebase-ui-components/references/.gitkeep +3 -0
- package/skills/rebase-webhooks/SKILL.md +623 -0
- package/skills/rebase-webhooks/references/.gitkeep +1 -0
- package/templates/template/AGENTS.md +2 -0
- package/templates/template/CLAUDE.md +2 -0
- package/templates/template/ai-instructions.md +6 -3
- package/templates/template/backend/package.json +1 -1
- package/templates/template/backend/src/env.ts +1 -1
- package/templates/template/backend/src/index.ts +9 -6
- package/templates/template/config/collections/presets/ecommerce/orders.ts +15 -5
- package/templates/template/config/collections/presets/ecommerce/products.ts +9 -3
- package/templates/template/config/collections/users.ts +7 -10
- package/templates/template/frontend/package.json +2 -2
- package/templates/template/frontend/src/App.tsx +1 -7
- package/templates/template/frontend/vite.config.ts +0 -1
- package/templates/template/package.json +1 -0
- 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 -1575
- package/dist/index.cjs.map +0 -1
- package/dist/utils/package-manager.test.d.ts +0 -1
- package/dist/utils/project.test.d.ts +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rebase-custom-functions
|
|
3
|
+
description: Guide for adding custom API endpoints to a Rebase backend using the file-based function discovery pattern. Use this skill when the user needs a custom endpoint, webhook handler, payment callback, PDF generator, or any server-side route beyond auto-generated CRUD.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Custom API Functions
|
|
7
|
+
|
|
8
|
+
> **IMPORTANT FOR AGENTS**: Rebase supports **auto-discovered custom Hono routes** via the `functionsDir` config option. **Do NOT** modify the main Hono `app` instance or create standalone Express/Fastify servers. Instead, drop a TypeScript file in the `functions/` directory and Rebase will auto-mount it.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Custom functions let you add arbitrary HTTP endpoints to your Rebase backend. They follow the same **file-based discovery** pattern as collections and cron jobs:
|
|
13
|
+
|
|
14
|
+
1. Create a TypeScript file in your `backend/functions/` directory
|
|
15
|
+
2. Default-export a **Hono app** (or a factory function that returns one)
|
|
16
|
+
3. Rebase auto-mounts it at `/api/functions/{filename}`
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
Enable custom functions by adding `functionsDir` to your backend config:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
const backend = await initializeRebaseBackend({
|
|
24
|
+
// ... other config
|
|
25
|
+
functionsDir: path.resolve(__dirname, "../functions"), // ← add this
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Creating a Function
|
|
30
|
+
|
|
31
|
+
Each file default-exports a Hono app:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// backend/functions/send-invoice.ts
|
|
35
|
+
import { Hono } from "hono";
|
|
36
|
+
|
|
37
|
+
const app = new Hono();
|
|
38
|
+
|
|
39
|
+
app.post("/", async (c) => {
|
|
40
|
+
const { orderId, email } = await c.req.json();
|
|
41
|
+
|
|
42
|
+
// Your custom logic here — send email, call Stripe, generate PDF, etc.
|
|
43
|
+
console.log(`Sending invoice for order ${orderId} to ${email}`);
|
|
44
|
+
|
|
45
|
+
return c.json({ success: true, message: `Invoice sent to ${email}` });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
app.get("/status/:id", async (c) => {
|
|
49
|
+
const id = c.req.param("id");
|
|
50
|
+
return c.json({ invoiceId: id, status: "sent" });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export default app;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This auto-mounts as:
|
|
57
|
+
- `POST /api/functions/send-invoice`
|
|
58
|
+
- `GET /api/functions/send-invoice/status/:id`
|
|
59
|
+
|
|
60
|
+
The **filename** (without extension) becomes the route prefix.
|
|
61
|
+
|
|
62
|
+
## Factory Pattern
|
|
63
|
+
|
|
64
|
+
You can also export a factory function:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// backend/functions/webhooks.ts
|
|
68
|
+
import { Hono } from "hono";
|
|
69
|
+
|
|
70
|
+
export default function () {
|
|
71
|
+
const app = new Hono();
|
|
72
|
+
|
|
73
|
+
app.post("/stripe", async (c) => {
|
|
74
|
+
const body = await c.req.text();
|
|
75
|
+
// Verify Stripe signature, process event
|
|
76
|
+
return c.json({ received: true });
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
app.post("/github", async (c) => {
|
|
80
|
+
const payload = await c.req.json();
|
|
81
|
+
// Process GitHub webhook
|
|
82
|
+
return c.json({ received: true });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return app;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Accessing Auth & Services
|
|
90
|
+
|
|
91
|
+
Custom functions run within the Hono middleware chain, so you have access to auth context:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// backend/functions/admin-export.ts
|
|
95
|
+
import { Hono } from "hono";
|
|
96
|
+
import type { HonoEnv } from "@rebasepro/server-core";
|
|
97
|
+
|
|
98
|
+
const app = new Hono<HonoEnv>();
|
|
99
|
+
|
|
100
|
+
app.get("/", async (c) => {
|
|
101
|
+
// Access the authenticated user from middleware
|
|
102
|
+
const user = c.get("user");
|
|
103
|
+
if (!user) {
|
|
104
|
+
return c.json({ error: "Unauthorized" }, 401);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Access the data driver to query collections
|
|
108
|
+
const driver = c.get("driver");
|
|
109
|
+
const entities = await driver.fetchCollection("products", {
|
|
110
|
+
limit: 1000,
|
|
111
|
+
orderBy: "created_at",
|
|
112
|
+
order: "desc"
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return c.json({ data: entities });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export default app;
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Invoking Functions from the Frontend
|
|
122
|
+
|
|
123
|
+
> **CRITICAL FOR AGENTS**: When calling custom backend functions from the frontend, **ALWAYS** use `client.functions.invoke()`. **NEVER** use raw `fetch()`, manually construct URLs, or manually extract auth tokens from `localStorage`. The SDK handles all of this automatically.
|
|
124
|
+
|
|
125
|
+
The `@rebasepro/client` SDK provides a `functions` namespace that handles:
|
|
126
|
+
- **Automatic routing** — appends `/api/functions/{name}` to the client's configured `baseUrl`
|
|
127
|
+
- **Automatic authentication** — injects the current session's JWT into the `Authorization: Bearer` header
|
|
128
|
+
- **Standardized errors** — throws `RebaseApiError` on non-2xx responses, matching the behavior of collection methods
|
|
129
|
+
- **401 retry** — automatically attempts token refresh on unauthorized responses
|
|
130
|
+
|
|
131
|
+
### Basic Usage
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Invoke a function by name — auth token is injected automatically
|
|
135
|
+
const result = await client.functions.invoke<{ job: JobData }>('extract-job', {
|
|
136
|
+
url: 'https://example.com/job-posting',
|
|
137
|
+
html: htmlContent,
|
|
138
|
+
});
|
|
139
|
+
console.log(result.job.title);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### With Options
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Custom HTTP method
|
|
146
|
+
const status = await client.functions.invoke<{ status: string }>('send-invoice', undefined, {
|
|
147
|
+
method: 'GET',
|
|
148
|
+
path: `status/${invoiceId}`,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// DELETE request
|
|
152
|
+
await client.functions.invoke('cleanup', { olderThan: '30d' }, {
|
|
153
|
+
method: 'DELETE',
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### TypeScript Generics
|
|
158
|
+
|
|
159
|
+
Use the generic type parameter to get full type safety on the response:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
interface ExtractResult {
|
|
163
|
+
job: {
|
|
164
|
+
title: string;
|
|
165
|
+
company_name: string;
|
|
166
|
+
description_md: string;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const result = await client.functions.invoke<ExtractResult>('extract-job', { url });
|
|
171
|
+
// result.job.title is typed as string
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Error Handling
|
|
175
|
+
|
|
176
|
+
Errors follow the same pattern as collection methods:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { RebaseApiError } from '@rebasepro/client';
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
const result = await client.functions.invoke('process-payment', { orderId });
|
|
183
|
+
} catch (err) {
|
|
184
|
+
if (err instanceof RebaseApiError) {
|
|
185
|
+
console.error(`Status ${err.status}: ${err.message}`);
|
|
186
|
+
// err.code and err.details are also available
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### ❌ Anti-Pattern — Do NOT Do This
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// WRONG: Manual fetch with manual URL and manual token extraction
|
|
195
|
+
const token = JSON.parse(localStorage.getItem('rebase_auth') || '{}').accessToken;
|
|
196
|
+
const res = await fetch(`${apiUrl}/api/functions/extract-job`, {
|
|
197
|
+
method: 'POST',
|
|
198
|
+
headers: {
|
|
199
|
+
'Content-Type': 'application/json',
|
|
200
|
+
'Authorization': `Bearer ${token}`,
|
|
201
|
+
},
|
|
202
|
+
body: JSON.stringify({ url }),
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### ✅ Correct Pattern
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// RIGHT: SDK handles URL, auth, Content-Type, and error handling
|
|
210
|
+
const result = await client.functions.invoke('extract-job', { url });
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Common Use Cases
|
|
214
|
+
|
|
215
|
+
- **Webhook handlers** — Stripe, GitHub, Slack, Twilio incoming webhooks
|
|
216
|
+
- **Payment processing** — Custom checkout or subscription logic
|
|
217
|
+
- **PDF/report generation** — Server-side document rendering
|
|
218
|
+
- **Third-party API integrations** — Proxy or aggregate external APIs
|
|
219
|
+
- **Custom auth flows** — Magic links, phone verification, SSO
|
|
220
|
+
- **Data export** — CSV/Excel downloads of collection data
|
|
221
|
+
- **Health checks** — Custom readiness/liveness probes
|
|
222
|
+
|
|
223
|
+
## File Discovery Rules
|
|
224
|
+
|
|
225
|
+
- Files must be `.ts` or `.js` (not `.d.ts`, not `.test.*`)
|
|
226
|
+
- `index.ts` / `index.js` are ignored
|
|
227
|
+
- Each file's default export must be a Hono app or a factory returning one
|
|
228
|
+
- The loader uses duck-typing (`fetch()` + `routes` array) — any Hono-compatible instance works
|
|
229
|
+
|
|
230
|
+
## References
|
|
231
|
+
|
|
232
|
+
- **Documentation:** [rebase.pro/docs](https://rebase.pro/docs)
|
|
233
|
+
- **GitHub:** [github.com/rebasepro/rebase](https://github.com/rebasepro/rebase)
|