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/AGENTS.md +42 -0
- package/README.md +7 -0
- package/dist/index.js +967 -1425
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/records.ts +7 -0
- package/src/cli-examples.ts +3 -58
- package/src/cli-runner.ts +1 -5
- package/src/command-registry.ts +7 -0
- package/src/commands/automations.test.ts +5 -5
- package/src/commands/displays.test.ts +2 -2
- package/src/commands/records.test.ts +58 -0
- package/src/commands/records.ts +19 -0
- package/src/index.test.ts +1 -8
- package/src/utils/examples.test.ts +22 -1
- package/src/utils/examples.ts +34 -566
- package/src/utils/schema-fields.ts +12 -10
- package/.claude/settings.local.json +0 -44
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/
|
|
1235
|
-
function
|
|
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
|
|
1248
|
-
return
|
|
1245
|
+
function toJsonObject(value) {
|
|
1246
|
+
return isJsonObject(value) ? value : void 0;
|
|
1249
1247
|
}
|
|
1250
|
-
function
|
|
1251
|
-
|
|
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
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
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
|
-
|
|
1286
|
-
const
|
|
1287
|
-
if (
|
|
1288
|
-
|
|
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: "
|
|
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:
|
|
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-
|
|
2199
|
-
label: "Formula
|
|
1658
|
+
slug: "formula-code",
|
|
1659
|
+
label: "Formula Code",
|
|
2200
1660
|
required: false,
|
|
2201
1661
|
config: {
|
|
2202
|
-
formulaText:
|
|
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: "
|
|
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-
|
|
2234
|
-
label: "
|
|
1693
|
+
slug: "formula-period",
|
|
1694
|
+
label: "Formula Period",
|
|
2235
1695
|
required: false,
|
|
2236
1696
|
config: {
|
|
2237
|
-
formulaText:
|
|
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: "
|
|
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 =
|
|
2423
|
-
const color =
|
|
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 (!
|
|
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 (!
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
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":"
|
|
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": "
|
|
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
|
|
3192
|
-
command: `zinkee --json records create contacts --set contact-name="Grace Hopper" --set contact-email=grace@example.com --set
|
|
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": "
|
|
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
|
|
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
|
|
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
|
|
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": "
|
|
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": "
|
|
3391
|
+
"axisType": "PRIMARY"
|
|
3932
3392
|
},
|
|
3933
3393
|
{
|
|
3934
3394
|
"typeCalc": "COUNT",
|
|
3935
3395
|
"fieldCalc": "id",
|
|
3936
3396
|
"color": "#E57373",
|
|
3937
|
-
"axisType": "
|
|
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
|
|
4084
|
-
command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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-
|
|
4440
|
-
"label": "
|
|
3899
|
+
"slug": "formula-period",
|
|
3900
|
+
"label": "Formula Period",
|
|
4441
3901
|
"required": false,
|
|
4442
3902
|
"system": false,
|
|
4443
3903
|
"config": {
|
|
4444
|
-
"formulaText": "
|
|
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":"
|
|
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": "
|
|
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
|
-
|
|
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
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
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
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
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
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
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
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
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
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
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
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6119
|
-
|
|
5976
|
+
method,
|
|
5977
|
+
headers: {
|
|
5978
|
+
"content-type": "application/json"
|
|
5979
|
+
},
|
|
5980
|
+
body: JSON.stringify(body)
|
|
6120
5981
|
};
|
|
6121
5982
|
}
|
|
6122
|
-
|
|
6123
|
-
|
|
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
|
|
6145
|
-
return value
|
|
5986
|
+
function segment(value) {
|
|
5987
|
+
return encodeURIComponent(value);
|
|
6146
5988
|
}
|
|
6147
|
-
function
|
|
6148
|
-
|
|
5989
|
+
function appendQuery(path, query) {
|
|
5990
|
+
const queryString = query.toString();
|
|
5991
|
+
return queryString.length > 0 ? `${path}?${queryString}` : path;
|
|
6149
5992
|
}
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
return [];
|
|
6000
|
+
createFolder(body) {
|
|
6001
|
+
return this.client.requestJson(
|
|
6002
|
+
"/api/v2/automation-folders",
|
|
6003
|
+
jsonOptions(body, "POST")
|
|
6004
|
+
);
|
|
6200
6005
|
}
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
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
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
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
|
-
|
|
6253
|
-
|
|
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
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6307
|
-
|
|
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
|
-
|
|
6325
|
-
|
|
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
|
-
|
|
6355
|
-
|
|
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
|
-
|
|
6373
|
-
|
|
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
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
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
|
-
|
|
6490
|
-
|
|
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
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
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
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
return dynamicExamples;
|
|
6117
|
+
getFlow(automation) {
|
|
6118
|
+
return this.client.getJson(
|
|
6119
|
+
`/api/v2/automations/${selectorValue(automation)}/flow`
|
|
6120
|
+
);
|
|
6578
6121
|
}
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
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
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
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
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
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
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6139
|
+
deleteWebhook(automation) {
|
|
6140
|
+
return this.client.requestJson(
|
|
6141
|
+
`/api/v2/automations/${selectorValue(automation)}/webhook-endpoint`,
|
|
6142
|
+
{ method: "DELETE" }
|
|
6143
|
+
);
|
|
6634
6144
|
}
|
|
6635
|
-
|
|
6636
|
-
|
|
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
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
return;
|
|
6148
|
+
getPlugin(pluginId) {
|
|
6149
|
+
return this.client.getJson(
|
|
6150
|
+
`/api/v2/automation-plugins/${segment(pluginId)}`
|
|
6151
|
+
);
|
|
6653
6152
|
}
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
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
|
-
|
|
6679
|
-
|
|
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
|
-
|
|
6704
|
-
|
|
6163
|
+
createConnection(input) {
|
|
6164
|
+
return this.client.requestJson(
|
|
6165
|
+
"/api/v2/automation-connections",
|
|
6166
|
+
jsonOptions(input, "POST")
|
|
6167
|
+
);
|
|
6705
6168
|
}
|
|
6706
|
-
|
|
6707
|
-
|
|
6169
|
+
updateConnection(connection, input) {
|
|
6170
|
+
return this.client.requestJson(
|
|
6171
|
+
`/api/v2/automation-connections/${selectorValue(connection)}`,
|
|
6172
|
+
jsonOptions(input, "PATCH")
|
|
6173
|
+
);
|
|
6708
6174
|
}
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
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,
|
|
7214
|
-
if (
|
|
7215
|
-
const match = folders.find((folder) => folder.id ===
|
|
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 ===
|
|
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 "${
|
|
6689
|
+
`Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
|
|
7228
6690
|
);
|
|
7229
6691
|
}
|
|
7230
|
-
throw new CliError("invalid_cli_usage", `Folder "${
|
|
6692
|
+
throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
|
|
7231
6693
|
}
|
|
7232
|
-
async function resolveFolderSelector(api,
|
|
7233
|
-
if (!
|
|
6694
|
+
async function resolveFolderSelector(api, selector) {
|
|
6695
|
+
if (!selector) {
|
|
7234
6696
|
return void 0;
|
|
7235
6697
|
}
|
|
7236
|
-
if (
|
|
7237
|
-
return
|
|
6698
|
+
if (selector.kind === "uuid") {
|
|
6699
|
+
return selector;
|
|
7238
6700
|
}
|
|
7239
6701
|
const folders = await api.listFolders();
|
|
7240
|
-
const resolved = resolveFolder(folders,
|
|
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 "${
|
|
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
|
|
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
|
|
8034
|
-
return
|
|
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/${
|
|
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/${
|
|
8048
|
-
|
|
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
|
|
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
|
|
8252
|
-
return encodeURIComponent(
|
|
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/${
|
|
7727
|
+
return this.client.getJson(`/api/v2/displays/${selectorValue3(display)}`);
|
|
8266
7728
|
}
|
|
8267
7729
|
createDisplay(body) {
|
|
8268
|
-
return this.client.requestJson("/api/v2/displays",
|
|
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/${
|
|
8273
|
-
|
|
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/${
|
|
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/${
|
|
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/${
|
|
8290
|
-
|
|
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/${
|
|
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/${
|
|
8301
|
-
|
|
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/${
|
|
8307
|
-
|
|
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/${
|
|
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/${
|
|
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/${
|
|
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/${
|
|
8329
|
-
|
|
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/${
|
|
8335
|
-
|
|
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/${
|
|
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/${
|
|
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/${
|
|
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/${
|
|
8357
|
-
|
|
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/${
|
|
8363
|
-
|
|
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/${
|
|
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/${
|
|
8375
|
-
|
|
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/${
|
|
8381
|
-
|
|
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/${
|
|
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/${
|
|
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/${
|
|
8398
|
-
|
|
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/${
|
|
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
|
|
8972
|
-
return
|
|
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/${
|
|
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/${
|
|
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
|
|
9178
|
-
return
|
|
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/${
|
|
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
|
|
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
|
|
9296
|
-
return
|
|
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
|
-
|
|
8770
|
+
jsonOptions4(body, "POST")
|
|
9309
8771
|
);
|
|
9310
8772
|
}
|
|
9311
8773
|
updateFolder(folder, body) {
|
|
9312
8774
|
return this.client.requestJson(
|
|
9313
|
-
`/api/v2/navigation/folders/${
|
|
9314
|
-
|
|
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/${
|
|
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
|
-
|
|
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,
|
|
9442
|
-
if (
|
|
9443
|
-
const match = folders.find((folder) => folder.id ===
|
|
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 "${
|
|
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 ===
|
|
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 "${
|
|
8918
|
+
`Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
|
|
9457
8919
|
);
|
|
9458
8920
|
}
|
|
9459
|
-
throw new CliError("invalid_cli_usage", `Folder "${
|
|
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
|
|
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
|
|
9726
|
-
return
|
|
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/${
|
|
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/${
|
|
9750
|
-
|
|
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/${
|
|
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/${
|
|
9761
|
-
|
|
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/${
|
|
9767
|
-
|
|
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/${
|
|
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,
|
|
10190
|
-
if (
|
|
10191
|
-
return
|
|
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 ===
|
|
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 "${
|
|
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,
|
|
10570
|
-
if (
|
|
10571
|
-
return
|
|
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 ===
|
|
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 "${
|
|
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,
|
|
10584
|
-
if (
|
|
10585
|
-
return
|
|
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 ===
|
|
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 "${
|
|
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(
|
|
10769
|
-
return
|
|
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,
|
|
10999
|
-
if (
|
|
11000
|
-
return
|
|
10544
|
+
function buildFolderLookup(folders, selector) {
|
|
10545
|
+
if (selector.kind === "uuid") {
|
|
10546
|
+
return selector;
|
|
11001
10547
|
}
|
|
11002
|
-
const matches = folders.filter((folder) => folder.name ===
|
|
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 "${
|
|
10561
|
+
`Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
|
|
11016
10562
|
);
|
|
11017
10563
|
}
|
|
11018
|
-
throw new CliError("invalid_cli_usage", `Folder "${
|
|
10564
|
+
throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
|
|
11019
10565
|
}
|
|
11020
|
-
function findFolderEntity(folders,
|
|
11021
|
-
if (
|
|
11022
|
-
const match = folders.find((folder) => folder.id ===
|
|
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 "${
|
|
10572
|
+
throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
|
|
11027
10573
|
}
|
|
11028
|
-
const matches = folders.filter((folder) => folder.name ===
|
|
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 "${
|
|
10581
|
+
`Folder "${selector.value}" is ambiguous. Found ${matches.length} matches.`
|
|
11036
10582
|
);
|
|
11037
10583
|
}
|
|
11038
|
-
throw new CliError("invalid_cli_usage", `Folder "${
|
|
10584
|
+
throw new CliError("invalid_cli_usage", `Folder "${selector.value}" was not found.`);
|
|
11039
10585
|
}
|
|
11040
|
-
async function resolveFolderSelector2(api,
|
|
11041
|
-
if (
|
|
11042
|
-
return
|
|
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,
|
|
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
|
-
|
|
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
|
}
|