@aloma.io/integration-sdk 3.8.52 → 3.8.53

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.
@@ -132,6 +132,9 @@ export class OpenAPIToConnector {
132
132
  */
133
133
  generateJSDoc(operation) {
134
134
  const lines = [];
135
+ const pathParams = [];
136
+ const queryParams = [];
137
+ const hasBody = !!operation.requestBody;
135
138
  if (operation.summary) {
136
139
  lines.push(` * ${operation.summary}`);
137
140
  }
@@ -139,40 +142,63 @@ export class OpenAPIToConnector {
139
142
  lines.push(` *`);
140
143
  // Split long descriptions into multiple lines
141
144
  const descLines = operation.description.split('\n');
142
- descLines.forEach(line => {
145
+ descLines.forEach((line) => {
143
146
  if (line.trim()) {
144
147
  lines.push(` * ${line.trim()}`);
145
148
  }
146
149
  });
147
150
  }
148
- // Document parameters with full details
149
- if (operation.parameters && operation.parameters.length > 0) {
150
- lines.push(' *');
151
- lines.push(' * @param {Object} args - Request arguments');
151
+ // Identify path and query parameters
152
+ if (operation.parameters) {
152
153
  for (const param of operation.parameters) {
153
- if (typeof param === 'object' && 'name' in param) {
154
- const paramName = param.name;
155
- const paramDesc = param.description || '';
156
- const paramRequired = param.required ? '(required)' : '(optional)';
157
- const paramType = param.schema?.type || 'any';
158
- const paramIn = param.in || '';
159
- let paramDoc = ` * @param {${paramType}} args.${paramName} ${paramRequired}`;
160
- if (paramDesc) {
161
- paramDoc += ` - ${paramDesc}`;
154
+ if (typeof param === 'object' && 'name' in param && 'in' in param) {
155
+ if (param.in === 'path') {
156
+ pathParams.push(param);
162
157
  }
163
- if (paramIn) {
164
- paramDoc += ` [${paramIn}]`;
158
+ else if (param.in === 'query') {
159
+ queryParams.push(param);
165
160
  }
166
- lines.push(paramDoc);
167
161
  }
168
162
  }
169
163
  }
170
- // Document request body
171
- if (operation.requestBody) {
164
+ // Check if using simple signature
165
+ const useSimpleSignature = queryParams.length === 0 && !hasBody && pathParams.length <= 1;
166
+ if (useSimpleSignature && pathParams.length === 1) {
167
+ // Simple signature documentation
168
+ const param = pathParams[0];
169
+ const paramType = param.schema?.type || 'string';
170
+ const paramDesc = param.description || '';
172
171
  lines.push(' *');
173
- const bodyDesc = operation.requestBody.description || 'Request body';
174
- const required = operation.requestBody.required ? '(required)' : '(optional)';
175
- lines.push(` * @param {Object} args.body ${required} - ${bodyDesc}`);
172
+ lines.push(` * @param {${paramType}} ${param.name} ${paramDesc}`);
173
+ lines.push(` * @param {Object} options (optional) - Request options`);
174
+ lines.push(` * @param {Object} options.headers - Custom headers`);
175
+ }
176
+ else {
177
+ // Options object documentation
178
+ lines.push(' *');
179
+ lines.push(` * @param {Object} options (optional) - Request options`);
180
+ // Document path parameters
181
+ for (const param of pathParams) {
182
+ const paramType = param.schema?.type || 'string';
183
+ const paramDesc = param.description || '';
184
+ const paramRequired = param.required ? '(required)' : '(optional)';
185
+ lines.push(` * @param {${paramType}} options.${param.name} ${paramRequired} - ${paramDesc} [path]`);
186
+ }
187
+ // Document query parameters
188
+ for (const param of queryParams) {
189
+ const paramType = param.schema?.type || 'any';
190
+ const paramDesc = param.description || '';
191
+ const paramRequired = param.required ? '(required)' : '(optional)';
192
+ lines.push(` * @param {${paramType}} options.${param.name} ${paramRequired} - ${paramDesc} [query]`);
193
+ }
194
+ // Document request body
195
+ if (operation.requestBody) {
196
+ const bodyDesc = operation.requestBody.description || 'Request body';
197
+ const required = operation.requestBody.required ? '(required)' : '(optional)';
198
+ lines.push(` * @param {Object} options.body ${required} - ${bodyDesc}`);
199
+ }
200
+ // Document headers
201
+ lines.push(` * @param {Object} options.headers (optional) - Custom headers to include in the request`);
176
202
  }
177
203
  // Document response
178
204
  lines.push(' *');
@@ -185,6 +211,205 @@ export class OpenAPIToConnector {
185
211
  getOperationsCount() {
186
212
  return this.extractOperations().length;
187
213
  }
214
+ /**
215
+ * Generate method signature with options object
216
+ */
217
+ generateMethodSignature(operation) {
218
+ const pathParams = [];
219
+ const queryParams = [];
220
+ const hasBody = !!operation.requestBody;
221
+ // Identify path and query parameters
222
+ if (operation.parameters) {
223
+ for (const param of operation.parameters) {
224
+ if (typeof param === 'object' && 'name' in param && 'in' in param) {
225
+ if (param.in === 'path') {
226
+ pathParams.push(param.name);
227
+ }
228
+ else if (param.in === 'query') {
229
+ queryParams.push(param.name);
230
+ }
231
+ }
232
+ }
233
+ }
234
+ // If there are no query params, no body, and only path params, use simple signature
235
+ if (queryParams.length === 0 && !hasBody && pathParams.length <= 1) {
236
+ const params = [];
237
+ for (const paramName of pathParams) {
238
+ params.push(`${paramName}: string`);
239
+ }
240
+ params.push(`options?: {headers?: {[key: string]: any}}`);
241
+ return `(${params.join(', ')})`;
242
+ }
243
+ // Otherwise, use options object pattern
244
+ return `(options?: {${[
245
+ ...pathParams.map((p) => `${p}?: string`),
246
+ ...queryParams.map((p) => `${p}?: any`),
247
+ hasBody ? 'body?: any' : '',
248
+ 'headers?: {[key: string]: any}',
249
+ ]
250
+ .filter(Boolean)
251
+ .join(', ')}})`;
252
+ }
253
+ /**
254
+ * Generate method implementation code
255
+ */
256
+ generateMethodImplementation(operation) {
257
+ const lines = [];
258
+ // Build URL with path parameters
259
+ let url = operation.path;
260
+ const pathParams = [];
261
+ const queryParams = [];
262
+ const hasBody = !!operation.requestBody;
263
+ // Identify path and query parameters
264
+ if (operation.parameters) {
265
+ for (const param of operation.parameters) {
266
+ if (typeof param === 'object' && 'name' in param && 'in' in param) {
267
+ if (param.in === 'path') {
268
+ pathParams.push(param.name);
269
+ }
270
+ else if (param.in === 'query') {
271
+ queryParams.push(param.name);
272
+ }
273
+ }
274
+ }
275
+ }
276
+ // Check if using simple signature (single path param, no query/body)
277
+ const useSimpleSignature = queryParams.length === 0 && !hasBody && pathParams.length <= 1;
278
+ if (useSimpleSignature && pathParams.length === 1) {
279
+ // Simple signature: (pathParam: string, options?: {headers?: ...})
280
+ const paramName = pathParams[0];
281
+ lines.push(` let url = '${url}';`);
282
+ lines.push(` if (${paramName}) {`);
283
+ lines.push(` url = url.replace('{${paramName}}', ${paramName});`);
284
+ lines.push(` }`);
285
+ lines.push('');
286
+ lines.push(` return this.api.fetch(url, {`);
287
+ lines.push(` method: '${operation.method}',`);
288
+ lines.push(` headers: options?.headers,`);
289
+ lines.push(` });`);
290
+ }
291
+ else {
292
+ // Options object pattern
293
+ lines.push(` options = options || {};`);
294
+ lines.push('');
295
+ // Replace path parameters
296
+ if (pathParams.length > 0) {
297
+ lines.push(` // Build URL with path parameters`);
298
+ lines.push(` let url = '${url}';`);
299
+ for (const paramName of pathParams) {
300
+ lines.push(` if (options.${paramName}) {`);
301
+ lines.push(` url = url.replace('{${paramName}}', options.${paramName});`);
302
+ lines.push(` }`);
303
+ }
304
+ lines.push('');
305
+ }
306
+ else {
307
+ lines.push(` const url = '${url}';`);
308
+ lines.push('');
309
+ }
310
+ // Build fetch options
311
+ lines.push(` const fetchOptions: any = {`);
312
+ lines.push(` method: '${operation.method}',`);
313
+ // Add query parameters
314
+ if (queryParams.length > 0) {
315
+ lines.push(` params: {},`);
316
+ }
317
+ // Add body if present
318
+ if (hasBody) {
319
+ lines.push(` body: options.body,`);
320
+ }
321
+ // Add headers if present
322
+ lines.push(` headers: options.headers,`);
323
+ lines.push(` };`);
324
+ lines.push('');
325
+ // Add query parameters to options
326
+ if (queryParams.length > 0) {
327
+ lines.push(` // Add query parameters`);
328
+ for (const paramName of queryParams) {
329
+ lines.push(` if (options.${paramName} !== undefined) {`);
330
+ lines.push(` fetchOptions.params.${paramName} = options.${paramName};`);
331
+ lines.push(` }`);
332
+ }
333
+ lines.push('');
334
+ }
335
+ // Make the API call
336
+ lines.push(` return this.api.fetch(url, fetchOptions);`);
337
+ }
338
+ return lines.join('\n');
339
+ }
340
+ /**
341
+ * Generate proper import paths with .mjs extensions for TypeScript module resolution
342
+ */
343
+ generateImportPath(relativePath) {
344
+ // For resource classes, we need to reference the compiled .mjs files
345
+ return relativePath.endsWith('.mjs') ? relativePath : `${relativePath}.mjs`;
346
+ }
347
+ /**
348
+ * Generate a resource class (does NOT extend AbstractController, receives controller reference)
349
+ */
350
+ generateResourceClass(className) {
351
+ const operations = this.extractOperations();
352
+ if (operations.length === 0) {
353
+ throw new Error('No operations found in OpenAPI specification');
354
+ }
355
+ const methods = operations
356
+ .map((operation) => {
357
+ const methodName = this.generateMethodName(operation);
358
+ const jsdoc = this.generateJSDoc(operation);
359
+ const signature = this.generateMethodSignature(operation);
360
+ const implementation = this.generateMethodImplementation(operation);
361
+ return ` /**\n${jsdoc}\n */\n async ${methodName}${signature} {\n${implementation}\n }`;
362
+ })
363
+ .join('\n\n');
364
+ return `import {AbstractController} from '@aloma.io/integration-sdk';
365
+
366
+ export default class ${className} {
367
+ private controller: AbstractController;
368
+
369
+ constructor(controller: AbstractController) {
370
+ this.controller = controller;
371
+ }
372
+
373
+ private get api() {
374
+ return this.controller['api'];
375
+ }
376
+
377
+ ${methods}
378
+ }`;
379
+ }
380
+ /**
381
+ * Generate a main controller that composes multiple resources
382
+ */
383
+ generateMainController(resources) {
384
+ // Get base URL from servers if available
385
+ const baseUrl = this.spec.servers && this.spec.servers.length > 0 ? this.spec.servers[0].url : 'API_BASE_URL';
386
+ const imports = resources
387
+ .map((resource) => `import ${resource.className} from '../resources/${resource.fileName}.mjs';`)
388
+ .join('\n');
389
+ const properties = resources
390
+ .map((resource) => ` ${resource.className.toLowerCase().replace('resource', '')}!: ${resource.className};`)
391
+ .join('\n');
392
+ const initializations = resources
393
+ .map((resource) => ` this.${resource.className.toLowerCase().replace('resource', '')} = new ${resource.className}(this);`)
394
+ .join('\n');
395
+ return `import {AbstractController} from '@aloma.io/integration-sdk';
396
+ ${imports}
397
+
398
+ export default class Controller extends AbstractController {
399
+ ${properties}
400
+
401
+ private api: any;
402
+
403
+ protected async start(): Promise<void> {
404
+ this.api = this.getClient({
405
+ baseUrl: '${baseUrl}',
406
+ });
407
+
408
+ // Initialize each resource - they receive 'this' controller reference
409
+ ${initializations}
410
+ }
411
+ }`;
412
+ }
188
413
  /**
189
414
  * Generate the connector controller code
190
415
  */
@@ -197,13 +422,26 @@ export class OpenAPIToConnector {
197
422
  .map((operation) => {
198
423
  const methodName = this.generateMethodName(operation);
199
424
  const jsdoc = this.generateJSDoc(operation);
200
- return ` /**\n${jsdoc}\n */\n async ${methodName}(args: any) {\n // TODO: Implement ${operation.method} ${operation.path}\n throw new Error('Method not implemented');\n }`;
425
+ const signature = this.generateMethodSignature(operation);
426
+ const implementation = this.generateMethodImplementation(operation);
427
+ return ` /**\n${jsdoc}\n */\n async ${methodName}${signature} {\n${implementation}\n }`;
201
428
  })
202
429
  .join('\n\n');
430
+ // Get base URL from servers if available
431
+ const baseUrl = this.spec.servers && this.spec.servers.length > 0 ? this.spec.servers[0].url : 'API_BASE_URL';
432
+ const startMethod = ` private api: any;
433
+
434
+ protected async start(): Promise<void> {
435
+ this.api = this.getClient({
436
+ baseUrl: '${baseUrl}',
437
+ });
438
+ }`;
203
439
  return `import {AbstractController} from '@aloma.io/integration-sdk';
204
440
 
205
441
  export default class Controller extends AbstractController {
206
442
 
443
+ ${startMethod}
444
+
207
445
  ${methods}
208
446
  }`;
209
447
  }
@@ -0,0 +1,32 @@
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
+
@@ -0,0 +1,310 @@
1
+ import {AbstractController} from '@aloma.io/integration-sdk';
2
+
3
+ export default class CompaniesResource extends AbstractController {
4
+
5
+ /**
6
+ * Retrieve a batch of companies
7
+ *
8
+ * Retrieve a batch of companies by ID (`companyId`) or by a unique property (`idProperty`). You can specify what is returned using the `properties` query parameter.
9
+ *
10
+ * @param {boolean} archived (optional) - Whether to return only results that have been archived. [query]
11
+ *
12
+ * @param {Object} body (required) - Request body
13
+ *
14
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/batch/read response
15
+ */
16
+ async read(archived?: any, body?: any) {
17
+ const url = '/crm/v3/objects/companies/batch/read';
18
+ const options: any = {
19
+ method: 'POST',
20
+ params: {},
21
+ body,
22
+ };
23
+
24
+ // Add query parameters
25
+ if (archived !== undefined) {
26
+ options.params.archived = archived;
27
+ }
28
+
29
+ return this.api.fetch(url, options);
30
+ }
31
+
32
+ /**
33
+ * Retrieve companies
34
+ *
35
+ * Retrieve all companies, using query parameters to control the information that gets returned.
36
+ *
37
+ * @param {integer} limit (optional) - The maximum number of results to display per page. [query]
38
+ * @param {string} after (optional) - The paging cursor token of the last successfully read resource will be returned as the `paging.next.after` JSON property of a paged response containing more results. [query]
39
+ * @param {array} properties (optional) - A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored. [query]
40
+ * @param {array} propertiesWithHistory (optional) - A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored. Usage of this parameter will reduce the maximum number of companies that can be read by a single request. [query]
41
+ * @param {array} associations (optional) - A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored. [query]
42
+ * @param {boolean} archived (optional) - Whether to return only results that have been archived. [query]
43
+ *
44
+ * @returns {Promise<Object>} GET /crm/v3/objects/companies response
45
+ */
46
+ async getPage(limit?: any, after?: any, properties?: any, propertiesWithHistory?: any, associations?: any, archived?: any) {
47
+ const url = '/crm/v3/objects/companies';
48
+ const options: any = {
49
+ method: 'GET',
50
+ params: {},
51
+ };
52
+
53
+ // Add query parameters
54
+ if (limit !== undefined) {
55
+ options.params.limit = limit;
56
+ }
57
+ if (after !== undefined) {
58
+ options.params.after = after;
59
+ }
60
+ if (properties !== undefined) {
61
+ options.params.properties = properties;
62
+ }
63
+ if (propertiesWithHistory !== undefined) {
64
+ options.params.propertiesWithHistory = propertiesWithHistory;
65
+ }
66
+ if (associations !== undefined) {
67
+ options.params.associations = associations;
68
+ }
69
+ if (archived !== undefined) {
70
+ options.params.archived = archived;
71
+ }
72
+
73
+ return this.api.fetch(url, options);
74
+ }
75
+
76
+ /**
77
+ * Create a company
78
+ *
79
+ * Create a single company. Include a `properties` object to define [property values](https://developers.hubspot.com/docs/guides/api/crm/properties) for the company, along with an `associations` array to define [associations](https://developers.hubspot.com/docs/guides/api/crm/associations/associations-v4) with other CRM records.
80
+ *
81
+ * @param {Object} body (required) - Request body
82
+ *
83
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies response
84
+ */
85
+ async create(body?: any) {
86
+ const url = '/crm/v3/objects/companies';
87
+ const options: any = {
88
+ method: 'POST',
89
+ body,
90
+ };
91
+
92
+ return this.api.fetch(url, options);
93
+ }
94
+
95
+ /**
96
+ * Search for companies
97
+ *
98
+ * Search for companies by filtering on properties, searching through associations, and sorting results. Learn more about [CRM search](https://developers.hubspot.com/docs/guides/api/crm/search#make-a-search-request).
99
+ *
100
+ * @param {Object} body (required) - Request body
101
+ *
102
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/search response
103
+ */
104
+ async doSearch(body?: any) {
105
+ const url = '/crm/v3/objects/companies/search';
106
+ const options: any = {
107
+ method: 'POST',
108
+ body,
109
+ };
110
+
111
+ return this.api.fetch(url, options);
112
+ }
113
+
114
+ /**
115
+ * Retrieve a company
116
+ *
117
+ * Retrieve a company by its ID (`companyId`) or by a unique property (`idProperty`). You can specify what is returned using the `properties` query parameter.
118
+ *
119
+ * @param {string} companyId (required) - The ID of the company [path]
120
+ * @param {array} properties (optional) - A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored. [query]
121
+ * @param {array} propertiesWithHistory (optional) - A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored. [query]
122
+ * @param {array} associations (optional) - A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored. [query]
123
+ * @param {boolean} archived (optional) - Whether to return only results that have been archived. [query]
124
+ * @param {string} idProperty (optional) - The name of a property whose values are unique for this object [query]
125
+ *
126
+ * @returns {Promise<Object>} GET /crm/v3/objects/companies/{companyId} response
127
+ */
128
+ async getById(companyId: string, properties?: any, propertiesWithHistory?: any, associations?: any, archived?: any, idProperty?: any) {
129
+ // Build URL with path parameters
130
+ let url = '/crm/v3/objects/companies/{companyId}';
131
+ if (companyId) {
132
+ url = url.replace('{companyId}', companyId);
133
+ }
134
+
135
+ const options: any = {
136
+ method: 'GET',
137
+ params: {},
138
+ };
139
+
140
+ // Add query parameters
141
+ if (properties !== undefined) {
142
+ options.params.properties = properties;
143
+ }
144
+ if (propertiesWithHistory !== undefined) {
145
+ options.params.propertiesWithHistory = propertiesWithHistory;
146
+ }
147
+ if (associations !== undefined) {
148
+ options.params.associations = associations;
149
+ }
150
+ if (archived !== undefined) {
151
+ options.params.archived = archived;
152
+ }
153
+ if (idProperty !== undefined) {
154
+ options.params.idProperty = idProperty;
155
+ }
156
+
157
+ return this.api.fetch(url, options);
158
+ }
159
+
160
+ /**
161
+ * Update a company
162
+ *
163
+ * Update a company by ID (`companyId`) or unique property value (`idProperty`). Provided property values will be overwritten. Read-only and non-existent properties will result in an error. Properties values can be cleared by passing an empty string.
164
+ *
165
+ * @param {string} companyId (required) [path]
166
+ * @param {string} idProperty (optional) - The name of a property whose values are unique for this object [query]
167
+ *
168
+ * @param {Object} body (required) - Request body
169
+ *
170
+ * @returns {Promise<Object>} PATCH /crm/v3/objects/companies/{companyId} response
171
+ */
172
+ async update(companyId: string, idProperty?: any, body?: any) {
173
+ // Build URL with path parameters
174
+ let url = '/crm/v3/objects/companies/{companyId}';
175
+ if (companyId) {
176
+ url = url.replace('{companyId}', companyId);
177
+ }
178
+
179
+ const options: any = {
180
+ method: 'PATCH',
181
+ params: {},
182
+ body,
183
+ };
184
+
185
+ // Add query parameters
186
+ if (idProperty !== undefined) {
187
+ options.params.idProperty = idProperty;
188
+ }
189
+
190
+ return this.api.fetch(url, options);
191
+ }
192
+
193
+ /**
194
+ * Archive a company
195
+ *
196
+ * Delete a company by ID. Deleted companies can be restored within 90 days of deletion. Learn more about [restoring records](https://knowledge.hubspot.com/records/restore-deleted-records).
197
+ *
198
+ * @param {string} companyId (required) [path]
199
+ *
200
+ * @returns {Promise<Object>} DELETE /crm/v3/objects/companies/{companyId} response
201
+ */
202
+ async archive(companyId: string) {
203
+ // Build URL with path parameters
204
+ let url = '/crm/v3/objects/companies/{companyId}';
205
+ if (companyId) {
206
+ url = url.replace('{companyId}', companyId);
207
+ }
208
+
209
+ const options: any = {
210
+ method: 'DELETE',
211
+ };
212
+
213
+ return this.api.fetch(url, options);
214
+ }
215
+
216
+ /**
217
+ * Create or update a batch of companies by unique property values
218
+ *
219
+ * Create or update companies identified by a unique property value as specified by the `idProperty` query parameter. `idProperty` query param refers to a property whose values are unique for the object.
220
+ *
221
+ * @param {Object} body (required) - Request body
222
+ *
223
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/batch/upsert response
224
+ */
225
+ async upsert(body?: any) {
226
+ const url = '/crm/v3/objects/companies/batch/upsert';
227
+ const options: any = {
228
+ method: 'POST',
229
+ body,
230
+ };
231
+
232
+ return this.api.fetch(url, options);
233
+ }
234
+
235
+ /**
236
+ * Create a batch of companies
237
+ *
238
+ * Create a batch of companies. The `inputs` array can contain a `properties` object to define property values for each company, along with an `associations` array to define [associations](https://developers.hubspot.com/docs/guides/api/crm/associations/associations-v4) with other CRM records.
239
+ *
240
+ * @param {Object} body (required) - Request body
241
+ *
242
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/batch/create response
243
+ */
244
+ async create(body?: any) {
245
+ const url = '/crm/v3/objects/companies/batch/create';
246
+ const options: any = {
247
+ method: 'POST',
248
+ body,
249
+ };
250
+
251
+ return this.api.fetch(url, options);
252
+ }
253
+
254
+ /**
255
+ * Update a batch of companies
256
+ *
257
+ * Update a batch of companies by ID.
258
+ *
259
+ * @param {Object} body (required) - Request body
260
+ *
261
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/batch/update response
262
+ */
263
+ async update(body?: any) {
264
+ const url = '/crm/v3/objects/companies/batch/update';
265
+ const options: any = {
266
+ method: 'POST',
267
+ body,
268
+ };
269
+
270
+ return this.api.fetch(url, options);
271
+ }
272
+
273
+ /**
274
+ * Archive a batch of companies
275
+ *
276
+ * Delete a batch of companies by ID. Deleted companies can be restored within 90 days of deletion. Learn more about [restoring records](https://knowledge.hubspot.com/records/restore-deleted-records).
277
+ *
278
+ * @param {Object} body (required) - Request body
279
+ *
280
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/batch/archive response
281
+ */
282
+ async archive(body?: any) {
283
+ const url = '/crm/v3/objects/companies/batch/archive';
284
+ const options: any = {
285
+ method: 'POST',
286
+ body,
287
+ };
288
+
289
+ return this.api.fetch(url, options);
290
+ }
291
+
292
+ /**
293
+ * Merge two companies
294
+ *
295
+ * Merge two company records. Learn more about [merging records](https://knowledge.hubspot.com/records/merge-records).
296
+ *
297
+ * @param {Object} body (required) - Request body
298
+ *
299
+ * @returns {Promise<Object>} POST /crm/v3/objects/companies/merge response
300
+ */
301
+ async merge(body?: any) {
302
+ const url = '/crm/v3/objects/companies/merge';
303
+ const options: any = {
304
+ method: 'POST',
305
+ body,
306
+ };
307
+
308
+ return this.api.fetch(url, options);
309
+ }
310
+ }