zinkee 0.1.12 → 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",
@@ -2189,17 +2196,17 @@ var fieldTypeDefinitions = [
2189
2196
  className: "FormulaField",
2190
2197
  aliases: ["formula", "FormulaField"],
2191
2198
  description: "Calculated field from a formula.",
2192
- 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"}}',
2193
2200
  examplePayloads: [
2194
2201
  {
2195
2202
  name: "Formula field (none)",
2196
2203
  payload: {
2197
2204
  type: "FormulaField",
2198
- slug: "formula-summary",
2199
- label: "Formula Summary",
2205
+ slug: "formula-code",
2206
+ label: "Formula Code",
2200
2207
  required: false,
2201
2208
  config: {
2202
- formulaText: "concat(firstName, ' ', lastName)",
2209
+ formulaText: 'concat("CUST-", f1e1d000-0000-0000-0000-000000000005)',
2203
2210
  uiFormatKind: "none",
2204
2211
  status: "ACTIVE",
2205
2212
  conditionalFormatting: []
@@ -2214,7 +2221,7 @@ var fieldTypeDefinitions = [
2214
2221
  label: "Formula Total",
2215
2222
  required: false,
2216
2223
  config: {
2217
- formulaText: "amount * 1.21",
2224
+ formulaText: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
2218
2225
  uiFormatKind: "number",
2219
2226
  status: "ACTIVE",
2220
2227
  numberFormatOptions: {
@@ -2230,11 +2237,11 @@ var fieldTypeDefinitions = [
2230
2237
  name: "Formula field (date)",
2231
2238
  payload: {
2232
2239
  type: "FormulaField",
2233
- slug: "formula-deadline",
2234
- label: "Computed Deadline",
2240
+ slug: "formula-period",
2241
+ label: "Formula Period",
2235
2242
  required: false,
2236
2243
  config: {
2237
- formulaText: "addDays(startDate, 7)",
2244
+ formulaText: 'date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")',
2238
2245
  uiFormatKind: "date",
2239
2246
  status: "ACTIVE",
2240
2247
  dateFormatOptions: {
@@ -2254,7 +2261,7 @@ var fieldTypeDefinitions = [
2254
2261
  label: "Computed Assignee",
2255
2262
  required: false,
2256
2263
  config: {
2257
- formulaText: "manager",
2264
+ formulaText: "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
2258
2265
  uiFormatKind: "member",
2259
2266
  status: "ACTIVE",
2260
2267
  conditionalFormatting: []
@@ -2991,11 +2998,11 @@ var specificExamples = {
2991
2998
  },
2992
2999
  {
2993
3000
  description: "Patch formula field (formula text).",
2994
- command: `zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"amount * 1.10","uiFormatKind":"number","status":"ACTIVE","numberFormatOptions":{"format":"number","decimals":2,"thousandsSeparator":true},"conditionalFormatting":[]}}'`,
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":[]}}'`,
2995
3002
  raw: `{
2996
3003
  "type": "FormulaField",
2997
3004
  "config": {
2998
- "formulaText": "amount * 1.10",
3005
+ "formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.10",
2999
3006
  "uiFormatKind": "number",
3000
3007
  "status": "ACTIVE",
3001
3008
  "numberFormatOptions": {
@@ -3906,8 +3913,8 @@ var specificExamples = {
3906
3913
  }`
3907
3914
  },
3908
3915
  {
3909
- description: "Create a bar CHART widget with a time-serie x-axis and two y-axis series.",
3910
- command: `zinkee --json displays widgets create 0f6f062f-1478-4df2-96a1-c495d037d260 --type CHART --name "Revenue by month" --origin-resource 2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e --layout '{"x":0,"y":0,"w":8,"h":6}' --chart-type bar --x-axis-field due-date --x-axis-date-format MONTH --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#4B9CD3","axisType":"BAR"}' --y-axis-serie '{"typeCalc":"COUNT","fieldCalc":"id","color":"#E57373","axisType":"LINE"}' --legend '{"position":"bottom"}'`,
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"}'`,
3911
3918
  raw: `{
3912
3919
  "type": "CHART",
3913
3920
  "source": {
@@ -3919,7 +3926,7 @@ var specificExamples = {
3919
3926
  },
3920
3927
  "presentation": { "name": "Revenue by month" },
3921
3928
  "chart": {
3922
- "chartType": "bar",
3929
+ "chartType": "bars",
3923
3930
  "xAxisFieldId": "due-date",
3924
3931
  "xAxisDateFormat": "MONTH",
3925
3932
  "xAxisAsTimeSerie": true,
@@ -3928,13 +3935,13 @@ var specificExamples = {
3928
3935
  "typeCalc": "SUM",
3929
3936
  "fieldCalc": "amount",
3930
3937
  "color": "#4B9CD3",
3931
- "axisType": "BAR"
3938
+ "axisType": "PRIMARY"
3932
3939
  },
3933
3940
  {
3934
3941
  "typeCalc": "COUNT",
3935
3942
  "fieldCalc": "id",
3936
3943
  "color": "#E57373",
3937
- "axisType": "LINE"
3944
+ "axisType": "SECONDARY"
3938
3945
  }
3939
3946
  ],
3940
3947
  "legend": { "position": "bottom" }
@@ -4080,11 +4087,11 @@ var specificExamples = {
4080
4087
  }`
4081
4088
  },
4082
4089
  {
4083
- description: "Replace the chart series with a weekly line.",
4084
- command: `zinkee --json displays widgets update 0f6f062f-1478-4df2-96a1-c495d037d260 22222222-2222-4222-a222-222222222222 --chart-type line --x-axis-field due-date --x-axis-date-format WEEK --x-axis-time-series --y-axis-serie '{"typeCalc":"SUM","fieldCalc":"amount","color":"#2E7D32","axisType":"LINE"}'`,
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"}'`,
4085
4092
  raw: `{
4086
4093
  "chart": {
4087
- "chartType": "line",
4094
+ "chartType": "lines",
4088
4095
  "xAxisFieldId": "due-date",
4089
4096
  "xAxisDateFormat": "WEEK",
4090
4097
  "xAxisAsTimeSerie": true,
@@ -4093,7 +4100,7 @@ var specificExamples = {
4093
4100
  "typeCalc": "SUM",
4094
4101
  "fieldCalc": "amount",
4095
4102
  "color": "#2E7D32",
4096
- "axisType": "LINE"
4103
+ "axisType": "PRIMARY"
4097
4104
  }
4098
4105
  ]
4099
4106
  }
@@ -4421,7 +4428,7 @@ var specificExamples = {
4421
4428
  "required": false,
4422
4429
  "system": false,
4423
4430
  "config": {
4424
- "formulaText": "amount * 1.21",
4431
+ "formulaText": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043 * 1.21",
4425
4432
  "uiFormatKind": "number",
4426
4433
  "status": "ACTIVE",
4427
4434
  "defaultValue": null,
@@ -4436,12 +4443,12 @@ var specificExamples = {
4436
4443
  {
4437
4444
  "id": "6d7e8f90-1234-5678-9abc-def012345678",
4438
4445
  "type": "FormulaField",
4439
- "slug": "formula-deadline",
4440
- "label": "Computed Deadline",
4446
+ "slug": "formula-period",
4447
+ "label": "Formula Period",
4441
4448
  "required": false,
4442
4449
  "system": false,
4443
4450
  "config": {
4444
- "formulaText": "addDays(startDate, 7)",
4451
+ "formulaText": "date_format(d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90, "AAAA-MM")",
4445
4452
  "uiFormatKind": "date",
4446
4453
  "status": "ACTIVE",
4447
4454
  "defaultValue": null,
@@ -4723,6 +4730,16 @@ var specificExamples = {
4723
4730
  response: `{
4724
4731
  "recordId": "550e8400-e29b-41d4-a716-446655440000",
4725
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
4726
4743
  }`
4727
4744
  }
4728
4745
  ]),
@@ -5804,7 +5821,7 @@ var specificExamples = {
5804
5821
  },
5805
5822
  {
5806
5823
  description: "Add a search-records action whose condition pulls its value from the trigger payload using --condition-json.",
5807
- command: `zinkee --json automations actions add automation-1 --type search_records --name "Find duplicates" --target-schema followups --condition-json '{"field":"email","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"payload_value"}}]}'`,
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"}}]}'`,
5808
5825
  raw: `{
5809
5826
  "type": "search_records",
5810
5827
  "name": "Find duplicates",
@@ -5819,7 +5836,7 @@ var specificExamples = {
5819
5836
  "rawValue": null,
5820
5837
  "source": {
5821
5838
  "type": "TRIGGER",
5822
- "id": "payload_value"
5839
+ "id": "f1e1d000-0000-0000-0000-000000000005"
5823
5840
  }
5824
5841
  }
5825
5842
  ]
@@ -6328,7 +6345,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6328
6345
  return buildCommandExamples([
6329
6346
  {
6330
6347
  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"}}'`,
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}"}}'`,
6332
6349
  raw: `{
6333
6350
  "type": "create_record",
6334
6351
  "name": "Create follow-up order",
@@ -6343,7 +6360,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6343
6360
  "rawValue": null,
6344
6361
  "source": {
6345
6362
  "type": "TRIGGER",
6346
- "id": "payload_value"
6363
+ "id": "${schemaField.fieldId}"
6347
6364
  }
6348
6365
  }
6349
6366
  }
@@ -6370,7 +6387,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6370
6387
  },
6371
6388
  {
6372
6389
  description: `Add a search-records action with a trigger-based condition on ${schemaField.schemaRef}.`,
6373
- command: `zinkee --json automations actions add ${automationId} --type search_records --name "Find duplicates" --target-schema ${schemaField.schemaRef} --condition-json '{"field":"${schemaField.fieldRef}","comparator":"eq","values":[{"rawValue":null,"source":{"type":"TRIGGER","id":"payload_value"}}]}'`,
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}"}}]}'`,
6374
6391
  raw: `{
6375
6392
  "type": "search_records",
6376
6393
  "name": "Find duplicates",
@@ -6385,7 +6402,7 @@ async function buildDynamicAutomationExamples(commandName, options = {}) {
6385
6402
  "rawValue": null,
6386
6403
  "source": {
6387
6404
  "type": "TRIGGER",
6388
- "id": "payload_value"
6405
+ "id": "${schemaField.fieldId}"
6389
6406
  }
6390
6407
  }
6391
6408
  ]
@@ -9773,6 +9790,12 @@ var RecordsApi = class {
9773
9790
  { method: "DELETE" }
9774
9791
  );
9775
9792
  }
9793
+ clearRecords(schema) {
9794
+ return this.client.requestJson(
9795
+ `/api/v2/schemas/${selectorValue8(schema)}/records:clear`,
9796
+ { method: "DELETE" }
9797
+ );
9798
+ }
9776
9799
  normalizeQueryInput(query) {
9777
9800
  const where = query.where?.map((expression) => ({
9778
9801
  field: expression.field,
@@ -10299,6 +10322,17 @@ function registerRecordsCommands(program, options = {}) {
10299
10322
  }
10300
10323
  writeLine9(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
10301
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
+ });
10302
10336
  }
10303
10337
 
10304
10338
  // src/commands/schemas.ts