shyim-hosting-test-cli 0.0.2 → 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/dist/index.js +217 -4
- package/package.json +2 -2
- package/src/commands/db.ts +129 -0
- package/src/commands/kv.ts +118 -0
- package/src/index.ts +4 -1
- package/tsup.config.ts +11 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
|
|
4
3
|
// src/index.ts
|
|
5
|
-
import { defineCommand as
|
|
4
|
+
import { defineCommand as defineCommand9, runMain } from "citty";
|
|
6
5
|
|
|
7
6
|
// src/commands/login.ts
|
|
8
7
|
import { defineCommand } from "citty";
|
|
@@ -380,8 +379,220 @@ var projectsCommand = defineCommand6({
|
|
|
380
379
|
}
|
|
381
380
|
});
|
|
382
381
|
|
|
382
|
+
// src/commands/kv.ts
|
|
383
|
+
import { defineCommand as defineCommand7 } from "citty";
|
|
384
|
+
import consola7 from "consola";
|
|
385
|
+
async function getProjectId() {
|
|
386
|
+
const projectConfig = await loadProjectConfig(process.cwd());
|
|
387
|
+
if (!projectConfig) {
|
|
388
|
+
consola7.error("No app-hosting.json found. Run `app-hosting init` first.");
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
return projectConfig.project_id;
|
|
392
|
+
}
|
|
393
|
+
var kvCommand = defineCommand7({
|
|
394
|
+
meta: {
|
|
395
|
+
name: "kv",
|
|
396
|
+
description: "Manage KV store"
|
|
397
|
+
},
|
|
398
|
+
subCommands: {
|
|
399
|
+
list: defineCommand7({
|
|
400
|
+
meta: {
|
|
401
|
+
name: "list",
|
|
402
|
+
description: "List KV keys"
|
|
403
|
+
},
|
|
404
|
+
args: {
|
|
405
|
+
prefix: {
|
|
406
|
+
type: "string",
|
|
407
|
+
description: "Filter by key prefix",
|
|
408
|
+
required: false
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
async run({ args }) {
|
|
412
|
+
const client = await createClient();
|
|
413
|
+
const projectId = await getProjectId();
|
|
414
|
+
const result = await client.kv.listKeys.query({
|
|
415
|
+
projectId,
|
|
416
|
+
prefix: args.prefix,
|
|
417
|
+
limit: 100
|
|
418
|
+
});
|
|
419
|
+
if (result.keys.length === 0) {
|
|
420
|
+
consola7.info("No keys found.");
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
for (const key of result.keys) {
|
|
424
|
+
const exp = key.expiration ? ` (expires ${new Date(key.expiration * 1e3).toLocaleString()})` : "";
|
|
425
|
+
consola7.log(` ${key.name}${exp}`);
|
|
426
|
+
}
|
|
427
|
+
if (result.cursor) {
|
|
428
|
+
consola7.info(`
|
|
429
|
+
... more keys available. Use --prefix to narrow results.`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}),
|
|
433
|
+
get: defineCommand7({
|
|
434
|
+
meta: {
|
|
435
|
+
name: "get",
|
|
436
|
+
description: "Get a KV value"
|
|
437
|
+
},
|
|
438
|
+
args: {
|
|
439
|
+
key: {
|
|
440
|
+
type: "positional",
|
|
441
|
+
description: "Key to read",
|
|
442
|
+
required: true
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
async run({ args }) {
|
|
446
|
+
const client = await createClient();
|
|
447
|
+
const projectId = await getProjectId();
|
|
448
|
+
const result = await client.kv.getValue.query({
|
|
449
|
+
projectId,
|
|
450
|
+
key: args.key
|
|
451
|
+
});
|
|
452
|
+
try {
|
|
453
|
+
const parsed = JSON.parse(result.value);
|
|
454
|
+
consola7.log(JSON.stringify(parsed, null, 2));
|
|
455
|
+
} catch {
|
|
456
|
+
consola7.log(result.value);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}),
|
|
460
|
+
delete: defineCommand7({
|
|
461
|
+
meta: {
|
|
462
|
+
name: "delete",
|
|
463
|
+
description: "Delete a KV key"
|
|
464
|
+
},
|
|
465
|
+
args: {
|
|
466
|
+
key: {
|
|
467
|
+
type: "positional",
|
|
468
|
+
description: "Key to delete",
|
|
469
|
+
required: true
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
async run({ args }) {
|
|
473
|
+
const client = await createClient();
|
|
474
|
+
const projectId = await getProjectId();
|
|
475
|
+
const key = args.key;
|
|
476
|
+
await client.kv.deleteKey.mutate({
|
|
477
|
+
projectId,
|
|
478
|
+
key
|
|
479
|
+
});
|
|
480
|
+
consola7.success(`Deleted key: ${key}`);
|
|
481
|
+
}
|
|
482
|
+
})
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// src/commands/db.ts
|
|
487
|
+
import { defineCommand as defineCommand8 } from "citty";
|
|
488
|
+
import consola8 from "consola";
|
|
489
|
+
async function getProjectId2() {
|
|
490
|
+
const projectConfig = await loadProjectConfig(process.cwd());
|
|
491
|
+
if (!projectConfig) {
|
|
492
|
+
consola8.error("No app-hosting.json found. Run `app-hosting init` first.");
|
|
493
|
+
process.exit(1);
|
|
494
|
+
}
|
|
495
|
+
return projectConfig.project_id;
|
|
496
|
+
}
|
|
497
|
+
var dbCommand = defineCommand8({
|
|
498
|
+
meta: {
|
|
499
|
+
name: "db",
|
|
500
|
+
description: "Manage D1 database"
|
|
501
|
+
},
|
|
502
|
+
subCommands: {
|
|
503
|
+
tables: defineCommand8({
|
|
504
|
+
meta: {
|
|
505
|
+
name: "tables",
|
|
506
|
+
description: "List database tables"
|
|
507
|
+
},
|
|
508
|
+
async run() {
|
|
509
|
+
const client = await createClient();
|
|
510
|
+
const projectId = await getProjectId2();
|
|
511
|
+
const tables = await client.d1.listTables.query({ projectId });
|
|
512
|
+
if (tables.length === 0) {
|
|
513
|
+
consola8.info("No tables found.");
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
for (const table of tables) {
|
|
517
|
+
consola8.log(` ${table}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}),
|
|
521
|
+
query: defineCommand8({
|
|
522
|
+
meta: {
|
|
523
|
+
name: "query",
|
|
524
|
+
description: "Run a read-only SQL query"
|
|
525
|
+
},
|
|
526
|
+
args: {
|
|
527
|
+
sql: {
|
|
528
|
+
type: "positional",
|
|
529
|
+
description: "SQL query to execute",
|
|
530
|
+
required: true
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
async run({ args }) {
|
|
534
|
+
const client = await createClient();
|
|
535
|
+
const projectId = await getProjectId2();
|
|
536
|
+
const result = await client.d1.execute.mutate({
|
|
537
|
+
projectId,
|
|
538
|
+
sql: args.sql
|
|
539
|
+
});
|
|
540
|
+
if (result.rows.length === 0) {
|
|
541
|
+
consola8.info("No rows returned.");
|
|
542
|
+
consola8.log(` ${result.meta.rows_read} read, ${result.meta.rows_written} written, ${result.meta.changes} changes`);
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const columns = Object.keys(result.rows[0]);
|
|
546
|
+
const colWidths = columns.map((col) => {
|
|
547
|
+
const values = result.rows.map((row) => formatValue(row[col]));
|
|
548
|
+
return Math.max(col.length, ...values.map((v) => v.length));
|
|
549
|
+
});
|
|
550
|
+
const header = columns.map((col, i) => col.padEnd(colWidths[i])).join(" ");
|
|
551
|
+
consola8.log(` ${header}`);
|
|
552
|
+
consola8.log(` ${colWidths.map((w) => "-".repeat(w)).join(" ")}`);
|
|
553
|
+
for (const row of result.rows) {
|
|
554
|
+
const line = columns.map((col, i) => formatValue(row[col]).padEnd(colWidths[i])).join(" ");
|
|
555
|
+
consola8.log(` ${line}`);
|
|
556
|
+
}
|
|
557
|
+
consola8.log(`
|
|
558
|
+
${result.rows.length} rows, ${result.meta.rows_read} read, ${result.meta.rows_written} written`);
|
|
559
|
+
}
|
|
560
|
+
}),
|
|
561
|
+
execute: defineCommand8({
|
|
562
|
+
meta: {
|
|
563
|
+
name: "execute",
|
|
564
|
+
description: "Execute a SQL statement (INSERT, UPDATE, DELETE, CREATE, etc.)"
|
|
565
|
+
},
|
|
566
|
+
args: {
|
|
567
|
+
sql: {
|
|
568
|
+
type: "positional",
|
|
569
|
+
description: "SQL statement to execute",
|
|
570
|
+
required: true
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
async run({ args }) {
|
|
574
|
+
const client = await createClient();
|
|
575
|
+
const projectId = await getProjectId2();
|
|
576
|
+
const result = await client.d1.execute.mutate({
|
|
577
|
+
projectId,
|
|
578
|
+
sql: args.sql
|
|
579
|
+
});
|
|
580
|
+
consola8.success(`${result.meta.changes} changes, ${result.meta.rows_read} read, ${result.meta.rows_written} written`);
|
|
581
|
+
if (result.rows.length > 0) {
|
|
582
|
+
consola8.log(JSON.stringify(result.rows, null, 2));
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
})
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
function formatValue(val) {
|
|
589
|
+
if (val === null || val === void 0) return "NULL";
|
|
590
|
+
if (typeof val === "object") return JSON.stringify(val);
|
|
591
|
+
return String(val);
|
|
592
|
+
}
|
|
593
|
+
|
|
383
594
|
// src/index.ts
|
|
384
|
-
var main =
|
|
595
|
+
var main = defineCommand9({
|
|
385
596
|
meta: {
|
|
386
597
|
name: "app-hosting",
|
|
387
598
|
version: "0.0.1",
|
|
@@ -393,7 +604,9 @@ var main = defineCommand7({
|
|
|
393
604
|
init: initCommand,
|
|
394
605
|
deploy: deployCommand,
|
|
395
606
|
dev: devCommand,
|
|
396
|
-
projects: projectsCommand
|
|
607
|
+
projects: projectsCommand,
|
|
608
|
+
kv: kvCommand,
|
|
609
|
+
db: dbCommand
|
|
397
610
|
}
|
|
398
611
|
});
|
|
399
612
|
runMain(main);
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shyim-hosting-test-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"app-hosting": "./dist/index.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"build": "tsup
|
|
9
|
+
"build": "tsup",
|
|
10
10
|
"dev": "tsx src/index.ts"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import consola from "consola";
|
|
3
|
+
import { createClient } from "../trpc";
|
|
4
|
+
import { loadProjectConfig } from "../project";
|
|
5
|
+
|
|
6
|
+
async function getProjectId() {
|
|
7
|
+
const projectConfig = await loadProjectConfig(process.cwd());
|
|
8
|
+
if (!projectConfig) {
|
|
9
|
+
consola.error("No app-hosting.json found. Run `app-hosting init` first.");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
return projectConfig.project_id;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const dbCommand = defineCommand({
|
|
16
|
+
meta: {
|
|
17
|
+
name: "db",
|
|
18
|
+
description: "Manage D1 database",
|
|
19
|
+
},
|
|
20
|
+
subCommands: {
|
|
21
|
+
tables: defineCommand({
|
|
22
|
+
meta: {
|
|
23
|
+
name: "tables",
|
|
24
|
+
description: "List database tables",
|
|
25
|
+
},
|
|
26
|
+
async run() {
|
|
27
|
+
const client = await createClient();
|
|
28
|
+
const projectId = await getProjectId();
|
|
29
|
+
|
|
30
|
+
const tables = await client.d1.listTables.query({ projectId });
|
|
31
|
+
|
|
32
|
+
if (tables.length === 0) {
|
|
33
|
+
consola.info("No tables found.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const table of tables) {
|
|
38
|
+
consola.log(` ${table}`);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
query: defineCommand({
|
|
44
|
+
meta: {
|
|
45
|
+
name: "query",
|
|
46
|
+
description: "Run a read-only SQL query",
|
|
47
|
+
},
|
|
48
|
+
args: {
|
|
49
|
+
sql: {
|
|
50
|
+
type: "positional",
|
|
51
|
+
description: "SQL query to execute",
|
|
52
|
+
required: true,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
async run({ args }) {
|
|
56
|
+
const client = await createClient();
|
|
57
|
+
const projectId = await getProjectId();
|
|
58
|
+
|
|
59
|
+
const result = await client.d1.execute.mutate({
|
|
60
|
+
projectId,
|
|
61
|
+
sql: args.sql as string,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (result.rows.length === 0) {
|
|
65
|
+
consola.info("No rows returned.");
|
|
66
|
+
consola.log(` ${result.meta.rows_read} read, ${result.meta.rows_written} written, ${result.meta.changes} changes`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Print as table
|
|
71
|
+
const columns = Object.keys(result.rows[0]!);
|
|
72
|
+
const colWidths = columns.map((col) => {
|
|
73
|
+
const values = result.rows.map((row) => formatValue(row[col]));
|
|
74
|
+
return Math.max(col.length, ...values.map((v) => v.length));
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Header
|
|
78
|
+
const header = columns.map((col, i) => col.padEnd(colWidths[i]!)).join(" ");
|
|
79
|
+
consola.log(` ${header}`);
|
|
80
|
+
consola.log(` ${colWidths.map((w) => "-".repeat(w)).join(" ")}`);
|
|
81
|
+
|
|
82
|
+
// Rows
|
|
83
|
+
for (const row of result.rows) {
|
|
84
|
+
const line = columns
|
|
85
|
+
.map((col, i) => formatValue(row[col]).padEnd(colWidths[i]!))
|
|
86
|
+
.join(" ");
|
|
87
|
+
consola.log(` ${line}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
consola.log(`\n ${result.rows.length} rows, ${result.meta.rows_read} read, ${result.meta.rows_written} written`);
|
|
91
|
+
},
|
|
92
|
+
}),
|
|
93
|
+
|
|
94
|
+
execute: defineCommand({
|
|
95
|
+
meta: {
|
|
96
|
+
name: "execute",
|
|
97
|
+
description: "Execute a SQL statement (INSERT, UPDATE, DELETE, CREATE, etc.)",
|
|
98
|
+
},
|
|
99
|
+
args: {
|
|
100
|
+
sql: {
|
|
101
|
+
type: "positional",
|
|
102
|
+
description: "SQL statement to execute",
|
|
103
|
+
required: true,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
async run({ args }) {
|
|
107
|
+
const client = await createClient();
|
|
108
|
+
const projectId = await getProjectId();
|
|
109
|
+
|
|
110
|
+
const result = await client.d1.execute.mutate({
|
|
111
|
+
projectId,
|
|
112
|
+
sql: args.sql as string,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
consola.success(`${result.meta.changes} changes, ${result.meta.rows_read} read, ${result.meta.rows_written} written`);
|
|
116
|
+
|
|
117
|
+
if (result.rows.length > 0) {
|
|
118
|
+
consola.log(JSON.stringify(result.rows, null, 2));
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
function formatValue(val: unknown): string {
|
|
126
|
+
if (val === null || val === undefined) return "NULL";
|
|
127
|
+
if (typeof val === "object") return JSON.stringify(val);
|
|
128
|
+
return String(val);
|
|
129
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import consola from "consola";
|
|
3
|
+
import { createClient } from "../trpc";
|
|
4
|
+
import { loadProjectConfig } from "../project";
|
|
5
|
+
|
|
6
|
+
async function getProjectId() {
|
|
7
|
+
const projectConfig = await loadProjectConfig(process.cwd());
|
|
8
|
+
if (!projectConfig) {
|
|
9
|
+
consola.error("No app-hosting.json found. Run `app-hosting init` first.");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
return projectConfig.project_id;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const kvCommand = defineCommand({
|
|
16
|
+
meta: {
|
|
17
|
+
name: "kv",
|
|
18
|
+
description: "Manage KV store",
|
|
19
|
+
},
|
|
20
|
+
subCommands: {
|
|
21
|
+
list: defineCommand({
|
|
22
|
+
meta: {
|
|
23
|
+
name: "list",
|
|
24
|
+
description: "List KV keys",
|
|
25
|
+
},
|
|
26
|
+
args: {
|
|
27
|
+
prefix: {
|
|
28
|
+
type: "string",
|
|
29
|
+
description: "Filter by key prefix",
|
|
30
|
+
required: false,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
async run({ args }) {
|
|
34
|
+
const client = await createClient();
|
|
35
|
+
const projectId = await getProjectId();
|
|
36
|
+
|
|
37
|
+
const result = await client.kv.listKeys.query({
|
|
38
|
+
projectId,
|
|
39
|
+
prefix: args.prefix as string | undefined,
|
|
40
|
+
limit: 100,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (result.keys.length === 0) {
|
|
44
|
+
consola.info("No keys found.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const key of result.keys) {
|
|
49
|
+
const exp = key.expiration
|
|
50
|
+
? ` (expires ${new Date(key.expiration * 1000).toLocaleString()})`
|
|
51
|
+
: "";
|
|
52
|
+
consola.log(` ${key.name}${exp}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (result.cursor) {
|
|
56
|
+
consola.info(`\n ... more keys available. Use --prefix to narrow results.`);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
|
|
61
|
+
get: defineCommand({
|
|
62
|
+
meta: {
|
|
63
|
+
name: "get",
|
|
64
|
+
description: "Get a KV value",
|
|
65
|
+
},
|
|
66
|
+
args: {
|
|
67
|
+
key: {
|
|
68
|
+
type: "positional",
|
|
69
|
+
description: "Key to read",
|
|
70
|
+
required: true,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
async run({ args }) {
|
|
74
|
+
const client = await createClient();
|
|
75
|
+
const projectId = await getProjectId();
|
|
76
|
+
|
|
77
|
+
const result = await client.kv.getValue.query({
|
|
78
|
+
projectId,
|
|
79
|
+
key: args.key as string,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Try to pretty-print JSON
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(result.value);
|
|
85
|
+
consola.log(JSON.stringify(parsed, null, 2));
|
|
86
|
+
} catch {
|
|
87
|
+
consola.log(result.value);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
}),
|
|
91
|
+
|
|
92
|
+
delete: defineCommand({
|
|
93
|
+
meta: {
|
|
94
|
+
name: "delete",
|
|
95
|
+
description: "Delete a KV key",
|
|
96
|
+
},
|
|
97
|
+
args: {
|
|
98
|
+
key: {
|
|
99
|
+
type: "positional",
|
|
100
|
+
description: "Key to delete",
|
|
101
|
+
required: true,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
async run({ args }) {
|
|
105
|
+
const client = await createClient();
|
|
106
|
+
const projectId = await getProjectId();
|
|
107
|
+
|
|
108
|
+
const key = args.key as string;
|
|
109
|
+
await client.kv.deleteKey.mutate({
|
|
110
|
+
projectId,
|
|
111
|
+
key,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
consola.success(`Deleted key: ${key}`);
|
|
115
|
+
},
|
|
116
|
+
}),
|
|
117
|
+
},
|
|
118
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import { defineCommand, runMain } from "citty";
|
|
3
2
|
import { loginCommand } from "./commands/login";
|
|
4
3
|
import { logoutCommand } from "./commands/logout";
|
|
@@ -6,6 +5,8 @@ import { initCommand } from "./commands/init";
|
|
|
6
5
|
import { deployCommand } from "./commands/deploy";
|
|
7
6
|
import { devCommand } from "./commands/dev";
|
|
8
7
|
import { projectsCommand } from "./commands/projects";
|
|
8
|
+
import { kvCommand } from "./commands/kv";
|
|
9
|
+
import { dbCommand } from "./commands/db";
|
|
9
10
|
|
|
10
11
|
const main = defineCommand({
|
|
11
12
|
meta: {
|
|
@@ -20,6 +21,8 @@ const main = defineCommand({
|
|
|
20
21
|
deploy: deployCommand,
|
|
21
22
|
dev: devCommand,
|
|
22
23
|
projects: projectsCommand,
|
|
24
|
+
kv: kvCommand,
|
|
25
|
+
db: dbCommand,
|
|
23
26
|
},
|
|
24
27
|
});
|
|
25
28
|
|