create-nyoworks 2.5.0 → 2.6.0
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/checks.d.ts +1 -0
- package/dist/checks.js +15 -0
- package/dist/init.js +85 -23
- package/package.json +1 -1
package/dist/checks.d.ts
CHANGED
package/dist/checks.js
CHANGED
|
@@ -87,6 +87,21 @@ export async function checkDependencies() {
|
|
|
87
87
|
console.log(pc.red("Please install the required dependencies before continuing."));
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
export async function getDockerComposeCommand() {
|
|
91
|
+
try {
|
|
92
|
+
await execa("docker", ["compose", "version"]);
|
|
93
|
+
return "docker compose";
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
try {
|
|
97
|
+
await execa("docker-compose", ["version"]);
|
|
98
|
+
return "docker-compose";
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return "docker compose";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
90
105
|
export function showClaudeMaxWarning() {
|
|
91
106
|
console.log();
|
|
92
107
|
console.log(pc.yellow("╔═══════════════════════════════════════════════════════════════════════╗"));
|
package/dist/init.js
CHANGED
|
@@ -5,18 +5,42 @@ import path from "path";
|
|
|
5
5
|
import os from "os";
|
|
6
6
|
import { execa } from "execa";
|
|
7
7
|
import { replacePlaceholders } from "./replace.js";
|
|
8
|
-
import { checkDependencies, showClaudeMaxWarning } from "./checks.js";
|
|
8
|
+
import { checkDependencies, showClaudeMaxWarning, getDockerComposeCommand } from "./checks.js";
|
|
9
9
|
const REPO = "naimozcan/nyoworks-framework";
|
|
10
10
|
const BRANCH = "main";
|
|
11
|
+
const PRODUCT_TYPES = [
|
|
12
|
+
{ title: "E-Commerce", value: "ecommerce", description: "Online store, product sales" },
|
|
13
|
+
{ title: "Booking", value: "booking", description: "Appointment/reservation system" },
|
|
14
|
+
{ title: "SaaS Platform", value: "saas", description: "Subscription-based software" },
|
|
15
|
+
{ title: "Marketplace", value: "marketplace", description: "Multi-vendor platform" },
|
|
16
|
+
{ title: "Content/Blog", value: "content", description: "Blog, news, CMS" },
|
|
17
|
+
{ title: "CRM", value: "crm", description: "Customer relationship management" },
|
|
18
|
+
{ title: "Custom", value: "custom", description: "Manual feature selection" },
|
|
19
|
+
];
|
|
20
|
+
const REQUIRED_FEATURES = {
|
|
21
|
+
ecommerce: ["payments", "crm", "notifications", "search", "storage"],
|
|
22
|
+
booking: ["appointments", "payments", "crm", "notifications"],
|
|
23
|
+
saas: ["payments", "subscriptions", "analytics", "notifications", "audit", "multitenant"],
|
|
24
|
+
marketplace: ["payments", "crm", "analytics", "notifications", "audit", "search", "storage", "multitenant"],
|
|
25
|
+
content: ["analytics", "search", "storage"],
|
|
26
|
+
crm: ["crm", "analytics", "notifications", "audit", "export"],
|
|
27
|
+
custom: [],
|
|
28
|
+
};
|
|
11
29
|
const AVAILABLE_FEATURES = [
|
|
12
30
|
{ title: "Analytics", value: "analytics", description: "User behavior tracking" },
|
|
13
|
-
{ title: "CRM", value: "crm", description: "Customer relationship management" },
|
|
14
|
-
{ title: "Payments", value: "payments", description: "Stripe integration" },
|
|
15
|
-
{ title: "Notifications", value: "notifications", description: "Email, SMS, Push" },
|
|
16
31
|
{ title: "Appointments", value: "appointments", description: "Booking system" },
|
|
17
32
|
{ title: "Audit", value: "audit", description: "Activity logging" },
|
|
33
|
+
{ title: "Auth Social", value: "auth-social", description: "Google, Apple, GitHub OAuth" },
|
|
34
|
+
{ title: "CRM", value: "crm", description: "Customer relationship management" },
|
|
18
35
|
{ title: "Export", value: "export", description: "PDF/CSV export" },
|
|
36
|
+
{ title: "i18n", value: "i18n", description: "Multi-language support" },
|
|
37
|
+
{ title: "Multitenant", value: "multitenant", description: "Multi-organization support" },
|
|
38
|
+
{ title: "Notifications", value: "notifications", description: "Email, SMS, Push" },
|
|
39
|
+
{ title: "Payments", value: "payments", description: "Stripe integration" },
|
|
19
40
|
{ title: "Realtime", value: "realtime", description: "WebSocket support" },
|
|
41
|
+
{ title: "Search", value: "search", description: "Full-text search" },
|
|
42
|
+
{ title: "Storage", value: "storage", description: "File uploads (S3/R2)" },
|
|
43
|
+
{ title: "Subscriptions", value: "subscriptions", description: "Plans & usage limits" },
|
|
20
44
|
];
|
|
21
45
|
const AVAILABLE_PLATFORMS = [
|
|
22
46
|
{ title: "Web", value: "web", description: "Next.js 16" },
|
|
@@ -65,14 +89,40 @@ export async function createProject(projectName) {
|
|
|
65
89
|
console.log(pc.cyan(pc.bold(" NYOWORKS Framework")));
|
|
66
90
|
console.log(pc.dim(" Create a new project"));
|
|
67
91
|
console.log();
|
|
92
|
+
let productType = "custom";
|
|
93
|
+
let requiredFeatures = [];
|
|
94
|
+
const nameResponse = await prompts({
|
|
95
|
+
type: projectName ? null : "text",
|
|
96
|
+
name: "name",
|
|
97
|
+
message: "Project name:",
|
|
98
|
+
initial: projectName || "my-project",
|
|
99
|
+
validate: (value) => (value.length > 0 ? true : "Project name is required"),
|
|
100
|
+
});
|
|
101
|
+
if (!nameResponse.name && !projectName) {
|
|
102
|
+
console.log(pc.red("Aborted."));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
const productResponse = await prompts({
|
|
106
|
+
type: "select",
|
|
107
|
+
name: "productType",
|
|
108
|
+
message: "Product type:",
|
|
109
|
+
choices: PRODUCT_TYPES,
|
|
110
|
+
initial: 0,
|
|
111
|
+
});
|
|
112
|
+
if (productResponse.productType) {
|
|
113
|
+
productType = productResponse.productType;
|
|
114
|
+
requiredFeatures = REQUIRED_FEATURES[productType] || [];
|
|
115
|
+
}
|
|
116
|
+
const featureChoices = AVAILABLE_FEATURES.map((f) => {
|
|
117
|
+
const isRequired = requiredFeatures.includes(f.value);
|
|
118
|
+
return {
|
|
119
|
+
title: isRequired ? `${f.title} [required]` : f.title,
|
|
120
|
+
value: f.value,
|
|
121
|
+
description: f.description,
|
|
122
|
+
selected: isRequired,
|
|
123
|
+
};
|
|
124
|
+
});
|
|
68
125
|
const response = await prompts([
|
|
69
|
-
{
|
|
70
|
-
type: projectName ? null : "text",
|
|
71
|
-
name: "name",
|
|
72
|
-
message: "Project name:",
|
|
73
|
-
initial: projectName || "my-project",
|
|
74
|
-
validate: (value) => (value.length > 0 ? true : "Project name is required"),
|
|
75
|
-
},
|
|
76
126
|
{
|
|
77
127
|
type: "multiselect",
|
|
78
128
|
name: "platforms",
|
|
@@ -86,7 +136,7 @@ export async function createProject(projectName) {
|
|
|
86
136
|
type: "multiselect",
|
|
87
137
|
name: "features",
|
|
88
138
|
message: "Select features:",
|
|
89
|
-
choices:
|
|
139
|
+
choices: featureChoices,
|
|
90
140
|
hint: "- Space to select. Return to submit",
|
|
91
141
|
instructions: false,
|
|
92
142
|
},
|
|
@@ -98,16 +148,13 @@ export async function createProject(projectName) {
|
|
|
98
148
|
initial: 0,
|
|
99
149
|
},
|
|
100
150
|
]);
|
|
101
|
-
|
|
102
|
-
console.log(pc.red("Aborted."));
|
|
103
|
-
process.exit(1);
|
|
104
|
-
}
|
|
105
|
-
const name = response.name || projectName;
|
|
151
|
+
const name = (nameResponse.name || projectName);
|
|
106
152
|
const code = generateCode(name);
|
|
107
153
|
const slug = generateSlug(name);
|
|
108
154
|
const databaseName = generateDatabaseName(name);
|
|
109
155
|
const platforms = response.platforms || ["web"];
|
|
110
|
-
const
|
|
156
|
+
const selectedFeatures = response.features || [];
|
|
157
|
+
const features = [...new Set([...requiredFeatures, ...selectedFeatures])];
|
|
111
158
|
const language = response.language || "tr";
|
|
112
159
|
const targetDir = path.resolve(process.cwd(), slug);
|
|
113
160
|
if (fs.existsSync(targetDir)) {
|
|
@@ -155,6 +202,13 @@ export async function createProject(projectName) {
|
|
|
155
202
|
await fs.copy(src, dest);
|
|
156
203
|
}
|
|
157
204
|
}
|
|
205
|
+
for (const feature of features) {
|
|
206
|
+
const src = path.join(repoDir, `packages/features/${feature}`);
|
|
207
|
+
const dest = path.join(targetDir, `packages/features/${feature}`);
|
|
208
|
+
if (await fs.pathExists(src)) {
|
|
209
|
+
await fs.copy(src, dest);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
158
212
|
const rootFiles = [
|
|
159
213
|
"package.json",
|
|
160
214
|
"pnpm-workspace.yaml",
|
|
@@ -180,6 +234,7 @@ export async function createProject(projectName) {
|
|
|
180
234
|
"${PROJECT_CODE}": code,
|
|
181
235
|
"${PROJECT_SLUG}": slug,
|
|
182
236
|
"${DATABASE_NAME}": databaseName,
|
|
237
|
+
"${PRODUCT_TYPE}": productType,
|
|
183
238
|
"${RESPONSE_LANGUAGE}": LANGUAGE_RESPONSES[language] || "Turkish",
|
|
184
239
|
};
|
|
185
240
|
process.stdout.write(pc.dim(" Replacing placeholders..."));
|
|
@@ -235,13 +290,14 @@ See \`docs/bible/data/schema.md\`
|
|
|
235
290
|
console.log();
|
|
236
291
|
console.log(pc.green(pc.bold("Project created successfully!")));
|
|
237
292
|
await checkDependencies();
|
|
293
|
+
const dockerCmd = await getDockerComposeCommand();
|
|
238
294
|
showClaudeMaxWarning();
|
|
239
295
|
console.log();
|
|
240
296
|
console.log(pc.bold(" Next steps:"));
|
|
241
297
|
console.log();
|
|
242
298
|
console.log(pc.cyan(` cd ${slug}`));
|
|
243
299
|
console.log(pc.cyan(" pnpm install"));
|
|
244
|
-
console.log(pc.cyan(
|
|
300
|
+
console.log(pc.cyan(` ${dockerCmd} up -d`) + " " + pc.dim("# Start PostgreSQL & Redis"));
|
|
245
301
|
console.log(pc.cyan(" pnpm dev"));
|
|
246
302
|
console.log();
|
|
247
303
|
console.log(pc.dim(" Optional:"));
|
|
@@ -251,18 +307,24 @@ See \`docs/bible/data/schema.md\`
|
|
|
251
307
|
console.log(pc.dim(" Configuration:"));
|
|
252
308
|
console.log(pc.dim(` Name: ${name}`));
|
|
253
309
|
console.log(pc.dim(` Code: ${code}`));
|
|
310
|
+
console.log(pc.dim(` Product: ${productType}`));
|
|
254
311
|
console.log(pc.dim(` Platforms: ${platforms.join(", ")}`));
|
|
255
312
|
console.log(pc.dim(` Features: ${features.join(", ") || "none"}`));
|
|
256
313
|
console.log(pc.dim(` Language: ${LANGUAGE_RESPONSES[language] || "Turkish"}`));
|
|
257
314
|
console.log();
|
|
258
315
|
process.stdout.write(pc.dim(" Building MCP server..."));
|
|
316
|
+
const mcpPath = path.join(targetDir, "mcp-server");
|
|
259
317
|
try {
|
|
260
|
-
await execa("pnpm", ["install"], { cwd:
|
|
261
|
-
await execa("pnpm", ["build"], { cwd:
|
|
318
|
+
await execa("pnpm", ["install"], { cwd: mcpPath });
|
|
319
|
+
await execa("pnpm", ["build"], { cwd: mcpPath });
|
|
262
320
|
console.log(pc.green(" done"));
|
|
263
321
|
}
|
|
264
|
-
catch {
|
|
265
|
-
console.log(pc.yellow("
|
|
322
|
+
catch (error) {
|
|
323
|
+
console.log(pc.yellow(" failed"));
|
|
324
|
+
if (error instanceof Error) {
|
|
325
|
+
console.log(pc.dim(` Error: ${error.message.split("\n")[0]}`));
|
|
326
|
+
}
|
|
327
|
+
console.log(pc.dim(" Run manually: cd mcp-server && pnpm install && pnpm build"));
|
|
266
328
|
}
|
|
267
329
|
const mcpConfigPath = path.join(targetDir, ".claude", "settings.local.json");
|
|
268
330
|
const mcpConfig = {
|