zinkee 0.1.15 → 0.1.18

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/index.js CHANGED
@@ -1238,553 +1238,6 @@ function formatCliErrorJson(error, meta = {}) {
1238
1238
  return JSON.stringify(buildJsonCliError(error, meta));
1239
1239
  }
1240
1240
 
1241
- // src/api/automations.ts
1242
- function jsonOptions(body, method) {
1243
- return {
1244
- method,
1245
- headers: {
1246
- "content-type": "application/json"
1247
- },
1248
- body: JSON.stringify(body)
1249
- };
1250
- }
1251
- function selectorValue(selector2) {
1252
- return encodeURIComponent(selector2.value);
1253
- }
1254
- function segment(value) {
1255
- return encodeURIComponent(value);
1256
- }
1257
- function appendQuery(path, query) {
1258
- const queryString = query.toString();
1259
- return queryString.length > 0 ? `${path}?${queryString}` : path;
1260
- }
1261
- var AutomationsApi = class {
1262
- constructor(client) {
1263
- this.client = client;
1264
- }
1265
- listFolders() {
1266
- return this.client.getJson("/api/v2/automation-folders");
1267
- }
1268
- createFolder(body) {
1269
- return this.client.requestJson(
1270
- "/api/v2/automation-folders",
1271
- jsonOptions(body, "POST")
1272
- );
1273
- }
1274
- updateFolder(folder, body) {
1275
- return this.client.requestJson(
1276
- `/api/v2/automation-folders/${selectorValue(folder)}`,
1277
- jsonOptions(body, "PATCH")
1278
- );
1279
- }
1280
- deleteFolder(folder) {
1281
- return this.client.requestJson(
1282
- `/api/v2/automation-folders/${selectorValue(folder)}`,
1283
- { method: "DELETE" }
1284
- );
1285
- }
1286
- moveAutomation(input) {
1287
- return this.client.requestJson(
1288
- `/api/v2/automation-folders/${segment(input.targetFolderId)}/automations:move`,
1289
- jsonOptions(input, "POST")
1290
- );
1291
- }
1292
- listAutomations(query = {}) {
1293
- const params = new URLSearchParams();
1294
- if (query.folderId) {
1295
- params.set("folderId", query.folderId);
1296
- }
1297
- if (query.status) {
1298
- params.set("status", query.status);
1299
- }
1300
- if (query.triggerType) {
1301
- params.set("triggerType", query.triggerType);
1302
- }
1303
- if (query.actionType) {
1304
- params.set("actionType", query.actionType);
1305
- }
1306
- if (query.pluginId) {
1307
- params.set("pluginId", query.pluginId);
1308
- }
1309
- if (query.search) {
1310
- params.set("search", query.search);
1311
- }
1312
- return this.client.getJson(
1313
- appendQuery("/api/v2/automations", params)
1314
- );
1315
- }
1316
- getAutomation(automation) {
1317
- return this.client.getJson(
1318
- `/api/v2/automations/${selectorValue(automation)}`
1319
- );
1320
- }
1321
- createAutomation(input) {
1322
- return this.client.requestJson(
1323
- "/api/v2/automations",
1324
- jsonOptions(input, "POST")
1325
- );
1326
- }
1327
- updateAutomation(automation, input) {
1328
- return this.client.requestJson(
1329
- `/api/v2/automations/${selectorValue(automation)}`,
1330
- jsonOptions(input, "PATCH")
1331
- );
1332
- }
1333
- deleteAutomation(automation) {
1334
- return this.client.requestJson(
1335
- `/api/v2/automations/${selectorValue(automation)}`,
1336
- { method: "DELETE" }
1337
- );
1338
- }
1339
- activateAutomation(automation) {
1340
- return this.client.requestJson(
1341
- `/api/v2/automations/${selectorValue(automation)}:activate`,
1342
- { method: "POST" }
1343
- );
1344
- }
1345
- deactivateAutomation(automation) {
1346
- return this.client.requestJson(
1347
- `/api/v2/automations/${selectorValue(automation)}:deactivate`,
1348
- { method: "POST" }
1349
- );
1350
- }
1351
- getTrigger(automation) {
1352
- return this.client.getJson(
1353
- `/api/v2/automations/${selectorValue(automation)}/trigger`
1354
- );
1355
- }
1356
- setTrigger(automation, input) {
1357
- return this.client.requestJson(
1358
- `/api/v2/automations/${selectorValue(automation)}/trigger`,
1359
- jsonOptions(input, "PUT")
1360
- );
1361
- }
1362
- listActions(automation) {
1363
- return this.client.getJson(
1364
- `/api/v2/automations/${selectorValue(automation)}/actions`
1365
- );
1366
- }
1367
- addAction(automation, input) {
1368
- return this.client.requestJson(
1369
- `/api/v2/automations/${selectorValue(automation)}/actions`,
1370
- jsonOptions(input, "POST")
1371
- );
1372
- }
1373
- updateAction(automation, actionId, input) {
1374
- return this.client.requestJson(
1375
- `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
1376
- jsonOptions(input, "PATCH")
1377
- );
1378
- }
1379
- deleteAction(automation, actionId) {
1380
- return this.client.requestJson(
1381
- `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
1382
- { method: "DELETE" }
1383
- );
1384
- }
1385
- getFlow(automation) {
1386
- return this.client.getJson(
1387
- `/api/v2/automations/${selectorValue(automation)}/flow`
1388
- );
1389
- }
1390
- setFlow(automation, input) {
1391
- return this.client.requestJson(
1392
- `/api/v2/automations/${selectorValue(automation)}/flow`,
1393
- jsonOptions(input, "PUT")
1394
- );
1395
- }
1396
- getWebhook(automation) {
1397
- return this.client.getJson(
1398
- `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`
1399
- );
1400
- }
1401
- setWebhook(automation, input) {
1402
- return this.client.requestJson(
1403
- `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
1404
- jsonOptions(input, "PUT")
1405
- );
1406
- }
1407
- deleteWebhook(automation) {
1408
- return this.client.requestJson(
1409
- `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
1410
- { method: "DELETE" }
1411
- );
1412
- }
1413
- listPlugins() {
1414
- return this.client.getJson("/api/v2/automation-plugins");
1415
- }
1416
- getPlugin(pluginId) {
1417
- return this.client.getJson(
1418
- `/api/v2/automation-plugins/${segment(pluginId)}`
1419
- );
1420
- }
1421
- listConnections() {
1422
- return this.client.getJson(
1423
- "/api/v2/automation-connections"
1424
- );
1425
- }
1426
- getConnection(connection) {
1427
- return this.client.getJson(
1428
- `/api/v2/automation-connections/${selectorValue(connection)}`
1429
- );
1430
- }
1431
- createConnection(input) {
1432
- return this.client.requestJson(
1433
- "/api/v2/automation-connections",
1434
- jsonOptions(input, "POST")
1435
- );
1436
- }
1437
- updateConnection(connection, input) {
1438
- return this.client.requestJson(
1439
- `/api/v2/automation-connections/${selectorValue(connection)}`,
1440
- jsonOptions(input, "PATCH")
1441
- );
1442
- }
1443
- deleteConnection(connection) {
1444
- return this.client.requestJson(
1445
- `/api/v2/automation-connections/${selectorValue(connection)}`,
1446
- { method: "DELETE" }
1447
- );
1448
- }
1449
- };
1450
-
1451
- // src/api/schemas.ts
1452
- function jsonOptions2(body, method) {
1453
- return {
1454
- method,
1455
- headers: {
1456
- "content-type": "application/json"
1457
- },
1458
- body: JSON.stringify(body)
1459
- };
1460
- }
1461
- function selectorValue2(selector2) {
1462
- return selector2.value;
1463
- }
1464
- var SchemasApi = class {
1465
- constructor(client) {
1466
- this.client = client;
1467
- }
1468
- listSchemas() {
1469
- return this.client.getJson("/api/v2/schemas");
1470
- }
1471
- getSchema(schema) {
1472
- return this.client.getJson(`/api/v2/schemas/${selectorValue2(schema)}`);
1473
- }
1474
- createSchema(input) {
1475
- return this.client.requestJson("/api/v2/schemas", jsonOptions2(input, "POST"));
1476
- }
1477
- updateSchema(schema, input) {
1478
- return this.client.requestJson(
1479
- `/api/v2/schemas/${selectorValue2(schema)}`,
1480
- jsonOptions2(input, "PATCH")
1481
- );
1482
- }
1483
- deleteSchema(schema) {
1484
- return this.client.requestJson(
1485
- `/api/v2/schemas/${selectorValue2(schema)}`,
1486
- { method: "DELETE" }
1487
- );
1488
- }
1489
- async listFields(schema) {
1490
- const result = await this.getSchema(schema);
1491
- return Array.isArray(result.fields) ? result.fields : [];
1492
- }
1493
- getField(schema, field) {
1494
- return this.client.getJson(
1495
- `/api/v2/schemas/${selectorValue2(schema)}/fields/${selectorValue2(field)}`
1496
- );
1497
- }
1498
- createField(schema, input) {
1499
- return this.client.requestJson(
1500
- `/api/v2/schemas/${selectorValue2(schema)}/fields`,
1501
- jsonOptions2(input, "POST")
1502
- );
1503
- }
1504
- updateField(schema, field, input) {
1505
- return this.client.requestJson(
1506
- `/api/v2/schemas/${selectorValue2(schema)}/fields/${selectorValue2(field)}`,
1507
- jsonOptions2(input, "PATCH")
1508
- );
1509
- }
1510
- deleteField(schema, field) {
1511
- return this.client.requestJson(
1512
- `/api/v2/schemas/${selectorValue2(schema)}/fields/${selectorValue2(field)}`,
1513
- { method: "DELETE" }
1514
- );
1515
- }
1516
- };
1517
-
1518
- // src/config.ts
1519
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
1520
- import { homedir } from "os";
1521
- import { dirname, join } from "path";
1522
- import { parseTOML, stringifyTOML } from "confbox/toml";
1523
- var defaultConfigPath = join(homedir(), ".config", "zinkee", "config.toml");
1524
- var redactedSecretMask = "********";
1525
- var ENV_API_KEY = "ZINKEE_API_KEY";
1526
- var ENV_BASE_URL = "ZINKEE_API_BASE_URL";
1527
- var ENV_PROFILE = "ZINKEE_PROFILE";
1528
- var DEFAULT_PRODUCTION_BASE_URL = "https://api-z2.zinkee.com";
1529
- var ProfileResolutionError = class extends Error {
1530
- name = "ProfileResolutionError";
1531
- constructor(message) {
1532
- super(message);
1533
- }
1534
- };
1535
- function isRecord2(value) {
1536
- return typeof value === "object" && value !== null && !Array.isArray(value);
1537
- }
1538
- function toStringValue(value) {
1539
- return typeof value === "string" ? value : void 0;
1540
- }
1541
- function toNonEmptyString(value) {
1542
- const normalized = value?.trim();
1543
- return normalized ? normalized : void 0;
1544
- }
1545
- function parseProfileConfig(value) {
1546
- const profile = {};
1547
- if (!isRecord2(value)) {
1548
- return profile;
1549
- }
1550
- for (const [key, rawValue] of Object.entries(value)) {
1551
- if (key === "api_key") {
1552
- profile.apiKey = toStringValue(rawValue);
1553
- continue;
1554
- }
1555
- if (key === "base_url") {
1556
- profile.baseUrl = toStringValue(rawValue);
1557
- continue;
1558
- }
1559
- profile[key] = rawValue;
1560
- }
1561
- return profile;
1562
- }
1563
- function parseConfig(toml) {
1564
- const parsed = parseTOML(toml);
1565
- const config = { profiles: {} };
1566
- if (!isRecord2(parsed)) {
1567
- return config;
1568
- }
1569
- for (const [key, value] of Object.entries(parsed)) {
1570
- if (key === "default_profile") {
1571
- config.defaultProfile = toStringValue(value);
1572
- continue;
1573
- }
1574
- if (key === "profiles") {
1575
- if (!isRecord2(value)) {
1576
- continue;
1577
- }
1578
- for (const [profileName, profileValue] of Object.entries(value)) {
1579
- config.profiles[profileName] = parseProfileConfig(profileValue);
1580
- }
1581
- continue;
1582
- }
1583
- config[key] = value;
1584
- }
1585
- return config;
1586
- }
1587
- function readConfig(filePath = defaultConfigPath) {
1588
- return parseConfig(readFileSync(filePath, "utf8"));
1589
- }
1590
- function readConfigIfExists(filePath = defaultConfigPath) {
1591
- try {
1592
- return readConfig(filePath);
1593
- } catch (error) {
1594
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
1595
- return void 0;
1596
- }
1597
- throw error;
1598
- }
1599
- }
1600
- function readRuntimeConfig(filePath = defaultConfigPath) {
1601
- return readConfigIfExists(filePath) ?? { profiles: {} };
1602
- }
1603
- function serializeProfileConfig(profile) {
1604
- const serialized = {};
1605
- for (const [key, value] of Object.entries(profile)) {
1606
- if (value === void 0) {
1607
- continue;
1608
- }
1609
- if (key === "apiKey") {
1610
- serialized.api_key = value;
1611
- continue;
1612
- }
1613
- if (key === "baseUrl") {
1614
- serialized.base_url = value;
1615
- continue;
1616
- }
1617
- serialized[key] = value;
1618
- }
1619
- return serialized;
1620
- }
1621
- function serializeConfig(config) {
1622
- const serialized = {};
1623
- if (config.defaultProfile !== void 0) {
1624
- serialized.default_profile = config.defaultProfile;
1625
- }
1626
- for (const [key, value] of Object.entries(config)) {
1627
- if (key === "defaultProfile" || key === "profiles" || value === void 0) {
1628
- continue;
1629
- }
1630
- serialized[key] = value;
1631
- }
1632
- const serializedProfiles = Object.fromEntries(
1633
- Object.entries(config.profiles).map(([name, profile]) => [name, serializeProfileConfig(profile)])
1634
- );
1635
- if (Object.keys(serializedProfiles).length > 0) {
1636
- serialized.profiles = serializedProfiles;
1637
- }
1638
- return stringifyTOML(serialized).trimEnd().concat("\n");
1639
- }
1640
- function writeConfig(config, filePath = defaultConfigPath) {
1641
- mkdirSync(dirname(filePath), { recursive: true });
1642
- writeFileSync(filePath, serializeConfig(config), "utf8");
1643
- }
1644
- function setProfileConfig(config, profileName, updates) {
1645
- return {
1646
- ...config,
1647
- profiles: {
1648
- ...config.profiles,
1649
- [profileName]: {
1650
- ...config.profiles[profileName],
1651
- ...updates
1652
- }
1653
- }
1654
- };
1655
- }
1656
- function removeProfileConfig(config, profileName) {
1657
- const nextProfiles = { ...config.profiles };
1658
- delete nextProfiles[profileName];
1659
- return {
1660
- ...config,
1661
- defaultProfile: config.defaultProfile === profileName ? void 0 : config.defaultProfile,
1662
- profiles: nextProfiles
1663
- };
1664
- }
1665
- function setDefaultProfile(config, profileName) {
1666
- return {
1667
- ...config,
1668
- defaultProfile: profileName
1669
- };
1670
- }
1671
- function redactSecret(value) {
1672
- if (value === void 0) {
1673
- return void 0;
1674
- }
1675
- if (value.length <= 4) {
1676
- return redactedSecretMask;
1677
- }
1678
- return `${redactedSecretMask}${value.slice(-4)}`;
1679
- }
1680
- function redactProfile(profile) {
1681
- return {
1682
- ...profile,
1683
- apiKey: redactSecret(profile.apiKey)
1684
- };
1685
- }
1686
- function redactConfig(config) {
1687
- return {
1688
- ...config,
1689
- profiles: Object.fromEntries(
1690
- Object.entries(config.profiles).map(([name, profile]) => [name, redactProfile(profile)])
1691
- )
1692
- };
1693
- }
1694
- function resolveProfile(config, overrides = {}) {
1695
- const profileName = overrides.profile ?? config.defaultProfile;
1696
- if (profileName) {
1697
- const profile = config.profiles[profileName];
1698
- if (!profile) {
1699
- const label = overrides.profile ? "Profile" : "Default profile";
1700
- throw new ProfileResolutionError(`${label} "${profileName}" not found in config.`);
1701
- }
1702
- return {
1703
- ...profile,
1704
- name: profileName,
1705
- baseUrl: overrides.baseUrl ?? profile.baseUrl,
1706
- apiKey: overrides.apiKey ?? profile.apiKey
1707
- };
1708
- }
1709
- throw new ProfileResolutionError("No profile could be resolved from config.");
1710
- }
1711
- function validateBaseUrl(value) {
1712
- let parsed;
1713
- try {
1714
- parsed = new URL(value);
1715
- } catch {
1716
- throw new ProfileResolutionError(
1717
- `Environment variable ${ENV_BASE_URL} must be an absolute http(s) URL.`
1718
- );
1719
- }
1720
- if (!["http:", "https:"].includes(parsed.protocol) || !parsed.host) {
1721
- throw new ProfileResolutionError(
1722
- `Environment variable ${ENV_BASE_URL} must be an absolute http(s) URL.`
1723
- );
1724
- }
1725
- return value.replace(/\/+$/, "");
1726
- }
1727
- function readEnvApiKey(env = process.env) {
1728
- return toNonEmptyString(env[ENV_API_KEY]);
1729
- }
1730
- function readEnvBaseUrl(env = process.env) {
1731
- const baseUrl = toNonEmptyString(env[ENV_BASE_URL]);
1732
- if (!baseUrl) {
1733
- return void 0;
1734
- }
1735
- return validateBaseUrl(baseUrl);
1736
- }
1737
- function readEnvProfile(env = process.env) {
1738
- return toNonEmptyString(env[ENV_PROFILE]);
1739
- }
1740
-
1741
- // src/runtime-context.ts
1742
- function resolveRuntimeContext(config, overrides = {}) {
1743
- const envProfile = readEnvProfile();
1744
- const envApiKey = readEnvApiKey();
1745
- const envBaseUrl = readEnvBaseUrl();
1746
- const profileOverride = overrides.profile ?? envProfile;
1747
- const apiKeyOverride = overrides.apiKey ?? envApiKey;
1748
- const baseUrlOverride = overrides.baseUrl ?? envBaseUrl;
1749
- if (apiKeyOverride && !baseUrlOverride) {
1750
- throw new ProfileResolutionError(
1751
- `Runtime API key was provided, but ${ENV_BASE_URL} or --base-url is missing.`
1752
- );
1753
- }
1754
- if (baseUrlOverride && !apiKeyOverride) {
1755
- throw new ProfileResolutionError(
1756
- `Runtime base URL was provided, but ${ENV_API_KEY} or --api-key is missing.`
1757
- );
1758
- }
1759
- if (apiKeyOverride && baseUrlOverride) {
1760
- return {
1761
- profile: profileOverride ?? "runtime",
1762
- baseUrl: baseUrlOverride,
1763
- apiKey: apiKeyOverride,
1764
- readOnly: overrides.readOnly ?? false,
1765
- json: overrides.json ?? false,
1766
- profileSource: overrides.profile !== void 0 ? "flag" : envProfile !== void 0 ? "env" : void 0,
1767
- baseUrlSource: overrides.baseUrl !== void 0 ? "flag" : envBaseUrl !== void 0 ? "env" : void 0,
1768
- apiKeySource: overrides.apiKey !== void 0 ? "flag" : envApiKey !== void 0 ? "env" : void 0
1769
- };
1770
- }
1771
- const profile = resolveProfile(config, {
1772
- profile: profileOverride,
1773
- baseUrl: baseUrlOverride,
1774
- apiKey: apiKeyOverride
1775
- });
1776
- return {
1777
- profile: profile.name,
1778
- baseUrl: baseUrlOverride ?? profile.baseUrl ?? DEFAULT_PRODUCTION_BASE_URL,
1779
- apiKey: apiKeyOverride ?? profile.apiKey,
1780
- readOnly: overrides.readOnly ?? false,
1781
- json: overrides.json ?? false,
1782
- profileSource: overrides.profile !== void 0 ? "flag" : envProfile !== void 0 ? "env" : "config",
1783
- baseUrlSource: overrides.baseUrl !== void 0 ? "flag" : envBaseUrl !== void 0 ? "env" : "config",
1784
- apiKeySource: overrides.apiKey !== void 0 ? "flag" : envApiKey !== void 0 ? "env" : "config"
1785
- };
1786
- }
1787
-
1788
1241
  // src/utils/schema-fields.ts
