@tradejs/infra 2.0.18 → 2.0.20
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/dist/ai.js +39 -74
- package/dist/ai.mjs +37 -74
- package/dist/chunk-2CZREG43.mjs +112 -0
- package/dist/chunk-DFMKDB2R.mjs +1285 -0
- package/dist/chunk-I2J6YDBD.mjs +910 -0
- package/dist/chunk-NWXFWTWU.mjs +1114 -0
- package/dist/chunk-SZQB7ER5.mjs +492 -0
- package/dist/chunk-YVIHTUV5.mjs +286 -0
- package/dist/coreResearch.d.mts +20 -0
- package/dist/coreResearch.d.ts +20 -0
- package/dist/coreResearch.js +89 -0
- package/dist/coreResearch.mjs +48 -0
- package/dist/internal-2coHaaos.d.mts +26 -0
- package/dist/internal-2coHaaos.d.ts +26 -0
- package/dist/ml.mjs +3 -3
- package/dist/runtimeDeployments.d.mts +10 -0
- package/dist/runtimeDeployments.d.ts +10 -0
- package/dist/runtimeDeployments.js +447 -0
- package/dist/runtimeDeployments.mjs +81 -0
- package/dist/runtimeStrategyConfigs.d.mts +28 -0
- package/dist/runtimeStrategyConfigs.d.ts +28 -0
- package/dist/runtimeStrategyConfigs.js +425 -0
- package/dist/runtimeStrategyConfigs.mjs +89 -0
- package/dist/strategyReleaseEvidence.d.mts +12 -0
- package/dist/strategyReleaseEvidence.d.ts +12 -0
- package/dist/strategyReleaseEvidence.js +120 -0
- package/dist/strategyReleaseEvidence.mjs +90 -0
- package/dist/timescale/candles.d.mts +38 -0
- package/dist/timescale/candles.d.ts +38 -0
- package/dist/timescale/candles.js +408 -0
- package/dist/timescale/candles.mjs +21 -0
- package/dist/timescale/client.d.mts +4 -0
- package/dist/timescale/client.d.ts +4 -0
- package/dist/timescale/client.js +109 -0
- package/dist/timescale/client.mjs +12 -0
- package/dist/timescale/derivatives.d.mts +90 -0
- package/dist/timescale/derivatives.d.ts +90 -0
- package/dist/timescale/derivatives.js +1270 -0
- package/dist/timescale/derivatives.mjs +26 -0
- package/dist/timescale/hyperliquidWhales.d.mts +149 -0
- package/dist/timescale/hyperliquidWhales.d.ts +149 -0
- package/dist/timescale/hyperliquidWhales.js +1893 -0
- package/dist/timescale/hyperliquidWhales.mjs +30 -0
- package/dist/timescale/marketContext.d.mts +188 -0
- package/dist/timescale/marketContext.d.ts +188 -0
- package/dist/timescale/marketContext.js +2091 -0
- package/dist/timescale/marketContext.mjs +60 -0
- package/dist/timescale/spread.d.mts +11 -0
- package/dist/timescale/spread.d.ts +11 -0
- package/dist/timescale/spread.js +215 -0
- package/dist/timescale/spread.mjs +11 -0
- package/dist/timescale.d.mts +9 -476
- package/dist/timescale.d.ts +9 -476
- package/dist/timescale.js +2121 -2112
- package/dist/timescale.mjs +73 -4070
- package/dist/tradingAccounts.d.mts +2 -8
- package/dist/tradingAccounts.d.ts +2 -8
- package/dist/tradingAccounts.js +0 -71
- package/dist/tradingAccounts.mjs +0 -65
- package/dist/values-BrvcmnfM.d.mts +6 -0
- package/dist/values-BrvcmnfM.d.ts +6 -0
- package/package.json +53 -2
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/runtimeStrategyConfigs.ts
|
|
31
|
+
var runtimeStrategyConfigs_exports = {};
|
|
32
|
+
__export(runtimeStrategyConfigs_exports, {
|
|
33
|
+
getRuntimeStrategyConfig: () => getRuntimeStrategyConfig,
|
|
34
|
+
getRuntimeStrategyConfigKeys: () => getRuntimeStrategyConfigKeys,
|
|
35
|
+
getRuntimeStrategyResultConfig: () => getRuntimeStrategyResultConfig,
|
|
36
|
+
loadRuntimeStrategyConfigs: () => loadRuntimeStrategyConfigs,
|
|
37
|
+
loadRuntimeStrategyNames: () => loadRuntimeStrategyNames,
|
|
38
|
+
resolveStrategyConfigIdentityByKey: () => resolveStrategyConfigIdentityByKey,
|
|
39
|
+
resolveStrategyNameByConfigKey: () => resolveStrategyNameByConfigKey,
|
|
40
|
+
saveRuntimeStrategyConfig: () => saveRuntimeStrategyConfig
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(runtimeStrategyConfigs_exports);
|
|
43
|
+
|
|
44
|
+
// src/redis.ts
|
|
45
|
+
var import_ioredis = __toESM(require("ioredis"));
|
|
46
|
+
var TTL_1D = 86400;
|
|
47
|
+
var SCREENSHOT_TOKEN_TTL_SECONDS = 15 * 60;
|
|
48
|
+
var toJson = (value) => JSON.stringify(value);
|
|
49
|
+
var logger = {
|
|
50
|
+
log: (level, message, ...args) => {
|
|
51
|
+
const method = level === "error" ? "error" : level === "warn" ? "warn" : "log";
|
|
52
|
+
console[method](`[infra:redis] ${message}`, ...args);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
var redisConnectionWarningShown = false;
|
|
56
|
+
var redisUnavailable = false;
|
|
57
|
+
var isRedisConnectivityError = (error) => {
|
|
58
|
+
const errorText = [error.name, error.message, String(error)].join(" ");
|
|
59
|
+
return /ECONNREFUSED|ECONNRESET|ECONNABORTED|EPIPE|ENOTFOUND|EAI_AGAIN|ETIMEDOUT|MaxRetriesPerRequestError|Connection is closed|Stream isn't writeable/i.test(
|
|
60
|
+
errorText
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
var toNonNegativeInt = (value, fallback) => {
|
|
64
|
+
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
65
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
66
|
+
};
|
|
67
|
+
var toPositiveInt = (value, fallback) => {
|
|
68
|
+
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
69
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
70
|
+
};
|
|
71
|
+
var markRedisUnavailable = (error) => {
|
|
72
|
+
redisUnavailable = true;
|
|
73
|
+
if (redisConnectionWarningShown) return;
|
|
74
|
+
redisConnectionWarningShown = true;
|
|
75
|
+
logger.log(
|
|
76
|
+
"warn",
|
|
77
|
+
"Redis is unavailable: %s. Cache-dependent features are temporarily disabled.",
|
|
78
|
+
error.message
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
var getRedis = () => {
|
|
82
|
+
if (!global.__redis__) {
|
|
83
|
+
const host = process.env.REDIS_HOST || "127.0.0.1";
|
|
84
|
+
const port = toPositiveInt(process.env.REDIS_PORT, 6379);
|
|
85
|
+
const connectTimeout = toPositiveInt(
|
|
86
|
+
process.env.REDIS_CONNECT_TIMEOUT_MS,
|
|
87
|
+
3e3
|
|
88
|
+
);
|
|
89
|
+
const maxRetriesPerRequest = toNonNegativeInt(
|
|
90
|
+
process.env.REDIS_MAX_RETRIES_PER_REQUEST,
|
|
91
|
+
1
|
|
92
|
+
);
|
|
93
|
+
global.__redis__ = new import_ioredis.default({
|
|
94
|
+
host,
|
|
95
|
+
port,
|
|
96
|
+
connectTimeout,
|
|
97
|
+
maxRetriesPerRequest,
|
|
98
|
+
enableOfflineQueue: false,
|
|
99
|
+
retryStrategy: (attempt) => Math.min(attempt * 200, 2e3)
|
|
100
|
+
});
|
|
101
|
+
global.__redis__.on("error", (error) => {
|
|
102
|
+
if (isRedisConnectivityError(error)) {
|
|
103
|
+
markRedisUnavailable(error);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
logger.log("error", "Redis client error: %s", String(error));
|
|
107
|
+
});
|
|
108
|
+
global.__redis__.on("ready", () => {
|
|
109
|
+
redisUnavailable = false;
|
|
110
|
+
if (redisConnectionWarningShown) {
|
|
111
|
+
redisConnectionWarningShown = false;
|
|
112
|
+
logger.log("info", "Redis connection restored");
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return global.__redis__;
|
|
117
|
+
};
|
|
118
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
119
|
+
var getRedisStatus = (redis) => String(redis.status ?? "ready");
|
|
120
|
+
var waitForRedisReady = async (redis) => {
|
|
121
|
+
if (getRedisStatus(redis) === "ready") {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
const readyTimeoutMs = toPositiveInt(
|
|
125
|
+
process.env.REDIS_READY_TIMEOUT_MS,
|
|
126
|
+
toPositiveInt(process.env.REDIS_CONNECT_TIMEOUT_MS, 3e3)
|
|
127
|
+
);
|
|
128
|
+
const startedAt = Date.now();
|
|
129
|
+
while (Date.now() - startedAt < readyTimeoutMs) {
|
|
130
|
+
if (getRedisStatus(redis) === "ready") {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
if (getRedisStatus(redis) === "end") {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
await sleep(50);
|
|
137
|
+
}
|
|
138
|
+
return getRedisStatus(redis) === "ready";
|
|
139
|
+
};
|
|
140
|
+
var getReadyRedis = async () => {
|
|
141
|
+
if (redisUnavailable) return null;
|
|
142
|
+
const redis = getRedis();
|
|
143
|
+
const ready = await waitForRedisReady(redis);
|
|
144
|
+
if (ready) {
|
|
145
|
+
return redis;
|
|
146
|
+
}
|
|
147
|
+
markRedisUnavailable(
|
|
148
|
+
new Error(`Redis is not ready (status=${getRedisStatus(redis)})`)
|
|
149
|
+
);
|
|
150
|
+
return null;
|
|
151
|
+
};
|
|
152
|
+
var toResultString = (result) => {
|
|
153
|
+
if (result == null) return null;
|
|
154
|
+
if (typeof result === "string") return result;
|
|
155
|
+
if (Buffer.isBuffer(result)) return result.toString("utf8");
|
|
156
|
+
return String(result);
|
|
157
|
+
};
|
|
158
|
+
var DEFAULT_OPTIONS = {
|
|
159
|
+
expire: TTL_1D
|
|
160
|
+
};
|
|
161
|
+
var parseJsonOrDeleteKey = async (redis, key, raw, fallback) => {
|
|
162
|
+
try {
|
|
163
|
+
return JSON.parse(raw);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
logger.log("error", "failed JSON.parse(%s): %s", key, String(e));
|
|
166
|
+
await redis.del(key);
|
|
167
|
+
return fallback;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
var getKeys = async (prefix) => {
|
|
171
|
+
if (redisUnavailable) return [];
|
|
172
|
+
const redis = await getReadyRedis();
|
|
173
|
+
if (!redis) return [];
|
|
174
|
+
const keys = [];
|
|
175
|
+
try {
|
|
176
|
+
let cursor = "0";
|
|
177
|
+
do {
|
|
178
|
+
const [nextCursor, batch] = await redis.scan(
|
|
179
|
+
cursor,
|
|
180
|
+
"MATCH",
|
|
181
|
+
`${prefix}*`,
|
|
182
|
+
"COUNT",
|
|
183
|
+
"200"
|
|
184
|
+
);
|
|
185
|
+
cursor = nextCursor;
|
|
186
|
+
for (const key of batch) {
|
|
187
|
+
if (key.startsWith(prefix)) {
|
|
188
|
+
keys.push(key);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} while (cursor !== "0");
|
|
192
|
+
} catch (e) {
|
|
193
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
194
|
+
markRedisUnavailable(e);
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
logger.log("warn", "failed SCAN for %s: %s", prefix, String(e));
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
return keys;
|
|
201
|
+
};
|
|
202
|
+
var getData = async (key, fallback = []) => {
|
|
203
|
+
if (redisUnavailable) return fallback;
|
|
204
|
+
const redis = await getReadyRedis();
|
|
205
|
+
if (!redis) return fallback;
|
|
206
|
+
try {
|
|
207
|
+
const rawJson = await redis.call("JSON.GET", key);
|
|
208
|
+
const raw = toResultString(rawJson);
|
|
209
|
+
if (raw == null) return fallback;
|
|
210
|
+
return parseJsonOrDeleteKey(redis, key, raw, fallback);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
213
|
+
markRedisUnavailable(e);
|
|
214
|
+
return fallback;
|
|
215
|
+
}
|
|
216
|
+
logger.log(
|
|
217
|
+
"error",
|
|
218
|
+
"failed JSON.GET %s: %s (fallback to GET)",
|
|
219
|
+
key,
|
|
220
|
+
String(e)
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const raw = await redis.get(key);
|
|
225
|
+
if (raw == null) return fallback;
|
|
226
|
+
return parseJsonOrDeleteKey(redis, key, raw, fallback);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
229
|
+
markRedisUnavailable(e);
|
|
230
|
+
return fallback;
|
|
231
|
+
}
|
|
232
|
+
logger.log("error", "failed GET %s: %s", key, String(e));
|
|
233
|
+
return fallback;
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
var setData = async (key, data, options = {}) => {
|
|
237
|
+
if (redisUnavailable) return;
|
|
238
|
+
const { expire } = { ...DEFAULT_OPTIONS, ...options };
|
|
239
|
+
const redis = await getReadyRedis();
|
|
240
|
+
if (!redis) return;
|
|
241
|
+
const value = toJson(data);
|
|
242
|
+
try {
|
|
243
|
+
await redis.call("JSON.SET", key, "$", value);
|
|
244
|
+
if (expire) {
|
|
245
|
+
await redis.expire(key, expire);
|
|
246
|
+
}
|
|
247
|
+
} catch (e) {
|
|
248
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
249
|
+
markRedisUnavailable(e);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
logger.log(
|
|
253
|
+
"error",
|
|
254
|
+
"failed JSON.SET %s: %s (fallback to SET)",
|
|
255
|
+
key,
|
|
256
|
+
String(e)
|
|
257
|
+
);
|
|
258
|
+
try {
|
|
259
|
+
if (expire) {
|
|
260
|
+
await redis.set(key, value, "EX", expire);
|
|
261
|
+
} else {
|
|
262
|
+
await redis.set(key, value);
|
|
263
|
+
}
|
|
264
|
+
} catch (e2) {
|
|
265
|
+
if (e2 instanceof Error && isRedisConnectivityError(e2)) {
|
|
266
|
+
markRedisUnavailable(e2);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
logger.log("error", "failed SET %s: %s", key, String(e2));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
var redisKeys = {
|
|
274
|
+
users: () => "users:index:",
|
|
275
|
+
user: (userName) => `users:index:${userName}`,
|
|
276
|
+
tradingAccounts: (userName) => `users:${userName}:trading-accounts:`,
|
|
277
|
+
tradingAccount: (userName, accountId) => `users:${userName}:trading-accounts:${accountId}`,
|
|
278
|
+
runtimeDeployments: (userName) => `users:${userName}:runtime:deployments:`,
|
|
279
|
+
runtimeDeployment: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}`,
|
|
280
|
+
runtimeDeploymentHeartbeat: (userName, deploymentId) => `users:${userName}:runtime:deployments:${deploymentId}:heartbeat`,
|
|
281
|
+
bots: (userName) => `users:${userName}:bots`,
|
|
282
|
+
botsPrefix: () => "users:",
|
|
283
|
+
bot: (userName, botId) => `users:${userName}:bots:${botId}`,
|
|
284
|
+
backtestConfig: (userName, config) => `users:${userName}:backtests:configs:${config}`,
|
|
285
|
+
strategies: (userName) => `users:${userName}:strategies`,
|
|
286
|
+
strategyConfig: (userName, strategyName, configId = "config") => `users:${userName}:strategies:${strategyName}:${configId}`,
|
|
287
|
+
strategyResults: (userName, strategyName) => `users:${userName}:strategies:${strategyName}:results`,
|
|
288
|
+
strategyCharts: (userName, mode) => `users:${userName}:strategies:charts:${mode}`,
|
|
289
|
+
strategyChartCards: (userName, mode) => `users:${userName}:strategies:charts:${mode}:cards:`,
|
|
290
|
+
strategyChartCard: (userName, mode, cardId) => `users:${userName}:strategies:charts:${mode}:cards:${cardId}`,
|
|
291
|
+
tests: (userName, strategyName) => strategyName ? `users:${userName}:tests:${strategyName}` : `users:${userName}:tests:`,
|
|
292
|
+
testOrders: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:orders`,
|
|
293
|
+
testConfig: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:config`,
|
|
294
|
+
testStat: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:stat`,
|
|
295
|
+
testSummaries: (userName) => `users:${userName}:tests:index:summary`,
|
|
296
|
+
cacheChunk: (userName, chunkId) => `users:${userName}:cache:tests:chunks:${chunkId}`,
|
|
297
|
+
cacheOrders: (userName, orderLogId) => `users:${userName}:cache:tests:orders:${orderLogId}`,
|
|
298
|
+
cachePositions: (userName, orderLogId) => `users:${userName}:cache:tests:positions:${orderLogId}`,
|
|
299
|
+
tickerUniverse: (userName, connectorName, universe, accountId) => universe || accountId ? `users:${userName}:cache:tickers:${connectorName}:${universe ?? "crypto"}:${accountId ?? "default"}` : `users:${userName}:cache:tickers:${connectorName}`,
|
|
300
|
+
signal: (symbol, signalId) => `signals:${symbol}:${signalId}`,
|
|
301
|
+
signalsBySymbol: (symbol) => `signals:${symbol}:`,
|
|
302
|
+
storeSignal: (symbol, signalId) => `store:signals:${symbol}:${signalId}`,
|
|
303
|
+
runtimeSignals: (userName) => `users:${userName}:runtime:signals:`,
|
|
304
|
+
runtimeSignal: (userName, signalId) => `users:${userName}:runtime:signals:${signalId}`,
|
|
305
|
+
runtimeSignalBuckets: (userName) => `users:${userName}:runtime:signals:days:`,
|
|
306
|
+
runtimeSignalBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signals:days:${dayKey}:${strategyName}`,
|
|
307
|
+
runtimeSignalEvaluations: (userName) => `users:${userName}:runtime:signal-evaluations:`,
|
|
308
|
+
runtimeSignalEvaluation: (userName, evaluationId) => `users:${userName}:runtime:signal-evaluations:${evaluationId}`,
|
|
309
|
+
runtimeSignalEvaluationBuckets: (userName) => `users:${userName}:runtime:signal-evaluations:days:`,
|
|
310
|
+
runtimeSignalEvaluationBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signal-evaluations:days:${dayKey}:${strategyName}`,
|
|
311
|
+
runtimeSignalEvaluationStatsBuckets: (userName) => `users:${userName}:runtime:signal-evaluation-stats:days:`,
|
|
312
|
+
runtimeSignalEvaluationStatsBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signal-evaluation-stats:days:${dayKey}:${strategyName}`,
|
|
313
|
+
runtimeLineageScopeBucket: (userName, dayKey) => `users:${userName}:runtime:lineage-scopes:days:${dayKey}`,
|
|
314
|
+
runtimeTrades: (userName) => `users:${userName}:runtime:trade-records:`,
|
|
315
|
+
runtimeTrade: (userName, orderId) => `users:${userName}:runtime:trade-records:${orderId}`,
|
|
316
|
+
runtimeTradeBuckets: (userName) => `users:${userName}:runtime:trade-records:days:`,
|
|
317
|
+
runtimeTradeBucket: (userName, dayKey) => `users:${userName}:runtime:trade-records:days:${dayKey}`,
|
|
318
|
+
runtimeClosedTradeBuckets: (userName) => `users:${userName}:runtime:closed-trade-records:days:`,
|
|
319
|
+
runtimeClosedTradeBucket: (userName, dayKey) => `users:${userName}:runtime:closed-trade-records:days:${dayKey}`,
|
|
320
|
+
runtimeActiveTrades: (userName) => `users:${userName}:runtime:active-trades:`,
|
|
321
|
+
runtimeActiveTrade: (userName, symbol, scopeId) => scopeId ? `users:${userName}:runtime:active-trades:${scopeId}:${symbol}` : `users:${userName}:runtime:active-trades:${symbol}`,
|
|
322
|
+
aiChatHistory: (userName, symbolKey) => `users:${userName}:ai:chats:${symbolKey}`,
|
|
323
|
+
analysis: (symbol, signalId) => `analysis:${symbol}:${signalId}`,
|
|
324
|
+
screenshotSessionToken: (token) => `auth:screenshot:${token}`,
|
|
325
|
+
backtestResults: (userName, config, timestamp) => `users:${userName}:backtests:results:${config}:${timestamp}`,
|
|
326
|
+
backtestJobs: (userName) => `users:${userName}:backtests:jobs:`,
|
|
327
|
+
backtestJob: (userName, jobId) => `users:${userName}:backtests:jobs:${jobId}`,
|
|
328
|
+
backtestRuns: (userName) => `users:${userName}:backtests:runs:`,
|
|
329
|
+
backtestRun: (userName, runId) => `users:${userName}:backtests:runs:${runId}`,
|
|
330
|
+
backtestRunResults: (userName, runId) => `users:${userName}:backtests:runs:${runId}:results`,
|
|
331
|
+
backtestLatestRun: (userName, config) => `users:${userName}:backtests:latest:${config}`,
|
|
332
|
+
researchRuns: (userName) => `users:${userName}:research:runs:`,
|
|
333
|
+
researchRun: (userName, runId) => `users:${userName}:research:runs:${runId}`,
|
|
334
|
+
researchLatestRun: (userName, strategyName) => `users:${userName}:research:latest:${strategyName}`,
|
|
335
|
+
mlSignalsByStrategy: (strategyName) => `ml:${strategyName}:signals:`,
|
|
336
|
+
mlSignals: () => "ml:",
|
|
337
|
+
mlSignal: (strategyName, signalId) => `ml:${strategyName}:signals:${signalId}`,
|
|
338
|
+
mlResultsByStrategy: (strategyName) => `ml:${strategyName}:results:`,
|
|
339
|
+
mlResults: () => "ml:",
|
|
340
|
+
mlResult: (strategyName, signalId) => `ml:${strategyName}:results:${signalId}`
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// src/runtimeStrategyConfigs.ts
|
|
344
|
+
var RESERVED_STRATEGY_NAMES = /* @__PURE__ */ new Set(["charts"]);
|
|
345
|
+
var RESERVED_CONFIG_IDS = /* @__PURE__ */ new Set(["results"]);
|
|
346
|
+
var isStrategyConfig = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
347
|
+
var resolveStrategyConfigIdentityByKey = (userName, key) => {
|
|
348
|
+
const parts = key.split(":");
|
|
349
|
+
if (parts.length !== 5) return null;
|
|
350
|
+
const [users, keyUserName, strategiesKey, strategyName, configId] = parts;
|
|
351
|
+
if (users !== "users" || keyUserName !== userName || strategiesKey !== "strategies" || !strategyName || !configId || RESERVED_STRATEGY_NAMES.has(strategyName) || RESERVED_CONFIG_IDS.has(configId) || !/^[a-zA-Z0-9_-]+$/.test(configId)) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
return { strategyName, configId };
|
|
355
|
+
};
|
|
356
|
+
var resolveStrategyNameByConfigKey = (userName, key) => resolveStrategyConfigIdentityByKey(userName, key)?.strategyName ?? null;
|
|
357
|
+
var getRuntimeStrategyConfigKeys = async (userName) => {
|
|
358
|
+
const keys = await getKeys(`${redisKeys.strategies(userName)}:`);
|
|
359
|
+
return keys.filter((key) => resolveStrategyConfigIdentityByKey(userName, key)).sort((left, right) => left.localeCompare(right));
|
|
360
|
+
};
|
|
361
|
+
var loadRuntimeStrategyConfigs = async (userName, {
|
|
362
|
+
onInvalidConfig
|
|
363
|
+
} = {}) => {
|
|
364
|
+
const configKeys = await getRuntimeStrategyConfigKeys(userName);
|
|
365
|
+
const records = await Promise.all(
|
|
366
|
+
configKeys.map(async (key) => {
|
|
367
|
+
const identity = resolveStrategyConfigIdentityByKey(userName, key);
|
|
368
|
+
if (!identity) return null;
|
|
369
|
+
const strategyConfig = await getData(key, null);
|
|
370
|
+
if (!isStrategyConfig(strategyConfig)) {
|
|
371
|
+
onInvalidConfig?.(key);
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
return { key, ...identity, strategyConfig };
|
|
375
|
+
})
|
|
376
|
+
);
|
|
377
|
+
return records.filter(
|
|
378
|
+
(record) => record != null
|
|
379
|
+
);
|
|
380
|
+
};
|
|
381
|
+
var loadRuntimeStrategyNames = async (userName) => [
|
|
382
|
+
...new Set(
|
|
383
|
+
(await getRuntimeStrategyConfigKeys(userName)).map(
|
|
384
|
+
(key) => resolveStrategyConfigIdentityByKey(userName, key)?.strategyName
|
|
385
|
+
).filter(
|
|
386
|
+
(strategyName) => Boolean(strategyName)
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
].sort((left, right) => left.localeCompare(right));
|
|
390
|
+
var getRuntimeStrategyConfig = async (userName, strategyName, configId = "config") => {
|
|
391
|
+
const value = await getData(
|
|
392
|
+
redisKeys.strategyConfig(userName, strategyName, configId),
|
|
393
|
+
null
|
|
394
|
+
);
|
|
395
|
+
return isStrategyConfig(value) ? value : null;
|
|
396
|
+
};
|
|
397
|
+
var saveRuntimeStrategyConfig = async ({
|
|
398
|
+
userName,
|
|
399
|
+
strategyName,
|
|
400
|
+
configId,
|
|
401
|
+
strategyConfig
|
|
402
|
+
}) => {
|
|
403
|
+
const key = redisKeys.strategyConfig(userName, strategyName, configId);
|
|
404
|
+
await setData(key, strategyConfig, { expire: 0 });
|
|
405
|
+
return { key, strategyName, configId, strategyConfig };
|
|
406
|
+
};
|
|
407
|
+
var getRuntimeStrategyResultConfig = async (userName, strategyName, symbol) => {
|
|
408
|
+
const results = await getData(
|
|
409
|
+
redisKeys.strategyResults(userName, strategyName),
|
|
410
|
+
null
|
|
411
|
+
);
|
|
412
|
+
const config = results?.[symbol]?.config;
|
|
413
|
+
return isStrategyConfig(config) ? config : null;
|
|
414
|
+
};
|
|
415
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
416
|
+
0 && (module.exports = {
|
|
417
|
+
getRuntimeStrategyConfig,
|
|
418
|
+
getRuntimeStrategyConfigKeys,
|
|
419
|
+
getRuntimeStrategyResultConfig,
|
|
420
|
+
loadRuntimeStrategyConfigs,
|
|
421
|
+
loadRuntimeStrategyNames,
|
|
422
|
+
resolveStrategyConfigIdentityByKey,
|
|
423
|
+
resolveStrategyNameByConfigKey,
|
|
424
|
+
saveRuntimeStrategyConfig
|
|
425
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getData,
|
|
3
|
+
getKeys,
|
|
4
|
+
redisKeys,
|
|
5
|
+
setData
|
|
6
|
+
} from "./chunk-6ZKAUA4Q.mjs";
|
|
7
|
+
|
|
8
|
+
// src/runtimeStrategyConfigs.ts
|
|
9
|
+
var RESERVED_STRATEGY_NAMES = /* @__PURE__ */ new Set(["charts"]);
|
|
10
|
+
var RESERVED_CONFIG_IDS = /* @__PURE__ */ new Set(["results"]);
|
|
11
|
+
var isStrategyConfig = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
12
|
+
var resolveStrategyConfigIdentityByKey = (userName, key) => {
|
|
13
|
+
const parts = key.split(":");
|
|
14
|
+
if (parts.length !== 5) return null;
|
|
15
|
+
const [users, keyUserName, strategiesKey, strategyName, configId] = parts;
|
|
16
|
+
if (users !== "users" || keyUserName !== userName || strategiesKey !== "strategies" || !strategyName || !configId || RESERVED_STRATEGY_NAMES.has(strategyName) || RESERVED_CONFIG_IDS.has(configId) || !/^[a-zA-Z0-9_-]+$/.test(configId)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return { strategyName, configId };
|
|
20
|
+
};
|
|
21
|
+
var resolveStrategyNameByConfigKey = (userName, key) => resolveStrategyConfigIdentityByKey(userName, key)?.strategyName ?? null;
|
|
22
|
+
var getRuntimeStrategyConfigKeys = async (userName) => {
|
|
23
|
+
const keys = await getKeys(`${redisKeys.strategies(userName)}:`);
|
|
24
|
+
return keys.filter((key) => resolveStrategyConfigIdentityByKey(userName, key)).sort((left, right) => left.localeCompare(right));
|
|
25
|
+
};
|
|
26
|
+
var loadRuntimeStrategyConfigs = async (userName, {
|
|
27
|
+
onInvalidConfig
|
|
28
|
+
} = {}) => {
|
|
29
|
+
const configKeys = await getRuntimeStrategyConfigKeys(userName);
|
|
30
|
+
const records = await Promise.all(
|
|
31
|
+
configKeys.map(async (key) => {
|
|
32
|
+
const identity = resolveStrategyConfigIdentityByKey(userName, key);
|
|
33
|
+
if (!identity) return null;
|
|
34
|
+
const strategyConfig = await getData(key, null);
|
|
35
|
+
if (!isStrategyConfig(strategyConfig)) {
|
|
36
|
+
onInvalidConfig?.(key);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return { key, ...identity, strategyConfig };
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
return records.filter(
|
|
43
|
+
(record) => record != null
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
var loadRuntimeStrategyNames = async (userName) => [
|
|
47
|
+
...new Set(
|
|
48
|
+
(await getRuntimeStrategyConfigKeys(userName)).map(
|
|
49
|
+
(key) => resolveStrategyConfigIdentityByKey(userName, key)?.strategyName
|
|
50
|
+
).filter(
|
|
51
|
+
(strategyName) => Boolean(strategyName)
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
].sort((left, right) => left.localeCompare(right));
|
|
55
|
+
var getRuntimeStrategyConfig = async (userName, strategyName, configId = "config") => {
|
|
56
|
+
const value = await getData(
|
|
57
|
+
redisKeys.strategyConfig(userName, strategyName, configId),
|
|
58
|
+
null
|
|
59
|
+
);
|
|
60
|
+
return isStrategyConfig(value) ? value : null;
|
|
61
|
+
};
|
|
62
|
+
var saveRuntimeStrategyConfig = async ({
|
|
63
|
+
userName,
|
|
64
|
+
strategyName,
|
|
65
|
+
configId,
|
|
66
|
+
strategyConfig
|
|
67
|
+
}) => {
|
|
68
|
+
const key = redisKeys.strategyConfig(userName, strategyName, configId);
|
|
69
|
+
await setData(key, strategyConfig, { expire: 0 });
|
|
70
|
+
return { key, strategyName, configId, strategyConfig };
|
|
71
|
+
};
|
|
72
|
+
var getRuntimeStrategyResultConfig = async (userName, strategyName, symbol) => {
|
|
73
|
+
const results = await getData(
|
|
74
|
+
redisKeys.strategyResults(userName, strategyName),
|
|
75
|
+
null
|
|
76
|
+
);
|
|
77
|
+
const config = results?.[symbol]?.config;
|
|
78
|
+
return isStrategyConfig(config) ? config : null;
|
|
79
|
+
};
|
|
80
|
+
export {
|
|
81
|
+
getRuntimeStrategyConfig,
|
|
82
|
+
getRuntimeStrategyConfigKeys,
|
|
83
|
+
getRuntimeStrategyResultConfig,
|
|
84
|
+
loadRuntimeStrategyConfigs,
|
|
85
|
+
loadRuntimeStrategyNames,
|
|
86
|
+
resolveStrategyConfigIdentityByKey,
|
|
87
|
+
resolveStrategyNameByConfigKey,
|
|
88
|
+
saveRuntimeStrategyConfig
|
|
89
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { StrategyEvidenceMarkerPayload, StrategyEvidenceMarkerEnvelope } from '@tradejs/types';
|
|
2
|
+
|
|
3
|
+
declare const canonicalStrategyEvidenceJson: (value: unknown) => string;
|
|
4
|
+
declare const strategyEvidenceSha256: (value: unknown) => string;
|
|
5
|
+
declare const strategyEvidenceFingerprint: (value: unknown) => string;
|
|
6
|
+
declare const strategyEvidenceFileSha256: (filePath: string) => Promise<string>;
|
|
7
|
+
declare const safeStrategyEvidenceSegment: (value: string, fallback?: string) => string;
|
|
8
|
+
declare const compactStrategyEvidenceTimestamp: (timestamp: number) => string;
|
|
9
|
+
declare const createStrategyEvidenceMarkerEnvelope: (payload: StrategyEvidenceMarkerPayload) => StrategyEvidenceMarkerEnvelope;
|
|
10
|
+
declare const verifyStrategyEvidenceMarkerEnvelope: (value: unknown) => StrategyEvidenceMarkerEnvelope;
|
|
11
|
+
|
|
12
|
+
export { canonicalStrategyEvidenceJson, compactStrategyEvidenceTimestamp, createStrategyEvidenceMarkerEnvelope, safeStrategyEvidenceSegment, strategyEvidenceFileSha256, strategyEvidenceFingerprint, strategyEvidenceSha256, verifyStrategyEvidenceMarkerEnvelope };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { StrategyEvidenceMarkerPayload, StrategyEvidenceMarkerEnvelope } from '@tradejs/types';
|
|
2
|
+
|
|
3
|
+
declare const canonicalStrategyEvidenceJson: (value: unknown) => string;
|
|
4
|
+
declare const strategyEvidenceSha256: (value: unknown) => string;
|
|
5
|
+
declare const strategyEvidenceFingerprint: (value: unknown) => string;
|
|
6
|
+
declare const strategyEvidenceFileSha256: (filePath: string) => Promise<string>;
|
|
7
|
+
declare const safeStrategyEvidenceSegment: (value: string, fallback?: string) => string;
|
|
8
|
+
declare const compactStrategyEvidenceTimestamp: (timestamp: number) => string;
|
|
9
|
+
declare const createStrategyEvidenceMarkerEnvelope: (payload: StrategyEvidenceMarkerPayload) => StrategyEvidenceMarkerEnvelope;
|
|
10
|
+
declare const verifyStrategyEvidenceMarkerEnvelope: (value: unknown) => StrategyEvidenceMarkerEnvelope;
|
|
11
|
+
|
|
12
|
+
export { canonicalStrategyEvidenceJson, compactStrategyEvidenceTimestamp, createStrategyEvidenceMarkerEnvelope, safeStrategyEvidenceSegment, strategyEvidenceFileSha256, strategyEvidenceFingerprint, strategyEvidenceSha256, verifyStrategyEvidenceMarkerEnvelope };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/strategyReleaseEvidence.ts
|
|
21
|
+
var strategyReleaseEvidence_exports = {};
|
|
22
|
+
__export(strategyReleaseEvidence_exports, {
|
|
23
|
+
canonicalStrategyEvidenceJson: () => canonicalStrategyEvidenceJson,
|
|
24
|
+
compactStrategyEvidenceTimestamp: () => compactStrategyEvidenceTimestamp,
|
|
25
|
+
createStrategyEvidenceMarkerEnvelope: () => createStrategyEvidenceMarkerEnvelope,
|
|
26
|
+
safeStrategyEvidenceSegment: () => safeStrategyEvidenceSegment,
|
|
27
|
+
strategyEvidenceFileSha256: () => strategyEvidenceFileSha256,
|
|
28
|
+
strategyEvidenceFingerprint: () => strategyEvidenceFingerprint,
|
|
29
|
+
strategyEvidenceSha256: () => strategyEvidenceSha256,
|
|
30
|
+
verifyStrategyEvidenceMarkerEnvelope: () => verifyStrategyEvidenceMarkerEnvelope
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(strategyReleaseEvidence_exports);
|
|
33
|
+
var import_node_crypto = require("crypto");
|
|
34
|
+
var import_node_fs = require("fs");
|
|
35
|
+
var import_types = require("@tradejs/types");
|
|
36
|
+
var SHA256_RE = /^[a-f0-9]{64}$/;
|
|
37
|
+
var LINEAGE_FINGERPRINT_RE = /^[a-f0-9]{16}$/;
|
|
38
|
+
var MARKER_TYPES = /* @__PURE__ */ new Set([
|
|
39
|
+
"G",
|
|
40
|
+
"L",
|
|
41
|
+
"E",
|
|
42
|
+
"D",
|
|
43
|
+
"P",
|
|
44
|
+
"R"
|
|
45
|
+
]);
|
|
46
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
47
|
+
var isString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
48
|
+
var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
49
|
+
var canonicalStrategyEvidenceJson = (value) => {
|
|
50
|
+
const normalize = (current) => {
|
|
51
|
+
if (Array.isArray(current)) return current.map(normalize);
|
|
52
|
+
const record = asRecord(current);
|
|
53
|
+
if (!record) return current;
|
|
54
|
+
return Object.fromEntries(
|
|
55
|
+
Object.entries(record).filter(([, entry]) => entry !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, normalize(entry)])
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
return JSON.stringify(normalize(value));
|
|
59
|
+
};
|
|
60
|
+
var strategyEvidenceSha256 = (value) => (0, import_node_crypto.createHash)("sha256").update(canonicalStrategyEvidenceJson(value)).digest("hex");
|
|
61
|
+
var strategyEvidenceFingerprint = (value) => strategyEvidenceSha256(value).slice(0, 16);
|
|
62
|
+
var strategyEvidenceFileSha256 = async (filePath) => {
|
|
63
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
64
|
+
for await (const chunk of (0, import_node_fs.createReadStream)(filePath)) hash.update(chunk);
|
|
65
|
+
return hash.digest("hex");
|
|
66
|
+
};
|
|
67
|
+
var safeStrategyEvidenceSegment = (value, fallback = "strategy") => {
|
|
68
|
+
const safe = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
69
|
+
return safe && safe !== "." && safe !== ".." ? safe : fallback;
|
|
70
|
+
};
|
|
71
|
+
var compactStrategyEvidenceTimestamp = (timestamp) => new Date(timestamp).toISOString().replace(/[-:]/g, "").replace(/\.000Z$/, "Z");
|
|
72
|
+
var createStrategyEvidenceMarkerEnvelope = (payload) => {
|
|
73
|
+
const payloadSha256 = strategyEvidenceSha256(payload);
|
|
74
|
+
return {
|
|
75
|
+
schema: import_types.STRATEGY_EVIDENCE_MARKERS_SCHEMA,
|
|
76
|
+
artifactId: `${safeStrategyEvidenceSegment(payload.strategy)}_${compactStrategyEvidenceTimestamp(payload.createdAt)}_${payloadSha256.slice(0, 16)}`,
|
|
77
|
+
payloadSha256,
|
|
78
|
+
payload
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
var verifyStrategyEvidenceMarkerEnvelope = (value) => {
|
|
82
|
+
const envelope = asRecord(value);
|
|
83
|
+
const payload = asRecord(envelope?.payload);
|
|
84
|
+
if (envelope?.schema !== import_types.STRATEGY_EVIDENCE_MARKERS_SCHEMA || !isString(envelope.artifactId) || !isString(envelope.payloadSha256) || !SHA256_RE.test(envelope.payloadSha256) || !payload || !isString(payload.strategy) || !isNumber(payload.createdAt) || !Array.isArray(payload.markers) || !Array.isArray(payload.sourceArtifacts)) {
|
|
85
|
+
throw new Error("Invalid strategy evidence marker envelope");
|
|
86
|
+
}
|
|
87
|
+
for (const value2 of payload.markers) {
|
|
88
|
+
const marker = asRecord(value2);
|
|
89
|
+
const coverage = asRecord(marker?.coverage);
|
|
90
|
+
if (!marker || !isString(marker.id) || !isString(marker.type) || !MARKER_TYPES.has(marker.type) || !isNumber(marker.timestamp) || !isString(marker.label) || !isString(marker.summary) || !isString(marker.artifactId) || !isString(marker.artifactSha256) || !SHA256_RE.test(marker.artifactSha256) || marker.gitSha !== void 0 && !isString(marker.gitSha) || marker.gateFingerprint !== void 0 && (!isString(marker.gateFingerprint) || !LINEAGE_FINGERPRINT_RE.test(marker.gateFingerprint)) || marker.configFingerprint !== void 0 && (!isString(marker.configFingerprint) || !LINEAGE_FINGERPRINT_RE.test(marker.configFingerprint)) || marker.contextFingerprint !== void 0 && (!isString(marker.contextFingerprint) || !LINEAGE_FINGERPRINT_RE.test(marker.contextFingerprint)) || marker.maxLossValue !== void 0 && !isNumber(marker.maxLossValue) || marker.coverage !== void 0 && (!coverage || !isNumber(coverage.startTime) || !isNumber(coverage.endTime) || coverage.startTime > coverage.endTime)) {
|
|
91
|
+
throw new Error("Invalid strategy evidence marker");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const value2 of payload.sourceArtifacts) {
|
|
95
|
+
const artifact = asRecord(value2);
|
|
96
|
+
if (!artifact || !isString(artifact.artifactId) || !isString(artifact.sha256) || !SHA256_RE.test(artifact.sha256) || artifact.path !== void 0 && typeof artifact.path !== "string") {
|
|
97
|
+
throw new Error("Invalid strategy evidence source artifact");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const payloadSha256 = strategyEvidenceSha256(payload);
|
|
101
|
+
if (payloadSha256 !== envelope.payloadSha256) {
|
|
102
|
+
throw new Error("Strategy evidence marker checksum mismatch");
|
|
103
|
+
}
|
|
104
|
+
const expectedId = `${safeStrategyEvidenceSegment(payload.strategy)}_${compactStrategyEvidenceTimestamp(payload.createdAt)}_${payloadSha256.slice(0, 16)}`;
|
|
105
|
+
if (expectedId !== envelope.artifactId) {
|
|
106
|
+
throw new Error("Strategy evidence marker artifact identity mismatch");
|
|
107
|
+
}
|
|
108
|
+
return value;
|
|
109
|
+
};
|
|
110
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
111
|
+
0 && (module.exports = {
|
|
112
|
+
canonicalStrategyEvidenceJson,
|
|
113
|
+
compactStrategyEvidenceTimestamp,
|
|
114
|
+
createStrategyEvidenceMarkerEnvelope,
|
|
115
|
+
safeStrategyEvidenceSegment,
|
|
116
|
+
strategyEvidenceFileSha256,
|
|
117
|
+
strategyEvidenceFingerprint,
|
|
118
|
+
strategyEvidenceSha256,
|
|
119
|
+
verifyStrategyEvidenceMarkerEnvelope
|
|
120
|
+
});
|