clawfire 0.1.0 → 0.2.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/README.md +371 -88
- package/dist/admin.d.cts +1 -1
- package/dist/admin.d.ts +1 -1
- package/dist/cli.js +11 -3
- package/dist/{config-QMBJRn9G.d.cts → config-D-Chojiu.d.cts} +7 -0
- package/dist/{config-QMBJRn9G.d.ts → config-D-Chojiu.d.ts} +7 -0
- package/dist/{dev-server-QAVWINAT.js → dev-server-QTNE5N7I.js} +336 -89
- package/dist/dev.cjs +335 -88
- package/dist/dev.cjs.map +1 -1
- package/dist/dev.d.cts +25 -19
- package/dist/dev.d.ts +25 -19
- package/dist/dev.js +336 -89
- package/dist/dev.js.map +1 -1
- package/dist/functions.d.cts +1 -1
- package/dist/functions.d.ts +1 -1
- package/dist/index.cjs +6 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/clawfire.config.ts +4 -0
- package/templates/starter/CLAUDE.md +1 -1
- package/templates/starter/clawfire.config.ts +4 -0
- package/templates/starter/dev.ts +2 -1
- package/templates/starter/public/index.html +0 -15
package/README.md
CHANGED
|
@@ -2,56 +2,168 @@
|
|
|
2
2
|
|
|
3
3
|
**AI-First Firebase App Framework — Speak. Build. Deploy.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/clawfire)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
Clawfire lets you build Firebase apps by talking to AI. Define your API contracts with Zod, and get type-safe routing, auto-generated clients, security rules, and deployment — all from a single source of truth.
|
|
9
|
+
|
|
10
|
+
---
|
|
6
11
|
|
|
7
12
|
## Features
|
|
8
13
|
|
|
9
|
-
- **Contract-based API** —
|
|
10
|
-
- **File-based Routing** — `app/routes
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
14
|
+
- **Contract-based API** — Define input/output with Zod schemas. Runtime validation, type safety, and docs come for free.
|
|
15
|
+
- **File-based Routing** — `app/routes/todos/create.ts` becomes `POST /api/todos/create`. No configuration.
|
|
16
|
+
- **Two-Port Dev Server** — Frontend app on port 3000, API + Playground on port 3456. One command.
|
|
17
|
+
- **Hot Reload** — API route changes reload instantly. CSS changes apply without page reload.
|
|
18
|
+
- **API Playground** — Interactive API explorer auto-generated from your route definitions.
|
|
19
|
+
- **Auto Client Generation** — Type-safe `api.todos.create({ title })` client generated from your contracts.
|
|
20
|
+
- **Firebase-Native** — Firestore, Auth, Functions, Hosting. Fully integrated, no alternatives needed.
|
|
21
|
+
- **Security by Default** — Input validation, CORS deny, rate limiting, XSS sanitization, log masking — all ON.
|
|
22
|
+
- **Auto Security Rules** — Firestore rules generated from model definitions.
|
|
23
|
+
- **AI Skills** — Six `/clawfire-*` Claude Code commands to manage your entire project.
|
|
24
|
+
|
|
25
|
+
---
|
|
17
26
|
|
|
18
27
|
## Quick Start
|
|
19
28
|
|
|
29
|
+
### 1. Create a New Project
|
|
30
|
+
|
|
20
31
|
```bash
|
|
21
|
-
|
|
32
|
+
mkdir my-app && cd my-app
|
|
22
33
|
npx clawfire init
|
|
34
|
+
npm install
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Start the Dev Server
|
|
23
38
|
|
|
24
|
-
|
|
25
|
-
npm
|
|
39
|
+
```bash
|
|
40
|
+
npm run dev
|
|
26
41
|
```
|
|
27
42
|
|
|
28
|
-
|
|
43
|
+
This starts **two servers** in a single process:
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
```
|
|
46
|
+
⚡ Clawfire Dev Server
|
|
47
|
+
─────────────────────────────────────
|
|
48
|
+
App : http://localhost:3000
|
|
49
|
+
API : http://localhost:3456/api/...
|
|
50
|
+
Playground : http://localhost:3456
|
|
51
|
+
|
|
52
|
+
Routes (5):
|
|
53
|
+
POST /api/health [public] Health check endpoint
|
|
54
|
+
POST /api/todos/create [public] Create a new todo
|
|
55
|
+
POST /api/todos/delete [public] Delete a todo
|
|
56
|
+
POST /api/todos/list [public] List all todos
|
|
57
|
+
POST /api/todos/update [public] Update a todo
|
|
58
|
+
|
|
59
|
+
Hot Reload : ON
|
|
60
|
+
Watching: app/routes/, app/schemas/, public/
|
|
61
|
+
```
|
|
31
62
|
|
|
32
|
-
|
|
33
|
-
// app/schemas/product.ts
|
|
34
|
-
import { defineModel } from "clawfire";
|
|
63
|
+
### 3. Open in Your Browser
|
|
35
64
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
| URL | What You'll See |
|
|
66
|
+
|-----|-----------------|
|
|
67
|
+
| [http://localhost:3000](http://localhost:3000) | Your app (Todo starter) |
|
|
68
|
+
| [http://localhost:3456](http://localhost:3456) | API Playground |
|
|
69
|
+
|
|
70
|
+
### 4. Test the API
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Via the API server directly
|
|
74
|
+
curl -s -X POST http://localhost:3456/api/health \
|
|
75
|
+
-H 'Content-Type: application/json' -d '{}' | jq
|
|
76
|
+
|
|
77
|
+
# Or via the frontend proxy (same result, no CORS issues)
|
|
78
|
+
curl -s -X POST http://localhost:3000/api/todos/create \
|
|
79
|
+
-H 'Content-Type: application/json' \
|
|
80
|
+
-d '{"title":"Learn Clawfire"}' | jq
|
|
50
81
|
```
|
|
51
82
|
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Dev Server Architecture
|
|
86
|
+
|
|
87
|
+
Clawfire runs a **two-port dev server** in a single process:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
DevServer
|
|
91
|
+
├─ Frontend Server (port 3000)
|
|
92
|
+
│ ├─ Serves public/ directory
|
|
93
|
+
│ ├─ Auto-injects HMR script into HTML
|
|
94
|
+
│ ├─ Proxies /api/* → API server (no CORS)
|
|
95
|
+
│ └─ SPA fallback → index.html
|
|
96
|
+
│
|
|
97
|
+
└─ API Server (port 3456)
|
|
98
|
+
├─ API routes at /api/*
|
|
99
|
+
├─ Playground UI at /
|
|
100
|
+
└─ SSE for live reload
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Key behaviors:**
|
|
104
|
+
|
|
105
|
+
- **HMR auto-injection** — Every HTML response gets a `<script>` tag injected automatically. You never write SSE code.
|
|
106
|
+
- **CSS hot replace** — Edit a `.css` file in `public/` and see changes instantly without page reload.
|
|
107
|
+
- **API proxy** — Your frontend can call `fetch('/api/todos/list')` — the frontend server proxies it to the API server. No CORS configuration needed.
|
|
108
|
+
- **SPA fallback** — Unknown paths serve `index.html`, supporting client-side routing.
|
|
109
|
+
- **Playground** — Always available at the API server root. Auto-discovers routes, shows auth levels, generates example payloads.
|
|
110
|
+
|
|
111
|
+
### Custom Ports
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx clawfire dev --port=4000 --api-port=5000
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Or in `clawfire.config.ts`:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
dev: {
|
|
121
|
+
port: 4000,
|
|
122
|
+
apiPort: 5000,
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Project Structure
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
my-app/
|
|
132
|
+
app/
|
|
133
|
+
store.ts In-memory data store (works without Firebase)
|
|
134
|
+
routes/ API route handlers (file-based routing)
|
|
135
|
+
health.ts → POST /api/health
|
|
136
|
+
todos/
|
|
137
|
+
list.ts → POST /api/todos/list
|
|
138
|
+
create.ts → POST /api/todos/create
|
|
139
|
+
update.ts → POST /api/todos/update
|
|
140
|
+
delete.ts → POST /api/todos/delete
|
|
141
|
+
schemas/ Firestore model definitions
|
|
142
|
+
todo.ts
|
|
143
|
+
public/
|
|
144
|
+
index.html Frontend app (vanilla JS, no build step)
|
|
145
|
+
generated/ Auto-generated files (DO NOT EDIT)
|
|
146
|
+
api-client.ts Typed API client
|
|
147
|
+
manifest.json API manifest
|
|
148
|
+
functions/
|
|
149
|
+
index.ts Firebase Functions entry point (for deploy)
|
|
150
|
+
dev.ts Dev server entry point
|
|
151
|
+
clawfire.config.ts Configuration
|
|
152
|
+
firebase.json Firebase config
|
|
153
|
+
firestore.rules Firestore security rules
|
|
154
|
+
firestore.indexes.json Firestore indexes
|
|
155
|
+
CLAUDE.md Project guide for Claude AI
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Core Concepts
|
|
161
|
+
|
|
52
162
|
### Define an API
|
|
53
163
|
|
|
54
|
-
|
|
164
|
+
Every API endpoint is a file in `app/routes/` that exports a `defineAPI` contract:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
55
167
|
// app/routes/products/list.ts
|
|
56
168
|
import { defineAPI, z } from "clawfire";
|
|
57
169
|
|
|
@@ -69,20 +181,137 @@ export default defineAPI({
|
|
|
69
181
|
hasMore: z.boolean(),
|
|
70
182
|
}),
|
|
71
183
|
meta: {
|
|
72
|
-
description: "
|
|
184
|
+
description: "List products",
|
|
73
185
|
auth: "public",
|
|
74
186
|
tags: ["products"],
|
|
75
187
|
},
|
|
76
188
|
handler: async (input, ctx) => {
|
|
77
|
-
// Your business logic here
|
|
78
189
|
return { products: [], hasMore: false };
|
|
79
190
|
},
|
|
80
191
|
});
|
|
81
192
|
```
|
|
82
193
|
|
|
83
|
-
|
|
194
|
+
**Rules:**
|
|
195
|
+
- All APIs are **POST only** — no HTTP method routing
|
|
196
|
+
- `input` and `output` must be `z.object({})`
|
|
197
|
+
- `meta.description` is required
|
|
198
|
+
- `handler` must be `async`
|
|
199
|
+
- File path = API path: `app/routes/products/list.ts` → `POST /api/products/list`
|
|
200
|
+
|
|
201
|
+
### Define a Model
|
|
202
|
+
|
|
203
|
+
Models define Firestore collections and auto-generate security rules:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
// app/schemas/product.ts
|
|
207
|
+
import { defineModel } from "clawfire";
|
|
208
|
+
|
|
209
|
+
export const Product = defineModel({
|
|
210
|
+
collection: "products",
|
|
211
|
+
fields: {
|
|
212
|
+
name: { type: "string", required: true },
|
|
213
|
+
price: { type: "number", required: true },
|
|
214
|
+
category: { type: "string", enum: ["electronics", "clothing"] },
|
|
215
|
+
},
|
|
216
|
+
timestamps: true,
|
|
217
|
+
rules: {
|
|
218
|
+
read: "public",
|
|
219
|
+
create: "role",
|
|
220
|
+
createRoles: ["admin"],
|
|
221
|
+
update: "authenticated",
|
|
222
|
+
delete: "role",
|
|
223
|
+
deleteRoles: ["admin"],
|
|
224
|
+
ownerField: "userId",
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Error Handling
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import { Errors } from "clawfire";
|
|
233
|
+
|
|
234
|
+
throw Errors.notFound("Product not found"); // 404
|
|
235
|
+
throw Errors.validation("Invalid input", err); // 400
|
|
236
|
+
throw Errors.forbidden("No access"); // 403
|
|
237
|
+
throw Errors.unauthorized("Login required"); // 401
|
|
238
|
+
throw Errors.conflict("Already exists"); // 409
|
|
239
|
+
throw Errors.rateLimited("Too many requests"); // 429
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Response format:**
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
// Success
|
|
246
|
+
{ "data": { "products": [...], "hasMore": false } }
|
|
247
|
+
|
|
248
|
+
// Error
|
|
249
|
+
{ "error": { "code": "NOT_FOUND", "message": "Product not found" } }
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Auth Levels
|
|
84
255
|
|
|
85
|
-
|
|
256
|
+
Every API endpoint declares an auth level in `meta.auth`:
|
|
257
|
+
|
|
258
|
+
| Level | Description | Header Required |
|
|
259
|
+
|-------|-------------|-----------------|
|
|
260
|
+
| `public` | No authentication | None |
|
|
261
|
+
| `authenticated` | Must be logged in | `Authorization: Bearer <token>` |
|
|
262
|
+
| `role` | Specific role required | Bearer token + role match |
|
|
263
|
+
| `reauth` | Recent login required (5 min) | Bearer token + fresh |
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
meta: {
|
|
267
|
+
description: "Delete user account",
|
|
268
|
+
auth: "reauth", // Must have re-authenticated within 5 minutes
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Configuration
|
|
275
|
+
|
|
276
|
+
All settings in `clawfire.config.ts`:
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
import { configureClawfire } from "clawfire";
|
|
280
|
+
|
|
281
|
+
export default configureClawfire({
|
|
282
|
+
firebase: {
|
|
283
|
+
apiKey: "...",
|
|
284
|
+
authDomain: "myapp.firebaseapp.com",
|
|
285
|
+
projectId: "my-project",
|
|
286
|
+
appId: "1:123:web:abc",
|
|
287
|
+
},
|
|
288
|
+
server: {
|
|
289
|
+
region: "us-central1",
|
|
290
|
+
cors: ["https://myapp.web.app"],
|
|
291
|
+
rateLimit: 100,
|
|
292
|
+
},
|
|
293
|
+
security: {
|
|
294
|
+
validateInput: true,
|
|
295
|
+
safeHeaders: true,
|
|
296
|
+
maskLogs: true,
|
|
297
|
+
},
|
|
298
|
+
playground: {
|
|
299
|
+
enabled: true,
|
|
300
|
+
},
|
|
301
|
+
dev: {
|
|
302
|
+
port: 3000, // Frontend server
|
|
303
|
+
apiPort: 3456, // API server + Playground
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Production Deployment
|
|
311
|
+
|
|
312
|
+
### Firebase Functions Entry Point
|
|
313
|
+
|
|
314
|
+
```ts
|
|
86
315
|
// functions/index.ts
|
|
87
316
|
import * as admin from "firebase-admin";
|
|
88
317
|
import * as functions from "firebase-functions";
|
|
@@ -106,10 +335,10 @@ export const api = functions.https.onRequest((req, res) => {
|
|
|
106
335
|
});
|
|
107
336
|
```
|
|
108
337
|
|
|
109
|
-
### Client
|
|
338
|
+
### Auto-Generated Client
|
|
110
339
|
|
|
111
|
-
```
|
|
112
|
-
//
|
|
340
|
+
```ts
|
|
341
|
+
// In your frontend code
|
|
113
342
|
import { api, configureClient } from "./generated/api-client";
|
|
114
343
|
import { getAuth } from "firebase/auth";
|
|
115
344
|
|
|
@@ -118,64 +347,118 @@ configureClient("https://us-central1-myapp.cloudfunctions.net", async () => {
|
|
|
118
347
|
return user ? user.getIdToken() : null;
|
|
119
348
|
});
|
|
120
349
|
|
|
350
|
+
// Fully typed — autocomplete and compile-time checking
|
|
121
351
|
const result = await api.products.list({ category: "electronics", limit: 10 });
|
|
122
352
|
```
|
|
123
353
|
|
|
124
|
-
|
|
354
|
+
---
|
|
125
355
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
clawfire.config.ts Clawfire configuration
|
|
356
|
+
## CLI Reference
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
clawfire init # Initialize a new project (starter template)
|
|
360
|
+
clawfire dev # Start dev server (frontend + API + Playground)
|
|
361
|
+
clawfire dev --port=4000 # Custom frontend port
|
|
362
|
+
clawfire dev --api-port=5000 # Custom API port
|
|
363
|
+
clawfire codegen # Generate route imports
|
|
364
|
+
clawfire playground # Generate standalone playground HTML
|
|
365
|
+
clawfire rules # Info about rules generation
|
|
366
|
+
clawfire help # Show help
|
|
138
367
|
```
|
|
139
368
|
|
|
140
|
-
|
|
369
|
+
---
|
|
141
370
|
|
|
142
|
-
|
|
143
|
-
|---------|-------------|
|
|
144
|
-
| `/clawfire-init` | Initialize project / connect Firebase |
|
|
145
|
-
| `/clawfire-model` | Create/modify data models |
|
|
146
|
-
| `/clawfire-api` | Create/modify APIs |
|
|
147
|
-
| `/clawfire-auth` | Configure authentication |
|
|
148
|
-
| `/clawfire-deploy` | Deploy to Firebase |
|
|
149
|
-
| `/clawfire-diagnose` | Diagnose and fix issues |
|
|
371
|
+
## AI Skills (Claude Code)
|
|
150
372
|
|
|
151
|
-
|
|
373
|
+
When using [Claude Code](https://claude.ai/claude-code), these slash commands are available:
|
|
152
374
|
|
|
153
|
-
|
|
|
154
|
-
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
|
167
|
-
|
|
168
|
-
| `clawfire
|
|
169
|
-
| `clawfire/
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
375
|
+
| Command | What It Does |
|
|
376
|
+
|---------|-------------|
|
|
377
|
+
| `/clawfire-init` | Initialize project, connect Firebase, set up config |
|
|
378
|
+
| `/clawfire-model` | Create/modify Firestore models → auto-generates rules + indexes |
|
|
379
|
+
| `/clawfire-api` | Create/modify API endpoints → auto-generates typed client |
|
|
380
|
+
| `/clawfire-auth` | Configure auth policies, roles, guards |
|
|
381
|
+
| `/clawfire-deploy` | Deploy to Firebase (explicit request only) |
|
|
382
|
+
| `/clawfire-diagnose` | Detect missing indexes, rule denials, permission issues |
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Package Exports
|
|
387
|
+
|
|
388
|
+
| Import Path | Contents |
|
|
389
|
+
|-------------|----------|
|
|
390
|
+
| `clawfire` | `defineAPI`, `defineModel`, `z`, `Errors`, `configureClawfire`, `ClawfireError` |
|
|
391
|
+
| `clawfire/functions` | `createRouter`, `createAdminDB`, `verifyToken`, `createSecurityMiddleware` |
|
|
392
|
+
| `clawfire/client` | `createClientAuth` |
|
|
393
|
+
| `clawfire/admin` | `generateFirestoreRules`, `generateFirestoreIndexes`, `setUserRole` |
|
|
394
|
+
| `clawfire/codegen` | `generateClientCode`, `discoverRoutes`, `generateRouteImports` |
|
|
395
|
+
| `clawfire/playground` | `generatePlaygroundHtml` |
|
|
396
|
+
| `clawfire/dev` | `DevServer`, `startDevServer`, `FileWatcher` |
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Security Defaults
|
|
401
|
+
|
|
402
|
+
All security features are **ON by default**:
|
|
403
|
+
|
|
404
|
+
| Feature | Default | Description |
|
|
405
|
+
|---------|---------|-------------|
|
|
406
|
+
| Input Validation | ON | Zod schema validation on every request |
|
|
407
|
+
| CORS | Deny all | Must explicitly allow origins |
|
|
408
|
+
| Rate Limiting | 100 req/min/IP | Per-endpoint configurable |
|
|
409
|
+
| XSS Sanitization | ON | `<` `>` auto-escaped in string inputs |
|
|
410
|
+
| Safe Headers | ON | `X-Frame-Options`, `X-Content-Type-Options` |
|
|
411
|
+
| Log Masking | ON | `password`, `token`, `secret` fields masked |
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Dev vs Production
|
|
416
|
+
|
|
417
|
+
| | Dev Server | Production (Firebase) |
|
|
418
|
+
|--|-----------|----------------------|
|
|
419
|
+
| Frontend | `localhost:3000` (static + HMR) | Firebase Hosting |
|
|
420
|
+
| API | `localhost:3456` | Firebase Functions |
|
|
421
|
+
| Playground | Always on at `:3456` | Configurable |
|
|
422
|
+
| CORS | Allow all (`*`) | Configured origins only |
|
|
423
|
+
| Rate Limiting | Disabled | Enabled |
|
|
424
|
+
| Auth | Optional / mockable | Firebase Auth |
|
|
425
|
+
| Hot Reload | Yes (API + CSS + HTML) | N/A |
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## Documentation
|
|
430
|
+
|
|
431
|
+
Full documentation is in the [`docs/`](./docs/) directory:
|
|
432
|
+
|
|
433
|
+
- [Getting Started](./docs/getting-started.md) — 5-minute quickstart
|
|
434
|
+
- [API Routes](./docs/api-routes.md) — `defineAPI`, file-based routing, handlers
|
|
435
|
+
- [Models](./docs/models.md) — `defineModel`, Firestore collections, rules
|
|
436
|
+
- [Dev Server](./docs/dev-server.md) — Two-port architecture, HMR, Playground
|
|
437
|
+
- [Authentication](./docs/authentication.md) — Auth levels, tokens, roles
|
|
438
|
+
- [Security](./docs/security.md) — Middleware, rate limiting, CORS, sanitization
|
|
439
|
+
- [Configuration](./docs/configuration.md) — All config options and defaults
|
|
440
|
+
- [Client Codegen](./docs/client-codegen.md) — Auto-generated typed API client
|
|
441
|
+
- [Deployment](./docs/deployment.md) — Firebase deploy workflow
|
|
442
|
+
- [CLI Reference](./docs/cli-reference.md) — All CLI commands and flags
|
|
443
|
+
- [Architecture](./docs/architecture.md) — How everything fits together
|
|
444
|
+
- [API Reference](./docs/api-reference.md) — Full TypeScript API reference
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Tech Stack
|
|
449
|
+
|
|
450
|
+
| Layer | Technology |
|
|
451
|
+
|-------|-----------|
|
|
452
|
+
| Database | Firestore |
|
|
453
|
+
| Auth | Firebase Auth |
|
|
454
|
+
| Hosting | Firebase Hosting |
|
|
455
|
+
| Backend | Firebase Functions |
|
|
456
|
+
| Schema | Zod |
|
|
457
|
+
| Language | TypeScript |
|
|
458
|
+
|
|
459
|
+
This stack is fixed by design. Clawfire is opinionated — one way to do things, done well.
|
|
460
|
+
|
|
461
|
+
---
|
|
179
462
|
|
|
180
463
|
## License
|
|
181
464
|
|
package/dist/admin.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { e as ModelDefinition } from './schema-BJsictSV.cjs';
|
|
2
2
|
export { f as ModelField, i as ModelIndex, j as ModelRules, h as defineModel, m as modelToZodSchema } from './schema-BJsictSV.cjs';
|
|
3
|
-
import { C as ClawfireConfig } from './config-
|
|
3
|
+
import { C as ClawfireConfig } from './config-D-Chojiu.cjs';
|
|
4
4
|
export { g as getUserRole, s as setCustomClaims, b as setUserRole } from './auth-DQ3cifhb.cjs';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
package/dist/admin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { e as ModelDefinition } from './schema-BJsictSV.js';
|
|
2
2
|
export { f as ModelField, i as ModelIndex, j as ModelRules, h as defineModel, m as modelToZodSchema } from './schema-BJsictSV.js';
|
|
3
|
-
import { C as ClawfireConfig } from './config-
|
|
3
|
+
import { C as ClawfireConfig } from './config-D-Chojiu.js';
|
|
4
4
|
export { g as getUserRole, s as setCustomClaims, b as setUserRole } from './auth-DtnUPbXT.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
package/dist/cli.js
CHANGED
|
@@ -26,6 +26,11 @@ function printHelp() {
|
|
|
26
26
|
clawfire rules Generate Firestore security rules
|
|
27
27
|
clawfire help Show this help
|
|
28
28
|
|
|
29
|
+
Dev Server Flags:
|
|
30
|
+
--port=<n> Frontend server port (default: 3000)
|
|
31
|
+
--api-port=<n> API server port (default: 3456)
|
|
32
|
+
--no-hot-reload Disable hot reload
|
|
33
|
+
|
|
29
34
|
Most tasks are done through AI Skills, not CLI.
|
|
30
35
|
Run Claude Code and use /clawfire-* commands instead.
|
|
31
36
|
`);
|
|
@@ -182,7 +187,7 @@ export const api = functions.https.onRequest((req, res) => {
|
|
|
182
187
|
console.log(" Next steps:");
|
|
183
188
|
console.log(" \x1B[36m1.\x1B[0m npm install");
|
|
184
189
|
console.log(" \x1B[36m2.\x1B[0m npm run dev");
|
|
185
|
-
console.log(" \x1B[36m3.\x1B[0m Open \x1B[1mhttp://localhost:
|
|
190
|
+
console.log(" \x1B[36m3.\x1B[0m Open \x1B[1mhttp://localhost:3000\x1B[0m in your browser");
|
|
186
191
|
console.log("");
|
|
187
192
|
console.log(" Your Todo app is ready! Try adding, completing, and deleting todos.");
|
|
188
193
|
console.log(" Edit files in \x1B[1mapp/routes/\x1B[0m and see changes instantly.\n");
|
|
@@ -190,12 +195,15 @@ export const api = functions.https.onRequest((req, res) => {
|
|
|
190
195
|
async function runDevServer() {
|
|
191
196
|
const projectDir = process.cwd();
|
|
192
197
|
const portArg = args.find((a) => a.startsWith("--port="));
|
|
193
|
-
const
|
|
198
|
+
const apiPortArg = args.find((a) => a.startsWith("--api-port="));
|
|
199
|
+
const port = portArg ? parseInt(portArg.split("=")[1], 10) : 3e3;
|
|
200
|
+
const apiPort = apiPortArg ? parseInt(apiPortArg.split("=")[1], 10) : 3456;
|
|
194
201
|
const noHotReload = args.includes("--no-hot-reload");
|
|
195
|
-
const { startDevServer } = await import("./dev-server-
|
|
202
|
+
const { startDevServer } = await import("./dev-server-QTNE5N7I.js");
|
|
196
203
|
await startDevServer({
|
|
197
204
|
projectDir,
|
|
198
205
|
port,
|
|
206
|
+
apiPort,
|
|
199
207
|
hotReload: !noHotReload
|
|
200
208
|
});
|
|
201
209
|
}
|
|
@@ -39,6 +39,13 @@ interface ClawfireConfig {
|
|
|
39
39
|
/** 경로 */
|
|
40
40
|
path?: string;
|
|
41
41
|
};
|
|
42
|
+
/** 개발 서버 설정 */
|
|
43
|
+
dev?: {
|
|
44
|
+
/** 프론트엔드 서버 포트 (기본: 3000) */
|
|
45
|
+
port?: number;
|
|
46
|
+
/** API 서버 포트 (기본: 3456) */
|
|
47
|
+
apiPort?: number;
|
|
48
|
+
};
|
|
42
49
|
}
|
|
43
50
|
declare function configureClawfire(config: ClawfireConfig): ClawfireConfig;
|
|
44
51
|
declare function getConfig(): ClawfireConfig;
|
|
@@ -39,6 +39,13 @@ interface ClawfireConfig {
|
|
|
39
39
|
/** 경로 */
|
|
40
40
|
path?: string;
|
|
41
41
|
};
|
|
42
|
+
/** 개발 서버 설정 */
|
|
43
|
+
dev?: {
|
|
44
|
+
/** 프론트엔드 서버 포트 (기본: 3000) */
|
|
45
|
+
port?: number;
|
|
46
|
+
/** API 서버 포트 (기본: 3456) */
|
|
47
|
+
apiPort?: number;
|
|
48
|
+
};
|
|
42
49
|
}
|
|
43
50
|
declare function configureClawfire(config: ClawfireConfig): ClawfireConfig;
|
|
44
51
|
declare function getConfig(): ClawfireConfig;
|