conduyt 1.2.0 → 1.3.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 +36 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6,6 +6,17 @@ import { Command } from "commander";
|
|
|
6
6
|
import { ConduytClient, buildQuery } from "./client.js";
|
|
7
7
|
import { saveConfig, resolveConfig, configPath } from "./config.js";
|
|
8
8
|
import { print, fail } from "./output.js";
|
|
9
|
+
// Exit cleanly when a downstream pipe closes early (e.g. `conduyt deals list |
|
|
10
|
+
// head`). Without this, the stdout write after the reader is gone throws an
|
|
11
|
+
// unhandled EPIPE and prints a Node stack trace — broken-pipe is normal Unix
|
|
12
|
+
// behavior, not an error. Mirror it on stderr too.
|
|
13
|
+
for (const stream of [process.stdout, process.stderr]) {
|
|
14
|
+
stream.on("error", (err) => {
|
|
15
|
+
if (err.code === "EPIPE")
|
|
16
|
+
process.exit(0);
|
|
17
|
+
throw err;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
9
20
|
// Derive the version from package.json at runtime so `--version` can never
|
|
10
21
|
// drift from the published package (dist/index.js -> ../package.json). Read at
|
|
11
22
|
// top level runs on every invocation, so fall back gracefully rather than
|
|
@@ -88,6 +99,13 @@ contacts
|
|
|
88
99
|
Object.assign(body, jsonArg(opts.json, "--json"));
|
|
89
100
|
return client.post("/api/v1/contacts", body);
|
|
90
101
|
}));
|
|
102
|
+
contacts
|
|
103
|
+
.command("delete <id>")
|
|
104
|
+
.description("Delete a contact by id (soft-delete; retained for audit, the contact's deals are unaffected)")
|
|
105
|
+
.action(run(async (client, id) => {
|
|
106
|
+
assertUuid(id, "contact id");
|
|
107
|
+
return client.del(`/api/v1/contacts/${encodeURIComponent(id)}`);
|
|
108
|
+
}));
|
|
91
109
|
// ---- deals ----
|
|
92
110
|
const deals = program.command("deals").description("Manage deals");
|
|
93
111
|
deals
|
|
@@ -254,6 +272,13 @@ deals
|
|
|
254
272
|
assertFiniteValue(body.value);
|
|
255
273
|
return client.post("/api/v1/deals", body);
|
|
256
274
|
}));
|
|
275
|
+
deals
|
|
276
|
+
.command("delete <id>")
|
|
277
|
+
.description("Delete a deal by id (soft-delete; drops out of lists/boards and pipeline totals, retained for audit)")
|
|
278
|
+
.action(run(async (client, id) => {
|
|
279
|
+
assertUuid(id, "deal id");
|
|
280
|
+
return client.del(`/api/v1/deals/${encodeURIComponent(id)}`);
|
|
281
|
+
}));
|
|
257
282
|
// ---- pipelines ----
|
|
258
283
|
// Default action preserves the original published `conduyt pipelines` (list)
|
|
259
284
|
// invocation now that pipelines is a group — without it, commander prints help
|
|
@@ -474,6 +499,17 @@ function assertFiniteValue(v) {
|
|
|
474
499
|
throw new Error("value must be a finite number.");
|
|
475
500
|
}
|
|
476
501
|
}
|
|
502
|
+
// Validate an id is a UUID before it is interpolated into a DELETE path, so a
|
|
503
|
+
// malformed value with slashes can't form a different (destructive) subroute.
|
|
504
|
+
// The path is also URL-encoded at the call site as defence in depth. The regex
|
|
505
|
+
// is inlined (not a module-level const) so it isn't in the temporal dead zone
|
|
506
|
+
// when an action callback runs during program.parse().
|
|
507
|
+
function assertUuid(id, label = "id") {
|
|
508
|
+
const uuidRe = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
509
|
+
if (!uuidRe.test(id.trim())) {
|
|
510
|
+
throw new Error(`${label} must be a UUID.`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
477
513
|
// Reject prototype-polluting keys in untrusted JSON. JSON.parse creates an OWN
|
|
478
514
|
// "__proto__" property, but Object.assign'ing it onto a {} body invokes the
|
|
479
515
|
// setter and changes the body's PROTOTYPE — so a validator could read an
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conduyt",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Command-line interface for Conduyt CRM
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Command-line interface for Conduyt CRM — manage contacts, deals, pipelines, and run insight queries from your terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|