create-restack-pattern 0.2.0 → 0.2.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/dist/index.js +48 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -54,14 +54,17 @@ Examples:
|
|
|
54
54
|
console.log();
|
|
55
55
|
p.intro(color.bgCyan(color.black(" create-restack-pattern ")));
|
|
56
56
|
let projectName = process.argv[2];
|
|
57
|
+
let isCurrentDir = projectName === ".";
|
|
57
58
|
if (!projectName || projectName.startsWith("-")) {
|
|
58
59
|
const nameInput = await p.text({
|
|
59
60
|
message: "What is your project named?",
|
|
60
|
-
placeholder: "my-restack-app",
|
|
61
|
+
placeholder: "my-restack-app (or . for current directory)",
|
|
61
62
|
defaultValue: "my-restack-app",
|
|
62
63
|
validate: (value) => {
|
|
63
64
|
if (!value)
|
|
64
65
|
return "Project name cannot be empty";
|
|
66
|
+
if (value === ".")
|
|
67
|
+
return;
|
|
65
68
|
if (!isValidProjectName(value)) {
|
|
66
69
|
return "Project name may only contain letters, numbers, hyphens, and underscores";
|
|
67
70
|
}
|
|
@@ -75,12 +78,41 @@ Examples:
|
|
|
75
78
|
process.exit(0);
|
|
76
79
|
}
|
|
77
80
|
projectName = nameInput;
|
|
81
|
+
isCurrentDir = projectName === ".";
|
|
78
82
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
process.
|
|
83
|
+
let targetDir;
|
|
84
|
+
let displayProjectName;
|
|
85
|
+
if (isCurrentDir) {
|
|
86
|
+
targetDir = process.cwd();
|
|
87
|
+
displayProjectName = path.basename(targetDir);
|
|
88
|
+
const existingFiles = readdirSync(targetDir);
|
|
89
|
+
if (existingFiles.length > 0) {
|
|
90
|
+
const confirmOverwrite = await p.confirm({
|
|
91
|
+
message: `Current directory is not empty (${existingFiles.length} item(s) found). Continue and scaffold into this directory?`,
|
|
92
|
+
initialValue: false,
|
|
93
|
+
});
|
|
94
|
+
if (p.isCancel(confirmOverwrite) || !confirmOverwrite) {
|
|
95
|
+
p.cancel("Operation cancelled.");
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
83
99
|
}
|
|
100
|
+
else {
|
|
101
|
+
if (!isValidProjectName(projectName)) {
|
|
102
|
+
p.cancel(color.red("Invalid project name. Use letters, numbers, hyphens, or underscores only."));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
targetDir = path.resolve(process.cwd(), projectName);
|
|
106
|
+
displayProjectName = projectName;
|
|
107
|
+
if (existsSync(targetDir)) {
|
|
108
|
+
p.cancel(color.red(`Error: Directory "${projectName}" already exists.`));
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const normalizedPkgName = displayProjectName
|
|
113
|
+
.toLowerCase()
|
|
114
|
+
.replace(/[^a-z0-9-_]/g, "-")
|
|
115
|
+
.replace(/^-+|-+$/g, "") || "restack-app";
|
|
84
116
|
const database = (await p.select({
|
|
85
117
|
message: "Select your database:",
|
|
86
118
|
options: [
|
|
@@ -148,7 +180,7 @@ Examples:
|
|
|
148
180
|
}
|
|
149
181
|
const s = p.spinner();
|
|
150
182
|
// 1. Scaffold files
|
|
151
|
-
s.start(`Scaffolding ${
|
|
183
|
+
s.start(`Scaffolding ${displayProjectName} (${database} + ${idStrategy}) ...`);
|
|
152
184
|
const baseDir = path.join(templateDir, "base");
|
|
153
185
|
const overlaysDir = path.join(templateDir, "overlays");
|
|
154
186
|
// Copy base template
|
|
@@ -172,7 +204,7 @@ Examples:
|
|
|
172
204
|
// 2. Patch package.json files
|
|
173
205
|
const rootPkgPath = path.join(targetDir, "package.json");
|
|
174
206
|
const rootPkg = JSON.parse(readFileSync(rootPkgPath, "utf-8"));
|
|
175
|
-
rootPkg.name =
|
|
207
|
+
rootPkg.name = normalizedPkgName;
|
|
176
208
|
if (packageManager !== "pnpm") {
|
|
177
209
|
rootPkg.workspaces = ["frontend", "backend", "packages/*"];
|
|
178
210
|
}
|
|
@@ -212,7 +244,7 @@ Examples:
|
|
|
212
244
|
writeFileSync(frontendPkgPath, `${JSON.stringify(frontendPkg, null, 2)}\n`);
|
|
213
245
|
}
|
|
214
246
|
}
|
|
215
|
-
s.stop(color.green(`Scaffolded ${
|
|
247
|
+
s.stop(color.green(`Scaffolded ${displayProjectName} files successfully!`));
|
|
216
248
|
// 3. Install dependencies
|
|
217
249
|
if (isCommandAvailable(packageManager)) {
|
|
218
250
|
s.start(`Installing dependencies using ${packageManager} ...`);
|
|
@@ -246,7 +278,9 @@ Examples:
|
|
|
246
278
|
}
|
|
247
279
|
// 5. Initialize git
|
|
248
280
|
try {
|
|
249
|
-
|
|
281
|
+
if (!existsSync(path.join(targetDir, ".git"))) {
|
|
282
|
+
execSync("git init", { cwd: targetDir, stdio: "ignore" });
|
|
283
|
+
}
|
|
250
284
|
}
|
|
251
285
|
catch {
|
|
252
286
|
// Non-fatal
|
|
@@ -258,8 +292,11 @@ Examples:
|
|
|
258
292
|
: `• For Backend:
|
|
259
293
|
${color.cyan("cp backend/.env.example backend/.env")}
|
|
260
294
|
(SQLite database file will be created automatically at ${color.yellow("sqlite.db")})`;
|
|
261
|
-
|
|
262
|
-
|
|
295
|
+
const cdStep = isCurrentDir
|
|
296
|
+
? `1. You are already in the project directory!`
|
|
297
|
+
: `1. Go to your project directory:
|
|
298
|
+
${color.cyan(`cd ${projectName}`)}`;
|
|
299
|
+
p.note(`${cdStep}
|
|
263
300
|
|
|
264
301
|
2. Configure environment variables:
|
|
265
302
|
${dbConfigStep}
|