@hoox-sh/hoox-shared 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/agent-config-fields.d.ts +32 -0
- package/dist/agent-config-fields.d.ts.map +1 -0
- package/dist/agent-config-fields.js +220 -0
- package/dist/analytics.d.ts +47 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +45 -0
- package/dist/api-client.d.ts +48 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +191 -0
- package/dist/colors.d.ts +76 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +82 -0
- package/dist/config.d.ts +61 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +146 -0
- package/dist/cron-handler.d.ts +38 -0
- package/dist/cron-handler.d.ts.map +1 -0
- package/dist/cron-handler.js +48 -0
- package/dist/d1/index.d.ts +9 -0
- package/dist/d1/index.d.ts.map +1 -0
- package/dist/d1/index.js +360 -0
- package/dist/d1/repository.d.ts +86 -0
- package/dist/d1/repository.d.ts.map +1 -0
- package/dist/d1/repository.js +297 -0
- package/dist/d1/schemas.d.ts +89 -0
- package/dist/d1/schemas.d.ts.map +1 -0
- package/dist/d1/schemas.js +81 -0
- package/dist/dashboard-manifest.d.ts +135 -0
- package/dist/dashboard-manifest.d.ts.map +1 -0
- package/dist/dashboard-manifest.js +401 -0
- package/dist/errors.d.ts +44 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +149 -0
- package/dist/exchange-client.d.ts +98 -0
- package/dist/exchange-client.d.ts.map +1 -0
- package/dist/exchange-client.js +107 -0
- package/dist/exchanges/base-exchange-client.d.ts +81 -0
- package/dist/exchanges/base-exchange-client.d.ts.map +1 -0
- package/dist/exchanges/base-exchange-client.js +123 -0
- package/dist/exchanges/index.d.ts +7 -0
- package/dist/exchanges/index.d.ts.map +1 -0
- package/dist/exchanges/index.js +123 -0
- package/dist/exchanges/types.d.ts +23 -0
- package/dist/exchanges/types.d.ts.map +1 -0
- package/dist/exchanges/types.js +1 -0
- package/dist/format-time.d.ts +28 -0
- package/dist/format-time.d.ts.map +1 -0
- package/dist/format-time.js +57 -0
- package/dist/formatters.d.ts +36 -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 +160 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4198 -0
- package/dist/kvKeys.d.ts +76 -0
- package/dist/kvKeys.d.ts.map +1 -0
- package/dist/kvKeys.js +107 -0
- package/dist/kvUtils.d.ts +30 -0
- package/dist/kvUtils.d.ts.map +1 -0
- package/dist/kvUtils.js +170 -0
- package/dist/legal.d.ts +15 -0
- package/dist/legal.d.ts.map +1 -0
- package/dist/legal.js +40 -0
- package/dist/middleware/auth.d.ts +102 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +151 -0
- package/dist/middleware/cors.d.ts +58 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +77 -0
- package/dist/middleware/index.d.ts +14 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +635 -0
- package/dist/middleware/logger.d.ts +17 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +202 -0
- package/dist/middleware/rate-limit.d.ts +30 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +181 -0
- package/dist/middleware/security-headers.d.ts +43 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +58 -0
- package/dist/middleware/validate.d.ts +25 -0
- package/dist/middleware/validate.d.ts.map +1 -0
- package/dist/middleware/validate.js +56 -0
- package/dist/operator-transport.d.ts +65 -0
- package/dist/operator-transport.d.ts.map +1 -0
- package/dist/operator-transport.js +87 -0
- package/dist/path-utils.d.ts +190 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/path-utils.js +188 -0
- package/dist/queue-handler.d.ts +47 -0
- package/dist/queue-handler.d.ts.map +1 -0
- package/dist/queue-handler.js +46 -0
- package/dist/router.d.ts +15 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +130 -0
- package/dist/schemas/index.d.ts +8 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +705 -0
- package/dist/schemas/registry.d.ts +12 -0
- package/dist/schemas/registry.d.ts.map +1 -0
- package/dist/schemas/registry.js +433 -0
- package/dist/schemas/types.d.ts +83 -0
- package/dist/schemas/types.d.ts.map +1 -0
- package/dist/schemas/types.js +1 -0
- package/dist/schemas/validators.d.ts +39 -0
- package/dist/schemas/validators.d.ts.map +1 -0
- package/dist/schemas/validators.js +290 -0
- package/dist/service-bindings.d.ts +78 -0
- package/dist/service-bindings.d.ts.map +1 -0
- package/dist/service-bindings.js +248 -0
- package/dist/session.d.ts +39 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +261 -0
- package/dist/sse.d.ts +39 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +154 -0
- package/dist/stores/config-store.d.ts +91 -0
- package/dist/stores/config-store.d.ts.map +1 -0
- package/dist/stores/config-store.js +255 -0
- package/dist/stores/service-store.d.ts +266 -0
- package/dist/stores/service-store.d.ts.map +1 -0
- package/dist/stores/service-store.js +516 -0
- package/dist/stores/ui-store.d.ts +67 -0
- package/dist/stores/ui-store.d.ts.map +1 -0
- package/dist/stores/ui-store.js +62 -0
- package/dist/test-utils.d.ts +136 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +128 -0
- package/dist/types/errors.d.ts +20 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +1 -0
- package/dist/types/router.d.ts +36 -0
- package/dist/types/router.d.ts.map +1 -0
- package/dist/types/router.js +1 -0
- package/dist/types.d.ts +442 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +83 -0
- package/dist/wizard/engine.d.ts +46 -0
- package/dist/wizard/engine.d.ts.map +1 -0
- package/dist/wizard/engine.js +525 -0
- package/dist/wizard/index.d.ts +11 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +544 -0
- package/dist/wizard/persistence.d.ts +18 -0
- package/dist/wizard/persistence.d.ts.map +1 -0
- package/dist/wizard/persistence.js +31 -0
- package/dist/wizard/presets.d.ts +38 -0
- package/dist/wizard/presets.d.ts.map +1 -0
- package/dist/wizard/presets.js +223 -0
- package/dist/wizard/provisioner.d.ts +15 -0
- package/dist/wizard/provisioner.d.ts.map +1 -0
- package/dist/wizard/provisioner.js +1 -0
- package/dist/wizard/types.d.ts +76 -0
- package/dist/wizard/types.d.ts.map +1 -0
- package/dist/wizard/types.js +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1,297 @@
|
|
|
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/errors.ts
|
|
19
|
+
function toError(err, fallback = "Unknown error") {
|
|
20
|
+
if (err instanceof Error)
|
|
21
|
+
return err.message;
|
|
22
|
+
if (typeof err === "string")
|
|
23
|
+
return err;
|
|
24
|
+
if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
|
|
25
|
+
return err.message;
|
|
26
|
+
}
|
|
27
|
+
if (err === null || err === undefined)
|
|
28
|
+
return fallback;
|
|
29
|
+
try {
|
|
30
|
+
return JSON.stringify(err) || fallback;
|
|
31
|
+
} catch {
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
var SENSITIVE_FIELDS = new Set([
|
|
36
|
+
"password",
|
|
37
|
+
"token",
|
|
38
|
+
"secret",
|
|
39
|
+
"api_key",
|
|
40
|
+
"apiKey",
|
|
41
|
+
"authorization"
|
|
42
|
+
]);
|
|
43
|
+
function hasSensitiveFields(obj) {
|
|
44
|
+
for (const key of Object.keys(obj)) {
|
|
45
|
+
if (SENSITIVE_FIELDS.has(key))
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
function hasErrorValues(obj) {
|
|
51
|
+
for (const v of Object.values(obj)) {
|
|
52
|
+
if (v instanceof Error)
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
function sanitizeOutput(data) {
|
|
58
|
+
if (data === null || data === undefined)
|
|
59
|
+
return data;
|
|
60
|
+
const t = typeof data;
|
|
61
|
+
if (t === "string" || t === "number" || t === "boolean")
|
|
62
|
+
return data;
|
|
63
|
+
if (data instanceof Error) {
|
|
64
|
+
return { name: data.name, message: data.message };
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(data)) {
|
|
67
|
+
return data.map(sanitizeOutput);
|
|
68
|
+
}
|
|
69
|
+
if (t === "object") {
|
|
70
|
+
const obj = data;
|
|
71
|
+
const keys = Object.keys(obj);
|
|
72
|
+
if (keys.length < 10) {
|
|
73
|
+
const sanitized2 = {};
|
|
74
|
+
for (const k of keys) {
|
|
75
|
+
if (k === "stack" || k === "cause")
|
|
76
|
+
continue;
|
|
77
|
+
const v = obj[k];
|
|
78
|
+
sanitized2[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
|
|
79
|
+
}
|
|
80
|
+
return sanitized2;
|
|
81
|
+
}
|
|
82
|
+
if (!hasSensitiveFields(obj) && !hasErrorValues(obj)) {
|
|
83
|
+
return obj;
|
|
84
|
+
}
|
|
85
|
+
const sanitized = {};
|
|
86
|
+
for (const k of keys) {
|
|
87
|
+
if (k === "stack" || k === "cause")
|
|
88
|
+
continue;
|
|
89
|
+
const v = obj[k];
|
|
90
|
+
sanitized[k] = v instanceof Error ? { name: v.name, message: v.message } : sanitizeOutput(v);
|
|
91
|
+
}
|
|
92
|
+
return sanitized;
|
|
93
|
+
}
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
function createJsonResponse(data, status = 200) {
|
|
97
|
+
return new Response(JSON.stringify(sanitizeOutput(data)), {
|
|
98
|
+
status,
|
|
99
|
+
headers: { "Content-Type": "application/json" }
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function createSuccessResponse(result) {
|
|
103
|
+
return createJsonResponse({ success: true, result }, 200);
|
|
104
|
+
}
|
|
105
|
+
function createErrorResponse(error, status) {
|
|
106
|
+
const message = typeof error === "string" ? error : error.message;
|
|
107
|
+
const statusCode = typeof error === "string" ? status ?? 500 : error.status ?? 500;
|
|
108
|
+
const body = { success: false, error: message };
|
|
109
|
+
if (typeof error !== "string" && error.code)
|
|
110
|
+
body.code = error.code;
|
|
111
|
+
if (typeof error !== "string" && error.details !== undefined)
|
|
112
|
+
body.details = error.details;
|
|
113
|
+
return new Response(JSON.stringify(body), {
|
|
114
|
+
status: statusCode,
|
|
115
|
+
headers: { "Content-Type": "application/json" }
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
var Errors = {
|
|
119
|
+
badRequest: (message) => createErrorResponse({ message, status: 400, code: "BAD_REQUEST" }),
|
|
120
|
+
unauthorized: (message = "Unauthorized") => createErrorResponse({ message, status: 401, code: "UNAUTHORIZED" }),
|
|
121
|
+
forbidden: (message = "Forbidden") => createErrorResponse({ message, status: 403, code: "FORBIDDEN" }),
|
|
122
|
+
notFound: (message = "Not found") => createErrorResponse({ message, status: 404, code: "NOT_FOUND" }),
|
|
123
|
+
methodNotAllowed: (message = "Method not allowed") => createErrorResponse({ message, status: 405, code: "METHOD_NOT_ALLOWED" }),
|
|
124
|
+
rateLimited: (retryAfter) => {
|
|
125
|
+
const res = createErrorResponse({
|
|
126
|
+
message: "Rate limit exceeded",
|
|
127
|
+
status: 429,
|
|
128
|
+
code: "RATE_LIMITED"
|
|
129
|
+
});
|
|
130
|
+
if (retryAfter)
|
|
131
|
+
res.headers.set("Retry-After", String(retryAfter));
|
|
132
|
+
return res;
|
|
133
|
+
},
|
|
134
|
+
internal: (err) => {
|
|
135
|
+
const message = err ? toError(err, "Internal server error") : "Internal server error";
|
|
136
|
+
return createErrorResponse({
|
|
137
|
+
message,
|
|
138
|
+
status: 500,
|
|
139
|
+
code: "INTERNAL_ERROR"
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/d1/repository.ts
|
|
145
|
+
class D1Repository {
|
|
146
|
+
db;
|
|
147
|
+
constructor(db) {
|
|
148
|
+
this.db = db;
|
|
149
|
+
}
|
|
150
|
+
async query(sql, params = []) {
|
|
151
|
+
try {
|
|
152
|
+
const stmt = this.db.prepare(sql).bind(...params);
|
|
153
|
+
const result = await stmt.all();
|
|
154
|
+
return {
|
|
155
|
+
success: result.success,
|
|
156
|
+
results: result.results,
|
|
157
|
+
error: result.error
|
|
158
|
+
};
|
|
159
|
+
} catch (error) {
|
|
160
|
+
return {
|
|
161
|
+
success: false,
|
|
162
|
+
error: toError(error)
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async execute(sql, params = []) {
|
|
167
|
+
try {
|
|
168
|
+
const stmt = this.db.prepare(sql).bind(...params);
|
|
169
|
+
const result = await stmt.run();
|
|
170
|
+
return {
|
|
171
|
+
success: result.success,
|
|
172
|
+
meta: {
|
|
173
|
+
last_row_id: result.meta?.last_row_id,
|
|
174
|
+
changes: result.meta?.changes,
|
|
175
|
+
duration: result.meta?.duration
|
|
176
|
+
},
|
|
177
|
+
error: result.error
|
|
178
|
+
};
|
|
179
|
+
} catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
error: toError(error)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async batch(statements) {
|
|
187
|
+
try {
|
|
188
|
+
const prepared = statements.map((s) => s.params && s.params.length > 0 ? this.db.prepare(s.query).bind(...s.params) : this.db.prepare(s.query));
|
|
189
|
+
const results = await this.db.batch(prepared);
|
|
190
|
+
return results.map((r) => ({
|
|
191
|
+
success: r.success,
|
|
192
|
+
meta: r.meta ? { last_row_id: r.meta.last_row_id, changes: r.meta.changes } : undefined,
|
|
193
|
+
error: r.error
|
|
194
|
+
}));
|
|
195
|
+
} catch (error) {
|
|
196
|
+
return statements.map(() => ({
|
|
197
|
+
success: false,
|
|
198
|
+
error: toError(error)
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
prepare(sql) {
|
|
203
|
+
return this.db.prepare(sql);
|
|
204
|
+
}
|
|
205
|
+
async getTrades(limit = 50, offset = 0) {
|
|
206
|
+
return this.query("SELECT * FROM trades ORDER BY timestamp DESC LIMIT ? OFFSET ?", [limit, offset]);
|
|
207
|
+
}
|
|
208
|
+
async insertTrade(trade) {
|
|
209
|
+
return this.execute(`INSERT INTO trades (id, timestamp, exchange, symbol, action, quantity, price, leverage, status, raw_response)
|
|
210
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
211
|
+
trade.id || crypto.randomUUID(),
|
|
212
|
+
trade.timestamp,
|
|
213
|
+
trade.exchange,
|
|
214
|
+
trade.symbol,
|
|
215
|
+
trade.action,
|
|
216
|
+
trade.quantity ?? null,
|
|
217
|
+
trade.price ?? null,
|
|
218
|
+
trade.leverage ?? null,
|
|
219
|
+
trade.status,
|
|
220
|
+
trade.raw_response ?? null
|
|
221
|
+
]);
|
|
222
|
+
}
|
|
223
|
+
async getPositions(status) {
|
|
224
|
+
if (status) {
|
|
225
|
+
return this.query("SELECT * FROM positions WHERE status = ? ORDER BY updated_at DESC", [status]);
|
|
226
|
+
}
|
|
227
|
+
return this.query("SELECT * FROM positions ORDER BY updated_at DESC");
|
|
228
|
+
}
|
|
229
|
+
async upsertPosition(position) {
|
|
230
|
+
return this.execute(`REPLACE INTO positions (id, exchange, symbol, side, entry_price, mark_price, liquidation_price, leverage, size, unrealized_pnl, status, updated_at)
|
|
231
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
232
|
+
position.id,
|
|
233
|
+
position.exchange,
|
|
234
|
+
position.symbol,
|
|
235
|
+
position.side,
|
|
236
|
+
position.entry_price ?? null,
|
|
237
|
+
position.mark_price ?? null,
|
|
238
|
+
position.liquidation_price ?? null,
|
|
239
|
+
position.leverage ?? null,
|
|
240
|
+
position.size,
|
|
241
|
+
position.unrealized_pnl ?? null,
|
|
242
|
+
position.status,
|
|
243
|
+
position.updated_at
|
|
244
|
+
]);
|
|
245
|
+
}
|
|
246
|
+
async getTradeSignals(limit = 10) {
|
|
247
|
+
return this.query(`SELECT signal_id, timestamp, symbol, signal_type, source, processed_at
|
|
248
|
+
FROM trade_signals
|
|
249
|
+
ORDER BY processed_at DESC
|
|
250
|
+
LIMIT ?`, [limit]);
|
|
251
|
+
}
|
|
252
|
+
async insertTradeSignal(signal) {
|
|
253
|
+
return this.execute(`INSERT INTO trade_signals (signal_id, timestamp, symbol, signal_type, source, raw_data)
|
|
254
|
+
VALUES (?, ?, ?, ?, ?, ?)`, [
|
|
255
|
+
signal.signal_id,
|
|
256
|
+
signal.timestamp,
|
|
257
|
+
signal.symbol,
|
|
258
|
+
signal.signal_type,
|
|
259
|
+
signal.source ?? null,
|
|
260
|
+
signal.raw_data ?? null
|
|
261
|
+
]);
|
|
262
|
+
}
|
|
263
|
+
async getSystemLogs(limit = 50) {
|
|
264
|
+
return this.query("SELECT * FROM system_logs ORDER BY timestamp DESC LIMIT ?", [limit]);
|
|
265
|
+
}
|
|
266
|
+
async insertSystemLog(log) {
|
|
267
|
+
return this.execute(`INSERT INTO system_logs (id, level, service, message, details) VALUES (?, ?, ?, ?, ?)`, [
|
|
268
|
+
log.id || crypto.randomUUID(),
|
|
269
|
+
log.level,
|
|
270
|
+
log.service,
|
|
271
|
+
log.message,
|
|
272
|
+
log.details ?? null
|
|
273
|
+
]);
|
|
274
|
+
}
|
|
275
|
+
async getLatestBalances() {
|
|
276
|
+
return this.query(`
|
|
277
|
+
SELECT b.id, b.exchange, b.asset, b.total, b.free, b.used, b.timestamp
|
|
278
|
+
FROM balances b
|
|
279
|
+
INNER JOIN (
|
|
280
|
+
SELECT exchange, asset, MAX(timestamp) as max_time
|
|
281
|
+
FROM balances
|
|
282
|
+
GROUP BY exchange, asset
|
|
283
|
+
) latest ON b.exchange = latest.exchange AND b.asset = latest.asset AND b.timestamp = latest.max_time
|
|
284
|
+
`);
|
|
285
|
+
}
|
|
286
|
+
async healthCheck() {
|
|
287
|
+
try {
|
|
288
|
+
await this.db.prepare("SELECT 1").first();
|
|
289
|
+
return true;
|
|
290
|
+
} catch {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
export {
|
|
296
|
+
D1Repository
|
|
297
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* TypeScript interfaces for D1 database tables
|
|
7
|
+
* Based on the schema defined in workers/trade-worker/schema.sql
|
|
8
|
+
*/
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
export declare const TradeRecordSchema: z.ZodObject<{
|
|
11
|
+
id: z.ZodString;
|
|
12
|
+
signal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
13
|
+
timestamp: z.ZodNumber;
|
|
14
|
+
exchange: z.ZodString;
|
|
15
|
+
symbol: z.ZodString;
|
|
16
|
+
action: z.ZodString;
|
|
17
|
+
quantity: z.ZodNullable<z.ZodNumber>;
|
|
18
|
+
price: z.ZodNullable<z.ZodNumber>;
|
|
19
|
+
leverage: z.ZodNullable<z.ZodNumber>;
|
|
20
|
+
status: z.ZodString;
|
|
21
|
+
error_message: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
22
|
+
raw_response: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
23
|
+
created_at: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
export declare const PositionRecordSchema: z.ZodObject<{
|
|
26
|
+
id: z.ZodString;
|
|
27
|
+
exchange: z.ZodString;
|
|
28
|
+
symbol: z.ZodString;
|
|
29
|
+
side: z.ZodEnum<{
|
|
30
|
+
LONG: "LONG";
|
|
31
|
+
SHORT: "SHORT";
|
|
32
|
+
}>;
|
|
33
|
+
entry_price: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
34
|
+
mark_price: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
35
|
+
liquidation_price: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
36
|
+
leverage: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
37
|
+
size: z.ZodNullable<z.ZodNumber>;
|
|
38
|
+
unrealized_pnl: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
39
|
+
status: z.ZodEnum<{
|
|
40
|
+
OPEN: "OPEN";
|
|
41
|
+
CLOSED: "CLOSED";
|
|
42
|
+
}>;
|
|
43
|
+
updated_at: z.ZodNumber;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export declare const BalanceRecordSchema: z.ZodObject<{
|
|
46
|
+
id: z.ZodString;
|
|
47
|
+
exchange: z.ZodString;
|
|
48
|
+
asset: z.ZodString;
|
|
49
|
+
free: z.ZodNullable<z.ZodNumber>;
|
|
50
|
+
used: z.ZodNullable<z.ZodNumber>;
|
|
51
|
+
total: z.ZodNullable<z.ZodNumber>;
|
|
52
|
+
timestamp: z.ZodNumber;
|
|
53
|
+
}, z.core.$strict>;
|
|
54
|
+
export declare const SystemLogRecordSchema: z.ZodObject<{
|
|
55
|
+
id: z.ZodString;
|
|
56
|
+
timestamp: z.ZodOptional<z.ZodNumber>;
|
|
57
|
+
level: z.ZodString;
|
|
58
|
+
service: z.ZodString;
|
|
59
|
+
message: z.ZodString;
|
|
60
|
+
details: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
61
|
+
}, z.core.$strict>;
|
|
62
|
+
export declare const TradeSignalRecordSchema: z.ZodObject<{
|
|
63
|
+
signal_id: z.ZodString;
|
|
64
|
+
timestamp: z.ZodNumber;
|
|
65
|
+
symbol: z.ZodString;
|
|
66
|
+
signal_type: z.ZodString;
|
|
67
|
+
source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
68
|
+
raw_data: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
69
|
+
processed_at: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
}, z.core.$strict>;
|
|
71
|
+
export type TradeRecord = z.infer<typeof TradeRecordSchema>;
|
|
72
|
+
export type PositionRecord = z.infer<typeof PositionRecordSchema>;
|
|
73
|
+
export type BalanceRecord = z.infer<typeof BalanceRecordSchema>;
|
|
74
|
+
export type SystemLogRecord = z.infer<typeof SystemLogRecordSchema>;
|
|
75
|
+
export type TradeSignalRecord = z.infer<typeof TradeSignalRecordSchema>;
|
|
76
|
+
/**
|
|
77
|
+
* Generic D1 query result wrapper
|
|
78
|
+
*/
|
|
79
|
+
export interface D1QueryResult<T = unknown> {
|
|
80
|
+
success: boolean;
|
|
81
|
+
results?: T[];
|
|
82
|
+
error?: string;
|
|
83
|
+
meta?: {
|
|
84
|
+
last_row_id?: number;
|
|
85
|
+
changes?: number;
|
|
86
|
+
duration?: number;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/d1/schemas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;kBAgBnB,CAAC;AAEZ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;kBAetB,CAAC;AAEZ,eAAO,MAAM,mBAAmB;;;;;;;;kBAUrB,CAAC;AAEZ,eAAO,MAAM,qBAAqB;;;;;;;kBASvB,CAAC;AAEZ,eAAO,MAAM,uBAAuB;;;;;;;;kBAUzB,CAAC;AAIZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH"}
|
|
@@ -0,0 +1,81 @@
|
|
|
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/d1/schemas.ts
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
var TradeRecordSchema = z.object({
|
|
21
|
+
id: z.string(),
|
|
22
|
+
signal_id: z.string().nullable().optional(),
|
|
23
|
+
timestamp: z.number().int().positive(),
|
|
24
|
+
exchange: z.string().min(1),
|
|
25
|
+
symbol: z.string().min(1),
|
|
26
|
+
action: z.string().min(1),
|
|
27
|
+
quantity: z.number().nullable(),
|
|
28
|
+
price: z.number().nullable(),
|
|
29
|
+
leverage: z.number().nullable(),
|
|
30
|
+
status: z.string().min(1),
|
|
31
|
+
error_message: z.string().nullable().optional(),
|
|
32
|
+
raw_response: z.string().nullable().optional(),
|
|
33
|
+
created_at: z.number().int().optional()
|
|
34
|
+
}).strict();
|
|
35
|
+
var PositionRecordSchema = z.object({
|
|
36
|
+
id: z.string(),
|
|
37
|
+
exchange: z.string().min(1),
|
|
38
|
+
symbol: z.string().min(1),
|
|
39
|
+
side: z.enum(["LONG", "SHORT"]),
|
|
40
|
+
entry_price: z.number().nullable().optional(),
|
|
41
|
+
mark_price: z.number().nullable().optional(),
|
|
42
|
+
liquidation_price: z.number().nullable().optional(),
|
|
43
|
+
leverage: z.number().nullable().optional(),
|
|
44
|
+
size: z.number().nullable(),
|
|
45
|
+
unrealized_pnl: z.number().nullable().optional(),
|
|
46
|
+
status: z.enum(["OPEN", "CLOSED"]),
|
|
47
|
+
updated_at: z.number().int()
|
|
48
|
+
}).strict();
|
|
49
|
+
var BalanceRecordSchema = z.object({
|
|
50
|
+
id: z.string(),
|
|
51
|
+
exchange: z.string().min(1),
|
|
52
|
+
asset: z.string().min(1),
|
|
53
|
+
free: z.number().nullable(),
|
|
54
|
+
used: z.number().nullable(),
|
|
55
|
+
total: z.number().nullable(),
|
|
56
|
+
timestamp: z.number().int().positive()
|
|
57
|
+
}).strict();
|
|
58
|
+
var SystemLogRecordSchema = z.object({
|
|
59
|
+
id: z.string(),
|
|
60
|
+
timestamp: z.number().int().optional(),
|
|
61
|
+
level: z.string().min(1),
|
|
62
|
+
service: z.string().min(1),
|
|
63
|
+
message: z.string().min(1),
|
|
64
|
+
details: z.string().nullable().optional()
|
|
65
|
+
}).strict();
|
|
66
|
+
var TradeSignalRecordSchema = z.object({
|
|
67
|
+
signal_id: z.string(),
|
|
68
|
+
timestamp: z.number().int().positive(),
|
|
69
|
+
symbol: z.string().min(1),
|
|
70
|
+
signal_type: z.string().min(1),
|
|
71
|
+
source: z.string().nullable().optional(),
|
|
72
|
+
raw_data: z.string().nullable().optional(),
|
|
73
|
+
processed_at: z.number().int().optional()
|
|
74
|
+
}).strict();
|
|
75
|
+
export {
|
|
76
|
+
TradeSignalRecordSchema,
|
|
77
|
+
TradeRecordSchema,
|
|
78
|
+
SystemLogRecordSchema,
|
|
79
|
+
PositionRecordSchema,
|
|
80
|
+
BalanceRecordSchema
|
|
81
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
export type DashboardFieldType = "boolean" | "number" | "text" | "select" | "json" | "textarea";
|
|
6
|
+
export type DashboardFieldKind = "normal" | "dangerous" | "secret";
|
|
7
|
+
export interface DashboardFieldOption {
|
|
8
|
+
value: string;
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
export interface DashboardSettingField {
|
|
12
|
+
/** Composite key: `sectionId:fieldName` (matches web dashboard) */
|
|
13
|
+
key: string;
|
|
14
|
+
label: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
type: DashboardFieldType;
|
|
17
|
+
default: string | number | boolean;
|
|
18
|
+
options?: DashboardFieldOption[];
|
|
19
|
+
kind?: DashboardFieldKind;
|
|
20
|
+
cliCommand?: string;
|
|
21
|
+
/** Optional bounds/pattern (e.g. cron interval_minutes min 1 max 1440). */
|
|
22
|
+
validation?: {
|
|
23
|
+
min?: number;
|
|
24
|
+
max?: number;
|
|
25
|
+
pattern?: string;
|
|
26
|
+
required?: boolean;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface DashboardSection {
|
|
30
|
+
id: string;
|
|
31
|
+
title: string;
|
|
32
|
+
description: string;
|
|
33
|
+
icon?: string;
|
|
34
|
+
priority: number;
|
|
35
|
+
fields: DashboardSettingField[];
|
|
36
|
+
}
|
|
37
|
+
export interface WorkerDashboardManifest {
|
|
38
|
+
worker: string;
|
|
39
|
+
displayName: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
sections: DashboardSection[];
|
|
42
|
+
}
|
|
43
|
+
/** Worker name → default CONFIG_KV prefix (web dashboard prefixes.ts). */
|
|
44
|
+
export declare const DASHBOARD_WORKER_PREFIX: Record<string, string>;
|
|
45
|
+
/** Section id → CONFIG_KV prefix (must stay in sync with web SECTION_PREFIX_MAP). */
|
|
46
|
+
export declare const DASHBOARD_SECTION_PREFIX: Record<string, string>;
|
|
47
|
+
/**
|
|
48
|
+
* Composite field keys (`section:field`) → exact CONFIG_KV keys when the
|
|
49
|
+
* section prefix + field name would not match what workers read.
|
|
50
|
+
*
|
|
51
|
+
* Prefer fixing dashboard.jsonc field names when possible; use this for
|
|
52
|
+
* nested paths (e.g. webhook:tradingview:…) and exchange enable flags.
|
|
53
|
+
*/
|
|
54
|
+
export declare const DASHBOARD_FIELD_KV_OVERRIDES: Record<string, string>;
|
|
55
|
+
/**
|
|
56
|
+
* Section ids that must not appear as flat CONFIG_KV keys in apply-manifest.
|
|
57
|
+
*
|
|
58
|
+
* - providers/models: edited via `agent:config` (see agent-config-fields.ts)
|
|
59
|
+
* - cron: wrangler trigger schedule, not KV
|
|
60
|
+
* - behavior: not read as flat behavior:* keys by the agent worker
|
|
61
|
+
*/
|
|
62
|
+
export declare const DASHBOARD_SECTIONS_NOT_FLAT_KV: ReadonlySet<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Sections that are not editable as flat or agent:config fields
|
|
65
|
+
* (no worker consumer yet).
|
|
66
|
+
*/
|
|
67
|
+
export declare const DASHBOARD_SECTIONS_UI_SKIP: ReadonlySet<string>;
|
|
68
|
+
/** True when a section should map to flat CONFIG_KV get/set / apply-manifest. */
|
|
69
|
+
export declare function isDashboardSectionFlatKv(sectionId: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* True when the section can be shown/edited in TUI/web worker settings.
|
|
72
|
+
* Includes agent:config-backed sections (providers/models) and flat KV.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isDashboardSectionEditable(sectionId: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Build CONFIG_KV key from worker + composite field key (`section:field`).
|
|
77
|
+
* Aligns with workers/dashboard prefixes + worker-facing keys in kvKeys.ts.
|
|
78
|
+
*
|
|
79
|
+
* Unknown sections keep `section:field` (namespaced) so bare keys like
|
|
80
|
+
* `kill_switch` are not written by accident. Mapped sections (including
|
|
81
|
+
* risk → trade:, signal → email:) produce worker-readable keys.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildDashboardKvKey(worker: string, fieldKey: string): string;
|
|
84
|
+
/** Strip line and block comments plus trailing commas (JSONC). */
|
|
85
|
+
export declare function stripJsonc(input: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Parse dashboard.jsonc content into a worker settings manifest.
|
|
88
|
+
*
|
|
89
|
+
* On parse/schema failure returns an empty-sections stub and optionally
|
|
90
|
+
* reports via `onError` (CLI/TUI should log; silent empty used to hide
|
|
91
|
+
* broken manifests from discovery).
|
|
92
|
+
*/
|
|
93
|
+
export declare function parseDashboardManifest(content: string, workerName: string, onError?: (message: string) => void): WorkerDashboardManifest;
|
|
94
|
+
/** Canonical worker list used by the web settings form. */
|
|
95
|
+
export declare const DASHBOARD_WORKER_IDS: readonly ["hoox", "trade-worker", "agent-worker", "telegram-worker", "d1-worker", "email-worker", "web3-wallet-worker", "analytics-worker", "report-worker", "pyne-worker"];
|
|
96
|
+
export type DashboardWorkerId = (typeof DASHBOARD_WORKER_IDS)[number];
|
|
97
|
+
/**
|
|
98
|
+
* Map worker id used in dashboard.jsonc / UI to filesystem folder name.
|
|
99
|
+
* Gateway settings live under workers/hoox-worker/dashboard.jsonc.
|
|
100
|
+
*/
|
|
101
|
+
export declare function dashboardWorkerDir(workerId: string): string;
|
|
102
|
+
/** Flat CONFIG_KV key definition derived from dashboard manifests. */
|
|
103
|
+
export interface DashboardKvManifestKey {
|
|
104
|
+
key: string;
|
|
105
|
+
type: "boolean" | "number" | "string";
|
|
106
|
+
default: string;
|
|
107
|
+
description: string;
|
|
108
|
+
secret?: boolean;
|
|
109
|
+
/** Source worker id (e.g. hoox, trade-worker) */
|
|
110
|
+
worker?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface DashboardKvManifest {
|
|
113
|
+
namespace: string;
|
|
114
|
+
keys: DashboardKvManifestKey[];
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Flatten worker dashboard manifests into a CONFIG_KV key list
|
|
118
|
+
* (for `hoox config kv manifest` / apply-manifest).
|
|
119
|
+
*
|
|
120
|
+
* First definition wins for duplicate keys (worker order follows
|
|
121
|
+
* `DASHBOARD_WORKER_IDS` then filesystem discovery). Prefer richer
|
|
122
|
+
* description/secret when a later duplicate is more complete.
|
|
123
|
+
*/
|
|
124
|
+
export declare function kvManifestFromDashboardManifests(manifests: WorkerDashboardManifest[]): DashboardKvManifest;
|
|
125
|
+
/**
|
|
126
|
+
* Load dashboard.jsonc files from a monorepo root and build the KV manifest.
|
|
127
|
+
* Pure filesystem helper used by CLI; returns empty keys if root missing.
|
|
128
|
+
*/
|
|
129
|
+
export declare function loadDashboardKvManifestFromRoot(root: string, onError?: (message: string) => void): DashboardKvManifest;
|
|
130
|
+
/**
|
|
131
|
+
* Discover workers/NAME/dashboard.jsonc under a monorepo root.
|
|
132
|
+
* Broken JSONC files are skipped (empty sections) after `onError` warning.
|
|
133
|
+
*/
|
|
134
|
+
export declare function loadDashboardManifestsFromRoot(root: string, onError?: (message: string) => void): WorkerDashboardManifest[];
|
|
135
|
+
//# sourceMappingURL=dashboard-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-manifest.d.ts","sourceRoot":"","sources":["../src/dashboard-manifest.ts"],"names":[],"mappings":"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"}
|