@kyro-cms/core 0.12.40 → 0.12.41

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.
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';require('../chunk-AHSFSERC.cjs');var commander=require('commander'),R=require('fs'),k=require('path'),url=require('url'),glob=require('glob'),child_process=require('child_process'),J=require('prompts'),q=require('crypto'),n=require('chalk');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var R__default=/*#__PURE__*/_interopDefault(R);var k__default=/*#__PURE__*/_interopDefault(k);var J__default=/*#__PURE__*/_interopDefault(J);var q__default=/*#__PURE__*/_interopDefault(q);var n__default=/*#__PURE__*/_interopDefault(n);function x(e){switch(e.type){case "text":case "email":case "password":case "textarea":case "color":case "code":case "markdown":case "date":case "richtext":case "json":return e.hasMany?"string[]":"string";case "number":return e.hasMany?"number[]":"number";case "checkbox":return "boolean";case "select":case "radio":if(e.options){let t=e.options.map(o=>`'${o.value}'`).join(" | ");return e.hasMany?`(${t})[]`:t}return e.hasMany?"string[]":"string";case "relationship":if(Array.isArray(e.relationTo)){if(e.relationTo.includes("*"))return e.hasMany?"any[]":"any";let t=e.relationTo.map(o=>`${C(o)} | string`).join(" | ");return e.hasMany?`(${t})[]`:`(${t})`}let r=e.relationTo||"unknown";return r==="*"?e.hasMany?"any[]":"any":e.hasMany?`(${C(r)} | string)[]`:`${C(r)} | string`;case "upload":return e.hasMany?"(Media | string)[]":"Media | string";case "array":return e.fields&&e.fields.length>0?`Array<{
3
- ${e.fields.filter(o=>o.name).map(o=>{let s=x(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
2
+ 'use strict';require('../chunk-AHSFSERC.cjs');var commander=require('commander'),$=require('fs'),A=require('path'),url=require('url'),glob=require('glob'),child_process=require('child_process'),J=require('prompts'),q=require('crypto'),n=require('chalk');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var $__default=/*#__PURE__*/_interopDefault($);var A__default=/*#__PURE__*/_interopDefault(A);var J__default=/*#__PURE__*/_interopDefault(J);var q__default=/*#__PURE__*/_interopDefault(q);var n__default=/*#__PURE__*/_interopDefault(n);function k(e){switch(e.type){case "text":case "email":case "password":case "textarea":case "color":case "code":case "markdown":case "date":case "richtext":case "json":return e.hasMany?"string[]":"string";case "number":return e.hasMany?"number[]":"number";case "checkbox":return "boolean";case "select":case "radio":if(e.options){let t=e.options.map(o=>`'${o.value}'`).join(" | ");return e.hasMany?`(${t})[]`:t}return e.hasMany?"string[]":"string";case "relationship":if(Array.isArray(e.relationTo)){if(e.relationTo.includes("*"))return e.hasMany?"any[]":"any";let t=e.relationTo.map(o=>`${w(o)} | string`).join(" | ");return e.hasMany?`(${t})[]`:`(${t})`}let r=e.relationTo||"unknown";return r==="*"?e.hasMany?"any[]":"any":e.hasMany?`(${w(r)} | string)[]`:`${w(r)} | string`;case "upload":return e.hasMany?"(Media | string)[]":"Media | string";case "array":return e.fields&&e.fields.length>0?`Array<{
3
+ ${e.fields.filter(o=>o.name).map(o=>{let s=k(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
4
4
  `)}
5
5
  }>`:"Record<string, any>[]";case "group":return e.fields&&e.fields.length>0?`{
6
- ${e.fields.filter(o=>o.name).map(o=>{let s=x(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
6
+ ${e.fields.filter(o=>o.name).map(o=>{let s=k(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
7
7
  `)}
8
- }`:"Record<string, any>";case "blocks":return "Block[]";default:return "any"}}function C(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function N(e){return e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function H(e){let r=C(e.slug),t=e.fields.filter(o=>o.name).map(o=>{let s=x(o);return ` ${o.name}${o.required?"":"?"}: ${s};`});return t.unshift(" id: string;"),t.push(" createdAt: string;"),t.push(" updatedAt: string;"),`export interface ${r} {
8
+ }`:"Record<string, any>";case "blocks":return "Block[]";default:return "any"}}function w(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function N(e){return e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function H(e){let r=w(e.slug),t=e.fields.filter(o=>o.name).map(o=>{let s=k(o);return ` ${o.name}${o.required?"":"?"}: ${s};`});return t.unshift(" id: string;"),t.push(" createdAt: string;"),t.push(" updatedAt: string;"),`export interface ${r} {
9
9
  ${t.join(`
10
10
  `)}
11
11
  }`}function O(e){let r=e.map(a=>H(a)),t=`// ============================================================================
@@ -96,7 +96,7 @@ export interface KyroDeleteResult<T> {
96
96
  // ============================================================================
97
97
 
98
98
  export interface KyroCollections {
99
- ${e.map(a=>` ${N(a.slug)}: ${C(a.slug)};`).join(`
99
+ ${e.map(a=>` ${N(a.slug)}: ${w(a.slug)};`).join(`
100
100
  `)}
101
101
  }
102
102
 
@@ -145,7 +145,7 @@ export interface Block {
145
145
  [key: string]: any;
146
146
  }
147
147
 
148
- `;for(let t of e){let o=C(t.slug),s=t.fields.filter(a=>a.name).map(a=>{let c=x(a);return ` ${a.name}${a.required?"":"?"}: ${c};`});s.unshift(" id: string;"),s.push(" createdAt: string;"),s.push(" updatedAt: string;"),r+=`export interface ${o} {
148
+ `;for(let t of e){let o=w(t.slug),s=t.fields.filter(a=>a.name).map(a=>{let c=k(a);return ` ${a.name}${a.required?"":"?"}: ${c};`});s.unshift(" id: string;"),s.push(" createdAt: string;"),s.push(" updatedAt: string;"),r+=`export interface ${o} {
149
149
  ${s.join(`
150
150
  `)}
151
151
  }
@@ -189,7 +189,7 @@ export function createKyroClient(opts: KyroClientOptions) {
189
189
  }
190
190
 
191
191
  return {
192
- ${e.map(t=>{let o=C(t.slug);return ` ${N(t.slug)}: {
192
+ ${e.map(t=>{let o=w(t.slug);return ` ${N(t.slug)}: {
193
193
  find: (args?: { where?: Record<string, any>; sort?: string; limit?: number; page?: number; draft?: boolean }) =>
194
194
  request<{ docs: ${o}[]; totalDocs: number; page: number; totalPages: number; hasNextPage: boolean; hasPrevPage: boolean }>(\`/${t.slug}\${args ? "?" + qs(args) : ""}\`),
195
195
  findByID: (id: string, args?: { draft?: boolean }) =>
@@ -208,7 +208,7 @@ ${e.map(t=>{let o=C(t.slug);return ` ${N(t.slug)}: {
208
208
  `)}
209
209
  };
210
210
  }
211
- `,r}function K(){return new commander.Command("generate").description("Generate TypeScript types from collection configs").option("-c, --config <path>","Path to config file or directory","./src/kyro").option("-o, --output <path>","Output file path","./src/types/kyro.d.ts").option("-w, --watch","Watch for changes and regenerate").option("--url <url>","URL of a running Kyro CMS instance (enables remote mode)").option("--api-key <key>","API key for authentication (required with --url)").action(async r=>{if(r.url){r.url||(console.error("\u274C --url is required when using --api"),process.exit(1)),r.apiKey||(console.error("\u274C --api-key is required when using --api"),process.exit(1));let s=k.resolve(r.output);try{let a=await Y(r.url,r.apiKey),c=G(a),p=k.join(s,"..");R.existsSync(p)||R.mkdirSync(p,{recursive:!0}),R.writeFileSync(s,c);}catch(a){console.error("\u274C Error:",a.message),process.exit(1);}return}let t=k.resolve(r.config),o=k.resolve(r.output);try{let s=await glob.glob(`${t}/**/*.{ts,js}`);s.length===0&&(console.error("\u274C No config files found at:",t),process.exit(1));let a=[];for(let d of s)try{let m=await import(d),f=Object.values(m).filter(u=>u&&u.slug&&u.fields);a.push(...f);}catch{console.warn(`\u26A0\uFE0F Could not parse: ${d}`);}a.length===0&&(console.error("\u274C No valid collection configs found"),process.exit(1));let c=O(a),p=k.join(o,"..");if(R.existsSync(p)||R.mkdirSync(p,{recursive:!0}),R.writeFileSync(o,c),r.watch){let{watch:d}=await import('fs');d(t,{recursive:!0},async(m,f)=>{let u=[];for(let S of s)try{let y=await import(S+`?t=${Date.now()}`),w=Object.values(y).filter(h=>h&&h.slug&&h.fields);u.push(...w);}catch{}let A=O(u);R.writeFileSync(o,A);});}}catch(s){console.error("\u274C Error:",s.message),process.exit(1);}})}function V(e=3){return q__default.default.randomBytes(e).toString("hex")}function Z(){return q__default.default.randomBytes(12).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,16)}function F(){let e=new commander.Command("deploy").description("Deploy Kyro CMS");return e.command("cloudflare").description("Deploy to Cloudflare Workers with Assets").option("-d, --database <type>","Database type (d1|postgres)").option("-u, --database-url <url>","PostgreSQL connection string").option("-n, --name <name>","Cloudflare project name").option("-b, --r2-bucket <name>","R2 storage bucket name").option("-e, --email <email>","Initial Super Admin email").option("-p, --password <password>","Initial Super Admin password").option("-y, --non-interactive","Skip all prompts and use defaults").action(async r=>{console.log(n__default.default.cyan("==============================================================================")),console.log(n__default.default.bold("\u{1F680} Kyro CMS Cloudflare Deployment (Workers)")),console.log(n__default.default.cyan(`==============================================================================
211
+ `,r}function K(){return new commander.Command("generate").description("Generate TypeScript types from collection configs").option("-c, --config <path>","Path to config file or directory","./src/kyro").option("-o, --output <path>","Output file path","./src/types/kyro.d.ts").option("-w, --watch","Watch for changes and regenerate").option("--url <url>","URL of a running Kyro CMS instance (enables remote mode)").option("--api-key <key>","API key for authentication (required with --url)").action(async r=>{if(r.url){r.url||(console.error("\u274C --url is required when using --api"),process.exit(1)),r.apiKey||(console.error("\u274C --api-key is required when using --api"),process.exit(1));let s=A.resolve(r.output);try{let a=await Y(r.url,r.apiKey),c=G(a),p=A.join(s,"..");$.existsSync(p)||$.mkdirSync(p,{recursive:!0}),$.writeFileSync(s,c);}catch(a){console.error("\u274C Error:",a.message),process.exit(1);}return}let t=A.resolve(r.config),o=A.resolve(r.output);try{let s=await glob.glob(`${t}/**/*.{ts,js}`);s.length===0&&(console.error("\u274C No config files found at:",t),process.exit(1));let a=[];for(let d of s)try{let m=await import(d),f=Object.values(m).filter(u=>u&&u.slug&&u.fields);a.push(...f);}catch{console.warn(`\u26A0\uFE0F Could not parse: ${d}`);}a.length===0&&(console.error("\u274C No valid collection configs found"),process.exit(1));let c=O(a),p=A.join(o,"..");if($.existsSync(p)||$.mkdirSync(p,{recursive:!0}),$.writeFileSync(o,c),r.watch){let{watch:d}=await import('fs');d(t,{recursive:!0},async(m,f)=>{let u=[];for(let x of s)try{let y=await import(x+`?t=${Date.now()}`),C=Object.values(y).filter(h=>h&&h.slug&&h.fields);u.push(...C);}catch{}let E=O(u);$.writeFileSync(o,E);});}}catch(s){console.error("\u274C Error:",s.message),process.exit(1);}})}function V(e=3){return q__default.default.randomBytes(e).toString("hex")}function Z(){return q__default.default.randomBytes(12).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,16)}function F(){let e=new commander.Command("deploy").description("Deploy Kyro CMS");return e.command("cloudflare").description("Deploy to Cloudflare Workers with Assets").option("-d, --database <type>","Database type (d1|postgres)").option("-u, --database-url <url>","PostgreSQL connection string").option("-n, --name <name>","Cloudflare project name").option("-b, --r2-bucket <name>","R2 storage bucket name").option("-e, --email <email>","Initial Super Admin email").option("-p, --password <password>","Initial Super Admin password").option("-y, --non-interactive","Skip all prompts and use defaults").action(async r=>{console.log(n__default.default.cyan("==============================================================================")),console.log(n__default.default.bold("\u{1F680} Kyro CMS Cloudflare Deployment (Workers)")),console.log(n__default.default.cyan(`==============================================================================
212
212
  `));let t=V(),o=Z(),{database:s,databaseUrl:a,name:c,r2Bucket:p,email:d,password:m,nonInteractive:f}=r,u=`kyro-postgres-hd-${t}`;if(a&&!s&&(s="postgres"),!f&&process.stdout.isTTY){console.log(n__default.default.yellow.bold("\u{1F4CB} Setup Configuration")),console.log(n__default.default.dim(`Answer the prompts below to configure your deployment.
213
213
  `));let i=[];s||i.push({type:"select",name:"database",message:n__default.default.cyan("\u250C\u2500 ")+n__default.default.bold("Select Database Infrastructure")+`
214
214
  `+n__default.default.cyan("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")+`
@@ -228,32 +228,32 @@ ${e.map(t=>{let o=C(t.slug);return ` ${N(t.slug)}: {
228
228
  \u250C\u2500 `)+n__default.default.bold("Initial Super Admin Password")+`
229
229
  `+n__default.default.cyan("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")+`
230
230
  `+n__default.default.magenta(" \u203A ")+n__default.default.dim("(default: auto-generate secure password)")});let l=await J__default.default(i);l.database&&(s=l.database),l.databaseUrl&&(a=l.databaseUrl),l.name&&(c=l.name),l.r2Bucket&&(p=l.r2Bucket),l.email&&(d=l.email),l.password&&(m=l.password);}c=c||`kyro-app-${t}`,p=p||`kyro-media-${t}`,d=d||"admin@kyro-cms.com",m=m||o,s=s||"d1",console.log(n__default.default.cyan(`
231
- \u2699\uFE0F Configuration Summary:`)),console.log(` \u2022 Target Hosting: ${n__default.default.bold("Cloudflare Workers with Assets")}`),console.log(` \u2022 Database Mode : ${n__default.default.bold(s)}`),console.log(` \u2022 Project Name : ${n__default.default.bold(c)}`),console.log(` \u2022 R2 Bucket Name: ${n__default.default.bold(p)}`),console.log(` \u2022 Admin Email : ${n__default.default.bold(d)}`);let S=R__default.default.existsSync(k__default.default.join(process.cwd(),"pnpm-lock.yaml"))?"pnpm":"npm",y=`${S} dlx wrangler`;console.log(`
232
- \u{1F50D} Checking Cloudflare Wrangler authentication...`);try{child_process.execSync(`${y} whoami`,{stdio:"ignore"}),console.log(n__default.default.green("\u2705 Cloudflare Wrangler Authenticated."));}catch{console.log(n__default.default.red("\u274C Cloudflare Wrangler authentication required.")),console.log(` Run ${n__default.default.bold(`${y} login`)} or set the ${n__default.default.bold("CLOUDFLARE_API_TOKEN")} env var.`),process.exit(1);}let w="",h="";if(s==="postgres"){a||(console.log(n__default.default.red("\u274C postgres mode requires a database URL.")),process.exit(1)),console.log(`
231
+ \u2699\uFE0F Configuration Summary:`)),console.log(` \u2022 Target Hosting: ${n__default.default.bold("Cloudflare Workers with Assets")}`),console.log(` \u2022 Database Mode : ${n__default.default.bold(s)}`),console.log(` \u2022 Project Name : ${n__default.default.bold(c)}`),console.log(` \u2022 R2 Bucket Name: ${n__default.default.bold(p)}`),console.log(` \u2022 Admin Email : ${n__default.default.bold(d)}`);let x=$__default.default.existsSync(A__default.default.join(process.cwd(),"pnpm-lock.yaml"))?"pnpm":"npm",y=`${x} dlx wrangler`;console.log(`
232
+ \u{1F50D} Checking Cloudflare Wrangler authentication...`);try{child_process.execSync(`${y} whoami`,{stdio:"ignore"}),console.log(n__default.default.green("\u2705 Cloudflare Wrangler Authenticated."));}catch{console.log(n__default.default.red("\u274C Cloudflare Wrangler authentication required.")),console.log(` Run ${n__default.default.bold(`${y} login`)} or set the ${n__default.default.bold("CLOUDFLARE_API_TOKEN")} env var.`),process.exit(1);}let C="",h="";if(s==="postgres"){a||(console.log(n__default.default.red("\u274C postgres mode requires a database URL.")),process.exit(1)),console.log(`
233
233
  \u26A1 Provisioning Cloudflare Hyperdrive (${u})...`);try{let i=child_process.execSync(`${y} hyperdrive list --json`,{stdio:"pipe"}).toString(),b=JSON.parse(i.slice(i.indexOf("["))).find(D=>D.name===u);b&&(h=b.id||b.uuid);}catch{}if(!h)try{let i=child_process.execSync(`${y} hyperdrive create "${u}" --connection-string="${a}" --json`,{stdio:"pipe"}).toString(),l=JSON.parse(i.slice(i.indexOf("{")));h=l.id||l.uuid;}catch{}console.log(n__default.default.green(`\u2705 Hyperdrive Provisioned (ID: ${h||"auto"})`));}else {let i=`${c}-d1`;console.log(`
234
- \u{1F5C2}\uFE0F Selecting or creating D1 database (${i})...`);try{let b=child_process.execSync(`${y} d1 create "${i}"`,{stdio:"pipe"}).toString().match(/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i);b&&(w=b[1]);}catch{try{let b=child_process.execSync(`${y} d1 list --json`,{stdio:"pipe"}).toString(),_=JSON.parse(b).find(W=>W.name===i);_&&(w=_.id||_.uuid);}catch{}}console.log(n__default.default.green(`\u2705 Using D1 database: ${i} (ID: ${w})`));}console.log(`
234
+ \u{1F5C2}\uFE0F Selecting or creating D1 database (${i})...`);try{let b=child_process.execSync(`${y} d1 create "${i}"`,{stdio:"pipe"}).toString().match(/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i);b&&(C=b[1]);}catch{try{let b=child_process.execSync(`${y} d1 list --json`,{stdio:"pipe"}).toString(),_=JSON.parse(b).find(W=>W.name===i);_&&(C=_.id||_.uuid);}catch{}}console.log(n__default.default.green(`\u2705 Using D1 database: ${i} (ID: ${C})`));}console.log(`
235
235
  \u{1F5C4}\uFE0F Provisioning R2 Bucket '${p}'...`);try{child_process.execSync(`${y} r2 bucket create "${p}"`,{stdio:"ignore"});}catch{console.log(`\u2139\uFE0F Bucket '${p}' already exists.`);}try{child_process.execSync(`echo "y" | ${y} r2 bucket dev-url enable "${p}"`,{stdio:"ignore"});}catch{}console.log(`
236
- \u2699\uFE0F Generating wrangler.toml...`);let E=`name = "${c}"
236
+ \u2699\uFE0F Generating wrangler.toml...`);let R=`name = "${c}"
237
237
  compatibility_date = "2026-01-01"
238
238
  compatibility_flags = ["nodejs_compat"]
239
239
 
240
240
  [assets]
241
241
  directory = "dist/client"
242
242
  binding = "ASSETS"
243
- `;s==="postgres"?E+=`
243
+ `;s==="postgres"?R+=`
244
244
  [[hyperdrive]]
245
245
  binding = "HYPERDRIVE"
246
246
  id = "${h}"
247
- `:E+=`
247
+ `:R+=`
248
248
  [[d1_databases]]
249
249
  binding = "DB"
250
250
  database_name = "${c}-d1"
251
- database_id = "${w}"
252
- `,E+=`
251
+ database_id = "${C}"
252
+ `,R+=`
253
253
  [[r2_buckets]]
254
254
  binding = "STORAGE_BUCKET"
255
255
  bucket_name = "${p}"
256
- `,R__default.default.writeFileSync(k__default.default.join(process.cwd(),"wrangler.toml"),E,"utf8"),console.log(`
256
+ `,$__default.default.writeFileSync(A__default.default.join(process.cwd(),"wrangler.toml"),R,"utf8"),console.log(`
257
257
  \u{1F5C3}\uFE0F Running schema migrations & seeding super admin...`);let B=`import bcrypt from 'bcryptjs'; console.log(bcrypt.hashSync('${m}', 10));`,I="";try{I=child_process.execSync(`node -e "${B}"`,{stdio:"pipe"}).toString().trim();}catch{}if(s==="postgres"){try{child_process.execSync(`DATABASE_URL="${a}" npx drizzle-kit push --force`,{stdio:"ignore"});}catch{}let i=`
258
258
  import postgres from 'postgres';
259
259
  import bcrypt from 'bcryptjs';
@@ -301,11 +301,13 @@ bucket_name = "${p}"
301
301
  INSERT OR IGNORE INTO users (id, email, password_hash, role, email_verified)
302
302
  VALUES ('admin-super-1', '${d}', '${I}', 'super_admin', 1);
303
303
  `;try{child_process.execSync(`${y} d1 execute "${c}-d1" --remote --command="${i.replace(/\n/g," ")}"`,{stdio:"ignore"}),console.log(n__default.default.green(" \u2705 D1 Schema Migrated & Super Admin Configured."));}catch{}}console.log(`
304
- \u{1F6E0}\uFE0F Building for Cloudflare...`);try{child_process.execSync(`${S} run build`,{stdio:"inherit"});}catch{console.log(n__default.default.red(`
304
+ \u{1F6E0}\uFE0F Building for Cloudflare...`);try{child_process.execSync(`${x} run build`,{stdio:"inherit"}),$__default.default.appendFileSync(A__default.default.join(process.cwd(),"wrangler.toml"),`
305
+ main = "dist/server/entry.mjs"
306
+ `);}catch{console.log(n__default.default.red(`
305
307
  \u274C Build Failed. Check the output above.`)),process.exit(1);}console.log(`
306
- \u2601\uFE0F Deploying to Cloudflare Workers...`),R__default.default.existsSync(k__default.default.join(process.cwd(),".wrangler"))&&R__default.default.rmSync(k__default.default.join(process.cwd(),".wrangler"),{recursive:true,force:true});try{child_process.execSync(`${y} deploy`,{stdio:"inherit"}),console.log(n__default.default.cyan(`
308
+ \u2601\uFE0F Deploying to Cloudflare Workers...`),$__default.default.existsSync(A__default.default.join(process.cwd(),".wrangler"))&&$__default.default.rmSync(A__default.default.join(process.cwd(),".wrangler"),{recursive:true,force:true});try{child_process.execSync(`${y} deploy`,{stdio:"inherit"}),console.log(n__default.default.cyan(`
307
309
  ==============================================================================`)),console.log(n__default.default.green.bold("\u{1F389} Kyro CMS Deployment Successful!")),console.log(n__default.default.cyan("==============================================================================")),console.log(`
308
310
  Super Admin Credentials:`),console.log(` \u2022 Email : ${n__default.default.bold(d)}`),console.log(` \u2022 Password: ${n__default.default.bold(m)}`),console.log(`
309
311
  Save these credentials! This is the only time the password is displayed.
310
312
  `);}catch{console.log(n__default.default.cyan(`
311
- ==============================================================================`)),console.log(n__default.default.red.bold("\u274C Kyro CMS Cloudflare Deployment Failed!")),console.log(n__default.default.cyan("==============================================================================")),console.log("Inspect the Wrangler output above for error details."),process.exit(1);}}),e}var se=url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))),ae=k.dirname(se),j="0.1.0";try{j=JSON.parse(R.readFileSync(k.join(ae,"../../package.json"),"utf-8")).version;}catch{}var T=new commander.Command;T.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(j);T.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async e=>{let{exec:r}=await import('child_process'),t=r(`astro dev --port ${e.port} --host ${e.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});t.stdout?.on("data",o=>process.stdout.write(o)),t.stderr?.on("data",o=>process.stderr.write(o)),process.on("SIGINT",()=>{t.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{t.kill("SIGTERM"),process.exit(0);});});T.addCommand(K());T.addCommand(F());var $=T.command("db").description("Database management commands");$.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit generate",(r,t,o)=>{r&&(console.error("\u274C Generation failed:",r.message),process.exit(1));});});$.command("migrate").description("Run database migrations").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit migrate",(r,t,o)=>{r&&(console.error("\u274C Migration failed:",r.message),process.exit(1));});});$.command("push").description("Push schema to database (development)").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit push",(r,t,o)=>{r&&(console.error("\u274C Push failed:",r.message),process.exit(1));});});$.command("seed").description("Seed database with initial data").action(async()=>{let{exec:e}=await import('child_process');e("npx tsx src/database/drizzle/seed.ts",(r,t,o)=>{r&&(console.error("\u274C Seeding failed:",r.message),process.exit(1));});});$.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit studio",(r,t,o)=>{r&&(console.error("\u274C Studio failed:",r.message),process.exit(1));});});var ie=T.command("auth").description("Authentication management commands");ie.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async e=>{(!e.email||!e.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:r}=await import('../bootstrap-BGO2NFKB.cjs'),t=process.env.DATABASE_URL||"",o=t.toLowerCase().startsWith("postgres://")||t.toLowerCase().startsWith("postgresql://"),s=t.toLowerCase().startsWith("mongodb://")||t.toLowerCase().startsWith("mongodb+srv://"),a=!t||t.includes(".db")||t.includes("sqlite")||t.includes("file:"),c;if(o){let{PostgresAuthAdapter:d}=await import('../postgres-auth-adapter-JKDYYULH.cjs'),{drizzle:m}=await import('drizzle-orm/postgres-js'),{default:f}=await import('postgres'),u=f(t,{max:1,onnotice:()=>{}}),A=m(u);c=new d({db:A});}else if(s){let{MongoDBAuthAdapter:d}=await import('../mongo-auth-adapter-JVE5M3S4.cjs'),m=await import('mongodb'),f=new m.MongoClient(t);await f.connect();let u=f.db();c=new d({db:u});}else {let{SQLiteAuthAdapter:d}=await import('../sqlite-adapter-PLD57WOH.cjs'),m=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";c=new d({path:m});}c.connect&&await c.connect();let p=await r({authAdapter:c,adminEmail:e.email,adminPassword:e.password,adminRole:e.role});c.disconnect&&await c.disconnect(),p.success||(console.error("\u274C Failed to create admin:",p.error),process.exit(1));}catch(r){console.error("\u274C Bootstrap failed:",r),process.exit(1);}});T.command("health").description("Check system health").action(async()=>{let e=process.env.DATABASE_URL||"",r=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),t=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),o=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:");if(r)try{let{default:s}=await import('postgres'),a=s(e,{max:1,onnotice:()=>{}});await a.unsafe("SELECT 1"),await a.end();}catch{}else if(t)try{let s=await import('mongodb'),a=new s.MongoClient(e);await a.connect(),await a.db().admin().ping(),await a.close();}catch{}else if(o)try{let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:a}=await import('fs');a(s);}catch{}});T.parse();process.argv.slice(2).length||T.outputHelp();
313
+ ==============================================================================`)),console.log(n__default.default.red.bold("\u274C Kyro CMS Cloudflare Deployment Failed!")),console.log(n__default.default.cyan("==============================================================================")),console.log("Inspect the Wrangler output above for error details."),process.exit(1);}}),e}var se=url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))),ae=A.dirname(se),j="0.1.0";try{j=JSON.parse($.readFileSync(A.join(ae,"../../package.json"),"utf-8")).version;}catch{}var T=new commander.Command;T.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(j);T.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async e=>{let{exec:r}=await import('child_process'),t=r(`astro dev --port ${e.port} --host ${e.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});t.stdout?.on("data",o=>process.stdout.write(o)),t.stderr?.on("data",o=>process.stderr.write(o)),process.on("SIGINT",()=>{t.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{t.kill("SIGTERM"),process.exit(0);});});T.addCommand(K());T.addCommand(F());var S=T.command("db").description("Database management commands");S.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit generate",(r,t,o)=>{r&&(console.error("\u274C Generation failed:",r.message),process.exit(1));});});S.command("migrate").description("Run database migrations").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit migrate",(r,t,o)=>{r&&(console.error("\u274C Migration failed:",r.message),process.exit(1));});});S.command("push").description("Push schema to database (development)").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit push",(r,t,o)=>{r&&(console.error("\u274C Push failed:",r.message),process.exit(1));});});S.command("seed").description("Seed database with initial data").action(async()=>{let{exec:e}=await import('child_process');e("npx tsx src/database/drizzle/seed.ts",(r,t,o)=>{r&&(console.error("\u274C Seeding failed:",r.message),process.exit(1));});});S.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit studio",(r,t,o)=>{r&&(console.error("\u274C Studio failed:",r.message),process.exit(1));});});var ie=T.command("auth").description("Authentication management commands");ie.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async e=>{(!e.email||!e.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:r}=await import('../bootstrap-BGO2NFKB.cjs'),t=process.env.DATABASE_URL||"",o=t.toLowerCase().startsWith("postgres://")||t.toLowerCase().startsWith("postgresql://"),s=t.toLowerCase().startsWith("mongodb://")||t.toLowerCase().startsWith("mongodb+srv://"),a=!t||t.includes(".db")||t.includes("sqlite")||t.includes("file:"),c;if(o){let{PostgresAuthAdapter:d}=await import('../postgres-auth-adapter-JKDYYULH.cjs'),{drizzle:m}=await import('drizzle-orm/postgres-js'),{default:f}=await import('postgres'),u=f(t,{max:1,onnotice:()=>{}}),E=m(u);c=new d({db:E});}else if(s){let{MongoDBAuthAdapter:d}=await import('../mongo-auth-adapter-JVE5M3S4.cjs'),m=await import('mongodb'),f=new m.MongoClient(t);await f.connect();let u=f.db();c=new d({db:u});}else {let{SQLiteAuthAdapter:d}=await import('../sqlite-adapter-PLD57WOH.cjs'),m=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";c=new d({path:m});}c.connect&&await c.connect();let p=await r({authAdapter:c,adminEmail:e.email,adminPassword:e.password,adminRole:e.role});c.disconnect&&await c.disconnect(),p.success||(console.error("\u274C Failed to create admin:",p.error),process.exit(1));}catch(r){console.error("\u274C Bootstrap failed:",r),process.exit(1);}});T.command("health").description("Check system health").action(async()=>{let e=process.env.DATABASE_URL||"",r=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),t=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),o=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:");if(r)try{let{default:s}=await import('postgres'),a=s(e,{max:1,onnotice:()=>{}});await a.unsafe("SELECT 1"),await a.end();}catch{}else if(t)try{let s=await import('mongodb'),a=new s.MongoClient(e);await a.connect(),await a.db().admin().ping(),await a.close();}catch{}else if(o)try{let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:a}=await import('fs');a(s);}catch{}});T.parse();process.argv.slice(2).length||T.outputHelp();
package/dist/cli/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import'../chunk-5J6HXUF6.js';import {Command}from'commander';import R,{readFileSync,existsSync,mkdirSync,writeFileSync}from'fs';import k,{dirname,join,resolve}from'path';import {fileURLToPath}from'url';import {glob}from'glob';import {execSync}from'child_process';import J from'prompts';import q from'crypto';import n from'chalk';function x(e){switch(e.type){case "text":case "email":case "password":case "textarea":case "color":case "code":case "markdown":case "date":case "richtext":case "json":return e.hasMany?"string[]":"string";case "number":return e.hasMany?"number[]":"number";case "checkbox":return "boolean";case "select":case "radio":if(e.options){let t=e.options.map(o=>`'${o.value}'`).join(" | ");return e.hasMany?`(${t})[]`:t}return e.hasMany?"string[]":"string";case "relationship":if(Array.isArray(e.relationTo)){if(e.relationTo.includes("*"))return e.hasMany?"any[]":"any";let t=e.relationTo.map(o=>`${C(o)} | string`).join(" | ");return e.hasMany?`(${t})[]`:`(${t})`}let r=e.relationTo||"unknown";return r==="*"?e.hasMany?"any[]":"any":e.hasMany?`(${C(r)} | string)[]`:`${C(r)} | string`;case "upload":return e.hasMany?"(Media | string)[]":"Media | string";case "array":return e.fields&&e.fields.length>0?`Array<{
3
- ${e.fields.filter(o=>o.name).map(o=>{let s=x(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
2
+ import'../chunk-5J6HXUF6.js';import {Command}from'commander';import $,{readFileSync,existsSync,mkdirSync,writeFileSync}from'fs';import A,{dirname,join,resolve}from'path';import {fileURLToPath}from'url';import {glob}from'glob';import {execSync}from'child_process';import J from'prompts';import q from'crypto';import n from'chalk';function k(e){switch(e.type){case "text":case "email":case "password":case "textarea":case "color":case "code":case "markdown":case "date":case "richtext":case "json":return e.hasMany?"string[]":"string";case "number":return e.hasMany?"number[]":"number";case "checkbox":return "boolean";case "select":case "radio":if(e.options){let t=e.options.map(o=>`'${o.value}'`).join(" | ");return e.hasMany?`(${t})[]`:t}return e.hasMany?"string[]":"string";case "relationship":if(Array.isArray(e.relationTo)){if(e.relationTo.includes("*"))return e.hasMany?"any[]":"any";let t=e.relationTo.map(o=>`${w(o)} | string`).join(" | ");return e.hasMany?`(${t})[]`:`(${t})`}let r=e.relationTo||"unknown";return r==="*"?e.hasMany?"any[]":"any":e.hasMany?`(${w(r)} | string)[]`:`${w(r)} | string`;case "upload":return e.hasMany?"(Media | string)[]":"Media | string";case "array":return e.fields&&e.fields.length>0?`Array<{
3
+ ${e.fields.filter(o=>o.name).map(o=>{let s=k(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
4
4
  `)}
5
5
  }>`:"Record<string, any>[]";case "group":return e.fields&&e.fields.length>0?`{
6
- ${e.fields.filter(o=>o.name).map(o=>{let s=x(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
6
+ ${e.fields.filter(o=>o.name).map(o=>{let s=k(o);return ` ${o.name}${o.required?"":"?"}: ${s};`}).join(`
7
7
  `)}
8
- }`:"Record<string, any>";case "blocks":return "Block[]";default:return "any"}}function C(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function N(e){return e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function H(e){let r=C(e.slug),t=e.fields.filter(o=>o.name).map(o=>{let s=x(o);return ` ${o.name}${o.required?"":"?"}: ${s};`});return t.unshift(" id: string;"),t.push(" createdAt: string;"),t.push(" updatedAt: string;"),`export interface ${r} {
8
+ }`:"Record<string, any>";case "blocks":return "Block[]";default:return "any"}}function w(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function N(e){return e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase())}function H(e){let r=w(e.slug),t=e.fields.filter(o=>o.name).map(o=>{let s=k(o);return ` ${o.name}${o.required?"":"?"}: ${s};`});return t.unshift(" id: string;"),t.push(" createdAt: string;"),t.push(" updatedAt: string;"),`export interface ${r} {
9
9
  ${t.join(`
10
10
  `)}
11
11
  }`}function O(e){let r=e.map(a=>H(a)),t=`// ============================================================================
@@ -96,7 +96,7 @@ export interface KyroDeleteResult<T> {
96
96
  // ============================================================================
97
97
 
98
98
  export interface KyroCollections {
99
- ${e.map(a=>` ${N(a.slug)}: ${C(a.slug)};`).join(`
99
+ ${e.map(a=>` ${N(a.slug)}: ${w(a.slug)};`).join(`
100
100
  `)}
101
101
  }
102
102
 
@@ -145,7 +145,7 @@ export interface Block {
145
145
  [key: string]: any;
146
146
  }
147
147
 
148
- `;for(let t of e){let o=C(t.slug),s=t.fields.filter(a=>a.name).map(a=>{let c=x(a);return ` ${a.name}${a.required?"":"?"}: ${c};`});s.unshift(" id: string;"),s.push(" createdAt: string;"),s.push(" updatedAt: string;"),r+=`export interface ${o} {
148
+ `;for(let t of e){let o=w(t.slug),s=t.fields.filter(a=>a.name).map(a=>{let c=k(a);return ` ${a.name}${a.required?"":"?"}: ${c};`});s.unshift(" id: string;"),s.push(" createdAt: string;"),s.push(" updatedAt: string;"),r+=`export interface ${o} {
149
149
  ${s.join(`
150
150
  `)}
151
151
  }
@@ -189,7 +189,7 @@ export function createKyroClient(opts: KyroClientOptions) {
189
189
  }
190
190
 
191
191
  return {
192
- ${e.map(t=>{let o=C(t.slug);return ` ${N(t.slug)}: {
192
+ ${e.map(t=>{let o=w(t.slug);return ` ${N(t.slug)}: {
193
193
  find: (args?: { where?: Record<string, any>; sort?: string; limit?: number; page?: number; draft?: boolean }) =>
194
194
  request<{ docs: ${o}[]; totalDocs: number; page: number; totalPages: number; hasNextPage: boolean; hasPrevPage: boolean }>(\`/${t.slug}\${args ? "?" + qs(args) : ""}\`),
195
195
  findByID: (id: string, args?: { draft?: boolean }) =>
@@ -208,7 +208,7 @@ ${e.map(t=>{let o=C(t.slug);return ` ${N(t.slug)}: {
208
208
  `)}
209
209
  };
210
210
  }
211
- `,r}function K(){return new Command("generate").description("Generate TypeScript types from collection configs").option("-c, --config <path>","Path to config file or directory","./src/kyro").option("-o, --output <path>","Output file path","./src/types/kyro.d.ts").option("-w, --watch","Watch for changes and regenerate").option("--url <url>","URL of a running Kyro CMS instance (enables remote mode)").option("--api-key <key>","API key for authentication (required with --url)").action(async r=>{if(r.url){r.url||(console.error("\u274C --url is required when using --api"),process.exit(1)),r.apiKey||(console.error("\u274C --api-key is required when using --api"),process.exit(1));let s=resolve(r.output);try{let a=await Y(r.url,r.apiKey),c=G(a),p=join(s,"..");existsSync(p)||mkdirSync(p,{recursive:!0}),writeFileSync(s,c);}catch(a){console.error("\u274C Error:",a.message),process.exit(1);}return}let t=resolve(r.config),o=resolve(r.output);try{let s=await glob(`${t}/**/*.{ts,js}`);s.length===0&&(console.error("\u274C No config files found at:",t),process.exit(1));let a=[];for(let d of s)try{let m=await import(d),f=Object.values(m).filter(u=>u&&u.slug&&u.fields);a.push(...f);}catch{console.warn(`\u26A0\uFE0F Could not parse: ${d}`);}a.length===0&&(console.error("\u274C No valid collection configs found"),process.exit(1));let c=O(a),p=join(o,"..");if(existsSync(p)||mkdirSync(p,{recursive:!0}),writeFileSync(o,c),r.watch){let{watch:d}=await import('fs');d(t,{recursive:!0},async(m,f)=>{let u=[];for(let S of s)try{let y=await import(S+`?t=${Date.now()}`),w=Object.values(y).filter(h=>h&&h.slug&&h.fields);u.push(...w);}catch{}let A=O(u);writeFileSync(o,A);});}}catch(s){console.error("\u274C Error:",s.message),process.exit(1);}})}function V(e=3){return q.randomBytes(e).toString("hex")}function Z(){return q.randomBytes(12).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,16)}function F(){let e=new Command("deploy").description("Deploy Kyro CMS");return e.command("cloudflare").description("Deploy to Cloudflare Workers with Assets").option("-d, --database <type>","Database type (d1|postgres)").option("-u, --database-url <url>","PostgreSQL connection string").option("-n, --name <name>","Cloudflare project name").option("-b, --r2-bucket <name>","R2 storage bucket name").option("-e, --email <email>","Initial Super Admin email").option("-p, --password <password>","Initial Super Admin password").option("-y, --non-interactive","Skip all prompts and use defaults").action(async r=>{console.log(n.cyan("==============================================================================")),console.log(n.bold("\u{1F680} Kyro CMS Cloudflare Deployment (Workers)")),console.log(n.cyan(`==============================================================================
211
+ `,r}function K(){return new Command("generate").description("Generate TypeScript types from collection configs").option("-c, --config <path>","Path to config file or directory","./src/kyro").option("-o, --output <path>","Output file path","./src/types/kyro.d.ts").option("-w, --watch","Watch for changes and regenerate").option("--url <url>","URL of a running Kyro CMS instance (enables remote mode)").option("--api-key <key>","API key for authentication (required with --url)").action(async r=>{if(r.url){r.url||(console.error("\u274C --url is required when using --api"),process.exit(1)),r.apiKey||(console.error("\u274C --api-key is required when using --api"),process.exit(1));let s=resolve(r.output);try{let a=await Y(r.url,r.apiKey),c=G(a),p=join(s,"..");existsSync(p)||mkdirSync(p,{recursive:!0}),writeFileSync(s,c);}catch(a){console.error("\u274C Error:",a.message),process.exit(1);}return}let t=resolve(r.config),o=resolve(r.output);try{let s=await glob(`${t}/**/*.{ts,js}`);s.length===0&&(console.error("\u274C No config files found at:",t),process.exit(1));let a=[];for(let d of s)try{let m=await import(d),f=Object.values(m).filter(u=>u&&u.slug&&u.fields);a.push(...f);}catch{console.warn(`\u26A0\uFE0F Could not parse: ${d}`);}a.length===0&&(console.error("\u274C No valid collection configs found"),process.exit(1));let c=O(a),p=join(o,"..");if(existsSync(p)||mkdirSync(p,{recursive:!0}),writeFileSync(o,c),r.watch){let{watch:d}=await import('fs');d(t,{recursive:!0},async(m,f)=>{let u=[];for(let x of s)try{let y=await import(x+`?t=${Date.now()}`),C=Object.values(y).filter(h=>h&&h.slug&&h.fields);u.push(...C);}catch{}let E=O(u);writeFileSync(o,E);});}}catch(s){console.error("\u274C Error:",s.message),process.exit(1);}})}function V(e=3){return q.randomBytes(e).toString("hex")}function Z(){return q.randomBytes(12).toString("base64").replace(/[^a-zA-Z0-9]/g,"").slice(0,16)}function F(){let e=new Command("deploy").description("Deploy Kyro CMS");return e.command("cloudflare").description("Deploy to Cloudflare Workers with Assets").option("-d, --database <type>","Database type (d1|postgres)").option("-u, --database-url <url>","PostgreSQL connection string").option("-n, --name <name>","Cloudflare project name").option("-b, --r2-bucket <name>","R2 storage bucket name").option("-e, --email <email>","Initial Super Admin email").option("-p, --password <password>","Initial Super Admin password").option("-y, --non-interactive","Skip all prompts and use defaults").action(async r=>{console.log(n.cyan("==============================================================================")),console.log(n.bold("\u{1F680} Kyro CMS Cloudflare Deployment (Workers)")),console.log(n.cyan(`==============================================================================
212
212
  `));let t=V(),o=Z(),{database:s,databaseUrl:a,name:c,r2Bucket:p,email:d,password:m,nonInteractive:f}=r,u=`kyro-postgres-hd-${t}`;if(a&&!s&&(s="postgres"),!f&&process.stdout.isTTY){console.log(n.yellow.bold("\u{1F4CB} Setup Configuration")),console.log(n.dim(`Answer the prompts below to configure your deployment.
213
213
  `));let i=[];s||i.push({type:"select",name:"database",message:n.cyan("\u250C\u2500 ")+n.bold("Select Database Infrastructure")+`
214
214
  `+n.cyan("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")+`
@@ -228,32 +228,32 @@ ${e.map(t=>{let o=C(t.slug);return ` ${N(t.slug)}: {
228
228
  \u250C\u2500 `)+n.bold("Initial Super Admin Password")+`
229
229
  `+n.cyan("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")+`
230
230
  `+n.magenta(" \u203A ")+n.dim("(default: auto-generate secure password)")});let l=await J(i);l.database&&(s=l.database),l.databaseUrl&&(a=l.databaseUrl),l.name&&(c=l.name),l.r2Bucket&&(p=l.r2Bucket),l.email&&(d=l.email),l.password&&(m=l.password);}c=c||`kyro-app-${t}`,p=p||`kyro-media-${t}`,d=d||"admin@kyro-cms.com",m=m||o,s=s||"d1",console.log(n.cyan(`
231
- \u2699\uFE0F Configuration Summary:`)),console.log(` \u2022 Target Hosting: ${n.bold("Cloudflare Workers with Assets")}`),console.log(` \u2022 Database Mode : ${n.bold(s)}`),console.log(` \u2022 Project Name : ${n.bold(c)}`),console.log(` \u2022 R2 Bucket Name: ${n.bold(p)}`),console.log(` \u2022 Admin Email : ${n.bold(d)}`);let S=R.existsSync(k.join(process.cwd(),"pnpm-lock.yaml"))?"pnpm":"npm",y=`${S} dlx wrangler`;console.log(`
232
- \u{1F50D} Checking Cloudflare Wrangler authentication...`);try{execSync(`${y} whoami`,{stdio:"ignore"}),console.log(n.green("\u2705 Cloudflare Wrangler Authenticated."));}catch{console.log(n.red("\u274C Cloudflare Wrangler authentication required.")),console.log(` Run ${n.bold(`${y} login`)} or set the ${n.bold("CLOUDFLARE_API_TOKEN")} env var.`),process.exit(1);}let w="",h="";if(s==="postgres"){a||(console.log(n.red("\u274C postgres mode requires a database URL.")),process.exit(1)),console.log(`
231
+ \u2699\uFE0F Configuration Summary:`)),console.log(` \u2022 Target Hosting: ${n.bold("Cloudflare Workers with Assets")}`),console.log(` \u2022 Database Mode : ${n.bold(s)}`),console.log(` \u2022 Project Name : ${n.bold(c)}`),console.log(` \u2022 R2 Bucket Name: ${n.bold(p)}`),console.log(` \u2022 Admin Email : ${n.bold(d)}`);let x=$.existsSync(A.join(process.cwd(),"pnpm-lock.yaml"))?"pnpm":"npm",y=`${x} dlx wrangler`;console.log(`
232
+ \u{1F50D} Checking Cloudflare Wrangler authentication...`);try{execSync(`${y} whoami`,{stdio:"ignore"}),console.log(n.green("\u2705 Cloudflare Wrangler Authenticated."));}catch{console.log(n.red("\u274C Cloudflare Wrangler authentication required.")),console.log(` Run ${n.bold(`${y} login`)} or set the ${n.bold("CLOUDFLARE_API_TOKEN")} env var.`),process.exit(1);}let C="",h="";if(s==="postgres"){a||(console.log(n.red("\u274C postgres mode requires a database URL.")),process.exit(1)),console.log(`
233
233
  \u26A1 Provisioning Cloudflare Hyperdrive (${u})...`);try{let i=execSync(`${y} hyperdrive list --json`,{stdio:"pipe"}).toString(),b=JSON.parse(i.slice(i.indexOf("["))).find(D=>D.name===u);b&&(h=b.id||b.uuid);}catch{}if(!h)try{let i=execSync(`${y} hyperdrive create "${u}" --connection-string="${a}" --json`,{stdio:"pipe"}).toString(),l=JSON.parse(i.slice(i.indexOf("{")));h=l.id||l.uuid;}catch{}console.log(n.green(`\u2705 Hyperdrive Provisioned (ID: ${h||"auto"})`));}else {let i=`${c}-d1`;console.log(`
234
- \u{1F5C2}\uFE0F Selecting or creating D1 database (${i})...`);try{let b=execSync(`${y} d1 create "${i}"`,{stdio:"pipe"}).toString().match(/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i);b&&(w=b[1]);}catch{try{let b=execSync(`${y} d1 list --json`,{stdio:"pipe"}).toString(),_=JSON.parse(b).find(W=>W.name===i);_&&(w=_.id||_.uuid);}catch{}}console.log(n.green(`\u2705 Using D1 database: ${i} (ID: ${w})`));}console.log(`
234
+ \u{1F5C2}\uFE0F Selecting or creating D1 database (${i})...`);try{let b=execSync(`${y} d1 create "${i}"`,{stdio:"pipe"}).toString().match(/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i);b&&(C=b[1]);}catch{try{let b=execSync(`${y} d1 list --json`,{stdio:"pipe"}).toString(),_=JSON.parse(b).find(W=>W.name===i);_&&(C=_.id||_.uuid);}catch{}}console.log(n.green(`\u2705 Using D1 database: ${i} (ID: ${C})`));}console.log(`
235
235
  \u{1F5C4}\uFE0F Provisioning R2 Bucket '${p}'...`);try{execSync(`${y} r2 bucket create "${p}"`,{stdio:"ignore"});}catch{console.log(`\u2139\uFE0F Bucket '${p}' already exists.`);}try{execSync(`echo "y" | ${y} r2 bucket dev-url enable "${p}"`,{stdio:"ignore"});}catch{}console.log(`
236
- \u2699\uFE0F Generating wrangler.toml...`);let E=`name = "${c}"
236
+ \u2699\uFE0F Generating wrangler.toml...`);let R=`name = "${c}"
237
237
  compatibility_date = "2026-01-01"
238
238
  compatibility_flags = ["nodejs_compat"]
239
239
 
240
240
  [assets]
241
241
  directory = "dist/client"
242
242
  binding = "ASSETS"
243
- `;s==="postgres"?E+=`
243
+ `;s==="postgres"?R+=`
244
244
  [[hyperdrive]]
245
245
  binding = "HYPERDRIVE"
246
246
  id = "${h}"
247
- `:E+=`
247
+ `:R+=`
248
248
  [[d1_databases]]
249
249
  binding = "DB"
250
250
  database_name = "${c}-d1"
251
- database_id = "${w}"
252
- `,E+=`
251
+ database_id = "${C}"
252
+ `,R+=`
253
253
  [[r2_buckets]]
254
254
  binding = "STORAGE_BUCKET"
255
255
  bucket_name = "${p}"
256
- `,R.writeFileSync(k.join(process.cwd(),"wrangler.toml"),E,"utf8"),console.log(`
256
+ `,$.writeFileSync(A.join(process.cwd(),"wrangler.toml"),R,"utf8"),console.log(`
257
257
  \u{1F5C3}\uFE0F Running schema migrations & seeding super admin...`);let B=`import bcrypt from 'bcryptjs'; console.log(bcrypt.hashSync('${m}', 10));`,I="";try{I=execSync(`node -e "${B}"`,{stdio:"pipe"}).toString().trim();}catch{}if(s==="postgres"){try{execSync(`DATABASE_URL="${a}" npx drizzle-kit push --force`,{stdio:"ignore"});}catch{}let i=`
258
258
  import postgres from 'postgres';
259
259
  import bcrypt from 'bcryptjs';
@@ -301,11 +301,13 @@ bucket_name = "${p}"
301
301
  INSERT OR IGNORE INTO users (id, email, password_hash, role, email_verified)
302
302
  VALUES ('admin-super-1', '${d}', '${I}', 'super_admin', 1);
303
303
  `;try{execSync(`${y} d1 execute "${c}-d1" --remote --command="${i.replace(/\n/g," ")}"`,{stdio:"ignore"}),console.log(n.green(" \u2705 D1 Schema Migrated & Super Admin Configured."));}catch{}}console.log(`
304
- \u{1F6E0}\uFE0F Building for Cloudflare...`);try{execSync(`${S} run build`,{stdio:"inherit"});}catch{console.log(n.red(`
304
+ \u{1F6E0}\uFE0F Building for Cloudflare...`);try{execSync(`${x} run build`,{stdio:"inherit"}),$.appendFileSync(A.join(process.cwd(),"wrangler.toml"),`
305
+ main = "dist/server/entry.mjs"
306
+ `);}catch{console.log(n.red(`
305
307
  \u274C Build Failed. Check the output above.`)),process.exit(1);}console.log(`
306
- \u2601\uFE0F Deploying to Cloudflare Workers...`),R.existsSync(k.join(process.cwd(),".wrangler"))&&R.rmSync(k.join(process.cwd(),".wrangler"),{recursive:true,force:true});try{execSync(`${y} deploy`,{stdio:"inherit"}),console.log(n.cyan(`
308
+ \u2601\uFE0F Deploying to Cloudflare Workers...`),$.existsSync(A.join(process.cwd(),".wrangler"))&&$.rmSync(A.join(process.cwd(),".wrangler"),{recursive:true,force:true});try{execSync(`${y} deploy`,{stdio:"inherit"}),console.log(n.cyan(`
307
309
  ==============================================================================`)),console.log(n.green.bold("\u{1F389} Kyro CMS Deployment Successful!")),console.log(n.cyan("==============================================================================")),console.log(`
308
310
  Super Admin Credentials:`),console.log(` \u2022 Email : ${n.bold(d)}`),console.log(` \u2022 Password: ${n.bold(m)}`),console.log(`
309
311
  Save these credentials! This is the only time the password is displayed.
310
312
  `);}catch{console.log(n.cyan(`
311
- ==============================================================================`)),console.log(n.red.bold("\u274C Kyro CMS Cloudflare Deployment Failed!")),console.log(n.cyan("==============================================================================")),console.log("Inspect the Wrangler output above for error details."),process.exit(1);}}),e}var se=fileURLToPath(import.meta.url),ae=dirname(se),j="0.1.0";try{j=JSON.parse(readFileSync(join(ae,"../../package.json"),"utf-8")).version;}catch{}var T=new Command;T.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(j);T.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async e=>{let{exec:r}=await import('child_process'),t=r(`astro dev --port ${e.port} --host ${e.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});t.stdout?.on("data",o=>process.stdout.write(o)),t.stderr?.on("data",o=>process.stderr.write(o)),process.on("SIGINT",()=>{t.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{t.kill("SIGTERM"),process.exit(0);});});T.addCommand(K());T.addCommand(F());var $=T.command("db").description("Database management commands");$.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit generate",(r,t,o)=>{r&&(console.error("\u274C Generation failed:",r.message),process.exit(1));});});$.command("migrate").description("Run database migrations").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit migrate",(r,t,o)=>{r&&(console.error("\u274C Migration failed:",r.message),process.exit(1));});});$.command("push").description("Push schema to database (development)").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit push",(r,t,o)=>{r&&(console.error("\u274C Push failed:",r.message),process.exit(1));});});$.command("seed").description("Seed database with initial data").action(async()=>{let{exec:e}=await import('child_process');e("npx tsx src/database/drizzle/seed.ts",(r,t,o)=>{r&&(console.error("\u274C Seeding failed:",r.message),process.exit(1));});});$.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit studio",(r,t,o)=>{r&&(console.error("\u274C Studio failed:",r.message),process.exit(1));});});var ie=T.command("auth").description("Authentication management commands");ie.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async e=>{(!e.email||!e.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:r}=await import('../bootstrap-VVIT6YBP.js'),t=process.env.DATABASE_URL||"",o=t.toLowerCase().startsWith("postgres://")||t.toLowerCase().startsWith("postgresql://"),s=t.toLowerCase().startsWith("mongodb://")||t.toLowerCase().startsWith("mongodb+srv://"),a=!t||t.includes(".db")||t.includes("sqlite")||t.includes("file:"),c;if(o){let{PostgresAuthAdapter:d}=await import('../postgres-auth-adapter-33QOIRXT.js'),{drizzle:m}=await import('drizzle-orm/postgres-js'),{default:f}=await import('postgres'),u=f(t,{max:1,onnotice:()=>{}}),A=m(u);c=new d({db:A});}else if(s){let{MongoDBAuthAdapter:d}=await import('../mongo-auth-adapter-5TJO5J5U.js'),m=await import('mongodb'),f=new m.MongoClient(t);await f.connect();let u=f.db();c=new d({db:u});}else {let{SQLiteAuthAdapter:d}=await import('../sqlite-adapter-EXYRYZEV.js'),m=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";c=new d({path:m});}c.connect&&await c.connect();let p=await r({authAdapter:c,adminEmail:e.email,adminPassword:e.password,adminRole:e.role});c.disconnect&&await c.disconnect(),p.success||(console.error("\u274C Failed to create admin:",p.error),process.exit(1));}catch(r){console.error("\u274C Bootstrap failed:",r),process.exit(1);}});T.command("health").description("Check system health").action(async()=>{let e=process.env.DATABASE_URL||"",r=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),t=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),o=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:");if(r)try{let{default:s}=await import('postgres'),a=s(e,{max:1,onnotice:()=>{}});await a.unsafe("SELECT 1"),await a.end();}catch{}else if(t)try{let s=await import('mongodb'),a=new s.MongoClient(e);await a.connect(),await a.db().admin().ping(),await a.close();}catch{}else if(o)try{let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:a}=await import('fs');a(s);}catch{}});T.parse();process.argv.slice(2).length||T.outputHelp();
313
+ ==============================================================================`)),console.log(n.red.bold("\u274C Kyro CMS Cloudflare Deployment Failed!")),console.log(n.cyan("==============================================================================")),console.log("Inspect the Wrangler output above for error details."),process.exit(1);}}),e}var se=fileURLToPath(import.meta.url),ae=dirname(se),j="0.1.0";try{j=JSON.parse(readFileSync(join(ae,"../../package.json"),"utf-8")).version;}catch{}var T=new Command;T.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(j);T.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async e=>{let{exec:r}=await import('child_process'),t=r(`astro dev --port ${e.port} --host ${e.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});t.stdout?.on("data",o=>process.stdout.write(o)),t.stderr?.on("data",o=>process.stderr.write(o)),process.on("SIGINT",()=>{t.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{t.kill("SIGTERM"),process.exit(0);});});T.addCommand(K());T.addCommand(F());var S=T.command("db").description("Database management commands");S.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit generate",(r,t,o)=>{r&&(console.error("\u274C Generation failed:",r.message),process.exit(1));});});S.command("migrate").description("Run database migrations").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit migrate",(r,t,o)=>{r&&(console.error("\u274C Migration failed:",r.message),process.exit(1));});});S.command("push").description("Push schema to database (development)").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit push",(r,t,o)=>{r&&(console.error("\u274C Push failed:",r.message),process.exit(1));});});S.command("seed").description("Seed database with initial data").action(async()=>{let{exec:e}=await import('child_process');e("npx tsx src/database/drizzle/seed.ts",(r,t,o)=>{r&&(console.error("\u274C Seeding failed:",r.message),process.exit(1));});});S.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:e}=await import('child_process');e("npx drizzle-kit studio",(r,t,o)=>{r&&(console.error("\u274C Studio failed:",r.message),process.exit(1));});});var ie=T.command("auth").description("Authentication management commands");ie.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async e=>{(!e.email||!e.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:r}=await import('../bootstrap-VVIT6YBP.js'),t=process.env.DATABASE_URL||"",o=t.toLowerCase().startsWith("postgres://")||t.toLowerCase().startsWith("postgresql://"),s=t.toLowerCase().startsWith("mongodb://")||t.toLowerCase().startsWith("mongodb+srv://"),a=!t||t.includes(".db")||t.includes("sqlite")||t.includes("file:"),c;if(o){let{PostgresAuthAdapter:d}=await import('../postgres-auth-adapter-33QOIRXT.js'),{drizzle:m}=await import('drizzle-orm/postgres-js'),{default:f}=await import('postgres'),u=f(t,{max:1,onnotice:()=>{}}),E=m(u);c=new d({db:E});}else if(s){let{MongoDBAuthAdapter:d}=await import('../mongo-auth-adapter-5TJO5J5U.js'),m=await import('mongodb'),f=new m.MongoClient(t);await f.connect();let u=f.db();c=new d({db:u});}else {let{SQLiteAuthAdapter:d}=await import('../sqlite-adapter-EXYRYZEV.js'),m=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";c=new d({path:m});}c.connect&&await c.connect();let p=await r({authAdapter:c,adminEmail:e.email,adminPassword:e.password,adminRole:e.role});c.disconnect&&await c.disconnect(),p.success||(console.error("\u274C Failed to create admin:",p.error),process.exit(1));}catch(r){console.error("\u274C Bootstrap failed:",r),process.exit(1);}});T.command("health").description("Check system health").action(async()=>{let e=process.env.DATABASE_URL||"",r=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),t=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),o=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:");if(r)try{let{default:s}=await import('postgres'),a=s(e,{max:1,onnotice:()=>{}});await a.unsafe("SELECT 1"),await a.end();}catch{}else if(t)try{let s=await import('mongodb'),a=new s.MongoClient(e);await a.connect(),await a.db().admin().ping(),await a.close();}catch{}else if(o)try{let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:a}=await import('fs');a(s);}catch{}});T.parse();process.argv.slice(2).length||T.outputHelp();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kyro-cms/core",
3
- "version": "0.12.40",
3
+ "version": "0.12.41",
4
4
  "description": "Astro-native headless CMS with multi-database adapters, multi-protocol APIs, and multi-vendor support",
5
5
  "engines": {
6
6
  "node": ">=22"