1789
1242
  function isJsonObject(value) {
1790
1243
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1792,7 +1245,7 @@ function isJsonObject(value) {
1792
1245
  function toJsonObject(value) {
1793
1246
  return isJsonObject(value) ? value : void 0;
1794
1247
  }
1795
- function toStringValue2(value) {
1248
+ function toStringValue(value) {
1796
1249
  return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1797
1250
  }
1798
1251
  function toNumberValue(value) {
@@ -2168,7 +1621,7 @@ var fieldTypeDefinitions = [
2168
1621
  targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
2169
1622
  targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2170
1623
  deleteBehavior: "RESTRICT",
2171
- defaultValue: "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621::Ref A",
1624
+ defaultValue: "CUST-12",
2172
1625
  filterFields: [
2173
1626
  {
2174
1627
  fatherField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
@@ -2426,8 +1879,8 @@ function normalizeOptionEntries(entries) {
2426
1879
  return [];
2427
1880
  }
2428
1881
  const id = toNumberValue(entry.id);
2429
- const name = toStringValue2(entry.name) ?? toStringValue2(entry.label);
2430
- const color = toStringValue2(entry.color) ?? "default";
1882
+ const name = toStringValue(entry.name) ?? toStringValue(entry.label);
1883
+ const color = toStringValue(entry.color) ?? "default";
2431
1884
  if (id === void 0 || !name) {
2432
1885
  return [];
2433
1886
  }
@@ -2484,7 +1937,7 @@ function normalizeReferencePayload(input) {
2484
1937
  ...conditionalFormatting !== void 0 ? { conditionalFormatting } : {}
2485
1938
  };
2486
1939
  const normalizedConfig = toJsonObject(normalized.config) ?? {};
2487
- if (!toStringValue2(normalizedConfig.targetSchema) || !toStringValue2(normalizedConfig.targetDisplayField)) {
1940
+ if (!toStringValue(normalizedConfig.targetSchema) || !toStringValue(normalizedConfig.targetDisplayField)) {
2488
1941
  const definition = resolveSchemaFieldType("reference");
2489
1942
  throw new CliError(
2490
1943
  "invalid_cli_usage",
@@ -2521,13 +1974,13 @@ function normalizeSchedulePayload(input) {
2521
1974
  };
2522
1975
  const normalizedConfig = toJsonObject(normalized.config) ?? {};
2523
1976
  const definition = resolveSchemaFieldType("schedule");
2524
- if (!toStringValue2(normalizedConfig.referenceField) || !toStringValue2(normalizedConfig.beginningPeriodField) || !toStringValue2(normalizedConfig.endingPeriodField) || !toStringValue2(normalizedConfig.frequency)) {
1977
+ if (!toStringValue(normalizedConfig.referenceField) || !toStringValue(normalizedConfig.beginningPeriodField) || !toStringValue(normalizedConfig.endingPeriodField) || !toStringValue(normalizedConfig.frequency)) {
2525
1978
  throw new CliError(
2526
1979
  "invalid_cli_usage",
2527
1980
  `Schedule fields require "referenceField", "beginningPeriodField", "endingPeriodField" and "frequency". Expected raw shape: ${definition.rawShape}`
2528
1981
  );
2529
1982
  }
2530
- const frequencyValue = toStringValue2(normalizedConfig.frequency);
1983
+ const frequencyValue = toStringValue(normalizedConfig.frequency);
2531
1984
  if (!scheduleAllowedFrequencies.has(frequencyValue)) {
2532
1985
  throw new CliError(
2533
1986
  "invalid_cli_usage",
@@ -2556,7 +2009,7 @@ function normalizeFormulaPayload(input) {
2556
2009
  ...config.conditionalFormatting !== void 0 ? { conditionalFormatting: config.conditionalFormatting } : {}
2557
2010
  };
2558
2011
  const normalizedConfig = toJsonObject(normalized.config) ?? {};
2559
- if (!toStringValue2(normalizedConfig.formulaText)) {
2012
+ if (!toStringValue(normalizedConfig.formulaText)) {
2560
2013
  const definition = resolveSchemaFieldType("formula");
2561
2014
  throw new CliError(
2562
2015
  "invalid_cli_usage",
@@ -2566,7 +2019,7 @@ function normalizeFormulaPayload(input) {
2566
2019
  return normalized;
2567
2020
  }
2568
2021
  function normalizeSchemaFieldCreatePayload(input) {
2569
- const rawType = toStringValue2(input.type);
2022
+ const rawType = toStringValue(input.type);
2570
2023
  const normalizedType = rawType ? normalizeSchemaFieldType(rawType) : void 0;
2571
2024
  const definition = resolveSchemaFieldTypeByClassName(normalizedType);
2572
2025
  if (!definition) {
@@ -3195,8 +2648,8 @@ var specificExamples = {
3195
2648
  }`
3196
2649
  },
3197
2650
  {
3198
- description: "Create a record mixing text, option, number, date and reference fields. Structured values go through --set-json.",
3199
- command: `zinkee --json records create contacts --set contact-name="Grace Hopper" --set contact-email=grace@example.com --set-json status=2 --set-json amount=1999.99 --set due-date=2026-06-01T09:00:00Z --set customer-ref=8ad602a1-f6e3-43f6-9ab2-f1c5afc99621 --set owner=6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d`,
2651
+ description: "Create a record mixing text, option, number, date, reference and member fields. ReferenceField values must match the target's current targetDisplayField (read it from the target record before writing).",
2652
+ command: `zinkee --json records create contacts --set contact-name="Grace Hopper" --set contact-email=grace@example.com --set status=2 --set amount=1999.99 --set due-date=2026-06-01T09:00:00Z --set customer-ref="CUST-12" --set owner=6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d`,
3200
2653
  raw: `{
3201
2654
  "values": {
3202
2655
  "contact-name": "Grace Hopper",
@@ -3204,7 +2657,7 @@ var specificExamples = {
3204
2657
  "status": 2,
3205
2658
  "amount": 1999.99,
3206
2659
  "due-date": "2026-06-01T09:00:00Z",
3207
- "customer-ref": "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621",
2660
+ "customer-ref": "CUST-12",
3208
2661
  "owner": "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
3209
2662
  }
3210
2663
  }`
@@ -3233,7 +2686,7 @@ var specificExamples = {
3233
2686
  },
3234
2687
  {
3235
2688
  description: "Patch multiple typed values at once.",
3236
- command: "zinkee --json records update contacts 550e8400-e29b-41d4-a716-446655440000 --set-json status=3 --set-json amount=2500.00 --set due-date=2026-07-01T09:00:00Z --set owner=6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d",
2689
+ command: "zinkee --json records update contacts 550e8400-e29b-41d4-a716-446655440000 --set status=3 --set amount=2500.00 --set due-date=2026-07-01T09:00:00Z --set owner=6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d",
3237
2690
  raw: `{
3238
2691
  "set": {
3239
2692
  "status": 3,
@@ -6117,670 +5570,615 @@ function buildSchemaFieldCreateExamples(type) {
6117
5570
  }`
6118
5571
  };
6119
5572
  }
6120
- return {
6121
- description: example.name,
6122
- command
6123
- };
6124
- })
6125
- );
6126
- }
6127
- function getCommandExamples(commandName, filters = {}) {
6128
- if (commandName === "schemas fields create") {
6129
- return buildSchemaFieldCreateExamples(filters.type);
5573
+ return {
5574
+ description: example.name,
5575
+ command
5576
+ };
5577
+ })
5578
+ );
5579
+ }
5580
+ function getCommandExamples(commandName, filters = {}) {
5581
+ if (commandName === "schemas fields create") {
5582
+ return buildSchemaFieldCreateExamples(filters.type);
5583
+ }
5584
+ return specificExamples[commandName] ?? fallbackExamples(commandName);
5585
+ }
5586
+ function getResolvedCommandExamples(commandName, filters = {}) {
5587
+ return getCommandExamples(commandName, filters);
5588
+ }
5589
+
5590
+ // src/cli-examples.ts
5591
+ function getStdout(stdout) {
5592
+ return stdout ?? process.stdout;
5593
+ }
5594
+ function extractExampleFilters(tokens) {
5595
+ const filters = {};
5596
+ for (let index = 0; index < tokens.length; index += 1) {
5597
+ const token = tokens[index];
5598
+ if (token === "--type") {
5599
+ const value = tokens[index + 1];
5600
+ if (value && !value.startsWith("-")) {
5601
+ filters.type = value;
5602
+ index += 1;
5603
+ }
5604
+ }
5605
+ }
5606
+ return filters;
5607
+ }
5608
+ function extractExampleRequest(argv, optionMeta = createDefaultOptionMetadata()) {
5609
+ if (!argv.includes("--example")) {
5610
+ return null;
5611
+ }
5612
+ const userArgs = argv.slice(2);
5613
+ const operands = collectOperandTokens(userArgs, optionMeta, { skipFlag: "--example" });
5614
+ const cmdPath = findCommandPath(operands, commandRegistry);
5615
+ if (!cmdPath) {
5616
+ throw new CliError("invalid_cli_usage", 'Provide a command after "--example".');
5617
+ }
5618
+ const remainingTokens = userArgs.slice(cmdPath.lastArgvIndex + 1);
5619
+ return {
5620
+ commandName: cmdPath.commandName,
5621
+ filters: extractExampleFilters(remainingTokens),
5622
+ json: argv.includes("--json")
5623
+ };
5624
+ }
5625
+ function showExamples(commandName, json, stdout, filters = {}) {
5626
+ const examples = getResolvedCommandExamples(commandName, filters);
5627
+ if (examples.length === 0) {
5628
+ throw new CliError("invalid_cli_usage", `No examples registered for "${commandName}".`);
5629
+ }
5630
+ const writer = getStdout(stdout);
5631
+ if (json) {
5632
+ writer.write(`${JSON.stringify(buildJsonSuccess({ examples }, { command: commandName }))}
5633
+ `);
5634
+ return;
5635
+ }
5636
+ writer.write("Examples:\n");
5637
+ for (const [index, example] of examples.entries()) {
5638
+ writer.write(`
5639
+ ${index + 1}. ${example.description}
5640
+ `);
5641
+ writer.write(` ${example.command}
5642
+ `);
5643
+ if (example.raw) {
5644
+ writer.write(" Equivalent JSON payload:\n");
5645
+ for (const line of example.raw.split("\n")) {
5646
+ writer.write(` ${line}
5647
+ `);
5648
+ }
5649
+ }
5650
+ if (example.response) {
5651
+ writer.write(" Example response:\n");
5652
+ for (const line of example.response.split("\n")) {
5653
+ writer.write(` ${line}
5654
+ `);
5655
+ }
5656
+ }
6130
5657
  }
6131
- return specificExamples[commandName] ?? fallbackExamples(commandName);
6132
- }
6133
- function selector(value) {
6134
- return {
6135
- kind: "uuid",
6136
- value
6137
- };
6138
5658
  }
6139
- async function createExampleAutomationContext(options = {}) {
6140
- if (options.enabled !== true) {
6141
- return null;
6142
- }
6143
- try {
6144
- const config = readRuntimeConfig(options.configPath ?? defaultConfigPath);
6145
- const runtime = resolveRuntimeContext(config, options.overrides);
6146
- if (!runtime.baseUrl) {
6147
- return null;
6148
- }
6149
- const client = new ApiClient({
6150
- baseUrl: runtime.baseUrl,
6151
- apiKey: runtime.apiKey
6152
- });
6153
- return {
6154
- automationsApi: new AutomationsApi(client),
6155
- schemasApi: new SchemasApi(client)
6156
- };
6157
- } catch {
6158
- return null;
5659
+
5660
+ // src/program.ts
5661
+ import { createRequire } from "module";
5662
+ import { Command as Command10 } from "commander";
5663
+
5664
+ // src/config.ts
5665
+ import { mkdirSync, readFileSync, writeFileSync } from "fs";
5666
+ import { homedir } from "os";
5667
+ import { dirname, join } from "path";
5668
+ import { parseTOML, stringifyTOML } from "confbox/toml";
5669
+ var defaultConfigPath = join(homedir(), ".config", "zinkee", "config.toml");
5670
+ var redactedSecretMask = "********";
5671
+ var ENV_API_KEY = "ZINKEE_API_KEY";
5672
+ var ENV_BASE_URL = "ZINKEE_API_BASE_URL";
5673
+ var ENV_PROFILE = "ZINKEE_PROFILE";
5674
+ var DEFAULT_PRODUCTION_BASE_URL = "https://api-z2.zinkee.com";
5675
+ var ProfileResolutionError = class extends Error {
5676
+ name = "ProfileResolutionError";
5677
+ constructor(message) {
5678
+ super(message);
6159
5679
  }
5680
+ };
5681
+ function isRecord2(value) {
5682
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6160
5683
  }
6161
- function referenceValue(value) {
6162
- return value.slug ?? value.id;
5684
+ function toStringValue2(value) {
5685
+ return typeof value === "string" ? value : void 0;
6163
5686
  }
6164
- function pickExampleField(fields) {
6165
- return fields.find((field) => !field.required || field.slug || field.id) ?? fields[0];
5687
+ function toNonEmptyString(value) {
5688
+ const normalized = value?.trim();
5689
+ return normalized ? normalized : void 0;
6166
5690
  }
6167
- async function findSchemaFieldReference(context) {
6168
- const schemas = await context.schemasApi.listSchemas();
6169
- for (const schema of schemas) {
6170
- if (typeof schema.id !== "string") {
5691
+ function parseProfileConfig(value) {
5692
+ const profile = {};
5693
+ if (!isRecord2(value)) {
5694
+ return profile;
5695
+ }
5696
+ for (const [key, rawValue] of Object.entries(value)) {
5697
+ if (key === "api_key") {
5698
+ profile.apiKey = toStringValue2(rawValue);
6171
5699
  continue;
6172
5700
  }
6173
- const fullSchema = await context.schemasApi.getSchema(selector(schema.id));
6174
- const fields = Array.isArray(fullSchema.fields) ? fullSchema.fields : [];
6175
- const field = pickExampleField(fields);
6176
- const schemaRef = referenceValue(schema);
6177
- const fieldRef = field ? referenceValue(field) : void 0;
6178
- const fieldId = typeof field?.id === "string" ? field.id : void 0;
6179
- if (!schemaRef || !fieldRef || !fieldId) {
5701
+ if (key === "base_url") {
5702
+ profile.baseUrl = toStringValue2(rawValue);
6180
5703
  continue;
6181
5704
  }
6182
- return {
6183
- schemaId: schema.id,
6184
- schemaRef,
6185
- fieldId,
6186
- fieldRef
6187
- };
5705
+ profile[key] = rawValue;
6188
5706
  }
6189
- return null;
6190
- }
6191
- async function findAutomationId(context) {
6192
- const automations = await context.automationsApi.listAutomations();
6193
- const first = automations.find((automation) => typeof automation.id === "string");
6194
- return typeof first?.id === "string" ? first.id : null;
5707
+ return profile;
6195
5708
  }
6196
- async function findAutomationWithAction(context) {
6197
- const automations = await context.automationsApi.listAutomations();
6198
- for (const automation of automations) {
6199
- if (typeof automation.id !== "string") {
5709
+ function parseConfig(toml) {
5710
+ const parsed = parseTOML(toml);
5711
+ const config = { profiles: {} };
5712
+ if (!isRecord2(parsed)) {
5713
+ return config;
5714
+ }
5715
+ for (const [key, value] of Object.entries(parsed)) {
5716
+ if (key === "default_profile") {
5717
+ config.defaultProfile = toStringValue2(value);
6200
5718
  continue;
6201
5719
  }
6202
- const actions = await context.automationsApi.listActions(selector(automation.id));
6203
- const firstAction = actions.find((action) => typeof action.id === "string");
6204
- if (typeof firstAction?.id === "string") {
6205
- return {
6206
- automationId: automation.id,
6207
- actionId: firstAction.id
6208
- };
5720
+ if (key === "profiles") {
5721
+ if (!isRecord2(value)) {
5722
+ continue;
5723
+ }
5724
+ for (const [profileName, profileValue] of Object.entries(value)) {
5725
+ config.profiles[profileName] = parseProfileConfig(profileValue);
5726
+ }
5727
+ continue;
6209
5728
  }
5729
+ config[key] = value;
6210
5730
  }
6211
- return null;
5731
+ return config;
6212
5732
  }
6213
- async function buildDynamicAutomationExamples(commandName, options = {}) {
6214
- const context = await createExampleAutomationContext(options);
6215
- if (!context) {
6216
- return [];
6217
- }
6218
- const schemaField = await findSchemaFieldReference(context);
6219
- const automationId = await findAutomationId(context);
6220
- const automationWithAction = await findAutomationWithAction(context);
6221
- const plugins = await context.automationsApi.listPlugins();
6222
- const pluginId = typeof plugins[0]?.id === "string" ? plugins[0].id : void 0;
6223
- const connections = await context.automationsApi.listConnections();
6224
- const connectionId = typeof connections[0]?.id === "string" ? connections[0].id : void 0;
6225
- switch (commandName) {
6226
- case "automations create":
6227
- if (!schemaField) {
6228
- return [];
6229
- }
6230
- return buildCommandExamples([
6231
- {
6232
- description: "Create a scheduled automation with a six-field cron expression. This is the safest first example because it does not depend on workspace schemas.",
6233
- command: 'zinkee --json automations create --name "Nightly invoice sync" --trigger-type scheduled --cron "0 15 10 * * 1"',
6234
- raw: `{
6235
- "name": "Nightly invoice sync",
6236
- "trigger": {
6237
- "type": "scheduled",
6238
- "config": {
6239
- "cronExpression": "0 15 10 * * 1"
5733
+ function readConfig(filePath = defaultConfigPath) {
5734
+ return parseConfig(readFileSync(filePath, "utf8"));
5735
+ }
5736
+ function readConfigIfExists(filePath = defaultConfigPath) {
5737
+ try {
5738
+ return readConfig(filePath);
5739
+ } catch (error) {
5740
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
5741
+ return void 0;
6240
5742
  }
5743
+ throw error;
6241
5744
  }
6242
- }`,
6243
- response: `{
6244
- "automationId": "d2df2478-2513-4ecb-a2aa-2cea8c3d614a",
6245
- "webhookEndpoint": null
6246
- }`
6247
- },
6248
- {
6249
- description: `Create a record-created automation using a real schema reference from this workspace (${schemaField.schemaRef}), with an 'is not empty' condition on ${schemaField.fieldRef}.`,
6250
- command: `zinkee --json automations create --name "Record created demo" --trigger-type record_created --trigger-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"ine","values":[{"rawValue":"","source":null}]}'`,
6251
- raw: `{
6252
- "name": "Record created demo",
6253
- "trigger": {
6254
- "type": "record_created",
6255
- "config": {
6256
- "schemaId": "${schemaField.schemaRef}",
6257
- "conditions": [
6258
- {
6259
- "field": "${schemaField.fieldRef}",
6260
- "comparator": "ine",
6261
- "values": [{"rawValue": "", "source": null}]
6262
- }
6263
- ]
5745
+ }
5746
+ function readRuntimeConfig(filePath = defaultConfigPath) {
5747
+ return readConfigIfExists(filePath) ?? { profiles: {} };
5748
+ }
5749
+ function serializeProfileConfig(profile) {
5750
+ const serialized = {};
5751
+ for (const [key, value] of Object.entries(profile)) {
5752
+ if (value === void 0) {
5753
+ continue;
6264
5754
  }
6265
- }
6266
- }`
6267
- },
6268
- {
6269
- description: `Create a record-changed automation watching ${schemaField.fieldRef} on ${schemaField.schemaRef}, with an 'is not empty' condition on that field.`,
6270
- command: `zinkee --json automations create --name "Record changed demo" --trigger-type record_changed --trigger-schema ${schemaField.schemaRef} --trigger-field ${schemaField.fieldRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"ine","values":[{"rawValue":"","source":null}]}'`,
6271
- raw: `{
6272
- "name": "Record changed demo",
6273
- "trigger": {
6274
- "type": "record_changed",
6275
- "config": {
6276
- "schemaId": "${schemaField.schemaRef}",
6277
- "fieldIds": ["${schemaField.fieldRef}"],
6278
- "conditions": [
6279
- {
6280
- "field": "${schemaField.fieldRef}",
6281
- "comparator": "ine",
6282
- "values": [{"rawValue": "", "source": null}]
6283
- }
6284
- ]
5755
+ if (key === "apiKey") {
5756
+ serialized.api_key = value;
5757
+ continue;
5758
+ }
5759
+ if (key === "baseUrl") {
5760
+ serialized.base_url = value;
5761
+ continue;
6285
5762
  }
5763
+ serialized[key] = value;
6286
5764
  }
6287
- }`
6288
- }
6289
- ]);
6290
- case "automations trigger set":
6291
- if (!automationId || !schemaField) {
6292
- return [];
6293
- }
6294
- return buildCommandExamples([
6295
- {
6296
- description: "Replace the trigger with a scheduled trigger on a real automation from this workspace.",
6297
- command: `zinkee --json automations trigger set ${automationId} --trigger-type scheduled --cron "0 15 10 * * 1"`,
6298
- raw: `{
6299
- "type": "scheduled",
6300
- "config": {
6301
- "cronExpression": "0 15 10 * * 1"
5765
+ return serialized;
5766
+ }
5767
+ function serializeConfig(config) {
5768
+ const serialized = {};
5769
+ if (config.defaultProfile !== void 0) {
5770
+ serialized.default_profile = config.defaultProfile;
6302
5771
  }
6303
- }`
6304
- },
6305
- {
6306
- description: `Replace the trigger with a record-created trigger on ${schemaField.schemaRef}, with an 'is not empty' condition on ${schemaField.fieldRef}.`,
6307
- command: `zinkee --json automations trigger set ${automationId} --trigger-type record_created --trigger-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"ine","values":[{"rawValue":"","source":null}]}'`,
6308
- raw: `{
6309
- "type": "record_created",
6310
- "config": {
6311
- "schemaId": "${schemaField.schemaRef}",
6312
- "conditions": [
6313
- {
6314
- "field": "${schemaField.fieldRef}",
6315
- "comparator": "ine",
6316
- "values": [{"rawValue": "", "source": null}]
6317
- }
6318
- ]
5772
+ for (const [key, value] of Object.entries(config)) {
5773
+ if (key === "defaultProfile" || key === "profiles" || value === void 0) {
5774
+ continue;
5775
+ }
5776
+ serialized[key] = value;
6319
5777
  }
6320
- }`
6321
- },
6322
- {
6323
- description: `Replace the trigger with a record-changed trigger watching ${schemaField.fieldRef} on ${schemaField.schemaRef}.`,
6324
- command: `zinkee --json automations trigger set ${automationId} --trigger-type record_changed --trigger-schema ${schemaField.schemaRef} --trigger-field ${schemaField.fieldRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"ine","values":[{"rawValue":"","source":null}]}'`,
6325
- raw: `{
6326
- "type": "record_changed",
6327
- "config": {
6328
- "schemaId": "${schemaField.schemaRef}",
6329
- "fieldIds": ["${schemaField.fieldRef}"],
6330
- "conditions": [
6331
- {
6332
- "field": "${schemaField.fieldRef}",
6333
- "comparator": "ine",
6334
- "values": [{"rawValue": "", "source": null}]
6335
- }
6336
- ]
5778
+ const serializedProfiles = Object.fromEntries(
5779
+ Object.entries(config.profiles).map(([name, profile]) => [name, serializeProfileConfig(profile)])
5780
+ );
5781
+ if (Object.keys(serializedProfiles).length > 0) {
5782
+ serialized.profiles = serializedProfiles;
6337
5783
  }
6338
- }`
6339
- }
6340
- ]);
6341
- case "automations actions add":
6342
- if (!automationId || !schemaField) {
6343
- return [];
6344
- }
6345
- return buildCommandExamples([
6346
- {
6347
- description: `Add a create-record action with literal and trigger-based mappings targeting ${schemaField.schemaRef}.`,
6348
- command: `zinkee --json automations actions add ${automationId} --type create_record --name "Create follow-up order" --target-schema ${schemaField.schemaRef} --map ${schemaField.fieldRef}=pending --map-json owner='{"rawValue":null,"source":{"type":"TRIGGER","id":"${schemaField.fieldId}"}}'`,
6349
- raw: `{
6350
- "type": "create_record",
6351
- "name": "Create follow-up order",
6352
- "config": {
6353
- "targetSchemaId": "${schemaField.schemaRef}",
6354
- "fieldMapping": {
6355
- "${schemaField.fieldRef}": {
6356
- "rawValue": "pending",
6357
- "source": null
6358
- },
6359
- "owner": {
6360
- "rawValue": null,
6361
- "source": {
6362
- "type": "TRIGGER",
6363
- "id": "${schemaField.fieldId}"
6364
- }
5784
+ return stringifyTOML(serialized).trimEnd().concat("\n");
5785
+ }
5786
+ function writeConfig(config, filePath = defaultConfigPath) {
5787
+ mkdirSync(dirname(filePath), { recursive: true });
5788
+ writeFileSync(filePath, serializeConfig(config), "utf8");
5789
+ }
5790
+ function setProfileConfig(config, profileName, updates) {
5791
+ return {
5792
+ ...config,
5793
+ profiles: {
5794
+ ...config.profiles,
5795
+ [profileName]: {
5796
+ ...config.profiles[profileName],
5797
+ ...updates
6365
5798
  }
6366
5799
  }
5800
+ };
5801
+ }
5802
+ function removeProfileConfig(config, profileName) {
5803
+ const nextProfiles = { ...config.profiles };
5804
+ delete nextProfiles[profileName];
5805
+ return {
5806
+ ...config,
5807
+ defaultProfile: config.defaultProfile === profileName ? void 0 : config.defaultProfile,
5808
+ profiles: nextProfiles
5809
+ };
5810
+ }
5811
+ function setDefaultProfile(config, profileName) {
5812
+ return {
5813
+ ...config,
5814
+ defaultProfile: profileName
5815
+ };
5816
+ }
5817
+ function redactSecret(value) {
5818
+ if (value === void 0) {
5819
+ return void 0;
6367
5820
  }
6368
- }`
6369
- },
6370
- {
6371
- description: `Add an update-record action that targets the trigger record on ${schemaField.schemaRef}.`,
6372
- command: `zinkee --json automations actions add ${automationId} --type update_record --name "Mark record as processed" --target-schema ${schemaField.schemaRef} --use-trigger-record --map ${schemaField.fieldRef}=processed`,
6373
- raw: `{
6374
- "type": "update_record",
6375
- "name": "Mark record as processed",
6376
- "config": {
6377
- "targetSchemaId": "${schemaField.schemaRef}",
6378
- "fieldMapping": {
6379
- "${schemaField.fieldRef}": {
6380
- "rawValue": "processed",
6381
- "source": null
6382
- }
6383
- },
6384
- "useTriggerRecord": true
5821
+ if (value.length <= 4) {
5822
+ return redactedSecretMask;
6385
5823
  }
6386
- }`
6387
- },
6388
- {
6389
- description: `Add a search-records action with a trigger-based condition on ${schemaField.schemaRef}.`,
6390
- command: `zinkee --json automations actions add ${automationId} --type search_records --name "Find duplicates" --target-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"${schemaField.fieldId}"}}]}'`,
6391
- raw: `{
6392
- "type": "search_records",
6393
- "name": "Find duplicates",
6394
- "config": {
6395
- "targetSchemaId": "${schemaField.schemaRef}",
6396
- "conditions": [
6397
- {
6398
- "field": "${schemaField.fieldRef}",
6399
- "comparator": "eq",
6400
- "values": [
6401
- {
6402
- "rawValue": null,
6403
- "source": {
6404
- "type": "TRIGGER",
6405
- "id": "${schemaField.fieldId}"
6406
- }
6407
- }
6408
- ]
6409
- }
6410
- ]
5824
+ return `${redactedSecretMask}${value.slice(-4)}`;
5825
+ }
5826
+ function redactProfile(profile) {
5827
+ return {
5828
+ ...profile,
5829
+ apiKey: redactSecret(profile.apiKey)
5830
+ };
5831
+ }
5832
+ function redactConfig(config) {
5833
+ return {
5834
+ ...config,
5835
+ profiles: Object.fromEntries(
5836
+ Object.entries(config.profiles).map(([name, profile]) => [name, redactProfile(profile)])
5837
+ )
5838
+ };
5839
+ }
5840
+ function resolveProfile(config, overrides = {}) {
5841
+ const profileName = overrides.profile ?? config.defaultProfile;
5842
+ if (profileName) {
5843
+ const profile = config.profiles[profileName];
5844
+ if (!profile) {
5845
+ const label = overrides.profile ? "Profile" : "Default profile";
5846
+ throw new ProfileResolutionError(`${label} "${profileName}" not found in config.`);
5847
+ }
5848
+ return {
5849
+ ...profile,
5850
+ name: profileName,
5851
+ baseUrl: overrides.baseUrl ?? profile.baseUrl,
5852
+ apiKey: overrides.apiKey ?? profile.apiKey
5853
+ };
6411
5854
  }
6412
- }`
6413
- },
6414
- ...connectionId ? buildCommandExamples([
6415
- {
6416
- description: `Add an HTTP request action authenticated through a stored connection (${connectionId}).`,
6417
- command: `zinkee --json automations actions add ${automationId} --type http_request --name "Notify external ERP" --method POST --url https://example.com/integrations/order-status --header X-Demo=codex --content-type application/json --timeout-ms 5000 --auth-mode STORED --connection ${connectionId}`,
6418
- raw: `{
6419
- "type": "http_request",
6420
- "name": "Notify external ERP",
6421
- "config": {
6422
- "method": "POST",
6423
- "url": "https://example.com/integrations/order-status",
6424
- "headers": {
6425
- "X-Demo": "codex"
6426
- },
6427
- "contentType": "application/json",
6428
- "timeoutMs": 5000,
6429
- "authMode": "STORED",
6430
- "connectionId": "${connectionId}"
5855
+ throw new ProfileResolutionError("No profile could be resolved from config.");
5856
+ }
5857
+ function validateBaseUrl(value) {
5858
+ let parsed;
5859
+ try {
5860
+ parsed = new URL(value);
5861
+ } catch {
5862
+ throw new ProfileResolutionError(
5863
+ `Environment variable ${ENV_BASE_URL} must be an absolute http(s) URL.`
5864
+ );
6431
5865
  }
6432
- }`
6433
- }
6434
- ]) : buildCommandExamples([
6435
- {
6436
- description: "Add an HTTP request action through the generic --type path.",
6437
- command: `zinkee --json automations actions add ${automationId} --type http_request --name "Notify external ERP" --method POST --url https://example.com/integrations/order-status --content-type application/json`,
6438
- raw: `{
6439
- "type": "http_request",
6440
- "name": "Notify external ERP",
6441
- "config": {
6442
- "method": "POST",
6443
- "url": "https://example.com/integrations/order-status",
6444
- "contentType": "application/json"
5866
+ if (!["http:", "https:"].includes(parsed.protocol) || !parsed.host) {
5867
+ throw new ProfileResolutionError(
5868
+ `Environment variable ${ENV_BASE_URL} must be an absolute http(s) URL.`
5869
+ );
6445
5870
  }
6446
- }`
6447
- }
6448
- ]),
6449
- ...pluginId ? buildCommandExamples([
6450
- {
6451
- description: `Add an execute-plugin action using an active plugin from this workspace (${pluginId}).`,
6452
- command: `zinkee --json automations actions add ${automationId} --type execute_plugin --name "Run billing plugin" --plugin ${pluginId} --arg mode=safe --arg-json steps='["one","two"]'`,
6453
- raw: `{
6454
- "type": "execute_plugin",
6455
- "name": "Run billing plugin",
6456
- "config": {
6457
- "pluginId": "${pluginId}",
6458
- "pluginArgs": {
6459
- "mode": "safe",
6460
- "steps": ["one", "two"]
6461
- }
5871
+ return value.replace(/\/+$/, "");
5872
+ }
5873
+ function readEnvApiKey(env = process.env) {
5874
+ return toNonEmptyString(env[ENV_API_KEY]);
5875
+ }
5876
+ function readEnvBaseUrl(env = process.env) {
5877
+ const baseUrl = toNonEmptyString(env[ENV_BASE_URL]);
5878
+ if (!baseUrl) {
5879
+ return void 0;
6462
5880
  }
6463
- }`
6464
- }
6465
- ]) : []
6466
- ]);
6467
- case "automations actions update":
6468
- if (!automationWithAction || !schemaField) {
6469
- return [];
6470
- }
6471
- return buildCommandExamples([
6472
- {
6473
- description: "Update a record action on a real automation/action pair using the trigger record.",
6474
- command: `zinkee --json automations actions update ${automationWithAction.automationId} ${automationWithAction.actionId} --type update_record --name "Update trigger record" --target-schema ${schemaField.schemaRef} --map ${schemaField.fieldRef}=ready --use-trigger-record`,
6475
- raw: `{
6476
- "type": "update_record",
6477
- "name": "Update trigger record",
6478
- "config": {
6479
- "targetSchemaId": "${schemaField.schemaRef}",
6480
- "fieldMapping": {
6481
- "${schemaField.fieldRef}": {
6482
- "rawValue": "ready",
6483
- "source": null
6484
- }
6485
- },
6486
- "useTriggerRecord": true
5881
+ return validateBaseUrl(baseUrl);
5882
+ }
5883
+ function readEnvProfile(env = process.env) {
5884
+ return toNonEmptyString(env[ENV_PROFILE]);
5885
+ }
5886
+
5887
+ // src/commands/config.ts
5888
+ function getCommandIo(stdout) {
5889
+ return stdout ?? process.stdout;
5890
+ }
5891
+ function writeLine(stdout, value) {
5892
+ stdout.write(`${value}
5893
+ `);
5894
+ }
5895
+ function getGlobalOptions(command) {
5896
+ return command.optsWithGlobals();
5897
+ }
5898
+ function emitJson(stdout, commandName, data, configPath) {
5899
+ writeLine(
5900
+ stdout,
5901
+ JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
5902
+ );
5903
+ }
5904
+ function toConfigurationError(filePath, error) {
5905
+ if (error instanceof CliError) {
5906
+ throw error;
6487
5907
  }
6488
- }`,
6489
- response: `{
6490
- "id": "${automationWithAction.actionId}",
6491
- "type": "update_record",
6492
- "name": "Update trigger record",
6493
- "config": {
6494
- "targetSchemaId": "${schemaField.schemaRef}",
6495
- "fieldMapping": {
6496
- "${schemaField.fieldRef}": {
6497
- "rawValue": "ready",
6498
- "source": null
6499
- }
6500
- },
6501
- "useTriggerRecord": true
5908
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
5909
+ throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
6502
5910
  }
6503
- }`
6504
- }
6505
- ]);
6506
- case "automations flow set":
6507
- if (!automationWithAction) {
6508
- return [];
6509
- }
6510
- return buildCommandExamples([
6511
- {
6512
- description: "Set flow entry actions using a real automation/action pair from this workspace.",
6513
- command: `zinkee --json automations flow set ${automationWithAction.automationId} --entry ${automationWithAction.actionId}`,
6514
- raw: `{
6515
- "entryActionIds": ["${automationWithAction.actionId}"],
6516
- "transitions": []
6517
- }`
6518
- }
6519
- ]);
6520
- case "automations connections create":
6521
- return buildCommandExamples([
6522
- {
6523
- description: "Create a stored workspace connection for HTTP request actions.",
6524
- command: `zinkee --json automations connections create --name "ERP API Key" --type api_key --scope workspace --config '{"headerName":"Authorization"}' --secret apiKey=super-secret --active`,
6525
- raw: `{
6526
- "name": "ERP API Key",
6527
- "type": "api_key",
6528
- "scope": "workspace",
6529
- "config": {
6530
- "headerName": "Authorization"
6531
- },
6532
- "secret": {
6533
- "apiKey": "super-secret"
6534
- },
6535
- "active": true
6536
- }`,
6537
- response: `{
6538
- "id": "4fc20b5c-9353-4991-b68e-1027cb674ed4",
6539
- "name": "ERP API Key",
6540
- "type": "api_key",
6541
- "scope": "workspace",
6542
- "ownerMemberId": "6c8a3e0d-7b1f-4c98-a2e9-8b9a2e3f5b14",
6543
- "active": true,
6544
- "config": {
6545
- "headerName": "Authorization"
6546
- },
6547
- "createdAt": "2026-04-21T09:00:00Z",
6548
- "updatedAt": "2026-04-21T09:00:00Z",
6549
- "createdBy": "developer@zinkee.com",
6550
- "updatedBy": "developer@zinkee.com"
6551
- }`
6552
- }
6553
- ]);
6554
- case "automations connections update":
6555
- if (!connectionId) {
6556
- return [];
5911
+ if (error instanceof Error) {
5912
+ throw new CliError("configuration_error", error.message);
5913
+ }
5914
+ throw error;
5915
+ }
5916
+ function registerConfigCommands(program, options = {}) {
5917
+ const filePath = options.configPath ?? defaultConfigPath;
5918
+ const stdout = getCommandIo(options.stdout);
5919
+ const config = program.command("config").description("Inspect local CLI config");
5920
+ config.command("path").description("Show the effective config file path").action(function action() {
5921
+ const data = { path: filePath };
5922
+ if (getGlobalOptions(this).json) {
5923
+ emitJson(stdout, "config path", data, filePath);
5924
+ return;
5925
+ }
5926
+ writeLine(stdout, filePath);
5927
+ });
5928
+ config.command("show").description("Show the local config with secrets redacted").action(function action() {
5929
+ try {
5930
+ const data = redactConfig(readConfig(filePath));
5931
+ if (getGlobalOptions(this).json) {
5932
+ emitJson(stdout, "config show", data, filePath);
5933
+ return;
6557
5934
  }
6558
- return buildCommandExamples([
6559
- {
6560
- description: "Patch an existing stored connection from this workspace.",
6561
- command: `zinkee --json automations connections update ${connectionId} --raw '{"set":{"name":"ERP API Key Updated","config":{"headerName":"Authorization"}}}'`,
6562
- raw: `{
6563
- "set": {
6564
- "name": "ERP API Key Updated",
6565
- "config": {
6566
- "headerName": "Authorization"
5935
+ writeLine(stdout, `Default profile: ${data.defaultProfile ?? "(none)"}`);
5936
+ printTable(
5937
+ Object.entries(data.profiles).map(([name, profile]) => ({
5938
+ name,
5939
+ default: data.defaultProfile === name ? "yes" : "",
5940
+ baseUrl: typeof profile.baseUrl === "string" ? profile.baseUrl : "",
5941
+ apiKey: typeof profile.apiKey === "string" ? profile.apiKey : ""
5942
+ })),
5943
+ ["name", "default", "baseUrl", "apiKey"],
5944
+ stdout
5945
+ );
5946
+ } catch (error) {
5947
+ toConfigurationError(filePath, error);
5948
+ }
5949
+ });
5950
+ config.command("validate").description("Validate that the local config can resolve a profile").action(function action() {
5951
+ try {
5952
+ const parsed = readConfig(filePath);
5953
+ const profile = resolveProfile(parsed);
5954
+ const data = {
5955
+ valid: true,
5956
+ profile: profile.name
5957
+ };
5958
+ if (getGlobalOptions(this).json) {
5959
+ emitJson(stdout, "config validate", data, filePath);
5960
+ return;
5961
+ }
5962
+ writeLine(stdout, `Config is valid. Resolved profile "${profile.name}".`);
5963
+ } catch (error) {
5964
+ toConfigurationError(filePath, error);
6567
5965
  }
6568
- }
6569
- }`,
6570
- response: `{
6571
- "id": "${connectionId}",
6572
- "name": "ERP API Key Updated",
6573
- "type": "api_key",
6574
- "scope": "workspace",
6575
- "ownerMemberId": "6c8a3e0d-7b1f-4c98-a2e9-8b9a2e3f5b14",
6576
- "active": true,
6577
- "config": {
6578
- "headerName": "Authorization"
6579
- },
6580
- "createdAt": "2026-04-21T09:00:00Z",
6581
- "updatedAt": "2026-04-21T10:15:00Z",
6582
- "createdBy": "developer@zinkee.com",
6583
- "updatedBy": "developer@zinkee.com"
6584
- }`
6585
- }
6586
- ]);
6587
- default:
6588
- return [];
6589
- }
6590
- }
6591
- async function getResolvedCommandExamples(commandName, filters = {}, options = {}) {
6592
- const dynamicExamples = commandName.startsWith("automations") ? await buildDynamicAutomationExamples(commandName, options) : [];
6593
- if (dynamicExamples.length > 0) {
6594
- return dynamicExamples;
6595
- }
6596
- return getCommandExamples(commandName, filters);
5966
+ });
6597
5967
  }
6598
5968
 
6599
- // src/cli-examples.ts
6600
- function getStdout(stdout) {
6601
- return stdout ?? process.stdout;
5969
+ // src/commands/automations.ts
5970
+ import { readFileSync as readFileSync2 } from "fs";
5971
+ import { InvalidArgumentError } from "commander";
5972
+
5973
+ // src/api/automations.ts
5974
+ function jsonOptions(body, method) {
5975
+ return {
5976
+ method,
5977
+ headers: {
5978
+ "content-type": "application/json"
5979
+ },
5980
+ body: JSON.stringify(body)
5981
+ };
6602
5982
  }
6603
- function extractExampleFilters(tokens) {
6604
- const filters = {};
6605
- for (let index = 0; index < tokens.length; index += 1) {
6606
- const token = tokens[index];
6607
- if (token === "--type") {
6608
- const value = tokens[index + 1];
6609
- if (value && !value.startsWith("-")) {
6610
- filters.type = value;
6611
- index += 1;
6612
- }
6613
- }
6614
- }
6615
- return filters;
5983
+ function selectorValue(selector) {
5984
+ return encodeURIComponent(selector.value);
6616
5985
  }
6617
- function extractExampleOverrides(tokens) {
6618
- const overrides = {};
6619
- for (let index = 0; index < tokens.length; index += 1) {
6620
- const token = tokens[index];
6621
- const value = tokens[index + 1];
6622
- if (!value || value.startsWith("-")) {
6623
- continue;
5986
+ function segment(value) {
5987
+ return encodeURIComponent(value);
5988
+ }
5989
+ function appendQuery(path, query) {
5990
+ const queryString = query.toString();
5991
+ return queryString.length > 0 ? `${path}?${queryString}` : path;
5992
+ }
5993
+ var AutomationsApi = class {
5994
+ constructor(client) {
5995
+ this.client = client;
5996
+ }
5997
+ listFolders() {
5998
+ return this.client.getJson("/api/v2/automation-folders");
5999
+ }
6000
+ createFolder(body) {
6001
+ return this.client.requestJson(
6002
+ "/api/v2/automation-folders",
6003
+ jsonOptions(body, "POST")
6004
+ );
6005
+ }
6006
+ updateFolder(folder, body) {
6007
+ return this.client.requestJson(
6008
+ `/api/v2/automation-folders/${selectorValue(folder)}`,
6009
+ jsonOptions(body, "PATCH")
6010
+ );
6011
+ }
6012
+ deleteFolder(folder) {
6013
+ return this.client.requestJson(
6014
+ `/api/v2/automation-folders/${selectorValue(folder)}`,
6015
+ { method: "DELETE" }
6016
+ );
6017
+ }
6018
+ moveAutomation(input) {
6019
+ return this.client.requestJson(
6020
+ `/api/v2/automation-folders/${segment(input.targetFolderId)}/automations:move`,
6021
+ jsonOptions(input, "POST")
6022
+ );
6023
+ }
6024
+ listAutomations(query = {}) {
6025
+ const params = new URLSearchParams();
6026
+ if (query.folderId) {
6027
+ params.set("folderId", query.folderId);
6624
6028
  }
6625
- if (token === "--profile") {
6626
- overrides.profile = value;
6627
- index += 1;
6628
- continue;
6029
+ if (query.status) {
6030
+ params.set("status", query.status);
6629
6031
  }
6630
- if (token === "--base-url") {
6631
- overrides.baseUrl = value;
6632
- index += 1;
6633
- continue;
6032
+ if (query.triggerType) {
6033
+ params.set("triggerType", query.triggerType);
6034
+ }
6035
+ if (query.actionType) {
6036
+ params.set("actionType", query.actionType);
6037
+ }
6038
+ if (query.pluginId) {
6039
+ params.set("pluginId", query.pluginId);
6634
6040
  }
6635
- if (token === "--api-key") {
6636
- overrides.apiKey = value;
6637
- index += 1;
6041
+ if (query.search) {
6042
+ params.set("search", query.search);
6638
6043
  }
6044
+ return this.client.getJson(
6045
+ appendQuery("/api/v2/automations", params)
6046
+ );
6639
6047
  }
6640
- return overrides;
6641
- }
6642
- function extractExampleRequest(argv, optionMeta = createDefaultOptionMetadata()) {
6643
- if (!argv.includes("--example")) {
6644
- return null;
6048
+ getAutomation(automation) {
6049
+ return this.client.getJson(
6050
+ `/api/v2/automations/${selectorValue(automation)}`
6051
+ );
6645
6052
  }
6646
- const userArgs = argv.slice(2);
6647
- const operands = collectOperandTokens(userArgs, optionMeta, { skipFlag: "--example" });
6648
- const cmdPath = findCommandPath(operands, commandRegistry);
6649
- if (!cmdPath) {
6650
- throw new CliError("invalid_cli_usage", 'Provide a command after "--example".');
6053
+ createAutomation(input) {
6054
+ return this.client.requestJson(
6055
+ "/api/v2/automations",
6056
+ jsonOptions(input, "POST")
6057
+ );
6651
6058
  }
6652
- const remainingTokens = userArgs.slice(cmdPath.lastArgvIndex + 1);
6653
- return {
6654
- commandName: cmdPath.commandName,
6655
- filters: extractExampleFilters(remainingTokens),
6656
- overrides: extractExampleOverrides(argv),
6657
- json: argv.includes("--json")
6658
- };
6659
- }
6660
- async function showExamples(commandName, json, stdout, filters = {}, options = {}) {
6661
- const examples = await getResolvedCommandExamples(commandName, filters, options);
6662
- if (examples.length === 0) {
6663
- throw new CliError("invalid_cli_usage", `No examples registered for "${commandName}".`);
6059
+ updateAutomation(automation, input) {
6060
+ return this.client.requestJson(
6061
+ `/api/v2/automations/${selectorValue(automation)}`,
6062
+ jsonOptions(input, "PATCH")
6063
+ );
6664
6064
  }
6665
- const writer = getStdout(stdout);
6666
- if (json) {
6667
- writer.write(`${JSON.stringify(buildJsonSuccess({ examples }, { command: commandName }))}
6668
- `);
6669
- return;
6065
+ deleteAutomation(automation) {
6066
+ return this.client.requestJson(
6067
+ `/api/v2/automations/${selectorValue(automation)}`,
6068
+ { method: "DELETE" }
6069
+ );
6670
6070
  }
6671
- writer.write("Examples:\n");
6672
- for (const [index, example] of examples.entries()) {
6673
- writer.write(`
6674
- ${index + 1}. ${example.description}
6675
- `);
6676
- writer.write(` ${example.command}
6677
- `);
6678
- if (example.raw) {
6679
- writer.write(" Equivalent JSON payload:\n");
6680
- for (const line of example.raw.split("\n")) {
6681
- writer.write(` ${line}
6682
- `);
6683
- }
6684
- }
6685
- if (example.response) {
6686
- writer.write(" Example response:\n");
6687
- for (const line of example.response.split("\n")) {
6688
- writer.write(` ${line}
6689
- `);
6690
- }
6691
- }
6071
+ activateAutomation(automation) {
6072
+ return this.client.requestJson(
6073
+ `/api/v2/automations/${selectorValue(automation)}:activate`,
6074
+ { method: "POST" }
6075
+ );
6076
+ }
6077
+ deactivateAutomation(automation) {
6078
+ return this.client.requestJson(
6079
+ `/api/v2/automations/${selectorValue(automation)}:deactivate`,
6080
+ { method: "POST" }
6081
+ );
6082
+ }
6083
+ getTrigger(automation) {
6084
+ return this.client.getJson(
6085
+ `/api/v2/automations/${selectorValue(automation)}/trigger`
6086
+ );
6087
+ }
6088
+ setTrigger(automation, input) {
6089
+ return this.client.requestJson(
6090
+ `/api/v2/automations/${selectorValue(automation)}/trigger`,
6091
+ jsonOptions(input, "PUT")
6092
+ );
6093
+ }
6094
+ listActions(automation) {
6095
+ return this.client.getJson(
6096
+ `/api/v2/automations/${selectorValue(automation)}/actions`
6097
+ );
6098
+ }
6099
+ addAction(automation, input) {
6100
+ return this.client.requestJson(
6101
+ `/api/v2/automations/${selectorValue(automation)}/actions`,
6102
+ jsonOptions(input, "POST")
6103
+ );
6104
+ }
6105
+ updateAction(automation, actionId, input) {
6106
+ return this.client.requestJson(
6107
+ `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
6108
+ jsonOptions(input, "PATCH")
6109
+ );
6110
+ }
6111
+ deleteAction(automation, actionId) {
6112
+ return this.client.requestJson(
6113
+ `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
6114
+ { method: "DELETE" }
6115
+ );
6116
+ }
6117
+ getFlow(automation) {
6118
+ return this.client.getJson(
6119
+ `/api/v2/automations/${selectorValue(automation)}/flow`
6120
+ );
6121
+ }
6122
+ setFlow(automation, input) {
6123
+ return this.client.requestJson(
6124
+ `/api/v2/automations/${selectorValue(automation)}/flow`,
6125
+ jsonOptions(input, "PUT")
6126
+ );
6127
+ }
6128
+ getWebhook(automation) {
6129
+ return this.client.getJson(
6130
+ `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`
6131
+ );
6132
+ }
6133
+ setWebhook(automation, input) {
6134
+ return this.client.requestJson(
6135
+ `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
6136
+ jsonOptions(input, "PUT")
6137
+ );
6138
+ }
6139
+ deleteWebhook(automation) {
6140
+ return this.client.requestJson(
6141
+ `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
6142
+ { method: "DELETE" }
6143
+ );
6692
6144
  }
6693
- }
6694
-
6695
- // src/program.ts
6696
- import { createRequire } from "module";
6697
- import { Command as Command10 } from "commander";
6698
-
6699
- // src/commands/config.ts
6700
- function getCommandIo(stdout) {
6701
- return stdout ?? process.stdout;
6702
- }
6703
- function writeLine(stdout, value) {
6704
- stdout.write(`${value}
6705
- `);
6706
- }
6707
- function getGlobalOptions(command) {
6708
- return command.optsWithGlobals();
6709
- }
6710
- function emitJson(stdout, commandName, data, configPath) {
6711
- writeLine(
6712
- stdout,
6713
- JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
6714
- );
6715
- }
6716
- function toConfigurationError(filePath, error) {
6717
- if (error instanceof CliError) {
6718
- throw error;
6145
+ listPlugins() {
6146
+ return this.client.getJson("/api/v2/automation-plugins");
6719
6147
  }
6720
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
6721
- throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
6148
+ getPlugin(pluginId) {
6149
+ return this.client.getJson(
6150
+ `/api/v2/automation-plugins/${segment(pluginId)}`
6151
+ );
6722
6152
  }
6723
- if (error instanceof Error) {
6724
- throw new CliError("configuration_error", error.message);
6153
+ listConnections() {
6154
+ return this.client.getJson(
6155
+ "/api/v2/automation-connections"
6156
+ );
6725
6157
  }
6726
- throw error;
6727
- }
6728
- function registerConfigCommands(program, options = {}) {
6729
- const filePath = options.configPath ?? defaultConfigPath;
6730
- const stdout = getCommandIo(options.stdout);
6731
- const config = program.command("config").description("Inspect local CLI config");
6732
- config.command("path").description("Show the effective config file path").action(function action() {
6733
- const data = { path: filePath };
6734
- if (getGlobalOptions(this).json) {
6735
- emitJson(stdout, "config path", data, filePath);
6736
- return;
6737
- }
6738
- writeLine(stdout, filePath);
6739
- });
6740
- config.command("show").description("Show the local config with secrets redacted").action(function action() {
6741
- try {
6742
- const data = redactConfig(readConfig(filePath));
6743
- if (getGlobalOptions(this).json) {
6744
- emitJson(stdout, "config show", data, filePath);
6745
- return;
6746
- }
6747
- writeLine(stdout, `Default profile: ${data.defaultProfile ?? "(none)"}`);
6748
- printTable(
6749
- Object.entries(data.profiles).map(([name, profile]) => ({
6750
- name,
6751
- default: data.defaultProfile === name ? "yes" : "",
6752
- baseUrl: typeof profile.baseUrl === "string" ? profile.baseUrl : "",
6753
- apiKey: typeof profile.apiKey === "string" ? profile.apiKey : ""
6754
- })),
6755
- ["name", "default", "baseUrl", "apiKey"],
6756
- stdout
6757
- );
6758
- } catch (error) {
6759
- toConfigurationError(filePath, error);
6760
- }
6761
- });
6762
- config.command("validate").description("Validate that the local config can resolve a profile").action(function action() {
6763
- try {
6764
- const parsed = readConfig(filePath);
6765
- const profile = resolveProfile(parsed);
6766
- const data = {
6767
- valid: true,
6768
- profile: profile.name
6769
- };
6770
- if (getGlobalOptions(this).json) {
6771
- emitJson(stdout, "config validate", data, filePath);
6772
- return;
6773
- }
6774
- writeLine(stdout, `Config is valid. Resolved profile "${profile.name}".`);
6775
- } catch (error) {
6776
- toConfigurationError(filePath, error);
6777
- }
6778
- });
6779
- }
6780
-
6781
- // src/commands/automations.ts
6782
- import { readFileSync as readFileSync2 } from "fs";
6783
- import { InvalidArgumentError } from "commander";
6158
+ getConnection(connection) {
6159
+ return this.client.getJson(
6160
+ `/api/v2/automation-connections/${selectorValue(connection)}`
6161
+ );
6162
+ }
6163
+ createConnection(input) {
6164
+ return this.client.requestJson(
6165
+ "/api/v2/automation-connections",
6166
+ jsonOptions(input, "POST")
6167
+ );
6168
+ }
6169
+ updateConnection(connection, input) {
6170
+ return this.client.requestJson(
6171
+ `/api/v2/automation-connections/${selectorValue(connection)}`,
6172
+ jsonOptions(input, "PATCH")
6173
+ );
6174
+ }
6175
+ deleteConnection(connection) {
6176
+ return this.client.requestJson(
6177
+ `/api/v2/automation-connections/${selectorValue(connection)}`,
6178
+ { method: "DELETE" }
6179
+ );
6180
+ }
6181
+ };
6784
6182
 
6785
6183
  // src/parsers/kv.ts
6786
6184
  function splitAssignment(input) {
@@ -6830,6 +6228,53 @@ function normalizeUuidOrSlug(input) {
6830
6228
  };
6831
6229
  }
6832
6230
 
6231
+ // src/runtime-context.ts
6232
+ function resolveRuntimeContext(config, overrides = {}) {
6233
+ const envProfile = readEnvProfile();
6234
+ const envApiKey = readEnvApiKey();
6235
+ const envBaseUrl = readEnvBaseUrl();
6236
+ const profileOverride = overrides.profile ?? envProfile;
6237
+ const apiKeyOverride = overrides.apiKey ?? envApiKey;
6238
+ const baseUrlOverride = overrides.baseUrl ?? envBaseUrl;
6239
+ if (apiKeyOverride && !baseUrlOverride) {
6240
+ throw new ProfileResolutionError(
6241
+ `Runtime API key was provided, but ${ENV_BASE_URL} or --base-url is missing.`
6242
+ );
6243
+ }
6244
+ if (baseUrlOverride && !apiKeyOverride) {
6245
+ throw new ProfileResolutionError(
6246
+ `Runtime base URL was provided, but ${ENV_API_KEY} or --api-key is missing.`
6247
+ );
6248
+ }
6249
+ if (apiKeyOverride && baseUrlOverride) {
6250
+ return {
6251
+ profile: profileOverride ?? "runtime",
6252
+ baseUrl: baseUrlOverride,
6253
+ apiKey: apiKeyOverride,
6254
+ readOnly: overrides.readOnly ?? false,
6255
+ json: overrides.json ?? false,
6256
+ profileSource: overrides.profile !== void 0 ? "flag" : envProfile !== void 0 ? "env" : void 0,
6257
+ baseUrlSource: overrides.baseUrl !== void 0 ? "flag" : envBaseUrl !== void 0 ? "env" : void 0,
6258
+ apiKeySource: overrides.apiKey !== void 0 ? "flag" : envApiKey !== void 0 ? "env" : void 0
6259
+ };
6260
+ }
6261
+ const profile = resolveProfile(config, {
6262
+ profile: profileOverride,
6263
+ baseUrl: baseUrlOverride,
6264
+ apiKey: apiKeyOverride
6265
+ });
6266
+ return {
6267
+ profile: profile.name,
6268
+ baseUrl: baseUrlOverride ?? profile.baseUrl ?? DEFAULT_PRODUCTION_BASE_URL,
6269
+ apiKey: apiKeyOverride ?? profile.apiKey,
6270
+ readOnly: overrides.readOnly ?? false,
6271
+ json: overrides.json ?? false,
6272
+ profileSource: overrides.profile !== void 0 ? "flag" : envProfile !== void 0 ? "env" : "config",
6273
+ baseUrlSource: overrides.baseUrl !== void 0 ? "flag" : envBaseUrl !== void 0 ? "env" : "config",
6274
+ apiKeySource: overrides.apiKey !== void 0 ? "flag" : envApiKey !== void 0 ? "env" : "config"
6275
+ };
6276
+ }
6277
+
6833
6278
  // src/commands/automations.ts
6834
6279
  function getCommandIo2(stdout) {
6835
6280
  return stdout ?? process.stdout;
@@ -7227,38 +6672,38 @@ function readConditions(literalConditions, jsonConditions, label) {
7227
6672
  )
7228
6673
  ];
7229
6674
  }
7230
- function resolveFolder(folders, selector2) {
7231
- if (selector2.kind === "uuid") {
7232
- const match = folders.find((folder) => folder.id === selector2.value);
6675
+ function resolveFolder(folders, selector) {
6676
+ if (selector.kind === "uuid") {
6677
+ const match = folders.find((folder) => folder.id === selector.value);
7233
6678
  if (match) {
7234
6679
  return match;
7235
6680
  }
7236
6681
  }
7237
- const matches = folders.filter((folder) => folder.name === selector2.value);
6682
+ const matches = folders.filter((folder) => folder.name === selector.value);
7238
6683
  if (matches.length === 1) {
7239
6684
  return matches[0];
7240
6685
  }
7241
6686
  if (matches.length > 1) {
7242
6687
  throw new CliError(
7243
6688
  "invalid_cli_usage",
7244
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
6689
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
7245
6690
  );
7246
6691
  }
7247
- throw new CliError("invalid_cli_usage", `Folder "${selector2.value}" was not found.`);
6692
+ throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
7248
6693
  }
7249
- async function resolveFolderSelector(api, selector2) {
7250
- if (!selector2) {
6694
+ async function resolveFolderSelector(api, selector) {
6695
+ if (!selector) {
7251
6696
  return void 0;
7252
6697
  }
7253
- if (selector2.kind === "uuid") {
7254
- return selector2;
6698
+ if (selector.kind === "uuid") {
6699
+ return selector;
7255
6700
  }
7256
6701
  const folders = await api.listFolders();
7257
- const resolved = resolveFolder(folders, selector2);
6702
+ const resolved = resolveFolder(folders, selector);
7258
6703
  if (typeof resolved.id !== "string" || resolved.id.length === 0) {
7259
6704
  throw new CliError(
7260
6705
  "invalid_cli_usage",
7261
- `Folder "${selector2.value}" is missing an id in the API response.`
6706
+ `Folder "${selector.value}" is missing an id in the API response.`
7262
6707
  );
7263
6708
  }
7264
6709
  return { kind: "uuid", value: resolved.id };
@@ -8038,7 +7483,7 @@ import { readFileSync as readFileSync3 } from "fs";
8038
7483
  import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
8039
7484
 
8040
7485
  // src/api/comments.ts
8041
- function jsonOptions3(body, method) {
7486
+ function jsonOptions2(body, method) {
8042
7487
  return {
8043
7488
  method,
8044
7489
  headers: {
@@ -8047,8 +7492,8 @@ function jsonOptions3(body, method) {
8047
7492
  body: JSON.stringify(body)
8048
7493
  };
8049
7494
  }
8050
- function selectorValue3(selector2) {
8051
- return selector2.value;
7495
+ function selectorValue2(selector) {
7496
+ return selector.value;
8052
7497
  }
8053
7498
  var CommentsApi = class {
8054
7499
  constructor(client) {
@@ -8056,13 +7501,13 @@ var CommentsApi = class {
8056
7501
  }
8057
7502
  listComments(schema, recordId) {
8058
7503
  return this.client.getJson(
8059
- `/api/v2/schemas/${selectorValue3(schema)}/records/${recordId}/comments`
7504
+ `/api/v2/schemas/${selectorValue2(schema)}/records/${recordId}/comments`
8060
7505
  );
8061
7506
  }
8062
7507
  createComment(schema, recordId, input) {
8063
7508
  return this.client.requestJson(
8064
- `/api/v2/schemas/${selectorValue3(schema)}/records/${recordId}/comments`,
8065
- jsonOptions3(input, "POST")
7509
+ `/api/v2/schemas/${selectorValue2(schema)}/records/${recordId}/comments`,
7510
+ jsonOptions2(input, "POST")
8066
7511
  );
8067
7512
  }
8068
7513
  };
@@ -8256,7 +7701,7 @@ import { readFileSync as readFileSync4 } from "fs";
8256
7701
  import { InvalidArgumentError as InvalidArgumentError3 } from "commander";
8257
7702
 
8258
7703
  // src/api/displays.ts
8259
- function jsonOptions4(body, method) {
7704
+ function jsonOptions3(body, method) {
8260
7705
  return {
8261
7706
  method,
8262
7707
  headers: {
@@ -8265,8 +7710,8 @@ function jsonOptions4(body, method) {
8265
7710
  body: JSON.stringify(body)
8266
7711
  };
8267
7712
  }
8268
- function selectorValue4(selector2) {
8269
- return encodeURIComponent(selector2.value);
7713
+ function selectorValue3(selector) {
7714
+ return encodeURIComponent(selector.value);
8270
7715
  }
8271
7716
  function segment2(value) {
8272
7717
  return encodeURIComponent(value);
@@ -8279,145 +7724,145 @@ var DisplaysApi = class {
8279
7724
  return this.client.getJson("/api/v2/displays");
8280
7725
  }
8281
7726
  getDisplay(display) {
8282
- return this.client.getJson(`/api/v2/displays/${selectorValue4(display)}`);
7727
+ return this.client.getJson(`/api/v2/displays/${selectorValue3(display)}`);
8283
7728
  }
8284
7729
  createDisplay(body) {
8285
- return this.client.requestJson("/api/v2/displays", jsonOptions4(body, "POST"));
7730
+ return this.client.requestJson("/api/v2/displays", jsonOptions3(body, "POST"));
8286
7731
  }
8287
7732
  updateDisplay(display, body) {
8288
7733
  return this.client.requestJson(
8289
- `/api/v2/displays/${selectorValue4(display)}`,
8290
- jsonOptions4(body, "PATCH")
7734
+ `/api/v2/displays/${selectorValue3(display)}`,
7735
+ jsonOptions3(body, "PATCH")
8291
7736
  );
8292
7737
  }
8293
7738
  deleteDisplay(display) {
8294
7739
  return this.client.requestJson(
8295
- `/api/v2/displays/${selectorValue4(display)}`,
7740
+ `/api/v2/displays/${selectorValue3(display)}`,
8296
7741
  { method: "DELETE" }
8297
7742
  );
8298
7743
  }
8299
7744
  getLayout(display) {
8300
7745
  return this.client.getJson(
8301
- `/api/v2/displays/${selectorValue4(display)}/layout`
7746
+ `/api/v2/displays/${selectorValue3(display)}/layout`
8302
7747
  );
8303
7748
  }
8304
7749
  patchLayout(display, body) {
8305
7750
  return this.client.requestJson(
8306
- `/api/v2/displays/${selectorValue4(display)}/layout`,
8307
- jsonOptions4(body, "PATCH")
7751
+ `/api/v2/displays/${selectorValue3(display)}/layout`,
7752
+ jsonOptions3(body, "PATCH")
8308
7753
  );
8309
7754
  }
8310
7755
  listTabs(display) {
8311
7756
  return this.client.getJson(
8312
- `/api/v2/displays/${selectorValue4(display)}/tabs`
7757
+ `/api/v2/displays/${selectorValue3(display)}/tabs`
8313
7758
  );
8314
7759
  }
8315
7760
  createTab(display, body) {
8316
7761
  return this.client.requestJson(
8317
- `/api/v2/displays/${selectorValue4(display)}/tabs`,
8318
- jsonOptions4(body, "POST")
7762
+ `/api/v2/displays/${selectorValue3(display)}/tabs`,
7763
+ jsonOptions3(body, "POST")
8319
7764
  );
8320
7765
  }
8321
7766
  updateTab(display, tabId, body) {
8322
7767
  return this.client.requestJson(
8323
- `/api/v2/displays/${selectorValue4(display)}/tabs/${segment2(tabId)}`,
8324
- jsonOptions4(body, "PATCH")
7768
+ `/api/v2/displays/${selectorValue3(display)}/tabs/${segment2(tabId)}`,
7769
+ jsonOptions3(body, "PATCH")
8325
7770
  );
8326
7771
  }
8327
7772
  deleteTab(display, tabId) {
8328
7773
  return this.client.requestJson(
8329
- `/api/v2/displays/${selectorValue4(display)}/tabs/${segment2(tabId)}`,
7774
+ `/api/v2/displays/${selectorValue3(display)}/tabs/${segment2(tabId)}`,
8330
7775
  { method: "DELETE" }
8331
7776
  );
8332
7777
  }
8333
7778
  listVariables(display) {
8334
7779
  return this.client.getJson(
8335
- `/api/v2/displays/${selectorValue4(display)}/variables`
7780
+ `/api/v2/displays/${selectorValue3(display)}/variables`
8336
7781
  );
8337
7782
  }
8338
7783
  getVariable(display, variableId) {
8339
7784
  return this.client.getJson(
8340
- `/api/v2/displays/${selectorValue4(display)}/variables/${segment2(variableId)}`
7785
+ `/api/v2/displays/${selectorValue3(display)}/variables/${segment2(variableId)}`
8341
7786
  );
8342
7787
  }
8343
7788
  createVariable(display, body) {
8344
7789
  return this.client.requestJson(
8345
- `/api/v2/displays/${selectorValue4(display)}/variables`,
8346
- jsonOptions4(body, "POST")
7790
+ `/api/v2/displays/${selectorValue3(display)}/variables`,
7791
+ jsonOptions3(body, "POST")
8347
7792
  );
8348
7793
  }
8349
7794
  updateVariable(display, variableId, body) {
8350
7795
  return this.client.requestJson(
8351
- `/api/v2/displays/${selectorValue4(display)}/variables/${segment2(variableId)}`,
8352
- jsonOptions4(body, "PATCH")
7796
+ `/api/v2/displays/${selectorValue3(display)}/variables/${segment2(variableId)}`,
7797
+ jsonOptions3(body, "PATCH")
8353
7798
  );
8354
7799
  }
8355
7800
  deleteVariable(display, variableId) {
8356
7801
  return this.client.requestJson(
8357
- `/api/v2/displays/${selectorValue4(display)}/variables/${segment2(variableId)}`,
7802
+ `/api/v2/displays/${selectorValue3(display)}/variables/${segment2(variableId)}`,
8358
7803
  { method: "DELETE" }
8359
7804
  );
8360
7805
  }
8361
7806
  listWidgets(display) {
8362
7807
  return this.client.getJson(
8363
- `/api/v2/displays/${selectorValue4(display)}/widgets`
7808
+ `/api/v2/displays/${selectorValue3(display)}/widgets`
8364
7809
  );
8365
7810
  }
8366
7811
  getWidget(display, widgetId) {
8367
7812
  return this.client.getJson(
8368
- `/api/v2/displays/${selectorValue4(display)}/widgets/${segment2(widgetId)}`
7813
+ `/api/v2/displays/${selectorValue3(display)}/widgets/${segment2(widgetId)}`
8369
7814
  );
8370
7815
  }
8371
7816
  createWidget(display, body) {
8372
7817
  return this.client.requestJson(
8373
- `/api/v2/displays/${selectorValue4(display)}/widgets`,
8374
- jsonOptions4(body, "POST")
7818
+ `/api/v2/displays/${selectorValue3(display)}/widgets`,
7819
+ jsonOptions3(body, "POST")
8375
7820
  );
8376
7821
  }
8377
7822
  updateWidget(display, widgetId, body) {
8378
7823
  return this.client.requestJson(
8379
- `/api/v2/displays/${selectorValue4(display)}/widgets/${segment2(widgetId)}`,
8380
- jsonOptions4(body, "PATCH")
7824
+ `/api/v2/displays/${selectorValue3(display)}/widgets/${segment2(widgetId)}`,
7825
+ jsonOptions3(body, "PATCH")
8381
7826
  );
8382
7827
  }
8383
7828
  deleteWidget(display, widgetId) {
8384
7829
  return this.client.requestJson(
8385
- `/api/v2/displays/${selectorValue4(display)}/widgets/${segment2(widgetId)}`,
7830
+ `/api/v2/displays/${selectorValue3(display)}/widgets/${segment2(widgetId)}`,
8386
7831
  { method: "DELETE" }
8387
7832
  );
8388
7833
  }
8389
7834
  createNavigationTarget(display, body) {
8390
7835
  return this.client.requestJson(
8391
- `/api/v2/displays/${selectorValue4(display)}/navigation-targets`,
8392
- jsonOptions4(body, "POST")
7836
+ `/api/v2/displays/${selectorValue3(display)}/navigation-targets`,
7837
+ jsonOptions3(body, "POST")
8393
7838
  );
8394
7839
  }
8395
7840
  updateNavigationTarget(display, targetId, body) {
8396
7841
  return this.client.requestJson(
8397
- `/api/v2/displays/${selectorValue4(display)}/navigation-targets/${segment2(targetId)}`,
8398
- jsonOptions4(body, "PATCH")
7842
+ `/api/v2/displays/${selectorValue3(display)}/navigation-targets/${segment2(targetId)}`,
7843
+ jsonOptions3(body, "PATCH")
8399
7844
  );
8400
7845
  }
8401
7846
  deleteNavigationTarget(display, targetId) {
8402
7847
  return this.client.requestJson(
8403
- `/api/v2/displays/${selectorValue4(display)}/navigation-targets/${segment2(targetId)}`,
7848
+ `/api/v2/displays/${selectorValue3(display)}/navigation-targets/${segment2(targetId)}`,
8404
7849
  { method: "DELETE" }
8405
7850
  );
8406
7851
  }
8407
7852
  getCrossWidgetFilter(display) {
8408
7853
  return this.client.getJson(
8409
- `/api/v2/displays/${selectorValue4(display)}/cross-widget-filter`
7854
+ `/api/v2/displays/${selectorValue3(display)}/cross-widget-filter`
8410
7855
  );
8411
7856
  }
8412
7857
  setCrossWidgetFilter(display, body) {
8413
7858
  return this.client.requestJson(
8414
- `/api/v2/displays/${selectorValue4(display)}/cross-widget-filter`,
8415
- jsonOptions4(body, "PUT")
7859
+ `/api/v2/displays/${selectorValue3(display)}/cross-widget-filter`,
7860
+ jsonOptions3(body, "PUT")
8416
7861
  );
8417
7862
  }
8418
7863
  deleteCrossWidgetFilter(display) {
8419
7864
  return this.client.requestJson(
8420
- `/api/v2/displays/${selectorValue4(display)}/cross-widget-filter`,
7865
+ `/api/v2/displays/${selectorValue3(display)}/cross-widget-filter`,
8421
7866
  { method: "DELETE" }
8422
7867
  );
8423
7868
  }
@@ -8985,8 +8430,8 @@ import { basename } from "path";
8985
8430
  import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
8986
8431
 
8987
8432
  // src/api/files.ts
8988
- function selectorValue5(selector2) {
8989
- return selector2.value;
8433
+ function selectorValue4(selector) {
8434
+ return selector.value;
8990
8435
  }
8991
8436
  var FilesApi = class {
8992
8437
  constructor(client) {
@@ -8999,11 +8444,11 @@ var FilesApi = class {
8999
8444
  });
9000
8445
  }
9001
8446
  downloadFile(file) {
9002
- return this.client.requestBinary(`/api/v2/files/${selectorValue5(file)}`);
8447
+ return this.client.requestBinary(`/api/v2/files/${selectorValue4(file)}`);
9003
8448
  }
9004
8449
  deleteFile(file) {
9005
8450
  return this.client.requestJson(
9006
- `/api/v2/files/${selectorValue5(file)}`,
8451
+ `/api/v2/files/${selectorValue4(file)}`,
9007
8452
  { method: "DELETE" }
9008
8453
  );
9009
8454
  }
@@ -9191,8 +8636,8 @@ function registerFilesCommands(program, options = {}) {
9191
8636
  import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
9192
8637
 
9193
8638
  // src/api/logs.ts
9194
- function selectorValue6(selector2) {
9195
- return selector2.value;
8639
+ function selectorValue5(selector) {
8640
+ return selector.value;
9196
8641
  }
9197
8642
  var LogsApi = class {
9198
8643
  constructor(client) {
@@ -9200,7 +8645,7 @@ var LogsApi = class {
9200
8645
  }
9201
8646
  listLogs(schema, recordId) {
9202
8647
  return this.client.getJson(
9203
- `/api/v2/schemas/${selectorValue6(schema)}/records/${recordId}/logs`
8648
+ `/api/v2/schemas/${selectorValue5(schema)}/records/${recordId}/logs`
9204
8649
  );
9205
8650
  }
9206
8651
  };
@@ -9300,7 +8745,7 @@ import { readFileSync as readFileSync6 } from "fs";
9300
8745
  import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
9301
8746
 
9302
8747
  // src/api/navigation.ts
9303
- function jsonOptions5(body, method) {
8748
+ function jsonOptions4(body, method) {
9304
8749
  return {
9305
8750
  method,
9306
8751
  headers: {
@@ -9309,8 +8754,8 @@ function jsonOptions5(body, method) {
9309
8754
  body: JSON.stringify(body)
9310
8755
  };
9311
8756
  }
9312
- function selectorValue7(selector2) {
9313
- return selector2.value;
8757
+ function selectorValue6(selector) {
8758
+ return selector.value;
9314
8759
  }
9315
8760
  var NavigationApi = class {
9316
8761
  constructor(client) {
@@ -9322,25 +8767,25 @@ var NavigationApi = class {
9322
8767
  createFolder(body) {
9323
8768
  return this.client.requestJson(
9324
8769
  "/api/v2/navigation/folders",
9325
- jsonOptions5(body, "POST")
8770
+ jsonOptions4(body, "POST")
9326
8771
  );
9327
8772
  }
9328
8773
  updateFolder(folder, body) {
9329
8774
  return this.client.requestJson(
9330
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
9331
- jsonOptions5(body, "PATCH")
8775
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
8776
+ jsonOptions4(body, "PATCH")
9332
8777
  );
9333
8778
  }
9334
8779
  deleteFolder(folder) {
9335
8780
  return this.client.requestJson(
9336
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
8781
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
9337
8782
  { method: "DELETE" }
9338
8783
  );
9339
8784
  }
9340
8785
  moveResource(body) {
9341
8786
  return this.client.requestJson(
9342
8787
  "/api/v2/navigation/resources:move",
9343
- jsonOptions5(body, "POST")
8788
+ jsonOptions4(body, "POST")
9344
8789
  );
9345
8790
  }
9346
8791
  };
@@ -9455,25 +8900,25 @@ function buildFolderBody(options) {
9455
8900
  }
9456
8901
  return body;
9457
8902
  }
9458
- function resolveFolder2(folders, selector2) {
9459
- if (selector2.kind === "uuid") {
9460
- const match = folders.find((folder) => folder.id === selector2.value);
8903
+ function resolveFolder2(folders, selector) {
8904
+ if (selector.kind === "uuid") {
8905
+ const match = folders.find((folder) => folder.id === selector.value);
9461
8906
  if (!match) {
9462
- throw new CliError("invalid_cli_usage", `Folder "${selector2.value}" was not found.`);
8907
+ throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
9463
8908
  }
9464
8909
  return match;
9465
8910
  }
9466
- const matches = folders.filter((folder) => folder.name === selector2.value);
8911
+ const matches = folders.filter((folder) => folder.name === selector.value);
9467
8912
  if (matches.length === 1) {
9468
8913
  return matches[0];
9469
8914
  }
9470
8915
  if (matches.length > 1) {
9471
8916
  throw new CliError(
9472
8917
  "invalid_cli_usage",
9473
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
8918
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
9474
8919
  );
9475
8920
  }
9476
- throw new CliError("invalid_cli_usage", `Folder "${selector2.value}" was not found.`);
8921
+ throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
9477
8922
  }
9478
8923
  function folderRows2(folders) {
9479
8924
  return folders.map((folder) => ({
@@ -9730,7 +9175,7 @@ import { readFileSync as readFileSync7 } from "fs";
9730
9175
  import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
9731
9176
 
9732
9177
  // src/api/records.ts
9733
- function jsonOptions6(body, method) {
9178
+ function jsonOptions5(body, method) {
9734
9179
  return {
9735
9180
  method,
9736
9181
  headers: {
@@ -9739,8 +9184,8 @@ function jsonOptions6(body, method) {
9739
9184
  body: JSON.stringify(body)
9740
9185
  };
9741
9186
  }
9742
- function selectorValue8(selector2) {
9743
- return selector2.value;
9187
+ function selectorValue7(selector) {
9188
+ return selector.value;
9744
9189
  }
9745
9190
  var RecordsApi = class {
9746
9191
  constructor(client) {
@@ -9754,7 +9199,7 @@ var RecordsApi = class {
9754
9199
  if (query.offset !== void 0) {
9755
9200
  params.set("offset", String(query.offset));
9756
9201
  }
9757
- const path = `/api/v2/schemas/${selectorValue8(schema)}/records`;
9202
+ const path = `/api/v2/schemas/${selectorValue7(schema)}/records`;
9758
9203
  const queryString = params.toString();
9759
9204
  return this.client.getJson(
9760
9205
  queryString ? `${path}?${queryString}` : path
@@ -9763,36 +9208,36 @@ var RecordsApi = class {
9763
9208
  queryRecords(schema, query) {
9764
9209
  const body = this.normalizeQueryInput(query);
9765
9210
  return this.client.requestJson(
9766
- `/api/v2/schemas/${selectorValue8(schema)}/records:query`,
9767
- jsonOptions6(body, "POST")
9211
+ `/api/v2/schemas/${selectorValue7(schema)}/records:query`,
9212
+ jsonOptions5(body, "POST")
9768
9213
  );
9769
9214
  }
9770
9215
  getRecord(schema, record) {
9771
9216
  return this.client.getJson(
9772
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`
9217
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`
9773
9218
  );
9774
9219
  }
9775
9220
  createRecord(schema, input) {
9776
9221
  return this.client.requestJson(
9777
- `/api/v2/schemas/${selectorValue8(schema)}/records`,
9778
- jsonOptions6(input, "POST")
9222
+ `/api/v2/schemas/${selectorValue7(schema)}/records`,
9223
+ jsonOptions5(input, "POST")
9779
9224
  );
9780
9225
  }
9781
9226
  updateRecord(schema, record, input) {
9782
9227
  return this.client.requestJson(
9783
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
9784
- jsonOptions6(input, "PATCH")
9228
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9229
+ jsonOptions5(input, "PATCH")
9785
9230
  );
9786
9231
  }
9787
9232
  deleteRecord(schema, record) {
9788
9233
  return this.client.requestJson(
9789
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
9234
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9790
9235
  { method: "DELETE" }
9791
9236
  );
9792
9237
  }
9793
9238
  clearRecords(schema) {
9794
9239
  return this.client.requestJson(
9795
- `/api/v2/schemas/${selectorValue8(schema)}/records:clear`,
9240
+ `/api/v2/schemas/${selectorValue7(schema)}/records:clear`,
9796
9241
  { method: "DELETE" }
9797
9242
  );
9798
9243
  }
@@ -9824,6 +9269,73 @@ var RecordsApi = class {
9824
9269
  }
9825
9270
  };
9826
9271
 
9272
+ // src/api/schemas.ts
9273
+ function jsonOptions6(body, method) {
9274
+ return {
9275
+ method,
9276
+ headers: {
9277
+ "content-type": "application/json"
9278
+ },
9279
+ body: JSON.stringify(body)
9280
+ };
9281
+ }
9282
+ function selectorValue8(selector) {
9283
+ return selector.value;
9284
+ }
9285
+ var SchemasApi = class {
9286
+ constructor(client) {
9287
+ this.client = client;
9288
+ }
9289
+ listSchemas() {
9290
+ return this.client.getJson("/api/v2/schemas");
9291
+ }
9292
+ getSchema(schema) {
9293
+ return this.client.getJson(`/api/v2/schemas/${selectorValue8(schema)}`);
9294
+ }
9295
+ createSchema(input) {
9296
+ return this.client.requestJson("/api/v2/schemas", jsonOptions6(input, "POST"));
9297
+ }
9298
+ updateSchema(schema, input) {
9299
+ return this.client.requestJson(
9300
+ `/api/v2/schemas/${selectorValue8(schema)}`,
9301
+ jsonOptions6(input, "PATCH")
9302
+ );
9303
+ }
9304
+ deleteSchema(schema) {
9305
+ return this.client.requestJson(
9306
+ `/api/v2/schemas/${selectorValue8(schema)}`,
9307
+ { method: "DELETE" }
9308
+ );
9309
+ }
9310
+ async listFields(schema) {
9311
+ const result = await this.getSchema(schema);
9312
+ return Array.isArray(result.fields) ? result.fields : [];
9313
+ }
9314
+ getField(schema, field) {
9315
+ return this.client.getJson(
9316
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`
9317
+ );
9318
+ }
9319
+ createField(schema, input) {
9320
+ return this.client.requestJson(
9321
+ `/api/v2/schemas/${selectorValue8(schema)}/fields`,
9322
+ jsonOptions6(input, "POST")
9323
+ );
9324
+ }
9325
+ updateField(schema, field, input) {
9326
+ return this.client.requestJson(
9327
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`,
9328
+ jsonOptions6(input, "PATCH")
9329
+ );
9330
+ }
9331
+ deleteField(schema, field) {
9332
+ return this.client.requestJson(
9333
+ `/api/v2/schemas/${selectorValue8(schema)}/fields/${selectorValue8(field)}`,
9334
+ { method: "DELETE" }
9335
+ );
9336
+ }
9337
+ };
9338
+
9827
9339
  // src/parsers/expressions.ts
9828
9340
  var supportedComparators = /* @__PURE__ */ new Set([
9829
9341
  "eq",
@@ -10209,14 +9721,14 @@ function getQueryRecords(result) {
10209
9721
  function getRecordIdentifier(record) {
10210
9722
  return typeof record.recordId === "string" ? record.recordId : "unknown";
10211
9723
  }
10212
- async function resolveSchemaSelector(api, selector2) {
10213
- if (selector2.kind === "uuid") {
10214
- return selector2;
9724
+ async function resolveSchemaSelector(api, selector) {
9725
+ if (selector.kind === "uuid") {
9726
+ return selector;
10215
9727
  }
10216
9728
  const schemas = await api.listSchemas();
10217
- const match = schemas.find((entry) => entry.slug === selector2.value);
9729
+ const match = schemas.find((entry) => entry.slug === selector.value);
10218
9730
  if (!match || typeof match.id !== "string") {
10219
- throw new CliError("invalid_cli_usage", `Schema "${selector2.value}" not found.`);
9731
+ throw new CliError("invalid_cli_usage", `Schema "${selector.value}" not found.`);
10220
9732
  }
10221
9733
  return {
10222
9734
  kind: "uuid",
@@ -10600,28 +10112,28 @@ function buildFieldUpdateInput(currentType, options) {
10600
10112
  applyFieldDefaultValue(input, options.default);
10601
10113
  return input;
10602
10114
  }
10603
- async function resolveSchemaSelector2(api, selector2) {
10604
- if (selector2.kind === "uuid") {
10605
- return selector2;
10115
+ async function resolveSchemaSelector2(api, selector) {
10116
+ if (selector.kind === "uuid") {
10117
+ return selector;
10606
10118
  }
10607
10119
  const schemas = await api.listSchemas();
10608
- const match = schemas.find((schema) => schema.slug === selector2.value);
10120
+ const match = schemas.find((schema) => schema.slug === selector.value);
10609
10121
  if (!match || typeof match.id !== "string") {
10610
- throw new CliError("invalid_cli_usage", `Schema "${selector2.value}" not found.`);
10122
+ throw new CliError("invalid_cli_usage", `Schema "${selector.value}" not found.`);
10611
10123
  }
10612
10124
  return {
10613
10125
  kind: "uuid",
10614
10126
  value: match.id
10615
10127
  };
10616
10128
  }
10617
- async function resolveFieldSelector(api, schema, selector2) {
10618
- if (selector2.kind === "uuid") {
10619
- return selector2;
10129
+ async function resolveFieldSelector(api, schema, selector) {
10130
+ if (selector.kind === "uuid") {
10131
+ return selector;
10620
10132
  }
10621
10133
  const fields = await api.listFields(schema);
10622
- const match = fields.find((field) => field.slug === selector2.value);
10134
+ const match = fields.find((field) => field.slug === selector.value);
10623
10135
  if (!match || typeof match.id !== "string") {
10624
- throw new CliError("invalid_cli_usage", `Field "${selector2.value}" not found.`);
10136
+ throw new CliError("invalid_cli_usage", `Field "${selector.value}" not found.`);
10625
10137
  }
10626
10138
  return {
10627
10139
  kind: "uuid",
@@ -10799,8 +10311,8 @@ function jsonOptions7(body, method) {
10799
10311
  body: JSON.stringify(body)
10800
10312
  };
10801
10313
  }
10802
- function selectorValue9(selector2) {
10803
- return selector2.value;
10314
+ function selectorValue9(selector) {
10315
+ return selector.value;
10804
10316
  }
10805
10317
  var TeamspaceApi = class {
10806
10318
  constructor(client) {
@@ -11029,11 +10541,11 @@ function emitTable5(stdout, data) {
11029
10541
  function getFolderIdentifier(folder) {
11030
10542
  return typeof folder.id === "string" ? folder.id : typeof folder.name === "string" ? folder.name : "unknown";
11031
10543
  }
11032
- function buildFolderLookup(folders, selector2) {
11033
- if (selector2.kind === "uuid") {
11034
- return selector2;
10544
+ function buildFolderLookup(folders, selector) {
10545
+ if (selector.kind === "uuid") {
10546
+ return selector;
11035
10547
  }
11036
- const matches = folders.filter((folder) => folder.name === selector2.value);
10548
+ const matches = folders.filter((folder) => folder.name === selector.value);
11037
10549
  if (matches.length === 1) {
11038
10550
  const folderId = matches[0]?.id;
11039
10551
  if (typeof folderId === "string" && folderId.length > 0) {
@@ -11046,37 +10558,37 @@ function buildFolderLookup(folders, selector2) {
11046
10558
  if (matches.length > 1) {
11047
10559
  throw new CliError(
11048
10560
  "invalid_cli_usage",
11049
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
10561
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
11050
10562
  );
11051
10563
  }
11052
- throw new CliError("invalid_cli_usage", `Folder "${selector2.value}" was not found.`);
10564
+ throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
11053
10565
  }
11054
- function findFolderEntity(folders, selector2) {
11055
- if (selector2.kind === "uuid") {
11056
- const match = folders.find((folder) => folder.id === selector2.value);
10566
+ function findFolderEntity(folders, selector) {
10567
+ if (selector.kind === "uuid") {
10568
+ const match = folders.find((folder) => folder.id === selector.value);
11057
10569
  if (match) {
11058
10570
  return match;
11059
10571
  }
11060
- throw new CliError("invalid_cli_usage", `Folder "${selector2.value}" was not found.`);
10572
+ throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
11061
10573
  }
11062
- const matches = folders.filter((folder) => folder.name === selector2.value);
10574
+ const matches = folders.filter((folder) => folder.name === selector.value);
11063
10575
  if (matches.length === 1) {
11064
10576
  return matches[0];
11065
10577
  }
11066
10578
  if (matches.length > 1) {
11067
10579
  throw new CliError(
11068
10580
  "invalid_cli_usage",
11069
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
10581
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
11070
10582
  );
11071
10583
  }
11072
- throw new CliError("invalid_cli_usage", `Folder "${selector2.value}" was not found.`);
10584
+ throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
11073
10585
  }
11074
- async function resolveFolderSelector2(api, selector2) {
11075
- if (selector2.kind === "uuid") {
11076
- return selector2;
10586
+ async function resolveFolderSelector2(api, selector) {
10587
+ if (selector.kind === "uuid") {
10588
+ return selector;
11077
10589
  }
11078
10590
  const folders = await api.listFolders(false);
11079
- return buildFolderLookup(folders, selector2);
10591
+ return buildFolderLookup(folders, selector);
11080
10592
  }
11081
10593
  function registerTeamspaceCommands(program, options = {}) {
11082
10594
  const filePath = options.configPath ?? defaultConfigPath;
@@ -11751,15 +11263,11 @@ async function runCli(argv) {
11751
11263
  const optionMeta = buildOptionMetadata(program);
11752
11264
  const exampleRequest = extractExampleRequest(argv, optionMeta);
11753
11265
  if (exampleRequest) {
11754
- await showExamples(
11266
+ showExamples(
11755
11267
  exampleRequest.commandName,
11756
11268
  exampleRequest.json,
11757
11269
  void 0,
11758
- exampleRequest.filters,
11759
- {
11760
- enabled: true,
11761
- overrides: exampleRequest.overrides
11762
- }
11270
+ exampleRequest.filters
11763
11271
  );
11764
11272
  throw new ExampleDisplayed();
11765
11273
  }