create-kyro 0.1.1 → 0.1.3

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.
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "my-kyro-app",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "astro dev",
8
+ "build": "astro build",
9
+ "preview": "astro preview",
10
+ "db:generate": "kyro generate",
11
+ "db:push": "kyro push",
12
+ "db:studio": "kyro studio"
13
+ },
14
+ "dependencies": {
15
+ "@astrojs/node": "^9.5.5",
16
+ "@astrojs/react": "^4.2.0",
17
+ "@kyro-cms/admin": "file:../../../admin",
18
+ "@kyro-cms/core": "file:../../..",
19
+ "@tailwindcss/vite": "^4.0.0",
20
+ "astro": "^5.4.0",
21
+ "lucide-react": "^0.475.0",
22
+ "react": "^19.0.0",
23
+ "react-dom": "^19.0.0",
24
+ "tailwindcss": "^4.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/react": "^19.0.0",
28
+ "@types/react-dom": "^19.0.0",
29
+ "typescript": "^5.7.3"
30
+ }
31
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "create-kyro",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Interactive scaffolding for Kyro CMS projects",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-kyro": "./bin.js"
7
+ "create-kyro": "bin.js"
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -34,13 +34,7 @@
34
34
  "astro"
35
35
  ],
36
36
  "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "https://github.com/your-username/kyro-cms.git",
40
- "directory": "packages/create-kyro"
41
- },
42
- "bugs": {
43
- "url": "https://github.com/your-username/kyro-cms/issues"
44
- },
45
- "homepage": "https://github.com/your-username/kyro-cms#readme"
46
- }
37
+ "publishConfig": {
38
+ "access": "public"
39
+ }
40
+ }
@@ -39,9 +39,7 @@ export const blogCollections: Record<string, CollectionConfig> = {
39
39
  name: 'featuredImage',
40
40
  type: 'upload',
41
41
  label: 'Featured Image',
42
- upload: {
43
- mimeTypes: ['image/*']
44
- }
42
+ relationTo: 'media'
45
43
  },
