zinkee 0.1.11 → 0.1.15

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 CHANGED
@@ -50,3 +50,45 @@ Use this order when reasoning about behavior:
50
50
  ## Testing
51
51
 
52
52
  Prefer focused command tests and parser/client unit tests.
53
+
54
+ > **Unit tests use `fetchMock` and never hit the real API.** When changing the
55
+ > shape of a payload (enum values, property names, structure), unit tests will
56
+ > still pass even if the real API would reject the request with `400`. For
57
+ > shape-sensitive changes — especially edits to strings in `src/utils/examples.ts`
58
+ > — also run the resulting command against a real workspace and confirm the API
59
+ > accepts it.
60
+
61
+ ## Contributing
62
+
63
+ ### Branches
64
+
65
+ - `feature/eng-<ticket>-<slug>` for Linear-tracked work
66
+ - `fix/<slug>` / `chore/<slug>` / `docs/<slug>` for untracked work
67
+ - Never push to `main` directly; always open a PR
68
+
69
+ ### Commits
70
+
71
+ - Conventional Commits format: `<type>(<scope>): <subject>` (e.g.
72
+ `fix(displays): correct chart-type values in widget examples`)
73
+ - Subject in imperative mood, under ~72 chars, no trailing period
74
+ - Body explains the *why*, not the *what* — the diff already shows what changed
75
+ - Stage files explicitly (`git add <path>`); never `git add -A`
76
+ - Don't add `Co-Authored-By:` trailers; existing history doesn't use them
77
+
78
+ ### Before committing
79
+
80
+ 1. `npm run typecheck` — must pass
81
+ 2. `npm test` — must pass
82
+ 3. For changes that affect runtime behaviour or `--example` output, also
83
+ exercise the affected commands against a live workspace (see Testing note
84
+ above).
85
+
86
+ ### Versioning
87
+
88
+ - Versioning is patch-only today (`0.1.x`). Bump the patch number unless the
89
+ team decides to move to a different scheme.
90
+ - Every PR that ships user-visible changes (new commands, fixed examples,
91
+ behaviour changes) bumps `package.json` version in the same PR — not in a
92
+ separate "release" PR.
93
+ - Before bumping, fetch `origin/main` to make sure the version you pick isn't
94
+ already taken by another PR that merged ahead of yours.
package/README.md CHANGED
@@ -273,10 +273,17 @@ zinkee records update projects <record-uuid> --set status=2
273
273
 
274
274
  # Delete
275
275
  zinkee records delete projects <record-uuid>
