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
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: functions
|
|
3
|
+
title: Functions
|
|
4
|
+
description: Add custom functions to your ChadStart app — with multiple runtimes, triggers, and formats.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Functions
|
|
8
|
+
|
|
9
|
+
## Introduction
|
|
10
|
+
|
|
11
|
+
Functions let you run custom logic on the server. Each function can be triggered by one or more events: an HTTP request, a scheduled cron job, or an emitted application event.
|
|
12
|
+
|
|
13
|
+
## Syntax
|
|
14
|
+
|
|
15
|
+
```yaml title="chadstart.yaml"
|
|
16
|
+
functions:
|
|
17
|
+
hello:
|
|
18
|
+
runtime: js # js (default) | bash | python | go | c++ | ruby | php
|
|
19
|
+
function: hello.js # file path relative to /functions (or CHADSTART_FUNCTIONS_FOLDER)
|
|
20
|
+
triggers:
|
|
21
|
+
- type: http
|
|
22
|
+
method: GET
|
|
23
|
+
path: /hello
|
|
24
|
+
- type: cron
|
|
25
|
+
schedule: "@daily"
|
|
26
|
+
- type: event
|
|
27
|
+
name: user.created
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Triggers
|
|
31
|
+
|
|
32
|
+
### HTTP trigger
|
|
33
|
+
|
|
34
|
+
Registers an HTTP route. The function receives an `event` object and a `ctx` context.
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
triggers:
|
|
38
|
+
- type: http
|
|
39
|
+
method: GET # GET | POST | PUT | PATCH | DELETE
|
|
40
|
+
path: /hello
|
|
41
|
+
# policies omitted → public (anyone can call)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Access policies
|
|
45
|
+
|
|
46
|
+
Add a `policies` array to restrict who can call an HTTP trigger:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
triggers:
|
|
50
|
+
- type: http
|
|
51
|
+
method: GET
|
|
52
|
+
path: /public-data
|
|
53
|
+
policies:
|
|
54
|
+
- access: public # Anyone can call (default when omitted)
|
|
55
|
+
|
|
56
|
+
- type: http
|
|
57
|
+
method: GET
|
|
58
|
+
path: /admin-data
|
|
59
|
+
policies:
|
|
60
|
+
- access: admin # Any valid JWT is required
|
|
61
|
+
|
|
62
|
+
- type: http
|
|
63
|
+
method: GET
|
|
64
|
+
path: /customer-data
|
|
65
|
+
policies:
|
|
66
|
+
- access: restricted # JWT required, filtered by entity
|
|
67
|
+
allow: Customer # Only Customer tokens are allowed (string or array)
|
|
68
|
+
|
|
69
|
+
- type: http
|
|
70
|
+
method: GET
|
|
71
|
+
path: /disabled
|
|
72
|
+
policies:
|
|
73
|
+
- access: forbidden # Always returns 403
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Policy access values:**
|
|
77
|
+
|
|
78
|
+
| Value | Emoji alias | Description |
|
|
79
|
+
| ------------ | ----------- | ----------------------------------------------------------------- |
|
|
80
|
+
| `public` | `🌐` | Open to everyone (default when `policies` is omitted) |
|
|
81
|
+
| `admin` | `👨🏻💻` | Requires any valid JWT (any entity) |
|
|
82
|
+
| `restricted` | `🔒` | Requires a valid JWT; combine with `allow` to limit to an entity |
|
|
83
|
+
| `forbidden` | `🚫` | Always returns 403 — disables the route |
|
|
84
|
+
|
|
85
|
+
### Cron trigger
|
|
86
|
+
|
|
87
|
+
Runs the function on a schedule. Supports standard cron expressions and predefined aliases.
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
triggers:
|
|
91
|
+
- type: cron
|
|
92
|
+
schedule: "*/10 * * * *" # every 10 minutes
|
|
93
|
+
- type: cron
|
|
94
|
+
schedule: "@daily" # once a day at midnight
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Predefined aliases:**
|
|
98
|
+
|
|
99
|
+
| Alias | Equivalent | Description |
|
|
100
|
+
| ----------- | --------------- | ------------------------ |
|
|
101
|
+
| `@yearly` | `0 0 1 1 *` | Once a year, Jan 1st |
|
|
102
|
+
| `@annually` | `0 0 1 1 *` | Same as @yearly |
|
|
103
|
+
| `@monthly` | `0 0 1 * *` | First day of each month |
|
|
104
|
+
| `@weekly` | `0 0 * * 0` | Every Sunday at midnight |
|
|
105
|
+
| `@daily` | `0 0 * * *` | Every day at midnight |
|
|
106
|
+
| `@midnight` | `0 0 * * *` | Same as @daily |
|
|
107
|
+
| `@hourly` | `0 * * * *` | Every hour |
|
|
108
|
+
|
|
109
|
+
### Event trigger
|
|
110
|
+
|
|
111
|
+
Runs the function when a named event is emitted via the shared `eventBus`.
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
triggers:
|
|
115
|
+
- type: event
|
|
116
|
+
name: user.created
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Emit from middleware or other functions:
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
const { eventBus } = require('./core/functions-engine');
|
|
123
|
+
eventBus.emit('user.created', { id: user.id });
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Function formats (JS runtime)
|
|
127
|
+
|
|
128
|
+
### Universal (recommended)
|
|
129
|
+
|
|
130
|
+
```js title="functions/hello.js"
|
|
131
|
+
module.exports = async function(event, ctx) {
|
|
132
|
+
if (ctx.trigger === 'http') return { message: 'Hello from HTTP!' };
|
|
133
|
+
if (ctx.trigger === 'cron') console.log('Running scheduled task');
|
|
134
|
+
if (ctx.trigger === 'event') console.log('Event payload:', event);
|
|
135
|
+
};
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The `event` object for HTTP triggers contains `{ req, body, query, params, headers }`.
|
|
139
|
+
The `ctx` object always has `{ trigger, name }` plus trigger-specific fields (`method`, `path`, `schedule`, `event`).
|
|
140
|
+
|
|
141
|
+
### AWS Lambda format
|
|
142
|
+
|
|
143
|
+
```js title="functions/hello.js"
|
|
144
|
+
exports.handler = async (event, context) => {
|
|
145
|
+
return { statusCode: 200, body: JSON.stringify({ message: 'Hello!' }) };
|
|
146
|
+
};
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Cloudflare Workers format
|
|
150
|
+
|
|
151
|
+
```js title="functions/hello.js"
|
|
152
|
+
export default {
|
|
153
|
+
async fetch(request) {
|
|
154
|
+
return new Response(JSON.stringify({ message: 'Hello!' }), {
|
|
155
|
+
headers: { 'Content-Type': 'application/json' },
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Runtimes
|
|
162
|
+
|
|
163
|
+
| Runtime | Execution | Notes |
|
|
164
|
+
| -------- | ------------------ | -------------------------------- |
|
|
165
|
+
| `js` | In-process | Default. Supports all formats. |
|
|
166
|
+
| `python` | Persistent worker | Reads `event` from stdin as JSON |
|
|
167
|
+
| `ruby` | Persistent worker | Reads `event` from stdin as JSON |
|
|
168
|
+
| `php` | Persistent worker | Reads `event` from stdin as JSON |
|
|
169
|
+
| `bash` | Per-invocation | Reads `event` from stdin as JSON |
|
|
170
|
+
| `go` | Per-invocation | `go run` per invocation |
|
|
171
|
+
| `c++` | Per-invocation | Compiled with `g++` |
|
|
172
|
+
|
|
173
|
+
Python/Ruby/PHP runtimes spawn one persistent worker process per runtime (not per request) for better performance.
|
|
174
|
+
|
|
175
|
+
## Configuration
|
|
176
|
+
|
|
177
|
+
### Function options
|
|
178
|
+
|
|
179
|
+
| Option | Default | Description |
|
|
180
|
+
| ------------ | ------- | ---------------------------------------------------- |
|
|
181
|
+
| `function`* | — | File name relative to the functions folder |
|
|
182
|
+
| `runtime` | `js` | Runtime to use |
|
|
183
|
+
| `description`| — | Optional description (shown in OpenAPI docs) |
|
|
184
|
+
| `triggers`* | — | Array of trigger definitions |
|
|
185
|
+
|
|
186
|
+
### HTTP trigger options
|
|
187
|
+
|
|
188
|
+
| Option | Default | Description |
|
|
189
|
+
| ---------- | -------- | -------------------------------------------------------- |
|
|
190
|
+
| `type`* | — | `http` |
|
|
191
|
+
| `method` | `GET` | HTTP verb: `GET` `POST` `PUT` `PATCH` `DELETE` |
|
|
192
|
+
| `path`* | — | URL path, e.g. `/hello` or `/users/:id/activate` |
|
|
193
|
+
| `policies` | `public` | Array of policy objects to restrict access (see above) |
|
|
194
|
+
|
|
195
|
+
!!! tip
|
|
196
|
+
Set `CHADSTART_FUNCTIONS_FOLDER` in your `.env` to use a different folder than `/functions`.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Get Started
|
|
3
|
+
description: ChadStart is an Open Source backend that fits in a single YAML file. Easy to edit, validate and version for humans and LLMs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Get Started 👋
|
|
7
|
+
|
|
8
|
+
## Introduction
|
|
9
|
+
|
|
10
|
+
ChadStart is a **1-file backend** for prototypes and MVPs.
|
|
11
|
+
|
|
12
|
+
Most backend tools feel too heavy for simple apps. They force you to use bloated configuration UIs. Even with AI tools that generate frontend code, the backend remains a pain to set up and validate. It slows you down when you just want to test an idea or build something simple.
|
|
13
|
+
|
|
14
|
+
ChadStart is an open source backend that fits in only 1 file. You define it in a simple yaml language to get data, auth, storage, logic and an admin panel.
|
|
15
|
+
|
|
16
|
+
**Key advantages:**
|
|
17
|
+
|
|
18
|
+
- 🧠 Zero friction setup
|
|
19
|
+
- 🚀 Ship your backend fast and stay focused on building your app
|
|
20
|
+
- 🤖 Easy for LLMs to generate
|
|
21
|
+
- 💻 Can run everywhere
|
|
22
|
+
|
|
23
|
+
## Install ChadStart
|
|
24
|
+
|
|
25
|
+
Follow the steps below to install ChadStart in your local machine.
|
|
26
|
+
|
|
27
|
+
### Prerequisites
|
|
28
|
+
|
|
29
|
+
- [NodeJS](https://nodejs.org/en/) (**20.x** or superior).
|
|
30
|
+
|
|
31
|
+
### Installation steps
|
|
32
|
+
|
|
33
|
+
Run this command to create a ChadStart project ready to use with Cursor IDE.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# NPX
|
|
37
|
+
npx chadstart my-project --cursor
|
|
38
|
+
|
|
39
|
+
# Yarn
|
|
40
|
+
yarn create chadstart my-project --cursor
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This will create a `my-project` folder with a ChadStart backend configured for Cursor.
|
|
44
|
+
|
|
45
|
+
You can replace `--cursor` with another option if you're using a different AI tool:
|
|
46
|
+
|
|
47
|
+
- `--copilot` if you're using **GitHub Copilot**
|
|
48
|
+
- `--windsurf` for **Windsurf**
|
|
49
|
+
- or remove it entirely if you're not using any AI coding tool
|
|
50
|
+
|
|
51
|
+
To start the ChadStart backend, run the following command in the new project folder:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
cd my-project
|
|
55
|
+
npm run start
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
You can now:
|
|
59
|
+
|
|
60
|
+
- See your **Admin panel** at http://localhost:3000 using the email `admin@chadstart.com` and the password `admin`
|
|
61
|
+
|
|
62
|
+
- Use your **REST API** at http://localhost:3000/api
|
|
63
|
+
|
|
64
|
+
!!! tip
|
|
65
|
+
If you already have a frontend app, we recommend that you use a **monorepo** structure with one folder for the backend and one folder for the frontend. For example you can run `npx chadstart server` at root level to add your ChadStart to a `server` folder that you put next to the `client` folder that will contain your frontend.
|
|
66
|
+
|
|
67
|
+
#### Note with PNPM
|
|
68
|
+
|
|
69
|
+
As [PNPM](https://pnpm.io/fr/) blocks postinstall scripts, we have to adapt the `package.json`. Add this to your `package.json` file before doing `pnpm install`:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
"pnpm": {
|
|
73
|
+
"onlyBuiltDependencies": [
|
|
74
|
+
"@nestjs/core",
|
|
75
|
+
"sharp",
|
|
76
|
+
"sqlite3"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
```
|
package/docs/groups.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: groups
|
|
3
|
+
title: Groups (nested entities)
|
|
4
|
+
slug: groups
|
|
5
|
+
description: TODO
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Groups (nested entities)
|
|
9
|
+
|
|
10
|
+
A group is a **reusable set of properties** that you can attach to your entities: whether they are [single](./entities.md#singles) or [collections](./entities.md#collections). They help you structure your nested data without having to repeat yourself. Some common use cases for groups are:
|
|
11
|
+
|
|
12
|
+
- Testimonials
|
|
13
|
+
- FAQs
|
|
14
|
+
- Widgets (CTA, UI elements like cards, blocks etc.)
|
|
15
|
+
|
|
16
|
+
Groups are automatically loaded when you fetch a list or a detail version of the parent entity (using both REST API and SDK).
|
|
17
|
+
|
|
18
|
+
## Syntax
|
|
19
|
+
|
|
20
|
+
Define your groups in the `chadstart.yaml` file to use it in entities as a property.
|
|
21
|
+
|
|
22
|
+
```yaml title="chadstart.yaml"
|
|
23
|
+
entities:
|
|
24
|
+
Service:
|
|
25
|
+
properties:
|
|
26
|
+
- name
|
|
27
|
+
- { name: description, helpText: 'Description of the service' }
|
|
28
|
+
- {
|
|
29
|
+
name: testimonials,
|
|
30
|
+
type: group, # Group type indicates that it is a group.
|
|
31
|
+
helpText: 'Add some testimonials for the service',
|
|
32
|
+
options: { group: Testimonial } # Pass the name of the group in the "group" option
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
groups:
|
|
36
|
+
Testimonial: # We create a testimonial group with 3 properties.
|
|
37
|
+
properties:
|
|
38
|
+
- { name: author, type: text }
|
|
39
|
+
- { name: content, type: text }
|
|
40
|
+
- { name: rating, type: number, helpText: '1 to 5 stars' }
|
|
41
|
+
validation:
|
|
42
|
+
rating: { isNotEmpty: true }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The code above will add testimonials to service. Once the `Testimonial` group is created, you can add it in as many entities as you want.
|
|
46
|
+
|
|
47
|
+
## Non-multiple groups
|
|
48
|
+
|
|
49
|
+
In the example above, each service can have several testimonials, but you can also have non-multiple groups.
|
|
50
|
+
|
|
51
|
+
This example shows a backend for a website where each page has a single "call to action" element that can be used as widget UI.
|
|
52
|
+
|
|
53
|
+
```yaml title="chadstart.yaml"
|
|
54
|
+
Homepage:
|
|
55
|
+
single: true
|
|
56
|
+
properties:
|
|
57
|
+
- { name: title, type: text }
|
|
58
|
+
- {
|
|
59
|
+
name: callToAction,
|
|
60
|
+
type: group,
|
|
61
|
+
options: { group: CallToAction, multiple: false }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
AboutPage:
|
|
65
|
+
single: true
|
|
66
|
+
properties:
|
|
67
|
+
- { name: title, type: text }
|
|
68
|
+
- { name: description, type: text }
|
|
69
|
+
- {
|
|
70
|
+
name: callToAction,
|
|
71
|
+
type: group,
|
|
72
|
+
options: { group: CallToAction, multiple: false }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
groups:
|
|
76
|
+
CallToAction:
|
|
77
|
+
properties:
|
|
78
|
+
- { name: title, type: string }
|
|
79
|
+
- { name: description, type: text }
|
|
80
|
+
- { name: buttonText, type: string, helpText: "Text for the button" }
|
|
81
|
+
- { name: buttonLink, type: link }
|
|
82
|
+
validation:
|
|
83
|
+
title: { isNotEmpty: true }
|
|
84
|
+
description: { isNotEmpty: true }
|
|
85
|
+
```
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: llm-rules
|
|
3
|
+
title: LLM Rules
|
|
4
|
+
description: Configure AI coding assistants to understand your ChadStart YAML backend. Works with Cursor, GitHub Copilot, Windsurf, and more.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# LLM Rules
|
|
8
|
+
|
|
9
|
+
ChadStart is designed to be **LLM-friendly**: the entire backend is described in a single YAML file that AI coding assistants can read, generate, and modify with ease.
|
|
10
|
+
|
|
11
|
+
When you scaffold a new project with the `--cursor`, `--copilot`, or `--windsurf` flag, ChadStart automatically creates the appropriate rules file that teaches your AI assistant about the `chadstart.yaml` format.
|
|
12
|
+
|
|
13
|
+
## Scaffolding with AI rules
|
|
14
|
+
|
|
15
|
+
=== "Cursor"
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx chadstart my-project --cursor
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Creates `.cursor/rules/chadstart.mdc` — a Cursor rules file that helps Cursor understand the ChadStart schema.
|
|
22
|
+
|
|
23
|
+
=== "GitHub Copilot"
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx chadstart my-project --copilot
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Creates `.github/copilot-instructions.md` — custom instructions for GitHub Copilot.
|
|
30
|
+
|
|
31
|
+
=== "Windsurf"
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx chadstart my-project --windsurf
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Creates `.windsurf/rules/chadstart.md` — rules for the Windsurf AI assistant.
|
|
38
|
+
|
|
39
|
+
=== "No AI tool"
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx chadstart my-project
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Creates the project without any AI assistant configuration.
|
|
46
|
+
|
|
47
|
+
## What the rules file contains
|
|
48
|
+
|
|
49
|
+
The generated rules file provides your AI assistant with:
|
|
50
|
+
|
|
51
|
+
- The full `chadstart.yaml` schema (entities, fields, auth, policies, etc.)
|
|
52
|
+
- Descriptions of available field types (`string`, `text`, `image`, `file`, `boolean`, `choice`, …)
|
|
53
|
+
- Examples of common patterns (authenticable entities, access policies, relations)
|
|
54
|
+
- Instructions on how to generate valid YAML for ChadStart
|
|
55
|
+
|
|
56
|
+
This means you can describe your app in plain English and let Cursor, Copilot, or Windsurf write the `chadstart.yaml` for you.
|
|
57
|
+
|
|
58
|
+
## Prompt examples
|
|
59
|
+
|
|
60
|
+
Once the rules file is in place you can use prompts like:
|
|
61
|
+
|
|
62
|
+
> *"Add a `Comment` entity with a `body` (text) field, a relation to `Post`, and make it authenticable so only the author can delete their own comments."*
|
|
63
|
+
|
|
64
|
+
> *"Add rate limiting: max 100 requests per minute."*
|
|
65
|
+
|
|
66
|
+
> *"Create a `Product` entity with a `name` (string), `price` (money), `image` (image), and a `category` choice field with options: Electronics, Clothing, Food."*
|
|
67
|
+
|
|
68
|
+
## Manual setup
|
|
69
|
+
|
|
70
|
+
If you already have an existing project and want to add AI rules manually, create one of the following files with content describing the [ChadStart YAML schema](./entities.md):
|
|
71
|
+
|
|
72
|
+
| AI tool | Rules file location |
|
|
73
|
+
| ------------------ | ---------------------------------------------- |
|
|
74
|
+
| **Cursor** | `.cursor/rules/chadstart.mdc` |
|
|
75
|
+
| **GitHub Copilot** | `.github/copilot-instructions.md` |
|
|
76
|
+
| **Windsurf** | `.windsurf/rules/chadstart.md` |
|
|
77
|
+
|
|
78
|
+
You can base your rules file on the [chadstart.example.yml](https://github.com/saulmmendoza/chadstart.com/blob/main/chadstart.example.yml) reference file, which documents every available configuration option.
|
|
79
|
+
|
|
80
|
+
!!! tip
|
|
81
|
+
Keep your rules file up to date whenever you upgrade ChadStart. Newer versions may introduce new field types, options, or top-level blocks that your AI assistant won't know about unless the rules file is updated.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: middlewares
|
|
3
|
+
title: Middlewares
|
|
4
|
+
description: Add middlewares to trigger custom logic at defined lifecycle events of your ChadStart backend. 6 available events related to entities.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Introduction
|
|
8
|
+
|
|
9
|
+
**Middleware functions** or **middlewares** are intermediary functions that sit between the client's request and the server's response. They have access to the request object (req) and the response object (res).
|
|
10
|
+
|
|
11
|
+
As ChadStart works with **ExpressJS**, ChadStart middlewares are [ExpressJS middlewares](https://expressjs.com/en/guide/using-middleware.html) enhanced with the [ChadStart SDK](./crud.md#using-the-javascript-sdk) that allows you to interact with your data with ease.
|
|
12
|
+
|
|
13
|
+
## Middleware use cases
|
|
14
|
+
|
|
15
|
+
Here are some examples of middleware use cases:
|
|
16
|
+
|
|
17
|
+
- Patch the request body before storing it in the DB
|
|
18
|
+
- Call an external API or any other custom logic
|
|
19
|
+
- Hide some data from the response
|
|
20
|
+
- Trigger an internal or external action on an event (see also [webhooks](./webhooks.md))
|
|
21
|
+
|
|
22
|
+
## Syntax
|
|
23
|
+
|
|
24
|
+
```yaml title="chadstart.yaml"
|
|
25
|
+
entities:
|
|
26
|
+
Project 🗂️:
|
|
27
|
+
properties:
|
|
28
|
+
- name
|
|
29
|
+
- { name: date, type: date }
|
|
30
|
+
middlewares:
|
|
31
|
+
beforeCreate:
|
|
32
|
+
- function: setDate.js
|
|
33
|
+
afterCreate:
|
|
34
|
+
- function: sendEmail.js
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This example triggers the function located at `/functions/setDate.js` before the item is created and stored in the database, and triggers `/functions/sendEmail.js` after.
|
|
38
|
+
|
|
39
|
+
```js title="/functions/setDate.js"
|
|
40
|
+
module.exports = async (req, res) => {
|
|
41
|
+
console.log('Hello from the function!')
|
|
42
|
+
|
|
43
|
+
req.body['date'] = new Date()
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
!!! tip
|
|
48
|
+
You can add **several middlewares** for an event. They will be processed sequentially in the order you define.
|
|
49
|
+
|
|
50
|
+
## Use your data with the ChadStart backend SDK
|
|
51
|
+
|
|
52
|
+
ChadStart passes the [JS SDK](./crud.md#using-the-javascript-sdk) to middleware functions as third argument. You can use it to fetch or write data.
|
|
53
|
+
|
|
54
|
+
```js title="/functions/patchDocumentNameIfEmpty.js"
|
|
55
|
+
module.exports = async (req, res, chadstart) => {
|
|
56
|
+
// If the 'name' property of the item is empty.
|
|
57
|
+
if (!req.body['name']) {
|
|
58
|
+
// Get the user from the request body.
|
|
59
|
+
const user = await chadstart.from('users').findOneById(req.body['userId'])
|
|
60
|
+
|
|
61
|
+
// Set a custom name based on the user.
|
|
62
|
+
req.body['name'] = `${user.name}'s untitled document`
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Events
|
|
68
|
+
|
|
69
|
+
This is the list and description of the 6 events available to which you can attach middlewares. All of them are related to an [entity](./entities.md)
|
|
70
|
+
|
|
71
|
+
| Name | Description |
|
|
72
|
+
| ---------------- | ------------------------ |
|
|
73
|
+
| **beforeCreate** | Before creating a record |
|
|
74
|
+
| **afterCreate** | After creating a record |
|
|
75
|
+
| **beforeUpdate** | Before updating a record |
|
|
76
|
+
| **afterUpdate** | After updating a record |
|
|
77
|
+
| **beforeDelete** | Before deleting a record |
|
|
78
|
+
| **afterDelete** | After deleting a record |
|