zinkee 0.1.39 → 0.1.41

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.
@@ -0,0 +1,77 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: read
10
+ id-token: write
11
+
12
+ jobs:
13
+ publish:
14
+ name: Publish package
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - name: Checkout repository
19
+ uses: actions/checkout@v6
20
+
21
+ - name: Set up Node.js
22
+ uses: actions/setup-node@v6
23
+ with:
24
+ node-version: 24
25
+ registry-url: https://registry.npmjs.org
26
+ package-manager-cache: false
27
+
28
+ - name: Check package version
29
+ id: version
30
+ shell: bash
31
+ run: |
32
+ package_name="$(node -p "require('./package.json').name")"
33
+ package_version="$(node -p "require('./package.json').version")"
34
+
35
+ set +e
36
+ lookup_output="$(npm view "${package_name}@${package_version}" version 2>&1)"
37
+ lookup_status=$?
38
+ set -e
39
+
40
+ if [ "$lookup_status" -eq 0 ]; then
41
+ echo "${package_name}@${package_version} is already published; skipping."
42
+ echo "already-published=true" >> "$GITHUB_OUTPUT"
43
+ elif echo "$lookup_output" | grep -q "E404"; then
44
+ echo "${package_name}@${package_version} is not published yet."
45
+ echo "already-published=false" >> "$GITHUB_OUTPUT"
46
+ else
47
+ echo "$lookup_output" >&2
48
+ exit "$lookup_status"
49
+ fi
50
+
51
+ - name: Set up trusted publishing
52
+ if: steps.version.outputs.already-published == 'false'
53
+ run: npm install --global npm@11.5.1
54
+
55
+ - name: Install dependencies
56
+ if: steps.version.outputs.already-published == 'false'
57
+ run: npm ci
58
+
59
+ - name: Run tests
60
+ if: steps.version.outputs.already-published == 'false'
61
+ run: npm test
62
+
63
+ - name: Run typecheck
64
+ if: steps.version.outputs.already-published == 'false'
65
+ run: npm run typecheck
66
+
67
+ - name: Build project
68
+ if: steps.version.outputs.already-published == 'false'
69
+ run: npm run build
70
+
71
+ - name: Inspect package contents
72
+ if: steps.version.outputs.already-published == 'false'
73
+ run: npm pack --dry-run
74
+
75
+ - name: Publish package
76
+ if: steps.version.outputs.already-published == 'false'
77
+ run: npm publish --access public
@@ -0,0 +1,36 @@
1
+ name: PR Checks
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ validate:
13
+ name: Test, Typecheck, and Build
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: 24
24
+ cache: npm
25
+
26
+ - name: Install dependencies
27
+ run: npm ci
28
+
29
+ - name: Run tests
30
+ run: npm test
31
+
32
+ - name: Run typecheck
33
+ run: npm run typecheck
34
+
35
+ - name: Build project
36
+ run: npm run build
package/AGENTS.md CHANGED
@@ -101,8 +101,9 @@ Prefer focused command tests and parser/client unit tests.
101
101
 
102
102
  - Versioning is patch-only today (`0.1.x`). Bump the patch number unless the
103
103
  team decides to move to a different scheme.
104
- - Every PR that ships user-visible changes (new commands, fixed examples,
105
- behaviour changes) bumps `package.json` version in the same PR — not in a
106
- separate "release" PR.
104
+ - If an agent determines that a PR requires a new published version, it must
105
+ bump the version in `package.json` in that same PR and keep
106
+ `package-lock.json` in sync. User-visible changes (new commands, fixed
107
+ examples, behaviour changes) always require this.
107
108
  - Before bumping, fetch `origin/main` to make sure the version you pick isn't
108
109
  already taken by another PR that merged ahead of yours.
