create-kyro 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -13
- package/dist/index.js +67 -664
- package/package.json +1 -1
- package/src/generators/astro.ts +7 -70
- package/src/generators/config.ts +39 -40
- package/src/generators/files.ts +18 -509
- package/src/generators/packagejson.ts +6 -35
- package/src/index.ts +5 -5
- package/src/prompts.ts +1 -62
- package/test/generators.test.ts +13 -100
- package/test/validators.test.ts +0 -1
package/src/prompts.ts
CHANGED
|
@@ -3,11 +3,7 @@ import { validateProjectName } from "./validators.js";
|
|
|
3
3
|
|
|
4
4
|
export interface Answers {
|
|
5
5
|
projectName: string;
|
|
6
|
-
database: "sqlite" | "postgres" | "
|
|
7
|
-
styling: "tailwind" | "cssmodules" | "styled" | "none";
|
|
8
|
-
auth: boolean;
|
|
9
|
-
versioning: boolean;
|
|
10
|
-
admin: boolean;
|
|
6
|
+
database: "sqlite" | "postgres" | "mongodb";
|
|
11
7
|
template: "minimal" | "blog" | "ecommerce" | "kitchen-sink";
|
|
12
8
|
}
|
|
13
9
|
|
|
@@ -38,11 +34,6 @@ export async function promptUser(): Promise<Answers> {
|
|
|
38
34
|
description: "Recommended for production. Robust and scalable.",
|
|
39
35
|
value: "postgres",
|
|
40
36
|
},
|
|
41
|
-
{
|
|
42
|
-
title: "MySQL",
|
|
43
|
-
description: "Popular choice for web applications.",
|
|
44
|
-
value: "mysql",
|
|
45
|
-
},
|
|
46
37
|
{
|
|
47
38
|
title: "MongoDB",
|
|
48
39
|
description: "Best for flexible, document-based schemas.",
|
|
@@ -50,58 +41,6 @@ export async function promptUser(): Promise<Answers> {
|
|
|
50
41
|
},
|
|
51
42
|
],
|
|
52
43
|
},
|
|
53
|
-
{
|
|
54
|
-
type: "select",
|
|
55
|
-
name: "styling",
|
|
56
|
-
message: "Styling:",
|
|
57
|
-
hint: " ",
|
|
58
|
-
choices: [
|
|
59
|
-
{
|
|
60
|
-
title: "Tailwind CSS",
|
|
61
|
-
description: "Utility-first CSS framework, excellent DX",
|
|
62
|
-
value: "tailwind",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
title: "CSS Modules",
|
|
66
|
-
description: "Scoped CSS, no extra dependencies",
|
|
67
|
-
value: "cssmodules",
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
title: "Styled Components",
|
|
71
|
-
description: "CSS-in-JS with tagged template literals",
|
|
72
|
-
value: "styled",
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
title: "None",
|
|
76
|
-
description: "Bring your own styling solution",
|
|
77
|
-
value: "none",
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
type: "toggle",
|
|
83
|
-
name: "auth",
|
|
84
|
-
message: "Add authentication (JWT)?",
|
|
85
|
-
initial: true,
|
|
86
|
-
active: "Yes",
|
|
87
|
-
inactive: "No",
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
type: "toggle",
|
|
91
|
-
name: "versioning",
|
|
92
|
-
message: "Add versioning/drafts?",
|
|
93
|
-
initial: true,
|
|
94
|
-
active: "Yes",
|
|
95
|
-
inactive: "No",
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: "toggle",
|
|
99
|
-
name: "admin",
|
|
100
|
-
message: "Include admin dashboard?",
|
|
101
|
-
initial: true,
|
|
102
|
-
active: "Yes",
|
|
103
|
-
inactive: "No",
|
|
104
|
-
},
|
|
105
44
|
{
|
|
106
45
|
type: "select",
|
|
107
46
|
name: "template",
|
package/test/generators.test.ts
CHANGED
|
@@ -10,10 +10,6 @@ import {
|
|
|
10
10
|
const baseAnswers: Answers = {
|
|
11
11
|
projectName: "test-project",
|
|
12
12
|
database: "sqlite",
|
|
13
|
-
styling: "tailwind",
|
|
14
|
-
auth: true,
|
|
15
|
-
versioning: true,
|
|
16
|
-
admin: true,
|
|
17
13
|
template: "blog",
|
|
18
14
|
};
|
|
19
15
|
|
|
@@ -32,12 +28,6 @@ describe("generators", () => {
|
|
|
32
28
|
expect(config).toContain("DATABASE_URL");
|
|
33
29
|
});
|
|
34
30
|
|
|
35
|
-
it("generates config with MySQL adapter", () => {
|
|
36
|
-
const answers = { ...baseAnswers, database: "mysql" as const };
|
|
37
|
-
const config = generateKyroConfig(answers);
|
|
38
|
-
expect(config).toContain("createDrizzleAdapter");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
31
|
it("generates config with MongoDB adapter", () => {
|
|
42
32
|
const answers = { ...baseAnswers, database: "mongodb" as const };
|
|
43
33
|
const config = generateKyroConfig(answers);
|
|
@@ -45,21 +35,11 @@ describe("generators", () => {
|
|
|
45
35
|
expect(config).toContain("MONGODB_URI");
|
|
46
36
|
});
|
|
47
37
|
|
|
48
|
-
it("includes auth
|
|
49
|
-
const config = generateKyroConfig(
|
|
38
|
+
it("includes auth (always enabled)", () => {
|
|
39
|
+
const config = generateKyroConfig(baseAnswers);
|
|
50
40
|
expect(config).toContain("auth: true");
|
|
51
41
|
});
|
|
52
42
|
|
|
53
|
-
it("omits auth when disabled", () => {
|
|
54
|
-
const config = generateKyroConfig({ ...baseAnswers, auth: false });
|
|
55
|
-
expect(config).not.toContain("auth: true");
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("includes versioning when enabled", () => {
|
|
59
|
-
const config = generateKyroConfig({ ...baseAnswers, versioning: true });
|
|
60
|
-
expect(config).toContain("versioning: true");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
43
|
it("imports correct template collections", () => {
|
|
64
44
|
const minimal = generateKyroConfig({
|
|
65
45
|
...baseAnswers,
|
|
@@ -86,14 +66,6 @@ describe("generators", () => {
|
|
|
86
66
|
expect(kitchen).toContain("kitchenSinkCollections");
|
|
87
67
|
});
|
|
88
68
|
|
|
89
|
-
it("includes all API protocols", () => {
|
|
90
|
-
const config = generateKyroConfig(baseAnswers);
|
|
91
|
-
expect(config).toContain("rest: true");
|
|
92
|
-
expect(config).toContain("graphql: true");
|
|
93
|
-
expect(config).toContain("trpc: true");
|
|
94
|
-
expect(config).toContain("websocket: true");
|
|
95
|
-
});
|
|
96
|
-
|
|
97
69
|
it("uses project name in config", () => {
|
|
98
70
|
const config = generateKyroConfig(baseAnswers);
|
|
99
71
|
expect(config).toContain("name: 'test-project'");
|
|
@@ -101,100 +73,41 @@ describe("generators", () => {
|
|
|
101
73
|
});
|
|
102
74
|
|
|
103
75
|
describe("generateAstroConfig", () => {
|
|
104
|
-
it("includes
|
|
105
|
-
const config = generateAstroConfig(baseAnswers);
|
|
106
|
-
expect(config).toContain("@astrojs/react");
|
|
107
|
-
expect(config).toContain("@tailwindcss/vite");
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("includes node adapter when admin enabled", () => {
|
|
76
|
+
it("includes kyro integration", () => {
|
|
111
77
|
const config = generateAstroConfig(baseAnswers);
|
|
112
|
-
expect(config).toContain("@
|
|
113
|
-
expect(config).toContain("
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it("includes SSR externals for native modules", () => {
|
|
117
|
-
const config = generateAstroConfig(baseAnswers);
|
|
118
|
-
expect(config).toContain("better-sqlite3");
|
|
119
|
-
expect(config).toContain("sharp");
|
|
120
|
-
expect(config).toContain("ssr");
|
|
121
|
-
expect(config).toContain("optimizeDeps");
|
|
78
|
+
expect(config).toContain("@kyro-cms/core");
|
|
79
|
+
expect(config).toContain("kyroAdmin");
|
|
122
80
|
});
|
|
123
81
|
|
|
124
82
|
it("sets correct server port", () => {
|
|
125
83
|
const config = generateAstroConfig(baseAnswers);
|
|
126
84
|
expect(config).toContain("port: 4321");
|
|
127
85
|
});
|
|
128
|
-
|
|
129
|
-
it("excludes react when not using tailwind", () => {
|
|
130
|
-
const answers = { ...baseAnswers, styling: "none" as const };
|
|
131
|
-
const config = generateAstroConfig(answers);
|
|
132
|
-
expect(config).not.toContain("@astrojs/react");
|
|
133
|
-
});
|
|
134
86
|
});
|
|
135
87
|
|
|
136
88
|
describe("generatePackageJson", () => {
|
|
137
89
|
it("includes core dependency", () => {
|
|
138
|
-
const pkg = generatePackageJson(baseAnswers
|
|
90
|
+
const pkg = generatePackageJson(baseAnswers);
|
|
139
91
|
expect(pkg.dependencies["@kyro-cms/core"]).toBeDefined();
|
|
140
92
|
});
|
|
141
93
|
|
|
142
|
-
it("includes admin
|
|
143
|
-
const pkg = generatePackageJson(baseAnswers
|
|
94
|
+
it("includes admin dependency", () => {
|
|
95
|
+
const pkg = generatePackageJson(baseAnswers);
|
|
144
96
|
expect(pkg.dependencies["@kyro-cms/admin"]).toBeDefined();
|
|
145
|
-
expect(pkg.dependencies["@astrojs/node"]).toBeDefined();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("omits admin dependencies when admin disabled", () => {
|
|
149
|
-
const pkg = generatePackageJson(
|
|
150
|
-
{ ...baseAnswers, admin: false },
|
|
151
|
-
"/test",
|
|
152
|
-
);
|
|
153
|
-
expect(pkg.dependencies["@kyro-cms/admin"]).toBeUndefined();
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it("includes database-specific dependencies", () => {
|
|
157
|
-
const pg = generatePackageJson(
|
|
158
|
-
{ ...baseAnswers, database: "postgres" },
|
|
159
|
-
"/test",
|
|
160
|
-
);
|
|
161
|
-
expect(pg.dependencies["pg"]).toBeDefined();
|
|
162
|
-
|
|
163
|
-
const mysql = generatePackageJson(
|
|
164
|
-
{ ...baseAnswers, database: "mysql" },
|
|
165
|
-
"/test",
|
|
166
|
-
);
|
|
167
|
-
expect(mysql.dependencies["mysql2"]).toBeDefined();
|
|
168
|
-
|
|
169
|
-
const mongo = generatePackageJson(
|
|
170
|
-
{ ...baseAnswers, database: "mongodb" },
|
|
171
|
-
"/test",
|
|
172
|
-
);
|
|
173
|
-
expect(mongo.dependencies["mongodb"]).toBeDefined();
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it("includes auth bootstrap script when auth enabled", () => {
|
|
177
|
-
const pkg = generatePackageJson({ ...baseAnswers, auth: true }, "/test");
|
|
178
|
-
expect(pkg.scripts["db:bootstrap"]).toBeDefined();
|
|
179
97
|
});
|
|
180
98
|
|
|
181
|
-
it("includes
|
|
182
|
-
const pkg = generatePackageJson(
|
|
183
|
-
|
|
184
|
-
"/test",
|
|
185
|
-
);
|
|
186
|
-
expect(pkg.scripts["db:generate"]).toBeDefined();
|
|
187
|
-
expect(pkg.scripts["db:push"]).toBeDefined();
|
|
188
|
-
expect(pkg.scripts["db:studio"]).toBeDefined();
|
|
99
|
+
it("includes astro dependency", () => {
|
|
100
|
+
const pkg = generatePackageJson(baseAnswers);
|
|
101
|
+
expect(pkg.dependencies["astro"]).toBeDefined();
|
|
189
102
|
});
|
|
190
103
|
|
|
191
104
|
it("has correct project name", () => {
|
|
192
|
-
const pkg = generatePackageJson(baseAnswers
|
|
105
|
+
const pkg = generatePackageJson(baseAnswers);
|
|
193
106
|
expect(pkg.name).toBe("test-project");
|
|
194
107
|
});
|
|
195
108
|
|
|
196
109
|
it("formats as valid JSON string", () => {
|
|
197
|
-
const pkg = generatePackageJson(baseAnswers
|
|
110
|
+
const pkg = generatePackageJson(baseAnswers);
|
|
198
111
|
const formatted = formatPackageJson(pkg);
|
|
199
112
|
expect(() => JSON.parse(formatted)).not.toThrow();
|
|
200
113
|
});
|