totalum-api-sdk 2.0.42 → 3.0.1

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 CHANGED
@@ -1,20 +1,106 @@
1
- ## Totalum api sdk wrapper
1
+ ## Totalum API SDK (v3.0.1)
2
2
 
3
- This library wraps the totalum public api, so you can easy call all endpoints.
3
+ Official TypeScript/JavaScript SDK for the Totalum API. This library provides a fully typed, modern interface to interact with all Totalum endpoints.
4
4
 
5
-
6
- ## Installation:
5
+ ## Installation
7
6
 
8
7
  ```bash
9
8
  npm i totalum-api-sdk
10
9
  ```
11
10
 
11
+ ## What's New in v3.0
12
+
13
+ - **Native Fetch**: Removed `axios` dependency, now using native `fetch` API (works in Node.js 18+ and browsers)
14
+ - **Typed Responses**: All methods return strongly-typed `TotalumApiResponse<T>` with proper TypeScript support
15
+ - **Better Error Handling**: Introduced `TotalumError` class for structured error handling
16
+ - **Renamed Methods**: More consistent naming (`getItems` → `getRecords`, `getItemById` → `getRecordById`, etc.)
17
+ - **Improved Type Safety**: Full TypeScript support with detailed response types
18
+ - **No Breaking Changes in API**: Same Totalum API, just better developer experience
19
+
20
+ ## Migration Guide (v2.x → v3.0)
21
+
22
+ ### Breaking Changes
23
+
24
+ #### 1. Method Names (CRUD Service)
25
+ ```javascript
26
+ // v2.x
27
+ await totalumClient.crud.getItemById(table, id);
28
+ await totalumClient.crud.getItems(table, query);
29
+ await totalumClient.crud.createItem(table, data);
30
+ await totalumClient.crud.editItemById(table, id, data);
31
+ await totalumClient.crud.deleteItemById(table, id);
32
+ await totalumClient.crud.addManyToManyReferenceItem(table, id, prop, refId);
33
+ await totalumClient.crud.dropManyToManyReferenceItem(table, id, prop, refId);
34
+ await totalumClient.crud.getManyToManyReferencesItems(table, id, prop, query);
35
+
36
+ // v3.0
37
+ await totalumClient.crud.getRecordById(table, id);
38
+ await totalumClient.crud.getRecords(table, query);
39
+ await totalumClient.crud.createRecord(table, data);
40
+ await totalumClient.crud.editRecordById(table, id, data);
41
+ await totalumClient.crud.deleteRecordById(table, id);
42
+ await totalumClient.crud.addManyToManyReferenceRecord(table, id, prop, refId);
43
+ await totalumClient.crud.dropManyToManyReferenceRecord(table, id, prop, refId);
44
+ await totalumClient.crud.getManyToManyReferencesRecords(table, id, prop, query);
45
+ ```
46
+
47
+ #### 2. Response Structure
48
+ ```javascript
49
+ // v2.x (using axios)
50
+ const result = await totalumClient.crud.getItems(table, {});
51
+ const items = result.data.data; // Double .data because of axios wrapper
52
+
53
+ // v3.0 (using fetch)
54
+ const result = await totalumClient.crud.getRecords(table, {});
55
+ if (result.errors) {
56
+ console.error('Error:', result.errors.errorMessage);
57
+ return;
58
+ }
59
+ const records = result.data; // Direct access to data
60
+ ```
61
+
62
+ #### 3. Error Handling
63
+ ```javascript
64
+ // v2.x (axios throws errors)
65
+ try {
66
+ const result = await totalumClient.crud.getItems(table, {});
67
+ const items = result.data.data;
68
+ } catch (error) {
69
+ console.error('Error:', error.message);
70
+ }
71
+
72
+ // v3.0 (errors in response object)
73
+ const result = await totalumClient.crud.getRecords(table, {});
74
+ if (result.errors) {
75
+ console.error('Error:', result.errors.errorMessage);
76
+ console.error('Error Code:', result.errors.errorCode);
77
+ return;
78
+ }
79
+ const records = result.data;
80
+ ```
81
+
82
+ ### Dependencies
83
+ ```json
84
+ // v2.x
85
+ {
86
+ "dependencies": {
87
+ "axios": "^1.x.x"
88
+ }
89
+ }
90
+
91
+ // v3.0 (no dependencies!)
92
+ {
93
+ "dependencies": {}
94
+ }
95
+ ```
96
+
97
+ **Note:** v3.0 requires Node.js 18+ (for native fetch support). If you're using an older Node.js version, you'll need to polyfill `fetch` or upgrade to Node.js 18+.
12
98
 
13
99
  # Usage of TotalumApiSdk
14
100
 
15
- Totalum allows you to use the SDK to perform actions such as creating users, creating items, creating pdfs, etc.
101
+ Totalum allows you to use the SDK to perform actions such as creating records, managing files, creating PDFs, sending emails, and more.
16
102
 
17
- Basically the Totalum sdk is a wrapper of the Totalum api, so if you want you can use the api directly if you prefer.
103
+ The SDK is a fully-typed wrapper around the Totalum REST API.
18
104
 
19
105
  ### What happens if you are not programming in javascript?
20
106
 
@@ -22,7 +108,7 @@ If you are not programming in javascript, you can use the api directly, see <a h
22
108
 
23
109
  ## Authentication
24
110
 
25
- **Note:** If you use totalumSdk inside a totalum plugin, you don't need to authenticate, you can start using totalum like this: modules.totalumSdk.your.function();-> example: modules.totalumSdk.crud.getItems('your_item', {})
111
+ **Note:** If you use totalumSdk inside a totalum plugin, you don't need to authenticate, you can start using totalum like this: modules.totalumSdk.your.function();-> example: modules.totalumSdk.crud.getRecords('your_table', {})
26
112
 
27
113
  You can choose to use one of the two authentication methods offered by Totalum Sdk:
28
114
 
