@tailor-platform/sdk 1.27.0 → 1.28.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @tailor-platform/sdk
2
2
 
3
+ ## 1.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#776](https://github.com/tailor-platform/sdk/pull/776) [`a2734bf`](https://github.com/tailor-platform/sdk/commit/a2734bfbfb71c06be324d162f2301f2930e3bfa6) Thanks [@toiroakr](https://github.com/toiroakr)! - Add managed vault guard to CLI secret commands and document runtime secret access via defineSecretManager
8
+
3
9
  ## 1.27.0
4
10
 
5
11
  ### Minor Changes
@@ -3,7 +3,7 @@ import "../chunk-Cz-A8uMR.mjs";
3
3
  import "../schema-BePzTFBV.mjs";
4
4
  import "../brand-GZnI4eYb.mjs";
5
5
  import { n as logger, r as styles } from "../logger-CqezTedh.mjs";
6
- import { C as listCommand$10, E as resumeCommand, F as showCommand, Ft as isValidMigrationNumber, G as listCommand$7, Ht as prompt, I as logBetaWarning, It as loadDiff, Jt as commonArgs, Kt as apiCommand, Mt as getMigrationFilePath, N as generateCommand$1, Nt as getMigrationFiles, O as listCommand$9, Q as listCommand$6, Qt as workspaceArgs, R as removeCommand$1, T as healthCommand, Ut as trnPrefix, V as getCommand$2, Vt as getNamespacesWithMigrations, W as tokenCommand, X as triggerCommand, Xt as deploymentArgs, Y as webhookCommand, Yt as confirmationArgs, Zt as isVerbose, b as createCommand$3, c as listCommand$11, ct as executionsCommand, dt as functionExecutionStatusToString, f as restoreCommand, ft as formatKeyValueTable, g as getCommand$4, gt as executeScript, ht as apply, i as updateCommand$2, it as startCommand, j as truncateCommand, kt as formatMigrationNumber, m as listCommand$12, n as queryCommand, o as removeCommand, ot as getCommand$3, pt as getCommand$1, q as generate, qt as defineAppCommand, r as isCLIError, tt as jobsCommand, u as inviteCommand, v as deleteCommand$3, yt as parseMigrationLabelNumber, z as listCommand$8 } from "../query-CgGbAmUg.mjs";
6
+ import { $t as workspaceArgs, C as listCommand$10, E as resumeCommand, F as showCommand, Ft as isValidMigrationNumber, G as listCommand$7, Ht as prompt, I as logBetaWarning, It as loadDiff, Jt as defineAppCommand, Mt as getMigrationFilePath, N as generateCommand$1, Nt as getMigrationFiles, O as listCommand$9, Q as listCommand$6, Qt as isVerbose, R as removeCommand$1, T as healthCommand, Ut as sdkNameLabelKey, V as getCommand$2, Vt as getNamespacesWithMigrations, W as tokenCommand, Wt as trnPrefix, X as triggerCommand, Xt as confirmationArgs, Y as webhookCommand, Yt as commonArgs, Zt as deploymentArgs, b as createCommand$3, c as listCommand$11, ct as executionsCommand, dt as functionExecutionStatusToString, f as restoreCommand, ft as formatKeyValueTable, g as getCommand$4, gt as executeScript, ht as apply, i as updateCommand$2, it as startCommand, j as truncateCommand, kt as formatMigrationNumber, m as listCommand$12, n as queryCommand, o as removeCommand, ot as getCommand$3, pt as getCommand$1, q as generate, qt as apiCommand, r as isCLIError, tt as jobsCommand, u as inviteCommand, v as deleteCommand$3, yt as parseMigrationLabelNumber, z as listCommand$8 } from "../query-WYq8RvYp.mjs";
7
7
  import { A as AuthInvokerSchema, L as PATScope, d as userAgent, i as fetchUserInfo, n as fetchAll, o as initOAuth2Client, s as initOperatorClient, w as FunctionExecution_Type } from "../client-bTbnbQbB.mjs";
8
8
  import { t as readPackageJson } from "../package-json-D3x2nBPB.mjs";
9
9
  import { S as writePlatformConfig, a as loadConfig, b as loadWorkspaceId, c as ExecutorSchema, g as getDistDir, i as resolveInlineSourcemap, o as WorkflowJobSchema, u as ResolverSchema, v as fetchLatestToken, x as readPlatformConfig, y as loadAccessToken } from "../application-CBJFUKrU.mjs";
