@jango-blockchained/hoox-shared 1.0.8
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 +27 -0
- package/dist/analytics.d.ts +22 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +34 -0
- package/dist/api-client.d.ts +34 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +124 -0
- package/dist/colors.d.ts +34 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +42 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +91 -0
- package/dist/d1/index.d.ts +5 -0
- package/dist/d1/index.d.ts.map +1 -0
- package/dist/d1/index.js +316 -0
- package/dist/d1/repository.d.ts +77 -0
- package/dist/d1/repository.d.ts.map +1 -0
- package/dist/d1/schemas.d.ts +85 -0
- package/dist/d1/schemas.d.ts.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +106 -0
- package/dist/exchange-client.d.ts +84 -0
- package/dist/exchange-client.d.ts.map +1 -0
- package/dist/exchange-client.js +104 -0
- package/dist/format-time.d.ts +24 -0
- package/dist/format-time.d.ts.map +1 -0
- package/dist/format-time.js +57 -0
- package/dist/formatters.d.ts +32 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +155 -0
- package/dist/health.d.ts +19 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +117 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2581 -0
- package/dist/kvKeys.d.ts +72 -0
- package/dist/kvKeys.d.ts.map +1 -0
- package/dist/kvKeys.js +107 -0
- package/dist/kvUtils.d.ts +26 -0
- package/dist/kvUtils.d.ts.map +1 -0
- package/dist/kvUtils.js +127 -0
- package/dist/legal.d.ts +11 -0
- package/dist/legal.d.ts.map +1 -0
- package/dist/legal.js +40 -0
- package/dist/middleware/auth.d.ts +59 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/cors.d.ts +28 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/index.d.ts +10 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +375 -0
- package/dist/middleware/logger.d.ts +16 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/rate-limit.d.ts +24 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/security-headers.d.ts +39 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/validate.d.ts +21 -0
- package/dist/middleware/validate.d.ts.map +1 -0
- package/dist/router.d.ts +11 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +123 -0
- package/dist/schemas/index.d.ts +4 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +656 -0
- package/dist/schemas/registry.d.ts +8 -0
- package/dist/schemas/registry.d.ts.map +1 -0
- package/dist/schemas/types.d.ts +79 -0
- package/dist/schemas/types.d.ts.map +1 -0
- package/dist/schemas/validators.d.ts +35 -0
- package/dist/schemas/validators.d.ts.map +1 -0
- package/dist/service-bindings.d.ts +32 -0
- package/dist/service-bindings.d.ts.map +1 -0
- package/dist/service-bindings.js +31 -0
- package/dist/session.d.ts +46 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +79 -0
- package/dist/sse.d.ts +26 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +91 -0
- package/dist/stores/config-store.d.ts +87 -0
- package/dist/stores/config-store.d.ts.map +1 -0
- package/dist/stores/config-store.js +132 -0
- package/dist/stores/service-store.d.ts +206 -0
- package/dist/stores/service-store.d.ts.map +1 -0
- package/dist/stores/service-store.js +359 -0
- package/dist/stores/ui-store.d.ts +63 -0
- package/dist/stores/ui-store.d.ts.map +1 -0
- package/dist/stores/ui-store.js +62 -0
- package/dist/types/errors.d.ts +16 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +1 -0
- package/dist/types/router.d.ts +22 -0
- package/dist/types/router.d.ts.map +1 -0
- package/dist/types/router.js +1 -0
- package/dist/types.d.ts +317 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +70 -0
- package/dist/wizard/engine.d.ts +42 -0
- package/dist/wizard/engine.d.ts.map +1 -0
- package/dist/wizard/index.d.ts +7 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +519 -0
- package/dist/wizard/persistence.d.ts +14 -0
- package/dist/wizard/persistence.d.ts.map +1 -0
- package/dist/wizard/presets.d.ts +34 -0
- package/dist/wizard/presets.d.ts.map +1 -0
- package/dist/wizard/provisioner.d.ts +11 -0
- package/dist/wizard/provisioner.d.ts.map +1 -0
- package/dist/wizard/types.d.ts +72 -0
- package/dist/wizard/types.d.ts.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
+
|
|
18
|
+
// src/wizard/presets.ts
|
|
19
|
+
var PRESETS = [
|
|
20
|
+
{
|
|
21
|
+
name: "minimal",
|
|
22
|
+
label: "Minimal",
|
|
23
|
+
description: "Gateway + D1 database \u2014 webhook processing only",
|
|
24
|
+
workers: ["hoox", "d1-worker", "analytics-worker"],
|
|
25
|
+
integrations: []
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "standard",
|
|
29
|
+
label: "Standard",
|
|
30
|
+
description: "Trading + analytics + Telegram notifications",
|
|
31
|
+
workers: [
|
|
32
|
+
"hoox",
|
|
33
|
+
"d1-worker",
|
|
34
|
+
"trade-worker",
|
|
35
|
+
"analytics-worker",
|
|
36
|
+
"telegram-worker"
|
|
37
|
+
],
|
|
38
|
+
integrations: ["binance", "telegram"]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "full",
|
|
42
|
+
label: "Full",
|
|
43
|
+
description: "All workers + AI agent + DeFi + email",
|
|
44
|
+
workers: [
|
|
45
|
+
"hoox",
|
|
46
|
+
"d1-worker",
|
|
47
|
+
"trade-worker",
|
|
48
|
+
"agent-worker",
|
|
49
|
+
"telegram-worker",
|
|
50
|
+
"analytics-worker",
|
|
51
|
+
"email-worker",
|
|
52
|
+
"web3-wallet-worker"
|
|
53
|
+
],
|
|
54
|
+
integrations: ["binance", "bybit", "mexc", "telegram", "openai", "wallet"]
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
var WORKER_DEPENDENCIES = {
|
|
58
|
+
"trade-worker": ["d1-worker"],
|
|
59
|
+
"agent-worker": ["d1-worker"],
|
|
60
|
+
"email-worker": ["d1-worker"],
|
|
61
|
+
"analytics-worker": ["d1-worker"],
|
|
62
|
+
"web3-wallet-worker": ["d1-worker", "hoox"]
|
|
63
|
+
};
|
|
64
|
+
function resolveDependencies(selected) {
|
|
65
|
+
const result = new Set(selected);
|
|
66
|
+
let changed = true;
|
|
67
|
+
while (changed) {
|
|
68
|
+
changed = false;
|
|
69
|
+
for (const worker of [...result]) {
|
|
70
|
+
const deps = WORKER_DEPENDENCIES[worker];
|
|
71
|
+
if (deps) {
|
|
72
|
+
for (const dep of deps) {
|
|
73
|
+
if (!result.has(dep)) {
|
|
74
|
+
result.add(dep);
|
|
75
|
+
changed = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return [...result];
|
|
82
|
+
}
|
|
83
|
+
var INTEGRATIONS = [
|
|
84
|
+
{
|
|
85
|
+
key: "binance",
|
|
86
|
+
label: "Binance Exchange",
|
|
87
|
+
workerName: "trade-worker",
|
|
88
|
+
secrets: {
|
|
89
|
+
BINANCE_KEY_BINDING: "Binance API Key",
|
|
90
|
+
BINANCE_SECRET_BINDING: "Binance API Secret"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
key: "mexc",
|
|
95
|
+
label: "MEXC Exchange",
|
|
96
|
+
workerName: "trade-worker",
|
|
97
|
+
secrets: {
|
|
98
|
+
MEXC_KEY_BINDING: "MEXC API Key",
|
|
99
|
+
MEXC_SECRET_BINDING: "MEXC API Secret"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
key: "bybit",
|
|
104
|
+
label: "Bybit Exchange",
|
|
105
|
+
workerName: "trade-worker",
|
|
106
|
+
secrets: {
|
|
107
|
+
BYBIT_KEY_BINDING: "Bybit API Key",
|
|
108
|
+
BYBIT_SECRET_BINDING: "Bybit API Secret"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: "wallet",
|
|
113
|
+
label: "Web3 Wallet (on-chain execution)",
|
|
114
|
+
workerName: "web3-wallet-worker",
|
|
115
|
+
secrets: {
|
|
116
|
+
WALLET_MNEMONIC_SECRET: "Wallet Mnemonic Phrase",
|
|
117
|
+
WALLET_PK_SECRET: "Wallet Private Key"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
key: "email",
|
|
122
|
+
label: "Email Signal Parsing",
|
|
123
|
+
workerName: "email-worker",
|
|
124
|
+
secrets: {
|
|
125
|
+
INTERNAL_KEY_BINDING: "Internal Auth Key",
|
|
126
|
+
EMAIL_HOST_BINDING: "Email Host (IMAP server)",
|
|
127
|
+
EMAIL_USER_BINDING: "Email Username",
|
|
128
|
+
EMAIL_PASS_BINDING: "Email Password"
|
|
129
|
+
},
|
|
130
|
+
vars: { USE_IMAP: "false" }
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: "telegram",
|
|
134
|
+
label: "Telegram Notifications",
|
|
135
|
+
workerName: "telegram-worker",
|
|
136
|
+
secrets: {
|
|
137
|
+
TG_BOT_TOKEN_BINDING: "Telegram Bot Token"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
key: "openai",
|
|
142
|
+
label: "OpenAI (AI Agent)",
|
|
143
|
+
workerName: "agent-worker",
|
|
144
|
+
secrets: {
|
|
145
|
+
AGENT_INTERNAL_KEY: "OpenAI API Key"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
key: "anthropic",
|
|
150
|
+
label: "Anthropic (AI Agent)",
|
|
151
|
+
workerName: "agent-worker",
|
|
152
|
+
secrets: {
|
|
153
|
+
AGENT_INTERNAL_KEY: "Anthropic API Key"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
key: "google-ai",
|
|
158
|
+
label: "Google AI (AI Agent)",
|
|
159
|
+
workerName: "agent-worker",
|
|
160
|
+
secrets: {
|
|
161
|
+
AGENT_INTERNAL_KEY: "Google AI API Key"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
key: "home-assistant",
|
|
166
|
+
label: "Home Assistant (Smart Home)",
|
|
167
|
+
workerName: "hoox",
|
|
168
|
+
secrets: {
|
|
169
|
+
HA_TOKEN_BINDING: "Home Assistant Token"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
var BASE_WORKERS = {
|
|
174
|
+
"d1-worker": {
|
|
175
|
+
enabled: true,
|
|
176
|
+
path: "workers/d1-worker",
|
|
177
|
+
vars: { database_name: "hoox-db" }
|
|
178
|
+
},
|
|
179
|
+
hoox: { enabled: true, path: "workers/hoox", vars: {} },
|
|
180
|
+
"agent-worker": { enabled: true, path: "workers/agent-worker", vars: {} },
|
|
181
|
+
"analytics-worker": {
|
|
182
|
+
enabled: true,
|
|
183
|
+
path: "workers/analytics-worker",
|
|
184
|
+
vars: {}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
var BASE_SECRETS = {
|
|
188
|
+
hoox: ["WEBHOOK_API_KEY_BINDING"],
|
|
189
|
+
"agent-worker": ["AGENT_INTERNAL_KEY", "INTERNAL_KEY_BINDING"],
|
|
190
|
+
"analytics-worker": ["CLOUDFLARE_API_TOKEN"]
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// src/wizard/engine.ts
|
|
194
|
+
var STEPS = [
|
|
195
|
+
{
|
|
196
|
+
id: "PREREQUISITES",
|
|
197
|
+
label: "System Prerequisites",
|
|
198
|
+
canGoBack: false,
|
|
199
|
+
optional: false,
|
|
200
|
+
validate: validatePrerequisites
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: "CLOUDFLARE_CONFIG",
|
|
204
|
+
label: "Cloudflare Configuration",
|
|
205
|
+
canGoBack: true,
|
|
206
|
+
optional: false,
|
|
207
|
+
validate: validateCloudflareConfig
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: "WORKER_SELECTION",
|
|
211
|
+
label: "Worker Selection",
|
|
212
|
+
canGoBack: true,
|
|
213
|
+
optional: false,
|
|
214
|
+
validate: validateWorkerSelection
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: "PROVISIONING",
|
|
218
|
+
label: "Infrastructure Provisioning",
|
|
219
|
+
canGoBack: true,
|
|
220
|
+
optional: true,
|
|
221
|
+
validate: () => []
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: "SECRETS",
|
|
225
|
+
label: "Secrets Configuration",
|
|
226
|
+
canGoBack: true,
|
|
227
|
+
optional: false,
|
|
228
|
+
validate: validateSecrets
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: "CONFIG_WRITE",
|
|
232
|
+
label: "Configuration Write",
|
|
233
|
+
canGoBack: true,
|
|
234
|
+
optional: false,
|
|
235
|
+
validate: () => []
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: "DEPLOY",
|
|
239
|
+
label: "Deploy",
|
|
240
|
+
canGoBack: false,
|
|
241
|
+
optional: true,
|
|
242
|
+
validate: () => []
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
id: "DONE",
|
|
246
|
+
label: "Complete",
|
|
247
|
+
canGoBack: false,
|
|
248
|
+
optional: false,
|
|
249
|
+
validate: () => []
|
|
250
|
+
}
|
|
251
|
+
];
|
|
252
|
+
var STEP_ORDER = STEPS.map((s) => s.id);
|
|
253
|
+
function createInitialState() {
|
|
254
|
+
return {
|
|
255
|
+
step: "PREREQUISITES",
|
|
256
|
+
completedSteps: [],
|
|
257
|
+
selectedWorkers: [],
|
|
258
|
+
selectedIntegrations: [],
|
|
259
|
+
secrets: {},
|
|
260
|
+
startedAt: Date.now(),
|
|
261
|
+
updatedAt: Date.now()
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function validatePrerequisites(_state, input) {
|
|
265
|
+
const errors = [];
|
|
266
|
+
if (!input.checksPassed) {
|
|
267
|
+
errors.push("System prerequisite checks must pass before continuing");
|
|
268
|
+
}
|
|
269
|
+
return errors;
|
|
270
|
+
}
|
|
271
|
+
function validateCloudflareConfig(_state, input) {
|
|
272
|
+
const errors = [];
|
|
273
|
+
const token = input.apiToken;
|
|
274
|
+
const accountId = input.accountId;
|
|
275
|
+
if (!token || String(token).trim().length === 0) {
|
|
276
|
+
errors.push("Cloudflare API token is required");
|
|
277
|
+
}
|
|
278
|
+
if (!accountId || String(accountId).trim().length === 0) {
|
|
279
|
+
errors.push("Cloudflare Account ID is required");
|
|
280
|
+
}
|
|
281
|
+
return errors;
|
|
282
|
+
}
|
|
283
|
+
function validateWorkerSelection(_state, input) {
|
|
284
|
+
const errors = [];
|
|
285
|
+
const preset = input.preset;
|
|
286
|
+
const customWorkers = input.workers;
|
|
287
|
+
if (preset === "custom" && (!customWorkers || customWorkers.length === 0)) {
|
|
288
|
+
errors.push("At least one worker must be selected");
|
|
289
|
+
}
|
|
290
|
+
return errors;
|
|
291
|
+
}
|
|
292
|
+
function validateSecrets(state, input) {
|
|
293
|
+
const errors = [];
|
|
294
|
+
const secrets = input.secrets;
|
|
295
|
+
if (!secrets || Object.keys(secrets).length === 0) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
for (const integrationKey of state.selectedIntegrations) {
|
|
299
|
+
const integration = INTEGRATIONS.find((i) => i.key === integrationKey);
|
|
300
|
+
if (!integration)
|
|
301
|
+
continue;
|
|
302
|
+
const integrationSecrets = secrets[integrationKey];
|
|
303
|
+
if (integrationSecrets) {
|
|
304
|
+
for (const secretName of Object.keys(integration.secrets)) {
|
|
305
|
+
const val = integrationSecrets[secretName];
|
|
306
|
+
if (!val || String(val).trim().length === 0) {
|
|
307
|
+
errors.push(`Secret "${integration.secrets[secretName]}" is required for ${integration.label}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return errors;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
class WizardEngine {
|
|
316
|
+
state;
|
|
317
|
+
constructor(initialState) {
|
|
318
|
+
this.state = { ...createInitialState(), ...initialState };
|
|
319
|
+
}
|
|
320
|
+
getState() {
|
|
321
|
+
return { ...this.state };
|
|
322
|
+
}
|
|
323
|
+
getCurrentStep() {
|
|
324
|
+
return STEPS.find((s) => s.id === this.state.step) ?? STEPS[0];
|
|
325
|
+
}
|
|
326
|
+
getCompletedSteps() {
|
|
327
|
+
return [...this.state.completedSteps];
|
|
328
|
+
}
|
|
329
|
+
canProceed() {
|
|
330
|
+
const step = this.getCurrentStep();
|
|
331
|
+
return step.optional || this.state.completedSteps.includes(step.id);
|
|
332
|
+
}
|
|
333
|
+
canGoBack() {
|
|
334
|
+
return this.getCurrentStep().canGoBack;
|
|
335
|
+
}
|
|
336
|
+
execute(input) {
|
|
337
|
+
const currentStep = this.getCurrentStep();
|
|
338
|
+
const errors = currentStep.validate(this.state, input);
|
|
339
|
+
if (errors.length > 0) {
|
|
340
|
+
return errors;
|
|
341
|
+
}
|
|
342
|
+
this.applyInput(input);
|
|
343
|
+
if (!this.state.completedSteps.includes(this.state.step)) {
|
|
344
|
+
this.state.completedSteps.push(this.state.step);
|
|
345
|
+
}
|
|
346
|
+
const currentIdx = STEP_ORDER.indexOf(this.state.step);
|
|
347
|
+
if (currentIdx < STEP_ORDER.length - 1) {
|
|
348
|
+
this.state.step = STEP_ORDER[currentIdx + 1];
|
|
349
|
+
}
|
|
350
|
+
this.state.updatedAt = Date.now();
|
|
351
|
+
return [];
|
|
352
|
+
}
|
|
353
|
+
goBack() {
|
|
354
|
+
if (!this.canGoBack())
|
|
355
|
+
return;
|
|
356
|
+
const currentIdx = STEP_ORDER.indexOf(this.state.step);
|
|
357
|
+
if (currentIdx > 0) {
|
|
358
|
+
const previousStep = STEP_ORDER[currentIdx - 1];
|
|
359
|
+
this.state.step = previousStep;
|
|
360
|
+
this.state.completedSteps = this.state.completedSteps.filter((s) => s !== this.state.step || STEP_ORDER.indexOf(s) <= STEP_ORDER.indexOf(previousStep));
|
|
361
|
+
}
|
|
362
|
+
this.state.updatedAt = Date.now();
|
|
363
|
+
}
|
|
364
|
+
reset() {
|
|
365
|
+
this.state = createInitialState();
|
|
366
|
+
}
|
|
367
|
+
buildConfig() {
|
|
368
|
+
const cf = this.state.cloudflareConfig;
|
|
369
|
+
const workers = {};
|
|
370
|
+
for (const [name, baseCfg] of Object.entries(BASE_WORKERS)) {
|
|
371
|
+
workers[name] = {
|
|
372
|
+
enabled: true,
|
|
373
|
+
path: baseCfg.path,
|
|
374
|
+
vars: { ...baseCfg.vars },
|
|
375
|
+
secrets: [...BASE_SECRETS[name] ?? []]
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
for (const key of this.state.selectedIntegrations) {
|
|
379
|
+
const integration = INTEGRATIONS.find((i) => i.key === key);
|
|
380
|
+
if (!integration)
|
|
381
|
+
continue;
|
|
382
|
+
const workerName = integration.workerName;
|
|
383
|
+
if (!workers[workerName]) {
|
|
384
|
+
workers[workerName] = {
|
|
385
|
+
enabled: true,
|
|
386
|
+
path: `workers/${workerName}`,
|
|
387
|
+
vars: {},
|
|
388
|
+
secrets: []
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
if (integration.vars) {
|
|
392
|
+
Object.assign(workers[workerName].vars, integration.vars);
|
|
393
|
+
}
|
|
394
|
+
for (const secretName of Object.keys(integration.secrets)) {
|
|
395
|
+
if (!workers[workerName].secrets.includes(secretName)) {
|
|
396
|
+
workers[workerName].secrets.push(secretName);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
for (const workerName of this.state.selectedWorkers) {
|
|
401
|
+
if (!workers[workerName]) {
|
|
402
|
+
workers[workerName] = {
|
|
403
|
+
enabled: true,
|
|
404
|
+
path: `workers/${workerName}`,
|
|
405
|
+
vars: {},
|
|
406
|
+
secrets: []
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
global: {
|
|
412
|
+
cloudflare_api_token: cf?.apiToken ?? "",
|
|
413
|
+
cloudflare_account_id: cf?.accountId ?? "",
|
|
414
|
+
cloudflare_secret_store_id: cf?.secretStoreId ?? "",
|
|
415
|
+
subdomain_prefix: cf?.subdomain ?? ""
|
|
416
|
+
},
|
|
417
|
+
workers
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
getProvisioningPlan() {
|
|
421
|
+
const plan = {
|
|
422
|
+
d1Databases: [],
|
|
423
|
+
kvNamespaces: [],
|
|
424
|
+
r2Buckets: [],
|
|
425
|
+
queues: []
|
|
426
|
+
};
|
|
427
|
+
const allWorkers = [
|
|
428
|
+
...Object.keys(BASE_WORKERS),
|
|
429
|
+
...this.state.selectedWorkers,
|
|
430
|
+
...this.state.selectedIntegrations.map((k) => {
|
|
431
|
+
const i = INTEGRATIONS.find((i2) => i2.key === k);
|
|
432
|
+
return i?.workerName ?? "";
|
|
433
|
+
}).filter(Boolean)
|
|
434
|
+
];
|
|
435
|
+
const workerSet = new Set(allWorkers);
|
|
436
|
+
if (workerSet.has("d1-worker")) {
|
|
437
|
+
plan.d1Databases.push("hoox-db");
|
|
438
|
+
}
|
|
439
|
+
if (workerSet.has("hoox") || workerSet.has("analytics-worker")) {
|
|
440
|
+
plan.kvNamespaces.push("CONFIG_KV");
|
|
441
|
+
}
|
|
442
|
+
if (workerSet.has("web3-wallet-worker")) {
|
|
443
|
+
plan.kvNamespaces.push("WEB3_CACHE_KV");
|
|
444
|
+
}
|
|
445
|
+
plan.d1Databases = [...new Set(plan.d1Databases)];
|
|
446
|
+
plan.kvNamespaces = [...new Set(plan.kvNamespaces)];
|
|
447
|
+
return plan;
|
|
448
|
+
}
|
|
449
|
+
applyInput(input) {
|
|
450
|
+
const step = this.state.step;
|
|
451
|
+
switch (step) {
|
|
452
|
+
case "PREREQUISITES":
|
|
453
|
+
break;
|
|
454
|
+
case "CLOUDFLARE_CONFIG":
|
|
455
|
+
this.state.cloudflareConfig = {
|
|
456
|
+
apiToken: String(input.apiToken ?? ""),
|
|
457
|
+
accountId: String(input.accountId ?? ""),
|
|
458
|
+
secretStoreId: String(input.secretStoreId ?? ""),
|
|
459
|
+
subdomain: String(input.subdomain ?? "cryptolinx")
|
|
460
|
+
};
|
|
461
|
+
break;
|
|
462
|
+
case "WORKER_SELECTION": {
|
|
463
|
+
const preset = input.preset;
|
|
464
|
+
this.state.preset = preset;
|
|
465
|
+
if (preset && preset !== "custom") {
|
|
466
|
+
const presetDef = PRESETS.find((p) => p.name === preset);
|
|
467
|
+
if (presetDef) {
|
|
468
|
+
const resolved = resolveDependencies(presetDef.workers);
|
|
469
|
+
this.state.selectedWorkers = resolved;
|
|
470
|
+
this.state.selectedIntegrations = presetDef.integrations;
|
|
471
|
+
}
|
|
472
|
+
} else {
|
|
473
|
+
const workers = input.workers;
|
|
474
|
+
const integrations = input.integrations;
|
|
475
|
+
if (workers) {
|
|
476
|
+
this.state.selectedWorkers = resolveDependencies(workers);
|
|
477
|
+
}
|
|
478
|
+
if (integrations) {
|
|
479
|
+
this.state.selectedIntegrations = integrations;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
break;
|
|
483
|
+
}
|
|
484
|
+
case "SECRETS":
|
|
485
|
+
this.state.secrets = input.secrets ?? {};
|
|
486
|
+
break;
|
|
487
|
+
case "PROVISIONING":
|
|
488
|
+
if (input.provisioningResults) {
|
|
489
|
+
this.state.provisioningResults = input.provisioningResults;
|
|
490
|
+
}
|
|
491
|
+
break;
|
|
492
|
+
case "CONFIG_WRITE":
|
|
493
|
+
case "DEPLOY":
|
|
494
|
+
case "DONE":
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
// src/wizard/persistence.ts
|
|
500
|
+
function serializeState(state) {
|
|
501
|
+
return JSON.stringify(state, null, 2);
|
|
502
|
+
}
|
|
503
|
+
function deserializeState(json) {
|
|
504
|
+
const parsed = JSON.parse(json);
|
|
505
|
+
return parsed;
|
|
506
|
+
}
|
|
507
|
+
var WIZARD_STATE_PATH = ".wizard-state.json";
|
|
508
|
+
export {
|
|
509
|
+
serializeState,
|
|
510
|
+
resolveDependencies,
|
|
511
|
+
deserializeState,
|
|
512
|
+
WizardEngine,
|
|
513
|
+
WORKER_DEPENDENCIES,
|
|
514
|
+
WIZARD_STATE_PATH,
|
|
515
|
+
PRESETS,
|
|
516
|
+
INTEGRATIONS,
|
|
517
|
+
BASE_WORKERS,
|
|
518
|
+
BASE_SECRETS
|
|
519
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { WizardState } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Serialize wizard state to JSON string.
|
|
4
|
+
*/
|
|
5
|
+
export declare function serializeState(state: WizardState): string;
|
|
6
|
+
/**
|
|
7
|
+
* Deserialize wizard state from JSON string.
|
|
8
|
+
*/
|
|
9
|
+
export declare function deserializeState(json: string): WizardState;
|
|
10
|
+
/**
|
|
11
|
+
* Path for wizard state file (relative to project root).
|
|
12
|
+
*/
|
|
13
|
+
export declare const WIZARD_STATE_PATH = ".wizard-state.json";
|
|
14
|
+
//# sourceMappingURL=persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/wizard/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAG1D;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker presets, dependency resolution, and integration definitions.
|
|
3
|
+
*
|
|
4
|
+
* Migrated from packages/cli/src/commands/init/types.ts
|
|
5
|
+
* Secret names updated to match the canonical Worker Manifest Schema
|
|
6
|
+
* (see packages/shared/src/schemas/registry.ts).
|
|
7
|
+
* Pure data — no runtime dependencies, Worker-compatible.
|
|
8
|
+
*/
|
|
9
|
+
import type { WorkerPreset, IntegratedService } from "./types";
|
|
10
|
+
export declare const PRESETS: WorkerPreset[];
|
|
11
|
+
/**
|
|
12
|
+
* Worker dependency graph.
|
|
13
|
+
* Key requires all values in its array.
|
|
14
|
+
*/
|
|
15
|
+
export declare const WORKER_DEPENDENCIES: Record<string, string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve transitive worker dependencies.
|
|
18
|
+
* Returns a deduplicated array of all workers including dependencies.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveDependencies(selected: string[]): string[];
|
|
21
|
+
/**
|
|
22
|
+
* All supported integrations.
|
|
23
|
+
*/
|
|
24
|
+
export declare const INTEGRATIONS: IntegratedService[];
|
|
25
|
+
export declare const BASE_WORKERS: Record<string, {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
path: string;
|
|
28
|
+
vars: Record<string, string>;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Base secrets for base workers (not integration-driven).
|
|
32
|
+
*/
|
|
33
|
+
export declare const BASE_SECRETS: Record<string, string[]>;
|
|
34
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/wizard/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAI/D,eAAO,MAAM,OAAO,EAAE,YAAY,EAqCjC,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAMxD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAkBhE;AAID;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iBAAiB,EAyF3C,CAAC;AAIF,eAAO,MAAM,YAAY,EAAE,MAAM,CAC/B,MAAM,EACN;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAcjE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAIjD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProvisioningPlan, ProvisionResult } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Interface for Cloudflare infrastructure provisioning.
|
|
4
|
+
* CLI implements via wrangler CLI (Bun.spawn).
|
|
5
|
+
* TUI implements via CliBridge (calls hoox infra provision).
|
|
6
|
+
*/
|
|
7
|
+
export interface Provisioner {
|
|
8
|
+
provision(plan: ProvisioningPlan): Promise<ProvisionResult>;
|
|
9
|
+
check(plan: ProvisioningPlan): Promise<ProvisionResult>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=provisioner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../src/wizard/provisioner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACzD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the Setup Wizard Engine.
|
|
3
|
+
* Pure types — no runtime dependencies, Worker-compatible.
|
|
4
|
+
*/
|
|
5
|
+
export type StepId = "PREREQUISITES" | "CLOUDFLARE_CONFIG" | "WORKER_SELECTION" | "PROVISIONING" | "SECRETS" | "CONFIG_WRITE" | "DEPLOY" | "DONE";
|
|
6
|
+
export type WorkerPresetName = "minimal" | "standard" | "full" | "custom";
|
|
7
|
+
export interface WorkerPreset {
|
|
8
|
+
name: WorkerPresetName;
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
workers: string[];
|
|
12
|
+
integrations: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface IntegratedService {
|
|
15
|
+
key: string;
|
|
16
|
+
label: string;
|
|
17
|
+
workerName: string;
|
|
18
|
+
secrets: Record<string, string>;
|
|
19
|
+
vars?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
export interface WorkerConfig {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
path: string;
|
|
24
|
+
vars: Record<string, string>;
|
|
25
|
+
secrets: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface WorkersJsonConfig {
|
|
28
|
+
global: {
|
|
29
|
+
cloudflare_api_token: string;
|
|
30
|
+
cloudflare_account_id: string;
|
|
31
|
+
cloudflare_secret_store_id: string;
|
|
32
|
+
subdomain_prefix: string;
|
|
33
|
+
};
|
|
34
|
+
workers: Record<string, WorkerConfig>;
|
|
35
|
+
}
|
|
36
|
+
export interface ProvisioningPlan {
|
|
37
|
+
d1Databases: string[];
|
|
38
|
+
kvNamespaces: string[];
|
|
39
|
+
r2Buckets: string[];
|
|
40
|
+
queues: string[];
|
|
41
|
+
}
|
|
42
|
+
export interface ProvisionResult {
|
|
43
|
+
success: boolean;
|
|
44
|
+
created: string[];
|
|
45
|
+
errors: string[];
|
|
46
|
+
}
|
|
47
|
+
export interface WizardCloudflareConfig {
|
|
48
|
+
apiToken: string;
|
|
49
|
+
accountId: string;
|
|
50
|
+
secretStoreId: string;
|
|
51
|
+
subdomain: string;
|
|
52
|
+
}
|
|
53
|
+
export interface WizardState {
|
|
54
|
+
step: StepId;
|
|
55
|
+
completedSteps: StepId[];
|
|
56
|
+
cloudflareConfig?: WizardCloudflareConfig;
|
|
57
|
+
selectedWorkers: string[];
|
|
58
|
+
selectedIntegrations: string[];
|
|
59
|
+
secrets: Record<string, Record<string, string>>;
|
|
60
|
+
preset?: WorkerPresetName;
|
|
61
|
+
provisioningResults?: ProvisionResult;
|
|
62
|
+
startedAt: number;
|
|
63
|
+
updatedAt: number;
|
|
64
|
+
}
|
|
65
|
+
export interface StepDefinition {
|
|
66
|
+
id: StepId;
|
|
67
|
+
label: string;
|
|
68
|
+
canGoBack: boolean;
|
|
69
|
+
optional: boolean;
|
|
70
|
+
validate(state: WizardState, input: Record<string, unknown>): string[];
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/wizard/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,MAAM,GACd,eAAe,GACf,mBAAmB,GACnB,kBAAkB,GAClB,cAAc,GACd,SAAS,GACT,cAAc,GACd,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,oBAAoB,EAAE,MAAM,CAAC;QAC7B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,0BAA0B,EAAE,MAAM,CAAC;QACnC,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,mBAAmB,CAAC,EAAE,eAAe,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;CACxE"}
|