totalum-api-sdk 3.0.4 → 3.0.6

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,4 +1,4 @@
1
- ## Totalum API SDK (v3.0.4)
1
+ ## Totalum API SDK (v3.0.5)
2
2
 
3
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
 
@@ -32,7 +32,7 @@ If you are not programming in javascript, you can use the api directly, see <a h
32
32
 
33
33
  ## Authentication
34
34
 
35
- **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', {})
35
+ **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.query('your_table')
36
36
 
37
37
  You can choose to use one of the two authentication methods offered by Totalum Sdk:
38
38
 
@@ -65,7 +65,7 @@ const options: AuthOptions = {
65
65
  const totalumClient = new TotalumApiSdk(options);
66
66
 
67
67
  // execute some TotalumApiSdk function
68
- const result = await totalumClient.crud.getRecords('your_table_name', {});
68
+ const result = await totalumClient.crud.query('your_table_name');
69
69
 
70
70
  ```
71
71
 
@@ -94,7 +94,7 @@ const options = {
94
94
  const totalumClient = new totalum.TotalumApiSdk(options);
95
95
 
96
96
  // execute some TotalumApiSdk function
97
- const result = await totalumClient.crud.getRecords('your_table_name', {});
97
+ const result = await totalumClient.crud.query('your_table_name');
98
98
 
99
99
  ```
100
100
 
@@ -102,7 +102,7 @@ const result = await totalumClient.crud.getRecords('your_table_name', {});
102
102
 
103
103
  ```html
104
104
  <head>
105
- <script src="https://cdn.jsdelivr.net/npm/totalum-api-sdk@3.0.2/dist/totalum-sdk.min.js"></script>
105
+ <script src="https://cdn.jsdelivr.net/npm/totalum-api-sdk@3.0.5/dist/totalum-sdk.min.js"></script>
106
106
  </head>
107
107
  <script>
108
108
  //Example of use TotalumSdk in your custom html page
@@ -116,7 +116,7 @@ const result = await totalumClient.crud.getRecords('your_table_name', {});
116
116
  const tableName = 'your-table-name'; // replace with your table name
117
117
 
118
118
  //example of endpoint execution
119
- totalumClient.crud.getRecords(tableName, {}).then((result) => {
119
+ totalumClient.crud.query(tableName).then((result) => {
120
120
  if (result.errors) {
121
121
  console.error("ERROR:", result.errors);
122
122
  return;
@@ -210,14 +210,14 @@ console.log('Record:', record);
210
210
 
211
211
  ```
212
212
 
213
- ### Get records
213
+ ### Query records (Recommended)
214
+
215
+ `totalumClient.crud.query()` is the **recommended** method for reading data. It replaces `getRecords`, `getNestedData`, and `getManyToManyReferencesRecords`.
214
216
 
215
217
  ```javascript
216
218
 
217
219
  // Get records from a table (default: first 50 records)
218
- const tableName = 'users'; // replace with your table name
219
-
220
- const result = await totalumClient.crud.getRecords(tableName, {});
220
+ const result = await totalumClient.crud.query('users');
221
221
 
222
222
  if (result.errors) {
223
223
  console.error('Error:', result.errors.errorMessage);
@@ -229,168 +229,80 @@ console.log('Records:', records);
229
229
 
230
230
  ```
231
231
 
232
- ### Get nested items
232
+ ### Query with nested relations
233
233
 
234
234
  ```javascript
235
235
 
236
- // imagine that you have 3 tables, client, order and product, and you want to get some clients with all orders and the products of the orders
237
-
238
- const nestedQuery: NestedQuery = {
239
- client: {
240
- order: {
241
- product: {}
242
- },
236
+ // Get clients with all orders and the products of each order
237
+ const result = await totalumClient.crud.query('client', {
238
+ order: {
239
+ product: true
243
240
  }
244
- }
241
+ });
245
242
 
246
- const result = await totalumClient.crud.getNestedData(nestedQuery);
243
+ const clients = result.data;
247
244
 
248
245
  ```
249
246
 
250
- ### Get nested items and filter
247
+ ### Query with filters, sort, and pagination
251
248
 
252
249
  ```javascript
253
250
 
254
- // As before you have client, order, and product tables, but you now want to only get the client with name 'Jhon' and limit to 10 results
255
-
256
- const nestedQuery: NestedQuery = {
257
- client: {
258
- tableFilter: {
259
- filter: [{
260
- name: 'Jhon'
261
- }],
262
- sort: {
263
- name: 1
264
- },
265
- pagination: {
266
- limit: 10,
267
- page: 0,
268
- }
269
- },
270
- order: {
271
- product: {}
272
- },
273
- }
274
- }
275
-
276
- // if you want you can filter to all other nested tables in the same way (adding tableFilter property to the nested table)
277
-
278
- const result = await totalumClient.crud.getNestedData(nestedQuery);
251
+ // Get clients named 'John', sorted by name, limited to 10 results
252
+ const result = await totalumClient.crud.query('client', {
253
+ _filter: { name: 'John' },
254
+ _sort: { name: 'asc' },
255
+ _limit: 10
256
+ });
279
257
 
280
258
  ```
281
259
 
282
- ### Nested Filter
283
-
284
- get table items by Filtering others related tables. (like a join filter in sql)
285
-
286
- **The difference between getNestedData and nestedFilter is that nestedFilter only gets the items of the table that you specify in the tableNameToGet parameter that matches the nested filter.**
287
-
288
-
289
- **Use Case:**
290
-
291
- Imagine you have 3 tables, `client`, `order` and `product`, and you want to get the clients that have an order with state equal to completed and that order_date is from 2021-01-01 to 2021-01-31, and that order must have a product with a product with the name `Cocacola`. And you to get only the first 50 clients that match the filter.
260
+ ### Query with OR conditions
292
261
 
293
262
  ```javascript
294
263
 
295
- // you can filter in all tables for all the properties of the table if you want, in this example we are filtering only the order and product tables
296
- const nestedFilter = {
297
- client: {
298
- order: {
299
- tableFilter: [
300
- {
301
- state: 'completed'
302
- },
303
- {
304
- order_date: {
305
- gte: new Date('2021-01-01'),
306
- }
307
- },
308
- {
309
- order_date: {
310
- lte: new Date('2021-01-31')
311
- }
312
- }
313
- ],
314
- product: {
315
- tableFilter: [
316
- {
317
- name: 'Cocacola'
318
- }
319
- ]
320
- }
321
- },
264
+ const result = await totalumClient.crud.query('users', {
265
+ _filter: {
266
+ _or: [
267
+ { role: 'admin' },
268
+ { role: 'moderator' }
269
+ ]
322
270
  }
323
- }
324
-
325
- const filterOptions = {
326
- pagination: {
327
- limit: 60,
328
- page: 0
329
- },
330
- sort: {
331
- // you can sort by any field of contact, for example, sort by email
332
- email: -1
333
- }
334
- };
335
-
336
- // the table name to get the data that matches the filter
337
- const tableNameToGet = 'client';
338
-
339
- const result = await totalumClient.filter.nestedFilter(nestedFilter, tableNameToGet, filterOptions);
340
-
341
- const clients = result.data;
271
+ });
342
272
 
343
273
  ```
344
274
 
345
-
346
- **Another use case:**
347
-
348
- You can also get the tables that are not in top.
349
-
350
- Imagine you have 3 tables, `client`, `order` and `product`, and you want to get the products that have an order with state equal to completed, and that order must have a client with the name `Jhon`. And you to get only the first 50 products that match the filter.
275
+ ### Query with nested filters and counts
351
276
 
352
277
  ```javascript
353
278
 
354
- const nestedFilter = {
355
- client: {
356
- tableFilter: [
357
- {
358
- name: 'Jhon'
359
- }
360
- ],
361
- order: {
362
- tableFilter: [
363
- {
364
- state: 'completed'
365
- }
366
- ],
367
- product: {}
368
- },
279
+ // Get companies with active employees, count them, sort by name
280
+ const result = await totalumClient.crud.query('company', {
281
+ _filter: { country: 'Spain' },
282
+ _sort: { name: 'asc' },
283
+ _limit: 10,
284
+ employee: {
285
+ _filter: { status: 'active' },
286
+ _has: true,
287
+ _count: true,
288
+ task: { _sort: { createdAt: 'desc' }, _limit: 5 }
369
289
  }
370
- }
290
+ });
371
291
 
372
- const filterOptions = {
373
- pagination: {
374
- limit: 60,
375
- page: 0
376
- },
377
- sort: {
378
- // you can sort by any field of product
379
- name: -1
380
- }
381
- };
292
+ ```
382
293
 
383
- // the table name to get the data that matches the filter
384
- const tableNameToGet = 'product';
294
+ ### Query manyToMany relations
385
295
 
386
- const result = await totalumClient.filter.nestedFilter(nestedFilter, tableNameToGet, filterOptions);
296
+ ```javascript
387
297
 
388
- const products = result.data;
298
+ // Get students with their courses (manyToMany)
299
+ const result = await totalumClient.crud.query('students', {
300
+ courses: true
301
+ });
389
302
 
390
303
  ```
391
304
 
392
- You can do the same approach to get the orders.
393
-
305
+ For full query documentation see: [Read and Filter Data](https://docs.totalum.app/docs/api/filtrarDatos)
394
306
 
395
307
  ### Delete record by id
396
308
 
@@ -507,84 +419,30 @@ console.log('Reference removed successfully');
507
419
 
508
420
  ```
509
421
 
510
- ### Get many-to-many references (get all records with a many-to-many relationship)
511
-
512
- ```javascript
513
-
514
- const tableName = 'students';
515
- const recordId = 'student-id-123';
516
- const propertyName = 'courses';
517
-
518
- // Optional query for filtering and sorting
519
- const query = {
520
- filter: [
521
- {
522
- 'courseName': { regex: 'Math', options: 'i' }
523
- },
524
- ],
525
- sort: {
526
- 'courseName': 1 // 1 for asc, -1 for desc
527
- },
528
- pagination: {
529
- limit: 50,
530
- page: 0,
531
- }
532
- };
533
-
534
- const result = await totalumClient.crud.getManyToManyReferencesRecords(tableName, recordId, propertyName, query);
535
-
536
- if (result.errors) {
537
- console.error('Error:', result.errors.errorMessage);
538
- return;
539
- }
540
-
541
- const relatedRecords = result.data;
542
- console.log('Related records:', relatedRecords);
422
+ ### Get many-to-many references
543
423
 
544
- ```
424
+ > **Note:** For reading manyToMany data, prefer using `totalumClient.crud.query()` with the relation property expanded (see "Query manyToMany relations" above).
545
425
 
546
426
 
547
427
  ## Functions for filter data
548
428
 
429
+ > **Note:** All filtering examples below use `totalumClient.crud.query()`, the recommended method. See "Query records" section above for more details.
430
+
549
431
  ### Filter data using AND filter
550
432
 
551
433
  ```javascript
552
434
 
553
- const tableName = 'users';
554
-
555
435
  // Get records applying AND filter (all conditions must be true)
556
- const filter = {
557
- filter: [
558
- {
559
- 'name': 'John' // exact match
560
- },
561
- {
562
- 'email': { regex: '@example.com', options: 'i' } // regex with case insensitive
563
- },
564
- // Note: gte and lte operators are only for date or number properties
565
- {
566
- 'age': { gte: 18 } // greater than or equal to 18
567
- },
568
- {
569
- 'age': { lte: 65 } // less than or equal to 65
570
- },
571
- {
572
- 'createdAt': { gte: new Date('2024-01-01') } // created after date
573
- },
574
- {
575
- 'createdAt': { lte: new Date('2024-12-31') } // created before date
576
- }
577
- ],
578
- sort: {
579
- 'name': 1 // 1 for ascending, -1 for descending
436
+ const result = await totalumClient.crud.query('users', {
437
+ _filter: {
438
+ name: 'John',
439
+ email: { regex: '@example.com', options: 'i' },
440
+ age: { gte: 18, lte: 65 },
441
+ createdAt: { gte: new Date('2024-01-01'), lte: new Date('2024-12-31') }
580
442
  },
581
- pagination: {
582
- limit: 50,
583
- page: 0,
584
- }
585
- };
586
-
587
- const result = await totalumClient.crud.getRecords(tableName, filter);
443
+ _sort: { name: 'asc' },
444
+ _limit: 50
445
+ });
588
446
 
589
447
  if (result.errors) {
590
448
  console.error('Error:', result.errors.errorMessage);
@@ -600,35 +458,18 @@ console.log('Filtered records:', records);
600
458
 
601
459
  ```javascript
602
460
 
603
- const tableName = 'users';
604
-
605
461
  // Get records applying OR filter (at least one condition must be true)
606
- const filter = {
607
- filter: [
608
- {
609
- or: [
610
- {
611
- 'name': 'John'
612
- },
613
- {
614
- 'email': { regex: '@example.com', options: 'i' }
615
- },
616
- {
617
- 'age': { gte: 18 }
618
- },
619
- ]
620
- }
621
- ],
622
- sort: {
623
- 'name': 1 // 1 for ascending, -1 for descending
462
+ const result = await totalumClient.crud.query('users', {
463
+ _filter: {
464
+ _or: [
465
+ { name: 'John' },
466
+ { email: { regex: '@example.com', options: 'i' } },
467
+ { age: { gte: 18 } }
468
+ ]
624
469
  },
625
- pagination: {
626
- limit: 50,
627
- page: 0,
628
- }
629
- };
630
-
631
- const result = await totalumClient.crud.getRecords(tableName, filter);
470
+ _sort: { name: 'asc' },
471
+ _limit: 50
472
+ });
632
473
 
633
474
  if (result.errors) {
634
475
  console.error('Error:', result.errors.errorMessage);
@@ -644,35 +485,18 @@ console.log('Filtered records:', records);
644
485
 
645
486
  ```javascript
646
487
 
647
- const tableName = 'users';
648
-
649
488
  // Get records applying both OR and AND filters
650
- const filter = {
651
- filter: [
652
- {
653
- or: [
654
- {
655
- 'role': 'admin'
656
- },
657
- {
658
- 'role': 'moderator'
659
- },
660
- ],
661
- },
662
- {
663
- 'status': 'active' // AND this condition must be true
664
- }
665
- ],
666
- sort: {
667
- 'name': 1
489
+ const result = await totalumClient.crud.query('users', {
490
+ _filter: {
491
+ _or: [
492
+ { role: 'admin' },
493
+ { role: 'moderator' }
494
+ ],
495
+ status: 'active' // AND this condition must be true
668
496
  },
669
- pagination: {
670
- limit: 50,
671
- page: 0,
672
- }
673
- };
674
-
675
- const result = await totalumClient.crud.getRecords(tableName, filter);
497
+ _sort: { name: 'asc' },
498
+ _limit: 50
499
+ });
676
500
 
677
501
  if (result.errors) {
678
502
  console.error('Error:', result.errors.errorMessage);
@@ -1278,28 +1102,50 @@ console.log('Tokens used:', chatCompletion.usage.total_tokens);
1278
1102
 
1279
1103
  ```javascript
1280
1104
 
1281
- // See OpenAI API docs: https://platform.openai.com/docs/api-reference/images
1282
- const body = {
1105
+ const result = await totalumClient.openai.generateImage({
1283
1106
  prompt: 'A beautiful sunset over the mountains',
1284
- size: '1024x1024', // '256x256' | '512x512' | '1024x1024'
1285
- fileName: 'sunset_image.png' // CAUTION: reusing names will overwrite files
1286
- };
1287
-
1288
- const result = await totalumClient.openai.generateImage(body);
1107
+ fileName: 'sunset_image',
1108
+ size: '1024x1024', // optional: '1024x1024', '1536x1024' (landscape), '1024x1536' (portrait), 'auto'
1109
+ quality: 'low', // optional: 'low' (fastest), 'medium', 'high', 'auto'
1110
+ output_format: 'png', // optional: 'png', 'jpeg', 'webp'
1111
+ background: 'auto' // optional: 'transparent' (requires png), 'opaque', 'auto'
1112
+ });
1289
1113
 
1290
1114
  if (result.errors) {
1291
1115
  console.error('Error:', result.errors.errorMessage);
1292
1116
  return;
1293
1117
  }
1294
1118
 
1295
- const imageFileName = result.data;
1296
- console.log('Image generated:', imageFileName);
1119
+ const { fileName, imageUrl } = result.data;
1120
+ console.log('Image file:', fileName);
1121
+ console.log('Image URL:', imageUrl); // signed URL to directly access the image
1122
+
1123
+ ```
1124
+
1125
+ ### Edit an image
1297
1126
 
1298
- // Get download URL to view/download the image
1299
- const urlResult = await totalumClient.files.getDownloadUrl(imageFileName);
1300
- if (!urlResult.errors) {
1301
- console.log('Image URL:', urlResult.data);
1127
+ Edit or transform existing images: change clothes, combine images, use as style reference, etc.
1128
+
1129
+ ```javascript
1130
+
1131
+ const result = await totalumClient.openai.editImage({
1132
+ prompt: 'Change ONLY the clothing to a blue suit. Keep the face and background the same.',
1133
+ imageUrls: ['https://example.com/photo.jpg'], // 1-16 image URLs
1134
+ fileName: 'edited-photo',
1135
+ input_fidelity: 'high', // 'high' preserves details (faces). 'low' allows creative freedom (style transfer).
1136
+ size: '1024x1024', // optional
1137
+ quality: 'low', // optional
1138
+ output_format: 'png' // optional
1139
+ });
1140
+
1141
+ if (result.errors) {
1142
+ console.error('Error:', result.errors.errorMessage);
1143
+ return;
1302
1144
  }
1303
1145
 
1146
+ const { fileName, imageUrl } = result.data;
1147
+ console.log('Edited image:', fileName);
1148
+ console.log('Image URL:', imageUrl);
1149
+
1304
1150
  ```
1305
1151
 
@@ -3,6 +3,7 @@ export declare const endpoints: {
3
3
  getObjectById: string;
4
4
  getObjects: string;
5
5
  getNestedData: string;
6
+ query: string;
6
7
  createObject: string;
7
8
  editObjectProperties: string;
8
9
  deleteObject: string;
@@ -43,6 +44,7 @@ export declare const endpoints: {
43
44
  createCompletion: string;
44
45
  createChatCompletion: string;
45
46
  generateImage: string;
47
+ editImage: string;
46
48
  };
47
49
  notifications: {
48
50
  createNotification: string;
@@ -53,4 +55,10 @@ export declare const endpoints: {
53
55
  email: {
54
56
  sendEmail: string;
55
57
  };
58
+ webScraper: {
59
+ scrape: string;
60
+ extract: string;
61
+ screenshot: string;
62
+ searchAndExtract: string;
63
+ };
56
64
  };
@@ -7,6 +7,7 @@ exports.endpoints = {
7
7
  getObjectById: 'api/v1/crud/:typeId/:id',
8
8
  getObjects: 'api/v1/crud/query/:typeId',
9
9
  getNestedData: 'api/v1/crud/nested',
10
+ query: 'api/v1/crud/advanced-query',
10
11
  createObject: 'api/v1/crud/:typeId',
11
12
  editObjectProperties: 'api/v1/crud/:typeId/:id',
12
13
  deleteObject: 'api/v1/crud/:typeId/:id',
@@ -47,6 +48,7 @@ exports.endpoints = {
47
48
  createCompletion: 'api/v1/openai/completion',
48
49
  createChatCompletion: 'api/v1/openai/chat-completion',
49
50
  generateImage: 'api/v1/openai/image',
51
+ editImage: 'api/v1/openai/image-edit',
50
52
  },
51
53
  notifications: {
52
54
  createNotification: 'api/v1/notifications',
@@ -56,5 +58,11 @@ exports.endpoints = {
56
58
  },
57
59
  email: {
58
60
  sendEmail: 'api/v1/startum/send-email-with-default-domain'
61
+ },
62
+ webScraper: {
63
+ scrape: 'api/v1/web-scraper/scrape',
64
+ extract: 'api/v1/web-scraper/extract',
65
+ screenshot: 'api/v1/web-scraper/screenshot',
66
+ searchAndExtract: 'api/v1/web-scraper/search-and-extract',
59
67
  }
60
68
  };
@@ -47,7 +47,8 @@ class FetchClient {
47
47
  errors: {
48
48
  errorCode: 'RESPONSE_PARSE_ERROR',
49
49
  errorMessage: `Failed to parse response: ${response.statusText}`
50
- }
50
+ },
51
+ data: null
51
52
  };
52
53
  }
53
54
  // Always return the API response structure {data, errors}
@@ -68,7 +69,8 @@ class FetchClient {
68
69
  errors: {
69
70
  errorCode: 'NETWORK_ERROR',
70
71
  errorMessage: error instanceof Error ? error.message : 'Network request failed'
71
- }
72
+ },
73
+ data: null
72
74
  };
73
75
  }
74
76
  });