chadstart 1.0.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/.dockerignore +10 -0
- package/.env.example +46 -0
- package/.github/workflows/browser-test.yml +34 -0
- package/.github/workflows/docker-publish.yml +54 -0
- package/.github/workflows/docs.yml +31 -0
- package/.github/workflows/npm-chadstart.yml +27 -0
- package/.github/workflows/npm-sdk.yml +38 -0
- package/.github/workflows/test.yml +85 -0
- package/.weblate +9 -0
- package/Dockerfile +23 -0
- package/README.md +348 -0
- package/admin/index.html +2802 -0
- package/admin/login.html +207 -0
- package/chadstart.example.yml +416 -0
- package/chadstart.schema.json +367 -0
- package/chadstart.yaml +53 -0
- package/cli/cli.js +295 -0
- package/core/api-generator.js +606 -0
- package/core/auth.js +298 -0
- package/core/db.js +384 -0
- package/core/entity-engine.js +166 -0
- package/core/error-reporter.js +132 -0
- package/core/file-storage.js +97 -0
- package/core/functions-engine.js +353 -0
- package/core/openapi.js +171 -0
- package/core/plugin-loader.js +92 -0
- package/core/realtime.js +93 -0
- package/core/schema-validator.js +50 -0
- package/core/seeder.js +231 -0
- package/core/telemetry.js +119 -0
- package/core/upload.js +372 -0
- package/core/workers/php_worker.php +19 -0
- package/core/workers/python_worker.py +33 -0
- package/core/workers/ruby_worker.rb +21 -0
- package/core/yaml-loader.js +64 -0
- package/demo/chadstart.yaml +178 -0
- package/demo/docker-compose.yml +31 -0
- package/demo/functions/greet.go +39 -0
- package/demo/functions/hello.cpp +18 -0
- package/demo/functions/hello.py +13 -0
- package/demo/functions/hello.rb +10 -0
- package/demo/functions/onTodoCreated.js +13 -0
- package/demo/functions/ping.sh +13 -0
- package/demo/functions/stats.js +22 -0
- package/demo/public/index.html +522 -0
- package/docker-compose.yml +17 -0
- package/docs/access-policies.md +155 -0
- package/docs/admin-ui.md +29 -0
- package/docs/angular.md +69 -0
- package/docs/astro.md +71 -0
- package/docs/auth.md +160 -0
- package/docs/cli.md +56 -0
- package/docs/config.md +127 -0
- package/docs/crud.md +627 -0
- package/docs/deploy.md +113 -0
- package/docs/docker.md +59 -0
- package/docs/entities.md +385 -0
- package/docs/functions.md +196 -0
- package/docs/getting-started.md +79 -0
- package/docs/groups.md +85 -0
- package/docs/index.md +5 -0
- package/docs/llm-rules.md +81 -0
- package/docs/middlewares.md +78 -0
- package/docs/overrides/home.html +350 -0
- package/docs/plugins.md +59 -0
- package/docs/react.md +75 -0
- package/docs/realtime.md +43 -0
- package/docs/s3-storage.md +40 -0
- package/docs/security.md +23 -0
- package/docs/stylesheets/extra.css +375 -0
- package/docs/svelte.md +71 -0
- package/docs/telemetry.md +97 -0
- package/docs/upload.md +168 -0
- package/docs/validation.md +115 -0
- package/docs/vue.md +86 -0
- package/docs/webhooks.md +87 -0
- package/index.js +11 -0
- package/locales/en/admin.json +169 -0
- package/mkdocs.yml +82 -0
- package/package.json +65 -0
- package/playwright.config.js +24 -0
- package/public/.gitkeep +0 -0
- package/sdk/README.md +284 -0
- package/sdk/package.json +39 -0
- package/sdk/scripts/build.js +58 -0
- package/sdk/src/index.js +368 -0
- package/sdk/test/sdk.test.cjs +340 -0
- package/sdk/types/index.d.ts +217 -0
- package/server/express-server.js +734 -0
- package/test/access-policies.test.js +96 -0
- package/test/ai.test.js +81 -0
- package/test/api-keys.test.js +361 -0
- package/test/auth.test.js +122 -0
- package/test/browser/admin-ui.spec.js +127 -0
- package/test/browser/global-setup.js +71 -0
- package/test/browser/global-teardown.js +11 -0
- package/test/db.test.js +227 -0
- package/test/entity-engine.test.js +193 -0
- package/test/error-reporter.test.js +140 -0
- package/test/functions-engine.test.js +240 -0
- package/test/groups.test.js +212 -0
- package/test/hot-reload.test.js +153 -0
- package/test/i18n.test.js +173 -0
- package/test/middleware.test.js +76 -0
- package/test/openapi.test.js +67 -0
- package/test/schema-validator.test.js +83 -0
- package/test/sdk.test.js +90 -0
- package/test/seeder.test.js +279 -0
- package/test/settings.test.js +109 -0
- package/test/telemetry.test.js +254 -0
- package/test/test.js +17 -0
- package/test/upload.test.js +265 -0
- package/test/validation.test.js +96 -0
- package/test/yaml-loader.test.js +93 -0
- package/utils/logger.js +24 -0
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# ChadStart
|
|
2
|
+
|
|
3
|
+
> YAML-first Backend as a Service — define your entire backend in a single YAML file.
|
|
4
|
+
|
|
5
|
+
Inspired by [Manifest](https://backend.manifest.build/), ChadStart auto-generates a fully functional backend — database schema, REST API, realtime subscriptions, OpenAPI docs, file storage, plugin system, **JWT authentication**, and an **Admin UI** — from one `chadstart.yaml` file.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Docker
|
|
14
|
+
|
|
15
|
+
**Run with `docker run`:**
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Create your chadstart.yaml first (see Configuration section below), then:
|
|
19
|
+
docker run -p 3000:3000 \
|
|
20
|
+
-e JWT_SECRET=your-secret \
|
|
21
|
+
-e DB_PATH=data/chadstart.db \
|
|
22
|
+
-v ./chadstart.yaml:/app/chadstart.yaml:ro \
|
|
23
|
+
-v ./data:/app/data \
|
|
24
|
+
ghcr.io/saulmmendoza/chadstart.com:latest
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Run with `docker compose`:**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 1. Create a .env file with your secrets:
|
|
31
|
+
echo "JWT_SECRET=$(openssl rand -hex 32)" > .env
|
|
32
|
+
|
|
33
|
+
# 2. Have a chadstart.yaml ready (see Configuration section below), then:
|
|
34
|
+
docker compose up
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
See [`docker-compose.yml`](docker-compose.yml) for the full example.
|
|
38
|
+
|
|
39
|
+
Create a `chadstart.yaml`:
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
name: Blog
|
|
43
|
+
|
|
44
|
+
entities:
|
|
45
|
+
Admin:
|
|
46
|
+
authenticable: true
|
|
47
|
+
properties:
|
|
48
|
+
- name
|
|
49
|
+
Customer:
|
|
50
|
+
authenticable: true
|
|
51
|
+
properties:
|
|
52
|
+
- name
|
|
53
|
+
- phone
|
|
54
|
+
|
|
55
|
+
Post:
|
|
56
|
+
properties:
|
|
57
|
+
- title
|
|
58
|
+
- content
|
|
59
|
+
- published
|
|
60
|
+
policies:
|
|
61
|
+
create:
|
|
62
|
+
- { access: restricted, allow: Admin }
|
|
63
|
+
read:
|
|
64
|
+
- access: public
|
|
65
|
+
update:
|
|
66
|
+
- { access: restricted, allow: Admin }
|
|
67
|
+
delete:
|
|
68
|
+
- { access: restricted, allow: Admin }
|
|
69
|
+
Comment:
|
|
70
|
+
properties:
|
|
71
|
+
- text
|
|
72
|
+
belongsTo:
|
|
73
|
+
- Post
|
|
74
|
+
policies:
|
|
75
|
+
create:
|
|
76
|
+
- access: restricted
|
|
77
|
+
read:
|
|
78
|
+
- access: public
|
|
79
|
+
|
|
80
|
+
files:
|
|
81
|
+
uploads:
|
|
82
|
+
path: ./uploads
|
|
83
|
+
public: true
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Start the server:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx chadstart dev # development with hot-reload
|
|
90
|
+
npx chadstart start # production
|
|
91
|
+
npx chadstart build # validate config and print summary
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## What Gets Generated
|
|
95
|
+
|
|
96
|
+
From the YAML above, ChadStart automatically provides:
|
|
97
|
+
|
|
98
|
+
| Feature | URL |
|
|
99
|
+
|---------|-----|
|
|
100
|
+
| REST API | `/api/posts`, `/api/comments`, ... |
|
|
101
|
+
| Auth (signup/login/me) | `/auth/admin/signup`, `/auth/admin/login`, ... |
|
|
102
|
+
| Admin UI | `/admin` |
|
|
103
|
+
| Swagger UI | `/docs` |
|
|
104
|
+
| OpenAPI JSON | `/openapi.json` |
|
|
105
|
+
| Realtime WebSocket | `ws://localhost:3000/realtime` |
|
|
106
|
+
| File uploads | `POST /files/uploads` |
|
|
107
|
+
| Health check | `/health` |
|
|
108
|
+
|
|
109
|
+
## Authentication & User Collections
|
|
110
|
+
|
|
111
|
+
User collections are entities with `authenticable: true`, gaining built-in `email` + `password` fields. Each one generates its own auth endpoints.
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
entities:
|
|
115
|
+
Admin:
|
|
116
|
+
authenticable: true
|
|
117
|
+
properties:
|
|
118
|
+
- name # extra fields beyond email + password
|
|
119
|
+
Customer:
|
|
120
|
+
authenticable: true
|
|
121
|
+
properties:
|
|
122
|
+
- name
|
|
123
|
+
- phone
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Auth Endpoints
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
POST /api/auth/admin/signup { email, password, name } → { token, user }
|
|
130
|
+
POST /api/auth/admin/login { email, password } → { token, user }
|
|
131
|
+
GET /api/auth/admin/me Authorization: Bearer <token> → user
|
|
132
|
+
|
|
133
|
+
POST /api/auth/customer/signup { email, password, ... } → { token, user }
|
|
134
|
+
POST /api/auth/customer/login ...
|
|
135
|
+
GET /api/auth/customer/me ...
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Passwords are hashed with **bcrypt**. Tokens are signed **JWT** (7-day expiry by default).
|
|
139
|
+
|
|
140
|
+
**Environment variables:**
|
|
141
|
+
```bash
|
|
142
|
+
JWT_SECRET=<long-random-string> # Required in production (NODE_ENV=production)
|
|
143
|
+
JWT_EXPIRES=7d # Optional — default 7d
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> ⚠️ `JWT_SECRET` defaults to a well-known dev value. Always set it in production.
|
|
147
|
+
|
|
148
|
+
## Entity Policies
|
|
149
|
+
|
|
150
|
+
Restrict who can read or write each entity using `policies`:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
entities:
|
|
154
|
+
Post:
|
|
155
|
+
policies:
|
|
156
|
+
read:
|
|
157
|
+
- access: public # anyone
|
|
158
|
+
create:
|
|
159
|
+
- { access: restricted, allow: Admin } # only authenticated Admins
|
|
160
|
+
Comment:
|
|
161
|
+
policies:
|
|
162
|
+
read:
|
|
163
|
+
- access: public
|
|
164
|
+
create:
|
|
165
|
+
- access: restricted # any authenticated user
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Access values:
|
|
169
|
+
| Value | Meaning |
|
|
170
|
+
|-------|---------|
|
|
171
|
+
| `public` | No auth required |
|
|
172
|
+
| `restricted` | Any authenticated user |
|
|
173
|
+
| `admin` | Admin entities only |
|
|
174
|
+
| `forbidden` | No access |
|
|
175
|
+
|
|
176
|
+
Emoji shortcuts: 🌐 = public, 🔒 = restricted, 👨🏻💻 = admin, 🚫 = forbidden
|
|
177
|
+
|
|
178
|
+
## Admin UI
|
|
179
|
+
|
|
180
|
+
A built-in dark-mode SPA at `/admin`:
|
|
181
|
+
|
|
182
|
+
- **Sidebar** with all entities and user collections
|
|
183
|
+
- **Data table** with CRUD (create, edit, delete) for every record
|
|
184
|
+
- **Login screen** — any user collection with `admin: true` (default) can sign in
|
|
185
|
+
|
|
186
|
+
> Multiple user collections can access the Admin UI. Set `admin: false` on a collection to exclude it.
|
|
187
|
+
|
|
188
|
+
## REST API
|
|
189
|
+
|
|
190
|
+
Standard CRUD for every entity:
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
GET /api/posts → list all (supports query filters)
|
|
194
|
+
GET /api/posts/:id → get one
|
|
195
|
+
POST /api/posts → create
|
|
196
|
+
PATCH /api/posts/:id → update
|
|
197
|
+
DELETE /api/posts/:id → delete
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Filter by any property:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
GET /api/posts?published=true
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Realtime
|
|
207
|
+
|
|
208
|
+
Connect via WebSocket at `ws://localhost:3000/realtime`:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
const ws = new WebSocket('ws://localhost:3000/realtime');
|
|
212
|
+
ws.send(JSON.stringify({ type: 'subscribe', channel: 'Post' }));
|
|
213
|
+
ws.onmessage = (e) => {
|
|
214
|
+
const { event, data } = JSON.parse(e.data);
|
|
215
|
+
// event: 'Post.created' | 'Post.updated' | 'Post.deleted'
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Subscribe to `*` to receive all events.
|
|
220
|
+
|
|
221
|
+
## File Storage
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
files:
|
|
225
|
+
uploads:
|
|
226
|
+
path: ./uploads
|
|
227
|
+
public: true
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
curl -F "file=@photo.jpg" http://localhost:3000/files/uploads # upload
|
|
232
|
+
GET /files/uploads/photo.jpg # download
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Plugin System
|
|
236
|
+
|
|
237
|
+
```yaml
|
|
238
|
+
plugins:
|
|
239
|
+
- repo: https://github.com/org/chadstart-plugin-auth
|
|
240
|
+
- path: ./my-local-plugin
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Plugin interface:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
module.exports = {
|
|
247
|
+
name: 'my-plugin',
|
|
248
|
+
register(app, core) {
|
|
249
|
+
app.get('/custom', (req, res) => res.json({ hello: 'world' }));
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
> ⚠️ Remote plugins execute arbitrary code. Only load plugins from trusted sources.
|
|
255
|
+
|
|
256
|
+
## YAML Schema Reference
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
name: string # Required — project name
|
|
260
|
+
port: 3000 # Optional — default 3000
|
|
261
|
+
|
|
262
|
+
entities:
|
|
263
|
+
EntityName:
|
|
264
|
+
authenticable: true # optional — makes entity a user collection with email+password
|
|
265
|
+
single: true # optional — makes entity a singleton (one record)
|
|
266
|
+
properties:
|
|
267
|
+
- fieldName # string shorthand (type: string)
|
|
268
|
+
- name: fieldName
|
|
269
|
+
type: string|integer|number|boolean|date|json
|
|
270
|
+
belongsTo:
|
|
271
|
+
- OtherEntity
|
|
272
|
+
policies:
|
|
273
|
+
create:
|
|
274
|
+
- access: public|restricted|admin|forbidden
|
|
275
|
+
- { access: restricted, allow: CollectionName }
|
|
276
|
+
read:
|
|
277
|
+
- access: public
|
|
278
|
+
update:
|
|
279
|
+
- access: restricted
|
|
280
|
+
delete:
|
|
281
|
+
- access: restricted
|
|
282
|
+
|
|
283
|
+
files:
|
|
284
|
+
bucketName:
|
|
285
|
+
path: ./uploads
|
|
286
|
+
public: true
|
|
287
|
+
|
|
288
|
+
public:
|
|
289
|
+
folder: ./public
|
|
290
|
+
|
|
291
|
+
plugins:
|
|
292
|
+
- repo: https://github.com/org/plugin
|
|
293
|
+
- path: ./local-plugin
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Rate Limiting
|
|
297
|
+
|
|
298
|
+
Auth endpoints: 30 req / 15 min per IP
|
|
299
|
+
API endpoints: 200 req / min per IP
|
|
300
|
+
Admin UI: 100 req / min per IP
|
|
301
|
+
|
|
302
|
+
## Project Structure
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
chadstart/
|
|
306
|
+
core/
|
|
307
|
+
yaml-loader.js # Read & parse chadstart.yaml
|
|
308
|
+
schema-validator.js # Validate YAML structure
|
|
309
|
+
entity-engine.js # Build internal model from config
|
|
310
|
+
db.js # SQLite CRUD layer
|
|
311
|
+
auth.js # JWT auth + user collection endpoints
|
|
312
|
+
api-generator.js # Generate Express REST routes with permission enforcement
|
|
313
|
+
realtime.js # WebSocket realtime subscriptions
|
|
314
|
+
openapi.js # OpenAPI 3.0 spec generator
|
|
315
|
+
file-storage.js # File upload/download routes
|
|
316
|
+
plugin-loader.js # Dynamic plugin loading
|
|
317
|
+
server/
|
|
318
|
+
express-server.js # Bootstrap everything together
|
|
319
|
+
admin/
|
|
320
|
+
index.html # Admin UI single-page app
|
|
321
|
+
cli/
|
|
322
|
+
cli.js # npx chadstart dev|start|build
|
|
323
|
+
utils/
|
|
324
|
+
logger.js # Simple leveled logger
|
|
325
|
+
test/
|
|
326
|
+
test.js # Built-in tests (39)
|
|
327
|
+
chadstart.yaml # Example config
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## CLI
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
npx chadstart dev [--config path] [--port N] # Hot-reload dev server
|
|
334
|
+
npx chadstart start [--config path] [--port N] # Production server
|
|
335
|
+
npx chadstart build [--config path] # Validate & summarize config
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Design Principles
|
|
339
|
+
|
|
340
|
+
- **YAML-first** — one file defines everything
|
|
341
|
+
- **Minimal dependencies** — express, ws, yaml, better-sqlite3, bcryptjs, jsonwebtoken, swagger-ui-express, express-rate-limit
|
|
342
|
+
- **Readable code** — easy to hack and extend
|
|
343
|
+
- **No magic** — every generated route is straightforward Express code
|
|
344
|
+
- **Self-hosted** — runs anywhere Node.js runs
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
ISC
|