@@ -1209,6 +1209,57 @@ const secretValueArgs = {
1209
1209
  })
1210
1210
  };
1211
1211
 
1212
+ //#endregion
1213
+ //#region src/cli/commands/secret/check-vault-managed.ts
1214
+ /**
1215
+ * Check if a vault is managed by defineSecretManager() and warn the user.
1216
+ * Returns management status and metadata needed for releasing ownership.
1217
+ * @param params - Check parameters
1218
+ * @returns Management status, TRN, and existing labels
1219
+ */
1220
+ async function checkVaultManaged(params) {
1221
+ const { client, workspaceId, vaultName } = params;
1222
+ const trn = `${trnPrefix(workspaceId)}:vault:${vaultName}`;
1223
+ const notManaged = {
1224
+ isManaged: false,
1225
+ trn,
1226
+ existingLabels: {}
1227
+ };
1228
+ let owner;
1229
+ let allLabels = {};
1230
+ try {
1231
+ const { metadata } = await client.getMetadata({ trn });
1232
+ allLabels = metadata?.labels ?? {};
1233
+ owner = allLabels[sdkNameLabelKey];
1234
+ } catch {
1235
+ return notManaged;
1236
+ }
1237
+ if (!owner) return notManaged;
1238
+ logger.warn(`Vault "${vaultName}" is managed by defineSecretManager() in tailor.config.ts (owner: "${owner}"). Changes made via CLI may conflict with the config on the next apply.`);
1239
+ return {
1240
+ isManaged: true,
1241
+ trn,
1242
+ existingLabels: allLabels
1243
+ };
1244
+ }
1245
+ /**
1246
+ * Release ownership of a managed vault by removing SDK labels from metadata.
1247
+ * Call this after the user has confirmed they want to proceed with a CLI operation on a managed vault.
1248
+ * @param params - Client, TRN, and existing labels from checkVaultManaged result
1249
+ * @param params.client
1250
+ * @param params.trn
1251
+ * @param params.existingLabels
1252
+ */
1253
+ async function releaseVaultOwnership(params) {
1254
+ const { client, trn, existingLabels } = params;
1255
+ const { [sdkNameLabelKey]: _, "sdk-version": __, ...remainingLabels } = existingLabels;
1256
+ await client.setMetadata({
1257
+ trn,
1258
+ labels: remainingLabels
1259
+ });
1260
+ logger.info("Config ownership has been removed from this vault. Remove it from defineSecretManager() in your config to prevent the next apply from re-claiming it.");
1261
+ }
1262
+
1212
1263
  //#endregion
1213
1264
  //#region src/cli/commands/secret/create.ts
