@hoox-sh/hoox-shared 1.4.0 → 1.6.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.
Files changed (110) hide show
  1. package/README.md +6 -0
  2. package/dist/agent-config-fields.d.ts +5 -0
  3. package/dist/agent-config-fields.d.ts.map +1 -1
  4. package/dist/agent-config-fields.js +21 -29
  5. package/dist/analytics.d.ts +3 -4
  6. package/dist/analytics.d.ts.map +1 -1
  7. package/dist/analytics.js +64 -19
  8. package/dist/api-client.js +12 -21
  9. package/dist/colors.js +5 -21
  10. package/dist/config.d.ts +10 -2
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +267 -51
  13. package/dist/cron-handler.js +0 -16
  14. package/dist/d1/index.js +8 -25
  15. package/dist/d1/repository.js +3 -19
  16. package/dist/d1/schemas.js +4 -20
  17. package/dist/dashboard-manifest.d.ts +2 -1
  18. package/dist/dashboard-manifest.d.ts.map +1 -1
  19. package/dist/dashboard-manifest.js +37 -33
  20. package/dist/entitlements.d.ts +46 -0
  21. package/dist/entitlements.d.ts.map +1 -0
  22. package/dist/entitlements.js +15 -0
  23. package/dist/errors.d.ts +1 -0
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +7 -23
  26. package/dist/exchange-client.d.ts +0 -19
  27. package/dist/exchange-client.d.ts.map +1 -1
  28. package/dist/exchange-client.js +1 -83
  29. package/dist/exchanges/base-exchange-client.d.ts.map +1 -1
  30. package/dist/exchanges/base-exchange-client.js +4 -19
  31. package/dist/exchanges/index.js +4 -19
  32. package/dist/format-time.js +2 -18
  33. package/dist/formatters.js +12 -28
  34. package/dist/health.js +3 -19
  35. package/dist/index.d.ts +7 -4
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +3568 -3766
  38. package/dist/kill-switch.js +12 -20
  39. package/dist/kvKeys.d.ts +8 -0
  40. package/dist/kvKeys.d.ts.map +1 -1
  41. package/dist/kvKeys.js +42 -46
  42. package/dist/kvUtils.js +8 -24
  43. package/dist/legal.js +5 -21
  44. package/dist/middleware/auth.d.ts +9 -0
  45. package/dist/middleware/auth.d.ts.map +1 -1
  46. package/dist/middleware/auth.js +9 -25
  47. package/dist/middleware/cors.js +4 -20
  48. package/dist/middleware/index.js +144 -165
  49. package/dist/middleware/logger.d.ts +2 -0
  50. package/dist/middleware/logger.d.ts.map +1 -1
  51. package/dist/middleware/logger.js +9 -25
  52. package/dist/middleware/rate-limit.d.ts +7 -0
  53. package/dist/middleware/rate-limit.d.ts.map +1 -1
  54. package/dist/middleware/rate-limit.js +5 -20
  55. package/dist/middleware/security-headers.js +2 -18
  56. package/dist/middleware/validate.d.ts +2 -0
  57. package/dist/middleware/validate.d.ts.map +1 -1
  58. package/dist/middleware/validate.js +5 -21
  59. package/dist/middleware/wait-until.js +2 -18
  60. package/dist/operator-transport.js +13 -17
  61. package/dist/path-utils.d.ts.map +1 -1
  62. package/dist/path-utils.js +28 -34
  63. package/dist/queue-handler.d.ts.map +1 -1
  64. package/dist/queue-handler.js +19 -24
  65. package/dist/router.d.ts +5 -0
  66. package/dist/router.d.ts.map +1 -1
  67. package/dist/router.js +0 -16
  68. package/dist/schemas/index.js +75 -50
  69. package/dist/schemas/registry.d.ts.map +1 -1
  70. package/dist/schemas/registry.js +33 -21
  71. package/dist/schemas/validators.d.ts.map +1 -1
  72. package/dist/schemas/validators.js +41 -43
  73. package/dist/service-bindings.d.ts +4 -0
  74. package/dist/service-bindings.d.ts.map +1 -1
  75. package/dist/service-bindings.js +13 -29
  76. package/dist/session.d.ts +10 -3
  77. package/dist/session.d.ts.map +1 -1
  78. package/dist/session.js +111 -51
  79. package/dist/sse.d.ts.map +1 -1
  80. package/dist/sse.js +34 -24
  81. package/dist/stores/config-store.d.ts +2 -50
  82. package/dist/stores/config-store.d.ts.map +1 -1
  83. package/dist/stores/config-store.js +153 -156
  84. package/dist/stores/service-store.d.ts +2 -192
  85. package/dist/stores/service-store.d.ts.map +1 -1
  86. package/dist/stores/service-store.js +40 -35
  87. package/dist/stores/ui-store.d.ts +2 -48
  88. package/dist/stores/ui-store.d.ts.map +1 -1
  89. package/dist/stores/ui-store.js +0 -16
  90. package/dist/tenant.d.ts +62 -0
  91. package/dist/tenant.d.ts.map +1 -0
  92. package/dist/tenant.js +56 -0
  93. package/dist/test-utils.js +11 -27
  94. package/dist/types.d.ts +10 -3
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js +29 -24
  97. package/dist/wizard/engine.d.ts.map +1 -1
  98. package/dist/wizard/engine.js +33 -27
  99. package/dist/wizard/index.d.ts +1 -0
  100. package/dist/wizard/index.d.ts.map +1 -1
  101. package/dist/wizard/index.js +48 -39
  102. package/dist/wizard/persistence.d.ts +4 -0
  103. package/dist/wizard/persistence.d.ts.map +1 -1
  104. package/dist/wizard/persistence.js +7 -19
  105. package/dist/wizard/presets.d.ts.map +1 -1
  106. package/dist/wizard/presets.js +13 -25
  107. package/dist/wizard/types.d.ts +6 -0
  108. package/dist/wizard/types.d.ts.map +1 -1
  109. package/dist/wizard/types.js +5 -0
  110. package/package.json +7 -2