package/dist/index.js CHANGED
@@ -1224,6 +1224,17 @@ function buildJsonSuccess(data, meta = {}) {
1224
1224
  function buildJsonError(error, meta = {}) {
1225
1225
  return { error, meta };
1226
1226
  }
1227
+ var FOLDER_TABLE_KEYS = ["folderId", "folderName", "folderIsRoot"];
1228
+ function folderColumns(folder) {
1229
+ if (!folder) {
1230
+ return { folderId: "", folderName: "", folderIsRoot: "" };
1231
+ }
1232
+ return {
1233
+ folderId: folder.id ?? "",
1234
+ folderName: folder.name ?? (folder.isRoot === true ? "(root)" : ""),
1235
+ folderIsRoot: folder.isRoot === void 0 ? "" : String(folder.isRoot)
1236
+ };
1237
+ }
1227
1238
  function getWriter(writer) {
1228
1239
  return writer ?? process.stdout;
1229
1240
  }
@@ -4963,21 +4974,36 @@ var specificExamples = {
4963
4974
  "name": "Executive Revenue",
4964
4975
  "layoutTemplate": "widget_row_tabs",
4965
4976
  "variableCount": 3,
4966
- "widgetCount": 6
4977
+ "widgetCount": 6,
4978
+ "folder": {
4979
+ "id": "b1a2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
4980
+ "name": "\u{1F4CA} Executive",
4981
+ "isRoot": false
4982
+ }
4967
4983
  },
4968
4984
  {
4969
4985
  "id": "6b7c8d9e-0f12-3456-789a-bcdef0123456",
4970
4986
  "name": "Sales Pipeline",
4971
4987
  "layoutTemplate": "freeform",
4972
4988
  "variableCount": 1,
4973
- "widgetCount": 3
4989
+ "widgetCount": 3,
4990
+ "folder": {
4991
+ "id": "a0b1c2d3-e4f5-4061-8273-8495a6b7c8d9",
4992
+ "name": null,
4993
+ "isRoot": true
4994
+ }
4974
4995
  },
4975
4996
  {
4976
4997
  "id": "ef012345-6789-4abc-8def-0123456789ab",
4977
4998
  "name": "Customer Detail",
4978
4999
  "layoutTemplate": "grid",
4979
5000
  "variableCount": 0,
4980
- "widgetCount": 2
5001
+ "widgetCount": 2,
5002
+ "folder": {
5003
+ "id": "b1a2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
5004
+ "name": "\u{1F4CA} Executive",
5005
+ "isRoot": false
5006
+ }
4981
5007
  }
4982
5008
  ]`
4983
5009
  }
@@ -5109,7 +5135,12 @@ var specificExamples = {
5109
5135
  "targetVariableId": "aaaaaaaa-1111-4111-a111-111111111111",
5110
5136
  "label": "Open customer"
5111
5137
  }
5112
- ]
5138
+ ],
5139
+ "folder": {
5140
+ "id": "b1a2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
5141
+ "name": "\u{1F4CA} Executive",
5142
+ "isRoot": false
5143
+ }
5113
5144
  }`
5114
5145
  }
5115
5146
  ]),
