@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 +1939 -3
- package/dist/main.cjs +2 -2
- package/dist/main.cjs.map +1 -1
- package/dist/module.js +2 -2
- package/dist/module.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,1943 @@
|
|
|
1
|
+
|
|
1
2
|
# truto-jsonata
|
|
2
3
|
|
|
3
|
-
`truto-jsonata` is a TypeScript/JavaScript 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
|
-
|
|
1938
|
+
const expression = trutoJsonata("$base64decode('SGVsbG8sIFdvcmxkIQ==')");
|
|
1939
|
+
expression.evaluate({}).then(result => { console.log(result); });
|
|
1940
|
+
// Output: 'Hello, World!'
|
|
1941
|
+
```
|
|
6
1942
|
|
|
7
|
-
|
|
1943
|
+
</details>
|