@@ -55,8 +141,8 @@ const options: AuthOptions = {
55
141
  const totalumClient = new TotalumApiSdk(options);
56
142
 
57
143
  // execute some TotalumApiSdk function
58
- const result = await totalumClient.crud.getItems('your_element_table_name', {});
59
-
144
+ const result = await totalumClient.crud.getRecords('your_table_name', {});
145
+
60
146
  ```
61
147
 
62
148
  **CommonJS Require:**
@@ -84,15 +170,15 @@ const options = {
84
170
  const totalumClient = new totalum.TotalumApiSdk(options);
85
171
 
86
172
  // execute some TotalumApiSdk function
87
- const result = await totalumClient.crud.getItems('your_element_table_name', {});
88
-
173
+ const result = await totalumClient.crud.getRecords('your_table_name', {});
174
+
89
175
  ```
90
176
 
91
177
  **HTML script import:** (Use this way if you are using standalone html, and you cannot import npm packages)
92
178
 
93
179
  ```html
94
180
  <head>
95
- <script src="https://cdn.jsdelivr.net/npm/totalum-api-sdk@2.0.37/dist/totalum-sdk.min.js"></script>
181
+ <script src="https://cdn.jsdelivr.net/npm/totalum-api-sdk@3.0.1/dist/totalum-sdk.min.js"></script>
96
182
  </head>
97
183
  <script>
98
184
  //Example of use TotalumSdk in your custom html page
@@ -103,42 +189,119 @@ const result = await totalumClient.crud.getItems('your_element_table_name', {});
103
189
  }
104
190
  });
105
191
 
106
- const tableElementName = 'your-table-name'; // replace with your table name
192
+ const tableName = 'your-table-name'; // replace with your table name
107
193
 
108
194
  //example of endpoint execution
109
- const result = totalumClient.crud.getItems(tableElementName, {}).then((result) => {
110
- const items = result.data.data;
111
- console.log("THE ITEMS", items);
195
+ totalumClient.crud.getRecords(tableName, {}).then((result) => {
196
+ if (result.errors) {
197
+ console.error("ERROR:", result.errors);
198
+ return;
199
+ }
200
+ const records = result.data;
201
+ console.log("THE RECORDS", records);
112
202
  });
113
-
203
+
114
204
  </script>
115
205
  ```
116
206
 
207
+ ## Response Structure
117
208
 
118
- ## Functions for create, read, filter, update, delete. (CRUD)
209
+ All SDK methods return a `TotalumApiResponse<T>` object with the following structure:
210
+
211
+ ```typescript
212
+ interface TotalumApiResponse<T> {
213
+ data?: T; // The successful response data
214
+ errors?: ErrorResult; // Error information if request failed
215
+ }
216
+
217
+ interface ErrorResult {
218
+ errorCode: string;
219
+ errorMessage: string;
220
+ hasManyErrors?: boolean;
221
+ multipleErrors?: Array<{ errorCode: string; errorMessage: string }>;
222
+ }
223
+ ```
224
+
225
+ **Example:**
226
+
227
+ ```typescript
228
+ const result = await totalumClient.crud.getRecordById('users', 'user-id-123');
229
+
230
+ // Always check for errors first
231
+ if (result.errors) {
232
+ console.error('Error:', result.errors.errorMessage);
233
+ console.error('Error Code:', result.errors.errorCode);
234
+ return;
235
+ }
236
+
237
+ // Now you can safely use result.data
238
+ const user = result.data;
239
+ console.log('User:', user);
240
+ ```
241
+
242
+ ## Error Handling
243
+
244
+ The SDK provides a `TotalumError` class for structured error handling:
245
+
246
+ ```typescript
247
+ import { TotalumError } from 'totalum-api-sdk';
248
+
249
+ const result = await totalumClient.crud.getRecordById('users', 'invalid-id');
250
+
251
+ if (result.errors) {
252
+ // You can create a TotalumError for better error handling
253
+ const error = new TotalumError(result.errors);
254
+ console.error('Error Code:', error.errorCode);
255
+ console.error('Error Message:', error.errorMessage);
119
256
 
257
+ // Check for multiple errors
258
+ if (error.hasManyErrors && error.multipleErrors) {
259
+ error.multipleErrors.forEach(err => {
260
+ console.error(`- ${err.errorCode}: ${err.errorMessage}`);
261
+ });
262
+ }
263
+ }
264
+ ```
265
+
266
+ ## Functions for create, read, filter, update, delete. (CRUD)
120
267
 
121
- ### Get item by id
122
268
 
269
+ ### Get record by id
123
270
 
124
271
  ```javascript
125
272
 
126
- // get item by id from your_element_table_name
127
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
128
- let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item object
129
- const result = await totalumClient.crud.getItemById(tableElementName, your_item_id);
130
- const item = result.data.data;
273
+ // Get a single record by id
274
+ const tableName = 'users'; // replace with your table name
275
+ const recordId = 'record-id-123'; // replace with your record id
276
+
277
+ const result = await totalumClient.crud.getRecordById(tableName, recordId);
278
+
279
+ if (result.errors) {
280
+ console.error('Error:', result.errors.errorMessage);
281
+ return;
282
+ }
283
+
284
+ const record = result.data;
285
+ console.log('Record:', record);
131
286
 
132
287
  ```
133
288
 
134
- ### Get items
289
+ ### Get records
135
290
 
136
291
  ```javascript
137
292
 
138
- // get items from your_element_table_name (for default 50 items per page)
139
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
140
- const result = await totalumClient.crud.getItems(tableElementName, {});
141
- const items = result.data.data;
293
+ // Get records from a table (default: first 50 records)
294
+ const tableName = 'users'; // replace with your table name
295
+
296
+ const result = await totalumClient.crud.getRecords(tableName, {});
297
+
298
+ if (result.errors) {
299
+ console.error('Error:', result.errors.errorMessage);
300
+ return;
301
+ }
302
+
303
+ const records = result.data;
304
+ console.log('Records:', records);
142
305
 
143
306
  ```
144
307
 
@@ -305,120 +468,191 @@ const products = result.data.data;
305
468
  You can do the same approach to get the orders.
306
469
 
307
470
 
308
- ### delete item by id
471
+ ### Delete record by id
309
472
 
310
473
  ```javascript
311
- // delete item by id from your_element_table_name
312
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
313
- let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item object
314
- const result = await totalumClient.crud.deleteItemById(tableElementName, your_item_id);
474
+
475
+ // Delete a record by id
476
+ const tableName = 'users';
477
+ const recordId = 'record-id-123';
478
+
479
+ const result = await totalumClient.crud.deleteRecordById(tableName, recordId);
480
+
481
+ if (result.errors) {
482
+ console.error('Error:', result.errors.errorMessage);
483
+ return;
484
+ }
485
+
486
+ console.log('Deleted count:', result.data.deletedCount);
487
+ console.log('Acknowledged:', result.data.acknowledged);
315
488
 
316
489
  ```
317
490
 
318
- ### edit item by id
491
+ ### Edit record by id
319
492
 
320
493
  ```javascript
321
- // edit item by id from your_element_table_name, you can edit 1 or multiple properties at the same time (like a patch)
322
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
323
- let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item object
324
- const result = await totalumClient.crud.editItemById(tableElementName, your_item_id, {your_item_property: 'new value'});
494
+
495
+ // Edit a record by id (you can edit one or multiple properties at the same time)
496
+ const tableName = 'users';
497
+ const recordId = 'record-id-123';
498
+ const updates = {
499
+ name: 'John Doe',
500
+ email: 'john@example.com',
501
+ age: 30
502
+ };
503
+
504
+ const result = await totalumClient.crud.editRecordById(tableName, recordId, updates);
505
+
506
+ if (result.errors) {
507
+ console.error('Error:', result.errors.errorMessage);
508
+ return;
509
+ }
510
+
511
+ // Returns the full updated record
512
+ const updatedRecord = result.data;
513
+ console.log('Updated record:', updatedRecord);
514
+ console.log('New name:', updatedRecord.name);
515
+ console.log('New email:', updatedRecord.email);
325
516
 
326
517
  ```
327
518
 
328
- ### create item
519
+ ### Create record
329
520
 
330
521
  ```javascript
331
- // create item from your_element_table_name, you need to pass at least the required properties
332
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
333
- const result = await totalumClient.crud.createItem(tableElementName, {your_item_property: 'new value'});
522
+
523
+ // Create a new record (you need to pass at least the required properties)
524
+ const tableName = 'users';
525
+ const newRecord = {
526
+ name: 'Jane Doe',
527
+ email: 'jane@example.com',
528
+ age: 25
529
+ };
530
+
531
+ const result = await totalumClient.crud.createRecord(tableName, newRecord);
532
+
533
+ if (result.errors) {
534
+ console.error('Error:', result.errors.errorMessage);
535
+ return;
536
+ }
537
+
538
+ // Returns the full created record
539
+ const createdRecord = result.data;
540
+ console.log('Created record:', createdRecord);
541
+ console.log('Record ID:', createdRecord._id);
542
+ console.log('Name:', createdRecord.name);
334
543
 
335
544
  ```
336
545
 
337
- ### add many to many reference item (add a reference to another item that have a many to many relationship)
546
+ ### Add many-to-many reference (add a reference to another record with a many-to-many relationship)
338
547
 
339
548
  ```javascript
340
549
 
341
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
342
- let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item
343
- const propertyName = 'your_property_name'; // replace 'your_property_name' with the name of the property that have a many to many relationship
344
- const referenceId = 'your_reference_item_id'; // replace 'your_reference_item_id' with the id of the item that you want to add as a many to many reference
345
- const result = await totalumClient.crud.addManyToManyReferenceItem(tableElementName, your_item_id, propertyName, referenceId);
550
+ const tableName = 'students';
551
+ const recordId = 'student-id-123';
552
+ const propertyName = 'courses'; // the property that defines the many-to-many relationship
553
+ const referenceId = 'course-id-456'; // the id of the record to link
554
+
555
+ const result = await totalumClient.crud.addManyToManyReferenceRecord(tableName, recordId, propertyName, referenceId);
556
+
557
+ if (result.errors) {
558
+ console.error('Error:', result.errors.errorMessage);
559
+ return;
560
+ }
561
+
562
+ console.log('Reference added successfully');
346
563
 
347
564
  ```
348
565
 
349
- ### drop many to many reference item (drop a reference to another item that have a many to many relationship)
566
+ ### Drop many-to-many reference (remove a reference from a many-to-many relationship)
350
567
 
351
568
  ```javascript
352
569
 
353
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
354
- let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item
355
- const propertyName = 'your_property_name'; // replace 'your_property_name' with the name of the property that have a many to many relationship
356
- const referenceId = 'your_reference_item_id'; // replace 'your_reference_item_id' with the id of the item that you want to drop as a many to many reference
357
- const result = await totalumClient.crud.dropManyToManyReferenceItem(tableElementName, your_item_id, propertyName, referenceId);
570
+ const tableName = 'students';
571
+ const recordId = 'student-id-123';
572
+ const propertyName = 'courses';
573
+ const referenceId = 'course-id-456'; // the id of the record to unlink
574
+
575
+ const result = await totalumClient.crud.dropManyToManyReferenceRecord(tableName, recordId, propertyName, referenceId);
576
+
577
+ if (result.errors) {
578
+ console.error('Error:', result.errors.errorMessage);
579
+ return;
580
+ }
581
+
582
+ console.log('Reference removed successfully');
358
583
 
359
584
  ```
360
585
 
361
- ### get many to many references items (get all items that have a many to many relationship with the item)
586
+ ### Get many-to-many references (get all records with a many-to-many relationship)
362
587
 
363
588
  ```javascript
364
589
 
365
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
366
- let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item
367
- const propertyName = 'your_property_name'; // replace 'your_property_name' with the name of the property that have a many to many relationship
590
+ const tableName = 'students';
591
+ const recordId = 'student-id-123';
592
+ const propertyName = 'courses';
368
593
 
369
- // the query is optional, you can use it to filter and sort the results
594
+ // Optional query for filtering and sorting
370
595
  const query = {
371
596
  filter: [
372
597
  {
373
- 'your_property_name': 'value' // add your custom filters here
598
+ 'courseName': { regex: 'Math', options: 'i' }
374
599
  },
375
600
  ],
376
- sort:{
377
- 'your_property_name': 1 // 1 for asc, -1 for desc
601
+ sort: {
602
+ 'courseName': 1 // 1 for asc, -1 for desc
378
603
  },
379
604
  pagination: {
380
605
  limit: 50,
381
606
  page: 0,
382
607
  }
383
608
  };
384
- const result = await totalumClient.crud.getManyToManyReferencesItems(tableElementName, your_item_id, propertyName, query);
609
+
610
+ const result = await totalumClient.crud.getManyToManyReferencesRecords(tableName, recordId, propertyName, query);
611
+
612
+ if (result.errors) {
613
+ console.error('Error:', result.errors.errorMessage);
614
+ return;
615
+ }
616
+
617
+ const relatedRecords = result.data;
618
+ console.log('Related records:', relatedRecords);
385
619
 
386
620
  ```
387
621
 
388
622
 
389
623
  ## Functions for filter data
390
624
 
391
- ### Filter data using totalum AND filter
625
+ ### Filter data using AND filter
392
626
 
393
627
  ```javascript
394
628
 
395
- const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
629
+ const tableName = 'users';
396
630
 
397
- // get items from your_element_table_name (for default 50 items per page) applying a filter AND query (all conditions must be true)
398
- const filter: FilterSearchQueryI = {
631
+ // Get records applying AND filter (all conditions must be true)
632
+ const filter = {
399
633
  filter: [
400
634
  {
401
- 'your_property_name': 'value' // it matches the value exactly
635
+ 'name': 'John' // exact match
402
636
  },
403
637
  {
404
- 'your_other_property_name': {regex: 'your regex query', options: 'i'} // it matches a value using a regex query and options: i for case insensitive (ignore if it is uppercase or lowercase)
638
+ 'email': { regex: '@example.com', options: 'i' } // regex with case insensitive
405
639
  },
406
- // PD: gte and lte operators are only allowed for properties of type date or number
640
+ // Note: gte and lte operators are only for date or number properties
407
641
  {
408
- 'your_other_property_name': {gte: new Date('your date')} // it matches a value greater than or equal to the date
642
+ 'age': { gte: 18 } // greater than or equal to 18
409
643
  },
410
644
  {
411
- 'your_other_property_name': {lte: new Date('your date')} // it matches a value less than or equal to the date
645
+ 'age': { lte: 65 } // less than or equal to 65
412
646
  },
413
647
  {
414
- 'your_other_property_name': {gte: 10} // it matches a value greater than or equal to 10
648
+ 'createdAt': { gte: new Date('2024-01-01') } // created after date
415
649
  },
416
650
  {
417
- 'your_other_property_name': {lte: 100} // it matches a value less than or equal to 100
651
+ 'createdAt': { lte: new Date('2024-12-31') } // created before date
418
652
  }
419
653
  ],
420
- sort:{
421
- 'your_property_name': 1 // 1 for asc, -1 for desc
654
+ sort: {
655
+ 'name': 1 // 1 for ascending, -1 for descending
422
656
  },
423
657
  pagination: {
424
658
  limit: 50,
@@ -426,34 +660,43 @@ const filter: FilterSearchQueryI = {
426
660
  }
427
661
  };
428
662
 
429
- const result = await totalumClient.crud.getItems(tableElementName, filter);
430
- const items = result.data.data;
663
+ const result = await totalumClient.crud.getRecords(tableName, filter);
664
+
665
+ if (result.errors) {
666
+ console.error('Error:', result.errors.errorMessage);
667
+ return;
668
+ }
669
+
670
+ const records = result.data;
671
+ console.log('Filtered records:', records);
431
672
 
432
673
  ```
433
674
 
434
- ### Filter data using totalum OR filter
675
+ ### Filter data using OR filter
435
676
 
436
677
  ```javascript
437
678
 
438
- // get items from your_element_table_name (for default 50 items per page) applying a filter OR query (at least one condition must be true)
439
- const filter: FilterSearchQueryI = {
679
+ const tableName = 'users';
680
+
681
+ // Get records applying OR filter (at least one condition must be true)
682
+ const filter = {
440
683
  filter: [
441
684
  {
442
685
  or: [
443
686
  {
444
- 'your_property_name': 'value' // it matches the value exactly
687
+ 'name': 'John'
445
688
  },
446
689
  {
447
- 'your_other_property_name': {regex: 'your regex query', options: 'i'} // it matches a value using a regex query and options: i for case insensitive (ignore if it is uppercase or lowercase)
690
+ 'email': { regex: '@example.com', options: 'i' }
448
691
  },
449
692
  {
450
- 'your_other_property_name': {gte: new Date('your date')} // it matches a value greater than or equal to the date
693
+ 'age': { gte: 18 }
451
694
  },
452
695
  ]
453
696
  }
454
697
  ],
455
698
  sort: {
456
- 'your_property_name': 1 // 1 for asc, -1 for desc
699
+ 'name': 1 // 1 for ascending, -1 for descending
457
700
  },
458
701
  pagination: {
459
702
  limit: 50,
@@ -461,35 +704,43 @@ const filter: FilterSearchQueryI = {
461
704
  }
462
705
  };
463
706
 
464
- const result = await totalumClient.crud.getItems(tableElementName, filter);
465
- const items = result.data.data;
707
+ const result = await totalumClient.crud.getRecords(tableName, filter);
708
+
709
+ if (result.errors) {
710
+ console.error('Error:', result.errors.errorMessage);
711
+ return;
712
+ }
713
+
714
+ const records = result.data;
715
+ console.log('Filtered records:', records);
466
716
 
467
717
  ```
468
718
 
469
- ### Filter data using totalum AND and OR filter
719
+ ### Filter data using AND and OR combined
470
720
 
471
721
  ```javascript
472
722
 
473
- // get items from your_element_table_name (for default 50 items per page) applying a filter OR and AND
474
- const filter: FilterSearchQueryI = {
723
+ const tableName = 'users';
724
+
725
+ // Get records applying both OR and AND filters
726
+ const filter = {
475
727
  filter: [
476
728
  {
477
729
  or: [
478
730
  {
479
- 'your_property_name_in_or': 'value' // it matches the value exactly
731
+ 'role': 'admin'
480
732
  },
481
733
  {
482
- 'your_other_property_name_in_or': {regex: 'your regex query', options: 'i'} // it matches a value using a regex query and options: i for case insensitive (ignore if it is uppercase or lowercase)
734
+ 'role': 'moderator'
483
735
  },
484
736
  ],
485
737
  },
486
738
  {
487
- 'your_other_property_name': 'value' // it matches the value exactly
739
+ 'status': 'active' // AND this condition must be true
488
740
  }
489
-
490
741
  ],
491
742
  sort: {
492
- 'your_property_name': 1 // 1 for asc, -1 for desc
743
+ 'name': 1
493
744
  },
494
745
  pagination: {
495
746
  limit: 50,
@@ -497,27 +748,40 @@ const filter: FilterSearchQueryI = {
497
748
  }
498
749
  };
499
750
 
500
- const result = await totalumClient.crud.getItems(tableElementName, filter);
501
- const items = result.data.data;
751
+ const result = await totalumClient.crud.getRecords(tableName, filter);
752
+
753
+ if (result.errors) {
754
+ console.error('Error:', result.errors.errorMessage);
755
+ return;
756
+ }
502
757
 
758
+ const records = result.data;
759
+ console.log('Filtered records:', records);
503
760
 
504
761
  ```
505
762
 
506
- ### Filter using your custom mongoDb aggregation query
763
+ ### Filter using custom MongoDB aggregation query
507
764
 
508
765
  ```javascript
509
766
 
510
- // filter results from your_element_table_name applying a filter query (a custom mongodb aggregation query)
767
+ const tableName = 'users';
768
+
769
+ // Custom MongoDB aggregation query as string
511
770
  const customMongoDbAggregationQueryInString = `
512
-
513
- your custom mongo aggregation query in string, for more info:
514
- https://docs.mongodb.com/manual/aggregation/
515
771
 
516
- or ask to chatgpt, he is very good writing mongo aggregation queries ;)
772
+ Your custom MongoDB aggregation query in string format
773
+ For more info: https://docs.mongodb.com/manual/aggregation/
517
774
 