@@ -7361,23 +7392,45 @@ function readJsonValueOption(raw, rawFile, rawLabel, rawFileLabel) {
7361
7392
  function readJsonObjectOption(raw, rawFile, rawLabel, rawFileLabel) {
7362
7393
  return readJsonValueOption(raw, rawFile, rawLabel, rawFileLabel) ?? {};
7363
7394
  }
7395
+ var NO_VALUE_COMPARATORS = /* @__PURE__ */ new Set([
7396
+ "chg",
7397
+ "changes",
7398
+ "ie",
7399
+ "is_empty",
7400
+ "ine",
7401
+ "is_not_empty"
7402
+ ]);
7403
+ function isNoValueComparator(comparator) {
7404
+ return NO_VALUE_COMPARATORS.has(comparator.toLowerCase());
7405
+ }
7406
+ function conditionFormatError(input) {
7407
+ return new CliError(
7408
+ "invalid_cli_usage",
7409
+ `Expected condition in the form field:comparator:value, or field:comparator for comparators without value (chg, ie, ine), received "${input}".`
7410
+ );
7411
+ }
7364
7412
  function parseCondition(input) {
7365
7413
  const firstSeparator = input.indexOf(":");
7366
7414
  const secondSeparator = input.indexOf(":", firstSeparator + 1);
7367
- if (firstSeparator <= 0 || secondSeparator <= firstSeparator + 1) {
7368
- throw new CliError(
7369
- "invalid_cli_usage",
7370
- `Expected condition in the form field:comparator:value, received "${input}".`
7371
- );
7415
+ if (firstSeparator <= 0) {
7416
+ throw conditionFormatError(input);
7417
+ }
7418
+ if (secondSeparator === -1) {
7419
+ const field2 = input.slice(0, firstSeparator).trim();
7420
+ const comparator2 = input.slice(firstSeparator + 1).trim();
7421
+ if (!field2 || !comparator2 || !isNoValueComparator(comparator2)) {
7422
+ throw conditionFormatError(input);
7423
+ }
7424
+ return { field: field2, comparator: comparator2, values: [] };
7425
+ }
7426
+ if (secondSeparator <= firstSeparator + 1) {
7427
+ throw conditionFormatError(input);
7372
7428
  }
7373
7429
  const field = input.slice(0, firstSeparator).trim();
7374
7430
  const comparator = input.slice(firstSeparator + 1, secondSeparator).trim();
7375
7431
  const value = input.slice(secondSeparator + 1).trim();
7376
7432
  if (!field || !comparator || !value) {
7377
- throw new CliError(
7378
- "invalid_cli_usage",
7379
- `Expected condition in the form field:comparator:value, received "${input}".`
7380
- );
7433
+ throw conditionFormatError(input);
7381
7434
  }
7382
7435
  return {
7383
7436
  field,
@@ -7524,10 +7577,11 @@ function normalizeAutomationConditions(conditions, label, options) {
7524
7577
  const field = typeof condition.field === "string" ? condition.field.trim() : "";
7525
7578
  const comparator = typeof condition.comparator === "string" ? condition.comparator.trim() : "";
7526
7579
  const values = condition.values;
7527
- if (!field || !comparator || !Array.isArray(values) || values.length === 0) {
7580
+ const allowsEmptyValues = isNoValueComparator(comparator);
7581
+ if (!field || !comparator || !Array.isArray(values) || values.length === 0 && !allowsEmptyValues) {
7528
7582
  throw new CliError(
7529
7583
  "invalid_cli_usage",
7530
- `Expected ${label} ${index + 1} to contain "field", "comparator", and a non-empty "values" array.`
7584
+ `Expected ${label} ${index + 1} to contain "field", "comparator", and a non-empty "values" array (comparators without value, e.g. chg/ie/ine, accept an empty array).`
7531
7585
  );
7532
7586
  }
7533
7587
  return {
@@ -7612,9 +7666,9 @@ function automationRows(automations) {
7612
7666
  id: automation.id ?? "",
7613
7667
  name: automation.name ?? "",
7614
7668
  status: automation.status ?? "",
7615
- folderId: automation.folderId ?? "",
7616
7669
  triggerType: isJsonObject2(automation.trigger) && typeof automation.trigger.type === "string" ? automation.trigger.type : "",
7617
- actionCount: Array.isArray(automation.actions) ? automation.actions.length : ""
7670
+ actionCount: Array.isArray(automation.actions) ? automation.actions.length : "",
7671
+ ...folderColumns(automation.folder)
7618
7672
  }));
7619
7673
  }
7620
7674
  function actionRows(actions) {
@@ -8004,7 +8058,7 @@ function addTriggerPayloadOptions(command) {
8004
8058
  []
8005
8059
  ).option(
8006
8060
  "--condition <field:comparator:value>",
8007
- "trigger condition",
8061
+ "trigger condition (use field:comparator for comparators without value: chg, ie, ine)",
8008
8062
  collectValues,
8009
8063
  []
8010
8064
  ).option(
@@ -8031,7 +8085,12 @@ function addActionPayloadOptions(command) {
8031
8085
  return command.option(
8032
8086
  "--type <type>",
8033
8087
  "action type (create_record|update_record|search_records|send_message|http_request|execute_plugin|generate_document)"
8034
- ).option("--name <name>", "action name").option("--target-schema <uuid>", "target schema id").option("--map <field=value>", "field mapping", collectValues, []).option("--map-json <field=json>", "JSON field mapping", collectValues, []).option("--condition <field:comparator:value>", "action condition", collectValues, []).option("--condition-json <json>", "action condition as JSON", collectValues, []).option("--use-trigger-record", "use the triggering record").option("--method <method>", "HTTP method").option("--url <url>", "HTTP target URL").option("--header <key=value>", "HTTP header", collectValues, []).option("--body <json>", "HTTP request body as JSON").option("--body-file <path>", "path to HTTP request body JSON").option("--content-type <type>", "HTTP content type").option(
8088
+ ).option("--name <name>", "action name").option("--target-schema <uuid>", "target schema id").option("--map <field=value>", "field mapping", collectValues, []).option("--map-json <field=json>", "JSON field mapping", collectValues, []).option(
8089
+ "--condition <field:comparator:value>",
8090
+ "action condition (use field:comparator for comparators without value: ie, ine)",
8091
+ collectValues,
8092
+ []
8093
+ ).option("--condition-json <json>", "action condition as JSON", collectValues, []).option("--use-trigger-record", "use the triggering record").option("--method <method>", "HTTP method").option("--url <url>", "HTTP target URL").option("--header <key=value>", "HTTP header", collectValues, []).option("--body <json>", "HTTP request body as JSON").option("--body-file <path>", "path to HTTP request body JSON").option("--content-type <type>", "HTTP content type").option(
8035
8094
  "--timeout-ms <n>",
8036
8095
  "HTTP timeout in milliseconds",
8037
8096
  parseNonNegativeInteger
@@ -8136,7 +8195,7 @@ function registerAutomationsCommands(program, options = {}) {
8136
8195
  }
8137
8196
  printTable(
8138
8197
  automationRows(data),
8139
- ["id", "name", "status", "folderId", "triggerType", "actionCount"],
8198
+ ["id", "name", "status", "triggerType", "actionCount", ...FOLDER_TABLE_KEYS],
8140
8199
  stdout
8141
8200
  );
8142
8201
  });
@@ -9247,7 +9306,8 @@ function displayRows(displays) {
9247
9306
  name: display.name ?? "",
9248
9307
  layoutTemplate: display.layoutTemplate ?? "",
9249
9308
  variableCount: display.variableCount ?? "",
9250
- widgetCount: display.widgetCount ?? ""
9309
+ widgetCount: display.widgetCount ?? "",
9310
+ ...folderColumns(display.folder)
9251
9311
  }));
9252
9312
  }
9253
9313
  function getDisplaySubresource(value) {
@@ -9497,7 +9557,11 @@ function registerDisplaysCommands(program, options = {}) {
9497
9557
  emitJson4(stdout, "displays list", data);
9498
9558
  return;
9499
9559
  }
9500
- printTable(displayRows(data), ["id", "name", "layoutTemplate", "variableCount", "widgetCount"], stdout);
9560
+ printTable(
9561
+ displayRows(data),
9562
+ ["id", "name", "layoutTemplate", "variableCount", "widgetCount", ...FOLDER_TABLE_KEYS],
9563
+ stdout
9564
+ );
9501
9565
  });
9502
9566
  displays.command("get").description("Get a display").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).action(async function action(display) {
9503
9567
  const { api, json } = createDisplaysApi(this, filePath);
@@ -11888,9 +11952,10 @@ function emitSchemasTable(stdout, schemas) {
11888
11952
  name: schema.name ?? "",
11889
11953
  slug: schema.slug ?? "",
11890
11954
  auditable: schema.auditable ?? "",
11891
- commentable: schema.commentable ?? ""
11955
+ commentable: schema.commentable ?? "",
11956
+ ...folderColumns(schema.folder)
11892
11957
  })),
11893
- ["id", "name", "slug", "auditable", "commentable"],
11958
+ ["id", "name", "slug", "auditable", "commentable", ...FOLDER_TABLE_KEYS],
11894
11959
  stdout
11895
11960
  );
11896
11961
  }