@revturbine/cli 0.5.2 → 0.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 (2) hide show
  1. package/dist/cli.js +43 -3
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3979,6 +3979,13 @@ var RevTurbineConfigSchema = z19.object({
3979
3979
  // The change set this export represents: the active change set by default,
3980
3980
  // or a specific change set when one is requested. Null for an unscoped export.
3981
3981
  change_set_id: z19.string().nullable().default(null).meta({ ...Unrestricted16, readOnly: true }),
3982
+ // Origin target identity (plan 131 TASK-10, cli.md "Target-aware, portable"):
3983
+ // stamped by the server on export so a downloaded Config File records where
3984
+ // it came from; upload tooling targets these by default and flags a tenant
3985
+ // mismatch against the session before sending. Optional — hand-authored and
3986
+ // pre-existing configs carry no target.
3987
+ tenant_id: z19.string().optional().meta({ ...Unrestricted16, readOnly: true }),
3988
+ environment_id: z19.string().optional().meta({ ...Unrestricted16, readOnly: true }),
3982
3989
  plans: z19.array(RevTurbineConfigPlansItemSchema).meta(Unrestricted16),
3983
3990
  // Optional for back-compat: pre-plan-88 configs (and the live export until web
3984
3991
  // adopts the new @revt-eng/schema) omit it. Add-on definitions only; pricing
@@ -5562,7 +5569,7 @@ function evaluate(graph, opts = {}) {
5562
5569
  }
5563
5570
 
5564
5571
  // src/schema/version.ts
5565
- var SCHEMA_VERSION = "0.1.107";
5572
+ var SCHEMA_VERSION = "0.1.108";
5566
5573
 
5567
5574
  // src/lib/credentials.ts
5568
5575
  import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
@@ -6024,6 +6031,26 @@ function requireSelectors(opts, positionalFiles, {
6024
6031
  return found;
6025
6032
  }
6026
6033
 
6034
+ // src/lib/target.ts
6035
+ function resolveUploadTarget(params) {
6036
+ const embedded = params.embedded ?? void 0;
6037
+ const explicit = params.explicit ?? void 0;
6038
+ if (explicit) {
6039
+ return {
6040
+ ok: true,
6041
+ tenantId: explicit,
6042
+ note: embedded && embedded !== explicit ? `retargeting deliberately: config was exported from ${embedded}, sending to ${explicit} (-t)` : void 0
6043
+ };
6044
+ }
6045
+ if (!embedded || embedded === params.session) {
6046
+ return { ok: true, tenantId: params.session };
6047
+ }
6048
+ return {
6049
+ ok: false,
6050
+ error: `this config was exported from tenant ${embedded}, but the session targets ${params.session}. Pass -t ${embedded} to send it back where it came from, or -t ${params.session} to retarget it deliberately.`
6051
+ };
6052
+ }
6053
+
6027
6054
  // src/lib/version-trail.ts
6028
6055
  function serverSchemaIsNewer(config, bundledVersion) {
6029
6056
  const server = config?.schema_version;
@@ -6086,6 +6113,17 @@ function connect(rawUrl, explicitTenantId) {
6086
6113
  }
6087
6114
  };
6088
6115
  }
6116
+ function uploadTenantFor(rawUrl, config, explicit) {
6117
+ const cred = getCredential(normalizeBaseUrl(rawUrl));
6118
+ const target = resolveUploadTarget({
6119
+ embedded: config?.tenant_id,
6120
+ explicit,
6121
+ session: cred?.tenant_id ?? "dev-tenant-001"
6122
+ });
6123
+ if (!target.ok) fail(EXIT.VALIDATION, target.error);
6124
+ if (target.note) diag(target.note);
6125
+ return target.tenantId;
6126
+ }
6089
6127
  function authHint(url, status) {
6090
6128
  if (status === 401 || status === 403) {
6091
6129
  diag(`Authentication required for ${url}. Log in with:
@@ -6526,7 +6564,7 @@ program.command("show").description(`Render a summary view of a config version.
6526
6564
  program.command("upload").description("Stage a Config File as the open draft (POST /api/config/import).").argument("<config>", "Path to a Config File").option("-u, --url <url>", "RevTurbine instance URL", DEFAULT_URL).option("-t, --tenant-id <id>", "x-tenant-id (defaults to the stored token tenant)").action(async (configFile2, opts) => {
6527
6565
  const config = verifyConfig(configFile2);
6528
6566
  if (config === null) fail(EXIT.VALIDATION, `Fix the issues above in ${configFile2}, then re-run.`);
6529
- const conn = connect(opts.url, opts.tenantId);
6567
+ const conn = connect(opts.url, uploadTenantFor(opts.url, config, opts.tenantId));
6530
6568
  diag(`Staging ${configFile2} as the open draft (${conn.url}/api/config/import) \u2026`);
6531
6569
  const { res, json } = await postJson(conn, "/api/config/import", config);
6532
6570
  if (!res.ok) {
@@ -6546,11 +6584,12 @@ program.command("upload").description("Stage a Config File as the open draft (PO
6546
6584
  });
6547
6585
  program.command("launch").description("Take a config live as a new Release: validate (launch gate), then submit \u2192 approve \u2192 deploy. Synchronous.").argument("[file]", "Config File to upload and launch directly").option("--draft", "Launch the already-open draft").option("-u, --url <url>", "RevTurbine instance URL", DEFAULT_URL).option("-t, --tenant-id <id>", "x-tenant-id (defaults to the stored token tenant)").option("--yes", "Accepted for parity with discard/restore; launch has no confirmation prompt").action(async (file, opts) => {
6548
6586
  const [sel] = requireSelectors(opts, file ? [file] : [], { count: 1, allowed: ["file", "draft"], command: "launch" });
6549
- const conn = connect(opts.url, opts.tenantId);
6587
+ let conn;
6550
6588
  let playbookVersionId;
6551
6589
  if (sel.kind === "file") {
6552
6590
  const config = verifyConfig(sel.path);
6553
6591
  if (config === null) fail(EXIT.VALIDATION, `Fix the issues above in ${sel.path}, then re-run.`);
6592
+ conn = connect(opts.url, uploadTenantFor(opts.url, config, opts.tenantId));
6554
6593
  diag(`Staging ${sel.path} as the open draft \u2026`);
6555
6594
  const { res, json } = await postJson(conn, "/api/config/import", config);
6556
6595
  if (!res.ok) {
@@ -6561,6 +6600,7 @@ program.command("launch").description("Take a config live as a new Release: vali
6561
6600
  if (!playbookVersionId) fail(EXIT.SERVER, "No playbook_version_id returned by the import \u2014 cannot launch.");
6562
6601
  diag(`\u2713 Staged (${playbookVersionId})`);
6563
6602
  } else {
6603
+ conn = connect(opts.url, opts.tenantId);
6564
6604
  playbookVersionId = await requireOpenDraft(conn);
6565
6605
  }
6566
6606
  await launchDraft(conn, playbookVersionId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revturbine/cli",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "revturbine — verify RevTurbine ExportedConfig files and ship them to a RevTurbine instance through the Change Set lifecycle.",
5
5
  "license": "MIT",
6
6
  "repository": {