276
+
277
+ # Clear all records from a schema (destructive — irreversible)
278
+ zinkee records clear projects
276
279
  ```
277
280
 
278
281
  Option values are written as numbers (`--set status=1`) but returned as strings (`"1"`). Number values are stored and returned as strings.
279
282
 
283
+ `records clear` removes every record from the schema's table. Heritage rules
284
+ (`CASCADE` / `SET NULL`) propagate to child schemas asynchronously through the
285
+ CDC pipeline, so related tables converge eventually. Blocked by `--read-only`.
286
+
280
287
  ---
281
288
 
282
289
  ## Files
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",
@@ -732,6 +739,197 @@ var commandRegistry = {
732
739
  }
733
740
  };
734
741
 
742
+ // src/utils/argv-rewrite.ts
743
+ var HOISTABLE_GLOBAL_FLAGS = {
744
+ "--profile": "value",
745
+ "--base-url": "value",
746
+ "--api-key": "value",
747
+ "--read-only": "boolean",
748
+ "--json": "boolean"
749
+ };
750
+ function isHoistableFlag(flagName) {
751
+ return Object.hasOwn(HOISTABLE_GLOBAL_FLAGS, flagName);
752
+ }
753
+ function getCommandPath(command) {
754
+ const parts = [];
755
+ let cursor = command;
756
+ while (cursor && cursor.parent) {
757
+ parts.unshift(cursor.name());
758
+ cursor = cursor.parent;
759
+ }
760
+ return parts.join(" ");
761
+ }
762
+ function buildOptionMetadata(program) {
763
+ const valueFlags = /* @__PURE__ */ new Set();
764
+ const booleanFlags = /* @__PURE__ */ new Set();
765
+ const localOptionsByCommand = /* @__PURE__ */ new Map();
766
+ function visit(command, isRoot) {
767
+ const localFlags = /* @__PURE__ */ new Set();
768
+ for (const option of command.options) {
769
+ if (!option.long) continue;
770
+ if (option.required || option.optional) {
771
+ valueFlags.add(option.long);
772
+ } else {
773
+ booleanFlags.add(option.long);
774
+ }
775
+ if (!isRoot) {
776
+ localFlags.add(option.long);
777
+ }
778
+ }
779
+ if (!isRoot) {
780
+ localOptionsByCommand.set(getCommandPath(command), localFlags);
781
+ }
782
+ for (const sub of command.commands) {
783
+ visit(sub, false);
784
+ }
785
+ }
786
+ visit(program, true);
787
+ return { valueFlags, booleanFlags, localOptionsByCommand };
788
+ }
789
+ function createDefaultOptionMetadata() {
790
+ return {
791
+ valueFlags: /* @__PURE__ */ new Set([
792
+ "--profile",
793
+ "--base-url",
794
+ "--api-key",
795
+ "--install-completion",
796
+ "--show-completion"
797
+ ]),
798
+ booleanFlags: /* @__PURE__ */ new Set([
799
+ "--read-only",
800
+ "--json",
801
+ "--example",
802
+ "--help"
803
+ ]),
804
+ localOptionsByCommand: /* @__PURE__ */ new Map()
805
+ };
806
+ }
807
+ function isFlagToken(token) {
808
+ return token.length > 1 && token.startsWith("-");
809
+ }
810
+ function splitFlagToken(token) {
811
+ if (token.startsWith("--") && token.includes("=")) {
812
+ const eqIdx = token.indexOf("=");
813
+ return {
814
+ flagName: token.slice(0, eqIdx),
815
+ inlineValue: token.slice(eqIdx + 1)
816
+ };
817
+ }
818
+ return { flagName: token, inlineValue: void 0 };
819
+ }
820
+ function flagConsumesValue(flagName, optionMeta) {
821
+ if (optionMeta.valueFlags.has(flagName)) {
822
+ return true;
823
+ }
824
+ if (optionMeta.booleanFlags.has(flagName)) {
825
+ return false;
826
+ }
827
+ return true;
828
+ }
829
+ function collectOperandTokens(userArgs, optionMeta, options = {}) {
830
+ const operands = [];
831
+ let i = 0;
832
+ while (i < userArgs.length) {
833
+ const token = userArgs[i];
834
+ if (token === "--") {
835
+ break;
836
+ }
837
+ if (isFlagToken(token)) {
838
+ const { flagName, inlineValue } = splitFlagToken(token);
839
+ if (options.skipFlag !== void 0 && flagName === options.skipFlag) {
840
+ i += 1;
841
+ continue;
842
+ }
843
+ if (inlineValue !== void 0) {
844
+ i += 1;
845
+ continue;
846
+ }
847
+ const consumes = flagConsumesValue(flagName, optionMeta);
848
+ const next = userArgs[i + 1];
849
+ if (consumes && next !== void 0 && !isFlagToken(next)) {
850
+ i += 2;
851
+ } else {
852
+ i += 1;
853
+ }
854
+ continue;
855
+ }
856
+ operands.push({ index: i, token });
857
+ i += 1;
858
+ }
859
+ return operands;
860
+ }
861
+ function findCommandPath(operands, registry) {
862
+ if (operands.length === 0) return null;
863
+ const commandsByLength = Object.keys(registry).sort(
864
+ (left, right) => right.split(" ").length - left.split(" ").length
865
+ );
866
+ for (let start = 0; start < operands.length; start += 1) {
867
+ for (const commandName of commandsByLength) {
868
+ const parts = commandName.split(" ");
869
+ if (start + parts.length > operands.length) continue;
870
+ let matches = true;
871
+ for (let j = 0; j < parts.length; j += 1) {
872
+ if (operands[start + j].token !== parts[j]) {
873
+ matches = false;
874
+ break;
875
+ }
876
+ }
877
+ if (matches) {
878
+ return {
879
+ commandName,
880
+ firstArgvIndex: operands[start].index,
881
+ lastArgvIndex: operands[start + parts.length - 1].index
882
+ };
883
+ }
884
+ }
885
+ }
886
+ return null;
887
+ }
888
+ function hoistGlobalOptions(argv, optionMeta, registry) {
889
+ if (argv.length < 3) return [...argv];
890
+ const userArgs = argv.slice(2);
891
+ const operands = collectOperandTokens(userArgs, optionMeta);
892
+ const cmdPath = findCommandPath(operands, registry);
893
+ if (!cmdPath) return [...argv];
894
+ const localOptions = optionMeta.localOptionsByCommand.get(cmdPath.commandName) ?? /* @__PURE__ */ new Set();
895
+ const hoisted = [];
896
+ const remaining = [];
897
+ let i = 0;
898
+ while (i < userArgs.length) {
899
+ const token = userArgs[i];
900
+ if (token === "--") {
901
+ remaining.push(...userArgs.slice(i));
902
+ break;
903
+ }
904
+ if (!isFlagToken(token)) {
905
+ remaining.push(token);
906
+ i += 1;
907
+ continue;
908
+ }
909
+ const { flagName, inlineValue } = splitFlagToken(token);
910
+ if (!isHoistableFlag(flagName)) {
911
+ remaining.push(token);
912
+ i += 1;
913
+ continue;
914
+ }
915
+ const isAfterCommandPath = i > cmdPath.lastArgvIndex;
916
+ const collidesWithLocal = localOptions.has(flagName);
917
+ const target = isAfterCommandPath && collidesWithLocal ? remaining : hoisted;
918
+ target.push(token);
919
+ const spec = HOISTABLE_GLOBAL_FLAGS[flagName];
920
+ if (spec === "value" && inlineValue === void 0) {
921
+ const next = userArgs[i + 1];
922
+ if (next !== void 0 && !isFlagToken(next)) {
923
+ target.push(next);
924
+ i += 2;
925
+ continue;
926
+ }
927
+ }
928
+ i += 1;
929
+ }
930
+ return [argv[0], argv[1], ...hoisted, ...remaining];
931
+ }
932
+
735
933
  // src/client.ts
736
934
  var ApiClientError = class extends Error {
737
935
  name = "ApiClientError";
@@ -1998,17 +2196,17 @@ var fieldTypeDefinitions = [
1998
2196
  className: "FormulaField",
1999
2197
  aliases: ["formula", "FormulaField"],
2000
2198
  description: "Calculated field from a formula.",
2001
- rawShape: `{"type":"FormulaField","slug":"formula-summary","label":"Formula Summary","config":{"formulaText":"concat(firstName, ' ', lastName)","uiFormatKind":"none"}}`,
2199
+ rawShape: '{"type":"FormulaField","slug":"formula-code","label":"Formula Code","config":{"formulaText":"concat(\\"CUST-\\", f1e1d000-0000-0000-0000-000000000005)","uiFormatKind":"none"}}',
2002
2200
  examplePayloads: [
2003
2201
  {
2004
2202
  name: "Formula field (none)",
2005
2203
  payload: {
2006
2204
  type: "FormulaField",
2007
- slug: "formula-summary",
2008
- label: "Formula Summary",
2205
+ slug: "formula-code",
2206
+ label: "Formula Code",
2009
2207
  required: false,
2010
2208
  config: {
2011
- formulaText: "concat(firstName, ' ', lastName)",
2209
+ formulaText: 'concat("CUST-", f1e1d000-0000-0000-0000-000000000005)',
2012
2210
  uiFormatKind: "none",
2013
2211
  status: "ACTIVE",
2014
2212
  conditionalFormatting: []
@@ -2023,7 +2221,7 @@ var fieldTypeDefinitions = [
2023
2221
  label: "Formula Total",
2024
2222
  required: false,
2025
2223
  config: {
2026
- formulaText: "amount * 1.21",
2224
+ formulaText: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
2027
2225
  uiFormatKind: "number",
2028
2226
  status: "ACTIVE",
2029
2227
  numberFormatOptions: {
@@ -2039,11 +2237,11 @@ var fieldTypeDefinitions = [
2039
2237
  name: "Formula field (date)",
2040
2238
  payload: {
2041
2239
  type: "FormulaField",
2042
- slug: "formula-deadline",
2043
- label: "Computed Deadline",
2240
+ slug: "formula-period",
2241
+ label: "Formula Period",
2044
2242
  required: false,
2045
2243
  config: {
2046
- formulaText: "addDays(startDate, 7)",
2244
+ formulaText: 'date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")',
2047
2245
  uiFormatKind: "date",
2048
2246
  status: "ACTIVE",
2049
2247
  dateFormatOptions: {
@@ -2063,7 +2261,7 @@ var fieldTypeDefinitions = [
2063
2261
  label: "Computed Assignee",
2064
2262
  required: false,
2065
2263
  config: {
2066
- formulaText: "manager",
2264
+ formulaText: "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
2067
2265
  uiFormatKind: "member",
2068
2266
  status: "ACTIVE",
2069
2267
  conditionalFormatting: []
@@ -2800,11 +2998,11 @@ var specificExamples = {
2800
2998
  },
2801
2999
  {
2802
3000
  description: "Patch formula field (formula text).",
2803
- command: `zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"amount * 1.10","uiFormatKind":"number","status":"ACTIVE","numberFormatOptions":{"format":"number","decimals":2,"thousandsSeparator":true},"conditionalFormatting":[]}}'`,
3001
+ 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":[]}}'`,
2804
3002
  raw: `{
2805
3003
  "type": "FormulaField",
2806
3004
  "config": {
2807
- "formulaText": "amount * 1.10",
3005
+ "formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.10",
2808
3006
  "uiFormatKind": "number",
2809
3007
  "status": "ACTIVE",
2810
3008
  "numberFormatOptions": {
@@ -3715,8 +3913,8 @@ var specificExamples = {
3715
3913
  }`
