conduyt 1.2.1 → 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 +25 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -99,6 +99,13 @@ contacts
|
|
|
99
99
|
Object.assign(body, jsonArg(opts.json, "--json"));
|
|
100
100
|
return client.post("/api/v1/contacts", body);
|
|
101
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
|
+
}));
|
|
102
109
|
// ---- deals ----
|
|
103
110
|
const deals = program.command("deals").description("Manage deals");
|
|
104
111
|
deals
|
|
@@ -265,6 +272,13 @@ deals
|
|
|
265
272
|
assertFiniteValue(body.value);
|
|
266
273
|
return client.post("/api/v1/deals", body);
|
|
267
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
|
+
}));
|
|
268
282
|
// ---- pipelines ----
|
|
269
283
|
// Default action preserves the original published `conduyt pipelines` (list)
|
|
270
284
|
// invocation now that pipelines is a group — without it, commander prints help
|
|
@@ -485,6 +499,17 @@ function assertFiniteValue(v) {
|
|
|
485
499
|
throw new Error("value must be a finite number.");
|
|
486
500
|
}
|
|
487
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
|
+
}
|
|
488
513
|
// Reject prototype-polluting keys in untrusted JSON. JSON.parse creates an OWN
|
|
489
514
|
// "__proto__" property, but Object.assign'ing it onto a {} body invokes the
|
|
490
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": {
|