@lerianstudio/matcher-mcp 1.2.0 → 1.2.1-beta.1
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/config.js +0 -33
- package/dist/config.js.map +1 -1
- package/dist/spec/enum-policy.js +83 -0
- package/dist/spec/enum-policy.js.map +1 -0
- package/dist/spec/openapi.yaml +15 -20
- package/dist/spec/schema-parity.js +393 -0
- package/dist/spec/schema-parity.js.map +1 -0
- package/dist/tools/context/create.js +18 -3
- package/dist/tools/context/create.js.map +1 -1
- package/dist/tools/context/update.js +20 -5
- package/dist/tools/context/update.js.map +1 -1
- package/dist/tools/exception/bulk-dispatch.js +11 -13
- package/dist/tools/exception/bulk-dispatch.js.map +1 -1
- package/dist/tools/exception/list.js +12 -3
- package/dist/tools/exception/list.js.map +1 -1
- package/dist/tools/fee-rule/create.js +36 -13
- package/dist/tools/fee-rule/create.js.map +1 -1
- package/dist/tools/generic/describe-operation.js +3 -2
- package/dist/tools/generic/describe-operation.js.map +1 -1
- package/dist/tools/ingestion/index.js +13 -8
- package/dist/tools/ingestion/index.js.map +1 -1
- package/dist/tools/ingestion/upload-begin.js +116 -0
- package/dist/tools/ingestion/upload-begin.js.map +1 -0
- package/dist/tools/ingestion/upload.js +47 -97
- package/dist/tools/ingestion/upload.js.map +1 -1
- package/dist/tools/source/create.js +6 -3
- package/dist/tools/source/create.js.map +1 -1
- package/package.json +1 -1
- package/dist/tools/ingestion/fetch-source.js +0 -105
- package/dist/tools/ingestion/fetch-source.js.map +0 -1
package/dist/config.js
CHANGED
|
@@ -10,7 +10,6 @@ const DEFAULT_MATCHER_API_URL = 'http://localhost:4018';
|
|
|
10
10
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
11
11
|
const DEFAULT_MAX_BODY_BYTES = 1_048_576; // 1 MiB
|
|
12
12
|
const DEFAULT_OTEL_SERVICE_NAME = 'matcher-mcp';
|
|
13
|
-
const DEFAULT_UPLOAD_MAX_FETCH_BYTES = 52_428_800; // 50 MiB
|
|
14
13
|
/**
|
|
15
14
|
* Parse a port from a raw env string, falling back to the default when unset.
|
|
16
15
|
* An explicitly-set but invalid value is a misconfiguration and throws, rather
|
|
@@ -75,36 +74,6 @@ function parseBool(raw, fallback, key) {
|
|
|
75
74
|
}
|
|
76
75
|
throw new Error(`invalid ${key}: ${raw} (expected one of true, false, 1, 0)`);
|
|
77
76
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Parse a comma-separated hostname allowlist, trimming each entry and dropping
|
|
80
|
-
* empties (so `"a,,b"` or a trailing comma doesn't produce a spurious `""`
|
|
81
|
-
* entry that would never exact-match a real hostname). Unset/empty env ⇒ `[]`
|
|
82
|
-
* — fail-closed default for `MCP_UPLOAD_ALLOWED_HOSTS`.
|
|
83
|
-
*/
|
|
84
|
-
function parseAllowedHosts(raw) {
|
|
85
|
-
if (raw === undefined) {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
return raw
|
|
89
|
-
.split(',')
|
|
90
|
-
.map((h) => h.trim())
|
|
91
|
-
.filter((h) => h.length > 0);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Parse a positive byte count from a raw env string, falling back to the default
|
|
95
|
-
* when unset. Shares `parseMaxBodyBytes`'s fail-loud semantics under its own
|
|
96
|
-
* env-var name so the error message names the right key.
|
|
97
|
-
*/
|
|
98
|
-
function parseUploadMaxFetchBytes(raw, fallback) {
|
|
99
|
-
if (raw === undefined || raw === '') {
|
|
100
|
-
return fallback;
|
|
101
|
-
}
|
|
102
|
-
const value = Number(raw);
|
|
103
|
-
if (!Number.isInteger(value) || value < 1) {
|
|
104
|
-
throw new Error(`invalid MCP_UPLOAD_MAX_FETCH_BYTES: ${raw} (expected a positive integer of bytes)`);
|
|
105
|
-
}
|
|
106
|
-
return value;
|
|
107
|
-
}
|
|
108
77
|
/**
|
|
109
78
|
* Build the config from a given environment map (defaults to process.env).
|
|
110
79
|
* Pure and side-effect-free so tests can drive it with a synthetic env.
|
|
@@ -121,8 +90,6 @@ export function loadConfig(env = process.env) {
|
|
|
121
90
|
enableTelemetry: parseBool(env.ENABLE_TELEMETRY, false, 'ENABLE_TELEMETRY'),
|
|
122
91
|
otelExporterOtlpEndpoint: otelEndpoint || undefined,
|
|
123
92
|
otelServiceName,
|
|
124
|
-
uploadAllowedHosts: Object.freeze(parseAllowedHosts(env.MCP_UPLOAD_ALLOWED_HOSTS)),
|
|
125
|
-
uploadMaxFetchBytes: parseUploadMaxFetchBytes(env.MCP_UPLOAD_MAX_FETCH_BYTES, DEFAULT_UPLOAD_MAX_FETCH_BYTES),
|
|
126
93
|
});
|
|
127
94
|
}
|
|
128
95
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,yEAAyE;AACzE,4EAA4E;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Enum policy allow-lists — the two sanctioned escapes the enum-parity gate
|
|
2
|
+
// (Task 1.3) consults when a curated tool's Zod field deliberately diverges from
|
|
3
|
+
// the OpenAPI spec's declaration.
|
|
4
|
+
//
|
|
5
|
+
// THE POLICY (full prose + audit table: docs/enum-policy.md)
|
|
6
|
+
// A curated tool models a field as a CLOSED Zod enum only for a closed,
|
|
7
|
+
// slow-moving algebra — comparison operators, context cardinality (1:1|1:N|N:M),
|
|
8
|
+
// fee normalization (NET|GROSS), lifecycle status transitions, fee-rule sides,
|
|
9
|
+
// sort orders, and the like. Anything that GROWS — business-day calendars,
|
|
10
|
+
// metadata field names, connection/config names, exception reason codes, format
|
|
11
|
+
// tokens that expand — is typed as a free `string` whose `.describe()` enumerates
|
|
12
|
+
// the CURRENT known values as a hint. Rationale: a closed enum that lags the
|
|
13
|
+
// backend REJECTS A VALID BACKEND VALUE at the client — strictly worse than a
|
|
14
|
+
// free string that lets the backend do final validation.
|
|
15
|
+
//
|
|
16
|
+
// HOW THE GATE USES THESE
|
|
17
|
+
// The parity gate compares each curated tool field against the spec. Two
|
|
18
|
+
// divergences are legitimate and must be declared here or the gate fails:
|
|
19
|
+
// - INTENTIONALLY_OPEN_FIELDS: the spec declares an enum but the tool
|
|
20
|
+
// deliberately types the field as a free string (a growing taxonomy).
|
|
21
|
+
// - INTENTIONALLY_OMITTED_FIELDS: a spec request-body/query field the curated
|
|
22
|
+
// tool deliberately does not expose (curation is opinionated). `reason` is
|
|
23
|
+
// required so the omission is a considered call, not an oversight.
|
|
24
|
+
//
|
|
25
|
+
// Both lists are EMPTY BY DEFAULT — add an entry only with a real, reasoned case.
|
|
26
|
+
// `operationId` is compile-time constrained to a real curated operation.
|
|
27
|
+
import { CURATED_OPERATION_IDS } from './curated-operations.js';
|
|
28
|
+
/**
|
|
29
|
+
* Spec-enum fields the curated tools deliberately type as a free string because
|
|
30
|
+
* the underlying value set GROWS. Kept in sync with the tool source, which
|
|
31
|
+
* carries the same rationale inline at each field.
|
|
32
|
+
*
|
|
33
|
+
* NB: both current entries are OUT OF the request-body parity gate's scope —
|
|
34
|
+
* listExceptions.reason is a query param (GET, no request body) and
|
|
35
|
+
* uploadFile.format rides a multipart body (no application/json). So the parity
|
|
36
|
+
* gate never consults these entries; they are policy documentation. The
|
|
37
|
+
* free-string behavior is instead enforced by the tools' own unit tests
|
|
38
|
+
* (exception/list.test.ts and ingestion/upload.test.ts each safeParse an
|
|
39
|
+
* out-of-list value). If either field is ever moved onto a JSON request body,
|
|
40
|
+
* its entry here becomes gate-live automatically.
|
|
41
|
+
*/
|
|
42
|
+
export const INTENTIONALLY_OPEN_FIELDS = [
|
|
43
|
+
// Exception reason codes are minted per new engine capability (AGED_BREAK,
|
|
44
|
+
// OVER_SETTLED, FX_RATE_VARIANCE were recent). A closed filter enum would lag
|
|
45
|
+
// and reject a valid reason. -> src/tools/exception/list.ts
|
|
46
|
+
{ operationId: 'listExceptions', fieldPath: 'reason' },
|
|
47
|
+
// Ingestion formats grow with the connector-parity roadmap (new parsers). A
|
|
48
|
+
// closed enum would block uploading a newly-supported format.
|
|
49
|
+
// -> src/tools/ingestion/upload.ts
|
|
50
|
+
{ operationId: 'uploadFile', fieldPath: 'format' },
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Spec request fields the curated tools deliberately do not expose. Each carries
|
|
54
|
+
* a required reason so the omission reads as a considered call, not an oversight.
|
|
55
|
+
*/
|
|
56
|
+
export const INTENTIONALLY_OMITTED_FIELDS = [
|
|
57
|
+
// context_create models inline `rules[]` and `sources[]` as permissive
|
|
58
|
+
// passthrough records (z.array(z.record(...))) rather than reproducing the full
|
|
59
|
+
// nested CreateMatchRule/CreateSource sub-schemas — the tool documents "prefer
|
|
60
|
+
// context_create with no rules then match_rule_create / source_create for
|
|
61
|
+
// richer control", and matcher is the authoritative validator of the inline
|
|
62
|
+
// payload. The array fields THEMSELVES are exposed; only their nested leaves are
|
|
63
|
+
// omitted here. A brand-new nested field the backend adds will still surface as
|
|
64
|
+
// a fresh drift (it won't be on this list), keeping the gate's teeth.
|
|
65
|
+
// -> src/tools/context/create.ts
|
|
66
|
+
{ operationId: 'createContext', fieldPath: 'rules[].priority', reason: 'inline rules[] passed through as an opaque record; matcher validates' },
|
|
67
|
+
{ operationId: 'createContext', fieldPath: 'rules[].type', reason: 'inline rules[] passed through as an opaque record; matcher validates' },
|
|
68
|
+
{ operationId: 'createContext', fieldPath: 'rules[].config', reason: 'inline rules[] passed through as an opaque record; matcher validates' },
|
|
69
|
+
{ operationId: 'createContext', fieldPath: 'sources[].name', reason: 'inline sources[] passed through as an opaque record; matcher validates' },
|
|
70
|
+
{ operationId: 'createContext', fieldPath: 'sources[].type', reason: 'inline sources[] passed through as an opaque record; matcher validates' },
|
|
71
|
+
{ operationId: 'createContext', fieldPath: 'sources[].side', reason: 'inline sources[] passed through as an opaque record; matcher validates' },
|
|
72
|
+
{ operationId: 'createContext', fieldPath: 'sources[].config', reason: 'inline sources[] passed through as an opaque record; matcher validates' },
|
|
73
|
+
{ operationId: 'createContext', fieldPath: 'sources[].mapping', reason: 'inline sources[] passed through as an opaque record; matcher validates' },
|
|
74
|
+
];
|
|
75
|
+
/**
|
|
76
|
+
* Spec-required fields the curated tools satisfy by INJECTING the value in the
|
|
77
|
+
* dispatch code rather than exposing a (required) Zod field. Empty by default —
|
|
78
|
+
* the curated tools mirror the spec's required scalars directly, so nothing is
|
|
79
|
+
* injected today. Add an entry only when a tool genuinely fills a spec-required
|
|
80
|
+
* field itself (and cite the injection site), never to silence a real gap.
|
|
81
|
+
*/
|
|
82
|
+
export const INTENTIONALLY_INJECTED_REQUIRED_FIELDS = [];
|
|
83
|
+
//# sourceMappingURL=enum-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-policy.js","sourceRoot":"","sources":["../../src/spec/enum-policy.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,iFAAiF;AACjF,kCAAkC;AAClC,EAAE;AACF,6DAA6D;AAC7D,wEAAwE;AACxE,iFAAiF;AACjF,+EAA+E;AAC/E,2EAA2E;AAC3E,gFAAgF;AAChF,kFAAkF;AAClF,6EAA6E;AAC7E,8EAA8E;AAC9E,yDAAyD;AACzD,EAAE;AACF,0BAA0B;AAC1B,yEAAyE;AACzE,0EAA0E;AAC1E,wEAAwE;AACxE,0EAA0E;AAC1E,gFAAgF;AAChF,+EAA+E;AAC/E,uEAAuE;AACvE,EAAE;AACF,kFAAkF;AAClF,yEAAyE;AAEzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAuC/D;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAsC;IAC1E,2EAA2E;IAC3E,8EAA8E;IAC9E,4DAA4D;IAC5D,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE;IACtD,4EAA4E;IAC5E,8DAA8D;IAC9D,mCAAmC;IACnC,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE;CACnD,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAyC;IAChF,uEAAuE;IACvE,gFAAgF;IAChF,+EAA+E;IAC/E,0EAA0E;IAC1E,4EAA4E;IAC5E,iFAAiF;IACjF,gFAAgF;IAChF,sEAAsE;IACtE,iCAAiC;IACjC,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,EAAE,sEAAsE,EAAE;IAC/I,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,sEAAsE,EAAE;IAC3I,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,sEAAsE,EAAE;IAC7I,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,wEAAwE,EAAE;IAC/I,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,wEAAwE,EAAE;IAC/I,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,wEAAwE,EAAE;IAC/I,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,EAAE,wEAAwE,EAAE;IACjJ,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,wEAAwE,EAAE;CACnJ,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sCAAsC,GACjD,EAAE,CAAA"}
|
package/dist/spec/openapi.yaml
CHANGED
|
@@ -810,6 +810,11 @@ components:
|
|
|
810
810
|
type: string
|
|
811
811
|
targetSystem:
|
|
812
812
|
description: Target system to dispatch to
|
|
813
|
+
enum:
|
|
814
|
+
- JIRA
|
|
815
|
+
- SERVICENOW
|
|
816
|
+
- WEBHOOK
|
|
817
|
+
- MANUAL
|
|
813
818
|
examples:
|
|
814
819
|
- JIRA
|
|
815
820
|
maxLength: 255
|
|
@@ -1648,7 +1653,7 @@ components:
|
|
|
1648
1653
|
properties:
|
|
1649
1654
|
config:
|
|
1650
1655
|
additionalProperties: {}
|
|
1651
|
-
description: Source-specific configuration object (connection and parsing settings).
|
|
1656
|
+
description: Source-specific configuration object (connection and parsing settings). Optional; defaults to an empty object when omitted.
|
|
1652
1657
|
type: object
|
|
1653
1658
|
mapping:
|
|
1654
1659
|
additionalProperties: {}
|
|
@@ -1684,7 +1689,6 @@ components:
|
|
|
1684
1689
|
- name
|
|
1685
1690
|
- type
|
|
1686
1691
|
- side
|
|
1687
|
-
- config
|
|
1688
1692
|
type: object
|
|
1689
1693
|
CreateExportJobRequest:
|
|
1690
1694
|
additionalProperties: false
|
|
@@ -1702,19 +1706,16 @@ components:
|
|
|
1702
1706
|
format: date
|
|
1703
1707
|
type: string
|
|
1704
1708
|
format:
|
|
1705
|
-
description: Export file format (
|
|
1709
|
+
description: Export file format (uppercase only).
|
|
1706
1710
|
enum:
|
|
1707
1711
|
- CSV
|
|
1708
1712
|
- JSON
|
|
1709
1713
|
- XML
|
|
1710
|
-
- csv
|
|
1711
|
-
- json
|
|
1712
|
-
- xml
|
|
1713
1714
|
examples:
|
|
1714
1715
|
- CSV
|
|
1715
1716
|
type: string
|
|
1716
1717
|
reportType:
|
|
1717
|
-
description: Report type to export
|
|
1718
|
+
description: Report type to export (uppercase only).
|
|
1718
1719
|
enum:
|
|
1719
1720
|
- MATCHED
|
|
1720
1721
|
- UNMATCHED
|
|
@@ -1723,13 +1724,6 @@ components:
|
|
|
1723
1724
|
- EXCEPTIONS
|
|
1724
1725
|
- MATCHES
|
|
1725
1726
|
- UNMATCHED_TRANSACTIONS
|
|
1726
|
-
- matched
|
|
1727
|
-
- unmatched
|
|
1728
|
-
- summary
|
|
1729
|
-
- variance
|
|
1730
|
-
- exceptions
|
|
1731
|
-
- matches
|
|
1732
|
-
- unmatched_transactions
|
|
1733
1727
|
examples:
|
|
1734
1728
|
- MATCHED
|
|
1735
1729
|
type: string
|
|
@@ -2089,7 +2083,7 @@ components:
|
|
|
2089
2083
|
properties:
|
|
2090
2084
|
config:
|
|
2091
2085
|
additionalProperties: {}
|
|
2092
|
-
description: Source-specific configuration object (connection and parsing settings).
|
|
2086
|
+
description: Source-specific configuration object (connection and parsing settings). Optional; defaults to an empty object when omitted.
|
|
2093
2087
|
type: object
|
|
2094
2088
|
name:
|
|
2095
2089
|
description: Human-readable name of the source.
|
|
@@ -2121,7 +2115,6 @@ components:
|
|
|
2121
2115
|
- name
|
|
2122
2116
|
- type
|
|
2123
2117
|
- side
|
|
2124
|
-
- config
|
|
2125
2118
|
type: object
|
|
2126
2119
|
CredentialMetadata:
|
|
2127
2120
|
additionalProperties: false
|
|
@@ -3838,6 +3831,11 @@ components:
|
|
|
3838
3831
|
examples:
|
|
3839
3832
|
- file appears semicolon-delimited but the source declares comma; declare delimiter semicolon in the source dialect
|
|
3840
3833
|
type: string
|
|
3834
|
+
droppedDuplicateReason:
|
|
3835
|
+
description: "Display-only explanation of why droppedDuplicateRows rows were dropped: names the (source, external_id) collapsing key and the field mapping to check so the count does not read as silent data loss. Empty unless droppedDuplicateRows > 0"
|
|
3836
|
+
examples:
|
|
3837
|
+
- Rows repeated a (source, external_id) key already present in this source and were dropped under the keep-first policy.
|
|
3838
|
+
type: string
|
|
3841
3839
|
droppedDuplicateRows:
|
|
3842
3840
|
description: Number of rows dropped as duplicates under the keep-first policy (same external_id within the upload or already persisted)
|
|
3843
3841
|
examples:
|
|
@@ -7395,10 +7393,7 @@ components:
|
|
|
7395
7393
|
- true
|
|
7396
7394
|
type: boolean
|
|
7397
7395
|
feeNormalization:
|
|
7398
|
-
description: Fee normalization mode. NET compares amounts after fees are deducted; GROSS compares amounts before fees.
|
|
7399
|
-
enum:
|
|
7400
|
-
- NET
|
|
7401
|
-
- GROSS
|
|
7396
|
+
description: "Fee normalization mode. NET compares amounts after fees are deducted; GROSS compares amounts before fees. Send an empty string to clear the mode; omit to leave it unchanged. (No enum constraint: unlike create, the update path accepts the empty string to clear.)"
|
|
7402
7397
|
examples:
|
|
7403
7398
|
- NET
|
|
7404
7399
|
type: string
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
// Curated-tool ⇄ OpenAPI request-body parity — the client-side sibling of the Go
|
|
2
|
+
// `check-huma-spec` gate.
|
|
3
|
+
//
|
|
4
|
+
// WHY THIS EXISTS
|
|
5
|
+
// A curated Zod tool (src/tools/<family>/*.ts) hand-writes its input shape and
|
|
6
|
+
// dispatches a fixed method+path. `curated-operations.test.ts` already pins that
|
|
7
|
+
// each tool's operation still EXISTS in the spec (structural drift). This file
|
|
8
|
+
// goes one layer deeper: it diffs each curated tool's declared Zod request shape
|
|
9
|
+
// against the spec's request-body JSON Schema and fails when the TOOL IS BEHIND —
|
|
10
|
+
// a body property the spec added that the tool never exposes, or a closed Zod
|
|
11
|
+
// enum that lags the spec's enum values. Either way an operator driving the tool
|
|
12
|
+
// blind (the .describe() text is the whole product) would be unable to send a
|
|
13
|
+
// field the backend accepts, or would be rejected client-side for a value the
|
|
14
|
+
// backend allows. The enum-policy allow-lists (enum-policy.ts) carve out the two
|
|
15
|
+
// sanctioned divergences (spec-enum→free-string, and deliberately-omitted field).
|
|
16
|
+
//
|
|
17
|
+
// SCOPE — A DECISION, NOT AN OVERSIGHT
|
|
18
|
+
// This gate covers REQUEST-BODY parity only. Query- and path-parameter drift is
|
|
19
|
+
// deliberately OUT OF SCOPE here: path params ride URL builders (a rename there
|
|
20
|
+
// breaks the dispatched path, which `curated-operations.test.ts`'s method+path
|
|
21
|
+
// reconciliation already guards), and the query surface is thin and mostly
|
|
22
|
+
// pagination. Body shape is where a curated tool silently rots against a growing
|
|
23
|
+
// backend contract, so that is what we pin.
|
|
24
|
+
//
|
|
25
|
+
// TOOL-AHEAD IS NOT A FAILURE
|
|
26
|
+
// Extra tool properties the spec lacks (or a tool enum with MORE values than the
|
|
27
|
+
// spec) are not flagged — a curated tool may intentionally lead the spec. Only
|
|
28
|
+
// the tool falling BEHIND the spec bites.
|
|
29
|
+
//
|
|
30
|
+
// ZOD 4 INTROSPECTION
|
|
31
|
+
// Dependency-free (no zod-to-json-schema). Zod 4 exposes `schema._def.type` as
|
|
32
|
+
// the discriminator and `_def.innerType` for the single-child wrappers
|
|
33
|
+
// (optional / default / nullable / readonly / catch / nonoptional); ZodPipe
|
|
34
|
+
// (transform/refine-with-effect) carries `_def.in`; ZodEnum carries
|
|
35
|
+
// `_def.entries`; ZodArray carries `_def.element`; ZodObject exposes `.shape`.
|
|
36
|
+
// The self-test fixtures in schema-parity.test.ts are the correctness proof for
|
|
37
|
+
// these unwrap wrinkles.
|
|
38
|
+
// --- Zod side --------------------------------------------------------------
|
|
39
|
+
/** Access the Zod 4 internal def, tolerating either accessor. */
|
|
40
|
+
function defOf(schema) {
|
|
41
|
+
if (schema === null || typeof schema !== 'object') {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const s = schema;
|
|
45
|
+
const d = s._def ?? s.def;
|
|
46
|
+
return d !== null && typeof d === 'object'
|
|
47
|
+
? d
|
|
48
|
+
: undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Peel the transparent single-child wrappers (optional / default / nullable /
|
|
52
|
+
* readonly / catch / nonoptional via `innerType`; transform/pipe via `in`) until
|
|
53
|
+
* a "core" schema (object / array / enum / scalar / record) is reached.
|
|
54
|
+
*/
|
|
55
|
+
function unwrap(schema) {
|
|
56
|
+
let current = schema;
|
|
57
|
+
for (let hops = 0; hops < 50; hops += 1) {
|
|
58
|
+
const d = defOf(current);
|
|
59
|
+
if (d === undefined) {
|
|
60
|
+
return current;
|
|
61
|
+
}
|
|
62
|
+
if (d['type'] === 'pipe' && d['in'] !== undefined) {
|
|
63
|
+
current = d['in'];
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (d['innerType'] !== undefined) {
|
|
67
|
+
current = d['innerType'];
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
return current;
|
|
71
|
+
}
|
|
72
|
+
return current;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Whether a Zod field is GUARANTEED to appear in the parsed payload.
|
|
76
|
+
* Peels wrappers outermost-first: the first wrapper that decides presence wins.
|
|
77
|
+
* `optional` → 'optional' (may be absent); `default`/`catch`/`prefault` →
|
|
78
|
+
* 'guaranteed' (a value is filled when the caller omits it); `nonoptional` →
|
|
79
|
+
* 'guaranteed' (explicitly strips optionality); `nullable`/`readonly`/`pipe`
|
|
80
|
+
* are transparent for presence and are peeled through. A bare scalar/object/
|
|
81
|
+
* array with no wrapper is required.
|
|
82
|
+
*/
|
|
83
|
+
function presenceOf(schema) {
|
|
84
|
+
let current = schema;
|
|
85
|
+
for (let hops = 0; hops < 50; hops += 1) {
|
|
86
|
+
const d = defOf(current);
|
|
87
|
+
if (d === undefined) {
|
|
88
|
+
return 'guaranteed';
|
|
89
|
+
}
|
|
90
|
+
const type = d['type'];
|
|
91
|
+
if (type === 'optional') {
|
|
92
|
+
return 'optional';
|
|
93
|
+
}
|
|
94
|
+
if (type === 'default' || type === 'catch' || type === 'prefault') {
|
|
95
|
+
return 'guaranteed';
|
|
96
|
+
}
|
|
97
|
+
if (type === 'nonoptional') {
|
|
98
|
+
return 'guaranteed';
|
|
99
|
+
}
|
|
100
|
+
if (type === 'pipe' && d['in'] !== undefined) {
|
|
101
|
+
current = d['in'];
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (d['innerType'] !== undefined) {
|
|
105
|
+
current = d['innerType'];
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
return 'guaranteed';
|
|
109
|
+
}
|
|
110
|
+
return 'guaranteed';
|
|
111
|
+
}
|
|
112
|
+
/** Recurse a Zod schema, appending property paths and closed enums to `out`. */
|
|
113
|
+
function walkZod(schema, path, out) {
|
|
114
|
+
const core = unwrap(schema);
|
|
115
|
+
const d = defOf(core);
|
|
116
|
+
const type = d?.['type'];
|
|
117
|
+
if (type === 'object') {
|
|
118
|
+
const shape = core.shape ?? {};
|
|
119
|
+
for (const [key, child] of Object.entries(shape)) {
|
|
120
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
121
|
+
out.propertyPaths.add(childPath);
|
|
122
|
+
if (presenceOf(child) === 'guaranteed') {
|
|
123
|
+
out.requiredPaths.add(childPath);
|
|
124
|
+
}
|
|
125
|
+
walkZod(child, childPath, out);
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (type === 'array') {
|
|
130
|
+
const element = core.element ?? d?.['element'];
|
|
131
|
+
if (element !== undefined) {
|
|
132
|
+
walkZod(element, `${path}[]`, out);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (type === 'enum' && path) {
|
|
137
|
+
const entries = d?.['entries'];
|
|
138
|
+
if (entries !== null && typeof entries === 'object') {
|
|
139
|
+
out.closedEnums.set(path, new Set(Object.values(entries).map(String)));
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// record / string / number / boolean / unknown → leaf; nothing to add.
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Introspect a curated tool's `ZodRawShape` into its property paths and closed
|
|
147
|
+
* enums. Wrapper types are unwrapped; arrays recurse into their element under a
|
|
148
|
+
* `[]` segment; enums surface their `.options`.
|
|
149
|
+
*/
|
|
150
|
+
export function introspectShape(shape) {
|
|
151
|
+
const out = {
|
|
152
|
+
propertyPaths: new Set(),
|
|
153
|
+
closedEnums: new Map(),
|
|
154
|
+
requiredPaths: new Set(),
|
|
155
|
+
};
|
|
156
|
+
for (const [key, schema] of Object.entries(shape)) {
|
|
157
|
+
out.propertyPaths.add(key);
|
|
158
|
+
if (presenceOf(schema) === 'guaranteed') {
|
|
159
|
+
out.requiredPaths.add(key);
|
|
160
|
+
}
|
|
161
|
+
walkZod(schema, key, out);
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
// --- Spec side -------------------------------------------------------------
|
|
166
|
+
/**
|
|
167
|
+
* Recurse an (already-dereferenced) JSON Schema fragment into `out`.
|
|
168
|
+
*
|
|
169
|
+
* FLAT-SCHEMA-ONLY (invariant, not a bug): traverses `properties`/`items`/`enum`
|
|
170
|
+
* only. Composition keywords (allOf/oneOf/anyOf) are NOT descended into — Huma
|
|
171
|
+
* emits flat schemas and the shipped spec has zero of them (a schema-parity.test
|
|
172
|
+
* canary asserts this stays true). If the generator ever emits a composed body,
|
|
173
|
+
* a property/enum under the composition would be invisible here (fail-OPEN), so
|
|
174
|
+
* the canary trips RED first, forcing composition traversal to be added.
|
|
175
|
+
*/
|
|
176
|
+
function walkSpec(node, path, out) {
|
|
177
|
+
if (node === null || typeof node !== 'object') {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const obj = node;
|
|
181
|
+
const enumVals = obj['enum'];
|
|
182
|
+
if (Array.isArray(enumVals) && path) {
|
|
183
|
+
out.closedEnums.set(path, new Set(enumVals.map(String)));
|
|
184
|
+
}
|
|
185
|
+
// `required` lists property NAMES required at THIS object level; project each
|
|
186
|
+
// onto the same dot/bracket path notation as its property entry below.
|
|
187
|
+
const required = obj['required'];
|
|
188
|
+
if (Array.isArray(required)) {
|
|
189
|
+
for (const name of required) {
|
|
190
|
+
if (typeof name === 'string') {
|
|
191
|
+
out.requiredPaths.add(path ? `${path}.${name}` : name);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const properties = obj['properties'];
|
|
196
|
+
if (properties !== null && typeof properties === 'object') {
|
|
197
|
+
for (const [key, child] of Object.entries(properties)) {
|
|
198
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
199
|
+
out.propertyPaths.add(childPath);
|
|
200
|
+
walkSpec(child, childPath, out);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const items = obj['items'];
|
|
204
|
+
if (items !== undefined) {
|
|
205
|
+
walkSpec(items, `${path}[]`, out);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Introspect a spec request-body JSON Schema (as produced by the loader, refs
|
|
210
|
+
* already inlined) into its property paths and enums — same path notation as
|
|
211
|
+
* {@link introspectShape} so the two are directly comparable.
|
|
212
|
+
*/
|
|
213
|
+
export function introspectSpecSchema(schema) {
|
|
214
|
+
const out = {
|
|
215
|
+
propertyPaths: new Set(),
|
|
216
|
+
closedEnums: new Map(),
|
|
217
|
+
requiredPaths: new Set(),
|
|
218
|
+
};
|
|
219
|
+
walkSpec(schema, '', out);
|
|
220
|
+
return out;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Diff a curated tool's Zod shape against a spec request-body schema, honoring
|
|
224
|
+
* the per-op allow-lists. Returns every gap where the TOOL IS BEHIND the spec.
|
|
225
|
+
* Pure — the gate and the self-test both drive it.
|
|
226
|
+
*/
|
|
227
|
+
export function compareShapeToSpec(shape, specSchema, allow) {
|
|
228
|
+
const tool = introspectShape(shape);
|
|
229
|
+
const spec = introspectSpecSchema(specSchema);
|
|
230
|
+
const findings = [];
|
|
231
|
+
// (1) Spec property the tool never exposes → missing, unless omitted-allow-listed.
|
|
232
|
+
for (const fieldPath of spec.propertyPaths) {
|
|
233
|
+
if (tool.propertyPaths.has(fieldPath)) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (allow.omittedFields.has(fieldPath)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
findings.push({ kind: 'missing-property', fieldPath });
|
|
240
|
+
}
|
|
241
|
+
// (2)/(3) Spec enums vs the tool's modeling of the same field.
|
|
242
|
+
for (const [fieldPath, specValues] of spec.closedEnums) {
|
|
243
|
+
if (!tool.propertyPaths.has(fieldPath)) {
|
|
244
|
+
// Absent entirely — already reported (or allow-listed) by pass (1).
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const toolValues = tool.closedEnums.get(fieldPath);
|
|
248
|
+
if (toolValues !== undefined) {
|
|
249
|
+
// (2) Closed tool enum must be a superset of the spec's values.
|
|
250
|
+
const missing = [...specValues].filter((v) => !toolValues.has(v));
|
|
251
|
+
if (missing.length > 0) {
|
|
252
|
+
findings.push({ kind: 'enum-missing-values', fieldPath, missing });
|
|
253
|
+
}
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// (3) Spec enum, but the tool types it as a free string — only OK if declared.
|
|
257
|
+
if (!allow.openFields.has(fieldPath)) {
|
|
258
|
+
findings.push({ kind: 'enum-modeled-as-string', fieldPath });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return findings;
|
|
262
|
+
}
|
|
263
|
+
/** A required path is unconditional only at the top level (no parent container). */
|
|
264
|
+
function isTopLevel(fieldPath) {
|
|
265
|
+
return !fieldPath.includes('.') && !fieldPath.includes('[');
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Diff the required-ness of a curated tool's fields against a spec request body.
|
|
269
|
+
* Returns every gap, its `kind` carrying the severity the gate applies:
|
|
270
|
+
* `spec-required-*` FAIL, `tool-required-spec-optional` WARN. Pure — the gate
|
|
271
|
+
* and the self-test both drive it.
|
|
272
|
+
*/
|
|
273
|
+
export function compareRequiredArrays(shape, specSchema, allow) {
|
|
274
|
+
const tool = introspectShape(shape);
|
|
275
|
+
const spec = introspectSpecSchema(specSchema);
|
|
276
|
+
const findings = [];
|
|
277
|
+
// FAIL direction: every spec-required field must be guaranteed by the tool.
|
|
278
|
+
for (const fieldPath of spec.requiredPaths) {
|
|
279
|
+
if (tool.requiredPaths.has(fieldPath)) {
|
|
280
|
+
continue; // tool guarantees it (non-optional or has a default)
|
|
281
|
+
}
|
|
282
|
+
if (allow.injectedFields.has(fieldPath)) {
|
|
283
|
+
continue; // tool code fills it before dispatch — invisible but accounted for
|
|
284
|
+
}
|
|
285
|
+
if (tool.propertyPaths.has(fieldPath)) {
|
|
286
|
+
// Exposed but optional → caller can omit a required field.
|
|
287
|
+
findings.push({ kind: 'spec-required-tool-optional', fieldPath });
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
// Not exposed at all. Absence of a NON-allow-listed field is coverage's job
|
|
291
|
+
// (compareShapeToSpec's missing-property). We only add value for the case
|
|
292
|
+
// coverage can't see: a TOP-LEVEL required field suppressed by the omitted
|
|
293
|
+
// allow-list — an unconditional 422 on every call. Nested paths under an
|
|
294
|
+
// optional/opaque container are conditional and passed through, so skip them.
|
|
295
|
+
if (isTopLevel(fieldPath) && allow.omittedFields.has(fieldPath)) {
|
|
296
|
+
findings.push({ kind: 'spec-required-tool-omitted', fieldPath });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// WARN direction: a tool-required field the spec exposes but marks optional.
|
|
300
|
+
for (const fieldPath of tool.requiredPaths) {
|
|
301
|
+
if (!spec.propertyPaths.has(fieldPath)) {
|
|
302
|
+
continue; // tool-ahead extra the spec lacks — not an over-constraint of it
|
|
303
|
+
}
|
|
304
|
+
if (!spec.requiredPaths.has(fieldPath)) {
|
|
305
|
+
findings.push({ kind: 'tool-required-spec-optional', fieldPath });
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return findings;
|
|
309
|
+
}
|
|
310
|
+
// --- The shape table -------------------------------------------------------
|
|
311
|
+
//
|
|
312
|
+
// Each curated operation whose spec entry declares an application/json request
|
|
313
|
+
// body maps here to the tool's exported input shape. The completeness guard in
|
|
314
|
+
// the test derives the required key set from CURATED_OPERATION_IDS ∩ (spec ops
|
|
315
|
+
// with a JSON body). So for any op ALREADY in CURATED_OPERATION_IDS, adding or
|
|
316
|
+
// retargeting its curated body-tool without wiring the shape here fails the gate
|
|
317
|
+
// (missing on one side, extra on the other).
|
|
318
|
+
//
|
|
319
|
+
// SCOPE LIMIT (do not overstate this): because the required set is filtered
|
|
320
|
+
// through the hand-maintained CURATED_OPERATION_IDS, this parity gate does NOT
|
|
321
|
+
// see an op that has a JSON body but is left in GENERIC_ONLY_OPERATION_IDS —
|
|
322
|
+
// hand-curate a Zod body-tool for such an op without promoting it into
|
|
323
|
+
// CURATED_OPERATION_IDS (and without wiring it here) and no field-parity test
|
|
324
|
+
// runs for it. That promotion/triage is guarded separately by
|
|
325
|
+
// curated-operations.test.ts (curated⇄generic disjointness + frozen counts +
|
|
326
|
+
// inverse spec coverage), not by field parity here. GET/list/delete ops (no
|
|
327
|
+
// body) and uploadFile (multipart, no application/json body) are absent by design.
|
|
328
|
+
import { addCommentInputShape } from '../tools/exception/add-comment.js';
|
|
329
|
+
import { adjustEntryInputShape } from '../tools/exception/adjust-entry.js';
|
|
330
|
+
import { bulkAssignInputShape } from '../tools/exception/bulk-assign.js';
|
|
331
|
+
import { bulkDispatchInputShape } from '../tools/exception/bulk-dispatch.js';
|
|
332
|
+
import { bulkResolveInputShape } from '../tools/exception/bulk-resolve.js';
|
|
333
|
+
import { closeDisputeInputShape } from '../tools/dispute/close.js';
|
|
334
|
+
import { createContextInputShape } from '../tools/context/create.js';
|
|
335
|
+
import { createFeeRuleInputShape } from '../tools/fee-rule/create.js';
|
|
336
|
+
import { createFeeScheduleInputShape } from '../tools/fee-schedule/create.js';
|
|
337
|
+
import { createFieldMapInputShape } from '../tools/field-map/create.js';
|
|
338
|
+
import { createMatchRuleInputShape } from '../tools/match-rule/create.js';
|
|
339
|
+
import { createSourceInputShape } from '../tools/source/create.js';
|
|
340
|
+
import { dispatchExceptionInputShape } from '../tools/exception/dispatch.js';
|
|
341
|
+
import { forceMatchInputShape } from '../tools/exception/force-match.js';
|
|
342
|
+
import { ignoreTransactionInputShape } from '../tools/ingestion/transaction-ignore.js';
|
|
343
|
+
import { openDisputeInputShape } from '../tools/exception/open-dispute.js';
|
|
344
|
+
import { reorderMatchRulesInputShape } from '../tools/match-rule/reorder.js';
|
|
345
|
+
import { simulateFeeScheduleInputShape } from '../tools/fee-schedule/simulate.js';
|
|
346
|
+
import { startMatchRunInputShape } from '../tools/matching/start.js';
|
|
347
|
+
import { submitEvidenceInputShape } from '../tools/dispute/submit-evidence.js';
|
|
348
|
+
import { updateContextInputShape } from '../tools/context/update.js';
|
|
349
|
+
import { updateFeeRuleInputShape } from '../tools/fee-rule/update.js';
|
|
350
|
+
import { updateFeeScheduleInputShape } from '../tools/fee-schedule/update.js';
|
|
351
|
+
import { updateFieldMapInputShape } from '../tools/field-map/update.js';
|
|
352
|
+
import { updateMatchRuleInputShape } from '../tools/match-rule/update.js';
|
|
353
|
+
import { updateSourceInputShape } from '../tools/source/update.js';
|
|
354
|
+
/** operationId → the curated tool's request-body input shape. */
|
|
355
|
+
export const TOOL_SHAPE_BY_OPERATION_ID = {
|
|
356
|
+
// fee-schedule
|
|
357
|
+
createFeeSchedule: createFeeScheduleInputShape,
|
|
358
|
+
simulateFeeSchedule: simulateFeeScheduleInputShape,
|
|
359
|
+
updateFeeSchedule: updateFeeScheduleInputShape,
|
|
360
|
+
// fee-rule
|
|
361
|
+
createFeeRule: createFeeRuleInputShape,
|
|
362
|
+
updateFeeRule: updateFeeRuleInputShape,
|
|
363
|
+
// match-rule
|
|
364
|
+
createMatchRule: createMatchRuleInputShape,
|
|
365
|
+
reorderMatchRules: reorderMatchRulesInputShape,
|
|
366
|
+
updateMatchRule: updateMatchRuleInputShape,
|
|
367
|
+
// context
|
|
368
|
+
createContext: createContextInputShape,
|
|
369
|
+
updateContext: updateContextInputShape,
|
|
370
|
+
// source
|
|
371
|
+
createSource: createSourceInputShape,
|
|
372
|
+
updateSource: updateSourceInputShape,
|
|
373
|
+
// field-map
|
|
374
|
+
createFieldMap: createFieldMapInputShape,
|
|
375
|
+
updateFieldMap: updateFieldMapInputShape,
|
|
376
|
+
// matching
|
|
377
|
+
runMatch: startMatchRunInputShape,
|
|
378
|
+
// exception
|
|
379
|
+
addComment: addCommentInputShape,
|
|
380
|
+
adjustEntryException: adjustEntryInputShape,
|
|
381
|
+
bulkAssignExceptions: bulkAssignInputShape,
|
|
382
|
+
bulkDispatchExceptions: bulkDispatchInputShape,
|
|
383
|
+
bulkResolveExceptions: bulkResolveInputShape,
|
|
384
|
+
dispatchException: dispatchExceptionInputShape,
|
|
385
|
+
forceMatchException: forceMatchInputShape,
|
|
386
|
+
openDispute: openDisputeInputShape,
|
|
387
|
+
// dispute
|
|
388
|
+
closeDispute: closeDisputeInputShape,
|
|
389
|
+
submitEvidence: submitEvidenceInputShape,
|
|
390
|
+
// ingestion
|
|
391
|
+
ignoreTransaction: ignoreTransactionInputShape,
|
|
392
|
+
};
|
|
393
|
+
//# sourceMappingURL=schema-parity.js.map
|