518
775
  `;
519
776
 
520
- const result = await totalumClient.filter.runCustomMongoAggregationQuery(tableElementName, customMongoDbAggregationQueryInString);
777
+ const result = await totalumClient.filter.runCustomMongoAggregationQuery(tableName, customMongoDbAggregationQueryInString);
778
+
779
+ if (result.errors) {
780
+ console.error('Error:', result.errors.errorMessage);
781
+ return;
782
+ }
783
+
784
+ const results = result.data;
521
785
 
522
786
  ```
523
787
 
@@ -525,9 +789,17 @@ const result = await totalumClient.filter.runCustomMongoAggregationQuery(tableEl
525
789
 
526
790
  ```javascript
527
791
 
528
- const result = await totalumClient.crud.getHistoricRecordUpdatesById(yourRecordId); // replace yourRecordId with the id of the record
792
+ const recordId = 'record-id-123';
793
+
794
+ const result = await totalumClient.crud.getHistoricRecordUpdatesById(recordId);
529
795
 
530
- const historicUpdates = result.data.data;
796
+ if (result.errors) {
797
+ console.error('Error:', result.errors.errorMessage);
798
+ return;
799
+ }
800
+
801
+ const historicUpdates = result.data;
802
+ console.log('Historic updates:', historicUpdates);
531
803
 
532
804
  ```
533
805
 
@@ -609,11 +881,18 @@ Depending on the platform you are using, you will need to transform the file to
609
881
  const FormData = require('form-data'); // if you are using node.js
610
882
 
611
883
  const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
612
- const file = yourFileBlob // your blob file created in the previous step
884
+ const file = yourFileBlob // your blob file created in the previous step
613
885
  const formData = new FormData();
614
886
  formData.append('file', file, fileName);
887
+
615
888
  const result = await totalumClient.files.uploadFile(formData);
616
- const fileNameId = result.data.data;
889
+
890
+ if (result.errors) {
891
+ console.error('Error:', result.errors.errorMessage);
892
+ return;
893
+ }
894
+
895
+ const fileNameId = result.data;
617
896
  ```
618
897
 
619
898
  **Using Totalum API**
@@ -638,9 +917,19 @@ Depending on the platform you are using, you will need to transform the file to
638
917
 
639
918
  ``` javascript
640
919
 
641
- //if you want to link this file to an item, you need to add the fileNameId to the item property of type file
642
- const result2 = await totalumClient.crud.editItemById('your_element_table_name', 'your_item_id', {'your_file_property_name': {name: fileNameId}});
643
- // now the file is linked to the item property, and you can see it in the totalum panel.
920
+ // If you want to link this file to a record, you need to add the fileNameId to the record property of type file
921
+ const tableName = 'documents';
922
+ const recordId = 'record-id-123';
923
+ const result2 = await totalumClient.crud.editRecordById(tableName, recordId, {
924
+ 'attachmentFile': { name: fileNameId }
925
+ });
926
+
927
+ if (result2.errors) {
928
+ console.error('Error:', result2.errors.errorMessage);
929
+ return;
930
+ }
931
+
932
+ console.log('File linked to record successfully');
644
933
 
645
934
  ```
646
935
 
@@ -648,138 +937,211 @@ const result2 = await totalumClient.crud.editItemById('your_element_table_name',
648
937
 
649
938
  ```javascript
650
939
 
651
- // you can remove a file from totalum using the file name id
652
- const fileNameId = 'your_file_name.png'; // replace 'your_file_name' with the name id of your file, replace .png with the extension of your file
940
+ // Remove a file from Totalum using the file name id
941
+ const fileNameId = 'your_file_name.png';
653
942
 
654
943
  const result = await totalumClient.files.deleteFile(fileNameId);
655
944
 
945
+ if (result.errors) {
946
+ console.error('Error:', result.errors.errorMessage);
947
+ return;
948
+ }
949
+
950
+ console.log('File deleted successfully');
951
+
656
952
  ```
657
953
 
658
- ### Get the download url of a file
954
+ ### Get the download URL of a file
659
955
 
660
956
  ```javascript
661
957
 
662
- // you can get the fileNameId from the result of the upload file function
663
- const fileNameId = 'your_file_name.png'; // replace 'your_file_name' with the name id of your file, replace .png with the extension of your file
958
+ // Get a signed download URL for a file
959
+ const fileNameId = 'your_file_name.png';
664
960
 
665
- //optional options
961
+ // Optional: set expiration time
666
962
  const options = {
667
- // the default expiration time is 128 hours, but you can set it to whatever you want, after the expiration time the url will not return the file
668
- expirationTime: Date.now() + (128 * 60 * 60 * 1000); // Set to expire in 128 hours, how it works is, set the current date in miliseconds + the miliseconds you want the url to expire
669
- }
963
+ // Default expiration is 128 hours. Set custom expiration in milliseconds from now
964
+ expirationTime: Date.now() + (128 * 60 * 60 * 1000) // 128 hours
965
+ };
670
966
 
