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,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: validation
|
|
3
|
+
title: Validation
|
|
4
|
+
description: Server-side validation for your user-generated content. Use many validators like "required", "minLength", "contains" or "matches" for every property.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Validation
|
|
8
|
+
|
|
9
|
+
## Introduction
|
|
10
|
+
|
|
11
|
+
Implementing **server-side validation** is very easy with ChadStart.
|
|
12
|
+
|
|
13
|
+
You can use the built-in **custom validators** to ensure that the data you are receiving is correctly formatted.
|
|
14
|
+
|
|
15
|
+
## Syntax
|
|
16
|
+
|
|
17
|
+
In your **chadstart.yaml**, you can add a _validation_ object that lists the properties and their validators:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
entities:
|
|
21
|
+
Dog:
|
|
22
|
+
properties:
|
|
23
|
+
- name
|
|
24
|
+
- { name: age, type: number }
|
|
25
|
+
validation:
|
|
26
|
+
name: { minLength: 3 } # The name should have at least 3 characters.
|
|
27
|
+
age: { min: 1, max: 30 } # Age should be a number between 1 and 30.
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
!!! tip "Tip"
|
|
31
|
+
**Type validation** is natively implemented with [property types](./entities.md#property-types). You do not need to set it.
|
|
32
|
+
|
|
33
|
+
Ex: sending a _string_ value for a [boolean](./entities.md#boolean) property type will throw an error.
|
|
34
|
+
|
|
35
|
+
## Inline syntax
|
|
36
|
+
|
|
37
|
+
If you want to keep it short you can simply pass the **validation** object to the **property object**:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
entities:
|
|
41
|
+
Author 🧑🏽🦱:
|
|
42
|
+
properties:
|
|
43
|
+
- name
|
|
44
|
+
- { name: email, type: email, validation: { isNotEmpty: true } }
|
|
45
|
+
- { name: bio, type: textarea, validation: { maxLength: 300 } }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Both syntaxes (block and inline) can be used simultaneously. In case of declaration conflict, the **inline** declaration will prevail.
|
|
49
|
+
|
|
50
|
+
## Validate optional properties
|
|
51
|
+
|
|
52
|
+
If you have some values that are optional **but** that need to be validated **if present**, you can add the `isOptional` validator. The value will be compared against validators only if not _undefined_ or _null_. Example:
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
entities:
|
|
56
|
+
Employee:
|
|
57
|
+
properties:
|
|
58
|
+
- name
|
|
59
|
+
- {
|
|
60
|
+
name: email,
|
|
61
|
+
type: email,
|
|
62
|
+
validation: { contains: '@company.com', isOptional: true }
|
|
63
|
+
} # If provided, the email should contain "@company.com"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Validation response
|
|
67
|
+
|
|
68
|
+
If the validation fails, the response will list the validation error(s) in its body:
|
|
69
|
+
|
|
70
|
+
```http
|
|
71
|
+
// Create a new Employee
|
|
72
|
+
POST /api/dynamic/employees
|
|
73
|
+
Content-Type: application/json
|
|
74
|
+
{
|
|
75
|
+
"name": "John Doe",
|
|
76
|
+
"email": "john@chadstart.com"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Response.
|
|
80
|
+
[
|
|
81
|
+
{
|
|
82
|
+
"property": "email",
|
|
83
|
+
"constraints": {
|
|
84
|
+
"contains": "The value must contain @company.com"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Available validators
|
|
91
|
+
|
|
92
|
+
| Validator | Type | Description |
|
|
93
|
+
| ---------------- | ------- | ------------------------------------------------------------------------------------ |
|
|
94
|
+
| `required` | boolean | Indicates whether the property must not be empty. |
|
|
95
|
+
| `isDefined` | boolean | Checks if value is defined (!== undefined, !== null). |
|
|
96
|
+
| `isOptional` | boolean | Checks if given value is empty (=== null, === undefined) and ignores all validators. |
|
|
97
|
+
| `equals` | any | Checks if value equals ("===") comparison. |
|
|
98
|
+
| `notEquals` | any | Checks if value not equal ("!==") comparison. |
|
|
99
|
+
| `isEmpty` | boolean | Indicates whether the property can be empty. |
|
|
100
|
+
| `isNotEmpty` | boolean | Indicates whether the property must not be empty. Alias for `required` |
|
|
101
|
+
| `isIn` | array | Checks if value is in an array of allowed values. |
|
|
102
|
+
| `isNotIn` | array | Checks if value not in an array of disallowed values. |
|
|
103
|
+
| `min` | number | The minimum value or length allowed for the property. |
|
|
104
|
+
| `max` | number | The maximum value or length allowed for the property. |
|
|
105
|
+
| `contains` | string | Checks if string contains the seed. |
|
|
106
|
+
| `notContains` | string | Checks if string does not contain the seed. |
|
|
107
|
+
| `isAlpha` | boolean | Checks if the string contains only letters (a-zA-Z). |
|
|
108
|
+
| `isAlphanumeric` | boolean | Checks if the string contains only letters and numbers. |
|
|
109
|
+
| `isAscii` | boolean | Checks if the string contains ASCII chars only. |
|
|
110
|
+
| `isEmail` | boolean | Checks if the string is an email. |
|
|
111
|
+
| `isJSON` | boolean | Checks if the string is valid JSON. |
|
|
112
|
+
| `minLength` | number | Checks if the string's length is not less than given number. |
|
|
113
|
+
| `maxLength` | number | Checks if the string's length is not more than given number. |
|
|
114
|
+
| `matches` | string | Checks if string matches the pattern. |
|
|
115
|
+
| `isMimeType` | boolean | Checks if the string matches to a valid MIME type format. |
|
package/docs/vue.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: vue
|
|
3
|
+
title: Create a Full-Stack app with Vue and ChadStart
|
|
4
|
+
description: Quick start guide to create a full-stack app using Vue as a frontend and ChadStart as a backend.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Quick start with Vue
|
|
8
|
+
|
|
9
|
+
Give a proper backend to your Vue.js app.
|
|
10
|
+
|
|
11
|
+
!!! warning
|
|
12
|
+
This quick start guide focuses exclusively on the **frontend**. To ensure the functionality of this code, your ChadStart backend must be [up and running](./getting-started.md#install-chadstart) at `http://localhost:3000`.
|
|
13
|
+
|
|
14
|
+
## 1. Create a Vue app
|
|
15
|
+
|
|
16
|
+
If you already have a Vue app running, you can skip this step.
|
|
17
|
+
|
|
18
|
+
We are using Vue.js v3 in this tutorial. You can replace `my-client` by the name of your front-end app
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
npm create vue@latest
|
|
22
|
+
cd my-client // If you called your app "my-client" when asked in the previous step
|
|
23
|
+
npm install
|
|
24
|
+
npm run dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 2. Install ChadStart SDK
|
|
28
|
+
|
|
29
|
+
Install the JS SDK from the root of your Vue app.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
npm i @chadstart/sdk
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 3. Use it in your app
|
|
36
|
+
|
|
37
|
+
In that example we are using a Cat entity [created previously](entities.md). Replace it by your own entity. This example uses TypeScript, you can remove the typing to have plain JS.
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
<script lang="ts">
|
|
41
|
+
import ChadStart from "@chadstart/sdk";
|
|
42
|
+
|
|
43
|
+
interface Cat {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
type: string;
|
|
47
|
+
image: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default {
|
|
51
|
+
data() {
|
|
52
|
+
return {
|
|
53
|
+
cats: [] as Cat[],
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
mounted() {
|
|
57
|
+
this.fetchCat();
|
|
58
|
+
},
|
|
59
|
+
methods: {
|
|
60
|
+
async fetchCat() {
|
|
61
|
+
|
|
62
|
+
// Init SDK
|
|
63
|
+
const chadstart = new ChadStart();
|
|
64
|
+
|
|
65
|
+
// Fetch Cats from the backend.
|
|
66
|
+
chadstart.from("cats")
|
|
67
|
+
.find<Cat>()
|
|
68
|
+
.then((res) => {
|
|
69
|
+
// Store the response in the "cats" array
|
|
70
|
+
this.cats = res.data;
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<ul>
|
|
79
|
+
<li v-for="cat of cats">{{ cat.name }}</li>
|
|
80
|
+
</ul>
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Checkout the [SDK doc](./crud.md#using-the-javascript-sdk) to see more usages of the SDK.,
|
package/docs/webhooks.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: webhooks
|
|
3
|
+
title: Webhooks
|
|
4
|
+
description: Send requests to third-party applications using ChadStart webhooks. Choose URL, method and send custom headers.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Webhooks
|
|
8
|
+
|
|
9
|
+
## Introduction
|
|
10
|
+
|
|
11
|
+
**Webhooks** are a way for an app to send automated real-time notifications to another app when a specific [event](./webhooks.md#hook-events) occurs. In ChadStart, there are 6 predefined events where you can hook HTTP requests.
|
|
12
|
+
|
|
13
|
+
Webhooks are useful to connect other applications or to trigger a micro-service like notifying someone or updating a file.
|
|
14
|
+
|
|
15
|
+
## Syntax
|
|
16
|
+
|
|
17
|
+
```yaml title="chadstart.yaml"
|
|
18
|
+
entities:
|
|
19
|
+
# You can attach one or several webhooks to each entity event.
|
|
20
|
+
Cat 😺:
|
|
21
|
+
properties:
|
|
22
|
+
- name
|
|
23
|
+
hooks:
|
|
24
|
+
beforeCreate:
|
|
25
|
+
- { url: 'https://my-webhook.com' }
|
|
26
|
+
|
|
27
|
+
Dog 🐶:
|
|
28
|
+
properties:
|
|
29
|
+
- name
|
|
30
|
+
hooks:
|
|
31
|
+
afterDelete:
|
|
32
|
+
# Pass .env variables with ${} interpolation.
|
|
33
|
+
- {
|
|
34
|
+
url: 'https://another-webhook.com',
|
|
35
|
+
headers: { authorization: 'Bearer ${API_KEY}' }
|
|
36
|
+
}
|
|
37
|
+
# Specific HTTP method.
|
|
38
|
+
- { url: 'https://another-one.com', method: 'PATCH' }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Webhook params
|
|
42
|
+
|
|
43
|
+
You can pass arguments using the long syntax:
|
|
44
|
+
|
|
45
|
+
| Option | Default | Type | Description |
|
|
46
|
+
| ----------- | ------- | ------------- | -------------------------------------------------------------------------------------- |
|
|
47
|
+
| **url\*** | - | string | The URL of your webhook |
|
|
48
|
+
| **method** | `POST` | _HTTP Method_ | The HTTP method of the request |
|
|
49
|
+
| **headers** | `{}` | object | Optional headers of the request. Use `${MY_DOTENV_VAR}` syntax to use dotenv variables |
|
|
50
|
+
|
|
51
|
+
Available HTTP Methods are `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
|
|
52
|
+
|
|
53
|
+
!!! note
|
|
54
|
+
ChadStart does not enforce HTTP request success or failure; the lifecycle process continues regardless.
|
|
55
|
+
|
|
56
|
+
## Webhook body
|
|
57
|
+
|
|
58
|
+
ChadStart attaches a **JSON body** with key information about the record concerned to the webhook HTTP request.
|
|
59
|
+
|
|
60
|
+
The main structure of the body of the triggered HTTP requests will remain the same and only the `record` value will change: on _before_ events the `record` will contain your payload, whereas in _after_ requests, the `record` value will reflect the item after the operation.
|
|
61
|
+
|
|
62
|
+
This is the structure of the body:
|
|
63
|
+
|
|
64
|
+
```json title="HTTP request body (content-type is application/json)"
|
|
65
|
+
{
|
|
66
|
+
"event": "beforeUpdate",
|
|
67
|
+
"createdAt": "2025-01-22T13:38:48.399Z",
|
|
68
|
+
"entity": "posts",
|
|
69
|
+
"record": {
|
|
70
|
+
"title": "my title",
|
|
71
|
+
"content": "my content"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Hook events
|
|
77
|
+
|
|
78
|
+
This is the list and description of the 6 hook events available. All of them are related to an [entity](./entities.md).
|
|
79
|
+
|
|
80
|
+
| Name | Description |
|
|
81
|
+
| ---------------- | ------------------------ |
|
|
82
|
+
| **beforeCreate** | Before creating a record |
|
|
83
|
+
| **afterCreate** | After creating a record |
|
|
84
|
+
| **beforeUpdate** | Before updating a record |
|
|
85
|
+
| **afterUpdate** | After updating a record |
|
|
86
|
+
| **beforeDelete** | Before deleting a record |
|
|
87
|
+
| **afterDelete** | After deleting a record |
|
package/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ChadStart — YAML-first Backend as a Service
|
|
5
|
+
*
|
|
6
|
+
* Programmatic API:
|
|
7
|
+
* const { createServer, startServer } = require('chadstart');
|
|
8
|
+
* await startServer('./chadstart.yaml');
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
module.exports = require('./server/express-server');
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
{
|
|
2
|
+
"page": {
|
|
3
|
+
"title": "ChadStart Admin"
|
|
4
|
+
},
|
|
5
|
+
"login": {
|
|
6
|
+
"title": "ChadStart Admin",
|
|
7
|
+
"collection_label": "Collection",
|
|
8
|
+
"collection_placeholder": "Admin collection name",
|
|
9
|
+
"change_collection": "Change collection",
|
|
10
|
+
"hide_collection": "Hide collection",
|
|
11
|
+
"email_label": "Email",
|
|
12
|
+
"email_placeholder": "admin@example.com",
|
|
13
|
+
"password_label": "Password",
|
|
14
|
+
"password_placeholder": "••••••••",
|
|
15
|
+
"sign_in": "Sign in",
|
|
16
|
+
"signing_in": "Signing in…",
|
|
17
|
+
"errors": {
|
|
18
|
+
"no_admin_collections": "No admin collections configured",
|
|
19
|
+
"all_fields_required": "All fields are required",
|
|
20
|
+
"collection_not_found": "Collection not found",
|
|
21
|
+
"login_failed": "Login failed",
|
|
22
|
+
"network_error": "Network error"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"sidebar": {
|
|
26
|
+
"subtitle": "Admin",
|
|
27
|
+
"collections": "Collections",
|
|
28
|
+
"entities": "Entities",
|
|
29
|
+
"admin": "Admin",
|
|
30
|
+
"config_editor": "⚙ Config Editor",
|
|
31
|
+
"api_keys": "🔑 API Keys",
|
|
32
|
+
"log_out": "Log out"
|
|
33
|
+
},
|
|
34
|
+
"header": {
|
|
35
|
+
"select_collection": "Select a collection",
|
|
36
|
+
"new_record": "+ New record"
|
|
37
|
+
},
|
|
38
|
+
"modal": {
|
|
39
|
+
"title_new": "New {{name}}",
|
|
40
|
+
"title_edit": "Edit {{name}} #{{id}}",
|
|
41
|
+
"cancel": "Cancel",
|
|
42
|
+
"save": "Save",
|
|
43
|
+
"saving": "Saving…"
|
|
44
|
+
},
|
|
45
|
+
"table": {
|
|
46
|
+
"no_records": "No records yet. Click + New record to create one.",
|
|
47
|
+
"actions": "Actions",
|
|
48
|
+
"edit": "Edit",
|
|
49
|
+
"delete": "Delete",
|
|
50
|
+
"delete_confirm": "Delete record #{{id}}?"
|
|
51
|
+
},
|
|
52
|
+
"toast": {
|
|
53
|
+
"failed_load_data": "Failed to load data",
|
|
54
|
+
"failed_load_schema": "Failed to load schema",
|
|
55
|
+
"record_created": "Record created",
|
|
56
|
+
"record_updated": "Record updated",
|
|
57
|
+
"record_deleted": "Record deleted",
|
|
58
|
+
"config_reloading": "Config saved — reloading server…",
|
|
59
|
+
"config_applied": "Config applied",
|
|
60
|
+
"config_saved": "Config saved successfully",
|
|
61
|
+
"config_reset": "Reset to last saved state",
|
|
62
|
+
"form_read_error": "Could not read form data",
|
|
63
|
+
"config_not_object": "Config must be a JSON object",
|
|
64
|
+
"invalid_json": "Invalid JSON: {{message}}",
|
|
65
|
+
"save_failed": "Save failed: {{message}}",
|
|
66
|
+
"config_load_failed": "Failed to load config: {{message}}"
|
|
67
|
+
},
|
|
68
|
+
"config": {
|
|
69
|
+
"tabs": {
|
|
70
|
+
"general": "General",
|
|
71
|
+
"entities": "Entities",
|
|
72
|
+
"functions": "Functions",
|
|
73
|
+
"files": "Files & Uploads",
|
|
74
|
+
"settings": "Settings",
|
|
75
|
+
"all": "All"
|
|
76
|
+
},
|
|
77
|
+
"descriptions": {
|
|
78
|
+
"general": "Application name, port, database path, and public static folder.",
|
|
79
|
+
"entities": "Entity definitions — properties, relations, and flags.",
|
|
80
|
+
"functions": "Custom function-based HTTP endpoint definitions (path, method, function).",
|
|
81
|
+
"files": "File bucket definitions for local uploads.",
|
|
82
|
+
"settings": "API rate limits and reusable property groups.",
|
|
83
|
+
"all": "Full configuration — all sections combined (raw JSON for advanced use)."
|
|
84
|
+
},
|
|
85
|
+
"save_btn": "Save Config",
|
|
86
|
+
"saving_btn": "Saving…",
|
|
87
|
+
"reset_btn": "Reset",
|
|
88
|
+
"editor_title": "Config Editor",
|
|
89
|
+
"json_label": "Full Configuration JSON",
|
|
90
|
+
"json_hint": "(read-only reference — switch to the All tab to edit directly)",
|
|
91
|
+
"json_label_edit": "Full Configuration JSON",
|
|
92
|
+
"json_hint_edit": "(edit directly — changes are saved on Save)",
|
|
93
|
+
"status": {
|
|
94
|
+
"loading": "Loading…",
|
|
95
|
+
"reloading": "Reloading…",
|
|
96
|
+
"applied": "✓ Config applied.",
|
|
97
|
+
"saved_reload": "✓ Saved — reload the page to see changes.",
|
|
98
|
+
"saved_restart": "✓ Saved — restart the server to apply changes."
|
|
99
|
+
},
|
|
100
|
+
"s3_note": {
|
|
101
|
+
"title": "S3 Storage",
|
|
102
|
+
"intro": "is configured via environment variables:",
|
|
103
|
+
"env_hint": "Set these in your",
|
|
104
|
+
"env_file": ".env",
|
|
105
|
+
"env_or": "file or deployment environment."
|
|
106
|
+
},
|
|
107
|
+
"general": {
|
|
108
|
+
"app_name": "App Name",
|
|
109
|
+
"port": "Port",
|
|
110
|
+
"port_hint": "Default: 3000",
|
|
111
|
+
"database": "Database path",
|
|
112
|
+
"database_placeholder": "data/chadstart.db",
|
|
113
|
+
"database_hint": "Path relative to the config file. Leave blank for the default.",
|
|
114
|
+
"public_folder": "Public folder",
|
|
115
|
+
"public_folder_placeholder": "public",
|
|
116
|
+
"public_folder_hint": "Folder for static files served at the root (HTML, CSS, JS, etc.)."
|
|
117
|
+
},
|
|
118
|
+
"entities": {
|
|
119
|
+
"entity_name": "Entity name",
|
|
120
|
+
"entity_placeholder": "Post",
|
|
121
|
+
"user_collection": "User collection",
|
|
122
|
+
"single": "Single",
|
|
123
|
+
"remove": "Remove",
|
|
124
|
+
"belongs_to": "Belongs to",
|
|
125
|
+
"belongs_to_hint": "(comma-separated)",
|
|
126
|
+
"belongs_to_placeholder": "User, Category",
|
|
127
|
+
"belongs_to_many": "Belongs to many",
|
|
128
|
+
"belongs_to_many_placeholder": "Tag",
|
|
129
|
+
"properties": "Properties",
|
|
130
|
+
"add_property": "+ Add property",
|
|
131
|
+
"add_entity": "+ Add entity",
|
|
132
|
+
"property_placeholder": "property name"
|
|
133
|
+
},
|
|
134
|
+
"functions": {
|
|
135
|
+
"name": "Name",
|
|
136
|
+
"name_placeholder": "sendEmail",
|
|
137
|
+
"path_label": "Path",
|
|
138
|
+
"path_placeholder": "/send-email",
|
|
139
|
+
"method": "Method",
|
|
140
|
+
"function": "Function",
|
|
141
|
+
"function_placeholder": "sendEmail.js",
|
|
142
|
+
"description": "Description",
|
|
143
|
+
"description_hint": "(optional)",
|
|
144
|
+
"description_placeholder": "What this endpoint does",
|
|
145
|
+
"remove": "Remove",
|
|
146
|
+
"add_endpoint": "+ Add endpoint"
|
|
147
|
+
},
|
|
148
|
+
"files": {
|
|
149
|
+
"name": "Name",
|
|
150
|
+
"name_placeholder": "images",
|
|
151
|
+
"path_label": "Path",
|
|
152
|
+
"path_placeholder": "uploads/images",
|
|
153
|
+
"public": "Public",
|
|
154
|
+
"remove": "Remove",
|
|
155
|
+
"add_bucket": "+ Add file bucket"
|
|
156
|
+
},
|
|
157
|
+
"settings": {
|
|
158
|
+
"rate_limits_hint": "Rate limits cap the number of API requests per time window.",
|
|
159
|
+
"name": "Name",
|
|
160
|
+
"name_placeholder": "api",
|
|
161
|
+
"max_requests": "Max requests",
|
|
162
|
+
"max_requests_placeholder": "200",
|
|
163
|
+
"window_ms": "Window (ms)",
|
|
164
|
+
"window_placeholder": "60000",
|
|
165
|
+
"remove": "Remove",
|
|
166
|
+
"add_rate_limit": "+ Add rate limit"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
package/mkdocs.yml
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
site_name: ChadStart
|
|
2
|
+
site_description: YAML-first Backend as a Service — define your entire backend in a single YAML file.
|
|
3
|
+
site_url: https://saulmmendoza.github.io/chadstart.com/
|
|
4
|
+
repo_url: https://github.com/saulmmendoza/chadstart.com
|
|
5
|
+
repo_name: saulmmendoza/chadstart.com
|
|
6
|
+
edit_uri: edit/main/docs/
|
|
7
|
+
|
|
8
|
+
theme:
|
|
9
|
+
name: material
|
|
10
|
+
custom_dir: docs/overrides
|
|
11
|
+
palette:
|
|
12
|
+
- scheme: default
|
|
13
|
+
primary: deep purple
|
|
14
|
+
accent: purple
|
|
15
|
+
toggle:
|
|
16
|
+
icon: material/brightness-7
|
|
17
|
+
name: Switch to dark mode
|
|
18
|
+
- scheme: slate
|
|
19
|
+
primary: deep purple
|
|
20
|
+
accent: purple
|
|
21
|
+
toggle:
|
|
22
|
+
icon: material/brightness-4
|
|
23
|
+
name: Switch to light mode
|
|
24
|
+
features:
|
|
25
|
+
- navigation.tabs
|
|
26
|
+
- navigation.sections
|
|
27
|
+
- navigation.top
|
|
28
|
+
- search.suggest
|
|
29
|
+
- search.highlight
|
|
30
|
+
- content.tabs.link
|
|
31
|
+
- content.code.copy
|
|
32
|
+
icon:
|
|
33
|
+
repo: fontawesome/brands/github
|
|
34
|
+
|
|
35
|
+
extra_css:
|
|
36
|
+
- stylesheets/extra.css
|
|
37
|
+
|
|
38
|
+
nav:
|
|
39
|
+
- Home: index.md
|
|
40
|
+
- Get Started: getting-started.md
|
|
41
|
+
- Core:
|
|
42
|
+
- Entities: entities.md
|
|
43
|
+
- CRUD: crud.md
|
|
44
|
+
- Authentication: auth.md
|
|
45
|
+
- Access Policies: access-policies.md
|
|
46
|
+
- Validation: validation.md
|
|
47
|
+
- Configuration: config.md
|
|
48
|
+
- Features:
|
|
49
|
+
- File & Image Uploads: upload.md
|
|
50
|
+
- S3 Storage: s3-storage.md
|
|
51
|
+
- Realtime: realtime.md
|
|
52
|
+
- Webhooks: webhooks.md
|
|
53
|
+
- Custom Endpoints: functions.md
|
|
54
|
+
- Middlewares: middlewares.md
|
|
55
|
+
- Groups: groups.md
|
|
56
|
+
- Security: security.md
|
|
57
|
+
- Telemetry: telemetry.md
|
|
58
|
+
- LLM Rules: llm-rules.md
|
|
59
|
+
- Admin UI: admin-ui.md
|
|
60
|
+
- CLI: cli.md
|
|
61
|
+
- Deploy:
|
|
62
|
+
- Deploy to Production: deploy.md
|
|
63
|
+
- Docker: docker.md
|
|
64
|
+
- Integrations:
|
|
65
|
+
- React: react.md
|
|
66
|
+
- Vue: vue.md
|
|
67
|
+
- Angular: angular.md
|
|
68
|
+
- Svelte: svelte.md
|
|
69
|
+
- Astro: astro.md
|
|
70
|
+
- Plugins: plugins.md
|
|
71
|
+
|
|
72
|
+
markdown_extensions:
|
|
73
|
+
- admonition
|
|
74
|
+
- pymdownx.details
|
|
75
|
+
- pymdownx.superfences
|
|
76
|
+
- pymdownx.highlight:
|
|
77
|
+
anchor_linenums: true
|
|
78
|
+
- pymdownx.tabbed:
|
|
79
|
+
alternate_style: true
|
|
80
|
+
- tables
|
|
81
|
+
- toc:
|
|
82
|
+
permalink: true
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chadstart",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "YAML-first Backend as a Service — define your entire backend in one YAML file",
|
|
5
|
+
"main": "server/express-server.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"chadstart": "./cli/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "node cli/cli.js dev",
|
|
11
|
+
"start": "node cli/cli.js start",
|
|
12
|
+
"start:prod": "NODE_ENV=production node cli/cli.js start",
|
|
13
|
+
"build": "node cli/cli.js build",
|
|
14
|
+
"seed": "node cli/cli.js seed",
|
|
15
|
+
"test": "mocha --timeout 10000 'test/*.test.js'",
|
|
16
|
+
"test:coverage": "c8 --reporter=text --reporter=json-summary mocha --timeout 10000 'test/*.test.js'",
|
|
17
|
+
"test:browser": "playwright test"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/saulmmendoza/chadstart.com.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/saulmmendoza/chadstart.com/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/saulmmendoza/chadstart.com#readme",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@aws-sdk/client-s3": "^3.1009.0",
|
|
33
|
+
"@opentelemetry/auto-instrumentations-node": "^0.71.0",
|
|
34
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.213.0",
|
|
35
|
+
"@opentelemetry/sdk-node": "^0.213.0",
|
|
36
|
+
"@sentry/node": "^10.43.0",
|
|
37
|
+
"@tailwindcss/browser": "4.2.1",
|
|
38
|
+
"ajv": "^8.18.0",
|
|
39
|
+
"ajv-formats": "^3.0.1",
|
|
40
|
+
"animate.css": "4.1.1",
|
|
41
|
+
"bcryptjs": "^3.0.3",
|
|
42
|
+
"better-sqlite3": "^12.6.2",
|
|
43
|
+
"busboy": "^1.6.0",
|
|
44
|
+
"chokidar": "^5.0.0",
|
|
45
|
+
"cronstrue": "^3.13.0",
|
|
46
|
+
"execa": "^9.6.1",
|
|
47
|
+
"express": "^5.2.1",
|
|
48
|
+
"express-rate-limit": "^8.3.1",
|
|
49
|
+
"htmx.org": "2.0.4",
|
|
50
|
+
"jsonwebtoken": "^9.0.3",
|
|
51
|
+
"node-cron": "^4.2.1",
|
|
52
|
+
"sharp": "^0.34.5",
|
|
53
|
+
"swagger-ui-express": "^5.0.1",
|
|
54
|
+
"ws": "^8.19.0",
|
|
55
|
+
"yaml": "^2.8.2"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@playwright/test": "^1.58.2",
|
|
59
|
+
"c8": "^11.0.0",
|
|
60
|
+
"mocha": "^11.7.5"
|
|
61
|
+
},
|
|
62
|
+
"overrides": {
|
|
63
|
+
"serialize-javascript": "^7.0.3"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { defineConfig, devices } = require('@playwright/test');
|
|
5
|
+
|
|
6
|
+
module.exports = defineConfig({
|
|
7
|
+
testDir: './test/browser',
|
|
8
|
+
timeout: 30000,
|
|
9
|
+
retries: 0,
|
|
10
|
+
workers: 1,
|
|
11
|
+
reporter: 'list',
|
|
12
|
+
globalSetup: require.resolve('./test/browser/global-setup.js'),
|
|
13
|
+
globalTeardown: require.resolve('./test/browser/global-teardown.js'),
|
|
14
|
+
use: {
|
|
15
|
+
baseURL: process.env.TEST_BASE_URL || 'http://localhost:4321',
|
|
16
|
+
headless: true,
|
|
17
|
+
},
|
|
18
|
+
projects: [
|
|
19
|
+
{
|
|
20
|
+
name: 'chromium',
|
|
21
|
+
use: { ...devices['Desktop Chrome'] },
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
});
|
package/public/.gitkeep
ADDED
|
File without changes
|