create-rigg 0.0.4 → 0.0.6

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.
Files changed (3) hide show
  1. package/README.md +11 -6
  2. package/dist/index.mjs +86 -53
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # rigg
2
2
 
3
+ <p>
4
+ <a href="https://npmx.dev/package/create-rigg"><img src="https://npmx.dev/api/registry/badge/version/create-rigg" alt="Version"></a>
5
+ <a href="https://www.npmjs.com/package/create-rigg"><img src="https://img.shields.io/npm/v/create-rigg.svg" alt="Version"></a>
6
+ </p>
7
+
3
8
  **The Unified Toolchain Starter for Node.js**
4
9
 
5
- Creates a new Node.js TypeScript project using the same opinionated toolchain as [Vite+](https://github.com/voidzero-dev/vite-plus), but for backend and non-web projects.
10
+ Creates a new Node.js TypeScript project using mostly the same toolchain as [Vite+](https://github.com/voidzero-dev/vite-plus), but for backend and non-web projects.
6
11
 
7
12
  ## Create a new project with rigg
8
13
 
@@ -20,17 +25,17 @@ The project follows most of the same toolchain as Vite+.
20
25
  | [Vitest](https://vitest.dev) | Testing |
21
26
  | [Oxlint](https://oxc.rs/docs/guide/usage/linter) | Linting |
22
27
  | [Oxfmt](https://oxc.rs/docs/guide/usage/formatter) | Formatting |
23
- | [tsdown](https://tsdown.dev) | Build & bundle |
24
28
  | [tsx](https://tsx.is) | Dev-mode execution |
29
+ | [tsdown](https://tsdown.dev) | Build |
25
30
 
26
- ## Backend framework
31
+ ### Backend framework
27
32
 
28
33
  You can also choose one of the following backend frameworks:
29
34
 
30
- - **None** — where you don't need a API framework, or you want to pick your own.
31
35
  - **Hono** — lightweight, modern API framework
32
36
  - **Fastify** — fast and low overhead
33
37
  - **Express** — familiar and widely supported
38
+ - **None** — where you don't need a API framework, or you want to pick your own.
34
39
 
35
40
  ## Scripts
36
41
 
@@ -38,7 +43,7 @@ Every generated project includes:
38
43
 
39
44
  ```bash
40
45
  pnpm dev # Run with tsx (no build step)
41
- pnpm build # Bundle with tsdown
46
+ pnpm build # Build with tsdown
42
47
  pnpm test # Run Vitest
43
48
  pnpm check # Lint + format check + type check
44
49
  pnpm fmt # Format
@@ -47,7 +52,7 @@ pnpm lint # Lint
47
52
  pnpm lint:fix # Lint with auto-fix
48
53
  ```
49
54
 
50
- The `pnpm` commands are just examples, you can also use `npm` or `yarn` or `bun` (depending on your package manager).
55
+ You can also use `npm` or `yarn` or `bun`, depending on your package manager.
51
56
 
52
57
  ## License
53
58
 
package/dist/index.mjs CHANGED
@@ -133,8 +133,11 @@ function run(cmd, args, opts) {
133
133
  stdio: "ignore",
134
134
  ...opts
135
135
  });
136
- if (result.status != null && result.status !== 0) process.exit(result.status);
137
136
  if (result.error) throw result.error;
137
+ if (result.status != null && result.status !== 0) {
138
+ p.cancel(`${cmd} ${args.join(" ")} failed with exit code ${result.status}`);
139
+ process.exit(result.status);
140
+ }
138
141
  }
139
142
  /** Recursively copies a directory, renaming _gitignore to .gitignore. */
140
143
  function copyDir(src, dest) {
@@ -152,9 +155,8 @@ function isEmpty(dir) {
152
155
  const files = fs.readdirSync(dir);
153
156
  return files.length === 0 || files.length === 1 && files[0] === ".git";
154
157
  }
155
- /** Prompts for a project name, or reads it from the first CLI argument. */
156
- async function promptProjectName(argv) {
157
- const fromArg = argv._[0] ?? "";
158
+ /** Resolves the project name from the CLI arg or prompts the user. */
159
+ async function resolveProjectName(fromArg) {
158
160
  if (fromArg) return fromArg;
159
161
  const answer = await p.text({
160
162
  message: "Project name:",
@@ -167,10 +169,9 @@ async function promptProjectName(argv) {
167
169
  }
168
170
  return answer || "rigg-project";
169
171
  }
170
- /** Prompts for a backend framework, or reads it from the --template flag. */
171
- async function promptFramework(argv) {
172
- const templateArg = argv.template;
173
- if (templateArg && FRAMEWORK_DEPS[templateArg]) return templateArg;
172
+ /** Resolves the framework from the --framework flag or prompts the user. */
173
+ async function resolveFramework(fromArg) {
174
+ if (fromArg && FRAMEWORK_DEPS[fromArg]) return fromArg;
174
175
  const answer = await p.select({
175
176
  message: "Backend framework:",
176
177
  options: FRAMEWORKS,
@@ -199,18 +200,20 @@ async function confirmOverwrite(projectName, targetDir) {
199
200
  });
200
201
  }
201
202
  /** Copies the base template, sets the package name, and writes the framework starter code. */
202
- function scaffoldFiles(projectName, framework, targetDir) {
203
+ function scaffoldFiles(options, targetDir) {
203
204
  const directory = path.dirname(fileURLToPath(import.meta.url));
204
205
  copyDir(path.join(directory, "..", "template"), targetDir);
205
206
  const pkgJsonPath = path.join(targetDir, "package.json");
206
207
  const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
207
- pkg.name = projectName;
208
+ pkg.name = options.projectName;
208
209
  fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + "\n");
209
210
  fs.mkdirSync(path.join(targetDir, "src"), { recursive: true });
210
- fs.writeFileSync(path.join(targetDir, "src", "index.ts"), FRAMEWORK_INDEX[framework]);
211
+ fs.writeFileSync(path.join(targetDir, "src", "index.ts"), FRAMEWORK_INDEX[options.framework]);
211
212
  }
212
213
  /** Installs shared dev dependencies and any framework-specific packages. */
213
- function installDependencies(pkgManager, framework, targetDir) {
214
+ function installDependencies(options, targetDir) {
215
+ const { pkgManager, framework, verbose } = options;
216
+ const stdio = verbose ? "inherit" : "ignore";
214
217
  p.log.step(`Installing dependencies with ${gradient(pkgManager, [[
215
218
  168,
216
219
  85,
@@ -228,8 +231,10 @@ function installDependencies(pkgManager, framework, targetDir) {
228
231
  "tsx",
229
232
  "typescript",
230
233
  "vitest"
231
- ], true), { cwd: targetDir });
232
- /** Install framework dependencies */
234
+ ], true), {
235
+ cwd: targetDir,
236
+ stdio
237
+ });
233
238
  if (framework !== "none") {
234
239
  p.log.step(`Installing ${gradient(FRAMEWORK_LABELS[framework], [[
235
240
  168,
@@ -240,34 +245,19 @@ function installDependencies(pkgManager, framework, targetDir) {
240
245
  102,
241
246
  241
242
247
  ]])}...`);
243
- const frameworkDeps = FRAMEWORK_DEPS[framework];
244
- if (frameworkDeps.deps.length > 0) run(pkgManager, addArgs(pkgManager, frameworkDeps.deps, false), { cwd: targetDir });
245
- if (frameworkDeps.devDeps.length > 0) run(pkgManager, addArgs(pkgManager, frameworkDeps.devDeps, true), { cwd: targetDir });
248
+ const { deps, devDeps } = FRAMEWORK_DEPS[framework];
249
+ if (deps.length > 0) run(pkgManager, addArgs(pkgManager, deps, false), {
250
+ cwd: targetDir,
251
+ stdio
252
+ });
253
+ if (devDeps.length > 0) run(pkgManager, addArgs(pkgManager, devDeps, true), {
254
+ cwd: targetDir,
255
+ stdio
256
+ });
246
257
  }
247
258
  }
248
- /** Prints the gradient outro with next steps. */
249
- function showOutro(projectName, framework, pkgManager) {
250
- const frameworkLabel = FRAMEWORK_LABELS[framework];
251
- const outroStops = [[
252
- 168,
253
- 85,
254
- 247
255
- ], [
256
- 99,
257
- 102,
258
- 241
259
- ]];
260
- const outroText = frameworkLabel !== "None" ? `Created ${projectName} with ${frameworkLabel}` : `Created ${projectName}`;
261
- const nameStart = 8;
262
- const outro = gradient(outroText, outroStops, [nameStart, nameStart + projectName.length]);
263
- const devCmd = pkgManager === "npm" ? "npm run dev" : `${pkgManager} dev`;
264
- p.outro(`${outro}\n\n ${pc.dim("Now run:")}\n cd ${projectName}\n ${devCmd}`);
265
- }
266
- async function main() {
267
- const argv = mri(process.argv.slice(2), {
268
- string: ["template", "pm"],
269
- alias: { t: "template" }
270
- });
259
+ /** Prints the gradient intro. */
260
+ function showIntro() {
271
261
  p.intro(pc.bold(gradient("rigg - The Unified Toolchain Starter for Node.js", [
272
262
  [
273
263
  255,
@@ -285,23 +275,49 @@ async function main() {
285
275
  241
286
276
  ]
287
277
  ], [0, 6])));
288
- const projectName = await promptProjectName(argv);
289
- const targetDir = path.resolve(process.cwd(), projectName);
290
- const pkgManager = argv.pm ?? detectPkgManager();
291
- await confirmOverwrite(projectName, targetDir);
292
- const framework = await promptFramework(argv);
293
- scaffoldFiles(projectName, framework, targetDir);
278
+ }
279
+ /** Prints the gradient outro with next steps. */
280
+ function showOutro(options) {
281
+ const { projectName, framework, pkgManager } = options;
282
+ const frameworkLabel = FRAMEWORK_LABELS[framework];
283
+ const title = gradient(frameworkLabel !== "None" ? `Created ${projectName} with ${frameworkLabel}` : `Created ${projectName}`, [[
284
+ 168,
285
+ 85,
286
+ 247
287
+ ], [
288
+ 99,
289
+ 102,
290
+ 241
291
+ ]], [8, 8 + projectName.length]);
292
+ const devCmd = pkgManager === "npm" ? "npm run dev" : `${pkgManager} dev`;
293
+ p.outro(`${title}\n\n ${pc.dim("Now run:")}\n cd ${projectName}\n ${devCmd}`);
294
+ }
295
+ /** Takes the CLI args and resolves all inputs into a single options object. */
296
+ async function resolveOptions(argv) {
297
+ const projectName = await resolveProjectName(argv._[0]);
298
+ await confirmOverwrite(projectName, path.resolve(process.cwd(), projectName));
299
+ return {
300
+ projectName,
301
+ framework: await resolveFramework(argv.framework),
302
+ pkgManager: argv.pm || detectPkgManager(),
303
+ verbose: argv.verbose ?? false
304
+ };
305
+ }
306
+ function initializeGit(options, targetDir) {
307
+ p.log.step("Initializing git repository");
294
308
  run("git", [
295
309
  "init",
296
310
  "-b",
297
311
  "main"
298
312
  ], {
299
313
  cwd: targetDir,
300
- stdio: "ignore"
314
+ stdio: options.verbose ? "inherit" : "ignore"
301
315
  });
302
- p.log.step("Initializing git repository");
303
- installDependencies(pkgManager, framework, targetDir);
316
+ }
317
+ function formatCode(options, targetDir) {
304
318
  p.log.step("Formatting code");
319
+ const { pkgManager, verbose } = options;
320
+ const stdio = verbose ? "inherit" : "ignore";
305
321
  const execCmd = pkgManager === "bun" ? "x" : "exec";
306
322
  const sep = pkgManager === "npm" || pkgManager === "yarn" ? ["--"] : [];
307
323
  run(pkgManager, [
@@ -311,7 +327,7 @@ async function main() {
311
327
  "--init"
312
328
  ], {
313
329
  cwd: targetDir,
314
- stdio: "ignore"
330
+ stdio
315
331
  });
316
332
  run(pkgManager, [
317
333
  execCmd,
@@ -320,7 +336,7 @@ async function main() {
320
336
  "--init"
321
337
  ], {
322
338
  cwd: targetDir,
323
- stdio: "ignore"
339
+ stdio
324
340
  });
325
341
  run(pkgManager, [
326
342
  execCmd,
@@ -329,9 +345,26 @@ async function main() {
329
345
  "."
330
346
  ], {
331
347
  cwd: targetDir,
332
- stdio: "ignore"
348
+ stdio
349
+ });
350
+ }
351
+ async function main() {
352
+ const argv = mri(process.argv.slice(2), {
353
+ string: ["framework", "pm"],
354
+ boolean: ["verbose"],
355
+ alias: {
356
+ f: "framework",
357
+ v: "verbose"
358
+ }
333
359
  });
334
- showOutro(projectName, framework, pkgManager);
360
+ showIntro();
361
+ const options = await resolveOptions(argv);
362
+ const targetDir = path.resolve(process.cwd(), options.projectName);
363
+ scaffoldFiles(options, targetDir);
364
+ initializeGit(options, targetDir);
365
+ installDependencies(options, targetDir);
366
+ formatCode(options, targetDir);
367
+ showOutro(options);
335
368
  }
336
369
  main().catch((err) => {
337
370
  console.error(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-rigg",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "The Unified Toolchain Starter for Node.js backend and non-web projects",
5
5
  "keywords": [
6
6
  "backend",
@@ -43,7 +43,7 @@
43
43
  "check": "oxlint && oxfmt --check && tsc --noEmit",
44
44
  "dev": "tsx src/index.ts",
45
45
  "build": "tsdown src/index.ts",
46
- "prepublishOnly": "oxlint && oxfmt && tsc --noEmit && vitest run && pnpm build"
46
+ "prepublishOnly": "git diff --exit-code && git diff --cached --exit-code && oxlint && oxfmt && tsc --noEmit && vitest run && pnpm build"
47
47
  },
48
48
  "dependencies": {
49
49
  "@clack/prompts": "^1.1.0",