conduyt 1.22.0 → 1.23.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/client.js +19 -0
- package/dist/index.js +60 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -56,6 +56,25 @@ export class ConduytClient {
|
|
|
56
56
|
del(path) {
|
|
57
57
|
return this.request("DELETE", path);
|
|
58
58
|
}
|
|
59
|
+
/** A POST whose body comes back as text (a CSV or XLSX export), not JSON. */
|
|
60
|
+
async postText(path, body) {
|
|
61
|
+
const url = `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
|
|
62
|
+
const res = await fetch(url, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" },
|
|
65
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
66
|
+
});
|
|
67
|
+
const text = await res.text();
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
let msg = text.slice(0, 500);
|
|
70
|
+
try {
|
|
71
|
+
msg = JSON.parse(text).error ?? msg;
|
|
72
|
+
}
|
|
73
|
+
catch { /* keep the raw text */ }
|
|
74
|
+
throw new Error(`Conduyt API ${res.status}: ${msg}`);
|
|
75
|
+
}
|
|
76
|
+
return { text, filename: res.headers.get("x-report-filename"), contentType: res.headers.get("content-type") };
|
|
77
|
+
}
|
|
59
78
|
// Stream `ai chat`'s text/event-stream response to stdout as clean answer
|
|
60
79
|
// text. The server frames SSE records as `data: {"text":"..."}\n\n`, ends
|
|
61
80
|
// with `data: [DONE]\n\n`, and reports in-stream failures as
|
package/dist/index.js
CHANGED
|
@@ -2221,6 +2221,66 @@ ringGroups
|
|
|
2221
2221
|
// Smart Dialing priorities: agents dial them one lead at a time, top to
|
|
2222
2222
|
// bottom. Dialing settings + reorder are admin-only in the API.
|
|
2223
2223
|
// ---------------------------------------------------------------------------
|
|
2224
|
+
// ── Custom reports: the Lead Activity grid (reporting P1, 2026-09-10) ──────────────────────────────────────────────
|
|
2225
|
+
const reports = program.command("reports").description("Custom reports: the Lead Activity grid (rollups, custom fields, Smart View populations, CSV/XLSX export)");
|
|
2226
|
+
reports
|
|
2227
|
+
.command("fields <entity>")
|
|
2228
|
+
.description("The field catalogue for a report base: columns, per-lead rollups (contacts/deals) and the account's custom fields (cf:<key>)")
|
|
2229
|
+
.option("--kind <kind>", "only base | rollup | custom")
|
|
2230
|
+
.action(run(async (client, entity, opts) => {
|
|
2231
|
+
const res = (await client.get(`/api/v1/reports/custom/fields?entity=${encodeURIComponent(entity)}`));
|
|
2232
|
+
const fields = Array.isArray(res?.fields) ? res.fields : [];
|
|
2233
|
+
return opts.kind ? fields.filter((f) => f.kind === opts.kind) : fields;
|
|
2234
|
+
}));
|
|
2235
|
+
reports
|
|
2236
|
+
.command("list")
|
|
2237
|
+
.description("List saved custom reports (shared and your own) with their last-run status")
|
|
2238
|
+
.action(run(async (client) => client.get("/api/v1/reports/custom")));
|
|
2239
|
+
reports
|
|
2240
|
+
.command("create")
|
|
2241
|
+
.description("Create a saved report from a JSON definition (name, entity, columns, filters, sortBy, groupBy, groupBy2, aggregate, measureField, population: { smartViewId })")
|
|
2242
|
+
.requiredOption("--json <definition>", "the definition as JSON (or @file)")
|
|
2243
|
+
.action(run(async (client, opts) => {
|
|
2244
|
+
const raw = opts.json.startsWith("@") ? (await import("node:fs")).readFileSync(opts.json.slice(1), "utf8") : opts.json;
|
|
2245
|
+
const body = JSON.parse(raw);
|
|
2246
|
+
if (typeof body.name !== "string" || typeof body.entity !== "string" || !Array.isArray(body.columns)) {
|
|
2247
|
+
throw new Error("The definition needs name, entity and columns.");
|
|
2248
|
+
}
|
|
2249
|
+
return client.post("/api/v1/reports/custom", body);
|
|
2250
|
+
}));
|
|
2251
|
+
reports
|
|
2252
|
+
.command("run <id>")
|
|
2253
|
+
.description("Run a saved report: a page of rows, the total, the metric, the chart data and (with groupBy2) the grouped rows")
|
|
2254
|
+
.option("--page <n>", "page number", "1")
|
|
2255
|
+
.option("--per-page <n>", "rows per page (1-500)", "100")
|
|
2256
|
+
.action(run(async (client, id, opts) => {
|
|
2257
|
+
assertUuid(id, "report id");
|
|
2258
|
+
const params = new URLSearchParams({ page: String(Math.max(1, Number(opts.page) || 1)), per_page: String(Math.min(500, Math.max(1, Number(opts.perPage) || 100))) });
|
|
2259
|
+
return client.post(`/api/v1/reports/custom/${id}/run?${params.toString()}`, {});
|
|
2260
|
+
}));
|
|
2261
|
+
reports
|
|
2262
|
+
.command("export <id>")
|
|
2263
|
+
.description("Export every matching row (up to 50,000) as CSV or XLSX; prints to stdout or writes --out")
|
|
2264
|
+
.option("--format <format>", "csv | xlsx", "csv")
|
|
2265
|
+
.option("--out <file>", "write the file here instead of stdout")
|
|
2266
|
+
.action(async (id, opts) => {
|
|
2267
|
+
try {
|
|
2268
|
+
assertUuid(id, "report id");
|
|
2269
|
+
const format = opts.format === "xlsx" ? "xlsx" : "csv";
|
|
2270
|
+
const client = new ConduytClient();
|
|
2271
|
+
const { text, filename } = await client.postText(`/api/v1/reports/custom/${id}/export?format=${format}`, {});
|
|
2272
|
+
if (opts.out) {
|
|
2273
|
+
(await import("node:fs")).writeFileSync(opts.out, text);
|
|
2274
|
+
print({ written: opts.out, bytes: Buffer.byteLength(text), filename });
|
|
2275
|
+
}
|
|
2276
|
+
else {
|
|
2277
|
+
process.stdout.write(text);
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
catch (err) {
|
|
2281
|
+
fail(err);
|
|
2282
|
+
}
|
|
2283
|
+
});
|
|
2224
2284
|
const smartViews = program.command("smart-views").description("Smart Views and their Smart Dialing priorities");
|
|
2225
2285
|
smartViews
|
|
2226
2286
|
.command("list")
|
package/package.json
CHANGED