@alexmc2/create-express-api-starter 0.1.5 → 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 +55 -83
- package/dist/cli.js +138 -19
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/templates/ts/mvc/README.md.ejs +1 -0
- package/templates/ts/simple/README.md.ejs +1 -0
package/README.md
CHANGED
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
A beginner-friendly npm CLI that scaffolds Express APIs with best-practice structure and optional educational comments.
|
|
6
6
|
|
|
7
|
+
## About
|
|
8
|
+
|
|
9
|
+
Most Express projects require some initial setup, including folders, middleware, error handling, and testing. This CLI tool automates this process so you can start writing routes immediately. It includes a standard, readable codebase with a pre-configured Jest and Supertest suite that passes right out of the box.
|
|
10
|
+
|
|
11
|
+
The CLI offers multiple configuration options to suit different preferences and use cases, including:
|
|
12
|
+
|
|
7
13
|
- JavaScript or TypeScript
|
|
8
14
|
- Simple or MVC architecture
|
|
9
15
|
- In-memory or PostgreSQL (local `psql` or Docker)
|
|
10
16
|
- npm workflow (`npm create`, `npm init`, or `npx`)
|
|
17
|
+
- Dependency installs with `npm` or `yarn`
|
|
11
18
|
|
|
12
19
|
<br />
|
|
13
20
|
|
|
@@ -15,35 +22,18 @@ A beginner-friendly npm CLI that scaffolds Express APIs with best-practice struc
|
|
|
15
22
|
|
|
16
23
|
<br />
|
|
17
24
|
|
|
18
|
-
>
|
|
25
|
+
> The CLI works on Linux, macOS, and Windows.
|
|
19
26
|
|
|
20
27
|
## Table of contents
|
|
21
28
|
|
|
22
|
-
- [
|
|
29
|
+
- [About](#about)
|
|
23
30
|
- [Table of contents](#table-of-contents)
|
|
24
31
|
- [Installation](#installation)
|
|
25
|
-
- [npm create (recommended)](#npm-create-recommended)
|
|
26
|
-
- [npm init](#npm-init)
|
|
27
|
-
- [npx (equivalent)](#npx-equivalent)
|
|
28
|
-
- [Global install (optional)](#global-install-optional)
|
|
29
32
|
- [Usage examples](#usage-examples)
|
|
30
|
-
- [Interactive flow](#interactive-flow)
|
|
31
|
-
- [Accept defaults (non-interactive)](#accept-defaults-non-interactive)
|
|
32
|
-
- [Dry run](#dry-run)
|
|
33
|
-
- [Why this exists](#why-this-exists)
|
|
34
33
|
- [How it works](#how-it-works)
|
|
35
34
|
- [Options](#options)
|
|
36
|
-
- [CLI flags](#cli-flags)
|
|
37
35
|
- [What gets generated](#what-gets-generated)
|
|
38
|
-
- [Project structure (Simple architecture, JavaScript)](#project-structure-simple-architecture-javascript)
|
|
39
|
-
- [Middleware](#middleware)
|
|
40
|
-
- [Error handling](#error-handling)
|
|
41
|
-
- [Scripts](#scripts)
|
|
42
|
-
- [Tests](#tests)
|
|
43
36
|
- [Database modes](#database-modes)
|
|
44
|
-
- [In-memory (default)](#in-memory-default)
|
|
45
|
-
- [Postgres (psql)](#postgres-psql)
|
|
46
|
-
- [Postgres (Docker)](#postgres-docker)
|
|
47
37
|
- [Educational comments](#educational-comments)
|
|
48
38
|
- [Design decisions](#design-decisions)
|
|
49
39
|
- [Requirements](#requirements)
|
|
@@ -77,14 +67,12 @@ npx @alexmc2/create-express-api-starter my-api
|
|
|
77
67
|
npm install -g @alexmc2/create-express-api-starter
|
|
78
68
|
```
|
|
79
69
|
|
|
80
|
-
> The npm package page may show `npm i @alexmc2/create-express-api-starter`. That command installs the package into your current project. For one-off scaffolding, use `npm create`, `npm init`, or `npx`.
|
|
81
|
-
|
|
82
70
|
## Usage examples
|
|
83
71
|
|
|
84
72
|
### Interactive flow
|
|
85
73
|
|
|
86
74
|
```bash
|
|
87
|
-
npm create @alexmc2/express-api-starter@latest
|
|
75
|
+
npm create @alexmc2/express-api-starter@latest
|
|
88
76
|
```
|
|
89
77
|
|
|
90
78
|
### Accept defaults (non-interactive)
|
|
@@ -109,28 +97,25 @@ npm test # Run the test suite
|
|
|
109
97
|
npm run lint # Run ESLint
|
|
110
98
|
```
|
|
111
99
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
## Why this exists
|
|
100
|
+
To use Yarn for dependency installation and command examples shown by the CLI:
|
|
115
101
|
|
|
116
|
-
|
|
102
|
+
```bash
|
|
103
|
+
npm create @alexmc2/express-api-starter@latest my-api -- --package-manager=yarn
|
|
104
|
+
```
|
|
117
105
|
|
|
118
|
-
|
|
106
|
+
Your API is live at `http://localhost:3000`. Go to `http://localhost:3000/health` to confirm.
|
|
119
107
|
|
|
120
108
|
## How it works
|
|
121
109
|
|
|
122
|
-
|
|
110
|
+
The interactive CLI prompts you for configuration preferences and generates your project files from templates.
|
|
123
111
|
|
|
124
|
-
|
|
125
|
-
2. **The generated project** - a standalone Express API in its own folder with its own dependencies, scripts, and tests. The CLI exits after creating it.
|
|
126
|
-
|
|
127
|
-
When you run `npm create @alexmc2/express-api-starter@latest my-api` (or the equivalent `npm init`/`npx` command), npm downloads the CLI, generates the project into `my-api/`, optionally runs `npm install`, and exits. The generated project has no dependency on this tool.
|
|
112
|
+
When you run `npm create @alexmc2/express-api-starter@latest my-api`, npm downloads the CLI to build the project directly in your folder. You are left with a standalone Express API with its own scripts and tests, and the generated project has no ongoing dependency on this tool. You can safely uninstall the CLI globally if you used that installation method.
|
|
128
113
|
|
|
129
114
|
## Options
|
|
130
115
|
|
|
131
116
|
The CLI walks you through these choices interactively. Use `--yes` to skip prompts and accept all defaults.
|
|
132
117
|
|
|
133
|
-
| Option
|
|
118
|
+
| **Option** | **Choices** | **Default** |
|
|
134
119
|
| --------------------------- | --------------------------------------------- | -------------- |
|
|
135
120
|
| **Language** | JavaScript, TypeScript | JavaScript |
|
|
136
121
|
| **Module system** (JS only) | CommonJS, ES Modules | CommonJS |
|
|
@@ -139,23 +124,27 @@ The CLI walks you through these choices interactively. Use `--yes` to skip promp
|
|
|
139
124
|
| **Database** | In-memory, Postgres (psql), Postgres (Docker) | In-memory |
|
|
140
125
|
| **Educational comments** | On, Off | On |
|
|
141
126
|
| **Install dependencies** | Yes, No | Yes |
|
|
127
|
+
| **Package manager** | npm, yarn | npm |
|
|
142
128
|
| **Initialise git repo** | Yes, No | Yes |
|
|
143
129
|
|
|
144
130
|
### CLI flags
|
|
145
131
|
|
|
146
|
-
| Flag
|
|
132
|
+
| **Flag** | **Effect** |
|
|
147
133
|
| -------------- | ----------------------------------------------------------- |
|
|
148
134
|
| `--yes` | Accept all defaults, skip prompts |
|
|
149
135
|
| `--dry-run` | Show the generation plan without writing files |
|
|
150
|
-
| `--no-install` | Skip
|
|
136
|
+
| `--no-install` | Skip dependency installation after generation |
|
|
151
137
|
| `--no-git` | Skip `git init` after generation |
|
|
152
|
-
| `--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` |
|
|
153
142
|
|
|
154
143
|
## What gets generated
|
|
155
144
|
|
|
156
145
|
### Project structure (Simple architecture, JavaScript)
|
|
157
146
|
|
|
158
|
-
```
|
|
147
|
+
```text
|
|
159
148
|
my-api/
|
|
160
149
|
├── src/
|
|
161
150
|
│ ├── app.js # Express app: middleware, routes, error handling
|
|
@@ -180,13 +169,13 @@ my-api/
|
|
|
180
169
|
└── jest.config.js
|
|
181
170
|
```
|
|
182
171
|
|
|
183
|
-
MVC
|
|
172
|
+
The MVC option organises the code into `controllers/`, `services/`, and `repositories/` to keep the business logic and data access separate.
|
|
184
173
|
|
|
185
174
|
Postgres modes additionally include `db/schema.sql`, `db/seed.sql`, `src/db/` (connection pool), and setup scripts in `scripts/`. Docker mode adds a `compose.yaml`.
|
|
186
175
|
|
|
187
176
|
### Middleware
|
|
188
177
|
|
|
189
|
-
|
|
178
|
+
The following middleware is pre-configured in every project:
|
|
190
179
|
|
|
191
180
|
- **express.json()** - parses JSON request bodies
|
|
192
181
|
- **cors** - enables cross-origin requests
|
|
@@ -205,7 +194,7 @@ Errors return a consistent JSON shape:
|
|
|
205
194
|
}
|
|
206
195
|
```
|
|
207
196
|
|
|
208
|
-
In development, a `stack` trace is included for debugging.
|
|
197
|
+
In development, a `stack` trace is included for debugging. This is omitted in production.
|
|
209
198
|
|
|
210
199
|
In PostgreSQL mode, duplicate values for unique fields (like `email`) return `409 Conflict` with a clear message instead of a generic `500`.
|
|
211
200
|
|
|
@@ -213,7 +202,7 @@ In PostgreSQL mode, duplicate values for unique fields (like `email`) return `40
|
|
|
213
202
|
|
|
214
203
|
**JavaScript projects:**
|
|
215
204
|
|
|
216
|
-
| Script
|
|
205
|
+
| **Script** | **Command** | **Purpose** |
|
|
217
206
|
| -------------- | --------------------------------------------------------------- | ---------------------------- |
|
|
218
207
|
| `npm run dev` | `node --watch src/server.js` or `nodemon src/server.js` | Dev server with auto-restart |
|
|
219
208
|
| `npm start` | `node src/server.js` | Production start |
|
|
@@ -224,7 +213,7 @@ Choosing `nodemon` adds it to `devDependencies` automatically.
|
|
|
224
213
|
|
|
225
214
|
**TypeScript projects:**
|
|
226
215
|
|
|
227
|
-
| Script
|
|
216
|
+
| **Script** | **Command** | **Purpose** |
|
|
228
217
|
| --------------- | ------------------------- | ---------------------------- |
|
|
229
218
|
| `npm run dev` | `tsx watch src/server.ts` | Dev server with auto-restart |
|
|
230
219
|
| `npm run build` | `tsc` | Compile to JavaScript |
|
|
@@ -234,7 +223,7 @@ Choosing `nodemon` adds it to `devDependencies` automatically.
|
|
|
234
223
|
|
|
235
224
|
**Postgres modes also include:**
|
|
236
225
|
|
|
237
|
-
| Script
|
|
226
|
+
| **Script** | **Purpose** |
|
|
238
227
|
| ------------------- | ------------------------------------------------- |
|
|
239
228
|
| `npm run db:create` | Create the database (psql mode only) |
|
|
240
229
|
| `npm run db:setup` | Apply `db/schema.sql` |
|
|
@@ -245,29 +234,24 @@ Choosing `nodemon` adds it to `devDependencies` automatically.
|
|
|
245
234
|
|
|
246
235
|
### Tests
|
|
247
236
|
|
|
248
|
-
|
|
237
|
+
The project includes a functional test suite using Jest and Supertest. In-memory mode works out of the box - just run `npm test` immediately after generation.
|
|
249
238
|
|
|
250
239
|
## Database modes
|
|
251
240
|
|
|
252
241
|
### In-memory (default)
|
|
253
242
|
|
|
254
|
-
Data
|
|
255
|
-
|
|
256
|
-
Good for learning the project structure and getting something running fast. The code uses a repository pattern, so switching to a real database later is straightforward.
|
|
243
|
+
Data is stored in a simple JavaScript array, so you don't need to install or configure anything. This is useful for prototyping, though data will reset every time the server restarts. Because the project uses a repository pattern, you can swap this for a real database later without having to refactor your routes.
|
|
257
244
|
|
|
258
245
|
### Postgres (psql)
|
|
259
246
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
- `pg` as a dependency with a connection pool
|
|
263
|
-
- `db/schema.sql` and `db/seed.sql` for table creation and sample data
|
|
264
|
-
- Node scripts for database management (`db:create`, `db:setup`, `db:seed`, `db:reset`) using the `pg` library
|
|
265
|
-
- A project-specific database name derived from your project name (e.g. `my-api` → `my_api_dev`)
|
|
266
|
-
- `DATABASE_URL` pre-configured with your OS username
|
|
247
|
+
If you have PostgreSQL running locally, this mode sets up everything you need to connect your app to a real database. The generated project includes:
|
|
267
248
|
|
|
268
|
-
|
|
249
|
+
- `pg` (node-postgres) with a pre-configured connection pool.
|
|
250
|
+
- `db/schema.sql` and `db/seed.sql` for your initial tables and test data.
|
|
251
|
+
- Management scripts (`db:setup`, `db:reset`, etc.) so you don't have to jump into the terminal to run SQL manually.
|
|
252
|
+
- A `DATABASE_URL` in your `.env` pre-filled with your OS username and a database name derived from your project.
|
|
269
253
|
|
|
270
|
-
**
|
|
254
|
+
**To get started:**
|
|
271
255
|
|
|
272
256
|
```bash
|
|
273
257
|
# After generation
|
|
@@ -281,11 +265,9 @@ The generated README includes OS-specific PostgreSQL installation and role setup
|
|
|
281
265
|
|
|
282
266
|
### Postgres (Docker)
|
|
283
267
|
|
|
284
|
-
|
|
268
|
+
If you prefer Docker to avoid a local installation, this mode provides a `compose.yaml` that runs PostgreSQL on port 5433 (avoiding conflicts with any local Postgres you might have).
|
|
285
269
|
|
|
286
|
-
|
|
287
|
-
- Node-based setup scripts using the `pg` library - no `psql` CLI needed on your machine
|
|
288
|
-
- A retry helper that waits for the database container to be ready before running setup
|
|
270
|
+
It includes a **retry helper** in the setup scripts. This solves the common issue where scripts fail because the database container isn't fully "ready" to accept connections yet.
|
|
289
271
|
|
|
290
272
|
```bash
|
|
291
273
|
# After generation
|
|
@@ -300,36 +282,26 @@ npm run db:down # Stop and remove container + data
|
|
|
300
282
|
|
|
301
283
|
## Educational comments
|
|
302
284
|
|
|
303
|
-
|
|
285
|
+
You can enable inline comments that explain the 'why' behind the code. These are designed to be short and useful, covering things like:
|
|
304
286
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
app.use(express.json());
|
|
309
|
-
|
|
310
|
-
// Set common HTTP security headers.
|
|
311
|
-
// Helmet applies safe defaults that reduce exposure to common web attacks.
|
|
312
|
-
app.use(helmet());
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
These comments cover middleware, routing, error handling, database scripts, and architecture patterns. They teach without getting in the way. Turn them off during generation if you prefer clean code.
|
|
287
|
+
- Why we use `express.json()` and what happens if you forget it.
|
|
288
|
+
- Why `helmet` is included for security.
|
|
289
|
+
- How the repository pattern simplifies your data logic.
|
|
316
290
|
|
|
317
291
|
## Design decisions
|
|
318
292
|
|
|
319
|
-
**Opinionated
|
|
320
|
-
|
|
321
|
-
**Module system is a choice (JS only).** CommonJS is the default because most Express tutorials use it. ES Modules are available if you prefer modern `import`/`export` syntax. TypeScript projects always use ESM-style imports that compile to CommonJS.
|
|
293
|
+
**Opinionated but swappable.** The tool uses a standard stack (Jest, Morgan, Helmet, and ESLint) so projects are functional immediately. There is no complex logic connecting these tools, so they are easy to swap out if a different library is preferred.
|
|
322
294
|
|
|
323
|
-
**
|
|
295
|
+
**Module system choice.** JavaScript projects allow choosing between CommonJS and ES Modules. TypeScript projects use ESM-style imports that compile to clean CommonJS.
|
|
324
296
|
|
|
325
|
-
**
|
|
297
|
+
**Auth, ORMs, and OpenAPI.** These are not included in the current templates. Since these are major architectural decisions, they are best left to the developer to decide based on specific project needs. These may be added as configurable options in later versions.
|
|
326
298
|
|
|
327
299
|
## Requirements
|
|
328
300
|
|
|
329
|
-
- **Node.js >= 20**
|
|
330
|
-
- **npm** (
|
|
331
|
-
- **Docker** (only
|
|
332
|
-
- **PostgreSQL** (only
|
|
301
|
+
- **Node.js >= 20**
|
|
302
|
+
- **npm** (comes with Node)
|
|
303
|
+
- **Docker** (only if using Docker DB mode)
|
|
304
|
+
- **PostgreSQL** (only if using local psql mode)
|
|
333
305
|
|
|
334
306
|
## Built with
|
|
335
307
|
|
|
@@ -342,7 +314,7 @@ These comments cover middleware, routing, error handling, database scripts, and
|
|
|
342
314
|
|
|
343
315
|
**Generated projects use:**
|
|
344
316
|
|
|
345
|
-
- Express
|
|
317
|
+
- Express 5
|
|
346
318
|
- Jest + Supertest for testing
|
|
347
319
|
- ESLint for linting
|
|
348
320
|
- `@swc/jest` for TypeScript test transforms
|
|
@@ -350,7 +322,7 @@ These comments cover middleware, routing, error handling, database scripts, and
|
|
|
350
322
|
|
|
351
323
|
## Contributing
|
|
352
324
|
|
|
353
|
-
|
|
325
|
+
If you find a bug or have an idea for a template, feel free to open an issue or a PR. See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
|
354
326
|
|
|
355
327
|
```bash
|
|
356
328
|
git clone https://github.com/alexmc2/create-express-api-starter.git
|
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":";;;AAAA,OAAOA,SAAQ;AACf,SAAS,qBAAqB;AAC9B,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;;;ACF9B,IAAM,cAAc,oBAAI,IAAI,CAAC,KAAK,QAAQ,OAAO,IAAI,CAAC;AACtD,IAAM,eAAe,oBAAI,IAAI,CAAC,KAAK,SAAS,MAAM,KAAK,CAAC;AAExD,SAAS,kBAAkB,OAAgD;AACzE,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAE5C,MAAI,YAAY,IAAI,UAAU,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,IAAI,UAAU,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,OAA4D;AAC7E,QAAM,gBAAgB,MAAM,MAAM,CAAC;AACnC,QAAM,cAAc,cAAc,QAAQ,GAAG;AAE7C,MAAI,gBAAgB,IAAI;AACtB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,cAAc,MAAM,GAAG,WAAW;AAAA,IACxC,OAAO,cAAc,MAAM,cAAc,CAAC;AAAA,EAC5C;AACF;AAEO,SAAS,UAAU,MAA4B;AACpD,QAAM,QAAQ;AAAA,IACZ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AAEA,QAAM,WAAW;AAAA,IACf,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AAEA,QAAM,eAAyB,CAAC;AAChC,QAAM,cAAwB,CAAC;AAE/B,MAAI,iBAAiB;AAErB,aAAW,SAAS,MAAM;AACxB,QAAI,gBAAgB;AAClB,kBAAY,KAAK,KAAK;AACtB;AAAA,IACF;AAEA,QAAI,UAAU,MAAM;AAClB,uBAAiB;AACjB;AAAA,IACF;AAEA,QAAI,CAAC,MAAM,WAAW,GAAG,KAAK,UAAU,KAAK;AAC3C,kBAAY,KAAK,KAAK;AACtB;AAAA,IACF;AAEA,QAAI,CAAC,MAAM,WAAW,IAAI,GAAG;AAC3B,mBAAa,KAAK,KAAK;AACvB;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,MAAM,IAAI,UAAU,KAAK;AAEvC,QAAI,SAAS,OAAO;AAClB,YAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAI,UAAU,UAAa,gBAAgB,QAAW;AACpD,qBAAa,KAAK,KAAK;AACvB;AAAA,MACF;AACA,YAAM,MAAM,eAAe;AAC3B,eAAS,MAAM;AACf;AAAA,IACF;AAEA,QAAI,SAAS,WAAW;AACtB,YAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAI,UAAU,UAAa,gBAAgB,QAAW;AACpD,qBAAa,KAAK,KAAK;AACvB;AAAA,MACF;AACA,YAAM,SAAS,eAAe;AAC9B,eAAS,SAAS;AAClB;AAAA,IACF;AAEA,QAAI,SAAS,cAAc;AACzB,YAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAI,UAAU,UAAa,gBAAgB,QAAW;AACpD,qBAAa,KAAK,KAAK;AACvB;AAAA,MACF;AAEA,YAAM,YAAY,eAAe;AACjC,YAAM,UAAU,CAAC;AACjB,eAAS,UAAU;AACnB;AAAA,IACF;AAEA,QAAI,SAAS,UAAU;AACrB,YAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAI,UAAU,UAAa,gBAAgB,QAAW;AACpD,qBAAa,KAAK,KAAK;AACvB;AAAA,MACF;AAEA,YAAM,QAAQ,eAAe;AAC7B,YAAM,MAAM,CAAC;AACb,eAAS,MAAM;AACf;AAAA,IACF;AAEA,QAAI,SAAS,WAAW;AACtB,YAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAI,UAAU,UAAa,gBAAgB,QAAW;AACpD,qBAAa,KAAK,KAAK;AACvB;AAAA,MACF;AAEA,YAAM,UAAU,eAAe;AAC/B,eAAS,UAAU;AACnB;AAAA,IACF;AAEA,iBAAa,KAAK,KAAK;AAAA,EACzB;AAEA,SAAO;AAAA,IACL,aAAa,YAAY,CAAC;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC3JA,OAAO,UAAU;AACjB,OAAOC,SAAQ;;;ACOR,SAAS,cAAc,UAA4B;AACxD,SAAO,aAAa,OAAO,eAAe;AAC5C;AAEO,SAAS,kBAAkB,cAAoC;AACpE,SAAO,iBAAiB,QAAQ,eAAe;AACjD;AAEO,SAAS,kBAAkB,cAAoC;AACpE,SAAO,iBAAiB,YAAY,YAAY;AAClD;AAEO,SAAS,kBAAkB,cAAoC;AACpE,SAAO,iBAAiB,QAAQ,QAAQ;AAC1C;AAEO,SAAS,cAAc,cAAoC;AAChE,MAAI,iBAAiB,iBAAiB;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,mBAAmB;AACtC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AClCO,SAAS,eAAe,aAA6B;AAC1D,QAAM,UAAU,YACb,KAAK,EACL,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,EAAE;AAEpB,UAAQ,WAAW,iBAAiB;AACtC;;;ACTA,OAAO,QAAQ;AAKf,IAAM,eAAe;AAErB,SAAS,UAAU,OAAuB;AACxC,SAAO,MAAM,QAAQ,cAAc,EAAE;AACvC;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,UAAU,KAAK,EAAE;AAC1B;AAEA,SAAS,WAAW,OAAe,OAAuB;AACxD,QAAM,UAAU,QAAQ,cAAc,KAAK;AAC3C,MAAI,WAAW,GAAG;AAChB,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,KAAK,GAAG,IAAI,OAAO,OAAO,CAAC;AACvC;AAEA,SAAS,oBAAoB,OAAyB;AACpD,SAAO,MAAM,OAAO,CAAC,KAAK,SAAS;AACjC,WAAO,KAAK,IAAI,KAAK,cAAc,IAAI,CAAC;AAAA,EAC1C,GAAG,CAAC;AACN;AAEA,SAAS,WAAW,OAAe,MAAyB;AAC1D,MAAI,SAAS,UAAU;AACrB,WAAO,GAAG,KAAK,KAAK;AAAA,EACtB;AAEA,MAAI,SAAS,WAAW;AACtB,WAAO,GAAG,MAAM,KAAK;AAAA,EACvB;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,GAAG,OAAO,KAAK;AAAA,EACxB;AAEA,MAAI,SAAS,SAAS;AACpB,WAAO,GAAG,IAAI,KAAK;AAAA,EACrB;AAEA,SAAO;AACT;AAEO,SAAS,UAAU,MAA0B;AAClD,MAAI,SAAS,WAAW;AACtB,WAAO,GAAG,KAAK,GAAG,MAAM,MAAM,CAAC;AAAA,EACjC;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,GAAG,KAAK,GAAG,OAAO,MAAM,CAAC;AAAA,EAClC;AAEA,MAAI,SAAS,SAAS;AACpB,WAAO,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC;AAAA,EAC9B;AAEA,SAAO,GAAG,KAAK,GAAG,KAAK,MAAM,CAAC;AAChC;AAQO,SAAS,oBAAoB,MAA+B;AACjE,QAAM,WAAW,KAAK,OAAO,CAAC,KAAK,QAAQ,KAAK,IAAI,KAAK,IAAI,IAAI,MAAM,GAAG,CAAC;AAE3E,SAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAM,MAAM,GAAG,KAAK,WAAW,IAAI,KAAK,QAAQ,CAAC;AACjD,UAAM,QAAQ,WAAW,IAAI,OAAO,IAAI,QAAQ,SAAS;AACzD,WAAO,GAAG,GAAG,KAAK,KAAK;AAAA,EACzB,CAAC;AACH;AAEO,SAAS,mBAAmB,UAA8B;AAC/D,SAAO,SAAS,IAAI,CAAC,YAAY,GAAG,KAAK,GAAG,KAAK,OAAO,CAAC,CAAC;AAC5D;AAEO,SAAS,UAAU,OAAe,OAAuB;AAC9D,QAAM,UAAU,MAAM,SAAS,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC;AAC5D,QAAM,QAAQ,KAAK,IAAI,IAAI,oBAAoB,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;AAEnE,QAAM,SAAS,GAAG,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,QAAQ,CAAC,CAAC,GAAG,CAAC;AAC3D,QAAM,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC;AAChC,QAAM,UAAU,GAAG,IAAI,IAAI,OAAO,KAAK,CAAC;AAExC,UAAQ,IAAI,MAAM;AAClB,UAAQ;AAAA,IACN,GAAG,IAAI,IAAI,WAAW,GAAG,KAAK,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI;AAAA,EAC/D;AACA,UAAQ,IAAI,GAAG,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE;AAExC,aAAW,QAAQ,SAAS;AAC1B,YAAQ,IAAI,GAAG,IAAI,IAAI,WAAW,MAAM,KAAK,CAAC,IAAI,IAAI,EAAE;AAAA,EAC1D;AAEA,UAAQ,IAAI,MAAM;AACpB;;;AHvFA,SAAS,sBAAsB,WAAqC;AAClE,QAAM,WAAW,CAAC,MAAM,UAAU,WAAW,EAAE;AAE/C,MAAI,CAAC,UAAU,aAAa;AAC1B,aAAS,KAAK,aAAa;AAAA,EAC7B;AAEA,WAAS,KAAK,sBAAsB;AAEpC,MAAI,UAAU,iBAAiB,iBAAiB;AAC9C,aAAS,KAAK,mBAAmB;AACjC,aAAS,KAAK,kBAAkB;AAChC,aAAS,KAAK,iBAAiB;AAAA,EACjC;AAEA,MAAI,UAAU,iBAAiB,mBAAmB;AAChD,aAAS,KAAK,eAAe;AAC7B,aAAS,KAAK,kBAAkB;AAChC,aAAS,KAAK,iBAAiB;AAAA,EACjC;AAEA,WAAS,KAAK,aAAa;AAE3B,MAAI,UAAU,aAAa,MAAM;AAC/B,aAAS,KAAK,eAAe;AAAA,EAC/B;AAEA,WAAS,KAAK,UAAU;AAExB,SAAO;AACT;AAEA,SAAS,oBACP,WACA,UACU;AACV,QAAM,eAAe,eAAe,UAAU,WAAW;AAEzD,MAAI,aAAa,SAAS;AACxB,WAAO;AAAA,MACLC,IAAG,OAAO,gDAAgD;AAAA,MAC1DA,IAAG,IAAI,qEAAqE;AAAA,MAC5E,GAAG,mBAAmB;AAAA,QACpB,mEAAmE,YAAY;AAAA,MACjF,CAAC;AAAA,MACDA,IAAG,IAAI,kCAAkC;AAAA,MACzC,GAAG,mBAAmB,CAAC,mBAAmB,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,MAAI,aAAa,UAAU;AACzB,WAAO;AAAA,MACLA,IAAG,OAAO,8CAA8C;AAAA,MACxDA,IAAG,IAAI,kEAAkE;AAAA,MACzEA,IAAG,IAAI,+CAA+C;AAAA,MACtD,GAAG,mBAAmB;AAAA,QACpB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACLA,IAAG,OAAO,8CAA8C;AAAA,IACxDA,IAAG,IAAI,gDAAgD;AAAA,IACvD,GAAG,mBAAmB;AAAA,MACpB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,gBACd,WACA,MACM;AACN,QAAM,gBACJ,UAAU,aAAa,OACnB,GAAG,cAAc,UAAU,QAAQ,CAAC,KAAK,kBAAkB,UAAU,YAAY,CAAC,MAClF,cAAc,UAAU,QAAQ;AAEtC,QAAM,iBAA4D;AAAA,IAChE;AAAA,MACE,KAAK;AAAA,MACL,OAAO,iBAAiB,KAAK,SAAS;AAAA,MACtC,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,kBAAkB,UAAU,YAAY;AAAA,MAC/C,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,cAAc,UAAU,YAAY;AAAA,MAC3C,MAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI,UAAU,aAAa,MAAM;AAC/B,mBAAe,KAAK;AAAA,MAClB,KAAK;AAAA,MACL,OAAO,kBAAkB,UAAU,YAAY;AAAA,MAC/C,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,iBAAe;AAAA,IACb;AAAA,MACE,KAAK;AAAA,MACL,OAAO,UAAU,cAAc,OAAO;AAAA,MACtC,MAAM,UAAU,cAAc,YAAY;AAAA,IAC5C;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,UAAU,cAAc,QAAQ;AAAA,MACvC,MAAM,UAAU,cAAc,YAAY;AAAA,IAC5C;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,UAAU,UAAU,QAAQ;AAAA,MACnC,MAAM,UAAU,UAAU,YAAY;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,eAAe,oBAAoB,cAAc;AAEvD,QAAM,YAAY,KAAK,MAAM,IAAI,CAAC,SAAS,GAAGA,IAAG,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;AAEtF,UAAQ,IAAI,EAAE;AACd,YAAU,0BAA0B,YAAY;AAChD,UAAQ,IAAI,EAAE;AACd,YAAU,mBAAmB,KAAK,MAAM,MAAM,KAAK,SAAS;AAC9D;AAEO,SAAS,eACd,WACA,WAA4B,QAAQ,UAC9B;AACN,QAAM,aAAa;AAAA,IACjB,UAAU,aAAa,OACnB,GAAG,cAAc,UAAU,QAAQ,CAAC,KAAK,kBAAkB,UAAU,YAAY,CAAC,MAClF,cAAc,UAAU,QAAQ;AAAA,IACpC,kBAAkB,UAAU,YAAY;AAAA,IACxC,cAAc,UAAU,YAAY;AAAA,EACtC;AAEA,QAAM,iBAA4D;AAAA,IAChE;AAAA,MACE,KAAK;AAAA,MACL,OAAO,UAAU;AAAA,MACjB,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,WAAW,KAAK,KAAK;AAAA,MAC5B,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,UAAU,cAAc,OAAO;AAAA,MACtC,MAAM,UAAU,cAAc,YAAY;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,UAAU,aAAa,MAAM;AAC/B,mBAAe,KAAK;AAAA,MAClB,KAAK;AAAA,MACL,OAAO,kBAAkB,UAAU,YAAY;AAAA,MAC/C,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,oBAAoB,cAAc;AAEvD,QAAM,mBAAmB,sBAAsB,SAAS;AAExD,UAAQ,IAAI,EAAE;AACd,YAAU,iBAAiB,YAAY;AACvC,UAAQ,IAAI,EAAE;AACd,YAAU,cAAc,mBAAmB,gBAAgB,CAAC;AAE5D,MAAI,UAAU,iBAAiB,iBAAiB;AAC9C,UAAM,aAAa,oBAAoB,WAAW,QAAQ;AAE1D,YAAQ,IAAI,EAAE;AACd,cAAU,kBAAkB,UAAU;AAAA,EACxC;AACF;AAEO,SAAS,iBAAiB,WAA2B;AAC1D,QAAM,WAAW,KAAK,SAAS,QAAQ,IAAI,GAAG,SAAS;AACvD,SAAO,YAAY;AACrB;;;AIxNA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAOC,SAAQ;;;ACNR,IAAM,uBAAuB;AAE7B,IAAM,qBAAqE;AAAA,EAChF,UAAU;AAAA,EACV,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,aAAa;AAAA,EACb,aAAa;AAAA,EACb,SAAS;AACX;;;ADAO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,cAAc;AACZ,UAAM,2BAA2B;AAAA,EACnC;AACF;AAEA,SAAS,aAAgB,OAAsB;AAC7C,MAAI,SAAS,KAAK,GAAG;AACnB,UAAM,IAAI,qBAAqB;AAAA,EACjC;AAEA,SAAO;AACT;AAEA,eAAsB,kBAAkB,YAAiD;AACvF,MAAI,WAAW,MAAM,OAAO,CAAC,QAAQ,MAAM,OAAO;AAChD,WAAO;AAAA,MACL,aAAa,WAAW,eAAe;AAAA,MACvC,UAAU,mBAAmB;AAAA,MAC7B,cAAc,mBAAmB;AAAA,MACjC,cAAc,mBAAmB;AAAA,MACjC,cAAc,mBAAmB;AAAA,MACjC,cAAc,mBAAmB;AAAA,MACjC,aAAa,mBAAmB;AAAA,MAChC,aAAa,WAAW,MAAM;AAAA,MAC9B,SAAS,WAAW,MAAM;AAAA,MAC1B,QAAQ,WAAW,MAAM;AAAA,IAC3B;AAAA,EACF;AAEA;AAAA,IACE;AAAA,MACEC,IAAG,KAAKA,IAAG,KAAK,4BAA4B,CAAC;AAAA,MAC7CA,IAAG,IAAI,sDAAsD;AAAA,IAC/D,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,QAAM,cAAc,WAAW,cAC3B,WAAW,cACX;AAAA,IACE,MAAM,KAAK;AAAA,MACT,SAAS;AAAA,MACT,aAAa;AAAA,MACb,cAAc;AAAA,MACd,SAAS,OAAO;AACd,YAAI,CAAC,MAAM,KAAK,GAAG;AACjB,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAEJ,QAAM,WAAW;AAAA,IACf,MAAM,OAAO;AAAA,MACX,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,MACjC,SAAS;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,eACJ,aAAa,OACR;AAAA,IACC,MAAM,OAAO;AAAA,MACX,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,MACjC,SAAS;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,IACA;AAEN,QAAM,eACJ,aAAa,OACR;AAAA,IACC,MAAM,OAAO;AAAA,MACX,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,MACjC,SAAS;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,IACA,mBAAmB;AAEzB,QAAM,eAAe;AAAA,IACnB,MAAM,OAAO;AAAA,MACX,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,MACjC,SAAS;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,eAAe;AAAA,IACnB,MAAM,OAAO;AAAA,MACX,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,MACjC,SAAS;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,cAAc;AAAA,IAClB,MAAM,QAAQ;AAAA,MACZ,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,WAAW,SAAS,UACpC,WAAW,MAAM,UACjB;AAAA,IACE,MAAM,QAAQ;AAAA,MACZ,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,IACnC,CAAC;AAAA,EACH;AAEJ,QAAM,UAAU,WAAW,SAAS,MAChC,WAAW,MAAM,MACjB;AAAA,IACE,MAAM,QAAQ;AAAA,MACZ,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,IACnC,CAAC;AAAA,EACH;AAEJ,QAAMA,IAAG,KAAK,8BAA8B,CAAC;AAE7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,WAAW,MAAM;AAAA,EAC3B;AACF;;;AEzMA,OAAOC,WAAU;AAEV,SAAS,oBAAoB,aAAoC;AACtE,QAAM,UAAU,YAAY,KAAK;AAEjC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,OAAO,YAAY,MAAM;AACvC,WAAO;AAAA,EACT;AAEA,MAAI,YAAYA,MAAK,SAAS,OAAO,GAAG;AACtC,WAAO;AAAA,EACT;AAEA,MAAI,kBAAkB,KAAK,OAAO,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACtBA,OAAOC,WAAU;AACjB,OAAO,QAAQ;AACf,OAAOC,SAAQ;AACf,OAAO,SAAS;;;ACHhB,OAAOC,WAAU;AACjB,SAAS,qBAAqB;AAC9B,OAAO,QAAQ;AAER,SAAS,iBAAiB,SAAiB,aAA6B;AAC7E,SAAOA,MAAK,QAAQ,SAAS,WAAW;AAC1C;AAEO,SAAS,sBAA8B;AAC5C,QAAM,YAAYA,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAE7D,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,WAAW,cAAc;AAAA,IACtCA,MAAK,QAAQ,WAAW,iBAAiB;AAAA,IACzCA,MAAK,QAAQ,QAAQ,IAAI,GAAG,WAAW;AAAA,EACzC;AAEA,aAAW,aAAa,YAAY;AAClC,QAAI,GAAG,WAAW,SAAS,GAAG;AAC5B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,uCAAuC;AACzD;;;ADEA,SAAS,YAAY,OAAuB;AAC1C,SAAO,MAAM,MAAMC,MAAK,GAAG,EAAE,KAAK,GAAG;AACvC;AAEA,SAAS,cAAc,cAA+B;AACpD,SAAO,aAAa,SAAS,MAAM;AACrC;AAEA,SAAS,eAAe,cAA8B;AACpD,SAAO,aAAa,SAAS,MAAM,IAC/B,aAAa,MAAM,GAAG,CAAC,OAAO,MAAM,IACpC;AACN;AAEA,SAAS,qBAAqB,QAAkC;AAC9D,QAAM,eAAe,oBAAoB;AAEzC,MAAI,OAAO,aAAa,MAAM;AAC5B,WAAO;AAAA,MACLA,MAAK,KAAK,cAAc,MAAM,QAAQ;AAAA,MACtCA,MAAK,KAAK,cAAc,MAAM,OAAO,YAAY;AAAA,IACnD;AAAA,EACF;AAEA,SAAO,CAACA,MAAK,KAAK,cAAc,OAAO,UAAU,OAAO,YAAY,CAAC;AACvE;AAEA,eAAe,mBACb,WACA,UAAkB,WACC;AACnB,QAAM,UAAU,MAAMC,IAAG,QAAQ,WAAW;AAAA,IAC1C,eAAe;AAAA,EACjB,CAAC;AAED,QAAM,gBAAgB,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACzE,QAAM,UAAoB,CAAC;AAE3B,aAAW,SAAS,eAAe;AACjC,UAAM,YAAYD,MAAK,KAAK,WAAW,MAAM,IAAI;AAEjD,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,eAAe,MAAM,mBAAmB,WAAW,OAAO;AAChE,cAAQ,KAAK,GAAG,YAAY;AAC5B;AAAA,IACF;AAEA,YAAQ,KAAKA,MAAK,SAAS,SAAS,SAAS,CAAC;AAAA,EAChD;AAEA,SAAO;AACT;AAEA,SAAS,sBACP,cACA,QACS;AACT,MAAI,iBAAiB,oBAAoB;AACvC,WAAO,OAAO,iBAAiB;AAAA,EACjC;AAEA,MAAI,iBAAiB,2BAA2B;AAC9C,WAAO,OAAO,iBAAiB;AAAA,EACjC;AAEA,MAAI,aAAa,WAAW,UAAU,GAAG;AACvC,WAAO,OAAO,iBAAiB;AAAA,EACjC;AAEA,MAAI,aAAa,WAAW,KAAK,GAAG;AAClC,WAAO,OAAO,iBAAiB;AAAA,EACjC;AAEA,MAAI,aAAa,WAAW,SAAS,GAAG;AACtC,WAAO,OAAO,iBAAiB;AAAA,EACjC;AAEA,SAAO;AACT;AAEA,SAAS,cACP,YACA,sBACa;AACb,SAAO;AAAA,IACL,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,oBAAoB,eAAe,oBAAoB;AAAA,IACvD,YAAY,cAAc,oBAAoB;AAAA,EAChD;AACF;AAEA,SAAS,cAAc,aAA6B;AAClD,QAAM,UAAU,YACb,KAAK,EACL,YAAY,EACZ,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,EAAE;AAEpB,SAAO,WAAW;AACpB;AAEA,SAAS,gBAAwB;AAC/B,MAAI;AACF,WAAO,GAAG,SAAS,EAAE;AAAA,EACvB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,YAAY;AAAA,EACrD;AACF;AAEA,SAAS,aAAa,QAAiD;AACrE,QAAM,eAAe,OAAO,aAAa;AACzC,QAAM,QAAQ,OAAO,iBAAiB;AACtC,QAAM,eAAe,OAAO,aAAa;AACzC,QAAM,aAAa,gBAAgB,OAAO,iBAAiB;AAC3D,QAAM,aAAa,OAAO,iBAAiB;AAC3C,QAAM,WAAW,OAAO,iBAAiB;AACzC,QAAM,SAAS,OAAO,iBAAiB;AACvC,QAAM,SAAS,eAAe,OAAO,WAAW;AAChD,QAAM,WAAW,aAAa,cAAc,IAAI;AAEhD,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA,YAAY,CAAC;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,cAAc,OAAO,WAAW;AAAA,IAC7C,cAAc;AAAA,IACd,kBAAkB,OAAO,cAAc,OAAO;AAAA,IAC9C,eAAe,cAAc,OAAO,QAAQ;AAAA,IAC5C,mBAAmB,kBAAkB,OAAO,YAAY;AAAA,IACxD,mBAAmB,kBAAkB,OAAO,YAAY;AAAA,IACxD,eAAe,cAAc,OAAO,YAAY;AAAA,IAChD,mBAAmB,kBAAkB,OAAO,YAAY;AAAA,IACxD,cAAc,aACV,0BACA;AAAA,IACJ;AAAA,IACA,aACE,OAAO,iBAAiB,oBACpB,+CAA+C,MAAM,KACrD,cAAc,mBAAmB,QAAQ,CAAC,4BAA4B,MAAM;AAAA,IAClF,YAAY;AAAA,EACd;AACF;AAEA,SAAS,cAAc,cAA8B;AACnD,SAAO,aAAa,MAAM,GAAG,EAAE,KAAKA,MAAK,GAAG;AAC9C;AAEA,eAAsB,YACpB,QACA,WACyB;AACzB,QAAM,gBAAgB,qBAAqB,MAAM;AAEjD,aAAW,gBAAgB,eAAe;AACxC,UAAM,qBAAqB,MAAMC,IAAG,WAAW,YAAY;AAE3D,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAI,MAAM,4BAA4B,YAAY,EAAE;AAAA,IAC5D;AAAA,EACF;AAEA,QAAM,gBAAgB,oBAAI,IAAoB;AAE9C,aAAW,gBAAgB,eAAe;AACxC,UAAM,WAAW,MAAM,mBAAmB,YAAY;AAEtD,eAAW,QAAQ,UAAU;AAC3B,YAAM,eAAe,YAAY,IAAI;AACrC,YAAM,aAAaD,MAAK,KAAK,cAAc,cAAc,YAAY,CAAC;AACtE,oBAAc,IAAI,cAAc,UAAU;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,KAAK,cAAc,QAAQ,CAAC,EAC7C,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,OAAO,CAAC,CAAC,YAAY,MAAM,sBAAsB,cAAc,MAAM,CAAC,EACtE,IAAI,CAAC,CAAC,cAAc,UAAU,MAAM,cAAc,YAAY,YAAY,CAAC;AAE9E,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,MACP,6BAA6B,SAAS;AAAA,MACtC,SAAS,MAAM,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,SAAS;AACX,GAAkD;AAChD,QAAM,OAAO,MAAM,YAAY,QAAQ,SAAS;AAEhD,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAEA,QAAMC,IAAG,UAAU,SAAS;AAE5B,QAAM,OAAO,aAAa,MAAM;AAEhC,aAAW,QAAQ,KAAK,OAAO;AAC7B,UAAM,kBAAkBD,MAAK;AAAA,MAC3B;AAAA,MACA,cAAc,KAAK,kBAAkB;AAAA,IACvC;AAEA,UAAMC,IAAG,UAAUD,MAAK,QAAQ,eAAe,CAAC;AAEhD,QAAI,KAAK,YAAY;AACnB,YAAM,WAAW,MAAMC,IAAG,SAAS,KAAK,oBAAoB,MAAM;AAClE,YAAM,WAAW,IAAI,OAAO,UAAU,IAAI;AAC1C,YAAMA,IAAG,UAAU,iBAAiB,UAAU,MAAM;AACpD;AAAA,IACF;AAEA,UAAMA,IAAG,KAAK,KAAK,oBAAoB,eAAe;AAAA,EACxD;AAEA,SAAO;AACT;;;AE/PA,SAAS,aAAa;AAEtB,eAAsB,cAAc,SAAiB,OAAiB,CAAC,WAAW,GAAqB;AACrG,MAAI;AACF,UAAM,MAAM,SAAS,MAAM;AAAA,MACzB,OAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,WAAW,SAAiB,MAAgB,KAA4B;AAC5F,QAAM,MAAM,SAAS,MAAM;AAAA,IACzB;AAAA,IACA,OAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,oBAAoB,KAAa,UAAU,OAAsB;AACrF,QAAM,OAAO,CAAC,WAAW,cAAc,WAAW;AAElD,MAAI,CAAC,SAAS;AACZ,SAAK,KAAK,kBAAkB;AAAA,EAC9B;AAEA,QAAM,WAAW,OAAO,MAAM,GAAG;AACnC;AAEA,eAAsB,YAAY,KAA4B;AAC5D,QAAM,WAAW,OAAO,CAAC,MAAM,GAAG,GAAG;AACvC;;;AChCA,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AAEf,eAAsB,oBAAoB,WAAkC;AAC1E,QAAM,SAAS,MAAMA,IAAG,WAAW,SAAS;AAE5C,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,QAAM,QAAQ,MAAMA,IAAG,KAAK,SAAS;AAErC,MAAI,CAAC,MAAM,YAAY,GAAG;AACxB,UAAM,IAAI,MAAM,sDAAsD,SAAS,EAAE;AAAA,EACnF;AAEA,QAAM,UAAU,MAAMA,IAAG,QAAQ,SAAS;AAC1C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI;AAAA,MACR,qBAAqBD,MAAK,SAAS,SAAS,CAAC;AAAA,IAC/C;AAAA,EACF;AACF;;;ACpBO,IAAM,SAAS;AAAA,EACpB,KAAK,SAAuB;AAC1B,YAAQ,IAAI,GAAG,UAAU,MAAM,CAAC,IAAI,OAAO,EAAE;AAAA,EAC/C;AAAA,EACA,QAAQ,SAAuB;AAC7B,YAAQ,IAAI,GAAG,UAAU,SAAS,CAAC,IAAI,OAAO,EAAE;AAAA,EAClD;AAAA,EACA,KAAK,SAAuB;AAC1B,YAAQ,KAAK,GAAG,UAAU,MAAM,CAAC,IAAI,OAAO,EAAE;AAAA,EAChD;AAAA,EACA,MAAM,SAAuB;AAC3B,YAAQ,MAAM,GAAG,UAAU,OAAO,CAAC,IAAI,OAAO,EAAE;AAAA,EAClD;AACF;;;AbCA,eAAe,sBAAqC;AAClD,QAAM,UAAU,MAAM,cAAc,QAAQ,CAAC,WAAW,CAAC;AAEzD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,QACE;AAAA,QACA;AAAA,MACF,EAAE,KAAK,GAAG;AAAA,IACZ;AAAA,EACF;AACF;AAEA,SAAS,wBAA8B;AACrC,UAAQ,GAAG,UAAU,MAAM;AACzB,WAAO,KAAK,oBAAoB;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;AAEA,eAAe,OAAO,MAA+B;AACnD,QAAM,aAAa,UAAU,IAAI;AAEjC,aAAW,eAAe,WAAW,cAAc;AACjD,WAAO,KAAK,iBAAiB,WAAW,gBAAgB;AAAA,EAC1D;AAEA,QAAM,aAAa,MAAM,kBAAkB,UAAU;AAErD,QAAM,mBAAmB,oBAAoB,WAAW,WAAW;AAEnE,MAAI,kBAAkB;AACpB,UAAM,IAAI,MAAM,gBAAgB;AAAA,EAClC;AAEA,QAAM,YAAY,iBAAiB,QAAQ,IAAI,GAAG,WAAW,WAAW;AAExE,QAAM,oBAAoB,SAAS;AAEnC,MAAI,WAAW,iBAAiB,iBAAiB;AAC/C,UAAM,oBAAoB;AAAA,EAC5B;AAEA,QAAM,iBAAiB;AAAA,IACrB,aAAa,WAAW;AAAA,IACxB,UAAU,WAAW;AAAA,IACrB,cAAc,WAAW;AAAA,IACzB,cAAc,WAAW;AAAA,IACzB,cAAc,WAAW;AAAA,IACzB,aAAa,WAAW;AAAA,IACxB,cAAc,WAAW;AAAA,EAC3B;AAEA,QAAM,OAAO,MAAM,YAAY,gBAAgB,SAAS;AAExD,MAAI,WAAW,QAAQ;AACrB,oBAAgB,YAAY,IAAI;AAChC;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAED,QAAM,kBAAkBE,MAAK,KAAK,WAAW,cAAc;AAC3D,MAAI,CAACC,IAAG,WAAW,eAAe,GAAG;AACnC,UAAM,IAAI;AAAA,MACR;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,GAAG;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,QAAQ,8BAA8B,SAAS,GAAG;AAEzD,MAAI,WAAW,aAAa;AAC1B,UAAM,iBAAiB,WAAW,MAAM,UACpC,qCACA;AACJ,WAAO,KAAK,4BAA4B,cAAc,MAAM;AAC5D,UAAM,oBAAoB,WAAW,WAAW,MAAM,OAAO;AAC7D,WAAO,QAAQ,yBAAyB;AAAA,EAC1C,OAAO;AACL,WAAO,KAAK,kCAAkC;AAAA,EAChD;AAEA,MAAI,WAAW,SAAS;AACtB,WAAO,KAAK,gCAAgC;AAC5C,UAAM,YAAY,SAAS;AAC3B,WAAO,QAAQ,6BAA6B;AAAA,EAC9C,OAAO;AACL,WAAO,KAAK,6BAA6B;AAAA,EAC3C;AAEA,SAAO,QAAQ,uBAAuB;AACtC,iBAAe,UAAU;AAC3B;AAEA,SAAS,kBAA2B;AAClC,MAAI,OAAO,QAAQ,KAAK,CAAC,MAAM,UAAU;AACvC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,WAAWA,IAAG,aAAa,QAAQ,KAAK,CAAC,CAAC;AAChD,UAAM,aAAaA,IAAG,aAAaC,eAAc,YAAY,GAAG,CAAC;AACjE,WAAO,aAAa;AAAA,EACtB,QAAQ;AACN,WAAO,cAAc,QAAQ,KAAK,CAAC,CAAC,EAAE,SAAS,YAAY;AAAA,EAC7D;AACF;AAEA,IAAM,eAAe,gBAAgB;AAErC,IAAI,cAAc;AAChB,wBAAsB;AAEtB,SAAO,QAAQ,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,UAAmB;AACtD,QAAI,iBAAiB,sBAAsB;AACzC,aAAO,KAAK,oBAAoB;AAChC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,MAAM,OAAO;AACpB,QAAI,iBAAiB,SAAS,MAAM,OAAO;AACzC,cAAQ,MAAMC,IAAG,KAAK,MAAM,KAAK,CAAC;AAAA,IACpC;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","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"]}
|
package/package.json
CHANGED