3716
3914
  },
3717
3915
  {
3718
- description: "Create a bar CHART widget with a time-serie x-axis and two y-axis series.",
3719
- command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bar --x-axis-field due-date --x-axis-date-format MONTH --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"BAR"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"id","color":"#E57373","axisType":"LINE"}' --legend '{"position":"bottom"}'`,
3916
+ description: "Create a bars CHART widget with a time-serie x-axis and two y-axis series.",
3917
+ 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"}'`,
3720
3918
  raw: `{
3721
3919
  "type": "CHART",
3722
3920
  "source": {
@@ -3728,7 +3926,7 @@ var specificExamples = {
3728
3926
  },
3729
3927
  "presentation": { "name": "Revenue by month" },
3730
3928
  "chart": {
3731
- "chartType": "bar",
3929
+ "chartType": "bars",
3732
3930
  "xAxisFieldId": "due-date",
3733
3931
  "xAxisDateFormat": "MONTH",
3734
3932
  "xAxisAsTimeSerie": true,
@@ -3737,13 +3935,13 @@ var specificExamples = {
3737
3935
  "typeCalc": "SUM",
3738
3936
  "fieldCalc": "amount",
3739
3937
  "color": "#4B9CD3",
3740
- "axisType": "BAR"
3938
+ "axisType": "PRIMARY"
3741
3939
  },
3742
3940
  {
3743
3941
  "typeCalc": "COUNT",
3744
3942
  "fieldCalc": "id",
3745
3943
  "color": "#E57373",
3746
- "axisType": "LINE"
3944
+ "axisType": "SECONDARY"
3747
3945
  }
3748
3946
  ],
3749
3947
  "legend": { "position": "bottom" }
@@ -3889,11 +4087,11 @@ var specificExamples = {
3889
4087
  }`
