@erdoai/cli 0.100.0 → 0.101.1
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 +43 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1072,22 +1072,27 @@ 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
|
-
// `clear_purpose` to remove it
|
|
1088
|
-
//
|
|
1089
|
-
//
|
|
1090
|
-
//
|
|
1090
|
+
// `clear_purpose` to remove it. Setting a purpose another dataset carries is
|
|
1091
|
+
// an atomic MOVE — the old carrier is cleared in the same transaction — and
|
|
1092
|
+
// the response warns naming the dataset it moved from. Pass
|
|
1093
|
+
// `purpose_sibling: true` only to declare a deliberate parallel carrier (a
|
|
1094
|
+
// separate program a human chose to run), which leaves the other carriers
|
|
1095
|
+
// alone.
|
|
1091
1096
|
setDatasetPurpose(slug, input) {
|
|
1092
1097
|
return this.request("POST", `/v1/datasets/${encodeURIComponent(slug)}/schema`, input);
|
|
1093
1098
|
}
|
|
@@ -6097,7 +6102,7 @@ datasetsCmd.command("list").description("List datasets").option(
|
|
|
6097
6102
|
}
|
|
6098
6103
|
});
|
|
6099
6104
|
datasetsCmd.command("purposes").description(
|
|
6100
|
-
"List the org's dataset purposes \u2014 the vocabulary of dataset roles in use (e.g. leads, page events).
|
|
6105
|
+
"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
6106
|
).option(
|
|
6102
6107
|
"--scope <own|managed>",
|
|
6103
6108
|
"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 +6119,7 @@ datasetsCmd.command("purposes").description(
|
|
|
6114
6119
|
return;
|
|
6115
6120
|
}
|
|
6116
6121
|
for (const p of purposes) {
|
|
6117
|
-
const target = p.
|
|
6122
|
+
const target = p.dataset_count > 1 ? `(split: ${p.dataset_count} datasets)` : p.dataset_slug ?? p.dataset_id ?? "(unbound)";
|
|
6118
6123
|
const count = `${p.dataset_count} dataset${p.dataset_count === 1 ? "" : "s"}`;
|
|
6119
6124
|
console.log(
|
|
6120
6125
|
scope === "managed" ? `${p.organization_slug ?? "-"} ${p.purpose} ${target} ${count} ${p.description}` : `${p.purpose} ${target} ${count} ${p.description}`
|
|
@@ -6124,9 +6129,36 @@ datasetsCmd.command("purposes").description(
|
|
|
6124
6129
|
fail(e);
|
|
6125
6130
|
}
|
|
6126
6131
|
});
|
|
6132
|
+
datasetsCmd.command("ensure <purpose>").description(
|
|
6133
|
+
"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."
|
|
6134
|
+
).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) => {
|
|
6135
|
+
try {
|
|
6136
|
+
const parsed = JSON.parse(readFileSync4(opts.schema, "utf8"));
|
|
6137
|
+
const declaredSchema = Array.isArray(parsed) ? { columns: parsed } : parsed;
|
|
6138
|
+
if (!declaredSchema || !Array.isArray(declaredSchema.columns)) {
|
|
6139
|
+
throw new Error('--schema must contain a JSON columns array or {"columns": [...]} object');
|
|
6140
|
+
}
|
|
6141
|
+
const result = await new ErdoClient().ensureDataset({
|
|
6142
|
+
purpose,
|
|
6143
|
+
...opts.name ? { name: opts.name } : {},
|
|
6144
|
+
...opts.description ? { description: opts.description } : {},
|
|
6145
|
+
...opts.purposeDescription ? { purpose_description: opts.purposeDescription } : {},
|
|
6146
|
+
...opts.preferredDataset ? { preferred_dataset: opts.preferredDataset } : {},
|
|
6147
|
+
...opts.emailColumn ? { email_column: opts.emailColumn } : {},
|
|
6148
|
+
...opts.phoneColumn ? { phone_column: opts.phoneColumn } : {},
|
|
6149
|
+
declared_schema: declaredSchema
|
|
6150
|
+
});
|
|
6151
|
+
console.log(`${result.slug} ${result.created ? "created" : "reused"} ${result.purpose}`);
|
|
6152
|
+
} catch (e) {
|
|
6153
|
+
fail(e);
|
|
6154
|
+
}
|
|
6155
|
+
});
|
|
6127
6156
|
datasetsCmd.command("set-purpose <slug> [purpose]").description(
|
|
6128
|
-
"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.
|
|
6157
|
+
"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. Setting a purpose another dataset carries is an atomic MOVE: the old carrier is cleared in the same transaction, so one call on the right dataset lands it (the response says which dataset it moved from). Use --sibling only when deliberately running a parallel table for the same purpose."
|
|
6129
6158
|
).option("--clear", "remove the dataset's purpose instead of setting one").option(
|
|
6159
|
+
"--sibling",
|
|
6160
|
+
"declare this dataset a deliberate parallel carrier of the purpose (a separate program a human chose to run) instead of moving the purpose off other datasets"
|
|
6161
|
+
).option(
|
|
6130
6162
|
"--description <text>",
|
|
6131
6163
|
"description for a purpose new to this org; ignored when the org already has an entry for it"
|
|
6132
6164
|
).action(async (slug, purpose, opts) => {
|
|
@@ -6142,6 +6174,7 @@ datasetsCmd.command("set-purpose <slug> [purpose]").description(
|
|
|
6142
6174
|
const res = await new ErdoClient().setDatasetPurpose(slug, {
|
|
6143
6175
|
...purpose ? { purpose } : {},
|
|
6144
6176
|
...opts.clear ? { clear_purpose: true } : {},
|
|
6177
|
+
...opts.sibling ? { purpose_sibling: true } : {},
|
|
6145
6178
|
...opts.description ? { purpose_description: opts.description } : {}
|
|
6146
6179
|
});
|
|
6147
6180
|
for (const w of res.warnings ?? []) console.error(`warning: ${w}`);
|