@outfitter/cli 0.1.0-rc.1 → 0.1.0-rc.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.
- package/README.md +21 -32
- package/dist/actions.js +1 -1
- package/dist/borders/index.d.ts +3 -0
- package/dist/borders/index.js +13 -0
- package/dist/box/index.d.ts +4 -0
- package/dist/box/index.js +13 -0
- package/dist/cli.d.ts +2 -103
- package/dist/cli.js +4 -51
- package/dist/colors/index.d.ts +3 -0
- package/dist/colors/index.js +18 -0
- package/dist/command.d.ts +3 -37
- package/dist/command.js +5 -1
- package/dist/demo/index.d.ts +78 -0
- package/dist/demo/index.js +148 -0
- package/dist/demo/registry.d.ts +7 -0
- package/dist/demo/registry.js +28 -0
- package/dist/demo/renderers/borders.d.ts +7 -0
- package/dist/demo/renderers/borders.js +17 -0
- package/dist/demo/renderers/box.d.ts +7 -0
- package/dist/demo/renderers/box.js +18 -0
- package/dist/demo/renderers/colors.d.ts +7 -0
- package/dist/demo/renderers/colors.js +18 -0
- package/dist/demo/renderers/indicators.d.ts +7 -0
- package/dist/demo/renderers/indicators.js +17 -0
- package/dist/demo/renderers/list.d.ts +7 -0
- package/dist/demo/renderers/list.js +19 -0
- package/dist/demo/renderers/markdown.d.ts +7 -0
- package/dist/demo/renderers/markdown.js +18 -0
- package/dist/demo/renderers/progress.d.ts +7 -0
- package/dist/demo/renderers/progress.js +17 -0
- package/dist/demo/renderers/spinner.d.ts +7 -0
- package/dist/demo/renderers/spinner.js +19 -0
- package/dist/demo/renderers/table.d.ts +7 -0
- package/dist/demo/renderers/table.js +19 -0
- package/dist/demo/renderers/text.d.ts +7 -0
- package/dist/demo/renderers/text.js +16 -0
- package/dist/demo/renderers/tree.d.ts +7 -0
- package/dist/demo/renderers/tree.js +18 -0
- package/dist/demo/section.d.ts +5 -0
- package/dist/demo/section.js +23 -0
- package/dist/demo/templates.d.ts +4 -0
- package/dist/demo/templates.js +10 -0
- package/dist/demo/types.d.ts +3 -0
- package/dist/demo/types.js +8 -0
- package/dist/index.d.ts +5 -607
- package/dist/index.js +10 -44
- package/dist/input.d.ts +9 -123
- package/dist/input.js +2 -3
- package/dist/list/index.d.ts +3 -0
- package/dist/list/index.js +9 -0
- package/dist/output.d.ts +2 -68
- package/dist/output.js +4 -150
- package/dist/pagination.d.ts +1 -34
- package/dist/pagination.js +1 -1
- package/dist/preset/full.d.ts +14 -0
- package/dist/preset/full.js +41 -0
- package/dist/preset/standard.d.ts +11 -0
- package/dist/preset/standard.js +30 -0
- package/dist/prompt/confirm.d.ts +4 -0
- package/dist/prompt/confirm.js +9 -0
- package/dist/prompt/group.d.ts +4 -0
- package/dist/prompt/group.js +9 -0
- package/dist/prompt/index.d.ts +7 -0
- package/dist/prompt/index.js +32 -0
- package/dist/prompt/select.d.ts +4 -0
- package/dist/prompt/select.js +11 -0
- package/dist/prompt/text.d.ts +4 -0
- package/dist/prompt/text.js +11 -0
- package/dist/prompt/types.d.ts +3 -0
- package/dist/prompt/types.js +8 -0
- package/dist/prompt/validators.d.ts +2 -0
- package/dist/prompt/validators.js +8 -0
- package/dist/render/borders.d.ts +2 -0
- package/dist/render/borders.js +15 -0
- package/dist/render/box.d.ts +3 -0
- package/dist/render/box.js +23 -0
- package/dist/render/colors.d.ts +2 -0
- package/dist/render/colors.js +20 -0
- package/dist/render/date.d.ts +2 -0
- package/dist/render/date.js +12 -0
- package/dist/render/format-relative.d.ts +2 -0
- package/dist/render/format-relative.js +8 -0
- package/dist/render/format.d.ts +2 -0
- package/dist/render/format.js +10 -0
- package/dist/render/heading.d.ts +3 -0
- package/dist/render/heading.js +14 -0
- package/dist/render/index.d.ts +32 -0
- package/dist/render/index.js +235 -0
- package/dist/render/indicators.d.ts +2 -0
- package/dist/render/indicators.js +14 -0
- package/dist/render/json.d.ts +2 -0
- package/dist/render/json.js +10 -0
- package/dist/render/layout.d.ts +5 -0
- package/dist/render/layout.js +25 -0
- package/dist/render/list.d.ts +2 -0
- package/dist/render/list.js +8 -0
- package/dist/render/markdown.d.ts +2 -0
- package/dist/render/markdown.js +10 -0
- package/dist/render/progress.d.ts +2 -0
- package/dist/render/progress.js +8 -0
- package/dist/render/separator.d.ts +3 -0
- package/dist/render/separator.js +14 -0
- package/dist/render/shapes.d.ts +2 -0
- package/dist/render/shapes.js +35 -0
- package/dist/render/spinner.d.ts +2 -0
- package/dist/render/spinner.js +12 -0
- package/dist/render/stack.d.ts +3 -0
- package/dist/render/stack.js +38 -0
- package/dist/render/table.d.ts +3 -0
- package/dist/render/table.js +12 -0
- package/dist/render/text.d.ts +2 -0
- package/dist/render/text.js +27 -0
- package/dist/render/tree.d.ts +2 -0
- package/dist/render/tree.js +10 -0
- package/dist/render/types.d.ts +2 -0
- package/dist/render/types.js +1 -0
- package/dist/shared/@outfitter/cli-0ggcy7fa.js +20 -0
- package/dist/shared/@outfitter/cli-0psys2vm.js +7 -0
- package/dist/shared/@outfitter/cli-1bghjef6.js +352 -0
- package/dist/shared/@outfitter/cli-1kwbnt86.d.ts +45 -0
- package/dist/shared/@outfitter/cli-2g8bx1aq.d.ts +50 -0
- package/dist/shared/@outfitter/cli-33e97cjs.d.ts +42 -0
- package/dist/shared/@outfitter/cli-34fqr7bp.js +37 -0
- package/dist/shared/@outfitter/cli-3b7ed3rm.d.ts +97 -0
- package/dist/shared/@outfitter/cli-3dxmmy4c.d.ts +20 -0
- package/dist/shared/@outfitter/cli-3f12z5kf.d.ts +83 -0
- package/dist/shared/@outfitter/cli-3hp8qwx3.js +11 -0
- package/dist/shared/@outfitter/cli-3t2zaenc.d.ts +59 -0
- package/dist/shared/@outfitter/cli-4cb5g831.d.ts +147 -0
- package/dist/shared/@outfitter/cli-4w2a1rfy.d.ts +23 -0
- package/dist/shared/@outfitter/cli-4x6pqnez.js +20 -0
- package/dist/shared/@outfitter/cli-671sxkhj.js +146 -0
- package/dist/shared/@outfitter/cli-6bztk73z.d.ts +51 -0
- package/dist/shared/@outfitter/cli-6fxffp8k.js +1 -0
- package/dist/shared/@outfitter/cli-6j9qynm8.js +118 -0
- package/dist/shared/@outfitter/cli-6m988kh0.d.ts +61 -0
- package/dist/shared/@outfitter/cli-72kg550t.d.ts +53 -0
- package/dist/shared/@outfitter/cli-74ba31gz.js +134 -0
- package/dist/shared/@outfitter/cli-7gnrb8cr.js +214 -0
- package/dist/shared/@outfitter/cli-7na6p4fs.d.ts +59 -0
- package/dist/shared/@outfitter/cli-7nm6edvh.d.ts +17 -0
- package/dist/shared/@outfitter/cli-85fg2vr5.js +123 -0
- package/dist/shared/@outfitter/cli-8a8xrzhy.js +20 -0
- package/dist/shared/@outfitter/cli-8aa1vhdn.d.ts +119 -0
- package/dist/shared/@outfitter/cli-8bwaw3pz.js +7 -0
- package/dist/shared/@outfitter/cli-8j5k6mr3.js +71 -0
- package/dist/shared/@outfitter/cli-8rx4g3s5.d.ts +41 -0
- package/dist/shared/@outfitter/cli-8xsmsbbd.d.ts +223 -0
- package/dist/shared/@outfitter/cli-96b2p4td.d.ts +56 -0
- package/dist/shared/@outfitter/cli-9khk3cbq.d.ts +190 -0
- package/dist/shared/@outfitter/cli-9mtjjykw.js +67 -0
- package/dist/shared/@outfitter/cli-9nbyj2bt.js +128 -0
- package/dist/shared/@outfitter/cli-a4q87517.d.ts +64 -0
- package/dist/shared/@outfitter/cli-afhjqmg3.js +63 -0
- package/dist/shared/@outfitter/cli-an9j0h80.js +117 -0
- package/dist/shared/@outfitter/cli-ay411nbr.js +122 -0
- package/dist/shared/@outfitter/cli-b0tzqgnf.d.ts +132 -0
- package/dist/shared/@outfitter/cli-b5c2k0d7.js +39 -0
- package/dist/shared/@outfitter/cli-b5epywry.js +1 -0
- package/dist/shared/@outfitter/cli-bc17qeh2.js +19 -0
- package/dist/shared/@outfitter/cli-bcmcaz1b.js +23 -0
- package/dist/shared/@outfitter/cli-bf3vma4q.js +61 -0
- package/dist/shared/@outfitter/cli-c8q4f71g.js +144 -0
- package/dist/shared/@outfitter/cli-c9knfqn5.d.ts +30 -0
- package/dist/shared/@outfitter/cli-cf1xexgn.d.ts +53 -0
- package/dist/shared/@outfitter/cli-cf2s94s1.d.ts +42 -0
- package/dist/shared/@outfitter/cli-cs45xd6q.js +59 -0
- package/dist/shared/@outfitter/cli-d7jpshq5.d.ts +128 -0
- package/dist/shared/@outfitter/cli-d9ad0rqj.js +75 -0
- package/dist/shared/@outfitter/cli-daw296mv.js +61 -0
- package/dist/shared/@outfitter/cli-e5ms1y0x.d.ts +91 -0
- package/dist/shared/@outfitter/cli-e73v3qqy.d.ts +93 -0
- package/dist/shared/@outfitter/cli-efy6jfcj.js +52 -0
- package/dist/shared/@outfitter/cli-en6zn6sj.js +1 -0
- package/dist/shared/@outfitter/cli-ep2cvtk8.js +48 -0
- package/dist/shared/@outfitter/cli-evx7qcp1.d.ts +300 -0
- package/dist/shared/@outfitter/cli-f75h8e94.js +7 -0
- package/dist/shared/@outfitter/cli-fakncnjp.d.ts +106 -0
- package/dist/shared/@outfitter/cli-feb5j90n.js +94 -0
- package/dist/shared/@outfitter/cli-h20jc0bs.d.ts +66 -0
- package/dist/shared/@outfitter/cli-hnpbqmc8.d.ts +328 -0
- package/dist/shared/@outfitter/cli-j19a91ck.js +30 -0
- package/dist/shared/@outfitter/cli-j4n8gaf3.js +95 -0
- package/dist/shared/@outfitter/cli-jejfypgf.js +85 -0
- package/dist/shared/@outfitter/cli-jhcdwvpn.js +135 -0
- package/dist/shared/@outfitter/cli-jjemfdta.js +85 -0
- package/dist/shared/@outfitter/cli-kc84wmch.js +267 -0
- package/dist/shared/@outfitter/cli-ktqme80d.js +7 -0
- package/dist/shared/@outfitter/cli-mhamvbty.d.ts +34 -0
- package/dist/shared/@outfitter/cli-mq0jp15z.js +1 -0
- package/dist/shared/@outfitter/cli-mymyavvj.d.ts +26 -0
- package/dist/shared/@outfitter/cli-n17gt1dz.js +19 -0
- package/dist/shared/@outfitter/cli-n9dbh0hp.js +51 -0
- package/dist/shared/@outfitter/cli-nvvc92c8.js +128 -0
- package/dist/shared/@outfitter/cli-p1m5dhrs.js +169 -0
- package/dist/shared/@outfitter/cli-p38sfxyk.js +25 -0
- package/dist/shared/@outfitter/cli-p3dqm1vd.js +22 -0
- package/dist/shared/@outfitter/cli-p9j1phge.js +20 -0
- package/dist/shared/@outfitter/cli-pkxmzavm.js +62 -0
- package/dist/shared/@outfitter/cli-q8r6jarq.d.ts +24 -0
- package/dist/shared/@outfitter/cli-qj83y5wj.d.ts +71 -0
- package/dist/shared/@outfitter/cli-qjfc3j11.d.ts +112 -0
- package/dist/shared/@outfitter/cli-qp4cbhqr.js +70 -0
- package/dist/shared/@outfitter/cli-s0kkx9m1.d.ts +164 -0
- package/dist/shared/@outfitter/cli-snxj55n6.js +43 -0
- package/dist/shared/@outfitter/cli-swwxvjvm.d.ts +24 -0
- package/dist/shared/@outfitter/cli-sx67mmfx.d.ts +98 -0
- package/dist/shared/@outfitter/cli-tarpsa8a.js +30 -0
- package/dist/shared/@outfitter/cli-thvzhjd1.js +126 -0
- package/dist/shared/@outfitter/cli-tqewy503.d.ts +36 -0
- package/dist/shared/@outfitter/cli-ttt7r0j7.d.ts +253 -0
- package/dist/shared/@outfitter/cli-tvw1xrdj.js +20 -0
- package/dist/shared/@outfitter/cli-v1tzwxkt.js +32 -0
- package/dist/shared/@outfitter/cli-vd60dj65.js +1 -0
- package/dist/shared/@outfitter/cli-vp88gxev.js +279 -0
- package/dist/shared/@outfitter/cli-vstbkzky.d.ts +74 -0
- package/dist/shared/@outfitter/cli-vtg0sqk2.d.ts +54 -0
- package/dist/shared/@outfitter/cli-w5y3xepp.js +20 -0
- package/dist/shared/@outfitter/cli-x4cavvc0.js +1 -0
- package/dist/shared/@outfitter/cli-xep6v2c0.js +52 -0
- package/dist/shared/@outfitter/cli-xg5y5fhk.js +86 -0
- package/dist/shared/@outfitter/cli-xsaheemc.d.ts +248 -0
- package/dist/shared/@outfitter/cli-xvqtqjxk.js +82 -0
- package/dist/shared/@outfitter/cli-y25tt8nc.d.ts +48 -0
- package/dist/shared/@outfitter/cli-zact3325.js +152 -0
- package/dist/shared/@outfitter/cli-zx598p8q.d.ts +26 -0
- package/dist/streaming/ansi.d.ts +2 -0
- package/dist/streaming/ansi.js +8 -0
- package/dist/streaming/index.d.ts +4 -0
- package/dist/streaming/index.js +17 -0
- package/dist/streaming/spinner.d.ts +3 -0
- package/dist/streaming/spinner.js +10 -0
- package/dist/streaming/writer.d.ts +2 -0
- package/dist/streaming/writer.js +9 -0
- package/dist/table/index.d.ts +4 -0
- package/dist/table/index.js +13 -0
- package/dist/terminal/detection.d.ts +2 -0
- package/dist/terminal/detection.js +23 -0
- package/dist/terminal/index.d.ts +2 -0
- package/dist/terminal/index.js +24 -0
- package/dist/theme/context.d.ts +9 -0
- package/dist/theme/context.js +14 -0
- package/dist/theme/create.d.ts +8 -0
- package/dist/theme/create.js +12 -0
- package/dist/theme/index.d.ts +17 -0
- package/dist/theme/index.js +42 -0
- package/dist/theme/presets/bold.d.ts +8 -0
- package/dist/theme/presets/bold.js +12 -0
- package/dist/theme/presets/default.d.ts +8 -0
- package/dist/theme/presets/default.js +11 -0
- package/dist/theme/presets/index.d.ts +12 -0
- package/dist/theme/presets/index.js +24 -0
- package/dist/theme/presets/minimal.d.ts +8 -0
- package/dist/theme/presets/minimal.js +12 -0
- package/dist/theme/presets/rounded.d.ts +8 -0
- package/dist/theme/presets/rounded.js +12 -0
- package/dist/theme/resolve.d.ts +8 -0
- package/dist/theme/resolve.js +11 -0
- package/dist/theme/types.d.ts +7 -0
- package/dist/theme/types.js +1 -0
- package/dist/tree/index.d.ts +3 -0
- package/dist/tree/index.js +11 -0
- package/dist/types.d.ts +1 -252
- package/dist/types.js +1 -1
- package/package.json +228 -20
- package/dist/shared/@outfitter/cli-4yy82cmp.js +0 -20
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ANSI escape sequences for terminal control.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ANSI escape sequences for cursor and screen control.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { ANSI } from "@outfitter/cli/streaming";
|
|
12
|
+
*
|
|
13
|
+
* // Move cursor up 2 lines and clear
|
|
14
|
+
* process.stdout.write(ANSI.cursorUp(2) + ANSI.clearLine);
|
|
15
|
+
*
|
|
16
|
+
* // Hide cursor during animation
|
|
17
|
+
* process.stdout.write(ANSI.hideCursor);
|
|
18
|
+
* // ... do animation ...
|
|
19
|
+
* process.stdout.write(ANSI.showCursor);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare const ANSI: {
|
|
23
|
+
/** Move cursor up n lines */
|
|
24
|
+
readonly cursorUp: (n: number) => string;
|
|
25
|
+
/** Move cursor down n lines */
|
|
26
|
+
readonly cursorDown: (n: number) => string;
|
|
27
|
+
/** Move cursor right n columns */
|
|
28
|
+
readonly cursorRight: (n: number) => string;
|
|
29
|
+
/** Move cursor left n columns */
|
|
30
|
+
readonly cursorLeft: (n: number) => string;
|
|
31
|
+
/** Move cursor to beginning of line */
|
|
32
|
+
readonly cursorToStart: "\x1B[G";
|
|
33
|
+
/** Clear entire line */
|
|
34
|
+
readonly clearLine: "\x1B[2K";
|
|
35
|
+
/** Clear from cursor to end of screen */
|
|
36
|
+
readonly clearToEnd: "\x1B[0J";
|
|
37
|
+
/** Clear from cursor to beginning of screen */
|
|
38
|
+
readonly clearToStart: "\x1B[1J";
|
|
39
|
+
/** Clear entire screen */
|
|
40
|
+
readonly clearScreen: "\x1B[2J";
|
|
41
|
+
/** Hide cursor */
|
|
42
|
+
readonly hideCursor: "\x1B[?25l";
|
|
43
|
+
/** Show cursor */
|
|
44
|
+
readonly showCursor: "\x1B[?25h";
|
|
45
|
+
/** Save cursor position */
|
|
46
|
+
readonly saveCursor: "\x1B[s";
|
|
47
|
+
/** Restore cursor position */
|
|
48
|
+
readonly restoreCursor: "\x1B[u";
|
|
49
|
+
/** Carriage return (move to start of line) */
|
|
50
|
+
readonly carriageReturn: "\r";
|
|
51
|
+
/** New line */
|
|
52
|
+
readonly newLine: "\n";
|
|
53
|
+
};
|
|
54
|
+
export { ANSI };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
defaultTheme
|
|
4
|
+
} from "./cli-cs45xd6q.js";
|
|
5
|
+
import {
|
|
6
|
+
BORDERS,
|
|
7
|
+
init_borders
|
|
8
|
+
} from "./cli-85fg2vr5.js";
|
|
9
|
+
|
|
10
|
+
// packages/cli/src/theme/presets/rounded.ts
|
|
11
|
+
init_borders();
|
|
12
|
+
var roundedTheme = {
|
|
13
|
+
...defaultTheme,
|
|
14
|
+
name: "rounded",
|
|
15
|
+
border: "rounded",
|
|
16
|
+
borderChars: BORDERS.rounded,
|
|
17
|
+
treeGuide: "rounded"
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { roundedTheme };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// @bun
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/demo/templates.ts
|
|
3
|
+
var DEFAULT_EXAMPLES = {
|
|
4
|
+
success: "Operation completed",
|
|
5
|
+
warning: "Proceed with caution",
|
|
6
|
+
error: "Something went wrong",
|
|
7
|
+
info: "For your information",
|
|
8
|
+
primary: "Main content",
|
|
9
|
+
secondary: "Supporting text",
|
|
10
|
+
muted: "(optional)",
|
|
11
|
+
accent: "Highlighted item",
|
|
12
|
+
highlight: "Important",
|
|
13
|
+
link: "https://example.com",
|
|
14
|
+
destructive: "Delete forever",
|
|
15
|
+
subtle: "Fine print",
|
|
16
|
+
bold: "Strong emphasis",
|
|
17
|
+
italic: "Subtle emphasis",
|
|
18
|
+
underline: "Underlined text",
|
|
19
|
+
dim: "De-emphasized",
|
|
20
|
+
boxContent: "Hello, world!",
|
|
21
|
+
boxTitle: "Status",
|
|
22
|
+
spinnerMessage: "Loading...",
|
|
23
|
+
progressLabel: "Progress",
|
|
24
|
+
listItems: ["First item", "Second item", "Third item"],
|
|
25
|
+
tableData: [
|
|
26
|
+
{ id: 1, name: "Alice", status: "Active" },
|
|
27
|
+
{ id: 2, name: "Bob", status: "Pending" }
|
|
28
|
+
],
|
|
29
|
+
treeData: {
|
|
30
|
+
src: {
|
|
31
|
+
components: {
|
|
32
|
+
Button: null,
|
|
33
|
+
Input: null
|
|
34
|
+
},
|
|
35
|
+
utils: null
|
|
36
|
+
},
|
|
37
|
+
tests: null
|
|
38
|
+
},
|
|
39
|
+
markdownSample: `# Heading
|
|
40
|
+
|
|
41
|
+
Some **bold** and *italic* text.
|
|
42
|
+
|
|
43
|
+
Use \`npm install\` to install.`
|
|
44
|
+
};
|
|
45
|
+
function getExample(key, custom) {
|
|
46
|
+
if (custom?.[key] !== undefined) {
|
|
47
|
+
return custom[key];
|
|
48
|
+
}
|
|
49
|
+
return DEFAULT_EXAMPLES[key];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { DEFAULT_EXAMPLES, getExample };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/render/list.ts
|
|
3
|
+
function toLetter(n) {
|
|
4
|
+
return String.fromCharCode(96 + n);
|
|
5
|
+
}
|
|
6
|
+
function toRoman(n) {
|
|
7
|
+
const numerals = [
|
|
8
|
+
[10, "x"],
|
|
9
|
+
[9, "ix"],
|
|
10
|
+
[5, "v"],
|
|
11
|
+
[4, "iv"],
|
|
12
|
+
[1, "i"]
|
|
13
|
+
];
|
|
14
|
+
let result = "";
|
|
15
|
+
let remaining = n;
|
|
16
|
+
for (const [value, symbol] of numerals) {
|
|
17
|
+
while (remaining >= value) {
|
|
18
|
+
result += symbol;
|
|
19
|
+
remaining -= value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
function getMarker(style, depth, index, isChecked) {
|
|
25
|
+
switch (style) {
|
|
26
|
+
case "bullet":
|
|
27
|
+
return "\u2022";
|
|
28
|
+
case "dash":
|
|
29
|
+
return "-";
|
|
30
|
+
case "number":
|
|
31
|
+
if (depth === 0) {
|
|
32
|
+
return `${index + 1}.`;
|
|
33
|
+
}
|
|
34
|
+
if (depth === 1) {
|
|
35
|
+
return `${toLetter(index + 1)}.`;
|
|
36
|
+
}
|
|
37
|
+
return `${toRoman(index + 1)}.`;
|
|
38
|
+
case "checkbox":
|
|
39
|
+
return isChecked ? "\u2611" : "\u2610";
|
|
40
|
+
default: {
|
|
41
|
+
const _exhaustive = style;
|
|
42
|
+
return _exhaustive;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function renderList(items, options) {
|
|
47
|
+
const style = options?.style ?? "dash";
|
|
48
|
+
const checkedSet = options?.checked ?? new Set;
|
|
49
|
+
const baseIndent = options?.indent ?? 2;
|
|
50
|
+
const lines = [];
|
|
51
|
+
let _globalIndex = 0;
|
|
52
|
+
const renderItem = (item, currentIndent, depth, indexAtDepth, currentStyle) => {
|
|
53
|
+
const indentStr = " ".repeat(currentIndent);
|
|
54
|
+
const text = typeof item === "string" ? item : item.text;
|
|
55
|
+
let isChecked = false;
|
|
56
|
+
if (currentStyle === "checkbox") {
|
|
57
|
+
if (typeof item !== "string" && item.checked !== undefined) {
|
|
58
|
+
isChecked = item.checked;
|
|
59
|
+
} else if (depth === 0) {
|
|
60
|
+
isChecked = checkedSet.has(indexAtDepth);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const marker = getMarker(currentStyle, depth, indexAtDepth, isChecked);
|
|
64
|
+
lines.push(`${indentStr}${marker} ${text}`);
|
|
65
|
+
_globalIndex++;
|
|
66
|
+
if (typeof item !== "string" && item.children) {
|
|
67
|
+
const childStyle = typeof item !== "string" && item.childStyle ? item.childStyle : currentStyle;
|
|
68
|
+
const childIndent = currentStyle === "number" ? currentIndent + marker.length + 1 : currentIndent + baseIndent;
|
|
69
|
+
const childDepth = childStyle !== currentStyle ? 0 : depth + 1;
|
|
70
|
+
let childIndex = 0;
|
|
71
|
+
for (const child of item.children) {
|
|
72
|
+
renderItem(child, childIndent, childDepth, childIndex, childStyle);
|
|
73
|
+
childIndex++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
let topIndex = 0;
|
|
78
|
+
for (const item of items) {
|
|
79
|
+
renderItem(item, 0, 0, topIndex, style);
|
|
80
|
+
topIndex++;
|
|
81
|
+
}
|
|
82
|
+
return lines.join(`
|
|
83
|
+
`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { renderList };
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ANSI escape code constants for terminal styling.
|
|
3
|
+
*/
|
|
4
|
+
declare const ANSI: {
|
|
5
|
+
readonly reset: "\x1B[0m";
|
|
6
|
+
readonly bold: "\x1B[1m";
|
|
7
|
+
readonly dim: "\x1B[2m";
|
|
8
|
+
readonly italic: "\x1B[3m";
|
|
9
|
+
readonly underline: "\x1B[4m";
|
|
10
|
+
readonly green: "\x1B[32m";
|
|
11
|
+
readonly yellow: "\x1B[33m";
|
|
12
|
+
readonly red: "\x1B[31m";
|
|
13
|
+
readonly blue: "\x1B[34m";
|
|
14
|
+
readonly cyan: "\x1B[36m";
|
|
15
|
+
readonly magenta: "\x1B[35m";
|
|
16
|
+
readonly white: "\x1B[37m";
|
|
17
|
+
readonly gray: "\x1B[90m";
|
|
18
|
+
readonly brightCyan: "\x1B[96m";
|
|
19
|
+
readonly brightRed: "\x1B[91m";
|
|
20
|
+
readonly brightYellow: "\x1B[93m";
|
|
21
|
+
readonly brightGreen: "\x1B[92m";
|
|
22
|
+
readonly brightBlue: "\x1B[94m";
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Theme interface with semantic and text color functions.
|
|
26
|
+
*
|
|
27
|
+
* Each function wraps text in ANSI escape codes when colors are supported.
|
|
28
|
+
* When colors are not supported (NO_COLOR set, non-TTY), functions return the text unchanged.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const theme = createTheme();
|
|
33
|
+
* console.log(theme.success("Done!")); // Green text
|
|
34
|
+
* console.log(theme.error("Failed!")); // Red text
|
|
35
|
+
* console.log(theme.muted("(optional)")); // Dim text
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
interface Theme {
|
|
39
|
+
/** Applies green color for success messages */
|
|
40
|
+
success: (text: string) => string;
|
|
41
|
+
/** Applies yellow color for warning messages */
|
|
42
|
+
warning: (text: string) => string;
|
|
43
|
+
/** Applies red color for error messages */
|
|
44
|
+
error: (text: string) => string;
|
|
45
|
+
/** Applies blue color for informational messages */
|
|
46
|
+
info: (text: string) => string;
|
|
47
|
+
/** Returns text unchanged (primary/default text) */
|
|
48
|
+
primary: (text: string) => string;
|
|
49
|
+
/** Applies gray color for secondary text */
|
|
50
|
+
secondary: (text: string) => string;
|
|
51
|
+
/** Applies dim styling for de-emphasized text */
|
|
52
|
+
muted: (text: string) => string;
|
|
53
|
+
/** Applies cyan color for interactive elements and highlights */
|
|
54
|
+
accent: (text: string) => string;
|
|
55
|
+
/** Applies bold for strong emphasis */
|
|
56
|
+
highlight: (text: string) => string;
|
|
57
|
+
/** Applies cyan + underline for URLs and clickable references */
|
|
58
|
+
link: (text: string) => string;
|
|
59
|
+
/** Applies bright red for dangerous actions */
|
|
60
|
+
destructive: (text: string) => string;
|
|
61
|
+
/** Applies dim gray for less prominent text than muted */
|
|
62
|
+
subtle: (text: string) => string;
|
|
63
|
+
/** Applies bold styling */
|
|
64
|
+
bold: (text: string) => string;
|
|
65
|
+
/** Applies italic styling */
|
|
66
|
+
italic: (text: string) => string;
|
|
67
|
+
/** Applies underline styling */
|
|
68
|
+
underline: (text: string) => string;
|
|
69
|
+
/** Applies dim styling (alias for muted style) */
|
|
70
|
+
dim: (text: string) => string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Available color names for the {@link applyColor} function.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { applyColor, ColorName } from "@outfitter/cli";
|
|
78
|
+
*
|
|
79
|
+
* const color: ColorName = "green";
|
|
80
|
+
* console.log(applyColor("Success", color));
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
type ColorName = "green" | "yellow" | "red" | "blue" | "cyan" | "magenta" | "white" | "gray";
|
|
84
|
+
/**
|
|
85
|
+
* Semantic color tokens as raw ANSI escape code strings.
|
|
86
|
+
*
|
|
87
|
+
* Unlike {@link Theme} which provides wrapper functions, Tokens provides
|
|
88
|
+
* raw ANSI codes that can be used directly in template strings.
|
|
89
|
+
*
|
|
90
|
+
* When colors are not supported (NO_COLOR set, colorLevel: 0), all tokens
|
|
91
|
+
* are empty strings.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* const tokens = createTokens();
|
|
96
|
+
* const reset = "\x1b[0m";
|
|
97
|
+
*
|
|
98
|
+
* console.log(`${tokens.success}Operation completed${reset}`);
|
|
99
|
+
* console.log(`${tokens.error}Failed to connect${reset}`);
|
|
100
|
+
* console.log(`${tokens.muted}(optional step)${reset}`);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
interface Tokens {
|
|
104
|
+
/** Green color for success messages */
|
|
105
|
+
success: string;
|
|
106
|
+
/** Yellow color for warning messages */
|
|
107
|
+
warning: string;
|
|
108
|
+
/** Red color for error messages */
|
|
109
|
+
error: string;
|
|
110
|
+
/** Blue color for informational messages */
|
|
111
|
+
info: string;
|
|
112
|
+
/** Default text color (typically empty string) */
|
|
113
|
+
primary: string;
|
|
114
|
+
/** Subdued color for secondary text */
|
|
115
|
+
secondary: string;
|
|
116
|
+
/** Dim/gray color for de-emphasized text */
|
|
117
|
+
muted: string;
|
|
118
|
+
/** Cyan color for interactive elements and highlights */
|
|
119
|
+
accent: string;
|
|
120
|
+
/** Bold for strong emphasis */
|
|
121
|
+
highlight: string;
|
|
122
|
+
/** Cyan + underline for URLs and clickable references */
|
|
123
|
+
link: string;
|
|
124
|
+
/** Bright red for dangerous actions */
|
|
125
|
+
destructive: string;
|
|
126
|
+
/** Dim gray for less prominent text than muted */
|
|
127
|
+
subtle: string;
|
|
128
|
+
/** Bold styling */
|
|
129
|
+
bold: string;
|
|
130
|
+
/** Italic styling */
|
|
131
|
+
italic: string;
|
|
132
|
+
/** Underline styling */
|
|
133
|
+
underline: string;
|
|
134
|
+
/** Dim styling */
|
|
135
|
+
dim: string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Configuration options for {@link createTokens}.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* // Force colors even with NO_COLOR set
|
|
143
|
+
* const tokens = createTokens({ forceColor: true });
|
|
144
|
+
*
|
|
145
|
+
* // Disable colors entirely
|
|
146
|
+
* const noColorTokens = createTokens({ colorLevel: 0 });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
interface TokenOptions {
|
|
150
|
+
/**
|
|
151
|
+
* Override NO_COLOR environment variable.
|
|
152
|
+
* When true, colors are enabled regardless of NO_COLOR.
|
|
153
|
+
*/
|
|
154
|
+
forceColor?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Color support level:
|
|
157
|
+
* - 0: No color support (all tokens are empty strings)
|
|
158
|
+
* - 1: Basic ANSI colors (16 colors)
|
|
159
|
+
* - 2: 256 color support
|
|
160
|
+
* - 3: True color (16 million colors)
|
|
161
|
+
*
|
|
162
|
+
* When not specified, level is auto-detected from environment.
|
|
163
|
+
*/
|
|
164
|
+
colorLevel?: 0 | 1 | 2 | 3;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Creates a theme with semantic and text color functions.
|
|
168
|
+
*
|
|
169
|
+
* The theme provides functions that wrap text in ANSI escape codes.
|
|
170
|
+
* When colors are not supported (NO_COLOR set, non-TTY), functions
|
|
171
|
+
* return the text unchanged.
|
|
172
|
+
*
|
|
173
|
+
* Color support is determined once at theme creation time using
|
|
174
|
+
* {@link supportsColor}.
|
|
175
|
+
*
|
|
176
|
+
* @returns Theme object with color functions
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const theme = createTheme();
|
|
181
|
+
*
|
|
182
|
+
* // Semantic colors
|
|
183
|
+
* console.log(theme.success("Done!")); // Green
|
|
184
|
+
* console.log(theme.warning("Caution")); // Yellow
|
|
185
|
+
* console.log(theme.error("Failed!")); // Red
|
|
186
|
+
* console.log(theme.info("Note")); // Blue
|
|
187
|
+
*
|
|
188
|
+
* // Text colors
|
|
189
|
+
* console.log(theme.primary("Main text")); // Default
|
|
190
|
+
* console.log(theme.secondary("Alt text")); // Gray
|
|
191
|
+
* console.log(theme.muted("(optional)")); // Dim
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
declare function createTheme(): Theme;
|
|
195
|
+
/**
|
|
196
|
+
* Resolves whether color tokens should be enabled based on options.
|
|
197
|
+
*
|
|
198
|
+
* @param options - Token options
|
|
199
|
+
* @returns `true` if colors should be enabled
|
|
200
|
+
*/
|
|
201
|
+
declare function resolveTokenColorEnabled(options?: TokenOptions): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Creates semantic color tokens as raw ANSI escape code strings.
|
|
204
|
+
*
|
|
205
|
+
* Unlike {@link createTheme} which returns wrapper functions, this returns
|
|
206
|
+
* raw ANSI codes that can be used directly in template strings. This is
|
|
207
|
+
* useful for more complex string formatting scenarios.
|
|
208
|
+
*
|
|
209
|
+
* Color support is determined at token creation time using environment
|
|
210
|
+
* detection (NO_COLOR, FORCE_COLOR) or explicit options.
|
|
211
|
+
*
|
|
212
|
+
* @param options - Optional configuration for color behavior
|
|
213
|
+
* @returns Object with semantic color tokens as ANSI strings
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* const tokens = createTokens();
|
|
218
|
+
* const reset = "\x1b[0m";
|
|
219
|
+
*
|
|
220
|
+
* // Use in template strings
|
|
221
|
+
* console.log(`${tokens.success}Done!${reset}`);
|
|
222
|
+
* console.log(`${tokens.error}Failed${reset}`);
|
|
223
|
+
*
|
|
224
|
+
* // Build complex formatted strings
|
|
225
|
+
* const status = `${tokens.info}Status:${reset} ${tokens.success}OK${reset}`;
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
declare function createTokens(options?: TokenOptions): Tokens;
|
|
229
|
+
/**
|
|
230
|
+
* Applies a named color to text using ANSI escape codes.
|
|
231
|
+
*
|
|
232
|
+
* Returns plain text if colors are not supported (NO_COLOR set, non-TTY).
|
|
233
|
+
* For semantic colors (success, error, etc.), use {@link createTheme} instead.
|
|
234
|
+
*
|
|
235
|
+
* @param text - The text to colorize
|
|
236
|
+
* @param color - The color name to apply
|
|
237
|
+
* @returns Text wrapped in ANSI escape codes, or plain text if colors not supported
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* console.log(applyColor("Success", "green"));
|
|
242
|
+
* console.log(applyColor("Warning", "yellow"));
|
|
243
|
+
* console.log(applyColor("Error", "red"));
|
|
244
|
+
* console.log(applyColor("Info", "blue"));
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
declare function applyColor(text: string, color: ColorName): string;
|
|
248
|
+
export { ANSI, Theme, ColorName, Tokens, TokenOptions, createTheme, resolveTokenColorEnabled, createTokens, applyColor };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getTerminalWidth
|
|
4
|
+
} from "./cli-671sxkhj.js";
|
|
5
|
+
|
|
6
|
+
// packages/cli/src/render/heading.ts
|
|
7
|
+
var ANSI_PATTERN = /\x1b\[[0-9;]*m/g;
|
|
8
|
+
function toTitleCase(text) {
|
|
9
|
+
return text.replace(/\w\S*/g, (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
|
|
10
|
+
}
|
|
11
|
+
function applyCase(text, caseMode) {
|
|
12
|
+
if (caseMode === "none") {
|
|
13
|
+
return text;
|
|
14
|
+
}
|
|
15
|
+
const hasAnsi = ANSI_PATTERN.test(text);
|
|
16
|
+
ANSI_PATTERN.lastIndex = 0;
|
|
17
|
+
if (!hasAnsi) {
|
|
18
|
+
switch (caseMode) {
|
|
19
|
+
case "upper":
|
|
20
|
+
return text.toUpperCase();
|
|
21
|
+
case "lower":
|
|
22
|
+
return text.toLowerCase();
|
|
23
|
+
case "title":
|
|
24
|
+
return toTitleCase(text);
|
|
25
|
+
default: {
|
|
26
|
+
const _exhaustive = caseMode;
|
|
27
|
+
return _exhaustive;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const sequences = [];
|
|
32
|
+
for (const match of text.matchAll(ANSI_PATTERN)) {
|
|
33
|
+
sequences.push({ index: match.index, seq: match[0] });
|
|
34
|
+
}
|
|
35
|
+
const stripped = Bun.stripANSI(text);
|
|
36
|
+
let transformed;
|
|
37
|
+
switch (caseMode) {
|
|
38
|
+
case "upper":
|
|
39
|
+
transformed = stripped.toUpperCase();
|
|
40
|
+
break;
|
|
41
|
+
case "lower":
|
|
42
|
+
transformed = stripped.toLowerCase();
|
|
43
|
+
break;
|
|
44
|
+
case "title":
|
|
45
|
+
transformed = toTitleCase(stripped);
|
|
46
|
+
break;
|
|
47
|
+
default: {
|
|
48
|
+
const _exhaustive = caseMode;
|
|
49
|
+
return _exhaustive;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
let result = transformed;
|
|
53
|
+
let offset = 0;
|
|
54
|
+
for (const { index, seq } of sequences) {
|
|
55
|
+
const insertPos = index + offset;
|
|
56
|
+
result = result.slice(0, insertPos) + seq + result.slice(insertPos);
|
|
57
|
+
offset += seq.length;
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
function getTextWidth(text) {
|
|
62
|
+
return Bun.stringWidth(text);
|
|
63
|
+
}
|
|
64
|
+
function renderHeading(text, options) {
|
|
65
|
+
const separator = options?.separator ?? "=";
|
|
66
|
+
const widthMode = options?.width ?? "text";
|
|
67
|
+
const caseMode = options?.case ?? "upper";
|
|
68
|
+
const transformedText = applyCase(text, caseMode);
|
|
69
|
+
let width;
|
|
70
|
+
if (widthMode === "text") {
|
|
71
|
+
width = getTextWidth(transformedText);
|
|
72
|
+
} else if (widthMode === "full") {
|
|
73
|
+
width = getTerminalWidth();
|
|
74
|
+
} else {
|
|
75
|
+
width = widthMode;
|
|
76
|
+
}
|
|
77
|
+
const separatorLine = separator.repeat(width);
|
|
78
|
+
return `${transformedText}
|
|
79
|
+
${separatorLine}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { renderHeading };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MultiSelectPromptOptions, PromptResult, SelectPromptOptions } from "./cli-3f12z5kf";
|
|
2
|
+
/**
|
|
3
|
+
* Prompts for single selection with Result wrapping.
|
|
4
|
+
*
|
|
5
|
+
* @param options - Select prompt options
|
|
6
|
+
* @returns Ok with selected value or Err with CancelledError
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { promptSelect } from "@outfitter/cli/prompt";
|
|
11
|
+
*
|
|
12
|
+
* const result = await promptSelect({
|
|
13
|
+
* message: "Pick a color:",
|
|
14
|
+
* options: [
|
|
15
|
+
* { value: "red", label: "Red", hint: "A warm color" },
|
|
16
|
+
* { value: "blue", label: "Blue", hint: "A cool color" },
|
|
17
|
+
* ],
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* if (result.isOk()) {
|
|
21
|
+
* console.log(`You picked: ${result.value}`);
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function promptSelect<T>(options: SelectPromptOptions<T>): PromptResult<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Prompts for multiple selections with Result wrapping.
|
|
28
|
+
*
|
|
29
|
+
* @param options - Multi-select prompt options
|
|
30
|
+
* @returns Ok with array of selected values or Err with CancelledError
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* import { promptMultiSelect } from "@outfitter/cli/prompt";
|
|
35
|
+
*
|
|
36
|
+
* const result = await promptMultiSelect({
|
|
37
|
+
* message: "Select toppings:",
|
|
38
|
+
* options: [
|
|
39
|
+
* { value: "cheese", label: "Cheese" },
|
|
40
|
+
* { value: "pepperoni", label: "Pepperoni" },
|
|
41
|
+
* { value: "mushrooms", label: "Mushrooms" },
|
|
42
|
+
* ],
|
|
43
|
+
* required: true,
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare function promptMultiSelect<T>(options: MultiSelectPromptOptions<T>): PromptResult<T[]>;
|
|
48
|
+
export { promptSelect, promptMultiSelect };
|