zinkee 0.1.41 → 0.1.43
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 +1 -0
- package/README.md +31 -2
- package/dist/index.js +506 -192
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/displays.ts +14 -2
- package/src/api/formulas.test.ts +65 -0
- package/src/api/formulas.ts +67 -0
- package/src/api/schemas.ts +3 -0
- package/src/command-registry.ts +21 -0
- package/src/commands/displays.test.ts +99 -0
- package/src/commands/displays.ts +19 -3
- package/src/commands/formulas.test.ts +194 -0
- package/src/commands/formulas.ts +243 -0
- package/src/commands/schemas.test.ts +89 -0
- package/src/commands/schemas.ts +13 -1
- package/src/program.ts +2 -0
- package/src/utils/examples.ts +110 -5
package/dist/index.js
CHANGED
|
@@ -9,6 +9,27 @@ import chalk from "chalk";
|
|
|
9
9
|
var readOutput = "table-json";
|
|
10
10
|
var writeOutput = "json-only";
|
|
11
11
|
var commandRegistry = {
|
|
12
|
+
"formulas recompute field": {
|
|
13
|
+
command: "formulas recompute field",
|
|
14
|
+
accessLevel: "write",
|
|
15
|
+
supportsExample: true,
|
|
16
|
+
supportsRaw: false,
|
|
17
|
+
output: writeOutput
|
|
18
|
+
},
|
|
19
|
+
"formulas recompute schema": {
|
|
20
|
+
command: "formulas recompute schema",
|
|
21
|
+
accessLevel: "write",
|
|
22
|
+
supportsExample: true,
|
|
23
|
+
supportsRaw: false,
|
|
24
|
+
output: writeOutput
|
|
25
|
+
},
|
|
26
|
+
"formulas recompute workspace": {
|
|
27
|
+
command: "formulas recompute workspace",
|
|
28
|
+
accessLevel: "write",
|
|
29
|
+
supportsExample: true,
|
|
30
|
+
supportsRaw: false,
|
|
31
|
+
output: writeOutput
|
|
32
|
+
},
|
|
12
33
|
"config path": {
|
|
13
34
|
command: "config path",
|
|
14
35
|
accessLevel: "read",
|
|
@@ -2229,6 +2250,60 @@ function buildCommandExamples(examples) {
|
|
|
2229
2250
|
}
|
|
2230
2251
|
var SAMPLE_UUID = "550e8400-e29b-41d4-a716-446655440001";
|
|
2231
2252
|
var specificExamples = {
|
|
2253
|
+
"formulas recompute field": buildCommandExamples([
|
|
2254
|
+
{
|
|
2255
|
+
description: "Queue a full recalculation of one formula column.",
|
|
2256
|
+
command: "zinkee --json formulas recompute field invoices total",
|
|
2257
|
+
raw: `{
|
|
2258
|
+
"scope": "FIELD",
|
|
2259
|
+
"schema": "invoices",
|
|
2260
|
+
"field": "total"
|
|
2261
|
+
}`,
|
|
2262
|
+
response: `{
|
|
2263
|
+
"requestId": "02ab5d47-cb5f-4eb2-afb8-e9a3a9eb34d4",
|
|
2264
|
+
"scope": "FIELD",
|
|
2265
|
+
"formulaCount": 1,
|
|
2266
|
+
"skippedFormulaCount": 0,
|
|
2267
|
+
"eventsQueued": 1,
|
|
2268
|
+
"status": "QUEUED"
|
|
2269
|
+
}`
|
|
2270
|
+
}
|
|
2271
|
+
]),
|
|
2272
|
+
"formulas recompute schema": buildCommandExamples([
|
|
2273
|
+
{
|
|
2274
|
+
description: "Queue recalculation of every active formula in one schema.",
|
|
2275
|
+
command: "zinkee --json formulas recompute schema invoices --yes",
|
|
2276
|
+
raw: `{
|
|
2277
|
+
"scope": "SCHEMA",
|
|
2278
|
+
"schema": "invoices"
|
|
2279
|
+
}`,
|
|
2280
|
+
response: `{
|
|
2281
|
+
"requestId": "02ab5d47-cb5f-4eb2-afb8-e9a3a9eb34d4",
|
|
2282
|
+
"scope": "SCHEMA",
|
|
2283
|
+
"formulaCount": 8,
|
|
2284
|
+
"skippedFormulaCount": 1,
|
|
2285
|
+
"eventsQueued": 8,
|
|
2286
|
+
"status": "QUEUED"
|
|
2287
|
+
}`
|
|
2288
|
+
}
|
|
2289
|
+
]),
|
|
2290
|
+
"formulas recompute workspace": buildCommandExamples([
|
|
2291
|
+
{
|
|
2292
|
+
description: "Queue recalculation of every active formula in the workspace.",
|
|
2293
|
+
command: "zinkee --json formulas recompute workspace --yes",
|
|
2294
|
+
raw: `{
|
|
2295
|
+
"scope": "WORKSPACE"
|
|
2296
|
+
}`,
|
|
2297
|
+
response: `{
|
|
2298
|
+
"requestId": "02ab5d47-cb5f-4eb2-afb8-e9a3a9eb34d4",
|
|
2299
|
+
"scope": "WORKSPACE",
|
|
2300
|
+
"formulaCount": 24,
|
|
2301
|
+
"skippedFormulaCount": 2,
|
|
2302
|
+
"eventsQueued": 24,
|
|
2303
|
+
"status": "QUEUED"
|
|
2304
|
+
}`
|
|
2305
|
+
}
|
|
2306
|
+
]),
|
|
2232
2307
|
"profiles list": buildCommandExamples([
|
|
2233
2308
|
{
|
|
2234
2309
|
description: "List all local profiles. The CLI always redacts the apiKey to ******** plus the last 4 chars.",
|
|
@@ -2536,6 +2611,20 @@ var specificExamples = {
|
|
|
2536
2611
|
}
|
|
2537
2612
|
]),
|
|
2538
2613
|
"schemas fields update": buildCommandExamples([
|
|
2614
|
+
{
|
|
2615
|
+
description: "Set the field description without changing its label or configuration.",
|
|
2616
|
+
command: 'zinkee --json schemas fields update contacts contact-name --description "Primary name shown for the customer"',
|
|
2617
|
+
raw: `{
|
|
2618
|
+
"description": "Primary name shown for the customer"
|
|
2619
|
+
}`
|
|
2620
|
+
},
|
|
2621
|
+
{
|
|
2622
|
+
description: "Clear the field description.",
|
|
2623
|
+
command: 'zinkee --json schemas fields update contacts contact-name --description ""',
|
|
2624
|
+
raw: `{
|
|
2625
|
+
"description": ""
|
|
2626
|
+
}`
|
|
2627
|
+
},
|
|
2539
2628
|
{
|
|
2540
2629
|
description: "Rename slug and label.",
|
|
2541
2630
|
command: `zinkee --json schemas fields update contacts contact-name --label "Customer Full Name" --raw '{"slug":"customer-full-name"}'`,
|
|
@@ -3305,10 +3394,11 @@ var specificExamples = {
|
|
|
3305
3394
|
]),
|
|
3306
3395
|
"displays create": buildCommandExamples([
|
|
3307
3396
|
{
|
|
3308
|
-
description: "Create a freeform display with an initial widget layout. Freeform layouts travel through --freeform-layouts.",
|
|
3309
|
-
command: `zinkee --json displays create --name "Control Proyecto Freeform" --template freeform --freeform-layouts '{"lg":[{"i":"widget-1","x":0,"y":0,"w":6,"h":5}]}'`,
|
|
3397
|
+
description: "Create a described freeform display with an initial widget layout. Freeform layouts travel through --freeform-layouts.",
|
|
3398
|
+
command: `zinkee --json displays create --name "Control Proyecto Freeform" --description "Project delivery overview" --template freeform --freeform-layouts '{"lg":[{"i":"widget-1","x":0,"y":0,"w":6,"h":5}]}'`,
|
|
3310
3399
|
raw: `{
|
|
3311
3400
|
"name": "Control Proyecto Freeform",
|
|
3401
|
+
"description": "Project delivery overview",
|
|
3312
3402
|
"layout": {
|
|
3313
3403
|
"template": "freeform",
|
|
3314
3404
|
"freeformLayouts": {
|
|
@@ -5145,6 +5235,20 @@ var specificExamples = {
|
|
|
5145
5235
|
}
|
|
5146
5236
|
]),
|
|
5147
5237
|
"displays update": buildCommandExamples([
|
|
5238
|
+
{
|
|
5239
|
+
description: "Update only the display description.",
|
|
5240
|
+
command: 'zinkee --json displays update 0f6f062f-1478-4df2-96a1-c495d037d260 --description "Sales pipeline overview"',
|
|
5241
|
+
raw: `{
|
|
5242
|
+
"description": "Sales pipeline overview"
|
|
5243
|
+
}`
|
|
5244
|
+
},
|
|
5245
|
+
{
|
|
5246
|
+
description: "Clear the display description.",
|
|
5247
|
+
command: 'zinkee --json displays update 0f6f062f-1478-4df2-96a1-c495d037d260 --description ""',
|
|
5248
|
+
raw: `{
|
|
5249
|
+
"description": ""
|
|
5250
|
+
}`
|
|
5251
|
+
},
|
|
5148
5252
|
{
|
|
5149
5253
|
description: "Rename a display (patch of top-level metadata only).",
|
|
5150
5254
|
command: 'zinkee --json displays update 0f6f062f-1478-4df2-96a1-c495d037d260 --name "Pipeline overview (renamed)"',
|
|
@@ -6441,8 +6545,21 @@ function buildSchemaFieldCreateExamples(type) {
|
|
|
6441
6545
|
const flat = filteredDefinitions.flatMap(
|
|
6442
6546
|
(definition) => definition.examplePayloads.map((example) => ({ definition, example }))
|
|
6443
6547
|
);
|
|
6444
|
-
|
|
6445
|
-
|
|
6548
|
+
const flagExamples = selectedDefinition === void 0 || selectedDefinition.key === "text" ? [
|
|
6549
|
+
{
|
|
6550
|
+
description: "Text field with a description.",
|
|
6551
|
+
command: 'zinkee --json schemas fields create contacts --type text --slug customer-name --label "Customer Name" --description "Primary name shown for the customer"',
|
|
6552
|
+
raw: `{
|
|
6553
|
+
"type": "TextField",
|
|
6554
|
+
"slug": "customer-name",
|
|
6555
|
+
"label": "Customer Name",
|
|
6556
|
+
"description": "Primary name shown for the customer"
|
|
6557
|
+
}`
|
|
6558
|
+
}
|
|
6559
|
+
] : [];
|
|
6560
|
+
return buildCommandExamples([
|
|
6561
|
+
...flagExamples,
|
|
6562
|
+
...flat.map(({ example }, index) => {
|
|
6446
6563
|
const slug = typeof example.payload.slug === "string" ? example.payload.slug : "field";
|
|
6447
6564
|
const command = `zinkee --json schemas fields create contacts --raw '${JSON.stringify(example.payload)}'`;
|
|
6448
6565
|
if (index === 0) {
|
|
@@ -6461,7 +6578,7 @@ function buildSchemaFieldCreateExamples(type) {
|
|
|
6461
6578
|
command
|
|
6462
6579
|
};
|
|
6463
6580
|
})
|
|
6464
|
-
);
|
|
6581
|
+
]);
|
|
6465
6582
|
}
|
|
6466
6583
|
function getCommandExamples(commandName, filters = {}) {
|
|
6467
6584
|
const examples = commandName === "schemas fields create" ? buildSchemaFieldCreateExamples(filters.type) : specificExamples[commandName] ?? fallbackExamples(commandName);
|
|
@@ -6573,7 +6690,7 @@ ${index + 1}. ${example.description}
|
|
|
6573
6690
|
|
|
6574
6691
|
// src/program.ts
|
|
6575
6692
|
import { createRequire } from "module";
|
|
6576
|
-
import { Command as
|
|
6693
|
+
import { Command as Command12 } from "commander";
|
|
6577
6694
|
|
|
6578
6695
|
// src/config.ts
|
|
6579
6696
|
import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -9572,7 +9689,7 @@ function registerDisplaysCommands(program, options = {}) {
|
|
|
9572
9689
|
}
|
|
9573
9690
|
printTable([{ id: data.id, name: data.name ?? "", layoutTemplate: data.layout?.template ?? "" }], ["id", "name", "layoutTemplate"], stdout);
|
|
9574
9691
|
});
|
|
9575
|
-
displays.command("create").description("Create a display").requiredOption("--name <name>", "display name").requiredOption("--template <template>", "layout template").option("--freeform-layouts <json>", "freeform layouts JSON").option("--freeform-layouts-file <path>", "freeform layouts JSON file").action(async function action(commandOptions) {
|
|
9692
|
+
displays.command("create").description("Create a display").requiredOption("--name <name>", "display name").option("--description <text>", "display description").requiredOption("--template <template>", "layout template").option("--freeform-layouts <json>", "freeform layouts JSON").option("--freeform-layouts-file <path>", "freeform layouts JSON file").action(async function action(commandOptions) {
|
|
9576
9693
|
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
9577
9694
|
ensureWritable3("displays create", readOnly, "write");
|
|
9578
9695
|
const layout2 = { template: commandOptions.template };
|
|
@@ -9583,18 +9700,30 @@ function registerDisplaysCommands(program, options = {}) {
|
|
|
9583
9700
|
"--freeform-layouts-file"
|
|
9584
9701
|
);
|
|
9585
9702
|
if (freeformLayouts !== void 0) layout2.freeformLayouts = freeformLayouts;
|
|
9586
|
-
const data = await api.createDisplay({
|
|
9703
|
+
const data = await api.createDisplay({
|
|
9704
|
+
name: commandOptions.name,
|
|
9705
|
+
description: commandOptions.description,
|
|
9706
|
+
layout: layout2
|
|
9707
|
+
});
|
|
9587
9708
|
if (json) {
|
|
9588
9709
|
emitJson4(stdout, "displays create", data);
|
|
9589
9710
|
return;
|
|
9590
9711
|
}
|
|
9591
9712
|
writeLine4(stdout, `Created display "${commandOptions.name}".`);
|
|
9592
9713
|
});
|
|
9593
|
-
displays.command("update").description("Update a display").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).option("--name <name>", "display name").action(async function action(display, commandOptions) {
|
|
9714
|
+
displays.command("update").description("Update a display").argument("<display>", "display uuid or slug", parseUuidOrSlugSelector3).option("--name <name>", "display name").option("--description <text>", 'display description (use "" to clear)').action(async function action(display, commandOptions) {
|
|
9594
9715
|
const { api, json, readOnly } = createDisplaysApi(this, filePath);
|
|
9595
9716
|
ensureWritable3("displays update", readOnly, "write");
|
|
9596
|
-
if (
|
|
9597
|
-
|
|
9717
|
+
if (commandOptions.name === void 0 && commandOptions.description === void 0) {
|
|
9718
|
+
throw new CliError("invalid_cli_usage", "Nothing to update.");
|
|
9719
|
+
}
|
|
9720
|
+
if (commandOptions.name !== void 0 && commandOptions.name.trim().length === 0) {
|
|
9721
|
+
throw new CliError("invalid_cli_usage", "Display name cannot be empty.");
|
|
9722
|
+
}
|
|
9723
|
+
const data = await api.updateDisplay(display, {
|
|
9724
|
+
name: commandOptions.name,
|
|
9725
|
+
description: commandOptions.description
|
|
9726
|
+
});
|
|
9598
9727
|
if (json) {
|
|
9599
9728
|
emitJson4(stdout, "displays update", data);
|
|
9600
9729
|
return;
|
|
@@ -10530,42 +10659,220 @@ function registerFilesCommands(program, options = {}) {
|
|
|
10530
10659
|
});
|
|
10531
10660
|
}
|
|
10532
10661
|
|
|
10533
|
-
// src/commands/
|
|
10662
|
+
// src/commands/formulas.ts
|
|
10534
10663
|
import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
|
|
10535
10664
|
|
|
10536
|
-
// src/api/
|
|
10665
|
+
// src/api/formulas.ts
|
|
10537
10666
|
function selectorValue6(selector) {
|
|
10538
10667
|
return selector.value;
|
|
10539
10668
|
}
|
|
10669
|
+
function toRequestBody(input) {
|
|
10670
|
+
if (input.scope === "FIELD") {
|
|
10671
|
+
return {
|
|
10672
|
+
scope: input.scope,
|
|
10673
|
+
schema: selectorValue6(input.schema),
|
|
10674
|
+
field: selectorValue6(input.field)
|
|
10675
|
+
};
|
|
10676
|
+
}
|
|
10677
|
+
if (input.scope === "SCHEMA") {
|
|
10678
|
+
return {
|
|
10679
|
+
scope: input.scope,
|
|
10680
|
+
schema: selectorValue6(input.schema)
|
|
10681
|
+
};
|
|
10682
|
+
}
|
|
10683
|
+
return { scope: input.scope };
|
|
10684
|
+
}
|
|
10685
|
+
var FormulasApi = class {
|
|
10686
|
+
constructor(client) {
|
|
10687
|
+
this.client = client;
|
|
10688
|
+
}
|
|
10689
|
+
recompute(input) {
|
|
10690
|
+
return this.client.requestJson(
|
|
10691
|
+
"/api/v2/formulas:recompute",
|
|
10692
|
+
{
|
|
10693
|
+
method: "POST",
|
|
10694
|
+
headers: {
|
|
10695
|
+
"content-type": "application/json"
|
|
10696
|
+
},
|
|
10697
|
+
body: JSON.stringify(toRequestBody(input))
|
|
10698
|
+
}
|
|
10699
|
+
);
|
|
10700
|
+
}
|
|
10701
|
+
};
|
|
10702
|
+
|
|
10703
|
+
// src/commands/formulas.ts
|
|
10704
|
+
function getCommandIo7(stdout) {
|
|
10705
|
+
return stdout ?? process.stdout;
|
|
10706
|
+
}
|
|
10707
|
+
function writeLine7(stdout, value) {
|
|
10708
|
+
stdout.write(`${value}
|
|
10709
|
+
`);
|
|
10710
|
+
}
|
|
10711
|
+
function getGlobalOptions7(command) {
|
|
10712
|
+
return command.optsWithGlobals();
|
|
10713
|
+
}
|
|
10714
|
+
function toConfigurationError7(filePath, error) {
|
|
10715
|
+
if (error instanceof CliError) {
|
|
10716
|
+
throw error;
|
|
10717
|
+
}
|
|
10718
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
10719
|
+
throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
|
|
10720
|
+
}
|
|
10721
|
+
if (error instanceof Error) {
|
|
10722
|
+
throw new CliError("configuration_error", error.message);
|
|
10723
|
+
}
|
|
10724
|
+
throw error;
|
|
10725
|
+
}
|
|
10726
|
+
function createFormulasApi(command, filePath) {
|
|
10727
|
+
try {
|
|
10728
|
+
const config = readRuntimeConfig(filePath);
|
|
10729
|
+
const runtime = resolveRuntimeContext(config, getGlobalOptions7(command));
|
|
10730
|
+
if (!runtime.baseUrl) {
|
|
10731
|
+
throw new CliError(
|
|
10732
|
+
"configuration_error",
|
|
10733
|
+
`Resolved profile "${runtime.profile}" is missing a base URL.`
|
|
10734
|
+
);
|
|
10735
|
+
}
|
|
10736
|
+
return {
|
|
10737
|
+
api: new FormulasApi(
|
|
10738
|
+
new ApiClient({
|
|
10739
|
+
baseUrl: runtime.baseUrl,
|
|
10740
|
+
apiKey: runtime.apiKey
|
|
10741
|
+
})
|
|
10742
|
+
),
|
|
10743
|
+
json: runtime.json,
|
|
10744
|
+
readOnly: runtime.readOnly
|
|
10745
|
+
};
|
|
10746
|
+
} catch (error) {
|
|
10747
|
+
toConfigurationError7(filePath, error);
|
|
10748
|
+
}
|
|
10749
|
+
}
|
|
10750
|
+
function ensureWritable6(commandName, readOnly) {
|
|
10751
|
+
if (readOnly) {
|
|
10752
|
+
throw new CliError(
|
|
10753
|
+
"command_not_allowed_in_read_only_mode",
|
|
10754
|
+
`Command "${commandName}" is not allowed in read-only mode.`,
|
|
10755
|
+
{
|
|
10756
|
+
commandMode: "write",
|
|
10757
|
+
executionMode: "read-only"
|
|
10758
|
+
}
|
|
10759
|
+
);
|
|
10760
|
+
}
|
|
10761
|
+
}
|
|
10762
|
+
function ensureConfirmed(commandName, confirmed) {
|
|
10763
|
+
if (!confirmed) {
|
|
10764
|
+
throw new CliError(
|
|
10765
|
+
"invalid_cli_usage",
|
|
10766
|
+
`Command "${commandName}" requires --yes because it may enqueue a large recalculation.`
|
|
10767
|
+
);
|
|
10768
|
+
}
|
|
10769
|
+
}
|
|
10770
|
+
function parseUuidOrSlugSelector6(input) {
|
|
10771
|
+
try {
|
|
10772
|
+
return normalizeUuidOrSlug(input);
|
|
10773
|
+
} catch (error) {
|
|
10774
|
+
const message = error instanceof Error ? error.message : "Invalid selector.";
|
|
10775
|
+
throw new InvalidArgumentError6(message);
|
|
10776
|
+
}
|
|
10777
|
+
}
|
|
10778
|
+
function emitResult(stdout, commandName, result, configPath, json) {
|
|
10779
|
+
if (json) {
|
|
10780
|
+
writeLine7(
|
|
10781
|
+
stdout,
|
|
10782
|
+
JSON.stringify(buildJsonSuccess(result, { command: commandName, configPath }))
|
|
10783
|
+
);
|
|
10784
|
+
return;
|
|
10785
|
+
}
|
|
10786
|
+
writeLine7(
|
|
10787
|
+
stdout,
|
|
10788
|
+
`Queued ${result.eventsQueued} formula recalculation event(s) for ${result.scope.toLowerCase()} scope (request ${result.requestId}).`
|
|
10789
|
+
);
|
|
10790
|
+
}
|
|
10791
|
+
async function recompute(command, commandName, input, options, requireConfirmation, confirmed) {
|
|
10792
|
+
const configPath = options.configPath ?? defaultConfigPath;
|
|
10793
|
+
const stdout = getCommandIo7(options.stdout);
|
|
10794
|
+
const { api, json, readOnly } = createFormulasApi(command, configPath);
|
|
10795
|
+
ensureWritable6(commandName, readOnly);
|
|
10796
|
+
if (requireConfirmation) {
|
|
10797
|
+
ensureConfirmed(commandName, confirmed);
|
|
10798
|
+
}
|
|
10799
|
+
const result = await api.recompute(input);
|
|
10800
|
+
emitResult(stdout, commandName, result, configPath, json);
|
|
10801
|
+
}
|
|
10802
|
+
function registerFormulasCommands(program, options = {}) {
|
|
10803
|
+
const formulas = program.command("formulas").description("Recalculate formula values");
|
|
10804
|
+
const recomputeCommand = formulas.command("recompute").description("Queue a full formula recalculation");
|
|
10805
|
+
recomputeCommand.command("field").description("Queue recalculation of one formula column").argument("<schema>", "schema UUID or slug", parseUuidOrSlugSelector6).argument("<field>", "formula field UUID or slug", parseUuidOrSlugSelector6).action(
|
|
10806
|
+
async function action(schema, field) {
|
|
10807
|
+
await recompute(
|
|
10808
|
+
this,
|
|
10809
|
+
"formulas recompute field",
|
|
10810
|
+
{ scope: "FIELD", schema, field },
|
|
10811
|
+
options,
|
|
10812
|
+
false
|
|
10813
|
+
);
|
|
10814
|
+
}
|
|
10815
|
+
);
|
|
10816
|
+
recomputeCommand.command("schema").description("Queue recalculation of all active formulas in one schema").argument("<schema>", "schema UUID or slug", parseUuidOrSlugSelector6).option("--yes", "confirm the potentially expensive recalculation").action(
|
|
10817
|
+
async function action(schema, commandOptions) {
|
|
10818
|
+
await recompute(
|
|
10819
|
+
this,
|
|
10820
|
+
"formulas recompute schema",
|
|
10821
|
+
{ scope: "SCHEMA", schema },
|
|
10822
|
+
options,
|
|
10823
|
+
true,
|
|
10824
|
+
commandOptions.yes
|
|
10825
|
+
);
|
|
10826
|
+
}
|
|
10827
|
+
);
|
|
10828
|
+
recomputeCommand.command("workspace").description("Queue recalculation of all active formulas in the workspace").option("--yes", "confirm the potentially expensive recalculation").action(async function action(commandOptions) {
|
|
10829
|
+
await recompute(
|
|
10830
|
+
this,
|
|
10831
|
+
"formulas recompute workspace",
|
|
10832
|
+
{ scope: "WORKSPACE" },
|
|
10833
|
+
options,
|
|
10834
|
+
true,
|
|
10835
|
+
commandOptions.yes
|
|
10836
|
+
);
|
|
10837
|
+
});
|
|
10838
|
+
}
|
|
10839
|
+
|
|
10840
|
+
// src/commands/logs.ts
|
|
10841
|
+
import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
|
|
10842
|
+
|
|
10843
|
+
// src/api/logs.ts
|
|
10844
|
+
function selectorValue7(selector) {
|
|
10845
|
+
return selector.value;
|
|
10846
|
+
}
|
|
10540
10847
|
var LogsApi = class {
|
|
10541
10848
|
constructor(client) {
|
|
10542
10849
|
this.client = client;
|
|
10543
10850
|
}
|
|
10544
10851
|
listLogs(schema, recordId) {
|
|
10545
10852
|
return this.client.getJson(
|
|
10546
|
-
`/api/v2/schemas/${
|
|
10853
|
+
`/api/v2/schemas/${selectorValue7(schema)}/records/${recordId}/logs`
|
|
10547
10854
|
);
|
|
10548
10855
|
}
|
|
10549
10856
|
};
|
|
10550
10857
|
|
|
10551
10858
|
// src/commands/logs.ts
|
|
10552
|
-
function
|
|
10859
|
+
function getCommandIo8(stdout) {
|
|
10553
10860
|
return stdout ?? process.stdout;
|
|
10554
10861
|
}
|
|
10555
|
-
function
|
|
10862
|
+
function writeLine8(stdout, value) {
|
|
10556
10863
|
stdout.write(`${value}
|
|
10557
10864
|
`);
|
|
10558
10865
|
}
|
|
10559
|
-
function
|
|
10866
|
+
function getGlobalOptions8(command) {
|
|
10560
10867
|
return command.optsWithGlobals();
|
|
10561
10868
|
}
|
|
10562
10869
|
function emitJson7(stdout, commandName, data, ..._extra) {
|
|
10563
|
-
|
|
10870
|
+
writeLine8(
|
|
10564
10871
|
stdout,
|
|
10565
10872
|
JSON.stringify(buildJsonSuccess(data, { command: commandName }))
|
|
10566
10873
|
);
|
|
10567
10874
|
}
|
|
10568
|
-
function
|
|
10875
|
+
function toConfigurationError8(filePath, error) {
|
|
10569
10876
|
if (error instanceof CliError) {
|
|
10570
10877
|
throw error;
|
|
10571
10878
|
}
|
|
@@ -10580,7 +10887,7 @@ function toConfigurationError7(filePath, error) {
|
|
|
10580
10887
|
function createLogsApi(command, filePath) {
|
|
10581
10888
|
try {
|
|
10582
10889
|
const config = readRuntimeConfig(filePath);
|
|
10583
|
-
const runtime = resolveRuntimeContext(config,
|
|
10890
|
+
const runtime = resolveRuntimeContext(config, getGlobalOptions8(command));
|
|
10584
10891
|
if (!runtime.baseUrl) {
|
|
10585
10892
|
throw new CliError(
|
|
10586
10893
|
"configuration_error",
|
|
@@ -10597,15 +10904,15 @@ function createLogsApi(command, filePath) {
|
|
|
10597
10904
|
json: runtime.json
|
|
10598
10905
|
};
|
|
10599
10906
|
} catch (error) {
|
|
10600
|
-
|
|
10907
|
+
toConfigurationError8(filePath, error);
|
|
10601
10908
|
}
|
|
10602
10909
|
}
|
|
10603
|
-
function
|
|
10910
|
+
function parseUuidOrSlugSelector7(input) {
|
|
10604
10911
|
try {
|
|
10605
10912
|
return normalizeUuidOrSlug(input);
|
|
10606
10913
|
} catch (error) {
|
|
10607
10914
|
const message = error instanceof Error ? error.message : "Invalid selector.";
|
|
10608
|
-
throw new
|
|
10915
|
+
throw new InvalidArgumentError7(message);
|
|
10609
10916
|
}
|
|
10610
10917
|
}
|
|
10611
10918
|
function isJsonObject5(value) {
|
|
@@ -10625,9 +10932,9 @@ function emitTable3(stdout, data) {
|
|
|
10625
10932
|
}
|
|
10626
10933
|
function registerLogsCommands(program, options = {}) {
|
|
10627
10934
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
10628
|
-
const stdout =
|
|
10935
|
+
const stdout = getCommandIo8(options.stdout);
|
|
10629
10936
|
const logs = program.command("logs").description("Inspect record change logs");
|
|
10630
|
-
logs.command("list").description("List change logs for a record").argument("<schema>", "schema uuid or slug",
|
|
10937
|
+
logs.command("list").description("List change logs for a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, record) {
|
|
10631
10938
|
const { api, json } = createLogsApi(this, filePath);
|
|
10632
10939
|
const data = await api.listLogs(schema, record.value);
|
|
10633
10940
|
if (json) {
|
|
@@ -10640,7 +10947,7 @@ function registerLogsCommands(program, options = {}) {
|
|
|
10640
10947
|
|
|
10641
10948
|
// src/commands/navigation.ts
|
|
10642
10949
|
import { readFileSync as readFileSync7 } from "fs";
|
|
10643
|
-
import { InvalidArgumentError as
|
|
10950
|
+
import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
|
|
10644
10951
|
|
|
10645
10952
|
// src/api/navigation.ts
|
|
10646
10953
|
function jsonOptions5(body, method) {
|
|
@@ -10652,7 +10959,7 @@ function jsonOptions5(body, method) {
|
|
|
10652
10959
|
body: JSON.stringify(body)
|
|
10653
10960
|
};
|
|
10654
10961
|
}
|
|
10655
|
-
function
|
|
10962
|
+
function selectorValue8(selector) {
|
|
10656
10963
|
return selector.value;
|
|
10657
10964
|
}
|
|
10658
10965
|
var NavigationApi = class {
|
|
@@ -10670,13 +10977,13 @@ var NavigationApi = class {
|
|
|
10670
10977
|
}
|
|
10671
10978
|
updateFolder(folder, body) {
|
|
10672
10979
|
return this.client.requestJson(
|
|
10673
|
-
`/api/v2/navigation/folders/${
|
|
10980
|
+
`/api/v2/navigation/folders/${selectorValue8(folder)}`,
|
|
10674
10981
|
jsonOptions5(body, "PATCH")
|
|
10675
10982
|
);
|
|
10676
10983
|
}
|
|
10677
10984
|
deleteFolder(folder) {
|
|
10678
10985
|
return this.client.requestJson(
|
|
10679
|
-
`/api/v2/navigation/folders/${
|
|
10986
|
+
`/api/v2/navigation/folders/${selectorValue8(folder)}`,
|
|
10680
10987
|
{ method: "DELETE" }
|
|
10681
10988
|
);
|
|
10682
10989
|
}
|
|
@@ -10689,20 +10996,20 @@ var NavigationApi = class {
|
|
|
10689
10996
|
};
|
|
10690
10997
|
|
|
10691
10998
|
// src/commands/navigation.ts
|
|
10692
|
-
function
|
|
10999
|
+
function getCommandIo9(stdout) {
|
|
10693
11000
|
return stdout ?? process.stdout;
|
|
10694
11001
|
}
|
|
10695
|
-
function
|
|
11002
|
+
function writeLine9(stdout, value) {
|
|
10696
11003
|
stdout.write(`${value}
|
|
10697
11004
|
`);
|
|
10698
11005
|
}
|
|
10699
|
-
function
|
|
11006
|
+
function getGlobalOptions9(command) {
|
|
10700
11007
|
return command.optsWithGlobals();
|
|
10701
11008
|
}
|
|
10702
11009
|
function emitJson8(stdout, commandName, data, configPath) {
|
|
10703
|
-
|
|
11010
|
+
writeLine9(stdout, JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath })));
|
|
10704
11011
|
}
|
|
10705
|
-
function
|
|
11012
|
+
function toConfigurationError9(filePath, error) {
|
|
10706
11013
|
if (error instanceof CliError) {
|
|
10707
11014
|
throw error;
|
|
10708
11015
|
}
|
|
@@ -10717,7 +11024,7 @@ function toConfigurationError8(filePath, error) {
|
|
|
10717
11024
|
function createNavigationApi(command, filePath) {
|
|
10718
11025
|
try {
|
|
10719
11026
|
const config = readRuntimeConfig(filePath);
|
|
10720
|
-
const runtime = resolveRuntimeContext(config,
|
|
11027
|
+
const runtime = resolveRuntimeContext(config, getGlobalOptions9(command));
|
|
10721
11028
|
if (!runtime.baseUrl) {
|
|
10722
11029
|
throw new CliError("configuration_error", `Resolved profile "${runtime.profile}" is missing a base URL.`);
|
|
10723
11030
|
}
|
|
@@ -10732,10 +11039,10 @@ function createNavigationApi(command, filePath) {
|
|
|
10732
11039
|
readOnly: runtime.readOnly
|
|
10733
11040
|
};
|
|
10734
11041
|
} catch (error) {
|
|
10735
|
-
|
|
11042
|
+
toConfigurationError9(filePath, error);
|
|
10736
11043
|
}
|
|
10737
11044
|
}
|
|
10738
|
-
function
|
|
11045
|
+
function ensureWritable7(commandName, readOnly, mode) {
|
|
10739
11046
|
if (readOnly) {
|
|
10740
11047
|
throw new CliError(
|
|
10741
11048
|
"command_not_allowed_in_read_only_mode",
|
|
@@ -10744,12 +11051,12 @@ function ensureWritable6(commandName, readOnly, mode) {
|
|
|
10744
11051
|
);
|
|
10745
11052
|
}
|
|
10746
11053
|
}
|
|
10747
|
-
function
|
|
11054
|
+
function parseUuidOrSlugSelector8(input) {
|
|
10748
11055
|
try {
|
|
10749
11056
|
return normalizeUuidOrSlug(input);
|
|
10750
11057
|
} catch (error) {
|
|
10751
11058
|
const message = error instanceof Error ? error.message : "Invalid selector.";
|
|
10752
|
-
throw new
|
|
11059
|
+
throw new InvalidArgumentError8(message);
|
|
10753
11060
|
}
|
|
10754
11061
|
}
|
|
10755
11062
|
function parseInteger(value, flagName) {
|
|
@@ -10828,7 +11135,7 @@ function folderRows2(folders) {
|
|
|
10828
11135
|
}
|
|
10829
11136
|
function registerNavigationCommands(program, options = {}) {
|
|
10830
11137
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
10831
|
-
const stdout =
|
|
11138
|
+
const stdout = getCommandIo9(options.stdout);
|
|
10832
11139
|
const navigation = program.command("navigation").description("Manage workspace navigation");
|
|
10833
11140
|
const folders = navigation.command("folders").description("Manage navigation folders");
|
|
10834
11141
|
folders.command("list").description("List navigation folders").action(async function action() {
|
|
@@ -10840,7 +11147,7 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
10840
11147
|
}
|
|
10841
11148
|
printTable(folderRows2(data), ["id", "order", "name", "resourceCount"], stdout);
|
|
10842
11149
|
});
|
|
10843
|
-
folders.command("get").description("Get a navigation folder by UUID or exact name").argument("<folder>", "folder UUID or exact name",
|
|
11150
|
+
folders.command("get").description("Get a navigation folder by UUID or exact name").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector8).action(async function action(folder) {
|
|
10844
11151
|
const { api, json } = createNavigationApi(this, filePath);
|
|
10845
11152
|
const data = await api.listFolders();
|
|
10846
11153
|
const resolved = resolveFolder2(data, folder);
|
|
@@ -10852,17 +11159,17 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
10852
11159
|
});
|
|
10853
11160
|
folders.command("create").description("Create a navigation folder").requiredOption("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)").option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"color":"blue","icon":"chart-line"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(commandOptions) {
|
|
10854
11161
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
10855
|
-
|
|
11162
|
+
ensureWritable7("navigation folders create", readOnly, "write");
|
|
10856
11163
|
const data = await api.createFolder(buildFolderBody(commandOptions));
|
|
10857
11164
|
if (json) {
|
|
10858
11165
|
emitJson8(stdout, "navigation folders create", data, filePath);
|
|
10859
11166
|
return;
|
|
10860
11167
|
}
|
|
10861
|
-
|
|
11168
|
+
writeLine9(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
|
|
10862
11169
|
});
|
|
10863
|
-
folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name",
|
|
11170
|
+
folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector8).option("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)").option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"color":"blue","icon":"chart-line"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(folder, commandOptions) {
|
|
10864
11171
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
10865
|
-
|
|
11172
|
+
ensureWritable7("navigation folders update", readOnly, "write");
|
|
10866
11173
|
const allFolders = await api.listFolders();
|
|
10867
11174
|
const resolved = resolveFolder2(allFolders, folder);
|
|
10868
11175
|
const body = buildFolderBody(commandOptions);
|
|
@@ -10874,11 +11181,11 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
10874
11181
|
emitJson8(stdout, "navigation folders update", data, filePath);
|
|
10875
11182
|
return;
|
|
10876
11183
|
}
|
|
10877
|
-
|
|
11184
|
+
writeLine9(stdout, `Updated navigation folder "${String(data.name ?? resolved.name ?? resolved.id)}".`);
|
|
10878
11185
|
});
|
|
10879
|
-
folders.command("delete").description("Delete a navigation folder").argument("<folder>", "folder UUID or exact name",
|
|
11186
|
+
folders.command("delete").description("Delete a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector8).action(async function action(folder) {
|
|
10880
11187
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
10881
|
-
|
|
11188
|
+
ensureWritable7("navigation folders delete", readOnly, "destructive");
|
|
10882
11189
|
const allFolders = await api.listFolders();
|
|
10883
11190
|
const resolved = resolveFolder2(allFolders, folder);
|
|
10884
11191
|
const data = await api.deleteFolder({ kind: "uuid", value: resolved.id });
|
|
@@ -10886,15 +11193,15 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
10886
11193
|
emitJson8(stdout, "navigation folders delete", data, filePath);
|
|
10887
11194
|
return;
|
|
10888
11195
|
}
|
|
10889
|
-
|
|
11196
|
+
writeLine9(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
|
|
10890
11197
|
});
|
|
10891
11198
|
navigation.command("resources").description("Manage navigation resources").command("move").description(
|
|
10892
11199
|
"Move a schema into a navigation folder. Only schemas can be moved (the navigation menu holds databases); schedules and sub-schemas follow their parent schema. Use the root folder UUID 00000000-0000-0000-0000-000000000000 to move it back to the workspace root."
|
|
10893
11200
|
).argument("<resource>", "schema UUID").requiredOption("--to <folder>", "target folder UUID or exact name").action(async function action(resourceId, commandOptions) {
|
|
10894
11201
|
const { api, json, readOnly } = createNavigationApi(this, filePath);
|
|
10895
|
-
|
|
11202
|
+
ensureWritable7("navigation resources move", readOnly, "write");
|
|
10896
11203
|
const allFolders = await api.listFolders();
|
|
10897
|
-
const resolved = resolveFolder2(allFolders,
|
|
11204
|
+
const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector8(commandOptions.to));
|
|
10898
11205
|
const data = await api.moveResource({
|
|
10899
11206
|
resourceId,
|
|
10900
11207
|
targetFolderId: resolved.id
|
|
@@ -10903,23 +11210,23 @@ function registerNavigationCommands(program, options = {}) {
|
|
|
10903
11210
|
emitJson8(stdout, "navigation resources move", data, filePath);
|
|
10904
11211
|
return;
|
|
10905
11212
|
}
|
|
10906
|
-
|
|
11213
|
+
writeLine9(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
|
|
10907
11214
|
});
|
|
10908
11215
|
}
|
|
10909
11216
|
|
|
10910
11217
|
// src/commands/profiles.ts
|
|
10911
|
-
function
|
|
11218
|
+
function getCommandIo10(stdout) {
|
|
10912
11219
|
return stdout ?? process.stdout;
|
|
10913
11220
|
}
|
|
10914
|
-
function
|
|
11221
|
+
function writeLine10(stdout, value) {
|
|
10915
11222
|
stdout.write(`${value}
|
|
10916
11223
|
`);
|
|
10917
11224
|
}
|
|
10918
|
-
function
|
|
11225
|
+
function getGlobalOptions10(command) {
|
|
10919
11226
|
return command.optsWithGlobals();
|
|
10920
11227
|
}
|
|
10921
11228
|
function emitJson9(stdout, commandName, data, configPath) {
|
|
10922
|
-
|
|
11229
|
+
writeLine10(
|
|
10923
11230
|
stdout,
|
|
10924
11231
|
JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
|
|
10925
11232
|
);
|
|
@@ -10975,14 +11282,14 @@ function emitProfilesTable(stdout, data) {
|
|
|
10975
11282
|
}
|
|
10976
11283
|
function registerProfilesCommands(program, options = {}) {
|
|
10977
11284
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
10978
|
-
const stdout =
|
|
11285
|
+
const stdout = getCommandIo10(options.stdout);
|
|
10979
11286
|
const profiles = program.command("profiles").description("Manage local CLI profiles");
|
|
10980
11287
|
profiles.command("list").description("List configured profiles").action(function action() {
|
|
10981
11288
|
const config = readRequiredConfig(filePath);
|
|
10982
11289
|
const data = Object.entries(config.profiles).map(
|
|
10983
11290
|
([name, profile]) => toDisplayProfile(name, profile, config.defaultProfile)
|
|
10984
11291
|
);
|
|
10985
|
-
if (
|
|
11292
|
+
if (getGlobalOptions10(this).json) {
|
|
10986
11293
|
emitJson9(stdout, "profiles list", data, filePath);
|
|
10987
11294
|
return;
|
|
10988
11295
|
}
|
|
@@ -10992,7 +11299,7 @@ function registerProfilesCommands(program, options = {}) {
|
|
|
10992
11299
|
const config = readRequiredConfig(filePath);
|
|
10993
11300
|
const profile = getRequiredProfile(config, profileName);
|
|
10994
11301
|
const data = toDisplayProfile(profileName, profile, config.defaultProfile);
|
|
10995
|
-
if (
|
|
11302
|
+
if (getGlobalOptions10(this).json) {
|
|
10996
11303
|
emitJson9(stdout, "profiles get", data, filePath);
|
|
10997
11304
|
return;
|
|
10998
11305
|
}
|
|
@@ -11007,11 +11314,11 @@ function registerProfilesCommands(program, options = {}) {
|
|
|
11007
11314
|
profile: profileName,
|
|
11008
11315
|
defaultProfile: nextConfig.defaultProfile
|
|
11009
11316
|
};
|
|
11010
|
-
if (
|
|
11317
|
+
if (getGlobalOptions10(this).json) {
|
|
11011
11318
|
emitJson9(stdout, "profiles use", data, filePath);
|
|
11012
11319
|
return;
|
|
11013
11320
|
}
|
|
11014
|
-
|
|
11321
|
+
writeLine10(stdout, `Using profile "${profileName}".`);
|
|
11015
11322
|
});
|
|
11016
11323
|
profiles.command("add").description("Add a profile to the local config").argument("<profile>", "profile name").requiredOption("--api-key <token>", "API key").option("--base-url <url>", "base URL").action(function action(profileName, commandOptions) {
|
|
11017
11324
|
const config = loadConfigForAdd(filePath);
|
|
@@ -11035,11 +11342,11 @@ function registerProfilesCommands(program, options = {}) {
|
|
|
11035
11342
|
nextConfig.profiles[profileName] ?? {},
|
|
11036
11343
|
nextConfig.defaultProfile
|
|
11037
11344
|
);
|
|
11038
|
-
if (
|
|
11345
|
+
if (getGlobalOptions10(this).json) {
|
|
11039
11346
|
emitJson9(stdout, "profiles add", data, filePath);
|
|
11040
11347
|
return;
|
|
11041
11348
|
}
|
|
11042
|
-
|
|
11349
|
+
writeLine10(stdout, `Added profile "${profileName}".`);
|
|
11043
11350
|
});
|
|
11044
11351
|
profiles.command("update").description("Update an existing profile").argument("<profile>", "profile name").option("--api-key <token>", "API key").option("--base-url <url>", "base URL").action(function action(profileName, commandOptions) {
|
|
11045
11352
|
if (commandOptions.apiKey === void 0 && commandOptions.baseUrl === void 0) {
|
|
@@ -11061,11 +11368,11 @@ function registerProfilesCommands(program, options = {}) {
|
|
|
11061
11368
|
nextConfig.profiles[profileName] ?? {},
|
|
11062
11369
|
nextConfig.defaultProfile
|
|
11063
11370
|
);
|
|
11064
|
-
if (
|
|
11371
|
+
if (getGlobalOptions10(this).json) {
|
|
11065
11372
|
emitJson9(stdout, "profiles update", data, filePath);
|
|
11066
11373
|
return;
|
|
11067
11374
|
}
|
|
11068
|
-
|
|
11375
|
+
writeLine10(stdout, `Updated profile "${profileName}".`);
|
|
11069
11376
|
});
|
|
11070
11377
|
profiles.command("remove").description("Remove a profile from the local config").argument("<profile>", "profile name").action(function action(profileName) {
|
|
11071
11378
|
const config = readRequiredConfig(filePath);
|
|
@@ -11076,17 +11383,17 @@ function registerProfilesCommands(program, options = {}) {
|
|
|
11076
11383
|
profile: profileName,
|
|
11077
11384
|
defaultProfile: nextConfig.defaultProfile
|
|
11078
11385
|
};
|
|
11079
|
-
if (
|
|
11386
|
+
if (getGlobalOptions10(this).json) {
|
|
11080
11387
|
emitJson9(stdout, "profiles remove", data, filePath);
|
|
11081
11388
|
return;
|
|
11082
11389
|
}
|
|
11083
|
-
|
|
11390
|
+
writeLine10(stdout, `Removed profile "${profileName}".`);
|
|
11084
11391
|
});
|
|
11085
11392
|
}
|
|
11086
11393
|
|
|
11087
11394
|
// src/commands/records.ts
|
|
11088
11395
|
import { readFileSync as readFileSync8 } from "fs";
|
|
11089
|
-
import { InvalidArgumentError as
|
|
11396
|
+
import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
|
|
11090
11397
|
|
|
11091
11398
|
// src/api/records.ts
|
|
11092
11399
|
function jsonOptions6(body, method) {
|
|
@@ -11098,7 +11405,7 @@ function jsonOptions6(body, method) {
|
|
|
11098
11405
|
body: JSON.stringify(body)
|
|
11099
11406
|
};
|
|
11100
11407
|
}
|
|
11101
|
-
function
|
|
11408
|
+
function selectorValue9(selector) {
|
|
11102
11409
|
return selector.value;
|
|
11103
11410
|
}
|
|
11104
11411
|
var RecordsApi = class {
|
|
@@ -11113,7 +11420,7 @@ var RecordsApi = class {
|
|
|
11113
11420
|
if (query.offset !== void 0) {
|
|
11114
11421
|
params.set("offset", String(query.offset));
|
|
11115
11422
|
}
|
|
11116
|
-
const path = `/api/v2/schemas/${
|
|
11423
|
+
const path = `/api/v2/schemas/${selectorValue9(schema)}/records`;
|
|
11117
11424
|
const queryString = params.toString();
|
|
11118
11425
|
return this.client.getJson(
|
|
11119
11426
|
queryString ? `${path}?${queryString}` : path
|
|
@@ -11122,36 +11429,36 @@ var RecordsApi = class {
|
|
|
11122
11429
|
queryRecords(schema, query) {
|
|
11123
11430
|
const body = this.normalizeQueryInput(query);
|
|
11124
11431
|
return this.client.requestJson(
|
|
11125
|
-
`/api/v2/schemas/${
|
|
11432
|
+
`/api/v2/schemas/${selectorValue9(schema)}/records:query`,
|
|
11126
11433
|
jsonOptions6(body, "POST")
|
|
11127
11434
|
);
|
|
11128
11435
|
}
|
|
11129
11436
|
getRecord(schema, record) {
|
|
11130
11437
|
return this.client.getJson(
|
|
11131
|
-
`/api/v2/schemas/${
|
|
11438
|
+
`/api/v2/schemas/${selectorValue9(schema)}/records/${selectorValue9(record)}`
|
|
11132
11439
|
);
|
|
11133
11440
|
}
|
|
11134
11441
|
createRecords(schema, records) {
|
|
11135
11442
|
return this.client.requestJson(
|
|
11136
|
-
`/api/v2/schemas/${
|
|
11443
|
+
`/api/v2/schemas/${selectorValue9(schema)}/records`,
|
|
11137
11444
|
jsonOptions6({ records }, "POST")
|
|
11138
11445
|
);
|
|
11139
11446
|
}
|
|
11140
11447
|
updateRecord(schema, record, input) {
|
|
11141
11448
|
return this.client.requestJson(
|
|
11142
|
-
`/api/v2/schemas/${
|
|
11449
|
+
`/api/v2/schemas/${selectorValue9(schema)}/records/${selectorValue9(record)}`,
|
|
11143
11450
|
jsonOptions6(input, "PATCH")
|
|
11144
11451
|
);
|
|
11145
11452
|
}
|
|
11146
11453
|
deleteRecords(schema, recordIds) {
|
|
11147
11454
|
return this.client.requestJson(
|
|
11148
|
-
`/api/v2/schemas/${
|
|
11455
|
+
`/api/v2/schemas/${selectorValue9(schema)}/records:delete`,
|
|
11149
11456
|
jsonOptions6({ recordIds }, "POST")
|
|
11150
11457
|
);
|
|
11151
11458
|
}
|
|
11152
11459
|
clearRecords(schema) {
|
|
11153
11460
|
return this.client.requestJson(
|
|
11154
|
-
`/api/v2/schemas/${
|
|
11461
|
+
`/api/v2/schemas/${selectorValue9(schema)}/records:clear`,
|
|
11155
11462
|
{ method: "DELETE" }
|
|
11156
11463
|
);
|
|
11157
11464
|
}
|
|
@@ -11193,7 +11500,7 @@ function jsonOptions7(body, method) {
|
|
|
11193
11500
|
body: JSON.stringify(body)
|
|
11194
11501
|
};
|
|
11195
11502
|
}
|
|
11196
|
-
function
|
|
11503
|
+
function selectorValue10(selector) {
|
|
11197
11504
|
return selector.value;
|
|
11198
11505
|
}
|
|
11199
11506
|
var SchemasApi = class {
|
|
@@ -11204,26 +11511,26 @@ var SchemasApi = class {
|
|
|
11204
11511
|
return this.client.getJson("/api/v2/schemas");
|
|
11205
11512
|
}
|
|
11206
11513
|
getSchema(schema) {
|
|
11207
|
-
return this.client.getJson(`/api/v2/schemas/${
|
|
11514
|
+
return this.client.getJson(`/api/v2/schemas/${selectorValue10(schema)}`);
|
|
11208
11515
|
}
|
|
11209
11516
|
createSchema(input) {
|
|
11210
11517
|
return this.client.requestJson("/api/v2/schemas", jsonOptions7(input, "POST"));
|
|
11211
11518
|
}
|
|
11212
11519
|
updateSchema(schema, input) {
|
|
11213
11520
|
return this.client.requestJson(
|
|
11214
|
-
`/api/v2/schemas/${
|
|
11521
|
+
`/api/v2/schemas/${selectorValue10(schema)}`,
|
|
11215
11522
|
jsonOptions7(input, "PATCH")
|
|
11216
11523
|
);
|
|
11217
11524
|
}
|
|
11218
11525
|
setUniqueFields(schema, input) {
|
|
11219
11526
|
return this.client.requestJson(
|
|
11220
|
-
`/api/v2/schemas/${
|
|
11527
|
+
`/api/v2/schemas/${selectorValue10(schema)}/unique-fields`,
|
|
11221
11528
|
jsonOptions7(input, "PUT")
|
|
11222
11529
|
);
|
|
11223
11530
|
}
|
|
11224
11531
|
deleteSchema(schema) {
|
|
11225
11532
|
return this.client.requestJson(
|
|
11226
|
-
`/api/v2/schemas/${
|
|
11533
|
+
`/api/v2/schemas/${selectorValue10(schema)}`,
|
|
11227
11534
|
{ method: "DELETE" }
|
|
11228
11535
|
);
|
|
11229
11536
|
}
|
|
@@ -11233,47 +11540,47 @@ var SchemasApi = class {
|
|
|
11233
11540
|
}
|
|
11234
11541
|
getField(schema, field) {
|
|
11235
11542
|
return this.client.getJson(
|
|
11236
|
-
`/api/v2/schemas/${
|
|
11543
|
+
`/api/v2/schemas/${selectorValue10(schema)}/fields/${selectorValue10(field)}`
|
|
11237
11544
|
);
|
|
11238
11545
|
}
|
|
11239
11546
|
createField(schema, input) {
|
|
11240
11547
|
return this.client.requestJson(
|
|
11241
|
-
`/api/v2/schemas/${
|
|
11548
|
+
`/api/v2/schemas/${selectorValue10(schema)}/fields`,
|
|
11242
11549
|
jsonOptions7(input, "POST")
|
|
11243
11550
|
);
|
|
11244
11551
|
}
|
|
11245
11552
|
updateField(schema, field, input) {
|
|
11246
11553
|
return this.client.requestJson(
|
|
11247
|
-
`/api/v2/schemas/${
|
|
11554
|
+
`/api/v2/schemas/${selectorValue10(schema)}/fields/${selectorValue10(field)}`,
|
|
11248
11555
|
jsonOptions7(input, "PATCH")
|
|
11249
11556
|
);
|
|
11250
11557
|
}
|
|
11251
11558
|
deleteField(schema, field) {
|
|
11252
11559
|
return this.client.requestJson(
|
|
11253
|
-
`/api/v2/schemas/${
|
|
11560
|
+
`/api/v2/schemas/${selectorValue10(schema)}/fields/${selectorValue10(field)}`,
|
|
11254
11561
|
{ method: "DELETE" }
|
|
11255
11562
|
);
|
|
11256
11563
|
}
|
|
11257
11564
|
};
|
|
11258
11565
|
|
|
11259
11566
|
// src/commands/records.ts
|
|
11260
|
-
function
|
|
11567
|
+
function getCommandIo11(stdout) {
|
|
11261
11568
|
return stdout ?? process.stdout;
|
|
11262
11569
|
}
|
|
11263
|
-
function
|
|
11570
|
+
function writeLine11(stdout, value) {
|
|
11264
11571
|
stdout.write(`${value}
|
|
11265
11572
|
`);
|
|
11266
11573
|
}
|
|
11267
|
-
function
|
|
11574
|
+
function getGlobalOptions11(command) {
|
|
11268
11575
|
return command.optsWithGlobals();
|
|
11269
11576
|
}
|
|
11270
11577
|
function emitJson10(stdout, commandName, data, configPath, meta = {}) {
|
|
11271
|
-
|
|
11578
|
+
writeLine11(
|
|
11272
11579
|
stdout,
|
|
11273
11580
|
JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
|
|
11274
11581
|
);
|
|
11275
11582
|
}
|
|
11276
|
-
function
|
|
11583
|
+
function toConfigurationError10(filePath, error) {
|
|
11277
11584
|
if (error instanceof CliError) {
|
|
11278
11585
|
throw error;
|
|
11279
11586
|
}
|
|
@@ -11288,7 +11595,7 @@ function toConfigurationError9(filePath, error) {
|
|
|
11288
11595
|
function createRecordsApi(command, filePath) {
|
|
11289
11596
|
try {
|
|
11290
11597
|
const config = readRuntimeConfig(filePath);
|
|
11291
|
-
const runtime = resolveRuntimeContext(config,
|
|
11598
|
+
const runtime = resolveRuntimeContext(config, getGlobalOptions11(command));
|
|
11292
11599
|
if (!runtime.baseUrl) {
|
|
11293
11600
|
throw new CliError(
|
|
11294
11601
|
"configuration_error",
|
|
@@ -11307,10 +11614,10 @@ function createRecordsApi(command, filePath) {
|
|
|
11307
11614
|
readOnly: runtime.readOnly
|
|
11308
11615
|
};
|
|
11309
11616
|
} catch (error) {
|
|
11310
|
-
|
|
11617
|
+
toConfigurationError10(filePath, error);
|
|
11311
11618
|
}
|
|
11312
11619
|
}
|
|
11313
|
-
function
|
|
11620
|
+
function ensureWritable8(commandName, readOnly, commandMode) {
|
|
11314
11621
|
if (readOnly) {
|
|
11315
11622
|
throw new CliError(
|
|
11316
11623
|
"command_not_allowed_in_read_only_mode",
|
|
@@ -11322,24 +11629,24 @@ function ensureWritable7(commandName, readOnly, commandMode) {
|
|
|
11322
11629
|
);
|
|
11323
11630
|
}
|
|
11324
11631
|
}
|
|
11325
|
-
function
|
|
11632
|
+
function parseUuidOrSlugSelector9(input) {
|
|
11326
11633
|
try {
|
|
11327
11634
|
return normalizeUuidOrSlug(input);
|
|
11328
11635
|
} catch (error) {
|
|
11329
11636
|
const message = error instanceof Error ? error.message : "Invalid selector.";
|
|
11330
|
-
throw new
|
|
11637
|
+
throw new InvalidArgumentError9(message);
|
|
11331
11638
|
}
|
|
11332
11639
|
}
|
|
11333
11640
|
function parseNonNegativeInteger2(input) {
|
|
11334
11641
|
if (!/^\d+$/.test(input.trim())) {
|
|
11335
|
-
throw new
|
|
11642
|
+
throw new InvalidArgumentError9(`Expected a non-negative integer, received "${input}".`);
|
|
11336
11643
|
}
|
|
11337
11644
|
return Number(input);
|
|
11338
11645
|
}
|
|
11339
11646
|
function parseCommaSeparatedValues(input, label) {
|
|
11340
11647
|
const values = input.split(",").map((value) => value.trim()).filter(Boolean);
|
|
11341
11648
|
if (values.length === 0) {
|
|
11342
|
-
throw new
|
|
11649
|
+
throw new InvalidArgumentError9(`Expected ${label} to contain at least one value.`);
|
|
11343
11650
|
}
|
|
11344
11651
|
return values;
|
|
11345
11652
|
}
|
|
@@ -11348,7 +11655,7 @@ function parseExpressionValue(input) {
|
|
|
11348
11655
|
return parseExpression(input);
|
|
11349
11656
|
} catch (error) {
|
|
11350
11657
|
const message = error instanceof Error ? error.message : "Invalid expression.";
|
|
11351
|
-
throw new
|
|
11658
|
+
throw new InvalidArgumentError9(message);
|
|
11352
11659
|
}
|
|
11353
11660
|
}
|
|
11354
11661
|
function parseKeyValueAssignment(input) {
|
|
@@ -11356,7 +11663,7 @@ function parseKeyValueAssignment(input) {
|
|
|
11356
11663
|
return parseKeyValue(input);
|
|
11357
11664
|
} catch (error) {
|
|
11358
11665
|
const message = error instanceof Error ? error.message : "Invalid assignment.";
|
|
11359
|
-
throw new
|
|
11666
|
+
throw new InvalidArgumentError9(message);
|
|
11360
11667
|
}
|
|
11361
11668
|
}
|
|
11362
11669
|
function parseJsonKeyValueAssignment(input) {
|
|
@@ -11364,7 +11671,7 @@ function parseJsonKeyValueAssignment(input) {
|
|
|
11364
11671
|
return parseJsonAssignment(input);
|
|
11365
11672
|
} catch (error) {
|
|
11366
11673
|
const message = error instanceof Error ? error.message : "Invalid JSON assignment.";
|
|
11367
|
-
throw new
|
|
11674
|
+
throw new InvalidArgumentError9(message);
|
|
11368
11675
|
}
|
|
11369
11676
|
}
|
|
11370
11677
|
function dedupeStrings(values) {
|
|
@@ -11381,7 +11688,7 @@ function toRecordUuid(value) {
|
|
|
11381
11688
|
function collectRecordIds(value, previous = []) {
|
|
11382
11689
|
const uuid = toRecordUuid(value.trim());
|
|
11383
11690
|
if (!uuid) {
|
|
11384
|
-
throw new
|
|
11691
|
+
throw new InvalidArgumentError9(`Expected a record UUID, received "${value}".`);
|
|
11385
11692
|
}
|
|
11386
11693
|
return [...previous, uuid];
|
|
11387
11694
|
}
|
|
@@ -11668,9 +11975,9 @@ async function resolveSchemaSelector(api, selector) {
|
|
|
11668
11975
|
}
|
|
11669
11976
|
function registerRecordsCommands(program, options = {}) {
|
|
11670
11977
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
11671
|
-
const stdout =
|
|
11978
|
+
const stdout = getCommandIo11(options.stdout);
|
|
11672
11979
|
const records = program.command("records").description("Manage schema records");
|
|
11673
|
-
records.command("list").description("List records for a schema with simple pagination").argument("<schema>", "schema uuid or slug",
|
|
11980
|
+
records.command("list").description("List records for a schema with simple pagination").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).action(async function action(schema, commandOptions) {
|
|
11674
11981
|
const { api, schemasApi, json } = createRecordsApi(this, filePath);
|
|
11675
11982
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11676
11983
|
const data = await api.listRecords(
|
|
@@ -11690,7 +11997,7 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11690
11997
|
}
|
|
11691
11998
|
emitTable4(stdout, recordsData);
|
|
11692
11999
|
});
|
|
11693
|
-
records.command("query").description("Query records for a schema").argument("<schema>", "schema uuid or slug",
|
|
12000
|
+
records.command("query").description("Query records for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option("--select <fields>", "field selection (comma-separated, repeatable)", collectSelectValues, []).option("--where <expression>", "where expression", collectWhereExpressions, []).option(
|
|
11694
12001
|
"--search <term>",
|
|
11695
12002
|
"free-text search term (matched across the schema's searchable fields)"
|
|
11696
12003
|
).option("--sort <field:direction>", "sort field(s)", collectSortValues, []).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
|
|
@@ -11713,7 +12020,7 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11713
12020
|
}
|
|
11714
12021
|
emitTable4(stdout, recordsData);
|
|
11715
12022
|
});
|
|
11716
|
-
records.command("get").description("Get a record by UUID or slug").argument("<schema>", "schema uuid or slug",
|
|
12023
|
+
records.command("get").description("Get a record by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema, record) {
|
|
11717
12024
|
const { api, schemasApi, json } = createRecordsApi(this, filePath);
|
|
11718
12025
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11719
12026
|
const data = await api.getRecord(resolvedSchema, record);
|
|
@@ -11723,7 +12030,7 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11723
12030
|
}
|
|
11724
12031
|
emitTable4(stdout, data);
|
|
11725
12032
|
});
|
|
11726
|
-
records.command("create").description("Create one or more records").argument("<schema>", "schema uuid or slug",
|
|
12033
|
+
records.command("create").description("Create one or more records").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option(
|
|
11727
12034
|
"--set <field=value>",
|
|
11728
12035
|
"set a string field (reference fields: a record id, 'recordId::label', or an exact display value)",
|
|
11729
12036
|
collectKeyValueAssignments,
|
|
@@ -11733,7 +12040,7 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11733
12040
|
"path to a JSON array of record objects (mutually exclusive with --set/--set-json/--raw/--raw-file)"
|
|
11734
12041
|
).action(async function action(schema, commandOptions) {
|
|
11735
12042
|
const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
|
|
11736
|
-
|
|
12043
|
+
ensureWritable8("records create", readOnly, "write");
|
|
11737
12044
|
const records2 = buildCreateRecords(commandOptions);
|
|
11738
12045
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11739
12046
|
const data = await api.createRecords(resolvedSchema, records2);
|
|
@@ -11741,22 +12048,22 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11741
12048
|
emitJson10(stdout, "records create", data, filePath);
|
|
11742
12049
|
return;
|
|
11743
12050
|
}
|
|
11744
|
-
|
|
12051
|
+
writeLine11(stdout, `Created ${data.created.length} record(s) in schema "${schema.value}".`);
|
|
11745
12052
|
if (data.errors.length > 0) {
|
|
11746
|
-
|
|
12053
|
+
writeLine11(stdout, `${data.errors.length} record(s) rejected:`);
|
|
11747
12054
|
for (const error of data.errors) {
|
|
11748
|
-
|
|
12055
|
+
writeLine11(stdout, ` - index ${error.index}: ${error.message}`);
|
|
11749
12056
|
}
|
|
11750
12057
|
}
|
|
11751
12058
|
});
|
|
11752
|
-
records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug",
|
|
12059
|
+
records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector9).option(
|
|
11753
12060
|
"--set <field=value>",
|
|
11754
12061
|
"set a string field (reference fields: a record id, 'recordId::label', or an exact display value)",
|
|
11755
12062
|
collectKeyValueAssignments,
|
|
11756
12063
|
[]
|
|
11757
12064
|
).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--unset <field>", "unset a field", collectStringValues, []).option("--raw <json>", "raw JSON object of fields to set").option("--raw-file <path>", "path to a JSON object of fields to set").action(async function action(schema, record, commandOptions) {
|
|
11758
12065
|
const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
|
|
11759
|
-
|
|
12066
|
+
ensureWritable8("records update", readOnly, "write");
|
|
11760
12067
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11761
12068
|
const data = await api.updateRecord(
|
|
11762
12069
|
resolvedSchema,
|
|
@@ -11767,14 +12074,14 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11767
12074
|
emitJson10(stdout, "records update", data, filePath);
|
|
11768
12075
|
return;
|
|
11769
12076
|
}
|
|
11770
|
-
|
|
12077
|
+
writeLine11(stdout, `Updated record "${getRecordIdentifier(data)}".`);
|
|
11771
12078
|
});
|
|
11772
|
-
records.command("delete").description("Delete one or more records").argument("<schema>", "schema uuid or slug",
|
|
12079
|
+
records.command("delete").description("Delete one or more records").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).option("--record <uuid>", "record uuid to delete (repeatable)", collectRecordIds, []).option(
|
|
11773
12080
|
"--records-file <path>",
|
|
11774
12081
|
"path to a file with one record uuid per line (merged with --record)"
|
|
11775
12082
|
).action(async function action(schema, commandOptions) {
|
|
11776
12083
|
const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
|
|
11777
|
-
|
|
12084
|
+
ensureWritable8("records delete", readOnly, "destructive");
|
|
11778
12085
|
const recordIds = resolveDeleteRecordIds(commandOptions);
|
|
11779
12086
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11780
12087
|
const data = await api.deleteRecords(resolvedSchema, recordIds);
|
|
@@ -11782,27 +12089,27 @@ function registerRecordsCommands(program, options = {}) {
|
|
|
11782
12089
|
emitJson10(stdout, "records delete", data, filePath);
|
|
11783
12090
|
return;
|
|
11784
12091
|
}
|
|
11785
|
-
|
|
12092
|
+
writeLine11(
|
|
11786
12093
|
stdout,
|
|
11787
12094
|
`Deleted ${recordIds.length} record(s) from schema "${schema.value}".`
|
|
11788
12095
|
);
|
|
11789
12096
|
});
|
|
11790
|
-
records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug",
|
|
12097
|
+
records.command("clear").description("Delete all records from a schema's table").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector9).action(async function action(schema) {
|
|
11791
12098
|
const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
|
|
11792
|
-
|
|
12099
|
+
ensureWritable8("records clear", readOnly, "destructive");
|
|
11793
12100
|
const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
|
|
11794
12101
|
const data = await api.clearRecords(resolvedSchema);
|
|
11795
12102
|
if (json) {
|
|
11796
12103
|
emitJson10(stdout, "records clear", data, filePath);
|
|
11797
12104
|
return;
|
|
11798
12105
|
}
|
|
11799
|
-
|
|
12106
|
+
writeLine11(stdout, `Cleared all records from schema "${schema.value}".`);
|
|
11800
12107
|
});
|
|
11801
12108
|
}
|
|
11802
12109
|
|
|
11803
12110
|
// src/commands/schemas.ts
|
|
11804
12111
|
import { readFileSync as readFileSync9 } from "fs";
|
|
11805
|
-
import { InvalidArgumentError as
|
|
12112
|
+
import { InvalidArgumentError as InvalidArgumentError10 } from "commander";
|
|
11806
12113
|
var HIGHLIGHTED_FIELD_HELP = `
|
|
11807
12114
|
Highlighted field:
|
|
11808
12115
|
The schema's "main" field. The frontend uses its value as each record's
|
|
@@ -11812,23 +12119,23 @@ Highlighted field:
|
|
|
11812
12119
|
- Detail view: the record's name in the left-hand record list you
|
|
11813
12120
|
browse to open each record's form.
|
|
11814
12121
|
`;
|
|
11815
|
-
function
|
|
12122
|
+
function getCommandIo12(stdout) {
|
|
11816
12123
|
return stdout ?? process.stdout;
|
|
11817
12124
|
}
|
|
11818
|
-
function
|
|
12125
|
+
function writeLine12(stdout, value) {
|
|
11819
12126
|
stdout.write(`${value}
|
|
11820
12127
|
`);
|
|
11821
12128
|
}
|
|
11822
|
-
function
|
|
12129
|
+
function getGlobalOptions12(command) {
|
|
11823
12130
|
return command.optsWithGlobals();
|
|
11824
12131
|
}
|
|
11825
12132
|
function emitJson11(stdout, commandName, data, configPath) {
|
|
11826
|
-
|
|
12133
|
+
writeLine12(
|
|
11827
12134
|
stdout,
|
|
11828
12135
|
JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
|
|
11829
12136
|
);
|
|
11830
12137
|
}
|
|
11831
|
-
function
|
|
12138
|
+
function toConfigurationError11(filePath, error) {
|
|
11832
12139
|
if (error instanceof CliError) {
|
|
11833
12140
|
throw error;
|
|
11834
12141
|
}
|
|
@@ -11843,7 +12150,7 @@ function toConfigurationError10(filePath, error) {
|
|
|
11843
12150
|
function createSchemasApi(command, filePath) {
|
|
11844
12151
|
try {
|
|
11845
12152
|
const config = readRuntimeConfig(filePath);
|
|
11846
|
-
const runtime = resolveRuntimeContext(config,
|
|
12153
|
+
const runtime = resolveRuntimeContext(config, getGlobalOptions12(command));
|
|
11847
12154
|
if (!runtime.baseUrl) {
|
|
11848
12155
|
throw new CliError(
|
|
11849
12156
|
"configuration_error",
|
|
@@ -11862,10 +12169,10 @@ function createSchemasApi(command, filePath) {
|
|
|
11862
12169
|
readOnly: runtime.readOnly
|
|
11863
12170
|
};
|
|
11864
12171
|
} catch (error) {
|
|
11865
|
-
|
|
12172
|
+
toConfigurationError11(filePath, error);
|
|
11866
12173
|
}
|
|
11867
12174
|
}
|
|
11868
|
-
function
|
|
12175
|
+
function ensureWritable9(commandName, readOnly, commandMode) {
|
|
11869
12176
|
if (readOnly) {
|
|
11870
12177
|
throw new CliError(
|
|
11871
12178
|
"command_not_allowed_in_read_only_mode",
|
|
@@ -11877,16 +12184,16 @@ function ensureWritable8(commandName, readOnly, commandMode) {
|
|
|
11877
12184
|
);
|
|
11878
12185
|
}
|
|
11879
12186
|
}
|
|
11880
|
-
function
|
|
12187
|
+
function parseUuidOrSlugSelector10(input) {
|
|
11881
12188
|
try {
|
|
11882
12189
|
return normalizeUuidOrSlug(input);
|
|
11883
12190
|
} catch (error) {
|
|
11884
12191
|
const message = error instanceof Error ? error.message : "Invalid selector.";
|
|
11885
|
-
throw new
|
|
12192
|
+
throw new InvalidArgumentError10(message);
|
|
11886
12193
|
}
|
|
11887
12194
|
}
|
|
11888
12195
|
function collectFieldSelectors(value, previous = []) {
|
|
11889
|
-
return [...previous,
|
|
12196
|
+
return [...previous, parseUuidOrSlugSelector10(value)];
|
|
11890
12197
|
}
|
|
11891
12198
|
function parseBooleanFlag(input) {
|
|
11892
12199
|
const normalized = input.trim().toLowerCase();
|
|
@@ -11896,7 +12203,7 @@ function parseBooleanFlag(input) {
|
|
|
11896
12203
|
if (["false", "0", "no", "n", "off"].includes(normalized)) {
|
|
11897
12204
|
return false;
|
|
11898
12205
|
}
|
|
11899
|
-
throw new
|
|
12206
|
+
throw new InvalidArgumentError10(`Expected a boolean value, received "${input}".`);
|
|
11900
12207
|
}
|
|
11901
12208
|
function isJsonObject7(value) {
|
|
11902
12209
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -12032,6 +12339,9 @@ function buildFieldCreateInput(options) {
|
|
|
12032
12339
|
if (options.required !== void 0) {
|
|
12033
12340
|
input.required = options.required;
|
|
12034
12341
|
}
|
|
12342
|
+
if (options.description !== void 0) {
|
|
12343
|
+
input.description = options.description;
|
|
12344
|
+
}
|
|
12035
12345
|
applyFieldDefaultValue(input, options.default);
|
|
12036
12346
|
if ("config" in input && isJsonObject7(input.config) && isEmptyObject6(input.config)) {
|
|
12037
12347
|
delete input.config;
|
|
@@ -12075,6 +12385,9 @@ function buildFieldUpdateInput(currentType, options) {
|
|
|
12075
12385
|
if (options.required !== void 0) {
|
|
12076
12386
|
input.required = options.required;
|
|
12077
12387
|
}
|
|
12388
|
+
if (options.description !== void 0) {
|
|
12389
|
+
input.description = options.description;
|
|
12390
|
+
}
|
|
12078
12391
|
applyFieldDefaultValue(input, options.default);
|
|
12079
12392
|
return input;
|
|
12080
12393
|
}
|
|
@@ -12111,7 +12424,7 @@ function isEmptyObject6(value) {
|
|
|
12111
12424
|
}
|
|
12112
12425
|
function registerSchemasCommands(program, options = {}) {
|
|
12113
12426
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
12114
|
-
const stdout =
|
|
12427
|
+
const stdout = getCommandIo12(options.stdout);
|
|
12115
12428
|
const schemas = program.command("schemas").description("Manage schemas and schema fields");
|
|
12116
12429
|
schemas.command("list").description("List schemas").action(async function action() {
|
|
12117
12430
|
const { api, json } = createSchemasApi(this, filePath);
|
|
@@ -12122,7 +12435,7 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12122
12435
|
}
|
|
12123
12436
|
emitSchemasTable(stdout, data);
|
|
12124
12437
|
});
|
|
12125
|
-
schemas.command("get").description("Get a schema by UUID or slug").argument("<schema>", "schema uuid or slug",
|
|
12438
|
+
schemas.command("get").description("Get a schema by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).action(async function action(schema) {
|
|
12126
12439
|
const { api, json } = createSchemasApi(this, filePath);
|
|
12127
12440
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12128
12441
|
const data = await api.getSchema(resolvedSchema);
|
|
@@ -12134,7 +12447,7 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12134
12447
|
});
|
|
12135
12448
|
schemas.command("create").description("Create a schema").requiredOption("--name <name>", "schema name").requiredOption("--slug <slug>", "schema slug").option("--auditable", "mark schema as auditable").option("--commentable", "mark schema as commentable").action(async function action(commandOptions) {
|
|
12136
12449
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12137
|
-
|
|
12450
|
+
ensureWritable9("schemas create", readOnly, "write");
|
|
12138
12451
|
const input = {
|
|
12139
12452
|
name: commandOptions.name,
|
|
12140
12453
|
slug: commandOptions.slug,
|
|
@@ -12146,15 +12459,15 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12146
12459
|
emitJson11(stdout, "schemas create", data, filePath);
|
|
12147
12460
|
return;
|
|
12148
12461
|
}
|
|
12149
|
-
|
|
12462
|
+
writeLine12(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
|
|
12150
12463
|
});
|
|
12151
|
-
schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug",
|
|
12464
|
+
schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).option("--name <name>", "schema name").option("--slug <slug>", "schema slug").option("--auditable <bool>", "auditable flag", parseBooleanFlag).option("--commentable <bool>", "commentable flag", parseBooleanFlag).option(
|
|
12152
12465
|
"--highlighted-field <field>",
|
|
12153
12466
|
"its value is used as each record's display name in the UI (field uuid or slug)",
|
|
12154
|
-
|
|
12467
|
+
parseUuidOrSlugSelector10
|
|
12155
12468
|
).action(async function action(schema, commandOptions) {
|
|
12156
12469
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12157
|
-
|
|
12470
|
+
ensureWritable9("schemas update", readOnly, "write");
|
|
12158
12471
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12159
12472
|
const input = buildSchemaUpdateInput(commandOptions);
|
|
12160
12473
|
if (commandOptions.highlightedField !== void 0) {
|
|
@@ -12176,16 +12489,16 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12176
12489
|
emitJson11(stdout, "schemas update", data, filePath);
|
|
12177
12490
|
return;
|
|
12178
12491
|
}
|
|
12179
|
-
|
|
12492
|
+
writeLine12(stdout, `Updated schema "${data.slug ?? schema.value}".`);
|
|
12180
12493
|
}).addHelpText("after", HIGHLIGHTED_FIELD_HELP);
|
|
12181
|
-
schemas.command("set-unique-fields").description("Set or clear the composite unique-field constraint on a schema").argument("<schema>", "schema uuid or slug",
|
|
12494
|
+
schemas.command("set-unique-fields").description("Set or clear the composite unique-field constraint on a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).option(
|
|
12182
12495
|
"--field <field>",
|
|
12183
12496
|
"field uuid or slug to include in the unique constraint (repeatable)",
|
|
12184
12497
|
collectFieldSelectors,
|
|
12185
12498
|
[]
|
|
12186
12499
|
).option("--clear", "clear the unique constraint (sends an empty field list)").action(async function action(schema, commandOptions) {
|
|
12187
12500
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12188
|
-
|
|
12501
|
+
ensureWritable9("schemas set-unique-fields", readOnly, "write");
|
|
12189
12502
|
const selectors = commandOptions.field ?? [];
|
|
12190
12503
|
if (commandOptions.clear && selectors.length > 0) {
|
|
12191
12504
|
throw new CliError(
|
|
@@ -12212,18 +12525,18 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12212
12525
|
return;
|
|
12213
12526
|
}
|
|
12214
12527
|
if (input.fieldIds.length === 0) {
|
|
12215
|
-
|
|
12528
|
+
writeLine12(stdout, `Cleared unique fields on schema "${schema.value}".`);
|
|
12216
12529
|
return;
|
|
12217
12530
|
}
|
|
12218
12531
|
const count = input.fieldIds.length;
|
|
12219
|
-
|
|
12532
|
+
writeLine12(
|
|
12220
12533
|
stdout,
|
|
12221
12534
|
`Set unique fields on schema "${schema.value}" (${count} field${count === 1 ? "" : "s"}).`
|
|
12222
12535
|
);
|
|
12223
12536
|
});
|
|
12224
|
-
schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug",
|
|
12537
|
+
schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).action(async function action(schema) {
|
|
12225
12538
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12226
|
-
|
|
12539
|
+
ensureWritable9("schemas delete", readOnly, "destructive");
|
|
12227
12540
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12228
12541
|
await api.deleteSchema(resolvedSchema);
|
|
12229
12542
|
const data = {
|
|
@@ -12234,10 +12547,10 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12234
12547
|
emitJson11(stdout, "schemas delete", data, filePath);
|
|
12235
12548
|
return;
|
|
12236
12549
|
}
|
|
12237
|
-
|
|
12550
|
+
writeLine12(stdout, `Deleted schema "${schema.value}".`);
|
|
12238
12551
|
});
|
|
12239
12552
|
const fields = schemas.command("fields").description("Manage schema fields");
|
|
12240
|
-
fields.command("list").description("List fields for a schema").argument("<schema>", "schema uuid or slug",
|
|
12553
|
+
fields.command("list").description("List fields for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).action(async function action(schema) {
|
|
12241
12554
|
const { api, json } = createSchemasApi(this, filePath);
|
|
12242
12555
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12243
12556
|
const data = await api.listFields(resolvedSchema);
|
|
@@ -12247,7 +12560,7 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12247
12560
|
}
|
|
12248
12561
|
emitFieldsTable(stdout, data);
|
|
12249
12562
|
});
|
|
12250
|
-
fields.command("get").description("Get a field by UUID or slug").argument("<schema>", "schema uuid or slug",
|
|
12563
|
+
fields.command("get").description("Get a field by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector10).action(async function action(schema, field) {
|
|
12251
12564
|
const { api, json } = createSchemasApi(this, filePath);
|
|
12252
12565
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12253
12566
|
const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
|
|
@@ -12258,9 +12571,9 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12258
12571
|
}
|
|
12259
12572
|
emitFieldsTable(stdout, [data]);
|
|
12260
12573
|
});
|
|
12261
|
-
fields.command("create").description(`Create a field in a schema.${buildSchemaFieldCreateHelpText()}`).argument("<schema>", "schema uuid or slug",
|
|
12574
|
+
fields.command("create").description(`Create a field in a schema.${buildSchemaFieldCreateHelpText()}`).argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).option("--type <type>", `field type (${formatSchemaFieldTypes()})`).option("--slug <slug>", "field slug").option("--label <label>", "field label").option("--description <text>", "field description").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload (see type-specific shapes in --help)").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
|
|
12262
12575
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12263
|
-
|
|
12576
|
+
ensureWritable9("schemas fields create", readOnly, "write");
|
|
12264
12577
|
const input = buildFieldCreateInput(commandOptions);
|
|
12265
12578
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12266
12579
|
let data;
|
|
@@ -12273,11 +12586,11 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12273
12586
|
emitJson11(stdout, "schemas fields create", data, filePath);
|
|
12274
12587
|
return;
|
|
12275
12588
|
}
|
|
12276
|
-
|
|
12589
|
+
writeLine12(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
|
|
12277
12590
|
});
|
|
12278
|
-
fields.command("update").description("Update a field in a schema").argument("<schema>", "schema uuid or slug",
|
|
12591
|
+
fields.command("update").description("Update a field in a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector10).option("--label <label>", "field label").option("--description <text>", 'field description (use "" to clear)').option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, field, commandOptions) {
|
|
12279
12592
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12280
|
-
|
|
12593
|
+
ensureWritable9("schemas fields update", readOnly, "write");
|
|
12281
12594
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12282
12595
|
const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
|
|
12283
12596
|
const currentField = await api.getField(resolvedSchema, resolvedField);
|
|
@@ -12289,7 +12602,7 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12289
12602
|
if (isEmptyObject6(input)) {
|
|
12290
12603
|
throw new CliError(
|
|
12291
12604
|
"invalid_cli_usage",
|
|
12292
|
-
'Provide at least one field update via "--label", "--required", "--raw", or "--raw-file".'
|
|
12605
|
+
'Provide at least one field update via "--label", "--description", "--required", "--default", "--raw", or "--raw-file".'
|
|
12293
12606
|
);
|
|
12294
12607
|
}
|
|
12295
12608
|
const data = await api.updateField(resolvedSchema, resolvedField, input);
|
|
@@ -12297,11 +12610,11 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12297
12610
|
emitJson11(stdout, "schemas fields update", data, filePath);
|
|
12298
12611
|
return;
|
|
12299
12612
|
}
|
|
12300
|
-
|
|
12613
|
+
writeLine12(stdout, `Updated field "${data.slug ?? field.value}".`);
|
|
12301
12614
|
});
|
|
12302
|
-
fields.command("delete").description("Delete a field from a schema").argument("<schema>", "schema uuid or slug",
|
|
12615
|
+
fields.command("delete").description("Delete a field from a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector10).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector10).action(async function action(schema, field) {
|
|
12303
12616
|
const { api, json, readOnly } = createSchemasApi(this, filePath);
|
|
12304
|
-
|
|
12617
|
+
ensureWritable9("schemas fields delete", readOnly, "destructive");
|
|
12305
12618
|
const resolvedSchema = await resolveSchemaSelector2(api, schema);
|
|
12306
12619
|
const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
|
|
12307
12620
|
await api.deleteField(resolvedSchema, resolvedField);
|
|
@@ -12314,13 +12627,13 @@ function registerSchemasCommands(program, options = {}) {
|
|
|
12314
12627
|
emitJson11(stdout, "schemas fields delete", data, filePath);
|
|
12315
12628
|
return;
|
|
12316
12629
|
}
|
|
12317
|
-
|
|
12630
|
+
writeLine12(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
|
|
12318
12631
|
});
|
|
12319
12632
|
}
|
|
12320
12633
|
|
|
12321
12634
|
// src/commands/teamspace.ts
|
|
12322
12635
|
import { readFileSync as readFileSync10 } from "fs";
|
|
12323
|
-
import { InvalidArgumentError as
|
|
12636
|
+
import { InvalidArgumentError as InvalidArgumentError11 } from "commander";
|
|
12324
12637
|
|
|
12325
12638
|
// src/api/teamspace.ts
|
|
12326
12639
|
function jsonOptions8(body, method) {
|
|
@@ -12332,7 +12645,7 @@ function jsonOptions8(body, method) {
|
|
|
12332
12645
|
body: JSON.stringify(body)
|
|
12333
12646
|
};
|
|
12334
12647
|
}
|
|
12335
|
-
function
|
|
12648
|
+
function selectorValue11(selector) {
|
|
12336
12649
|
return selector.value;
|
|
12337
12650
|
}
|
|
12338
12651
|
var TeamspaceApi = class {
|
|
@@ -12358,13 +12671,13 @@ var TeamspaceApi = class {
|
|
|
12358
12671
|
}
|
|
12359
12672
|
updateFolder(folder, input) {
|
|
12360
12673
|
return this.client.requestJson(
|
|
12361
|
-
`/api/v2/teamspaces/folders/${
|
|
12674
|
+
`/api/v2/teamspaces/folders/${selectorValue11(folder)}`,
|
|
12362
12675
|
jsonOptions8(input, "PATCH")
|
|
12363
12676
|
);
|
|
12364
12677
|
}
|
|
12365
12678
|
deleteFolder(folder) {
|
|
12366
12679
|
return this.client.requestJson(
|
|
12367
|
-
`/api/v2/teamspaces/folders/${
|
|
12680
|
+
`/api/v2/teamspaces/folders/${selectorValue11(folder)}`,
|
|
12368
12681
|
{ method: "DELETE" }
|
|
12369
12682
|
);
|
|
12370
12683
|
}
|
|
@@ -12383,23 +12696,23 @@ var TeamspaceApi = class {
|
|
|
12383
12696
|
};
|
|
12384
12697
|
|
|
12385
12698
|
// src/commands/teamspace.ts
|
|
12386
|
-
function
|
|
12699
|
+
function getCommandIo13(stdout) {
|
|
12387
12700
|
return stdout ?? process.stdout;
|
|
12388
12701
|
}
|
|
12389
|
-
function
|
|
12702
|
+
function writeLine13(stdout, value) {
|
|
12390
12703
|
stdout.write(`${value}
|
|
12391
12704
|
`);
|
|
12392
12705
|
}
|
|
12393
|
-
function
|
|
12706
|
+
function getGlobalOptions13(command) {
|
|
12394
12707
|
return command.optsWithGlobals();
|
|
12395
12708
|
}
|
|
12396
12709
|
function emitJson12(stdout, commandName, data, configPath) {
|
|
12397
|
-
|
|
12710
|
+
writeLine13(
|
|
12398
12711
|
stdout,
|
|
12399
12712
|
JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
|
|
12400
12713
|
);
|
|
12401
12714
|
}
|
|
12402
|
-
function
|
|
12715
|
+
function toConfigurationError12(filePath, error) {
|
|
12403
12716
|
if (error instanceof CliError) {
|
|
12404
12717
|
throw error;
|
|
12405
12718
|
}
|
|
@@ -12414,7 +12727,7 @@ function toConfigurationError11(filePath, error) {
|
|
|
12414
12727
|
function createTeamspaceApi(command, filePath) {
|
|
12415
12728
|
try {
|
|
12416
12729
|
const config = readRuntimeConfig(filePath);
|
|
12417
|
-
const runtime = resolveRuntimeContext(config,
|
|
12730
|
+
const runtime = resolveRuntimeContext(config, getGlobalOptions13(command));
|
|
12418
12731
|
if (!runtime.baseUrl) {
|
|
12419
12732
|
throw new CliError(
|
|
12420
12733
|
"configuration_error",
|
|
@@ -12432,10 +12745,10 @@ function createTeamspaceApi(command, filePath) {
|
|
|
12432
12745
|
readOnly: runtime.readOnly
|
|
12433
12746
|
};
|
|
12434
12747
|
} catch (error) {
|
|
12435
|
-
|
|
12748
|
+
toConfigurationError12(filePath, error);
|
|
12436
12749
|
}
|
|
12437
12750
|
}
|
|
12438
|
-
function
|
|
12751
|
+
function ensureWritable10(commandName, readOnly, commandMode) {
|
|
12439
12752
|
if (readOnly) {
|
|
12440
12753
|
throw new CliError(
|
|
12441
12754
|
"command_not_allowed_in_read_only_mode",
|
|
@@ -12447,17 +12760,17 @@ function ensureWritable9(commandName, readOnly, commandMode) {
|
|
|
12447
12760
|
);
|
|
12448
12761
|
}
|
|
12449
12762
|
}
|
|
12450
|
-
function
|
|
12763
|
+
function parseUuidOrSlugSelector11(input) {
|
|
12451
12764
|
try {
|
|
12452
12765
|
return normalizeUuidOrSlug(input);
|
|
12453
12766
|
} catch (error) {
|
|
12454
12767
|
const message = error instanceof Error ? error.message : "Invalid selector.";
|
|
12455
|
-
throw new
|
|
12768
|
+
throw new InvalidArgumentError11(message);
|
|
12456
12769
|
}
|
|
12457
12770
|
}
|
|
12458
12771
|
function parseNonNegativeInteger3(input) {
|
|
12459
12772
|
if (!/^\d+$/.test(input.trim())) {
|
|
12460
|
-
throw new
|
|
12773
|
+
throw new InvalidArgumentError11(`Expected a non-negative integer, received "${input}".`);
|
|
12461
12774
|
}
|
|
12462
12775
|
return Number(input);
|
|
12463
12776
|
}
|
|
@@ -12613,7 +12926,7 @@ async function resolveFolderSelector2(api, selector) {
|
|
|
12613
12926
|
}
|
|
12614
12927
|
function registerTeamspaceCommands(program, options = {}) {
|
|
12615
12928
|
const filePath = options.configPath ?? defaultConfigPath;
|
|
12616
|
-
const stdout =
|
|
12929
|
+
const stdout = getCommandIo13(options.stdout);
|
|
12617
12930
|
const teamspace = program.command("teamspace").description("Manage teamspace folders and resources");
|
|
12618
12931
|
const folders = teamspace.command("folders").description("Manage teamspace folders");
|
|
12619
12932
|
folders.command("list").description("List teamspace folders").option("--include-resources", "include the published resources inside each folder").action(async function action(commandOptions) {
|
|
@@ -12625,7 +12938,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
12625
12938
|
}
|
|
12626
12939
|
emitTable5(stdout, data);
|
|
12627
12940
|
});
|
|
12628
|
-
folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name",
|
|
12941
|
+
folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector11).option("--include-resources", "include the published resources inside each folder").action(async function action(folder, commandOptions) {
|
|
12629
12942
|
const { api, json } = createTeamspaceApi(this, filePath);
|
|
12630
12943
|
const resolvedFolder = await resolveFolderSelector2(api, folder);
|
|
12631
12944
|
const allFolders = await api.listFolders(Boolean(commandOptions.includeResources));
|
|
@@ -12638,46 +12951,46 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
12638
12951
|
});
|
|
12639
12952
|
folders.command("create").description("Create a teamspace folder").requiredOption("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)", parseNonNegativeInteger3).option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"icon":"folder-users","color":"gold"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(commandOptions) {
|
|
12640
12953
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
12641
|
-
|
|
12954
|
+
ensureWritable10("teamspace folders create", readOnly, "write");
|
|
12642
12955
|
const data = await api.createFolder(buildFolderCreateInput(commandOptions));
|
|
12643
12956
|
if (json) {
|
|
12644
12957
|
emitJson12(stdout, "teamspace folders create", data, filePath);
|
|
12645
12958
|
return;
|
|
12646
12959
|
}
|
|
12647
|
-
|
|
12960
|
+
writeLine13(stdout, `Created folder "${getFolderIdentifier(data)}".`);
|
|
12648
12961
|
});
|
|
12649
|
-
folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name",
|
|
12962
|
+
folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector11).option("--name <name>", "folder name").option("--order <n>", "display order (lower values appear first)", parseNonNegativeInteger3).option("--props <json>", 'additionalProperties JSON: free-form client metadata, e.g. {"icon":"folder-users","color":"gold"}').option("--props-file <path>", "path to a file with the additionalProperties JSON").action(async function action(folder, commandOptions) {
|
|
12650
12963
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
12651
|
-
|
|
12964
|
+
ensureWritable10("teamspace folders update", readOnly, "write");
|
|
12652
12965
|
const resolvedFolder = await resolveFolderSelector2(api, folder);
|
|
12653
12966
|
const data = await api.updateFolder(resolvedFolder, buildFolderUpdateInput(commandOptions));
|
|
12654
12967
|
if (json) {
|
|
12655
12968
|
emitJson12(stdout, "teamspace folders update", data, filePath);
|
|
12656
12969
|
return;
|
|
12657
12970
|
}
|
|
12658
|
-
|
|
12971
|
+
writeLine13(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
|
|
12659
12972
|
});
|
|
12660
|
-
folders.command("delete").description("Delete a teamspace folder").argument("<folder>", "folder UUID or exact name",
|
|
12973
|
+
folders.command("delete").description("Delete a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector11).action(async function action(folder) {
|
|
12661
12974
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
12662
|
-
|
|
12975
|
+
ensureWritable10("teamspace folders delete", readOnly, "destructive");
|
|
12663
12976
|
const resolvedFolder = await resolveFolderSelector2(api, folder);
|
|
12664
12977
|
const data = await api.deleteFolder(resolvedFolder);
|
|
12665
12978
|
if (json) {
|
|
12666
12979
|
emitJson12(stdout, "teamspace folders delete", data, filePath);
|
|
12667
12980
|
return;
|
|
12668
12981
|
}
|
|
12669
|
-
|
|
12982
|
+
writeLine13(stdout, `Deleted folder "${resolvedFolder.value}".`);
|
|
12670
12983
|
});
|
|
12671
12984
|
const resources = teamspace.command("resources").description("Manage teamspace resources");
|
|
12672
12985
|
resources.command("publish").description(
|
|
12673
12986
|
"Publish a resource to a teamspace folder. Publishing an already-published resource moves it to the new folder."
|
|
12674
|
-
).argument("<resource>", "schema UUID, schema slug, or display UUID",
|
|
12987
|
+
).argument("<resource>", "schema UUID, schema slug, or display UUID", parseUuidOrSlugSelector11).requiredOption(
|
|
12675
12988
|
"--to <folder>",
|
|
12676
12989
|
"target folder UUID or exact name (root folder UUID is 00000000-0000-0000-0000-000000000000)",
|
|
12677
|
-
|
|
12990
|
+
parseUuidOrSlugSelector11
|
|
12678
12991
|
).action(async function action(resource, commandOptions) {
|
|
12679
12992
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
12680
|
-
|
|
12993
|
+
ensureWritable10("teamspace resources publish", readOnly, "write");
|
|
12681
12994
|
const folder = await resolveFolderSelector2(api, commandOptions.to);
|
|
12682
12995
|
const data = await api.publishResource({
|
|
12683
12996
|
resourceId: resource.value,
|
|
@@ -12687,17 +13000,17 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
12687
13000
|
emitJson12(stdout, "teamspace resources publish", data, filePath);
|
|
12688
13001
|
return;
|
|
12689
13002
|
}
|
|
12690
|
-
|
|
13003
|
+
writeLine13(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
|
|
12691
13004
|
});
|
|
12692
|
-
resources.command("unpublish").description("Unpublish a resource from teamspace (removes it from its shared folder)").argument("<resource>", "schema UUID, schema slug, or display UUID",
|
|
13005
|
+
resources.command("unpublish").description("Unpublish a resource from teamspace (removes it from its shared folder)").argument("<resource>", "schema UUID, schema slug, or display UUID", parseUuidOrSlugSelector11).action(async function action(resource) {
|
|
12693
13006
|
const { api, json, readOnly } = createTeamspaceApi(this, filePath);
|
|
12694
|
-
|
|
13007
|
+
ensureWritable10("teamspace resources unpublish", readOnly, "write");
|
|
12695
13008
|
const data = await api.unpublishResource(resource.value);
|
|
12696
13009
|
if (json) {
|
|
12697
13010
|
emitJson12(stdout, "teamspace resources unpublish", data, filePath);
|
|
12698
13011
|
return;
|
|
12699
13012
|
}
|
|
12700
|
-
|
|
13013
|
+
writeLine13(stdout, `Unpublished resource "${resource.value}".`);
|
|
12701
13014
|
});
|
|
12702
13015
|
}
|
|
12703
13016
|
|
|
@@ -12705,7 +13018,7 @@ function registerTeamspaceCommands(program, options = {}) {
|
|
|
12705
13018
|
var require2 = createRequire(import.meta.url);
|
|
12706
13019
|
var { version } = require2("../package.json");
|
|
12707
13020
|
function buildProgram(options = {}) {
|
|
12708
|
-
const program = new
|
|
13021
|
+
const program = new Command12();
|
|
12709
13022
|
program.name("zinkee").description("CLI for Zinkee API v2").version(version).enablePositionalOptions().showHelpAfterError().option("--profile <name>", "select a profile from config").option("--base-url <url>", "override the configured base URL").option("--api-key <token>", "override the configured API key").option("--read-only", "run in read-only mode").option("--example", "show examples for a command").option("--json", "emit JSON output").option("--install-completion [shell]", "install shell completion (bash, zsh, fish, powershell)").option("--show-completion [shell]", "print shell completion script for the current shell");
|
|
12710
13023
|
registerProfilesCommands(program, options);
|
|
12711
13024
|
registerAutomationsCommands(program, options);
|
|
@@ -12713,6 +13026,7 @@ function buildProgram(options = {}) {
|
|
|
12713
13026
|
registerDisplaysCommands(program, options);
|
|
12714
13027
|
registerDocumentTemplatesCommands(program, options);
|
|
12715
13028
|
registerFilesCommands(program, options);
|
|
13029
|
+
registerFormulasCommands(program, options);
|
|
12716
13030
|
registerNavigationCommands(program, options);
|
|
12717
13031
|
registerSchemasCommands(program, options);
|
|
12718
13032
|
registerRecordsCommands(program, options);
|