@hesed/mysql 0.6.0 → 0.6.1
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 +13 -13
- package/dist/commands/mysql/describe-table.d.ts +1 -1
- package/dist/commands/mysql/explain.d.ts +1 -1
- package/dist/commands/mysql/indexes.d.ts +1 -1
- package/dist/commands/mysql/query.d.ts +1 -1
- package/dist/mysql/config-loader.d.ts +6 -6
- package/dist/mysql/database.d.ts +19 -19
- package/dist/mysql/formatters.js +1 -0
- package/dist/mysql/mysql-client.js +5 -4
- package/dist/mysql/mysql-utils.d.ts +4 -4
- package/dist/mysql/mysql-utils.js +15 -9
- package/dist/mysql/query-validator.d.ts +6 -6
- package/dist/mysql/query-validator.js +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ $ npm install -g @hesed/mysql
|
|
|
26
26
|
$ mq COMMAND
|
|
27
27
|
running command...
|
|
28
28
|
$ mq (--version)
|
|
29
|
-
@hesed/mysql/0.6.
|
|
29
|
+
@hesed/mysql/0.6.1 linux-x64 node-v24.18.0
|
|
30
30
|
$ mq --help [COMMAND]
|
|
31
31
|
USAGE
|
|
32
32
|
$ mq COMMAND
|
|
@@ -82,7 +82,7 @@ EXAMPLES
|
|
|
82
82
|
$ mq mysql auth add -p prod
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
_See code: [src/commands/mysql/auth/add.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
85
|
+
_See code: [src/commands/mysql/auth/add.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/auth/add.ts)_
|
|
86
86
|
|
|
87
87
|
## `mq mysql auth delete`
|
|
88
88
|
|
|
@@ -107,7 +107,7 @@ EXAMPLES
|
|
|
107
107
|
$ mq mysql auth delete -p prod
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
_See code: [src/commands/mysql/auth/delete.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
110
|
+
_See code: [src/commands/mysql/auth/delete.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/auth/delete.ts)_
|
|
111
111
|
|
|
112
112
|
## `mq mysql auth list`
|
|
113
113
|
|
|
@@ -127,7 +127,7 @@ EXAMPLES
|
|
|
127
127
|
$ mq mysql auth list
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
_See code: [src/commands/mysql/auth/list.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
130
|
+
_See code: [src/commands/mysql/auth/list.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/auth/list.ts)_
|
|
131
131
|
|
|
132
132
|
## `mq mysql auth profile`
|
|
133
133
|
|
|
@@ -152,7 +152,7 @@ EXAMPLES
|
|
|
152
152
|
$ mq mysql auth profile --default test
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
_See code: [src/commands/mysql/auth/profile.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
155
|
+
_See code: [src/commands/mysql/auth/profile.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/auth/profile.ts)_
|
|
156
156
|
|
|
157
157
|
## `mq mysql auth test`
|
|
158
158
|
|
|
@@ -177,7 +177,7 @@ EXAMPLES
|
|
|
177
177
|
$ mq mysql auth test -p prod
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
_See code: [src/commands/mysql/auth/test.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
180
|
+
_See code: [src/commands/mysql/auth/test.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/auth/test.ts)_
|
|
181
181
|
|
|
182
182
|
## `mq mysql auth update`
|
|
183
183
|
|
|
@@ -211,7 +211,7 @@ EXAMPLES
|
|
|
211
211
|
$ mq mysql auth update -p test
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
-
_See code: [src/commands/mysql/auth/update.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
214
|
+
_See code: [src/commands/mysql/auth/update.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/auth/update.ts)_
|
|
215
215
|
|
|
216
216
|
## `mq mysql databases`
|
|
217
217
|
|
|
@@ -236,7 +236,7 @@ EXAMPLES
|
|
|
236
236
|
$ mq mysql databases -p staging
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
-
_See code: [src/commands/mysql/databases.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
239
|
+
_See code: [src/commands/mysql/databases.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/databases.ts)_
|
|
240
240
|
|
|
241
241
|
## `mq mysql describe-table TABLE`
|
|
242
242
|
|
|
@@ -265,7 +265,7 @@ EXAMPLES
|
|
|
265
265
|
$ mq mysql describe-table orders --toon -p prod
|
|
266
266
|
```
|
|
267
267
|
|
|
268
|
-
_See code: [src/commands/mysql/describe-table.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
268
|
+
_See code: [src/commands/mysql/describe-table.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/describe-table.ts)_
|
|
269
269
|
|
|
270
270
|
## `mq mysql explain QUERY`
|
|
271
271
|
|
|
@@ -294,7 +294,7 @@ EXAMPLES
|
|
|
294
294
|
$ mq mysql explain "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --json
|
|
295
295
|
```
|
|
296
296
|
|
|
297
|
-
_See code: [src/commands/mysql/explain.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
297
|
+
_See code: [src/commands/mysql/explain.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/explain.ts)_
|
|
298
298
|
|
|
299
299
|
## `mq mysql indexes TABLE`
|
|
300
300
|
|
|
@@ -323,7 +323,7 @@ EXAMPLES
|
|
|
323
323
|
$ mq mysql indexes orders --json -p prod
|
|
324
324
|
```
|
|
325
325
|
|
|
326
|
-
_See code: [src/commands/mysql/indexes.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
326
|
+
_See code: [src/commands/mysql/indexes.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/indexes.ts)_
|
|
327
327
|
|
|
328
328
|
## `mq mysql query QUERY`
|
|
329
329
|
|
|
@@ -355,7 +355,7 @@ EXAMPLES
|
|
|
355
355
|
$ mq mysql query "DELETE FROM sessions" -p prod --skip-confirmation
|
|
356
356
|
```
|
|
357
357
|
|
|
358
|
-
_See code: [src/commands/mysql/query.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
358
|
+
_See code: [src/commands/mysql/query.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/query.ts)_
|
|
359
359
|
|
|
360
360
|
## `mq mysql tables`
|
|
361
361
|
|
|
@@ -380,5 +380,5 @@ EXAMPLES
|
|
|
380
380
|
$ mq mysql tables -p local
|
|
381
381
|
```
|
|
382
382
|
|
|
383
|
-
_See code: [src/commands/mysql/tables.ts](https://github.com/hesedcasa/mysql/blob/v0.6.
|
|
383
|
+
_See code: [src/commands/mysql/tables.ts](https://github.com/hesedcasa/mysql/blob/v0.6.1/src/commands/mysql/tables.ts)_
|
|
384
384
|
<!-- commandsstop -->
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ConnectionOptions as MySQL2ConnectionOptions } from 'mysql2/promise';
|
|
2
|
-
export
|
|
2
|
+
export type DatabaseProfile = {
|
|
3
3
|
database: string;
|
|
4
4
|
host: string;
|
|
5
5
|
maxConcurrentQueries?: number;
|
|
@@ -8,20 +8,20 @@ export interface DatabaseProfile {
|
|
|
8
8
|
queryQueueTimeoutMs?: number;
|
|
9
9
|
ssl?: boolean;
|
|
10
10
|
user: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
11
|
+
};
|
|
12
|
+
type SafetyConfig = {
|
|
13
13
|
blacklistedOperations: string[];
|
|
14
14
|
defaultLimit: number;
|
|
15
15
|
maxConcurrentQueries?: number;
|
|
16
16
|
queryQueueTimeoutMs?: number;
|
|
17
17
|
requireConfirmationFor: string[];
|
|
18
|
-
}
|
|
19
|
-
export
|
|
18
|
+
};
|
|
19
|
+
export type MySQLConfig = {
|
|
20
20
|
defaultFormat: 'csv' | 'json' | 'table' | 'toon';
|
|
21
21
|
defaultProfile: string;
|
|
22
22
|
profiles: Record<string, DatabaseProfile>;
|
|
23
23
|
safety: SafetyConfig;
|
|
24
|
-
}
|
|
24
|
+
};
|
|
25
25
|
type MySQLConnectionOptions = Pick<MySQL2ConnectionOptions, 'connectTimeout' | 'database' | 'host' | 'multipleStatements' | 'password' | 'port' | 'ssl' | 'user'>;
|
|
26
26
|
export declare function getMySQLConnectionOptions(config: MySQLConfig, profileName: string): MySQLConnectionOptions;
|
|
27
27
|
export {};
|
package/dist/mysql/database.d.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import type { ApiResult } from '@hesed/plugin-lib';
|
|
2
2
|
export type OutputFormat = 'csv' | 'json' | 'table' | 'toon';
|
|
3
|
-
export
|
|
3
|
+
export type QueryData = {
|
|
4
4
|
message?: string;
|
|
5
5
|
notices?: string;
|
|
6
6
|
requiresConfirmation?: boolean;
|
|
7
7
|
result?: unknown;
|
|
8
|
-
}
|
|
9
|
-
export
|
|
8
|
+
};
|
|
9
|
+
export type DatabaseListData = {
|
|
10
10
|
databases: string[];
|
|
11
11
|
result?: string;
|
|
12
|
-
}
|
|
13
|
-
export
|
|
12
|
+
};
|
|
13
|
+
export type TableListData = {
|
|
14
14
|
result?: string;
|
|
15
15
|
tables: string[];
|
|
16
|
-
}
|
|
17
|
-
export
|
|
16
|
+
};
|
|
17
|
+
export type TableStructureData = {
|
|
18
18
|
result?: string;
|
|
19
|
-
structure: Record<string, unknown
|
|
20
|
-
}
|
|
21
|
-
export
|
|
22
|
-
indexes: Record<string, unknown
|
|
19
|
+
structure: Array<Record<string, unknown>>;
|
|
20
|
+
};
|
|
21
|
+
export type IndexData = {
|
|
22
|
+
indexes: Array<Record<string, unknown>>;
|
|
23
23
|
result?: string;
|
|
24
|
-
}
|
|
25
|
-
export
|
|
26
|
-
plan: Record<string, unknown
|
|
24
|
+
};
|
|
25
|
+
export type ExplainData = {
|
|
26
|
+
plan: Array<Record<string, unknown>>;
|
|
27
27
|
result?: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
28
|
+
};
|
|
29
|
+
type ConnectionTestData = {
|
|
30
30
|
database: string;
|
|
31
31
|
result?: string;
|
|
32
32
|
version: string;
|
|
33
|
-
}
|
|
33
|
+
};
|
|
34
34
|
export type QueryResult = ApiResult & {
|
|
35
35
|
data?: QueryData;
|
|
36
36
|
};
|
|
@@ -52,7 +52,7 @@ export type ExplainResult = ApiResult & {
|
|
|
52
52
|
export type ConnectionTestResult = ApiResult & {
|
|
53
53
|
data?: ConnectionTestData;
|
|
54
54
|
};
|
|
55
|
-
export
|
|
55
|
+
export type DatabaseUtil = {
|
|
56
56
|
closeAll(): Promise<void>;
|
|
57
57
|
describeTable(profileName: string, table: string, format?: OutputFormat): Promise<TableStructureResult>;
|
|
58
58
|
executeQuery(profileName: string, query: string, format?: OutputFormat, skipConfirmation?: boolean): Promise<QueryResult>;
|
|
@@ -60,5 +60,5 @@ export interface DatabaseUtil {
|
|
|
60
60
|
listDatabases(profileName: string): Promise<DatabaseListResult>;
|
|
61
61
|
listTables(profileName: string): Promise<TableListResult>;
|
|
62
62
|
showIndexes(profileName: string, table: string, format?: OutputFormat): Promise<IndexResult>;
|
|
63
|
-
}
|
|
63
|
+
};
|
|
64
64
|
export {};
|
package/dist/mysql/formatters.js
CHANGED
|
@@ -68,9 +68,10 @@ export async function testDirectConnection(profile) {
|
|
|
68
68
|
return result;
|
|
69
69
|
}
|
|
70
70
|
export async function closeConnections() {
|
|
71
|
-
if (mysqlUtil) {
|
|
72
|
-
|
|
73
|
-
mysqlUtil = null;
|
|
74
|
-
cachedConfig = null;
|
|
71
|
+
if (!mysqlUtil) {
|
|
72
|
+
return;
|
|
75
73
|
}
|
|
74
|
+
await mysqlUtil.closeAll();
|
|
75
|
+
mysqlUtil = null;
|
|
76
|
+
cachedConfig = null;
|
|
76
77
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { MySQLConfig } from './config-loader.js';
|
|
2
1
|
import type { ConnectionTestResult, DatabaseListResult, DatabaseUtil, ExplainResult, IndexResult, OutputFormat, QueryResult, TableListResult, TableStructureResult } from './database.js';
|
|
2
|
+
import { type MySQLConfig } from './config-loader.js';
|
|
3
3
|
export declare class MySQLUtil implements DatabaseUtil {
|
|
4
|
-
private config;
|
|
5
|
-
private pools;
|
|
6
|
-
private querySlots;
|
|
4
|
+
private readonly config;
|
|
5
|
+
private readonly pools;
|
|
6
|
+
private readonly querySlots;
|
|
7
7
|
constructor(config: MySQLConfig);
|
|
8
8
|
closeAll(): Promise<void>;
|
|
9
9
|
describeTable(profileName: string, table: string, format?: 'json' | 'table' | 'toon'): Promise<TableStructureResult>;
|
|
@@ -4,6 +4,10 @@ import { FORMATTERS } from './formatters.js';
|
|
|
4
4
|
import { analyzeQuery, applyDefaultLimit, checkBlacklist, getQueryType, requiresConfirmation } from './query-validator.js';
|
|
5
5
|
const DEFAULT_MAX_CONCURRENT_QUERIES = 5;
|
|
6
6
|
const DEFAULT_QUEUE_TIMEOUT_MS = 60_000;
|
|
7
|
+
// Formats that must emit only the data payload on stdout.
|
|
8
|
+
const MACHINE_FORMATS = new Set(['csv', 'json', 'toon']);
|
|
9
|
+
// Query types whose result set is rows rather than an OkPacket.
|
|
10
|
+
const READ_QUERY_TYPES = new Set(['DESCRIBE', 'EXPLAIN', 'SELECT', 'SHOW']);
|
|
7
11
|
export class MySQLUtil {
|
|
8
12
|
config;
|
|
9
13
|
pools;
|
|
@@ -16,14 +20,16 @@ export class MySQLUtil {
|
|
|
16
20
|
async closeAll() {
|
|
17
21
|
// Reject queued queries first so nothing waits forever on a closed util.
|
|
18
22
|
for (const slot of this.querySlots.values()) {
|
|
19
|
-
|
|
23
|
+
const { waiting } = slot;
|
|
24
|
+
slot.waiting = [];
|
|
25
|
+
for (const waiter of waiting) {
|
|
20
26
|
waiter.reject(new Error('Connections were closed while the query was waiting for a free slot'));
|
|
21
27
|
}
|
|
22
28
|
}
|
|
23
29
|
this.querySlots.clear();
|
|
24
30
|
const pools = [...this.pools.values()];
|
|
25
31
|
this.pools.clear();
|
|
26
|
-
await Promise.allSettled(pools.map((pool) => pool.end()));
|
|
32
|
+
await Promise.allSettled(pools.map(async (pool) => pool.end()));
|
|
27
33
|
}
|
|
28
34
|
async describeTable(profileName, table, format = 'table') {
|
|
29
35
|
try {
|
|
@@ -66,7 +72,7 @@ export class MySQLUtil {
|
|
|
66
72
|
}
|
|
67
73
|
// Machine-readable formats must emit only the data payload on stdout, so
|
|
68
74
|
// analysis warnings and status lines are collected as notices instead.
|
|
69
|
-
const
|
|
75
|
+
const isMachineFormat = MACHINE_FORMATS.has(format);
|
|
70
76
|
const notices = [];
|
|
71
77
|
const warnings = analyzeQuery(query);
|
|
72
78
|
if (warnings.length > 0) {
|
|
@@ -83,7 +89,7 @@ export class MySQLUtil {
|
|
|
83
89
|
}
|
|
84
90
|
try {
|
|
85
91
|
const [rows, fields] = await this.runQuery(profileName, finalQuery);
|
|
86
|
-
const isRead = queryType
|
|
92
|
+
const isRead = READ_QUERY_TYPES.has(queryType);
|
|
87
93
|
let data = isRead
|
|
88
94
|
? this.formatReadResult(rows, fields, format, notices)
|
|
89
95
|
: this.formatWriteResult(rows, notices, format);
|
|
@@ -95,8 +101,8 @@ export class MySQLUtil {
|
|
|
95
101
|
// For machine formats the data is returned alone and notices go to stderr.
|
|
96
102
|
return {
|
|
97
103
|
data: {
|
|
98
|
-
notices:
|
|
99
|
-
result:
|
|
104
|
+
notices: isMachineFormat ? notice : undefined,
|
|
105
|
+
result: isMachineFormat ? data : `${notice}\n\n${data}`,
|
|
100
106
|
},
|
|
101
107
|
success: true,
|
|
102
108
|
};
|
|
@@ -212,7 +218,7 @@ export class MySQLUtil {
|
|
|
212
218
|
}
|
|
213
219
|
// Grants a query slot for the profile, or waits until one frees up. The
|
|
214
220
|
// returned release callback must be invoked exactly once per acquisition.
|
|
215
|
-
acquireQuerySlot(profileName) {
|
|
221
|
+
async acquireQuerySlot(profileName) {
|
|
216
222
|
const limit = this.getQueryLimit(profileName);
|
|
217
223
|
let slot = this.querySlots.get(profileName);
|
|
218
224
|
if (!slot) {
|
|
@@ -231,7 +237,7 @@ export class MySQLUtil {
|
|
|
231
237
|
};
|
|
232
238
|
if (state.active < limit) {
|
|
233
239
|
state.active += 1;
|
|
234
|
-
return
|
|
240
|
+
return release;
|
|
235
241
|
}
|
|
236
242
|
const timeoutMs = this.config.profiles[profileName]?.queryQueueTimeoutMs ??
|
|
237
243
|
this.config.safety.queryQueueTimeoutMs ??
|
|
@@ -312,7 +318,7 @@ export class MySQLUtil {
|
|
|
312
318
|
async runQuery(profileName, sql) {
|
|
313
319
|
const release = await this.acquireQuerySlot(profileName);
|
|
314
320
|
try {
|
|
315
|
-
return
|
|
321
|
+
return await this.getPool(profileName).query(sql);
|
|
316
322
|
}
|
|
317
323
|
finally {
|
|
318
324
|
release();
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
type BlacklistCheckResult = {
|
|
2
2
|
allowed: boolean;
|
|
3
3
|
reason?: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
4
|
+
};
|
|
5
|
+
type ConfirmationCheckResult = {
|
|
6
6
|
message?: string;
|
|
7
7
|
required: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
8
|
+
};
|
|
9
|
+
type QueryWarning = {
|
|
10
10
|
level: 'info' | 'warning';
|
|
11
11
|
message: string;
|
|
12
12
|
suggestion: string;
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
export declare function checkBlacklist(query: string, blacklistedOperations: string[]): BlacklistCheckResult;
|
|
15
15
|
export declare function requiresConfirmation(query: string, confirmationOperations: string[]): ConfirmationCheckResult;
|
|
16
16
|
export declare function getQueryType(query: string): string;
|
|
@@ -26,7 +26,7 @@ export function requiresConfirmation(query, confirmationOperations) {
|
|
|
26
26
|
}
|
|
27
27
|
export function getQueryType(query) {
|
|
28
28
|
const normalizedQuery = query.trim().toUpperCase();
|
|
29
|
-
const firstWord = normalizedQuery.split(/\s
|
|
29
|
+
const firstWord = normalizedQuery.split(/\s+/, 1)[0];
|
|
30
30
|
const knownTypes = [
|
|
31
31
|
'SELECT',
|
|
32
32
|
'INSERT',
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hesed/mysql",
|
|
3
3
|
"description": "CLI for MySQL database interaction",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"author": "Hesed",
|
|
6
6
|
"bin": {
|
|
7
7
|
"mq": "./bin/run.js"
|
|
8
8
|
},
|
|
9
9
|
"bugs": "https://github.com/hesedcasa/mysql/issues",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@hesed/plugin-lib": "^0.
|
|
11
|
+
"@hesed/plugin-lib": "^0.12.1",
|
|
12
12
|
"@inquirer/prompts": "^8.3.0",
|
|
13
13
|
"@oclif/core": "^4",
|
|
14
14
|
"@toon-format/toon": "^2.1.0",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"@types/fs-extra": "^11.0.4",
|
|
24
24
|
"@types/mocha": "^10",
|
|
25
25
|
"@types/node": "^26",
|
|
26
|
-
"@types/sinon": "^
|
|
26
|
+
"@types/sinon": "^22.0.0",
|
|
27
27
|
"c8": "^11.0.0",
|
|
28
28
|
"chai": "^6",
|
|
29
|
-
"eslint": "^
|
|
30
|
-
"eslint-config-oclif": "^
|
|
29
|
+
"eslint": "^10",
|
|
30
|
+
"eslint-config-oclif": "^7",
|
|
31
31
|
"eslint-config-prettier": "^10",
|
|
32
32
|
"esmock": "^2.7.3",
|
|
33
33
|
"mocha": "^11",
|
|
@@ -37,10 +37,11 @@
|
|
|
37
37
|
"sinon": "^22.0.0",
|
|
38
38
|
"ts-node": "^10",
|
|
39
39
|
"ts-prune": "^0.10.3",
|
|
40
|
-
"typescript": "^5"
|
|
40
|
+
"typescript": "^5",
|
|
41
|
+
"typescript-eslint": "^8.67.0"
|
|
41
42
|
},
|
|
42
43
|
"engines": {
|
|
43
|
-
"node": ">=
|
|
44
|
+
"node": ">=22.13.0"
|
|
44
45
|
},
|
|
45
46
|
"files": [
|
|
46
47
|
"./bin",
|