create-daloy 0.1.23 → 0.1.24
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/bin/create-daloy.mjs +53 -12
- package/package.json +1 -1
package/bin/create-daloy.mjs
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
// Zero runtime dependencies; uses only Node built-ins.
|
|
4
4
|
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
6
|
+
import { existsSync, openSync } from "node:fs";
|
|
7
7
|
import { mkdir, readdir, readFile, writeFile, copyFile, rm } from "node:fs/promises";
|
|
8
8
|
import { createInterface } from "node:readline/promises";
|
|
9
9
|
import { stdin as input, stdout as output } from "node:process";
|
|
10
|
+
import { ReadStream as TtyReadStream } from "node:tty";
|
|
10
11
|
import path from "node:path";
|
|
11
12
|
import { fileURLToPath } from "node:url";
|
|
12
13
|
|
|
@@ -794,9 +795,43 @@ function runQuiet(cmd, args, cwd) {
|
|
|
794
795
|
//
|
|
795
796
|
// `ask`/`askYesNo` use readline for resilience (paste, history, multi-line
|
|
796
797
|
// input). `askChoice` upgrades to raw-mode arrow-key navigation when stdin is
|
|
797
|
-
// a TTY
|
|
798
|
+
// a TTY. When package-manager wrappers hide raw mode on process.stdin (pnpm
|
|
799
|
+
// does this on some terminals), we reopen the controlling TTY directly before
|
|
800
|
+
// falling back to the numbered prompt used by the readline-driven tests.
|
|
798
801
|
// ----------------------------------------------------------------------------
|
|
799
802
|
|
|
803
|
+
function choiceInputMode({ stdinIsTTY, hasRawMode, platform }) {
|
|
804
|
+
if (stdinIsTTY && hasRawMode) return "stdin";
|
|
805
|
+
if (platform !== "win32") return "tty";
|
|
806
|
+
return "numbered";
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
function openChoiceInputStream() {
|
|
810
|
+
const mode = choiceInputMode({
|
|
811
|
+
stdinIsTTY: process.stdin.isTTY,
|
|
812
|
+
hasRawMode: typeof process.stdin.setRawMode === "function",
|
|
813
|
+
platform: process.platform,
|
|
814
|
+
});
|
|
815
|
+
if (mode === "stdin") {
|
|
816
|
+
return { stream: process.stdin, dispose: () => {} };
|
|
817
|
+
}
|
|
818
|
+
if (mode !== "tty") return null;
|
|
819
|
+
try {
|
|
820
|
+
const fd = openSync("/dev/tty", "r");
|
|
821
|
+
const stream = new TtyReadStream(fd);
|
|
822
|
+
if (!stream.isTTY || typeof stream.setRawMode !== "function") {
|
|
823
|
+
stream.destroy();
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
return {
|
|
827
|
+
stream,
|
|
828
|
+
dispose: () => stream.destroy(),
|
|
829
|
+
};
|
|
830
|
+
} catch {
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
800
835
|
function printPromptHeader(question) {
|
|
801
836
|
console.log(`${color(COLORS.cyan, SYMBOLS.stepActive)} ${color(COLORS.bold, question)}`);
|
|
802
837
|
}
|
|
@@ -842,8 +877,9 @@ function optionDescription(option) {
|
|
|
842
877
|
// Arrow-key powered choice prompt. Falls back to numbered input whenever raw
|
|
843
878
|
// mode is unavailable (CI, piped stdin, integration tests).
|
|
844
879
|
async function askChoice(rl, question, choices, defaultChoice) {
|
|
845
|
-
const
|
|
846
|
-
if (!
|
|
880
|
+
const rawInputHandle = openChoiceInputStream();
|
|
881
|
+
if (!rawInputHandle) return askChoiceNumbered(rl, question, choices, defaultChoice);
|
|
882
|
+
const rawInput = rawInputHandle.stream;
|
|
847
883
|
|
|
848
884
|
printPromptHeader(question);
|
|
849
885
|
printRailLine(color(COLORS.dim, `Use \u2191 \u2193 to navigate, Enter to confirm, type a number to jump.`));
|
|
@@ -875,9 +911,9 @@ async function askChoice(rl, question, choices, defaultChoice) {
|
|
|
875
911
|
|
|
876
912
|
// Pause readline so it doesn't fight us for stdin while we're in raw mode.
|
|
877
913
|
rl.pause();
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
914
|
+
rawInput.setRawMode(true);
|
|
915
|
+
rawInput.resume();
|
|
916
|
+
rawInput.setEncoding("utf8");
|
|
881
917
|
|
|
882
918
|
// Initial render
|
|
883
919
|
process.stdout.write(render(index) + "\n");
|
|
@@ -891,9 +927,10 @@ async function askChoice(rl, question, choices, defaultChoice) {
|
|
|
891
927
|
process.stdout.write(render(newIndex) + "\n");
|
|
892
928
|
}
|
|
893
929
|
function cleanup() {
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
930
|
+
rawInput.removeListener("data", onData);
|
|
931
|
+
rawInput.setRawMode(false);
|
|
932
|
+
rawInput.pause();
|
|
933
|
+
rawInputHandle.dispose();
|
|
897
934
|
}
|
|
898
935
|
function onData(chunk) {
|
|
899
936
|
const data = chunk.toString();
|
|
@@ -934,7 +971,7 @@ async function askChoice(rl, question, choices, defaultChoice) {
|
|
|
934
971
|
rerender(index);
|
|
935
972
|
}
|
|
936
973
|
}
|
|
937
|
-
|
|
974
|
+
rawInput.on("data", onData);
|
|
938
975
|
});
|
|
939
976
|
|
|
940
977
|
// Replace the rendered list with a single confirmation line.
|
|
@@ -1272,4 +1309,8 @@ async function main() {
|
|
|
1272
1309
|
}
|
|
1273
1310
|
}
|
|
1274
1311
|
|
|
1275
|
-
|
|
1312
|
+
if (process.env.DALOY_TEST_IMPORT !== "1") {
|
|
1313
|
+
await main();
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
export { choiceInputMode };
|
package/package.json
CHANGED