@kyro-cms/core 0.12.39 → 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.
- package/dist/cli/index.cjs +22 -21
- package/dist/cli/index.js +22 -21
- package/package.json +2 -2
package/dist/cli/index.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';require('../chunk-AHSFSERC.cjs');var commander=require('commander')
|
|
3
|
-
${e.fields.filter(o=>o.name).map(o=>{let s=
|
|
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=
|
|
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
|
|
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)}: ${
|
|
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=
|
|
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=
|
|
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=
|
|
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,33 +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
|
|
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
|
|
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&&(
|
|
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
|
|
237
|
-
main = "dist/server/entry.mjs"
|
|
236
|
+
\u2699\uFE0F Generating wrangler.toml...`);let R=`name = "${c}"
|
|
238
237
|
compatibility_date = "2026-01-01"
|
|
239
238
|
compatibility_flags = ["nodejs_compat"]
|
|
240
239
|
|
|
241
240
|
[assets]
|
|
242
241
|
directory = "dist/client"
|
|
243
242
|
binding = "ASSETS"
|
|
244
|
-
`;s==="postgres"?
|
|
243
|
+
`;s==="postgres"?R+=`
|
|
245
244
|
[[hyperdrive]]
|
|
246
245
|
binding = "HYPERDRIVE"
|
|
247
246
|
id = "${h}"
|
|
248
|
-
`:
|
|
247
|
+
`:R+=`
|
|
249
248
|
[[d1_databases]]
|
|
250
249
|
binding = "DB"
|
|
251
250
|
database_name = "${c}-d1"
|
|
252
|
-
database_id = "${
|
|
253
|
-
`,
|
|
251
|
+
database_id = "${C}"
|
|
252
|
+
`,R+=`
|
|
254
253
|
[[r2_buckets]]
|
|
255
254
|
binding = "STORAGE_BUCKET"
|
|
256
255
|
bucket_name = "${p}"
|
|
257
|
-
|
|
256
|
+
`,$__default.default.writeFileSync(A__default.default.join(process.cwd(),"wrangler.toml"),R,"utf8"),console.log(`
|
|
258
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=`
|
|
259
258
|
import postgres from 'postgres';
|
|
260
259
|
import bcrypt from 'bcryptjs';
|
|
@@ -302,11 +301,13 @@ bucket_name = "${p}"
|
|
|
302
301
|
INSERT OR IGNORE INTO users (id, email, password_hash, role, email_verified)
|
|
303
302
|
VALUES ('admin-super-1', '${d}', '${I}', 'super_admin', 1);
|
|
304
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(`
|
|
305
|
-
\u{1F6E0}\uFE0F Building for Cloudflare...`);try{child_process.execSync(`${
|
|
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(`
|
|
306
307
|
\u274C Build Failed. Check the output above.`)),process.exit(1);}console.log(`
|
|
307
|
-
\u2601\uFE0F Deploying to Cloudflare Workers...`)
|
|
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(`
|
|
308
309
|
==============================================================================`)),console.log(n__default.default.green.bold("\u{1F389} Kyro CMS Deployment Successful!")),console.log(n__default.default.cyan("==============================================================================")),console.log(`
|
|
309
310
|
Super Admin Credentials:`),console.log(` \u2022 Email : ${n__default.default.bold(d)}`),console.log(` \u2022 Password: ${n__default.default.bold(m)}`),console.log(`
|
|
310
311
|
Save these credentials! This is the only time the password is displayed.
|
|
311
312
|
`);}catch{console.log(n__default.default.cyan(`
|
|
312
|
-
==============================================================================`)),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=
|
|
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
|
|
3
|
-
${e.fields.filter(o=>o.name).map(o=>{let s=
|
|
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=
|
|
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
|
|
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)}: ${
|
|
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=
|
|
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=
|
|
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
|
|
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,33 +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
|
|
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
|
|
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&&(
|
|
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
|
|
237
|
-
main = "dist/server/entry.mjs"
|
|
236
|
+
\u2699\uFE0F Generating wrangler.toml...`);let R=`name = "${c}"
|
|
238
237
|
compatibility_date = "2026-01-01"
|
|
239
238
|
compatibility_flags = ["nodejs_compat"]
|
|
240
239
|
|
|
241
240
|
[assets]
|
|
242
241
|
directory = "dist/client"
|
|
243
242
|
binding = "ASSETS"
|
|
244
|
-
`;s==="postgres"?
|
|
243
|
+
`;s==="postgres"?R+=`
|
|
245
244
|
[[hyperdrive]]
|
|
246
245
|
binding = "HYPERDRIVE"
|
|
247
246
|
id = "${h}"
|
|
248
|
-
`:
|
|
247
|
+
`:R+=`
|
|
249
248
|
[[d1_databases]]
|
|
250
249
|
binding = "DB"
|
|
251
250
|
database_name = "${c}-d1"
|
|
252
|
-
database_id = "${
|
|
253
|
-
`,
|
|
251
|
+
database_id = "${C}"
|
|
252
|
+
`,R+=`
|
|
254
253
|
[[r2_buckets]]
|
|
255
254
|
binding = "STORAGE_BUCKET"
|
|
256
255
|
bucket_name = "${p}"
|
|
257
|
-
|
|
256
|
+
`,$.writeFileSync(A.join(process.cwd(),"wrangler.toml"),R,"utf8"),console.log(`
|
|
258
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=`
|
|
259
258
|
import postgres from 'postgres';
|
|
260
259
|
import bcrypt from 'bcryptjs';
|
|
@@ -302,11 +301,13 @@ bucket_name = "${p}"
|
|
|
302
301
|
INSERT OR IGNORE INTO users (id, email, password_hash, role, email_verified)
|
|
303
302
|
VALUES ('admin-super-1', '${d}', '${I}', 'super_admin', 1);
|
|
304
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(`
|
|
305
|
-
\u{1F6E0}\uFE0F Building for Cloudflare...`);try{execSync(`${
|
|
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(`
|
|
306
307
|
\u274C Build Failed. Check the output above.`)),process.exit(1);}console.log(`
|
|
307
|
-
\u2601\uFE0F Deploying to Cloudflare Workers...`)
|
|
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(`
|
|
308
309
|
==============================================================================`)),console.log(n.green.bold("\u{1F389} Kyro CMS Deployment Successful!")),console.log(n.cyan("==============================================================================")),console.log(`
|
|
309
310
|
Super Admin Credentials:`),console.log(` \u2022 Email : ${n.bold(d)}`),console.log(` \u2022 Password: ${n.bold(m)}`),console.log(`
|
|
310
311
|
Save these credentials! This is the only time the password is displayed.
|
|
311
312
|
`);}catch{console.log(n.cyan(`
|
|
312
|
-
==============================================================================`)),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
|
|
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.
|
|
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"
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
"ws": "^8.18.0",
|
|
192
192
|
"zod": "^3.24.0",
|
|
193
193
|
"zod-to-json-schema": "^3.25.2",
|
|
194
|
-
"@kyro-cms/ai": "0.12.
|
|
194
|
+
"@kyro-cms/ai": "0.12.39"
|
|
195
195
|
},
|
|
196
196
|
"devDependencies": {
|
|
197
197
|
"@tailwindcss/vite": "^4.0.0",
|