@kyro-cms/core 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -1,205 +1,524 @@
1
1
  # Kyro CMS
2
2
 
3
+ <div align="center">
4
+
3
5
  **Astro-Native Headless CMS with Multi-Database Adapters, Multi-Protocol APIs, and Multi-Vendor Support**
4
6
 
5
- Kyro is an open-source, TypeScript-native headless CMS inspired by Payload CMS but architected specifically for Astro JS. It provides zero-inference tRPC, SQL-sovereign Drizzle schemas, and built-in multi-tenancy.
7
+ [![npm version](https://img.shields.io/npm/v/@kyro-cms/core.svg)](https://www.npmjs.com/package/@kyro-cms/core)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)
10
+
11
+ </div>
6
12
 
7
13
  ---
8
14
 
9
- ## Features
15
+ ## Why Kyro?
10
16
 
11
- ### Local-First with SQLite
12
- ```typescript
13
- import { createKyro, LocalAdapter } from '@kyro-cms/core';
17
+ Kyro is built for **Astro** from the ground up. Unlike other CMS solutions that bolt on Astro support, Kyro is architected to leverage Astro's islands architecture, server output modes, and performance-first approach.
14
18
 
15
- const kyro = createKyro({
16
- adapter: new LocalAdapter({ path: './data.db' }),
17
- collections: [productsCollection],
18
- });
19
- ```
20
- Works out of the box - no external database required.
21
-
22
- ### Deploy Anywhere with Adapters
23
- - **Local/SQLite**: Zero-config local development
24
- - **PostgreSQL/MySQL/SQLite**: Via Drizzle ORM
25
- - **MongoDB**: NoSQL flexibility
19
+ ### Key Features
26
20
 
27
- ### E-Commerce Ready
28
- Pre-built collections for:
29
- - Products with variants, pricing, inventory
30
- - Customers with addresses, orders
31
- - Orders with items, shipping, payments
32
- - Coupons and promotions
33
- - Inventory tracking
21
+ - **Local-First** - SQLite for zero-config development, no external database needed
22
+ - **Multi-Database** - SQLite, PostgreSQL, MySQL, MongoDB via unified adapter interface
23
+ - **Multi-Protocol API** - REST, GraphQL, tRPC, and WebSocket from a single config
24
+ - **Multi-Vendor** - Built-in tenant scoping and row-level access control
25
+ - **E-Commerce Ready** - Products, orders, customers, inventory, coupons out of the box
26
+ - **Plugin System** - Extend with SEO, analytics, reviews, and more
27
+ - **Any Styling** - Tailwind, CSS Modules, Styled Components, or plain CSS
34
28
 
35
- ### Multi-Protocol API
36
- - **REST**: Hono-based with query params
37
- - **GraphQL**: Dynamic schema
38
- - **tRPC**: Type-safe RPC (zero inference)
39
- - **WebSocket**: Real-time pub/sub
29
+ ---
40
30
 
41
- ### Multi-Vendor Ready
42
- Row-level access control with tenant scoping built-in.
31
+ ## Quick Start
43
32
 
44
- ### Plugin System
45
- Extend with:
46
- - SEO (sitemaps, structured data)
47
- - Analytics
48
- - Reviews & Comments
49
- - Wishlists
33
+ ### Option 1: Create New Project (Recommended)
50
34
 
51
- ### Any Styling System
52
- - Plain CSS
53
- - Tailwind CSS
54
- - CSS-in-JS
55
- - Styled Components
56
- - Vanilla Extract
35
+ ```bash
36
+ npm create kyro@latest
37
+ ```
57
38
 
58
- ---
39
+ This launches an interactive wizard that asks:
40
+ - Project name
41
+ - Database (SQLite, PostgreSQL, MySQL, MongoDB)
42
+ - API protocols (REST, GraphQL, tRPC, WebSocket)
43
+ - Styling (Tailwind, CSS Modules, Styled Components, None)
44
+ - Authentication (JWT)
45
+ - Versioning/Drafts
46
+ - Admin dashboard
47
+ - Starting template (Minimal, Blog, E-commerce)
59
48
 
60
- ## Quick Start
49
+ ### Option 2: Add to Existing Project
61
50
 
62
51
  ```bash
63
52
  npm install @kyro-cms/core
64
53
  ```
65
54
 
66
- ### Basic Setup
55
+ ```typescript
56
+ // kyro.config.ts
57
+ import { defineConfig, localAdapter } from '@kyro-cms/core';
58
+
59
+ export default defineConfig({
60
+ name: 'my-app',
61
+ adapter: localAdapter({ path: './data.db' }),
62
+ collections: {
63
+ posts: {
64
+ slug: 'posts',
65
+ label: 'Posts',
66
+ fields: [
67
+ { name: 'title', type: 'text', required: true },
68
+ { name: 'slug', type: 'text', required: true },
69
+ { name: 'content', type: 'richtext' },
70
+ { name: 'published', type: 'checkbox', defaultValue: false },
71
+ ],
72
+ },
73
+ },
74
+ api: {
75
+ rest: true,
76
+ graphql: true,
77
+ },
78
+ });
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Database Adapters
84
+
85
+ ### SQLite (Local-First)
67
86
 
68
87
  ```typescript
69
- import { createKyro, LocalAdapter } from '@kyro-cms/core';
88
+ import { localAdapter } from '@kyro-cms/core';
70
89
 
71
- const kyro = createKyro({
72
- adapter: new LocalAdapter(),
73
- collections: [{
74
- slug: 'posts',
75
- fields: [
76
- { name: 'title', type: 'text', required: true },
77
- { name: 'content', type: 'richtext' },
78
- ],
79
- }],
90
+ const adapter = localAdapter({
91
+ path: './data.db', // or ':memory:' for in-memory
80
92
  });
93
+ ```
94
+
95
+ Perfect for development and small projects. Zero configuration required.
81
96
 
82
- await kyro.init();
97
+ ### PostgreSQL/MySQL (Production)
98
+
99
+ ```typescript
100
+ import { drizzleAdapter } from '@kyro-cms/core';
101
+
102
+ const adapter = drizzleAdapter({
103
+ connectionString: process.env.DATABASE_URL,
104
+ });
105
+ ```
106
+
107
+ ### MongoDB (Flexible Schemas)
108
+
109
+ ```typescript
110
+ import { mongoAdapter } from '@kyro-cms/core';
111
+
112
+ const adapter = mongoAdapter({
113
+ connectionString: process.env.MONGODB_URI,
114
+ });
83
115
  ```
84
116
 
117
+ ---
118
+
119
+ ## API Protocols
120
+
121
+ Kyro exposes your data through multiple protocols simultaneously.
122
+
85
123
  ### REST API
86
124
 
87
125
  ```bash
88
- curl http://localhost:3000/api/posts
89
- curl -X POST http://localhost:3000/api/posts \
90
- -H "Content-Type: application/json" \
91
- -d '{"title":"Hello World"}'
126
+ # List documents
127
+ GET /api/posts
128
+
129
+ # Get single document
130
+ GET /api/posts/:id
131
+
132
+ # Create document
133
+ POST /api/posts
134
+ { "title": "Hello World" }
135
+
136
+ # Update document
137
+ PATCH /api/posts/:id
138
+ { "title": "Updated Title" }
139
+
140
+ # Delete document
141
+ DELETE /api/posts/:id
92
142
  ```
93
143
 
94
144
  ### GraphQL
95
145
 
96
146
  ```graphql
97
- query { postsFind { docs { id title } totalDocs } }
98
- mutation { postsCreate(data: { title: "New Post" }) { doc { id } } }
147
+ query {
148
+ postsFind(where: {}, page: 1, limit: 10) {
149
+ docs {
150
+ id
151
+ title
152
+ slug
153
+ }
154
+ totalDocs
155
+ }
156
+ }
157
+
158
+ mutation {
159
+ postsCreate(data: { title: "New Post", slug: "new-post" }) {
160
+ doc {
161
+ id
162
+ title
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ ### tRPC
169
+
170
+ ```typescript
171
+ const client = createTRPCClient({
172
+ router: kyro.router,
173
+ transformer: superjson,
174
+ });
175
+
176
+ // Type-safe queries
177
+ const posts = await client.posts.find.query({ page: 1 });
178
+ const newPost = await client.posts.create.mutate({
179
+ title: "Hello",
180
+ slug: "hello"
181
+ });
182
+ ```
183
+
184
+ ### WebSocket (Real-time)
185
+
186
+ ```typescript
187
+ const ws = new WebSocket('ws://localhost:4321/api/ws');
188
+
189
+ ws.send(JSON.stringify({
190
+ type: 'subscribe',
191
+ collection: 'posts',
192
+ event: 'create'
193
+ }));
194
+
195
+ ws.onmessage = (event) => {
196
+ const data = JSON.parse(event.data);
197
+ // Handle real-time updates
198
+ };
99
199
  ```
100
200
 
101
201
  ---
102
202
 
103
- ## E-Commerce Example
203
+ ## Field Types
204
+
205
+ Kyro supports 21 field types:
206
+
207
+ | Type | Description |
208
+ |------|-------------|
209
+ | `text` | Single-line text input |
210
+ | `textarea` | Multi-line text |
211
+ | `richtext` | Rich text editor content |
212
+ | `markdown` | Markdown content |
213
+ | `number` | Numeric values |
214
+ | `email` | Email with validation |
215
+ | `password` | Hashed password storage |
216
+ | `checkbox` | Boolean toggle |
217
+ | `date` | Date/time picker |
218
+ | `select` | Dropdown selection |
219
+ | `radio` | Radio button group |
220
+ | `color` | Color picker |
221
+ | `json` | JSON data |
222
+ | `code` | Code editor content |
223
+ | `array` | Repeatable field groups |
224
+ | `group` | Nested field groups |
225
+ | `relationship` | Link to other documents |
226
+ | `upload` | File/media uploads |
227
+ | `blocks` | Structured content blocks |
228
+ | `row` | Horizontal field layout |
229
+ | `collapsible` | Collapsible field sections |
230
+ | `tabs` | Tabbed interface |
231
+
232
+ ### Example: Complex Fields
104
233
 
105
234
  ```typescript
106
- import { createKyro, LocalAdapter } from '@kyro-cms/core';
107
- import {
108
- productsCollection,
109
- ordersCollection,
110
- customersCollection,
111
- ecommerceCollections
112
- } from '@kyro-cms/core/examples/ecommerce';
235
+ fields: [
236
+ { name: 'title', type: 'text', required: true },
237
+
238
+ {
239
+ name: 'author',
240
+ type: 'relationship',
241
+ relationTo: 'users',
242
+ required: true
243
+ },
244
+
245
+ {
246
+ name: 'tags',
247
+ type: 'array',
248
+ fields: [
249
+ { name: 'name', type: 'text' },
250
+ { name: 'slug', type: 'text' },
251
+ ]
252
+ },
253
+
254
+ {
255
+ name: 'metadata',
256
+ type: 'group',
257
+ fields: [
258
+ { name: 'views', type: 'number', defaultValue: 0 },
259
+ { name: 'featured', type: 'checkbox' },
260
+ ]
261
+ }
262
+ ]
263
+ ```
264
+
265
+ ---
266
+
267
+ ## E-Commerce Collections
268
+
269
+ Pre-built collections for building online stores:
270
+
271
+ ```typescript
272
+ import { ecommerceCollections } from '@kyro-cms/core';
113
273
 
114
274
  const kyro = createKyro({
115
- adapter: new LocalAdapter({ path: './store.db' }),
275
+ adapter: localAdapter({ path: './store.db' }),
116
276
  collections: ecommerceCollections,
117
- tenantScoped: true, // Multi-vendor
118
277
  });
119
278
 
120
- await kyro.init();
279
+ // Includes:
280
+ // - products (with variants, pricing, inventory)
281
+ // - categories (hierarchical)
282
+ // - customers (with addresses)
283
+ // - orders (with items, status tracking)
284
+ // - coupons (percentage, fixed, free shipping)
285
+ // - store settings (globals)
121
286
  ```
122
287
 
123
288
  ---
124
289
 
290
+ ## Authentication
291
+
292
+ Built-in JWT authentication:
293
+
294
+ ```typescript
295
+ import { Auth, createAuth } from '@kyro-cms/core';
296
+
297
+ const auth = createAuth(adapter, {
298
+ secret: process.env.JWT_SECRET,
299
+ expiresIn: '24h',
300
+ refreshExpiresIn: '7d',
301
+ });
302
+
303
+ // Register
304
+ await auth.register({
305
+ email: 'user@example.com',
306
+ password: 'secure123',
307
+ role: 'customer',
308
+ });
309
+
310
+ // Login
311
+ const result = await auth.login({
312
+ email: 'user@example.com',
313
+ password: 'secure123',
314
+ });
315
+
316
+ console.log(result.token); // JWT token
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Version History & Drafts
322
+
323
+ Track document changes with built-in versioning:
324
+
325
+ ```typescript
326
+ import { createVersionManager } from '@kyro-cms/core';
327
+
328
+ const versions = createVersionManager(adapter, {
329
+ versioningEnabled: true,
330
+ maxVersionsPerDocument: 50,
331
+ });
332
+
333
+ // Create a new version
334
+ const version = await versions.createVersion({
335
+ collection: 'posts',
336
+ documentId: 'abc123',
337
+ data: { title: 'Updated Post' },
338
+ status: 'draft',
339
+ createdBy: 'user123',
340
+ });
341
+
342
+ // Publish
343
+ await versions.publishVersion({
344
+ collection: 'posts',
345
+ documentId: 'abc123',
346
+ versionId: version.id,
347
+ publishedBy: 'user123',
348
+ });
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Admin Dashboard
354
+
355
+ Kyro includes a full admin dashboard:
356
+
357
+ ```bash
358
+ npm install @kyro-cms/admin
359
+ ```
360
+
361
+ ```astro
362
+ ---
363
+ // admin/index.astro
364
+ import { Admin } from '@kyro-cms/admin';
365
+ import config from '../kyro.config';
366
+ ---
367
+
368
+ <Admin client:load config={config} />
369
+ ```
370
+
371
+ Features:
372
+ - Collection browser with filtering and sorting
373
+ - Document editor with all field types
374
+ - Media library
375
+ - Global settings editor
376
+ - Dark mode support
377
+
378
+ ---
379
+
125
380
  ## Plugin System
126
381
 
382
+ Extend Kyro with plugins:
383
+
127
384
  ```typescript
128
- import { createKyro, SEOPLugin, ReviewsPlugin } from '@kyro-cms/core';
385
+ import {
386
+ KyroPlugin,
387
+ SEOPLugin,
388
+ AnalyticsPlugin,
389
+ CommentsPlugin,
390
+ ReviewsPlugin,
391
+ WishlistPlugin
392
+ } from '@kyro-cms/core';
129
393
 
130
394
  const kyro = createKyro({
131
- adapter: new LocalAdapter(),
395
+ adapter: localAdapter(),
132
396
  collections: [...],
133
397
  plugins: [
134
- new SEOPLugin(),
398
+ new SEOPLugin({
399
+ sitemap: true,
400
+ robotsTxt: true,
401
+ }),
402
+ new AnalyticsPlugin({
403
+ providers: ['google', 'plausible'],
404
+ }),
405
+ new CommentsPlugin(),
135
406
  new ReviewsPlugin(),
136
407
  ],
137
408
  });
138
409
  ```
139
410
 
411
+ ### Creating Plugins
412
+
413
+ ```typescript
414
+ import { KyroPlugin } from '@kyro-cms/core';
415
+
416
+ class MyPlugin extends KyroPlugin {
417
+ name = 'my-plugin';
418
+
419
+ hooks = {
420
+ 'collection.beforeCreate': async (args) => {
421
+ // Transform data before creation
422
+ return { ...args, data: { ...args.data, source: 'my-plugin' } };
423
+ },
424
+
425
+ 'document.afterSave': async (args) => {
426
+ // Send webhook, log analytics, etc.
427
+ await sendWebhook(args);
428
+ },
429
+ };
430
+ }
431
+ ```
432
+
140
433
  ---
141
434
 
142
- ## Styling
435
+ ## Styling System
436
+
437
+ Kyro ships with a complete styling system:
143
438
 
144
439
  ```typescript
145
- import { ecommerce2026Theme, generateCSSVariables } from '@kyro-cms/core';
440
+ import {
441
+ ecommerce2026Theme,
442
+ generateCSSVariables,
443
+ generateTailwindConfig
444
+ } from '@kyro-cms/core';
146
445
 
147
446
  // Generate CSS variables
148
- const css = generateCSSVariables(ecommerce2026Theme);
447
+ const cssVars = generateCSSVariables(ecommerce2026Theme);
448
+
449
+ // Generate Tailwind config
450
+ const tailwindConfig = generateTailwindConfig(ecommerce2026Theme);
451
+
452
+ // Custom themes
453
+ import { createAdminStyling } from '@kyro-cms/core';
454
+
455
+ const myTheme = createAdminStyling({
456
+ primaryColor: '#6366f1',
457
+ borderRadius: 'medium',
458
+ fontFamily: 'Inter',
459
+ });
149
460
  ```
150
461
 
151
462
  ---
152
463
 
153
- ## Architecture
464
+ ## Deployment
154
465
 
466
+ ### Vercel
467
+
468
+ ```bash
469
+ vercel --prod
155
470
  ```
156
- ┌──────────────────────────────────────────────────────────────┐
157
- │ Your Config │
158
- │ (CollectionConfig[]) │
159
- └───────────────────────────┬──────────────────────────────────┘
160
-
161
-
162
- ┌──────────────────────────────────────────────────────────────┐
163
- │ Registry │
164
- │ • Stores configs │
165
- │ • Generates Zod schemas │
166
- │ • Validates config │
167
- └───────────────────────────┬──────────────────────────────────┘
168
-
169
- ┌────────────────┼────────────────┐
170
- ▼ ▼ ▼
171
- ┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐
172
- │ Local/SQLite │ │ Drizzle │ │ MongoDB │
173
- │ (Local-first) │ │ (SQL) │ │ (NoSQL) │
174
- └─────────────────┘ └─────────────┘ └─────────────────┘
175
-
176
-
177
- ┌──────────────────────────────────────────────────────────────┐
178
- │ Multi-Protocol API Gateway │
179
- │ • REST (Hono) • GraphQL • tRPC • WebSocket │
180
- └──────────────────────────────────────────────────────────────┘
471
+
472
+ Environment variables:
473
+ - `DATABASE_URL` - PostgreSQL connection string
474
+ - `JWT_SECRET` - JWT signing secret
475
+
476
+ ### Railway
477
+
478
+ ```bash
479
+ railway up
480
+ ```
481
+
482
+ ### Docker
483
+
484
+ ```bash
485
+ cd deployments/docker
486
+ docker-compose up -d
181
487
  ```
182
488
 
489
+ See `deployments/` for complete configuration.
490
+
183
491
  ---
184
492
 
185
493
  ## Project Structure
186
494
 
187
495
  ```
188
496
  kyro-cms/
497
+ ├── packages/
498
+ │ └── create-kyro/ # Project scaffolding CLI
189
499
  ├── src/
190
- │ ├── index.ts # Main exports
191
- │ ├── registry/ # Configuration engine
192
- │ ├── fields/ # 21 field types
193
- │ ├── database/ # Adapters (Local, Drizzle, MongoDB)
194
- │ ├── api/ # REST, GraphQL, tRPC, WebSocket
195
- │ ├── plugins/ # Plugin system
196
- │ ├── styling/ # Theming & CSS generation
197
- │ └── cli/ # CLI tools
198
- ├── admin/ # Admin dashboard
199
- ├── examples/
200
- │ ├── basic.config.ts # Blog example
201
- └── ecommerce.config.ts # E-commerce example
202
- └── docs/ # Documentation
500
+ │ ├── index.ts # Main exports
501
+ │ ├── createKyro.ts # Factory function
502
+ │ ├── registry/ # Config registry & validation
503
+ │ ├── fields/ # 21 field type definitions
504
+ │ ├── database/ # Adapter implementations
505
+ ├── local/ # SQLite adapter
506
+ ├── drizzle/ # SQL adapters
507
+ └── mongodb/ # MongoDB adapter
508
+ ├── api/ # Multi-protocol gateway
509
+ │ │ ├── rest/ # Hono REST
510
+ ├── graphql/ # GraphQL schema
511
+ │ ├── trpc/ # tRPC router
512
+ │ │ └── ws/ # WebSocket server
513
+ │ ├── auth/ # JWT authentication
514
+ │ ├── versions/ # Version history
515
+ │ ├── plugins/ # Plugin system
516
+ │ ├── styling/ # Theming
517
+ │ └── cli/ # CLI tools
518
+ ├── admin/ # Admin dashboard (Astro)
519
+ ├── examples/ # Example configurations
520
+ ├── docs/ # Documentation
521
+ └── deployments/ # Deployment configs
203
522
  ```
204
523
 
205
524
  ---
@@ -207,9 +526,20 @@ kyro-cms/
207
526
  ## CLI Commands
208
527
 
209
528
  ```bash
210
- kyro generate # Generate TypeScript types
211
- kyro migrate # Run migrations
212
- kyro health # Check system health
529
+ # Initialize a new project
530
+ npm create kyro@latest
531
+
532
+ # Generate TypeScript types
533
+ kyro generate
534
+
535
+ # Push schema to database
536
+ kyro push
537
+
538
+ # Open database studio
539
+ kyro studio
540
+
541
+ # Check system health
542
+ kyro health
213
543
  ```
214
544
 
215
545
  ---
@@ -220,22 +550,31 @@ kyro health # Check system health
220
550
  - [API Reference](docs/api.md)
221
551
  - [E-Commerce Guide](docs/ecommerce.md)
222
552
  - [Plugin Development](docs/plugins.md)
223
- - [Styling Guide](docs/styling.md)
553
+ - [Deployment Guide](docs/deployment.md)
554
+
555
+ ---
556
+
557
+ ## Contributing
558
+
559
+ Contributions are welcome! Please read our contributing guide before submitting PRs.
560
+
561
+ 1. Fork the repository
562
+ 2. Create your feature branch (`git checkout -b feature/amazing`)
563
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
564
+ 4. Push to the branch (`git push origin feature/amazing`)
565
+ 5. Open a Pull Request
224
566
 
225
567
  ---
226
568
 
227
569
  ## License
228
570
 
229
- MIT
571
+ MIT License - see [LICENSE](LICENSE) for details.
230
572
 
231
573
  ---
232
574
 
233
- ## Roadmap
575
+ ## Acknowledgments
234
576
 
235
- - [x] Local-first SQLite adapter
236
- - [x] E-commerce collections
237
- - [x] Plugin system
238
- - [x] Styling abstraction
239
- - [ ] Full admin dashboard
240
- - [ ] Authentication
241
- - [ ] Version history
577
+ Built with inspiration from:
578
+ - [Payload CMS](https://payloadcms.com/) - The headless CMS that pushed the industry forward
579
+ - [Strapi](https://strapi.io/) - Open source headless CMS
580
+ - [Sanity](https://www.sanity.io/) - Real-time content infrastructure