@erdoai/cli 0.99.0 → 0.101.0
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/dist/index.js +48 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1072,17 +1072,20 @@ var ErdoClient = class {
|
|
|
1072
1072
|
const qs = q.toString();
|
|
1073
1073
|
return this.request("GET", `/v1/datasets${qs ? `?${qs}` : ""}`);
|
|
1074
1074
|
}
|
|
1075
|
-
// The org's dataset vocabulary: every purpose in use, its
|
|
1076
|
-
//
|
|
1075
|
+
// The org's dataset vocabulary: every purpose in use, its current dataset,
|
|
1076
|
+
// and the declared producer contract on that same dataset.
|
|
1077
1077
|
// scope="managed" reads the same across every client organization a manager
|
|
1078
1078
|
// account operates; each entry then names its organization and its
|
|
1079
|
-
//
|
|
1079
|
+
// current dataset slug is org-qualified, so it can be queried as-is.
|
|
1080
1080
|
listDatasetPurposes(params) {
|
|
1081
1081
|
const q = new URLSearchParams();
|
|
1082
1082
|
if (params?.scope) q.set("scope", params.scope);
|
|
1083
1083
|
const qs = q.toString();
|
|
1084
1084
|
return this.request("GET", `/v1/datasets-purposes${qs ? `?${qs}` : ""}`);
|
|
1085
1085
|
}
|
|
1086
|
+
ensureDataset(input) {
|
|
1087
|
+
return this.request("POST", "/v1/datasets-ensure", input);
|
|
1088
|
+
}
|
|
1086
1089
|
// Correct which dataset carries a purpose. Pass `purpose` to set one,
|
|
1087
1090
|
// `clear_purpose` to remove it; moving a purpose is clearing it from the old
|
|
1088
1091
|
// dataset and setting it on the right one. Setting a purpose the org already
|
|
@@ -4132,7 +4135,7 @@ function renderDecision(detail) {
|
|
|
4132
4135
|
["class", d.decision_class],
|
|
4133
4136
|
["source", d.source],
|
|
4134
4137
|
["applies", d.applicability === "standing" ? "standing (until superseded)" : "one-off authorization"],
|
|
4135
|
-
["decided by", d.decider_kind]
|
|
4138
|
+
["decided by", d.decided_by_name ? `${d.decided_by_name} (${d.decider_kind})` : d.decider_kind]
|
|
4136
4139
|
];
|
|
4137
4140
|
if (d.subject_label) facts.push(["subject", d.subject_label]);
|
|
4138
4141
|
if (d.execution_status) facts.push(["execution", d.execution_status]);
|
|
@@ -4545,7 +4548,7 @@ function renderAttentionItemReport(item, report) {
|
|
|
4545
4548
|
console.log(` ${d.slug} \u2014 ${d.what}`);
|
|
4546
4549
|
if (d.why) console.log(` why: ${d.why}`);
|
|
4547
4550
|
if (d.alternatives_considered) console.log(` alternatives considered: ${d.alternatives_considered}`);
|
|
4548
|
-
console.log(` decided by: ${d.decider_kind}`);
|
|
4551
|
+
console.log(` decided by: ${d.decided_by_name ? `${d.decided_by_name} (${d.decider_kind})` : d.decider_kind}`);
|
|
4549
4552
|
console.log(` status: ${d.status}`);
|
|
4550
4553
|
if (d.outcome_label) console.log(` outcome: ${d.outcome_label}`);
|
|
4551
4554
|
} else {
|
|
@@ -6097,7 +6100,7 @@ datasetsCmd.command("list").description("List datasets").option(
|
|
|
6097
6100
|
}
|
|
6098
6101
|
});
|
|
6099
6102
|
datasetsCmd.command("purposes").description(
|
|
6100
|
-
"List the org's dataset purposes \u2014 the vocabulary of dataset roles in use (e.g. leads, page events).
|
|
6103
|
+
"List the org's dataset purposes \u2014 the vocabulary of dataset roles in use (e.g. leads, page events). Each purpose resolves to the current dataset and its declared schema: write there rather than creating a sibling (one purpose = one dataset per org)."
|
|
6101
6104
|
).option(
|
|
6102
6105
|
"--scope <own|managed>",
|
|
6103
6106
|
"whose vocabulary to read: own (default) or managed, which reads every client organization a manager account operates and prints the organization alongside each purpose"
|
|
@@ -6114,7 +6117,7 @@ datasetsCmd.command("purposes").description(
|
|
|
6114
6117
|
return;
|
|
6115
6118
|
}
|
|
6116
6119
|
for (const p of purposes) {
|
|
6117
|
-
const target = p.
|
|
6120
|
+
const target = p.dataset_count > 1 ? `(split: ${p.dataset_count} datasets)` : p.dataset_slug ?? p.dataset_id ?? "(unbound)";
|
|
6118
6121
|
const count = `${p.dataset_count} dataset${p.dataset_count === 1 ? "" : "s"}`;
|
|
6119
6122
|
console.log(
|
|
6120
6123
|
scope === "managed" ? `${p.organization_slug ?? "-"} ${p.purpose} ${target} ${count} ${p.description}` : `${p.purpose} ${target} ${count} ${p.description}`
|
|
@@ -6124,6 +6127,30 @@ datasetsCmd.command("purposes").description(
|
|
|
6124
6127
|
fail(e);
|
|
6125
6128
|
}
|
|
6126
6129
|
});
|
|
6130
|
+
datasetsCmd.command("ensure <purpose>").description(
|
|
6131
|
+
"Create or reuse the one dataset for a purpose and verify its declared producer contract. Refuses legacy splits and incompatible populated datasets instead of choosing silently."
|
|
6132
|
+
).requiredOption("--schema <file>", "JSON file containing { columns: [...] } or a columns array").option("--name <name>", "dataset name when creation is required").option("--description <text>", "dataset description when creation is required").option("--purpose-description <text>", "what writes and reads this purpose").option("--preferred-dataset <slug>", "existing bound dataset slug or id to adopt").option("--email-column <name>", "for a leads purpose: which declared column holds the email (default email)").option("--phone-column <name>", "for a leads purpose: which declared column holds the phone (default phone)").action(async (purpose, opts) => {
|
|
6133
|
+
try {
|
|
6134
|
+
const parsed = JSON.parse(readFileSync4(opts.schema, "utf8"));
|
|
6135
|
+
const declaredSchema = Array.isArray(parsed) ? { columns: parsed } : parsed;
|
|
6136
|
+
if (!declaredSchema || !Array.isArray(declaredSchema.columns)) {
|
|
6137
|
+
throw new Error('--schema must contain a JSON columns array or {"columns": [...]} object');
|
|
6138
|
+
}
|
|
6139
|
+
const result = await new ErdoClient().ensureDataset({
|
|
6140
|
+
purpose,
|
|
6141
|
+
...opts.name ? { name: opts.name } : {},
|
|
6142
|
+
...opts.description ? { description: opts.description } : {},
|
|
6143
|
+
...opts.purposeDescription ? { purpose_description: opts.purposeDescription } : {},
|
|
6144
|
+
...opts.preferredDataset ? { preferred_dataset: opts.preferredDataset } : {},
|
|
6145
|
+
...opts.emailColumn ? { email_column: opts.emailColumn } : {},
|
|
6146
|
+
...opts.phoneColumn ? { phone_column: opts.phoneColumn } : {},
|
|
6147
|
+
declared_schema: declaredSchema
|
|
6148
|
+
});
|
|
6149
|
+
console.log(`${result.slug} ${result.created ? "created" : "reused"} ${result.purpose}`);
|
|
6150
|
+
} catch (e) {
|
|
6151
|
+
fail(e);
|
|
6152
|
+
}
|
|
6153
|
+
});
|
|
6127
6154
|
datasetsCmd.command("set-purpose <slug> [purpose]").description(
|
|
6128
6155
|
"Set (or with --clear, remove) the dataset's purpose \u2014 the org-vocabulary role `datasets purposes` reports. Use it to CORRECT a purpose that names the wrong dataset: one purpose maps to one dataset per org, so a purpose left on the wrong one points everything that resolves through the vocabulary at the wrong rows. Moving a purpose is two calls \u2014 clear it from the old dataset, set it on the right one. Setting a purpose the org already uses elsewhere succeeds and prints a warning naming what it now shadows."
|
|
6129
6156
|
).option("--clear", "remove the dataset's purpose instead of setting one").option(
|
|
@@ -7432,7 +7459,7 @@ pipelinesCmd.command("get <slug>").description("Show one event pipeline \u2014 s
|
|
|
7432
7459
|
});
|
|
7433
7460
|
pipelinesCmd.command("update <slug>").description(
|
|
7434
7461
|
"Update an event pipeline's editable fields \u2014 omitted fields keep their current values (merge). Use get first for the current transform/actions; --transform-js/--pipeline accept @file"
|
|
7435
|
-
).option("--name <name>", "new name").option("--description <description>", "new description").option("--state <state>", "new state: active, disabled, or proposed").option("--transform-js <jsOr@file>", "new transform \u2014 function transform(event) { \u2026 } (or @path to a file)").option(
|
|
7462
|
+
).option("--name <name>", "new name").option("--description <description>", "new description").option("--state <state>", "new state: active, disabled, or proposed").option("--transform-js <jsOr@file>", "new transform \u2014 function transform(event) { \u2026 } (or @path to a file)").option("--turnstile <jsonOr@file>", `optional managed form protection settings; use @file for widget credentials, or '{"enabled":false}' to disable`).option(
|
|
7436
7463
|
"--pipeline <jsonOr@file>",
|
|
7437
7464
|
`replacement ordered actions array as JSON (or @path to a file), e.g. '[{"type":"dataset.write","key_column":"email","dataset_slug":"acme-leads"}]'`
|
|
7438
7465
|
).action(
|
|
@@ -7441,6 +7468,18 @@ pipelinesCmd.command("update <slug>").description(
|
|
|
7441
7468
|
if (opts.name !== void 0) body.name = opts.name;
|
|
7442
7469
|
if (opts.description !== void 0) body.description = opts.description;
|
|
7443
7470
|
if (opts.state !== void 0) body.state = opts.state;
|
|
7471
|
+
const turnstileRaw = readMaybeFile(opts.turnstile);
|
|
7472
|
+
if (turnstileRaw !== void 0) {
|
|
7473
|
+
try {
|
|
7474
|
+
const protection = JSON.parse(turnstileRaw);
|
|
7475
|
+
if (!protection || Array.isArray(protection) || typeof protection !== "object" || typeof protection.enabled !== "boolean") {
|
|
7476
|
+
throw new Error("invalid settings");
|
|
7477
|
+
}
|
|
7478
|
+
body.turnstile = protection;
|
|
7479
|
+
} catch {
|
|
7480
|
+
fail(new Error("--turnstile must be a JSON object with an enabled boolean"));
|
|
7481
|
+
}
|
|
7482
|
+
}
|
|
7444
7483
|
const transformJs = readMaybeFile(opts.transformJs);
|
|
7445
7484
|
if (transformJs !== void 0) body.transform_js = transformJs;
|
|
7446
7485
|
const pipelineRaw = readMaybeFile(opts.pipeline);
|
|
@@ -7456,7 +7495,7 @@ pipelinesCmd.command("update <slug>").description(
|
|
|
7456
7495
|
if (Object.keys(body).length === 0) {
|
|
7457
7496
|
fail(
|
|
7458
7497
|
new Error(
|
|
7459
|
-
"nothing to update \u2014 pass at least one of --name, --description, --state, --transform-js, --pipeline"
|
|
7498
|
+
"nothing to update \u2014 pass at least one of --name, --description, --state, --transform-js, --pipeline, --turnstile"
|
|
7460
7499
|
)
|
|
7461
7500
|
);
|
|
7462
7501
|
}
|