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.
Files changed (115) hide show
  1. package/.dockerignore +10 -0
  2. package/.env.example +46 -0
  3. package/.github/workflows/browser-test.yml +34 -0
  4. package/.github/workflows/docker-publish.yml +54 -0
  5. package/.github/workflows/docs.yml +31 -0
  6. package/.github/workflows/npm-chadstart.yml +27 -0
  7. package/.github/workflows/npm-sdk.yml +38 -0
  8. package/.github/workflows/test.yml +85 -0
  9. package/.weblate +9 -0
  10. package/Dockerfile +23 -0
  11. package/README.md +348 -0
  12. package/admin/index.html +2802 -0
  13. package/admin/login.html +207 -0
  14. package/chadstart.example.yml +416 -0
  15. package/chadstart.schema.json +367 -0
  16. package/chadstart.yaml +53 -0
  17. package/cli/cli.js +295 -0
  18. package/core/api-generator.js +606 -0
  19. package/core/auth.js +298 -0
  20. package/core/db.js +384 -0
  21. package/core/entity-engine.js +166 -0
  22. package/core/error-reporter.js +132 -0
  23. package/core/file-storage.js +97 -0
  24. package/core/functions-engine.js +353 -0
  25. package/core/openapi.js +171 -0
  26. package/core/plugin-loader.js +92 -0
  27. package/core/realtime.js +93 -0
  28. package/core/schema-validator.js +50 -0
  29. package/core/seeder.js +231 -0
  30. package/core/telemetry.js +119 -0
  31. package/core/upload.js +372 -0
  32. package/core/workers/php_worker.php +19 -0
  33. package/core/workers/python_worker.py +33 -0
  34. package/core/workers/ruby_worker.rb +21 -0
  35. package/core/yaml-loader.js +64 -0
  36. package/demo/chadstart.yaml +178 -0
  37. package/demo/docker-compose.yml +31 -0
  38. package/demo/functions/greet.go +39 -0
  39. package/demo/functions/hello.cpp +18 -0
  40. package/demo/functions/hello.py +13 -0
  41. package/demo/functions/hello.rb +10 -0
  42. package/demo/functions/onTodoCreated.js +13 -0
  43. package/demo/functions/ping.sh +13 -0
  44. package/demo/functions/stats.js +22 -0
  45. package/demo/public/index.html +522 -0
  46. package/docker-compose.yml +17 -0
  47. package/docs/access-policies.md +155 -0
  48. package/docs/admin-ui.md +29 -0
  49. package/docs/angular.md +69 -0
  50. package/docs/astro.md +71 -0
  51. package/docs/auth.md +160 -0
  52. package/docs/cli.md +56 -0
  53. package/docs/config.md +127 -0
  54. package/docs/crud.md +627 -0
  55. package/docs/deploy.md +113 -0
  56. package/docs/docker.md +59 -0
  57. package/docs/entities.md +385 -0
  58. package/docs/functions.md +196 -0
  59. package/docs/getting-started.md +79 -0
  60. package/docs/groups.md +85 -0
  61. package/docs/index.md +5 -0
  62. package/docs/llm-rules.md +81 -0
  63. package/docs/middlewares.md +78 -0
  64. package/docs/overrides/home.html +350 -0
  65. package/docs/plugins.md +59 -0
  66. package/docs/react.md +75 -0
  67. package/docs/realtime.md +43 -0
  68. package/docs/s3-storage.md +40 -0
  69. package/docs/security.md +23 -0
  70. package/docs/stylesheets/extra.css +375 -0
  71. package/docs/svelte.md +71 -0
  72. package/docs/telemetry.md +97 -0
  73. package/docs/upload.md +168 -0
  74. package/docs/validation.md +115 -0
  75. package/docs/vue.md +86 -0
  76. package/docs/webhooks.md +87 -0
  77. package/index.js +11 -0
  78. package/locales/en/admin.json +169 -0
  79. package/mkdocs.yml +82 -0
  80. package/package.json +65 -0
  81. package/playwright.config.js +24 -0
  82. package/public/.gitkeep +0 -0
  83. package/sdk/README.md +284 -0
  84. package/sdk/package.json +39 -0
  85. package/sdk/scripts/build.js +58 -0
  86. package/sdk/src/index.js +368 -0
  87. package/sdk/test/sdk.test.cjs +340 -0
  88. package/sdk/types/index.d.ts +217 -0
  89. package/server/express-server.js +734 -0
  90. package/test/access-policies.test.js +96 -0
  91. package/test/ai.test.js +81 -0
  92. package/test/api-keys.test.js +361 -0
  93. package/test/auth.test.js +122 -0
  94. package/test/browser/admin-ui.spec.js +127 -0
  95. package/test/browser/global-setup.js +71 -0
  96. package/test/browser/global-teardown.js +11 -0
  97. package/test/db.test.js +227 -0
  98. package/test/entity-engine.test.js +193 -0
  99. package/test/error-reporter.test.js +140 -0
  100. package/test/functions-engine.test.js +240 -0
  101. package/test/groups.test.js +212 -0
  102. package/test/hot-reload.test.js +153 -0
  103. package/test/i18n.test.js +173 -0
  104. package/test/middleware.test.js +76 -0
  105. package/test/openapi.test.js +67 -0
  106. package/test/schema-validator.test.js +83 -0
  107. package/test/sdk.test.js +90 -0
  108. package/test/seeder.test.js +279 -0
  109. package/test/settings.test.js +109 -0
  110. package/test/telemetry.test.js +254 -0
  111. package/test/test.js +17 -0
  112. package/test/upload.test.js +265 -0
  113. package/test/validation.test.js +96 -0
  114. package/test/yaml-loader.test.js +93 -0
  115. package/utils/logger.js +24 -0
