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,350 @@
|
|
|
1
|
+
{% extends "main.html" %}
|
|
2
|
+
|
|
3
|
+
{% block tabs %}
|
|
4
|
+
{{ super() }}
|
|
5
|
+
|
|
6
|
+
<!-- ═══════════════════════════════════════════════════════════
|
|
7
|
+
HERO / PARALLAX SECTION
|
|
8
|
+
═══════════════════════════════════════════════════════════ -->
|
|
9
|
+
<section class="mdx-container">
|
|
10
|
+
|
|
11
|
+
<!-- Tech grid background overlay -->
|
|
12
|
+
<div class="mdx-tech-bg" aria-hidden="true"></div>
|
|
13
|
+
|
|
14
|
+
<!-- Floating warrior mascots (parallax) -->
|
|
15
|
+
<div class="mdx-mascot mdx-mascot--left" aria-hidden="true">
|
|
16
|
+
<img
|
|
17
|
+
src="https://github.com/user-attachments/assets/9fc6de81-e30f-4f4d-becd-6b332cd5b208"
|
|
18
|
+
alt="ChadStart warrior mascot"
|
|
19
|
+
loading="lazy"
|
|
20
|
+
>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="mdx-mascot mdx-mascot--right" aria-hidden="true">
|
|
23
|
+
<img
|
|
24
|
+
src="https://github.com/user-attachments/assets/1060a160-bfc2-471c-8503-5cbd71783d20"
|
|
25
|
+
alt="ChadStart warrior mascot"
|
|
26
|
+
loading="lazy"
|
|
27
|
+
>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="md-grid md-typeset">
|
|
31
|
+
<div class="mdx-hero">
|
|
32
|
+
|
|
33
|
+
<!-- Left column: headline + CTA -->
|
|
34
|
+
<div class="mdx-hero__teaser">
|
|
35
|
+
<h1>Your backend.<br><span class="mdx-hero__accent">One YAML file.</span></h1>
|
|
36
|
+
<p class="mdx-hero__description">
|
|
37
|
+
ChadStart is an open-source Backend as a Service that fits in a
|
|
38
|
+
single YAML file. Define entities, auth, storage, and custom logic — then ship.
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<div class="mdx-cta-group">
|
|
42
|
+
<a
|
|
43
|
+
href="{{ page.next_page.url | url }}"
|
|
44
|
+
title="Get Started"
|
|
45
|
+
class="mdx-cta mdx-cta--primary"
|
|
46
|
+
>
|
|
47
|
+
<span>Get Started →</span>
|
|
48
|
+
</a>
|
|
49
|
+
<a
|
|
50
|
+
href="{{ config.repo_url }}"
|
|
51
|
+
title="View on GitHub"
|
|
52
|
+
class="mdx-cta mdx-cta--ghost"
|
|
53
|
+
>
|
|
54
|
+
{% include ".icons/fontawesome/brands/github.svg" %}
|
|
55
|
+
<span>GitHub</span>
|
|
56
|
+
</a>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<!-- Right column: YAML preview -->
|
|
61
|
+
<div class="mdx-hero__code">
|
|
62
|
+
<pre><code class="language-yaml"><span class="nc">entities</span>:
|
|
63
|
+
<span class="nc">Post</span>:
|
|
64
|
+
<span class="na">fields</span>:
|
|
65
|
+
<span class="na">title</span>: <span class="s">string</span>
|
|
66
|
+
<span class="na">body</span>: <span class="s">text</span>
|
|
67
|
+
<span class="na">published</span>: <span class="s">boolean</span>
|
|
68
|
+
|
|
69
|
+
<span class="nc">User</span>:
|
|
70
|
+
<span class="na">authenticable</span>: <span class="kc">true</span>
|
|
71
|
+
<span class="na">fields</span>:
|
|
72
|
+
<span class="na">username</span>: <span class="s">string</span>
|
|
73
|
+
<span class="na">avatar</span>: <span class="s">image</span>
|
|
74
|
+
|
|
75
|
+
<span class="nc">rateLimits</span>:
|
|
76
|
+
<span class="na">windowMs</span>: <span class="m">60000</span>
|
|
77
|
+
<span class="na">max</span>: <span class="m">100</span></code></pre>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</section>
|
|
83
|
+
{% endblock %}
|
|
84
|
+
|
|
85
|
+
{% block content %}
|
|
86
|
+
|
|
87
|
+
<!-- ═══════════════════════════════════════════════════════════
|
|
88
|
+
GETTING STARTED — quick commands
|
|
89
|
+
═══════════════════════════════════════════════════════════ -->
|
|
90
|
+
<section class="mdx-getting-started">
|
|
91
|
+
<div class="md-grid md-typeset">
|
|
92
|
+
<h2 class="mdx-section-title">Get started in seconds</h2>
|
|
93
|
+
|
|
94
|
+
<div class="mdx-gs-steps">
|
|
95
|
+
|
|
96
|
+
<div class="mdx-gs-step">
|
|
97
|
+
<div class="mdx-gs-step__num">1</div>
|
|
98
|
+
<div class="mdx-gs-step__body">
|
|
99
|
+
<p class="mdx-gs-step__label">Create your project</p>
|
|
100
|
+
<div class="mdx-gs-step__code">
|
|
101
|
+
<pre><code>npx chadstart my-project --cursor</code></pre>
|
|
102
|
+
<span class="mdx-gs-step__note">
|
|
103
|
+
Replace <code>--cursor</code> with <code>--copilot</code>,
|
|
104
|
+
<code>--windsurf</code>, or omit entirely.
|
|
105
|
+
</span>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div class="mdx-gs-step">
|
|
111
|
+
<div class="mdx-gs-step__num">2</div>
|
|
112
|
+
<div class="mdx-gs-step__body">
|
|
113
|
+
<p class="mdx-gs-step__label">Start the server</p>
|
|
114
|
+
<div class="mdx-gs-step__code">
|
|
115
|
+
<pre><code>cd my-project && npm run start</code></pre>
|
|
116
|
+
<span class="mdx-gs-step__note">
|
|
117
|
+
Admin panel at <code>http://localhost:3000</code>
|
|
118
|
+
· REST API at <code>/api</code>
|
|
119
|
+
</span>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="mdx-gs-step">
|
|
125
|
+
<div class="mdx-gs-step__num">3</div>
|
|
126
|
+
<div class="mdx-gs-step__body">
|
|
127
|
+
<p class="mdx-gs-step__label">Edit <code>chadstart.yaml</code> and ship</p>
|
|
128
|
+
<div class="mdx-gs-step__code">
|
|
129
|
+
<pre><code>npm run deploy</code></pre>
|
|
130
|
+
<span class="mdx-gs-step__note">
|
|
131
|
+
Deploy to any Node.js host or Docker container.
|
|
132
|
+
</span>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</section>
|
|
140
|
+
|
|
141
|
+
<!-- ═══════════════════════════════════════════════════════════
|
|
142
|
+
ALL FEATURES GRID
|
|
143
|
+
═══════════════════════════════════════════════════════════ -->
|
|
144
|
+
<section class="mdx-features">
|
|
145
|
+
<div class="md-grid md-typeset">
|
|
146
|
+
<h2 class="mdx-section-title">Everything your backend needs</h2>
|
|
147
|
+
<div class="mdx-features__grid">
|
|
148
|
+
|
|
149
|
+
<div class="mdx-feature-card">
|
|
150
|
+
<div class="mdx-feature-card__icon">🧠</div>
|
|
151
|
+
<h3>Zero friction setup</h3>
|
|
152
|
+
<p>One command to scaffold a project. One YAML file to define everything. No sprawling config directories.</p>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div class="mdx-feature-card">
|
|
156
|
+
<div class="mdx-feature-card__icon">🔑</div>
|
|
157
|
+
<h3>Authentication built-in</h3>
|
|
158
|
+
<p>Mark any entity as <code>authenticable: true</code> to get register, login, and JWT-based auth routes instantly.</p>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div class="mdx-feature-card">
|
|
162
|
+
<div class="mdx-feature-card__icon">📊</div>
|
|
163
|
+
<h3>Admin panel included</h3>
|
|
164
|
+
<p>A full-featured admin UI is generated from your schema — browse, create, update, and delete records out of the box.</p>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<div class="mdx-feature-card">
|
|
168
|
+
<div class="mdx-feature-card__icon">🚀</div>
|
|
169
|
+
<h3>REST API in seconds</h3>
|
|
170
|
+
<p>Full CRUD REST endpoints are automatically generated for every entity. No boilerplate, no glue code.</p>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div class="mdx-feature-card">
|
|
174
|
+
<div class="mdx-feature-card__icon">🤖</div>
|
|
175
|
+
<h3>LLM-friendly</h3>
|
|
176
|
+
<p>Plain YAML is easy for AI coding assistants to read and generate. Ship faster with Cursor, Copilot, or Windsurf.</p>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<div class="mdx-feature-card">
|
|
180
|
+
<div class="mdx-feature-card__icon">💻</div>
|
|
181
|
+
<h3>Runs anywhere</h3>
|
|
182
|
+
<p>Deploy to any Node.js host, use Docker, or run locally. Lightweight enough for a side project, solid enough for production.</p>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<div class="mdx-feature-card">
|
|
186
|
+
<div class="mdx-feature-card__icon">🗂️</div>
|
|
187
|
+
<h3>File & image uploads</h3>
|
|
188
|
+
<p>Add <code>image</code> or <code>file</code> field types to get upload endpoints with optional S3 storage support.</p>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<div class="mdx-feature-card">
|
|
192
|
+
<div class="mdx-feature-card__icon">⚡</div>
|
|
193
|
+
<h3>Realtime & webhooks</h3>
|
|
194
|
+
<p>Built-in WebSocket support and webhook triggers let you react to data changes in real time.</p>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<div class="mdx-feature-card">
|
|
198
|
+
<div class="mdx-feature-card__icon">🔌</div>
|
|
199
|
+
<h3>Custom endpoints</h3>
|
|
200
|
+
<p>Drop a <code>.js</code> file in your functions folder and wire it to any HTTP route in your YAML — full Express power, zero config.</p>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<div class="mdx-feature-card">
|
|
204
|
+
<div class="mdx-feature-card__icon">🛡️</div>
|
|
205
|
+
<h3>Access policies</h3>
|
|
206
|
+
<p>Control who can read, create, update, or delete each entity with a simple policy array — public, restricted, or admin-only.</p>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<div class="mdx-feature-card">
|
|
210
|
+
<div class="mdx-feature-card__icon">✅</div>
|
|
211
|
+
<h3>Validation</h3>
|
|
212
|
+
<p>Add field-level validation rules in YAML — min/max length, regex, required, and more. Invalid requests are automatically rejected.</p>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div class="mdx-feature-card">
|
|
216
|
+
<div class="mdx-feature-card__icon">🌊</div>
|
|
217
|
+
<h3>Rate limiting</h3>
|
|
218
|
+
<p>Protect your API from abuse with configurable rate limits. Set <code>windowMs</code> and <code>max</code> with two lines of YAML.</p>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div class="mdx-feature-card">
|
|
222
|
+
<div class="mdx-feature-card__icon">☁️</div>
|
|
223
|
+
<h3>S3 storage</h3>
|
|
224
|
+
<p>Plug in any S3-compatible provider for file uploads with a few environment variables. Works with AWS, Cloudflare R2, and more.</p>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<div class="mdx-feature-card">
|
|
228
|
+
<div class="mdx-feature-card__icon">🔀</div>
|
|
229
|
+
<h3>Middlewares</h3>
|
|
230
|
+
<p>Inject custom logic before or after any route. Great for logging, request transformations, or custom auth flows.</p>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div class="mdx-feature-card">
|
|
234
|
+
<div class="mdx-feature-card__icon">👥</div>
|
|
235
|
+
<h3>Groups</h3>
|
|
236
|
+
<p>Assign users to groups to implement role-based access control. Define which groups can access which entities and operations.</p>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<div class="mdx-feature-card">
|
|
240
|
+
<div class="mdx-feature-card__icon">🔐</div>
|
|
241
|
+
<h3>Security hardening</h3>
|
|
242
|
+
<p>Helmet.js headers, CORS configuration, JWT secrets, and bcrypt password hashing — security best practices out of the box.</p>
|
|
243
|
+
</div>
|
|
244
|
+
|
|
245
|
+
<div class="mdx-feature-card">
|
|
246
|
+
<div class="mdx-feature-card__icon">📡</div>
|
|
247
|
+
<h3>OpenTelemetry</h3>
|
|
248
|
+
<p>Built-in observability with OpenTelemetry. Send traces and metrics to any OTLP-compatible backend like Grafana or Datadog.</p>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<div class="mdx-feature-card">
|
|
252
|
+
<div class="mdx-feature-card__icon">🗝️</div>
|
|
253
|
+
<h3>API keys</h3>
|
|
254
|
+
<p>Generate and manage API keys per entity. Control per-key permissions: create, read, update, delete for each collection.</p>
|
|
255
|
+
</div>
|
|
256
|
+
|
|
257
|
+
<div class="mdx-feature-card">
|
|
258
|
+
<div class="mdx-feature-card__icon">⌨️</div>
|
|
259
|
+
<h3>CLI</h3>
|
|
260
|
+
<p>The <code>chadstart</code> CLI scaffolds new projects in seconds, pre-configured for your favorite AI coding assistant.</p>
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
<div class="mdx-feature-card">
|
|
264
|
+
<div class="mdx-feature-card__icon">🧩</div>
|
|
265
|
+
<h3>Plugins</h3>
|
|
266
|
+
<p>Extend ChadStart with community or custom plugins. Add new field types, routes, or behaviors without forking the core.</p>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<div class="mdx-feature-card">
|
|
270
|
+
<div class="mdx-feature-card__icon">⚛️</div>
|
|
271
|
+
<h3>Framework integrations</h3>
|
|
272
|
+
<p>Official guides and SDK helpers for React, Vue, Angular, Svelte, and Astro. Drop in and start calling your API immediately.</p>
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
</section>
|
|
278
|
+
|
|
279
|
+
{% endblock %}
|
|
280
|
+
|
|
281
|
+
{% block footer %}
|
|
282
|
+
{{ super() }}
|
|
283
|
+
{% endblock %}
|
|
284
|
+
|
|
285
|
+
{% block scripts %}
|
|
286
|
+
{{ super() }}
|
|
287
|
+
<script>
|
|
288
|
+
(function () {
|
|
289
|
+
'use strict';
|
|
290
|
+
|
|
291
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
292
|
+
var hero = document.querySelector('.mdx-container');
|
|
293
|
+
var mascotLeft = document.querySelector('.mdx-mascot--left');
|
|
294
|
+
var mascotRight = document.querySelector('.mdx-mascot--right');
|
|
295
|
+
|
|
296
|
+
if (!hero || (!mascotLeft && !mascotRight)) return;
|
|
297
|
+
|
|
298
|
+
var scrollY = 0;
|
|
299
|
+
var mouseX = 0.5; /* normalised 0-1, centred */
|
|
300
|
+
var mouseY = 0.5;
|
|
301
|
+
var rafPending = false;
|
|
302
|
+
|
|
303
|
+
function applyParallax() {
|
|
304
|
+
var heroH = hero.offsetHeight;
|
|
305
|
+
var progress = Math.min(scrollY / (heroH || 1), 1);
|
|
306
|
+
|
|
307
|
+
/* Scroll: mascots drift upward (foreground is faster than background) */
|
|
308
|
+
var scrollOffset = progress * 60;
|
|
309
|
+
|
|
310
|
+
/* Mouse: subtle lateral + vertical nudge gives depth illusion */
|
|
311
|
+
var mx = (mouseX - 0.5) * 30; /* ±15 px */
|
|
312
|
+
var my = (mouseY - 0.5) * 15; /* ±7.5 px */
|
|
313
|
+
|
|
314
|
+
/* Apply to the wrapper div; CSS float-animation lives on the img
|
|
315
|
+
so these two transforms never interfere with each other. */
|
|
316
|
+
if (mascotLeft) {
|
|
317
|
+
mascotLeft.style.transform =
|
|
318
|
+
'translate(' + (-mx) + 'px, ' + (-(scrollOffset + my)) + 'px)';
|
|
319
|
+
}
|
|
320
|
+
if (mascotRight) {
|
|
321
|
+
mascotRight.style.transform =
|
|
322
|
+
'translate(' + mx + 'px, ' + (-(scrollOffset + my)) + 'px)';
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
rafPending = false;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* rAF batching: coalesces rapid scroll/mousemove events into one
|
|
329
|
+
paint-cycle update, capping work to ~60 fps automatically. */
|
|
330
|
+
function scheduleUpdate() {
|
|
331
|
+
if (!rafPending) {
|
|
332
|
+
rafPending = true;
|
|
333
|
+
requestAnimationFrame(applyParallax);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
window.addEventListener('scroll', function () {
|
|
338
|
+
scrollY = window.scrollY || window.pageYOffset;
|
|
339
|
+
scheduleUpdate();
|
|
340
|
+
}, { passive: true });
|
|
341
|
+
|
|
342
|
+
document.addEventListener('mousemove', function (e) {
|
|
343
|
+
mouseX = e.clientX / window.innerWidth;
|
|
344
|
+
mouseY = e.clientY / window.innerHeight;
|
|
345
|
+
scheduleUpdate();
|
|
346
|
+
}, { passive: true });
|
|
347
|
+
});
|
|
348
|
+
}());
|
|
349
|
+
</script>
|
|
350
|
+
{% endblock %}
|
package/docs/plugins.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Plugin System
|
|
2
|
+
|
|
3
|
+
ChadStart supports plugins to extend the server with custom routes and logic.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
Add plugins in `chadstart.yaml`:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
plugins:
|
|
11
|
+
- repo: https://github.com/org/chadstart-plugin-auth
|
|
12
|
+
- path: ./my-local-plugin
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| Option | Description |
|
|
16
|
+
|--------|-------------|
|
|
17
|
+
| `repo` | Load plugin from a remote GitHub repository |
|
|
18
|
+
| `path` | Load plugin from a local directory |
|
|
19
|
+
|
|
20
|
+
> ⚠️ Remote plugins execute arbitrary code. Only load plugins from trusted sources.
|
|
21
|
+
|
|
22
|
+
## Plugin Interface
|
|
23
|
+
|
|
24
|
+
A plugin is a Node.js module that exports an object with a `name` and a `register` function:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
module.exports = {
|
|
28
|
+
name: 'my-plugin',
|
|
29
|
+
register(app, core) {
|
|
30
|
+
// app — Express application instance
|
|
31
|
+
// core — ChadStart core utilities
|
|
32
|
+
app.get('/custom', (req, res) => res.json({ hello: 'world' }));
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Local Plugin Example
|
|
38
|
+
|
|
39
|
+
Create `./my-local-plugin/index.js`:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
module.exports = {
|
|
43
|
+
name: 'custom-routes',
|
|
44
|
+
register(app, core) {
|
|
45
|
+
app.get('/ping', (req, res) => res.json({ pong: true }));
|
|
46
|
+
app.post('/notify', (req, res) => {
|
|
47
|
+
// custom business logic
|
|
48
|
+
res.json({ sent: true });
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then reference it in `chadstart.yaml`:
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
plugins:
|
|
58
|
+
- path: ./my-local-plugin
|
|
59
|
+
```
|
package/docs/react.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: react
|
|
3
|
+
title: Create a Full-Stack app with React and ChadStart
|
|
4
|
+
description: Quick start guide to create a full-stack app using React as a frontend and ChadStart as a backend.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Quick start with React
|
|
8
|
+
|
|
9
|
+
Give a proper backend to your React 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 React app
|
|
15
|
+
|
|
16
|
+
If you already have a React app, you can skip this step.
|
|
17
|
+
|
|
18
|
+
There are several ways to do that. We will use the easiest one: **create-react-app**. You can replace `my-client` by the name of your front-end app.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
npx create-react-app my-client
|
|
22
|
+
cd my-client
|
|
23
|
+
npm start
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 2. Install ChadStart SDK
|
|
27
|
+
|
|
28
|
+
Install the JS SDK from the root of your React app.
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
npm i @chadstart/sdk
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 3. Use it in your app
|
|
35
|
+
|
|
36
|
+
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.
|
|
37
|
+
|
|
38
|
+
```js title="App.tsx"
|
|
39
|
+
import ChadStart from '@chadstart/sdk';
|
|
40
|
+
import { useEffect, useState } from "react";
|
|
41
|
+
|
|
42
|
+
function App() {
|
|
43
|
+
interface Cat {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const [cats, setCat] = useState<Cat[]>([]);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
// Init SDK.
|
|
52
|
+
const chadstart = new ChadStart();
|
|
53
|
+
|
|
54
|
+
// Fetch the list of Cats.
|
|
55
|
+
chadstart.from("cats")
|
|
56
|
+
.find<Cat>()
|
|
57
|
+
.then((res) => {
|
|
58
|
+
setCat(res.data);
|
|
59
|
+
});
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
// Display a list of Cats.
|
|
63
|
+
return (
|
|
64
|
+
<ul>
|
|
65
|
+
{cats.map((cat) => (
|
|
66
|
+
<li>{cat.name}</li>
|
|
67
|
+
))}
|
|
68
|
+
</ul>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default App;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Checkout the [SDK doc](./crud.md#using-the-javascript-sdk) to see more usages of the SDK: CRUD operations, file upload, authentication,
|
package/docs/realtime.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Realtime
|
|
2
|
+
|
|
3
|
+
ChadStart provides realtime event streaming via WebSocket.
|
|
4
|
+
|
|
5
|
+
## Connecting
|
|
6
|
+
|
|
7
|
+
Connect to the WebSocket server at `ws://localhost:3000/realtime`:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
const ws = new WebSocket('ws://localhost:3000/realtime');
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Subscribing to Events
|
|
14
|
+
|
|
15
|
+
Send a `subscribe` message to listen for changes on a specific entity:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
ws.send(JSON.stringify({ type: 'subscribe', channel: 'Post' }));
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Subscribe to `*` to receive all events:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
ws.send(JSON.stringify({ type: 'subscribe', channel: '*' }));
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Receiving Events
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
ws.onmessage = (e) => {
|
|
31
|
+
const { event, data } = JSON.parse(e.data);
|
|
32
|
+
// event: 'Post.created' | 'Post.updated' | 'Post.deleted'
|
|
33
|
+
console.log(event, data);
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Event Types
|
|
38
|
+
|
|
39
|
+
| Event | Triggered When |
|
|
40
|
+
|-------|---------------|
|
|
41
|
+
| `EntityName.created` | A new record is created |
|
|
42
|
+
| `EntityName.updated` | A record is updated |
|
|
43
|
+
| `EntityName.deleted` | A record is deleted |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: s3-storage
|
|
3
|
+
title: S3 Storage
|
|
4
|
+
description: Use any S3-compatible storage to store your user assets in your ChadStart backend. Images, videos, documents...
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# S3 Storage
|
|
8
|
+
|
|
9
|
+
## Introduction
|
|
10
|
+
|
|
11
|
+
ChadStart supports **S3 storage** to manage assets. To use it, ensure you have:
|
|
12
|
+
|
|
13
|
+
- A **storage bucket** (or equivalent).
|
|
14
|
+
- Access credentials with read and write permissions.
|
|
15
|
+
|
|
16
|
+
## Configuration
|
|
17
|
+
|
|
18
|
+
Define these variables in your `.env` file:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
S3_BUCKET=my-bucket-name
|
|
22
|
+
S3_ENDPOINT=https://your-s3-provider.com
|
|
23
|
+
S3_REGION=XXX
|
|
24
|
+
S3_ACCESS_KEY_ID=XXX
|
|
25
|
+
S3_SECRET_ACCESS_KEY=XXX
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Optionally, you can set a folder prefix to prepend your object path:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
S3_FOLDER_PREFIX=development/chadstart
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
!!! note
|
|
35
|
+
S3 storage in ChadStart has been **validated** with **AWS S3** and **Digital Ocean Spaces**. Other S3-compatible providers may work, but they have not been officially tested.
|
|
36
|
+
|
|
37
|
+
## ChadStart guides
|
|
38
|
+
|
|
39
|
+
- [AWS S3 Storage guide](https://chadstart.com/integrations/s3-storage)
|
|
40
|
+
- [Digital Ocean Spaces guide](https://chadstart.com/integrations/digital-ocean-spaces)
|
package/docs/security.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: security
|
|
3
|
+
title: Security
|
|
4
|
+
description: Implement Security in your ChadStart backend and make sure that your app is protected.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Security
|
|
8
|
+
|
|
9
|
+
Implement security measures in your ChadStart backend.
|
|
10
|
+
|
|
11
|
+
## Rate limiting
|
|
12
|
+
|
|
13
|
+
Rate-limiting can protect your backend from **brute-force attacks** by blocking requests after reaching a limit.
|
|
14
|
+
|
|
15
|
+
You can implement one or several throttler definitions to limit API calls in the `chadstart.yaml` file. The following example allow no more than 2 calls per second, and 50 calls per minute:
|
|
16
|
+
|
|
17
|
+
```yaml title="chadstart.yaml"
|
|
18
|
+
name: my app
|
|
19
|
+
|
|
20
|
+
rateLimits:
|
|
21
|
+
- { name: 'short', limit: 2, ttl: 1000 } # 2 requests per second
|
|
22
|
+
- { name: 'medium', limit: 50, ttl: 60000 } # 50 requests per minute.
|
|
23
|
+
```
|