@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
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @hoox/shared
|
|
2
|
+
|
|
3
|
+
Shared types, custom router with path parameter support (`:param` syntax), middleware (auth, CORS, rate-limit, logger), error factories (`Errors.*`), generic exchange provider factory (`ExchangeRouter`, `IExchangeProvider`), and utilities.
|
|
4
|
+
|
|
5
|
+
## For CLI Users
|
|
6
|
+
|
|
7
|
+
This is an internal package — installed automatically as a workspace dependency. No CLI commands needed.
|
|
8
|
+
|
|
9
|
+
→ [Architecture Overview](../../docs/devops/architecture/overview.md)
|
|
10
|
+
|
|
11
|
+
## For Operators
|
|
12
|
+
|
|
13
|
+
This package provides the shared foundation for all Hoox workers. It includes:
|
|
14
|
+
|
|
15
|
+
- **Custom Router** — Lightweight routing with exact-match fast path and `:param` path parameter support. Handlers receive extracted params as an optional 4th argument.
|
|
16
|
+
- **Error Factories** — `Errors.*` helpers (`badRequest`, `unauthorized`, `forbidden`, `notFound`, `internal`, etc.) for consistent JSON error responses across all workers.
|
|
17
|
+
- **Exchange Provider Factory** — Generic `ExchangeRouter<TClient, TEnv>` and `IExchangeProvider<TClient, TEnv>` for registering and resolving exchange clients by name.
|
|
18
|
+
- **Middleware** — Logger (`createLogger`, `withRequestLog`), auth (`requireInternalAuth`), CORS, rate limiting, and Zod validation.
|
|
19
|
+
- **Utilities** — `toError`, `serviceFetch`, `createJsonResponse`, KV helpers, health check, analytics tracking.
|
|
20
|
+
|
|
21
|
+
→ [Architecture Overview](../../docs/devops/architecture/overview.md)
|
|
22
|
+
|
|
23
|
+
## Development
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun test packages/shared
|
|
27
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics tracking utilities for Cloudflare Workers
|
|
3
|
+
* Centralizes the trackAnalytics helper used across all workers
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Environment with optional analytics service binding.
|
|
7
|
+
* Workers that support analytics tracking should extend this type.
|
|
8
|
+
*/
|
|
9
|
+
export interface AnalyticsEnv {
|
|
10
|
+
ANALYTICS_SERVICE?: Fetcher;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Track an analytics event by forwarding to the analytics worker.
|
|
15
|
+
* Non-blocking: failures are logged but never throw.
|
|
16
|
+
*
|
|
17
|
+
* @param env - Worker environment with optional ANALYTICS_SERVICE binding
|
|
18
|
+
* @param endpoint - Analytics endpoint path (e.g., "/track/api-call")
|
|
19
|
+
* @param body - JSON-serializable payload to send
|
|
20
|
+
*/
|
|
21
|
+
export declare function trackAnalytics(env: AnalyticsEnv, endpoint: string, body: Record<string, unknown>): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAaf"}
|
|
@@ -0,0 +1,34 @@
|
|
|
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/analytics.ts
|
|
19
|
+
async function trackAnalytics(env, endpoint, body) {
|
|
20
|
+
if (!env.ANALYTICS_SERVICE)
|
|
21
|
+
return;
|
|
22
|
+
try {
|
|
23
|
+
await env.ANALYTICS_SERVICE.fetch(new Request(`http://localhost${endpoint}`, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: { "Content-Type": "application/json" },
|
|
26
|
+
body: JSON.stringify(body)
|
|
27
|
+
}));
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.error("Analytics tracking failed:", e);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
trackAnalytics
|
|
34
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client — Bun fetch wrapper with AbortController timeouts, retry logic,
|
|
3
|
+
* and connection-aware error handling for the Hoox TUI dashboard.
|
|
4
|
+
*
|
|
5
|
+
* All fetch calls include a 5s timeout via AbortController.
|
|
6
|
+
* Network errors (fetch failures, timeouts) are retried with exponential backoff.
|
|
7
|
+
* HTTP 401/403 errors are NOT retried — they indicate auth/config issues.
|
|
8
|
+
* HTTP 429 (rate limit) triggers a backing-off warning.
|
|
9
|
+
*/
|
|
10
|
+
export declare class WorkerAPIError extends Error {
|
|
11
|
+
status: number;
|
|
12
|
+
retryable: boolean;
|
|
13
|
+
constructor(message: string, options?: {
|
|
14
|
+
cause?: unknown;
|
|
15
|
+
status?: number;
|
|
16
|
+
retryable?: boolean;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Perform an API fetch with timeout, retry logic, and error handling.
|
|
21
|
+
*
|
|
22
|
+
* Retry behavior:
|
|
23
|
+
* - Network errors (connection refused, DNS, timeout): up to MAX_RETRIES,
|
|
24
|
+
* with exponential backoff: 1s → 2s → 4s → ... capped at 16s.
|
|
25
|
+
* - HTTP 401/403: NO retry — fail immediately.
|
|
26
|
+
* - HTTP 429 (rate limited): NO retry — fail with rate limit info.
|
|
27
|
+
* - HTTP 5xx: retry once.
|
|
28
|
+
*
|
|
29
|
+
* @param path API path (e.g. "/workers")
|
|
30
|
+
* @param options Fetch options (merged with auth header and timeout signal)
|
|
31
|
+
* @returns Parsed JSON response body
|
|
32
|
+
*/
|
|
33
|
+
export declare function hooxFetch<T = unknown>(path: string, options?: RequestInit): Promise<T>;
|
|
34
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmBH,qBAAa,cAAe,SAAQ,KAAK;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;gBAGjB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE;CAOtE;AAyCD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EACzC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC,CA8FZ"}
|
|
@@ -0,0 +1,124 @@
|
|
|
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/api-client.ts
|
|
19
|
+
var exports_api_client = {};
|
|
20
|
+
__export(exports_api_client, {
|
|
21
|
+
hooxFetch: () => hooxFetch,
|
|
22
|
+
WorkerAPIError: () => WorkerAPIError
|
|
23
|
+
});
|
|
24
|
+
function isRetryableStatus(status) {
|
|
25
|
+
if (status === 401 || status === 403 || status === 429)
|
|
26
|
+
return false;
|
|
27
|
+
if (status >= 500)
|
|
28
|
+
return true;
|
|
29
|
+
if (status === 408)
|
|
30
|
+
return true;
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
function isNetworkError(error) {
|
|
34
|
+
if (error instanceof Error) {
|
|
35
|
+
const msg = error.message.toLowerCase();
|
|
36
|
+
return error.name === "AbortError" || error.name === "TimeoutError" || msg.includes("fetch") || msg.includes("network") || msg.includes("econnrefused") || msg.includes("enotfound") || msg.includes("dns") || msg.includes("timeout");
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function sleep(ms) {
|
|
41
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
42
|
+
}
|
|
43
|
+
async function hooxFetch(path, options) {
|
|
44
|
+
let lastError;
|
|
45
|
+
for (let attempt = 0;attempt <= MAX_RETRIES; attempt++) {
|
|
46
|
+
const controller = new AbortController;
|
|
47
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
48
|
+
try {
|
|
49
|
+
const url = `${API_BASE}${path}`;
|
|
50
|
+
const headers = {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
...API_TOKEN ? { Authorization: `Bearer ${API_TOKEN}` } : {},
|
|
53
|
+
...options?.headers
|
|
54
|
+
};
|
|
55
|
+
const response = await fetch(url, {
|
|
56
|
+
...options,
|
|
57
|
+
headers,
|
|
58
|
+
signal: controller.signal
|
|
59
|
+
});
|
|
60
|
+
if (response.status === 429) {
|
|
61
|
+
throw new WorkerAPIError("API rate limited \u2014 backing off", {
|
|
62
|
+
status: 429,
|
|
63
|
+
retryable: false
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (response.status === 401 || response.status === 403) {
|
|
67
|
+
throw new WorkerAPIError(`Authentication failed (HTTP ${response.status})`, { status: response.status, retryable: false });
|
|
68
|
+
}
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
if (attempt < MAX_RETRIES && isRetryableStatus(response.status)) {
|
|
71
|
+
const delay = Math.min(BASE_RETRY_DELAY_MS * Math.pow(2, attempt), MAX_RETRY_DELAY_MS);
|
|
72
|
+
await sleep(delay);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
throw new WorkerAPIError(`HTTP ${response.status}: ${response.statusText}`, {
|
|
76
|
+
status: response.status,
|
|
77
|
+
retryable: isRetryableStatus(response.status)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return await response.json();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
lastError = error;
|
|
83
|
+
if (error instanceof WorkerAPIError && !error.retryable) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
if (attempt < MAX_RETRIES && isNetworkError(error)) {
|
|
87
|
+
const delay = Math.min(BASE_RETRY_DELAY_MS * Math.pow(2, attempt), MAX_RETRY_DELAY_MS);
|
|
88
|
+
await sleep(delay);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (!(error instanceof WorkerAPIError)) {
|
|
92
|
+
throw new WorkerAPIError(`Network request failed: ${error.message}`, { cause: error, retryable: false, status: 0 });
|
|
93
|
+
}
|
|
94
|
+
throw error;
|
|
95
|
+
} finally {
|
|
96
|
+
clearTimeout(timeoutId);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
throw new WorkerAPIError("Max retries exhausted", {
|
|
100
|
+
cause: lastError,
|
|
101
|
+
retryable: false
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
var API_BASE, API_TOKEN, FETCH_TIMEOUT_MS = 5000, MAX_RETRIES = 3, BASE_RETRY_DELAY_MS = 1000, MAX_RETRY_DELAY_MS = 16000, WorkerAPIError;
|
|
105
|
+
var init_api_client = __esm(() => {
|
|
106
|
+
API_BASE = process.env.HOOX_API_URL || "http://localhost:8787";
|
|
107
|
+
API_TOKEN = process.env.HOOX_API_TOKEN || "";
|
|
108
|
+
WorkerAPIError = class WorkerAPIError extends Error {
|
|
109
|
+
status;
|
|
110
|
+
retryable;
|
|
111
|
+
constructor(message, options) {
|
|
112
|
+
super(message, { cause: options?.cause });
|
|
113
|
+
this.name = "WorkerAPIError";
|
|
114
|
+
this.status = options?.status ?? 0;
|
|
115
|
+
this.retryable = options?.retryable ?? false;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
init_api_client();
|
|
120
|
+
|
|
121
|
+
export {
|
|
122
|
+
hooxFetch,
|
|
123
|
+
WorkerAPIError
|
|
124
|
+
};
|
package/dist/colors.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color Tokens — Maps hoox landing page design system to terminal-safe RGBA hex values.
|
|
3
|
+
*
|
|
4
|
+
* Design DNA:
|
|
5
|
+
* - Dark monochrome background: oklch(0.08 0 0) → #0D1117
|
|
6
|
+
* - Orange accent: oklch(0.7 0.2 45) → #E8780A
|
|
7
|
+
* - Squared edges (no rounding — editorial aesthetic)
|
|
8
|
+
*
|
|
9
|
+
* Usage: import { Colors } from "@hoox/shared"
|
|
10
|
+
* <text fg={Colors.accent}>Important</text>
|
|
11
|
+
*/
|
|
12
|
+
export declare const Colors: {
|
|
13
|
+
readonly background: "#0D1117";
|
|
14
|
+
readonly foreground: "#EEEEEE";
|
|
15
|
+
readonly card: "#1C1C1F";
|
|
16
|
+
readonly border: "#484848";
|
|
17
|
+
readonly muted: "#A0A0A0";
|
|
18
|
+
readonly "muted-foreground": "#6E6E6E";
|
|
19
|
+
readonly dim: "#3B3B3D";
|
|
20
|
+
readonly accent: "#E8780A";
|
|
21
|
+
readonly "accent-dim": "#B85E08";
|
|
22
|
+
readonly success: "#00FF88";
|
|
23
|
+
readonly warning: "#FFAA00";
|
|
24
|
+
readonly error: "#FF4444";
|
|
25
|
+
readonly info: "#4488FF";
|
|
26
|
+
readonly text: "#EEEEEE";
|
|
27
|
+
readonly "text-muted": "#A0A0A0";
|
|
28
|
+
readonly "text-dim": "#6E6E6E";
|
|
29
|
+
readonly panel: "#1C1C1F";
|
|
30
|
+
readonly divider: "#484848";
|
|
31
|
+
readonly highlight: "#E8780A";
|
|
32
|
+
};
|
|
33
|
+
export type ColorKey = keyof typeof Colors;
|
|
34
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;CA2BT,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,MAAM,CAAC"}
|
package/dist/colors.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
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/colors.ts
|
|
19
|
+
var Colors = {
|
|
20
|
+
background: "#0D1117",
|
|
21
|
+
foreground: "#EEEEEE",
|
|
22
|
+
card: "#1C1C1F",
|
|
23
|
+
border: "#484848",
|
|
24
|
+
muted: "#A0A0A0",
|
|
25
|
+
"muted-foreground": "#6E6E6E",
|
|
26
|
+
dim: "#3B3B3D",
|
|
27
|
+
accent: "#E8780A",
|
|
28
|
+
"accent-dim": "#B85E08",
|
|
29
|
+
success: "#00FF88",
|
|
30
|
+
warning: "#FFAA00",
|
|
31
|
+
error: "#FF4444",
|
|
32
|
+
info: "#4488FF",
|
|
33
|
+
text: "#EEEEEE",
|
|
34
|
+
"text-muted": "#A0A0A0",
|
|
35
|
+
"text-dim": "#6E6E6E",
|
|
36
|
+
panel: "#1C1C1F",
|
|
37
|
+
divider: "#484848",
|
|
38
|
+
highlight: "#E8780A"
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
Colors
|
|
42
|
+
};
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface HooxConfig {
|
|
2
|
+
apiUrl: string;
|
|
3
|
+
apiToken: string;
|
|
4
|
+
refreshIntervalMs: number;
|
|
5
|
+
theme: "dark" | "light";
|
|
6
|
+
activeExchanges: string[];
|
|
7
|
+
notifications: {
|
|
8
|
+
alerts: boolean;
|
|
9
|
+
trades: boolean;
|
|
10
|
+
debug: boolean;
|
|
11
|
+
system: boolean;
|
|
12
|
+
};
|
|
13
|
+
soundEnabled: boolean;
|
|
14
|
+
defaultView: string;
|
|
15
|
+
}
|
|
16
|
+
/** Read config from disk, merging with defaults and env vars */
|
|
17
|
+
export declare function readConfigSync(): HooxConfig;
|
|
18
|
+
export declare function readConfig(): Promise<HooxConfig>;
|
|
19
|
+
/** Write config to disk */
|
|
20
|
+
export declare function writeConfigSync(config: HooxConfig): void;
|
|
21
|
+
export declare function writeConfig(config: HooxConfig): Promise<void>;
|
|
22
|
+
/** Validate config — returns array of error messages */
|
|
23
|
+
export declare function validateConfig(config: Partial<HooxConfig>): string[];
|
|
24
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAkBD,gEAAgE;AAChE,wBAAgB,cAAc,IAAI,UAAU,CAsB3C;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAEtD;AAED,2BAA2B;AAC3B,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CASxD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,EAAE,CAepE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
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/config.ts
|
|
19
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
20
|
+
import { join } from "path";
|
|
21
|
+
import { homedir } from "os";
|
|
22
|
+
var HOX_DIR = join(homedir(), ".hoox");
|
|
23
|
+
var CONFIG_PATH = join(HOX_DIR, "config.json");
|
|
24
|
+
var DEFAULT_CONFIG = {
|
|
25
|
+
apiUrl: "http://localhost:8787",
|
|
26
|
+
apiToken: "",
|
|
27
|
+
refreshIntervalMs: 500,
|
|
28
|
+
theme: "dark",
|
|
29
|
+
activeExchanges: ["binance", "bybit", "mexc"],
|
|
30
|
+
notifications: {
|
|
31
|
+
alerts: true,
|
|
32
|
+
trades: true,
|
|
33
|
+
debug: false,
|
|
34
|
+
system: true
|
|
35
|
+
},
|
|
36
|
+
soundEnabled: true,
|
|
37
|
+
defaultView: "dashboard"
|
|
38
|
+
};
|
|
39
|
+
function readConfigSync() {
|
|
40
|
+
const envConfig = {
|
|
41
|
+
apiUrl: process.env.HOOX_API_URL,
|
|
42
|
+
apiToken: process.env.HOOX_API_TOKEN
|
|
43
|
+
};
|
|
44
|
+
let fileConfig = {};
|
|
45
|
+
try {
|
|
46
|
+
if (existsSync(CONFIG_PATH)) {
|
|
47
|
+
fileConfig = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
48
|
+
}
|
|
49
|
+
} catch {}
|
|
50
|
+
return {
|
|
51
|
+
...DEFAULT_CONFIG,
|
|
52
|
+
...fileConfig,
|
|
53
|
+
...Object.fromEntries(Object.entries(envConfig).filter(([_, v]) => v !== undefined))
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function readConfig() {
|
|
57
|
+
return readConfigSync();
|
|
58
|
+
}
|
|
59
|
+
function writeConfigSync(config) {
|
|
60
|
+
try {
|
|
61
|
+
if (!existsSync(HOX_DIR)) {
|
|
62
|
+
mkdirSync(HOX_DIR, { recursive: true });
|
|
63
|
+
}
|
|
64
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.error("Failed to write config:", err);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function writeConfig(config) {
|
|
70
|
+
writeConfigSync(config);
|
|
71
|
+
}
|
|
72
|
+
function validateConfig(config) {
|
|
73
|
+
const errors = [];
|
|
74
|
+
if (config.apiUrl && !config.apiUrl.startsWith("http")) {
|
|
75
|
+
errors.push("apiUrl must start with http:// or https://");
|
|
76
|
+
}
|
|
77
|
+
if (config.refreshIntervalMs !== undefined && config.refreshIntervalMs < 100) {
|
|
78
|
+
errors.push("refreshIntervalMs must be >= 100ms");
|
|
79
|
+
}
|
|
80
|
+
if (config.theme && !["dark", "light"].includes(config.theme)) {
|
|
81
|
+
errors.push('theme must be "dark" or "light"');
|
|
82
|
+
}
|
|
83
|
+
return errors;
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
writeConfigSync,
|
|
87
|
+
writeConfig,
|
|
88
|
+
validateConfig,
|
|
89
|
+
readConfigSync,
|
|
90
|
+
readConfig
|
|
91
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { D1Repository } from "./repository";
|
|
2
|
+
export type { BatchStatement } from "./repository";
|
|
3
|
+
export type { TradeRecord, PositionRecord, BalanceRecord, SystemLogRecord, TradeSignalRecord, D1QueryResult, } from "./schemas";
|
|
4
|
+
export { TradeRecordSchema, PositionRecordSchema, BalanceRecordSchema, SystemLogRecordSchema, TradeSignalRecordSchema, } from "./schemas";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/d1/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,WAAW,CAAC"}
|