3890
4088
  },
3891
4089
  {
3892
- description: "Replace the chart series with a weekly line.",
3893
- command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type line --x-axis-field due-date --x-axis-date-format WEEK --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"LINE"}'`,
4090
+ description: "Replace the chart series with weekly lines.",
4091
+ 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"}'`,
3894
4092
  raw: `{
3895
4093
  "chart": {
3896
- "chartType": "line",
4094
+ "chartType": "lines",
3897
4095
  "xAxisFieldId": "due-date",
3898
4096
  "xAxisDateFormat": "WEEK",
3899
4097
  "xAxisAsTimeSerie": true,
@@ -3902,7 +4100,7 @@ var specificExamples = {
3902
4100
  "typeCalc": "SUM",
3903
4101
  "fieldCalc": "amount",
3904
4102
  "color": "#2E7D32",
3905
- "axisType": "LINE"
4103
+ "axisType": "PRIMARY"
3906
4104
  }
3907
4105
  ]
3908
4106
  }
@@ -4230,7 +4428,7 @@ var specificExamples = {
4230
4428
  "required": false,
4231
4429
  "system": false,
4232
4430
  "config": {
4233
- "formulaText": "amount * 1.21",
4431
+ "formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
4234
4432
  "uiFormatKind": "number",
4235
4433
  "status": "ACTIVE",
4236
4434
  "defaultValue": null,
@@ -4245,12 +4443,12 @@ var specificExamples = {
4245
4443
  {
4246
4444
  "id": "6d7e8f90-1234-5678-9abc-def012345678",
4247
4445
  "type": "FormulaField",
4248
- "slug": "formula-deadline",
4249
- "label": "Computed Deadline",
4446
+ "slug": "formula-period",
4447
+ "label": "Formula Period",
4250
4448
  "required": false,
4251
4449
  "system": false,
4252
4450
  "config": {
4253
- "formulaText": "addDays(startDate, 7)",
4451
+ "formulaText": "date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")",
4254
4452
  "uiFormatKind": "date",
4255
4453
  "status": "ACTIVE",
4256
4454
  "defaultValue": null,
@@ -4532,6 +4730,16 @@ var specificExamples = {
4532
4730
  response: `{
4533
4731
  "recordId": "550e8400-e29b-41d4-a716-446655440000",
4534
4732
  "deleted": true
4733
+ }`
4734
+ }
4735
+ ]),
4736
+ "records clear": buildCommandExamples([
4737
+ {
4738
+ description: "Delete every record from a schema's table. Heritage rules (CASCADE / SET NULL) propagate to child schemas asynchronously via the CDC pipeline.",
4739
+ command: "zinkee --json records clear contacts",
4740
+ response: `{
4741
+ "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4742
+ "cleared": true
4535
4743
  }`
4536
4744
  }
4537
4745
  ]),
@@ -5613,7 +5821,7 @@ var specificExamples = {
5613
5821
  },
5614
5822
  {
5615
5823
  description: "Add a search-records action whose condition pulls its value from the trigger payload using --condition-json.",
5616
- command: `zinkee --json automations actions add automation-1 --type search_records --name "Find duplicates" --target-schema followups --condition-json '{"field":"email","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"payload_value"}}]}'`,
5824
+ 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"}}]}'`,
5617
5825
  raw: `{
5618
5826
  "type": "search_records",
5619
5827
  "name": "Find duplicates",
@@ -5628,7 +5836,7 @@ var specificExamples = {
5628
5836
  "rawValue": null,
5629
5837
  "source": {
5630
5838
  "type": "TRIGGER",
5631
- "id": "payload_value"
5839
+ "id": "f1e1d000-0000-0000-0000-000000000005"
5632
5840
  }
5633
5841
  }
5634
5842
  ]
@@ -6137,7 +6345,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6137
6345
  return buildCommandExamples([
6138
6346
  {
6139
6347
  description: `Add a create-record action with literal and trigger-based mappings targeting ${schemaField.schemaRef}.`,
6140
- 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"}}'`,
6348
+ command: `zinkee --json automations actions add ${automationId} --type create_record --name "Create follow-up order" --target-schema ${schemaField.schemaRef} --map ${schemaField.fieldRef}=pending --map-json owner='{"rawValue":null,"source":{"type":"TRIGGER","id":"${schemaField.fieldId}"}}'`,
6141
6349
  raw: `{
6142
6350
  "type": "create_record",
6143
6351
  "name": "Create follow-up order",
@@ -6152,7 +6360,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6152
6360
  "rawValue": null,
6153
6361
  "source": {
6154
6362
  "type": "TRIGGER",
6155
- "id": "payload_value"
6363
+ "id": "${schemaField.fieldId}"
6156
6364
  }
6157
6365
  }
6158
6366
  }
@@ -6179,7 +6387,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6179
6387
  },
6180
6388
  {
6181
6389
  description: `Add a search-records action with a trigger-based condition on ${schemaField.schemaRef}.`,
6182
- command: `zinkee --json automations actions add ${automationId} --type search_records --name "Find duplicates" --target-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"payload_value"}}]}'`,
6390
+ command: `zinkee --json automations actions add ${automationId} --type search_records --name "Find duplicates" --target-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"${schemaField.fieldId}"}}]}'`,
6183
6391
  raw: `{
6184
6392
  "type": "search_records",
6185
6393
  "name": "Find duplicates",
@@ -6194,7 +6402,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6194
6402
  "rawValue": null,
6195
6403
  "source": {
6196
6404
  "type": "TRIGGER",
6197
- "id": "payload_value"
6405
+ "id": "${schemaField.fieldId}"
6198
6406
  }
6199
6407
  }
6200
6408
  ]
@@ -6392,26 +6600,6 @@ async function getResolvedCommandExamples(commandName, filters = {}, options = {
6392
6600
  function getStdout(stdout) {
6393
6601
  return stdout ?? process.stdout;
6394
6602
  }
6395
- function resolveExampleCommand(tokens) {
6396
- const commands = Object.keys(commandRegistry).sort(
6397
- (left, right) => right.split(" ").length - left.split(" ").length
6398
- );
6399
- for (const commandName of commands) {
6400
- const commandTokens2 = commandName.split(" ");
6401
- const matches = commandTokens2.every((token, index) => tokens[index] === token);
6402
- if (matches) {
6403
- return {
6404
- commandName,
6405
- remainingTokens: tokens.slice(commandTokens2.length)
6406
- };
6407
- }
6408
- }
6409
- const commandTokens = tokens.filter((token) => !token.startsWith("-"));
6410
- return {
6411
- commandName: commandTokens.join(" "),
6412
- remainingTokens: []
6413
- };
6414
- }
6415
6603
  function extractExampleFilters(tokens) {
6416
6604
  const filters = {};
6417
6605
  for (let index = 0; index < tokens.length; index += 1) {
@@ -6451,18 +6639,19 @@ function extractExampleOverrides(tokens) {
6451
6639
  }
6452
6640
  return overrides;
6453
6641
  }
6454
- function extractExampleRequest(argv) {
6455
- const exampleIndex = argv.indexOf("--example");
6456
- if (exampleIndex === -1) {
6642
+ function extractExampleRequest(argv, optionMeta = createDefaultOptionMetadata()) {
6643
+ if (!argv.includes("--example")) {
6457
6644
  return null;
6458
6645
  }
6459
- const requestTokens = argv.slice(exampleIndex + 1);
6460
- const { commandName, remainingTokens } = resolveExampleCommand(requestTokens);
6461
- if (commandName.length === 0) {
6646
+ const userArgs = argv.slice(2);
6647
+ const operands = collectOperandTokens(userArgs, optionMeta, { skipFlag: "--example" });
6648
+ const cmdPath = findCommandPath(operands, commandRegistry);
6649
+ if (!cmdPath) {
6462
6650
  throw new CliError("invalid_cli_usage", 'Provide a command after "--example".');
6463
6651
  }
6652
+ const remainingTokens = userArgs.slice(cmdPath.lastArgvIndex + 1);
6464
6653
  return {
6465
- commandName,
6654
+ commandName: cmdPath.commandName,
6466
6655
  filters: extractExampleFilters(remainingTokens),
6467
6656
  overrides: extractExampleOverrides(argv),
6468
6657
  json: argv.includes("--json")
@@ -9601,6 +9790,12 @@ var RecordsApi = class {
9601
9790
  { method: "DELETE" }
9602
9791
  );
9603
9792
  }
9793
+ clearRecords(schema) {
9794
+ return this.client.requestJson(
9795
+ `/api/v2/schemas/${selectorValue8(schema)}/records:clear`,
9796
+ { method: "DELETE" }
9797
+ );
9798
+ }
9604
9799
  normalizeQueryInput(query) {
9605
9800
  const where = query.where?.map((expression) => ({
9606
9801
  field: expression.field,
@@ -10127,6 +10322,17 @@ function registerRecordsCommands(program, options = {}) {
10127
10322
  }
10128
10323
  writeLine9(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
10129
10324
  });
10325
+ records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema) {
10326
+ const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
10327
+ ensureWritable6("records clear", readOnly, "destructive");
10328
+ const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
10329
+ const data = await api.clearRecords(resolvedSchema);
10330
+ if (json) {
10331
+ emitJson9(stdout, "records clear", data, filePath);
10332
+ return;
10333
+ }
10334
+ writeLine9(stdout, `Cleared all records from schema "${schema.value}".`);
10335
+ });
10130
10336
  }
10131
10337
 
10132
10338
  // src/commands/schemas.ts
@@ -11541,7 +11747,9 @@ async function runCli(argv) {
11541
11747
  process.exitCode = exitCode;
11542
11748
  return;
11543
11749
  }
11544
- const exampleRequest = extractExampleRequest(argv);
11750
+ const program = buildProgram();
11751
+ const optionMeta = buildOptionMetadata(program);
11752
+ const exampleRequest = extractExampleRequest(argv, optionMeta);
11545
11753
  if (exampleRequest) {
11546
11754
  await showExamples(
11547
11755
  exampleRequest.commandName,
@@ -11555,7 +11763,8 @@ async function runCli(argv) {
11555
11763
  );
11556
11764
  throw new ExampleDisplayed();
11557
11765
  }
11558
- await buildProgram().parseAsync(argv);
11766
+ const rewrittenArgv = hoistGlobalOptions(argv, optionMeta, commandRegistry);
11767
+ await program.parseAsync(rewrittenArgv);
11559
11768
  } catch (error) {
11560
11769
  if (error instanceof ExampleDisplayed) {
11561
11770
  process.exitCode = 0;