@ampeco/public-api-mcp 0.3.0 → 0.4.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 +61 -0
- package/dist/build/index.js +52 -7
- package/dist/build/index.js.map +1 -1
- package/dist/build/types.d.ts +24 -2
- package/dist/build/types.d.ts.map +1 -1
- package/dist/generated/build-stats.json +7 -1
- package/dist/generated/endpoints.json +9 -3
- package/dist/generated/response-schemas.json +84437 -0
- package/dist/generated/schemas.d.ts +46 -46
- package/dist/server/factory.d.ts +2 -2
- package/dist/server/factory.d.ts.map +1 -1
- package/dist/server/factory.js +129 -27
- package/dist/server/factory.js.map +1 -1
- package/dist/server/factory.test.js +5 -5
- package/dist/server/factory.test.js.map +1 -1
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +4 -2
- package/dist/server/http.js.map +1 -1
- package/dist/server/index.js +5 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/loader.d.ts +6 -1
- package/dist/server/loader.d.ts.map +1 -1
- package/dist/server/loader.js +9 -0
- package/dist/server/loader.js.map +1 -1
- package/dist/server/resources/handlers.js +2 -2
- package/dist/server/resources/handlers.js.map +1 -1
- package/dist/server/stdio.d.ts.map +1 -1
- package/dist/server/stdio.js +4 -2
- package/dist/server/stdio.js.map +1 -1
- package/dist/server/utils/response-transformer.d.ts +78 -0
- package/dist/server/utils/response-transformer.d.ts.map +1 -0
- package/dist/server/utils/response-transformer.js +423 -0
- package/dist/server/utils/response-transformer.js.map +1 -0
- package/dist/server/utils/response-transformer.test.d.ts +2 -0
- package/dist/server/utils/response-transformer.test.d.ts.map +1 -0
- package/dist/server/utils/response-transformer.test.js +103 -0
- package/dist/server/utils/response-transformer.test.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response transformation utilities for handling large API responses
|
|
3
|
+
*
|
|
4
|
+
* This module implements schema-driven smart response transformation to:
|
|
5
|
+
* - Preserve critical pagination metadata
|
|
6
|
+
* - Provide statistical summaries (min/max/sum/avg/median/percentiles)
|
|
7
|
+
* - Include categorical distributions
|
|
8
|
+
* - Sample representative items
|
|
9
|
+
* - Dramatically reduce token usage (80-95% for large responses)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Detect if response needs transformation
|
|
13
|
+
*/
|
|
14
|
+
export function shouldTransform(response, options) {
|
|
15
|
+
const maxSize = options.maxResponseSize || 20000;
|
|
16
|
+
const responseText = JSON.stringify(response);
|
|
17
|
+
if (responseText.length < maxSize) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
// Check if response contains arrays that could be summarized
|
|
21
|
+
return hasLargeArrays(response);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if response contains large arrays
|
|
25
|
+
*/
|
|
26
|
+
function hasLargeArrays(obj) {
|
|
27
|
+
if (Array.isArray(obj) && obj.length > 10) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
if (typeof obj === "object" && obj !== null) {
|
|
31
|
+
for (const value of Object.values(obj)) {
|
|
32
|
+
if (Array.isArray(value) && value.length > 10) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extract pagination metadata from response
|
|
41
|
+
*/
|
|
42
|
+
function extractPaginationMetadata(response) {
|
|
43
|
+
const metadata = {};
|
|
44
|
+
// Common pagination patterns
|
|
45
|
+
const paginationKeys = [
|
|
46
|
+
"pagination",
|
|
47
|
+
"paging",
|
|
48
|
+
"page",
|
|
49
|
+
"cursor",
|
|
50
|
+
"nextCursor",
|
|
51
|
+
"next",
|
|
52
|
+
"nextPage",
|
|
53
|
+
"hasMore",
|
|
54
|
+
"hasNext",
|
|
55
|
+
"total",
|
|
56
|
+
"totalCount",
|
|
57
|
+
"count",
|
|
58
|
+
"limit",
|
|
59
|
+
"offset",
|
|
60
|
+
"size",
|
|
61
|
+
"totalPages",
|
|
62
|
+
"currentPage",
|
|
63
|
+
];
|
|
64
|
+
// Extract pagination from top level
|
|
65
|
+
for (const key of paginationKeys) {
|
|
66
|
+
if (key in response) {
|
|
67
|
+
metadata[key] = response[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Check for nested pagination object
|
|
71
|
+
if (response.pagination && typeof response.pagination === "object") {
|
|
72
|
+
metadata.pagination = response.pagination;
|
|
73
|
+
}
|
|
74
|
+
if (response.meta && typeof response.meta === "object") {
|
|
75
|
+
metadata.meta = response.meta;
|
|
76
|
+
}
|
|
77
|
+
return metadata;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Compute statistics for numeric field
|
|
81
|
+
*/
|
|
82
|
+
function computeNumericStats(values) {
|
|
83
|
+
if (values.length === 0) {
|
|
84
|
+
return { min: 0, max: 0, avg: 0, sum: 0, median: 0 };
|
|
85
|
+
}
|
|
86
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
87
|
+
const sum = values.reduce((acc, val) => acc + val, 0);
|
|
88
|
+
const percentile = (p) => {
|
|
89
|
+
const index = Math.ceil((p / 100) * sorted.length) - 1;
|
|
90
|
+
return sorted[Math.max(0, index)];
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
min: sorted[0],
|
|
94
|
+
max: sorted[sorted.length - 1],
|
|
95
|
+
avg: sum / values.length,
|
|
96
|
+
sum: sum,
|
|
97
|
+
median: percentile(50),
|
|
98
|
+
p25: percentile(25),
|
|
99
|
+
p75: percentile(75),
|
|
100
|
+
p95: percentile(95),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Compute distribution for categorical field
|
|
105
|
+
*/
|
|
106
|
+
function computeDistribution(values) {
|
|
107
|
+
const distribution = {};
|
|
108
|
+
for (const value of values) {
|
|
109
|
+
const key = String(value);
|
|
110
|
+
distribution[key] = (distribution[key] || 0) + 1;
|
|
111
|
+
}
|
|
112
|
+
return distribution;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Extract field types from OpenAPI schema (SCHEMA-DRIVEN APPROACH)
|
|
116
|
+
* Uses improved ID field detection and categorical field filtering
|
|
117
|
+
*/
|
|
118
|
+
function extractFieldTypesFromSchema(schema) {
|
|
119
|
+
try {
|
|
120
|
+
const numeric = [];
|
|
121
|
+
const categorical = [];
|
|
122
|
+
if (!schema || typeof schema !== "object") {
|
|
123
|
+
return { numeric, categorical };
|
|
124
|
+
}
|
|
125
|
+
// Handle case where schema is array schema directly
|
|
126
|
+
if (schema.type === "array" && schema.items) {
|
|
127
|
+
return extractFieldTypesFromSchema(schema.items);
|
|
128
|
+
}
|
|
129
|
+
if (schema.type !== "object" || !schema.properties) {
|
|
130
|
+
return { numeric, categorical };
|
|
131
|
+
}
|
|
132
|
+
for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {
|
|
133
|
+
// IMPROVED: More precise ID field detection
|
|
134
|
+
// Only skip fields that are clearly IDs (exact match or suffix pattern)
|
|
135
|
+
const isIdField = /^id$|^.*[_-]id$/i.test(fieldName) || // Matches: id, user_id, session-id
|
|
136
|
+
/^.*Id$/i.test(fieldName); // Matches: userId, sessionId
|
|
137
|
+
if (isIdField) {
|
|
138
|
+
continue; // Skip ID fields for statistics
|
|
139
|
+
}
|
|
140
|
+
// Numeric fields: number or integer type
|
|
141
|
+
if (fieldSchema.type === "number" || fieldSchema.type === "integer") {
|
|
142
|
+
numeric.push(fieldName);
|
|
143
|
+
}
|
|
144
|
+
// Categorical fields: enums or strings (excluding dates)
|
|
145
|
+
else if (fieldSchema.enum && fieldSchema.enum.length > 0) {
|
|
146
|
+
// Only include enums with reasonable cardinality
|
|
147
|
+
if (fieldSchema.enum.length <= 50) {
|
|
148
|
+
// Max 50 distinct values
|
|
149
|
+
categorical.push(fieldName);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (fieldSchema.type === "string" &&
|
|
153
|
+
!fieldSchema.format?.includes("date") &&
|
|
154
|
+
!fieldSchema.format?.includes("time") &&
|
|
155
|
+
!fieldSchema.format?.includes("uuid") // Exclude UUIDs
|
|
156
|
+
) {
|
|
157
|
+
// Add heuristics to avoid free-text fields
|
|
158
|
+
const likelyFreeText = [
|
|
159
|
+
"description",
|
|
160
|
+
"comment",
|
|
161
|
+
"note",
|
|
162
|
+
"text",
|
|
163
|
+
"message",
|
|
164
|
+
"body",
|
|
165
|
+
"content",
|
|
166
|
+
].some((keyword) => fieldName.toLowerCase().includes(keyword));
|
|
167
|
+
// Check for max length constraint (long strings unlikely to be categorical)
|
|
168
|
+
const hasLongMaxLength = fieldSchema.maxLength && fieldSchema.maxLength > 100;
|
|
169
|
+
if (!likelyFreeText && !hasLongMaxLength) {
|
|
170
|
+
// Mark as categorical but will be validated at runtime
|
|
171
|
+
categorical.push(fieldName);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return { numeric, categorical };
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
// Log error and return empty (will fallback to runtime detection)
|
|
179
|
+
console.error("[Transformer] Error extracting field types from schema:", error);
|
|
180
|
+
return { numeric: [], categorical: [] };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Auto-detect numeric and categorical fields (FALLBACK: runtime detection)
|
|
185
|
+
* This is used when schema is not available or as validation
|
|
186
|
+
*/
|
|
187
|
+
function detectFieldTypes(items) {
|
|
188
|
+
if (items.length === 0) {
|
|
189
|
+
return { numeric: [], categorical: [] };
|
|
190
|
+
}
|
|
191
|
+
const numeric = [];
|
|
192
|
+
const categorical = [];
|
|
193
|
+
const sampleItem = items[0];
|
|
194
|
+
for (const [key, value] of Object.entries(sampleItem)) {
|
|
195
|
+
// IMPROVED: Use same precise ID detection
|
|
196
|
+
const isIdField = /^id$|^.*[_-]id$/i.test(key) || /^.*Id$/i.test(key);
|
|
197
|
+
if (isIdField) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (typeof value === "number") {
|
|
201
|
+
numeric.push(key);
|
|
202
|
+
}
|
|
203
|
+
else if (typeof value === "string" || typeof value === "boolean") {
|
|
204
|
+
// Only track categorical if field has reasonable cardinality
|
|
205
|
+
const uniqueValues = new Set(items.slice(0, 100).map((item) => item[key]));
|
|
206
|
+
if (uniqueValues.size <= 20) {
|
|
207
|
+
categorical.push(key);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return { numeric, categorical };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Transform array data with statistics and sampling
|
|
215
|
+
*/
|
|
216
|
+
function transformArray(items, arrayName, options, responseSchema // Optional OpenAPI response schema
|
|
217
|
+
) {
|
|
218
|
+
const sampleSize = options.sampleSize || 5;
|
|
219
|
+
let numericFields = [];
|
|
220
|
+
let categoricalFields = [];
|
|
221
|
+
// Try schema-driven detection first (with error handling)
|
|
222
|
+
if (responseSchema) {
|
|
223
|
+
try {
|
|
224
|
+
console.error("[Transformer] Using schema-driven field detection");
|
|
225
|
+
// Find the array schema in the response schema
|
|
226
|
+
let arrayItemSchema = null;
|
|
227
|
+
if (responseSchema.properties?.[arrayName]?.items) {
|
|
228
|
+
arrayItemSchema = responseSchema.properties[arrayName].items;
|
|
229
|
+
}
|
|
230
|
+
else if (responseSchema.type === "array") {
|
|
231
|
+
arrayItemSchema = responseSchema.items;
|
|
232
|
+
}
|
|
233
|
+
if (arrayItemSchema) {
|
|
234
|
+
const schemaFields = extractFieldTypesFromSchema(arrayItemSchema);
|
|
235
|
+
numericFields = schemaFields.numeric;
|
|
236
|
+
categoricalFields = schemaFields.categorical;
|
|
237
|
+
console.error(`[Transformer] Schema detected ${numericFields.length} numeric fields, ` +
|
|
238
|
+
`${categoricalFields.length} categorical fields`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
console.error("[Transformer] Error in schema-driven detection, falling back to runtime:", error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Fallback to runtime detection if schema detection didn't work
|
|
246
|
+
if (numericFields.length === 0 && categoricalFields.length === 0) {
|
|
247
|
+
console.error("[Transformer] Falling back to runtime field detection");
|
|
248
|
+
try {
|
|
249
|
+
const detected = detectFieldTypes(items);
|
|
250
|
+
numericFields = detected.numeric;
|
|
251
|
+
categoricalFields = detected.categorical;
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.error("[Transformer] Runtime detection failed:", error);
|
|
255
|
+
// Continue with empty field lists (will still return sample and count)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const result = {
|
|
259
|
+
arrayName,
|
|
260
|
+
count: items.length,
|
|
261
|
+
sample: items.slice(0, Math.min(sampleSize, items.length)),
|
|
262
|
+
};
|
|
263
|
+
// Compute statistics if enabled
|
|
264
|
+
if (options.computeStats !== false) {
|
|
265
|
+
const statistics = {
|
|
266
|
+
count: items.length,
|
|
267
|
+
};
|
|
268
|
+
// Numeric statistics
|
|
269
|
+
if (numericFields.length > 0) {
|
|
270
|
+
statistics.numericFields = {};
|
|
271
|
+
for (const field of numericFields) {
|
|
272
|
+
const values = items
|
|
273
|
+
.map((item) => item[field])
|
|
274
|
+
.filter((val) => typeof val === "number" && !isNaN(val));
|
|
275
|
+
if (values.length > 0) {
|
|
276
|
+
statistics.numericFields[field] = computeNumericStats(values);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Categorical distributions (with runtime cardinality validation)
|
|
281
|
+
if (options.includeDistribution !== false && categoricalFields.length > 0) {
|
|
282
|
+
statistics.categoricalFields = {};
|
|
283
|
+
for (const field of categoricalFields) {
|
|
284
|
+
const values = items.map((item) => item[field]).filter((val) => val != null);
|
|
285
|
+
if (values.length === 0)
|
|
286
|
+
continue;
|
|
287
|
+
// Runtime cardinality check - only compute distribution if reasonable
|
|
288
|
+
const uniqueValues = new Set(values);
|
|
289
|
+
const cardinality = uniqueValues.size;
|
|
290
|
+
// Only include if cardinality is reasonable relative to dataset size
|
|
291
|
+
const cardinalityRatio = cardinality / values.length;
|
|
292
|
+
if (cardinality <= 50 || cardinalityRatio <= 0.3) {
|
|
293
|
+
// Max 50 values OR <30% unique
|
|
294
|
+
statistics.categoricalFields[field] = computeDistribution(values);
|
|
295
|
+
}
|
|
296
|
+
// Else: skip field (too many unique values, not truly categorical)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
result.statistics = statistics;
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Main transformation function
|
|
305
|
+
*/
|
|
306
|
+
export function transformResponse(response, options = {}, responseSchema // Optional OpenAPI response schema for the endpoint
|
|
307
|
+
) {
|
|
308
|
+
const startTime = Date.now();
|
|
309
|
+
if (!options.enabled) {
|
|
310
|
+
// Transformation disabled - return original
|
|
311
|
+
return {
|
|
312
|
+
status: response.status || 200,
|
|
313
|
+
metadata: {},
|
|
314
|
+
data: {
|
|
315
|
+
_transformation: {
|
|
316
|
+
applied: false,
|
|
317
|
+
reason: "Transformation disabled",
|
|
318
|
+
originalSize: JSON.stringify(response).length,
|
|
319
|
+
transformedSize: JSON.stringify(response).length,
|
|
320
|
+
timestamp: new Date().toISOString(),
|
|
321
|
+
},
|
|
322
|
+
full: response,
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
if (!shouldTransform(response, options)) {
|
|
327
|
+
// Response is small enough - no transformation needed
|
|
328
|
+
return {
|
|
329
|
+
status: response.status || 200,
|
|
330
|
+
metadata: {},
|
|
331
|
+
data: {
|
|
332
|
+
_transformation: {
|
|
333
|
+
applied: false,
|
|
334
|
+
reason: "Response size below threshold",
|
|
335
|
+
originalSize: JSON.stringify(response).length,
|
|
336
|
+
transformedSize: JSON.stringify(response).length,
|
|
337
|
+
timestamp: new Date().toISOString(),
|
|
338
|
+
},
|
|
339
|
+
full: response,
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// Extract pagination metadata
|
|
344
|
+
const metadata = extractPaginationMetadata(response);
|
|
345
|
+
// Find the main data array
|
|
346
|
+
let arrayData = null;
|
|
347
|
+
let arrayName = "data";
|
|
348
|
+
if (Array.isArray(response)) {
|
|
349
|
+
arrayData = response;
|
|
350
|
+
arrayName = "items";
|
|
351
|
+
}
|
|
352
|
+
else if (typeof response === "object") {
|
|
353
|
+
// Common array field names
|
|
354
|
+
const arrayFieldNames = ["data", "items", "results", "records", "list"];
|
|
355
|
+
for (const fieldName of arrayFieldNames) {
|
|
356
|
+
if (Array.isArray(response[fieldName])) {
|
|
357
|
+
arrayData = response[fieldName];
|
|
358
|
+
arrayName = fieldName;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// If no common field found, find first large array
|
|
363
|
+
if (!arrayData) {
|
|
364
|
+
for (const [key, value] of Object.entries(response)) {
|
|
365
|
+
if (Array.isArray(value) && value.length > 10) {
|
|
366
|
+
arrayData = value;
|
|
367
|
+
arrayName = key;
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (!arrayData) {
|
|
374
|
+
// No array found - return original
|
|
375
|
+
return {
|
|
376
|
+
status: response.status || 200,
|
|
377
|
+
metadata,
|
|
378
|
+
data: {
|
|
379
|
+
_transformation: {
|
|
380
|
+
applied: false,
|
|
381
|
+
reason: "No transformable arrays found",
|
|
382
|
+
originalSize: JSON.stringify(response).length,
|
|
383
|
+
transformedSize: JSON.stringify(response).length,
|
|
384
|
+
timestamp: new Date().toISOString(),
|
|
385
|
+
},
|
|
386
|
+
full: response,
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
// Transform the array (pass schema for field detection)
|
|
391
|
+
const transformedArray = transformArray(arrayData, arrayName, options, responseSchema);
|
|
392
|
+
const originalSize = JSON.stringify(response).length;
|
|
393
|
+
const transformedSize = JSON.stringify({
|
|
394
|
+
status: response.status,
|
|
395
|
+
metadata,
|
|
396
|
+
data: transformedArray,
|
|
397
|
+
}).length;
|
|
398
|
+
const result = {
|
|
399
|
+
status: response.status || 200,
|
|
400
|
+
metadata,
|
|
401
|
+
data: {
|
|
402
|
+
...transformedArray,
|
|
403
|
+
_transformation: {
|
|
404
|
+
applied: true,
|
|
405
|
+
reason: `Large response (${originalSize} bytes) transformed to preserve metadata and provide statistics`,
|
|
406
|
+
originalSize,
|
|
407
|
+
transformedSize,
|
|
408
|
+
timestamp: new Date().toISOString(),
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
_originalShape: {
|
|
412
|
+
topLevelKeys: Object.keys(response),
|
|
413
|
+
arrayFields: [{ name: arrayName, length: arrayData.length }],
|
|
414
|
+
scalarFields: Object.keys(response).filter((k) => !Array.isArray(response[k]) && typeof response[k] !== "object"),
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
const duration = Date.now() - startTime;
|
|
418
|
+
console.error(`[Response Transformer] Transformed ${arrayName} array (${arrayData.length} items) ` +
|
|
419
|
+
`in ${duration}ms. Size: ${originalSize} → ${transformedSize} bytes ` +
|
|
420
|
+
`(${(((originalSize - transformedSize) / originalSize) * 100).toFixed(1)}% reduction)`);
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=response-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-transformer.js","sourceRoot":"","sources":["../../../src/server/utils/response-transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-transformer.test.d.ts","sourceRoot":"","sources":["../../../src/server/utils/response-transformer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { transformResponse } from "./response-transformer.js";
|
|
3
|
+
describe("Response Transformer", () => {
|
|
4
|
+
describe("Numeric statistics with sum", () => {
|
|
5
|
+
it("should include sum in numeric field statistics", () => {
|
|
6
|
+
const response = {
|
|
7
|
+
data: [
|
|
8
|
+
{ id: 1, price: 100, quantity: 5 },
|
|
9
|
+
{ id: 2, price: 200, quantity: 3 },
|
|
10
|
+
{ id: 3, price: 150, quantity: 7 },
|
|
11
|
+
{ id: 4, price: 300, quantity: 2 },
|
|
12
|
+
{ id: 5, price: 250, quantity: 4 },
|
|
13
|
+
{ id: 6, price: 180, quantity: 6 },
|
|
14
|
+
{ id: 7, price: 220, quantity: 8 },
|
|
15
|
+
{ id: 8, price: 280, quantity: 1 },
|
|
16
|
+
{ id: 9, price: 190, quantity: 9 },
|
|
17
|
+
{ id: 10, price: 210, quantity: 3 },
|
|
18
|
+
{ id: 11, price: 240, quantity: 5 },
|
|
19
|
+
],
|
|
20
|
+
total: 11,
|
|
21
|
+
};
|
|
22
|
+
const result = transformResponse(response, {
|
|
23
|
+
enabled: true,
|
|
24
|
+
maxResponseSize: 100, // Force transformation
|
|
25
|
+
computeStats: true,
|
|
26
|
+
});
|
|
27
|
+
expect(result.data.statistics?.numericFields?.price).toBeDefined();
|
|
28
|
+
expect(result.data.statistics?.numericFields?.quantity).toBeDefined();
|
|
29
|
+
// Verify sum is included
|
|
30
|
+
expect(result.data.statistics?.numericFields?.price.sum).toBe(2320);
|
|
31
|
+
expect(result.data.statistics?.numericFields?.quantity.sum).toBe(53);
|
|
32
|
+
// Verify other stats are still present
|
|
33
|
+
expect(result.data.statistics?.numericFields?.price.min).toBe(100);
|
|
34
|
+
expect(result.data.statistics?.numericFields?.price.max).toBe(300);
|
|
35
|
+
expect(result.data.statistics?.numericFields?.price.avg).toBeCloseTo(210.91, 2);
|
|
36
|
+
});
|
|
37
|
+
it("should handle empty arrays with sum", () => {
|
|
38
|
+
const response = {
|
|
39
|
+
data: [],
|
|
40
|
+
total: 0,
|
|
41
|
+
};
|
|
42
|
+
const result = transformResponse(response, {
|
|
43
|
+
enabled: true,
|
|
44
|
+
maxResponseSize: 0,
|
|
45
|
+
computeStats: true,
|
|
46
|
+
});
|
|
47
|
+
// Empty array shouldn't transform
|
|
48
|
+
expect(result.data._transformation.applied).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
it("should handle single numeric value with sum", () => {
|
|
51
|
+
const response = {
|
|
52
|
+
data: [
|
|
53
|
+
{ id: 1, amount: 42 },
|
|
54
|
+
{ id: 2, amount: 42 },
|
|
55
|
+
{ id: 3, amount: 42 },
|
|
56
|
+
{ id: 4, amount: 42 },
|
|
57
|
+
{ id: 5, amount: 42 },
|
|
58
|
+
{ id: 6, amount: 42 },
|
|
59
|
+
{ id: 7, amount: 42 },
|
|
60
|
+
{ id: 8, amount: 42 },
|
|
61
|
+
{ id: 9, amount: 42 },
|
|
62
|
+
{ id: 10, amount: 42 },
|
|
63
|
+
{ id: 11, amount: 42 },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
const result = transformResponse(response, {
|
|
67
|
+
enabled: true,
|
|
68
|
+
maxResponseSize: 100,
|
|
69
|
+
computeStats: true,
|
|
70
|
+
});
|
|
71
|
+
expect(result.data.statistics?.numericFields?.amount).toBeDefined();
|
|
72
|
+
expect(result.data.statistics?.numericFields?.amount.sum).toBe(462); // 11 * 42
|
|
73
|
+
expect(result.data.statistics?.numericFields?.amount.min).toBe(42);
|
|
74
|
+
expect(result.data.statistics?.numericFields?.amount.max).toBe(42);
|
|
75
|
+
expect(result.data.statistics?.numericFields?.amount.avg).toBe(42);
|
|
76
|
+
});
|
|
77
|
+
it("should calculate sum correctly with decimal values", () => {
|
|
78
|
+
const response = {
|
|
79
|
+
data: [
|
|
80
|
+
{ id: 1, score: 3.14 },
|
|
81
|
+
{ id: 2, score: 2.71 },
|
|
82
|
+
{ id: 3, score: 1.41 },
|
|
83
|
+
{ id: 4, score: 1.73 },
|
|
84
|
+
{ id: 5, score: 2.23 },
|
|
85
|
+
{ id: 6, score: 0.57 },
|
|
86
|
+
{ id: 7, score: 1.61 },
|
|
87
|
+
{ id: 8, score: 2.44 },
|
|
88
|
+
{ id: 9, score: 3.33 },
|
|
89
|
+
{ id: 10, score: 1.99 },
|
|
90
|
+
{ id: 11, score: 4.66 },
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
const result = transformResponse(response, {
|
|
94
|
+
enabled: true,
|
|
95
|
+
maxResponseSize: 100,
|
|
96
|
+
computeStats: true,
|
|
97
|
+
});
|
|
98
|
+
expect(result.data.statistics?.numericFields?.score).toBeDefined();
|
|
99
|
+
expect(result.data.statistics?.numericFields?.score.sum).toBeCloseTo(25.82, 2);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=response-transformer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-transformer.test.js","sourceRoot":"","sources":["../../../src/server/utils/response-transformer.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ampeco/public-api-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "MCP server that dynamically exposes the AMPECO.CHARGE Public API defined by an OpenAPI 3 specification",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli/index.js",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"start": "node dist/cli/index.js",
|
|
23
23
|
"type-check": "tsc --noEmit",
|
|
24
24
|
"test": "vitest",
|
|
25
|
+
"package:mcpb": "bash scripts/package-mcpb.sh",
|
|
25
26
|
"prepublishOnly": "npm run build"
|
|
26
27
|
},
|
|
27
28
|
"keywords": [
|