@bffless/skills 1.7.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.
- package/.claude-plugin/marketplace.json +18 -0
- package/LICENSE.md +19 -0
- package/README.md +117 -0
- package/package.json +24 -0
- package/plugins/bffless/.claude-plugin/plugin.json +21 -0
- package/plugins/bffless/skills/authentication/SKILL.md +204 -0
- package/plugins/bffless/skills/authorization/SKILL.md +59 -0
- package/plugins/bffless/skills/bffless/SKILL.md +158 -0
- package/plugins/bffless/skills/cache-and-storage/SKILL.md +151 -0
- package/plugins/bffless/skills/chat/SKILL.md +196 -0
- package/plugins/bffless/skills/pipelines/SKILL.md +162 -0
- package/plugins/bffless/skills/proxy-rules/SKILL.md +110 -0
- package/plugins/bffless/skills/repository/SKILL.md +64 -0
- package/plugins/bffless/skills/share-links/SKILL.md +53 -0
- package/plugins/bffless/skills/traffic-splitting/SKILL.md +63 -0
- package/plugins/bffless/skills/upload-artifact/SKILL.md +195 -0
- package/plugins/bffless/skills/use-bff-state/SKILL.md +174 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cache-and-storage
|
|
3
|
+
description: Cache rules for HTTP caching headers, storage backends, API keys for CI/CD, and user roles/permissions
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cache Rules, Storage & API Keys
|
|
7
|
+
|
|
8
|
+
## Cache Rules
|
|
9
|
+
|
|
10
|
+
Docs: https://docs.bffless.app/configuration/cache-rules
|
|
11
|
+
|
|
12
|
+
Cache rules control HTTP caching headers per path pattern. Rules are evaluated by priority (higher number = evaluated first).
|
|
13
|
+
|
|
14
|
+
### MCP: Create cache rule
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
create_cache_rule(
|
|
18
|
+
projectId: "uuid",
|
|
19
|
+
pathPattern: "*.js", // glob pattern
|
|
20
|
+
name: "JavaScript assets", // optional display name
|
|
21
|
+
description: "Cache JS files", // optional
|
|
22
|
+
browserMaxAge: 3600, // Cache-Control max-age (seconds)
|
|
23
|
+
cdnMaxAge: 86400, // s-maxage for CDN (seconds)
|
|
24
|
+
staleWhileRevalidate: 600, // stale-while-revalidate window
|
|
25
|
+
immutable: false, // mark as immutable (infinite cache)
|
|
26
|
+
isEnabled: true,
|
|
27
|
+
priority: 10 // higher = evaluated first
|
|
28
|
+
)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### MCP: List cache rules
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
list_cache_rules(projectId: "uuid")
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### MCP: Delete cache rule
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
delete_cache_rule(id: "uuid")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Recommended patterns
|
|
44
|
+
|
|
45
|
+
| Pattern | browserMaxAge | cdnMaxAge | immutable | Use Case |
|
|
46
|
+
|---------|--------------|-----------|-----------|----------|
|
|
47
|
+
| `*.js` | 3600 | 86400 | false | Versioned JS bundles |
|
|
48
|
+
| `*.css` | 3600 | 86400 | false | Stylesheets |
|
|
49
|
+
| `*.png`, `*.jpg`, `*.webp` | 86400 | 604800 | false | Images |
|
|
50
|
+
| `index.html` | 300 | 300 | false | HTML entry point (changes often) |
|
|
51
|
+
| `assets/*` | 31536000 | 31536000 | true | Hashed/fingerprinted assets |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Storage Backends
|
|
56
|
+
|
|
57
|
+
Docs: https://docs.bffless.app/configuration/storage
|
|
58
|
+
|
|
59
|
+
BFFLESS supports multiple storage backends for uploaded files:
|
|
60
|
+
|
|
61
|
+
| Backend | Use Case |
|
|
62
|
+
|---------|----------|
|
|
63
|
+
| **Local** | Development only |
|
|
64
|
+
| **MinIO** | Self-hosted S3-compatible |
|
|
65
|
+
| **AWS S3** | Amazon S3 |
|
|
66
|
+
| **Google Cloud Storage** | GCS (S3 compatibility mode) |
|
|
67
|
+
| **Azure Blob Storage** | Azure |
|
|
68
|
+
|
|
69
|
+
Storage key format: `{owner}/{repo}/{commitSha}/{path/to/file}`
|
|
70
|
+
|
|
71
|
+
Configured via `STORAGE_TYPE` environment variable. Credentials are encrypted at rest with AES-256.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## API Keys
|
|
76
|
+
|
|
77
|
+
Docs: https://docs.bffless.app/reference/security
|
|
78
|
+
|
|
79
|
+
API keys authenticate CI/CD pipelines and programmatic access.
|
|
80
|
+
|
|
81
|
+
### Types
|
|
82
|
+
|
|
83
|
+
- **Project-scoped** - Only works for a specific repository (`owner/repo`)
|
|
84
|
+
- **Global** - Works across all projects (admin only)
|
|
85
|
+
|
|
86
|
+
### MCP: Create API key
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
create_api_key(
|
|
90
|
+
name: "GitHub Actions CI",
|
|
91
|
+
repository: "owner/repo", // omit for global key
|
|
92
|
+
isGlobal: false, // true for global (admin only)
|
|
93
|
+
expiresAt: "2027-01-01T00:00:00Z" // optional expiration
|
|
94
|
+
)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Returns the raw key **only once** at creation. Store it securely (e.g., GitHub Actions secret).
|
|
98
|
+
|
|
99
|
+
### MCP: List API keys
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
list_api_keys(page?: 1, limit?: 20)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Returns key metadata (name, repository, lastUsedAt, expiresAt) but NOT the raw key.
|
|
106
|
+
|
|
107
|
+
### MCP: Delete API key
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
delete_api_key(id: "uuid")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Usage
|
|
114
|
+
|
|
115
|
+
API keys are passed via the `X-API-Key` header:
|
|
116
|
+
```
|
|
117
|
+
curl -H "X-API-Key: bff_xxxxxxxxxxxx" https://admin.yourdomain.com/api/...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Users & Roles
|
|
123
|
+
|
|
124
|
+
### Global roles
|
|
125
|
+
|
|
126
|
+
| Role | Access |
|
|
127
|
+
|------|--------|
|
|
128
|
+
| `admin` | Full system access, manage users, global API keys |
|
|
129
|
+
| `user` | Create/manage own projects |
|
|
130
|
+
| `member` | Access only granted projects (default for new users) |
|
|
131
|
+
|
|
132
|
+
### Project roles
|
|
133
|
+
|
|
134
|
+
| Role | Access |
|
|
135
|
+
|------|--------|
|
|
136
|
+
| `owner` | Full control, delete/transfer project |
|
|
137
|
+
| `admin` | Manage permissions, full CRUD |
|
|
138
|
+
| `contributor` | Create deployments, upload assets |
|
|
139
|
+
| `viewer` | Read-only access |
|
|
140
|
+
|
|
141
|
+
### MCP: List users
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
list_users(search?: "email@", role?: "admin", sortBy?: "createdAt", sortOrder?: "desc", page?: 1, limit?: 20)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### MCP: Update user role
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
update_user_role(id: "user-uuid", role: "admin") // "admin" | "user"
|
|
151
|
+
```
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chat
|
|
3
|
+
description: Adding AI chat to a site with full page or popup widget layouts, skills, streaming, and message persistence
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Chat
|
|
7
|
+
|
|
8
|
+
**Docs**: https://docs.bffless.app/features/chat/
|
|
9
|
+
|
|
10
|
+
Add an AI-powered chat experience to any site — no backend code required. Choose between a full page chat interface or a popup widget, give your chatbot domain knowledge with skills, and let BFFless handle streaming, persistence, and deployment.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
BFFless Chat provides:
|
|
15
|
+
|
|
16
|
+
- **No backend code** — configure everything through the admin UI
|
|
17
|
+
- **Streaming responses** — real-time token-by-token output via Server-Sent Events
|
|
18
|
+
- **Skills** — domain-specific knowledge from markdown files deployed with your site
|
|
19
|
+
- **Message persistence** — conversations and messages saved automatically to DB Records
|
|
20
|
+
- **A/B testable** — combine with traffic splitting to test different skills or prompts
|
|
21
|
+
- **Two layouts** — full page chat or floating popup widget
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Generate a Chat Schema
|
|
26
|
+
|
|
27
|
+
1. Go to **Pipelines → DB Records**
|
|
28
|
+
2. Click **Generate Schema**
|
|
29
|
+
3. Select **Chat Schema**
|
|
30
|
+
4. Enter a name (e.g., `support`)
|
|
31
|
+
5. Choose a scope:
|
|
32
|
+
- **User-scoped** — conversations tied to authenticated users
|
|
33
|
+
- **Guest-scoped** — conversations accessible without authentication
|
|
34
|
+
6. Click **Generate**
|
|
35
|
+
|
|
36
|
+
This creates:
|
|
37
|
+
- A `{name}_conversations` DB Record for conversation metadata
|
|
38
|
+
- A `{name}_messages` DB Record for individual messages
|
|
39
|
+
- A pipeline with a `POST /api/chat` endpoint pre-configured with the AI handler
|
|
40
|
+
|
|
41
|
+
### 2. Configure an AI Provider
|
|
42
|
+
|
|
43
|
+
1. Navigate to **Settings → AI**
|
|
44
|
+
2. Select a provider (OpenAI, Anthropic, or Google AI)
|
|
45
|
+
3. Enter your API key
|
|
46
|
+
4. Choose a default model
|
|
47
|
+
5. Click **Test Connection** to verify
|
|
48
|
+
6. Save
|
|
49
|
+
|
|
50
|
+
### 3. Connect Your Frontend
|
|
51
|
+
|
|
52
|
+
Use the AI SDK's `useChat` hook:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { useChat } from '@ai-sdk/react';
|
|
56
|
+
|
|
57
|
+
function Chat() {
|
|
58
|
+
const { messages, input, handleInputChange, handleSubmit, status } = useChat({
|
|
59
|
+
api: '/api/chat',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div>
|
|
64
|
+
{messages.map((m) => (
|
|
65
|
+
<div key={m.id}>
|
|
66
|
+
<strong>{m.role}:</strong> {m.parts.map(p => p.text).join('')}
|
|
67
|
+
</div>
|
|
68
|
+
))}
|
|
69
|
+
<form onSubmit={handleSubmit}>
|
|
70
|
+
<input value={input} onChange={handleInputChange} placeholder="Type a message..." />
|
|
71
|
+
<button type="submit" disabled={status === 'streaming'}>Send</button>
|
|
72
|
+
</form>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 4. Deploy
|
|
79
|
+
|
|
80
|
+
Push your code to GitHub and deploy with the `bffless/upload-artifact` GitHub Action. Your chat endpoint is live as soon as the deployment completes.
|
|
81
|
+
|
|
82
|
+
## Chat Layouts
|
|
83
|
+
|
|
84
|
+
### Full Page Chat
|
|
85
|
+
|
|
86
|
+
A standalone chat page that takes over the full viewport. Includes suggested prompts, real-time streaming with markdown rendering, and a clean conversational UI.
|
|
87
|
+
|
|
88
|
+
Best for: dedicated support pages, knowledge base assistants, internal tools.
|
|
89
|
+
|
|
90
|
+
### Popup Widget
|
|
91
|
+
|
|
92
|
+
A floating chat bubble that opens a slide-up chat panel. Users can start a new conversation or close the widget without losing context. The widget stays accessible on any page.
|
|
93
|
+
|
|
94
|
+
Best for: landing pages, documentation sites, e-commerce — anywhere you want chat available without dedicating a full page.
|
|
95
|
+
|
|
96
|
+
## Skills
|
|
97
|
+
|
|
98
|
+
Skills are markdown files that give your chatbot domain-specific knowledge. Deploy them alongside your site and the AI loads relevant skills on-demand during conversations.
|
|
99
|
+
|
|
100
|
+
Skills are **versioned with each deployment** — when an alias points to a commit, the skills for that commit are used. This makes them git-managed, rollback-safe, and A/B testable with traffic splitting.
|
|
101
|
+
|
|
102
|
+
### Creating a Skill
|
|
103
|
+
|
|
104
|
+
Add a `SKILL.md` file to `.bffless/skills/<skill-name>/`:
|
|
105
|
+
|
|
106
|
+
```markdown
|
|
107
|
+
---
|
|
108
|
+
name: pricing-faq
|
|
109
|
+
description: Answer questions about pricing, plans, and billing
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
# Pricing FAQ
|
|
113
|
+
|
|
114
|
+
(Your knowledge content here in markdown)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Deploying Skills
|
|
118
|
+
|
|
119
|
+
Upload skills alongside your build artifacts:
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
- name: Deploy build
|
|
123
|
+
uses: bffless/upload-artifact@v1
|
|
124
|
+
with:
|
|
125
|
+
source: dist
|
|
126
|
+
|
|
127
|
+
- name: Deploy skills
|
|
128
|
+
uses: bffless/upload-artifact@v1
|
|
129
|
+
with:
|
|
130
|
+
source: .bffless
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Configuring Skills in Pipelines
|
|
134
|
+
|
|
135
|
+
Set the skills mode in the AI handler configuration:
|
|
136
|
+
|
|
137
|
+
| Mode | Description |
|
|
138
|
+
|------|-------------|
|
|
139
|
+
| **None** | Disable all skills (default) |
|
|
140
|
+
| **All** | Enable all uploaded skills |
|
|
141
|
+
| **Selected** | Enable only specific skills by name |
|
|
142
|
+
|
|
143
|
+
## Message Persistence
|
|
144
|
+
|
|
145
|
+
When enabled, conversations and messages are automatically saved to DB Records. The handler manages:
|
|
146
|
+
|
|
147
|
+
- **Conversations**: chat_id, message_count, total_tokens, model
|
|
148
|
+
- **Messages**: conversation_id, role, content, tokens_used
|
|
149
|
+
|
|
150
|
+
Message persistence is optional — for simple use cases, skip it entirely and chat works without any database configuration.
|
|
151
|
+
|
|
152
|
+
## Configuration
|
|
153
|
+
|
|
154
|
+
Key settings for the AI chat handler:
|
|
155
|
+
|
|
156
|
+
| Setting | Description | Options / Default |
|
|
157
|
+
|---------|-------------|-------------------|
|
|
158
|
+
| **Mode** | Chat or Completion | `chat`, `completion` |
|
|
159
|
+
| **Provider** | AI provider | `openai`, `anthropic`, `google` |
|
|
160
|
+
| **Model** | Specific model | Provider-dependent |
|
|
161
|
+
| **System Prompt** | Instructions for the AI | Free-text |
|
|
162
|
+
| **Response Format** | Stream or JSON | `stream`, `message` |
|
|
163
|
+
| **Skills Mode** | Which skills to enable | `none`, `all`, `selected` |
|
|
164
|
+
| **Temperature** | Response creativity | `0` – `2` (default: `0.7`) |
|
|
165
|
+
| **Max Tokens** | Maximum output length | `256` – `100000` (default: `4096`) |
|
|
166
|
+
| **Max History** | Messages in context | `0` – `200` (default: `50`) |
|
|
167
|
+
|
|
168
|
+
## Supported Providers
|
|
169
|
+
|
|
170
|
+
| Provider | Models | Default |
|
|
171
|
+
|----------|--------|---------|
|
|
172
|
+
| OpenAI | gpt-4o, gpt-4-turbo, gpt-4, gpt-4o-mini, gpt-3.5-turbo | gpt-4o |
|
|
173
|
+
| Anthropic | claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5 | claude-sonnet-4-6 |
|
|
174
|
+
| Google AI | gemini-1.5-pro, gemini-1.5-flash, gemini-1.5-flash-8b | gemini-1.5-pro |
|
|
175
|
+
|
|
176
|
+
## Demo
|
|
177
|
+
|
|
178
|
+
- Full page chat: https://chat.docs.bffless.app/
|
|
179
|
+
- Popup widget: https://chat.docs.bffless.app/popup/
|
|
180
|
+
- Source code: https://github.com/bffless/demo-chat
|
|
181
|
+
|
|
182
|
+
## Troubleshooting
|
|
183
|
+
|
|
184
|
+
**Chat responses not streaming?**
|
|
185
|
+
- Verify response format is set to **Stream (SSE)**
|
|
186
|
+
- Ensure the AI handler is the **last step** in your pipeline
|
|
187
|
+
- Check frontend is using `useChat` from `@ai-sdk/react`
|
|
188
|
+
|
|
189
|
+
**Skills not loading?**
|
|
190
|
+
- Verify `.bffless/skills/` exists in your deployment
|
|
191
|
+
- Ensure skills mode is set to **All** or **Selected** (not None)
|
|
192
|
+
- Check each skill has valid `SKILL.md` with YAML frontmatter (name and description)
|
|
193
|
+
|
|
194
|
+
**Messages not persisting?**
|
|
195
|
+
- Ensure **Message Persistence** is enabled in the AI handler config
|
|
196
|
+
- Verify both Conversations Schema and Messages Schema are selected
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pipelines
|
|
3
|
+
description: Backend automation without code using handler chains
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pipelines
|
|
7
|
+
|
|
8
|
+
**Docs**: https://docs.bffless.app/features/pipelines/
|
|
9
|
+
|
|
10
|
+
Pipelines provide backend functionality for static sites without writing server code. Chain handlers together to process forms, store data, send emails, call AI models, accept payments, and more.
|
|
11
|
+
|
|
12
|
+
## Handler Types
|
|
13
|
+
|
|
14
|
+
| Handler | Type | Purpose |
|
|
15
|
+
|---------|------|---------|
|
|
16
|
+
| **Form** | `form_handler` | Parse form submissions (multipart, JSON, URL-encoded) |
|
|
17
|
+
| **Data Create** | `data_create` | Create DB records in a pipeline schema |
|
|
18
|
+
| **Data Query** | `data_query` | Read/list DB records with filters, sorting, pagination |
|
|
19
|
+
| **Data Update** | `data_update` | Update existing DB records |
|
|
20
|
+
| **Data Delete** | `data_delete` | Delete DB records |
|
|
21
|
+
| **Aggregate** | `db_aggregate` | Count/Sum/Avg/Min/Max on data, with optional groupBy for grouped results |
|
|
22
|
+
| **Email** | `email_handler` | Send emails via configured provider |
|
|
23
|
+
| **Response** | `response_handler` | Return custom JSON, status codes, or redirect |
|
|
24
|
+
| **Function** | `function_handler` | Custom JavaScript for transformation/logic |
|
|
25
|
+
| **AI** | `ai_handler` | Call OpenAI/Anthropic/Google AI models (chat or completion) |
|
|
26
|
+
| **HTTP Request** | `http_request` | Make outbound HTTP requests to external APIs |
|
|
27
|
+
| **File Upload** | `file_upload_handler` | Upload files from forms or URLs to storage |
|
|
28
|
+
| **File Serve** | `file_serve_handler` | Serve files from storage with Range request support |
|
|
29
|
+
| **Image Convert** | `image_convert_handler` | Convert images between PNG/JPEG/WebP using sharp |
|
|
30
|
+
| **Signed URL** | `signed_url` | Generate time-limited presigned URLs for storage files |
|
|
31
|
+
| **Replicate** | `replicate` | Call Replicate ML models (image gen, embeddings, etc.) |
|
|
32
|
+
| **Embed Store** | `embed_store` | Store embedding vectors for semantic search |
|
|
33
|
+
| **Vector Search** | `vector_search` | Query embeddings by cosine similarity |
|
|
34
|
+
| **Stripe Checkout** | `stripe_checkout` | Create Stripe Checkout sessions for payments/subscriptions |
|
|
35
|
+
| **Stripe Webhook** | `stripe_webhook` | Validate Stripe webhook signatures and parse events |
|
|
36
|
+
|
|
37
|
+
## DB Records
|
|
38
|
+
|
|
39
|
+
Schema-based data storage built into BFFless:
|
|
40
|
+
|
|
41
|
+
1. Define schema in project settings (fields, types, validation)
|
|
42
|
+
2. Use Data CRUD handlers to interact with records
|
|
43
|
+
3. Query with filters, sorting, pagination
|
|
44
|
+
|
|
45
|
+
## AI Handler
|
|
46
|
+
|
|
47
|
+
Call AI models directly from pipelines. Supports chat (multi-turn) and completion (single-turn) modes.
|
|
48
|
+
|
|
49
|
+
Key config:
|
|
50
|
+
- `provider`: `openai`, `anthropic`, or `google`
|
|
51
|
+
- `mode`: `chat` or `completion`
|
|
52
|
+
- `messageField`: field name containing the user message (from input)
|
|
53
|
+
- `systemPrompt`: system instructions for the AI
|
|
54
|
+
- `persistMessages`: store conversation history in a pipeline schema
|
|
55
|
+
- `persistMessagesSchemaId`: which schema to store messages in
|
|
56
|
+
|
|
57
|
+
## HTTP Request Handler
|
|
58
|
+
|
|
59
|
+
Make outbound API calls to external services from within a pipeline.
|
|
60
|
+
|
|
61
|
+
Key config:
|
|
62
|
+
- `url`: target URL (supports expressions like `${steps.prev.apiUrl}`)
|
|
63
|
+
- `method`: GET, POST, PATCH, DELETE
|
|
64
|
+
- `body`: request body (expressions supported)
|
|
65
|
+
- `headers`: custom headers to add
|
|
66
|
+
- `forwardAuth`: forward the original request's auth header
|
|
67
|
+
|
|
68
|
+
## File Handlers
|
|
69
|
+
|
|
70
|
+
**Upload** (`file_upload_handler`): Handles multipart file uploads or downloads from URLs. Supports allowed MIME type filtering, max file size, optional image conversion, and date-bucketed storage.
|
|
71
|
+
|
|
72
|
+
**Serve** (`file_serve_handler`): Streams files from storage with HTTP Range support for video/audio playback. Config: `subDir`, `cacheMaxAge`.
|
|
73
|
+
|
|
74
|
+
**Image Convert** (`image_convert_handler`): Converts between PNG, JPEG, WebP. Config: `inputPath`, `outputFormat`, `quality`.
|
|
75
|
+
|
|
76
|
+
**Signed URL** (`signed_url`): Generates time-limited presigned URLs for private storage files. Config: `path`, `expiresIn` (seconds, default 3600).
|
|
77
|
+
|
|
78
|
+
## Stripe Handlers
|
|
79
|
+
|
|
80
|
+
**Checkout** (`stripe_checkout`): Creates Stripe Checkout sessions. Config: `priceId`, `mode` (payment/subscription), `successUrl`, `cancelUrl`, `customerEmail`, `environment` (live/test).
|
|
81
|
+
|
|
82
|
+
**Webhook** (`stripe_webhook`): Validates webhook signatures and parses events. Config: `allowedEventTypes` (optional filter), `environment`.
|
|
83
|
+
|
|
84
|
+
## Vector/Embedding Handlers
|
|
85
|
+
|
|
86
|
+
**Embed Store** (`embed_store`): Stores embedding vectors in the database. Supports single embeddings or chunked documents. Config: `schemaId`, `recordId`, `embedding` or `chunks`.
|
|
87
|
+
|
|
88
|
+
**Vector Search** (`vector_search`): Queries embeddings by cosine similarity. Config: `schemaId`, `queryVector`, `limit`, `threshold`.
|
|
89
|
+
|
|
90
|
+
**Replicate** (`replicate`): Calls Replicate ML models for image generation, embeddings, etc. Auto-uploads large files to Replicate's Files API. Config: `model`, `version`, `input`.
|
|
91
|
+
|
|
92
|
+
## Expression Syntax
|
|
93
|
+
|
|
94
|
+
Access data throughout the pipeline using expressions:
|
|
95
|
+
|
|
96
|
+
- `input.*` - Parsed request body
|
|
97
|
+
- `query.*` - URL query parameters
|
|
98
|
+
- `params.*` - URL path parameters
|
|
99
|
+
- `headers.*` - Request headers
|
|
100
|
+
- `steps.<name>.*` - Output from previous handler
|
|
101
|
+
- `user.*` - Authenticated user info (if applicable)
|
|
102
|
+
|
|
103
|
+
Example: `${input.email}` or `${steps.createUser.id}`
|
|
104
|
+
|
|
105
|
+
## Validators
|
|
106
|
+
|
|
107
|
+
Pipelines support validators that run before any steps execute:
|
|
108
|
+
|
|
109
|
+
- `auth_required` - Require authenticated user
|
|
110
|
+
- `rate_limit` - Rate limit requests (by IP or user)
|
|
111
|
+
|
|
112
|
+
Both support conditions to selectively apply (e.g., only rate limit POST requests).
|
|
113
|
+
|
|
114
|
+
## Common Workflows
|
|
115
|
+
|
|
116
|
+
**Contact form:**
|
|
117
|
+
1. Form handler → parse submission
|
|
118
|
+
2. Data CRUD → store in "submissions" schema
|
|
119
|
+
3. Email → notify admin
|
|
120
|
+
4. Response → thank you message
|
|
121
|
+
|
|
122
|
+
**AI chat:**
|
|
123
|
+
1. Form handler → parse user message
|
|
124
|
+
2. AI handler → call model with conversation context
|
|
125
|
+
3. Response → return AI response
|
|
126
|
+
|
|
127
|
+
**File upload with processing:**
|
|
128
|
+
1. File Upload → store file
|
|
129
|
+
2. Image Convert → resize/convert
|
|
130
|
+
3. Data Create → store metadata
|
|
131
|
+
4. Response → return file URL
|
|
132
|
+
|
|
133
|
+
**Stripe payment:**
|
|
134
|
+
1. Form handler → parse product selection
|
|
135
|
+
2. Stripe Checkout → create session
|
|
136
|
+
3. Response → redirect to Stripe
|
|
137
|
+
|
|
138
|
+
**Semantic search:**
|
|
139
|
+
1. Form handler → parse query
|
|
140
|
+
2. AI/Replicate → generate query embedding
|
|
141
|
+
3. Vector Search → find similar records
|
|
142
|
+
4. Response → return results
|
|
143
|
+
|
|
144
|
+
## Configuration Tips
|
|
145
|
+
|
|
146
|
+
1. Name handlers descriptively for readable expressions
|
|
147
|
+
2. Use Response handler last to control what client sees
|
|
148
|
+
3. Test with simple inputs before adding validation
|
|
149
|
+
4. Check pipeline logs for debugging failed executions
|
|
150
|
+
5. Use `postSteps` for async work after the response is sent (e.g., sending emails)
|
|
151
|
+
|
|
152
|
+
## Troubleshooting
|
|
153
|
+
|
|
154
|
+
**Pipeline not triggering?**
|
|
155
|
+
- Verify endpoint path matches request URL
|
|
156
|
+
- Check HTTP method (GET, POST, etc.) is correct
|
|
157
|
+
- Ensure pipeline is enabled and rule set is assigned to alias
|
|
158
|
+
|
|
159
|
+
**Expression returning undefined?**
|
|
160
|
+
- Check handler name matches exactly (case-sensitive)
|
|
161
|
+
- Verify previous handler completed successfully
|
|
162
|
+
- Use pipeline logs to see actual values at each step
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: proxy-rules
|
|
3
|
+
description: Forward requests to backend APIs without CORS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Proxy Rules
|
|
7
|
+
|
|
8
|
+
**Docs**: https://docs.bffless.app/features/proxy-rules/
|
|
9
|
+
|
|
10
|
+
Proxy rules forward requests from your static site to backend APIs, eliminating CORS issues and hiding API endpoints from clients.
|
|
11
|
+
|
|
12
|
+
## Configuration Levels
|
|
13
|
+
|
|
14
|
+
**Project defaults**: Apply to all aliases unless overridden
|
|
15
|
+
|
|
16
|
+
**Alias overrides**: Specific aliases can have their own proxy rule sets assigned
|
|
17
|
+
|
|
18
|
+
## Rule Sets
|
|
19
|
+
|
|
20
|
+
Proxy rules are organized into **rule sets** — named, reusable groups of rules.
|
|
21
|
+
|
|
22
|
+
An alias can have **multiple rule sets** attached. When multiple rule sets are assigned, their rules are merged in priority order (first set wins if two sets define the same path+method).
|
|
23
|
+
|
|
24
|
+
This allows logical grouping, e.g.:
|
|
25
|
+
- `api-proxy` — routes to your backend API
|
|
26
|
+
- `pipelines` — pipeline-based handlers for chat, forms, etc.
|
|
27
|
+
- `auth-proxy` — cookie-to-bearer token transformation
|
|
28
|
+
|
|
29
|
+
### Assigning Rule Sets to Aliases
|
|
30
|
+
|
|
31
|
+
Use `update_alias` with `proxyRuleSetIds` (array) to attach one or more rule sets:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
update_alias(
|
|
35
|
+
repository: "owner/repo",
|
|
36
|
+
alias: "production",
|
|
37
|
+
proxyRuleSetIds: ["rule-set-id-1", "rule-set-id-2"]
|
|
38
|
+
)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The legacy `proxyRuleSetId` (singular) still works for backwards compatibility but only supports one rule set.
|
|
42
|
+
|
|
43
|
+
**Important**: After creating proxy rules, you must assign the rule set(s) to an alias for rules to take effect. Rules won't be active until linked to an alias.
|
|
44
|
+
|
|
45
|
+
## Rule Structure
|
|
46
|
+
|
|
47
|
+
Each rule specifies:
|
|
48
|
+
- **Path pattern**: Which requests to intercept
|
|
49
|
+
- **Target**: Backend URL to forward to
|
|
50
|
+
- **Strip prefix**: Whether to remove the matched prefix
|
|
51
|
+
|
|
52
|
+
## Pattern Types
|
|
53
|
+
|
|
54
|
+
**Prefix match** (most common):
|
|
55
|
+
```
|
|
56
|
+
/api/* → https://api.example.com
|
|
57
|
+
```
|
|
58
|
+
Request to `/api/users` forwards to `https://api.example.com/users`
|
|
59
|
+
|
|
60
|
+
**Exact match**:
|
|
61
|
+
```
|
|
62
|
+
/health → https://backend.example.com/status
|
|
63
|
+
```
|
|
64
|
+
Only exact path matches, no wildcards
|
|
65
|
+
|
|
66
|
+
**Suffix match**:
|
|
67
|
+
```
|
|
68
|
+
*.json → https://data.example.com
|
|
69
|
+
```
|
|
70
|
+
Matches any path ending in `.json`
|
|
71
|
+
|
|
72
|
+
## Strip Prefix Behavior
|
|
73
|
+
|
|
74
|
+
With strip prefix ON (default):
|
|
75
|
+
```
|
|
76
|
+
/api/* → https://backend.com
|
|
77
|
+
/api/users → https://backend.com/users
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
With strip prefix OFF:
|
|
81
|
+
```
|
|
82
|
+
/api/* → https://backend.com
|
|
83
|
+
/api/users → https://backend.com/api/users
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Common Patterns
|
|
87
|
+
|
|
88
|
+
**API proxy**: `/api/*` → your backend server
|
|
89
|
+
|
|
90
|
+
**Third-party API**: `/stripe/*` → `https://api.stripe.com` (hides API from client)
|
|
91
|
+
|
|
92
|
+
**Microservices**: Different prefixes route to different services
|
|
93
|
+
|
|
94
|
+
## Security Notes
|
|
95
|
+
|
|
96
|
+
- All proxy targets must use HTTPS
|
|
97
|
+
- BFFless validates targets to prevent SSRF attacks
|
|
98
|
+
- Headers like `Host` are rewritten to match target
|
|
99
|
+
- Client IP forwarded via `X-Forwarded-For`
|
|
100
|
+
|
|
101
|
+
## Troubleshooting
|
|
102
|
+
|
|
103
|
+
**Requests not proxying?**
|
|
104
|
+
- Check path pattern matches request URL exactly
|
|
105
|
+
- Verify rule set is assigned to the alias via `update_alias`
|
|
106
|
+
- Confirm target URL is HTTPS and reachable
|
|
107
|
+
|
|
108
|
+
**Getting CORS errors still?**
|
|
109
|
+
- Ensure the proxy rule set is assigned to the alias being accessed
|
|
110
|
+
- Check browser DevTools for actual request URL (may not be hitting proxy)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: repository
|
|
3
|
+
description: Browse deployments, manage aliases, view branches
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Repository
|
|
7
|
+
|
|
8
|
+
**Docs**: https://docs.bffless.app/features/repository-overview/
|
|
9
|
+
|
|
10
|
+
The Repository is your central hub for browsing deployments, managing aliases, and navigating your project's content.
|
|
11
|
+
|
|
12
|
+
## Content Browser
|
|
13
|
+
|
|
14
|
+
The browser has four panels:
|
|
15
|
+
|
|
16
|
+
1. **Files Panel**: Navigate directory structure, search files
|
|
17
|
+
2. **Preview Panel**: Live preview of selected file
|
|
18
|
+
3. **History Panel**: Deployment timeline, compare versions
|
|
19
|
+
4. **References Panel**: See which aliases point to this deployment
|
|
20
|
+
|
|
21
|
+
## Deployments
|
|
22
|
+
|
|
23
|
+
Each deployment is an immutable snapshot of your build output. Deployments are identified by:
|
|
24
|
+
|
|
25
|
+
- **Deployment ID**: Unique hash
|
|
26
|
+
- **Git info**: Branch, commit SHA, commit message (if available)
|
|
27
|
+
- **Timestamp**: When deployed
|
|
28
|
+
- **Size**: Total file size
|
|
29
|
+
|
|
30
|
+
## Aliases
|
|
31
|
+
|
|
32
|
+
Aliases are named pointers to deployments. Two types:
|
|
33
|
+
|
|
34
|
+
**Manual aliases**: You control which deployment they point to
|
|
35
|
+
- `production`, `staging`, `v1.2.0`
|
|
36
|
+
- Update manually or via API
|
|
37
|
+
|
|
38
|
+
**Auto-preview aliases**: Automatically created for branches/PRs
|
|
39
|
+
- `preview-feature-branch`, `pr-123`
|
|
40
|
+
- Updated on each push, deleted when branch is deleted
|
|
41
|
+
|
|
42
|
+
## Common Workflows
|
|
43
|
+
|
|
44
|
+
**Deploy new version:**
|
|
45
|
+
1. Upload via CLI/API/GitHub Action
|
|
46
|
+
2. New deployment appears in Repository
|
|
47
|
+
3. Update alias to point to new deployment
|
|
48
|
+
|
|
49
|
+
**Rollback:**
|
|
50
|
+
1. Find previous deployment in History
|
|
51
|
+
2. Update production alias to point to it
|
|
52
|
+
3. Instant rollback, no rebuild needed
|
|
53
|
+
|
|
54
|
+
**Preview PRs:**
|
|
55
|
+
1. Configure auto-preview in project settings
|
|
56
|
+
2. Each PR gets unique preview URL
|
|
57
|
+
3. Preview updates on each push
|
|
58
|
+
|
|
59
|
+
## Navigation Tips
|
|
60
|
+
|
|
61
|
+
- Use keyboard shortcuts: `j/k` to navigate files, `Enter` to preview
|
|
62
|
+
- Search supports glob patterns: `*.html`, `components/**`
|
|
63
|
+
- Click deployment hash to copy full URL
|
|
64
|
+
- Right-click alias for quick actions menu
|