@doikayt/typescript-build-config 0.1.17 → 0.1.18
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/package.json +1 -1
- package/src/init.js +47 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doikayt/typescript-build-config",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Shared build configuration for TypeScript projects — ESLint, Prettier, tsconfig, and Playwright presets",
|
|
5
5
|
"_comments": {
|
|
6
6
|
"exports": "This block lists the config files that will be extended by files in in src/toplevel - which are copied to consuming project root folder. An example: eslint.config.js imports from '@doikayt/typescript-build-config/eslint'.",
|
package/src/init.js
CHANGED
|
@@ -42,38 +42,71 @@ function dirIsEmpty(dir) {
|
|
|
42
42
|
return !existsSync(dir) || readdirSync(dir).length === 0;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// Default interactive prompt.
|
|
46
|
-
|
|
45
|
+
// Default interactive prompt. Buffers input lines as they arrive and lets each
|
|
46
|
+
// question pull the next one, so it works with both a live terminal and piped /
|
|
47
|
+
// non-interactive stdin (scripts, CI). `rl.question` alone drops lines that
|
|
48
|
+
// arrive before the next call — with a pipe every line lands at once, which made
|
|
49
|
+
// init silently no-op. On EOF, unanswered prompts default to No. Injectable, so
|
|
50
|
+
// runInit stays testable without stdin.
|
|
51
|
+
function createAskYesNo() {
|
|
47
52
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
const lines = []; // input lines not yet consumed by a prompt
|
|
54
|
+
const waiters = []; // prompt resolvers waiting for the next line
|
|
55
|
+
let closed = false;
|
|
56
|
+
rl.on("line", (line) => {
|
|
57
|
+
const waiter = waiters.shift();
|
|
58
|
+
if (waiter) waiter(line);
|
|
59
|
+
else lines.push(line);
|
|
60
|
+
});
|
|
61
|
+
rl.on("close", () => {
|
|
62
|
+
closed = true;
|
|
63
|
+
while (waiters.length) waiters.shift()("");
|
|
64
|
+
});
|
|
65
|
+
const ask = (question) =>
|
|
66
|
+
new Promise((res) => {
|
|
67
|
+
process.stdout.write(question);
|
|
68
|
+
const answer = (line) => res(/^y(es)?$/i.test(line.trim()));
|
|
69
|
+
if (lines.length) answer(lines.shift());
|
|
70
|
+
else if (closed) answer("");
|
|
71
|
+
else waiters.push(answer);
|
|
72
|
+
});
|
|
73
|
+
ask.close = () => rl.close();
|
|
74
|
+
return ask;
|
|
54
75
|
}
|
|
55
76
|
|
|
56
77
|
export async function runInit({
|
|
57
78
|
cwd = process.cwd(),
|
|
58
|
-
prompt
|
|
79
|
+
prompt,
|
|
59
80
|
resolveDevVersions = resolveVersions,
|
|
60
81
|
log = console.log,
|
|
61
82
|
} = {}) {
|
|
83
|
+
// One readline interface for all prompts (see createAskYesNo); close it even
|
|
84
|
+
// on error so a leftover interface never keeps the process alive.
|
|
85
|
+
const ownAsk = prompt ? null : createAskYesNo();
|
|
86
|
+
const ask = prompt ?? ownAsk;
|
|
87
|
+
try {
|
|
88
|
+
return await collectAndScaffold({ cwd, ask, resolveDevVersions, log });
|
|
89
|
+
} finally {
|
|
90
|
+
ownAsk?.close();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function collectAndScaffold({ cwd, ask, resolveDevVersions, log }) {
|
|
62
95
|
const pkgPath = resolve(cwd, "package.json");
|
|
63
96
|
const raw = readFileSync(pkgPath, "utf8");
|
|
64
97
|
|
|
65
98
|
// Collect every answer up front, before doing any work or printing next
|
|
66
99
|
// steps, so the flow reads: ask everything → act → report.
|
|
67
|
-
const ui = await
|
|
100
|
+
const ui = await ask(
|
|
68
101
|
"Is this a UI project that needs Playwright (e2e)? Default is No. [y/N] ",
|
|
69
102
|
);
|
|
70
103
|
|
|
71
|
-
const library = await
|
|
72
|
-
"Is this a publishable library (published to npm)? Default is No
|
|
73
|
-
"app/CLI
|
|
104
|
+
const library = await ask(
|
|
105
|
+
"Is this a publishable library (published to npm)? Default is No\n" +
|
|
106
|
+
" — a non-library (an app/CLI) is marked private so it is never published. [y/N] ",
|
|
74
107
|
);
|
|
75
108
|
|
|
76
|
-
const wantDemo = await
|
|
109
|
+
const wantDemo = await ask(
|
|
77
110
|
"Scaffold a starter demo (minimal src module + README + project.json) so\n" +
|
|
78
111
|
"you can build, test, and release immediately? Default is No; existing\n" +
|
|
79
112
|
"files are never overwritten. [y/N] ",
|