package/sdk/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # @chadstart/sdk
2
+
3
+ Official JavaScript/TypeScript SDK for [Chadstart](https://github.com/saulmmendoza/chadstart.com) — the YAML-first Backend as a Service.
4
+
5
+ Works in **any JS/TS project**: browsers, React, Vue, Svelte, Angular, Astro, Node.js, and more.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @chadstart/sdk
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ ```js
20
+ import Chadstart from '@chadstart/sdk'
21
+
22
+ // Initialize with your backend URL (defaults to http://localhost:3000)
23
+ const client = new Chadstart('https://your-chadstart-backend.com')
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Collections
29
+
30
+ ### List items (paginated)
31
+
32
+ ```js
33
+ // Fetch all posts (returns paginated result)
34
+ const result = await client.from('posts').find()
35
+ // { data: [...], currentPage: 1, lastPage: 1, total: 10, perPage: 10, from: 1, to: 10 }
36
+
37
+ // With pagination
38
+ const result = await client.from('posts').find({ page: 2, perPage: 20 })
39
+ ```
40
+
41
+ ### Filtering
42
+
43
+ ```js
44
+ const posts = await client
45
+ .from('posts')
46
+ .where('published = true')
47
+ .andWhere('views > 100')
48
+ .find()
49
+ ```
50
+
51
+ **Supported operators:**
52
+
53
+ | Operator | Description | Example |
54
+ | -------- | --------------------- | -------------------------------- |
55
+ | `=` | equals | `.where('isActive = true')` |
56
+ | `!=` | not equals | `.where('status != draft')` |
57
+ | `>` | greater than | `.where('age > 18')` |
58
+ | `>=` | greater than or equal | `.where('price >= 10')` |
59
+ | `<` | less than | `.where('stock < 5')` |
60
+ | `<=` | less than or equal | `.where('amount <= 400')` |
61
+ | `like` | pattern match | `.where('name like %jo%')` |
62
+ | `in` | included in | `.where('status in new,active')` |
63
+
64
+ ### Ordering
65
+
66
+ ```js
67
+ const posts = await client
68
+ .from('posts')
69
+ .orderBy('createdAt', { desc: true })
70
+ .find()
71
+ ```
72
+
73
+ ### Relations
74
+
75
+ ```js
76
+ const posts = await client
77
+ .from('posts')
78
+ .with(['author', 'tags'])
79
+ .find()
80
+
81
+ // Nested relations
82
+ const cities = await client
83
+ .from('cities')
84
+ .with(['region', 'region.country'])
85
+ .find()
86
+ ```
87
+
88
+ ### Get a single item by ID
89
+
90
+ ```js
91
+ const post = await client.from('posts').findOneById('2c4e6a8b-...')
92
+ ```
93
+
94
+ ### Create an item
95
+
96
+ ```js
97
+ const newPost = await client.from('posts').create({
98
+ title: 'Hello World',
99
+ published: true,
100
+ })
101
+ ```
102
+
103
+ ### Update an item (full replace — PUT)
104
+
105
+ ```js
106
+ const updated = await client.from('posts').update('2c4e6a8b-...', {
107
+ title: 'Updated Title',
108
+ published: false,
109
+ })
110
+ ```
111
+
112
+ ### Patch an item (partial update — PATCH)
113
+
114
+ ```js
115
+ const patched = await client.from('posts').patch('2c4e6a8b-...', {
116
+ published: true,
117
+ })
118
+ ```
119
+
120
+ ### Delete an item
121
+
122
+ ```js
123
+ const deleted = await client.from('posts').delete('2c4e6a8b-...')
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Singles
129
+
130
+ Singles are entities with only one record (e.g. homepage content, site settings).
131
+
132
+ ```js
133
+ // Get
134
+ const homepage = await client.single('homepage').get()
135
+
136
+ // Full replace (PUT)
137
+ const updated = await client.single('homepage').update({
138
+ title: 'Welcome!',
139
+ description: 'My awesome site',
140
+ })
141
+
142
+ // Partial update (PATCH)
143
+ const patched = await client.single('homepage').patch({ title: 'New Title' })
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Authentication
149
+
150
+ Chadstart supports multiple authenticable entity types.
151
+
152
+ ```js
153
+ // Sign up
154
+ const { token, user } = await client.auth('customers').signup({
155
+ email: 'alice@example.com',
156
+ password: 'secret',
157
+ name: 'Alice',
158
+ })
159
+ // Token is stored automatically
160
+
161
+ // Log in
162
+ const { token, user } = await client.auth('customers').login({
163
+ email: 'alice@example.com',
164
+ password: 'secret',
165
+ })
166
+ // Token is stored automatically
167
+
168
+ // Get current user (requires a stored token)
169
+ const me = await client.auth('customers').me()
170
+
171
+ // Log out
172
+ client.auth('customers').logout()
173
+ ```
174
+
175
+ ### Manual token management
176
+
177
+ ```js
178
+ // Store a token manually (e.g. from localStorage)
179
+ client.setToken(localStorage.getItem('token'))
180
+
181
+ // Clear the token
182
+ client.clearToken()
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Error Handling
188
+
189
+ All methods throw a `ChadstartError` on non-2xx responses.
190
+
191
+ ```js
192
+ import Chadstart, { ChadstartError } from '@chadstart/sdk'
193
+
194
+ try {
195
+ const post = await client.from('posts').findOneById('missing-id')
196
+ } catch (err) {
197
+ if (err instanceof ChadstartError) {
198
+ console.log(err.status) // e.g. 404
199
+ console.log(err.message) // e.g. "Not found"
200
+ console.log(err.data) // raw response body
201
+ }
202
+ }
203
+ ```
204
+
205
+ ---
206
+
207
+ ## TypeScript
208
+
209
+ Full TypeScript support is included out of the box.
210
+
211
+ ```ts
212
+ import Chadstart from '@chadstart/sdk'
213
+
214
+ interface Post {
215
+ id: string
216
+ title: string
217
+ published: boolean
218
+ }
219
+
220
+ const client = new Chadstart('https://api.example.com')
221
+
222
+ const { data } = await client.from<Post>('posts').find()
223
+ // ^? Post[]
224
+
225
+ const post = await client.from<Post>('posts').findOneById('abc')
226
+ // ^? Post
227
+ ```
228
+
229
+ ---
230
+
231
+ ## CommonJS usage
232
+
233
+ ```js
234
+ const Chadstart = require('@chadstart/sdk')
235
+ const client = new Chadstart('http://localhost:3000')
236
+ ```
237
+
238
+ ---
239
+
240
+ ## API Reference
241
+
242
+ ### `new Chadstart(baseUrl?)`
243
+
244
+ | Parameter | Type | Default | Description |
245
+ | --------- | -------- | -------------------------- | ------------------------ |
246
+ | `baseUrl` | `string` | `'http://localhost:3000'` | Your Chadstart server URL |
247
+
248
+ ### `client.from(slug)` → `CollectionQuery`
249
+
250
+ | Method | Description |
251
+ | --------------------------- | ------------------------------------ |
252
+ | `.where(condition)` | Add a filter |
253
+ | `.andWhere(condition)` | Add an additional filter |
254
+ | `.with(relations)` | Load relations |
255
+ | `.orderBy(field, options?)` | Order results |
256
+ | `.find(params?)` | Fetch paginated list |
257
+ | `.findOneById(id)` | Fetch one item by ID |
258
+ | `.create(data)` | Create a new item |
259
+ | `.update(id, data)` | Replace an item (PUT) |
260
+ | `.patch(id, data)` | Partially update an item (PATCH) |
261
+ | `.delete(id)` | Delete an item |
262
+
263
+ ### `client.single(slug)` → `SingleQuery`
264
+
265
+ | Method | Description |
266
+ | --------------- | -------------------------------- |
267
+ | `.get()` | Fetch the single entity |
268
+ | `.update(data)` | Replace the single entity (PUT) |
269
+ | `.patch(data)` | Partially update it (PATCH) |
270
+
271
+ ### `client.auth(slug)` → `AuthQuery`
272
+
273
+ | Method | Description |
274
+ | --------------- | ---------------------------------------------------- |
275
+ | `.signup(data)` | Register a user; auto-stores the returned token |
276
+ | `.login(data)` | Log in a user; auto-stores the returned token |
277
+ | `.me()` | Get the currently authenticated user |
278
+ | `.logout()` | Clear the stored token |
279
+
280
+ ---
281
+
282
+ ## License
283
+
284
+ ISC
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "chadstart-sdk",
3
+ "version": "1.0.0",
4
+ "description": "Official JavaScript/TypeScript SDK for Chadstart BaaS",
5
+ "keywords": ["chadstart", "sdk", "baas", "backend", "rest", "crud"],
6
+ "author": "Chadstart",
7
+ "license": "ISC",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/saulmmendoza/chadstart.com.git",
11
+ "directory": "sdk"
12
+ },
13
+ "homepage": "https://github.com/saulmmendoza/chadstart.com#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/saulmmendoza/chadstart.com/issues"
16
+ },
17
+ "type": "module",
18
+ "main": "./dist/index.cjs",
19
+ "module": "./dist/index.js",
20
+ "types": "./types/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.cjs",
25
+ "types": "./types/index.d.ts"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "types",
31
+ "README.md"
32
+ ],
33
+ "scripts": {
34
+ "build": "node scripts/build.js",
35
+ "test": "node test/sdk.test.cjs",
36
+ "prepublishOnly": "npm run build"
37
+ },
38
+ "devDependencies": {}
39
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Build script: converts sdk/src/index.js (ESM) into:
3
+ * dist/index.js (ESM, unchanged)
4
+ * dist/index.cjs (CommonJS, wrapped)
5
+ *
6
+ * No external dependencies required — uses only Node.js built-ins.
7
+ */
8
+
9
+ import { readFileSync, writeFileSync, mkdirSync } from 'fs';
10
+ import { fileURLToPath } from 'url';
11
+ import { dirname, join } from 'path';
12
+
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const root = join(__dirname, '..');
15
+
16
+ const src = readFileSync(join(root, 'src', 'index.js'), 'utf8');
17
+
18
+ // ── ESM build (verbatim copy) ─────────────────────────────────────────────────
19
+ mkdirSync(join(root, 'dist'), { recursive: true });
20
+ writeFileSync(join(root, 'dist', 'index.js'), src, 'utf8');
21
+
22
+ // ── CJS build ─────────────────────────────────────────────────────────────────
23
+ // Strip ESM export statements and wrap in a CJS module.
24
+ let cjs = src;
25
+
26
+ // Remove `export default Chadstart;`
27
+ cjs = cjs.replace(/^export default \w+;\n?/m, '');
28
+
29
+ // Remove named export line: `export { Chadstart, ... };`
30
+ cjs = cjs.replace(/^export \{[^}]+\};\n?/m, '');
31
+
32
+ // Remove `export ` keyword from class/function declarations
33
+ cjs = cjs.replace(/^export (class|function|const|let|var) /gm, '$1 ');
34
+
35
+ // Append CommonJS exports at the end
36
+ cjs += `
37
+ // CommonJS exports
38
+ Object.defineProperty(exports, '__esModule', { value: true });
39
+ exports.default = Chadstart;
40
+ exports.Chadstart = Chadstart;
41
+ exports.ChadstartError = ChadstartError;
42
+ exports.CollectionQuery = CollectionQuery;
43
+ exports.SingleQuery = SingleQuery;
44
+ exports.AuthQuery = AuthQuery;
45
+ module.exports = exports.default;
46
+ module.exports.default = exports.default;
47
+ module.exports.Chadstart = Chadstart;
48
+ module.exports.ChadstartError = ChadstartError;
49
+ module.exports.CollectionQuery = CollectionQuery;
50
+ module.exports.SingleQuery = SingleQuery;
51
+ module.exports.AuthQuery = AuthQuery;
52
+ `;
53
+
54
+ // Replace the ESM import/export template with a CJS-safe header
55
+ writeFileSync(join(root, 'dist', 'index.cjs'), `'use strict';\n\n${cjs}`, 'utf8');
56
+
57
+ console.log('✓ dist/index.js (ESM)');
58
+ console.log('✓ dist/index.cjs (CJS)');