@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,87 @@
|
|
|
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/operator-transport.ts
|
|
19
|
+
function stripTrailingSlashes(url) {
|
|
20
|
+
return url.replace(/\/+$/, "");
|
|
21
|
+
}
|
|
22
|
+
function parseTransport(raw) {
|
|
23
|
+
if (!raw)
|
|
24
|
+
return null;
|
|
25
|
+
const v = raw.trim().toLowerCase();
|
|
26
|
+
if (VALID_TRANSPORTS.has(v)) {
|
|
27
|
+
return v;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function resolveOperatorTransportProfile(env = process.env, options = {}) {
|
|
32
|
+
const accessClientId = env.CF_ACCESS_CLIENT_ID?.trim() ?? "";
|
|
33
|
+
const accessClientSecret = env.CF_ACCESS_CLIENT_SECRET?.trim() ?? "";
|
|
34
|
+
const hasAccess = Boolean(accessClientId && accessClientSecret);
|
|
35
|
+
const explicit = parseTransport(env.HOOX_TRANSPORT) ?? parseTransport(options.configTransport);
|
|
36
|
+
const transport = explicit ?? (hasAccess ? "access" : "public");
|
|
37
|
+
const apiFromEnv = env.HOOX_API_URL?.trim();
|
|
38
|
+
const apiFromConfig = options.configApiUrl?.trim();
|
|
39
|
+
const tokenFromEnv = env.HOOX_API_TOKEN?.trim();
|
|
40
|
+
const tokenFromConfig = options.configApiToken?.trim();
|
|
41
|
+
return {
|
|
42
|
+
transport,
|
|
43
|
+
apiBase: stripTrailingSlashes(apiFromEnv || apiFromConfig || DEFAULT_API_BASE),
|
|
44
|
+
bearerToken: tokenFromEnv || tokenFromConfig || "",
|
|
45
|
+
accessClientId,
|
|
46
|
+
accessClientSecret
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function buildOperatorAuthHeaders(profile) {
|
|
50
|
+
const headers = {};
|
|
51
|
+
if (profile.bearerToken) {
|
|
52
|
+
headers.Authorization = `Bearer ${profile.bearerToken}`;
|
|
53
|
+
}
|
|
54
|
+
const useAccessHeaders = profile.transport === "access" || Boolean(profile.accessClientId) && Boolean(profile.accessClientSecret);
|
|
55
|
+
if (useAccessHeaders && profile.accessClientId && profile.accessClientSecret) {
|
|
56
|
+
headers["CF-Access-Client-Id"] = profile.accessClientId;
|
|
57
|
+
headers["CF-Access-Client-Secret"] = profile.accessClientSecret;
|
|
58
|
+
}
|
|
59
|
+
return headers;
|
|
60
|
+
}
|
|
61
|
+
function hasOperatorClientCredentials(profile) {
|
|
62
|
+
if (profile.bearerToken)
|
|
63
|
+
return true;
|
|
64
|
+
return Boolean(profile.accessClientId && profile.accessClientSecret);
|
|
65
|
+
}
|
|
66
|
+
function operatorUrl(profile, path) {
|
|
67
|
+
const base = profile.apiBase.replace(/\/+$/, "");
|
|
68
|
+
const p = path.startsWith("/") ? path : `/${path}`;
|
|
69
|
+
return `${base}${p}`;
|
|
70
|
+
}
|
|
71
|
+
var DEFAULT_API_BASE = "http://localhost:8787", VALID_TRANSPORTS;
|
|
72
|
+
var init_operator_transport = __esm(() => {
|
|
73
|
+
VALID_TRANSPORTS = new Set([
|
|
74
|
+
"public",
|
|
75
|
+
"access",
|
|
76
|
+
"mtls",
|
|
77
|
+
"tunnel"
|
|
78
|
+
]);
|
|
79
|
+
});
|
|
80
|
+
init_operator_transport();
|
|
81
|
+
|
|
82
|
+
export {
|
|
83
|
+
resolveOperatorTransportProfile,
|
|
84
|
+
operatorUrl,
|
|
85
|
+
hasOperatorClientCredentials,
|
|
86
|
+
buildOperatorAuthHeaders
|
|
87
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Branded type for Hoox paths to prevent accidental string usage.
|
|
7
|
+
* This ensures type safety when working with paths.
|
|
8
|
+
*/
|
|
9
|
+
export type HooxPath = string & {
|
|
10
|
+
readonly __brand: "HooxPath";
|
|
11
|
+
};
|
|
12
|
+
/** Where resolveHooxRuntimeRoot found (or failed to find) a setup monorepo. */
|
|
13
|
+
export type RuntimeRootSource = "env" | "cwd" | "global" | "none";
|
|
14
|
+
/** Result of resolveHooxRuntimeRoot(). */
|
|
15
|
+
export interface RuntimeRootResult {
|
|
16
|
+
/** Absolute monorepo root, or null if none found. */
|
|
17
|
+
root: string | null;
|
|
18
|
+
/** Which resolution step produced the result. */
|
|
19
|
+
source: RuntimeRootSource;
|
|
20
|
+
/** Paths inspected (for doctor / error messages). */
|
|
21
|
+
checked: {
|
|
22
|
+
env?: string;
|
|
23
|
+
cwd: string | null;
|
|
24
|
+
global: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets the Hoox home directory location: $HOME/.hoox
|
|
29
|
+
*
|
|
30
|
+
* Behavior:
|
|
31
|
+
* - HOOX_HOME env wins when set (absolute or relative, then resolved)
|
|
32
|
+
* - Else $HOME/.hoox on macOS, Linux, Windows
|
|
33
|
+
* - Falls back to current working directory if HOME is not available
|
|
34
|
+
* - Resolves to absolute path
|
|
35
|
+
*
|
|
36
|
+
* @returns Absolute path to $HOME/.hoox as a branded HooxPath
|
|
37
|
+
* @throws Never — always returns a valid path
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const hooxHome = getHooxHome();
|
|
42
|
+
* // Returns: "/Users/alice/.hoox" (macOS)
|
|
43
|
+
* // Returns: "/home/alice/.hoox" (Linux)
|
|
44
|
+
* // Returns: "C:\\Users\\alice\\.hoox" (Windows)
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function getHooxHome(): HooxPath;
|
|
48
|
+
/**
|
|
49
|
+
* True when `dir` looks like a hoox monorepo root.
|
|
50
|
+
*
|
|
51
|
+
* Markers match CLI verifyRepoRoot: root wrangler.jsonc + packages/cli package.
|
|
52
|
+
*/
|
|
53
|
+
export declare function isHooxSetupRoot(dir: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Walk up from `startDir` looking for a hoox monorepo root.
|
|
56
|
+
*
|
|
57
|
+
* @returns Absolute root path, or null if not found
|
|
58
|
+
*/
|
|
59
|
+
export declare function findHooxSetupRoot(startDir?: string): string | null;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve the Hoox tool/runtime monorepo root (local checkout or global clone).
|
|
62
|
+
*
|
|
63
|
+
* Order:
|
|
64
|
+
* 1. HOOX_REPO — must pass isHooxSetupRoot or result is source "env" with root null
|
|
65
|
+
* 2. Walk up from cwd
|
|
66
|
+
* 3. getHooxRepoPath() ($HOME/.hoox/repo or $HOOX_HOME/repo)
|
|
67
|
+
*
|
|
68
|
+
* Project cwd and tool root are intentionally separate: a random project
|
|
69
|
+
* directory can still use the global runtime for TUI / templates.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveHooxRuntimeRoot(options?: {
|
|
72
|
+
cwd?: string;
|
|
73
|
+
env?: NodeJS.ProcessEnv;
|
|
74
|
+
}): RuntimeRootResult;
|
|
75
|
+
/**
|
|
76
|
+
* Candidate TUI entry files under a monorepo root (source first, then dist).
|
|
77
|
+
*/
|
|
78
|
+
export declare function getTuiEntryCandidates(runtimeRoot: string): string[];
|
|
79
|
+
/**
|
|
80
|
+
* Resolves a relative path within the Hoox home directory.
|
|
81
|
+
*
|
|
82
|
+
* Behavior:
|
|
83
|
+
* - Joins the relative path with $HOME/.hoox
|
|
84
|
+
* - Resolves to absolute path
|
|
85
|
+
* - Prevents path traversal attacks (../ sequences)
|
|
86
|
+
*
|
|
87
|
+
* @param relativePath - Path relative to $HOME/.hoox (e.g., "repo", "config/wrangler.jsonc")
|
|
88
|
+
* @returns Absolute path as a branded HooxPath
|
|
89
|
+
* @throws Error if path contains suspicious traversal patterns
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const repoPath = resolveHooxPath("repo");
|
|
94
|
+
* // Returns: "/Users/alice/.hoox/repo"
|
|
95
|
+
*
|
|
96
|
+
* const configPath = resolveHooxPath("config/wrangler.jsonc");
|
|
97
|
+
* // Returns: "/Users/alice/.hoox/config/wrangler.jsonc"
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function resolveHooxPath(relativePath: string): HooxPath;
|
|
101
|
+
/**
|
|
102
|
+
* Checks if a given path is within the Hoox home directory.
|
|
103
|
+
*
|
|
104
|
+
* @param path - Path to check
|
|
105
|
+
* @returns true if path is within $HOME/.hoox, false otherwise
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* isWithinHooxHome("/Users/alice/.hoox/repo"); // true
|
|
110
|
+
* isWithinHooxHome("/Users/alice/other"); // false
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export declare function isWithinHooxHome(path: string): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Gets the relative path from Hoox home directory.
|
|
116
|
+
*
|
|
117
|
+
* @param absolutePath - Absolute path to resolve
|
|
118
|
+
* @returns Relative path from $HOME/.hoox, or null if path is outside Hoox home
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* getRelativeHooxPath("/Users/alice/.hoox/repo/src");
|
|
123
|
+
* // Returns: "repo/src"
|
|
124
|
+
*
|
|
125
|
+
* getRelativeHooxPath("/Users/alice/other");
|
|
126
|
+
* // Returns: null
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export declare function getRelativeHooxPath(absolutePath: string): string | null;
|
|
130
|
+
/**
|
|
131
|
+
* Constructs a path to the Hoox repository location.
|
|
132
|
+
*
|
|
133
|
+
* @returns Path to $HOME/.hoox/repo as a branded HooxPath
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const repoPath = getHooxRepoPath();
|
|
138
|
+
* // Returns: "/Users/alice/.hoox/repo"
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function getHooxRepoPath(): HooxPath;
|
|
142
|
+
/**
|
|
143
|
+
* Constructs a path to the Hoox configuration directory.
|
|
144
|
+
*
|
|
145
|
+
* @returns Path to $HOME/.hoox/config as a branded HooxPath
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const configDir = getHooxConfigDir();
|
|
150
|
+
* // Returns: "/Users/alice/.hoox/config"
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export declare function getHooxConfigDir(): HooxPath;
|
|
154
|
+
/**
|
|
155
|
+
* Constructs a path to the Hoox data directory.
|
|
156
|
+
*
|
|
157
|
+
* @returns Path to $HOME/.hoox/data as a branded HooxPath
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const dataDir = getHooxDataDir();
|
|
162
|
+
* // Returns: "/Users/alice/.hoox/data"
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
export declare function getHooxDataDir(): HooxPath;
|
|
166
|
+
/**
|
|
167
|
+
* Constructs a path to the Hoox wrangler configuration file.
|
|
168
|
+
*
|
|
169
|
+
* @returns Path to $HOME/.hoox/config/wrangler.jsonc as a branded HooxPath
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* const wranglerPath = getHooxWranglerPath();
|
|
174
|
+
* // Returns: "/Users/alice/.hoox/config/wrangler.jsonc"
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export declare function getHooxWranglerPath(): HooxPath;
|
|
178
|
+
/**
|
|
179
|
+
* Constructs a path to the Hoox state file.
|
|
180
|
+
*
|
|
181
|
+
* @returns Path to $HOME/.hoox/data/state.json as a branded HooxPath
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const statePath = getHooxStatePath();
|
|
186
|
+
* // Returns: "/Users/alice/.hoox/data/state.json"
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export declare function getHooxStatePath(): HooxPath;
|
|
190
|
+
//# sourceMappingURL=path-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0BH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AAEjE,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElE,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,iDAAiD;IACjD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,qDAAqD;IACrD,OAAO,EAAE;QACP,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAgBtC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWpD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,GAAE,MAAsB,GAC/B,MAAM,GAAG,IAAI,CAQf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,iBAAiB,CAoDpB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAOnE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,CAiC9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAStD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBvE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,QAAQ,CAE1C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAE3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,IAAI,QAAQ,CAEzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAE9C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAE3C"}
|
|
@@ -0,0 +1,188 @@
|
|
|
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/path-utils.ts
|
|
19
|
+
import { existsSync } from "fs";
|
|
20
|
+
import { homedir } from "os";
|
|
21
|
+
import { dirname, join, resolve } from "path";
|
|
22
|
+
function createHooxPath(path) {
|
|
23
|
+
return path;
|
|
24
|
+
}
|
|
25
|
+
function getHooxHome() {
|
|
26
|
+
try {
|
|
27
|
+
const override = process.env.HOOX_HOME?.trim();
|
|
28
|
+
if (override) {
|
|
29
|
+
return createHooxPath(resolve(override));
|
|
30
|
+
}
|
|
31
|
+
const home = homedir();
|
|
32
|
+
if (!home || home.length === 0) {
|
|
33
|
+
return createHooxPath(resolve(process.cwd(), ".hoox"));
|
|
34
|
+
}
|
|
35
|
+
return createHooxPath(join(home, ".hoox"));
|
|
36
|
+
} catch {
|
|
37
|
+
return createHooxPath(resolve(process.cwd(), ".hoox"));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function isHooxSetupRoot(dir) {
|
|
41
|
+
if (!dir)
|
|
42
|
+
return false;
|
|
43
|
+
try {
|
|
44
|
+
const root = resolve(dir);
|
|
45
|
+
return existsSync(join(root, "wrangler.jsonc")) && existsSync(join(root, "packages", "cli", "package.json"));
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function findHooxSetupRoot(startDir = process.cwd()) {
|
|
51
|
+
let dir = resolve(startDir);
|
|
52
|
+
for (;; ) {
|
|
53
|
+
if (isHooxSetupRoot(dir))
|
|
54
|
+
return dir;
|
|
55
|
+
const parent = dirname(dir);
|
|
56
|
+
if (parent === dir)
|
|
57
|
+
return null;
|
|
58
|
+
dir = parent;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function resolveHooxRuntimeRoot(options) {
|
|
62
|
+
const env = options?.env ?? process.env;
|
|
63
|
+
const cwd = resolve(options?.cwd ?? process.cwd());
|
|
64
|
+
const globalRepo = getHooxRepoPath();
|
|
65
|
+
const envRepo = env.HOOX_REPO?.trim();
|
|
66
|
+
if (envRepo) {
|
|
67
|
+
const resolved = resolve(envRepo);
|
|
68
|
+
if (isHooxSetupRoot(resolved)) {
|
|
69
|
+
return {
|
|
70
|
+
root: resolved,
|
|
71
|
+
source: "env",
|
|
72
|
+
checked: {
|
|
73
|
+
env: resolved,
|
|
74
|
+
cwd: findHooxSetupRoot(cwd),
|
|
75
|
+
global: globalRepo
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
root: null,
|
|
81
|
+
source: "env",
|
|
82
|
+
checked: {
|
|
83
|
+
env: resolved,
|
|
84
|
+
cwd: findHooxSetupRoot(cwd),
|
|
85
|
+
global: globalRepo
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const local = findHooxSetupRoot(cwd);
|
|
90
|
+
if (local) {
|
|
91
|
+
return {
|
|
92
|
+
root: local,
|
|
93
|
+
source: "cwd",
|
|
94
|
+
checked: { cwd: local, global: globalRepo }
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (isHooxSetupRoot(globalRepo)) {
|
|
98
|
+
return {
|
|
99
|
+
root: globalRepo,
|
|
100
|
+
source: "global",
|
|
101
|
+
checked: { cwd: null, global: globalRepo }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
root: null,
|
|
106
|
+
source: "none",
|
|
107
|
+
checked: { cwd: null, global: globalRepo }
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function getTuiEntryCandidates(runtimeRoot) {
|
|
111
|
+
const root = resolve(runtimeRoot);
|
|
112
|
+
return [
|
|
113
|
+
join(root, "packages", "tui", "src", "main.tsx"),
|
|
114
|
+
join(root, "packages", "tui", "dist", "main.js"),
|
|
115
|
+
join(root, "packages", "tui", "src", "main.ts")
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
function resolveHooxPath(relativePath) {
|
|
119
|
+
if (!relativePath || typeof relativePath !== "string") {
|
|
120
|
+
throw new Error("relativePath must be a non-empty string");
|
|
121
|
+
}
|
|
122
|
+
if (relativePath.includes("..")) {
|
|
123
|
+
throw new Error(`Path traversal detected in relativePath: "${relativePath}"`);
|
|
124
|
+
}
|
|
125
|
+
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
126
|
+
const hooxHome = getHooxHome();
|
|
127
|
+
const fullPath = join(hooxHome, normalizedPath);
|
|
128
|
+
const resolvedPath = resolve(fullPath);
|
|
129
|
+
const resolvedHome = resolve(hooxHome);
|
|
130
|
+
if (!resolvedPath.startsWith(resolvedHome)) {
|
|
131
|
+
throw new Error(`Resolved path "${resolvedPath}" is outside Hoox home directory`);
|
|
132
|
+
}
|
|
133
|
+
return createHooxPath(resolvedPath);
|
|
134
|
+
}
|
|
135
|
+
function isWithinHooxHome(path) {
|
|
136
|
+
try {
|
|
137
|
+
const hooxHome = getHooxHome();
|
|
138
|
+
const resolvedPath = resolve(path);
|
|
139
|
+
const resolvedHome = resolve(hooxHome);
|
|
140
|
+
return resolvedPath.startsWith(resolvedHome);
|
|
141
|
+
} catch {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function getRelativeHooxPath(absolutePath) {
|
|
146
|
+
try {
|
|
147
|
+
if (!isWithinHooxHome(absolutePath)) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const hooxHome = getHooxHome();
|
|
151
|
+
const resolvedPath = resolve(absolutePath);
|
|
152
|
+
const resolvedHome = resolve(hooxHome);
|
|
153
|
+
const relativePath = resolvedPath.slice(resolvedHome.length);
|
|
154
|
+
return relativePath.startsWith("/") || relativePath.startsWith("\\") ? relativePath.slice(1) : relativePath;
|
|
155
|
+
} catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function getHooxRepoPath() {
|
|
160
|
+
return resolveHooxPath("repo");
|
|
161
|
+
}
|
|
162
|
+
function getHooxConfigDir() {
|
|
163
|
+
return resolveHooxPath("config");
|
|
164
|
+
}
|
|
165
|
+
function getHooxDataDir() {
|
|
166
|
+
return resolveHooxPath("data");
|
|
167
|
+
}
|
|
168
|
+
function getHooxWranglerPath() {
|
|
169
|
+
return resolveHooxPath("config/wrangler.jsonc");
|
|
170
|
+
}
|
|
171
|
+
function getHooxStatePath() {
|
|
172
|
+
return resolveHooxPath("data/state.json");
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
resolveHooxRuntimeRoot,
|
|
176
|
+
resolveHooxPath,
|
|
177
|
+
isWithinHooxHome,
|
|
178
|
+
isHooxSetupRoot,
|
|
179
|
+
getTuiEntryCandidates,
|
|
180
|
+
getRelativeHooxPath,
|
|
181
|
+
getHooxWranglerPath,
|
|
182
|
+
getHooxStatePath,
|
|
183
|
+
getHooxRepoPath,
|
|
184
|
+
getHooxHome,
|
|
185
|
+
getHooxDataDir,
|
|
186
|
+
getHooxConfigDir,
|
|
187
|
+
findHooxSetupRoot
|
|
188
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import type { MessageBatch } from "@cloudflare/workers-types";
|
|
6
|
+
export interface QueueHandlerOptions<T> {
|
|
7
|
+
/** Maximum number of retry attempts */
|
|
8
|
+
maxRetries: number;
|
|
9
|
+
/** Array of delay times in seconds for exponential backoff */
|
|
10
|
+
backoffDelays: number[];
|
|
11
|
+
/** Handler function called for each message */
|
|
12
|
+
onMessage: (message: T, attemptNumber: number) => Promise<unknown> | unknown;
|
|
13
|
+
/** Called when a message fails and will be retried */
|
|
14
|
+
onRetry?: (message: T, attemptNumber: number, error: string, delaySeconds: number) => void | Promise<void>;
|
|
15
|
+
/** Called when message is moved to DLQ (max retries exceeded) */
|
|
16
|
+
onDLQ?: (message: T, attemptNumber: number, error: string) => void | Promise<void>;
|
|
17
|
+
/** Logger function for debugging */
|
|
18
|
+
logger?: {
|
|
19
|
+
info(msg: string, data?: unknown): void;
|
|
20
|
+
error(msg: string, data?: unknown): void;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a reusable queue handler with retry + exponential backoff logic.
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const handler = createQueueHandler({
|
|
29
|
+
* maxRetries: 5,
|
|
30
|
+
* backoffDelays: [0, 30, 60, 300, 900],
|
|
31
|
+
* onMessage: async (msg) => {
|
|
32
|
+
* await executeTask(msg);
|
|
33
|
+
* },
|
|
34
|
+
* onDLQ: async (msg, attempts, error) => {
|
|
35
|
+
* await logFailedTask(msg, error);
|
|
36
|
+
* }
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* export default {
|
|
40
|
+
* async queue(batch, env, ctx) {
|
|
41
|
+
* return await handler(batch);
|
|
42
|
+
* }
|
|
43
|
+
* };
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function createQueueHandler<T>(options: QueueHandlerOptions<T>): (batch: MessageBatch<T>) => Promise<void>;
|
|
47
|
+
//# sourceMappingURL=queue-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-handler.d.ts","sourceRoot":"","sources":["../src/queue-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,+CAA+C;IAC/C,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7E,sDAAsD;IACtD,OAAO,CAAC,EAAE,CACR,OAAO,EAAE,CAAC,EACV,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,KACjB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,iEAAiE;IACjE,KAAK,CAAC,EAAE,CACN,OAAO,EAAE,CAAC,EACV,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,KACV,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,oCAAoC;IACpC,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QACxC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KAC1C,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAIrD,OAAO,YAAY,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAmCrD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
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/queue-handler.ts
|
|
19
|
+
function createQueueHandler(options) {
|
|
20
|
+
const { maxRetries, backoffDelays, onMessage, onRetry, onDLQ, logger } = options;
|
|
21
|
+
return async (batch) => {
|
|
22
|
+
for (const msg of batch.messages) {
|
|
23
|
+
const attemptNumber = msg.attempts || 0;
|
|
24
|
+
const logId = `[${msg.id}]`;
|
|
25
|
+
try {
|
|
26
|
+
logger?.info(`${logId} Processing message (attempt ${attemptNumber + 1})`);
|
|
27
|
+
await onMessage(msg.body, attemptNumber);
|
|
28
|
+
logger?.info(`${logId} Message processed successfully`);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
31
|
+
if (attemptNumber < maxRetries) {
|
|
32
|
+
const delaySeconds = backoffDelays[attemptNumber] ?? backoffDelays[backoffDelays.length - 1];
|
|
33
|
+
logger?.info(`${logId} Retrying in ${delaySeconds}s (attempt ${attemptNumber + 2}/${maxRetries + 1})`);
|
|
34
|
+
await onRetry?.(msg.body, attemptNumber, errorMsg, delaySeconds);
|
|
35
|
+
msg.retry({ delaySeconds });
|
|
36
|
+
} else {
|
|
37
|
+
logger?.error(`${logId} Max retries exceeded (${maxRetries + 1} attempts), moving to DLQ`);
|
|
38
|
+
await onDLQ?.(msg.body, attemptNumber, errorMsg);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
createQueueHandler
|
|
46
|
+
};
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Router implementation for Cloudflare Workers
|
|
7
|
+
* Provides standardized routing across all workers with path parameter support
|
|
8
|
+
*
|
|
9
|
+
* Supports exact matching (fast path) and pattern matching for `:param` segments.
|
|
10
|
+
* Path parameters are extracted and passed as the 4th argument to handlers.
|
|
11
|
+
*/
|
|
12
|
+
import type { Router } from "./types/router";
|
|
13
|
+
export type { Handler, MiddlewareHandler, RouteParams } from "./types/router";
|
|
14
|
+
export declare function createRouter<TEnv = unknown>(): Router<TEnv>;
|
|
15
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,OAAO,KAAK,EAKV,MAAM,EACP,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE9E,wBAAgB,YAAY,CAAC,IAAI,GAAG,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,CAsM3D"}
|