@alexmc2/create-express-api-starter 0.1.6 → 0.2.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/README.md +13 -2
- package/dist/cli.js +138 -19
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ The CLI offers multiple configuration options to suit different preferences and
|
|
|
14
14
|
- Simple or MVC architecture
|
|
15
15
|
- In-memory or PostgreSQL (local `psql` or Docker)
|
|
16
16
|
- npm workflow (`npm create`, `npm init`, or `npx`)
|
|
17
|
+
- Dependency installs with `npm` or `yarn`
|
|
17
18
|
|
|
18
19
|
<br />
|
|
19
20
|
|
|
@@ -96,6 +97,12 @@ npm test # Run the test suite
|
|
|
96
97
|
npm run lint # Run ESLint
|
|
97
98
|
```
|
|
98
99
|
|
|
100
|
+
To use Yarn for dependency installation and command examples shown by the CLI:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm create @alexmc2/express-api-starter@latest my-api -- --package-manager=yarn
|
|
104
|
+
```
|
|
105
|
+
|
|
99
106
|
Your API is live at `http://localhost:3000`. Go to `http://localhost:3000/health` to confirm.
|
|
100
107
|
|
|
101
108
|
## How it works
|
|
@@ -117,6 +124,7 @@ The CLI walks you through these choices interactively. Use `--yes` to skip promp
|
|
|
117
124
|
| **Database** | In-memory, Postgres (psql), Postgres (Docker) | In-memory |
|
|
118
125
|
| **Educational comments** | On, Off | On |
|
|
119
126
|
| **Install dependencies** | Yes, No | Yes |
|
|
127
|
+
| **Package manager** | npm, yarn | npm |
|
|
120
128
|
| **Initialise git repo** | Yes, No | Yes |
|
|
121
129
|
|
|
122
130
|
### CLI flags
|
|
@@ -125,9 +133,12 @@ The CLI walks you through these choices interactively. Use `--yes` to skip promp
|
|
|
125
133
|
| -------------- | ----------------------------------------------------------- |
|
|
126
134
|
| `--yes` | Accept all defaults, skip prompts |
|
|
127
135
|
| `--dry-run` | Show the generation plan without writing files |
|
|
128
|
-
| `--no-install` | Skip
|
|
136
|
+
| `--no-install` | Skip dependency installation after generation |
|
|
129
137
|
| `--no-git` | Skip `git init` after generation |
|
|
130
|
-
| `--verbose` | Show full
|
|
138
|
+
| `--verbose` | Show full dependency install output instead of quiet mode |
|
|
139
|
+
| `--package-manager=<name>` | Choose dependency installer: `npm` or `yarn` |
|
|
140
|
+
| `--pm <name>` | Alias for `--package-manager` |
|
|
141
|
+
| `--yarn` | Shortcut for `--package-manager=yarn` |
|
|
131
142
|
|
|
132
143
|
## What gets generated
|
|
133
144
|
|
package/dist/cli.js
CHANGED
|
@@ -23,6 +23,16 @@ function parseBooleanValue(value) {
|
|
|
23
23
|
}
|
|
24
24
|
return void 0;
|
|
25
25
|
}
|
|
26
|
+
function parsePackageManagerValue(value) {
|
|
27
|
+
if (value === void 0) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
const normalized = value.trim().toLowerCase();
|
|
31
|
+
if (normalized === "npm" || normalized === "yarn") {
|
|
32
|
+
return normalized;
|
|
33
|
+
}
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
26
36
|
function splitFlag(token) {
|
|
27
37
|
const withoutPrefix = token.slice(2);
|
|
28
38
|
const equalsIndex = withoutPrefix.indexOf("=");
|
|
@@ -43,19 +53,22 @@ function parseArgs(argv) {
|
|
|
43
53
|
dryRun: false,
|
|
44
54
|
install: true,
|
|
45
55
|
git: true,
|
|
46
|
-
verbose: false
|
|
56
|
+
verbose: false,
|
|
57
|
+
packageManager: "npm"
|
|
47
58
|
};
|
|
48
59
|
const provided = {
|
|
49
60
|
yes: false,
|
|
50
61
|
dryRun: false,
|
|
51
62
|
install: false,
|
|
52
63
|
git: false,
|
|
53
|
-
verbose: false
|
|
64
|
+
verbose: false,
|
|
65
|
+
packageManager: false
|
|
54
66
|
};
|
|
55
67
|
const unknownFlags = [];
|
|
56
68
|
const positionals = [];
|
|
57
69
|
let positionalOnly = false;
|
|
58
|
-
for (
|
|
70
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
71
|
+
const token = argv[index];
|
|
59
72
|
if (positionalOnly) {
|
|
60
73
|
positionals.push(token);
|
|
61
74
|
continue;
|
|
@@ -125,6 +138,38 @@ function parseArgs(argv) {
|
|
|
125
138
|
provided.verbose = true;
|
|
126
139
|
continue;
|
|
127
140
|
}
|
|
141
|
+
if (name === "package-manager" || name === "pm") {
|
|
142
|
+
let rawValue = value;
|
|
143
|
+
if (rawValue === void 0) {
|
|
144
|
+
const nextToken = argv[index + 1];
|
|
145
|
+
if (nextToken !== void 0 && !nextToken.startsWith("-")) {
|
|
146
|
+
const parsedNextToken = parsePackageManagerValue(nextToken);
|
|
147
|
+
if (parsedNextToken !== void 0) {
|
|
148
|
+
rawValue = nextToken;
|
|
149
|
+
index += 1;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const packageManager = parsePackageManagerValue(rawValue);
|
|
154
|
+
if (packageManager === void 0) {
|
|
155
|
+
unknownFlags.push(token);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
flags.packageManager = packageManager;
|
|
159
|
+
provided.packageManager = true;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (name === "yarn") {
|
|
163
|
+
const parsedValue = parseBooleanValue(value);
|
|
164
|
+
if (value !== void 0 && parsedValue === void 0) {
|
|
165
|
+
unknownFlags.push(token);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const useYarn = parsedValue ?? true;
|
|
169
|
+
flags.packageManager = useYarn ? "yarn" : "npm";
|
|
170
|
+
provided.packageManager = true;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
128
173
|
unknownFlags.push(token);
|
|
129
174
|
}
|
|
130
175
|
return {
|
|
@@ -162,6 +207,9 @@ function databaseLabel(databaseMode) {
|
|
|
162
207
|
}
|
|
163
208
|
return "In-memory";
|
|
164
209
|
}
|
|
210
|
+
function packageManagerLabel(packageManager) {
|
|
211
|
+
return packageManager === "yarn" ? "Yarn" : "npm";
|
|
212
|
+
}
|
|
165
213
|
|
|
166
214
|
// src/core/naming.ts
|
|
167
215
|
function toDatabaseName(projectName) {
|
|
@@ -246,27 +294,39 @@ function printCard(title, lines) {
|
|
|
246
294
|
}
|
|
247
295
|
|
|
248
296
|
// src/cli/output.ts
|
|
297
|
+
function installCommand(selection) {
|
|
298
|
+
return `${selection.packageManager} install`;
|
|
299
|
+
}
|
|
300
|
+
function scriptCommand(selection, script) {
|
|
301
|
+
if (selection.packageManager === "yarn") {
|
|
302
|
+
return `yarn ${script}`;
|
|
303
|
+
}
|
|
304
|
+
if (script === "test") {
|
|
305
|
+
return "npm test";
|
|
306
|
+
}
|
|
307
|
+
return `npm run ${script}`;
|
|
308
|
+
}
|
|
249
309
|
function buildNextStepCommands(selection) {
|
|
250
310
|
const commands = [`cd ${selection.projectName}`];
|
|
251
311
|
if (!selection.installDeps) {
|
|
252
|
-
commands.push(
|
|
312
|
+
commands.push(installCommand(selection));
|
|
253
313
|
}
|
|
254
314
|
commands.push("cp .env.example .env");
|
|
255
315
|
if (selection.databaseMode === "postgres-psql") {
|
|
256
|
-
commands.push("
|
|
257
|
-
commands.push("
|
|
258
|
-
commands.push("
|
|
316
|
+
commands.push(scriptCommand(selection, "db:create"));
|
|
317
|
+
commands.push(scriptCommand(selection, "db:setup"));
|
|
318
|
+
commands.push(scriptCommand(selection, "db:seed"));
|
|
259
319
|
}
|
|
260
320
|
if (selection.databaseMode === "postgres-docker") {
|
|
261
|
-
commands.push("
|
|
262
|
-
commands.push("
|
|
263
|
-
commands.push("
|
|
321
|
+
commands.push(scriptCommand(selection, "db:up"));
|
|
322
|
+
commands.push(scriptCommand(selection, "db:setup"));
|
|
323
|
+
commands.push(scriptCommand(selection, "db:seed"));
|
|
264
324
|
}
|
|
265
|
-
commands.push("
|
|
325
|
+
commands.push(scriptCommand(selection, "dev"));
|
|
266
326
|
if (selection.language === "ts") {
|
|
267
|
-
commands.push("
|
|
327
|
+
commands.push(scriptCommand(selection, "build"));
|
|
268
328
|
}
|
|
269
|
-
commands.push("
|
|
329
|
+
commands.push(scriptCommand(selection, "test"));
|
|
270
330
|
return commands;
|
|
271
331
|
}
|
|
272
332
|
function buildPsqlSetupLines(selection, platform) {
|
|
@@ -279,7 +339,7 @@ function buildPsqlSetupLines(selection, platform) {
|
|
|
279
339
|
`DATABASE_URL=postgres://postgres:<your-password>@localhost:5432/${databaseName}`
|
|
280
340
|
]),
|
|
281
341
|
pc2.dim("# Then run the db scripts below:"),
|
|
282
|
-
...formatCommandLines(["
|
|
342
|
+
...formatCommandLines([scriptCommand(selection, "db:create")])
|
|
283
343
|
];
|
|
284
344
|
}
|
|
285
345
|
if (platform === "darwin") {
|
|
@@ -344,6 +404,11 @@ function printDryRunPlan(selection, plan) {
|
|
|
344
404
|
value: selection.installDeps ? "Yes" : "No",
|
|
345
405
|
tone: selection.installDeps ? "success" : "warn"
|
|
346
406
|
},
|
|
407
|
+
{
|
|
408
|
+
key: "Package manager",
|
|
409
|
+
value: packageManagerLabel(selection.packageManager),
|
|
410
|
+
tone: "accent"
|
|
411
|
+
},
|
|
347
412
|
{
|
|
348
413
|
key: "Init git",
|
|
349
414
|
value: selection.initGit ? "Yes" : "No",
|
|
@@ -378,6 +443,11 @@ function printNextSteps(selection, platform = process.platform) {
|
|
|
378
443
|
key: "Educational",
|
|
379
444
|
value: selection.educational ? "On" : "Off",
|
|
380
445
|
tone: selection.educational ? "success" : "muted"
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
key: "Package manager",
|
|
449
|
+
value: packageManagerLabel(selection.packageManager),
|
|
450
|
+
tone: "accent"
|
|
381
451
|
}
|
|
382
452
|
];
|
|
383
453
|
if (selection.language === "js") {
|
|
@@ -425,6 +495,7 @@ var DEFAULT_SELECTIONS = {
|
|
|
425
495
|
databaseMode: "memory",
|
|
426
496
|
educational: true,
|
|
427
497
|
installDeps: true,
|
|
498
|
+
packageManager: "npm",
|
|
428
499
|
initGit: true
|
|
429
500
|
};
|
|
430
501
|
|
|
@@ -451,6 +522,7 @@ async function collectSelections(parsedArgs) {
|
|
|
451
522
|
databaseMode: DEFAULT_SELECTIONS.databaseMode,
|
|
452
523
|
educational: DEFAULT_SELECTIONS.educational,
|
|
453
524
|
installDeps: parsedArgs.flags.install,
|
|
525
|
+
packageManager: parsedArgs.flags.packageManager,
|
|
454
526
|
initGit: parsedArgs.flags.git,
|
|
455
527
|
dryRun: parsedArgs.flags.dryRun
|
|
456
528
|
};
|
|
@@ -570,6 +642,22 @@ async function collectSelections(parsedArgs) {
|
|
|
570
642
|
initialValue: DEFAULT_SELECTIONS.installDeps
|
|
571
643
|
})
|
|
572
644
|
);
|
|
645
|
+
const packageManager = parsedArgs.provided.packageManager ? parsedArgs.flags.packageManager : unwrapPrompt(
|
|
646
|
+
await select({
|
|
647
|
+
message: "Package manager",
|
|
648
|
+
initialValue: DEFAULT_SELECTIONS.packageManager,
|
|
649
|
+
options: [
|
|
650
|
+
{
|
|
651
|
+
value: "npm",
|
|
652
|
+
label: "npm"
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
value: "yarn",
|
|
656
|
+
label: "yarn"
|
|
657
|
+
}
|
|
658
|
+
]
|
|
659
|
+
})
|
|
660
|
+
);
|
|
573
661
|
const initGit = parsedArgs.provided.git ? parsedArgs.flags.git : unwrapPrompt(
|
|
574
662
|
await confirm({
|
|
575
663
|
message: "Initialize git repository",
|
|
@@ -586,6 +674,7 @@ async function collectSelections(parsedArgs) {
|
|
|
586
674
|
databaseMode,
|
|
587
675
|
educational,
|
|
588
676
|
installDeps,
|
|
677
|
+
packageManager,
|
|
589
678
|
initGit,
|
|
590
679
|
dryRun: parsedArgs.flags.dryRun
|
|
591
680
|
};
|
|
@@ -820,12 +909,27 @@ async function runCommand(command, args, cwd) {
|
|
|
820
909
|
stdio: "inherit"
|
|
821
910
|
});
|
|
822
911
|
}
|
|
823
|
-
|
|
912
|
+
function npmInstallArgs(verbose) {
|
|
824
913
|
const args = ["install", "--no-audit", "--no-fund"];
|
|
825
914
|
if (!verbose) {
|
|
826
915
|
args.push("--loglevel=error");
|
|
827
916
|
}
|
|
828
|
-
|
|
917
|
+
return args;
|
|
918
|
+
}
|
|
919
|
+
function yarnInstallArgs(verbose) {
|
|
920
|
+
const args = ["install"];
|
|
921
|
+
if (!verbose) {
|
|
922
|
+
args.push("--silent");
|
|
923
|
+
}
|
|
924
|
+
return args;
|
|
925
|
+
}
|
|
926
|
+
function formatInstallCommand(packageManager, verbose = false) {
|
|
927
|
+
const args = packageManager === "yarn" ? yarnInstallArgs(verbose) : npmInstallArgs(verbose);
|
|
928
|
+
return `${packageManager} ${args.join(" ")}`;
|
|
929
|
+
}
|
|
930
|
+
async function installDependencies(cwd, packageManager, verbose = false) {
|
|
931
|
+
const args = packageManager === "yarn" ? yarnInstallArgs(verbose) : npmInstallArgs(verbose);
|
|
932
|
+
await runCommand(packageManager, args, cwd);
|
|
829
933
|
}
|
|
830
934
|
async function initGitRepo(cwd) {
|
|
831
935
|
await runCommand("git", ["init"], cwd);
|
|
@@ -879,6 +983,17 @@ async function ensurePsqlAvailable() {
|
|
|
879
983
|
);
|
|
880
984
|
}
|
|
881
985
|
}
|
|
986
|
+
async function ensurePackageManagerAvailable(packageManager) {
|
|
987
|
+
const hasPackageManager = await commandExists(packageManager, ["--version"]);
|
|
988
|
+
if (!hasPackageManager) {
|
|
989
|
+
throw new Error(
|
|
990
|
+
[
|
|
991
|
+
`Package manager "${packageManager}" was selected, but it was not found.`,
|
|
992
|
+
`Install ${packageManager} or rerun with --package-manager=npm.`
|
|
993
|
+
].join(" ")
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
882
997
|
function registerSigintHandler() {
|
|
883
998
|
process.on("SIGINT", () => {
|
|
884
999
|
logger.warn("Cancelled by user.");
|
|
@@ -930,9 +1045,13 @@ async function runCli(argv) {
|
|
|
930
1045
|
}
|
|
931
1046
|
logger.success(`Project files generated at ${targetDir}.`);
|
|
932
1047
|
if (selections.installDeps) {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1048
|
+
await ensurePackageManagerAvailable(selections.packageManager);
|
|
1049
|
+
const installCommand2 = formatInstallCommand(
|
|
1050
|
+
selections.packageManager,
|
|
1051
|
+
parsedArgs.flags.verbose
|
|
1052
|
+
);
|
|
1053
|
+
logger.info(`Installing dependencies (${installCommand2})...`);
|
|
1054
|
+
await installDependencies(targetDir, selections.packageManager, parsedArgs.flags.verbose);
|
|
936
1055
|
logger.success("Dependencies installed.");
|
|
937
1056
|
} else {
|
|
938
1057
|
logger.info("Skipped dependency installation.");
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/index.ts","../src/cli/args.ts","../src/cli/output.ts","../src/core/labels.ts","../src/core/naming.ts","../src/utils/terminalUi.ts","../src/cli/prompts.ts","../src/core/defaults.ts","../src/core/validation.ts","../src/generator/index.ts","../src/utils/paths.ts","../src/utils/exec.ts","../src/utils/files.ts","../src/utils/logger.ts"],"sourcesContent":["import pc from 'picocolors';\nimport { pathToFileURL } from 'node:url';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { parseArgs } from './args.js';\nimport { printDryRunPlan, printNextSteps } from './output.js';\nimport { collectSelections, PromptCancelledError } from './prompts.js';\nimport { validateProjectName } from '../core/validation.js';\nimport { generateProject, planProject } from '../generator/index.js';\nimport { commandExists, initGitRepo, installDependencies } from '../utils/exec.js';\nimport { assertSafeTargetDir } from '../utils/files.js';\nimport { logger } from '../utils/logger.js';\nimport { resolveTargetDir } from '../utils/paths.js';\n\nasync function ensurePsqlAvailable(): Promise<void> {\n const hasPsql = await commandExists('psql', ['--version']);\n\n if (!hasPsql) {\n throw new Error(\n [\n 'Postgres (psql) mode requires the `psql` client tool, but it was not found.',\n 'Install Postgres client tools and make sure `psql --version` works, or rerun and choose Postgres (Docker).'\n ].join(' ')\n );\n }\n}\n\nfunction registerSigintHandler(): void {\n process.on('SIGINT', () => {\n logger.warn('Cancelled by user.');\n process.exit(1);\n });\n}\n\nasync function runCli(argv: string[]): Promise<void> {\n const parsedArgs = parseArgs(argv);\n\n for (const unknownFlag of parsedArgs.unknownFlags) {\n logger.warn(`Unknown flag \"${unknownFlag}\" was ignored.`);\n }\n\n const selections = await collectSelections(parsedArgs);\n\n const projectNameError = validateProjectName(selections.projectName);\n\n if (projectNameError) {\n throw new Error(projectNameError);\n }\n\n const targetDir = resolveTargetDir(process.cwd(), selections.projectName);\n\n await assertSafeTargetDir(targetDir);\n\n if (selections.databaseMode === 'postgres-psql') {\n await ensurePsqlAvailable();\n }\n\n const templateConfig = {\n projectName: selections.projectName,\n language: selections.language,\n moduleSystem: selections.moduleSystem,\n jsDevWatcher: selections.jsDevWatcher,\n architecture: selections.architecture,\n educational: selections.educational,\n databaseMode: selections.databaseMode\n };\n\n const plan = await planProject(templateConfig, targetDir);\n\n if (selections.dryRun) {\n printDryRunPlan(selections, plan);\n return;\n }\n\n await generateProject({\n config: templateConfig,\n targetDir\n });\n\n const packageJsonPath = path.join(targetDir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) {\n throw new Error(\n [\n 'Project generation did not produce package.json.',\n 'This can happen if the installed CLI/templates are out of sync.',\n 'Reinstall the latest package version and try again.'\n ].join(' ')\n );\n }\n\n logger.success(`Project files generated at ${targetDir}.`);\n\n if (selections.installDeps) {\n const installCommand = parsedArgs.flags.verbose\n ? 'npm install --no-audit --no-fund'\n : 'npm install --no-audit --no-fund --loglevel=error';\n logger.info(`Installing dependencies (${installCommand})...`);\n await installDependencies(targetDir, parsedArgs.flags.verbose);\n logger.success('Dependencies installed.');\n } else {\n logger.info('Skipped dependency installation.');\n }\n\n if (selections.initGit) {\n logger.info('Initializing git repository...');\n await initGitRepo(targetDir);\n logger.success('Git repository initialized.');\n } else {\n logger.info('Skipped git initialization.');\n }\n\n logger.success('Scaffolding complete.');\n printNextSteps(selections);\n}\n\nfunction isCliEntrypoint(): boolean {\n if (typeof process.argv[1] !== 'string') {\n return false;\n }\n\n try {\n const argvPath = fs.realpathSync(process.argv[1]);\n const modulePath = fs.realpathSync(fileURLToPath(import.meta.url));\n return argvPath === modulePath;\n } catch {\n return pathToFileURL(process.argv[1]).href === import.meta.url;\n }\n}\n\nconst isEntrypoint = isCliEntrypoint();\n\nif (isEntrypoint) {\n registerSigintHandler();\n\n runCli(process.argv.slice(2)).catch((error: unknown) => {\n if (error instanceof PromptCancelledError) {\n logger.warn('Cancelled by user.');\n process.exit(1);\n }\n\n const message = error instanceof Error ? error.message : 'Unexpected error';\n logger.error(message);\n if (error instanceof Error && error.stack) {\n console.error(pc.gray(error.stack));\n }\n process.exit(1);\n });\n}\n\nexport { runCli };\n","import type { ParsedArgs } from '../core/types.js';\n\nconst TRUE_VALUES = new Set(['1', 'true', 'yes', 'on']);\nconst FALSE_VALUES = new Set(['0', 'false', 'no', 'off']);\n\nfunction parseBooleanValue(value: string | undefined): boolean | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const normalized = value.trim().toLowerCase();\n\n if (TRUE_VALUES.has(normalized)) {\n return true;\n }\n\n if (FALSE_VALUES.has(normalized)) {\n return false;\n }\n\n return undefined;\n}\n\nfunction splitFlag(token: string): { name: string; value: string | undefined } {\n const withoutPrefix = token.slice(2);\n const equalsIndex = withoutPrefix.indexOf('=');\n\n if (equalsIndex === -1) {\n return {\n name: withoutPrefix,\n value: undefined\n };\n }\n\n return {\n name: withoutPrefix.slice(0, equalsIndex),\n value: withoutPrefix.slice(equalsIndex + 1)\n };\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const flags = {\n yes: false,\n dryRun: false,\n install: true,\n git: true,\n verbose: false\n };\n\n const provided = {\n yes: false,\n dryRun: false,\n install: false,\n git: false,\n verbose: false\n };\n\n const unknownFlags: string[] = [];\n const positionals: string[] = [];\n\n let positionalOnly = false;\n\n for (const token of argv) {\n if (positionalOnly) {\n positionals.push(token);\n continue;\n }\n\n if (token === '--') {\n positionalOnly = true;\n continue;\n }\n\n if (!token.startsWith('-') || token === '-') {\n positionals.push(token);\n continue;\n }\n\n if (!token.startsWith('--')) {\n unknownFlags.push(token);\n continue;\n }\n\n const { name, value } = splitFlag(token);\n\n if (name === 'yes') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n flags.yes = parsedValue ?? true;\n provided.yes = true;\n continue;\n }\n\n if (name === 'dry-run') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n flags.dryRun = parsedValue ?? true;\n provided.dryRun = true;\n continue;\n }\n\n if (name === 'no-install') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n const noInstall = parsedValue ?? true;\n flags.install = !noInstall;\n provided.install = true;\n continue;\n }\n\n if (name === 'no-git') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n const noGit = parsedValue ?? true;\n flags.git = !noGit;\n provided.git = true;\n continue;\n }\n\n if (name === 'verbose') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n flags.verbose = parsedValue ?? true;\n provided.verbose = true;\n continue;\n }\n\n unknownFlags.push(token);\n }\n\n return {\n projectName: positionals[0],\n positionals,\n unknownFlags,\n flags,\n provided\n };\n}\n","import path from 'node:path';\nimport pc from 'picocolors';\n\nimport {\n architectureLabel,\n databaseLabel,\n jsDevWatcherLabel,\n languageLabel,\n moduleSystemLabel,\n} from '../core/labels.js';\nimport { toDatabaseName } from '../core/naming.js';\nimport type { GenerationPlan, UserSelections } from '../core/types.js';\nimport {\n formatCommandLines,\n formatKeyValueLines,\n printCard,\n} from '../utils/terminalUi.js';\n\nfunction buildNextStepCommands(selection: UserSelections): string[] {\n const commands = [`cd ${selection.projectName}`];\n\n if (!selection.installDeps) {\n commands.push('npm install');\n }\n\n commands.push('cp .env.example .env');\n\n if (selection.databaseMode === 'postgres-psql') {\n commands.push('npm run db:create');\n commands.push('npm run db:setup');\n commands.push('npm run db:seed');\n }\n\n if (selection.databaseMode === 'postgres-docker') {\n commands.push('npm run db:up');\n commands.push('npm run db:setup');\n commands.push('npm run db:seed');\n }\n\n commands.push('npm run dev');\n\n if (selection.language === 'ts') {\n commands.push('npm run build');\n }\n\n commands.push('npm test');\n\n return commands;\n}\n\nfunction buildPsqlSetupLines(\n selection: UserSelections,\n platform: NodeJS.Platform,\n): string[] {\n const databaseName = toDatabaseName(selection.projectName);\n\n if (platform === 'win32') {\n return [\n pc.yellow('Windows first-time setup (run once if needed):'),\n pc.dim('# Edit .env and use the role/password from the PostgreSQL installer'),\n ...formatCommandLines([\n `DATABASE_URL=postgres://postgres:<your-password>@localhost:5432/${databaseName}`,\n ]),\n pc.dim('# Then run the db scripts below:'),\n ...formatCommandLines(['npm run db:create']),\n ];\n }\n\n if (platform === 'darwin') {\n return [\n pc.yellow('macOS first-time setup (run once if needed):'),\n pc.dim('# Homebrew installs often already create a role for your OS user'),\n pc.dim('# Run these only if you get a role/auth error'),\n ...formatCommandLines([\n 'createuser --createdb \"$USER\"',\n `psql -d postgres -c \"ALTER USER \\\\\"$USER\\\\\" WITH PASSWORD 'postgres';\"`,\n ]),\n ];\n }\n\n return [\n pc.yellow('Linux first-time setup (run once if needed):'),\n pc.dim('# Create a Postgres role matching your OS user'),\n ...formatCommandLines([\n 'sudo -u postgres createuser --createdb \"$USER\"',\n `sudo -u postgres psql -c \"ALTER USER \\\\\"$USER\\\\\" WITH PASSWORD 'postgres';\"`,\n ]),\n ];\n}\n\nexport function printDryRunPlan(\n selection: UserSelections,\n plan: GenerationPlan,\n): void {\n const languageValue =\n selection.language === 'js'\n ? `${languageLabel(selection.language)} (${moduleSystemLabel(selection.moduleSystem)})`\n : languageLabel(selection.language);\n\n const summaryEntries: Parameters<typeof formatKeyValueLines>[0] = [\n {\n key: 'Target',\n value: formatTargetPath(plan.targetDir),\n tone: 'accent',\n },\n {\n key: 'Language',\n value: languageValue,\n tone: 'accent',\n },\n {\n key: 'Architecture',\n value: architectureLabel(selection.architecture),\n tone: 'accent',\n },\n {\n key: 'Database',\n value: databaseLabel(selection.databaseMode),\n tone: 'accent',\n },\n ];\n\n if (selection.language === 'js') {\n summaryEntries.push({\n key: 'Dev watcher',\n value: jsDevWatcherLabel(selection.jsDevWatcher),\n tone: 'accent',\n });\n }\n\n summaryEntries.push(\n {\n key: 'Educational',\n value: selection.educational ? 'On' : 'Off',\n tone: selection.educational ? 'success' : 'muted',\n },\n {\n key: 'Install deps',\n value: selection.installDeps ? 'Yes' : 'No',\n tone: selection.installDeps ? 'success' : 'warn',\n },\n {\n key: 'Init git',\n value: selection.initGit ? 'Yes' : 'No',\n tone: selection.initGit ? 'success' : 'warn',\n },\n );\n\n const summaryLines = formatKeyValueLines(summaryEntries);\n\n const fileLines = plan.files.map((file) => `${pc.dim('-')} ${file.outputRelativePath}`);\n\n console.log('');\n printCard('Dry Run: Configuration', summaryLines);\n console.log('');\n printCard(`Dry Run: Files (${plan.files.length})`, fileLines);\n}\n\nexport function printNextSteps(\n selection: UserSelections,\n platform: NodeJS.Platform = process.platform,\n): void {\n const stackParts = [\n selection.language === 'js'\n ? `${languageLabel(selection.language)} (${moduleSystemLabel(selection.moduleSystem)})`\n : languageLabel(selection.language),\n architectureLabel(selection.architecture),\n databaseLabel(selection.databaseMode),\n ];\n\n const summaryEntries: Parameters<typeof formatKeyValueLines>[0] = [\n {\n key: 'Project',\n value: selection.projectName,\n tone: 'accent',\n },\n {\n key: 'Stack',\n value: stackParts.join(' | '),\n tone: 'accent',\n },\n {\n key: 'Educational',\n value: selection.educational ? 'On' : 'Off',\n tone: selection.educational ? 'success' : 'muted',\n },\n ];\n\n if (selection.language === 'js') {\n summaryEntries.push({\n key: 'Dev watcher',\n value: jsDevWatcherLabel(selection.jsDevWatcher),\n tone: 'accent',\n });\n }\n\n const summaryLines = formatKeyValueLines(summaryEntries);\n\n const nextStepCommands = buildNextStepCommands(selection);\n\n console.log('');\n printCard('Project Ready', summaryLines);\n console.log('');\n printCard('Next Steps', formatCommandLines(nextStepCommands));\n\n if (selection.databaseMode === 'postgres-psql') {\n const setupLines = buildPsqlSetupLines(selection, platform);\n\n console.log('');\n printCard('Postgres Setup', setupLines);\n }\n}\n\nexport function formatTargetPath(targetDir: string): string {\n const relative = path.relative(process.cwd(), targetDir);\n return relative || '.';\n}\n","import type {\n Architecture,\n DatabaseMode,\n JsDevWatcher,\n Language,\n ModuleSystem,\n} from './types.js';\n\nexport function languageLabel(language: Language): string {\n return language === 'ts' ? 'TypeScript' : 'JavaScript';\n}\n\nexport function moduleSystemLabel(moduleSystem: ModuleSystem): string {\n return moduleSystem === 'esm' ? 'ES Modules' : 'CommonJS';\n}\n\nexport function jsDevWatcherLabel(jsDevWatcher: JsDevWatcher): string {\n return jsDevWatcher === 'nodemon' ? 'nodemon' : 'node --watch';\n}\n\nexport function architectureLabel(architecture: Architecture): string {\n return architecture === 'mvc' ? 'MVC' : 'Simple';\n}\n\nexport function databaseLabel(databaseMode: DatabaseMode): string {\n if (databaseMode === 'postgres-psql') {\n return 'Postgres (psql)';\n }\n\n if (databaseMode === 'postgres-docker') {\n return 'Postgres (Docker)';\n }\n\n return 'In-memory';\n}\n","export function toDatabaseName(projectName: string): string {\n const cleaned = projectName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+/, '')\n .replace(/_+$/, '');\n\n return (cleaned || 'express_api') + '_dev';\n}\n","import pc from 'picocolors';\n\ntype StatusTone = 'info' | 'success' | 'warn' | 'error';\ntype ValueTone = 'default' | 'accent' | 'success' | 'warn' | 'muted';\n\nconst ANSI_PATTERN = /\\u001b\\[[0-9;]*m/g;\n\nfunction stripAnsi(value: string): string {\n return value.replace(ANSI_PATTERN, '');\n}\n\nfunction displayLength(value: string): number {\n return stripAnsi(value).length;\n}\n\nfunction padDisplay(value: string, width: number): string {\n const padding = width - displayLength(value);\n if (padding <= 0) {\n return value;\n }\n\n return `${value}${' '.repeat(padding)}`;\n}\n\nfunction minimumContentWidth(lines: string[]): number {\n return lines.reduce((max, line) => {\n return Math.max(max, displayLength(line));\n }, 0);\n}\n\nfunction styleValue(value: string, tone: ValueTone): string {\n if (tone === 'accent') {\n return pc.cyan(value);\n }\n\n if (tone === 'success') {\n return pc.green(value);\n }\n\n if (tone === 'warn') {\n return pc.yellow(value);\n }\n\n if (tone === 'muted') {\n return pc.dim(value);\n }\n\n return value;\n}\n\nexport function statusTag(tone: StatusTone): string {\n if (tone === 'success') {\n return pc.bold(pc.green('[ok]'));\n }\n\n if (tone === 'warn') {\n return pc.bold(pc.yellow('[!!]'));\n }\n\n if (tone === 'error') {\n return pc.bold(pc.red('[x]'));\n }\n\n return pc.bold(pc.cyan('[..]'));\n}\n\ninterface KeyValueRow {\n key: string;\n value: string;\n tone?: ValueTone;\n}\n\nexport function formatKeyValueLines(rows: KeyValueRow[]): string[] {\n const keyWidth = rows.reduce((max, row) => Math.max(max, row.key.length), 0);\n\n return rows.map((row) => {\n const key = pc.bold(padDisplay(row.key, keyWidth));\n const value = styleValue(row.value, row.tone ?? 'default');\n return `${key} ${value}`;\n });\n}\n\nexport function formatCommandLines(commands: string[]): string[] {\n return commands.map((command) => pc.bold(pc.cyan(command)));\n}\n\nexport function printCard(title: string, lines: string[]): void {\n const content = lines.length > 0 ? lines : [pc.dim('(none)')];\n const width = Math.max(30, minimumContentWidth([title, ...content]));\n\n const border = pc.dim(pc.cyan(`+${'-'.repeat(width + 2)}+`));\n const edge = pc.dim(pc.cyan('|'));\n const divider = pc.dim('-'.repeat(width));\n\n console.log(border);\n console.log(\n `${edge} ${padDisplay(pc.bold(pc.cyan(title)), width)} ${edge}`,\n );\n console.log(`${edge} ${divider} ${edge}`);\n\n for (const line of content) {\n console.log(`${edge} ${padDisplay(line, width)} ${edge}`);\n }\n\n console.log(border);\n}\n","import {\n confirm,\n intro,\n isCancel,\n outro,\n select,\n text\n} from '@clack/prompts';\nimport pc from 'picocolors';\n\nimport { DEFAULT_PROJECT_NAME, DEFAULT_SELECTIONS } from '../core/defaults.js';\nimport type { ParsedArgs, UserSelections } from '../core/types.js';\n\nexport class PromptCancelledError extends Error {\n constructor() {\n super('Prompt cancelled by user.');\n }\n}\n\nfunction unwrapPrompt<T>(value: T | symbol): T {\n if (isCancel(value)) {\n throw new PromptCancelledError();\n }\n\n return value as T;\n}\n\nexport async function collectSelections(parsedArgs: ParsedArgs): Promise<UserSelections> {\n if (parsedArgs.flags.yes || !process.stdin.isTTY) {\n return {\n projectName: parsedArgs.projectName ?? DEFAULT_PROJECT_NAME,\n language: DEFAULT_SELECTIONS.language,\n moduleSystem: DEFAULT_SELECTIONS.moduleSystem,\n jsDevWatcher: DEFAULT_SELECTIONS.jsDevWatcher,\n architecture: DEFAULT_SELECTIONS.architecture,\n databaseMode: DEFAULT_SELECTIONS.databaseMode,\n educational: DEFAULT_SELECTIONS.educational,\n installDeps: parsedArgs.flags.install,\n initGit: parsedArgs.flags.git,\n dryRun: parsedArgs.flags.dryRun\n };\n }\n\n intro(\n [\n pc.bold(pc.cyan('Create Express API Starter')),\n pc.dim('Scaffold an Express backend with practical defaults.')\n ].join('\\n')\n );\n\n const projectName = parsedArgs.projectName\n ? parsedArgs.projectName\n : unwrapPrompt(\n await text({\n message: 'Project name',\n placeholder: DEFAULT_PROJECT_NAME,\n defaultValue: DEFAULT_PROJECT_NAME,\n validate(value) {\n if (!value.trim()) {\n return 'Project name is required.';\n }\n\n return undefined;\n }\n })\n );\n\n const language = unwrapPrompt(\n await select({\n message: 'Language',\n initialValue: DEFAULT_SELECTIONS.language,\n options: [\n {\n value: 'js',\n label: 'JavaScript'\n },\n {\n value: 'ts',\n label: 'TypeScript'\n }\n ]\n })\n ) as UserSelections['language'];\n\n const moduleSystem =\n language === 'js'\n ? (unwrapPrompt(\n await select({\n message: 'Module system',\n initialValue: DEFAULT_SELECTIONS.moduleSystem,\n options: [\n {\n value: 'commonjs',\n label: 'CommonJS'\n },\n {\n value: 'esm',\n label: 'ES Modules'\n }\n ]\n })\n ) as UserSelections['moduleSystem'])\n : 'commonjs';\n\n const jsDevWatcher =\n language === 'js'\n ? (unwrapPrompt(\n await select({\n message: 'Dev watcher (JavaScript)',\n initialValue: DEFAULT_SELECTIONS.jsDevWatcher,\n options: [\n {\n value: 'node-watch',\n label: 'node --watch (built-in)'\n },\n {\n value: 'nodemon',\n label: 'nodemon'\n }\n ]\n })\n ) as UserSelections['jsDevWatcher'])\n : DEFAULT_SELECTIONS.jsDevWatcher;\n\n const architecture = unwrapPrompt(\n await select({\n message: 'Architecture',\n initialValue: DEFAULT_SELECTIONS.architecture,\n options: [\n {\n value: 'simple',\n label: 'Simple'\n },\n {\n value: 'mvc',\n label: 'MVC'\n }\n ]\n })\n ) as UserSelections['architecture'];\n\n const databaseMode = unwrapPrompt(\n await select({\n message: 'Database',\n initialValue: DEFAULT_SELECTIONS.databaseMode,\n options: [\n {\n value: 'memory',\n label: 'In-memory'\n },\n {\n value: 'postgres-psql',\n label: 'Postgres (psql)'\n },\n {\n value: 'postgres-docker',\n label: 'Postgres (Docker)'\n }\n ]\n })\n ) as UserSelections['databaseMode'];\n\n const educational = unwrapPrompt(\n await confirm({\n message: 'Add educational comments',\n initialValue: DEFAULT_SELECTIONS.educational\n })\n );\n\n const installDeps = parsedArgs.provided.install\n ? parsedArgs.flags.install\n : unwrapPrompt(\n await confirm({\n message: 'Install dependencies now',\n initialValue: DEFAULT_SELECTIONS.installDeps\n })\n );\n\n const initGit = parsedArgs.provided.git\n ? parsedArgs.flags.git\n : unwrapPrompt(\n await confirm({\n message: 'Initialize git repository',\n initialValue: DEFAULT_SELECTIONS.initGit\n })\n );\n\n outro(pc.cyan('Scaffolding project files...'));\n\n return {\n projectName,\n language,\n moduleSystem,\n jsDevWatcher,\n architecture,\n databaseMode,\n educational,\n installDeps,\n initGit,\n dryRun: parsedArgs.flags.dryRun\n };\n}\n","import type { UserSelections } from './types.js';\n\nexport const DEFAULT_PROJECT_NAME = 'my-api';\n\nexport const DEFAULT_SELECTIONS: Omit<UserSelections, 'projectName' | 'dryRun'> = {\n language: 'js',\n moduleSystem: 'commonjs',\n jsDevWatcher: 'node-watch',\n architecture: 'simple',\n databaseMode: 'memory',\n educational: true,\n installDeps: true,\n initGit: true\n};\n","import path from 'node:path';\n\nexport function validateProjectName(projectName: string): string | null {\n const trimmed = projectName.trim();\n\n if (!trimmed) {\n return 'Project name is required.';\n }\n\n if (trimmed === '.' || trimmed === '..') {\n return 'Project name cannot be \".\" or \"..\".';\n }\n\n if (trimmed !== path.basename(trimmed)) {\n return 'Project name must be a folder name, not a path.';\n }\n\n if (/[^a-zA-Z0-9._-]/.test(trimmed)) {\n return 'Project name can only include letters, numbers, \".\", \"_\", and \"-\".';\n }\n\n return null;\n}\n","import path from 'node:path';\nimport os from 'node:os';\nimport fs from 'fs-extra';\nimport ejs from 'ejs';\n\nimport {\n architectureLabel,\n databaseLabel,\n jsDevWatcherLabel,\n languageLabel,\n moduleSystemLabel,\n} from '../core/labels.js';\nimport { toDatabaseName } from '../core/naming.js';\nimport type {\n GenerationPlan,\n PlannedFile,\n TemplateConfig,\n} from '../core/types.js';\nimport { resolveTemplatesDir } from '../utils/paths.js';\n\ninterface GenerateProjectInput {\n config: TemplateConfig;\n targetDir: string;\n dryRun?: boolean;\n}\n\nfunction toPosixPath(value: string): string {\n return value.split(path.sep).join('/');\n}\n\nfunction isEjsTemplate(relativePath: string): boolean {\n return relativePath.endsWith('.ejs');\n}\n\nfunction stripEjsSuffix(relativePath: string): string {\n return relativePath.endsWith('.ejs')\n ? relativePath.slice(0, -'.ejs'.length)\n : relativePath;\n}\n\nfunction resolveTemplateRoots(config: TemplateConfig): string[] {\n const templatesDir = resolveTemplatesDir();\n\n if (config.language === 'ts') {\n return [\n path.join(templatesDir, 'ts', 'shared'),\n path.join(templatesDir, 'ts', config.architecture),\n ];\n }\n\n return [path.join(templatesDir, config.language, config.architecture)];\n}\n\nasync function listFilesRecursive(\n directory: string,\n baseDir: string = directory,\n): Promise<string[]> {\n const entries = await fs.readdir(directory, {\n withFileTypes: true,\n });\n\n const sortedEntries = entries.sort((a, b) => a.name.localeCompare(b.name));\n const results: string[] = [];\n\n for (const entry of sortedEntries) {\n const entryPath = path.join(directory, entry.name);\n\n if (entry.isDirectory()) {\n const childEntries = await listFilesRecursive(entryPath, baseDir);\n results.push(...childEntries);\n continue;\n }\n\n results.push(path.relative(baseDir, entryPath));\n }\n\n return results;\n}\n\nfunction shouldIncludeTemplate(\n relativePath: string,\n config: TemplateConfig,\n): boolean {\n if (relativePath === 'compose.yaml.ejs') {\n return config.databaseMode === 'postgres-docker';\n }\n\n if (relativePath === 'scripts/dbCreate.js.ejs') {\n return config.databaseMode === 'postgres-psql';\n }\n\n if (relativePath.startsWith('scripts/')) {\n return config.databaseMode !== 'memory';\n }\n\n if (relativePath.startsWith('db/')) {\n return config.databaseMode !== 'memory';\n }\n\n if (relativePath.startsWith('src/db/')) {\n return config.databaseMode !== 'memory';\n }\n\n return true;\n}\n\nfunction toPlannedFile(\n sourcePath: string,\n relativeTemplatePath: string,\n): PlannedFile {\n return {\n templateSourcePath: sourcePath,\n templateRelativePath: relativeTemplatePath,\n outputRelativePath: stripEjsSuffix(relativeTemplatePath),\n isTemplate: isEjsTemplate(relativeTemplatePath),\n };\n}\n\nfunction toPackageName(projectName: string): string {\n const cleaned = projectName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+/, '')\n .replace(/-+$/, '');\n\n return cleaned || 'express-api';\n}\n\nfunction getOsUsername(): string {\n try {\n return os.userInfo().username;\n } catch {\n return process.env.USER ?? process.env.USERNAME ?? 'postgres';\n }\n}\n\nfunction templateData(config: TemplateConfig): Record<string, unknown> {\n const isTypeScript = config.language === 'ts';\n const isEsm = config.moduleSystem === 'esm';\n const isJavaScript = config.language === 'js';\n const useNodemon = isJavaScript && config.jsDevWatcher === 'nodemon';\n const isPostgres = config.databaseMode !== 'memory';\n const isDocker = config.databaseMode === 'postgres-docker';\n const isPsql = config.databaseMode === 'postgres-psql';\n const dbName = toDatabaseName(config.projectName);\n const username = isPostgres ? getOsUsername() : '';\n\n return {\n ...config,\n isTypeScript,\n isEsm,\n isCommonJs: !isEsm,\n isPostgres,\n isDocker,\n isPsql,\n packageName: toPackageName(config.projectName),\n databaseName: dbName,\n educationalLabel: config.educational ? 'On' : 'Off',\n languageLabel: languageLabel(config.language),\n moduleSystemLabel: moduleSystemLabel(config.moduleSystem),\n architectureLabel: architectureLabel(config.architecture),\n databaseLabel: databaseLabel(config.databaseMode),\n jsDevWatcherLabel: jsDevWatcherLabel(config.jsDevWatcher),\n jsDevCommand: useNodemon\n ? 'nodemon src/server.js'\n : 'node --watch src/server.js',\n useNodemon,\n databaseUrl:\n config.databaseMode === 'postgres-docker'\n ? `postgres://postgres:postgres@localhost:5433/${dbName}`\n : `postgres://${encodeURIComponent(username)}:postgres@localhost:5432/${dbName}`,\n osUsername: username,\n };\n}\n\nfunction fromPosixPath(relativePath: string): string {\n return relativePath.split('/').join(path.sep);\n}\n\nexport async function planProject(\n config: TemplateConfig,\n targetDir: string,\n): Promise<GenerationPlan> {\n const templateRoots = resolveTemplateRoots(config);\n\n for (const templateRoot of templateRoots) {\n const templateRootExists = await fs.pathExists(templateRoot);\n\n if (!templateRootExists) {\n throw new Error(`Template root not found: ${templateRoot}`);\n }\n }\n\n const templateFiles = new Map<string, string>();\n\n for (const templateRoot of templateRoots) {\n const allFiles = await listFilesRecursive(templateRoot);\n\n for (const file of allFiles) {\n const relativePath = toPosixPath(file);\n const sourcePath = path.join(templateRoot, fromPosixPath(relativePath));\n templateFiles.set(relativePath, sourcePath);\n }\n }\n\n const files = Array.from(templateFiles.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .filter(([relativePath]) => shouldIncludeTemplate(relativePath, config))\n .map(([relativePath, sourcePath]) => toPlannedFile(sourcePath, relativePath));\n\n return {\n targetDir,\n actions: [\n `Create project directory: ${targetDir}`,\n `Write ${files.length} files`,\n ],\n files,\n };\n}\n\nexport async function generateProject({\n config,\n targetDir,\n dryRun = false,\n}: GenerateProjectInput): Promise<GenerationPlan> {\n const plan = await planProject(config, targetDir);\n\n if (dryRun) {\n return plan;\n }\n\n await fs.ensureDir(targetDir);\n\n const data = templateData(config);\n\n for (const file of plan.files) {\n const destinationPath = path.join(\n targetDir,\n fromPosixPath(file.outputRelativePath),\n );\n\n await fs.ensureDir(path.dirname(destinationPath));\n\n if (file.isTemplate) {\n const template = await fs.readFile(file.templateSourcePath, 'utf8');\n const rendered = ejs.render(template, data);\n await fs.writeFile(destinationPath, rendered, 'utf8');\n continue;\n }\n\n await fs.copy(file.templateSourcePath, destinationPath);\n }\n\n return plan;\n}\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport fs from 'fs-extra';\n\nexport function resolveTargetDir(baseDir: string, projectName: string): string {\n return path.resolve(baseDir, projectName);\n}\n\nexport function resolveTemplatesDir(): string {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n\n const candidates = [\n path.resolve(moduleDir, '../templates'),\n path.resolve(moduleDir, '../../templates'),\n path.resolve(process.cwd(), 'templates')\n ];\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error('Unable to locate templates directory.');\n}\n","import { execa } from 'execa';\n\nexport async function commandExists(command: string, args: string[] = ['--version']): Promise<boolean> {\n try {\n await execa(command, args, {\n stdio: 'ignore'\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runCommand(command: string, args: string[], cwd: string): Promise<void> {\n await execa(command, args, {\n cwd,\n stdio: 'inherit'\n });\n}\n\nexport async function installDependencies(cwd: string, verbose = false): Promise<void> {\n const args = ['install', '--no-audit', '--no-fund'];\n\n if (!verbose) {\n args.push('--loglevel=error');\n }\n\n await runCommand('npm', args, cwd);\n}\n\nexport async function initGitRepo(cwd: string): Promise<void> {\n await runCommand('git', ['init'], cwd);\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\n\nexport async function assertSafeTargetDir(targetDir: string): Promise<void> {\n const exists = await fs.pathExists(targetDir);\n\n if (!exists) {\n return;\n }\n\n const stats = await fs.stat(targetDir);\n\n if (!stats.isDirectory()) {\n throw new Error(`Target path already exists and is not a directory: ${targetDir}`);\n }\n\n const entries = await fs.readdir(targetDir);\n if (entries.length > 0) {\n throw new Error(\n `Target directory \"${path.basename(targetDir)}\" already exists and is not empty.`\n );\n }\n}\n","import { statusTag } from './terminalUi.js';\n\nexport const logger = {\n info(message: string): void {\n console.log(`${statusTag('info')} ${message}`);\n },\n success(message: string): void {\n console.log(`${statusTag('success')} ${message}`);\n },\n warn(message: string): void {\n console.warn(`${statusTag('warn')} ${message}`);\n },\n error(message: string): void {\n console.error(`${statusTag('error')} ${message}`);\n }\n};\n"],"mappings":"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","names":["pc","fs","path","fileURLToPath","pc","pc","pc","pc","path","path","fs","path","path","fs","path","fs","path","fs","fileURLToPath","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/index.ts","../src/cli/args.ts","../src/cli/output.ts","../src/core/labels.ts","../src/core/naming.ts","../src/utils/terminalUi.ts","../src/cli/prompts.ts","../src/core/defaults.ts","../src/core/validation.ts","../src/generator/index.ts","../src/utils/paths.ts","../src/utils/exec.ts","../src/utils/files.ts","../src/utils/logger.ts"],"sourcesContent":["import pc from 'picocolors';\nimport { pathToFileURL } from 'node:url';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { parseArgs } from './args.js';\nimport { printDryRunPlan, printNextSteps } from './output.js';\nimport { collectSelections, PromptCancelledError } from './prompts.js';\nimport type { PackageManager } from '../core/types.js';\nimport { validateProjectName } from '../core/validation.js';\nimport { generateProject, planProject } from '../generator/index.js';\nimport {\n commandExists,\n formatInstallCommand,\n initGitRepo,\n installDependencies,\n} from '../utils/exec.js';\nimport { assertSafeTargetDir } from '../utils/files.js';\nimport { logger } from '../utils/logger.js';\nimport { resolveTargetDir } from '../utils/paths.js';\n\nasync function ensurePsqlAvailable(): Promise<void> {\n const hasPsql = await commandExists('psql', ['--version']);\n\n if (!hasPsql) {\n throw new Error(\n [\n 'Postgres (psql) mode requires the `psql` client tool, but it was not found.',\n 'Install Postgres client tools and make sure `psql --version` works, or rerun and choose Postgres (Docker).'\n ].join(' ')\n );\n }\n}\n\nasync function ensurePackageManagerAvailable(packageManager: PackageManager): Promise<void> {\n const hasPackageManager = await commandExists(packageManager, ['--version']);\n\n if (!hasPackageManager) {\n throw new Error(\n [\n `Package manager \"${packageManager}\" was selected, but it was not found.`,\n `Install ${packageManager} or rerun with --package-manager=npm.`\n ].join(' ')\n );\n }\n}\n\nfunction registerSigintHandler(): void {\n process.on('SIGINT', () => {\n logger.warn('Cancelled by user.');\n process.exit(1);\n });\n}\n\nasync function runCli(argv: string[]): Promise<void> {\n const parsedArgs = parseArgs(argv);\n\n for (const unknownFlag of parsedArgs.unknownFlags) {\n logger.warn(`Unknown flag \"${unknownFlag}\" was ignored.`);\n }\n\n const selections = await collectSelections(parsedArgs);\n\n const projectNameError = validateProjectName(selections.projectName);\n\n if (projectNameError) {\n throw new Error(projectNameError);\n }\n\n const targetDir = resolveTargetDir(process.cwd(), selections.projectName);\n\n await assertSafeTargetDir(targetDir);\n\n if (selections.databaseMode === 'postgres-psql') {\n await ensurePsqlAvailable();\n }\n\n const templateConfig = {\n projectName: selections.projectName,\n language: selections.language,\n moduleSystem: selections.moduleSystem,\n jsDevWatcher: selections.jsDevWatcher,\n architecture: selections.architecture,\n educational: selections.educational,\n databaseMode: selections.databaseMode\n };\n\n const plan = await planProject(templateConfig, targetDir);\n\n if (selections.dryRun) {\n printDryRunPlan(selections, plan);\n return;\n }\n\n await generateProject({\n config: templateConfig,\n targetDir\n });\n\n const packageJsonPath = path.join(targetDir, 'package.json');\n if (!fs.existsSync(packageJsonPath)) {\n throw new Error(\n [\n 'Project generation did not produce package.json.',\n 'This can happen if the installed CLI/templates are out of sync.',\n 'Reinstall the latest package version and try again.'\n ].join(' ')\n );\n }\n\n logger.success(`Project files generated at ${targetDir}.`);\n\n if (selections.installDeps) {\n await ensurePackageManagerAvailable(selections.packageManager);\n\n const installCommand = formatInstallCommand(\n selections.packageManager,\n parsedArgs.flags.verbose\n );\n logger.info(`Installing dependencies (${installCommand})...`);\n await installDependencies(targetDir, selections.packageManager, parsedArgs.flags.verbose);\n logger.success('Dependencies installed.');\n } else {\n logger.info('Skipped dependency installation.');\n }\n\n if (selections.initGit) {\n logger.info('Initializing git repository...');\n await initGitRepo(targetDir);\n logger.success('Git repository initialized.');\n } else {\n logger.info('Skipped git initialization.');\n }\n\n logger.success('Scaffolding complete.');\n printNextSteps(selections);\n}\n\nfunction isCliEntrypoint(): boolean {\n if (typeof process.argv[1] !== 'string') {\n return false;\n }\n\n try {\n const argvPath = fs.realpathSync(process.argv[1]);\n const modulePath = fs.realpathSync(fileURLToPath(import.meta.url));\n return argvPath === modulePath;\n } catch {\n return pathToFileURL(process.argv[1]).href === import.meta.url;\n }\n}\n\nconst isEntrypoint = isCliEntrypoint();\n\nif (isEntrypoint) {\n registerSigintHandler();\n\n runCli(process.argv.slice(2)).catch((error: unknown) => {\n if (error instanceof PromptCancelledError) {\n logger.warn('Cancelled by user.');\n process.exit(1);\n }\n\n const message = error instanceof Error ? error.message : 'Unexpected error';\n logger.error(message);\n if (error instanceof Error && error.stack) {\n console.error(pc.gray(error.stack));\n }\n process.exit(1);\n });\n}\n\nexport { runCli };\n","import type { PackageManager, ParsedArgs } from '../core/types.js';\n\nconst TRUE_VALUES = new Set(['1', 'true', 'yes', 'on']);\nconst FALSE_VALUES = new Set(['0', 'false', 'no', 'off']);\n\nfunction parseBooleanValue(value: string | undefined): boolean | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const normalized = value.trim().toLowerCase();\n\n if (TRUE_VALUES.has(normalized)) {\n return true;\n }\n\n if (FALSE_VALUES.has(normalized)) {\n return false;\n }\n\n return undefined;\n}\n\nfunction parsePackageManagerValue(value: string | undefined): PackageManager | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const normalized = value.trim().toLowerCase();\n\n if (normalized === 'npm' || normalized === 'yarn') {\n return normalized;\n }\n\n return undefined;\n}\n\nfunction splitFlag(token: string): { name: string; value: string | undefined } {\n const withoutPrefix = token.slice(2);\n const equalsIndex = withoutPrefix.indexOf('=');\n\n if (equalsIndex === -1) {\n return {\n name: withoutPrefix,\n value: undefined\n };\n }\n\n return {\n name: withoutPrefix.slice(0, equalsIndex),\n value: withoutPrefix.slice(equalsIndex + 1)\n };\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const flags = {\n yes: false,\n dryRun: false,\n install: true,\n git: true,\n verbose: false,\n packageManager: 'npm' as PackageManager\n };\n\n const provided = {\n yes: false,\n dryRun: false,\n install: false,\n git: false,\n verbose: false,\n packageManager: false\n };\n\n const unknownFlags: string[] = [];\n const positionals: string[] = [];\n\n let positionalOnly = false;\n\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n\n if (positionalOnly) {\n positionals.push(token);\n continue;\n }\n\n if (token === '--') {\n positionalOnly = true;\n continue;\n }\n\n if (!token.startsWith('-') || token === '-') {\n positionals.push(token);\n continue;\n }\n\n if (!token.startsWith('--')) {\n unknownFlags.push(token);\n continue;\n }\n\n const { name, value } = splitFlag(token);\n\n if (name === 'yes') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n flags.yes = parsedValue ?? true;\n provided.yes = true;\n continue;\n }\n\n if (name === 'dry-run') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n flags.dryRun = parsedValue ?? true;\n provided.dryRun = true;\n continue;\n }\n\n if (name === 'no-install') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n const noInstall = parsedValue ?? true;\n flags.install = !noInstall;\n provided.install = true;\n continue;\n }\n\n if (name === 'no-git') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n const noGit = parsedValue ?? true;\n flags.git = !noGit;\n provided.git = true;\n continue;\n }\n\n if (name === 'verbose') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n flags.verbose = parsedValue ?? true;\n provided.verbose = true;\n continue;\n }\n\n if (name === 'package-manager' || name === 'pm') {\n let rawValue = value;\n\n if (rawValue === undefined) {\n const nextToken = argv[index + 1];\n\n if (nextToken !== undefined && !nextToken.startsWith('-')) {\n const parsedNextToken = parsePackageManagerValue(nextToken);\n\n if (parsedNextToken !== undefined) {\n rawValue = nextToken;\n index += 1;\n }\n }\n }\n\n const packageManager = parsePackageManagerValue(rawValue);\n if (packageManager === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n flags.packageManager = packageManager;\n provided.packageManager = true;\n continue;\n }\n\n if (name === 'yarn') {\n const parsedValue = parseBooleanValue(value);\n if (value !== undefined && parsedValue === undefined) {\n unknownFlags.push(token);\n continue;\n }\n\n const useYarn = parsedValue ?? true;\n flags.packageManager = useYarn ? 'yarn' : 'npm';\n provided.packageManager = true;\n continue;\n }\n\n unknownFlags.push(token);\n }\n\n return {\n projectName: positionals[0],\n positionals,\n unknownFlags,\n flags,\n provided\n };\n}\n","import path from 'node:path';\nimport pc from 'picocolors';\n\nimport {\n architectureLabel,\n databaseLabel,\n jsDevWatcherLabel,\n languageLabel,\n moduleSystemLabel,\n packageManagerLabel,\n} from '../core/labels.js';\nimport { toDatabaseName } from '../core/naming.js';\nimport type { GenerationPlan, UserSelections } from '../core/types.js';\nimport {\n formatCommandLines,\n formatKeyValueLines,\n printCard,\n} from '../utils/terminalUi.js';\n\nfunction installCommand(selection: UserSelections): string {\n return `${selection.packageManager} install`;\n}\n\nfunction scriptCommand(selection: UserSelections, script: string): string {\n if (selection.packageManager === 'yarn') {\n return `yarn ${script}`;\n }\n\n if (script === 'test') {\n return 'npm test';\n }\n\n return `npm run ${script}`;\n}\n\nfunction buildNextStepCommands(selection: UserSelections): string[] {\n const commands = [`cd ${selection.projectName}`];\n\n if (!selection.installDeps) {\n commands.push(installCommand(selection));\n }\n\n commands.push('cp .env.example .env');\n\n if (selection.databaseMode === 'postgres-psql') {\n commands.push(scriptCommand(selection, 'db:create'));\n commands.push(scriptCommand(selection, 'db:setup'));\n commands.push(scriptCommand(selection, 'db:seed'));\n }\n\n if (selection.databaseMode === 'postgres-docker') {\n commands.push(scriptCommand(selection, 'db:up'));\n commands.push(scriptCommand(selection, 'db:setup'));\n commands.push(scriptCommand(selection, 'db:seed'));\n }\n\n commands.push(scriptCommand(selection, 'dev'));\n\n if (selection.language === 'ts') {\n commands.push(scriptCommand(selection, 'build'));\n }\n\n commands.push(scriptCommand(selection, 'test'));\n\n return commands;\n}\n\nfunction buildPsqlSetupLines(\n selection: UserSelections,\n platform: NodeJS.Platform,\n): string[] {\n const databaseName = toDatabaseName(selection.projectName);\n\n if (platform === 'win32') {\n return [\n pc.yellow('Windows first-time setup (run once if needed):'),\n pc.dim('# Edit .env and use the role/password from the PostgreSQL installer'),\n ...formatCommandLines([\n `DATABASE_URL=postgres://postgres:<your-password>@localhost:5432/${databaseName}`,\n ]),\n pc.dim('# Then run the db scripts below:'),\n ...formatCommandLines([scriptCommand(selection, 'db:create')]),\n ];\n }\n\n if (platform === 'darwin') {\n return [\n pc.yellow('macOS first-time setup (run once if needed):'),\n pc.dim('# Homebrew installs often already create a role for your OS user'),\n pc.dim('# Run these only if you get a role/auth error'),\n ...formatCommandLines([\n 'createuser --createdb \"$USER\"',\n `psql -d postgres -c \"ALTER USER \\\\\"$USER\\\\\" WITH PASSWORD 'postgres';\"`,\n ]),\n ];\n }\n\n return [\n pc.yellow('Linux first-time setup (run once if needed):'),\n pc.dim('# Create a Postgres role matching your OS user'),\n ...formatCommandLines([\n 'sudo -u postgres createuser --createdb \"$USER\"',\n `sudo -u postgres psql -c \"ALTER USER \\\\\"$USER\\\\\" WITH PASSWORD 'postgres';\"`,\n ]),\n ];\n}\n\nexport function printDryRunPlan(\n selection: UserSelections,\n plan: GenerationPlan,\n): void {\n const languageValue =\n selection.language === 'js'\n ? `${languageLabel(selection.language)} (${moduleSystemLabel(selection.moduleSystem)})`\n : languageLabel(selection.language);\n\n const summaryEntries: Parameters<typeof formatKeyValueLines>[0] = [\n {\n key: 'Target',\n value: formatTargetPath(plan.targetDir),\n tone: 'accent',\n },\n {\n key: 'Language',\n value: languageValue,\n tone: 'accent',\n },\n {\n key: 'Architecture',\n value: architectureLabel(selection.architecture),\n tone: 'accent',\n },\n {\n key: 'Database',\n value: databaseLabel(selection.databaseMode),\n tone: 'accent',\n },\n ];\n\n if (selection.language === 'js') {\n summaryEntries.push({\n key: 'Dev watcher',\n value: jsDevWatcherLabel(selection.jsDevWatcher),\n tone: 'accent',\n });\n }\n\n summaryEntries.push(\n {\n key: 'Educational',\n value: selection.educational ? 'On' : 'Off',\n tone: selection.educational ? 'success' : 'muted',\n },\n {\n key: 'Install deps',\n value: selection.installDeps ? 'Yes' : 'No',\n tone: selection.installDeps ? 'success' : 'warn',\n },\n {\n key: 'Package manager',\n value: packageManagerLabel(selection.packageManager),\n tone: 'accent',\n },\n {\n key: 'Init git',\n value: selection.initGit ? 'Yes' : 'No',\n tone: selection.initGit ? 'success' : 'warn',\n },\n );\n\n const summaryLines = formatKeyValueLines(summaryEntries);\n\n const fileLines = plan.files.map((file) => `${pc.dim('-')} ${file.outputRelativePath}`);\n\n console.log('');\n printCard('Dry Run: Configuration', summaryLines);\n console.log('');\n printCard(`Dry Run: Files (${plan.files.length})`, fileLines);\n}\n\nexport function printNextSteps(\n selection: UserSelections,\n platform: NodeJS.Platform = process.platform,\n): void {\n const stackParts = [\n selection.language === 'js'\n ? `${languageLabel(selection.language)} (${moduleSystemLabel(selection.moduleSystem)})`\n : languageLabel(selection.language),\n architectureLabel(selection.architecture),\n databaseLabel(selection.databaseMode),\n ];\n\n const summaryEntries: Parameters<typeof formatKeyValueLines>[0] = [\n {\n key: 'Project',\n value: selection.projectName,\n tone: 'accent',\n },\n {\n key: 'Stack',\n value: stackParts.join(' | '),\n tone: 'accent',\n },\n {\n key: 'Educational',\n value: selection.educational ? 'On' : 'Off',\n tone: selection.educational ? 'success' : 'muted',\n },\n {\n key: 'Package manager',\n value: packageManagerLabel(selection.packageManager),\n tone: 'accent',\n },\n ];\n\n if (selection.language === 'js') {\n summaryEntries.push({\n key: 'Dev watcher',\n value: jsDevWatcherLabel(selection.jsDevWatcher),\n tone: 'accent',\n });\n }\n\n const summaryLines = formatKeyValueLines(summaryEntries);\n\n const nextStepCommands = buildNextStepCommands(selection);\n\n console.log('');\n printCard('Project Ready', summaryLines);\n console.log('');\n printCard('Next Steps', formatCommandLines(nextStepCommands));\n\n if (selection.databaseMode === 'postgres-psql') {\n const setupLines = buildPsqlSetupLines(selection, platform);\n\n console.log('');\n printCard('Postgres Setup', setupLines);\n }\n}\n\nexport function formatTargetPath(targetDir: string): string {\n const relative = path.relative(process.cwd(), targetDir);\n return relative || '.';\n}\n","import type {\n Architecture,\n DatabaseMode,\n JsDevWatcher,\n Language,\n ModuleSystem,\n PackageManager,\n} from './types.js';\n\nexport function languageLabel(language: Language): string {\n return language === 'ts' ? 'TypeScript' : 'JavaScript';\n}\n\nexport function moduleSystemLabel(moduleSystem: ModuleSystem): string {\n return moduleSystem === 'esm' ? 'ES Modules' : 'CommonJS';\n}\n\nexport function jsDevWatcherLabel(jsDevWatcher: JsDevWatcher): string {\n return jsDevWatcher === 'nodemon' ? 'nodemon' : 'node --watch';\n}\n\nexport function architectureLabel(architecture: Architecture): string {\n return architecture === 'mvc' ? 'MVC' : 'Simple';\n}\n\nexport function databaseLabel(databaseMode: DatabaseMode): string {\n if (databaseMode === 'postgres-psql') {\n return 'Postgres (psql)';\n }\n\n if (databaseMode === 'postgres-docker') {\n return 'Postgres (Docker)';\n }\n\n return 'In-memory';\n}\n\nexport function packageManagerLabel(packageManager: PackageManager): string {\n return packageManager === 'yarn' ? 'Yarn' : 'npm';\n}\n","export function toDatabaseName(projectName: string): string {\n const cleaned = projectName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+/, '')\n .replace(/_+$/, '');\n\n return (cleaned || 'express_api') + '_dev';\n}\n","import pc from 'picocolors';\n\ntype StatusTone = 'info' | 'success' | 'warn' | 'error';\ntype ValueTone = 'default' | 'accent' | 'success' | 'warn' | 'muted';\n\nconst ANSI_PATTERN = /\\u001b\\[[0-9;]*m/g;\n\nfunction stripAnsi(value: string): string {\n return value.replace(ANSI_PATTERN, '');\n}\n\nfunction displayLength(value: string): number {\n return stripAnsi(value).length;\n}\n\nfunction padDisplay(value: string, width: number): string {\n const padding = width - displayLength(value);\n if (padding <= 0) {\n return value;\n }\n\n return `${value}${' '.repeat(padding)}`;\n}\n\nfunction minimumContentWidth(lines: string[]): number {\n return lines.reduce((max, line) => {\n return Math.max(max, displayLength(line));\n }, 0);\n}\n\nfunction styleValue(value: string, tone: ValueTone): string {\n if (tone === 'accent') {\n return pc.cyan(value);\n }\n\n if (tone === 'success') {\n return pc.green(value);\n }\n\n if (tone === 'warn') {\n return pc.yellow(value);\n }\n\n if (tone === 'muted') {\n return pc.dim(value);\n }\n\n return value;\n}\n\nexport function statusTag(tone: StatusTone): string {\n if (tone === 'success') {\n return pc.bold(pc.green('[ok]'));\n }\n\n if (tone === 'warn') {\n return pc.bold(pc.yellow('[!!]'));\n }\n\n if (tone === 'error') {\n return pc.bold(pc.red('[x]'));\n }\n\n return pc.bold(pc.cyan('[..]'));\n}\n\ninterface KeyValueRow {\n key: string;\n value: string;\n tone?: ValueTone;\n}\n\nexport function formatKeyValueLines(rows: KeyValueRow[]): string[] {\n const keyWidth = rows.reduce((max, row) => Math.max(max, row.key.length), 0);\n\n return rows.map((row) => {\n const key = pc.bold(padDisplay(row.key, keyWidth));\n const value = styleValue(row.value, row.tone ?? 'default');\n return `${key} ${value}`;\n });\n}\n\nexport function formatCommandLines(commands: string[]): string[] {\n return commands.map((command) => pc.bold(pc.cyan(command)));\n}\n\nexport function printCard(title: string, lines: string[]): void {\n const content = lines.length > 0 ? lines : [pc.dim('(none)')];\n const width = Math.max(30, minimumContentWidth([title, ...content]));\n\n const border = pc.dim(pc.cyan(`+${'-'.repeat(width + 2)}+`));\n const edge = pc.dim(pc.cyan('|'));\n const divider = pc.dim('-'.repeat(width));\n\n console.log(border);\n console.log(\n `${edge} ${padDisplay(pc.bold(pc.cyan(title)), width)} ${edge}`,\n );\n console.log(`${edge} ${divider} ${edge}`);\n\n for (const line of content) {\n console.log(`${edge} ${padDisplay(line, width)} ${edge}`);\n }\n\n console.log(border);\n}\n","import {\n confirm,\n intro,\n isCancel,\n outro,\n select,\n text\n} from '@clack/prompts';\nimport pc from 'picocolors';\n\nimport { DEFAULT_PROJECT_NAME, DEFAULT_SELECTIONS } from '../core/defaults.js';\nimport type { ParsedArgs, UserSelections } from '../core/types.js';\n\nexport class PromptCancelledError extends Error {\n constructor() {\n super('Prompt cancelled by user.');\n }\n}\n\nfunction unwrapPrompt<T>(value: T | symbol): T {\n if (isCancel(value)) {\n throw new PromptCancelledError();\n }\n\n return value as T;\n}\n\nexport async function collectSelections(parsedArgs: ParsedArgs): Promise<UserSelections> {\n if (parsedArgs.flags.yes || !process.stdin.isTTY) {\n return {\n projectName: parsedArgs.projectName ?? DEFAULT_PROJECT_NAME,\n language: DEFAULT_SELECTIONS.language,\n moduleSystem: DEFAULT_SELECTIONS.moduleSystem,\n jsDevWatcher: DEFAULT_SELECTIONS.jsDevWatcher,\n architecture: DEFAULT_SELECTIONS.architecture,\n databaseMode: DEFAULT_SELECTIONS.databaseMode,\n educational: DEFAULT_SELECTIONS.educational,\n installDeps: parsedArgs.flags.install,\n packageManager: parsedArgs.flags.packageManager,\n initGit: parsedArgs.flags.git,\n dryRun: parsedArgs.flags.dryRun\n };\n }\n\n intro(\n [\n pc.bold(pc.cyan('Create Express API Starter')),\n pc.dim('Scaffold an Express backend with practical defaults.')\n ].join('\\n')\n );\n\n const projectName = parsedArgs.projectName\n ? parsedArgs.projectName\n : unwrapPrompt(\n await text({\n message: 'Project name',\n placeholder: DEFAULT_PROJECT_NAME,\n defaultValue: DEFAULT_PROJECT_NAME,\n validate(value) {\n if (!value.trim()) {\n return 'Project name is required.';\n }\n\n return undefined;\n }\n })\n );\n\n const language = unwrapPrompt(\n await select({\n message: 'Language',\n initialValue: DEFAULT_SELECTIONS.language,\n options: [\n {\n value: 'js',\n label: 'JavaScript'\n },\n {\n value: 'ts',\n label: 'TypeScript'\n }\n ]\n })\n ) as UserSelections['language'];\n\n const moduleSystem =\n language === 'js'\n ? (unwrapPrompt(\n await select({\n message: 'Module system',\n initialValue: DEFAULT_SELECTIONS.moduleSystem,\n options: [\n {\n value: 'commonjs',\n label: 'CommonJS'\n },\n {\n value: 'esm',\n label: 'ES Modules'\n }\n ]\n })\n ) as UserSelections['moduleSystem'])\n : 'commonjs';\n\n const jsDevWatcher =\n language === 'js'\n ? (unwrapPrompt(\n await select({\n message: 'Dev watcher (JavaScript)',\n initialValue: DEFAULT_SELECTIONS.jsDevWatcher,\n options: [\n {\n value: 'node-watch',\n label: 'node --watch (built-in)'\n },\n {\n value: 'nodemon',\n label: 'nodemon'\n }\n ]\n })\n ) as UserSelections['jsDevWatcher'])\n : DEFAULT_SELECTIONS.jsDevWatcher;\n\n const architecture = unwrapPrompt(\n await select({\n message: 'Architecture',\n initialValue: DEFAULT_SELECTIONS.architecture,\n options: [\n {\n value: 'simple',\n label: 'Simple'\n },\n {\n value: 'mvc',\n label: 'MVC'\n }\n ]\n })\n ) as UserSelections['architecture'];\n\n const databaseMode = unwrapPrompt(\n await select({\n message: 'Database',\n initialValue: DEFAULT_SELECTIONS.databaseMode,\n options: [\n {\n value: 'memory',\n label: 'In-memory'\n },\n {\n value: 'postgres-psql',\n label: 'Postgres (psql)'\n },\n {\n value: 'postgres-docker',\n label: 'Postgres (Docker)'\n }\n ]\n })\n ) as UserSelections['databaseMode'];\n\n const educational = unwrapPrompt(\n await confirm({\n message: 'Add educational comments',\n initialValue: DEFAULT_SELECTIONS.educational\n })\n );\n\n const installDeps = parsedArgs.provided.install\n ? parsedArgs.flags.install\n : unwrapPrompt(\n await confirm({\n message: 'Install dependencies now',\n initialValue: DEFAULT_SELECTIONS.installDeps\n })\n );\n\n const packageManager = parsedArgs.provided.packageManager\n ? parsedArgs.flags.packageManager\n : (unwrapPrompt(\n await select({\n message: 'Package manager',\n initialValue: DEFAULT_SELECTIONS.packageManager,\n options: [\n {\n value: 'npm',\n label: 'npm'\n },\n {\n value: 'yarn',\n label: 'yarn'\n }\n ]\n })\n ) as UserSelections['packageManager']);\n\n const initGit = parsedArgs.provided.git\n ? parsedArgs.flags.git\n : unwrapPrompt(\n await confirm({\n message: 'Initialize git repository',\n initialValue: DEFAULT_SELECTIONS.initGit\n })\n );\n\n outro(pc.cyan('Scaffolding project files...'));\n\n return {\n projectName,\n language,\n moduleSystem,\n jsDevWatcher,\n architecture,\n databaseMode,\n educational,\n installDeps,\n packageManager,\n initGit,\n dryRun: parsedArgs.flags.dryRun\n };\n}\n","import type { UserSelections } from './types.js';\n\nexport const DEFAULT_PROJECT_NAME = 'my-api';\n\nexport const DEFAULT_SELECTIONS: Omit<UserSelections, 'projectName' | 'dryRun'> = {\n language: 'js',\n moduleSystem: 'commonjs',\n jsDevWatcher: 'node-watch',\n architecture: 'simple',\n databaseMode: 'memory',\n educational: true,\n installDeps: true,\n packageManager: 'npm',\n initGit: true\n};\n","import path from 'node:path';\n\nexport function validateProjectName(projectName: string): string | null {\n const trimmed = projectName.trim();\n\n if (!trimmed) {\n return 'Project name is required.';\n }\n\n if (trimmed === '.' || trimmed === '..') {\n return 'Project name cannot be \".\" or \"..\".';\n }\n\n if (trimmed !== path.basename(trimmed)) {\n return 'Project name must be a folder name, not a path.';\n }\n\n if (/[^a-zA-Z0-9._-]/.test(trimmed)) {\n return 'Project name can only include letters, numbers, \".\", \"_\", and \"-\".';\n }\n\n return null;\n}\n","import path from 'node:path';\nimport os from 'node:os';\nimport fs from 'fs-extra';\nimport ejs from 'ejs';\n\nimport {\n architectureLabel,\n databaseLabel,\n jsDevWatcherLabel,\n languageLabel,\n moduleSystemLabel,\n} from '../core/labels.js';\nimport { toDatabaseName } from '../core/naming.js';\nimport type {\n GenerationPlan,\n PlannedFile,\n TemplateConfig,\n} from '../core/types.js';\nimport { resolveTemplatesDir } from '../utils/paths.js';\n\ninterface GenerateProjectInput {\n config: TemplateConfig;\n targetDir: string;\n dryRun?: boolean;\n}\n\nfunction toPosixPath(value: string): string {\n return value.split(path.sep).join('/');\n}\n\nfunction isEjsTemplate(relativePath: string): boolean {\n return relativePath.endsWith('.ejs');\n}\n\nfunction stripEjsSuffix(relativePath: string): string {\n return relativePath.endsWith('.ejs')\n ? relativePath.slice(0, -'.ejs'.length)\n : relativePath;\n}\n\nfunction resolveTemplateRoots(config: TemplateConfig): string[] {\n const templatesDir = resolveTemplatesDir();\n\n if (config.language === 'ts') {\n return [\n path.join(templatesDir, 'ts', 'shared'),\n path.join(templatesDir, 'ts', config.architecture),\n ];\n }\n\n return [path.join(templatesDir, config.language, config.architecture)];\n}\n\nasync function listFilesRecursive(\n directory: string,\n baseDir: string = directory,\n): Promise<string[]> {\n const entries = await fs.readdir(directory, {\n withFileTypes: true,\n });\n\n const sortedEntries = entries.sort((a, b) => a.name.localeCompare(b.name));\n const results: string[] = [];\n\n for (const entry of sortedEntries) {\n const entryPath = path.join(directory, entry.name);\n\n if (entry.isDirectory()) {\n const childEntries = await listFilesRecursive(entryPath, baseDir);\n results.push(...childEntries);\n continue;\n }\n\n results.push(path.relative(baseDir, entryPath));\n }\n\n return results;\n}\n\nfunction shouldIncludeTemplate(\n relativePath: string,\n config: TemplateConfig,\n): boolean {\n if (relativePath === 'compose.yaml.ejs') {\n return config.databaseMode === 'postgres-docker';\n }\n\n if (relativePath === 'scripts/dbCreate.js.ejs') {\n return config.databaseMode === 'postgres-psql';\n }\n\n if (relativePath.startsWith('scripts/')) {\n return config.databaseMode !== 'memory';\n }\n\n if (relativePath.startsWith('db/')) {\n return config.databaseMode !== 'memory';\n }\n\n if (relativePath.startsWith('src/db/')) {\n return config.databaseMode !== 'memory';\n }\n\n return true;\n}\n\nfunction toPlannedFile(\n sourcePath: string,\n relativeTemplatePath: string,\n): PlannedFile {\n return {\n templateSourcePath: sourcePath,\n templateRelativePath: relativeTemplatePath,\n outputRelativePath: stripEjsSuffix(relativeTemplatePath),\n isTemplate: isEjsTemplate(relativeTemplatePath),\n };\n}\n\nfunction toPackageName(projectName: string): string {\n const cleaned = projectName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+/, '')\n .replace(/-+$/, '');\n\n return cleaned || 'express-api';\n}\n\nfunction getOsUsername(): string {\n try {\n return os.userInfo().username;\n } catch {\n return process.env.USER ?? process.env.USERNAME ?? 'postgres';\n }\n}\n\nfunction templateData(config: TemplateConfig): Record<string, unknown> {\n const isTypeScript = config.language === 'ts';\n const isEsm = config.moduleSystem === 'esm';\n const isJavaScript = config.language === 'js';\n const useNodemon = isJavaScript && config.jsDevWatcher === 'nodemon';\n const isPostgres = config.databaseMode !== 'memory';\n const isDocker = config.databaseMode === 'postgres-docker';\n const isPsql = config.databaseMode === 'postgres-psql';\n const dbName = toDatabaseName(config.projectName);\n const username = isPostgres ? getOsUsername() : '';\n\n return {\n ...config,\n isTypeScript,\n isEsm,\n isCommonJs: !isEsm,\n isPostgres,\n isDocker,\n isPsql,\n packageName: toPackageName(config.projectName),\n databaseName: dbName,\n educationalLabel: config.educational ? 'On' : 'Off',\n languageLabel: languageLabel(config.language),\n moduleSystemLabel: moduleSystemLabel(config.moduleSystem),\n architectureLabel: architectureLabel(config.architecture),\n databaseLabel: databaseLabel(config.databaseMode),\n jsDevWatcherLabel: jsDevWatcherLabel(config.jsDevWatcher),\n jsDevCommand: useNodemon\n ? 'nodemon src/server.js'\n : 'node --watch src/server.js',\n useNodemon,\n databaseUrl:\n config.databaseMode === 'postgres-docker'\n ? `postgres://postgres:postgres@localhost:5433/${dbName}`\n : `postgres://${encodeURIComponent(username)}:postgres@localhost:5432/${dbName}`,\n osUsername: username,\n };\n}\n\nfunction fromPosixPath(relativePath: string): string {\n return relativePath.split('/').join(path.sep);\n}\n\nexport async function planProject(\n config: TemplateConfig,\n targetDir: string,\n): Promise<GenerationPlan> {\n const templateRoots = resolveTemplateRoots(config);\n\n for (const templateRoot of templateRoots) {\n const templateRootExists = await fs.pathExists(templateRoot);\n\n if (!templateRootExists) {\n throw new Error(`Template root not found: ${templateRoot}`);\n }\n }\n\n const templateFiles = new Map<string, string>();\n\n for (const templateRoot of templateRoots) {\n const allFiles = await listFilesRecursive(templateRoot);\n\n for (const file of allFiles) {\n const relativePath = toPosixPath(file);\n const sourcePath = path.join(templateRoot, fromPosixPath(relativePath));\n templateFiles.set(relativePath, sourcePath);\n }\n }\n\n const files = Array.from(templateFiles.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .filter(([relativePath]) => shouldIncludeTemplate(relativePath, config))\n .map(([relativePath, sourcePath]) => toPlannedFile(sourcePath, relativePath));\n\n return {\n targetDir,\n actions: [\n `Create project directory: ${targetDir}`,\n `Write ${files.length} files`,\n ],\n files,\n };\n}\n\nexport async function generateProject({\n config,\n targetDir,\n dryRun = false,\n}: GenerateProjectInput): Promise<GenerationPlan> {\n const plan = await planProject(config, targetDir);\n\n if (dryRun) {\n return plan;\n }\n\n await fs.ensureDir(targetDir);\n\n const data = templateData(config);\n\n for (const file of plan.files) {\n const destinationPath = path.join(\n targetDir,\n fromPosixPath(file.outputRelativePath),\n );\n\n await fs.ensureDir(path.dirname(destinationPath));\n\n if (file.isTemplate) {\n const template = await fs.readFile(file.templateSourcePath, 'utf8');\n const rendered = ejs.render(template, data);\n await fs.writeFile(destinationPath, rendered, 'utf8');\n continue;\n }\n\n await fs.copy(file.templateSourcePath, destinationPath);\n }\n\n return plan;\n}\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport fs from 'fs-extra';\n\nexport function resolveTargetDir(baseDir: string, projectName: string): string {\n return path.resolve(baseDir, projectName);\n}\n\nexport function resolveTemplatesDir(): string {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n\n const candidates = [\n path.resolve(moduleDir, '../templates'),\n path.resolve(moduleDir, '../../templates'),\n path.resolve(process.cwd(), 'templates')\n ];\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error('Unable to locate templates directory.');\n}\n","import { execa } from 'execa';\n\nimport type { PackageManager } from '../core/types.js';\n\nexport async function commandExists(command: string, args: string[] = ['--version']): Promise<boolean> {\n try {\n await execa(command, args, {\n stdio: 'ignore'\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runCommand(command: string, args: string[], cwd: string): Promise<void> {\n await execa(command, args, {\n cwd,\n stdio: 'inherit'\n });\n}\n\nfunction npmInstallArgs(verbose: boolean): string[] {\n const args = ['install', '--no-audit', '--no-fund'];\n\n if (!verbose) {\n args.push('--loglevel=error');\n }\n\n return args;\n}\n\nfunction yarnInstallArgs(verbose: boolean): string[] {\n const args = ['install'];\n\n if (!verbose) {\n args.push('--silent');\n }\n\n return args;\n}\n\nexport function formatInstallCommand(packageManager: PackageManager, verbose = false): string {\n const args = packageManager === 'yarn' ? yarnInstallArgs(verbose) : npmInstallArgs(verbose);\n return `${packageManager} ${args.join(' ')}`;\n}\n\nexport async function installDependencies(\n cwd: string,\n packageManager: PackageManager,\n verbose = false\n): Promise<void> {\n const args = packageManager === 'yarn' ? yarnInstallArgs(verbose) : npmInstallArgs(verbose);\n await runCommand(packageManager, args, cwd);\n}\n\nexport async function initGitRepo(cwd: string): Promise<void> {\n await runCommand('git', ['init'], cwd);\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\n\nexport async function assertSafeTargetDir(targetDir: string): Promise<void> {\n const exists = await fs.pathExists(targetDir);\n\n if (!exists) {\n return;\n }\n\n const stats = await fs.stat(targetDir);\n\n if (!stats.isDirectory()) {\n throw new Error(`Target path already exists and is not a directory: ${targetDir}`);\n }\n\n const entries = await fs.readdir(targetDir);\n if (entries.length > 0) {\n throw new Error(\n `Target directory \"${path.basename(targetDir)}\" already exists and is not empty.`\n );\n }\n}\n","import { statusTag } from './terminalUi.js';\n\nexport const logger = {\n info(message: string): void {\n console.log(`${statusTag('info')} ${message}`);\n },\n success(message: string): void {\n console.log(`${statusTag('success')} ${message}`);\n },\n warn(message: string): void {\n console.warn(`${statusTag('warn')} ${message}`);\n },\n error(message: string): void {\n console.error(`${statusTag('error')} ${message}`);\n }\n};\n"],"mappings":"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","names":["pc","fs","path","fileURLToPath","pc","pc","pc","pc","path","path","fs","path","path","fs","path","fs","path","fs","installCommand","fileURLToPath","pc"]}
|