@opsrev/acculynx-cli 1.11.0 → 1.12.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.
@@ -13,12 +13,61 @@ function getConfig(options) {
13
13
  };
14
14
  }
15
15
 
16
+ // src/sanitize.ts
17
+ var PUNCTUATION = {
18
+ "\u2012": "-",
19
+ // figure dash
20
+ "\u2013": "-",
21
+ // en dash
22
+ "\u2014": "-",
23
+ // em dash
24
+ "\u2015": "-",
25
+ // horizontal bar
26
+ "\u2018": "'",
27
+ // left single quote
28
+ "\u2019": "'",
29
+ // right single quote
30
+ "\u2032": "'",
31
+ // prime
32
+ "\u201C": '"',
33
+ // left double quote
34
+ "\u201D": '"',
35
+ // right double quote
36
+ "\u2033": '"'
37
+ // double prime
38
+ };
39
+ var PUNCTUATION_RE = new RegExp(`[${Object.keys(PUNCTUATION).join("")}]`, "g");
40
+ function toAscii(s) {
41
+ return s.replace(PUNCTUATION_RE, (ch) => PUNCTUATION[ch]).normalize("NFKD").replace(/[̀-ͯ]/g, "").replace(/[^\x00-\x7F]/g, "").replace(/ {2,}/g, " ").trim();
42
+ }
43
+ function sanitizeDeep(value) {
44
+ if (typeof value === "string") return toAscii(value);
45
+ if (Array.isArray(value)) return value.map(sanitizeDeep);
46
+ if (value !== null && typeof value === "object") {
47
+ const out = {};
48
+ for (const [key, v] of Object.entries(value)) out[key] = sanitizeDeep(v);
49
+ return out;
50
+ }
51
+ return value;
52
+ }
53
+
16
54
  // src/api-client.ts
17
55
  var MAX_RETRIES = 3;
18
56
  var INITIAL_DELAY_MS = 1e3;
19
57
  async function sleep(ms) {
20
58
  return new Promise((resolve) => setTimeout(resolve, ms));
21
59
  }
60
+ function sanitizeForm(form) {
61
+ const out = new FormData();
62
+ for (const [key, value] of form.entries()) {
63
+ if (typeof value === "string") {
64
+ out.append(key, toAscii(value));
65
+ } else {
66
+ out.append(key, value, toAscii(value.name) || "file");
67
+ }
68
+ }
69
+ return out;
70
+ }
22
71
  async function fetchWithRetry(url, init, retries = MAX_RETRIES) {
23
72
  const response = await fetch(url, init);
24
73
  if (response.status === 429 && retries > 0) {
@@ -53,7 +102,7 @@ function createApiClient(config) {
53
102
  const response = await fetchWithRetry(url, {
54
103
  method: "POST",
55
104
  headers: { ...headers, "Content-Type": "application/json" },
56
- body: JSON.stringify(body)
105
+ body: JSON.stringify(sanitizeDeep(body))
57
106
  });
58
107
  if (!response.ok) {
59
108
  const text2 = await response.text();
@@ -70,7 +119,7 @@ function createApiClient(config) {
70
119
  const response = await fetchWithRetry(url, {
71
120
  method: "POST",
72
121
  headers: formHeaders,
73
- body
122
+ body: sanitizeForm(body)
74
123
  });
75
124
  if (!response.ok) {
76
125
  const text2 = await response.text();
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ import {
33
33
  ping,
34
34
  readStdin,
35
35
  usersList
36
- } from "./chunk-FEKZ3BED.js";
36
+ } from "./chunk-GAJNPAO3.js";
37
37
 
38
38
  // src/index.ts
39
39
  import { createRequire } from "module";
package/dist/mcp.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  jobsList,
33
33
  ping,
34
34
  usersList
35
- } from "./chunk-FEKZ3BED.js";
35
+ } from "./chunk-GAJNPAO3.js";
36
36
 
37
37
  // src/mcp.ts
38
38
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opsrev/acculynx-cli",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "CLI for the AccuLynx roofing CRM API",
5
5
  "type": "module",
6
6
  "bin": {