package/README.md CHANGED
@@ -41,4 +41,10 @@ The named subdirectories with deep-import support are: `middleware`, `d1`, `sche
41
41
 
42
42
  ```bash
43
43
  bun test packages/shared
44
+ bun run build:shared # emits dist/ (gitignored)
45
+ bun run typecheck # builds shared first, then tsc every workspace
44
46
  ```
47
+
48
+ Worker `tsc` resolves `@hoox-sh/hoox-shared/<subpath>` through this package's
49
+ `exports` map to `dist/*.d.ts`. `bun run typecheck` (and the pre-push hook)
50
+ builds `dist/` first so a clean tree does not fail with missing-module errors.
@@ -18,12 +18,17 @@ export type AgentConfigFieldSpec = {
18
18
  export declare const AGENT_CONFIG_EMBEDDED_FIELDS: Readonly<Record<string, AgentConfigFieldSpec>>;
19
19
  /** Sections whose fields are edited via agent:config (not flat KV). */
20
20
  export declare const DASHBOARD_SECTIONS_AGENT_CONFIG: ReadonlySet<string>;
21
+ /** True when `fieldKey` is stored inside the agent:config KV document. */
21
22
  export declare function isAgentConfigEmbeddedField(fieldKey: string): boolean;
23
+ /** True when the dashboard section is edited via agent:config (not flat KV). */
22
24
  export declare function isAgentConfigSection(sectionId: string): boolean;
23
25
  /** Parse agent:config KV payload (handles double-encoded JSON strings). */
24
26
  export declare function parseAgentConfigJson(raw: string | null | undefined): Record<string, unknown>;
27
+ /** Serialize an agent:config object for CONFIG_KV. */
25
28
  export declare function serializeAgentConfigForKv(config: Record<string, unknown>): string;
29
+ /** Read one embedded agent:config field as a scalar or JSON string. */
26
30
  export declare function getAgentConfigEmbeddedValue(config: Record<string, unknown>, fieldKey: string): string | number | boolean | undefined;
