@zaly/tui 0.0.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/LICENSE +21 -0
- package/README.md +59 -0
- package/assets/schemas/theme.schema.json +899 -0
- package/assets/themes/LICENSE-tokyonight.txt +201 -0
- package/assets/themes/NOTICES.md +69 -0
- package/assets/themes/ayu-dark.json +119 -0
- package/assets/themes/catppuccin-frappe.json +124 -0
- package/assets/themes/catppuccin-latte.json +124 -0
- package/assets/themes/catppuccin-macchiato.json +124 -0
- package/assets/themes/catppuccin-mocha.json +124 -0
- package/assets/themes/dracula-soft.json +119 -0
- package/assets/themes/dracula.json +119 -0
- package/assets/themes/everforest-dark.json +118 -0
- package/assets/themes/everforest-light.json +118 -0
- package/assets/themes/github-dark.json +123 -0
- package/assets/themes/github-light.json +123 -0
- package/assets/themes/gruvbox-dark-medium.json +112 -0
- package/assets/themes/kanagawa-dragon.json +115 -0
- package/assets/themes/kanagawa-wave.json +115 -0
- package/assets/themes/material-theme-palenight.json +114 -0
- package/assets/themes/min-dark.json +55 -0
- package/assets/themes/min-light.json +59 -0
- package/assets/themes/monokai.json +116 -0
- package/assets/themes/night-owl.json +116 -0
- package/assets/themes/nord.json +101 -0
- package/assets/themes/one-dark-pro.json +110 -0
- package/assets/themes/one-light.json +108 -0
- package/assets/themes/poimandres.json +123 -0
- package/assets/themes/rose-pine.json +98 -0
- package/assets/themes/solarized-dark.json +116 -0
- package/assets/themes/solarized-light.json +116 -0
- package/assets/themes/synthwave-84.json +100 -0
- package/assets/themes/tokyonight-day.json +157 -0
- package/assets/themes/tokyonight-moon.json +157 -0
- package/assets/themes/tokyonight-night.json +157 -0
- package/assets/themes/tokyonight-storm.json +157 -0
- package/assets/themes/vesper.json +103 -0
- package/assets/themes/vitesse-dark.json +126 -0
- package/assets/themes/vitesse-light.json +126 -0
- package/dist/ansi-Clq0ozyA.mjs +206 -0
- package/dist/ansi-Clq0ozyA.mjs.map +1 -0
- package/dist/ansi.d.mts +48 -0
- package/dist/ansi.d.mts.map +1 -0
- package/dist/ansi.mjs +2 -0
- package/dist/autocomplete-Dfw-yQDa.d.mts +100 -0
- package/dist/autocomplete-Dfw-yQDa.d.mts.map +1 -0
- package/dist/box-DyaByEiG.mjs +386 -0
- package/dist/box-DyaByEiG.mjs.map +1 -0
- package/dist/builder-D49ECBEf.mjs +385 -0
- package/dist/builder-D49ECBEf.mjs.map +1 -0
- package/dist/callbacks-CNjGNxVw.mjs +279 -0
- package/dist/callbacks-CNjGNxVw.mjs.map +1 -0
- package/dist/client-D6C_uczF.mjs +142 -0
- package/dist/client-D6C_uczF.mjs.map +1 -0
- package/dist/clipboard.d.mts +104 -0
- package/dist/clipboard.d.mts.map +1 -0
- package/dist/clipboard.mjs +404 -0
- package/dist/clipboard.mjs.map +1 -0
- package/dist/flex-Bguo-fUe.mjs +202 -0
- package/dist/flex-Bguo-fUe.mjs.map +1 -0
- package/dist/image-Cm5T-uw-.mjs +108 -0
- package/dist/image-Cm5T-uw-.mjs.map +1 -0
- package/dist/image.d.mts +123 -0
- package/dist/image.d.mts.map +1 -0
- package/dist/image.mjs +2 -0
- package/dist/index.d.mts +64 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +222 -0
- package/dist/index.mjs.map +1 -0
- package/dist/input-B5Vy-iaa.d.mts +141 -0
- package/dist/input-B5Vy-iaa.d.mts.map +1 -0
- package/dist/inspect-D1d9t-ni.mjs +101 -0
- package/dist/inspect-D1d9t-ni.mjs.map +1 -0
- package/dist/inspect-D6FW_QUo.d.mts +67 -0
- package/dist/inspect-D6FW_QUo.d.mts.map +1 -0
- package/dist/kitty-JbCJC0iQ.mjs +673 -0
- package/dist/kitty-JbCJC0iQ.mjs.map +1 -0
- package/dist/markdown.d.mts +24 -0
- package/dist/markdown.d.mts.map +1 -0
- package/dist/markdown.mjs +2 -0
- package/dist/md.bun.d.mts +14 -0
- package/dist/md.bun.d.mts.map +1 -0
- package/dist/md.bun.mjs +28 -0
- package/dist/md.bun.mjs.map +1 -0
- package/dist/md.node.d.mts +14 -0
- package/dist/md.node.d.mts.map +1 -0
- package/dist/md.node.mjs +126 -0
- package/dist/md.node.mjs.map +1 -0
- package/dist/node-BZ7f6HzU.mjs +316 -0
- package/dist/node-BZ7f6HzU.mjs.map +1 -0
- package/dist/picker-D8OLb6kZ.d.mts +36 -0
- package/dist/picker-D8OLb6kZ.d.mts.map +1 -0
- package/dist/picker-ndVVt6qF.mjs +621 -0
- package/dist/picker-ndVVt6qF.mjs.map +1 -0
- package/dist/queries-DH3bj74K.d.mts +1963 -0
- package/dist/queries-DH3bj74K.d.mts.map +1 -0
- package/dist/reactive-f7NpAi69.mjs +623 -0
- package/dist/reactive-f7NpAi69.mjs.map +1 -0
- package/dist/registry-U654j61Y.mjs +356 -0
- package/dist/registry-U654j61Y.mjs.map +1 -0
- package/dist/render-DxVLqqB9.mjs +74 -0
- package/dist/render-DxVLqqB9.mjs.map +1 -0
- package/dist/renderer-CdLCkJB-.mjs +42 -0
- package/dist/renderer-CdLCkJB-.mjs.map +1 -0
- package/dist/renderer-CxL4xbkl.mjs +2644 -0
- package/dist/renderer-CxL4xbkl.mjs.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/search-FvGnswRl.d.mts +49 -0
- package/dist/search-FvGnswRl.d.mts.map +1 -0
- package/dist/select-CbmAZdpt.d.mts +116 -0
- package/dist/select-CbmAZdpt.d.mts.map +1 -0
- package/dist/services/logger.d.mts +2 -0
- package/dist/services/logger.mjs +71 -0
- package/dist/services/logger.mjs.map +1 -0
- package/dist/services/notifier.d.mts +17 -0
- package/dist/services/notifier.d.mts.map +1 -0
- package/dist/services/notifier.mjs +71 -0
- package/dist/services/notifier.mjs.map +1 -0
- package/dist/services/picker.d.mts +36 -0
- package/dist/services/picker.d.mts.map +1 -0
- package/dist/services/picker.mjs +137 -0
- package/dist/services/picker.mjs.map +1 -0
- package/dist/services/prompt.d.mts +30 -0
- package/dist/services/prompt.d.mts.map +1 -0
- package/dist/services/prompt.mjs +83 -0
- package/dist/services/prompt.mjs.map +1 -0
- package/dist/shiki-BrjVUkeh.mjs +423 -0
- package/dist/shiki-BrjVUkeh.mjs.map +1 -0
- package/dist/size-D8JogYLy.mjs +34 -0
- package/dist/size-D8JogYLy.mjs.map +1 -0
- package/dist/style.d.mts +10 -0
- package/dist/style.d.mts.map +1 -0
- package/dist/style.mjs +4 -0
- package/dist/text.d.mts +33 -0
- package/dist/text.d.mts.map +1 -0
- package/dist/text.mjs +111 -0
- package/dist/text.mjs.map +1 -0
- package/dist/theme.config-CU3B50HN.mjs +832 -0
- package/dist/theme.config-CU3B50HN.mjs.map +1 -0
- package/dist/themes.d.mts +113 -0
- package/dist/themes.d.mts.map +1 -0
- package/dist/themes.mjs +2 -0
- package/dist/tree-C28QOVIK.d.mts +23 -0
- package/dist/tree-C28QOVIK.d.mts.map +1 -0
- package/dist/types-B9Eh7k2v.d.mts +212 -0
- package/dist/types-B9Eh7k2v.d.mts.map +1 -0
- package/dist/types-D3jk1rtk.d.mts +140 -0
- package/dist/types-D3jk1rtk.d.mts.map +1 -0
- package/dist/utils-3M4D_AXZ.mjs +40 -0
- package/dist/utils-3M4D_AXZ.mjs.map +1 -0
- package/dist/widgets/autocomplete.d.mts +2 -0
- package/dist/widgets/autocomplete.mjs +165 -0
- package/dist/widgets/autocomplete.mjs.map +1 -0
- package/dist/widgets/box.d.mts +2 -0
- package/dist/widgets/box.mjs +2 -0
- package/dist/widgets/code.d.mts +48 -0
- package/dist/widgets/code.d.mts.map +1 -0
- package/dist/widgets/code.mjs +59 -0
- package/dist/widgets/code.mjs.map +1 -0
- package/dist/widgets/completions/actions.d.mts +41 -0
- package/dist/widgets/completions/actions.d.mts.map +1 -0
- package/dist/widgets/completions/actions.mjs +48 -0
- package/dist/widgets/completions/actions.mjs.map +1 -0
- package/dist/widgets/completions/files.d.mts +29 -0
- package/dist/widgets/completions/files.d.mts.map +1 -0
- package/dist/widgets/completions/files.mjs +42 -0
- package/dist/widgets/completions/files.mjs.map +1 -0
- package/dist/widgets/completions/github.d.mts +64 -0
- package/dist/widgets/completions/github.d.mts.map +1 -0
- package/dist/widgets/completions/github.mjs +137 -0
- package/dist/widgets/completions/github.mjs.map +1 -0
- package/dist/widgets/completions/index.d.mts +4 -0
- package/dist/widgets/completions/index.mjs +4 -0
- package/dist/widgets/diff.d.mts +57 -0
- package/dist/widgets/diff.d.mts.map +1 -0
- package/dist/widgets/diff.mjs +199 -0
- package/dist/widgets/diff.mjs.map +1 -0
- package/dist/widgets/divider.d.mts +11 -0
- package/dist/widgets/divider.d.mts.map +1 -0
- package/dist/widgets/divider.mjs +9 -0
- package/dist/widgets/divider.mjs.map +1 -0
- package/dist/widgets/image.d.mts +37 -0
- package/dist/widgets/image.d.mts.map +1 -0
- package/dist/widgets/image.mjs +77 -0
- package/dist/widgets/image.mjs.map +1 -0
- package/dist/widgets/input.d.mts +2 -0
- package/dist/widgets/input.mjs +497 -0
- package/dist/widgets/input.mjs.map +1 -0
- package/dist/widgets/log.d.mts +2 -0
- package/dist/widgets/log.mjs +130 -0
- package/dist/widgets/log.mjs.map +1 -0
- package/dist/widgets/markdown.d.mts +45 -0
- package/dist/widgets/markdown.d.mts.map +1 -0
- package/dist/widgets/markdown.mjs +124 -0
- package/dist/widgets/markdown.mjs.map +1 -0
- package/dist/widgets/overlay.d.mts +2 -0
- package/dist/widgets/overlay.mjs +18 -0
- package/dist/widgets/overlay.mjs.map +1 -0
- package/dist/widgets/picker.d.mts +2 -0
- package/dist/widgets/picker.mjs +2 -0
- package/dist/widgets/progress.d.mts +48 -0
- package/dist/widgets/progress.d.mts.map +1 -0
- package/dist/widgets/progress.mjs +48 -0
- package/dist/widgets/progress.mjs.map +1 -0
- package/dist/widgets/select.d.mts +2 -0
- package/dist/widgets/select.mjs +195 -0
- package/dist/widgets/select.mjs.map +1 -0
- package/dist/widgets/show.d.mts +55 -0
- package/dist/widgets/show.d.mts.map +1 -0
- package/dist/widgets/show.mjs +85 -0
- package/dist/widgets/show.mjs.map +1 -0
- package/dist/widgets/spinner.d.mts +65 -0
- package/dist/widgets/spinner.d.mts.map +1 -0
- package/dist/widgets/spinner.mjs +147 -0
- package/dist/widgets/spinner.mjs.map +1 -0
- package/dist/widgets/text.d.mts +2 -0
- package/dist/widgets/text.mjs +32 -0
- package/dist/widgets/text.mjs.map +1 -0
- package/dist/widgets/tree.d.mts +2 -0
- package/dist/widgets/tree.mjs +73 -0
- package/dist/widgets/tree.mjs.map +1 -0
- package/dist/widgets/widget.d.mts +49 -0
- package/dist/widgets/widget.d.mts.map +1 -0
- package/dist/widgets/widget.mjs +40 -0
- package/dist/widgets/widget.mjs.map +1 -0
- package/dist/worker-DjHuQSbY.mjs +27 -0
- package/dist/worker-DjHuQSbY.mjs.map +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Nt as Size, P as RenderCtx, Z as StyleState, f as BaseEvents, nt as Reactive, p as Node } from "./queries-DH3bj74K.mjs";
|
|
2
|
+
import { a as StyleBuilder } from "./inspect-D6FW_QUo.mjs";
|
|
3
|
+
import { MaybePromise } from "@zaly/shared";
|
|
4
|
+
import { DetectedFile } from "@zaly/shared/detect";
|
|
5
|
+
//#region src/widgets/input.d.ts
|
|
6
|
+
interface InputState extends StyleState {
|
|
7
|
+
/** Current text content. May include `\n` for multi-line input. */
|
|
8
|
+
value?: string;
|
|
9
|
+
/** Shown dim when `value` is empty. */
|
|
10
|
+
placeholder?: Reactive<string | undefined>;
|
|
11
|
+
/** Cursor position as a char index in `value`. Clamped to `[0, value.length]`. */
|
|
12
|
+
cursor?: number;
|
|
13
|
+
/** Render width. Defaults to `fill`. */
|
|
14
|
+
width?: Size;
|
|
15
|
+
/** Submitted input history, newest last. */
|
|
16
|
+
history?: readonly string[];
|
|
17
|
+
/** Threshold for showing pasted content as an attachment rather than raw text */
|
|
18
|
+
pasteMaxLines?: number;
|
|
19
|
+
pasteMaxChars?: number;
|
|
20
|
+
canAttach?: (file: InputAttachment) => boolean;
|
|
21
|
+
format?: (value: string, ctx: {
|
|
22
|
+
style: StyleBuilder;
|
|
23
|
+
}) => MaybePromise<string>;
|
|
24
|
+
validate?: (value: string) => boolean;
|
|
25
|
+
}
|
|
26
|
+
type InputValue = {
|
|
27
|
+
value: string;
|
|
28
|
+
attachments: InputAttachment[];
|
|
29
|
+
};
|
|
30
|
+
/** A clipboard or bracketed paste that exceeds the `pasteMax*` thresholds. **/
|
|
31
|
+
type Paste = {
|
|
32
|
+
type: "paste";
|
|
33
|
+
text: string;
|
|
34
|
+
};
|
|
35
|
+
/** A file or image attachment detected from the clipboard. */
|
|
36
|
+
type InputAttachment = DetectedFile & {
|
|
37
|
+
path: string;
|
|
38
|
+
};
|
|
39
|
+
type InputEvents = BaseEvents & {
|
|
40
|
+
/** Fired when the submitted history changes. */
|
|
41
|
+
history: {
|
|
42
|
+
history: string[];
|
|
43
|
+
added: string;
|
|
44
|
+
};
|
|
45
|
+
/** Fired when plain Enter is pressed. Payload is the current value. */
|
|
46
|
+
submit: {
|
|
47
|
+
value: string;
|
|
48
|
+
attachments: InputAttachment[];
|
|
49
|
+
};
|
|
50
|
+
/** Fired when the user pastes a non-text resource via the
|
|
51
|
+
* `input.paste` action. Images and file references both land here,
|
|
52
|
+
* discriminated by `attachment.kind`. One event fires per image
|
|
53
|
+
* paste; one per file in a multi-file paste.
|
|
54
|
+
*
|
|
55
|
+
* Wrapped under `attachment` because `InputAttachment` carries its
|
|
56
|
+
* own `type` field (MIME) that would shadow the envelope's `type`
|
|
57
|
+
* discriminator if spread directly. */
|
|
58
|
+
attach: {
|
|
59
|
+
attachment: InputAttachment;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Multi-line text input with auto-grow.
|
|
64
|
+
*
|
|
65
|
+
* Editing commands (`cursorLeft`, `deleteWordBack`, `submit`, …) live on
|
|
66
|
+
* `this.actions` as zero-arg methods. The input router maps keymap
|
|
67
|
+
* bindings like `"input.cursorLeft"` onto those methods — users bind
|
|
68
|
+
* different keys by configuring the keymap, not by patching the class.
|
|
69
|
+
* The methods are also callable directly (`input.actions.submit()`),
|
|
70
|
+
* which is handy in tests or for higher-level macros.
|
|
71
|
+
*
|
|
72
|
+
* What this class *still* handles via its `key` event listener:
|
|
73
|
+
* - **Printable character insertion.** An unbound keystroke whose
|
|
74
|
+
* `text` is set and has no ctrl/alt/meta modifier becomes a literal
|
|
75
|
+
* insert at the cursor. There's no action for every printable char
|
|
76
|
+
* in the keymap; the raw-key fallback handles them.
|
|
77
|
+
* - **Paste events.** Whole payload inserted at cursor; always.
|
|
78
|
+
*
|
|
79
|
+
* Everything else (navigation, editing, submit/newline) goes through
|
|
80
|
+
* the router → actions pipeline. Unbound non-printable keys fall back
|
|
81
|
+
* to `emit("key", …)` and bubble to the parent chain.
|
|
82
|
+
*
|
|
83
|
+
* Rendering word-wraps each logical line to `ctx.width`, so long
|
|
84
|
+
* messages naturally grow vertically. The UI surface resizes its
|
|
85
|
+
* reserved footer when the Input's row count changes, so the stream
|
|
86
|
+
* above shifts accordingly.
|
|
87
|
+
*/
|
|
88
|
+
declare class Input extends Node<InputState, InputEvents> {
|
|
89
|
+
#private;
|
|
90
|
+
/** Class-level scope tag used by the input router to bind keymaps. */
|
|
91
|
+
static readonly type = "input";
|
|
92
|
+
readonly type = "input";
|
|
93
|
+
/**
|
|
94
|
+
* Editing actions. Parameterless — they close over `this` — so both
|
|
95
|
+
* the router (via keymap dispatch) and application code can invoke
|
|
96
|
+
* them. Add to the keymap in `src/input/actions.ts` to give them
|
|
97
|
+
* default key bindings.
|
|
98
|
+
*/
|
|
99
|
+
actions: {
|
|
100
|
+
"input.cursorDown": () => void;
|
|
101
|
+
"input.cursorLeft": () => void;
|
|
102
|
+
"input.cursorLineEnd": () => void;
|
|
103
|
+
"input.cursorLineStart": () => void;
|
|
104
|
+
"input.cursorRight": () => void;
|
|
105
|
+
"input.cursorUp": () => void;
|
|
106
|
+
"input.deleteCharBack": () => void;
|
|
107
|
+
"input.deleteCharForward": () => void;
|
|
108
|
+
"input.deleteWordBack": () => void;
|
|
109
|
+
"input.insertNewline": () => void;
|
|
110
|
+
"input.insertTab": () => void;
|
|
111
|
+
"input.paste": () => void;
|
|
112
|
+
"input.submit": () => void;
|
|
113
|
+
};
|
|
114
|
+
constructor(initial?: InputState);
|
|
115
|
+
get history(): readonly string[];
|
|
116
|
+
set history(v: readonly string[]);
|
|
117
|
+
attach(att: InputAttachment | Paste): void;
|
|
118
|
+
paste(text: string): void;
|
|
119
|
+
insert(text: string): void;
|
|
120
|
+
replace(text: string): void;
|
|
121
|
+
/** Consume the input's current value and attachments.
|
|
122
|
+
* Pastes are replaced inline with their text; file/image
|
|
123
|
+
* attachments are returned in the `attachments` array and removed from the value. */
|
|
124
|
+
consume(): InputValue;
|
|
125
|
+
historyAdd(value: string): void;
|
|
126
|
+
protected _render(ctx: RenderCtx): Promise<string[]>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Factory for `Input`. All fields optional; default is an empty,
|
|
130
|
+
* focusable input that fills `ctx.width` and has no placeholder.
|
|
131
|
+
*
|
|
132
|
+
* ```ts
|
|
133
|
+
* input({ placeholder: "type a message…" })
|
|
134
|
+
* const i = input({ value: "draft" })
|
|
135
|
+
* i.on("submit", (text) => console.log("user typed", text))
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
declare function input(state?: InputState): Input;
|
|
139
|
+
//#endregion
|
|
140
|
+
export { InputValue as a, InputState as i, InputAttachment as n, input as o, InputEvents as r, Input as t };
|
|
141
|
+
//# sourceMappingURL=input-B5Vy-iaa.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-B5Vy-iaa.d.mts","names":[],"sources":["../src/widgets/input.ts"],"mappings":";;;;;UAoBiB,mBAAmB;;EAElC;;EAEA,cAAc;;EAEd;;EAEA,QAAQ;;EAER;;EAEA;EACA;EACA,aAAa,MAAM;EACnB,UAAU,eAAe;IAAO,OAAO;QAAmB;EAC1D,YAAY;;KAGF;EAAe;EAAe,aAAa;;;KAMlD;EAAU;EAAe;;;KAGlB,kBAAkB;EAAiB;;KAEnC,cAAc;;EAExB;IAAW;IAAmB;;;EAE9B;IAAU;IAAe,aAAa;;;;;;;;;;EAStC;IAAU,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+BX,cAAc,KAAK,YAAY;;;kBAE1B;WAEE;;;;;;;EAgBT;;;;;;;;;;;;;;;EAyJT,YAAY,UAAS;MA2BjB;MAIA,QAAQ;EAKZ,OAAO,KAAK,kBAAkB;EAqB9B,MAAM;EASN,OAAO;EAWP,QAAQ;;;;EAQR,WAAW;EA2BX,WAAW;YAqHK,QAAQ,KAAK,YAAY;;;;;;;;;;;;iBAyD3B,MAAM,QAAO,aAAkB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { t as styleBuilder } from "./builder-D49ECBEf.mjs";
|
|
2
|
+
import { hasAnsi } from "@zaly/shared/ansi";
|
|
3
|
+
import { hasColors } from "@zaly/shared/env";
|
|
4
|
+
import { formatWithOptions, inspect } from "node:util";
|
|
5
|
+
//#region src/style/inspect.ts
|
|
6
|
+
const MD_RE = /[`*_#[\]\->~|]/;
|
|
7
|
+
const JSON_RE = /^\s*[{[]/;
|
|
8
|
+
const FORMAT_RE = /%[sdifjoOc%]/;
|
|
9
|
+
/** True when `s` looks like markdown we should render — contains MD
|
|
10
|
+
* markers and isn't already ANSI-styled. Mirrors rekal's `Formatter.markdown`
|
|
11
|
+
* skip test so we avoid double-rendering pre-styled strings. */
|
|
12
|
+
function isMarkdown(s) {
|
|
13
|
+
return MD_RE.test(s) && !hasAnsi(s) && !JSON_RE.test(s);
|
|
14
|
+
}
|
|
15
|
+
const isFormatString = (v) => typeof v === "string" && FORMAT_RE.test(v) && !hasAnsi(v);
|
|
16
|
+
/**
|
|
17
|
+
* Inspect a list of args the way `console.log` does, returning a single
|
|
18
|
+
* string. Collapses `util.format` placeholders right-to-left, unwraps
|
|
19
|
+
* `Error` values to their message (unless `stacktrace: true`), and falls
|
|
20
|
+
* back to `util.formatWithOptions` for mixed values.
|
|
21
|
+
*/
|
|
22
|
+
function inspectFormat(msg, opts = {}) {
|
|
23
|
+
const data = opts.stacktrace ? msg : msg.map((v) => v instanceof Error ? v.message : v);
|
|
24
|
+
opts = {
|
|
25
|
+
colors: hasColors,
|
|
26
|
+
...opts
|
|
27
|
+
};
|
|
28
|
+
let ret = [];
|
|
29
|
+
for (let i = data.length - 1; i >= 0; i--) {
|
|
30
|
+
const item = data[i];
|
|
31
|
+
if (isFormatString(item)) ret = [formatWithOptions(opts, item, ...ret)];
|
|
32
|
+
else ret.unshift(item);
|
|
33
|
+
}
|
|
34
|
+
if (ret.length > 1 && isFormatString(ret[0])) return formatWithOptions(opts, ...ret);
|
|
35
|
+
return ret.map((v) => typeof v === "string" ? v : inspect$1(v, opts)).join(" ");
|
|
36
|
+
}
|
|
37
|
+
function inspectNumber(value) {
|
|
38
|
+
return new Intl.NumberFormat("en-US", {
|
|
39
|
+
notation: "standard",
|
|
40
|
+
useGrouping: true
|
|
41
|
+
}).format(value).replace(/,/g, "_");
|
|
42
|
+
}
|
|
43
|
+
function inspectField(key, s) {
|
|
44
|
+
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return s.syntaxField(key);
|
|
45
|
+
return s.syntaxString(JSON.stringify(key));
|
|
46
|
+
}
|
|
47
|
+
function inspect$1(value, opts = {}) {
|
|
48
|
+
opts = {
|
|
49
|
+
colors: hasColors,
|
|
50
|
+
null: true,
|
|
51
|
+
undefined: true,
|
|
52
|
+
...opts
|
|
53
|
+
};
|
|
54
|
+
const indent = opts.indent ?? 2;
|
|
55
|
+
const s = opts.colors ? opts.style ?? styleBuilder() : styleBuilder(false);
|
|
56
|
+
const sym = {
|
|
57
|
+
",": s.syntaxDelimiter(","),
|
|
58
|
+
":": s.syntaxDelimiter(":"),
|
|
59
|
+
"[": s.syntaxBracket("["),
|
|
60
|
+
"]": s.syntaxBracket("]"),
|
|
61
|
+
"{": s.syntaxBracket("{"),
|
|
62
|
+
"}": s.syntaxBracket("}")
|
|
63
|
+
};
|
|
64
|
+
const seen = /* @__PURE__ */ new Set();
|
|
65
|
+
const $inspect = (v, depth) => {
|
|
66
|
+
if (seen.has(v)) return s.bold("[Circular]");
|
|
67
|
+
if (typeof v === "object" && v !== null) seen.add(v);
|
|
68
|
+
if (v === null) return s.syntaxConstant("null");
|
|
69
|
+
switch (typeof v) {
|
|
70
|
+
case "boolean": return s.syntaxBoolean(String(v));
|
|
71
|
+
case "bigint": return s.syntaxNumber(`${v}n`);
|
|
72
|
+
case "number": return s.syntaxNumber(inspectNumber(v));
|
|
73
|
+
case "string": return s.syntaxString(JSON.stringify(v));
|
|
74
|
+
case "symbol": return s.syntaxSpecial(String(v));
|
|
75
|
+
case "function": return s.syntaxFunction(`[Function${v.name ? `: ${v.name}` : ""}]`);
|
|
76
|
+
case "undefined": return s.syntaxConstant("undefined");
|
|
77
|
+
case "object": {
|
|
78
|
+
if (Array.isArray(v)) {
|
|
79
|
+
const items = v.map((item) => $inspect(item, depth + 1));
|
|
80
|
+
return `${sym["["]} ${items.join(`${sym[","]} `)} ${sym["]"]}`;
|
|
81
|
+
}
|
|
82
|
+
if (!(Object.getPrototypeOf(v) === Object.prototype)) break;
|
|
83
|
+
const entries = Object.entries(v).filter(([_, val]) => !(val === void 0 && !opts.undefined || val === null && !opts.null)).map(([key, val]) => `${inspectField(key, s)}: ${$inspect(val, depth + 1)}`);
|
|
84
|
+
if (indent) {
|
|
85
|
+
const padding = " ".repeat(indent * depth);
|
|
86
|
+
return `${sym["{"]}\n${padding}${entries.join(`${sym[","]}\n${padding}`)}\n${" ".repeat(indent * (depth - 1))}${sym["}"]}`;
|
|
87
|
+
}
|
|
88
|
+
return `${sym["{"]} ${entries.join(`${sym[","]} `)} ${sym["}"]}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return inspect(v, {
|
|
92
|
+
colors: true,
|
|
93
|
+
compact: true
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
return $inspect(value, 1);
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { inspectFormat as n, isMarkdown as r, inspect$1 as t };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=inspect-D1d9t-ni.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-D1d9t-ni.mjs","names":["inspect","nodeInspect"],"sources":["../src/style/inspect.ts"],"sourcesContent":["import type { StyleBuilder } from \"./builder.ts\"\n\nimport { hasAnsi } from \"@zaly/shared/ansi\"\nimport { hasColors } from \"@zaly/shared/env\"\nimport { formatWithOptions, inspect as nodeInspect } from \"node:util\"\nimport { styleBuilder } from \"./builder.ts\"\n\nexport interface InspectOpts {\n style?: StyleBuilder\n indent?: number\n undefined?: boolean\n null?: boolean\n /** When `true`, preserve Error stack traces. Default: `false` — Error\n * values are reduced to their `.message` so logs stay compact. */\n stacktrace?: boolean\n colors?: boolean\n}\n\n// Markdown-ish characters. Matches rekal's skip regex.\nconst MD_RE = /[`*_#[\\]\\->~|]/\nconst JSON_RE = /^\\s*[{[]/\n\n// `util.format` placeholder tokens (`%s`, `%d`, …).\nconst FORMAT_RE = /%[sdifjoOc%]/\n\n/** True when `s` looks like markdown we should render — contains MD\n * markers and isn't already ANSI-styled. Mirrors rekal's `Formatter.markdown`\n * skip test so we avoid double-rendering pre-styled strings. */\nexport function isMarkdown(s: string): boolean {\n return MD_RE.test(s) && !hasAnsi(s) && !JSON_RE.test(s)\n}\n\nconst isFormatString = (v: unknown): v is string =>\n typeof v === \"string\" && FORMAT_RE.test(v) && !hasAnsi(v)\n\n/**\n * Inspect a list of args the way `console.log` does, returning a single\n * string. Collapses `util.format` placeholders right-to-left, unwraps\n * `Error` values to their message (unless `stacktrace: true`), and falls\n * back to `util.formatWithOptions` for mixed values.\n */\nexport function inspectFormat(msg: unknown[], opts: InspectOpts = {}): string {\n const data = opts.stacktrace ? msg : msg.map((v) => (v instanceof Error ? v.message : v))\n opts = { colors: hasColors, ...opts }\n\n let ret: unknown[] = []\n // oxlint-disable-next-line oxc/no-accumulating-spread\n for (let i = data.length - 1; i >= 0; i--) {\n const item = data[i]\n if (isFormatString(item)) ret = [formatWithOptions(opts, item, ...ret)]\n else ret.unshift(item)\n }\n\n if (ret.length > 1 && isFormatString(ret[0])) return formatWithOptions(opts, ...ret)\n return ret.map((v) => (typeof v === \"string\" ? v : inspect(v, opts))).join(\" \")\n}\n\nfunction inspectNumber(value: number): string {\n return new Intl.NumberFormat(\"en-US\", {\n notation: \"standard\",\n useGrouping: true,\n })\n .format(value)\n .replace(/,/g, \"_\")\n}\n\nfunction inspectField(key: string, s: StyleBuilder): string {\n if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) return s.syntaxField(key)\n return s.syntaxString(JSON.stringify(key))\n}\n\nexport function inspect(value: unknown, opts: InspectOpts = {}): string {\n opts = { colors: hasColors, null: true, undefined: true, ...opts }\n const indent = opts.indent ?? 2\n const s = opts.colors ? (opts.style ?? styleBuilder()) : styleBuilder(false)\n const sym = {\n \",\": s.syntaxDelimiter(\",\"),\n \":\": s.syntaxDelimiter(\":\"),\n \"[\": s.syntaxBracket(\"[\"),\n \"]\": s.syntaxBracket(\"]\"),\n \"{\": s.syntaxBracket(\"{\"),\n \"}\": s.syntaxBracket(\"}\"),\n }\n const seen = new Set()\n\n const $inspect = (v: unknown, depth: number): string => {\n if (seen.has(v)) return s.bold(\"[Circular]\")\n if (typeof v === \"object\" && v !== null) seen.add(v)\n if (v === null) return s.syntaxConstant(\"null\")\n switch (typeof v) {\n case \"boolean\": {\n return s.syntaxBoolean(String(v))\n }\n case \"bigint\": {\n return s.syntaxNumber(`${v}n`)\n }\n case \"number\": {\n return s.syntaxNumber(inspectNumber(v))\n }\n case \"string\": {\n return s.syntaxString(JSON.stringify(v))\n }\n case \"symbol\": {\n return s.syntaxSpecial(String(v))\n }\n case \"function\": {\n return s.syntaxFunction(`[Function${v.name ? `: ${v.name}` : \"\"}]`)\n }\n case \"undefined\": {\n return s.syntaxConstant(\"undefined\")\n }\n case \"object\": {\n if (Array.isArray(v)) {\n const items = v.map((item) => $inspect(item, depth + 1))\n return `${sym[\"[\"]} ${items.join(`${sym[\",\"]} `)} ${sym[\"]\"]}`\n }\n const isPlainObject = Object.getPrototypeOf(v) === Object.prototype\n if (!isPlainObject) break\n const entries = Object.entries(v)\n .filter(\n ([_, val]) => !((val === undefined && !opts.undefined) || (val === null && !opts.null))\n )\n .map(([key, val]) => `${inspectField(key, s)}: ${$inspect(val, depth + 1)}`)\n if (indent) {\n const padding = \" \".repeat(indent * depth)\n return `${sym[\"{\"]}\\n${padding}${entries.join(`${sym[\",\"]}\\n${padding}`)}\\n${\" \".repeat(indent * (depth - 1))}${sym[\"}\"]}`\n }\n return `${sym[\"{\"]} ${entries.join(`${sym[\",\"]} `)} ${sym[\"}\"]}`\n }\n }\n return nodeInspect(v, { colors: true, compact: true })\n }\n return $inspect(value, 1)\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { c as Color, f as Style, i as AnsiColorName, s as BrightAnsiColorName, t as Theme } from "./types-B9Eh7k2v.mjs";
|
|
2
|
+
//#region src/style/builder.d.ts
|
|
3
|
+
type AttrName = "bold" | "dim" | "italic" | "underline" | "inverse" | "strikethrough";
|
|
4
|
+
type AnyThemeKey = Exclude<keyof Theme, "shiki" | "$schema"> | (string & {});
|
|
5
|
+
type ChainSlot = Exclude<keyof Theme, "fg" | "bg" | AttrName>;
|
|
6
|
+
type FgChainKey = AnsiColorName | BrightAnsiColorName | ChainSlot;
|
|
7
|
+
type BgChainKey = `bg${Capitalize<FgChainKey>}`;
|
|
8
|
+
type FgExtractKey = `fg${Capitalize<FgChainKey>}`;
|
|
9
|
+
type StyleBuilder = {
|
|
10
|
+
theme: Theme;
|
|
11
|
+
(text: string): string;
|
|
12
|
+
fg: (color: Color) => StyleBuilder;
|
|
13
|
+
bg: (color: Color) => StyleBuilder;
|
|
14
|
+
add: (slot?: AnyThemeKey | Style) => StyleBuilder;
|
|
15
|
+
lighten: (n: number) => StyleBuilder;
|
|
16
|
+
darken: (n: number) => StyleBuilder;
|
|
17
|
+
} & { readonly [K in AttrName | FgChainKey | BgChainKey | FgExtractKey]: StyleBuilder; };
|
|
18
|
+
/**
|
|
19
|
+
* Build styled strings via chainable property access.
|
|
20
|
+
*
|
|
21
|
+
* ```ts
|
|
22
|
+
* style().red.bold("err") // → "\x1b[1;31merr\x1b[0m"
|
|
23
|
+
* style().primary.bgAccent("x") // theme slots via the default theme
|
|
24
|
+
* style(myTheme).primary("x") // override the bound theme
|
|
25
|
+
* style().fg("#82aaff")("x") // hex via the escape hatch
|
|
26
|
+
* style().primary[300]("x") // tonal variant of the last color
|
|
27
|
+
* style().bgDiffAdd[200].fgDiffAdd("x") // per-channel variants on a Style slot
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Each property access returns a fresh builder, so intermediates can be
|
|
31
|
+
* reused and extended without mutation:
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* const err = style().red.bold
|
|
35
|
+
* err("oops"); err.underline("fatal")
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Calling an empty builder is a no-op: `styleBuilder()("x")` returns `"x"` unchanged.
|
|
39
|
+
*/
|
|
40
|
+
declare function styleBuilder(theme?: Theme | false): StyleBuilder;
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/style/inspect.d.ts
|
|
43
|
+
interface InspectOpts {
|
|
44
|
+
style?: StyleBuilder;
|
|
45
|
+
indent?: number;
|
|
46
|
+
undefined?: boolean;
|
|
47
|
+
null?: boolean;
|
|
48
|
+
/** When `true`, preserve Error stack traces. Default: `false` — Error
|
|
49
|
+
* values are reduced to their `.message` so logs stay compact. */
|
|
50
|
+
stacktrace?: boolean;
|
|
51
|
+
colors?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** True when `s` looks like markdown we should render — contains MD
|
|
54
|
+
* markers and isn't already ANSI-styled. Mirrors rekal's `Formatter.markdown`
|
|
55
|
+
* skip test so we avoid double-rendering pre-styled strings. */
|
|
56
|
+
declare function isMarkdown(s: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Inspect a list of args the way `console.log` does, returning a single
|
|
59
|
+
* string. Collapses `util.format` placeholders right-to-left, unwraps
|
|
60
|
+
* `Error` values to their message (unless `stacktrace: true`), and falls
|
|
61
|
+
* back to `util.formatWithOptions` for mixed values.
|
|
62
|
+
*/
|
|
63
|
+
declare function inspectFormat(msg: unknown[], opts?: InspectOpts): string;
|
|
64
|
+
declare function inspect(value: unknown, opts?: InspectOpts): string;
|
|
65
|
+
//#endregion
|
|
66
|
+
export { StyleBuilder as a, isMarkdown as i, inspect as n, styleBuilder as o, inspectFormat as r, InspectOpts as t };
|
|
67
|
+
//# sourceMappingURL=inspect-D6FW_QUo.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-D6FW_QUo.d.mts","names":[],"sources":["../src/style/builder.ts","../src/style/inspect.ts"],"mappings":";;KAOK;KAEA,cAAc,cAAc;KAK5B,YAAY,cAAc,qBAAqB;KAE/C,aAAa,gBAAgB,sBAAsB;KACnD,kBAAkB,WAAW;KAC7B,oBAAoB,WAAW;KAExB;EACV,OAAO;GACN;EACD,KAAK,OAAO,UAAU;EACtB,KAAK,OAAO,UAAU;EACtB,MAAM,OAAO,cAAc,UAAU;EACrC,UAAU,cAAc;EACxB,SAAS,cAAc;gBAGb,KAAK,WAAW,aAAa,aAAa,eAAe;;;;;;;;;;;;;;;;;;;;;;;iBAyBrD,aAAa,QAAO,gBAA+B;;;UChDlD;EACf,QAAQ;EACR;EACA;EACA;;;EAGA;EACA;;;;;iBAac,WAAW;;;;;;;iBAaX,cAAc,gBAAgB,OAAM;iBA8BpC,QAAQ,gBAAgB,OAAM"}
|