create-kerf-component 0.15.2 → 0.15.4
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 +3 -2
- package/index.js +56 -11
- 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
|
-
|
|
17
|
-
|
|
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).
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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)));
|