autotel-pact 3.0.0 → 4.0.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/attrs-DbCs1ou0.cjs +61 -0
- package/dist/attrs-DbCs1ou0.cjs.map +1 -0
- package/dist/attrs-ElwK54Ym.js +43 -0
- package/dist/attrs-ElwK54Ym.js.map +1 -0
- package/dist/audit.cjs +155 -394
- package/dist/audit.cjs.map +1 -1
- package/dist/audit.d.cts +15 -13
- package/dist/audit.d.cts.map +1 -0
- package/dist/audit.d.ts +15 -13
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +153 -388
- package/dist/audit.js.map +1 -1
- package/dist/auto-wrap.cjs +206 -240
- package/dist/auto-wrap.cjs.map +1 -1
- package/dist/auto-wrap.d.cts +9 -7
- package/dist/auto-wrap.d.cts.map +1 -0
- package/dist/auto-wrap.d.ts +9 -7
- package/dist/auto-wrap.d.ts.map +1 -0
- package/dist/auto-wrap.js +205 -233
- package/dist/auto-wrap.js.map +1 -1
- package/dist/broker.cjs +65 -68
- package/dist/broker.cjs.map +1 -1
- package/dist/broker.d.cts +11 -9
- package/dist/broker.d.cts.map +1 -0
- package/dist/broker.d.ts +11 -9
- package/dist/broker.d.ts.map +1 -0
- package/dist/broker.js +64 -67
- package/dist/broker.js.map +1 -1
- package/dist/cli.cjs +166 -620
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +3 -2
- package/dist/cli.d.cts.map +1 -0
- package/dist/cli.d.ts +3 -2
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +165 -614
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +245 -952
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -86
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +90 -86
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +216 -918
- package/dist/index.js.map +1 -1
- package/dist/labels-0Cwk5E-8.cjs +41 -0
- package/dist/labels-0Cwk5E-8.cjs.map +1 -0
- package/dist/labels-BQjT_Zrv.js +23 -0
- package/dist/labels-BQjT_Zrv.js.map +1 -0
- package/dist/{ledger-D88TzN1c.d.cts → ledger-BAFsRX6y.d.cts} +8 -6
- package/dist/ledger-BAFsRX6y.d.cts.map +1 -0
- package/dist/ledger-BayQwemz.cjs +267 -0
- package/dist/ledger-BayQwemz.cjs.map +1 -0
- package/dist/{ledger-BuBmfWNc.d.ts → ledger-Bzh_6tbV.d.ts} +8 -6
- package/dist/ledger-Bzh_6tbV.d.ts.map +1 -0
- package/dist/ledger-sII3Ig3Y.js +174 -0
- package/dist/ledger-sII3Ig3Y.js.map +1 -0
- package/dist/pact-file-B8QjVrC7.cjs +76 -0
- package/dist/pact-file-B8QjVrC7.cjs.map +1 -0
- package/dist/pact-file-CkE4NFZ1.js +57 -0
- package/dist/pact-file-CkE4NFZ1.js.map +1 -0
- package/dist/processor.cjs +112 -185
- package/dist/processor.cjs.map +1 -1
- package/dist/processor.d.cts +41 -40
- package/dist/processor.d.cts.map +1 -0
- package/dist/processor.d.ts +41 -40
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +111 -179
- package/dist/processor.js.map +1 -1
- package/dist/provider.cjs +90 -205
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +26 -25
- package/dist/provider.d.cts.map +1 -0
- package/dist/provider.d.ts +26 -25
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +88 -199
- package/dist/provider.js.map +1 -1
- package/dist/tag.cjs +14 -44
- package/dist/tag.cjs.map +1 -1
- package/dist/tag.d.cts +4 -2
- package/dist/tag.d.cts.map +1 -0
- package/dist/tag.d.ts +4 -2
- package/dist/tag.d.ts.map +1 -0
- package/dist/tag.js +13 -42
- package/dist/tag.js.map +1 -1
- package/dist/types-D_0kgK2e.d.cts +154 -0
- package/dist/types-D_0kgK2e.d.cts.map +1 -0
- package/dist/types-D_0kgK2e.d.ts +154 -0
- package/dist/types-D_0kgK2e.d.ts.map +1 -0
- package/package.json +6 -6
- package/dist/types-BHGiwqcp.d.cts +0 -157
- package/dist/types-BHGiwqcp.d.ts +0 -157
package/dist/audit.cjs
CHANGED
|
@@ -1,412 +1,173 @@
|
|
|
1
|
-
'
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_ledger = require('./ledger-BayQwemz.cjs');
|
|
3
|
+
const require_pact_file = require('./pact-file-B8QjVrC7.cjs');
|
|
4
|
+
const require_broker = require('./broker.cjs');
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
node_path = require_ledger.__toESM(node_path, 1);
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
|
|
9
|
-
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
10
|
-
|
|
11
|
-
// src/audit.ts
|
|
12
|
-
|
|
13
|
-
// src/broker.ts
|
|
14
|
-
function authHeaders(config) {
|
|
15
|
-
const headers = {
|
|
16
|
-
Accept: "application/json"
|
|
17
|
-
};
|
|
18
|
-
if (config.token) {
|
|
19
|
-
headers.Authorization = `Bearer ${config.token}`;
|
|
20
|
-
} else if (config.username && config.password) {
|
|
21
|
-
const encoded = Buffer.from(`${config.username}:${config.password}`).toString("base64");
|
|
22
|
-
headers.Authorization = `Basic ${encoded}`;
|
|
23
|
-
}
|
|
24
|
-
return headers;
|
|
25
|
-
}
|
|
26
|
-
function trimBaseUrl(url) {
|
|
27
|
-
return url.replace(/\/$/, "");
|
|
28
|
-
}
|
|
29
|
-
function parseBrokerVerificationResult(consumer, provider, json) {
|
|
30
|
-
if (!json || typeof json !== "object") return null;
|
|
31
|
-
const body = json;
|
|
32
|
-
const success = body.success === true || body.success === void 0 && body.result === "success";
|
|
33
|
-
const verifiedAt = typeof body.verifiedAt === "string" ? body.verifiedAt : typeof body.verified_at === "string" ? body.verified_at : typeof body.createdAt === "string" ? body.createdAt : void 0;
|
|
34
|
-
return {
|
|
35
|
-
consumer,
|
|
36
|
-
provider,
|
|
37
|
-
success: !!success,
|
|
38
|
-
verifiedAt
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
async function fetchBrokerVerifications(config, pairs) {
|
|
42
|
-
const base = trimBaseUrl(config.baseUrl);
|
|
43
|
-
const headers = authHeaders(config);
|
|
44
|
-
const results = [];
|
|
45
|
-
for (const { consumer, provider } of pairs) {
|
|
46
|
-
const url = `${base}/pacts/provider/${encodeURIComponent(provider)}/consumer/${encodeURIComponent(consumer)}/latest/verification-results`;
|
|
47
|
-
try {
|
|
48
|
-
const res = await fetch(url, { headers });
|
|
49
|
-
if (!res.ok) {
|
|
50
|
-
results.push({
|
|
51
|
-
consumer,
|
|
52
|
-
provider,
|
|
53
|
-
success: false,
|
|
54
|
-
error: `HTTP ${res.status} ${res.statusText}`.trim()
|
|
55
|
-
});
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
const json = await res.json();
|
|
59
|
-
const parsed = parseBrokerVerificationResult(consumer, provider, json);
|
|
60
|
-
results.push(
|
|
61
|
-
parsed ?? {
|
|
62
|
-
consumer,
|
|
63
|
-
provider,
|
|
64
|
-
success: false,
|
|
65
|
-
error: "Unparseable broker response"
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
results.push({
|
|
70
|
-
consumer,
|
|
71
|
-
provider,
|
|
72
|
-
success: false,
|
|
73
|
-
error: error instanceof Error ? error.message : String(error)
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return results;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// src/types.ts
|
|
81
|
-
var LEDGER_ENTRY_SPEC = "autotel-pact-ledger-entry/v0.2.0";
|
|
82
|
-
var AUDIT_MATRIX_SPEC = "autotel-pact-audit-matrix/v0.2.0";
|
|
83
|
-
function isInteractionLedgerEntry(entry) {
|
|
84
|
-
return entry.type !== "provider_verification_run";
|
|
85
|
-
}
|
|
86
|
-
function isProviderVerificationRun(entry) {
|
|
87
|
-
return entry.type === "provider_verification_run";
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// src/ledger-normalize.ts
|
|
91
|
-
function isRecord(value) {
|
|
92
|
-
return typeof value === "object" && value !== null;
|
|
93
|
-
}
|
|
94
|
-
function normalizeLedgerRecord(parsed) {
|
|
95
|
-
if (!isRecord(parsed) || parsed.spec !== LEDGER_ENTRY_SPEC) return null;
|
|
96
|
-
const { consumer, provider, observed_at } = parsed;
|
|
97
|
-
if (typeof consumer !== "string" || typeof provider !== "string" || typeof observed_at !== "string") {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
if (parsed.type === "provider_verification_run") {
|
|
101
|
-
if (typeof parsed.error !== "string") return null;
|
|
102
|
-
const entry2 = {
|
|
103
|
-
type: "provider_verification_run",
|
|
104
|
-
spec: LEDGER_ENTRY_SPEC,
|
|
105
|
-
consumer,
|
|
106
|
-
provider,
|
|
107
|
-
outcome: "failed",
|
|
108
|
-
source: parsed.source === "production" ? "production" : "test",
|
|
109
|
-
role: "provider",
|
|
110
|
-
observed_at,
|
|
111
|
-
error: parsed.error
|
|
112
|
-
};
|
|
113
|
-
if (typeof parsed.run_id === "string") entry2.run_id = parsed.run_id;
|
|
114
|
-
if (typeof parsed.git_sha === "string") entry2.git_sha = parsed.git_sha;
|
|
115
|
-
if (typeof parsed.trace_id === "string") entry2.trace_id = parsed.trace_id;
|
|
116
|
-
if (typeof parsed.span_id === "string") entry2.span_id = parsed.span_id;
|
|
117
|
-
return entry2;
|
|
118
|
-
}
|
|
119
|
-
if (typeof parsed.interaction !== "string") return null;
|
|
120
|
-
const states = Array.isArray(parsed.states) ? parsed.states.filter((s) => typeof s === "string") : [];
|
|
121
|
-
const entry = {
|
|
122
|
-
type: "interaction",
|
|
123
|
-
spec: LEDGER_ENTRY_SPEC,
|
|
124
|
-
consumer,
|
|
125
|
-
provider,
|
|
126
|
-
interaction: parsed.interaction,
|
|
127
|
-
states,
|
|
128
|
-
kind: parsed.kind === "http" ? "http" : "message",
|
|
129
|
-
outcome: parsed.outcome === "failed" ? "failed" : "passed",
|
|
130
|
-
source: parsed.source === "production" ? "production" : "test",
|
|
131
|
-
role: parsed.role === "provider" ? "provider" : "consumer",
|
|
132
|
-
duration_ms: typeof parsed.duration_ms === "number" && parsed.duration_ms >= 0 ? parsed.duration_ms : 0,
|
|
133
|
-
observed_at
|
|
134
|
-
};
|
|
135
|
-
if (typeof parsed.interaction_id === "string" && parsed.interaction_id.length > 0) {
|
|
136
|
-
entry.interaction_id = parsed.interaction_id;
|
|
137
|
-
}
|
|
138
|
-
if (typeof parsed.trace_id === "string") entry.trace_id = parsed.trace_id;
|
|
139
|
-
if (typeof parsed.span_id === "string") entry.span_id = parsed.span_id;
|
|
140
|
-
if (typeof parsed.run_id === "string") entry.run_id = parsed.run_id;
|
|
141
|
-
if (typeof parsed.git_sha === "string") entry.git_sha = parsed.git_sha;
|
|
142
|
-
if (typeof parsed.error === "string") entry.error = parsed.error;
|
|
143
|
-
return entry;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// src/ledger.ts
|
|
147
|
-
var DEFAULT_DIR = ".autotel-pact";
|
|
148
|
-
function resolveLedgerDir(opts = {}) {
|
|
149
|
-
return path__default.default.resolve(process.cwd(), opts.dir ?? process.env.AUTOTEL_PACT_LEDGER_DIR ?? DEFAULT_DIR);
|
|
150
|
-
}
|
|
151
|
-
function readLedger(opts = {}) {
|
|
152
|
-
const dir = resolveLedgerDir(opts);
|
|
153
|
-
if (!fs.existsSync(dir)) return [];
|
|
154
|
-
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
155
|
-
const entries = [];
|
|
156
|
-
for (const file of files) {
|
|
157
|
-
const text = fs.readFileSync(path__default.default.join(dir, file), "utf8");
|
|
158
|
-
for (const line of text.split("\n")) {
|
|
159
|
-
if (!line.trim()) continue;
|
|
160
|
-
try {
|
|
161
|
-
const normalized = normalizeLedgerRecord(JSON.parse(line));
|
|
162
|
-
if (normalized) entries.push(normalized);
|
|
163
|
-
} catch {
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return entries;
|
|
168
|
-
}
|
|
169
|
-
Promise.resolve();
|
|
170
|
-
function listPactFiles(dir) {
|
|
171
|
-
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) return [];
|
|
172
|
-
const out = [];
|
|
173
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
174
|
-
const full = path__default.default.join(dir, entry.name);
|
|
175
|
-
if (entry.isDirectory()) {
|
|
176
|
-
out.push(...listPactFiles(full));
|
|
177
|
-
} else if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
178
|
-
out.push(full);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return out;
|
|
182
|
-
}
|
|
183
|
-
function extractInteractionId(metadata) {
|
|
184
|
-
if (!metadata) return void 0;
|
|
185
|
-
const id = metadata.interactionId ?? metadata.interaction_id;
|
|
186
|
-
return typeof id === "string" && id.length > 0 ? id : void 0;
|
|
187
|
-
}
|
|
188
|
-
function interactionsFromPactFile(pact) {
|
|
189
|
-
const consumer = pact.consumer?.name;
|
|
190
|
-
const provider = pact.provider?.name;
|
|
191
|
-
if (!consumer || !provider) return [];
|
|
192
|
-
const keys = [];
|
|
193
|
-
for (const m of pact.messages ?? []) {
|
|
194
|
-
keys.push({
|
|
195
|
-
consumer,
|
|
196
|
-
provider,
|
|
197
|
-
interaction: m.description,
|
|
198
|
-
kind: "message",
|
|
199
|
-
interactionId: extractInteractionId(m.metadata)
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
for (const i of pact.interactions ?? []) {
|
|
203
|
-
keys.push({
|
|
204
|
-
consumer,
|
|
205
|
-
provider,
|
|
206
|
-
interaction: i.description,
|
|
207
|
-
kind: "http",
|
|
208
|
-
interactionId: extractInteractionId(i.metadata)
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
return keys;
|
|
212
|
-
}
|
|
213
|
-
function parsePactFile(filePath) {
|
|
214
|
-
try {
|
|
215
|
-
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
216
|
-
} catch {
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// src/audit.ts
|
|
222
|
-
var DEFAULT_PACTS_DIR = "./pacts";
|
|
223
|
-
var DEFAULT_WINDOW_DAYS = 14;
|
|
8
|
+
//#region src/audit.ts
|
|
9
|
+
const DEFAULT_PACTS_DIR = "./pacts";
|
|
10
|
+
const DEFAULT_WINDOW_DAYS = 14;
|
|
224
11
|
function keyOf(k) {
|
|
225
|
-
|
|
226
|
-
|
|
12
|
+
const identity = k.interactionId ?? k.interaction;
|
|
13
|
+
return `${k.consumer}::${k.provider}::${k.kind}::${identity}`;
|
|
227
14
|
}
|
|
228
15
|
function pairKey(consumer, provider) {
|
|
229
|
-
|
|
16
|
+
return `${consumer}::${provider}`;
|
|
230
17
|
}
|
|
231
18
|
function inWindow(observedAt, cutoff) {
|
|
232
|
-
|
|
233
|
-
|
|
19
|
+
const t = Date.parse(observedAt);
|
|
20
|
+
return Number.isFinite(t) && t >= cutoff;
|
|
234
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Compute the audit matrix from pact files, ledger, and optional broker data.
|
|
24
|
+
*/
|
|
235
25
|
function computeAuditMatrix(input) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
rows.sort(
|
|
334
|
-
(a, b) => a.consumer.localeCompare(b.consumer) || a.provider.localeCompare(b.provider) || a.interaction.localeCompare(b.interaction)
|
|
335
|
-
);
|
|
336
|
-
const counts = {
|
|
337
|
-
total: rows.length,
|
|
338
|
-
contracted: rows.filter((r) => r.contracted).length,
|
|
339
|
-
observed: rows.filter((r) => r.observed).length,
|
|
340
|
-
contracted_and_test_seen: rows.filter((r) => r.contracted && r.test_seen).length,
|
|
341
|
-
contracted_not_test_seen: rows.filter((r) => r.contracted && !r.test_seen).length,
|
|
342
|
-
test_or_prod_seen_not_contracted: rows.filter(
|
|
343
|
-
(r) => !r.contracted && (r.test_seen || r.prod_seen)
|
|
344
|
-
).length,
|
|
345
|
-
test_seen: rows.filter((r) => r.test_seen).length,
|
|
346
|
-
prod_seen: rows.filter((r) => r.prod_seen).length,
|
|
347
|
-
provider_verified: rows.filter((r) => r.provider_verified).length,
|
|
348
|
-
broker_verified: rows.filter((r) => r.broker_verified).length
|
|
349
|
-
};
|
|
350
|
-
const matrix = {
|
|
351
|
-
spec: AUDIT_MATRIX_SPEC,
|
|
352
|
-
rows,
|
|
353
|
-
counts,
|
|
354
|
-
window_days: windowDays,
|
|
355
|
-
generated_at: now.toISOString()
|
|
356
|
-
};
|
|
357
|
-
if (verificationFailures.length > 0) {
|
|
358
|
-
matrix.verification_failures = verificationFailures;
|
|
359
|
-
}
|
|
360
|
-
return matrix;
|
|
26
|
+
const windowDays = input.windowDays ?? DEFAULT_WINDOW_DAYS;
|
|
27
|
+
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
28
|
+
const cutoff = now.getTime() - windowDays * 24 * 60 * 60 * 1e3;
|
|
29
|
+
const verificationFailures = [];
|
|
30
|
+
const recentInteractions = [];
|
|
31
|
+
for (const entry of input.ledger) {
|
|
32
|
+
if (!inWindow(entry.observed_at, cutoff)) continue;
|
|
33
|
+
if (require_ledger.isProviderVerificationRun(entry)) {
|
|
34
|
+
verificationFailures.push(entry);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (require_ledger.isInteractionLedgerEntry(entry)) recentInteractions.push(entry);
|
|
38
|
+
}
|
|
39
|
+
const brokerByPair = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const b of input.brokerVerifications ?? []) brokerByPair.set(pairKey(b.consumer, b.provider), b);
|
|
41
|
+
const testSeenByKey = /* @__PURE__ */ new Map();
|
|
42
|
+
const prodSeenByKey = /* @__PURE__ */ new Map();
|
|
43
|
+
const providerVerifiedByKey = /* @__PURE__ */ new Map();
|
|
44
|
+
const anyObservedByKey = /* @__PURE__ */ new Map();
|
|
45
|
+
for (const entry of recentInteractions) {
|
|
46
|
+
const k = keyOf({
|
|
47
|
+
consumer: entry.consumer,
|
|
48
|
+
provider: entry.provider,
|
|
49
|
+
interaction: entry.interaction,
|
|
50
|
+
kind: entry.kind,
|
|
51
|
+
interactionId: entry.interaction_id
|
|
52
|
+
});
|
|
53
|
+
const push = (map) => {
|
|
54
|
+
const arr = map.get(k) ?? [];
|
|
55
|
+
arr.push(entry);
|
|
56
|
+
map.set(k, arr);
|
|
57
|
+
};
|
|
58
|
+
push(anyObservedByKey);
|
|
59
|
+
if (entry.source === "test" && entry.role === "consumer") push(testSeenByKey);
|
|
60
|
+
if (entry.source === "production") push(prodSeenByKey);
|
|
61
|
+
if (entry.role === "provider" && entry.outcome === "passed") push(providerVerifiedByKey);
|
|
62
|
+
}
|
|
63
|
+
const contractedByKey = /* @__PURE__ */ new Map();
|
|
64
|
+
for (const c of input.contracted) contractedByKey.set(keyOf(c), c);
|
|
65
|
+
const rows = [];
|
|
66
|
+
function pushRow(parts, k, isContracted) {
|
|
67
|
+
const testObs = testSeenByKey.get(k) ?? [];
|
|
68
|
+
const prodObs = prodSeenByKey.get(k) ?? [];
|
|
69
|
+
const providerObs = providerVerifiedByKey.get(k) ?? [];
|
|
70
|
+
const latest = (anyObservedByKey.get(k) ?? []).toSorted((a, b) => b.observed_at.localeCompare(a.observed_at))[0];
|
|
71
|
+
const broker = brokerByPair.get(pairKey(parts.consumer, parts.provider));
|
|
72
|
+
rows.push({
|
|
73
|
+
consumer: parts.consumer,
|
|
74
|
+
provider: parts.provider,
|
|
75
|
+
interaction: parts.interaction,
|
|
76
|
+
interaction_id: parts.interactionId ?? latest?.interaction_id,
|
|
77
|
+
kind: parts.kind,
|
|
78
|
+
contracted: isContracted,
|
|
79
|
+
observed: testObs.length > 0 || prodObs.length > 0,
|
|
80
|
+
test_seen: testObs.length > 0,
|
|
81
|
+
prod_seen: prodObs.length > 0,
|
|
82
|
+
provider_verified: providerObs.length > 0,
|
|
83
|
+
broker_verified: broker?.success === true,
|
|
84
|
+
broker_verified_at: broker?.verifiedAt,
|
|
85
|
+
broker_error: broker?.error,
|
|
86
|
+
last_observed_at: latest?.observed_at,
|
|
87
|
+
last_outcome: latest?.outcome
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
for (const [k, contracted] of contractedByKey) pushRow(contracted, k, true);
|
|
91
|
+
for (const [k, observations] of anyObservedByKey) {
|
|
92
|
+
if (contractedByKey.has(k)) continue;
|
|
93
|
+
const first = observations[0];
|
|
94
|
+
pushRow({
|
|
95
|
+
consumer: first.consumer,
|
|
96
|
+
provider: first.provider,
|
|
97
|
+
interaction: first.interaction,
|
|
98
|
+
kind: first.kind,
|
|
99
|
+
interactionId: first.interaction_id
|
|
100
|
+
}, k, false);
|
|
101
|
+
}
|
|
102
|
+
rows.sort((a, b) => a.consumer.localeCompare(b.consumer) || a.provider.localeCompare(b.provider) || a.interaction.localeCompare(b.interaction));
|
|
103
|
+
const matrix = {
|
|
104
|
+
spec: require_ledger.AUDIT_MATRIX_SPEC,
|
|
105
|
+
rows,
|
|
106
|
+
counts: {
|
|
107
|
+
total: rows.length,
|
|
108
|
+
contracted: rows.filter((r) => r.contracted).length,
|
|
109
|
+
observed: rows.filter((r) => r.observed).length,
|
|
110
|
+
contracted_and_test_seen: rows.filter((r) => r.contracted && r.test_seen).length,
|
|
111
|
+
contracted_not_test_seen: rows.filter((r) => r.contracted && !r.test_seen).length,
|
|
112
|
+
test_or_prod_seen_not_contracted: rows.filter((r) => !r.contracted && (r.test_seen || r.prod_seen)).length,
|
|
113
|
+
test_seen: rows.filter((r) => r.test_seen).length,
|
|
114
|
+
prod_seen: rows.filter((r) => r.prod_seen).length,
|
|
115
|
+
provider_verified: rows.filter((r) => r.provider_verified).length,
|
|
116
|
+
broker_verified: rows.filter((r) => r.broker_verified).length
|
|
117
|
+
},
|
|
118
|
+
window_days: windowDays,
|
|
119
|
+
generated_at: now.toISOString()
|
|
120
|
+
};
|
|
121
|
+
if (verificationFailures.length > 0) matrix.verification_failures = verificationFailures;
|
|
122
|
+
return matrix;
|
|
361
123
|
}
|
|
362
124
|
async function runAudit(opts = {}) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
125
|
+
const pactsDir = node_path.default.resolve(process.cwd(), opts.pactsDir ?? DEFAULT_PACTS_DIR);
|
|
126
|
+
const contracted = [];
|
|
127
|
+
const pairs = /* @__PURE__ */ new Set();
|
|
128
|
+
for (const file of require_pact_file.listPactFiles(pactsDir)) {
|
|
129
|
+
const pact = require_pact_file.parsePactFile(file);
|
|
130
|
+
if (!pact) continue;
|
|
131
|
+
const interactions = require_pact_file.interactionsFromPactFile(pact);
|
|
132
|
+
contracted.push(...interactions);
|
|
133
|
+
const consumer = pact.consumer?.name;
|
|
134
|
+
const provider = pact.provider?.name;
|
|
135
|
+
if (consumer && provider) pairs.add(pairKey(consumer, provider));
|
|
136
|
+
}
|
|
137
|
+
const ledger = require_ledger.readLedger(opts);
|
|
138
|
+
let brokerVerifications;
|
|
139
|
+
if (opts.broker) brokerVerifications = await require_broker.fetchBrokerVerifications(opts.broker, [...pairs].map((p) => {
|
|
140
|
+
const [consumer, provider] = p.split("::");
|
|
141
|
+
return {
|
|
142
|
+
consumer,
|
|
143
|
+
provider
|
|
144
|
+
};
|
|
145
|
+
}));
|
|
146
|
+
return computeAuditMatrix({
|
|
147
|
+
contracted,
|
|
148
|
+
ledger,
|
|
149
|
+
brokerVerifications,
|
|
150
|
+
windowDays: opts.windowDays
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/** Sync audit without broker (backward compatible for tests). */
|
|
392
154
|
function runAuditSync(opts = {}) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
});
|
|
155
|
+
const pactsDir = node_path.default.resolve(process.cwd(), opts.pactsDir ?? DEFAULT_PACTS_DIR);
|
|
156
|
+
const contracted = [];
|
|
157
|
+
for (const file of require_pact_file.listPactFiles(pactsDir)) {
|
|
158
|
+
const pact = require_pact_file.parsePactFile(file);
|
|
159
|
+
if (pact) contracted.push(...require_pact_file.interactionsFromPactFile(pact));
|
|
160
|
+
}
|
|
161
|
+
return computeAuditMatrix({
|
|
162
|
+
contracted,
|
|
163
|
+
ledger: require_ledger.readLedger(opts),
|
|
164
|
+
windowDays: opts.windowDays
|
|
165
|
+
});
|
|
405
166
|
}
|
|
406
167
|
|
|
168
|
+
//#endregion
|
|
407
169
|
exports.computeAuditMatrix = computeAuditMatrix;
|
|
408
170
|
exports.keyOf = keyOf;
|
|
409
171
|
exports.runAudit = runAudit;
|
|
410
172
|
exports.runAuditSync = runAuditSync;
|
|
411
|
-
//# sourceMappingURL=audit.cjs.map
|
|
412
173
|
//# sourceMappingURL=audit.cjs.map
|