tinky-mouse 0.1.0
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 +190 -0
- package/README.ja-JP.md +95 -0
- package/README.md +95 -0
- package/README.zh-CN.md +95 -0
- package/lib/contexts/MouseContext.d.ts +53 -0
- package/lib/contexts/MouseContext.js +169 -0
- package/lib/hooks/use-mouse-context.d.ts +9 -0
- package/lib/hooks/use-mouse-context.js +20 -0
- package/lib/hooks/use-mouse.d.ts +20 -0
- package/lib/hooks/use-mouse.js +32 -0
- package/lib/hooks/useMouse.d.ts +4 -0
- package/lib/hooks/useMouse.js +16 -0
- package/lib/hooks/useMouseContext.d.ts +1 -0
- package/lib/hooks/useMouseContext.js +12 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +11 -0
- package/lib/utils/events.d.ts +17 -0
- package/lib/utils/events.js +14 -0
- package/lib/utils/input.d.ts +12 -0
- package/lib/utils/input.js +51 -0
- package/lib/utils/mouse.d.ts +90 -0
- package/lib/utils/mouse.js +222 -0
- package/lib/utils/sequences.d.ts +52 -0
- package/lib/utils/sequences.js +90 -0
- package/package.json +73 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMouseEventName = getMouseEventName;
|
|
4
|
+
exports.parseSGRMouseEvent = parseSGRMouseEvent;
|
|
5
|
+
exports.parseX11MouseEvent = parseX11MouseEvent;
|
|
6
|
+
exports.parseMouseEvent = parseMouseEvent;
|
|
7
|
+
exports.isIncompleteMouseSequence = isIncompleteMouseSequence;
|
|
8
|
+
var sequences_js_1 = require("./sequences.js");
|
|
9
|
+
/**
|
|
10
|
+
* Derives the `MouseEventName` from the SGR button code and release state.
|
|
11
|
+
*
|
|
12
|
+
* @param buttonCode - The numerical code from the SGR sequence.
|
|
13
|
+
* @param isRelease - Whether the event is a release event (last char is 'm').
|
|
14
|
+
* @returns The `MouseEventName` or `null` if unknown.
|
|
15
|
+
*/
|
|
16
|
+
function getMouseEventName(buttonCode, isRelease) {
|
|
17
|
+
var isMove = (buttonCode & 32) !== 0;
|
|
18
|
+
if (buttonCode === 66) {
|
|
19
|
+
return "scroll-left";
|
|
20
|
+
}
|
|
21
|
+
else if (buttonCode === 67) {
|
|
22
|
+
return "scroll-right";
|
|
23
|
+
}
|
|
24
|
+
else if ((buttonCode & 64) === 64) {
|
|
25
|
+
if ((buttonCode & 1) === 0) {
|
|
26
|
+
return "scroll-up";
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return "scroll-down";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (isMove) {
|
|
33
|
+
return "move";
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
var button = buttonCode & 3;
|
|
37
|
+
var type = isRelease ? "release" : "press";
|
|
38
|
+
switch (button) {
|
|
39
|
+
case 0:
|
|
40
|
+
return "left-".concat(type);
|
|
41
|
+
case 1:
|
|
42
|
+
return "middle-".concat(type);
|
|
43
|
+
case 2:
|
|
44
|
+
return "right-".concat(type);
|
|
45
|
+
default:
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function getButtonFromCode(code) {
|
|
51
|
+
var button = code & 3;
|
|
52
|
+
switch (button) {
|
|
53
|
+
case 0:
|
|
54
|
+
return "left";
|
|
55
|
+
case 1:
|
|
56
|
+
return "middle";
|
|
57
|
+
case 2:
|
|
58
|
+
return "right";
|
|
59
|
+
default:
|
|
60
|
+
return "none";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Parses an SGR (1006) mouse sequence.
|
|
65
|
+
*
|
|
66
|
+
* @param buffer - The input string containing the sequence.
|
|
67
|
+
* @returns An object containing the parsed event and the length of the matched sequence, or `null` if not an SGR sequence.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* parseSGRMouseEvent("\x1b[<0;10;10M"); // Left press at 10,10
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
function parseSGRMouseEvent(buffer) {
|
|
75
|
+
var match = buffer.match(sequences_js_1.SGR_MOUSE_REGEX);
|
|
76
|
+
if (match) {
|
|
77
|
+
var buttonCode = parseInt(match[1], 10);
|
|
78
|
+
var col = parseInt(match[2], 10);
|
|
79
|
+
var row = parseInt(match[3], 10);
|
|
80
|
+
var action = match[4];
|
|
81
|
+
var isRelease = action === "m";
|
|
82
|
+
var shift = (buttonCode & 4) !== 0;
|
|
83
|
+
var meta = (buttonCode & 8) !== 0;
|
|
84
|
+
var ctrl = (buttonCode & 16) !== 0;
|
|
85
|
+
var name_1 = getMouseEventName(buttonCode, isRelease);
|
|
86
|
+
if (name_1) {
|
|
87
|
+
return {
|
|
88
|
+
event: {
|
|
89
|
+
name: name_1,
|
|
90
|
+
ctrl: ctrl,
|
|
91
|
+
meta: meta,
|
|
92
|
+
shift: shift,
|
|
93
|
+
col: col,
|
|
94
|
+
row: row,
|
|
95
|
+
button: getButtonFromCode(buttonCode),
|
|
96
|
+
},
|
|
97
|
+
length: match[0].length,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Parses an X11 mouse sequence.
|
|
106
|
+
*
|
|
107
|
+
* @param buffer - The input string containing the sequence.
|
|
108
|
+
* @returns An object containing the parsed event and the length of the matched sequence, or `null` if not an X11 sequence.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* parseX11MouseEvent("\x1b[M..."); // Parsed X11 event
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
function parseX11MouseEvent(buffer) {
|
|
116
|
+
var match = buffer.match(sequences_js_1.X11_MOUSE_REGEX);
|
|
117
|
+
if (!match)
|
|
118
|
+
return null;
|
|
119
|
+
// The 3 bytes are in match[1]
|
|
120
|
+
var b = match[1].charCodeAt(0) - 32;
|
|
121
|
+
var col = match[1].charCodeAt(1) - 32;
|
|
122
|
+
var row = match[1].charCodeAt(2) - 32;
|
|
123
|
+
var shift = (b & 4) !== 0;
|
|
124
|
+
var meta = (b & 8) !== 0;
|
|
125
|
+
var ctrl = (b & 16) !== 0;
|
|
126
|
+
var isMove = (b & 32) !== 0;
|
|
127
|
+
var isWheel = (b & 64) !== 0;
|
|
128
|
+
var name = null;
|
|
129
|
+
if (isWheel) {
|
|
130
|
+
var button = b & 3;
|
|
131
|
+
switch (button) {
|
|
132
|
+
case 0:
|
|
133
|
+
name = "scroll-up";
|
|
134
|
+
break;
|
|
135
|
+
case 1:
|
|
136
|
+
name = "scroll-down";
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if (isMove) {
|
|
143
|
+
name = "move";
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
var button = b & 3;
|
|
147
|
+
if (button === 3) {
|
|
148
|
+
// X11 reports 'release' (3) for all button releases without specifying which one.
|
|
149
|
+
// We'll default to 'left-release' as a best-effort guess if we don't track state.
|
|
150
|
+
name = "left-release";
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
switch (button) {
|
|
154
|
+
case 0:
|
|
155
|
+
name = "left-press";
|
|
156
|
+
break;
|
|
157
|
+
case 1:
|
|
158
|
+
name = "middle-press";
|
|
159
|
+
break;
|
|
160
|
+
case 2:
|
|
161
|
+
name = "right-press";
|
|
162
|
+
break;
|
|
163
|
+
default:
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (name) {
|
|
169
|
+
var button = getButtonFromCode(b);
|
|
170
|
+
if (name === "left-release" && button === "none") {
|
|
171
|
+
button = "left";
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
event: {
|
|
175
|
+
name: name,
|
|
176
|
+
ctrl: ctrl,
|
|
177
|
+
meta: meta,
|
|
178
|
+
shift: shift,
|
|
179
|
+
col: col,
|
|
180
|
+
row: row,
|
|
181
|
+
button: button,
|
|
182
|
+
},
|
|
183
|
+
length: match[0].length,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Attempts to parse a mouse event from the buffer, trying both SGR and X11 formats.
|
|
190
|
+
*
|
|
191
|
+
* @param buffer - The input string.
|
|
192
|
+
* @returns The parsed event and length, or `null`.
|
|
193
|
+
*/
|
|
194
|
+
function parseMouseEvent(buffer) {
|
|
195
|
+
return parseSGRMouseEvent(buffer) || parseX11MouseEvent(buffer);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Checks if the buffer contains an incomplete mouse sequence.
|
|
199
|
+
* This is useful for knowing if we should wait for more data before processing.
|
|
200
|
+
*
|
|
201
|
+
* @param buffer - The input string.
|
|
202
|
+
* @returns `true` if the buffer looks like the start of a mouse sequence but is incomplete.
|
|
203
|
+
*/
|
|
204
|
+
function isIncompleteMouseSequence(buffer) {
|
|
205
|
+
if (!(0, sequences_js_1.couldBeMouseSequence)(buffer))
|
|
206
|
+
return false;
|
|
207
|
+
// If it matches a complete sequence, it's not incomplete.
|
|
208
|
+
if (parseMouseEvent(buffer))
|
|
209
|
+
return false;
|
|
210
|
+
if (buffer.startsWith(sequences_js_1.X11_EVENT_PREFIX)) {
|
|
211
|
+
// X11 needs exactly 3 bytes after prefix.
|
|
212
|
+
return buffer.length < sequences_js_1.X11_EVENT_PREFIX.length + 3;
|
|
213
|
+
}
|
|
214
|
+
if (buffer.startsWith(sequences_js_1.SGR_EVENT_PREFIX)) {
|
|
215
|
+
// SGR sequences end with 'm' or 'M'.
|
|
216
|
+
// If it doesn't have it yet, it's incomplete.
|
|
217
|
+
// Add a reasonable max length check to fail early on garbage.
|
|
218
|
+
return !/[mM]/.test(buffer) && buffer.length < 50;
|
|
219
|
+
}
|
|
220
|
+
// It's a prefix of the prefix (e.g. "ESC" or "ESC [")
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** ESC character (ASCII 27). */
|
|
2
|
+
export declare const ESC = "\u001B";
|
|
3
|
+
/** Prefix for SGR (1006) mouse sequences. */
|
|
4
|
+
export declare const SGR_EVENT_PREFIX = "\u001B[<";
|
|
5
|
+
/** Prefix for X11 mouse sequences. */
|
|
6
|
+
export declare const X11_EVENT_PREFIX = "\u001B[M";
|
|
7
|
+
/** Regex to match a complete SGR mouse event sequence. */
|
|
8
|
+
export declare const SGR_MOUSE_REGEX: RegExp;
|
|
9
|
+
/** Regex to match a complete X11 mouse event sequence. */
|
|
10
|
+
export declare const X11_MOUSE_REGEX: RegExp;
|
|
11
|
+
/**
|
|
12
|
+
* Checks if the buffer starts with or is a prefix of an SGR mouse sequence.
|
|
13
|
+
*
|
|
14
|
+
* @param buffer - The input string buffer.
|
|
15
|
+
* @returns `true` if it could be an SGR sequence, `false` otherwise.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* couldBeSGRMouseSequence("\x1b[<"); // true
|
|
20
|
+
* couldBeSGRMouseSequence("\x1b[<0;0;0M"); // true
|
|
21
|
+
* couldBeSGRMouseSequence("hello"); // false
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function couldBeSGRMouseSequence(buffer: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Checks if the buffer starts with or is a prefix of any known mouse sequence (SGR or X11).
|
|
27
|
+
*
|
|
28
|
+
* @param buffer - The input string buffer.
|
|
29
|
+
* @returns `true` if it could be a mouse sequence, `false` otherwise.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* couldBeMouseSequence("\x1b[M"); // true
|
|
34
|
+
* couldBeMouseSequence("\x1b[<"); // true
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function couldBeMouseSequence(buffer: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if the buffer *starts* with a complete mouse sequence.
|
|
40
|
+
* Returns the length of the sequence if matched, or 0 if not.
|
|
41
|
+
*
|
|
42
|
+
* @param buffer - The input string buffer.
|
|
43
|
+
* @returns The length of the sequence in bytes/characters, or 0 if no complete sequence is found at the start.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* getMouseSequenceLength("\x1b[<0;10;10M"); // Returns length of the sequence
|
|
48
|
+
* getMouseSequenceLength("\x1b[M "); // Returns length of X11 sequence
|
|
49
|
+
* getMouseSequenceLength("not mouse"); // 0
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function getMouseSequenceLength(buffer: string): number;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.X11_MOUSE_REGEX = exports.SGR_MOUSE_REGEX = exports.X11_EVENT_PREFIX = exports.SGR_EVENT_PREFIX = exports.ESC = void 0;
|
|
4
|
+
exports.couldBeSGRMouseSequence = couldBeSGRMouseSequence;
|
|
5
|
+
exports.couldBeMouseSequence = couldBeMouseSequence;
|
|
6
|
+
exports.getMouseSequenceLength = getMouseSequenceLength;
|
|
7
|
+
/* eslint-disable no-control-regex */
|
|
8
|
+
/** ESC character (ASCII 27). */
|
|
9
|
+
exports.ESC = "\u001B";
|
|
10
|
+
/** Prefix for SGR (1006) mouse sequences. */
|
|
11
|
+
exports.SGR_EVENT_PREFIX = "".concat(exports.ESC, "[<");
|
|
12
|
+
/** Prefix for X11 mouse sequences. */
|
|
13
|
+
exports.X11_EVENT_PREFIX = "".concat(exports.ESC, "[M");
|
|
14
|
+
/** Regex to match a complete SGR mouse event sequence. */
|
|
15
|
+
exports.SGR_MOUSE_REGEX = /^\x1b\[<(\d+);(\d+);(\d+)([mM])/; // SGR mouse events
|
|
16
|
+
// X11 is ESC [ M followed by 3 bytes.
|
|
17
|
+
/** Regex to match a complete X11 mouse event sequence. */
|
|
18
|
+
exports.X11_MOUSE_REGEX = /^\x1b\[M([\s\S]{3})/;
|
|
19
|
+
/**
|
|
20
|
+
* Checks if the buffer starts with or is a prefix of an SGR mouse sequence.
|
|
21
|
+
*
|
|
22
|
+
* @param buffer - The input string buffer.
|
|
23
|
+
* @returns `true` if it could be an SGR sequence, `false` otherwise.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* couldBeSGRMouseSequence("\x1b[<"); // true
|
|
28
|
+
* couldBeSGRMouseSequence("\x1b[<0;0;0M"); // true
|
|
29
|
+
* couldBeSGRMouseSequence("hello"); // false
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function couldBeSGRMouseSequence(buffer) {
|
|
33
|
+
if (buffer.length === 0)
|
|
34
|
+
return true;
|
|
35
|
+
// Check if buffer is a prefix of a mouse sequence starter
|
|
36
|
+
if (exports.SGR_EVENT_PREFIX.startsWith(buffer))
|
|
37
|
+
return true;
|
|
38
|
+
// Check if buffer is a mouse sequence prefix
|
|
39
|
+
if (buffer.startsWith(exports.SGR_EVENT_PREFIX))
|
|
40
|
+
return true;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Checks if the buffer starts with or is a prefix of any known mouse sequence (SGR or X11).
|
|
45
|
+
*
|
|
46
|
+
* @param buffer - The input string buffer.
|
|
47
|
+
* @returns `true` if it could be a mouse sequence, `false` otherwise.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* couldBeMouseSequence("\x1b[M"); // true
|
|
52
|
+
* couldBeMouseSequence("\x1b[<"); // true
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
function couldBeMouseSequence(buffer) {
|
|
56
|
+
if (buffer.length === 0)
|
|
57
|
+
return true;
|
|
58
|
+
// Check SGR prefix
|
|
59
|
+
if (exports.SGR_EVENT_PREFIX.startsWith(buffer) ||
|
|
60
|
+
buffer.startsWith(exports.SGR_EVENT_PREFIX))
|
|
61
|
+
return true;
|
|
62
|
+
// Check X11 prefix
|
|
63
|
+
if (exports.X11_EVENT_PREFIX.startsWith(buffer) ||
|
|
64
|
+
buffer.startsWith(exports.X11_EVENT_PREFIX))
|
|
65
|
+
return true;
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Checks if the buffer *starts* with a complete mouse sequence.
|
|
70
|
+
* Returns the length of the sequence if matched, or 0 if not.
|
|
71
|
+
*
|
|
72
|
+
* @param buffer - The input string buffer.
|
|
73
|
+
* @returns The length of the sequence in bytes/characters, or 0 if no complete sequence is found at the start.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* getMouseSequenceLength("\x1b[<0;10;10M"); // Returns length of the sequence
|
|
78
|
+
* getMouseSequenceLength("\x1b[M "); // Returns length of X11 sequence
|
|
79
|
+
* getMouseSequenceLength("not mouse"); // 0
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
function getMouseSequenceLength(buffer) {
|
|
83
|
+
var sgrMatch = buffer.match(exports.SGR_MOUSE_REGEX);
|
|
84
|
+
if (sgrMatch)
|
|
85
|
+
return sgrMatch[0].length;
|
|
86
|
+
var x11Match = buffer.match(exports.X11_MOUSE_REGEX);
|
|
87
|
+
if (x11Match)
|
|
88
|
+
return x11Match[0].length;
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tinky-mouse",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Mouse event handling for tinky applications",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"tinky",
|
|
7
|
+
"mouse",
|
|
8
|
+
"event",
|
|
9
|
+
"input",
|
|
10
|
+
"terminal",
|
|
11
|
+
"interaction"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/ByteLandTechnology/tinky-mouse#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/ByteLandTechnology/tinky-mouse/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/ByteLandTechnology/tinky-mouse.git"
|
|
20
|
+
},
|
|
21
|
+
"license": "Apache-2.0",
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "ByteLand Technology Limited"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./lib/index.js",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "bun test",
|
|
29
|
+
"build": "tsc && npm run docs",
|
|
30
|
+
"lint": "eslint src tests",
|
|
31
|
+
"prepublish": "npm run build",
|
|
32
|
+
"prepare": "husky",
|
|
33
|
+
"docs": "typedoc --plugin typedoc-plugin-markdown --disableSources --out docs/api && prettier --write docs/api"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"./bin/*",
|
|
37
|
+
"./lib/*"
|
|
38
|
+
],
|
|
39
|
+
"typings": "./lib/index.d.ts",
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"tinky": "^1.2.2"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@commitlint/cli": "^20.3.0",
|
|
45
|
+
"@commitlint/config-conventional": "^20.3.0",
|
|
46
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
47
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
48
|
+
"@semantic-release/git": "^10.0.1",
|
|
49
|
+
"@semantic-release/github": "^12.0.2",
|
|
50
|
+
"@semantic-release/npm": "^13.1.3",
|
|
51
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
52
|
+
"@types/bun": "^1.3.6",
|
|
53
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
54
|
+
"eslint": "^9.39.2",
|
|
55
|
+
"eslint-plugin-react": "^7.37.5",
|
|
56
|
+
"husky": "^9.1.7",
|
|
57
|
+
"jiti": "^2.6.1",
|
|
58
|
+
"lint-staged": "^16.2.7",
|
|
59
|
+
"prettier": "^3.7.4",
|
|
60
|
+
"semantic-release": "^25.0.2",
|
|
61
|
+
"typedoc": "^0.28.16",
|
|
62
|
+
"typedoc-plugin-markdown": "^4.9.0",
|
|
63
|
+
"typescript-eslint": "^8.53.0"
|
|
64
|
+
},
|
|
65
|
+
"commitlint": {
|
|
66
|
+
"extends": [
|
|
67
|
+
"@commitlint/config-conventional"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"lint-staged": {
|
|
71
|
+
"*.{js,ts,jsx,tsx,json,md,yaml,yml}": "prettier --write"
|
|
72
|
+
}
|
|
73
|
+
}
|