create-kerf-component 0.15.2 → 0.15.3

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 +3 -2
  2. package/index.js +56 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -13,8 +13,9 @@ npm install
13
13
  npm run build
14
14
  ```
15
15
 
16
- Pass `.` to scaffold into the current directory. The target directory's basename
17
- is used as the package name.
16
+ Run it with **no argument** (`npm create kerf-component`) and it prompts for the
17
+ directory. Pass `.` to scaffold into the current directory. The target
18
+ directory's basename is used as the package name.
18
19
 
19
20
  ## What you get
20
21
 
package/index.js CHANGED
@@ -12,21 +12,54 @@
12
12
  // npx create-kerf-component <dir>
13
13
  //
14
14
  // <dir> is the target directory; its basename is the default package name (pass
15
- // `.` to scaffold into the current directory). No third-party dependencies the
15
+ // `.` to scaffold into the current directory). Run with NO argument and it
16
+ // prompts for the directory (or reads it from piped stdin) — `npm create
17
+ // kerf-component` alone just works. No third-party dependencies — the
16
18
  // initializer is plain Node so `npm create` runs it with zero install latency.
17
19
 
18
20
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
19
21
  import { basename, dirname, join, resolve } from 'node:path';
22
+ import { createInterface } from 'node:readline/promises';
20
23
  import { fileURLToPath } from 'node:url';
21
24
 
22
25
  const TEMPLATE_DIR = join(dirname(fileURLToPath(import.meta.url)), 'template');
23
26
  const TOKEN = /__PKG_NAME__/g;
27
+ const DEFAULT_NAME = 'my-kerf-component';
24
28
 
25
29
  function fail(msg) {
26
30
  process.stderr.write(`create-kerf-component: ${msg}\n`);
27
31
  process.exit(1);
28
32
  }
29
33
 
34
+ const USAGE =
35
+ 'Usage: npm create kerf-component@latest <dir>\n' +
36
+ ' (or: npx create-kerf-component <dir>)\n\n' +
37
+ 'Scaffolds a kerf component package into <dir>. Pass `.` for the current directory.\n';
38
+
39
+ // Ask for the target directory when none was passed. `npm create kerf-component`
40
+ // (no arg) is the most natural invocation, so prompt rather than error.
41
+ async function promptForTarget() {
42
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
43
+ try {
44
+ const answer = await rl.question(`Directory (\`.\` for current) [${DEFAULT_NAME}]: `);
45
+ return answer.trim() || DEFAULT_NAME;
46
+ } finally {
47
+ rl.close();
48
+ }
49
+ }
50
+
51
+ // Non-TTY fallback: read the first line of piped stdin (scripted/test input).
52
+ // Resolves null if the stream closes without a line.
53
+ async function readFirstLine() {
54
+ const rl = createInterface({ input: process.stdin });
55
+ try {
56
+ for await (const line of rl) return line;
57
+ return null;
58
+ } finally {
59
+ rl.close();
60
+ }
61
+ }
62
+
30
63
  // npm package name rules, trimmed to what we actually need to guard: no spaces,
31
64
  // no uppercase, no leading dot/underscore, URL-safe. (Scoped names like
32
65
  // `@scope/name` are allowed.)
@@ -45,15 +78,27 @@ function walk(dir) {
45
78
  return out;
46
79
  }
47
80
 
48
- function main(argv) {
49
- const target = argv[2];
50
- if (target == null || target === '' || target === '--help' || target === '-h') {
51
- process.stdout.write(
52
- 'Usage: npm create kerf-component@latest <dir>\n' +
53
- ' (or: npx create-kerf-component <dir>)\n\n' +
54
- 'Scaffolds a kerf component package into <dir>. Pass `.` for the current directory.\n',
55
- );
56
- process.exit(target == null || target === '' ? 1 : 0);
81
+ async function main(argv) {
82
+ let target = argv[2];
83
+
84
+ if (target === '--help' || target === '-h') {
85
+ process.stdout.write(USAGE);
86
+ process.exit(0);
87
+ }
88
+
89
+ if (target == null || target === '') {
90
+ // No directory given. Prompt interactively when attached to a terminal (the
91
+ // `npm create kerf-component` happy path); when stdin is piped (scripts/CI),
92
+ // take the first piped line; if there's nothing to read, print usage + fail.
93
+ if (process.stdin.isTTY) {
94
+ target = await promptForTarget();
95
+ } else {
96
+ target = ((await readFirstLine()) ?? '').trim();
97
+ }
98
+ if (target === '') {
99
+ process.stderr.write(USAGE);
100
+ process.exit(1);
101
+ }
57
102
  }
58
103
 
59
104
  const targetDir = resolve(process.cwd(), target);
@@ -96,4 +141,4 @@ function main(argv) {
96
141
  );
97
142
  }
98
143
 
99
- main(process.argv);
144
+ main(process.argv).catch((err) => fail(err?.message ?? String(err)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kerf-component",
3
- "version": "0.15.2",
3
+ "version": "0.15.3",
4
4
  "description": "Scaffold a publishable kerf component package that already follows kerf's hard packaging rules.",
5
5
  "type": "module",
6
6
  "license": "MIT",