zinkee 0.1.12 → 0.1.17

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
@@ -660,6 +660,13 @@ var commandRegistry = {
660
660
  supportsRaw: false,
661
661
  output: writeOutput
662
662
  },
663
+ "records clear": {
664
+ command: "records clear",
665
+ accessLevel: "destructive",
666
+ supportsExample: true,
667
+ supportsRaw: false,
668
+ output: writeOutput
669
+ },
663
670
  "comments list": {
664
671
  command: "comments list",
665
672
  accessLevel: "read",
@@ -1231,574 +1238,27 @@ function formatCliErrorJson(error, meta = {}) {
1231
1238
  return JSON.stringify(buildJsonCliError(error, meta));
1232
1239
  }
1233
1240
 
1234
- // src/api/automations.ts
1235
- function jsonOptions(body, method) {
1236
- return {
1237
- method,
1238
- headers: {
1239
- "content-type": "application/json"
1240
- },
1241
- body: JSON.stringify(body)
1242
- };
1243
- }
1244
- function selectorValue(selector2) {
1245
- return encodeURIComponent(selector2.value);
1241
+ // src/utils/schema-fields.ts
1242
+ function isJsonObject(value) {
1243
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1246
1244
  }
1247
- function segment(value) {
1248
- return encodeURIComponent(value);
1245
+ function toJsonObject(value) {
1246
+ return isJsonObject(value) ? value : void 0;
1249
1247
  }
1250
- function appendQuery(path, query) {
1251
- const queryString = query.toString();
1252
- return queryString.length > 0 ? `${path}?${queryString}` : path;
1248
+ function toStringValue(value) {
1249
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1253
1250
  }
1254
- var AutomationsApi = class {
1255
- constructor(client) {
1256
- this.client = client;
1257
- }
1258
- listFolders() {
1259
- return this.client.getJson("/api/v2/automation-folders");
1260
- }
1261
- createFolder(body) {
1262
- return this.client.requestJson(
1263
- "/api/v2/automation-folders",
1264
- jsonOptions(body, "POST")
1265
- );
1266
- }
1267
- updateFolder(folder, body) {
1268
- return this.client.requestJson(
1269
- `/api/v2/automation-folders/${selectorValue(folder)}`,
1270
- jsonOptions(body, "PATCH")
1271
- );
1272
- }
1273
- deleteFolder(folder) {
1274
- return this.client.requestJson(
1275
- `/api/v2/automation-folders/${selectorValue(folder)}`,
1276
- { method: "DELETE" }
1277
- );
1278
- }
1279
- moveAutomation(input) {
1280
- return this.client.requestJson(
1281
- `/api/v2/automation-folders/${segment(input.targetFolderId)}/automations:move`,
1282
- jsonOptions(input, "POST")
1283
- );
1251
+ function toNumberValue(value) {
1252
+ if (typeof value === "number" && Number.isFinite(value)) {
1253
+ return value;
1284
1254
  }
1285
- listAutomations(query = {}) {
1286
- const params = new URLSearchParams();
1287
- if (query.folderId) {
1288
- params.set("folderId", query.folderId);
1289
- }
1290
- if (query.status) {
1291
- params.set("status", query.status);
1292
- }
1293
- if (query.triggerType) {
1294
- params.set("triggerType", query.triggerType);
1295
- }
1296
- if (query.actionType) {
1297
- params.set("actionType", query.actionType);
1298
- }
1299
- if (query.pluginId) {
1300
- params.set("pluginId", query.pluginId);
1301
- }
1302
- if (query.search) {
1303
- params.set("search", query.search);
1255
+ if (typeof value === "string" && value.trim().length > 0) {
1256
+ const parsed = Number(value);
1257
+ if (Number.isFinite(parsed)) {
1258
+ return parsed;
1304
1259
  }
1305
- return this.client.getJson(
1306
- appendQuery("/api/v2/automations", params)
1307
- );
1308
- }
1309
- getAutomation(automation) {
1310
- return this.client.getJson(
1311
- `/api/v2/automations/${selectorValue(automation)}`
1312
- );
1313
- }
1314
- createAutomation(input) {
1315
- return this.client.requestJson(
1316
- "/api/v2/automations",
1317
- jsonOptions(input, "POST")
1318
- );
1319
- }
1320
- updateAutomation(automation, input) {
1321
- return this.client.requestJson(
1322
- `/api/v2/automations/${selectorValue(automation)}`,
1323
- jsonOptions(input, "PATCH")
1324
- );
1325
- }
1326
- deleteAutomation(automation) {
1327
- return this.client.requestJson(
1328
- `/api/v2/automations/${selectorValue(automation)}`,
1329
- { method: "DELETE" }
1330
- );
1331
- }
1332
- activateAutomation(automation) {
1333
- return this.client.requestJson(
1334
- `/api/v2/automations/${selectorValue(automation)}:activate`,
1335
- { method: "POST" }
1336
- );
1337
- }
1338
- deactivateAutomation(automation) {
1339
- return this.client.requestJson(
1340
- `/api/v2/automations/${selectorValue(automation)}:deactivate`,
1341
- { method: "POST" }
1342
- );
1343
- }
1344
- getTrigger(automation) {
1345
- return this.client.getJson(
1346
- `/api/v2/automations/${selectorValue(automation)}/trigger`
1347
- );
1348
- }
1349
- setTrigger(automation, input) {
1350
- return this.client.requestJson(
1351
- `/api/v2/automations/${selectorValue(automation)}/trigger`,
1352
- jsonOptions(input, "PUT")
1353
- );
1354
- }
1355
- listActions(automation) {
1356
- return this.client.getJson(
1357
- `/api/v2/automations/${selectorValue(automation)}/actions`
1358
- );
1359
- }
1360
- addAction(automation, input) {
1361
- return this.client.requestJson(
1362
- `/api/v2/automations/${selectorValue(automation)}/actions`,
1363
- jsonOptions(input, "POST")
1364
- );
1365
- }
1366
- updateAction(automation, actionId, input) {
1367
- return this.client.requestJson(
1368
- `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
1369
- jsonOptions(input, "PATCH")
1370
- );
1371
- }
1372
- deleteAction(automation, actionId) {
1373
- return this.client.requestJson(
1374
- `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
1375
- { method: "DELETE" }
1376
- );
1377
- }
1378
- getFlow(automation) {
1379
- return this.client.getJson(
1380
- `/api/v2/automations/${selectorValue(automation)}/flow`
1381
- );
1382
- }
1383
- setFlow(automation, input) {
1384
- return this.client.requestJson(
1385
- `/api/v2/automations/${selectorValue(automation)}/flow`,
1386
- jsonOptions(input, "PUT")
1387
- );
1388
- }
1389
- getWebhook(automation) {
1390
- return this.client.getJson(
1391
- `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`
1392
- );
1393
- }
1394
- setWebhook(automation, input) {
1395
- return this.client.requestJson(
1396
- `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
1397
- jsonOptions(input, "PUT")
1398
- );
1399
- }
1400
- deleteWebhook(automation) {
1401
- return this.client.requestJson(
1402
- `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
1403
- { method: "DELETE" }
1404
- );
1405
- }
1406
- listPlugins() {
1407
- return this.client.getJson("/api/v2/automation-plugins");
1408
- }
1409
- getPlugin(pluginId) {
1410
- return this.client.getJson(
1411
- `/api/v2/automation-plugins/${segment(pluginId)}`
1412
- );
1413
- }
1414
- listConnections() {
1415
- return this.client.getJson(
1416
- "/api/v2/automation-connections"
1417
- );
1418
- }
1419
- getConnection(connection) {
1420
- return this.client.getJson(
1421
- `/api/v2/automation-connections/${selectorValue(connection)}`
1422
- );
1423
- }
1424
- createConnection(input) {
1425
- return this.client.requestJson(
1426
- "/api/v2/automation-connections",
1427
- jsonOptions(input, "POST")
1428
- );
1429
- }
1430
- updateConnection(connection, input) {
1431
- return this.client.requestJson(
1432
- `/api/v2/automation-connections/${selectorValue(connection)}`,
1433
- jsonOptions(input, "PATCH")
1434
- );
1435
- }
1436
- deleteConnection(connection) {
1437
- return this.client.requestJson(
1438
- `/api/v2/automation-connections/${selectorValue(connection)}`,
1439
- { method: "DELETE" }
1440
- );
1441
1260
  }
1442
- };
1443
-
1444
- // src/api/schemas.ts
1445
- function jsonOptions2(body, method) {
1446
- return {
1447
- method,
1448
- headers: {
1449
- "content-type": "application/json"
1450
- },
1451
- body: JSON.stringify(body)
1452
- };
1453
- }
1454
- function selectorValue2(selector2) {
1455
- return selector2.value;
1456
- }
1457
- var SchemasApi = class {
1458
- constructor(client) {
1459
- this.client = client;
1460
- }
1461
- listSchemas() {
1462
- return this.client.getJson("/api/v2/schemas");
1463
- }
1464
- getSchema(schema) {
1465
- return this.client.getJson(`/api/v2/schemas/${selectorValue2(schema)}`);
1466
- }
1467
- createSchema(input) {
1468
- return this.client.requestJson("/api/v2/schemas", jsonOptions2(input, "POST"));
1469
- }
1470
- updateSchema(schema, input) {
1471
- return this.client.requestJson(
1472
- `/api/v2/schemas/${selectorValue2(schema)}`,
1473
- jsonOptions2(input, "PATCH")
1474
- );
1475
- }
1476
- deleteSchema(schema) {
1477
- return this.client.requestJson(
1478
- `/api/v2/schemas/${selectorValue2(schema)}`,
1479
- { method: "DELETE" }
1480
- );
1481
- }
1482
- async listFields(schema) {
1483
- const result = await this.getSchema(schema);
1484
- return Array.isArray(result.fields) ? result.fields : [];
1485
- }
1486
- getField(schema, field) {
1487
- return this.client.getJson(
1488
- `/api/v2/schemas/${selectorValue2(schema)}/fields/${selectorValue2(field)}`
1489
- );
1490
- }
1491
- createField(schema, input) {
1492
- return this.client.requestJson(
1493
- `/api/v2/schemas/${selectorValue2(schema)}/fields`,
1494
- jsonOptions2(input, "POST")
1495
- );
1496
- }
1497
- updateField(schema, field, input) {
1498
- return this.client.requestJson(
1499
- `/api/v2/schemas/${selectorValue2(schema)}/fields/${selectorValue2(field)}`,
1500
- jsonOptions2(input, "PATCH")
1501
- );
1502
- }
1503
- deleteField(schema, field) {
1504
- return this.client.requestJson(
1505
- `/api/v2/schemas/${selectorValue2(schema)}/fields/${selectorValue2(field)}`,
1506
- { method: "DELETE" }
1507
- );
1508
- }
1509
- };
1510
-
1511
- // src/config.ts
1512
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
1513
- import { homedir } from "os";
1514
- import { dirname, join } from "path";
1515
- import { parseTOML, stringifyTOML } from "confbox/toml";
1516
- var defaultConfigPath = join(homedir(), ".config", "zinkee", "config.toml");
1517
- var redactedSecretMask = "********";
1518
- var ENV_API_KEY = "ZINKEE_API_KEY";
1519
- var ENV_BASE_URL = "ZINKEE_API_BASE_URL";
1520
- var ENV_PROFILE = "ZINKEE_PROFILE";
1521
- var DEFAULT_PRODUCTION_BASE_URL = "https://api-z2.zinkee.com";
1522
- var ProfileResolutionError = class extends Error {
1523
- name = "ProfileResolutionError";
1524
- constructor(message) {
1525
- super(message);
1526
- }
1527
- };
1528
- function isRecord2(value) {
1529
- return typeof value === "object" && value !== null && !Array.isArray(value);
1530
- }
1531
- function toStringValue(value) {
1532
- return typeof value === "string" ? value : void 0;
1533
- }
1534
- function toNonEmptyString(value) {
1535
- const normalized = value?.trim();
1536
- return normalized ? normalized : void 0;
1537
- }
1538
- function parseProfileConfig(value) {
1539
- const profile = {};
1540
- if (!isRecord2(value)) {
1541
- return profile;
1542
- }
1543
- for (const [key, rawValue] of Object.entries(value)) {
1544
- if (key === "api_key") {
1545
- profile.apiKey = toStringValue(rawValue);
1546
- continue;
1547
- }
1548
- if (key === "base_url") {
1549
- profile.baseUrl = toStringValue(rawValue);
1550
- continue;
1551
- }
1552
- profile[key] = rawValue;
1553
- }
1554
- return profile;
1555
- }
1556
- function parseConfig(toml) {
1557
- const parsed = parseTOML(toml);
1558
- const config = { profiles: {} };
1559
- if (!isRecord2(parsed)) {
1560
- return config;
1561
- }
1562
- for (const [key, value] of Object.entries(parsed)) {
1563
- if (key === "default_profile") {
1564
- config.defaultProfile = toStringValue(value);
1565
- continue;
1566
- }
1567
- if (key === "profiles") {
1568
- if (!isRecord2(value)) {
1569
- continue;
1570
- }
1571
- for (const [profileName, profileValue] of Object.entries(value)) {
1572
- config.profiles[profileName] = parseProfileConfig(profileValue);
1573
- }
1574
- continue;
1575
- }
1576
- config[key] = value;
1577
- }
1578
- return config;
1579
- }
1580
- function readConfig(filePath = defaultConfigPath) {
1581
- return parseConfig(readFileSync(filePath, "utf8"));
1582
- }
1583
- function readConfigIfExists(filePath = defaultConfigPath) {
1584
- try {
1585
- return readConfig(filePath);
1586
- } catch (error) {
1587
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
1588
- return void 0;
1589
- }
1590
- throw error;
1591
- }
1592
- }
1593
- function readRuntimeConfig(filePath = defaultConfigPath) {
1594
- return readConfigIfExists(filePath) ?? { profiles: {} };
1595
- }
1596
- function serializeProfileConfig(profile) {
1597
- const serialized = {};
1598
- for (const [key, value] of Object.entries(profile)) {
1599
- if (value === void 0) {
1600
- continue;
1601
- }
1602
- if (key === "apiKey") {
1603
- serialized.api_key = value;
1604
- continue;
1605
- }
1606
- if (key === "baseUrl") {
1607
- serialized.base_url = value;
1608
- continue;
1609
- }
1610
- serialized[key] = value;
1611
- }
1612
- return serialized;
1613
- }
1614
- function serializeConfig(config) {
1615
- const serialized = {};
1616
- if (config.defaultProfile !== void 0) {
1617
- serialized.default_profile = config.defaultProfile;
1618
- }
1619
- for (const [key, value] of Object.entries(config)) {
1620
- if (key === "defaultProfile" || key === "profiles" || value === void 0) {
1621
- continue;
1622
- }
1623
- serialized[key] = value;
1624
- }
1625
- const serializedProfiles = Object.fromEntries(
1626
- Object.entries(config.profiles).map(([name, profile]) => [name, serializeProfileConfig(profile)])
1627
- );
1628
- if (Object.keys(serializedProfiles).length > 0) {
1629
- serialized.profiles = serializedProfiles;
1630
- }
1631
- return stringifyTOML(serialized).trimEnd().concat("\n");
1632
- }
1633
- function writeConfig(config, filePath = defaultConfigPath) {
1634
- mkdirSync(dirname(filePath), { recursive: true });
1635
- writeFileSync(filePath, serializeConfig(config), "utf8");
1636
- }
1637
- function setProfileConfig(config, profileName, updates) {
1638
- return {
1639
- ...config,
1640
- profiles: {
1641
- ...config.profiles,
1642
- [profileName]: {
1643
- ...config.profiles[profileName],
1644
- ...updates
1645
- }
1646
- }
1647
- };
1648
- }
1649
- function removeProfileConfig(config, profileName) {
1650
- const nextProfiles = { ...config.profiles };
1651
- delete nextProfiles[profileName];
1652
- return {
1653
- ...config,
1654
- defaultProfile: config.defaultProfile === profileName ? void 0 : config.defaultProfile,
1655
- profiles: nextProfiles
1656
- };
1657
- }
1658
- function setDefaultProfile(config, profileName) {
1659
- return {
1660
- ...config,
1661
- defaultProfile: profileName
1662
- };
1663
- }
1664
- function redactSecret(value) {
1665
- if (value === void 0) {
1666
- return void 0;
1667
- }
1668
- if (value.length <= 4) {
1669
- return redactedSecretMask;
1670
- }
1671
- return `${redactedSecretMask}${value.slice(-4)}`;
1672
- }
1673
- function redactProfile(profile) {
1674
- return {
1675
- ...profile,
1676
- apiKey: redactSecret(profile.apiKey)
1677
- };
1678
- }
1679
- function redactConfig(config) {
1680
- return {
1681
- ...config,
1682
- profiles: Object.fromEntries(
1683
- Object.entries(config.profiles).map(([name, profile]) => [name, redactProfile(profile)])
1684
- )
1685
- };
1686
- }
1687
- function resolveProfile(config, overrides = {}) {
1688
- const profileName = overrides.profile ?? config.defaultProfile;
1689
- if (profileName) {
1690
- const profile = config.profiles[profileName];
1691
- if (!profile) {
1692
- const label = overrides.profile ? "Profile" : "Default profile";
1693
- throw new ProfileResolutionError(`${label} "${profileName}" not found in config.`);
1694
- }
1695
- return {
1696
- ...profile,
1697
- name: profileName,
1698
- baseUrl: overrides.baseUrl ?? profile.baseUrl,
1699
- apiKey: overrides.apiKey ?? profile.apiKey
1700
- };
1701
- }
1702
- throw new ProfileResolutionError("No profile could be resolved from config.");
1703
- }
1704
- function validateBaseUrl(value) {
1705
- let parsed;
1706
- try {
1707
- parsed = new URL(value);
1708
- } catch {
1709
- throw new ProfileResolutionError(
1710
- `Environment variable ${ENV_BASE_URL} must be an absolute http(s) URL.`
1711
- );
1712
- }
1713
- if (!["http:", "https:"].includes(parsed.protocol) || !parsed.host) {
1714
- throw new ProfileResolutionError(
1715
- `Environment variable ${ENV_BASE_URL} must be an absolute http(s) URL.`
1716
- );
1717
- }
1718
- return value.replace(/\/+$/, "");
1719
- }
1720
- function readEnvApiKey(env = process.env) {
1721
- return toNonEmptyString(env[ENV_API_KEY]);
1722
- }
1723
- function readEnvBaseUrl(env = process.env) {
1724
- const baseUrl = toNonEmptyString(env[ENV_BASE_URL]);
1725
- if (!baseUrl) {
1726
- return void 0;
1727
- }
1728
- return validateBaseUrl(baseUrl);
1729
- }
1730
- function readEnvProfile(env = process.env) {
1731
- return toNonEmptyString(env[ENV_PROFILE]);
1732
- }
1733
-
1734
- // src/runtime-context.ts
1735
- function resolveRuntimeContext(config, overrides = {}) {
1736
- const envProfile = readEnvProfile();
1737
- const envApiKey = readEnvApiKey();
1738
- const envBaseUrl = readEnvBaseUrl();
1739
- const profileOverride = overrides.profile ?? envProfile;
1740
- const apiKeyOverride = overrides.apiKey ?? envApiKey;
1741
- const baseUrlOverride = overrides.baseUrl ?? envBaseUrl;
1742
- if (apiKeyOverride && !baseUrlOverride) {
1743
- throw new ProfileResolutionError(
1744
- `Runtime API key was provided, but ${ENV_BASE_URL} or --base-url is missing.`
1745
- );
1746
- }
1747
- if (baseUrlOverride && !apiKeyOverride) {
1748
- throw new ProfileResolutionError(
1749
- `Runtime base URL was provided, but ${ENV_API_KEY} or --api-key is missing.`
1750
- );
1751
- }
1752
- if (apiKeyOverride && baseUrlOverride) {
1753
- return {
1754
- profile: profileOverride ?? "runtime",
1755
- baseUrl: baseUrlOverride,
1756
- apiKey: apiKeyOverride,
1757
- readOnly: overrides.readOnly ?? false,
1758
- json: overrides.json ?? false,
1759
- profileSource: overrides.profile !== void 0 ? "flag" : envProfile !== void 0 ? "env" : void 0,
1760
- baseUrlSource: overrides.baseUrl !== void 0 ? "flag" : envBaseUrl !== void 0 ? "env" : void 0,
1761
- apiKeySource: overrides.apiKey !== void 0 ? "flag" : envApiKey !== void 0 ? "env" : void 0
1762
- };
1763
- }
1764
- const profile = resolveProfile(config, {
1765
- profile: profileOverride,
1766
- baseUrl: baseUrlOverride,
1767
- apiKey: apiKeyOverride
1768
- });
1769
- return {
1770
- profile: profile.name,
1771
- baseUrl: baseUrlOverride ?? profile.baseUrl ?? DEFAULT_PRODUCTION_BASE_URL,
1772
- apiKey: apiKeyOverride ?? profile.apiKey,
1773
- readOnly: overrides.readOnly ?? false,
1774
- json: overrides.json ?? false,
1775
- profileSource: overrides.profile !== void 0 ? "flag" : envProfile !== void 0 ? "env" : "config",
1776
- baseUrlSource: overrides.baseUrl !== void 0 ? "flag" : envBaseUrl !== void 0 ? "env" : "config",
1777
- apiKeySource: overrides.apiKey !== void 0 ? "flag" : envApiKey !== void 0 ? "env" : "config"
1778
- };
1779
- }
1780
-
1781
- // src/utils/schema-fields.ts
1782
- function isJsonObject(value) {
1783
- return typeof value === "object" && value !== null && !Array.isArray(value);
1784
- }
1785
- function toJsonObject(value) {
1786
- return isJsonObject(value) ? value : void 0;
1787
- }
1788
- function toStringValue2(value) {
1789
- return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1790
- }
1791
- function toNumberValue(value) {
1792
- if (typeof value === "number" && Number.isFinite(value)) {
1793
- return value;
1794
- }
1795
- if (typeof value === "string" && value.trim().length > 0) {
1796
- const parsed = Number(value);
1797
- if (Number.isFinite(parsed)) {
1798
- return parsed;
1799
- }
1800
- }
1801
- return void 0;
1261
+ return void 0;
1802
1262
  }
1803
1263
  var fieldTypeDefinitions = [
1804
1264
  {
@@ -2161,7 +1621,7 @@ var fieldTypeDefinitions = [
2161
1621
  targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
2162
1622
  targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2163
1623
  deleteBehavior: "RESTRICT",
2164
- defaultValue: "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621::Ref A",
1624
+ defaultValue: "CUST-12",
2165
1625
  filterFields: [
2166
1626
  {
2167
1627
  fatherField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
@@ -2189,17 +1649,17 @@ var fieldTypeDefinitions = [
2189
1649
  className: "FormulaField",
2190
1650
  aliases: ["formula", "FormulaField"],
2191
1651
  description: "Calculated field from a formula.",
2192
- rawShape: `{"type":"FormulaField","slug":"formula-summary","label":"Formula Summary","config":{"formulaText":"concat(firstName, ' ', lastName)","uiFormatKind":"none"}}`,
1652
+ rawShape: '{"type":"FormulaField","slug":"formula-code","label":"Formula Code","config":{"formulaText":"concat(\\"CUST-\\", f1e1d000-0000-0000-0000-000000000005)","uiFormatKind":"none"}}',
2193
1653
  examplePayloads: [
2194
1654
  {
2195
1655
  name: "Formula field (none)",
2196
1656
  payload: {
2197
1657
  type: "FormulaField",
2198
- slug: "formula-summary",
2199
- label: "Formula Summary",
1658
+ slug: "formula-code",
1659
+ label: "Formula Code",
2200
1660
  required: false,
2201
1661
  config: {
2202
- formulaText: "concat(firstName, ' ', lastName)",
1662
+ formulaText: 'concat("CUST-", f1e1d000-0000-0000-0000-000000000005)',
2203
1663
  uiFormatKind: "none",
2204
1664
  status: "ACTIVE",
2205
1665
  conditionalFormatting: []
@@ -2214,7 +1674,7 @@ var fieldTypeDefinitions = [
2214
1674
  label: "Formula Total",
2215
1675
  required: false,
2216
1676
  config: {
2217
- formulaText: "amount * 1.21",
1677
+ formulaText: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
2218
1678
  uiFormatKind: "number",
2219
1679
  status: "ACTIVE",
2220
1680
  numberFormatOptions: {
@@ -2230,11 +1690,11 @@ var fieldTypeDefinitions = [
2230
1690
  name: "Formula field (date)",
2231
1691
  payload: {
2232
1692
  type: "FormulaField",
2233
- slug: "formula-deadline",
2234
- label: "Computed Deadline",
1693
+ slug: "formula-period",
1694
+ label: "Formula Period",
2235
1695
  required: false,
2236
1696
  config: {
2237
- formulaText: "addDays(startDate, 7)",
1697
+ formulaText: 'date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")',
2238
1698
  uiFormatKind: "date",
2239
1699
  status: "ACTIVE",
2240
1700
  dateFormatOptions: {
@@ -2254,7 +1714,7 @@ var fieldTypeDefinitions = [
2254
1714
  label: "Computed Assignee",
2255
1715
  required: false,
2256
1716
  config: {
2257
- formulaText: "manager",
1717
+ formulaText: "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
2258
1718
  uiFormatKind: "member",
2259
1719
  status: "ACTIVE",
2260
1720
  conditionalFormatting: []
@@ -2419,8 +1879,8 @@ function normalizeOptionEntries(entries) {
2419
1879
  return [];
2420
1880
  }
2421
1881
  const id = toNumberValue(entry.id);
2422
- const name = toStringValue2(entry.name) ?? toStringValue2(entry.label);
2423
- const color = toStringValue2(entry.color) ?? "default";
1882
+ const name = toStringValue(entry.name) ?? toStringValue(entry.label);
1883
+ const color = toStringValue(entry.color) ?? "default";
2424
1884
  if (id === void 0 || !name) {
2425
1885
  return [];
2426
1886
  }
@@ -2477,7 +1937,7 @@ function normalizeReferencePayload(input) {
2477
1937
  ...conditionalFormatting !== void 0 ? { conditionalFormatting } : {}
2478
1938
  };
2479
1939
  const normalizedConfig = toJsonObject(normalized.config) ?? {};
2480
- if (!toStringValue2(normalizedConfig.targetSchema) || !toStringValue2(normalizedConfig.targetDisplayField)) {
1940
+ if (!toStringValue(normalizedConfig.targetSchema) || !toStringValue(normalizedConfig.targetDisplayField)) {
2481
1941
  const definition = resolveSchemaFieldType("reference");
2482
1942
  throw new CliError(
2483
1943
  "invalid_cli_usage",
@@ -2514,13 +1974,13 @@ function normalizeSchedulePayload(input) {
2514
1974
  };
2515
1975
  const normalizedConfig = toJsonObject(normalized.config) ?? {};
2516
1976
  const definition = resolveSchemaFieldType("schedule");
2517
- 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)) {
2518
1978
  throw new CliError(
2519
1979
  "invalid_cli_usage",
2520
1980
  `Schedule fields require "referenceField", "beginningPeriodField", "endingPeriodField" and "frequency". Expected raw shape: ${definition.rawShape}`
2521
1981
  );
2522
1982
  }
2523
- const frequencyValue = toStringValue2(normalizedConfig.frequency);
1983
+ const frequencyValue = toStringValue(normalizedConfig.frequency);
2524
1984
  if (!scheduleAllowedFrequencies.has(frequencyValue)) {
2525
1985
  throw new CliError(
2526
1986
  "invalid_cli_usage",
@@ -2549,7 +2009,7 @@ function normalizeFormulaPayload(input) {
2549
2009
  ...config.conditionalFormatting !== void 0 ? { conditionalFormatting: config.conditionalFormatting } : {}
2550
2010
  };
2551
2011
  const normalizedConfig = toJsonObject(normalized.config) ?? {};
2552
- if (!toStringValue2(normalizedConfig.formulaText)) {
2012
+ if (!toStringValue(normalizedConfig.formulaText)) {
2553
2013
  const definition = resolveSchemaFieldType("formula");
2554
2014
  throw new CliError(
2555
2015
  "invalid_cli_usage",
@@ -2559,7 +2019,7 @@ function normalizeFormulaPayload(input) {
2559
2019
  return normalized;
2560
2020
  }
2561
2021
  function normalizeSchemaFieldCreatePayload(input) {
2562
- const rawType = toStringValue2(input.type);
2022
+ const rawType = toStringValue(input.type);
2563
2023
  const normalizedType = rawType ? normalizeSchemaFieldType(rawType) : void 0;
2564
2024
  const definition = resolveSchemaFieldTypeByClassName(normalizedType);
2565
2025
  if (!definition) {
@@ -2991,11 +2451,11 @@ var specificExamples = {
2991
2451
  },
2992
2452
  {
2993
2453
  description: "Patch formula field (formula text).",
2994
- command: `zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"amount * 1.10","uiFormatKind":"number","status":"ACTIVE","numberFormatOptions":{"format":"number","decimals":2,"thousandsSeparator":true},"conditionalFormatting":[]}}'`,
2454
+ command: `zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.10","uiFormatKind":"number","status":"ACTIVE","numberFormatOptions":{"format":"number","decimals":2,"thousandsSeparator":true},"conditionalFormatting":[]}}'`,
2995
2455
  raw: `{
2996
2456
  "type": "FormulaField",
2997
2457
  "config": {
2998
- "formulaText": "amount * 1.10",
2458
+ "formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.10",
2999
2459
  "uiFormatKind": "number",
3000
2460
  "status": "ACTIVE",
3001
2461
  "numberFormatOptions": {
@@ -3188,8 +2648,8 @@ var specificExamples = {
3188
2648
  }`
3189
2649
  },
3190
2650
  {
3191
- description: "Create a record mixing text, option, number, date and reference fields. Structured values go through --set-json.",
3192
- 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`,
3193
2653
  raw: `{
3194
2654
  "values": {
3195
2655
  "contact-name": "Grace Hopper",
@@ -3197,7 +2657,7 @@ var specificExamples = {
3197
2657
  "status": 2,
3198
2658
  "amount": 1999.99,
3199
2659
  "due-date": "2026-06-01T09:00:00Z",
3200
- "customer-ref": "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621",
2660
+ "customer-ref": "CUST-12",
3201
2661
  "owner": "6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
3202
2662
  }
3203
2663
  }`
@@ -3226,7 +2686,7 @@ var specificExamples = {
3226
2686
  },
3227
2687
  {
3228
2688
  description: "Patch multiple typed values at once.",
3229
- 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",
3230
2690
  raw: `{
3231
2691
  "set": {
3232
2692
  "status": 3,
@@ -3906,8 +3366,8 @@ var specificExamples = {
3906
3366
  }`
3907
3367
  },
3908
3368
  {
3909
- description: "Create a bar CHART widget with a time-serie x-axis and two y-axis series.",
3910
- command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bar --x-axis-field due-date --x-axis-date-format MONTH --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"BAR"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"id","color":"#E57373","axisType":"LINE"}' --legend '{"position":"bottom"}'`,
3369
+ description: "Create a bars CHART widget with a time-serie x-axis and two y-axis series.",
3370
+ command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bars --x-axis-field due-date --x-axis-date-format MONTH --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"PRIMARY"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"id","color":"#E57373","axisType":"SECONDARY"}' --legend '{"position":"bottom"}'`,
3911
3371
  raw: `{
3912
3372
  "type": "CHART",
3913
3373
  "source": {
@@ -3919,7 +3379,7 @@ var specificExamples = {
3919
3379
  },
3920
3380
  "presentation": { "name": "Revenue by month" },
3921
3381
  "chart": {
3922
- "chartType": "bar",
3382
+ "chartType": "bars",
3923
3383
  "xAxisFieldId": "due-date",
3924
3384
  "xAxisDateFormat": "MONTH",
3925
3385
  "xAxisAsTimeSerie": true,
@@ -3928,13 +3388,13 @@ var specificExamples = {
3928
3388
  "typeCalc": "SUM",
3929
3389
  "fieldCalc": "amount",
3930
3390
  "color": "#4B9CD3",
3931
- "axisType": "BAR"
3391
+ "axisType": "PRIMARY"
3932
3392
  },
3933
3393
  {
3934
3394
  "typeCalc": "COUNT",
3935
3395
  "fieldCalc": "id",
3936
3396
  "color": "#E57373",
3937
- "axisType": "LINE"
3397
+ "axisType": "SECONDARY"
3938
3398
  }
3939
3399
  ],
3940
3400
  "legend": { "position": "bottom" }
@@ -4080,11 +3540,11 @@ var specificExamples = {
4080
3540
  }`
4081
3541
  },
4082
3542
  {
4083
- description: "Replace the chart series with a weekly line.",
4084
- command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type line --x-axis-field due-date --x-axis-date-format WEEK --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"LINE"}'`,
3543
+ description: "Replace the chart series with weekly lines.",
3544
+ command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type lines --x-axis-field due-date --x-axis-date-format WEEK --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"PRIMARY"}'`,
4085
3545
  raw: `{
4086
3546
  "chart": {
4087
- "chartType": "line",
3547
+ "chartType": "lines",
4088
3548
  "xAxisFieldId": "due-date",
4089
3549
  "xAxisDateFormat": "WEEK",
4090
3550
  "xAxisAsTimeSerie": true,
@@ -4093,7 +3553,7 @@ var specificExamples = {
4093
3553
  "typeCalc": "SUM",
4094
3554
  "fieldCalc": "amount",
4095
3555
  "color": "#2E7D32",
4096
- "axisType": "LINE"
3556
+ "axisType": "PRIMARY"
4097
3557
  }
4098
3558
  ]
4099
3559
  }
@@ -4421,7 +3881,7 @@ var specificExamples = {
4421
3881
  "required": false,
4422
3882
  "system": false,
4423
3883
  "config": {
4424
- "formulaText": "amount * 1.21",
3884
+ "formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
4425
3885
  "uiFormatKind": "number",
4426
3886
  "status": "ACTIVE",
4427
3887
  "defaultValue": null,
@@ -4436,12 +3896,12 @@ var specificExamples = {
4436
3896
  {
4437
3897
  "id": "6d7e8f90-1234-5678-9abc-def012345678",
4438
3898
  "type": "FormulaField",
4439
- "slug": "formula-deadline",
4440
- "label": "Computed Deadline",
3899
+ "slug": "formula-period",
3900
+ "label": "Formula Period",
4441
3901
  "required": false,
4442
3902
  "system": false,
4443
3903
  "config": {
4444
- "formulaText": "addDays(startDate, 7)",
3904
+ "formulaText": "date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")",
4445
3905
  "uiFormatKind": "date",
4446
3906
  "status": "ACTIVE",
4447
3907
  "defaultValue": null,
@@ -4723,6 +4183,16 @@ var specificExamples = {
4723
4183
  response: `{
4724
4184
  "recordId": "550e8400-e29b-41d4-a716-446655440000",
4725
4185
  "deleted": true
4186
+ }`
4187
+ }
4188
+ ]),
4189
+ "records clear": buildCommandExamples([
4190
+ {
4191
+ description: "Delete every record from a schema's table. Heritage rules (CASCADE / SET NULL) propagate to child schemas asynchronously via the CDC pipeline.",
4192
+ command: "zinkee --json records clear contacts",
4193
+ response: `{
4194
+ "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4195
+ "cleared": true
4726
4196
  }`
4727
4197
  }
4728
4198
  ]),
@@ -5804,7 +5274,7 @@ var specificExamples = {
5804
5274
  },
5805
5275
  {
5806
5276
  description: "Add a search-records action whose condition pulls its value from the trigger payload using --condition-json.",
5807
- command: `zinkee --json automations actions add automation-1 --type search_records --name "Find duplicates" --target-schema followups --condition-json '{"field":"email","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"payload_value"}}]}'`,
5277
+ command: `zinkee --json automations actions add automation-1 --type search_records --name "Find duplicates" --target-schema followups --condition-json '{"field":"email","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"f1e1d000-0000-0000-0000-000000000005"}}]}'`,
5808
5278
  raw: `{
5809
5279
  "type": "search_records",
5810
5280
  "name": "Find duplicates",
@@ -5819,7 +5289,7 @@ var specificExamples = {
5819
5289
  "rawValue": null,
5820
5290
  "source": {
5821
5291
  "type": "TRIGGER",
5822
- "id": "payload_value"
5292
+ "id": "f1e1d000-0000-0000-0000-000000000005"
5823
5293
  }
5824
5294
  }
5825
5295
  ]
@@ -6026,744 +5496,689 @@ var specificExamples = {
6026
5496
  "updatedBy": "developer@zinkee.com"
6027
5497
  }`
6028
5498
  }
6029
- ]),
6030
- "automations folders create": buildCommandExamples([
6031
- {
6032
- description: "Create one flat automation folder.",
6033
- command: 'zinkee --json automations folders create --name "Codex Frontend Demo"',
6034
- raw: `{
6035
- "name": "Codex Frontend Demo"
6036
- }`,
6037
- response: `{
6038
- "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
6039
- "name": "Codex Frontend Demo",
6040
- "isRoot": false,
6041
- "automationCount": 0
6042
- }`
5499
+ ]),
5500
+ "automations folders create": buildCommandExamples([
5501
+ {
5502
+ description: "Create one flat automation folder.",
5503
+ command: 'zinkee --json automations folders create --name "Codex Frontend Demo"',
5504
+ raw: `{
5505
+ "name": "Codex Frontend Demo"
5506
+ }`,
5507
+ response: `{
5508
+ "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
5509
+ "name": "Codex Frontend Demo",
5510
+ "isRoot": false,
5511
+ "automationCount": 0
5512
+ }`
5513
+ }
5514
+ ]),
5515
+ "automations folders update": buildCommandExamples([
5516
+ {
5517
+ description: "Rename a non-root automation folder. The folder argument accepts a UUID or an exact name.",
5518
+ command: 'zinkee --json automations folders update "Codex Frontend Demo" --name "Codex Frontend Demo Updated"',
5519
+ raw: `{
5520
+ "name": "Codex Frontend Demo Updated"
5521
+ }`,
5522
+ response: `{
5523
+ "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
5524
+ "name": "Codex Frontend Demo Updated",
5525
+ "isRoot": false,
5526
+ "automationCount": 2
5527
+ }`
5528
+ }
5529
+ ]),
5530
+ "automations folders move": buildCommandExamples([
5531
+ {
5532
+ description: "Move one automation into a target folder by exact folder name.",
5533
+ command: 'zinkee --json automations folders move automation-1 --to "Codex Frontend Demo"',
5534
+ raw: `{
5535
+ "automationId": "automation-1"
5536
+ }`,
5537
+ response: `{
5538
+ "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
5539
+ "name": "Codex Frontend Demo",
5540
+ "isRoot": false
5541
+ }`
5542
+ }
5543
+ ])
5544
+ };
5545
+ function fallbackExamples(commandName) {
5546
+ switch (commandName) {
5547
+ default:
5548
+ return [];
5549
+ }
5550
+ }
5551
+ function buildSchemaFieldCreateExamples(type) {
5552
+ const definitions = getSchemaFieldTypeDefinitions();
5553
+ const selectedDefinition = resolveSchemaFieldType(type);
5554
+ const filteredDefinitions = selectedDefinition ? definitions.filter((definition) => definition.key === selectedDefinition.key) : definitions;
5555
+ const flat = filteredDefinitions.flatMap(
5556
+ (definition) => definition.examplePayloads.map((example) => ({ definition, example }))
5557
+ );
5558
+ return buildCommandExamples(
5559
+ flat.map(({ example }, index) => {
5560
+ const slug = typeof example.payload.slug === "string" ? example.payload.slug : "field";
5561
+ const command = `zinkee --json schemas fields create contacts --raw '${JSON.stringify(example.payload)}'`;
5562
+ if (index === 0) {
5563
+ return {
5564
+ description: example.name,
5565
+ command,
5566
+ response: `{
5567
+ "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
5568
+ "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
5569
+ "slug": "${slug}"
5570
+ }`
5571
+ };
5572
+ }
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
+ }
5657
+ }
5658
+ }
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);
5679
+ }
5680
+ };
5681
+ function isRecord2(value) {
5682
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5683
+ }
5684
+ function toStringValue2(value) {
5685
+ return typeof value === "string" ? value : void 0;
5686
+ }
5687
+ function toNonEmptyString(value) {
5688
+ const normalized = value?.trim();
5689
+ return normalized ? normalized : void 0;
5690
+ }
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);
5699
+ continue;
5700
+ }
5701
+ if (key === "base_url") {
5702
+ profile.baseUrl = toStringValue2(rawValue);
5703
+ continue;
5704
+ }
5705
+ profile[key] = rawValue;
5706
+ }
5707
+ return profile;
5708
+ }
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);
5718
+ continue;
5719
+ }
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;
5728
+ }
5729
+ config[key] = value;
5730
+ }
5731
+ return config;
5732
+ }
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;
5742
+ }
5743
+ throw error;
5744
+ }
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;
5754
+ }
5755
+ if (key === "apiKey") {
5756
+ serialized.api_key = value;
5757
+ continue;
6043
5758
  }
6044
- ]),
6045
- "automations folders update": buildCommandExamples([
6046
- {
6047
- description: "Rename a non-root automation folder. The folder argument accepts a UUID or an exact name.",
6048
- command: 'zinkee --json automations folders update "Codex Frontend Demo" --name "Codex Frontend Demo Updated"',
6049
- raw: `{
6050
- "name": "Codex Frontend Demo Updated"
6051
- }`,
6052
- response: `{
6053
- "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
6054
- "name": "Codex Frontend Demo Updated",
6055
- "isRoot": false,
6056
- "automationCount": 2
6057
- }`
5759
+ if (key === "baseUrl") {
5760
+ serialized.base_url = value;
5761
+ continue;
6058
5762
  }
6059
- ]),
6060
- "automations folders move": buildCommandExamples([
6061
- {
6062
- description: "Move one automation into a target folder by exact folder name.",
6063
- command: 'zinkee --json automations folders move automation-1 --to "Codex Frontend Demo"',
6064
- raw: `{
6065
- "automationId": "automation-1"
6066
- }`,
6067
- response: `{
6068
- "id": "cdfc14e3-3169-4ffb-8d9b-b11858a9240f",
6069
- "name": "Codex Frontend Demo",
6070
- "isRoot": false
6071
- }`
5763
+ serialized[key] = value;
5764
+ }
5765
+ return serialized;
5766
+ }
5767
+ function serializeConfig(config) {
5768
+ const serialized = {};
5769
+ if (config.defaultProfile !== void 0) {
5770
+ serialized.default_profile = config.defaultProfile;
5771
+ }
5772
+ for (const [key, value] of Object.entries(config)) {
5773
+ if (key === "defaultProfile" || key === "profiles" || value === void 0) {
5774
+ continue;
6072
5775
  }
6073
- ])
6074
- };
6075
- function fallbackExamples(commandName) {
6076
- switch (commandName) {
6077
- default:
6078
- return [];
5776
+ serialized[key] = value;
5777
+ }
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;
6079
5783
  }
5784
+ return stringifyTOML(serialized).trimEnd().concat("\n");
6080
5785
  }
6081
- function buildSchemaFieldCreateExamples(type) {
6082
- const definitions = getSchemaFieldTypeDefinitions();
6083
- const selectedDefinition = resolveSchemaFieldType(type);
6084
- const filteredDefinitions = selectedDefinition ? definitions.filter((definition) => definition.key === selectedDefinition.key) : definitions;
6085
- const flat = filteredDefinitions.flatMap(
6086
- (definition) => definition.examplePayloads.map((example) => ({ definition, example }))
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
5798
+ }
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;
5820
+ }
5821
+ if (value.length <= 4) {
5822
+ return redactedSecretMask;
5823
+ }
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
+ };
5854
+ }
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
+ );
5865
+ }
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
+ );
5870
+ }
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;
5880
+ }
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 }))
6087
5902
  );
6088
- return buildCommandExamples(
6089
- flat.map(({ example }, index) => {
6090
- const slug = typeof example.payload.slug === "string" ? example.payload.slug : "field";
6091
- const command = `zinkee --json schemas fields create contacts --raw '${JSON.stringify(example.payload)}'`;
6092
- if (index === 0) {
6093
- return {
6094
- description: example.name,
6095
- command,
6096
- response: `{
6097
- "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
6098
- "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
6099
- "slug": "${slug}"
6100
- }`
6101
- };
5903
+ }
5904
+ function toConfigurationError(filePath, error) {
5905
+ if (error instanceof CliError) {
5906
+ throw error;
5907
+ }
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}.`);
5910
+ }
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;
6102
5934
  }
6103
- return {
6104
- description: example.name,
6105
- command
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
6106
5957
  };
6107
- })
6108
- );
6109
- }
6110
- function getCommandExamples(commandName, filters = {}) {
6111
- if (commandName === "schemas fields create") {
6112
- return buildSchemaFieldCreateExamples(filters.type);
6113
- }
6114
- return specificExamples[commandName] ?? fallbackExamples(commandName);
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);
5965
+ }
5966
+ });
6115
5967
  }
6116
- function selector(value) {
5968
+
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) {
6117
5975
  return {
6118
- kind: "uuid",
6119
- value
5976
+ method,
5977
+ headers: {
5978
+ "content-type": "application/json"
5979
+ },
5980
+ body: JSON.stringify(body)
6120
5981
  };
6121
5982
  }
6122
- async function createExampleAutomationContext(options = {}) {
6123
- if (options.enabled !== true) {
6124
- return null;
6125
- }
6126
- try {
6127
- const config = readRuntimeConfig(options.configPath ?? defaultConfigPath);
6128
- const runtime = resolveRuntimeContext(config, options.overrides);
6129
- if (!runtime.baseUrl) {
6130
- return null;
6131
- }
6132
- const client = new ApiClient({
6133
- baseUrl: runtime.baseUrl,
6134
- apiKey: runtime.apiKey
6135
- });
6136
- return {
6137
- automationsApi: new AutomationsApi(client),
6138
- schemasApi: new SchemasApi(client)
6139
- };
6140
- } catch {
6141
- return null;
6142
- }
5983
+ function selectorValue(selector) {
5984
+ return encodeURIComponent(selector.value);
6143
5985
  }
6144
- function referenceValue(value) {
6145
- return value.slug ?? value.id;
5986
+ function segment(value) {
5987
+ return encodeURIComponent(value);
6146
5988
  }
6147
- function pickExampleField(fields) {
6148
- return fields.find((field) => !field.required || field.slug || field.id) ?? fields[0];
5989
+ function appendQuery(path, query) {
5990
+ const queryString = query.toString();
5991
+ return queryString.length > 0 ? `${path}?${queryString}` : path;
6149
5992
  }
6150
- async function findSchemaFieldReference(context) {
6151
- const schemas = await context.schemasApi.listSchemas();
6152
- for (const schema of schemas) {
6153
- if (typeof schema.id !== "string") {
6154
- continue;
6155
- }
6156
- const fullSchema = await context.schemasApi.getSchema(selector(schema.id));
6157
- const fields = Array.isArray(fullSchema.fields) ? fullSchema.fields : [];
6158
- const field = pickExampleField(fields);
6159
- const schemaRef = referenceValue(schema);
6160
- const fieldRef = field ? referenceValue(field) : void 0;
6161
- const fieldId = typeof field?.id === "string" ? field.id : void 0;
6162
- if (!schemaRef || !fieldRef || !fieldId) {
6163
- continue;
6164
- }
6165
- return {
6166
- schemaId: schema.id,
6167
- schemaRef,
6168
- fieldId,
6169
- fieldRef
6170
- };
5993
+ var AutomationsApi = class {
5994
+ constructor(client) {
5995
+ this.client = client;
6171
5996
  }
6172
- return null;
6173
- }
6174
- async function findAutomationId(context) {
6175
- const automations = await context.automationsApi.listAutomations();
6176
- const first = automations.find((automation) => typeof automation.id === "string");
6177
- return typeof first?.id === "string" ? first.id : null;
6178
- }
6179
- async function findAutomationWithAction(context) {
6180
- const automations = await context.automationsApi.listAutomations();
6181
- for (const automation of automations) {
6182
- if (typeof automation.id !== "string") {
6183
- continue;
6184
- }
6185
- const actions = await context.automationsApi.listActions(selector(automation.id));
6186
- const firstAction = actions.find((action) => typeof action.id === "string");
6187
- if (typeof firstAction?.id === "string") {
6188
- return {
6189
- automationId: automation.id,
6190
- actionId: firstAction.id
6191
- };
6192
- }
5997
+ listFolders() {
5998
+ return this.client.getJson("/api/v2/automation-folders");
6193
5999
  }
6194
- return null;
6195
- }
6196
- async function buildDynamicAutomationExamples(commandName, options = {}) {
6197
- const context = await createExampleAutomationContext(options);
6198
- if (!context) {
6199
- return [];
6000
+ createFolder(body) {
6001
+ return this.client.requestJson(
6002
+ "/api/v2/automation-folders",
6003
+ jsonOptions(body, "POST")
6004
+ );
6200
6005
  }
6201
- const schemaField = await findSchemaFieldReference(context);
6202
- const automationId = await findAutomationId(context);
6203
- const automationWithAction = await findAutomationWithAction(context);
6204
- const plugins = await context.automationsApi.listPlugins();
6205
- const pluginId = typeof plugins[0]?.id === "string" ? plugins[0].id : void 0;
6206
- const connections = await context.automationsApi.listConnections();
6207
- const connectionId = typeof connections[0]?.id === "string" ? connections[0].id : void 0;
6208
- switch (commandName) {
6209
- case "automations create":
6210
- if (!schemaField) {
6211
- return [];
6212
- }
6213
- return buildCommandExamples([
6214
- {
6215
- 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.",
6216
- command: 'zinkee --json automations create --name "Nightly invoice sync" --trigger-type scheduled --cron "0 15 10 * * 1"',
6217
- raw: `{
6218
- "name": "Nightly invoice sync",
6219
- "trigger": {
6220
- "type": "scheduled",
6221
- "config": {
6222
- "cronExpression": "0 15 10 * * 1"
6223
- }
6006
+ updateFolder(folder, body) {
6007
+ return this.client.requestJson(
6008
+ `/api/v2/automation-folders/${selectorValue(folder)}`,
6009
+ jsonOptions(body, "PATCH")
6010
+ );
6224
6011
  }
6225
- }`,
6226
- response: `{
6227
- "automationId": "d2df2478-2513-4ecb-a2aa-2cea8c3d614a",
6228
- "webhookEndpoint": null
6229
- }`
6230
- },
6231
- {
6232
- 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}.`,
6233
- 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}]}'`,
6234
- raw: `{
6235
- "name": "Record created demo",
6236
- "trigger": {
6237
- "type": "record_created",
6238
- "config": {
6239
- "schemaId": "${schemaField.schemaRef}",
6240
- "conditions": [
6241
- {
6242
- "field": "${schemaField.fieldRef}",
6243
- "comparator": "ine",
6244
- "values": [{"rawValue": "", "source": null}]
6245
- }
6246
- ]
6247
- }
6012
+ deleteFolder(folder) {
6013
+ return this.client.requestJson(
6014
+ `/api/v2/automation-folders/${selectorValue(folder)}`,
6015
+ { method: "DELETE" }
6016
+ );
6248
6017
  }
6249
- }`
6250
- },
6251
- {
6252
- description: `Create a record-changed automation watching ${schemaField.fieldRef} on ${schemaField.schemaRef}, with an 'is not empty' condition on that field.`,
6253
- 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}]}'`,
6254
- raw: `{
6255
- "name": "Record changed demo",
6256
- "trigger": {
6257
- "type": "record_changed",
6258
- "config": {
6259
- "schemaId": "${schemaField.schemaRef}",
6260
- "fieldIds": ["${schemaField.fieldRef}"],
6261
- "conditions": [
6262
- {
6263
- "field": "${schemaField.fieldRef}",
6264
- "comparator": "ine",
6265
- "values": [{"rawValue": "", "source": null}]
6266
- }
6267
- ]
6268
- }
6018
+ moveAutomation(input) {
6019
+ return this.client.requestJson(
6020
+ `/api/v2/automation-folders/${segment(input.targetFolderId)}/automations:move`,
6021
+ jsonOptions(input, "POST")
6022
+ );
6269
6023
  }
6270
- }`
6271
- }
6272
- ]);
6273
- case "automations trigger set":
6274
- if (!automationId || !schemaField) {
6275
- return [];
6276
- }
6277
- return buildCommandExamples([
6278
- {
6279
- description: "Replace the trigger with a scheduled trigger on a real automation from this workspace.",
6280
- command: `zinkee --json automations trigger set ${automationId} --trigger-type scheduled --cron "0 15 10 * * 1"`,
6281
- raw: `{
6282
- "type": "scheduled",
6283
- "config": {
6284
- "cronExpression": "0 15 10 * * 1"
6024
+ listAutomations(query = {}) {
6025
+ const params = new URLSearchParams();
6026
+ if (query.folderId) {
6027
+ params.set("folderId", query.folderId);
6028
+ }
6029
+ if (query.status) {
6030
+ params.set("status", query.status);
6031
+ }
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);
6040
+ }
6041
+ if (query.search) {
6042
+ params.set("search", query.search);
6043
+ }
6044
+ return this.client.getJson(
6045
+ appendQuery("/api/v2/automations", params)
6046
+ );
6285
6047
  }
6286
- }`
6287
- },
6288
- {
6289
- description: `Replace the trigger with a record-created trigger on ${schemaField.schemaRef}, with an 'is not empty' condition on ${schemaField.fieldRef}.`,
6290
- 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}]}'`,
6291
- raw: `{
6292
- "type": "record_created",
6293
- "config": {
6294
- "schemaId": "${schemaField.schemaRef}",
6295
- "conditions": [
6296
- {
6297
- "field": "${schemaField.fieldRef}",
6298
- "comparator": "ine",
6299
- "values": [{"rawValue": "", "source": null}]
6300
- }
6301
- ]
6048
+ getAutomation(automation) {
6049
+ return this.client.getJson(
6050
+ `/api/v2/automations/${selectorValue(automation)}`
6051
+ );
6302
6052
  }
6303
- }`
6304
- },
6305
- {
6306
- description: `Replace the trigger with a record-changed trigger watching ${schemaField.fieldRef} on ${schemaField.schemaRef}.`,
6307
- 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}]}'`,
6308
- raw: `{
6309
- "type": "record_changed",
6310
- "config": {
6311
- "schemaId": "${schemaField.schemaRef}",
6312
- "fieldIds": ["${schemaField.fieldRef}"],
6313
- "conditions": [
6314
- {
6315
- "field": "${schemaField.fieldRef}",
6316
- "comparator": "ine",
6317
- "values": [{"rawValue": "", "source": null}]
6318
- }
6319
- ]
6053
+ createAutomation(input) {
6054
+ return this.client.requestJson(
6055
+ "/api/v2/automations",
6056
+ jsonOptions(input, "POST")
6057
+ );
6320
6058
  }
6321
- }`
6322
- }
6323
- ]);
6324
- case "automations actions add":
6325
- if (!automationId || !schemaField) {
6326
- return [];
6327
- }
6328
- return buildCommandExamples([
6329
- {
6330
- description: `Add a create-record action with literal and trigger-based mappings targeting ${schemaField.schemaRef}.`,
6331
- 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":"payload_value"}}'`,
6332
- raw: `{
6333
- "type": "create_record",
6334
- "name": "Create follow-up order",
6335
- "config": {
6336
- "targetSchemaId": "${schemaField.schemaRef}",
6337
- "fieldMapping": {
6338
- "${schemaField.fieldRef}": {
6339
- "rawValue": "pending",
6340
- "source": null
6341
- },
6342
- "owner": {
6343
- "rawValue": null,
6344
- "source": {
6345
- "type": "TRIGGER",
6346
- "id": "payload_value"
6347
- }
6348
- }
6349
- }
6059
+ updateAutomation(automation, input) {
6060
+ return this.client.requestJson(
6061
+ `/api/v2/automations/${selectorValue(automation)}`,
6062
+ jsonOptions(input, "PATCH")
6063
+ );
6350
6064
  }
6351
- }`
6352
- },
6353
- {
6354
- description: `Add an update-record action that targets the trigger record on ${schemaField.schemaRef}.`,
6355
- 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`,
6356
- raw: `{
6357
- "type": "update_record",
6358
- "name": "Mark record as processed",
6359
- "config": {
6360
- "targetSchemaId": "${schemaField.schemaRef}",
6361
- "fieldMapping": {
6362
- "${schemaField.fieldRef}": {
6363
- "rawValue": "processed",
6364
- "source": null
6365
- }
6366
- },
6367
- "useTriggerRecord": true
6065
+ deleteAutomation(automation) {
6066
+ return this.client.requestJson(
6067
+ `/api/v2/automations/${selectorValue(automation)}`,
6068
+ { method: "DELETE" }
6069
+ );
6368
6070
  }
6369
- }`
6370
- },
6371
- {
6372
- description: `Add a search-records action with a trigger-based condition on ${schemaField.schemaRef}.`,
6373
- 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":"payload_value"}}]}'`,
6374
- raw: `{
6375
- "type": "search_records",
6376
- "name": "Find duplicates",
6377
- "config": {
6378
- "targetSchemaId": "${schemaField.schemaRef}",
6379
- "conditions": [
6380
- {
6381
- "field": "${schemaField.fieldRef}",
6382
- "comparator": "eq",
6383
- "values": [
6384
- {
6385
- "rawValue": null,
6386
- "source": {
6387
- "type": "TRIGGER",
6388
- "id": "payload_value"
6389
- }
6390
- }
6391
- ]
6392
- }
6393
- ]
6071
+ activateAutomation(automation) {
6072
+ return this.client.requestJson(
6073
+ `/api/v2/automations/${selectorValue(automation)}:activate`,
6074
+ { method: "POST" }
6075
+ );
6394
6076
  }
6395
- }`
6396
- },
6397
- ...connectionId ? buildCommandExamples([
6398
- {
6399
- description: `Add an HTTP request action authenticated through a stored connection (${connectionId}).`,
6400
- 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}`,
6401
- raw: `{
6402
- "type": "http_request",
6403
- "name": "Notify external ERP",
6404
- "config": {
6405
- "method": "POST",
6406
- "url": "https://example.com/integrations/order-status",
6407
- "headers": {
6408
- "X-Demo": "codex"
6409
- },
6410
- "contentType": "application/json",
6411
- "timeoutMs": 5000,
6412
- "authMode": "STORED",
6413
- "connectionId": "${connectionId}"
6077
+ deactivateAutomation(automation) {
6078
+ return this.client.requestJson(
6079
+ `/api/v2/automations/${selectorValue(automation)}:deactivate`,
6080
+ { method: "POST" }
6081
+ );
6414
6082
  }
6415
- }`
6416
- }
6417
- ]) : buildCommandExamples([
6418
- {
6419
- description: "Add an HTTP request action through the generic --type path.",
6420
- 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`,
6421
- raw: `{
6422
- "type": "http_request",
6423
- "name": "Notify external ERP",
6424
- "config": {
6425
- "method": "POST",
6426
- "url": "https://example.com/integrations/order-status",
6427
- "contentType": "application/json"
6083
+ getTrigger(automation) {
6084
+ return this.client.getJson(
6085
+ `/api/v2/automations/${selectorValue(automation)}/trigger`
6086
+ );
6428
6087
  }
6429
- }`
6430
- }
6431
- ]),
6432
- ...pluginId ? buildCommandExamples([
6433
- {
6434
- description: `Add an execute-plugin action using an active plugin from this workspace (${pluginId}).`,
6435
- command: `zinkee --json automations actions add ${automationId} --type execute_plugin --name "Run billing plugin" --plugin ${pluginId} --arg mode=safe --arg-json steps='["one","two"]'`,
6436
- raw: `{
6437
- "type": "execute_plugin",
6438
- "name": "Run billing plugin",
6439
- "config": {
6440
- "pluginId": "${pluginId}",
6441
- "pluginArgs": {
6442
- "mode": "safe",
6443
- "steps": ["one", "two"]
6444
- }
6088
+ setTrigger(automation, input) {
6089
+ return this.client.requestJson(
6090
+ `/api/v2/automations/${selectorValue(automation)}/trigger`,
6091
+ jsonOptions(input, "PUT")
6092
+ );
6445
6093
  }
6446
- }`
6447
- }
6448
- ]) : []
6449
- ]);
6450
- case "automations actions update":
6451
- if (!automationWithAction || !schemaField) {
6452
- return [];
6453
- }
6454
- return buildCommandExamples([
6455
- {
6456
- description: "Update a record action on a real automation/action pair using the trigger record.",
6457
- 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`,
6458
- raw: `{
6459
- "type": "update_record",
6460
- "name": "Update trigger record",
6461
- "config": {
6462
- "targetSchemaId": "${schemaField.schemaRef}",
6463
- "fieldMapping": {
6464
- "${schemaField.fieldRef}": {
6465
- "rawValue": "ready",
6466
- "source": null
6467
- }
6468
- },
6469
- "useTriggerRecord": true
6094
+ listActions(automation) {
6095
+ return this.client.getJson(
6096
+ `/api/v2/automations/${selectorValue(automation)}/actions`
6097
+ );
6470
6098
  }
6471
- }`,
6472
- response: `{
6473
- "id": "${automationWithAction.actionId}",
6474
- "type": "update_record",
6475
- "name": "Update trigger record",
6476
- "config": {
6477
- "targetSchemaId": "${schemaField.schemaRef}",
6478
- "fieldMapping": {
6479
- "${schemaField.fieldRef}": {
6480
- "rawValue": "ready",
6481
- "source": null
6482
- }
6483
- },
6484
- "useTriggerRecord": true
6099
+ addAction(automation, input) {
6100
+ return this.client.requestJson(
6101
+ `/api/v2/automations/${selectorValue(automation)}/actions`,
6102
+ jsonOptions(input, "POST")
6103
+ );
6485
6104
  }
6486
- }`
6487
- }
6488
- ]);
6489
- case "automations flow set":
6490
- if (!automationWithAction) {
6491
- return [];
6492
- }
6493
- return buildCommandExamples([
6494
- {
6495
- description: "Set flow entry actions using a real automation/action pair from this workspace.",
6496
- command: `zinkee --json automations flow set ${automationWithAction.automationId} --entry ${automationWithAction.actionId}`,
6497
- raw: `{
6498
- "entryActionIds": ["${automationWithAction.actionId}"],
6499
- "transitions": []
6500
- }`
6501
- }
6502
- ]);
6503
- case "automations connections create":
6504
- return buildCommandExamples([
6505
- {
6506
- description: "Create a stored workspace connection for HTTP request actions.",
6507
- command: `zinkee --json automations connections create --name "ERP API Key" --type api_key --scope workspace --config '{"headerName":"Authorization"}' --secret apiKey=super-secret --active`,
6508
- raw: `{
6509
- "name": "ERP API Key",
6510
- "type": "api_key",
6511
- "scope": "workspace",
6512
- "config": {
6513
- "headerName": "Authorization"
6514
- },
6515
- "secret": {
6516
- "apiKey": "super-secret"
6517
- },
6518
- "active": true
6519
- }`,
6520
- response: `{
6521
- "id": "4fc20b5c-9353-4991-b68e-1027cb674ed4",
6522
- "name": "ERP API Key",
6523
- "type": "api_key",
6524
- "scope": "workspace",
6525
- "ownerMemberId": "6c8a3e0d-7b1f-4c98-a2e9-8b9a2e3f5b14",
6526
- "active": true,
6527
- "config": {
6528
- "headerName": "Authorization"
6529
- },
6530
- "createdAt": "2026-04-21T09:00:00Z",
6531
- "updatedAt": "2026-04-21T09:00:00Z",
6532
- "createdBy": "developer@zinkee.com",
6533
- "updatedBy": "developer@zinkee.com"
6534
- }`
6535
- }
6536
- ]);
6537
- case "automations connections update":
6538
- if (!connectionId) {
6539
- return [];
6540
- }
6541
- return buildCommandExamples([
6542
- {
6543
- description: "Patch an existing stored connection from this workspace.",
6544
- command: `zinkee --json automations connections update ${connectionId} --raw '{"set":{"name":"ERP API Key Updated","config":{"headerName":"Authorization"}}}'`,
6545
- raw: `{
6546
- "set": {
6547
- "name": "ERP API Key Updated",
6548
- "config": {
6549
- "headerName": "Authorization"
6550
- }
6105
+ updateAction(automation, actionId, input) {
6106
+ return this.client.requestJson(
6107
+ `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
6108
+ jsonOptions(input, "PATCH")
6109
+ );
6551
6110
  }
6552
- }`,
6553
- response: `{
6554
- "id": "${connectionId}",
6555
- "name": "ERP API Key Updated",
6556
- "type": "api_key",
6557
- "scope": "workspace",
6558
- "ownerMemberId": "6c8a3e0d-7b1f-4c98-a2e9-8b9a2e3f5b14",
6559
- "active": true,
6560
- "config": {
6561
- "headerName": "Authorization"
6562
- },
6563
- "createdAt": "2026-04-21T09:00:00Z",
6564
- "updatedAt": "2026-04-21T10:15:00Z",
6565
- "createdBy": "developer@zinkee.com",
6566
- "updatedBy": "developer@zinkee.com"
6567
- }`
6568
- }
6569
- ]);
6570
- default:
6571
- return [];
6111
+ deleteAction(automation, actionId) {
6112
+ return this.client.requestJson(
6113
+ `/api/v2/automations/${selectorValue(automation)}/actions/${segment(actionId)}`,
6114
+ { method: "DELETE" }
6115
+ );
6572
6116
  }
6573
- }
6574
- async function getResolvedCommandExamples(commandName, filters = {}, options = {}) {
6575
- const dynamicExamples = commandName.startsWith("automations") ? await buildDynamicAutomationExamples(commandName, options) : [];
6576
- if (dynamicExamples.length > 0) {
6577
- return dynamicExamples;
6117
+ getFlow(automation) {
6118
+ return this.client.getJson(
6119
+ `/api/v2/automations/${selectorValue(automation)}/flow`
6120
+ );
6578
6121
  }
6579
- return getCommandExamples(commandName, filters);
6580
- }
6581
-
6582
- // src/cli-examples.ts
6583
- function getStdout(stdout) {
6584
- return stdout ?? process.stdout;
6585
- }
6586
- function extractExampleFilters(tokens) {
6587
- const filters = {};
6588
- for (let index = 0; index < tokens.length; index += 1) {
6589
- const token = tokens[index];
6590
- if (token === "--type") {
6591
- const value = tokens[index + 1];
6592
- if (value && !value.startsWith("-")) {
6593
- filters.type = value;
6594
- index += 1;
6595
- }
6596
- }
6122
+ setFlow(automation, input) {
6123
+ return this.client.requestJson(
6124
+ `/api/v2/automations/${selectorValue(automation)}/flow`,
6125
+ jsonOptions(input, "PUT")
6126
+ );
6597
6127
  }
6598
- return filters;
6599
- }
6600
- function extractExampleOverrides(tokens) {
6601
- const overrides = {};
6602
- for (let index = 0; index < tokens.length; index += 1) {
6603
- const token = tokens[index];
6604
- const value = tokens[index + 1];
6605
- if (!value || value.startsWith("-")) {
6606
- continue;
6607
- }
6608
- if (token === "--profile") {
6609
- overrides.profile = value;
6610
- index += 1;
6611
- continue;
6612
- }
6613
- if (token === "--base-url") {
6614
- overrides.baseUrl = value;
6615
- index += 1;
6616
- continue;
6617
- }
6618
- if (token === "--api-key") {
6619
- overrides.apiKey = value;
6620
- index += 1;
6621
- }
6128
+ getWebhook(automation) {
6129
+ return this.client.getJson(
6130
+ `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`
6131
+ );
6622
6132
  }
6623
- return overrides;
6624
- }
6625
- function extractExampleRequest(argv, optionMeta = createDefaultOptionMetadata()) {
6626
- if (!argv.includes("--example")) {
6627
- return null;
6133
+ setWebhook(automation, input) {
6134
+ return this.client.requestJson(
6135
+ `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
6136
+ jsonOptions(input, "PUT")
6137
+ );
6628
6138
  }
6629
- const userArgs = argv.slice(2);
6630
- const operands = collectOperandTokens(userArgs, optionMeta, { skipFlag: "--example" });
6631
- const cmdPath = findCommandPath(operands, commandRegistry);
6632
- if (!cmdPath) {
6633
- throw new CliError("invalid_cli_usage", 'Provide a command after "--example".');
6139
+ deleteWebhook(automation) {
6140
+ return this.client.requestJson(
6141
+ `/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
6142
+ { method: "DELETE" }
6143
+ );
6634
6144
  }
6635
- const remainingTokens = userArgs.slice(cmdPath.lastArgvIndex + 1);
6636
- return {
6637
- commandName: cmdPath.commandName,
6638
- filters: extractExampleFilters(remainingTokens),
6639
- overrides: extractExampleOverrides(argv),
6640
- json: argv.includes("--json")
6641
- };
6642
- }
6643
- async function showExamples(commandName, json, stdout, filters = {}, options = {}) {
6644
- const examples = await getResolvedCommandExamples(commandName, filters, options);
6645
- if (examples.length === 0) {
6646
- throw new CliError("invalid_cli_usage", `No examples registered for "${commandName}".`);
6145
+ listPlugins() {
6146
+ return this.client.getJson("/api/v2/automation-plugins");
6647
6147
  }
6648
- const writer = getStdout(stdout);
6649
- if (json) {
6650
- writer.write(`${JSON.stringify(buildJsonSuccess({ examples }, { command: commandName }))}
6651
- `);
6652
- return;
6148
+ getPlugin(pluginId) {
6149
+ return this.client.getJson(
6150
+ `/api/v2/automation-plugins/${segment(pluginId)}`
6151
+ );
6653
6152
  }
6654
- writer.write("Examples:\n");
6655
- for (const [index, example] of examples.entries()) {
6656
- writer.write(`
6657
- ${index + 1}. ${example.description}
6658
- `);
6659
- writer.write(` ${example.command}
6660
- `);
6661
- if (example.raw) {
6662
- writer.write(" Equivalent JSON payload:\n");
6663
- for (const line of example.raw.split("\n")) {
6664
- writer.write(` ${line}
6665
- `);
6666
- }
6667
- }
6668
- if (example.response) {
6669
- writer.write(" Example response:\n");
6670
- for (const line of example.response.split("\n")) {
6671
- writer.write(` ${line}
6672
- `);
6673
- }
6674
- }
6153
+ listConnections() {
6154
+ return this.client.getJson(
6155
+ "/api/v2/automation-connections"
6156
+ );
6675
6157
  }
6676
- }
6677
-
6678
- // src/program.ts
6679
- import { createRequire } from "module";
6680
- import { Command as Command10 } from "commander";
6681
-
6682
- // src/commands/config.ts
6683
- function getCommandIo(stdout) {
6684
- return stdout ?? process.stdout;
6685
- }
6686
- function writeLine(stdout, value) {
6687
- stdout.write(`${value}
6688
- `);
6689
- }
6690
- function getGlobalOptions(command) {
6691
- return command.optsWithGlobals();
6692
- }
6693
- function emitJson(stdout, commandName, data, configPath) {
6694
- writeLine(
6695
- stdout,
6696
- JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
6697
- );
6698
- }
6699
- function toConfigurationError(filePath, error) {
6700
- if (error instanceof CliError) {
6701
- throw error;
6158
+ getConnection(connection) {
6159
+ return this.client.getJson(
6160
+ `/api/v2/automation-connections/${selectorValue(connection)}`
6161
+ );
6702
6162
  }
6703
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
6704
- throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
6163
+ createConnection(input) {
6164
+ return this.client.requestJson(
6165
+ "/api/v2/automation-connections",
6166
+ jsonOptions(input, "POST")
6167
+ );
6705
6168
  }
6706
- if (error instanceof Error) {
6707
- throw new CliError("configuration_error", error.message);
6169
+ updateConnection(connection, input) {
6170
+ return this.client.requestJson(
6171
+ `/api/v2/automation-connections/${selectorValue(connection)}`,
6172
+ jsonOptions(input, "PATCH")
6173
+ );
6708
6174
  }
6709
- throw error;
6710
- }
6711
- function registerConfigCommands(program, options = {}) {
6712
- const filePath = options.configPath ?? defaultConfigPath;
6713
- const stdout = getCommandIo(options.stdout);
6714
- const config = program.command("config").description("Inspect local CLI config");
6715
- config.command("path").description("Show the effective config file path").action(function action() {
6716
- const data = { path: filePath };
6717
- if (getGlobalOptions(this).json) {
6718
- emitJson(stdout, "config path", data, filePath);
6719
- return;
6720
- }
6721
- writeLine(stdout, filePath);
6722
- });
6723
- config.command("show").description("Show the local config with secrets redacted").action(function action() {
6724
- try {
6725
- const data = redactConfig(readConfig(filePath));
6726
- if (getGlobalOptions(this).json) {
6727
- emitJson(stdout, "config show", data, filePath);
6728
- return;
6729
- }
6730
- writeLine(stdout, `Default profile: ${data.defaultProfile ?? "(none)"}`);
6731
- printTable(
6732
- Object.entries(data.profiles).map(([name, profile]) => ({
6733
- name,
6734
- default: data.defaultProfile === name ? "yes" : "",
6735
- baseUrl: typeof profile.baseUrl === "string" ? profile.baseUrl : "",
6736
- apiKey: typeof profile.apiKey === "string" ? profile.apiKey : ""
6737
- })),
6738
- ["name", "default", "baseUrl", "apiKey"],
6739
- stdout
6740
- );
6741
- } catch (error) {
6742
- toConfigurationError(filePath, error);
6743
- }
6744
- });
6745
- config.command("validate").description("Validate that the local config can resolve a profile").action(function action() {
6746
- try {
6747
- const parsed = readConfig(filePath);
6748
- const profile = resolveProfile(parsed);
6749
- const data = {
6750
- valid: true,
6751
- profile: profile.name
6752
- };
6753
- if (getGlobalOptions(this).json) {
6754
- emitJson(stdout, "config validate", data, filePath);
6755
- return;
6756
- }
6757
- writeLine(stdout, `Config is valid. Resolved profile "${profile.name}".`);
6758
- } catch (error) {
6759
- toConfigurationError(filePath, error);
6760
- }
6761
- });
6762
- }
6763
-
6764
- // src/commands/automations.ts
6765
- import { readFileSync as readFileSync2 } from "fs";
6766
- import { InvalidArgumentError } from "commander";
6175
+ deleteConnection(connection) {
6176
+ return this.client.requestJson(
6177
+ `/api/v2/automation-connections/${selectorValue(connection)}`,
6178
+ { method: "DELETE" }
6179
+ );
6180
+ }
6181
+ };
6767
6182
 
6768
6183
  // src/parsers/kv.ts
6769
6184
  function splitAssignment(input) {
@@ -6813,6 +6228,53 @@ function normalizeUuidOrSlug(input) {
6813
6228
  };
6814
6229
  }
6815
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
+
6816
6278
  // src/commands/automations.ts
6817
6279
  function getCommandIo2(stdout) {
6818
6280
  return stdout ?? process.stdout;
@@ -7210,38 +6672,38 @@ function readConditions(literalConditions, jsonConditions, label) {
7210
6672
  )
7211
6673
  ];
7212
6674
  }
7213
- function resolveFolder(folders, selector2) {
7214
- if (selector2.kind === "uuid") {
7215
- 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);
7216
6678
  if (match) {
7217
6679
  return match;
7218
6680
  }
7219
6681
  }
7220
- const matches = folders.filter((folder) => folder.name === selector2.value);
6682
+ const matches = folders.filter((folder) => folder.name === selector.value);
7221
6683
  if (matches.length === 1) {
7222
6684
  return matches[0];
7223
6685
  }
7224
6686
  if (matches.length > 1) {
7225
6687
  throw new CliError(
7226
6688
  "invalid_cli_usage",
7227
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
6689
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
7228
6690
  );
7229
6691
  }
7230
- 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.`);
7231
6693
  }
7232
- async function resolveFolderSelector(api, selector2) {
7233
- if (!selector2) {
6694
+ async function resolveFolderSelector(api, selector) {
6695
+ if (!selector) {
7234
6696
  return void 0;
7235
6697
  }
7236
- if (selector2.kind === "uuid") {
7237
- return selector2;
6698
+ if (selector.kind === "uuid") {
6699
+ return selector;
7238
6700
  }
7239
6701
  const folders = await api.listFolders();
7240
- const resolved = resolveFolder(folders, selector2);
6702
+ const resolved = resolveFolder(folders, selector);
7241
6703
  if (typeof resolved.id !== "string" || resolved.id.length === 0) {
7242
6704
  throw new CliError(
7243
6705
  "invalid_cli_usage",
7244
- `Folder "${selector2.value}" is missing an id in the API response.`
6706
+ `Folder "${selector.value}" is missing an id in the API response.`
7245
6707
  );
7246
6708
  }
7247
6709
  return { kind: "uuid", value: resolved.id };
@@ -8021,7 +7483,7 @@ import { readFileSync as readFileSync3 } from "fs";
8021
7483
  import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
8022
7484
 
8023
7485
  // src/api/comments.ts
8024
- function jsonOptions3(body, method) {
7486
+ function jsonOptions2(body, method) {
8025
7487
  return {
8026
7488
  method,
8027
7489
  headers: {
@@ -8030,8 +7492,8 @@ function jsonOptions3(body, method) {
8030
7492
  body: JSON.stringify(body)
8031
7493
  };
8032
7494
  }
8033
- function selectorValue3(selector2) {
8034
- return selector2.value;
7495
+ function selectorValue2(selector) {
7496
+ return selector.value;
8035
7497
  }
8036
7498
  var CommentsApi = class {
8037
7499
  constructor(client) {
@@ -8039,13 +7501,13 @@ var CommentsApi = class {
8039
7501
  }
8040
7502
  listComments(schema, recordId) {
8041
7503
  return this.client.getJson(
8042
- `/api/v2/schemas/${selectorValue3(schema)}/records/${recordId}/comments`
7504
+ `/api/v2/schemas/${selectorValue2(schema)}/records/${recordId}/comments`
8043
7505
  );
8044
7506
  }
8045
7507
  createComment(schema, recordId, input) {
8046
7508
  return this.client.requestJson(
8047
- `/api/v2/schemas/${selectorValue3(schema)}/records/${recordId}/comments`,
8048
- jsonOptions3(input, "POST")
7509
+ `/api/v2/schemas/${selectorValue2(schema)}/records/${recordId}/comments`,
7510
+ jsonOptions2(input, "POST")
8049
7511
  );
8050
7512
  }
8051
7513
  };
@@ -8239,7 +7701,7 @@ import { readFileSync as readFileSync4 } from "fs";
8239
7701
  import { InvalidArgumentError as InvalidArgumentError3 } from "commander";
8240
7702
 
8241
7703
  // src/api/displays.ts
8242
- function jsonOptions4(body, method) {
7704
+ function jsonOptions3(body, method) {
8243
7705
  return {
8244
7706
  method,
8245
7707
  headers: {
@@ -8248,8 +7710,8 @@ function jsonOptions4(body, method) {
8248
7710
  body: JSON.stringify(body)
8249
7711
  };
8250
7712
  }
8251
- function selectorValue4(selector2) {
8252
- return encodeURIComponent(selector2.value);
7713
+ function selectorValue3(selector) {
7714
+ return encodeURIComponent(selector.value);
8253
7715
  }
8254
7716
  function segment2(value) {
8255
7717
  return encodeURIComponent(value);
@@ -8262,145 +7724,145 @@ var DisplaysApi = class {
8262
7724
  return this.client.getJson("/api/v2/displays");
8263
7725
  }
8264
7726
  getDisplay(display) {
8265
- return this.client.getJson(`/api/v2/displays/${selectorValue4(display)}`);
7727
+ return this.client.getJson(`/api/v2/displays/${selectorValue3(display)}`);
8266
7728
  }
8267
7729
  createDisplay(body) {
8268
- return this.client.requestJson("/api/v2/displays", jsonOptions4(body, "POST"));
7730
+ return this.client.requestJson("/api/v2/displays", jsonOptions3(body, "POST"));
8269
7731
  }
8270
7732
  updateDisplay(display, body) {
8271
7733
  return this.client.requestJson(
8272
- `/api/v2/displays/${selectorValue4(display)}`,
8273
- jsonOptions4(body, "PATCH")
7734
+ `/api/v2/displays/${selectorValue3(display)}`,
7735
+ jsonOptions3(body, "PATCH")
8274
7736
  );
8275
7737
  }
8276
7738
  deleteDisplay(display) {
8277
7739
  return this.client.requestJson(
8278
- `/api/v2/displays/${selectorValue4(display)}`,
7740
+ `/api/v2/displays/${selectorValue3(display)}`,
8279
7741
  { method: "DELETE" }
8280
7742
  );
8281
7743
  }
8282
7744
  getLayout(display) {
8283
7745
  return this.client.getJson(
8284
- `/api/v2/displays/${selectorValue4(display)}/layout`
7746
+ `/api/v2/displays/${selectorValue3(display)}/layout`
8285
7747
  );
8286
7748
  }
8287
7749
  patchLayout(display, body) {
8288
7750
  return this.client.requestJson(
8289
- `/api/v2/displays/${selectorValue4(display)}/layout`,
8290
- jsonOptions4(body, "PATCH")
7751
+ `/api/v2/displays/${selectorValue3(display)}/layout`,
7752
+ jsonOptions3(body, "PATCH")
8291
7753
  );
8292
7754
  }
8293
7755
  listTabs(display) {
8294
7756
  return this.client.getJson(
8295
- `/api/v2/displays/${selectorValue4(display)}/tabs`
7757
+ `/api/v2/displays/${selectorValue3(display)}/tabs`
8296
7758
  );
8297
7759
  }
8298
7760
  createTab(display, body) {
8299
7761
  return this.client.requestJson(
8300
- `/api/v2/displays/${selectorValue4(display)}/tabs`,
8301
- jsonOptions4(body, "POST")
7762
+ `/api/v2/displays/${selectorValue3(display)}/tabs`,
7763
+ jsonOptions3(body, "POST")
8302
7764
  );
8303
7765
  }
8304
7766
  updateTab(display, tabId, body) {
8305
7767
  return this.client.requestJson(
8306
- `/api/v2/displays/${selectorValue4(display)}/tabs/${segment2(tabId)}`,
8307
- jsonOptions4(body, "PATCH")
7768
+ `/api/v2/displays/${selectorValue3(display)}/tabs/${segment2(tabId)}`,
7769
+ jsonOptions3(body, "PATCH")
8308
7770
  );
8309
7771
  }
8310
7772
  deleteTab(display, tabId) {
8311
7773
  return this.client.requestJson(
8312
- `/api/v2/displays/${selectorValue4(display)}/tabs/${segment2(tabId)}`,
7774
+ `/api/v2/displays/${selectorValue3(display)}/tabs/${segment2(tabId)}`,
8313
7775
  { method: "DELETE" }
8314
7776
  );
8315
7777
  }
8316
7778
  listVariables(display) {
8317
7779
  return this.client.getJson(
8318
- `/api/v2/displays/${selectorValue4(display)}/variables`
7780
+ `/api/v2/displays/${selectorValue3(display)}/variables`
8319
7781
  );
8320
7782
  }
8321
7783
  getVariable(display, variableId) {
8322
7784
  return this.client.getJson(
8323
- `/api/v2/displays/${selectorValue4(display)}/variables/${segment2(variableId)}`
7785
+ `/api/v2/displays/${selectorValue3(display)}/variables/${segment2(variableId)}`
8324
7786
  );
8325
7787
  }
8326
7788
  createVariable(display, body) {
8327
7789
  return this.client.requestJson(
8328
- `/api/v2/displays/${selectorValue4(display)}/variables`,
8329
- jsonOptions4(body, "POST")
7790
+ `/api/v2/displays/${selectorValue3(display)}/variables`,
7791
+ jsonOptions3(body, "POST")
8330
7792
  );
8331
7793
  }
8332
7794
  updateVariable(display, variableId, body) {
8333
7795
  return this.client.requestJson(
8334
- `/api/v2/displays/${selectorValue4(display)}/variables/${segment2(variableId)}`,
8335
- jsonOptions4(body, "PATCH")
7796
+ `/api/v2/displays/${selectorValue3(display)}/variables/${segment2(variableId)}`,
7797
+ jsonOptions3(body, "PATCH")
8336
7798
  );
8337
7799
  }
8338
7800
  deleteVariable(display, variableId) {
8339
7801
  return this.client.requestJson(
8340
- `/api/v2/displays/${selectorValue4(display)}/variables/${segment2(variableId)}`,
7802
+ `/api/v2/displays/${selectorValue3(display)}/variables/${segment2(variableId)}`,
8341
7803
  { method: "DELETE" }
8342
7804
  );
8343
7805
  }
8344
7806
  listWidgets(display) {
8345
7807
  return this.client.getJson(
8346
- `/api/v2/displays/${selectorValue4(display)}/widgets`
7808
+ `/api/v2/displays/${selectorValue3(display)}/widgets`
8347
7809
  );
8348
7810
  }
8349
7811
  getWidget(display, widgetId) {
8350
7812
  return this.client.getJson(
8351
- `/api/v2/displays/${selectorValue4(display)}/widgets/${segment2(widgetId)}`
7813
+ `/api/v2/displays/${selectorValue3(display)}/widgets/${segment2(widgetId)}`
8352
7814
  );
8353
7815
  }
8354
7816
  createWidget(display, body) {
8355
7817
  return this.client.requestJson(
8356
- `/api/v2/displays/${selectorValue4(display)}/widgets`,
8357
- jsonOptions4(body, "POST")
7818
+ `/api/v2/displays/${selectorValue3(display)}/widgets`,
7819
+ jsonOptions3(body, "POST")
8358
7820
  );
8359
7821
  }
8360
7822
  updateWidget(display, widgetId, body) {
8361
7823
  return this.client.requestJson(
8362
- `/api/v2/displays/${selectorValue4(display)}/widgets/${segment2(widgetId)}`,
8363
- jsonOptions4(body, "PATCH")
7824
+ `/api/v2/displays/${selectorValue3(display)}/widgets/${segment2(widgetId)}`,
7825
+ jsonOptions3(body, "PATCH")
8364
7826
  );
8365
7827
  }
8366
7828
  deleteWidget(display, widgetId) {
8367
7829
  return this.client.requestJson(
8368
- `/api/v2/displays/${selectorValue4(display)}/widgets/${segment2(widgetId)}`,
7830
+ `/api/v2/displays/${selectorValue3(display)}/widgets/${segment2(widgetId)}`,
8369
7831
  { method: "DELETE" }
8370
7832
  );
8371
7833
  }
8372
7834
  createNavigationTarget(display, body) {
8373
7835
  return this.client.requestJson(
8374
- `/api/v2/displays/${selectorValue4(display)}/navigation-targets`,
8375
- jsonOptions4(body, "POST")
7836
+ `/api/v2/displays/${selectorValue3(display)}/navigation-targets`,
7837
+ jsonOptions3(body, "POST")
8376
7838
  );
8377
7839
  }
8378
7840
  updateNavigationTarget(display, targetId, body) {
8379
7841
  return this.client.requestJson(
8380
- `/api/v2/displays/${selectorValue4(display)}/navigation-targets/${segment2(targetId)}`,
8381
- jsonOptions4(body, "PATCH")
7842
+ `/api/v2/displays/${selectorValue3(display)}/navigation-targets/${segment2(targetId)}`,
7843
+ jsonOptions3(body, "PATCH")
8382
7844
  );
8383
7845
  }
8384
7846
  deleteNavigationTarget(display, targetId) {
8385
7847
  return this.client.requestJson(
8386
- `/api/v2/displays/${selectorValue4(display)}/navigation-targets/${segment2(targetId)}`,
7848
+ `/api/v2/displays/${selectorValue3(display)}/navigation-targets/${segment2(targetId)}`,
8387
7849
  { method: "DELETE" }
8388
7850
  );
8389
7851
  }
8390
7852
  getCrossWidgetFilter(display) {
8391
7853
  return this.client.getJson(
8392
- `/api/v2/displays/${selectorValue4(display)}/cross-widget-filter`
7854
+ `/api/v2/displays/${selectorValue3(display)}/cross-widget-filter`
8393
7855
  );
8394
7856
  }
8395
7857
  setCrossWidgetFilter(display, body) {
8396
7858
  return this.client.requestJson(
8397
- `/api/v2/displays/${selectorValue4(display)}/cross-widget-filter`,
8398
- jsonOptions4(body, "PUT")
7859
+ `/api/v2/displays/${selectorValue3(display)}/cross-widget-filter`,
7860
+ jsonOptions3(body, "PUT")
8399
7861
  );
8400
7862
  }
8401
7863
  deleteCrossWidgetFilter(display) {
8402
7864
  return this.client.requestJson(
8403
- `/api/v2/displays/${selectorValue4(display)}/cross-widget-filter`,
7865
+ `/api/v2/displays/${selectorValue3(display)}/cross-widget-filter`,
8404
7866
  { method: "DELETE" }
8405
7867
  );
8406
7868
  }
@@ -8968,8 +8430,8 @@ import { basename } from "path";
8968
8430
  import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
8969
8431
 
8970
8432
  // src/api/files.ts
8971
- function selectorValue5(selector2) {
8972
- return selector2.value;
8433
+ function selectorValue4(selector) {
8434
+ return selector.value;
8973
8435
  }
8974
8436
  var FilesApi = class {
8975
8437
  constructor(client) {
@@ -8982,11 +8444,11 @@ var FilesApi = class {
8982
8444
  });
8983
8445
  }
8984
8446
  downloadFile(file) {
8985
- return this.client.requestBinary(`/api/v2/files/${selectorValue5(file)}`);
8447
+ return this.client.requestBinary(`/api/v2/files/${selectorValue4(file)}`);
8986
8448
  }
8987
8449
  deleteFile(file) {
8988
8450
  return this.client.requestJson(
8989
- `/api/v2/files/${selectorValue5(file)}`,
8451
+ `/api/v2/files/${selectorValue4(file)}`,
8990
8452
  { method: "DELETE" }
8991
8453
  );
8992
8454
  }
@@ -9174,8 +8636,8 @@ function registerFilesCommands(program, options = {}) {
9174
8636
  import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
9175
8637
 
9176
8638
  // src/api/logs.ts
9177
- function selectorValue6(selector2) {
9178
- return selector2.value;
8639
+ function selectorValue5(selector) {
8640
+ return selector.value;
9179
8641
  }
9180
8642
  var LogsApi = class {
9181
8643
  constructor(client) {
@@ -9183,7 +8645,7 @@ var LogsApi = class {
9183
8645
  }
9184
8646
  listLogs(schema, recordId) {
9185
8647
  return this.client.getJson(
9186
- `/api/v2/schemas/${selectorValue6(schema)}/records/${recordId}/logs`
8648
+ `/api/v2/schemas/${selectorValue5(schema)}/records/${recordId}/logs`
9187
8649
  );
9188
8650
  }
9189
8651
  };
@@ -9283,7 +8745,7 @@ import { readFileSync as readFileSync6 } from "fs";
9283
8745
  import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
9284
8746
 
9285
8747
  // src/api/navigation.ts
9286
- function jsonOptions5(body, method) {
8748
+ function jsonOptions4(body, method) {
9287
8749
  return {
9288
8750
  method,
9289
8751
  headers: {
@@ -9292,8 +8754,8 @@ function jsonOptions5(body, method) {
9292
8754
  body: JSON.stringify(body)
9293
8755
  };
9294
8756
  }
9295
- function selectorValue7(selector2) {
9296
- return selector2.value;
8757
+ function selectorValue6(selector) {
8758
+ return selector.value;
9297
8759
  }
9298
8760
  var NavigationApi = class {
9299
8761
  constructor(client) {
@@ -9305,25 +8767,25 @@ var NavigationApi = class {
9305
8767
  createFolder(body) {
9306
8768
  return this.client.requestJson(
9307
8769
  "/api/v2/navigation/folders",
9308
- jsonOptions5(body, "POST")
8770
+ jsonOptions4(body, "POST")
9309
8771
  );
9310
8772
  }
9311
8773
  updateFolder(folder, body) {
9312
8774
  return this.client.requestJson(
9313
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
9314
- jsonOptions5(body, "PATCH")
8775
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
8776
+ jsonOptions4(body, "PATCH")
9315
8777
  );
9316
8778
  }
9317
8779
  deleteFolder(folder) {
9318
8780
  return this.client.requestJson(
9319
- `/api/v2/navigation/folders/${selectorValue7(folder)}`,
8781
+ `/api/v2/navigation/folders/${selectorValue6(folder)}`,
9320
8782
  { method: "DELETE" }
9321
8783
  );
9322
8784
  }
9323
8785
  moveResource(body) {
9324
8786
  return this.client.requestJson(
9325
8787
  "/api/v2/navigation/resources:move",
9326
- jsonOptions5(body, "POST")
8788
+ jsonOptions4(body, "POST")
9327
8789
  );
9328
8790
  }
9329
8791
  };
@@ -9438,25 +8900,25 @@ function buildFolderBody(options) {
9438
8900
  }
9439
8901
  return body;
9440
8902
  }
9441
- function resolveFolder2(folders, selector2) {
9442
- if (selector2.kind === "uuid") {
9443
- 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);
9444
8906
  if (!match) {
9445
- 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.`);
9446
8908
  }
9447
8909
  return match;
9448
8910
  }
9449
- const matches = folders.filter((folder) => folder.name === selector2.value);
8911
+ const matches = folders.filter((folder) => folder.name === selector.value);
9450
8912
  if (matches.length === 1) {
9451
8913
  return matches[0];
9452
8914
  }
9453
8915
  if (matches.length > 1) {
9454
8916
  throw new CliError(
9455
8917
  "invalid_cli_usage",
9456
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
8918
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
9457
8919
  );
9458
8920
  }
9459
- 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.`);
9460
8922
  }
9461
8923
  function folderRows2(folders) {
9462
8924
  return folders.map((folder) => ({
@@ -9713,7 +9175,7 @@ import { readFileSync as readFileSync7 } from "fs";
9713
9175
  import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
9714
9176
 
9715
9177
  // src/api/records.ts
9716
- function jsonOptions6(body, method) {
9178
+ function jsonOptions5(body, method) {
9717
9179
  return {
9718
9180
  method,
9719
9181
  headers: {
@@ -9722,8 +9184,8 @@ function jsonOptions6(body, method) {
9722
9184
  body: JSON.stringify(body)
9723
9185
  };
9724
9186
  }
9725
- function selectorValue8(selector2) {
9726
- return selector2.value;
9187
+ function selectorValue7(selector) {
9188
+ return selector.value;
9727
9189
  }
9728
9190
  var RecordsApi = class {
9729
9191
  constructor(client) {
@@ -9737,7 +9199,7 @@ var RecordsApi = class {
9737
9199
  if (query.offset !== void 0) {
9738
9200
  params.set("offset", String(query.offset));
9739
9201
  }
9740
- const path = `/api/v2/schemas/${selectorValue8(schema)}/records`;
9202
+ const path = `/api/v2/schemas/${selectorValue7(schema)}/records`;
9741
9203
  const queryString = params.toString();
9742
9204
  return this.client.getJson(
9743
9205
  queryString ? `${path}?${queryString}` : path
@@ -9746,30 +9208,36 @@ var RecordsApi = class {
9746
9208
  queryRecords(schema, query) {
9747
9209
  const body = this.normalizeQueryInput(query);
9748
9210
  return this.client.requestJson(
9749
- `/api/v2/schemas/${selectorValue8(schema)}/records:query`,
9750
- jsonOptions6(body, "POST")
9211
+ `/api/v2/schemas/${selectorValue7(schema)}/records:query`,
9212
+ jsonOptions5(body, "POST")
9751
9213
  );
9752
9214
  }
9753
9215
  getRecord(schema, record) {
9754
9216
  return this.client.getJson(
9755
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`
9217
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`
9756
9218
  );
9757
9219
  }
9758
9220
  createRecord(schema, input) {
9759
9221
  return this.client.requestJson(
9760
- `/api/v2/schemas/${selectorValue8(schema)}/records`,
9761
- jsonOptions6(input, "POST")
9222
+ `/api/v2/schemas/${selectorValue7(schema)}/records`,
9223
+ jsonOptions5(input, "POST")
9762
9224
  );
9763
9225
  }
9764
9226
  updateRecord(schema, record, input) {
9765
9227
  return this.client.requestJson(
9766
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
9767
- jsonOptions6(input, "PATCH")
9228
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9229
+ jsonOptions5(input, "PATCH")
9768
9230
  );
9769
9231
  }
9770
9232
  deleteRecord(schema, record) {
9771
9233
  return this.client.requestJson(
9772
- `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
9234
+ `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9235
+ { method: "DELETE" }
9236
+ );
9237
+ }
9238
+ clearRecords(schema) {
9239
+ return this.client.requestJson(
9240
+ `/api/v2/schemas/${selectorValue7(schema)}/records:clear`,
9773
9241
  { method: "DELETE" }
9774
9242
  );
9775
9243
  }
@@ -9801,6 +9269,73 @@ var RecordsApi = class {
9801
9269
  }
9802
9270
  };
9803
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
+
9804
9339
  // src/parsers/expressions.ts
9805
9340
  var supportedComparators = /* @__PURE__ */ new Set([
9806
9341
  "eq",
@@ -10186,14 +9721,14 @@ function getQueryRecords(result) {
10186
9721
  function getRecordIdentifier(record) {
10187
9722
  return typeof record.recordId === "string" ? record.recordId : "unknown";
10188
9723
  }
10189
- async function resolveSchemaSelector(api, selector2) {
10190
- if (selector2.kind === "uuid") {
10191
- return selector2;
9724
+ async function resolveSchemaSelector(api, selector) {
9725
+ if (selector.kind === "uuid") {
9726
+ return selector;
10192
9727
  }
10193
9728
  const schemas = await api.listSchemas();
10194
- const match = schemas.find((entry) => entry.slug === selector2.value);
9729
+ const match = schemas.find((entry) => entry.slug === selector.value);
10195
9730
  if (!match || typeof match.id !== "string") {
10196
- throw new CliError("invalid_cli_usage", `Schema "${selector2.value}" not found.`);
9731
+ throw new CliError("invalid_cli_usage", `Schema "${selector.value}" not found.`);
10197
9732
  }
10198
9733
  return {
10199
9734
  kind: "uuid",
@@ -10299,6 +9834,17 @@ function registerRecordsCommands(program, options = {}) {
10299
9834
  }
10300
9835
  writeLine9(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
10301
9836
  });
9837
+ records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema) {
9838
+ const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
9839
+ ensureWritable6("records clear", readOnly, "destructive");
9840
+ const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
9841
+ const data = await api.clearRecords(resolvedSchema);
9842
+ if (json) {
9843
+ emitJson9(stdout, "records clear", data, filePath);
9844
+ return;
9845
+ }
9846
+ writeLine9(stdout, `Cleared all records from schema "${schema.value}".`);
9847
+ });
10302
9848
  }
10303
9849
 
10304
9850
  // src/commands/schemas.ts
@@ -10566,28 +10112,28 @@ function buildFieldUpdateInput(currentType, options) {
10566
10112
  applyFieldDefaultValue(input, options.default);
10567
10113
  return input;
10568
10114
  }
10569
- async function resolveSchemaSelector2(api, selector2) {
10570
- if (selector2.kind === "uuid") {
10571
- return selector2;
10115
+ async function resolveSchemaSelector2(api, selector) {
10116
+ if (selector.kind === "uuid") {
10117
+ return selector;
10572
10118
  }
10573
10119
  const schemas = await api.listSchemas();
10574
- const match = schemas.find((schema) => schema.slug === selector2.value);
10120
+ const match = schemas.find((schema) => schema.slug === selector.value);
10575
10121
  if (!match || typeof match.id !== "string") {
10576
- throw new CliError("invalid_cli_usage", `Schema "${selector2.value}" not found.`);
10122
+ throw new CliError("invalid_cli_usage", `Schema "${selector.value}" not found.`);
10577
10123
  }
10578
10124
  return {
10579
10125
  kind: "uuid",
10580
10126
  value: match.id
10581
10127
  };
10582
10128
  }
10583
- async function resolveFieldSelector(api, schema, selector2) {
10584
- if (selector2.kind === "uuid") {
10585
- return selector2;
10129
+ async function resolveFieldSelector(api, schema, selector) {
10130
+ if (selector.kind === "uuid") {
10131
+ return selector;
10586
10132
  }
10587
10133
  const fields = await api.listFields(schema);
10588
- const match = fields.find((field) => field.slug === selector2.value);
10134
+ const match = fields.find((field) => field.slug === selector.value);
10589
10135
  if (!match || typeof match.id !== "string") {
10590
- throw new CliError("invalid_cli_usage", `Field "${selector2.value}" not found.`);
10136
+ throw new CliError("invalid_cli_usage", `Field "${selector.value}" not found.`);
10591
10137
  }
10592
10138
  return {
10593
10139
  kind: "uuid",
@@ -10765,8 +10311,8 @@ function jsonOptions7(body, method) {
10765
10311
  body: JSON.stringify(body)
10766
10312
  };
10767
10313
  }
10768
- function selectorValue9(selector2) {
10769
- return selector2.value;
10314
+ function selectorValue9(selector) {
10315
+ return selector.value;
10770
10316
  }
10771
10317
  var TeamspaceApi = class {
10772
10318
  constructor(client) {
@@ -10995,11 +10541,11 @@ function emitTable5(stdout, data) {
10995
10541
  function getFolderIdentifier(folder) {
10996
10542
  return typeof folder.id === "string" ? folder.id : typeof folder.name === "string" ? folder.name : "unknown";
10997
10543
  }
10998
- function buildFolderLookup(folders, selector2) {
10999
- if (selector2.kind === "uuid") {
11000
- return selector2;
10544
+ function buildFolderLookup(folders, selector) {
10545
+ if (selector.kind === "uuid") {
10546
+ return selector;
11001
10547
  }
11002
- const matches = folders.filter((folder) => folder.name === selector2.value);
10548
+ const matches = folders.filter((folder) => folder.name === selector.value);
11003
10549
  if (matches.length === 1) {
11004
10550
  const folderId = matches[0]?.id;
11005
10551
  if (typeof folderId === "string" && folderId.length > 0) {
@@ -11012,37 +10558,37 @@ function buildFolderLookup(folders, selector2) {
11012
10558
  if (matches.length > 1) {
11013
10559
  throw new CliError(
11014
10560
  "invalid_cli_usage",
11015
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
10561
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
11016
10562
  );
11017
10563
  }
11018
- 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.`);
11019
10565
  }
11020
- function findFolderEntity(folders, selector2) {
11021
- if (selector2.kind === "uuid") {
11022
- 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);
11023
10569
  if (match) {
11024
10570
  return match;
11025
10571
  }
11026
- 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.`);
11027
10573
  }
11028
- const matches = folders.filter((folder) => folder.name === selector2.value);
10574
+ const matches = folders.filter((folder) => folder.name === selector.value);
11029
10575
  if (matches.length === 1) {
11030
10576
  return matches[0];
11031
10577
  }
11032
10578
  if (matches.length > 1) {
11033
10579
  throw new CliError(
11034
10580
  "invalid_cli_usage",
11035
- `Folder "${selector2.value}" is ambiguous. Found ${matches.length} matches.`
10581
+ `Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
11036
10582
  );
11037
10583
  }
11038
- 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.`);
11039
10585
  }
11040
- async function resolveFolderSelector2(api, selector2) {
11041
- if (selector2.kind === "uuid") {
11042
- return selector2;
10586
+ async function resolveFolderSelector2(api, selector) {
10587
+ if (selector.kind === "uuid") {
10588
+ return selector;
11043
10589
  }
11044
10590
  const folders = await api.listFolders(false);
11045
- return buildFolderLookup(folders, selector2);
10591
+ return buildFolderLookup(folders, selector);
11046
10592
  }
11047
10593
  function registerTeamspaceCommands(program, options = {}) {
11048
10594
  const filePath = options.configPath ?? defaultConfigPath;
@@ -11717,15 +11263,11 @@ async function runCli(argv) {
11717
11263
  const optionMeta = buildOptionMetadata(program);
11718
11264
  const exampleRequest = extractExampleRequest(argv, optionMeta);
11719
11265
  if (exampleRequest) {
11720
- await showExamples(
11266
+ showExamples(
11721
11267
  exampleRequest.commandName,
11722
11268
  exampleRequest.json,
11723
11269
  void 0,
11724
- exampleRequest.filters,
11725
- {
11726
- enabled: true,
11727
- overrides: exampleRequest.overrides
11728
- }
11270
+ exampleRequest.filters
11729
11271
  );
11730
11272
  throw new ExampleDisplayed();
11731
11273
  }