@hesed/mysql 0.5.1 → 0.6.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/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.5.1 linux-x64 node-v24.17.0
29
+ @hesed/mysql/0.6.0 linux-x64 node-v24.18.0
30
30
  $ mq --help [COMMAND]
31
31
  USAGE
32
32
  $ mq COMMAND
@@ -45,7 +45,7 @@ USAGE
45
45
  * [`mq mysql auth update`](#mq-mysql-auth-update)
46
46
  * [`mq mysql databases`](#mq-mysql-databases)
47
47
  * [`mq mysql describe-table TABLE`](#mq-mysql-describe-table-table)
48
- * [`mq mysql explain-query QUERY`](#mq-mysql-explain-query-query)
48
+ * [`mq mysql explain QUERY`](#mq-mysql-explain-query)
49
49
  * [`mq mysql indexes TABLE`](#mq-mysql-indexes-table)
50
50
  * [`mq mysql query QUERY`](#mq-mysql-query-query)
51
51
  * [`mq mysql tables`](#mq-mysql-tables)
@@ -57,16 +57,18 @@ Add MySQL authentication
57
57
  ```
58
58
  USAGE
59
59
  $ mq mysql auth add -p <value> --host <value> --port <value> -u <value> --password <value> -d <value> --ssl
60
- [--json]
60
+ --maxConcurrentQueries <value> --queryQueueTimeoutMs <value> [--json]
61
61
 
62
62
  FLAGS
63
- -d, --database=<value> (required) Database name
64
- -p, --profile=<value> (required) Profile name
65
- -u, --user=<value> (required) Username
66
- --host=<value> (required) MySQL host
67
- --password=<value> (required) Password
68
- --port=<value> (required) MySQL port
69
- --ssl (required) Use SSL
63
+ -d, --database=<value> (required) Database name
64
+ -p, --profile=<value> (required) Profile name
65
+ -u, --user=<value> (required) Username
66
+ --host=<value> (required) MySQL host
67
+ --maxConcurrentQueries=<value> (required) Max concurrent queries for this profile
68
+ --password=<value> (required) Password
69
+ --port=<value> (required) MySQL port
70
+ --queryQueueTimeoutMs=<value> (required) Milliseconds a query may wait for a free query slot before failing
71
+ --ssl (required) Use SSL
70
72
 
71
73
  GLOBAL FLAGS
72
74
  --json Format output as json.
@@ -80,7 +82,7 @@ EXAMPLES
80
82
  $ mq mysql auth add -p prod
81
83
  ```
82
84
 
83
- _See code: [src/commands/mysql/auth/add.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/auth/add.ts)_
85
+ _See code: [src/commands/mysql/auth/add.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/auth/add.ts)_
84
86
 
85
87
  ## `mq mysql auth delete`
86
88
 
@@ -105,7 +107,7 @@ EXAMPLES
105
107
  $ mq mysql auth delete -p prod
106
108
  ```
107
109
 
108
- _See code: [src/commands/mysql/auth/delete.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/auth/delete.ts)_
110
+ _See code: [src/commands/mysql/auth/delete.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/auth/delete.ts)_
109
111
 
110
112
  ## `mq mysql auth list`
111
113
 
@@ -125,7 +127,7 @@ EXAMPLES
125
127
  $ mq mysql auth list
126
128
  ```
127
129
 
128
- _See code: [src/commands/mysql/auth/list.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/auth/list.ts)_
130
+ _See code: [src/commands/mysql/auth/list.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/auth/list.ts)_
129
131
 
130
132
  ## `mq mysql auth profile`
131
133
 
@@ -150,7 +152,7 @@ EXAMPLES
150
152
  $ mq mysql auth profile --default test
151
153
  ```
152
154
 
153
- _See code: [src/commands/mysql/auth/profile.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/auth/profile.ts)_
155
+ _See code: [src/commands/mysql/auth/profile.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/auth/profile.ts)_
154
156
 
155
157
  ## `mq mysql auth test`
156
158
 
@@ -175,7 +177,7 @@ EXAMPLES
175
177
  $ mq mysql auth test -p prod
176
178
  ```
177
179
 
178
- _See code: [src/commands/mysql/auth/test.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/auth/test.ts)_
180
+ _See code: [src/commands/mysql/auth/test.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/auth/test.ts)_
179
181
 
180
182
  ## `mq mysql auth update`
181
183
 
@@ -184,16 +186,18 @@ Update MySQL authentication
184
186
  ```
185
187
  USAGE
186
188
  $ mq mysql auth update -p <value> --host <value> --port <value> -u <value> --password <value> -d <value> --ssl
187
- [--json]
189
+ --maxConcurrentQueries <value> --queryQueueTimeoutMs <value> [--json]
188
190
 
189
191
  FLAGS
190
- -d, --database=<value> (required) Database name
191
- -p, --profile=<value> (required) Profile name
192
- -u, --user=<value> (required) Username
193
- --host=<value> (required) MySQL host
194
- --password=<value> (required) Password
195
- --port=<value> (required) MySQL port
196
- --ssl (required) Use SSL
192
+ -d, --database=<value> (required) Database name
193
+ -p, --profile=<value> (required) Profile name
194
+ -u, --user=<value> (required) Username
195
+ --host=<value> (required) MySQL host
196
+ --maxConcurrentQueries=<value> (required) Max concurrent queries for this profile
197
+ --password=<value> (required) Password
198
+ --port=<value> (required) MySQL port
199
+ --queryQueueTimeoutMs=<value> (required) Milliseconds a query may wait for a free query slot before failing
200
+ --ssl (required) Use SSL
197
201
 
198
202
  GLOBAL FLAGS
199
203
  --json Format output as json.
@@ -207,7 +211,7 @@ EXAMPLES
207
211
  $ mq mysql auth update -p test
208
212
  ```
209
213
 
210
- _See code: [src/commands/mysql/auth/update.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/auth/update.ts)_
214
+ _See code: [src/commands/mysql/auth/update.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/auth/update.ts)_
211
215
 
212
216
  ## `mq mysql databases`
213
217
 
@@ -232,7 +236,7 @@ EXAMPLES
232
236
  $ mq mysql databases -p staging
233
237
  ```
234
238
 
235
- _See code: [src/commands/mysql/databases.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/databases.ts)_
239
+ _See code: [src/commands/mysql/databases.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/databases.ts)_
236
240
 
237
241
  ## `mq mysql describe-table TABLE`
238
242
 
@@ -240,15 +244,14 @@ Describe the structure of a MySQL table
240
244
 
241
245
  ```
242
246
  USAGE
243
- $ mq mysql describe-table TABLE [--json] [--format table|json|toon] [-p <value>]
247
+ $ mq mysql describe-table TABLE [--json] [-p <value>] [--toon]
244
248
 
245
249
  ARGUMENTS
246
250
  TABLE Table name to describe
247
251
 
248
252
  FLAGS
249
253
  -p, --profile=<value> Database profile name from config
250
- --format=<option> [default: table] Output format
251
- <options: table|json|toon>
254
+ --toon Format output as toon
252
255
 
253
256
  GLOBAL FLAGS
254
257
  --json Format output as json.
@@ -259,26 +262,25 @@ DESCRIPTION
259
262
  EXAMPLES
260
263
  $ mq mysql describe-table users
261
264
 
262
- $ mq mysql describe-table orders --format json -p prod
265
+ $ mq mysql describe-table orders --toon -p prod
263
266
  ```
264
267
 
265
- _See code: [src/commands/mysql/describe-table.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/describe-table.ts)_
268
+ _See code: [src/commands/mysql/describe-table.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/describe-table.ts)_
266
269
 
267
- ## `mq mysql explain-query QUERY`
270
+ ## `mq mysql explain QUERY`
268
271
 
269
272
  Show the execution plan for a MySQL query
270
273
 
271
274
  ```
272
275
  USAGE
273
- $ mq mysql explain-query QUERY [--json] [--format table|json|toon] [-p <value>]
276
+ $ mq mysql explain QUERY [--json] [-p <value>] [--toon]
274
277
 
275
278
  ARGUMENTS
276
279
  QUERY SQL query to explain
277
280
 
278
281
  FLAGS
279
282
  -p, --profile=<value> Database profile name from config
280
- --format=<option> [default: table] Output format
281
- <options: table|json|toon>
283
+ --toon Format output as toon
282
284
 
283
285
  GLOBAL FLAGS
284
286
  --json Format output as json.
@@ -287,12 +289,12 @@ DESCRIPTION
287
289
  Show the execution plan for a MySQL query
288
290
 
289
291
  EXAMPLES
290
- $ mq mysql explain-query "SELECT * FROM users WHERE id = 1"
292
+ $ mq mysql explain "SELECT * FROM users WHERE id = 1"
291
293
 
292
- $ mq mysql explain-query "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --format json
294
+ $ mq mysql explain "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --json
293
295
  ```
294
296
 
295
- _See code: [src/commands/mysql/explain-query.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/explain-query.ts)_
297
+ _See code: [src/commands/mysql/explain.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/explain.ts)_
296
298
 
297
299
  ## `mq mysql indexes TABLE`
298
300
 
@@ -300,15 +302,14 @@ Show indexes for a MySQL table
300
302
 
301
303
  ```
302
304
  USAGE
303
- $ mq mysql indexes TABLE [--json] [--format table|json|toon] [-p <value>]
305
+ $ mq mysql indexes TABLE [--json] [-p <value>] [--toon]
304
306
 
305
307
  ARGUMENTS
306
308
  TABLE Table name to show indexes for
307
309
 
308
310
  FLAGS
309
311
  -p, --profile=<value> Database profile name from config
310
- --format=<option> [default: table] Output format
311
- <options: table|json|toon>
312
+ --toon Format output as toon
312
313
 
313
314
  GLOBAL FLAGS
314
315
  --json Format output as json.
@@ -319,10 +320,10 @@ DESCRIPTION
319
320
  EXAMPLES
320
321
  $ mq mysql indexes users
321
322
 
322
- $ mq mysql indexes orders --format json -p prod
323
+ $ mq mysql indexes orders --json -p prod
323
324
  ```
324
325
 
325
- _See code: [src/commands/mysql/indexes.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/indexes.ts)_
326
+ _See code: [src/commands/mysql/indexes.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/indexes.ts)_
326
327
 
327
328
  ## `mq mysql query QUERY`
328
329
 
@@ -330,16 +331,15 @@ Execute a SQL query against a MySQL database
330
331
 
331
332
  ```
332
333
  USAGE
333
- $ mq mysql query QUERY [--json] [--format table|json|csv|toon] [-p <value>] [--skip-confirmation]
334
+ $ mq mysql query QUERY [--json] [-p <value>] [--skip-confirmation] [--toon]
334
335
 
335
336
  ARGUMENTS
336
337
  QUERY SQL query to execute
337
338
 
338
339
  FLAGS
339
340
  -p, --profile=<value> Database profile name from config
340
- --format=<option> [default: table] Output format
341
- <options: table|json|csv|toon>
342
341
  --skip-confirmation Skip confirmation prompt for destructive operations
342
+ --toon Format output as toon
343
343
 
344
344
  GLOBAL FLAGS
345
345
  --json Format output as json.
@@ -348,14 +348,14 @@ DESCRIPTION
348
348
  Execute a SQL query against a MySQL database
349
349
 
350
350
  EXAMPLES
351
- $ mq mysql query "SELECT * FROM users LIMIT 10"
351
+ $ mq mysql query "SELECT * FROM users LIMIT 10" --json
352
352
 
353
- $ mq mysql query "UPDATE users SET email = 'user@email.com' WHERE id = 999" --format json
353
+ $ mq mysql query "UPDATE users SET email = 'user@email.com' WHERE id = 999"
354
354
 
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.5.1/src/commands/mysql/query.ts)_
358
+ _See code: [src/commands/mysql/query.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/query.ts)_
359
359
 
360
360
  ## `mq mysql tables`
361
361
 
@@ -363,11 +363,14 @@ List all tables in the current MySQL database
363
363
 
364
364
  ```
365
365
  USAGE
366
- $ mq mysql tables [-p <value>]
366
+ $ mq mysql tables [--json] [-p <value>]
367
367
 
368
368
  FLAGS
369
369
  -p, --profile=<value> Database profile name from config
370
370
 
371
+ GLOBAL FLAGS
372
+ --json Format output as json.
373
+
371
374
  DESCRIPTION
372
375
  List all tables in the current MySQL database
373
376
 
@@ -377,5 +380,5 @@ EXAMPLES
377
380
  $ mq mysql tables -p local
378
381
  ```
379
382
 
380
- _See code: [src/commands/mysql/tables.ts](https://github.com/hesedcasa/mysql/blob/v0.5.1/src/commands/mysql/tables.ts)_
383
+ _See code: [src/commands/mysql/tables.ts](https://github.com/hesedcasa/mysql/blob/v0.6.0/src/commands/mysql/tables.ts)_
381
384
  <!-- commandsstop -->
@@ -7,6 +7,4 @@ export declare abstract class BaseCommand extends Command {
7
7
  protected toErrorJson(err: unknown): {
8
8
  error: string;
9
9
  };
10
- private formatFlagValue;
11
- private hasFormatFlag;
12
10
  }
@@ -4,8 +4,6 @@ export class BaseCommand extends Command {
4
4
  jsonEnabled() {
5
5
  const separatorIndex = this.argv.indexOf('--');
6
6
  const flagArgs = separatorIndex === -1 ? this.argv : this.argv.slice(0, separatorIndex);
7
- if (this.hasFormatFlag(flagArgs))
8
- return this.formatFlagValue(flagArgs) === 'json';
9
7
  return flagArgs.includes('--json');
10
8
  }
11
9
  // oclif sets this.parsed=true only after Parser.parse() returns successfully.
@@ -36,15 +34,4 @@ export class BaseCommand extends Command {
36
34
  const message = err instanceof Error ? err.message : String(err);
37
35
  return { error: message };
38
36
  }
39
- formatFlagValue(flagArgs) {
40
- for (const [index, arg] of flagArgs.entries()) {
41
- if (arg === '--format')
42
- return flagArgs[index + 1];
43
- if (arg.startsWith('--format='))
44
- return arg.slice('--format='.length);
45
- }
46
- }
47
- hasFormatFlag(flagArgs) {
48
- return flagArgs.some((arg) => arg === '--format' || arg.startsWith('--format='));
49
- }
50
37
  }
@@ -7,6 +7,20 @@ const fields = [
7
7
  { description: 'Password', name: 'password', type: 'string' },
8
8
  { char: 'd', description: 'Database name', name: 'database', type: 'string' },
9
9
  { default: false, description: 'Use SSL', name: 'ssl', required: false, type: 'boolean' },
10
+ {
11
+ default: 5,
12
+ description: 'Max concurrent queries for this profile',
13
+ name: 'maxConcurrentQueries',
14
+ required: false,
15
+ type: 'number',
16
+ },
17
+ {
18
+ default: 60_000,
19
+ description: 'Milliseconds a query may wait for a free query slot before failing',
20
+ name: 'queryQueueTimeoutMs',
21
+ required: false,
22
+ type: 'number',
23
+ },
10
24
  ];
11
25
  export default createAuthAddCommand({
12
26
  clearClients: closeConnections,
@@ -7,6 +7,20 @@ const fields = [
7
7
  { description: 'Password', name: 'password', type: 'string' },
8
8
  { char: 'd', description: 'Database name', name: 'database', type: 'string' },
9
9
  { default: false, description: 'Use SSL', name: 'ssl', required: false, type: 'boolean' },
10
+ {
11
+ default: 5,
12
+ description: 'Max concurrent queries for this profile',
13
+ name: 'maxConcurrentQueries',
14
+ required: false,
15
+ type: 'number',
16
+ },
17
+ {
18
+ default: 60_000,
19
+ description: 'Milliseconds a query may wait for a free query slot before failing',
20
+ name: 'queryQueueTimeoutMs',
21
+ required: false,
22
+ type: 'number',
23
+ },
10
24
  ];
11
25
  export default createAuthUpdateCommand({
12
26
  clearClients: closeConnections,
@@ -1,11 +1,10 @@
1
- import { Command } from '@oclif/core';
2
- export default class MySQLDatabases extends Command {
1
+ import type { ApiResult } from '@hesed/plugin-lib';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ export default class MySQLDatabases extends BaseCommand {
3
4
  static description: string;
4
- static enableJsonFlag: boolean;
5
5
  static examples: string[];
6
6
  static flags: {
7
7
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
8
  };
9
- jsonEnabled(): boolean;
10
- run(): Promise<string[]>;
9
+ run(): Promise<ApiResult>;
11
10
  }
@@ -1,22 +1,21 @@
1
- import { Command, Flags } from '@oclif/core';
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
2
3
  import { closeConnections, listDatabases } from '../../mysql/index.js';
3
- export default class MySQLDatabases extends Command {
4
+ export default class MySQLDatabases extends BaseCommand {
4
5
  static description = 'List all databases accessible on the MySQL server';
5
- static enableJsonFlag = true;
6
6
  static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> -p staging'];
7
7
  static flags = {
8
8
  profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
9
9
  };
10
- jsonEnabled() {
11
- return true;
12
- }
13
10
  async run() {
14
11
  const { flags } = await this.parse(MySQLDatabases);
15
12
  const result = await listDatabases(this.config, flags.profile);
16
13
  await closeConnections();
17
14
  if (result.success) {
18
- return result.databases ?? [];
15
+ this.log(result.data?.result ?? '');
16
+ delete result.data.result;
17
+ return result;
19
18
  }
20
- this.error(result.error ?? 'Failed to list databases');
19
+ this.error(String(result.error ?? 'Failed to list databases'));
21
20
  }
22
21
  }
@@ -1,3 +1,4 @@
1
+ import { ApiResult } from '@hesed/plugin-lib';
1
2
  import { BaseCommand } from '../../base-command.js';
2
3
  export default class MySQLDescribeTable extends BaseCommand {
3
4
  static args: {
@@ -6,8 +7,8 @@ export default class MySQLDescribeTable extends BaseCommand {
6
7
  static description: string;
7
8
  static examples: string[];
8
9
  static flags: {
9
- format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  };
12
- run(): Promise<unknown>;
13
+ run(): Promise<ApiResult>;
13
14
  }
@@ -8,24 +8,21 @@ export default class MySQLDescribeTable extends BaseCommand {
8
8
  static description = 'Describe the structure of a MySQL table';
9
9
  static examples = [
10
10
  '<%= config.bin %> <%= command.id %> users',
11
- '<%= config.bin %> <%= command.id %> orders --format json -p prod',
11
+ '<%= config.bin %> <%= command.id %> orders --toon -p prod',
12
12
  ];
13
13
  static flags = {
14
- format: Flags.string({
15
- default: 'table',
16
- description: 'Output format',
17
- options: ['table', 'json', 'toon'],
18
- }),
19
14
  profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
15
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
20
16
  };
21
17
  async run() {
22
18
  const { args, flags } = await this.parse(MySQLDescribeTable);
23
- const result = await describeTable(this.config, args.table, flags.profile, flags.format);
19
+ const result = await describeTable(this.config, args.table, flags.profile, flags.toon ? 'toon' : flags.json ? 'json' : 'table');
24
20
  await closeConnections();
25
21
  if (result.success) {
26
- this.log(result.result ?? '');
22
+ this.log(result.data?.result ?? '');
23
+ delete result.data.result;
27
24
  return result;
28
25
  }
29
- this.error(result.error ?? 'Failed to describe table');
26
+ this.error(String(result.error ?? 'Failed to describe table'));
30
27
  }
31
28
  }
@@ -1,3 +1,4 @@
1
+ import { ApiResult } from '@hesed/plugin-lib';
1
2
  import { BaseCommand } from '../../base-command.js';
2
3
  export default class MySQLExplain extends BaseCommand {
3
4
  static args: {
@@ -6,8 +7,8 @@ export default class MySQLExplain extends BaseCommand {
6
7
  static description: string;
7
8
  static examples: string[];
8
9
  static flags: {
9
- format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  };
12
- run(): Promise<unknown>;
13
+ run(): Promise<ApiResult>;
13
14
  }
@@ -8,24 +8,21 @@ export default class MySQLExplain extends BaseCommand {
8
8
  static description = 'Show the execution plan for a MySQL query';
9
9
  static examples = [
10
10
  '<%= config.bin %> <%= command.id %> "SELECT * FROM users WHERE id = 1"',
11
- '<%= config.bin %> <%= command.id %> "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --format json',
11
+ '<%= config.bin %> <%= command.id %> "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --json',
12
12
  ];
13
13
  static flags = {
14
- format: Flags.string({
15
- default: 'table',
16
- description: 'Output format',
17
- options: ['table', 'json', 'toon'],
18
- }),
19
14
  profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
15
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
20
16
  };
21
17
  async run() {
22
18
  const { args, flags } = await this.parse(MySQLExplain);
23
- const result = await explainQuery(this.config, args.query, flags.profile, flags.format);
19
+ const result = await explainQuery(this.config, args.query, flags.profile, flags.toon ? 'toon' : flags.json ? 'json' : 'table');
24
20
  await closeConnections();
25
21
  if (result.success) {
26
- this.log(result.result ?? '');
22
+ this.log(result.data?.result ?? '');
23
+ delete result.data.result;
27
24
  return result;
28
25
  }
29
- this.error(result.error ?? 'Failed to explain query');
26
+ this.error(String(result.error ?? 'Failed to explain query'));
30
27
  }
31
28
  }
@@ -1,3 +1,4 @@
1
+ import { ApiResult } from '@hesed/plugin-lib';
1
2
  import { BaseCommand } from '../../base-command.js';
2
3
  export default class MySQLIndexes extends BaseCommand {
3
4
  static args: {
@@ -6,8 +7,8 @@ export default class MySQLIndexes extends BaseCommand {
6
7
  static description: string;
7
8
  static examples: string[];
8
9
  static flags: {
9
- format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  };
12
- run(): Promise<unknown>;
13
+ run(): Promise<ApiResult>;
13
14
  }
@@ -8,24 +8,21 @@ export default class MySQLIndexes extends BaseCommand {
8
8
  static description = 'Show indexes for a MySQL table';
9
9
  static examples = [
10
10
  '<%= config.bin %> <%= command.id %> users',
11
- '<%= config.bin %> <%= command.id %> orders --format json -p prod',
11
+ '<%= config.bin %> <%= command.id %> orders --json -p prod',
12
12
  ];
13
13
  static flags = {
14
- format: Flags.string({
15
- default: 'table',
16
- description: 'Output format',
17
- options: ['table', 'json', 'toon'],
18
- }),
19
14
  profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
15
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
20
16
  };
21
17
  async run() {
22
18
  const { args, flags } = await this.parse(MySQLIndexes);
23
- const result = await showIndexes(this.config, args.table, flags.profile, flags.format);
19
+ const result = await showIndexes(this.config, args.table, flags.profile, flags.toon ? 'toon' : flags.json ? 'json' : 'table');
24
20
  await closeConnections();
25
21
  if (result.success) {
26
- this.log(result.result ?? '');
22
+ this.log(result.data?.result ?? '');
23
+ delete result.data.result;
27
24
  return result;
28
25
  }
29
- this.error(result.error ?? 'Failed to show indexes');
26
+ this.error(String(result.error ?? 'Failed to show indexes'));
30
27
  }
31
28
  }
@@ -1,3 +1,4 @@
1
+ import { ApiResult } from '@hesed/plugin-lib';
1
2
  import { BaseCommand } from '../../base-command.js';
2
3
  export default class MySQLQuery extends BaseCommand {
3
4
  static args: {
@@ -6,9 +7,9 @@ export default class MySQLQuery extends BaseCommand {
6
7
  static description: string;
7
8
  static examples: string[];
8
9
  static flags: {
9
- format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
11
  'skip-confirmation': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ toon: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
13
  };
13
- run(): Promise<unknown>;
14
+ run(): Promise<ApiResult>;
14
15
  }
@@ -7,40 +7,37 @@ export default class MySQLQuery extends BaseCommand {
7
7
  };
8
8
  static description = 'Execute a SQL query against a MySQL database';
9
9
  static examples = [
10
- '<%= config.bin %> <%= command.id %> "SELECT * FROM users LIMIT 10"',
11
- '<%= config.bin %> <%= command.id %> "UPDATE users SET email = \'user@email.com\' WHERE id = 999" --format json',
10
+ '<%= config.bin %> <%= command.id %> "SELECT * FROM users LIMIT 10" --json',
11
+ '<%= config.bin %> <%= command.id %> "UPDATE users SET email = \'user@email.com\' WHERE id = 999"',
12
12
  '<%= config.bin %> <%= command.id %> "DELETE FROM sessions" -p prod --skip-confirmation',
13
13
  ];
14
14
  static flags = {
15
- format: Flags.string({
16
- default: 'table',
17
- description: 'Output format',
18
- options: ['table', 'json', 'csv', 'toon'],
19
- }),
20
15
  profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
21
16
  'skip-confirmation': Flags.boolean({
22
17
  default: false,
23
18
  description: 'Skip confirmation prompt for destructive operations',
24
19
  }),
20
+ toon: Flags.boolean({ description: 'Format output as toon', required: false }),
25
21
  };
26
22
  async run() {
27
23
  const { args, flags } = await this.parse(MySQLQuery);
28
- const result = await executeQuery(this.config, args.query, flags.profile, flags.format, flags['skip-confirmation']);
24
+ const result = await executeQuery(this.config, args.query, flags.profile, flags.toon ? 'toon' : flags.json ? 'json' : 'table', flags['skip-confirmation']);
29
25
  await closeConnections();
30
26
  if (result.success) {
31
27
  // Notices (warnings, row counts) go to stderr so machine-readable formats
32
28
  // leave stdout as clean, parseable data.
33
- if (result.notices)
34
- this.logToStderr(result.notices);
35
- if (this.jsonEnabled())
36
- return this.parseJsonOutput(result.result);
37
- this.log(result.result ?? '');
29
+ if (result.data?.notices)
30
+ this.logToStderr(result.data.notices);
31
+ // result is a formatted string for human/csv/toon output; for --json it
32
+ // holds the parsed payload, but jsonEnabled() suppresses log() in that case.
33
+ this.log(typeof result.data?.result === 'string' ? result.data.result : '');
34
+ delete result.data.notices;
38
35
  return result;
39
36
  }
40
- if (result.requiresConfirmation) {
41
- this.log(`${result.message ?? 'Destructive operation requires confirmation.'}\nRe-run with --skip-confirmation to proceed.`);
37
+ if (result.data?.requiresConfirmation) {
38
+ this.log(`${result.data?.message ?? 'Destructive operation requires confirmation.'}\nRe-run with --skip-confirmation to proceed.`);
42
39
  return result;
43
40
  }
44
- this.error(result.error ?? 'Query failed');
41
+ this.error(String(result.error ?? 'Query failed'));
45
42
  }
46
43
  }
@@ -1,10 +1,10 @@
1
- import { Command } from '@oclif/core';
2
- export default class MySQLTables extends Command {
1
+ import type { ApiResult } from '@hesed/plugin-lib';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ export default class MySQLTables extends BaseCommand {
3
4
  static description: string;
4
5
  static examples: string[];
5
6
  static flags: {
6
7
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  };
8
- jsonEnabled(): boolean;
9
- run(): Promise<string[]>;
9
+ run(): Promise<ApiResult>;
10
10
  }