@aloma.io/integration-sdk 3.8.57 → 3.8.60
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/build/builder/runtime-context.d.mts +11 -0
- package/build/builder/runtime-context.mjs +36 -8
- package/build/cli.mjs +11 -5
- package/build/openapi-to-connector.d.mts +16 -1
- package/build/openapi-to-connector.mjs +115 -9
- package/package.json +1 -1
- package/src/builder/runtime-context.mts +38 -9
- package/src/cli.mts +11 -5
- package/src/openapi-to-connector.mts +135 -9
- package/test/nested-resolver.test.mjs +184 -0
- package/test/openapi-generator-bugs.test.mjs +248 -0
- package/test/openapi-nested-paths.test.mjs +100 -0
- package/test/scenarios/complex/expected/orders-resource.mts +3 -5
- package/test/scenarios/complex/expected/products-resource.mts +3 -5
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { OpenAPIToConnector } from '../build/openapi-to-connector.mjs';
|
|
2
|
+
|
|
3
|
+
// Simple test framework matching project convention
|
|
4
|
+
const colors = {
|
|
5
|
+
green: '\x1b[32m',
|
|
6
|
+
red: '\x1b[31m',
|
|
7
|
+
yellow: '\x1b[33m',
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
cyan: '\x1b[36m'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
let passed = 0;
|
|
13
|
+
let failed = 0;
|
|
14
|
+
|
|
15
|
+
async function test(name, fn) {
|
|
16
|
+
try {
|
|
17
|
+
console.log(`${colors.cyan}Running: ${name}${colors.reset}`);
|
|
18
|
+
await fn();
|
|
19
|
+
console.log(`${colors.green}✓ PASS: ${name}${colors.reset}\n`);
|
|
20
|
+
passed++;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.log(`${colors.red}✗ FAIL: ${name}${colors.reset}`);
|
|
23
|
+
console.log(`${colors.red} Error: ${error.message}${colors.reset}\n`);
|
|
24
|
+
failed++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function assert(condition, message) {
|
|
29
|
+
if (!condition) throw new Error(message || 'Assertion failed');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function assertEqual(actual, expected, message) {
|
|
33
|
+
if (actual !== expected) {
|
|
34
|
+
throw new Error(message || `Expected "${expected}", got "${actual}"`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Minimal OpenAPI spec for testing
|
|
39
|
+
const minimalSpec = {
|
|
40
|
+
openapi: '3.0.0',
|
|
41
|
+
info: { title: 'Test API', version: '1.0.0' },
|
|
42
|
+
paths: {}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// --- TESTS ---
|
|
46
|
+
|
|
47
|
+
// Test 1: GET /crm/v3/objects/contacts with opId -> crm.contacts.getPage
|
|
48
|
+
await test('nestedPaths: GET /crm/v3/objects/contacts -> crm.contacts.getPage', async () => {
|
|
49
|
+
const generator = new OpenAPIToConnector(minimalSpec, 'hubspot', { nestedPaths: true });
|
|
50
|
+
assert(typeof generator.deriveMethodPath === 'function', 'deriveMethodPath should be a method on the generator');
|
|
51
|
+
const result = generator.deriveMethodPath('GET', '/crm/v3/objects/contacts', 'get-/crm/v3/objects/contacts_getPage');
|
|
52
|
+
assertEqual(result, 'crm.contacts.getPage');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Test 2: POST /crm/v3/objects/contacts with opId -> crm.contacts.create
|
|
56
|
+
await test('nestedPaths: POST /crm/v3/objects/contacts -> crm.contacts.create', async () => {
|
|
57
|
+
const generator = new OpenAPIToConnector(minimalSpec, 'hubspot', { nestedPaths: true });
|
|
58
|
+
const result = generator.deriveMethodPath('POST', '/crm/v3/objects/contacts', 'post-/crm/v3/objects/contacts_create');
|
|
59
|
+
assertEqual(result, 'crm.contacts.create');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Test 3: Dedup - POST /crm/v3/objects/contacts/merge with opId _merge -> crm.contacts.merge (NOT crm.contacts.merge.merge)
|
|
63
|
+
await test('nestedPaths: dedup - POST /crm/v3/objects/contacts/merge -> crm.contacts.merge', async () => {
|
|
64
|
+
const generator = new OpenAPIToConnector(minimalSpec, 'hubspot', { nestedPaths: true });
|
|
65
|
+
const result = generator.deriveMethodPath('POST', '/crm/v3/objects/contacts/merge', 'post-/crm/v3/objects/contacts/merge_merge');
|
|
66
|
+
assertEqual(result, 'crm.contacts.merge');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Test 4: Batch - POST /crm/v3/objects/contacts/batch/archive -> crm.contacts.batch.archive (NOT duplicated)
|
|
70
|
+
await test('nestedPaths: batch - POST /crm/v3/objects/contacts/batch/archive -> crm.contacts.batch.archive', async () => {
|
|
71
|
+
const generator = new OpenAPIToConnector(minimalSpec, 'hubspot', { nestedPaths: true });
|
|
72
|
+
const result = generator.deriveMethodPath('POST', '/crm/v3/objects/contacts/batch/archive', 'post-/crm/v3/objects/contacts/batch/archive_archive');
|
|
73
|
+
assertEqual(result, 'crm.contacts.batch.archive');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Test 5: Flat mode (nestedPaths: false) -> just getPage (existing behavior unchanged)
|
|
77
|
+
await test('flat mode (nestedPaths: false): same input -> just getPage', async () => {
|
|
78
|
+
const generator = new OpenAPIToConnector(minimalSpec, 'hubspot', { nestedPaths: false });
|
|
79
|
+
const result = generator.deriveMethodPath('GET', '/crm/v3/objects/contacts', 'get-/crm/v3/objects/contacts_getPage');
|
|
80
|
+
assertEqual(result, 'getPage');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Test 6: Flat mode with no options (default behavior unchanged)
|
|
84
|
+
await test('flat mode (no options): same input -> just getPage', async () => {
|
|
85
|
+
const generator = new OpenAPIToConnector(minimalSpec, 'hubspot');
|
|
86
|
+
const result = generator.deriveMethodPath('GET', '/crm/v3/objects/contacts', 'get-/crm/v3/objects/contacts_getPage');
|
|
87
|
+
assertEqual(result, 'getPage');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// --- SUMMARY ---
|
|
91
|
+
console.log(`\n${colors.yellow}--- OpenAPI Nested Paths Test Results ---${colors.reset}`);
|
|
92
|
+
console.log(`${colors.green}Passed: ${passed}${colors.reset}`);
|
|
93
|
+
console.log(`${colors.red}Failed: ${failed}${colors.reset}`);
|
|
94
|
+
|
|
95
|
+
if (failed > 0) {
|
|
96
|
+
console.log(`\n${colors.red}Some tests failed!${colors.reset}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
} else {
|
|
99
|
+
console.log(`\n${colors.green}All nested path tests passed!${colors.reset}`);
|
|
100
|
+
}
|
|
@@ -117,7 +117,7 @@ export function getOrders(this: any, options?: {status?: string, customerId?: st
|
|
|
117
117
|
fetchOptions.params.limit = options.limit;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
return this.api.fetch(url, fetchOptions);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
@@ -156,7 +156,7 @@ export function createOrder(this: any, options: {customerId: string /** Customer
|
|
|
156
156
|
headers: options.headers,
|
|
157
157
|
};
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
return this.api.fetch(url, fetchOptions);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
/**
|
|
@@ -187,7 +187,6 @@ export function getOrder(this: any, orderId: string) {
|
|
|
187
187
|
return this.api.fetch(url, {
|
|
188
188
|
method: 'GET',
|
|
189
189
|
});
|
|
190
|
-
return this.api.fetch(url, fetchOptions);
|
|
191
190
|
}
|
|
192
191
|
|
|
193
192
|
/**
|
|
@@ -229,7 +228,7 @@ export function updateOrderStatus(this: any, orderId: string, options: {status:
|
|
|
229
228
|
headers: options.headers,
|
|
230
229
|
};
|
|
231
230
|
|
|
232
|
-
|
|
231
|
+
return this.api.fetch(url, fetchOptions);
|
|
233
232
|
}
|
|
234
233
|
|
|
235
234
|
/**
|
|
@@ -260,5 +259,4 @@ export function cancelOrder(this: any, orderId: string) {
|
|
|
260
259
|
return this.api.fetch(url, {
|
|
261
260
|
method: 'POST',
|
|
262
261
|
});
|
|
263
|
-
return this.api.fetch(url, fetchOptions);
|
|
264
262
|
}
|
|
@@ -98,7 +98,7 @@ export function getProducts(this: any, options?: {limit?: number, category?: str
|
|
|
98
98
|
fetchOptions.params.archived = options.archived;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
return this.api.fetch(url, fetchOptions);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
@@ -138,7 +138,7 @@ export function createProduct(this: any, options: {name: string /** Product name
|
|
|
138
138
|
headers: options.headers,
|
|
139
139
|
};
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
return this.api.fetch(url, fetchOptions);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/**
|
|
@@ -169,7 +169,6 @@ export function getProduct(this: any, productId: string) {
|
|
|
169
169
|
return this.api.fetch(url, {
|
|
170
170
|
method: 'GET',
|
|
171
171
|
});
|
|
172
|
-
return this.api.fetch(url, fetchOptions);
|
|
173
172
|
}
|
|
174
173
|
|
|
175
174
|
/**
|
|
@@ -215,7 +214,7 @@ export function updateProduct(this: any, productId: string, options: {name: stri
|
|
|
215
214
|
headers: options.headers,
|
|
216
215
|
};
|
|
217
216
|
|
|
218
|
-
|
|
217
|
+
return this.api.fetch(url, fetchOptions);
|
|
219
218
|
}
|
|
220
219
|
|
|
221
220
|
/**
|
|
@@ -235,5 +234,4 @@ export function deleteProduct(this: any, productId: string) {
|
|
|
235
234
|
return this.api.fetch(url, {
|
|
236
235
|
method: 'DELETE',
|
|
237
236
|
});
|
|
238
|
-
return this.api.fetch(url, fetchOptions);
|
|
239
237
|
}
|