shyim-hosting-test-cli 0.0.3 → 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 -3
- package/package.json +1 -1
- package/src/commands/db.ts +129 -0
- package/src/commands/kv.ts +118 -0
- package/src/index.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { defineCommand as
|
|
4
|
+
import { defineCommand as defineCommand9, runMain } from "citty";
|
|
5
5
|
|
|
6
6
|
// src/commands/login.ts
|
|
7
7
|
import { defineCommand } from "citty";
|
|
@@ -379,8 +379,220 @@ var projectsCommand = defineCommand6({
|
|
|
379
379
|
}
|
|
380
380
|
});
|
|
381
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
|
+
|
|
382
594
|
// src/index.ts
|
|
383
|
-
var main =
|
|
595
|
+
var main = defineCommand9({
|
|
384
596
|
meta: {
|
|
385
597
|
name: "app-hosting",
|
|
386
598
|
version: "0.0.1",
|
|
@@ -392,7 +604,9 @@ var main = defineCommand7({
|
|
|
392
604
|
init: initCommand,
|
|
393
605
|
deploy: deployCommand,
|
|
394
606
|
dev: devCommand,
|
|
395
|
-
projects: projectsCommand
|
|
607
|
+
projects: projectsCommand,
|
|
608
|
+
kv: kvCommand,
|
|
609
|
+
db: dbCommand
|
|
396
610
|
}
|
|
397
611
|
});
|
|
398
612
|
runMain(main);
|
package/package.json
CHANGED
|
@@ -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
|
@@ -5,6 +5,8 @@ import { initCommand } from "./commands/init";
|
|
|
5
5
|
import { deployCommand } from "./commands/deploy";
|
|
6
6
|
import { devCommand } from "./commands/dev";
|
|
7
7
|
import { projectsCommand } from "./commands/projects";
|
|
8
|
+
import { kvCommand } from "./commands/kv";
|
|
9
|
+
import { dbCommand } from "./commands/db";
|
|
8
10
|
|
|
9
11
|
const main = defineCommand({
|
|
10
12
|
meta: {
|
|
@@ -19,6 +21,8 @@ const main = defineCommand({
|
|
|
19
21
|
deploy: deployCommand,
|
|
20
22
|
dev: devCommand,
|
|
21
23
|
projects: projectsCommand,
|
|
24
|
+
kv: kvCommand,
|
|
25
|
+
db: dbCommand,
|
|
22
26
|
},
|
|
23
27
|
});
|
|
24
28
|
|