@aloma.io/integration-sdk 3.8.54 → 3.8.55
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/openapi-to-connector.d.mts +4 -0
- package/build/openapi-to-connector.mjs +118 -15
- package/package.json +1 -1
- package/src/openapi-to-connector.mts +144 -17
- package/examples/api-without-servers.json +0 -32
- package/examples/companies-resource-class.mts +0 -310
- package/examples/companies-resource.mts +0 -310
- package/examples/complete-example.sh +0 -116
- package/examples/create-hubspot-connector.sh +0 -33
- package/examples/generate-connector.sh +0 -35
- package/examples/generated-controller.mts +0 -81
- package/examples/hubspot-companies.json +0 -1889
- package/examples/hubspot-contacts.json +0 -1919
- package/examples/hubspot-controller-individual-params.mts +0 -323
- package/examples/hubspot-controller-with-implementation.mts +0 -315
- package/examples/hubspot-controller.mts +0 -192
- package/examples/hubspot-lists.json +0 -5525
- package/examples/main-controller-with-resources.mts +0 -35
- package/examples/stripe.json +0 -182829
- package/examples/utility-click.json +0 -8992
@@ -32,6 +32,10 @@ export declare class OpenAPIToConnector {
|
|
32
32
|
* Generate method signature with options object
|
33
33
|
*/
|
34
34
|
private generateMethodSignature;
|
35
|
+
/**
|
36
|
+
* Get TypeScript type for a parameter based on its schema
|
37
|
+
*/
|
38
|
+
private getParameterType;
|
35
39
|
/**
|
36
40
|
* Generate method implementation code
|
37
41
|
*/
|
@@ -186,7 +186,12 @@ export class OpenAPIToConnector {
|
|
186
186
|
else {
|
187
187
|
// Options object documentation
|
188
188
|
lines.push(' *');
|
189
|
-
|
189
|
+
// Check if there are any required parameters
|
190
|
+
const hasRequiredParams = pathParams.some(p => p.required) ||
|
191
|
+
queryParams.some(p => p.required) ||
|
192
|
+
(operation.requestBody && operation.requestBody.required);
|
193
|
+
const optionsRequired = hasRequiredParams ? '(required)' : '(optional)';
|
194
|
+
lines.push(` * @param {Object} options ${optionsRequired} - Request options`);
|
190
195
|
// Document path parameters
|
191
196
|
for (const param of pathParams) {
|
192
197
|
const paramType = param.schema?.type || 'string';
|
@@ -228,15 +233,20 @@ export class OpenAPIToConnector {
|
|
228
233
|
const pathParams = [];
|
229
234
|
const queryParams = [];
|
230
235
|
const hasBody = !!operation.requestBody;
|
231
|
-
// Identify path and query parameters
|
236
|
+
// Identify path and query parameters with their types and required status
|
232
237
|
if (operation.parameters) {
|
233
238
|
for (const param of operation.parameters) {
|
234
239
|
if (typeof param === 'object' && 'name' in param && 'in' in param) {
|
240
|
+
const paramInfo = {
|
241
|
+
name: param.name,
|
242
|
+
required: param.required || false,
|
243
|
+
type: this.getParameterType(param)
|
244
|
+
};
|
235
245
|
if (param.in === 'path') {
|
236
|
-
pathParams.push(
|
246
|
+
pathParams.push(paramInfo);
|
237
247
|
}
|
238
248
|
else if (param.in === 'query') {
|
239
|
-
queryParams.push(
|
249
|
+
queryParams.push(paramInfo);
|
240
250
|
}
|
241
251
|
}
|
242
252
|
}
|
@@ -244,21 +254,114 @@ export class OpenAPIToConnector {
|
|
244
254
|
// If there are no query params, no body, and only path params, use simple signature
|
245
255
|
if (queryParams.length === 0 && !hasBody && pathParams.length <= 1) {
|
246
256
|
const params = [];
|
247
|
-
for (const
|
248
|
-
params.push(`${
|
257
|
+
for (const paramInfo of pathParams) {
|
258
|
+
params.push(`${paramInfo.name}: ${paramInfo.type}`);
|
249
259
|
}
|
250
260
|
params.push(`options?: {headers?: {[key: string]: any}}`);
|
251
261
|
return `(${params.join(', ')})`;
|
252
262
|
}
|
253
|
-
//
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
263
|
+
// Check if there are any required parameters
|
264
|
+
const hasRequiredParams = pathParams.some(p => p.required) ||
|
265
|
+
queryParams.some(p => p.required) ||
|
266
|
+
(hasBody && operation.requestBody?.required);
|
267
|
+
// Build detailed options object with proper types
|
268
|
+
// Group nested properties into objects (e.g., PrimaryContact.FirstName -> PrimaryContact: {FirstName: string})
|
269
|
+
const nestedObjects = new Map();
|
270
|
+
const flatProps = [];
|
271
|
+
// Process all parameters (path + query)
|
272
|
+
const allParams = [...pathParams, ...queryParams];
|
273
|
+
for (const paramInfo of allParams) {
|
274
|
+
if (paramInfo.name.includes('.')) {
|
275
|
+
// This is a nested property like PrimaryContact.FirstName
|
276
|
+
const parts = paramInfo.name.split('.');
|
277
|
+
const objectName = parts[0];
|
278
|
+
const propertyName = parts.slice(1).join('.');
|
279
|
+
if (!nestedObjects.has(objectName)) {
|
280
|
+
nestedObjects.set(objectName, []);
|
281
|
+
}
|
282
|
+
nestedObjects.get(objectName).push({
|
283
|
+
name: propertyName,
|
284
|
+
type: paramInfo.type,
|
285
|
+
required: paramInfo.required
|
286
|
+
});
|
287
|
+
}
|
288
|
+
else {
|
289
|
+
// This is a flat property
|
290
|
+
flatProps.push({
|
291
|
+
name: paramInfo.name,
|
292
|
+
type: paramInfo.type,
|
293
|
+
required: paramInfo.required
|
294
|
+
});
|
295
|
+
}
|
296
|
+
}
|
297
|
+
// Build the options properties array
|
298
|
+
const optionProps = [];
|
299
|
+
// Add flat properties
|
300
|
+
for (const prop of flatProps) {
|
301
|
+
const optional = prop.required ? '' : '?';
|
302
|
+
optionProps.push(`${prop.name}${optional}: ${prop.type}`);
|
303
|
+
}
|
304
|
+
// Add nested objects
|
305
|
+
for (const [objectName, properties] of nestedObjects) {
|
306
|
+
const nestedProps = properties.map(p => {
|
307
|
+
const optional = p.required ? '' : '?';
|
308
|
+
return `${p.name}${optional}: ${p.type}`;
|
309
|
+
}).join(', ');
|
310
|
+
// Check if all properties are optional
|
311
|
+
const allOptional = properties.every(p => !p.required);
|
312
|
+
const optional = allOptional ? '?' : '';
|
313
|
+
optionProps.push(`${objectName}${optional}: {${nestedProps}}`);
|
314
|
+
}
|
315
|
+
// Add request body
|
316
|
+
if (hasBody) {
|
317
|
+
optionProps.push('body?: any');
|
318
|
+
}
|
319
|
+
// Add custom headers
|
320
|
+
optionProps.push('headers?: {[key: string]: any}');
|
321
|
+
// If there are too many parameters, use simplified signature to avoid parsing issues
|
322
|
+
// Also check if any parameter name is too long (over 100 chars) which can cause issues
|
323
|
+
const hasLongParamNames = optionProps.some(prop => prop.length > 100);
|
324
|
+
if (optionProps.length > 15 || hasLongParamNames) {
|
325
|
+
const required = hasRequiredParams ? '' : '?';
|
326
|
+
return `(options${required}: {[key: string]: any})`;
|
327
|
+
}
|
328
|
+
const required = hasRequiredParams ? '' : '?';
|
329
|
+
return `(options${required}: {${optionProps.join(', ')}})`;
|
330
|
+
}
|
331
|
+
/**
|
332
|
+
* Get TypeScript type for a parameter based on its schema
|
333
|
+
*/
|
334
|
+
getParameterType(param) {
|
335
|
+
if (param.schema) {
|
336
|
+
const schema = param.schema;
|
337
|
+
// Handle different schema types
|
338
|
+
if (schema.type) {
|
339
|
+
switch (schema.type) {
|
340
|
+
case 'string':
|
341
|
+
return 'string';
|
342
|
+
case 'integer':
|
343
|
+
case 'number':
|
344
|
+
return 'number';
|
345
|
+
case 'boolean':
|
346
|
+
return 'boolean';
|
347
|
+
case 'array':
|
348
|
+
return 'any[]';
|
349
|
+
case 'object':
|
350
|
+
return 'any';
|
351
|
+
default:
|
352
|
+
return 'any';
|
353
|
+
}
|
354
|
+
}
|
355
|
+
// Handle enum
|
356
|
+
if (schema.enum) {
|
357
|
+
return 'string';
|
358
|
+
}
|
359
|
+
// Handle $ref
|
360
|
+
if (schema.$ref) {
|
361
|
+
return 'any';
|
362
|
+
}
|
363
|
+
}
|
364
|
+
return 'any';
|
262
365
|
}
|
263
366
|
/**
|
264
367
|
* Generate method implementation code
|
package/package.json
CHANGED
@@ -225,7 +225,15 @@ export class OpenAPIToConnector {
|
|
225
225
|
} else {
|
226
226
|
// Options object documentation
|
227
227
|
lines.push(' *');
|
228
|
-
|
228
|
+
|
229
|
+
// Check if there are any required parameters
|
230
|
+
const hasRequiredParams =
|
231
|
+
pathParams.some((p) => p.required) ||
|
232
|
+
queryParams.some((p) => p.required) ||
|
233
|
+
(operation.requestBody && operation.requestBody.required);
|
234
|
+
|
235
|
+
const optionsRequired = hasRequiredParams ? '(required)' : '(optional)';
|
236
|
+
lines.push(` * @param {Object} options ${optionsRequired} - Request options`);
|
229
237
|
|
230
238
|
// Document path parameters
|
231
239
|
for (const param of pathParams) {
|
@@ -272,18 +280,24 @@ export class OpenAPIToConnector {
|
|
272
280
|
* Generate method signature with options object
|
273
281
|
*/
|
274
282
|
private generateMethodSignature(operation: OperationInfo): string {
|
275
|
-
const pathParams: string
|
276
|
-
const queryParams: string
|
283
|
+
const pathParams: Array<{name: string; required: boolean; type: string}> = [];
|
284
|
+
const queryParams: Array<{name: string; required: boolean; type: string}> = [];
|
277
285
|
const hasBody = !!operation.requestBody;
|
278
286
|
|
279
|
-
// Identify path and query parameters
|
287
|
+
// Identify path and query parameters with their types and required status
|
280
288
|
if (operation.parameters) {
|
281
289
|
for (const param of operation.parameters) {
|
282
290
|
if (typeof param === 'object' && 'name' in param && 'in' in param) {
|
291
|
+
const paramInfo = {
|
292
|
+
name: param.name,
|
293
|
+
required: param.required || false,
|
294
|
+
type: this.getParameterType(param),
|
295
|
+
};
|
296
|
+
|
283
297
|
if (param.in === 'path') {
|
284
|
-
pathParams.push(
|
298
|
+
pathParams.push(paramInfo);
|
285
299
|
} else if (param.in === 'query') {
|
286
|
-
queryParams.push(
|
300
|
+
queryParams.push(paramInfo);
|
287
301
|
}
|
288
302
|
}
|
289
303
|
}
|
@@ -292,22 +306,135 @@ export class OpenAPIToConnector {
|
|
292
306
|
// If there are no query params, no body, and only path params, use simple signature
|
293
307
|
if (queryParams.length === 0 && !hasBody && pathParams.length <= 1) {
|
294
308
|
const params: string[] = [];
|
295
|
-
for (const
|
296
|
-
params.push(`${
|
309
|
+
for (const paramInfo of pathParams) {
|
310
|
+
params.push(`${paramInfo.name}: ${paramInfo.type}`);
|
297
311
|
}
|
298
312
|
params.push(`options?: {headers?: {[key: string]: any}}`);
|
299
313
|
return `(${params.join(', ')})`;
|
300
314
|
}
|
301
315
|
|
302
|
-
//
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
hasBody
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
316
|
+
// Check if there are any required parameters
|
317
|
+
const hasRequiredParams =
|
318
|
+
pathParams.some((p) => p.required) ||
|
319
|
+
queryParams.some((p) => p.required) ||
|
320
|
+
(hasBody && operation.requestBody?.required);
|
321
|
+
|
322
|
+
// Build detailed options object with proper types
|
323
|
+
// Group nested properties into objects (e.g., PrimaryContact.FirstName -> PrimaryContact: {FirstName: string})
|
324
|
+
const nestedObjects: Map<string, Array<{name: string; type: string; required: boolean}>> = new Map();
|
325
|
+
const flatProps: Array<{name: string; type: string; required: boolean}> = [];
|
326
|
+
|
327
|
+
// Process all parameters (path + query)
|
328
|
+
const allParams = [...pathParams, ...queryParams];
|
329
|
+
|
330
|
+
for (const paramInfo of allParams) {
|
331
|
+
if (paramInfo.name.includes('.')) {
|
332
|
+
// This is a nested property like PrimaryContact.FirstName
|
333
|
+
const parts = paramInfo.name.split('.');
|
334
|
+
const objectName = parts[0];
|
335
|
+
const propertyName = parts.slice(1).join('.');
|
336
|
+
|
337
|
+
if (!nestedObjects.has(objectName)) {
|
338
|
+
nestedObjects.set(objectName, []);
|
339
|
+
}
|
340
|
+
nestedObjects.get(objectName)!.push({
|
341
|
+
name: propertyName,
|
342
|
+
type: paramInfo.type,
|
343
|
+
required: paramInfo.required,
|
344
|
+
});
|
345
|
+
} else {
|
346
|
+
// This is a flat property
|
347
|
+
flatProps.push({
|
348
|
+
name: paramInfo.name,
|
349
|
+
type: paramInfo.type,
|
350
|
+
required: paramInfo.required,
|
351
|
+
});
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
355
|
+
// Build the options properties array
|
356
|
+
const optionProps: string[] = [];
|
357
|
+
|
358
|
+
// Add flat properties
|
359
|
+
for (const prop of flatProps) {
|
360
|
+
const optional = prop.required ? '' : '?';
|
361
|
+
optionProps.push(`${prop.name}${optional}: ${prop.type}`);
|
362
|
+
}
|
363
|
+
|
364
|
+
// Add nested objects
|
365
|
+
for (const [objectName, properties] of nestedObjects) {
|
366
|
+
const nestedProps = properties
|
367
|
+
.map((p) => {
|
368
|
+
const optional = p.required ? '' : '?';
|
369
|
+
return `${p.name}${optional}: ${p.type}`;
|
370
|
+
})
|
371
|
+
.join(', ');
|
372
|
+
|
373
|
+
// Check if all properties are optional
|
374
|
+
const allOptional = properties.every((p) => !p.required);
|
375
|
+
const optional = allOptional ? '?' : '';
|
376
|
+
|
377
|
+
optionProps.push(`${objectName}${optional}: {${nestedProps}}`);
|
378
|
+
}
|
379
|
+
|
380
|
+
// Add request body
|
381
|
+
if (hasBody) {
|
382
|
+
optionProps.push('body?: any');
|
383
|
+
}
|
384
|
+
|
385
|
+
// Add custom headers
|
386
|
+
optionProps.push('headers?: {[key: string]: any}');
|
387
|
+
|
388
|
+
// If there are too many parameters, use simplified signature to avoid parsing issues
|
389
|
+
// Also check if any parameter name is too long (over 100 chars) which can cause issues
|
390
|
+
const hasLongParamNames = optionProps.some((prop) => prop.length > 100);
|
391
|
+
if (optionProps.length > 15 || hasLongParamNames) {
|
392
|
+
const required = hasRequiredParams ? '' : '?';
|
393
|
+
return `(options${required}: {[key: string]: any})`;
|
394
|
+
}
|
395
|
+
|
396
|
+
const required = hasRequiredParams ? '' : '?';
|
397
|
+
return `(options${required}: {${optionProps.join(', ')}})`;
|
398
|
+
}
|
399
|
+
|
400
|
+
/**
|
401
|
+
* Get TypeScript type for a parameter based on its schema
|
402
|
+
*/
|
403
|
+
private getParameterType(param: any): string {
|
404
|
+
if (param.schema) {
|
405
|
+
const schema = param.schema;
|
406
|
+
|
407
|
+
// Handle different schema types
|
408
|
+
if (schema.type) {
|
409
|
+
switch (schema.type) {
|
410
|
+
case 'string':
|
411
|
+
return 'string';
|
412
|
+
case 'integer':
|
413
|
+
case 'number':
|
414
|
+
return 'number';
|
415
|
+
case 'boolean':
|
416
|
+
return 'boolean';
|
417
|
+
case 'array':
|
418
|
+
return 'any[]';
|
419
|
+
case 'object':
|
420
|
+
return 'any';
|
421
|
+
default:
|
422
|
+
return 'any';
|
423
|
+
}
|
424
|
+
}
|
425
|
+
|
426
|
+
// Handle enum
|
427
|
+
if (schema.enum) {
|
428
|
+
return 'string';
|
429
|
+
}
|
430
|
+
|
431
|
+
// Handle $ref
|
432
|
+
if (schema.$ref) {
|
433
|
+
return 'any';
|
434
|
+
}
|
435
|
+
}
|
436
|
+
|
437
|
+
return 'any';
|
311
438
|
}
|
312
439
|
|
313
440
|
/**
|
@@ -1,32 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"openapi": "3.0.0",
|
3
|
-
"info": {
|
4
|
-
"title": "Test API",
|
5
|
-
"version": "1.0.0",
|
6
|
-
"description": "API without servers definition"
|
7
|
-
},
|
8
|
-
"paths": {
|
9
|
-
"/users": {
|
10
|
-
"get": {
|
11
|
-
"summary": "List users",
|
12
|
-
"operationId": "listUsers",
|
13
|
-
"parameters": [
|
14
|
-
{
|
15
|
-
"name": "limit",
|
16
|
-
"in": "query",
|
17
|
-
"schema": {
|
18
|
-
"type": "integer"
|
19
|
-
},
|
20
|
-
"description": "Maximum number of users"
|
21
|
-
}
|
22
|
-
],
|
23
|
-
"responses": {
|
24
|
-
"200": {
|
25
|
-
"description": "Success"
|
26
|
-
}
|
27
|
-
}
|
28
|
-
}
|
29
|
-
}
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|