31
+ /** Immutably set one embedded agent:config field and return the next document. */
27
32
  export declare function setAgentConfigEmbeddedValue(config: Record<string, unknown>, fieldKey: string, value: string | number | boolean): Record<string, unknown>;
28
33
  /** Expand agent:config into dashboard composite field keys for UI forms. */
29
34
  export declare function expandAgentConfigToFieldMap(config: Record<string, unknown>): Record<string, string | number | boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-config-fields.d.ts","sourceRoot":"","sources":["../src/agent-config-fields.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,iBAAkB,CAAC;AAEnD,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EACC,iBAAiB,GACjB,eAAe,GACf,WAAW,GACX,YAAY,GACZ,yBAAyB,GACzB,qBAAqB,GACrB,mBAAmB,CAAC;CACzB,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CACjD,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAiBrC,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,+BAA+B,EAAE,WAAW,CAAC,MAAM,CAG9D,CAAC;AAEH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKpE;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAER;AAUD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CA+BvC;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsCzB;AAED,4EAA4E;AAC5E,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAO3C;AAED,yEAAyE;AACzE,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACjD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB"}
1
+ {"version":3,"file":"agent-config-fields.d.ts","sourceRoot":"","sources":["../src/agent-config-fields.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,iBAAkB,CAAC;AAEnD,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EACC,iBAAiB,GACjB,eAAe,GACf,WAAW,GACX,YAAY,GACZ,yBAAyB,GACzB,qBAAqB,GACrB,mBAAmB,CAAC;CACzB,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CACjD,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAiBrC,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,+BAA+B,EAAE,WAAW,CAAC,MAAM,CAG9D,CAAC;AAEH,0EAA0E;AAC1E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKpE;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB;AAED,sDAAsD;AACtD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAER;AAUD,uEAAuE;AACvE,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CA+BvC;AAED,kFAAkF;AAClF,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsCzB;AAED,4EAA4E;AAC5E,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAO3C;AAED,yEAAyE;AACzE,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GACjD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB"}
@@ -1,20 +1,4 @@
1
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
2
  // src/kvKeys.ts
19
3
  var KV_TRADE_DEFAULT_LEVERAGE = "trade:default_leverage";
20
4
  var KV_TRADE_MAX_POSITION_SIZE = "trade:max_position_size";
@@ -26,6 +10,10 @@ var KV_BOT_ENABLED = "bot:enabled";
26
10
  var KV_BOT_DEFAULT_CHAT_ID = "bot:default_chat_id";
27
11
  var KV_BOT_NOTIFY_ON_EXECUTION = "bot:notify_on_execution";
28
12
  var KV_BOT_NOTIFY_ON_ERROR = "bot:notify_on_error";
13
+ var KV_BOT_NOTIFY_ON_STARTUP = "bot:notify_on_startup";
14
+ var KV_BOT_AI_SUMMARIES_ENABLED = "bot:ai_summaries_enabled";
15
+ var KV_BOT_SUMMARY_STYLE = "bot:summary_style";
16
+ var KV_BOT_INCLUDE_PNL = "bot:include_pnl";
29
17
  var KV_TELEGRAM_ALLOWED_CHAT_IDS = "telegram:allowed_chat_ids";
30
18
  var KV_WEBHOOK_IP_CHECK_ENABLED = "webhook:tradingview:ip_check_enabled";
31
19
  var KV_WEBHOOK_ALLOWED_IPS = "webhook:tradingview:allowed_ips";
@@ -57,6 +45,10 @@ var KVKeys = {
57
45
  KV_BOT_DEFAULT_CHAT_ID,
58
46
  KV_BOT_NOTIFY_ON_EXECUTION,
59
47
  KV_BOT_NOTIFY_ON_ERROR,
48
+ KV_BOT_NOTIFY_ON_STARTUP,
49
+ KV_BOT_AI_SUMMARIES_ENABLED,
50
+ KV_BOT_SUMMARY_STYLE,
51
+ KV_BOT_INCLUDE_PNL,
60
52
  KV_TELEGRAM_ALLOWED_CHAT_IDS,
61
53
  KV_WEBHOOK_IP_CHECK_ENABLED,
62
54
  KV_WEBHOOK_ALLOWED_IPS,
@@ -143,9 +135,9 @@ function getAgentConfigEmbeddedValue(config, fieldKey) {
143
135
  const map = config.modelMap;
144
136
  if (!map || typeof map !== "object" || Array.isArray(map))
145
137
  return;
146
- const v2 = map[spec.provider];
147
- if (typeof v2 === "string" || typeof v2 === "number" || typeof v2 === "boolean")
148
- return v2;
138
+ const v = map[spec.provider];
139
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean")
140
+ return v;
149
141
  return;
150
142
  }
151
143
  const v = config[spec.key];
@@ -210,15 +202,15 @@ function applyAgentConfigFieldUpdates(config, updates) {
210
202
  return next;
211
203
  }
212
204
  export {
213
- setAgentConfigEmbeddedValue,
214
- serializeAgentConfigForKv,
215
- parseAgentConfigJson,
216
- isAgentConfigSection,
217
- isAgentConfigEmbeddedField,
218
- getAgentConfigEmbeddedValue,
219
- expandAgentConfigToFieldMap,
220
- applyAgentConfigFieldUpdates,
221
- DASHBOARD_SECTIONS_AGENT_CONFIG,
205
+ AGENT_CONFIG_EMBEDDED_FIELDS,
222
206
  AGENT_CONFIG_KV_KEY,
223
- AGENT_CONFIG_EMBEDDED_FIELDS
207
+ DASHBOARD_SECTIONS_AGENT_CONFIG,
208
+ applyAgentConfigFieldUpdates,
209
+ expandAgentConfigToFieldMap,
210
+ getAgentConfigEmbeddedValue,
211
+ isAgentConfigEmbeddedField,
212
+ isAgentConfigSection,
213
+ parseAgentConfigJson,
214
+ serializeAgentConfigForKv,
215
+ setAgentConfigEmbeddedValue
224
216
  };
@@ -2,10 +2,6 @@
2
2
  * Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- /**
6
- * Analytics tracking utilities for Cloudflare Workers
7
- * Centralizes the trackAnalytics helper used across all workers
8
- */
9
5
  /**
10
6
  * Environment with optional analytics service binding.
11
7
  * Workers that support analytics tracking should extend this type.
@@ -22,6 +18,9 @@
22
18
  */
23
19
  export interface AnalyticsEnv {
24
20
  ANALYTICS_SERVICE?: Fetcher;
21
+ /** Opt-in tenant isolation (see tenant.ts). Absent = self-host default. */
22
+ TENANT_ID?: string;
23
+ TENANT_MODE?: string;
25
24
  }
26
25
  /**
27
26
  * Optional configuration for trackAnalytics.
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAqDf"}
package/dist/analytics.js CHANGED
@@ -1,41 +1,86 @@
1
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);
2
+ // src/tenant.ts
3
+ var TENANT_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
4
+ function isTenantFlagOn(env) {
5
+ const v = env?.TENANT_MODE;
6
+ return v === "true" || v === "1";
7
+ }
8
+ function tenantScope(env) {
9
+ if (!isTenantFlagOn(env))
10
+ return { enabled: false, tenantId: null };
11
+ const id = (env?.TENANT_ID ?? "").trim();
12
+ if (!id || !TENANT_ID_RE.test(id)) {
13
+ throw new Error("TENANT_MODE is enabled but TENANT_ID is missing or invalid (expected [A-Za-z0-9_-], 1-64 chars)");
14
+ }
15
+ return { enabled: true, tenantId: id };
16
+ }
17
+ function isTenantMode(env) {
18
+ try {
19
+ return tenantScope(env).enabled;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+ function effectiveTenantId(env, msg) {
25
+ if (isTenantFlagOn(env)) {
26
+ return tenantScope(env).tenantId;
27
+ }
28
+ const m = typeof msg?.tenantId === "string" ? msg.tenantId.trim() : "";
29
+ return m && TENANT_ID_RE.test(m) ? m : null;
30
+ }
31
+ function scopeKey(env, key, msg) {
32
+ const id = effectiveTenantId(env, msg);
33
+ return id ? `t/${id}/${key}` : key;
34
+ }
35
+ function scopeR2Key(env, key, msg) {
36
+ const id = effectiveTenantId(env, msg);
37
+ return id ? `t-${id}/${key}` : key;
38
+ }
39
+ function withTenantId(env, obj) {
40
+ const ts = tenantScope(env);
41
+ return ts.enabled && ts.tenantId ? { ...obj, tenantId: ts.tenantId } : obj;
42
+ }
43
+ function tenantContextOf(env) {
44
+ const ts = tenantScope(env);
45
+ return ts.enabled && ts.tenantId ? { tenantId: ts.tenantId } : null;
46
+ }
17
47
 
18
48
  // src/analytics.ts
19
49
  async function trackAnalytics(env, endpoint, body, options) {
20
50
  if (!env.ANALYTICS_SERVICE)
21
51
  return;
22
52
  try {
53
+ let tenantId = null;
54
+ try {
55
+ tenantId = effectiveTenantId(env);
56
+ } catch {
57
+ tenantId = null;
58
+ }
59
+ const rest = { ...body };
60
+ delete rest.tenant_id;
61
+ delete rest.tenantId;
23
62
  const payload = {
24
- ...body,
63
+ ...rest,
64
+ ...tenantId ? { tenant_id: tenantId } : {},
25
65
  ...options?.indexes ? { indexes: [...options.indexes] } : {}
26
66
  };
27
67
  const headers = {
28
68
  "Content-Type": "application/json"
29
69
  };
30
70
  const internalKey = env.INTERNAL_KEY_BINDING;
31
- if (internalKey) {
32
- headers["X-Internal-Auth-Key"] = internalKey;
71
+ if (!internalKey) {
72
+ console.error("Analytics tracking skipped: INTERNAL_KEY_BINDING missing");
73
+ return;
33
74
  }
34
- await env.ANALYTICS_SERVICE.fetch(new Request(`http://localhost${endpoint}`, {
75
+ headers["X-Internal-Auth-Key"] = internalKey;
76
+ const response = await env.ANALYTICS_SERVICE.fetch(new Request(`http://localhost${endpoint}`, {
35
77
  method: "POST",
36
78
  headers,
37
79
  body: JSON.stringify(payload)
38
80
  }));
81
+ if (!response.ok) {
82
+ console.error(`Analytics tracking failed: HTTP ${response.status} ${response.statusText}`);
83
+ }
39
84
  } catch (e) {
40
85
  console.error("Analytics tracking failed:", e);
41
86
  }
@@ -1,19 +1,15 @@
1
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
- });
2
+ var __esm = (fn, res, err) => () => {
3
+ if (fn)
4
+ try {
5
+ res = fn(fn = 0);
6
+ } catch (e) {
7
+ err = [e];
8
+ }
9
+ if (err)
10
+ throw err[0];
11
+ return res;
15
12
  };
16
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
13
 
18
14
  // src/operator-transport.ts
19
15
  function stripTrailingSlashes(url) {
@@ -83,11 +79,6 @@ var init_operator_transport = __esm(() => {
83
79
  });
84
80
 
85
81
  // src/api-client.ts
86
- var exports_api_client = {};
87
- __export(exports_api_client, {
88
- hooxFetch: () => hooxFetch,
89
- WorkerAPIError: () => WorkerAPIError
90
- });
91
82
  function isRetryableStatus(status) {
92
83
  if (status === 401 || status === 403 || status === 429)
93
84
  return false;
@@ -190,6 +181,6 @@ var init_api_client = __esm(() => {
190
181
  init_api_client();
191
182
 
192
183
  export {
193
- hooxFetch,
194
- WorkerAPIError
184
+ WorkerAPIError,
185
+ hooxFetch
195
186
  };
package/dist/colors.js CHANGED
@@ -1,20 +1,4 @@
1
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
2
  // src/colors.ts
19
3
  var Colors = {
20
4
  background: "#050508",
@@ -73,10 +57,10 @@ var AlertSeverityColor = {
73
57
  critical: Colors.error
74
58
  };
75
59
  export {
76
- WorkerStatusColor,
77
- LogLevelColor,
78
- CoolBracketPalette,
79
- ConnectionStatusColor,
60
+ AlertSeverityColor,
80
61
  Colors,
81
- AlertSeverityColor
62
+ ConnectionStatusColor,
63
+ CoolBracketPalette,
64
+ LogLevelColor,
65
+ WorkerStatusColor
82
66
  };
package/dist/config.d.ts CHANGED
@@ -28,8 +28,12 @@ export interface HooxConfig {
28
28
  soundEnabled: boolean;
29
29
  defaultView: string;
30
30
  }
31
- /** Read config from disk, merging with defaults and env vars */
31
+ /**
32
+ * Read operator config from `$HOOX_HOME/config.json` (default `~/.hoox`).
33
+ * Env `HOOX_API_URL` / `HOOX_API_TOKEN` override file values.
34
+ */
32
35
  export declare function readConfigSync(): HooxConfig;
36
+ /** Async alias of {@link readConfigSync}. */
33
37
  export declare function readConfig(): Promise<HooxConfig>;
34
38
  /**
35
39
  * Ensure `~/.hoox` exists with owner-only permissions.
@@ -53,8 +57,12 @@ export declare function isUnixModeGroupOrWorldAccessible(mode: number): boolean;
53
57
  export declare function isConfigWorldOrGroupReadable(filePath?: string): boolean;
54
58
  /** Human-readable warning when config perms are too open. */
55
59
  export declare function formatConfigPermissionWarning(filePath?: string): string | null;
56
- /** Write config to disk with owner-only permissions. */
60
+ /**
61
+ * Write operator config to `$HOOX_HOME/config.json` with owner-only mode.
62
+ * Throws when the directory or file cannot be written.
63
+ */
57
64
  export declare function writeConfigSync(config: HooxConfig): void;
65
+ /** Async alias of {@link writeConfigSync}. Throws on I/O failure. */
58
66
  export declare function writeConfig(config: HooxConfig): Promise<void>;
59
67
  /** Validate config — returns array of error messages */
60
68
  export declare function validateConfig(config: Partial<HooxConfig>): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH,8DAA8D;AAC9D,eAAO,MAAM,aAAa,MAAQ,CAAC;AACnC,wDAAwD;AACxD,eAAO,MAAM,qBAAqB,MAAQ,CAAC;AAE3C,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,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;AAmBD,gEAAgE;AAChE,wBAAgB,cAAc,IAAI,UAAU,CAsB3C;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAEtD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAgB,GAAG,IAAI,CAS/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAA8B,GACnC,IAAI,CAON;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,GAAE,MAAoB,GAC7B,OAAO,CAOT;AAED,6DAA6D;AAC7D,wBAAgB,6BAA6B,CAC3C,QAAQ,GAAE,MAAoB,GAC7B,MAAM,GAAG,IAAI,CAOf;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAWxD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AASD,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,EAAE,CAqBpE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgCH,8DAA8D;AAC9D,eAAO,MAAM,aAAa,MAAQ,CAAC;AACnC,wDAAwD;AACxD,eAAO,MAAM,qBAAqB,MAAQ,CAAC;AAE3C,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,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;AAmBD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,CAsB3C;AAED,6CAA6C;AAC7C,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAEtD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAkB,GAAG,IAAI,CASjE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAA8B,GACnC,IAAI,CAON;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,GAAE,MAAqB,GAC9B,OAAO,CAOT;AAED,6DAA6D;AAC7D,wBAAgB,6BAA6B,CAC3C,QAAQ,GAAE,MAAqB,GAC9B,MAAM,GAAG,IAAI,CAOf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAOxD;AAED,qEAAqE;AACrE,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AASD,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,EAAE,CAqBpE"}