@tradejs/cli 3.1.2 → 3.1.3

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/cli.js CHANGED
@@ -28102,16 +28102,19 @@ var init_runtimeScorecard2 = __esm({
28102
28102
  var runtimeConfig_exports = {};
28103
28103
  __export(runtimeConfig_exports, {
28104
28104
  buildBootstrapRuntimeDeployment: () => buildBootstrapRuntimeDeployment,
28105
+ isEquivalentRuntimeStrategyRelease: () => isEquivalentRuntimeStrategyRelease,
28105
28106
  main: () => main37,
28107
+ pointRuntimeDeploymentAtRelease: () => pointRuntimeDeploymentAtRelease,
28106
28108
  runtimeConfig: () => runtimeConfig
28107
28109
  });
28108
- var import_config9, import_promises28, import_node_path23, import_runtimeDeployments2, import_runtimeStrategyConfigs2, import_runtimeStrategyReleases, import_runtimeStrategies, import_strategies11, argv, action, option, hasFlag, required2, projectRoot12, userName2, OPERATIONAL_CONFIG_KEYS, toReleaseConfig, writeMigrationBackup, publish, buildBootstrapRuntimeDeployment, bootstrap, migrate, publishDraft, updateControlState, rollback, verify, inspect, runtimeConfig, main37;
28110
+ var import_config9, import_promises28, import_node_path23, import_node_util2, import_runtimeDeployments2, import_runtimeStrategyConfigs2, import_runtimeStrategyReleases, import_runtimeStrategies, import_strategies11, argv, action, option, hasFlag, required2, projectRoot12, userName2, OPERATIONAL_CONFIG_KEYS, toReleaseConfig, writeMigrationBackup, publish, buildBootstrapRuntimeDeployment, isEquivalentRuntimeStrategyRelease, pointRuntimeDeploymentAtRelease, bootstrap, migrate, rollout, publishDraft, updateControlState, rollback, verify, inspect, runtimeConfig, main37;
28109
28111
  var init_runtimeConfig = __esm({
28110
28112
  "src/scripts/runtimeConfig.ts"() {
28111
28113
  "use strict";
28112
28114
  import_config9 = require("dotenv/config");
28113
28115
  import_promises28 = require("fs/promises");
28114
28116
  import_node_path23 = __toESM(require("path"));
28117
+ import_node_util2 = require("util");
28115
28118
  import_runtimeDeployments2 = require("@tradejs/infra/runtimeDeployments");
28116
28119
  import_runtimeStrategyConfigs2 = require("@tradejs/infra/runtimeStrategyConfigs");
28117
28120
  import_runtimeStrategyReleases = require("@tradejs/infra/runtimeStrategyReleases");
@@ -28203,6 +28206,29 @@ var init_runtimeConfig = __esm({
28203
28206
  }
28204
28207
  ]
28205
28208
  });
28209
+ isEquivalentRuntimeStrategyRelease = ({
28210
+ release,
28211
+ config: config2,
28212
+ strategyPackage,
28213
+ strategyPackageVersion,
28214
+ runtimePackageVersion
28215
+ }) => Boolean(
28216
+ release && (0, import_node_util2.isDeepStrictEqual)(release.config, config2) && (release.strategyPackage ?? null) === (strategyPackage ?? null) && (release.strategyPackageVersion ?? null) === (strategyPackageVersion ?? null) && (release.runtimePackageVersion ?? null) === (runtimePackageVersion ?? null)
28217
+ );
28218
+ pointRuntimeDeploymentAtRelease = ({
28219
+ deployment,
28220
+ strategyName,
28221
+ releaseVersion
28222
+ }) => ({
28223
+ ...deployment,
28224
+ strategies: deployment.strategies.map(
28225
+ (strategy) => strategy.strategyName === strategyName ? {
28226
+ strategyName,
28227
+ releaseVersion,
28228
+ controlState: "entries_paused"
28229
+ } : strategy
28230
+ )
28231
+ });
28206
28232
  bootstrap = async () => {
28207
28233
  const strategyName = required2("strategy");
28208
28234
  const deploymentId = required2("deployment");
@@ -28340,6 +28366,95 @@ var init_runtimeConfig = __esm({
28340
28366
  )
28341
28367
  );
28342
28368
  };
28369
+ rollout = async () => {
28370
+ const strategyName = required2("strategy");
28371
+ const deploymentId = required2("deployment");
28372
+ const configFile = import_node_path23.default.resolve(projectRoot12, required2("file"));
28373
+ const [deployment, sourceConfig] = await Promise.all([
28374
+ (0, import_runtimeDeployments2.getRuntimeDeployment)(userName2, deploymentId),
28375
+ (0, import_promises28.readFile)(configFile, "utf8").then(
28376
+ (value) => JSON.parse(value)
28377
+ )
28378
+ ]);
28379
+ if (!deployment) throw new Error(`Deployment not found: ${deploymentId}`);
28380
+ const reference = deployment.strategies.find(
28381
+ (strategy) => strategy.strategyName === strategyName
28382
+ );
28383
+ if (!reference?.releaseVersion) {
28384
+ throw new Error(`${strategyName} is not a versioned deployment reference`);
28385
+ }
28386
+ const [config2, metadata, currentRelease] = await Promise.all([
28387
+ toReleaseConfig(strategyName, sourceConfig),
28388
+ (0, import_runtimeStrategies.getRuntimeStrategyPackageMetadata)({ strategyName, projectRoot: projectRoot12 }),
28389
+ (0, import_runtimeStrategyReleases.getRuntimeStrategyRelease)(userName2, strategyName, reference.releaseVersion)
28390
+ ]);
28391
+ const unchanged = isEquivalentRuntimeStrategyRelease({
28392
+ release: currentRelease,
28393
+ config: config2,
28394
+ ...metadata
28395
+ });
28396
+ const preview = {
28397
+ deploymentId,
28398
+ strategyName,
28399
+ currentReleaseVersion: reference.releaseVersion,
28400
+ nextControlState: "entries_paused",
28401
+ unchanged,
28402
+ config: config2,
28403
+ ...metadata
28404
+ };
28405
+ if (!hasFlag("write")) {
28406
+ console.log(JSON.stringify({ dryRun: true, ...preview }, null, 2));
28407
+ return;
28408
+ }
28409
+ if (unchanged) {
28410
+ console.log(
28411
+ JSON.stringify(
28412
+ {
28413
+ rolledOut: false,
28414
+ reason: "release_config_and_packages_unchanged",
28415
+ release: currentRelease,
28416
+ deployment
28417
+ },
28418
+ null,
28419
+ 2
28420
+ )
28421
+ );
28422
+ return;
28423
+ }
28424
+ const backupPath = await writeMigrationBackup({
28425
+ userName: userName2,
28426
+ capturedAt: Date.now(),
28427
+ reason: "rollout",
28428
+ deployment,
28429
+ currentRelease,
28430
+ sourceConfig
28431
+ });
28432
+ const release = await (0, import_runtimeStrategyReleases.publishRuntimeStrategyRelease)({
28433
+ userName: userName2,
28434
+ strategyName,
28435
+ config: config2,
28436
+ ...metadata,
28437
+ createdBy: `cli:${userName2}`
28438
+ });
28439
+ const updatedDeployment = pointRuntimeDeploymentAtRelease({
28440
+ deployment,
28441
+ strategyName,
28442
+ releaseVersion: release.releaseVersion
28443
+ });
28444
+ await (0, import_runtimeDeployments2.saveRuntimeDeployment)(userName2, updatedDeployment);
28445
+ console.log(
28446
+ JSON.stringify(
28447
+ {
28448
+ rolledOut: true,
28449
+ backupPath,
28450
+ release,
28451
+ deployment: updatedDeployment
28452
+ },
28453
+ null,
28454
+ 2
28455
+ )
28456
+ );
28457
+ };
28343
28458
  publishDraft = async () => {
28344
28459
  const strategyName = required2("strategy");
28345
28460
  const draft = await (0, import_runtimeStrategyReleases.getRuntimeStrategyDraft)(userName2, strategyName);
@@ -28450,6 +28565,7 @@ var init_runtimeConfig = __esm({
28450
28565
  runtimeConfig = async () => {
28451
28566
  if (action === "bootstrap") return bootstrap();
28452
28567
  if (action === "migrate") return migrate();
28568
+ if (action === "rollout") return rollout();
28453
28569
  if (action === "publish-draft") return publishDraft();
28454
28570
  if (action === "verify") return verify();
28455
28571
  if (action === "pause") return updateControlState("entries_paused");
@@ -28457,7 +28573,7 @@ var init_runtimeConfig = __esm({
28457
28573
  if (action === "rollback") return rollback();
28458
28574
  if (action === "inspect") return inspect();
28459
28575
  throw new Error(
28460
- "Usage: tradejs runtime-config inspect|verify|bootstrap|migrate|publish-draft|pause|resume|rollback"
28576
+ "Usage: tradejs runtime-config inspect|verify|bootstrap|migrate|rollout|publish-draft|pause|resume|rollback"
28461
28577
  );
28462
28578
  };
28463
28579
  main37 = runtimeConfig;
@@ -31,13 +31,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var runtimeConfig_exports = {};
32
32
  __export(runtimeConfig_exports, {
33
33
  buildBootstrapRuntimeDeployment: () => buildBootstrapRuntimeDeployment,
34
+ isEquivalentRuntimeStrategyRelease: () => isEquivalentRuntimeStrategyRelease,
34
35
  main: () => main,
36
+ pointRuntimeDeploymentAtRelease: () => pointRuntimeDeploymentAtRelease,
35
37
  runtimeConfig: () => runtimeConfig
36
38
  });
37
39
  module.exports = __toCommonJS(runtimeConfig_exports);
38
40
  var import_config = require("dotenv/config");
39
41
  var import_promises = require("fs/promises");
40
42
  var import_node_path = __toESM(require("path"));
43
+ var import_node_util = require("util");
41
44
  var import_runtimeDeployments = require("@tradejs/infra/runtimeDeployments");
42
45
  var import_runtimeStrategyConfigs = require("@tradejs/infra/runtimeStrategyConfigs");
43
46
  var import_runtimeStrategyReleases = require("@tradejs/infra/runtimeStrategyReleases");
@@ -129,6 +132,29 @@ var buildBootstrapRuntimeDeployment = ({
129
132
  }
130
133
  ]
131
134
  });
135
+ var isEquivalentRuntimeStrategyRelease = ({
136
+ release,
137
+ config,
138
+ strategyPackage,
139
+ strategyPackageVersion,
140
+ runtimePackageVersion
141
+ }) => Boolean(
142
+ release && (0, import_node_util.isDeepStrictEqual)(release.config, config) && (release.strategyPackage ?? null) === (strategyPackage ?? null) && (release.strategyPackageVersion ?? null) === (strategyPackageVersion ?? null) && (release.runtimePackageVersion ?? null) === (runtimePackageVersion ?? null)
143
+ );
144
+ var pointRuntimeDeploymentAtRelease = ({
145
+ deployment,
146
+ strategyName,
147
+ releaseVersion
148
+ }) => ({
149
+ ...deployment,
150
+ strategies: deployment.strategies.map(
151
+ (strategy) => strategy.strategyName === strategyName ? {
152
+ strategyName,
153
+ releaseVersion,
154
+ controlState: "entries_paused"
155
+ } : strategy
156
+ )
157
+ });
132
158
  var bootstrap = async () => {
133
159
  const strategyName = required("strategy");
134
160
  const deploymentId = required("deployment");
@@ -266,6 +292,95 @@ var migrate = async () => {
266
292
  )
267
293
  );
268
294
  };
295
+ var rollout = async () => {
296
+ const strategyName = required("strategy");
297
+ const deploymentId = required("deployment");
298
+ const configFile = import_node_path.default.resolve(projectRoot, required("file"));
299
+ const [deployment, sourceConfig] = await Promise.all([
300
+ (0, import_runtimeDeployments.getRuntimeDeployment)(userName, deploymentId),
301
+ (0, import_promises.readFile)(configFile, "utf8").then(
302
+ (value) => JSON.parse(value)
303
+ )
304
+ ]);
305
+ if (!deployment) throw new Error(`Deployment not found: ${deploymentId}`);
306
+ const reference = deployment.strategies.find(
307
+ (strategy) => strategy.strategyName === strategyName
308
+ );
309
+ if (!reference?.releaseVersion) {
310
+ throw new Error(`${strategyName} is not a versioned deployment reference`);
311
+ }
312
+ const [config, metadata, currentRelease] = await Promise.all([
313
+ toReleaseConfig(strategyName, sourceConfig),
314
+ (0, import_runtimeStrategies.getRuntimeStrategyPackageMetadata)({ strategyName, projectRoot }),
315
+ (0, import_runtimeStrategyReleases.getRuntimeStrategyRelease)(userName, strategyName, reference.releaseVersion)
316
+ ]);
317
+ const unchanged = isEquivalentRuntimeStrategyRelease({
318
+ release: currentRelease,
319
+ config,
320
+ ...metadata
321
+ });
322
+ const preview = {
323
+ deploymentId,
324
+ strategyName,
325
+ currentReleaseVersion: reference.releaseVersion,
326
+ nextControlState: "entries_paused",
327
+ unchanged,
328
+ config,
329
+ ...metadata
330
+ };
331
+ if (!hasFlag("write")) {
332
+ console.log(JSON.stringify({ dryRun: true, ...preview }, null, 2));
333
+ return;
334
+ }
335
+ if (unchanged) {
336
+ console.log(
337
+ JSON.stringify(
338
+ {
339
+ rolledOut: false,
340
+ reason: "release_config_and_packages_unchanged",
341
+ release: currentRelease,
342
+ deployment
343
+ },
344
+ null,
345
+ 2
346
+ )
347
+ );
348
+ return;
349
+ }
350
+ const backupPath = await writeMigrationBackup({
351
+ userName,
352
+ capturedAt: Date.now(),
353
+ reason: "rollout",
354
+ deployment,
355
+ currentRelease,
356
+ sourceConfig
357
+ });
358
+ const release = await (0, import_runtimeStrategyReleases.publishRuntimeStrategyRelease)({
359
+ userName,
360
+ strategyName,
361
+ config,
362
+ ...metadata,
363
+ createdBy: `cli:${userName}`
364
+ });
365
+ const updatedDeployment = pointRuntimeDeploymentAtRelease({
366
+ deployment,
367
+ strategyName,
368
+ releaseVersion: release.releaseVersion
369
+ });
370
+ await (0, import_runtimeDeployments.saveRuntimeDeployment)(userName, updatedDeployment);
371
+ console.log(
372
+ JSON.stringify(
373
+ {
374
+ rolledOut: true,
375
+ backupPath,
376
+ release,
377
+ deployment: updatedDeployment
378
+ },
379
+ null,
380
+ 2
381
+ )
382
+ );
383
+ };
269
384
  var publishDraft = async () => {
270
385
  const strategyName = required("strategy");
271
386
  const draft = await (0, import_runtimeStrategyReleases.getRuntimeStrategyDraft)(userName, strategyName);
@@ -376,6 +491,7 @@ var inspect = async () => {
376
491
  var runtimeConfig = async () => {
377
492
  if (action === "bootstrap") return bootstrap();
378
493
  if (action === "migrate") return migrate();
494
+ if (action === "rollout") return rollout();
379
495
  if (action === "publish-draft") return publishDraft();
380
496
  if (action === "verify") return verify();
381
497
  if (action === "pause") return updateControlState("entries_paused");
@@ -383,13 +499,15 @@ var runtimeConfig = async () => {
383
499
  if (action === "rollback") return rollback();
384
500
  if (action === "inspect") return inspect();
385
501
  throw new Error(
386
- "Usage: tradejs runtime-config inspect|verify|bootstrap|migrate|publish-draft|pause|resume|rollback"
502
+ "Usage: tradejs runtime-config inspect|verify|bootstrap|migrate|rollout|publish-draft|pause|resume|rollback"
387
503
  );
388
504
  };
389
505
  var main = runtimeConfig;
390
506
  // Annotate the CommonJS export names for ESM import in node:
391
507
  0 && (module.exports = {
392
508
  buildBootstrapRuntimeDeployment,
509
+ isEquivalentRuntimeStrategyRelease,
393
510
  main,
511
+ pointRuntimeDeploymentAtRelease,
394
512
  runtimeConfig
395
513
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/cli",
3
- "version": "3.1.2",
3
+ "version": "3.1.3",
4
4
  "description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -32,13 +32,13 @@
32
32
  "tradejs": "dist/cli.js"
33
33
  },
34
34
  "dependencies": {
35
- "@tradejs/connectors": "^3.1.2",
36
- "@tradejs/core": "^3.1.2",
37
- "@tradejs/indicators": "^3.1.2",
38
- "@tradejs/infra": "^3.1.2",
39
- "@tradejs/node": "^3.1.2",
35
+ "@tradejs/connectors": "^3.1.3",
36
+ "@tradejs/core": "^3.1.3",
37
+ "@tradejs/indicators": "^3.1.3",
38
+ "@tradejs/infra": "^3.1.3",
39
+ "@tradejs/node": "^3.1.3",
40
40
  "@tradejs/strategy-kit": "^3.0.0",
41
- "@tradejs/types": "^3.1.2",
41
+ "@tradejs/types": "^3.1.3",
42
42
  "args": "^5.0.3",
43
43
  "bcryptjs": "^2.4.3",
44
44
  "chalk": "4.1.2",