46
44
  {
47
45
  name: 'category',
@@ -61,7 +59,10 @@ export const blogCollections: Record<string, CollectionConfig> = {
61
59
  name: 'status',
62
60
  type: 'select',
63
61
  label: 'Status',
64
- options: ['draft', 'published'],
62
+ options: [
63
+ { label: 'Draft', value: 'draft' },
64
+ { label: 'Published', value: 'published' }
65
+ ],
65
66
  defaultValue: 'draft'
66
67
  },
67
68
  {
@@ -166,8 +167,8 @@ export const blogCollections: Record<string, CollectionConfig> = {
166
167
  };
167
168
 
168
169
  export const blogGlobals = {
169
- siteSettings: {
170
- name: 'siteSettings',
170
+ 'site-settings': {
171
+ name: 'site-settings',
171
172
  label: 'Site Settings',
172
173
  fields: {
173
174
  siteName: { type: 'text', defaultValue: 'My Blog' },
@@ -1,38 +0,0 @@
1
- import type { Answers } from '../prompts.js';
2
-
3
- export function generateAstroConfig(answers: Answers): string {
4
- const integrations: string[] = [];
5
- const vitePlugins: string[] = [];
6
-
7
- if (answers.styling === 'tailwind') {
8
- integrations.push(" react(),");
9
- vitePlugins.push(" tailwindcss(),");
10
- }
11
-
12
- const adapter = answers.admin ? `
13
- adapter: node({
14
- mode: 'standalone'
15
- }),` : '';
16
-
17
- const config = `import { defineConfig } from 'astro/config';
18
- ${answers.styling === 'tailwind' ? "import react from '@astrojs/react';\nimport tailwindcss from '@tailwindcss/vite';" : ''}
19
-
20
- export default defineConfig({
21
- output: 'server',${adapter}
22
-
23
- integrations: [
24
- ${integrations.join('\n')}
25
- ],${vitePlugins.length > 0 ? `
26
- vite: {
27
- plugins: [
28
- ${vitePlugins.join('\n')}
29
- ],
30
- },` : ''}
31
- server: {
32
- port: 4321,
33
- host: true,
34
- },
35
- });`;
36
-
37
- return config;
38
- }
@@ -1,80 +0,0 @@
1
- import type { Answers } from '../prompts.js';
2
-
3
- export function generateKyroConfig(answers: Answers): string {
4
- const imports: string[] = ["import { defineConfig } from '@kyro-cms/core';"];
5
- const adapterLines: string[] = [];
6
-
7
- if (answers.database === 'sqlite') {
8
- imports.push("import { localAdapter } from '@kyro-cms/core';");
9
- adapterLines.push(` adapter: localAdapter({ path: './data.db' }),`);
10
- } else if (answers.database === 'postgres') {
11
- imports.push("import { drizzleAdapter } from '@kyro-cms/core';");
12
- adapterLines.push(` adapter: drizzleAdapter({`);
13
- adapterLines.push(` connectionString: process.env.DATABASE_URL,`);
14
- adapterLines.push(` }),`);
15
- } else if (answers.database === 'mysql') {
16
- imports.push("import { drizzleAdapter } from '@kyro-cms/core';");
17
- adapterLines.push(` adapter: drizzleAdapter({`);
18
- adapterLines.push(` connectionString: process.env.DATABASE_URL,`);
19
- adapterLines.push(` }),`);
20
- } else if (answers.database === 'mongodb') {
21
- imports.push("import { mongoAdapter } from '@kyro-cms/core';");
22
- adapterLines.push(` adapter: mongoAdapter({`);
23
- adapterLines.push(` connectionString: process.env.MONGODB_URI,`);
24
- adapterLines.push(` }),`);
25
- }
26
-
27
- const apiConfig: string[] = [];
28
- if (answers.apis.includes('rest')) {
29
- apiConfig.push(" rest: true,");
30
- }
31
- if (answers.apis.includes('graphql')) {
32
- apiConfig.push(" graphql: true,");
33
- }
34
- if (answers.apis.includes('trpc')) {
35
- apiConfig.push(" trpc: true,");
36
- }
37
- if (answers.apis.includes('websocket')) {
38
- apiConfig.push(" websocket: true,");
39
- }
40
-
41
- const features: string[] = [];
42
- if (answers.auth) {
43
- features.push(" auth: true,");
44
- }
45
- if (answers.versioning) {
46
- features.push(" versioning: true,");
47
- }
48
-
49
- let templateImports = '';
50
- let collectionsLine = '';
51
-
52
- if (answers.template === 'minimal') {
53
- templateImports = `import { minimalCollections } from '@kyro-cms/core';`;
54
- collectionsLine = ' ...minimalCollections,';
55
- } else if (answers.template === 'blog') {
56
- templateImports = `import { blogCollections } from '@kyro-cms/core';`;
57
- collectionsLine = ' ...blogCollections,';
58
- } else if (answers.template === 'ecommerce') {
59
- templateImports = `import { ecommerceCollections } from '@kyro-cms/core';`;
60
- collectionsLine = ' ...ecommerceCollections,';
61
- }
62
-
63
- const config = `${imports.join('\n')}
64
- ${templateImports}
65
-
66
- export default defineConfig({
67
- name: '${answers.projectName}',
68
- prefix: '/api',${adapterLines.length > 0 ? '\n' + adapterLines.join('\n') : ''}
69
-
70
- collections: {
71
- ${collectionsLine}
72
- },${features.length > 0 ? '\n' + features.join('\n') : ''}
73
-
74
- api: {
75
- ${apiConfig.join('\n')}
76
- },
77
- });`;
78
-
79
- return config;
80
- }
@@ -1,159 +0,0 @@
1
- import type { Answers } from '../prompts.js';
2
- import { writeFileSync, mkdirSync } from 'fs';
3
- import { join } from 'path';
4
-
5
- export function generateProjectFiles(answers: Answers, projectDir: string): void {
6
- const srcDir = join(projectDir, 'src');
7
- const pagesDir = join(srcDir, 'pages');
8
- const publicDir = join(projectDir, 'public');
9
-
10
- mkdirSync(pagesDir, { recursive: true });
11
- mkdirSync(publicDir, { recursive: true });
12
-
13
- if (answers.database === 'sqlite') {
14
- mkdirSync(join(projectDir, 'data'), { recursive: true });
15
- }
16
-
17
- const tsconfig = `{
18
- "extends": "astro/tsconfigs/strict",
19
- "compilerOptions": {
20
- "baseUrl": ".",
21
- "paths": {
22
- "@/*": ["./src/*"]
23
- }
24
- }
25
- }`;
26
-
27
- writeFileSync(join(projectDir, 'tsconfig.json'), tsconfig);
28
-
29
- const gitignore = `node_modules/
30
- dist/
31
- .astro/
32
- data/
33
- *.db
34
- .env
35
- .env.local
36
- .DS_Store
37
- `;
38
-
39
- writeFileSync(join(projectDir, '.gitignore'), gitignore);
40
-
41
- const readme = `# ${answers.projectName}
42
-
43
- A Kyro CMS project.
44
-
45
- ## Getting Started
46
-
47
- \`\`\`bash
48
- npm install
49
- npm run dev
50
- \`\`\`
51
-
52
- ## Documentation
53
-
54
- Visit [https://kyro.cms](https://kyro.cms) for full documentation.
55
- `;
56
-
57
- writeFileSync(join(projectDir, 'README.md'), readme);
58
-
59
- const spec = `# ${answers.projectName}
60
-
61
- ## Overview
62
-
63
- This project uses Kyro CMS - an Astro-native headless CMS.
64
-
65
- ## Configuration
66
-
67
- - **Database**: ${answers.database === 'sqlite' ? 'SQLite (local-first)' : answers.database}
68
- - **APIs**: ${answers.apis.join(', ')}
69
- - **Styling**: ${answers.styling}
70
- - **Auth**: ${answers.auth ? 'Enabled' : 'Disabled'}
71
- - **Versioning**: ${answers.versioning ? 'Enabled' : 'Disabled'}
72
- - **Admin**: ${answers.admin ? 'Included' : 'Not included'}
73
- - **Template**: ${answers.template}
74
-
75
- ## Collections
76
-
77
- ${
78
- answers.template === 'minimal' ? '- Posts' :
79
- answers.template === 'blog' ? '- Posts\n- Categories\n- Media' :
80
- '- Products\n- Categories\n- Customers\n- Orders\n- Coupons'
81
- }
82
- `;
83
-
84
- writeFileSync(join(projectDir, 'SPEC.md'), spec);
85
-
86
- const indexPage = `---
87
- const title = "${answers.projectName}";
88
- ---
89
- <!DOCTYPE html>
90
- <html lang="en">
91
- <head>
92
- <meta charset="UTF-8" />
93
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
94
- <title>${answers.projectName}</title>
95
- </head>
96
- <body>
97
- <main>
98
- <h1>Welcome to ${answers.projectName}</h1>
99
- <p>Your Kyro CMS is ready.</p>
100
- ${
101
- answers.admin
102
- ? '<p><a href="/admin">Go to Admin Dashboard →</a></p>'
103
- : ''
104
- }
105
- </main>
106
- </body>
107
- </html>
108
-
109
- <style>
110
- main {
111
- max-width: 800px;
112
- margin: 4rem auto;
113
- padding: 2rem;
114
- text-align: center;
115
- font-family: system-ui, sans-serif;
116
- }
117
- h1 {
118
- font-size: 2.5rem;
119
- margin-bottom: 1rem;
120
- }
121
- p {
122
- color: #666;
123
- }
124
- a {
125
- color: #6366f1;
126
- text-decoration: none;
127
- }
128
- a:hover {
129
- text-decoration: underline;
130
- }
131
- </style>
132
- `;
133
-
134
- writeFileSync(join(pagesDir, 'index.astro'), indexPage);
135
-
136
- if (answers.admin) {
137
- const adminDir = join(srcDir, 'admin');
138
- mkdirSync(adminDir, { recursive: true });
139
-
140
- const adminIndex = `---
141
- import { Admin } from '@kyro-cms/admin';
142
- import config from '../kyro.config';
143
- ---
144
- <!DOCTYPE html>
145
- <html lang="en">
146
- <head>
147
- <meta charset="UTF-8" />
148
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
149
- <title>Admin - ${answers.projectName}</title>
150
- </head>
151
- <body>
152
- <Admin client:load config={config} />
153
- </body>
154
- </html>
155
- `;
156
-
157
- writeFileSync(join(adminDir, 'index.astro'), adminIndex);
158
- }
159
- }
@@ -1,72 +0,0 @@
1
- import type { Answers } from '../prompts.js';
2
-
3
- export interface PackageJson {
4
- name: string;
5
- version: string;
6
- type: string;
7
- private: boolean;
8
- scripts: Record<string, string>;
9
- dependencies: Record<string, string>;
10
- devDependencies: Record<string, string>;
11
- }
12
-
13
- export function generatePackageJson(answers: Answers, projectDir: string): PackageJson {
14
- const deps: Record<string, string> = {
15
- '@kyro-cms/core': 'latest',
16
- 'astro': '^5.4.0'
17
- };
18
-
19
- const devDeps: Record<string, string> = {
20
- 'typescript': '^5.7.3'
21
- };
22
-
23
- if (answers.styling === 'tailwind') {
24
- deps['@astrojs/react'] = '^4.2.0';
25
- deps['react'] = '^19.0.0';
26
- deps['react-dom'] = '^19.0.0';
27
- deps['tailwindcss'] = '^4.0.0';
28
- deps['@tailwindcss/vite'] = '^4.0.0';
29
- devDeps['@types/react'] = '^19.0.0';
30
- devDeps['@types/react-dom'] = '^19.0.0';
31
- }
32
-
33
- if (answers.database === 'postgres') {
34
- deps['pg'] = '^8.13.1';
35
- deps['@types/pg'] = '^8.11.0';
36
- } else if (answers.database === 'mysql') {
37
- deps['mysql2'] = '^3.12.0';
38
- } else if (answers.database === 'mongodb') {
39
- deps['mongodb'] = '^6.12.0';
40
- }
41
-
42
- if (answers.admin) {
43
- deps['@kyro-cms/admin'] = 'latest';
44
- deps['lucide-react'] = '^0.475.0';
45
- }
46
-
47
- const scripts: Record<string, string> = {
48
- 'dev': 'astro dev',
49
- 'build': 'astro build',
50
- 'preview': 'astro preview'
51
- };
52
-
53
- if (answers.database === 'sqlite') {
54
- scripts['db:generate'] = 'kyro generate';
55
- scripts['db:push'] = 'kyro push';
56
- scripts['db:studio'] = 'kyro studio';
57
- }
58
-
59
- return {
60
- name: answers.projectName,
61
- version: '0.1.0',
62
- type: 'module',
63
- private: true,
64
- scripts,
65
- dependencies: deps,
66
- devDependencies: devDeps
67
- };
68
- }
69
-
70
- export function formatPackageJson(pkg: PackageJson): string {
71
- return JSON.stringify(pkg, null, 2);
72
- }
package/src/index.ts DELETED
@@ -1,97 +0,0 @@
1
- import { promptUser, type Answers } from './prompts.js';
2
- import { logger } from './utils/logger.js';
3
- import { generatePackageJson, formatPackageJson } from './generators/packagejson.js';
4
- import { generateKyroConfig } from './generators/config.js';
5
- import { generateAstroConfig } from './generators/astro.js';
6
- import { generateProjectFiles } from './generators/files.js';
7
- import { writeFileSync, mkdirSync, cpSync, existsSync } from 'fs';
8
- import { join } from 'path';
9
- import { execSync } from 'child_process';
10
-
11
- const VERSION = '0.1.0';
12
-
13
- async function main() {
14
- logger.intro('create-kyro', VERSION);
15
-
16
- const answers = await promptUser();
17
- const projectDir = join(process.cwd(), answers.projectName);
18
-
19
- if (existsSync(projectDir)) {
20
- logger.error(`Directory "${answers.projectName}" already exists.`);
21
- process.exit(1);
22
- }
23
-
24
- const steps = [
25
- 'Creating project directory',
26
- 'Generating configuration files',
27
- 'Installing dependencies',
28
- 'Initializing git repository',
29
- ];
30
-
31
- logger.step(1, steps.length, steps[0]);
32
- mkdirSync(projectDir, { recursive: true });
33
- logger.success('Project directory created');
34
-
35
- logger.step(2, steps.length, steps[1]);
36
-
37
- const pkg = generatePackageJson(answers, projectDir);
38
- writeFileSync(
39
- join(projectDir, 'package.json'),
40
- formatPackageJson(pkg)
41
- );
42
- logger.success('package.json generated');
43
-
44
- const kyroConfig = generateKyroConfig(answers);
45
- writeFileSync(join(projectDir, 'kyro.config.ts'), kyroConfig);
46
- logger.success('kyro.config.ts generated');
47
-
48
- const astroConfig = generateAstroConfig(answers);
49
- writeFileSync(join(projectDir, 'astro.config.mjs'), astroConfig);
50
- logger.success('astro.config.mjs generated');
51
-
52
- generateProjectFiles(answers, projectDir);
53
- logger.success('Project files generated');
54
-
55
- logger.step(3, steps.length, steps[2]);
56
- console.log(' Installing dependencies...');
57
-
58
- try {
59
- execSync('npm install', {
60
- cwd: projectDir,
61
- stdio: 'inherit',
62
- env: { ...process.env, npm_config_loglevel: 'warn' }
63
- });
64
- logger.success('Dependencies installed');
65
- } catch (error) {
66
- logger.error('Failed to install dependencies');
67
- process.exit(1);
68
- }
69
-
70
- logger.step(4, steps.length, steps[3]);
71
- try {
72
- execSync('git init && git add . && git commit -m "Initial commit - created with create-kyro"', {
73
- cwd: projectDir,
74
- stdio: 'pipe'
75
- });
76
- logger.success('Git repository initialized');
77
- } catch {
78
- logger.warning('Could not initialize git repository');
79
- }
80
-
81
- logger.done();
82
-
83
- console.log(' To get started:');
84
- console.log(` ${logger ? '\x1b[36m' : ''}cd ${answers.projectName}${logger ? '\x1b[0m' : ''}`);
85
- console.log(` ${logger ? '\x1b[36m' : ''}npm run dev${logger ? '\x1b[0m' : ''}`);
86
- console.log('');
87
- console.log(' Visit http://localhost:4321 to see your app.');
88
- if (answers.admin) {
89
- console.log(' Visit http://localhost:4321/admin for the admin dashboard.');
90
- }
91
- console.log('');
92
- }
93
-
94
- main().catch((error) => {
95
- logger.error(`Unexpected error: ${error.message}`);
96
- process.exit(1);
97
- });