zinkee 0.1.31 → 0.1.33
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 +5 -2
- package/dist/index.js +97 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/records.ts +4 -4
- package/src/commands/records.test.ts +135 -1
- package/src/commands/records.ts +84 -10
- package/src/commands/schemas.ts +13 -2
- package/src/utils/examples.ts +20 -4
package/README.md
CHANGED
|
@@ -299,8 +299,11 @@ zinkee --json records get projects <record-uuid>
|
|
|
299
299
|
# Update
|
|
300
300
|
zinkee records update projects <record-uuid> --set status=2
|
|
301
301
|
|
|
302
|
-
# Delete
|
|
303
|
-
zinkee records delete projects <record-uuid>
|
|
302
|
+
# Delete one or more records (--record is repeatable)
|
|
303
|
+
zinkee records delete projects --record <record-uuid> --record <record-uuid>
|
|
304
|
+
|
|
305
|
+
# Delete many records listing one uuid per line in a file (merged with --record, de-duplicated)
|
|
306
|
+
zinkee records delete projects --records-file ./record-ids.txt
|
|
304
307
|
|
|
305
308
|
# Clear all records from a schema (destructive — irreversible)
|
|
306
309
|
zinkee records clear projects
|
package/dist/index.js
CHANGED
|
@@ -2444,7 +2444,7 @@ var specificExamples = {
|
|
|
2444
2444
|
}`
|
|
2445
2445
|
},
|
|
2446
2446
|
{
|
|
2447
|
-
description: "Set the highlighted (main) field
|
|
2447
|
+
description: "Set the schema's highlighted (main) field \u2014 the field whose value names each record in the UI (activity-panel title and detail-view record list).",
|
|
2448
2448
|
command: "zinkee --json schemas update contacts --highlighted-field contact-name",
|
|
2449
2449
|
raw: `{
|
|
2450
2450
|
"highlightedField": "c60b8526-5835-4c9f-aecd-9a16c7704a34"
|
|
@@ -4533,10 +4533,24 @@ var specificExamples = {
|
|
|
4533
4533
|
]),
|
|
4534
4534
|
"records delete": buildCommandExamples([
|
|
4535
4535
|
{
|
|
4536
|
-
description: "Delete
|
|
4537
|
-
command: `zinkee --json records delete contacts
|
|
4536
|
+
description: "Delete one or more records by id (--record is repeatable).",
|
|
4537
|
+
command: `zinkee --json records delete contacts --record 550e8400-e29b-41d4-a716-446655440000 --record 6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d`,
|
|
4538
4538
|
response: `{
|
|
4539
|
-
"
|
|
4539
|
+
"recordIds": [
|
|
4540
|
+
"550e8400-e29b-41d4-a716-446655440000",
|
|
4541
|
+
"6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
|
|
4542
|
+
],
|
|
4543
|
+
"deleted": true
|
|
4544
|
+
}`
|
|
4545
|
+
},
|
|
4546
|
+
{
|
|
4547
|
+
description: "Delete many records listing one uuid per line in a file (merged with any --record flags and de-duplicated).",
|
|
4548
|
+
command: `zinkee --json records delete contacts --records-file ./record-ids.txt`,
|
|
4549
|
+
response: `{
|
|
4550
|
+
"recordIds": [
|
|
4551
|
+
"550e8400-e29b-41d4-a716-446655440000",
|
|
4552
|
+
"6c8a3e0d-4e5f-4a1b-9c2d-3e4f5a6b7c8d"
|
|
4553
|
+
],
|
|
4540
4554
|
"deleted": true
|
|
4541
4555
|
}`
|
|
4542
4556
|
}
|
|
@@ -10733,10 +10747,10 @@ var RecordsApi = class {
|
|
|
10733
10747
|
jsonOptions6(input, "PATCH")
|
|
10734
10748
|
);
|
|
10735
10749
|
}
|
|
10736
|
-
|
|
10750
|
+
deleteRecords(schema, recordIds) {
|
|
10737
10751
|
return this.client.requestJson(
|
|
10738
|
-
`/api/v2/schemas/${selectorValue8(schema)}/records
|
|
10739
|
-
{
|
|
10752
|
+
`/api/v2/schemas/${selectorValue8(schema)}/records:delete`,
|
|
10753
|
+
jsonOptions6({ recordIds }, "POST")
|
|
10740
10754
|
);
|
|
10741
10755
|
}
|
|
10742
10756
|
clearRecords(schema) {
|
|
@@ -10960,6 +10974,61 @@ function parseJsonKeyValueAssignment(input) {
|
|
|
10960
10974
|
function dedupeStrings(values) {
|
|
10961
10975
|
return [...new Set(values)];
|
|
10962
10976
|
}
|
|
10977
|
+
function toRecordUuid(value) {
|
|
10978
|
+
try {
|
|
10979
|
+
const normalized = normalizeUuidOrSlug(value);
|
|
10980
|
+
return normalized.kind === "uuid" ? normalized.value : null;
|
|
10981
|
+
} catch {
|
|
10982
|
+
return null;
|
|
10983
|
+
}
|
|
10984
|
+
}
|
|
10985
|
+
function collectRecordIds(value, previous = []) {
|
|
10986
|
+
const uuid = toRecordUuid(value.trim());
|
|
10987
|
+
if (!uuid) {
|
|
10988
|
+
throw new InvalidArgumentError8(`Expected a record UUID, received "${value}".`);
|
|
10989
|
+
}
|
|
10990
|
+
return [...previous, uuid];
|
|
10991
|
+
}
|
|
10992
|
+
function readRecordIdsFromFile(path) {
|
|
10993
|
+
let contents;
|
|
10994
|
+
try {
|
|
10995
|
+
contents = readFileSync8(path, "utf8");
|
|
10996
|
+
} catch (error) {
|
|
10997
|
+
const message = error instanceof Error ? error.message : "Unable to read file.";
|
|
10998
|
+
throw new CliError(
|
|
10999
|
+
"invalid_cli_usage",
|
|
11000
|
+
`Failed to read record ids from ${path}: ${message}`
|
|
11001
|
+
);
|
|
11002
|
+
}
|
|
11003
|
+
const ids = [];
|
|
11004
|
+
contents.split(/\r?\n/).forEach((line, index) => {
|
|
11005
|
+
const value = line.trim();
|
|
11006
|
+
if (!value) {
|
|
11007
|
+
return;
|
|
11008
|
+
}
|
|
11009
|
+
const uuid = toRecordUuid(value);
|
|
11010
|
+
if (!uuid) {
|
|
11011
|
+
throw new CliError(
|
|
11012
|
+
"invalid_cli_usage",
|
|
11013
|
+
`Invalid record UUID "${value}" at ${path}:${index + 1}.`
|
|
11014
|
+
);
|
|
11015
|
+
}
|
|
11016
|
+
ids.push(uuid);
|
|
11017
|
+
});
|
|
11018
|
+
return ids;
|
|
11019
|
+
}
|
|
11020
|
+
function resolveDeleteRecordIds(options) {
|
|
11021
|
+
const flagIds = options.record ?? [];
|
|
11022
|
+
const fileIds = options.recordsFile ? readRecordIdsFromFile(options.recordsFile) : [];
|
|
11023
|
+
const recordIds = dedupeStrings([...flagIds, ...fileIds]);
|
|
11024
|
+
if (recordIds.length === 0) {
|
|
11025
|
+
throw new CliError(
|
|
11026
|
+
"invalid_cli_usage",
|
|
11027
|
+
'Provide at least one record id via "--record <uuid>" (repeatable) or "--records-file <path>".'
|
|
11028
|
+
);
|
|
11029
|
+
}
|
|
11030
|
+
return recordIds;
|
|
11031
|
+
}
|
|
10963
11032
|
function collectStringValues(value, previous = []) {
|
|
10964
11033
|
return [...previous, value];
|
|
10965
11034
|
}
|
|
@@ -11234,21 +11303,23 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11234
11303
|
}
|
|
11235
11304
|
writeLine10(stdout, `Updated record "${getRecordIdentifier(data)}".`);
|
|
11236
11305
|
});
|
|
11237
|
-
records.command("delete").description("Delete
|
|
11306
|
+
records.command("delete").description("Delete one or more records").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--record <uuid>", "record uuid to delete (repeatable)", collectRecordIds, []).option(
|
|
11307
|
+
"--records-file <path>",
|
|
11308
|
+
"path to a file with one record uuid per line (merged with --record)"
|
|
11309
|
+
).action(async function action(schema, commandOptions) {
|
|
11238
11310
|
const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
|
|
11239
11311
|
ensureWritable7("records delete", readOnly, "destructive");
|
|
11312
|
+
const recordIds = resolveDeleteRecordIds(commandOptions);
|
|
11240
11313
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11241
|
-
await api.
|
|
11242
|
-
const data = {
|
|
11243
|
-
schema: resolvedSchema.value,
|
|
11244
|
-
record: record.value,
|
|
11245
|
-
deleted: true
|
|
11246
|
-
};
|
|
11314
|
+
const data = await api.deleteRecords(resolvedSchema, recordIds);
|
|
11247
11315
|
if (json) {
|
|
11248
11316
|
emitJson10(stdout, "records delete", data, filePath);
|
|
11249
11317
|
return;
|
|
11250
11318
|
}
|
|
11251
|
-
writeLine10(
|
|
11319
|
+
writeLine10(
|
|
11320
|
+
stdout,
|
|
11321
|
+
`Deleted ${recordIds.length} record(s) from schema "${schema.value}".`
|
|
11322
|
+
);
|
|
11252
11323
|
});
|
|
11253
11324
|
records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
|
|
11254
11325
|
const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
|
|
@@ -11266,6 +11337,15 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11266
11337
|
// src/commands/schemas.ts
|
|
11267
11338
|
import { readFileSync as readFileSync9 } from "fs";
|
|
11268
11339
|
import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
|
|
11340
|
+
var HIGHLIGHTED_FIELD_HELP = `
|
|
11341
|
+
Highlighted field:
|
|
11342
|
+
The schema's "main" field. The frontend uses its value as each record's
|
|
11343
|
+
display name, in two places:
|
|
11344
|
+
- Activity panel: the record's title in the activity side panel
|
|
11345
|
+
(the panel with the record's logs and comments).
|
|
11346
|
+
- Detail view: the record's name in the left-hand record list you
|
|
11347
|
+
browse to open each record's form.
|
|
11348
|
+
`;
|
|
11269
11349
|
function getCommandIo11(stdout) {
|
|
11270
11350
|
return stdout ?? process.stdout;
|
|
11271
11351
|
}
|
|
@@ -11603,7 +11683,7 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
11603
11683
|
});
|
|
11604
11684
|
schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option("--name <name>", "schema name").option("--slug <slug>", "schema slug").option("--auditable <bool>", "auditable flag", parseBooleanFlag).option("--commentable <bool>", "commentable flag", parseBooleanFlag).option(
|
|
11605
11685
|
"--highlighted-field <field>",
|
|
11606
|
-
"
|
|
11686
|
+
"its value is used as each record's display name in the UI (field uuid or slug)",
|
|
11607
11687
|
parseUuidOrSlugSelector9
|
|
11608
11688
|
).action(async function action(schema, commandOptions) {
|
|
11609
11689
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
@@ -11630,7 +11710,7 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
11630
11710
|
return;
|
|
11631
11711
|
}
|
|
11632
11712
|
writeLine11(stdout, `Updated schema "${data.slug ?? schema.value}".`);
|
|
11633
|
-
});
|
|
11713
|
+
}).addHelpText("after", HIGHLIGHTED_FIELD_HELP);
|
|
11634
11714
|
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
11715
|
"--field <field>",
|
|
11636
11716
|
"field uuid or slug to include in the unique constraint (repeatable)",
|