@jango-blockchained/hoox-cli 0.5.0 → 0.5.2
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/package.json +1 -1
- package/src/commands/check/check-command.ts +8 -65
- package/src/commands/check/prerequisites-command.ts +7 -6
- package/src/commands/clone/clone-command.test.ts +8 -10
- package/src/commands/config/config-command.test.ts +4 -4
- package/src/commands/config/config-command.ts +10 -11
- package/src/commands/config/env-command.test.ts +2 -2
- package/src/commands/config/env-command.ts +40 -43
- package/src/commands/config/kv-command.ts +60 -60
- package/src/commands/dashboard/dashboard-command.ts +32 -30
- package/src/commands/db/db-command.ts +79 -80
- package/src/commands/deploy/deploy-command.test.ts +54 -34
- package/src/commands/deploy/deploy-command.ts +3 -84
- package/src/commands/dev/dev-command.test.ts +84 -62
- package/src/commands/disclaimer/disclaimer-command.ts +21 -0
- package/src/commands/disclaimer/index.ts +1 -0
- package/src/commands/init/init-command.test.ts +69 -91
- package/src/commands/init/init-command.ts +19 -15
- package/src/commands/logs/logs-command.test.ts +0 -1
- package/src/commands/monitor/monitor-command.test.ts +37 -29
- package/src/commands/repair/repair-command.test.ts +60 -41
- package/src/commands/repair/repair-service.ts +26 -0
- package/src/commands/schema/index.ts +1 -0
- package/src/commands/schema/schema-command.ts +137 -0
- package/src/commands/test/test-command.test.ts +2 -3
- package/src/commands/update/update-command.ts +6 -65
- package/src/commands/waf/waf-command.ts +56 -59
- package/src/index.ts +5 -13
- package/src/services/config/config-service.ts +1 -6
- package/src/services/db/db-service.test.ts +13 -1
- package/src/services/env/env-service.test.ts +41 -18
- package/src/services/env/env-service.ts +45 -59
- package/src/services/kv/kv-sync-service.ts +14 -5
- package/src/services/schema/index.ts +1 -0
- package/src/services/schema/schema-service.ts +99 -0
- package/src/services/secrets/secrets-service.test.ts +42 -35
- package/src/services/secrets/types.ts +1 -1
- package/src/ui/menu.ts +1 -1
- package/src/utils/error-handler.ts +62 -0
- package/src/utils/errors.ts +1 -0
- package/src/utils/git.ts +134 -0
- package/src/utils/theme.ts +0 -2
|
@@ -14,11 +14,8 @@ import type { Command } from "commander";
|
|
|
14
14
|
import { CloudflareService } from "../../services/cloudflare/cloudflare-service.js";
|
|
15
15
|
import type { WranglerResult } from "../../services/cloudflare/types.js";
|
|
16
16
|
import { CLIError, ExitCode } from "../../utils/errors.js";
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
formatError,
|
|
20
|
-
formatTable,
|
|
21
|
-
} from "../../utils/formatters.js";
|
|
17
|
+
import { formatSuccess, formatTable } from "../../utils/formatters.js";
|
|
18
|
+
import { withErrorHandling } from "../../utils/error-handler.js";
|
|
22
19
|
import { theme, icons } from "../../utils/theme.js";
|
|
23
20
|
import type { FormatOptions } from "../../utils/formatters.js";
|
|
24
21
|
import type { WafStatus, WafRule, WafRuleInput } from "./types.js";
|
|
@@ -461,15 +458,15 @@ export function registerWafCommand(program: Command): void {
|
|
|
461
458
|
.description(
|
|
462
459
|
"Show WAF status (enabled/disabled, active rules, recent blocks)"
|
|
463
460
|
)
|
|
464
|
-
.action(
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
461
|
+
.action(
|
|
462
|
+
withErrorHandling(
|
|
463
|
+
async (_, cmd: Command) => {
|
|
464
|
+
const opts: FormatOptions = cmd.parent!.parent!.opts();
|
|
465
|
+
await handleStatus(opts);
|
|
466
|
+
},
|
|
467
|
+
{ service: "waf" }
|
|
468
|
+
)
|
|
469
|
+
);
|
|
473
470
|
|
|
474
471
|
// -- waf rules -------------------------------------------------------------
|
|
475
472
|
const rules = waf.command("rules").description("Manage WAF firewall rules");
|
|
@@ -477,43 +474,43 @@ export function registerWafCommand(program: Command): void {
|
|
|
477
474
|
rules
|
|
478
475
|
.command("list")
|
|
479
476
|
.description("List all WAF firewall rules")
|
|
480
|
-
.action(
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
477
|
+
.action(
|
|
478
|
+
withErrorHandling(
|
|
479
|
+
async (_, cmd: Command) => {
|
|
480
|
+
const opts: FormatOptions = cmd.parent!.parent!.parent!.opts();
|
|
481
|
+
await handleRulesList(opts);
|
|
482
|
+
},
|
|
483
|
+
{ service: "waf" }
|
|
484
|
+
)
|
|
485
|
+
);
|
|
489
486
|
|
|
490
487
|
rules
|
|
491
488
|
.command("add <type> <value>")
|
|
492
489
|
.description(
|
|
493
490
|
"Add a WAF rule. Types: ip-allowlist, ip-blocklist, rate-limit, custom"
|
|
494
491
|
)
|
|
495
|
-
.action(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
492
|
+
.action(
|
|
493
|
+
withErrorHandling(
|
|
494
|
+
async (type: string, value: string, _, cmd: Command) => {
|
|
495
|
+
const opts: FormatOptions = cmd.parent!.parent!.parent!.opts();
|
|
496
|
+
await handleRulesAdd(type, value, opts);
|
|
497
|
+
},
|
|
498
|
+
{ service: "waf" }
|
|
499
|
+
)
|
|
500
|
+
);
|
|
504
501
|
|
|
505
502
|
rules
|
|
506
503
|
.command("remove <ruleId>")
|
|
507
504
|
.description("Remove a WAF rule by ID")
|
|
508
|
-
.action(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
505
|
+
.action(
|
|
506
|
+
withErrorHandling(
|
|
507
|
+
async (ruleId: string, _, cmd: Command) => {
|
|
508
|
+
const opts: FormatOptions = cmd.parent!.parent!.parent!.opts();
|
|
509
|
+
await handleRulesRemove(ruleId, opts);
|
|
510
|
+
},
|
|
511
|
+
{ service: "waf" }
|
|
512
|
+
)
|
|
513
|
+
);
|
|
517
514
|
|
|
518
515
|
// -- waf mode --------------------------------------------------------------
|
|
519
516
|
const mode = waf
|
|
@@ -523,26 +520,26 @@ export function registerWafCommand(program: Command): void {
|
|
|
523
520
|
mode
|
|
524
521
|
.command("enable")
|
|
525
522
|
.description("Enable WAF protection on the zone")
|
|
526
|
-
.action(
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
523
|
+
.action(
|
|
524
|
+
withErrorHandling(
|
|
525
|
+
async (_, cmd: Command) => {
|
|
526
|
+
const opts: FormatOptions = cmd.parent!.parent!.parent!.opts();
|
|
527
|
+
await handleMode("on", opts);
|
|
528
|
+
},
|
|
529
|
+
{ service: "waf" }
|
|
530
|
+
)
|
|
531
|
+
);
|
|
535
532
|
|
|
536
533
|
mode
|
|
537
534
|
.command("disable")
|
|
538
535
|
.description("Disable WAF protection on the zone")
|
|
539
|
-
.action(
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
536
|
+
.action(
|
|
537
|
+
withErrorHandling(
|
|
538
|
+
async (_, cmd: Command) => {
|
|
539
|
+
const opts: FormatOptions = cmd.parent!.parent!.parent!.opts();
|
|
540
|
+
await handleMode("off", opts);
|
|
541
|
+
},
|
|
542
|
+
{ service: "waf" }
|
|
543
|
+
)
|
|
544
|
+
);
|
|
548
545
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,10 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { Command } from "commander";
|
|
9
9
|
import { toError } from "@jango-blockchained/hoox-shared";
|
|
10
|
-
import {
|
|
11
|
-
FULL_LEGAL_NOTICE,
|
|
12
|
-
COPYRIGHT,
|
|
13
|
-
} from "@jango-blockchained/hoox-shared/legal";
|
|
10
|
+
import { COPYRIGHT } from "@jango-blockchained/hoox-shared/legal";
|
|
14
11
|
import { CLIError, ExitCode } from "./utils/errors.js";
|
|
15
12
|
import { formatError } from "./utils/formatters.js";
|
|
16
13
|
import { theme } from "./utils/theme.js";
|
|
@@ -146,18 +143,11 @@ import { registerDbCommand } from "./commands/db/index.js";
|
|
|
146
143
|
import { registerMonitorCommand } from "./commands/monitor/index.js";
|
|
147
144
|
import { registerRepairCommand } from "./commands/repair/index.js";
|
|
148
145
|
import { registerUpdateCommand } from "./commands/update/index.js";
|
|
146
|
+
import { registerSchemaCommand } from "./commands/schema/index.js";
|
|
149
147
|
import { registerTUICommand } from "./commands/tui/index.js";
|
|
148
|
+
import { registerDisclaimerCommand } from "./commands/disclaimer/index.js";
|
|
150
149
|
import { runInteractiveTUI } from "./ui/index.js";
|
|
151
150
|
|
|
152
|
-
// ── Legal / Disclaimer command ──────────────────────────────────────────
|
|
153
|
-
|
|
154
|
-
program
|
|
155
|
-
.command("disclaimer")
|
|
156
|
-
.description("Display legal disclaimers and trademark information")
|
|
157
|
-
.action(() => {
|
|
158
|
-
console.log(FULL_LEGAL_NOTICE);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
151
|
// ── Command registration ────────────────────────────────────────────────
|
|
162
152
|
|
|
163
153
|
registerInitCommand(program);
|
|
@@ -174,8 +164,10 @@ registerDashboardCommand(program);
|
|
|
174
164
|
registerDbCommand(program);
|
|
175
165
|
registerMonitorCommand(program);
|
|
176
166
|
registerRepairCommand(program);
|
|
167
|
+
registerSchemaCommand(program);
|
|
177
168
|
registerUpdateCommand(program);
|
|
178
169
|
registerTUICommand(program);
|
|
170
|
+
registerDisclaimerCommand(program);
|
|
179
171
|
|
|
180
172
|
// ---------------------------------------------------------------------------
|
|
181
173
|
// preAction hooks — auto-check wrangler version before dev/deploy
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { parse, printParseErrorCode } from "jsonc-parser";
|
|
2
2
|
import type { ParseError } from "jsonc-parser";
|
|
3
|
-
import type {
|
|
4
|
-
HooxConfig,
|
|
5
|
-
WorkerConfig,
|
|
6
|
-
GlobalConfig,
|
|
7
|
-
DevConfig,
|
|
8
|
-
} from "./types";
|
|
3
|
+
import type { HooxConfig, WorkerConfig, GlobalConfig } from "./types";
|
|
9
4
|
|
|
10
5
|
/**
|
|
11
6
|
* Loads, parses, and validates the central wrangler.jsonc configuration.
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
1
|
+
import { describe, expect, it, mock, afterEach } from "bun:test";
|
|
2
2
|
import { DbService } from "./db-service.js";
|
|
3
|
+
import { ConfigService } from "../config/config-service.js";
|
|
4
|
+
|
|
5
|
+
const origLoad = ConfigService.prototype.load;
|
|
6
|
+
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
ConfigService.prototype.load = origLoad;
|
|
9
|
+
});
|
|
3
10
|
|
|
4
11
|
describe("DbService", () => {
|
|
5
12
|
describe("resolveDbName", () => {
|
|
@@ -10,6 +17,11 @@ describe("DbService", () => {
|
|
|
10
17
|
});
|
|
11
18
|
|
|
12
19
|
it("falls back to default when no config exists", async () => {
|
|
20
|
+
// Mock ConfigService.load to throw (simulating no config)
|
|
21
|
+
ConfigService.prototype.load = mock(async () => {
|
|
22
|
+
throw new Error("Config file not found");
|
|
23
|
+
}) as typeof ConfigService.prototype.load;
|
|
24
|
+
|
|
13
25
|
const svc = new DbService();
|
|
14
26
|
const name = await svc.resolveDbName();
|
|
15
27
|
expect(name).toBe("my-database");
|
|
@@ -5,7 +5,7 @@ describe("EnvService", () => {
|
|
|
5
5
|
describe("getDefinitions", () => {
|
|
6
6
|
it("returns all known env var definitions", () => {
|
|
7
7
|
const defs = EnvService.getDefinitions();
|
|
8
|
-
expect(defs.length).toBe(
|
|
8
|
+
expect(defs.length).toBe(28);
|
|
9
9
|
expect(defs.some((d) => d.name === "CLOUDFLARE_API_TOKEN")).toBe(true);
|
|
10
10
|
});
|
|
11
11
|
|
|
@@ -50,17 +50,26 @@ describe("EnvService", () => {
|
|
|
50
50
|
describe("getWorkerDevVars", () => {
|
|
51
51
|
it("maps vars to correct workers", () => {
|
|
52
52
|
const vars = {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
AGENT_INTERNAL_KEY: "sk-123",
|
|
54
|
+
TG_BOT_TOKEN_BINDING: "tg-456",
|
|
55
|
+
INTERNAL_KEY_BINDING: "d1-789",
|
|
56
|
+
DASHBOARD_USER: "admin",
|
|
57
|
+
DASHBOARD_PASS: "pass",
|
|
58
|
+
TELEGRAM_INTERNAL_KEY: "tg-int-key",
|
|
56
59
|
};
|
|
57
60
|
const result = EnvService.getWorkerDevVars(vars);
|
|
58
61
|
expect(result["workers/agent-worker"]).toBeDefined();
|
|
59
|
-
expect(result["workers/agent-worker"].
|
|
62
|
+
expect(result["workers/agent-worker"].AGENT_INTERNAL_KEY).toBe("sk-123");
|
|
60
63
|
expect(result["workers/telegram-worker"]).toBeDefined();
|
|
61
|
-
expect(result["workers/telegram-worker"].
|
|
64
|
+
expect(result["workers/telegram-worker"].TG_BOT_TOKEN_BINDING).toBe(
|
|
62
65
|
"tg-456"
|
|
63
66
|
);
|
|
67
|
+
expect(result["workers/dashboard"]).toBeDefined();
|
|
68
|
+
expect(result["workers/dashboard"].DASHBOARD_USER).toBe("admin");
|
|
69
|
+
expect(result["workers/dashboard"].DASHBOARD_PASS).toBe("pass");
|
|
70
|
+
expect(result["workers/dashboard"].TELEGRAM_INTERNAL_KEY).toBe(
|
|
71
|
+
"tg-int-key"
|
|
72
|
+
);
|
|
64
73
|
});
|
|
65
74
|
|
|
66
75
|
it("omits workers with no matching vars", () => {
|
|
@@ -69,7 +78,7 @@ describe("EnvService", () => {
|
|
|
69
78
|
});
|
|
70
79
|
|
|
71
80
|
it("omits empty-string vars", () => {
|
|
72
|
-
const result = EnvService.getWorkerDevVars({
|
|
81
|
+
const result = EnvService.getWorkerDevVars({ INTERNAL_KEY_BINDING: "" });
|
|
73
82
|
expect(Object.keys(result).length).toBe(0);
|
|
74
83
|
});
|
|
75
84
|
|
|
@@ -77,14 +86,18 @@ describe("EnvService", () => {
|
|
|
77
86
|
const vars = {
|
|
78
87
|
WEBHOOK_API_KEY_BINDING: "webhook-key",
|
|
79
88
|
HA_TOKEN_BINDING: "ha-token",
|
|
80
|
-
|
|
89
|
+
API_SERVICE_KEY_BINDING: "api-key",
|
|
81
90
|
TELEGRAM_SECRET_TOKEN: "tg-secret",
|
|
82
91
|
WALLET_MNEMONIC_SECRET: "mnemonic",
|
|
83
92
|
WALLET_PK_SECRET: "pk",
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
EMAIL_HOST_BINDING: "imap.example.com",
|
|
94
|
+
EMAIL_USER_BINDING: "user",
|
|
95
|
+
EMAIL_PASS_BINDING: "pass",
|
|
96
|
+
INTERNAL_KEY_BINDING: "int-key",
|
|
97
|
+
DASHBOARD_USER: "admin",
|
|
98
|
+
DASHBOARD_PASS: "pass",
|
|
99
|
+
SESSION_SECRET: "secret-32-char-min-for-session",
|
|
100
|
+
TELEGRAM_INTERNAL_KEY: "tg-int-key",
|
|
88
101
|
};
|
|
89
102
|
const result = EnvService.getWorkerDevVars(vars);
|
|
90
103
|
expect(result["workers/hoox"]).toBeDefined();
|
|
@@ -92,7 +105,9 @@ describe("EnvService", () => {
|
|
|
92
105
|
"webhook-key"
|
|
93
106
|
);
|
|
94
107
|
expect(result["workers/hoox"].HA_TOKEN_BINDING).toBe("ha-token");
|
|
95
|
-
expect(result["workers/trade-worker"].
|
|
108
|
+
expect(result["workers/trade-worker"].API_SERVICE_KEY_BINDING).toBe(
|
|
109
|
+
"api-key"
|
|
110
|
+
);
|
|
96
111
|
expect(result["workers/telegram-worker"].TELEGRAM_SECRET_TOKEN).toBe(
|
|
97
112
|
"tg-secret"
|
|
98
113
|
);
|
|
@@ -101,9 +116,18 @@ describe("EnvService", () => {
|
|
|
101
116
|
"mnemonic"
|
|
102
117
|
);
|
|
103
118
|
expect(result["workers/email-worker"]).toBeDefined();
|
|
104
|
-
expect(result["workers/email-worker"].
|
|
119
|
+
expect(result["workers/email-worker"].EMAIL_HOST_BINDING).toBe(
|
|
105
120
|
"imap.example.com"
|
|
106
121
|
);
|
|
122
|
+
expect(result["workers/dashboard"]).toBeDefined();
|
|
123
|
+
expect(result["workers/dashboard"].DASHBOARD_USER).toBe("admin");
|
|
124
|
+
expect(result["workers/dashboard"].DASHBOARD_PASS).toBe("pass");
|
|
125
|
+
expect(result["workers/dashboard"].SESSION_SECRET).toBe(
|
|
126
|
+
"secret-32-char-min-for-session"
|
|
127
|
+
);
|
|
128
|
+
expect(result["workers/dashboard"].TELEGRAM_INTERNAL_KEY).toBe(
|
|
129
|
+
"tg-int-key"
|
|
130
|
+
);
|
|
107
131
|
});
|
|
108
132
|
});
|
|
109
133
|
|
|
@@ -133,12 +157,12 @@ describe("EnvService", () => {
|
|
|
133
157
|
CLOUDFLARE_API_TOKEN: "cfut_xxx",
|
|
134
158
|
CLOUDFLARE_ACCOUNT_ID: "abc123",
|
|
135
159
|
SUBDOMAIN_PREFIX: "myapp",
|
|
136
|
-
D1_INTERNAL_KEY: "d1-key",
|
|
137
160
|
TRADE_INTERNAL_KEY: "trade-key",
|
|
138
161
|
AGENT_INTERNAL_KEY: "agent-key",
|
|
139
162
|
WEBHOOK_API_KEY_BINDING: "webhook-key",
|
|
140
163
|
INTERNAL_KEY_BINDING: "int-key",
|
|
141
|
-
|
|
164
|
+
API_SERVICE_KEY_BINDING: "api-key",
|
|
165
|
+
TELEGRAM_INTERNAL_KEY: "tg-key",
|
|
142
166
|
DASHBOARD_USER: "admin",
|
|
143
167
|
DASHBOARD_PASS: "pass123",
|
|
144
168
|
SESSION_SECRET: "a".repeat(32),
|
|
@@ -152,12 +176,11 @@ describe("EnvService", () => {
|
|
|
152
176
|
CLOUDFLARE_API_TOKEN: "tok",
|
|
153
177
|
CLOUDFLARE_ACCOUNT_ID: "id",
|
|
154
178
|
SUBDOMAIN_PREFIX: "p",
|
|
155
|
-
D1_INTERNAL_KEY: "k",
|
|
156
179
|
TRADE_INTERNAL_KEY: "k",
|
|
157
180
|
AGENT_INTERNAL_KEY: "k",
|
|
158
181
|
WEBHOOK_API_KEY_BINDING: "wk",
|
|
159
182
|
INTERNAL_KEY_BINDING: "ik",
|
|
160
|
-
|
|
183
|
+
API_SERVICE_KEY_BINDING: "ak",
|
|
161
184
|
DASHBOARD_USER: "u",
|
|
162
185
|
DASHBOARD_PASS: "p",
|
|
163
186
|
SESSION_SECRET: "short",
|
|
@@ -52,7 +52,7 @@ export class EnvService {
|
|
|
52
52
|
hint: "Prefix for worker URLs",
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
|
-
name: "
|
|
55
|
+
name: "INTERNAL_KEY_BINDING",
|
|
56
56
|
required: true,
|
|
57
57
|
secret: true,
|
|
58
58
|
section: "Internal Auth",
|
|
@@ -87,12 +87,19 @@ export class EnvService {
|
|
|
87
87
|
hint: "Shared internal auth key for inter-worker communication",
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
|
-
name: "
|
|
90
|
+
name: "API_SERVICE_KEY_BINDING",
|
|
91
91
|
required: true,
|
|
92
92
|
secret: true,
|
|
93
93
|
section: "Internal Auth",
|
|
94
94
|
hint: "API service key for trade-worker",
|
|
95
95
|
},
|
|
96
|
+
{
|
|
97
|
+
name: "TELEGRAM_INTERNAL_KEY",
|
|
98
|
+
required: true,
|
|
99
|
+
secret: true,
|
|
100
|
+
section: "Internal Auth",
|
|
101
|
+
hint: "Internal key for telegram worker auth",
|
|
102
|
+
},
|
|
96
103
|
{
|
|
97
104
|
name: "HA_TOKEN_BINDING",
|
|
98
105
|
required: false,
|
|
@@ -101,7 +108,7 @@ export class EnvService {
|
|
|
101
108
|
hint: "Home Assistant token for hoox",
|
|
102
109
|
},
|
|
103
110
|
{
|
|
104
|
-
name: "
|
|
111
|
+
name: "TG_BOT_TOKEN_BINDING",
|
|
105
112
|
required: false,
|
|
106
113
|
secret: true,
|
|
107
114
|
section: "Telegram",
|
|
@@ -114,64 +121,44 @@ export class EnvService {
|
|
|
114
121
|
section: "Telegram",
|
|
115
122
|
hint: "Telegram webhook secret token",
|
|
116
123
|
},
|
|
124
|
+
// AI provider keys consolidated into AGENT_INTERNAL_KEY (above)
|
|
117
125
|
{
|
|
118
|
-
name: "
|
|
119
|
-
required: false,
|
|
120
|
-
secret: true,
|
|
121
|
-
section: "AI Providers",
|
|
122
|
-
hint: "OpenAI API key",
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
name: "AGENT_ANTHROPIC_KEY",
|
|
126
|
-
required: false,
|
|
127
|
-
secret: true,
|
|
128
|
-
section: "AI Providers",
|
|
129
|
-
hint: "Anthropic API key",
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
name: "AGENT_GOOGLE_KEY",
|
|
133
|
-
required: false,
|
|
134
|
-
secret: true,
|
|
135
|
-
section: "AI Providers",
|
|
136
|
-
hint: "Google AI API key",
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: "BINANCE_API_KEY",
|
|
126
|
+
name: "BINANCE_KEY_BINDING",
|
|
140
127
|
required: false,
|
|
141
128
|
secret: true,
|
|
142
129
|
section: "Exchanges",
|
|
143
130
|
hint: "Binance API key",
|
|
144
131
|
},
|
|
145
132
|
{
|
|
146
|
-
name: "
|
|
133
|
+
name: "BINANCE_SECRET_BINDING",
|
|
147
134
|
required: false,
|
|
148
135
|
secret: true,
|
|
149
136
|
section: "Exchanges",
|
|
150
137
|
hint: "Binance API secret",
|
|
151
138
|
},
|
|
152
139
|
{
|
|
153
|
-
name: "
|
|
140
|
+
name: "MEXC_KEY_BINDING",
|
|
154
141
|
required: false,
|
|
155
142
|
secret: true,
|
|
156
143
|
section: "Exchanges",
|
|
157
144
|
hint: "MEXC API key",
|
|
158
145
|
},
|
|
159
146
|
{
|
|
160
|
-
name: "
|
|
147
|
+
name: "MEXC_SECRET_BINDING",
|
|
161
148
|
required: false,
|
|
162
149
|
secret: true,
|
|
163
150
|
section: "Exchanges",
|
|
164
151
|
hint: "MEXC API secret",
|
|
165
152
|
},
|
|
166
153
|
{
|
|
167
|
-
name: "
|
|
154
|
+
name: "BYBIT_KEY_BINDING",
|
|
168
155
|
required: false,
|
|
169
156
|
secret: true,
|
|
170
157
|
section: "Exchanges",
|
|
171
158
|
hint: "Bybit API key",
|
|
172
159
|
},
|
|
173
160
|
{
|
|
174
|
-
name: "
|
|
161
|
+
name: "BYBIT_SECRET_BINDING",
|
|
175
162
|
required: false,
|
|
176
163
|
secret: true,
|
|
177
164
|
section: "Exchanges",
|
|
@@ -179,33 +166,27 @@ export class EnvService {
|
|
|
179
166
|
},
|
|
180
167
|
// Email
|
|
181
168
|
{
|
|
182
|
-
name: "
|
|
169
|
+
name: "EMAIL_HOST_BINDING",
|
|
183
170
|
required: false,
|
|
184
171
|
secret: true,
|
|
185
172
|
section: "Email",
|
|
186
173
|
hint: "Email IMAP server host",
|
|
187
174
|
},
|
|
188
175
|
{
|
|
189
|
-
name: "
|
|
176
|
+
name: "EMAIL_USER_BINDING",
|
|
190
177
|
required: false,
|
|
191
178
|
secret: true,
|
|
192
179
|
section: "Email",
|
|
193
180
|
hint: "Email IMAP username",
|
|
194
181
|
},
|
|
195
182
|
{
|
|
196
|
-
name: "
|
|
183
|
+
name: "EMAIL_PASS_BINDING",
|
|
197
184
|
required: false,
|
|
198
185
|
secret: true,
|
|
199
186
|
section: "Email",
|
|
200
187
|
hint: "Email IMAP password",
|
|
201
188
|
},
|
|
202
|
-
|
|
203
|
-
name: "INTERNAL_KEY",
|
|
204
|
-
required: false,
|
|
205
|
-
secret: true,
|
|
206
|
-
section: "Email",
|
|
207
|
-
hint: "Internal auth key for email-worker",
|
|
208
|
-
},
|
|
189
|
+
// INTERNAL_KEY_BINDING consolidated into INTERNAL_KEY_BINDING (above)
|
|
209
190
|
// Wallet
|
|
210
191
|
{
|
|
211
192
|
name: "WALLET_MNEMONIC_SECRET",
|
|
@@ -322,24 +303,19 @@ export class EnvService {
|
|
|
322
303
|
"HA_TOKEN_BINDING",
|
|
323
304
|
],
|
|
324
305
|
"workers/trade-worker": [
|
|
325
|
-
"
|
|
306
|
+
"API_SERVICE_KEY_BINDING",
|
|
326
307
|
"INTERNAL_KEY_BINDING",
|
|
327
|
-
"
|
|
328
|
-
"
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"
|
|
332
|
-
"
|
|
333
|
-
],
|
|
334
|
-
"workers/agent-worker": [
|
|
335
|
-
"AGENT_INTERNAL_KEY",
|
|
336
|
-
"AGENT_OPENAI_KEY",
|
|
337
|
-
"AGENT_ANTHROPIC_KEY",
|
|
338
|
-
"AGENT_GOOGLE_KEY",
|
|
308
|
+
"BINANCE_KEY_BINDING",
|
|
309
|
+
"BINANCE_SECRET_BINDING",
|
|
310
|
+
"MEXC_KEY_BINDING",
|
|
311
|
+
"MEXC_SECRET_BINDING",
|
|
312
|
+
"BYBIT_KEY_BINDING",
|
|
313
|
+
"BYBIT_SECRET_BINDING",
|
|
339
314
|
],
|
|
340
|
-
"workers/
|
|
315
|
+
"workers/agent-worker": ["AGENT_INTERNAL_KEY"],
|
|
316
|
+
"workers/d1-worker": ["INTERNAL_KEY_BINDING"],
|
|
341
317
|
"workers/telegram-worker": [
|
|
342
|
-
"
|
|
318
|
+
"TG_BOT_TOKEN_BINDING",
|
|
343
319
|
"TELEGRAM_SECRET_TOKEN",
|
|
344
320
|
],
|
|
345
321
|
"workers/web3-wallet-worker": [
|
|
@@ -347,12 +323,22 @@ export class EnvService {
|
|
|
347
323
|
"WALLET_PK_SECRET",
|
|
348
324
|
],
|
|
349
325
|
"workers/email-worker": [
|
|
350
|
-
"
|
|
351
|
-
"
|
|
352
|
-
"
|
|
353
|
-
"
|
|
326
|
+
"EMAIL_HOST_BINDING",
|
|
327
|
+
"EMAIL_USER_BINDING",
|
|
328
|
+
"EMAIL_PASS_BINDING",
|
|
329
|
+
"INTERNAL_KEY_BINDING",
|
|
354
330
|
],
|
|
355
331
|
"workers/analytics-worker": ["CLOUDFLARE_API_TOKEN"],
|
|
332
|
+
"workers/dashboard": [
|
|
333
|
+
"DASHBOARD_USER",
|
|
334
|
+
"DASHBOARD_PASS",
|
|
335
|
+
"SESSION_SECRET",
|
|
336
|
+
"INTERNAL_KEY_BINDING",
|
|
337
|
+
"AGENT_INTERNAL_KEY",
|
|
338
|
+
"TRADE_INTERNAL_KEY",
|
|
339
|
+
"TELEGRAM_INTERNAL_KEY",
|
|
340
|
+
"API_SERVICE_KEY_BINDING",
|
|
341
|
+
],
|
|
356
342
|
};
|
|
357
343
|
const result: Record<string, Record<string, string>> = {};
|
|
358
344
|
for (const [workerPath, varNames] of Object.entries(workerMap)) {
|
|
@@ -16,7 +16,7 @@ export class KvSyncService {
|
|
|
16
16
|
if (namespaceId) return namespaceId;
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
const proc = Bun.spawn(["wrangler", "kv
|
|
19
|
+
const proc = Bun.spawn(["wrangler", "kv", "namespace", "list"], {
|
|
20
20
|
stdout: "pipe",
|
|
21
21
|
stderr: "pipe",
|
|
22
22
|
});
|
|
@@ -46,7 +46,7 @@ export class KvSyncService {
|
|
|
46
46
|
|
|
47
47
|
async list(namespaceId: string): Promise<Array<{ name: string }>> {
|
|
48
48
|
const proc = Bun.spawn(
|
|
49
|
-
["wrangler", "kv
|
|
49
|
+
["wrangler", "kv", "key", "list", "--namespace-id", namespaceId],
|
|
50
50
|
{ stdout: "pipe", stderr: "pipe" }
|
|
51
51
|
);
|
|
52
52
|
const stdout = await new Response(proc.stdout).text();
|
|
@@ -71,7 +71,7 @@ export class KvSyncService {
|
|
|
71
71
|
|
|
72
72
|
async get(namespaceId: string, key: string): Promise<string | null> {
|
|
73
73
|
const proc = Bun.spawn(
|
|
74
|
-
["wrangler", "kv
|
|
74
|
+
["wrangler", "kv", "key", "get", "--namespace-id", namespaceId, key],
|
|
75
75
|
{ stdout: "pipe", stderr: "pipe" }
|
|
76
76
|
);
|
|
77
77
|
const stdout = await new Response(proc.stdout).text();
|
|
@@ -90,7 +90,16 @@ export class KvSyncService {
|
|
|
90
90
|
|
|
91
91
|
async set(namespaceId: string, key: string, value: string): Promise<void> {
|
|
92
92
|
const proc = Bun.spawn(
|
|
93
|
-
[
|
|
93
|
+
[
|
|
94
|
+
"wrangler",
|
|
95
|
+
"kv",
|
|
96
|
+
"key",
|
|
97
|
+
"put",
|
|
98
|
+
"--namespace-id",
|
|
99
|
+
namespaceId,
|
|
100
|
+
key,
|
|
101
|
+
value,
|
|
102
|
+
],
|
|
94
103
|
{ stdout: "pipe", stderr: "pipe" }
|
|
95
104
|
);
|
|
96
105
|
const exitCode = await proc.exited;
|
|
@@ -105,7 +114,7 @@ export class KvSyncService {
|
|
|
105
114
|
|
|
106
115
|
async delete(namespaceId: string, key: string): Promise<void> {
|
|
107
116
|
const proc = Bun.spawn(
|
|
108
|
-
["wrangler", "kv
|
|
117
|
+
["wrangler", "kv", "key", "delete", "--namespace-id", namespaceId, key],
|
|
109
118
|
{ stdout: "pipe", stderr: "pipe" }
|
|
110
119
|
);
|
|
111
120
|
const exitCode = await proc.exited;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SchemaService } from "./schema-service.js";
|