zinkee 0.1.30 → 0.1.31
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/README.md +24 -0
- package/dist/index.js +138 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/schemas.ts +12 -0
- package/src/command-registry.ts +7 -0
- package/src/commands/schemas.test.ts +112 -0
- package/src/commands/schemas.ts +76 -2
- package/src/utils/examples.ts +81 -1
package/README.md
CHANGED
|
@@ -248,6 +248,30 @@ date_format(44b72f55-3fc3-40f4-88bb-343bb4a6270c, "AAAA-MM")
|
|
|
248
248
|
- Functions: `concat`, `if`, `date_format`, `datetime_diff`, arithmetic (`+`,`-`,`*`,`/`)
|
|
249
249
|
- Invalid formulas are created with status `DRAFT` and evaluate to `null`
|
|
250
250
|
|
|
251
|
+
### Set unique fields
|
|
252
|
+
|
|
253
|
+
Define a composite unique constraint: the listed fields must be unique **together**
|
|
254
|
+
across the schema's records. `--field` accepts a field UUID or slug and is repeatable;
|
|
255
|
+
the order you pass them is the order of the constraint.
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Single field must be unique
|
|
259
|
+
zinkee schemas set-unique-fields contacts --field email
|
|
260
|
+
|
|
261
|
+
# Composite: the (contact-name, notes) combination must be unique
|
|
262
|
+
zinkee schemas set-unique-fields contacts --field contact-name --field notes
|
|
263
|
+
|
|
264
|
+
# Remove the unique constraint
|
|
265
|
+
zinkee schemas set-unique-fields contacts --clear
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Notes:
|
|
269
|
+
|
|
270
|
+
- Pass either one or more `--field`, or `--clear` — not both, and not neither.
|
|
271
|
+
- Every `--field` must already exist in the schema, otherwise the command fails.
|
|
272
|
+
- If existing records already violate the requested constraint, the backend rejects
|
|
273
|
+
it with `409 Conflict`.
|
|
274
|
+
|
|
251
275
|
---
|
|
252
276
|
|
|
253
277
|
## Records
|
package/dist/index.js
CHANGED
|
@@ -667,6 +667,13 @@ var commandRegistry = {
|
|
|
667
667
|
supportsRaw: false,
|
|
668
668
|
output: writeOutput
|
|
669
669
|
},
|
|
670
|
+
"schemas set-unique-fields": {
|
|
671
|
+
command: "schemas set-unique-fields",
|
|
672
|
+
accessLevel: "write",
|
|
673
|
+
supportsExample: true,
|
|
674
|
+
supportsRaw: false,
|
|
675
|
+
output: writeOutput
|
|
676
|
+
},
|
|
670
677
|
"schemas delete": {
|
|
671
678
|
command: "schemas delete",
|
|
672
679
|
accessLevel: "destructive",
|
|
@@ -2417,7 +2424,8 @@ var specificExamples = {
|
|
|
2417
2424
|
"conditionalFormatting": []
|
|
2418
2425
|
}
|
|
2419
2426
|
}
|
|
2420
|
-
]
|
|
2427
|
+
],
|
|
2428
|
+
"uniqueFields": []
|
|
2421
2429
|
}`
|
|
2422
2430
|
},
|
|
2423
2431
|
{
|
|
@@ -2440,6 +2448,79 @@ var specificExamples = {
|
|
|
2440
2448
|
command: "zinkee --json schemas update contacts --highlighted-field contact-name",
|
|
2441
2449
|
raw: `{
|
|
2442
2450
|
"highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
|
|
2451
|
+
}`
|
|
2452
|
+
}
|
|
2453
|
+
]),
|
|
2454
|
+
"schemas set-unique-fields": buildCommandExamples([
|
|
2455
|
+
{
|
|
2456
|
+
description: "Set a composite unique constraint: the listed fields must be unique together across records.",
|
|
2457
|
+
command: "zinkee --json schemas set-unique-fields contacts --field contact-name --field notes",
|
|
2458
|
+
raw: `{
|
|
2459
|
+
"fieldIds": [
|
|
2460
|
+
"c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
2461
|
+
"1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
|
|
2462
|
+
]
|
|
2463
|
+
}`,
|
|
2464
|
+
response: `{
|
|
2465
|
+
"id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
|
|
2466
|
+
"name": "Contacts",
|
|
2467
|
+
"slug": "contacts",
|
|
2468
|
+
"folder": {
|
|
2469
|
+
"id": "7f4e7c25-d8b2-4c1a-9f3e-6a7b5c8d9e1f",
|
|
2470
|
+
"name": "Customers",
|
|
2471
|
+
"isRoot": false
|
|
2472
|
+
},
|
|
2473
|
+
"auditable": true,
|
|
2474
|
+
"commentable": true,
|
|
2475
|
+
"highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
2476
|
+
"fields": [
|
|
2477
|
+
{
|
|
2478
|
+
"id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
2479
|
+
"type": "TextField",
|
|
2480
|
+
"slug": "contact-name",
|
|
2481
|
+
"label": "Customer Name",
|
|
2482
|
+
"required": true,
|
|
2483
|
+
"system": false,
|
|
2484
|
+
"config": {
|
|
2485
|
+
"textType": "NORMAL",
|
|
2486
|
+
"defaultValue": "Unknown",
|
|
2487
|
+
"conditionalFormatting": []
|
|
2488
|
+
}
|
|
2489
|
+
},
|
|
2490
|
+
{
|
|
2491
|
+
"id": "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd",
|
|
2492
|
+
"type": "TextField",
|
|
2493
|
+
"slug": "notes",
|
|
2494
|
+
"label": "Notes",
|
|
2495
|
+
"required": false,
|
|
2496
|
+
"system": false,
|
|
2497
|
+
"config": {
|
|
2498
|
+
"textType": "LONG",
|
|
2499
|
+
"defaultValue": null,
|
|
2500
|
+
"conditionalFormatting": []
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
],
|
|
2504
|
+
"uniqueFields": [
|
|
2505
|
+
"c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
2506
|
+
"1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
|
|
2507
|
+
]
|
|
2508
|
+
}`
|
|
2509
|
+
},
|
|
2510
|
+
{
|
|
2511
|
+
description: "Set a single-field unique constraint.",
|
|
2512
|
+
command: "zinkee --json schemas set-unique-fields contacts --field contact-name",
|
|
2513
|
+
raw: `{
|
|
2514
|
+
"fieldIds": [
|
|
2515
|
+
"c60b8526-5835-4c9f-aecd-9a16c7704a34"
|
|
2516
|
+
]
|
|
2517
|
+
}`
|
|
2518
|
+
},
|
|
2519
|
+
{
|
|
2520
|
+
description: "Clear the unique constraint (no field must be unique anymore).",
|
|
2521
|
+
command: "zinkee --json schemas set-unique-fields contacts --clear",
|
|
2522
|
+
raw: `{
|
|
2523
|
+
"fieldIds": []
|
|
2443
2524
|
}`
|
|
2444
2525
|
}
|
|
2445
2526
|
]),
|
|
@@ -4290,6 +4371,10 @@ var specificExamples = {
|
|
|
4290
4371
|
"conditionalFormatting": []
|
|
4291
4372
|
}
|
|
4292
4373
|
}
|
|
4374
|
+
],
|
|
4375
|
+
"uniqueFields": [
|
|
4376
|
+
"c60b8526-5835-4c9f-aecd-9a16c7704a34",
|
|
4377
|
+
"1d2e3f4a-5b6c-7d8e-9f01-23456789abcd"
|
|
4293
4378
|
]
|
|
4294
4379
|
}`
|
|
4295
4380
|
}
|
|
@@ -10720,6 +10805,12 @@ var SchemasApi = class {
|
|
|
10720
10805
|
jsonOptions7(input, "PATCH")
|
|
10721
10806
|
);
|
|
10722
10807
|
}
|
|
10808
|
+
setUniqueFields(schema, input) {
|
|
10809
|
+
return this.client.requestJson(
|
|
10810
|
+
`/api/v2/schemas/${selectorValue9(schema)}/unique-fields`,
|
|
10811
|
+
jsonOptions7(input, "PUT")
|
|
10812
|
+
);
|
|
10813
|
+
}
|
|
10723
10814
|
deleteSchema(schema) {
|
|
10724
10815
|
return this.client.requestJson(
|
|
10725
10816
|
`/api/v2/schemas/${selectorValue9(schema)}`,
|
|
@@ -11248,6 +11339,9 @@ function parseUuidOrSlugSelector9(input) {
|
|
|
11248
11339
|
throw new InvalidArgumentError9(message);
|
|
11249
11340
|
}
|
|
11250
11341
|
}
|
|
11342
|
+
function collectFieldSelectors(value, previous = []) {
|
|
11343
|
+
return [...previous, parseUuidOrSlugSelector9(value)];
|
|
11344
|
+
}
|
|
11251
11345
|
function parseBooleanFlag(input) {
|
|
11252
11346
|
const normalized = input.trim().toLowerCase();
|
|
11253
11347
|
if (["true", "1", "yes", "y", "on"].includes(normalized)) {
|
|
@@ -11537,6 +11631,49 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
11537
11631
|
}
|
|
11538
11632
|
writeLine11(stdout, `Updated schema "${data.slug ?? schema.value}".`);
|
|
11539
11633
|
});
|
|
11634
|
+
schemas.command("set-unique-fields").description("Set or clear the composite unique-field constraint on a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option(
|
|
11635
|
+
"--field <field>",
|
|
11636
|
+
"field uuid or slug to include in the unique constraint (repeatable)",
|
|
11637
|
+
collectFieldSelectors,
|
|
11638
|
+
[]
|
|
11639
|
+
).option("--clear", "clear the unique constraint (sends an empty field list)").action(async function action(schema, commandOptions) {
|
|
11640
|
+
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
11641
|
+
ensureWritable8("schemas set-unique-fields", readOnly, "write");
|
|
11642
|
+
const selectors = commandOptions.field ?? [];
|
|
11643
|
+
if (commandOptions.clear && selectors.length > 0) {
|
|
11644
|
+
throw new CliError(
|
|
11645
|
+
"invalid_cli_usage",
|
|
11646
|
+
'Use either "--field" or "--clear", not both.'
|
|
11647
|
+
);
|
|
11648
|
+
}
|
|
11649
|
+
if (!commandOptions.clear && selectors.length === 0) {
|
|
11650
|
+
throw new CliError(
|
|
11651
|
+
"invalid_cli_usage",
|
|
11652
|
+
'Provide at least one field via "--field", or pass "--clear" to remove the unique constraint.'
|
|
11653
|
+
);
|
|
11654
|
+
}
|
|
11655
|
+
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
11656
|
+
const resolvedFields = await Promise.all(
|
|
11657
|
+
selectors.map((selector) => resolveFieldSelector(api, resolvedSchema, selector))
|
|
11658
|
+
);
|
|
11659
|
+
const input = {
|
|
11660
|
+
fieldIds: resolvedFields.map((field) => field.value)
|
|
11661
|
+
};
|
|
11662
|
+
const data = await api.setUniqueFields(resolvedSchema, input);
|
|
11663
|
+
if (json) {
|
|
11664
|
+
emitJson11(stdout, "schemas set-unique-fields", data, filePath);
|
|
11665
|
+
return;
|
|
11666
|
+
}
|
|
11667
|
+
if (input.fieldIds.length === 0) {
|
|
11668
|
+
writeLine11(stdout, `Cleared unique fields on schema "${schema.value}".`);
|
|
11669
|
+
return;
|
|
11670
|
+
}
|
|
11671
|
+
const count = input.fieldIds.length;
|
|
11672
|
+
writeLine11(
|
|
11673
|
+
stdout,
|
|
11674
|
+
`Set unique fields on schema "${schema.value}" (${count} field${count === 1 ? "" : "s"}).`
|
|
11675
|
+
);
|
|
11676
|
+
});
|
|
11540
11677
|
schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema) {
|
|
11541
11678
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
11542
11679
|
ensureWritable8("schemas delete", readOnly, "destructive");
|