@energio/holded-mcp 1.3.0 → 1.5.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/README.md +33 -5
- package/dist/index.js +1 -1
- package/dist/schemas/common.d.ts +6 -12
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/common.js +7 -10
- package/dist/schemas/common.js.map +1 -1
- package/dist/schemas/crm/funnels.d.ts +1 -4
- package/dist/schemas/crm/funnels.d.ts.map +1 -1
- package/dist/schemas/crm/leads.d.ts +1 -4
- package/dist/schemas/crm/leads.d.ts.map +1 -1
- package/dist/schemas/invoicing/attachment-input.d.ts.map +1 -1
- package/dist/schemas/invoicing/attachment-input.js +0 -1
- package/dist/schemas/invoicing/attachment-input.js.map +1 -1
- package/dist/schemas/invoicing/documents.d.ts +2 -9
- package/dist/schemas/invoicing/documents.d.ts.map +1 -1
- package/dist/schemas/invoicing/documents.js +23 -3
- package/dist/schemas/invoicing/documents.js.map +1 -1
- package/dist/tools/crm/funnels.d.ts.map +1 -1
- package/dist/tools/crm/funnels.js +13 -1
- package/dist/tools/crm/funnels.js.map +1 -1
- package/dist/tools/crm/leads.d.ts.map +1 -1
- package/dist/tools/crm/leads.js +14 -1
- package/dist/tools/crm/leads.js.map +1 -1
- package/dist/tools/factory.d.ts +15 -0
- package/dist/tools/factory.d.ts.map +1 -1
- package/dist/tools/factory.js +19 -9
- package/dist/tools/factory.js.map +1 -1
- package/dist/tools/invoicing/contacts.d.ts.map +1 -1
- package/dist/tools/invoicing/contacts.js +2 -0
- package/dist/tools/invoicing/contacts.js.map +1 -1
- package/dist/tools/invoicing/documents.d.ts.map +1 -1
- package/dist/tools/invoicing/documents.js +52 -2
- package/dist/tools/invoicing/documents.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/custom-fields.d.ts +66 -0
- package/dist/utils/custom-fields.d.ts.map +1 -0
- package/dist/utils/custom-fields.js +133 -0
- package/dist/utils/custom-fields.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom-fields map serialization and repair.
|
|
3
|
+
*
|
|
4
|
+
* Holded's `POST /documents/{docType}` and `POST|PUT /contacts[{id}]` endpoints
|
|
5
|
+
* decompose each `customFields` entry via their own `Object.entries` — every
|
|
6
|
+
* own-prop becomes a separate `{field: <key>, value: <val>}` row. The single
|
|
7
|
+
* reliable workaround is to send one own-prop per entry: `[{"src":"val"}]` →
|
|
8
|
+
* Holded unpacks to `[{field:"src", value:"val"}]`.
|
|
9
|
+
*
|
|
10
|
+
* Other endpoints behave normally and accept the documented `[{field, value}]`
|
|
11
|
+
* shape, or (for funnel PUT) store the array byte-for-byte.
|
|
12
|
+
*
|
|
13
|
+
* See `docs/superpowers/specs/2026-04-16-customfields-map-interface-design.md`
|
|
14
|
+
* and DRIFT entries DRIFT-INV-14 / DRIFT-INV-15.
|
|
15
|
+
*
|
|
16
|
+
* Per-resource variant lookup:
|
|
17
|
+
*
|
|
18
|
+
* | Resource | POST | PUT |
|
|
19
|
+
* |----------|----------------|----------------|
|
|
20
|
+
* | Document | map-per-entry | documented |
|
|
21
|
+
* | Contact | map-per-entry | map-per-entry |
|
|
22
|
+
* | Lead | documented | documented |
|
|
23
|
+
* | Funnel | (n/a) | map-per-entry |
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Convert a caller-facing customFields map to the wire shape expected by a
|
|
27
|
+
* specific Holded endpoint variant. Returns `undefined` when the input is
|
|
28
|
+
* undefined or empty so callers can spread the result straight into a body
|
|
29
|
+
* without introducing a `customFields: []` noise field.
|
|
30
|
+
*/
|
|
31
|
+
export function serialize(map, variant) {
|
|
32
|
+
if (!map)
|
|
33
|
+
return undefined;
|
|
34
|
+
const keys = Object.keys(map);
|
|
35
|
+
if (keys.length === 0)
|
|
36
|
+
return undefined;
|
|
37
|
+
if (variant === "documented") {
|
|
38
|
+
return keys.map((k) => ({ field: k, value: map[k] }));
|
|
39
|
+
}
|
|
40
|
+
// map-per-entry
|
|
41
|
+
return keys.map((k) => ({ [k]: map[k] }));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse any observed wire shape back into a caller-facing map. Idempotent
|
|
45
|
+
* on arrays of known shapes; returns `{}` for any non-array input (including
|
|
46
|
+
* an already-parsed map — callers must not re-parse).
|
|
47
|
+
*
|
|
48
|
+
* Priority order:
|
|
49
|
+
* 1. null/undefined/non-array → {}
|
|
50
|
+
* 2. empty array → {}
|
|
51
|
+
* 3. whole-array mangled pairs → collapse each pair into {K: V}
|
|
52
|
+
* 4. entry-by-entry:
|
|
53
|
+
* {field, value} exact → {K: V}
|
|
54
|
+
* single own-prop {K: V} → {K: V}
|
|
55
|
+
* otherwise → skip
|
|
56
|
+
*
|
|
57
|
+
* Rule 3 runs before rule 4: a legitimate pair
|
|
58
|
+
* [{field:"field", value:X}, {field:"value", value:Y}]
|
|
59
|
+
* is indistinguishable from the mangled output of `[{field:X, value:Y}]`;
|
|
60
|
+
* the mangled interpretation wins. Custom fields literally named "field"
|
|
61
|
+
* or "value" are accepted as an unavoidable heuristic cost.
|
|
62
|
+
*/
|
|
63
|
+
export function parse(raw) {
|
|
64
|
+
if (!Array.isArray(raw))
|
|
65
|
+
return {};
|
|
66
|
+
if (raw.length === 0)
|
|
67
|
+
return {};
|
|
68
|
+
// Rule 3: whole-array mangled pairs
|
|
69
|
+
if (raw.length % 2 === 0 && raw.every(isRowObject) && allMangledPairs(raw)) {
|
|
70
|
+
const out = {};
|
|
71
|
+
for (let i = 0; i < raw.length; i += 2) {
|
|
72
|
+
const key = String(raw[i].value);
|
|
73
|
+
const val = String(raw[i + 1].value);
|
|
74
|
+
out[key] = val;
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
// Rule 4: entry-by-entry
|
|
79
|
+
const out = {};
|
|
80
|
+
for (const entry of raw) {
|
|
81
|
+
if (!isRowObject(entry))
|
|
82
|
+
continue;
|
|
83
|
+
const keys = Object.keys(entry);
|
|
84
|
+
if (keys.length === 2 && "field" in entry && "value" in entry) {
|
|
85
|
+
out[String(entry.field)] = String(entry.value);
|
|
86
|
+
}
|
|
87
|
+
else if (keys.length === 1) {
|
|
88
|
+
const [k] = keys;
|
|
89
|
+
const v = entry[k];
|
|
90
|
+
if (typeof v === "string") {
|
|
91
|
+
out[k] = v;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// else: skip silently
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Mutate-in-place: if `item` is an object with a `customFields` property,
|
|
100
|
+
* overwrite it with `parse(item.customFields)`. No-op otherwise. Returns
|
|
101
|
+
* `item` for chaining.
|
|
102
|
+
*
|
|
103
|
+
* Call sites:
|
|
104
|
+
* - Direct handlers (documents): after `makeApiRequest`, call on each
|
|
105
|
+
* returned document.
|
|
106
|
+
* - Factory `responseTransform`: return `repairCustomFieldsInPlace(item)`.
|
|
107
|
+
*/
|
|
108
|
+
export function repairCustomFieldsInPlace(item) {
|
|
109
|
+
if (item && typeof item === "object" && "customFields" in item) {
|
|
110
|
+
const target = item;
|
|
111
|
+
target.customFields = parse(target.customFields);
|
|
112
|
+
}
|
|
113
|
+
return item;
|
|
114
|
+
}
|
|
115
|
+
function isRowObject(v) {
|
|
116
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
117
|
+
}
|
|
118
|
+
function allMangledPairs(rows) {
|
|
119
|
+
for (let i = 0; i < rows.length; i += 2) {
|
|
120
|
+
const a = rows[i];
|
|
121
|
+
const b = rows[i + 1];
|
|
122
|
+
if (Object.keys(a).length !== 2 ||
|
|
123
|
+
a.field !== "field" ||
|
|
124
|
+
typeof a.value !== "string")
|
|
125
|
+
return false;
|
|
126
|
+
if (Object.keys(b).length !== 2 ||
|
|
127
|
+
b.field !== "value" ||
|
|
128
|
+
typeof b.value !== "string")
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=custom-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-fields.js","sourceRoot":"","sources":["../../src/utils/custom-fields.ts"],"names":[],"mappings":"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"}
|