1214
1265
  const createSecretCommand = defineAppCommand({
@@ -1216,7 +1267,8 @@ const createSecretCommand = defineAppCommand({
1216
1267
  description: "Create a secret in a vault.",
1217
1268
  args: z.object({
1218
1269
  ...workspaceArgs,
1219
- ...secretValueArgs
1270
+ ...secretValueArgs,
1271
+ ...confirmationArgs
1220
1272
  }).strict(),
1221
1273
  run: async (args) => {
1222
1274
  const client = await initOperatorClient(await loadAccessToken({
@@ -1227,6 +1279,17 @@ const createSecretCommand = defineAppCommand({
1227
1279
  workspaceId: args["workspace-id"],
1228
1280
  profile: args.profile
1229
1281
  });
1282
+ const managed = await checkVaultManaged({
1283
+ client,
1284
+ workspaceId,
1285
+ vaultName: args["vault-name"]
1286
+ });
1287
+ if (managed.isManaged && !args.yes) {
1288
+ if (!await prompt.confirm({
1289
+ message: "Do you want to proceed?",
1290
+ default: false
1291
+ })) return;
1292
+ }
1230
1293
  try {
1231
1294
  await client.createSecretManagerSecret({
1232
1295
  workspaceId,
@@ -1241,6 +1304,10 @@ const createSecretCommand = defineAppCommand({
1241
1304
  }
1242
1305
  throw error;
1243
1306
  }
1307
+ if (managed.isManaged) await releaseVaultOwnership({
1308
+ client,
1309
+ ...managed
1310
+ });
1244
1311
  logger.success(`Secret: ${args.name} created in vault: ${args["vault-name"]}`);
1245
1312
  }
1246
1313
  });
@@ -1264,6 +1331,11 @@ const deleteSecretCommand = defineAppCommand({
1264
1331
  workspaceId: args["workspace-id"],
1265
1332
  profile: args.profile
1266
1333
  });
1334
+ const managed = await checkVaultManaged({
1335
+ client,
1336
+ workspaceId,
1337
+ vaultName: args["vault-name"]
1338
+ });
1267
1339
  if (!args.yes) {
1268
1340
  if (await prompt.text({ message: `Enter the secret name to confirm deletion ("${args.name}"):` }) !== args.name) {
1269
1341
  logger.info("Secret deletion cancelled.");
@@ -1280,6 +1352,10 @@ const deleteSecretCommand = defineAppCommand({
1280
1352
  if (error instanceof ConnectError && error.code === Code.NotFound) throw new Error(`Secret "${args.name}" not found in vault "${args["vault-name"]}".`);
1281
1353
  throw error;
1282
1354
  }
1355
+ if (managed.isManaged) await releaseVaultOwnership({
1356
+ client,
1357
+ ...managed
1358
+ });
1283
1359
  logger.success(`Secret: ${args.name} deleted from vault: ${args["vault-name"]}`);
1284
1360
  }
1285
1361
  });
@@ -1346,7 +1422,8 @@ const updateSecretCommand = defineAppCommand({
1346
1422
  description: "Update a secret in a vault.",
1347
1423
  args: z.object({
1348
1424
  ...workspaceArgs,
1349
- ...secretValueArgs
1425
+ ...secretValueArgs,
1426
+ ...confirmationArgs
1350
1427
  }).strict(),
1351
1428
  run: async (args) => {
1352
1429
  const client = await initOperatorClient(await loadAccessToken({
@@ -1357,6 +1434,17 @@ const updateSecretCommand = defineAppCommand({
1357
1434
  workspaceId: args["workspace-id"],
1358
1435
  profile: args.profile
1359
1436
  });
1437
+ const managed = await checkVaultManaged({
1438
+ client,
1439
+ workspaceId,
1440
+ vaultName: args["vault-name"]
1441
+ });
1442
+ if (managed.isManaged && !args.yes) {
1443
+ if (!await prompt.confirm({
1444
+ message: "Do you want to proceed?",
1445
+ default: false
1446
+ })) return;
1447
+ }
1360
1448
  try {
1361
1449
  await client.updateSecretManagerSecret({
1362
1450
  workspaceId,
@@ -1368,6 +1456,10 @@ const updateSecretCommand = defineAppCommand({
1368
1456
  if (error instanceof ConnectError && error.code === Code.NotFound) throw new Error(`Secret "${args.name}" not found in vault "${args["vault-name"]}".`);
1369
1457
  throw error;
1370
1458
  }
1459
+ if (managed.isManaged) await releaseVaultOwnership({
1460
+ client,
1461
+ ...managed
1462
+ });
1371
1463
  logger.success(`Secret: ${args.name} updated in vault: ${args["vault-name"]}`);
1372
1464
  }
1373
1465
  });
@@ -1429,6 +1521,11 @@ const deleteCommand$1 = defineAppCommand({
1429
1521
  workspaceId: args["workspace-id"],
1430
1522
  profile: args.profile
1431
1523
  });
1524
+ const managed = await checkVaultManaged({
1525
+ client,
1526
+ workspaceId,
1527
+ vaultName: args.name
1528
+ });
1432
1529
  if (!args.yes) {
1433
1530
  if (await prompt.text({ message: `Enter the vault name to confirm deletion ("${args.name}"):` }) !== args.name) {
1434
1531
  logger.info("Vault deletion cancelled.");
@@ -1444,6 +1541,7 @@ const deleteCommand$1 = defineAppCommand({
1444
1541
  if (error instanceof ConnectError && error.code === Code.NotFound) throw new Error(`Vault "${args.name}" not found.`);
1445
1542
  throw error;
1446
1543
  }
1544
+ if (managed.isManaged) logger.info("Remove this vault from defineSecretManager() in your config to prevent the next apply from re-creating it.");
1447
1545
  logger.success(`Vault: ${args.name} deleted`);
1448
1546
  }
1449
1547
  });