671
967
  const result = await totalumClient.files.getDownloadUrl(fileNameId, options);
672
- let [fileUrl] = result.data.data;
673
- // the result will be a full url that you can use to download the file
968
+
969
+ if (result.errors) {
970
+ console.error('Error:', result.errors.errorMessage);
971
+ return;
972
+ }
973
+
974
+ const fileUrl = result.data;
975
+ console.log('Download URL:', fileUrl);
674
976
 
675
977
  ```
676
978
 
677
- ### Generate a pdf from a template
979
+ ### Generate a PDF from a template
678
980
 
679
981
  ```javascript
680
982
 
681
- const templateId = 'your_template_id'; // replace 'your_template_id' with the id of your template id, go to totalum -> configuration -> pdf templates
983
+ // Go to Totalum -> Configuration -> PDF Templates to get your template ID
984
+ const templateId = 'template-id-123';
682
985
 
683
- // the variables will be replaced in your template with handlebars
684
- const variablesExample = { // replace the variables with your variables, can contain nested objects of n deep, can contain strings, numbers, dates, etc.
685
- 'your_variable_name': 'your_variable_value',
686
- 'your_other_variable_name': {
687
- 'your_other_variable_name': 'your_other_variable_value'
688
- 'your_other_variable_name': 10,
689
- 'your_other_variable_name': new Date('your date'),
986
+ // Variables will be replaced in your template using Handlebars
987
+ const variables = {
988
+ 'customerName': 'John Doe',
989
+ 'orderDetails': {
990
+ 'orderId': 'ORD-12345',
991
+ 'amount': 150.50,
992
+ 'date': new Date(),
690
993
  },
994
+ };
995
+
996
+ const fileName = 'invoice_12345.pdf';
997
+ // CAUTION: if you use the same name, the previous PDF will be overwritten
998
+
999
+ const result = await totalumClient.files.generatePdfByTemplate(templateId, variables, fileName);
1000
+
1001
+ if (result.errors) {
1002
+ console.error('Error:', result.errors.errorMessage);
1003
+ return;
691
1004
  }
692
1005
 
693
- const fileName = 'your_pdf_name.pdf'; // replace 'your_pdf_name' with the name of your pdf
694
- //CAUTION: if you use the same name for multiple pdfs, the pdfs will be overwritten
695
- const result = await totalumClient.files.generatePdfByTemplate(templateId, variablesExample, name);
696
- const fileResult = result.data.data;
697
- // with the fileUrl you can download the pdf
1006
+ const generatedFileName = result.data;
1007
+ console.log('PDF generated:', generatedFileName);
698
1008
 
699
- //if you want to link this pdf to an item, you need to add the fileName to the item property of type file
700
- const result2 = await totalumClient.crud.editItemById('your_element_table_name', 'your_item_id', {'your_pdf_property_name': {name: fileResult.fileName}});
1009
+ // Link this PDF to a record
1010
+ const tableName = 'invoices';
1011
+ const recordId = 'invoice-record-123';
1012
+ const result2 = await totalumClient.crud.editRecordById(tableName, recordId, {
1013
+ 'pdfFile': { name: generatedFileName }
1014
+ });
701
1015
 
702
1016
  ```
703
1017
 
704
- ### get OCR of an image (get the text of an image)
1018
+ ### Get OCR of an image (extract text from image)
705
1019
 
706
1020
  ```javascript
707
1021
 
708
- // you can only do ocr of a file that is previously uploaded to totalum (see the upload file function)
709
- // then you can do ocr of the file using the file name of the file uploaded
710
- const fileNameId = 'your_file_name_id.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your image
1022
+ // First upload the image to Totalum, then extract text from it
1023
+ const fileNameId = 'uploaded_image.png';
1024
+
711
1025
  const result = await totalumClient.files.ocrOfImage(fileNameId);
712
- const ocrResult = result.data.data;
713
- // ocrResult.text will contain all text of the image
714
- // ocrResult.fullDetails will contain all details of the image, like the language, the position of the text, etc.
1026
+
1027
+ if (result.errors) {
1028
+ console.error('Error:', result.errors.errorMessage);
1029
+ return;
1030
+ }
1031
+
1032
+ const ocrResult = result.data;
1033
+ console.log('Extracted text:', ocrResult.text);
1034
+ console.log('Full details:', ocrResult.fullDetails);
715
1035
 
716
1036
  ```
717
1037
 
718
- ### get OCR of a pdf (get the text of a pdf)
1038
+ ### Get OCR of a PDF (extract text from PDF)
719
1039
 
720
1040
  ```javascript
721
1041
 
722
- // you can only do ocr of a file that is previously uploaded to totalum (see the upload file function)
723
- // then you can do ocr of the file using the file name of the file uploaded
724
- const fileName = 'your_file_name_id.pdf'; // replace 'your_file_name' with the name of your file
725
- const result = await totalumClient.files.ocrOfPdf(fileName);
726
- const ocrResult = result.data.data;
727
- // ocrResult.text will contain all text of the pdf
728
- // ocrResult.fullDetails will contain all details of the pdf, like the language, in which page is the text, the position of the text, etc.
1042
+ // First upload the PDF to Totalum, then extract text from it
1043
+ const fileNameId = 'uploaded_document.pdf';
1044
+
1045
+ const result = await totalumClient.files.ocrOfPdf(fileNameId);
1046
+
1047
+ if (result.errors) {
1048
+ console.error('Error:', result.errors.errorMessage);
1049
+ return;
1050
+ }
1051
+
1052
+ const ocrResult = result.data;
1053
+ console.log('Extracted text:', ocrResult.text);
1054
+ console.log('Full details:', ocrResult.fullDetails);
729
1055
 
730
1056
  ```
731
1057
 
732
- ### scan an invoice (get the details of an invoice)
1058
+ ### Scan an invoice (extract structured data from invoice)
733
1059
 
734
1060
  ```javascript
735
1061
 
736
- // you can only do scan of a file that is previously uploaded to totalum (see the upload file function)
737
- // then you can do scan of the file using the file name of the file uploaded
738
- const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
739
- const file = yourFileBlob // replace yourFile with your file object binary blob (in blob format)
1062
+ // First upload the invoice file to Totalum
1063
+ const fileName = 'invoice.png';
1064
+ const file = yourFileBlob;
740
1065
  const formData = new FormData();
741
1066
  formData.append('file', file, fileName);
742
- const result = await totalumClient.files.uploadFile(formData);
743
- const fileNameId = result.data.data;
744
1067
 
1068
+ const uploadResult = await totalumClient.files.uploadFile(formData);
1069
+
1070
+ if (uploadResult.errors) {
1071
+ console.error('Error:', uploadResult.errors.errorMessage);
1072
+ return;
1073
+ }
1074
+
1075
+ const fileNameId = uploadResult.data;
1076
+
1077
+ // Scan the invoice to extract structured data
745
1078
  const result = await totalumClient.files.scanInvoice(fileNameId);
746
- const invoiceResult = result.data.data;
1079
+
1080
+ if (result.errors) {
1081
+ console.error('Error:', result.errors.errorMessage);
1082
+ return;
1083
+ }
1084
+
1085
+ const invoiceData = result.data.data;
1086
+ const metadata = result.data.metadata;
1087
+
1088
+ console.log('Invoice data:', invoiceData);
1089
+ console.log('Total amount:', invoiceData.totalAmountIncludingTaxes);
1090
+ console.log('Invoice number:', invoiceData.complete_invoice_number);
1091
+ console.log('Usage units:', metadata.usageUnits);
747
1092
 
748
1093
  ```
749
1094
 
750
- ### scan a document (get the details of a document)
1095
+ ### Scan a document (extract custom fields from document)
751
1096
 
752
1097
  ```javascript
753
1098
 
754
- // first upload the file to totalum
755
- const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
756
- const file = yourFileBlob // replace yourFile with your file object binary blob (in blob format)
1099
+ // First upload the document
1100
+ const fileName = 'document.png';
1101
+ const file = yourFileBlob;
757
1102
  const formData = new FormData();
758
1103
  formData.append('file', file, fileName);
759
- const result = await totalumClient.files.uploadFile(formData);
760
- const fileNameId = result.data.data;
761
1104
 
762
- // define the json properties that you want to extract from the document
763
- // this is just an example, you can define your own properties following the JSON schema format, the api will return a json with the properties that you define here
764
- const properties = {
1105
+ const uploadResult = await totalumClient.files.uploadFile(formData);
1106
+
1107
+ if (uploadResult.errors) {
1108
+ console.error('Error:', uploadResult.errors.errorMessage);
1109
+ return;
1110
+ }
1111
+
1112
+ const fileNameId = uploadResult.data;
1113
+
1114
+ // Define the JSON schema for properties you want to extract
1115
+ const properties = {
765
1116
  "fecha": {
766
- "type": "string",
767
- "format": "date",
768
- "description": "introduce here your description for help api to extract this value"
1117
+ "type": "string",
1118
+ "format": "date",
1119
+ "description": "The date of the document"
769
1120
  },
770
1121
  "import": {
771
- "type": "number",
772
- "description": "the import"
1122
+ "type": "number",
1123
+ "description": "The total amount"
773
1124
  },
774
1125
  "currency": {
775
- "type": "string",
776
- "enum": ["EUR", "USD", "GBP", "OTHER"],
777
- "description": "if currency is not EUR, USD or GBP set OTHER"
1126
+ "type": "string",
1127
+ "enum": ["EUR", "USD", "GBP", "OTHER"],
1128
+ "description": "Currency code"
778
1129
  }
779
- }
1130
+ };
780
1131
 
781
1132
  const result = await totalumClient.files.scanDocument(fileNameId, properties);
782
- const documentResult = result.data.data;
1133
+
1134
+ if (result.errors) {
1135
+ console.error('Error:', result.errors.errorMessage);
1136
+ return;
1137
+ }
1138
+
1139
+ const documentData = result.data.data;
1140
+ const metadata = result.data.metadata;
1141
+
1142
+ console.log('Extracted data:', documentData);
1143
+ console.log('OCR text:', metadata.ocrFullResultText);
1144
+ console.log('Usage units:', metadata.usageUnits);
783
1145
 
784
1146
  ```
785
1147
 
@@ -789,23 +1151,40 @@ Create a PDF directly from custom HTML:
789
1151
 
790
1152
  ```javascript
791
1153
 
792
- const htmlContent = '<html><body><h1>Hello World</h1><p>This is a PDF created from HTML</p></body></html>';
793
- const fileName = 'my-generated-pdf.pdf'; // replace with your desired file name
1154
+ const htmlContent = `
1155
+ <html>
1156
+ <body>
1157
+ <h1>Hello World</h1>
1158
+ <p>This is a PDF created from HTML</p>
1159
+ </body>
1160
+ </html>
1161
+ `;
1162
+
1163
+ const fileName = 'my-generated-pdf.pdf';
794
1164
 
795
1165
  const result = await totalumClient.files.createPdfFromHtml({
796
1166
  html: htmlContent,
797
1167
  name: fileName
798
1168
  });
799
1169
 
800
- const fileResult = result.data.data;
801
- // fileResult contains the generated PDF file information
1170
+ if (result.errors) {
1171
+ console.error('Error:', result.errors.errorMessage);
1172
+ return;
1173
+ }
1174
+
1175
+ const generatedFileName = result.data;
1176
+ console.log('PDF generated:', generatedFileName);
802
1177
 
803
- // if you want to link this pdf to an item, you need to add the fileName to the item property of type file
804
- const result2 = await totalumClient.crud.editItemById('your_element_table_name', 'your_item_id', {'your_pdf_property_name': {name: fileResult.fileName}});
1178
+ // Link this PDF to a record
1179
+ const tableName = 'documents';
1180
+ const recordId = 'doc-record-123';
1181
+ const result2 = await totalumClient.crud.editRecordById(tableName, recordId, {
1182
+ 'pdfFile': { name: generatedFileName }
1183
+ });
805
1184
 
806
1185
  ```
807
1186
 
808
- **Note:** The HTML is automatically encoded to base64 by the SDK before sending it to the API.
1187
+ **Note:** The HTML is automatically encoded to base64 by the SDK before sending it to the API. Works in both Node.js and browser environments.
809
1188
 
810
1189
 
811
1190
  ## Functions for send emails
@@ -822,6 +1201,14 @@ const emailPayload = {
822
1201
 
823
1202
  const result = await totalumClient.email.sendEmail(emailPayload);
824
1203
 
1204
+ if (result.errors) {
1205
+ console.error('Error:', result.errors.errorMessage);
1206
+ return;
1207
+ }
1208
+
1209
+ console.log('Email sent successfully');
1210
+ console.log('Message ID:', result.data.messageId);
1211
+
825
1212
  ```
826
1213
 
827
1214
  ### Send an email with all options
@@ -852,6 +1239,14 @@ const emailPayload = {
852
1239
 
853
1240
  const result = await totalumClient.email.sendEmail(emailPayload);
854
1241
 
1242
+ if (result.errors) {
1243
+ console.error('Error:', result.errors.errorMessage);
1244
+ return;
1245
+ }
1246
+
1247
+ console.log('Email sent successfully');
1248
+ console.log('Message ID:', result.data.messageId);
1249
+
855
1250
  ```
856
1251
 
857
1252
  ### Send an email with files from Totalum storage
@@ -860,8 +1255,15 @@ const result = await totalumClient.email.sendEmail(emailPayload);
860
1255
 
861
1256
  // First, get the download URL of the file uploaded to Totalum
862
1257
  const fileNameId = 'your_file_name.pdf';
1258
+
863
1259
  const fileUrlResult = await totalumClient.files.getDownloadUrl(fileNameId);
864
- const [fileUrl] = fileUrlResult.data.data;
1260
+
1261
+ if (fileUrlResult.errors) {
1262
+ console.error('Error:', fileUrlResult.errors.errorMessage);
1263
+ return;
1264
+ }
1265
+
1266
+ const fileUrl = fileUrlResult.data;
865
1267
 
866
1268
  // Then, send the email with the attachment
867
1269
  const emailPayload = {
@@ -879,12 +1281,20 @@ const emailPayload = {
879
1281
 
880
1282
  const result = await totalumClient.email.sendEmail(emailPayload);
881
1283
 
1284
+ if (result.errors) {
1285
+ console.error('Error:', result.errors.errorMessage);
1286
+ return;
1287
+ }
1288
+
1289
+ console.log('Email sent successfully');
1290
+
882
1291
  ```
883
1292
 
884
1293
  **Important notes:**
885
1294
  - Maximum attachments: 10 per email
886
1295
  - Maximum size per attachment: 15MB
887
1296
  - All attachments must be provided as valid HTTP/HTTPS URLs
1297
+ - The SDK validates attachments before sending
888
1298
 
889
1299
 
890
1300
  ## Functions for call OpenAI API without need to have an OpenAI account
@@ -894,15 +1304,22 @@ const result = await totalumClient.email.sendEmail(emailPayload);
894
1304
 
895
1305
  ```javascript
896
1306
 
897
- //body the openai completion body, more info here: https://platform.openai.com/docs/api-reference/completions/create
898
- const body={
899
- // see the openai api docs for more info
900
- }
1307
+ // See OpenAI API docs: https://platform.openai.com/docs/api-reference/completions/create
1308
+ const body = {
1309
+ model: 'gpt-3.5-turbo-instruct',
1310
+ prompt: 'Say hello in Spanish',
1311
+ max_tokens: 50
1312
+ };
901
1313
 
902
1314
  const result = await totalumClient.openai.createCompletion(body);
903
- const gptCompletion = result.data.data;
904
1315
 
905
- // returns the completion provided by openai api
1316
+ if (result.errors) {
1317
+ console.error('Error:', result.errors.errorMessage);
1318
+ return;
1319
+ }
1320
+
1321
+ const completion = result.data;
1322
+ console.log('Completion:', completion);
906
1323
 
907
1324
  ```
908
1325
 
@@ -910,21 +1327,26 @@ const gptCompletion = result.data.data;
910
1327
 
911
1328
  ```javascript
912
1329
 
913
- //body the openai chat completion body, more info here: https://platform.openai.com/docs/api-reference/chat/create
914
- const bodyExample={
915
- // see the openai api docs for more info
1330
+ // See OpenAI API docs: https://platform.openai.com/docs/api-reference/chat/create
1331
+ const body = {
916
1332
  messages: [
917
- {content: 'You are a math specialist assistant', role: 'system'},
918
- {content: 'how I can resolve a matrix', role: 'user'}
919
- //etc...
1333
+ { content: 'You are a math specialist assistant', role: 'system' },
1334
+ { content: 'How do I solve a matrix?', role: 'user' }
920
1335
  ],
921
1336
  model: 'gpt-3.5-turbo',
922
- max_tokens: 30,
1337
+ max_tokens: 150,
1338
+ };
1339
+
1340
+ const result = await totalumClient.openai.createChatCompletion(body);
1341
+
1342
+ if (result.errors) {
1343
+ console.error('Error:', result.errors.errorMessage);
1344
+ return;
923
1345
  }
924
1346
 
925
- const result = await totalumClient.openai.createChatCompletion(bodyExample);
926
- const chatCompletion = result.data.data;
927
- // returns the completion provided by openai api
1347
+ const chatCompletion = result.data;
1348
+ console.log('Response:', chatCompletion.choices[0].message.content);
1349
+ console.log('Tokens used:', chatCompletion.usage.total_tokens);
928
1350
 
929
1351
  ```
930
1352
 
@@ -932,16 +1354,28 @@ const chatCompletion = result.data.data;
932
1354
 
933
1355
  ```javascript
934
1356
 
935
- //body the openai chat completion body, more info here: https://platform.openai.com/docs/api-reference/chat/create
936
- const bodyExample={
937
- prompt:'your prompt',
938
- size: '256x256' | '512x512' | '1024x1024',
939
- fileName: 'file-name-of-file-saved.png' // CAUTION: if you use the same name for multiple images, the images will be overwritten
1357
+ // See OpenAI API docs: https://platform.openai.com/docs/api-reference/images
1358
+ const body = {
1359
+ prompt: 'A beautiful sunset over the mountains',
1360
+ size: '1024x1024', // '256x256' | '512x512' | '1024x1024'
1361
+ fileName: 'sunset_image.png' // CAUTION: reusing names will overwrite files
1362
+ };
1363
+
1364
+ const result = await totalumClient.openai.generateImage(body);
1365
+
1366
+ if (result.errors) {
1367
+ console.error('Error:', result.errors.errorMessage);
1368
+ return;
940
1369
  }
941
1370
 
942
- const result = await totalumClient.openai.generateImage(bodyExample);
943
- const imageCompletion = result.data.data;
944
- // returns the file name with the file generated by openai, if is not an url, you can download it using files.getDownloadUrl(imageCompletion);
1371
+ const imageFileName = result.data;
1372
+ console.log('Image generated:', imageFileName);
1373
+
1374
+ // Get download URL to view/download the image
1375
+ const urlResult = await totalumClient.files.getDownloadUrl(imageFileName);
1376
+ if (!urlResult.errors) {
1377
+ console.log('Image URL:', urlResult.data);
1378
+ }
945
1379
 
946
1380
  ```
947
1381