@truto/truto-jsonata 1.0.1 → 1.0.2

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,7 +1,1943 @@
1
+
1
2
  # truto-jsonata
2
3
 
3
- `truto-jsonata` is a TypeScript/JavaScript library built on top of the [jsonata](https://www.npmjs.com/package/jsonata) library.
4
+ `truto-jsonata` is a TypeScript/JavaScript library that extends the capabilities of [JSONata](https://www.npmjs.com/package/jsonata) with a rich set of custom functions for data transformation, text conversion, cryptographic operations, and utility functions. It simplifies complex data manipulation tasks, making it easier to work with JSON data in Node.js applications.
5
+
6
+ ## Table of Contents
7
+
8
+ - [Features](#features)
9
+
10
+ - [Requirements](#requirements)
11
+
12
+ - [Installation](#installation)
13
+
14
+ - [Usage](#usage)
15
+
16
+ - [Custom Functions](#custom-functions)
17
+
18
+ - [Data Transformation and Utility Functions](data-transformation-and-utility-functions)
19
+
20
+ - [Markdown and Text Conversion](#markdown-and-text-conversion)
21
+
22
+ - [Array and Object Utilities (Lodash Enhancements)](#array-and-object-utilities-lodash-enhancements)
23
+
24
+ - [Parsing and URL Functions](#parsing-and-url-functions)
25
+
26
+ - [Miscellaneous](#miscellaneous)
27
+
28
+ ## Features
29
+
30
+ - **Enhanced JSONata Expressions**: Adds custom functions to JSONata expressions for advanced data manipulation.
31
+
32
+ - **Data Transformation**: Functions for date parsing, currency conversion, and object manipulation.
33
+
34
+ - **Text Conversion**: Convert between Markdown, HTML, Notion, Slack, and Google Docs formats.
35
+
36
+ - **Cryptographic Operations**: Generate digests and signatures.
37
+
38
+ - **Utility Functions**: Lodash-inspired array and object utilities.
39
+
40
+ - **Parsing Utilities**: URL parsing and JSON parsing functions.
41
+
42
+ - **Miscellaneous**: Functions for similarity checks, node sorting, and more.
43
+
44
+ ## Requirements
45
+
46
+ - **Node.js**: Version 22 or higher.
47
+
48
+ - **TypeScript**: (Optional) If you're using TypeScript in your project.
49
+
50
+ ## Installation
51
+
52
+ Install the package using npm:
53
+
54
+ ```bash
55
+ npm i @truto/truto-jsonata
56
+ ```
57
+
58
+ Or with yarn:
59
+
60
+ ```bash
61
+ yarn add @truto/truto-jsonata
62
+ ```
63
+
64
+ ## Usage
65
+
66
+ To use `truto-jsonata`, import the default function and pass your JSONata expression as a string. This function returns an `Expression` object with all custom functions registered.
67
+
68
+ ```javascript
69
+
70
+ import trutoJsonata from '@truto/truto-jsonata';
71
+ cons expressionString = 'your JSONata expression here';
72
+ const expression = trutoJsonata(expressionString);
73
+
74
+ // Evaluate the expression with your data
75
+ const data = { /* your data object */ };
76
+ const result = expression.evaluate(data);
77
+ ```
78
+
79
+ Alternatively, if you already have a JSONata expression and want to register the custom functions:
80
+
81
+ ```javascript
82
+
83
+ import jsonata from 'jsonata';
84
+ import registerJsonataExtensions from '@truto/truto-jsonata/registerJsonataExtensions';
85
+ const expression = jsonata('your expression');
86
+
87
+ registerJsonataExtensions(expression);
88
+ // Now you can use custom functions in your expression
89
+ ```
90
+
91
+ ## Custom Functions
92
+
93
+ Below is a detailed list of all custom functions added to JSONata expressions, along with examples demonstrating how to use each one.
94
+
95
+ ### Data Transformation and Utility Functions
96
+
97
+ <details>
98
+ <summary> dtFromIso(datetimeString)</summary>
99
+
100
+ Converts an ISO date-time string to a [Luxon DateTime](https://moment.github.io/luxon/api-docs/index.html#datetime) object.
101
+
102
+ **Example:**
103
+
104
+ ```javascript
105
+ import trutoJsonata from '@truto/truto-jsonata'
106
+
107
+ const expression = trutoJsonata("$dtFromIso('2024-11-05T12:00:00Z')");
108
+ expression.evaluate({}).then(result => { console.log(result)});
109
+ // Output: DateTime { ts: 2024-11-05T12:00:00.000+00:00, zone: UTC, locale: en-US }
110
+ ```
111
+
112
+ </details>
113
+
114
+ <details>
115
+ <summary> dtFromFormat(datetimeString, format)</summary>
116
+
117
+ Parses a date-time string according to the specified format and returns a [Luxon DateTime](https://moment.github.io/luxon/api-docs/index.html#datetime) object.
118
+
119
+ **Example:**
120
+
121
+ ```javascript
122
+ import trutoJsonata from '@truto/truto-jsonata'
123
+
124
+ const expression = trutoJsonata("$dtFromFormat('01-11-2022 12:00', 'dd-MM-yyyy HH:mm')");
125
+ expression.evaluate({}).then(result => { console.log(result });
126
+ // Output: DateTime { ts: 2022-11-01T12:00:00.000+00:00, zone: UTC, locale: en-US }
127
+ ```
128
+
129
+ </details>
130
+
131
+ <details>
132
+ <summary> removeEmptyItems(array)</summary>
133
+
134
+ Filters out empty objects from an array.
135
+
136
+ **Example:**
137
+
138
+ ```javascript
139
+ import trutoJsonata from '@truto/truto-jsonata';
140
+
141
+ const data = [{}, { a: 1 }, []];
142
+ const expression = trutoJsonata("$removeEmptyItems(data)");
143
+ expression.evaluate({ data }).then(result => { console.log(result); });
144
+ //Output: [ { a: 1 } ]
145
+ ```
146
+
147
+ </details>
148
+
149
+ <details>
150
+ <summary> removeEmpty(object)</summary>
151
+
152
+ Removes all properties with empty values (`null`, `undefined`, empty string, empty array) from an object.
153
+
154
+ **Example:**
155
+
156
+ ```javascript
157
+ import trutoJsonata from '@truto/truto-jsonata';
158
+
159
+ const data = ["1", "2", "3", ""];
160
+ const blankData = []
161
+ let expression = trutoJsonata("$removeEmpty(data)");
162
+ expression.evaluate({ data }).then(result => { console.log(result); });
163
+
164
+ //another example
165
+ expression = trutoJsonata("$removeEmpty(blankData)");
166
+ expression.evaluate({ blankData }).then(result => { console.log(result); });
167
+ /* Output:
168
+ [ "1", "2", "3", "" ]
169
+ undefined
170
+ */
171
+ ```
172
+
173
+ </details>
174
+
175
+ <details>
176
+ <summary>convertCurrencyToSubunit(amount, currencyCode)</summary>
177
+
178
+ Converts a currency amount to its smallest subunit (e.g., dollars to cents).
179
+
180
+ **Example:**
181
+
182
+ ```javascript
183
+ import trutoJsonata from '@truto/truto-jsonata';
184
+
185
+ const expression = trutoJsonata("$convertCurrencyToSubunit(5.50, 'USD')");
186
+ expression.evaluate({}).then(result => { console.log(result); });
187
+ // Output: 550
188
+ ```
189
+
190
+ </details>
191
+
192
+ <details>
193
+ <summary>convertCurrencyFromSubunit(amountInSubunit, currencyCode)</summary>
194
+
195
+ Converts an amount in subunits back to the main currency unit.
196
+
197
+ **Example:**
198
+
199
+ ```javascript
200
+ import trutoJsonata from '@truto/truto-jsonata';
201
+
202
+ const expression = trutoJsonata("$convertCurrencyFromSubunit(550, 'USD')");
203
+ expression.evaluate({}).then(result => { console.log(result); });
204
+ // Output: 5.50
205
+ ```
206
+
207
+ </details>
208
+
209
+ <details>
210
+ <summary>convertQueryToSql(query, keysToMap = [], mapping = {}, dataTypes = {}, customOperatorMapping = {}, options = {})</summary>
211
+
212
+
213
+ Converts a query object into an SQL query string.
214
+
215
+ **Parameters**:
216
+
217
+ - **`query`**
218
+ The query object to be converted into SQL.
219
+
220
+ - **`keysToMap`** _(Optional)_
221
+ A list of keys that should be processed in the SQL conversion.
222
+ - **`mapping`** _(Optional)_
223
+ An object to map the original keys to SQL-compatible keys.
224
+ - **`dataTypes`** _(Optional)_
225
+ An object that specifies the data type for each field in the query.
226
+
227
+ Supported Data Types:
228
+
229
+ - `string`
230
+ - `double_quote_string`
231
+ - `number`
232
+ - `boolean`
233
+ - `dotnetdate`
234
+
235
+ - **`customOperatorMapping`** _(Optional)_
236
+ An object to provide a custom mapping for operators (e.g., replacing `eq` with `=`).
237
+
238
+ - **`options`** _(Optional)_
239
+ An object providing additional options for the conversion.
240
+
241
+ Supported Options:
242
+
243
+ - **`useOrForIn`** _(Boolean)_: Use `OR` instead of `IN` for array comparisons.
244
+ default: `false`
245
+ - **`conjunction`** _(String)_: Logical conjunction for combining conditions (`'AND'` or `'OR'`).
246
+ default: `'AND'`
247
+ - **`useDoubleQuotes`** _(Boolean)_: Use double quotes for string values.
248
+ default: `false`
249
+ - **`noSpaceBetweenOperator`** _(Boolean)_: No space between operators and values.
250
+ default: `false`
251
+ - **`noQuotes`** _(Boolean)_: Do not use quotes around string values.
252
+ default: `false`
253
+ - **`noQuotesForDate`** _(Boolean)_: No quotes for date values.
254
+ default: `false`
255
+ - **`groupComparisonInBrackets`** _(Boolean)_: Group comparisons in brackets.
256
+ default: `false`
257
+ - **`escapeSingleQuotes`** _(Boolean)_: Escape single quotes within string values.
258
+ default: `false`
259
+
260
+ ***Supported Operators***:
261
+
262
+ - **`eq`**: Equals (`=`)
263
+ - **`ne`**: Not Equals (`<>`)
264
+ - **`gt`**: Greater Than (`>`)
265
+ - **`gte`**: Greater Than or Equal (`>=`)
266
+ - **`lt`**: Less Than (`<`)
267
+ - **`lte`**: Less Than or Equal (`<=`)
268
+ - **`in`**: In List (`IN`)
269
+ - **`nin`**: Not In List (`NOT IN`)
270
+ - **`like`**: Like (`LIKE`)
271
+
272
+ **Example:**
273
+
274
+ ```javascript
275
+ import trutoJsonata from '@truto/truto-jsonata';
276
+
277
+ // Example 1: Basic usage with common operators
278
+ const data1 = {
279
+ name: { eq: 'John' },
280
+ age: { gte: '30' },
281
+ };
282
+
283
+ const expression1 = trutoJsonata("$convertQueryToSql(data)");
284
+ expression1.evaluate({ data: data1 }).then(result => {
285
+ console.log(result);
286
+ // Output: name = 'John' AND age >= 30
287
+ });
288
+
289
+ // Example 2: Using 'like' operator
290
+ const data2 = {
291
+ name: { like: 'John' },
292
+ };
293
+
294
+ const expression2 = trutoJsonata("$convertQueryToSql(data)");
295
+ expression2.evaluate({ data: data2 }).then(result => {
296
+ console.log(result);
297
+ // Output: (name = 'John' OR name = 'Jane')
298
+ });
299
+
300
+ // Example 3: Using 'lt' and 'lte' operators
301
+ const data3 = {
302
+ price: { lt: 100 },
303
+ discount: { lte: 20 },
304
+ };
305
+
306
+ const expression3 = trutoJsonata("$convertQueryToSql(data)");
307
+ expression3.evaluate({ data: data3 }).then(result => {
308
+ console.log(result);
309
+ // Output: price < 100 AND discount <= 20
310
+ });
311
+
312
+ // Example 4: Using 'gt' and 'gte' operators
313
+ const data4 = {
314
+ rating: { gt: 4 },
315
+ reviews: { gte: 100 },
316
+ };
317
+
318
+ const expression4 = trutoJsonata("$convertQueryToSql(data)");
319
+ expression4.evaluate({ data: data4 }).then(result => {
320
+ console.log(result);
321
+ // Output: rating > 4 AND reviews >= 100
322
+ });
323
+
324
+ // Example 5: Using 'ne' (not equal) operator
325
+ const data5 = {
326
+ status: { ne: 'inactive' },
327
+ };
328
+
329
+ const expression5 = trutoJsonata("$convertQueryToSql(data)");
330
+ expression5.evaluate({ data: data5 }).then(result => {
331
+ console.log(result);
332
+ // Output: status <> inactive
333
+ });
334
+
335
+ // Example 6: Using 'nin' (not in) operator
336
+ const data6 = {
337
+ category: { nin: ['Electronics', 'Furniture'] },
338
+ };
339
+
340
+ const expression6 = trutoJsonata("$convertQueryToSql(data)");
341
+ expression6.evaluate({ data: data6 }).then(result => {
342
+ console.log(result);
343
+ // Output: category NOT IN ('Electronics','Furniture')
344
+ });
345
+
346
+ // Example 7: Using 'startswith', 'endswith', and 'contains' operators
347
+ const data = {
348
+ title: { in: ['Intro to Programming', 'Intro to JavaScript'] },
349
+ author: { eq: 'Smith' },
350
+ };
351
+
352
+ const expression = trutoJsonata("$convertQueryToSql(data)");
353
+ expression.evaluate({ data }).then(result => {
354
+ console.log(result);
355
+ // Output: title IN ('Intro to Programming','Intro to JavaScript') AND author = 'Smith'
356
+ });
357
+
358
+
359
+ // Example 8: Using custom operator mapping
360
+ const customOperatorMapping = {
361
+ eq: '=',
362
+ ne: '<>',
363
+ lt: '<',
364
+ lte: '<=',
365
+ gt: '>',
366
+ gte: '>=',
367
+ in: 'IN',
368
+ nin: 'NOT IN',
369
+ startswith: 'LIKE',
370
+ endswith: 'LIKE',
371
+ contains: 'LIKE',
372
+ };
373
+
374
+ const data8 = {
375
+ status: { ne: 'inactive' },
376
+ };
377
+
378
+ const expression8 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, customOperatorMapping)");
379
+ expression8.evaluate({ data: data8, customOperatorMapping }).then(result => {
380
+ console.log(result);
381
+ // Output: status <> 'inactive'
382
+ });
383
+
384
+ // Example 9: Using data types
385
+ const dataTypes = {
386
+ created_at: 'string',
387
+ };
388
+
389
+ const data9 = {
390
+ created_at: { eq: '2021-01-01' },
391
+ };
392
+
393
+ const expression9 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, dataTypes)");
394
+ expression9.evaluate({ data: data9, dataTypes }).then(result => {
395
+ console.log(result);
396
+ // Output: created_at = '2021-01-01'
397
+ });
398
+
399
+ // Example 10: Using mapping for keys
400
+ const mapping = {
401
+ firstName: 'first_name',
402
+ lastName: 'last_name',
403
+ };
404
+
405
+ const data10 = {
406
+ firstName: { eq: 'John' },
407
+ lastName: { eq: 'Doe' },
408
+ };
409
+
410
+ const expression10 = trutoJsonata("$convertQueryToSql(data, [], mapping, {}, {}, {})");
411
+ expression10.evaluate({ data: data10, mapping }).then(result => {
412
+ console.log(result);
413
+ // Output: first_name = 'John' AND last_name = 'Doe'
414
+ });
415
+
416
+ // Example 11: Using options (e.g., conjunction, groupComparisonInBrackets)
417
+ const options = {
418
+ conjunction: 'OR',
419
+ groupComparisonInBrackets: true,
420
+ };
421
+
422
+ const data11 = {
423
+ name: { eq: 'Alice' },
424
+ city: { eq: 'Wonderland' },
425
+ };
426
+
427
+ const expression11 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
428
+ expression11.evaluate({ data: data11, options }).then(result => {
429
+ console.log(result);
430
+ // Output: (name = 'Alice' OR city = 'Wonderland')
431
+ });
432
+
433
+ // Example 12: Using 'useOrForIn' option
434
+ const options12 = {
435
+ useOrForIn: true,
436
+ };
437
+
438
+ const data12 = {
439
+ id: { in: [1, 2, 3] },
440
+ };
441
+
442
+ const expression12 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
443
+ expression12.evaluate({ data: data12, options: options12 }).then(result => {
444
+ console.log(result);
445
+ // Output: (id = 1 OR id = 2 OR id = 3)
446
+ });
447
+
448
+ // Example 13: Handling 'noQuotes' and 'useDoubleQuotes' options
449
+ const options13 = {
450
+ noQuotes: true,
451
+ useDoubleQuotes: true,
452
+ };
453
+
454
+ const data13 = {
455
+ category: { eq: 'Books' },
456
+ };
457
+
458
+ const expression13 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
459
+ expression13.evaluate({ data: data13, options: options13 }).then(result => {
460
+ console.log(result);
461
+ // Output: category = Books
462
+ });
463
+
464
+ // Example 14: Escaping single quotes in values
465
+ const options14 = {
466
+ escapeSingleQuotes: true,
467
+ };
468
+
469
+ const data14 = {
470
+ name: { eq: "O'Reilly" },
471
+ };
472
+
473
+ const expression14 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
474
+ expression14.evaluate({ data: data14, options: options14 }).then(result => {
475
+ console.log(result);
476
+ // Output: name = 'O''Reilly'
477
+ });
478
+
479
+ // Example 15: Using 'noSpaceBetweenOperator' option
480
+ const options15 = {
481
+ noSpaceBetweenOperator: true,
482
+ };
483
+
484
+ const data15 = {
485
+ price: { gt: '100' },
486
+ };
487
+
488
+ const expression15 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
489
+ expression15.evaluate({ data: data15, options: options15 }).then(result => {
490
+ console.log(result);
491
+ // Output: price>100
492
+ });
493
+
494
+ // Example 16: Using 'groupComparisonInBrackets' with 'AND' conjunction
495
+ const options16 = {
496
+ groupComparisonInBrackets: true,
497
+ conjunction: 'AND'
498
+ };
499
+
500
+ const data16 = {
501
+ category: { eq: 'Books' },
502
+ availability: { eq: 'In Stock' },
503
+ };
504
+
505
+ const expression16 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
506
+ expression16.evaluate({ data: data16, options: options16 }).then(result => {
507
+ console.log(result);
508
+ // Output: (category = 'Books' AND availability = 'In Stock')
509
+ });
510
+
511
+ // Example 17: Using 'noQuotesForDate' with a date value
512
+ const options17 = {
513
+ noQuotesForDate: true,
514
+ };
515
+
516
+ const data17 = {
517
+ created_at: { eq: '2021-12-31' },
518
+ };
519
+
520
+ const dataTypes17 = {
521
+ created_at: 'date|yyyy-MM-dd'
522
+ };
523
+
524
+ const expression17 = trutoJsonata("$convertQueryToSql(data, [], {}, dataTypes, {}, options)");
525
+ expression17.evaluate({ data: data17, dataTypes: dataTypes17, options: options17 }).then(result => {
526
+ console.log(result);
527
+ // Output: created_at = 2021-12-31
528
+ });
529
+
530
+ // Example 18: Using 'useDoubleQuotes' and 'groupComparisonInBrackets' options
531
+ const options18 = {
532
+ useDoubleQuotes: true,
533
+ groupComparisonInBrackets: true,
534
+ };
535
+
536
+ const data18 = {
537
+ product: { eq: 'Laptop' },
538
+ brand: { eq: 'Dell' },
539
+ };
540
+
541
+ const expression18 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
542
+ expression18.evaluate({ data: data18, options: options18 }).then(result => {
543
+ console.log(result);
544
+ // Output: (product = "Laptop" AND brand = "Dell")
545
+ });
546
+
547
+ // Example 19: Using a custom conjunction ('NOR')
548
+ const options19 = {
549
+ conjunction: 'NOR',
550
+ };
551
+
552
+ const data19 = {
553
+ available: { eq: 'No' },
554
+ sold: { eq: 'Yes' },
555
+ };
556
+
557
+ const expression19 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
558
+ expression19.evaluate({ data: data19, options: options19 }).then(result => {
559
+ console.log(result);
560
+ // Output: available = 'No' NOR sold = 'Yes'
561
+ });
562
+
563
+ // Example 20: Using 'dotnetdate' data type with 'groupComparisonInBrackets'
564
+ const data20 = {
565
+ modified_at: { eq: '2023-01-01T00:00:00Z' },
566
+ };
567
+
568
+ const dataTypes20 = {
569
+ modified_at: 'dotnetdate'
570
+ };
571
+
572
+ const options20 = {
573
+ groupComparisonInBrackets: true,
574
+ };
575
+
576
+ const expression20 = trutoJsonata("$convertQueryToSql(data, [], {}, dataTypes, {}, options)");
577
+ expression20.evaluate({ data: data20, dataTypes: dataTypes20, options: options20 }).then(result => {
578
+ console.log(result);
579
+ // Output: (modified_at = DateTime(2023,01,01))
580
+ });
581
+
582
+ // Example 21: Using 'noQuotes' option for numeric comparison
583
+ const options21 = {
584
+ noQuotes: true,
585
+ };
586
+
587
+ const data21 = {
588
+ rating: { gt: '4.5' },
589
+ };
590
+
591
+ const expression21 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
592
+ expression21.evaluate({ data: data21, options: options21 }).then(result => {
593
+ console.log(result);
594
+ // Output: rating > 4.5
595
+ });
596
+
597
+ // Example 22: Combining 'useOrForIn' with custom conjunction
598
+ const options22 = {
599
+ useOrForIn: true,
600
+ conjunction: 'OR',
601
+ };
602
+
603
+ const data22 = {
604
+ productId: { in: [101, 102, 103] },
605
+ };
606
+
607
+ const expression22 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
608
+ expression22.evaluate({ data: data22, options: options22 }).then(result => {
609
+ console.log(result);
610
+ // Output: (productId = 101 OR productId = 102 OR productId = 103)
611
+ });
612
+
613
+ // Example 23: Using 'escapeSingleQuotes' with a string that contains a single quote
614
+ const options23 = {
615
+ escapeSingleQuotes: true,
616
+ };
617
+
618
+ const data23 = {
619
+ publisher: { eq: "McGraw-Hill's" },
620
+ };
621
+
622
+ const expression23 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
623
+ expression23.evaluate({ data: data23, options: options23 }).then(result => {
624
+ console.log(result);
625
+ // Output: publisher = 'McGraw-Hill\'s'
626
+ });
627
+
628
+ // Example 24: 'noSpaceBetweenOperator' with 'gt' operator
629
+ const options24 = {
630
+ noSpaceBetweenOperator: true,
631
+ };
632
+
633
+ const data24 = {
634
+ inventory: { gt: '50' },
635
+ };
636
+
637
+ const expression25 = trutoJsonata("$convertQueryToSql(data, [], {}, {}, {}, options)");
638
+ expression25.evaluate({ data: data24, options: options24 }).then(result => {
639
+ console.log(result);
640
+ // Output: inventory>50
641
+ });
642
+
643
+ // Example 25: Using 'noQuotesForDate' and escaping single quotes in the same data
644
+ const options25 = {
645
+ noQuotesForDate: true,
646
+ escapeSingleQuotes: true,
647
+ };
648
+
649
+ const data25 = {
650
+ releaseDate: { eq: '2023-03-15' },
651
+ author: { eq: "J.K. O'Rourke" },
652
+ };
653
+
654
+ const dataTypes25 = {
655
+ releaseDate: 'date|yyyy-MM-dd'
656
+ };
657
+
658
+ const expression25 = trutoJsonata("$convertQueryToSql(data, [], {}, dataTypes, {}, options)");
659
+ expression25.evaluate({ data: data25, dataTypes: dataTypes25, options: options25 }).then(result => {
660
+ console.log(result);
661
+ // Output: releaseDate = 2023-03-15 AND author = 'J.K. O\'Rourke'
662
+ });
663
+ ```
664
+
665
+ </details>
666
+
667
+ <details>
668
+ <summary>mapValues(value, mapping, lowerCase = false, defaultValue = null)</summary>
669
+
670
+ Transforms a value (object, array, string, or number) based on a provided mapping. The function applies mappings recursively and can handle case insensitivity or default values if the mapping doesn’t exist.
671
+
672
+ **Example:**
673
+
674
+ ```javascript
675
+ import trutoJsonata from '@truto/truto-jsonata';
676
+
677
+ // Example 1: Basic mapping with default options
678
+ const roleKey = "1";
679
+ const roleMapping = {
680
+ "1": "owner",
681
+ "2": "admin",
682
+ "3": "member",
683
+ "4": "guest"
684
+ };
685
+
686
+ // Create a JSONata expression using the $mapValues function
687
+ const roleExpression = trutoJsonata("$mapValues(roleKey, roleMapping)");
688
+
689
+ roleExpression.evaluate({ roleKey, roleMapping }).then(result => {
690
+ console.log(result); // Output: "owner"
691
+ });
692
+
693
+ // Example 2: Using defaultValue
694
+ const roleKey2 = null;
695
+
696
+ // Create a JSONata expression with defaultValue set to 'Unknown'
697
+ const roleExpression2 = trutoJsonata("$mapValues(roleKey2, roleMapping, false, 'Unknown')");
698
+
699
+ roleExpression2.evaluate({ roleKey: roleKey2, roleMapping }).then(result => {
700
+ console.log(result); // Output: "Unknown"
701
+ });
702
+
703
+ // Example 3: Case-insensitive mapping (lowerCase = false)
704
+ const caseInsensitiveKey = "admin";
705
+ const caseInsensitiveMapping = {
706
+ "OWNER": "Owner",
707
+ "ADMIN": "Administrator",
708
+ "GUEST": "Guest"
709
+ };
710
+
711
+ // lowerCase set to false (default)
712
+ const caseInsensitiveExpression = trutoJsonata("$mapValues(caseInsensitiveKey, caseInsensitiveMapping, false)");
713
+
714
+ caseInsensitiveExpression.evaluate({ caseInsensitiveKey, caseInsensitiveMapping }).then(result => {
715
+ console.log(result);
716
+ // Output: "Administrator"
717
+ // Keys are coverted to lowerCase and matched here
718
+ });
719
+
720
+ // Example 4: Array input
721
+ const roleKeysArray = ["1", "3", "5"];
722
+
723
+ // Create a JSONata expression to map an array of role keys
724
+ const roleExpression3 = trutoJsonata("$mapValues(roleKeysArray, roleMapping)");
725
+
726
+ roleExpression3.evaluate({ roleKeysArray, roleMapping }).then(result => {
727
+ console.log(result); // Output: ["owner", "member", "5"]
728
+ });
729
+
730
+ // Example 5: Object input with nested keys (refer roleMapping above)
731
+ const userRoles = {
732
+ user1: "1",
733
+ user2: "2",
734
+ user3: "5"
735
+ };
736
+
737
+ // Create a JSONata expression to map values within an object
738
+ const roleExpression4 = trutoJsonata("$mapValues(userRoles, roleMapping)");
739
+
740
+ roleExpression4.evaluate({ userRoles, roleMapping }).then(result => {
741
+ console.log(result); // Output: { user1: "owner", user2: "admin", user3: "5" }
742
+ });
743
+
744
+ // Example 6: Using mapValues on mixed type arrays
745
+ const mixedArray = ["1", "Admin", 500, null, undefined];
746
+
747
+ const mappingForMixedArray = {
748
+ "1": "Owner",
749
+ "Admin": "Administrator",
750
+ "500": "Server Error"
751
+ };
752
+
753
+ const mixedArrayExpression = trutoJsonata("$mapValues(mixedArray, mappingForMixedArray)");
754
+
755
+ mixedArrayExpression.evaluate({ mixedArray, mappingForMixedArray }).then(result => {
756
+ console.log(result); // Output: ["Owner", "Administrator", "Server Error", null, undefined]
757
+ });
758
+
759
+ ```
760
+
761
+ </details>
762
+
763
+ <details>
764
+ <summary>zipSqlResponse(columns, data, key)</summary>
765
+
766
+ Converts an SQL response (typically with column metadata and row data) into an array of objects, where each object represents a row with column names as keys.
767
+
768
+ **Example:**
769
+
770
+ ```javascript
771
+ import trutoJsonata from '@truto/truto-jsonata';
772
+
773
+ const columns = [
774
+ { name: 'id' },
775
+ { name: 'name' },
776
+ { name: 'age' }
777
+ ];
778
+ const data = [
779
+ [1, 'Alice', 30],
780
+ [2, 'Bob', 25],
781
+ [3, 'Charlie', 35]
782
+ ];
783
+ const key = 'name';
784
+ const expression = trutoJsonata("$zipSqlResponse(columns, data, key)");
785
+ expression.evaluate({ columns, data, key }).then(result => { console.log(result); });
786
+ /*
787
+ Output:
788
+ [
789
+ { id: 1, name: 'Alice', age: 30 },
790
+ { id: 2, name: 'Bob', age: 25 },
791
+ { id: 3, name: 'Charlie', age: 35 }
792
+ ]
793
+ */
794
+ ```
795
+
796
+ </details>
797
+
798
+ <details>
799
+ <summary> firstNonEmpty(...values)</summary>
800
+
801
+ Returns the first argument that is not `null` or `undefined.
802
+
803
+ **Example:**
804
+
805
+ ```javascript
806
+ import trutoJsonata from '@truto/truto-jsonata';
807
+
808
+ const expression = trutoJsonata("$firstNonEmpty( null, ['3'], undefined)");
809
+ expression.evaluate({}).then(result => { console.log(result); });
810
+ // Output: [ "3" ]
811
+ ```
812
+
813
+ </details>
814
+
815
+ <details>
816
+ <summary> jsonParse(jsonString)</summary>
817
+
818
+ Parses a JSON string into an object.
819
+
820
+ **Example:**
821
+
822
+ ```javascript
823
+ import trutoJsonata from '@truto/truto-jsonata';
824
+
825
+ const expression = trutoJsonata("$jsonParse('{\"name\":\"Alice\"}')");
826
+ expression.evaluate({}).then(result => { console.log(result); });
827
+ // Output: { name: 'Alice' }
828
+ ```
829
+
830
+ </details>
831
+
832
+ <details>
833
+ <summary> getMimeType(fileName)</summary>
834
+
835
+ Returns the MIME type based on the file extension.
836
+
837
+ **Example:**
838
+
839
+ ```javascript
840
+ import trutoJsonata from '@truto/truto-jsonata';
841
+
842
+ const expression = trutoJsonata("$getMimeType('html')");
843
+ expression.evaluate({}).then(result => { console.log(result); });
844
+ // Output: 'text/html'
845
+ ```
846
+
847
+ </details>
848
+
849
+ <details>
850
+ <summary>uuid()</summary>
851
+
852
+ Generates a new UUID (version 4).
853
+
854
+ **Example:**
855
+
856
+ ```javascript
857
+ import trutoJsonata from '@truto/truto-jsonata';
858
+
859
+ const expression = trutoJsonata("$uuid()");
860
+ expression.evaluate({ }).then(result => { console.log(result); });
861
+ // Output: A UUID string
862
+ ```
863
+
864
+ </details>
865
+
866
+ <details>
867
+ <summary>getArrayBuffer(file)</summary>
868
+
869
+ Converts a `Blob` file to an `ArrayBuffer`. If no file is provided, the function returns `undefined`.
870
+
871
+ **Example:**
872
+
873
+ ```javascript
874
+ import trutoJsonata from '@truto/truto-jsonata';
875
+
876
+ const file = new Blob(['Hello, World!'], { type: 'text/plain' });
877
+ const expression = trutoJsonata("$getArrayBuffer(file)");
878
+ expression.evaluate({ file}).then(result => { console.log(result); });
879
+ // Output: ArrayBuffer(13) [ 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33 ]
880
+ ```
881
+
882
+ </details>
883
+
884
+ <details>
885
+ <summary>blob(content, options)</summary>
886
+
887
+ Creates a `Blob` object from content with the specified MIME type.
888
+
889
+ **Example:**
890
+
891
+ ```javascript
892
+ import trutoJsonata from '@truto/truto-jsonata';
893
+
894
+ const content = ['Hello, World!'];
895
+ const options = { type: 'text/plain' };
896
+ const expression = trutoJsonata("$blob(content, options)");
897
+ console.log(expression.evaluate({ content, options }));
898
+ /* Output:
899
+ Blob (13 bytes) {
900
+ type: "text/plain;charset=utf-8"
901
+ }
902
+ */
903
+ ```
904
+
905
+ </details>
906
+
907
+ <details>
908
+ <summary>digest(text, algorithm = 'SHA-256', stringType = 'hex')</summary>
909
+
910
+ Generates a cryptographic hash of the input text using a specified hashing algorithm and output format.
911
+
912
+ **Example:**
913
+
914
+ ```javascript
915
+ import trutoJsonata from '@truto/truto-jsonata';
916
+
917
+ // Example 1: Default Usage (SHA-256, Hex Output)
918
+ const text1 = 'Hello, World!';
919
+ const algorithm1 = 'SHA-256';
920
+ const stringType1 = 'hex';
921
+
922
+ const expression1 = trutoJsonata("$digest(text, algorithm, stringType)");
923
+ expression1.evaluate({ text: text1, algorithm: algorithm1, stringType: stringType1 }).then(result => {
924
+ console.log(result);
925
+ // Output: "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b53ee6b9c6fbc9c39"
926
+ });
927
+
928
+ // Example 2: SHA-512 Algorithm, Hex Output
929
+ const text2 = 'The quick brown fox jumps over the lazy dog';
930
+ const algorithm2 = 'SHA-512';
931
+ const stringType2 = 'hex';
932
+
933
+ const expression2 = trutoJsonata("$digest(text, algorithm, stringType)");
934
+ expression2.evaluate({ text: text2, algorithm: algorithm2, stringType: stringType2 }).then(result => {
935
+ console.log(result);
936
+ // Output: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64..."
937
+ });
938
+
939
+ // Example 3: SHA-256 Algorithm, Base64 Output
940
+ const text3 = 'Data security is key';
941
+ const algorithm3 = 'SHA-256';
942
+ const stringType3 = 'base64';
943
+
944
+ const expression3 = trutoJsonata("$digest(text, algorithm, stringType)");
945
+ expression3.evaluate({ text: text3, algorithm: algorithm3, stringType: stringType3 }).then(result => {
946
+ console.log(result);
947
+ // Output: "Xh3mV+fAAG7ScGPjo4PElmR3obnFzGrxnbwGpEE4lI4="
948
+
949
+ });
950
+
951
+ ```
952
+
953
+ </details>
954
+
955
+ <details>
956
+ <summary>sign(text, algorithm = 'SHA-256', secret, outputFormat = 'hex')</summary>
957
+
958
+ Generates a cryptographic HMAC signature of the input text using a specified hash algorithm and secret key.
959
+
960
+ **Example:**
961
+
962
+ ```javascript
963
+ import trutoJsonata from '@truto/truto-jsonata';
964
+
965
+ // Example 1: Default Configuration (SHA-256, Hex Output)
966
+ const text1 = 'Hello, World!';
967
+ const algorithm1 = 'SHA-256';
968
+ const secret1 = 'mySecretKey';
969
+ const outputFormat1 = 'hex';
970
+
971
+ const expression1 = trutoJsonata("$sign(text, algorithm, secret, outputFormat)");
972
+ expression1.evaluate({ text: text1, algorithm: algorithm1, secret: secret1, outputFormat: outputFormat1 }).then(result => {
973
+ console.log(result);
974
+ // Output: "7a60d197fc6a4e91ab6f09f17d74e5a62d3a57ef6c4dc028ef2b8f38a328d2b9"
975
+ });
976
+
977
+ // Example 2: SHA-512 Algorithm, Hex Output
978
+ const text2 = 'The quick brown fox jumps over the lazy dog';
979
+ const algorithm2 = 'SHA-512';
980
+ const secret2 = 'anotherSecretKey';
981
+ const outputFormat2 = 'hex';
982
+
983
+ const expression2 = trutoJsonata("$sign(text, algorithm, secret, outputFormat)");
984
+ expression2.evaluate({ text: text2, algorithm: algorithm2, secret: secret2, outputFormat: outputFormat2 }).then(result => {
985
+ console.log(result);
986
+ /*
987
+ Output:"b9b229b20c8c1088f0d89e2324a8c8cc8e5fd1ec80d1783b00320df3e7a9b660f2d86b2f06089ee1a6b5ef35ee0d4d38de836fe4b46e4f35c9eea66c92ab3c0f"
988
+ */
989
+ });
990
+ ```
991
+
992
+ </details>
993
+
994
+ <details>
995
+ <summary>xmlToJs(xml, options = { compact: true, spaces: 4 } )</summary>
996
+
997
+ Converts an XML string into a JavaScript object.
998
+
999
+ **Example:**
1000
+
1001
+ ```javascript
1002
+ import trutoJsonata from '@truto/truto-jsonata';
1003
+
1004
+ // Example 1: Default Configuration (Compact Format, Indentation = 4 Spaces)
1005
+ const xmlData1 = `
1006
+ <note>
1007
+ <to>User</to>
1008
+ <message>Hello, World!</message>
1009
+ </note>
1010
+ `;
1011
+ const expression1 = trutoJsonata("$xmlToJs(xmlData)");
1012
+ expression1.evaluate({ xmlData: xmlData1 }).then(result => {
1013
+ console.log(result);
1014
+ /*
1015
+ Output:
1016
+ {
1017
+ note: {
1018
+ to: {
1019
+ _text: "User"
1020
+ },
1021
+ message: {
1022
+ _text: "Hello, World!"
1023
+ }
1024
+ }
1025
+ }
1026
+ */
1027
+ });
1028
+
1029
+ // Example 2: Non-Compact Format with no spaces specified
1030
+ const xmlData2 = `
1031
+ <library>
1032
+ <book>
1033
+ <title>1984</title>
1034
+ <author>George Orwell</author>
1035
+ </book>
1036
+ <book>
1037
+ <title>Brave New World</title>
1038
+ <author>Aldous Huxley</author>
1039
+ </book>
1040
+ </library>
1041
+ `;
1042
+
1043
+ const options2 = { compact: false };
1044
+ const expression2 = trutoJsonata("$xmlToJs(xmlData, options)");
1045
+ expression2.evaluate({ xmlData: xmlData2, options: options2 }).then(result => {
1046
+ console.log(result);
1047
+ /*
1048
+ Output:
1049
+ {
1050
+ elements: [
1051
+ {
1052
+ type: "element",
1053
+ name: "library",
1054
+ elements: [
1055
+ {
1056
+ type: "element",
1057
+ name: "book",
1058
+ elements: [
1059
+ { type: "element", name: "title", elements: [{ type: "text", text: "1984" }] },
1060
+ { type: "element", name: "author", elements: [{ type: "text", text: "George Orwell" }] }
1061
+ ]
1062
+ },
1063
+ {
1064
+ type: "element",
1065
+ name: "book",
1066
+ elements: [
1067
+ { type: "element", name: "title", elements: [{ type: "text", text: "Brave New World" }] },
1068
+ { type: "element", name: "author", elements: [{ type: "text", text: "Aldous Huxley" }] }
1069
+ ]
1070
+ }
1071
+ ]
1072
+ }
1073
+ ]
1074
+ }
1075
+ */
1076
+ });
1077
+
1078
+ // Example 3: Compact Format with Custom Indentation (spaces = 2)
1079
+ const xmlData3 = `
1080
+ <users>
1081
+ <user>
1082
+ <name>Alice</name>
1083
+ <age>30</age>
1084
+ </user>
1085
+ <user>
1086
+ <name>Bob</name>
1087
+ <age>25</age>
1088
+ </user>
1089
+ </users>
1090
+ `;
1091
+
1092
+ const options3 = { compact: true, spaces: 2 };
1093
+ const expression3 = trutoJsonata("$xmlToJs(xmlData, options)");
1094
+ expression3.evaluate({ xmlData: xmlData3, options: options3 }).then(result => {
1095
+ console.log(result);
1096
+ /*
1097
+ Output:
1098
+ {
1099
+ users: {
1100
+ user: [
1101
+ {
1102
+ name: {
1103
+ _text: "Alice"
1104
+ },
1105
+ age: {
1106
+ _text: "30"
1107
+ }
1108
+ },
1109
+ {
1110
+ name: {
1111
+ _text: "Bob"
1112
+ },
1113
+ age: {
1114
+ _text: "25"
1115
+ }
1116
+ }
1117
+ ]
1118
+ }
1119
+ }
1120
+ */
1121
+ });
1122
+ ```
1123
+
1124
+ </details>
1125
+
1126
+ <details>
1127
+ <summary>jsToXml(json, options = { compact: true, spaces: 4 } )</summary>
1128
+
1129
+ Converts a JavaScript object into an XML string.
1130
+
1131
+ **Example:**
1132
+
1133
+ ```javascript
1134
+ import trutoJsonata from '@truto/truto-jsonata';
1135
+
1136
+ // Example 1: Default Configuration (Compact Format, Indentation = 4 Spaces)
1137
+ const jsonData1 = {
1138
+ note: {
1139
+ to: { _text: "User" },
1140
+ message: { _text: "Hello, World!" }
1141
+ }
1142
+ };
1143
+
1144
+ const expression1 = trutoJsonata("$jsToXml(jsonData)");
1145
+ expression1.evaluate({ jsonData: jsonData1 }).then(result => {
1146
+ console.log(result);
1147
+ /*
1148
+ Output:
1149
+ <note>
1150
+ <to>User</to>
1151
+ <message>Hello, World!</message>
1152
+ </note>
1153
+ */
1154
+ });
1155
+
1156
+ // Example 2: Non-Compact with no spaces specified
1157
+ const jsonData2 = {
1158
+ elements: [
1159
+ {
1160
+ type: "element",
1161
+ name: "library",
1162
+ elements: [
1163
+ {
1164
+ type: "element",
1165
+ name: "book",
1166
+ elements: [
1167
+ { type: "element", name: "title", elements: [{ type: "text", text: "1984" }] },
1168
+ { type: "element", name: "author", elements: [{ type: "text", text: "George Orwell" }] }
1169
+ ]
1170
+ },
1171
+ {
1172
+ type: "element",
1173
+ name: "book",
1174
+ elements: [
1175
+ { type: "element", name: "title", elements: [{ type: "text", text: "Brave New World" }] },
1176
+ { type: "element", name: "author", elements: [{ type: "text", text: "Aldous Huxley" }] }
1177
+ ]
1178
+ }
1179
+ ]
1180
+ }
1181
+ ]
1182
+ };
1183
+
1184
+ const options2 = { compact: false };
1185
+ const expression2 = trutoJsonata("$jsToXml(jsonData, options)");
1186
+ expression2.evaluate({ jsonData: jsonData2, options: options2 }).then(result => {
1187
+ console.log(result);
1188
+ /*
1189
+ Output:
1190
+ <library><book><title>1984</title><author>George Orwell</author></book><book><title>Brave New World</title><author>Aldous Huxley</author></book></library>
1191
+ */
1192
+ });
1193
+
1194
+ // Example 3: Non-Compact with Custom Indentation (4 Spaces)
1195
+ const jsonData3 = {
1196
+ elements: [
1197
+ {
1198
+ type: "element",
1199
+ name: "catalog",
1200
+ elements: [
1201
+ {
1202
+ type: "element",
1203
+ name: "product",
1204
+ elements: [
1205
+ { type: "element", name: "name", elements: [{ type: "text", text: "Laptop" }] },
1206
+ { type: "element", name: "price", elements: [{ type: "text", text: "$1200" }] }
1207
+ ]
1208
+ },
1209
+ {
1210
+ type: "element",
1211
+ name: "product",
1212
+ elements: [
1213
+ { type: "element", name: "name", elements: [{ type: "text", text: "Smartphone" }] },
1214
+ { type: "element", name: "price", elements: [{ type: "text", text: "$800" }] }
1215
+ ]
1216
+ }
1217
+ ]
1218
+ }
1219
+ ]
1220
+ };
1221
+
1222
+ const options3 = { compact: false, spaces: 4 };
1223
+ const expression3 = trutoJsonata("$jsToXml(jsonData, options)");
1224
+ expression3.evaluate({ jsonData: jsonData3, options: options3 }).then(result => {
1225
+ console.log(result);
1226
+ /*
1227
+ Output:
1228
+ <catalog>
1229
+ <product>
1230
+ <name>Laptop</name>
1231
+ <price>$1200</price>
1232
+ </product>
1233
+ <product>
1234
+ <name>Smartphone</name>
1235
+ <price>$800</price>
1236
+ </product>
1237
+ </catalog>
1238
+ */
1239
+ });
1240
+ ```
1241
+
1242
+ </details>
1243
+
1244
+ ### Markdown and Text Conversion
1245
+
1246
+ <details>
1247
+ <summary>convertMarkdownToGoogleDocs(text)</summary>
1248
+
1249
+ Converts Markdown text into a Google Docs API-compatible request format for applying text styles and content. For more details on the Google Docs API request format, refer to the [Google Docs API documentation](https://developers.google.com/docs/api/reference/rest/v1/documents/request).
1250
+
1251
+ **Example:**
1252
+
1253
+ ```javascript
1254
+ import trutoJsonata from '@truto/truto-jsonata';
1255
+
1256
+ const markdownText = `
1257
+ # Hello, World!
1258
+ This is a *bold* statement.
1259
+ `;
1260
+
1261
+ // Use convertMarkdownToGoogleDocs to convert Markdown to Google Docs format
1262
+ const expression = trutoJsonata("$convertMarkdownToGoogleDocs(markdownText)");
1263
+ expression.evaluate({ markdownText}).then(result => { console.log(result); });
1264
+
1265
+ //Output :
1266
+ /*
1267
+ {
1268
+ requests: [
1269
+ {
1270
+ insertText: [Object ...],
1271
+ }, {
1272
+ insertText: [Object ...],
1273
+ }, {
1274
+ insertText: [Object ...],
1275
+ }, {
1276
+ insertText: [Object ...],
1277
+ }, {
1278
+ insertText: [Object ...],
1279
+ }, {
1280
+ insertText: [Object ...],
1281
+ }, {
1282
+ updateParagraphStyle: [Object ...],
1283
+ }, {
1284
+ updateTextStyle: [Object ...],
1285
+ }
1286
+ ],
1287
+ }
1288
+ */
1289
+ ```
1290
+
1291
+ </details>
1292
+
1293
+ <details>
1294
+ <summary>convertMarkdownToNotion(markdown)</summary>
1295
+
1296
+ Converts Markdown text into a format compatible with Notion. For more details on the Notion API block format, refer to the [Notion Blocks Documentation](https://developers.notion.com/reference/block).
1297
+
1298
+ **Example:**
1299
+
1300
+ ```javascript
1301
+ import trutoJsonata from '@truto/truto-jsonata';
1302
+
1303
+ // Define Markdown text to convert
1304
+ const markdownText = `
1305
+ # Hello, Notion!
1306
+ This is some **bold** text.
1307
+ `;
1308
+
1309
+ // Use convertMarkdownToNotion to transform Markdown into Notion block format
1310
+ const expression = trutoJsonata("$convertMarkdownToNotion(markdownText)");
1311
+ expression.evaluate({ markdownText}).then(result => { console.log(result); });
1312
+ /*
1313
+ Output:
1314
+ {
1315
+ children: [
1316
+ {
1317
+ type: "paragraph",
1318
+ paragraph: [Object ...],
1319
+ }, {
1320
+ type: "heading_1",
1321
+ heading_1: [Object ...],
1322
+ }, {
1323
+ type: "paragraph",
1324
+ paragraph: [Object ...],
1325
+ }
1326
+ ],
1327
+ }
1328
+ */
1329
+ ```
1330
+
1331
+ </details>
1332
+
1333
+ <details>
1334
+ <summary>convertMarkdownToSlack(markdown)</summary>
1335
+
1336
+ Converts Markdown text into a format compatible with Slack messages.
1337
+
1338
+ **Example:**
1339
+
1340
+ ```javascript
1341
+ import trutoJsonata from '@truto/truto-jsonata';
1342
+
1343
+ // Define Markdown text to convert
1344
+ const markdownText = `
1345
+ # Hello, Slack!
1346
+ This is a message with *italic* and **bold** text.
1347
+ `;
1348
+
1349
+ // Use convertMarkdownToSlack to transform Markdown into Slack format
1350
+ const expression = trutoJsonata("$convertMarkdownToSlack(markdownText)");
1351
+ expression.evaluate({ markdownText}).then(result => { console.log(result); });
1352
+
1353
+ /*
1354
+ Output:
1355
+ [
1356
+ {
1357
+ type: "section",
1358
+ text: {
1359
+ type: "mrkdwn",
1360
+ text: "\n",
1361
+ },
1362
+ }, {
1363
+ type: "header",
1364
+ text: {
1365
+ type: "plain_text",
1366
+ text: "Hello, Slack!",
1367
+ emoji: true,
1368
+ },
1369
+ }, {
1370
+ type: "section",
1371
+ text: {
1372
+ type: "mrkdwn",
1373
+ text: "This is a message with *italic* and *bold* text.",
1374
+ },
1375
+ }
1376
+ ]
1377
+ */
1378
+ ```
1379
+
1380
+ </details>
1381
+
1382
+ <details>
1383
+ <summary>convertNotionToMarkdown(blocks)</summary>
1384
+
1385
+ Transforms a list of Notion blocks into a Markdown-formatted string, preserving content structure, lists, and hierarchical relationships.
1386
+
1387
+ **Example:**
1388
+
1389
+ ```javascript
1390
+ import trutoJsonata from '@truto/truto-jsonata';
1391
+
1392
+ // Define Notion blocks structure to convert
1393
+ const notionBlocks = [
1394
+ { type: 'heading_1', text: { content: 'Introduction' } },
1395
+ { type: 'paragraph', text: { content: 'This is a paragraph.' } },
1396
+ {
1397
+ type: 'bulleted_list_item',
1398
+ text: { content: 'List item 1' },
1399
+ children: [
1400
+ { type: 'bulleted_list_item', text: { content: 'Nested item 1' } }
1401
+ ]
1402
+ },
1403
+ { type: 'bulleted_list_item', text: { content: 'List item 2' } }
1404
+ ];
1405
+ const expression = trutoJsonata("$convertNotionToMarkdown(notionBlocks)");
1406
+ expression.evaluate({ notionBlocks}).then(result => { console.log(result); });
1407
+
1408
+ /*
1409
+ Output:
1410
+ # Introduction
1411
+
1412
+ This is a paragraph.
1413
+
1414
+ - List item 1
1415
+ - Nested item 1
1416
+ - List item 2
1417
+ */
1418
+ ```
1419
+
1420
+ </details>
1421
+
1422
+ <details>
1423
+ <summary>convertHtmlToMarkdown(htmlString)</summary>
1424
+
1425
+ Converts HTML content to Markdown format.
1426
+
1427
+ **Example:**
1428
+
1429
+ ```javascript
1430
+ import trutoJsonata from '@truto/truto-jsonata';
1431
+
1432
+ // Define an HTML string to convert
1433
+ const htmlContent = `
1434
+ <h1>Welcome to Markdown</h1>
1435
+ <p>This is a <strong>bold</strong> statement.</p>
1436
+ <ul>
1437
+ <li>Item 1</li>
1438
+ <li>Item 2</li>
1439
+ </ul>
1440
+ `;
1441
+
1442
+ // Use convertHtmlToMarkdown to transform HTML into Markdown
1443
+ const expression = trutoJsonata("$convertHtmlToMarkdown(htmlContent)");
1444
+ expression.evaluate({ htmlContent }).then(result => { console.log(result); });
1445
+
1446
+ /*
1447
+ Output:
1448
+
1449
+ Welcome to Markdown
1450
+ ===================
1451
+
1452
+ This is a **bold** statement.
1453
+
1454
+ * Item 1
1455
+ * Item 2
1456
+
1457
+ */
1458
+ ```
1459
+
1460
+ </details>
1461
+
1462
+ ---
1463
+
1464
+ ### Array and Object Utilities (Lodash Enhancements)
1465
+
1466
+ These functions are inspired by [Lodash](https://lodash.com/) and adapted for use within JSONata expressions.
1467
+
1468
+ <details>
1469
+ <summary>difference(array1, array2)</summary>
1470
+
1471
+ Returns an array of elements from `array1` not in `array2`
1472
+
1473
+ **Example:**
1474
+
1475
+ ```javascript
1476
+ import trutoJsonata from '@truto/truto-jsonata';
1477
+
1478
+ const dataArray = [1, 2, 3]
1479
+ const differentArray = [2, 3]
1480
+ const expression = trutoJsonata("$difference(dataArray,differentArray)");
1481
+ expression.evaluate({}).then(result => { console.log(result); });
1482
+ // Output: [1]
1483
+ ```
1484
+
1485
+ </details>
1486
+
1487
+ <details>
1488
+ <summary>groupBy(array, iteratee)</summary>
1489
+
1490
+ Groups the elements of an array based on the given iteratee (key).
1491
+
1492
+ **Example:**
1493
+
1494
+ ```javascript
1495
+ import trutoJsonata from '@truto/truto-jsonata';
1496
+
1497
+ const data = [
1498
+ { type: 'fruit', name: 'apple' },
1499
+ { type: 'vegetable', name: 'carrot' },
1500
+ { type: 'fruit', name: 'banana' }
1501
+ ];
1502
+ const expression = trutoJsonata("$groupBy(data, 'type')");
1503
+ expression.evaluate({ data }).then(result => { console.log(result); });
1504
+ /*
1505
+ Output:
1506
+ {
1507
+ fruit: [
1508
+ {
1509
+ type: "fruit",
1510
+ name: "apple",
1511
+ }, {
1512
+ type: "fruit",
1513
+ name: "banana",
1514
+ }
1515
+ ],
1516
+ vegetable: [
1517
+ {
1518
+ type: "vegetable",
1519
+ name: "carrot",
1520
+ }
1521
+ ],
1522
+ }
1523
+ */
1524
+ ```
1525
+
1526
+ </details>
1527
+
1528
+ <details>
1529
+ <summary>keyBy(array, iteratee)</summary>
1530
+
1531
+ Creates an object composed of keys generated from the results of running each element of `array` through `iteratee`
1532
+
1533
+ **Example:**
1534
+
1535
+ ```javascript
1536
+ import trutoJsonata from '@truto/truto-jsonata';
1537
+
1538
+ const data = [
1539
+ { id: 'a', value: 1 },
1540
+ { id: 'b', value: 2 }
1541
+ ];
1542
+ const expression = trutoJsonata("$keyBy(data, 'id')");
1543
+
1544
+ expression.evaluate({ data }).then(result => { console.log(result); });
1545
+ // Output: { a: { id: 'a', value: 1 }, b: { id: 'b', value: 2 } }
1546
+ ```
1547
+
1548
+ </details>
1549
+
1550
+ <details>
1551
+ <summary>pick(object, keys)</summary>
1552
+
1553
+ Creates an object composed of the selected `keys`
1554
+
1555
+ **Example:**
1556
+
1557
+ ```javascript
1558
+ import trutoJsonata from '@truto/truto-jsonata';
1559
+
1560
+ const data = { name: 'Alice', age: 30, email: 'alice@example.com' };
1561
+ const expression = trutoJsonata("$pick(data, ['name', 'email'])");
1562
+ expression.evaluate({ data }).then(result => { console.log(result); });
1563
+ // Output: { name: 'Alice', email: 'alice@example.com' }
1564
+ ```
1565
+
1566
+ </details>
1567
+
1568
+ <details>
1569
+ <summary>omit(object, keys)</summary>
1570
+
1571
+ Creates an object without the specified `keys`
1572
+
1573
+ **Example:**
1574
+
1575
+ ```javascript
1576
+ import trutoJsonata from '@truto/truto-jsonata';
1577
+
1578
+ const data = { name: 'Alice', age: 30, email: 'alice@example.com' };
1579
+ const expression = trutoJsonata("$omit(data, ['age'])");
1580
+ expression.evaluate({ data }).then(result => { console.log(result); });
1581
+ // Output: { name: 'Alice', email: 'alice@example.com' }
1582
+ ```
1583
+
1584
+ </details>
1585
+
1586
+ <details>
1587
+ <summary>compact(array)</summary>
1588
+
1589
+ Creates an array with all falsey values removed.
1590
+
1591
+ **Example:**
1592
+
1593
+ ```javascript
1594
+ import trutoJsonata from '@truto/truto-jsonata';
1595
+
1596
+ const data = [0, 1, false, 2, '', 3];
1597
+ const expression = trutoJsonata("$compact(data)");
1598
+ expression.evaluate({ data }).then(result => { console.log(result); });
1599
+ // Output: [1, 2, 3]
1600
+ ```
1601
+
1602
+ </details>
1603
+
1604
+ <details>
1605
+ <summary>join(array, separator)</summary>
1606
+
1607
+ Joins the elements of an array into a string, separated by `separator`
1608
+
1609
+ **Example:**
1610
+
1611
+ ```javascript
1612
+ import trutoJsonata from '@truto/truto-jsonata';
1613
+
1614
+ const data = ['apple', 'banana', 'cherry'];
1615
+ const expression = trutoJsonata("$join(data, '; ')");
1616
+ expression.evaluate({ data }).then(result => { console.log(result); });
1617
+ // Output: 'apple; banana; cherry'
1618
+ ```
1619
+
1620
+ </details>
1621
+
1622
+ <details>
1623
+ <summary>orderBy(collection, iteratees, orders)</summary>
1624
+
1625
+ Sorts the collection based on `iteratees` and `orders`
1626
+
1627
+ **Example:**
1628
+
1629
+ ```javascript
1630
+
1631
+ import trutoJsonata from '@truto/truto-jsonata';
1632
+
1633
+ const data = [
1634
+ { name: 'Alice', age: 30 },
1635
+ { name: 'Bob', age: 25 }
1636
+ ];
1637
+ const expression = trutoJsonata("$orderBy(data, ['age'], ['desc'])");
1638
+ expression.evaluate({ data }).then(result => { console.log(result); });
1639
+ /* Output:
1640
+ [
1641
+ {
1642
+ name: "Alice",
1643
+ age: 30,
1644
+ }, {
1645
+ name: "Bob",
1646
+ age: 25,
1647
+ }
1648
+ ]
1649
+ */
1650
+ ```
1651
+
1652
+ </details>
1653
+
1654
+ <details>
1655
+ <summary>find(collection, attr)</summary>
1656
+
1657
+ Returns a new array containing only the elements that satisfy the attr condition
1658
+ (i.e. non-falsy values for attr)
1659
+ **Example:**
1660
+
1661
+ ```javascript
1662
+ import trutoJsonata from '@truto/truto-jsonata';
1663
+
1664
+ const data = [
1665
+ {active : false},
1666
+ {active: "" },
1667
+ {active: true },
1668
+ ];
1669
+ const otherData = [{ name: 'John' }]
1670
+ const expression = trutoJsonata("$find(data, 'active')");
1671
+ const otherExpression = trutoJsonata("$find(otherData, 'name')");
1672
+ expression.evaluate({ data }).then(result => { console.log(result); });
1673
+ otherExpression.evaluate({ otherData }).then(result => { console.log(result); });
1674
+ /* Output:
1675
+ {
1676
+ active: true,
1677
+ }
1678
+ {
1679
+ name: "John",
1680
+ }
1681
+ */
1682
+ ```
1683
+
1684
+ </details>
1685
+
1686
+ <details>
1687
+ <summary>lofilter(collection, predicate)</summary>
1688
+
1689
+ Filters the collection based on the `predicate`
1690
+
1691
+ **Example:**
1692
+
1693
+ ```javascript
1694
+ import trutoJsonata from '@truto/truto-jsonata';
1695
+
1696
+ const data = [
1697
+ {active : false},
1698
+ {active: "" },
1699
+ {active: true },
1700
+ ];
1701
+ const otherData = [{ name: 'John' }]
1702
+ const expression = trutoJsonata("$lofilter(data, 'active')");
1703
+ const otherExpression = trutoJsonata("$lofilter(otherData, 'name')");
1704
+ expression.evaluate({ data }).then(result => { console.log(result); });
1705
+ otherExpression.evaluate({ otherData }).then(result => { console.log(result); });
1706
+ /*
1707
+ Output:
1708
+ [
1709
+ {
1710
+ active: true,
1711
+ }
1712
+ ]
1713
+ [
1714
+ {
1715
+ name: "John",
1716
+ }
1717
+ ]
1718
+ */
1719
+ ```
1720
+
1721
+ </details>
1722
+
1723
+ <details>
1724
+ <summary>values(object)</summary>
1725
+
1726
+ Returns an array of the object's own enumerable property values.
1727
+
1728
+ **Example:**
1729
+
1730
+ ```javascript
1731
+ import trutoJsonata from '@truto/truto-jsonata';
1732
+
1733
+ const data = { a: 1, b: 2, c: 3 };
1734
+ const expression = trutoJsonata("$values(data)");
1735
+ expression.evaluate({ data }).then(result => { console.log(result); });
1736
+ // Output: [1, 2, 3]
1737
+ ```
1738
+
1739
+ </details>
1740
+
1741
+ ---
1742
+
1743
+ ### Parsing and URL Functions
1744
+
1745
+ <details>
1746
+ <summary>parseUrl(urlString)</summary>
1747
+
1748
+ Parses a URL string and returns a [URL object](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL)
1749
+
1750
+ **Example:**
1751
+
1752
+ ```javascript
1753
+ import trutoJsonata from '@truto/truto-jsonata';
1754
+
1755
+ const data = 'https://example.com/path?query=123#hash';
1756
+ const expression = trutoJsonata("$parseUrl(data)");
1757
+ expression.evaluate({ data }).then(result => { console.log(result); });
1758
+ /*
1759
+ Output:
1760
+ URL {
1761
+ href: "https://example.com/path?query=123#hash",
1762
+ origin: "https://example.com",
1763
+ protocol: "https:",
1764
+ username: "",
1765
+ password: "",
1766
+ host: "example.com",
1767
+ hostname: "example.com",
1768
+ port: "",
1769
+ pathname: "/path",
1770
+ hash: "#hash",
1771
+ search: "?query=123",
1772
+ searchParams: URLSearchParams {
1773
+ "query": "123",
1774
+ },
1775
+ toJSON: [Function: toJSON],
1776
+ toString: [Function: toString],
1777
+ }
1778
+ */
1779
+ ```
1780
+
1781
+ </details>
1782
+
1783
+ ---
1784
+
1785
+ ### Miscellaneous
1786
+
1787
+ <details>
1788
+ <summary>mostSimilar(value, possibleValues, threshold = 0.8)</summary>
1789
+
1790
+ Finds the most similar string from a list of possible values based on the Dice Coefficient similarity score. If the similarity exceeds the threshold, the closest match is returned.
1791
+
1792
+ **Parameters:**
1793
+
1794
+ - **value**: The input string for which to find a similar match.
1795
+ - **possibleValues**: An array of strings to compare against the input.
1796
+ - **threshold**: A minimum similarity score (default is `0.8`), above which the closest match is returned.
1797
+
1798
+ **Example Usage:**
1799
+
1800
+ ```javascript
1801
+ import trutoJsonata from '@truto/truto-jsonata';
1802
+
1803
+ // Define input and possible values
1804
+ const input = 'appl';
1805
+ const possibleValues = ['apple', 'apricot', 'banana'];
1806
+ const threshold = 0.8;
1807
+ // Use mostSimilar to find the closest match
1808
+ const expression = trutoJsonata("$mostSimilar(input, possibleValues, threshold)");
1809
+ expression.evaluate({ input, possibleValues, threshold }).then(result => { console.log(result); });
1810
+ // Output: 'apple' (since 'apple' is the most similar to 'appl' and exceeds the similarity threshold)
1811
+ ```
1812
+
1813
+ </details>
1814
+
1815
+ <details>
1816
+ <summary>sortNodes(array, idKey = 'id',
1817
+ parentIdKey = 'parent_id',
1818
+ sequenceKey = 'sequence')</summary>
1819
+
1820
+ Sorts a flat list of nodes into a hierarchical, parent-child structure based on `parent_id`, then sorts nodes by a specified sequence key, and finally flattens the sorted structure.
1821
+
1822
+ **Parameters:**
1823
+
1824
+ - **array**: An array of node objects to be sorted.
1825
+ - **idKey**: The key for the node's unique identifier (default is `"id"`).
1826
+ - **parentIdKey**: The key for the node's parent identifier (default is `"parent_id"`).
1827
+ - **sequenceKey**: The key used to sort nodes within each hierarchy level (default is `"sequence"`).
1828
+
1829
+ **Node Structure:**
1830
+
1831
+ Each node should follow this format:
1832
+
1833
+ ```typescript
1834
+ {
1835
+ id: string | number,
1836
+ parent_id?: string | number | null,
1837
+ sequence: number,
1838
+ }
1839
+ ```
1840
+
1841
+ **Example Usage:**
1842
+
1843
+ ```javascript
1844
+ import trutoJsonata from '@truto/truto-jsonata';
1845
+
1846
+ // Example 1: Basic Parent-Child Structure with Root Nodes
1847
+ const nodes1 = [
1848
+ { id: 1, sequence: 1 },
1849
+ { id: 2, parent_id: 1, sequence: 2 },
1850
+ { id: 3, sequence: 3 },
1851
+ { id: 4, parent_id: 1, sequence: 1 }
1852
+ ];
1853
+ const expression1 = trutoJsonata("$sortNodes(nodes)");
1854
+ expression1.evaluate({ nodes: nodes1 }).then(result => {
1855
+ console.log(result);
1856
+ /*
1857
+ Output:
1858
+ [
1859
+ { id: 1, sequence: 1 },
1860
+ { id: 4, parent_id: 1, sequence: 1 },
1861
+ { id: 2, parent_id: 1, sequence: 2 },
1862
+ { id: 3, sequence: 3 }
1863
+ ]
1864
+ */
1865
+ });
1866
+
1867
+ // Example 2: Multiple Root Nodes with Nested Children, Custom Sequence
1868
+ const nodes2 = [
1869
+ { uniqueId: 1, seqNumber: 2 },
1870
+ { uniqueId: 2, parentUniqueId: 1, seqNumber: 1 },
1871
+ { uniqueId: 3, seqNumber: 1 },
1872
+ { uniqueId: 4, parentUniqueId: 3, seqNumber: 2 },
1873
+ { uniqueId: 5, parentUniqueId: 3, seqNumber: 1 }
1874
+ ];
1875
+ const options2 = { idKey: 'uniqueId', parentIdKey: 'parentUniqueId', sequenceKey: 'seqNumber' };
1876
+ const expression2 = trutoJsonata("$sortNodes(nodes, idKey, parentIdKey, sequenceKey)");
1877
+ expression2.evaluate({ nodes: nodes2, ...options2 }).then(result => {
1878
+ console.log(result);
1879
+ /*
1880
+ Output:
1881
+ [
1882
+ { uniqueId: 3, seqNumber: 1 },
1883
+ { uniqueId: 5, parentUniqueId: 3, seqNumber: 1 },
1884
+ { uniqueId: 4, parentUniqueId: 3, seqNumber: 2 },
1885
+ { uniqueId: 1, seqNumber: 2 },
1886
+ { uniqueId: 2, parentUniqueId: 1, seqNumber: 1 }
1887
+ ]
1888
+ */
1889
+ });
1890
+ ```
1891
+
1892
+ </details>
1893
+
1894
+ <details>
1895
+ <summary>wrap(value, wrapper, endWrapper)</summary>
1896
+
1897
+ Wraps `value` with `wrapper` and `endWrapper` (if provided). If `endWrapper` is not provided, `wrapper` is used for both ends.
1898
+
1899
+ **Example:**
1900
+
1901
+ ```javascript
1902
+ import trutoJsonata from '@truto/truto-jsonata';
1903
+
1904
+ const expression = trutoJsonata("$wrap('content', '<div>', '</div>')");
1905
+ expression.evaluate({}).then(result => { console.log(result); });
1906
+ // Output: '<div>content</div>'
1907
+ ```
1908
+
1909
+ </details>
1910
+
1911
+ <details>
1912
+ <summary>base64encode(input)</summary>
1913
+
1914
+ Encodes the input data in Base64.
1915
+
1916
+ **Example:**
1917
+
1918
+ ```javascript
1919
+ import trutoJsonata from '@truto/truto-jsonata';
1920
+
1921
+ const expression = trutoJsonata("$base64encode('Hello, World!')");
1922
+ expression.evaluate({}).then(result => { console.log(result); });
1923
+ // Output: 'SGVsbG8sIFdvcmxkIQ=='
1924
+ ```
1925
+
1926
+ </details>
1927
+
1928
+ <details>
1929
+ <summary>base64decode(base64String)</summary>
1930
+
1931
+ Decodes a Base64-encoded string.
1932
+
1933
+ **Example:**
1934
+
1935
+ ```javascript
1936
+ import trutoJsonata from '@truto/truto-jsonata';
4
1937
 
5
- ## Requires
1938
+ const expression = trutoJsonata("$base64decode('SGVsbG8sIFdvcmxkIQ==')");
1939
+ expression.evaluate({}).then(result => { console.log(result); });
1940
+ // Output: 'Hello, World!'
1941
+ ```
6
1942
 
7
- NodeJS 22+
1943
+ </details>