@n8n/expression-runtime 0.2.0 → 0.3.0
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/ARCHITECTURE.md +5 -6
- package/LICENSE_EE.md +27 -0
- package/README.md +8 -8
- package/dist/bridge/isolated-vm-bridge.d.ts +132 -0
- package/dist/bridge/isolated-vm-bridge.d.ts.map +1 -0
- package/dist/bridge/isolated-vm-bridge.js +427 -0
- package/dist/bridge/isolated-vm-bridge.js.map +1 -0
- package/dist/build.tsbuildinfo +1 -1
- package/dist/bundle/runtime.esm.js +45 -0
- package/dist/bundle/runtime.esm.js.map +7 -0
- package/dist/bundle/runtime.iife.js +45 -0
- package/dist/bundle/runtime.iife.js.map +7 -0
- package/dist/extensions/array-extensions.d.ts +34 -0
- package/dist/extensions/array-extensions.d.ts.map +1 -0
- package/dist/extensions/array-extensions.js +610 -0
- package/dist/extensions/array-extensions.js.map +1 -0
- package/dist/extensions/boolean-extensions.d.ts +6 -0
- package/dist/extensions/boolean-extensions.d.ts.map +1 -0
- package/dist/extensions/boolean-extensions.js +33 -0
- package/dist/extensions/boolean-extensions.js.map +1 -0
- package/dist/extensions/date-extensions.d.ts +3 -0
- package/dist/extensions/date-extensions.d.ts.map +1 -0
- package/dist/extensions/date-extensions.js +515 -0
- package/dist/extensions/date-extensions.js.map +1 -0
- package/dist/extensions/expression-extension-error.d.ts +7 -0
- package/dist/extensions/expression-extension-error.d.ts.map +1 -0
- package/dist/extensions/expression-extension-error.js +11 -0
- package/dist/extensions/expression-extension-error.js.map +1 -0
- package/dist/extensions/extend.d.ts +12 -0
- package/dist/extensions/extend.d.ts.map +1 -0
- package/dist/extensions/extend.js +134 -0
- package/dist/extensions/extend.js.map +1 -0
- package/dist/extensions/extensions.d.ts +43 -0
- package/dist/extensions/extensions.d.ts.map +1 -0
- package/dist/extensions/extensions.js +2 -0
- package/dist/extensions/extensions.js.map +1 -0
- package/dist/extensions/number-extensions.d.ts +27 -0
- package/dist/extensions/number-extensions.d.ts.map +1 -0
- package/dist/extensions/number-extensions.js +221 -0
- package/dist/extensions/number-extensions.js.map +1 -0
- package/dist/extensions/object-extensions.d.ts +46 -0
- package/dist/extensions/object-extensions.d.ts.map +1 -0
- package/dist/extensions/object-extensions.js +277 -0
- package/dist/extensions/object-extensions.js.map +1 -0
- package/dist/extensions/string-extensions.d.ts +38 -0
- package/dist/extensions/string-extensions.d.ts.map +1 -0
- package/dist/extensions/string-extensions.js +735 -0
- package/dist/extensions/string-extensions.js.map +1 -0
- package/dist/extensions/utils.d.ts +4 -0
- package/dist/extensions/utils.d.ts.map +1 -0
- package/dist/extensions/utils.js +27 -0
- package/dist/extensions/utils.js.map +1 -0
- package/dist/runtime/index.d.ts +17 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +23 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/lazy-proxy.d.ts +18 -0
- package/dist/runtime/lazy-proxy.d.ts.map +1 -0
- package/dist/runtime/lazy-proxy.js +150 -0
- package/dist/runtime/lazy-proxy.js.map +1 -0
- package/dist/runtime/reset.d.ts +16 -0
- package/dist/runtime/reset.d.ts.map +1 -0
- package/dist/runtime/reset.js +124 -0
- package/dist/runtime/reset.js.map +1 -0
- package/dist/runtime/safe-globals.d.ts +21 -0
- package/dist/runtime/safe-globals.d.ts.map +1 -0
- package/dist/runtime/safe-globals.js +110 -0
- package/dist/runtime/safe-globals.js.map +1 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/runtime.d.ts +0 -102
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/runtime.js +0 -6
- package/dist/types/runtime.js.map +1 -1
- package/package.json +15 -3
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
import { toBase64, fromBase64 } from 'js-base64';
|
|
2
|
+
import SHA from 'jssha';
|
|
3
|
+
import { DateTime } from 'luxon';
|
|
4
|
+
import MD5 from 'md5';
|
|
5
|
+
import { titleCase } from 'title-case';
|
|
6
|
+
import { transliterate } from 'transliteration';
|
|
7
|
+
import { ExpressionExtensionError } from './expression-extension-error';
|
|
8
|
+
import { toDateTime as numberToDateTime } from './number-extensions';
|
|
9
|
+
export const SupportedHashAlgorithms = [
|
|
10
|
+
'md5',
|
|
11
|
+
'sha1',
|
|
12
|
+
'sha224',
|
|
13
|
+
'sha256',
|
|
14
|
+
'sha384',
|
|
15
|
+
'sha512',
|
|
16
|
+
'sha3',
|
|
17
|
+
];
|
|
18
|
+
// All symbols from https://www.xe.com/symbols/ as for 2022/11/09
|
|
19
|
+
const CURRENCY_REGEXP = /(\u004c\u0065\u006b|\u060b|\u0024|\u0192|\u20bc|\u0042\u0072|\u0042\u005a\u0024|\u0024\u0062|\u004b\u004d|\u0050|\u043b\u0432|\u0052\u0062|\u17db|\u00a5|\u20a1|\u006b\u006e|\u20b1|\u004b\u010d|\u006b\u0072|\u0052\u0044\u0024|\u00a3|\u20ac|\u00a2|\u0051|\u004c|\u0046\u0074|\u20b9|\u0052\u0070|\ufdfc|\u20aa|\u004a\u0024|\u20a9|\u20ad|\u0434\u0435\u043d|\u0052\u004d|\u20a8|\u20ae|\u004d\u0054|\u0043\u0024|\u20a6|\u0042\u002f\u002e|\u0047\u0073|\u0053\u002f\u002e|\u007a\u0142|\u006c\u0065\u0069|\u20bd|\u0414\u0438\u043d\u002e|\u0053|\u0052|\u0043\u0048\u0046|\u004e\u0054\u0024|\u0e3f|\u0054\u0054\u0024|\u20ba|\u20b4|\u0024\u0055|\u0042\u0073|\u20ab|\u005a\u0024)/gu;
|
|
20
|
+
const DOMAIN_EXTRACT_REGEXP = /^(?:(?:https?|ftp):\/\/)?(?:mailto:)?(?:\/\/)?((?:www\.)?(?:(?:[-\w]+\.)+(?:[a-zA-Z]{2,}|xn--[a-zA-Z0-9]+)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?(?:\/[^\s?]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/i;
|
|
21
|
+
const DOMAIN_REGEXP = /^(?:www\.)?((?:(?:[-\w]+\.)+(?:[a-zA-Z]{2,}|xn--[a-zA-Z0-9]+)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?(?:\/[^\s?]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/i;
|
|
22
|
+
const EMAIL_REGEXP = /(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@(?<domain>(\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;
|
|
23
|
+
const URL_REGEXP_EXACT = /^(?:(?:https?|ftp):\/\/)(?:www\.)?((?:(?:[-\w]+\.)+(?:[a-zA-Z]{2,}|xn--[a-zA-Z0-9]+)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?(?:\/[^\s?#]*)?(?:\?[^\s#]*)?(?=([^\s]+#.*)?)#?[^\s]*$/i;
|
|
24
|
+
const URL_REGEXP = /(?:(?:https?|ftp):\/\/)(?:www\.)?((?:(?:[-\w]+\.)+(?:[a-zA-Z]{2,}|xn--[a-zA-Z0-9]+)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?(?:\/[^\s?#]*)?(?:\?[^\s#]*)?(?=([^\s]+#.*)?)#?[^\s]*/i;
|
|
25
|
+
const CHAR_TEST_REGEXP = /\p{L}/u;
|
|
26
|
+
const PUNC_TEST_REGEXP = /[!?.]/;
|
|
27
|
+
/**
|
|
28
|
+
* Inline version of tryToParseDateTime from n8n-workflow/type-validation.ts
|
|
29
|
+
* Avoids circular dependency.
|
|
30
|
+
*/
|
|
31
|
+
function tryToParseDateTime(value, defaultZone) {
|
|
32
|
+
if (DateTime.isDateTime(value) && value.isValid) {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
if (value instanceof Date) {
|
|
36
|
+
const fromJSDate = DateTime.fromJSDate(value, { zone: defaultZone });
|
|
37
|
+
if (fromJSDate.isValid) {
|
|
38
|
+
return fromJSDate;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const dateString = String(value).trim();
|
|
42
|
+
const isoDate = DateTime.fromISO(dateString, { zone: defaultZone, setZone: true });
|
|
43
|
+
if (isoDate.isValid) {
|
|
44
|
+
return isoDate;
|
|
45
|
+
}
|
|
46
|
+
const httpDate = DateTime.fromHTTP(dateString, { zone: defaultZone, setZone: true });
|
|
47
|
+
if (httpDate.isValid) {
|
|
48
|
+
return httpDate;
|
|
49
|
+
}
|
|
50
|
+
const rfc2822Date = DateTime.fromRFC2822(dateString, { zone: defaultZone, setZone: true });
|
|
51
|
+
if (rfc2822Date.isValid) {
|
|
52
|
+
return rfc2822Date;
|
|
53
|
+
}
|
|
54
|
+
const sqlDate = DateTime.fromSQL(dateString, { zone: defaultZone, setZone: true });
|
|
55
|
+
if (sqlDate.isValid) {
|
|
56
|
+
return sqlDate;
|
|
57
|
+
}
|
|
58
|
+
const parsedDateTime = DateTime.fromMillis(Date.parse(dateString), { zone: defaultZone });
|
|
59
|
+
if (parsedDateTime.isValid) {
|
|
60
|
+
return parsedDateTime;
|
|
61
|
+
}
|
|
62
|
+
throw new ExpressionExtensionError('Value is not a valid date');
|
|
63
|
+
}
|
|
64
|
+
function hash(value, extraArgs) {
|
|
65
|
+
const algorithm = extraArgs[0]?.toLowerCase() ?? 'md5';
|
|
66
|
+
switch (algorithm) {
|
|
67
|
+
case 'base64':
|
|
68
|
+
return toBase64(value);
|
|
69
|
+
case 'md5':
|
|
70
|
+
return MD5(value);
|
|
71
|
+
case 'sha1':
|
|
72
|
+
case 'sha224':
|
|
73
|
+
case 'sha256':
|
|
74
|
+
case 'sha384':
|
|
75
|
+
case 'sha512':
|
|
76
|
+
case 'sha3':
|
|
77
|
+
const variant = {
|
|
78
|
+
sha1: 'SHA-1',
|
|
79
|
+
sha224: 'SHA-224',
|
|
80
|
+
sha256: 'SHA-256',
|
|
81
|
+
sha384: 'SHA-384',
|
|
82
|
+
sha512: 'SHA-512',
|
|
83
|
+
sha3: 'SHA3-512',
|
|
84
|
+
}[algorithm];
|
|
85
|
+
return new SHA(variant, 'TEXT').update(value).getHash('HEX');
|
|
86
|
+
default:
|
|
87
|
+
throw new ExpressionExtensionError(`Unknown algorithm ${algorithm}. Available algorithms are: ${SupportedHashAlgorithms.join()}, and Base64.`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function isEmpty(value) {
|
|
91
|
+
return value === '';
|
|
92
|
+
}
|
|
93
|
+
function isNotEmpty(value) {
|
|
94
|
+
return !isEmpty(value);
|
|
95
|
+
}
|
|
96
|
+
function length(value) {
|
|
97
|
+
return value.length;
|
|
98
|
+
}
|
|
99
|
+
export function toJsonString(value) {
|
|
100
|
+
return JSON.stringify(value);
|
|
101
|
+
}
|
|
102
|
+
function removeMarkdown(value) {
|
|
103
|
+
let output = value;
|
|
104
|
+
try {
|
|
105
|
+
output = output.replace(/^([\s\t]*)([*\-+]|\d\.)\s+/gm, '$1');
|
|
106
|
+
output = output
|
|
107
|
+
// Header
|
|
108
|
+
.replace(/\n={2,}/g, '\n')
|
|
109
|
+
// Strikethrough
|
|
110
|
+
.replace(/~~/g, '')
|
|
111
|
+
// Fenced codeblocks
|
|
112
|
+
.replace(/`{3}.*\n/g, '');
|
|
113
|
+
output = output
|
|
114
|
+
// Remove HTML tags
|
|
115
|
+
.replace(/<[\w|\s|=|'|"|:|(|)|,|;|/|0-9|.|-]+[>|\\>]/g, '')
|
|
116
|
+
// Remove setext-style headers
|
|
117
|
+
.replace(/^[=-]{2,}\s*$/g, '')
|
|
118
|
+
// Remove footnotes?
|
|
119
|
+
.replace(/\[\^.+?\](: .*?$)?/g, '')
|
|
120
|
+
.replace(/\s{0,2}\[.*?\]: .*?$/g, '')
|
|
121
|
+
// Remove images
|
|
122
|
+
.replace(/!\[.*?\][[(].*?[\])]/g, '')
|
|
123
|
+
// Remove inline links
|
|
124
|
+
.replace(/\[(.*?)\][[(].*?[\])]/g, '$1')
|
|
125
|
+
// Remove Blockquotes
|
|
126
|
+
.replace(/>/g, '')
|
|
127
|
+
// Remove reference-style links?
|
|
128
|
+
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '')
|
|
129
|
+
// Remove atx-style headers
|
|
130
|
+
.replace(/^#{1,6}\s*([^#]*)\s*(#{1,6})?/gm, '$1')
|
|
131
|
+
.replace(/([*_]{1,3})(\S.*?\S)\1/g, '$2')
|
|
132
|
+
.replace(/(`{3,})(.*?)\1/gm, '$2')
|
|
133
|
+
.replace(/^-{3,}\s*$/g, '')
|
|
134
|
+
.replace(/`(.+?)`/g, '$1')
|
|
135
|
+
.replace(/\n{2,}/g, '\n\n');
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
return output;
|
|
141
|
+
}
|
|
142
|
+
function removeTags(value) {
|
|
143
|
+
return value.replace(/<[^>]*>?/gm, '');
|
|
144
|
+
}
|
|
145
|
+
function toDate(value) {
|
|
146
|
+
const date = new Date(Date.parse(value));
|
|
147
|
+
if (date.toString() === 'Invalid Date') {
|
|
148
|
+
throw new ExpressionExtensionError('cannot convert to date');
|
|
149
|
+
}
|
|
150
|
+
// If time component is not specified, force 00:00h
|
|
151
|
+
if (!/:/.test(value)) {
|
|
152
|
+
date.setHours(0, 0, 0);
|
|
153
|
+
}
|
|
154
|
+
return date;
|
|
155
|
+
}
|
|
156
|
+
export function toDateTime(value, extraArgs = ['']) {
|
|
157
|
+
try {
|
|
158
|
+
const [valueFormat] = extraArgs;
|
|
159
|
+
if (valueFormat) {
|
|
160
|
+
if (valueFormat === 'ms' ||
|
|
161
|
+
valueFormat === 's' ||
|
|
162
|
+
valueFormat === 'us' ||
|
|
163
|
+
valueFormat === 'excel') {
|
|
164
|
+
return numberToDateTime(Number(value), [valueFormat]);
|
|
165
|
+
}
|
|
166
|
+
return DateTime.fromFormat(value, valueFormat);
|
|
167
|
+
}
|
|
168
|
+
return tryToParseDateTime(value);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw new ExpressionExtensionError('cannot convert to Luxon DateTime');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function urlDecode(value, extraArgs) {
|
|
175
|
+
const [entireString = false] = extraArgs;
|
|
176
|
+
if (entireString) {
|
|
177
|
+
return decodeURI(value.toString());
|
|
178
|
+
}
|
|
179
|
+
return decodeURIComponent(value.toString());
|
|
180
|
+
}
|
|
181
|
+
function urlEncode(value, extraArgs) {
|
|
182
|
+
const [entireString = false] = extraArgs;
|
|
183
|
+
if (entireString) {
|
|
184
|
+
return encodeURI(value.toString());
|
|
185
|
+
}
|
|
186
|
+
return encodeURIComponent(value.toString());
|
|
187
|
+
}
|
|
188
|
+
function toInt(value, extraArgs) {
|
|
189
|
+
const [radix] = extraArgs;
|
|
190
|
+
const int = parseInt(value.replace(CURRENCY_REGEXP, ''), radix);
|
|
191
|
+
if (isNaN(int)) {
|
|
192
|
+
throw new ExpressionExtensionError('cannot convert to integer');
|
|
193
|
+
}
|
|
194
|
+
return int;
|
|
195
|
+
}
|
|
196
|
+
function toFloat(value) {
|
|
197
|
+
if (value.includes(',')) {
|
|
198
|
+
throw new ExpressionExtensionError('cannot convert to float, expected . as decimal separator');
|
|
199
|
+
}
|
|
200
|
+
const float = parseFloat(value.replace(CURRENCY_REGEXP, ''));
|
|
201
|
+
if (isNaN(float)) {
|
|
202
|
+
throw new ExpressionExtensionError('cannot convert to float');
|
|
203
|
+
}
|
|
204
|
+
return float;
|
|
205
|
+
}
|
|
206
|
+
function toNumber(value) {
|
|
207
|
+
const num = Number(value.replace(CURRENCY_REGEXP, ''));
|
|
208
|
+
if (isNaN(num)) {
|
|
209
|
+
throw new ExpressionExtensionError('cannot convert to number');
|
|
210
|
+
}
|
|
211
|
+
return num;
|
|
212
|
+
}
|
|
213
|
+
function quote(value, extraArgs) {
|
|
214
|
+
const [quoteChar = '"'] = extraArgs;
|
|
215
|
+
return `${quoteChar}${value
|
|
216
|
+
.replace(/\\/g, '\\\\')
|
|
217
|
+
.replace(new RegExp(`\\${quoteChar}`, 'g'), `\\${quoteChar}`)}${quoteChar}`;
|
|
218
|
+
}
|
|
219
|
+
function isNumeric(value) {
|
|
220
|
+
if (value.includes(' '))
|
|
221
|
+
return false;
|
|
222
|
+
return !isNaN(value) && !isNaN(parseFloat(value));
|
|
223
|
+
}
|
|
224
|
+
function isUrl(value) {
|
|
225
|
+
return URL_REGEXP_EXACT.test(value);
|
|
226
|
+
}
|
|
227
|
+
function isDomain(value) {
|
|
228
|
+
return DOMAIN_REGEXP.test(value);
|
|
229
|
+
}
|
|
230
|
+
function isEmail(value) {
|
|
231
|
+
const result = EMAIL_REGEXP.test(value);
|
|
232
|
+
// email regex is loose so check manually for now
|
|
233
|
+
if (result && value.includes(' ')) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
function toTitleCase(value) {
|
|
239
|
+
return titleCase(value);
|
|
240
|
+
}
|
|
241
|
+
function replaceSpecialChars(value) {
|
|
242
|
+
return transliterate(value, { unknown: '?' });
|
|
243
|
+
}
|
|
244
|
+
function toSentenceCase(value) {
|
|
245
|
+
let current = value.slice();
|
|
246
|
+
let buffer = '';
|
|
247
|
+
while (CHAR_TEST_REGEXP.test(current)) {
|
|
248
|
+
const charIndex = current.search(CHAR_TEST_REGEXP);
|
|
249
|
+
current =
|
|
250
|
+
current.slice(0, charIndex) +
|
|
251
|
+
current[charIndex].toLocaleUpperCase() +
|
|
252
|
+
current.slice(charIndex + 1).toLocaleLowerCase();
|
|
253
|
+
const puncIndex = current.search(PUNC_TEST_REGEXP);
|
|
254
|
+
if (puncIndex === -1) {
|
|
255
|
+
buffer += current;
|
|
256
|
+
current = '';
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
buffer += current.slice(0, puncIndex + 1);
|
|
260
|
+
current = current.slice(puncIndex + 1);
|
|
261
|
+
}
|
|
262
|
+
return buffer;
|
|
263
|
+
}
|
|
264
|
+
function toSnakeCase(value) {
|
|
265
|
+
return value
|
|
266
|
+
.toLocaleLowerCase()
|
|
267
|
+
.replace(/[ \-]/g, '_')
|
|
268
|
+
.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,.\/:;<=>?@\[\]^`{|}~]/g, '');
|
|
269
|
+
}
|
|
270
|
+
function extractEmail(value) {
|
|
271
|
+
const matched = EMAIL_REGEXP.exec(value);
|
|
272
|
+
if (!matched) {
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
return matched[0];
|
|
276
|
+
}
|
|
277
|
+
function extractDomain(value) {
|
|
278
|
+
if (isEmail(value)) {
|
|
279
|
+
const matched = EMAIL_REGEXP.exec(value);
|
|
280
|
+
// This shouldn't happen
|
|
281
|
+
if (!matched) {
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
return matched.groups?.domain;
|
|
285
|
+
}
|
|
286
|
+
const domainMatch = value.match(DOMAIN_EXTRACT_REGEXP);
|
|
287
|
+
if (domainMatch) {
|
|
288
|
+
return domainMatch[1];
|
|
289
|
+
}
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
function extractUrl(value) {
|
|
293
|
+
const matched = URL_REGEXP.exec(value);
|
|
294
|
+
if (!matched) {
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
return matched[0];
|
|
298
|
+
}
|
|
299
|
+
function extractUrlPath(value) {
|
|
300
|
+
try {
|
|
301
|
+
const url = new URL(value);
|
|
302
|
+
return url.pathname;
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
return undefined;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function parseJson(value) {
|
|
309
|
+
try {
|
|
310
|
+
return JSON.parse(value);
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
if (value.includes("'")) {
|
|
314
|
+
throw new ExpressionExtensionError("Parsing failed. Check you're using double quotes");
|
|
315
|
+
}
|
|
316
|
+
throw new ExpressionExtensionError('Parsing failed');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function toBoolean(value) {
|
|
320
|
+
const normalized = value.toLowerCase();
|
|
321
|
+
const FALSY = new Set(['false', 'no', '0']);
|
|
322
|
+
return normalized.length > 0 && !FALSY.has(normalized);
|
|
323
|
+
}
|
|
324
|
+
function base64Encode(value) {
|
|
325
|
+
return toBase64(value);
|
|
326
|
+
}
|
|
327
|
+
function base64Decode(value) {
|
|
328
|
+
return fromBase64(value);
|
|
329
|
+
}
|
|
330
|
+
removeMarkdown.doc = {
|
|
331
|
+
name: 'removeMarkdown',
|
|
332
|
+
description: 'Removes any Markdown formatting from the string. Also removes HTML tags.',
|
|
333
|
+
section: 'edit',
|
|
334
|
+
returnType: 'string',
|
|
335
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-removeMarkdown',
|
|
336
|
+
examples: [{ example: '"*bold*, [link]()".removeMarkdown()', evaluated: '"bold, link"' }],
|
|
337
|
+
};
|
|
338
|
+
removeTags.doc = {
|
|
339
|
+
name: 'removeTags',
|
|
340
|
+
description: 'Removes tags, such as HTML or XML, from the string.',
|
|
341
|
+
section: 'edit',
|
|
342
|
+
returnType: 'string',
|
|
343
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-removeTags',
|
|
344
|
+
examples: [{ example: '"<b>bold</b>, <a>link</a>".removeTags()', evaluated: '"bold, link"' }],
|
|
345
|
+
};
|
|
346
|
+
toDate.doc = {
|
|
347
|
+
name: 'toDate',
|
|
348
|
+
description: 'Converts a string to a date.',
|
|
349
|
+
section: 'cast',
|
|
350
|
+
returnType: 'Date',
|
|
351
|
+
hidden: true,
|
|
352
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toDate',
|
|
353
|
+
};
|
|
354
|
+
toDateTime.doc = {
|
|
355
|
+
name: 'toDateTime',
|
|
356
|
+
description: 'Converts the string to a <a target="_blank" href="https://moment.github.io/luxon/api-docs/">Luxon</a> DateTime. Useful for further transformation. Supported formats for the string are ISO 8601, HTTP, RFC2822, SQL and Unix timestamp in milliseconds. To parse other formats, use <a target="_blank" href="https://moment.github.io/luxon/api-docs/index.html#datetimefromformat"> <code>DateTime.fromFormat()</code></a>.',
|
|
357
|
+
section: 'cast',
|
|
358
|
+
returnType: 'DateTime',
|
|
359
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toDateTime',
|
|
360
|
+
examples: [
|
|
361
|
+
{ example: '"2024-03-29T18:06:31.798+01:00".toDateTime()' },
|
|
362
|
+
{ example: '"Fri, 29 Mar 2024 18:08:01 +0100".toDateTime()' },
|
|
363
|
+
{ example: '"20240329".toDateTime()' },
|
|
364
|
+
{ example: '"1711732132990".toDateTime("ms")' },
|
|
365
|
+
{ example: '"31-01-2024".toDateTime("dd-MM-yyyy")' },
|
|
366
|
+
],
|
|
367
|
+
args: [
|
|
368
|
+
{
|
|
369
|
+
name: 'format',
|
|
370
|
+
optional: true,
|
|
371
|
+
description: 'The format of the date string. Options are <code>ms</code> (for Unix timestamp in milliseconds), <code>s</code> (for Unix timestamp in seconds), <code>us</code> (for Unix timestamp in microseconds) or <code>excel</code> (for days since 1900). Custom formats can be specified using <a href="https://moment.github.io/luxon/#/formatting?id=table-of-tokens">Luxon tokens</a>.',
|
|
372
|
+
type: 'string',
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
};
|
|
376
|
+
toBoolean.doc = {
|
|
377
|
+
name: 'toBoolean',
|
|
378
|
+
description: 'Converts the string to a boolean value. <code>0</code>, <code>false</code> and <code>no</code> resolve to <code>false</code>, everything else to <code>true</code>. Case-insensitive.',
|
|
379
|
+
section: 'cast',
|
|
380
|
+
returnType: 'boolean',
|
|
381
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toBoolean',
|
|
382
|
+
examples: [
|
|
383
|
+
{ example: '"true".toBoolean()', evaluated: 'true' },
|
|
384
|
+
{ example: '"false".toBoolean()', evaluated: 'false' },
|
|
385
|
+
{ example: '"0".toBoolean()', evaluated: 'false' },
|
|
386
|
+
{ example: '"hello".toBoolean()', evaluated: 'true' },
|
|
387
|
+
],
|
|
388
|
+
};
|
|
389
|
+
toFloat.doc = {
|
|
390
|
+
name: 'toFloat',
|
|
391
|
+
description: 'Converts a string to a decimal number.',
|
|
392
|
+
section: 'cast',
|
|
393
|
+
returnType: 'number',
|
|
394
|
+
aliases: ['toDecimalNumber'],
|
|
395
|
+
hidden: true,
|
|
396
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toDecimalNumber',
|
|
397
|
+
};
|
|
398
|
+
toInt.doc = {
|
|
399
|
+
name: 'toInt',
|
|
400
|
+
description: 'Converts a string to an integer.',
|
|
401
|
+
section: 'cast',
|
|
402
|
+
returnType: 'number',
|
|
403
|
+
args: [{ name: 'radix?', type: 'number' }],
|
|
404
|
+
aliases: ['toWholeNumber'],
|
|
405
|
+
hidden: true,
|
|
406
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toInt',
|
|
407
|
+
};
|
|
408
|
+
toSentenceCase.doc = {
|
|
409
|
+
name: 'toSentenceCase',
|
|
410
|
+
description: 'Changes the capitalization of the string to sentence case. The first letter of each sentence is capitalized and all others are lowercased.',
|
|
411
|
+
examples: [{ example: '"quick! brown FOX".toSentenceCase()', evaluated: '"Quick! Brown fox"' }],
|
|
412
|
+
section: 'case',
|
|
413
|
+
returnType: 'string',
|
|
414
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toSentenceCase',
|
|
415
|
+
};
|
|
416
|
+
toSnakeCase.doc = {
|
|
417
|
+
name: 'toSnakeCase',
|
|
418
|
+
description: 'Changes the format of the string to snake case. Spaces and dashes are replaced by <code>_</code>, symbols are removed and all letters are lowercased.',
|
|
419
|
+
examples: [{ example: '"quick brown $FOX".toSnakeCase()', evaluated: '"quick_brown_fox"' }],
|
|
420
|
+
section: 'case',
|
|
421
|
+
returnType: 'string',
|
|
422
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toSnakeCase',
|
|
423
|
+
};
|
|
424
|
+
toTitleCase.doc = {
|
|
425
|
+
name: 'toTitleCase',
|
|
426
|
+
description: "Changes the capitalization of the string to title case. The first letter of each word is capitalized and the others left unchanged. Short prepositions and conjunctions aren't capitalized (e.g. 'a', 'the').",
|
|
427
|
+
examples: [{ example: '"quick a brown FOX".toTitleCase()', evaluated: '"Quick a Brown Fox"' }],
|
|
428
|
+
section: 'case',
|
|
429
|
+
returnType: 'string',
|
|
430
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toTitleCase',
|
|
431
|
+
};
|
|
432
|
+
urlEncode.doc = {
|
|
433
|
+
name: 'urlEncode',
|
|
434
|
+
description: 'Encodes the string so that it can be used in a URL. Spaces and special characters are replaced with codes of the form <code>%XX</code>.',
|
|
435
|
+
section: 'edit',
|
|
436
|
+
args: [
|
|
437
|
+
{
|
|
438
|
+
name: 'allChars',
|
|
439
|
+
optional: true,
|
|
440
|
+
description: 'Whether to encode characters that are part of the URI syntax (e.g. <code>=</code>, <code>?</code>)',
|
|
441
|
+
default: 'false',
|
|
442
|
+
type: 'boolean',
|
|
443
|
+
},
|
|
444
|
+
],
|
|
445
|
+
returnType: 'string',
|
|
446
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-urlEncode',
|
|
447
|
+
examples: [
|
|
448
|
+
{ example: '"name=Nathan Automat".urlEncode()', evaluated: '"name%3DNathan%20Automat"' },
|
|
449
|
+
{ example: '"name=Nathan Automat".urlEncode(true)', evaluated: '"name=Nathan%20Automat"' },
|
|
450
|
+
],
|
|
451
|
+
};
|
|
452
|
+
urlDecode.doc = {
|
|
453
|
+
name: 'urlDecode',
|
|
454
|
+
description: 'Decodes a URL-encoded string. Replaces any character codes in the form of <code>%XX</code> with their corresponding characters.',
|
|
455
|
+
args: [
|
|
456
|
+
{
|
|
457
|
+
name: 'allChars',
|
|
458
|
+
optional: true,
|
|
459
|
+
description: 'Whether to decode characters that are part of the URI syntax (e.g. <code>=</code>, <code>?</code>)',
|
|
460
|
+
default: 'false',
|
|
461
|
+
type: 'boolean',
|
|
462
|
+
},
|
|
463
|
+
],
|
|
464
|
+
section: 'edit',
|
|
465
|
+
returnType: 'string',
|
|
466
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-urlDecode',
|
|
467
|
+
examples: [
|
|
468
|
+
{ example: '"name%3DNathan%20Automat".urlDecode()', evaluated: '"name=Nathan Automat"' },
|
|
469
|
+
{ example: '"name%3DNathan%20Automat".urlDecode(true)', evaluated: '"name%3DNathan Automat"' },
|
|
470
|
+
],
|
|
471
|
+
};
|
|
472
|
+
replaceSpecialChars.doc = {
|
|
473
|
+
name: 'replaceSpecialChars',
|
|
474
|
+
description: 'Replaces special characters in the string with the closest ASCII character',
|
|
475
|
+
section: 'edit',
|
|
476
|
+
returnType: 'string',
|
|
477
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-replaceSpecialChars',
|
|
478
|
+
examples: [{ example: '"déjà".replaceSpecialChars()', evaluated: '"deja"' }],
|
|
479
|
+
};
|
|
480
|
+
length.doc = {
|
|
481
|
+
name: 'length',
|
|
482
|
+
section: 'query',
|
|
483
|
+
hidden: true,
|
|
484
|
+
description: 'Returns the character count of a string.',
|
|
485
|
+
returnType: 'number',
|
|
486
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings',
|
|
487
|
+
};
|
|
488
|
+
isDomain.doc = {
|
|
489
|
+
name: 'isDomain',
|
|
490
|
+
description: 'Returns <code>true</code> if a string is a domain.',
|
|
491
|
+
section: 'validation',
|
|
492
|
+
returnType: 'boolean',
|
|
493
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isDomain',
|
|
494
|
+
examples: [
|
|
495
|
+
{ example: '"n8n.io".isDomain()', evaluated: 'true' },
|
|
496
|
+
{ example: '"http://n8n.io".isDomain()', evaluated: 'false' },
|
|
497
|
+
{ example: '"hello".isDomain()', evaluated: 'false' },
|
|
498
|
+
],
|
|
499
|
+
};
|
|
500
|
+
isEmail.doc = {
|
|
501
|
+
name: 'isEmail',
|
|
502
|
+
description: 'Returns <code>true</code> if the string is an email.',
|
|
503
|
+
section: 'validation',
|
|
504
|
+
returnType: 'boolean',
|
|
505
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isEmail',
|
|
506
|
+
examples: [
|
|
507
|
+
{ example: '"me@example.com".isEmail()', evaluated: 'true' },
|
|
508
|
+
{ example: '"It\'s me@example.com".isEmail()', evaluated: 'false' },
|
|
509
|
+
{ example: '"hello".isEmail()', evaluated: 'false' },
|
|
510
|
+
],
|
|
511
|
+
};
|
|
512
|
+
isNumeric.doc = {
|
|
513
|
+
name: 'isNumeric',
|
|
514
|
+
description: 'Returns <code>true</code> if the string represents a number.',
|
|
515
|
+
section: 'validation',
|
|
516
|
+
returnType: 'boolean',
|
|
517
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isNumeric',
|
|
518
|
+
examples: [
|
|
519
|
+
{ example: '"1.2234".isNumeric()', evaluated: 'true' },
|
|
520
|
+
{ example: '"hello".isNumeric()', evaluated: 'false' },
|
|
521
|
+
{ example: '"123E23".isNumeric()', evaluated: 'true' },
|
|
522
|
+
],
|
|
523
|
+
};
|
|
524
|
+
isUrl.doc = {
|
|
525
|
+
name: 'isUrl',
|
|
526
|
+
description: 'Returns <code>true</code> if a string is a valid URL',
|
|
527
|
+
section: 'validation',
|
|
528
|
+
returnType: 'boolean',
|
|
529
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isUrl',
|
|
530
|
+
examples: [
|
|
531
|
+
{ example: '"https://n8n.io".isUrl()', evaluated: 'true' },
|
|
532
|
+
{ example: '"n8n.io".isUrl()', evaluated: 'false' },
|
|
533
|
+
{ example: '"hello".isUrl()', evaluated: 'false' },
|
|
534
|
+
],
|
|
535
|
+
};
|
|
536
|
+
isEmpty.doc = {
|
|
537
|
+
name: 'isEmpty',
|
|
538
|
+
description: 'Returns <code>true</code> if the string has no characters or is <code>null</code>',
|
|
539
|
+
section: 'validation',
|
|
540
|
+
returnType: 'boolean',
|
|
541
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isEmpty',
|
|
542
|
+
examples: [
|
|
543
|
+
{ example: '"".isEmpty()', evaluated: 'true' },
|
|
544
|
+
{ example: '"hello".isEmpty()', evaluated: 'false' },
|
|
545
|
+
],
|
|
546
|
+
};
|
|
547
|
+
isNotEmpty.doc = {
|
|
548
|
+
name: 'isNotEmpty',
|
|
549
|
+
description: 'Returns <code>true</code> if the string has at least one character.',
|
|
550
|
+
section: 'validation',
|
|
551
|
+
returnType: 'boolean',
|
|
552
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-isNotEmpty',
|
|
553
|
+
examples: [
|
|
554
|
+
{ example: '"hello".isNotEmpty()', evaluated: 'true' },
|
|
555
|
+
{ example: '"".isNotEmpty()', evaluated: 'false' },
|
|
556
|
+
],
|
|
557
|
+
};
|
|
558
|
+
toJsonString.doc = {
|
|
559
|
+
name: 'toJsonString',
|
|
560
|
+
description: "Prepares the string to be inserted into a JSON object. Escapes any quotes and special characters (e.g. new lines), and wraps the string in quotes.The same as JavaScript's JSON.stringify().",
|
|
561
|
+
section: 'edit',
|
|
562
|
+
returnType: 'string',
|
|
563
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toJsonString',
|
|
564
|
+
examples: [
|
|
565
|
+
{
|
|
566
|
+
example: 'The "best" colours: red\nbrown.toJsonString()',
|
|
567
|
+
evaluated: '"The \\"best\\" colours: red\\nbrown"',
|
|
568
|
+
},
|
|
569
|
+
{ example: 'foo.toJsonString()', evaluated: '"foo"' },
|
|
570
|
+
],
|
|
571
|
+
};
|
|
572
|
+
extractEmail.doc = {
|
|
573
|
+
name: 'extractEmail',
|
|
574
|
+
description: 'Extracts the first email found in the string. Returns <code>undefined</code> if none is found.',
|
|
575
|
+
section: 'edit',
|
|
576
|
+
returnType: 'string',
|
|
577
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-extractEmail',
|
|
578
|
+
examples: [
|
|
579
|
+
{ example: '"My email is me@example.com".extractEmail()', evaluated: "'me@example.com'" },
|
|
580
|
+
],
|
|
581
|
+
};
|
|
582
|
+
extractDomain.doc = {
|
|
583
|
+
name: 'extractDomain',
|
|
584
|
+
description: 'If the string is an email address or URL, returns its domain (or <code>undefined</code> if nothing found). If the string also contains other content, try using <code>extractEmail()</code> or <code>extractUrl()</code> first.',
|
|
585
|
+
section: 'edit',
|
|
586
|
+
returnType: 'string',
|
|
587
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-extractDomain',
|
|
588
|
+
examples: [
|
|
589
|
+
{ example: '"me@example.com".extractDomain()', evaluated: "'example.com'" },
|
|
590
|
+
{ example: '"http://n8n.io/workflows".extractDomain()', evaluated: "'n8n.io'" },
|
|
591
|
+
{
|
|
592
|
+
example: '"It\'s me@example.com".extractEmail().extractDomain()',
|
|
593
|
+
evaluated: "'example.com'",
|
|
594
|
+
},
|
|
595
|
+
],
|
|
596
|
+
};
|
|
597
|
+
extractUrl.doc = {
|
|
598
|
+
name: 'extractUrl',
|
|
599
|
+
description: 'Extracts the first URL found in the string. Returns <code>undefined</code> if none is found. Only recognizes full URLs, e.g. those starting with <code>http</code>.',
|
|
600
|
+
section: 'edit',
|
|
601
|
+
returnType: 'string',
|
|
602
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-extractUrl',
|
|
603
|
+
examples: [{ example: '"Check out http://n8n.io".extractUrl()', evaluated: "'http://n8n.io'" }],
|
|
604
|
+
};
|
|
605
|
+
extractUrlPath.doc = {
|
|
606
|
+
name: 'extractUrlPath',
|
|
607
|
+
description: 'Returns the part of a URL after the domain, or <code>undefined</code> if no URL found. If the string also contains other content, try using <code>extractUrl()</code> first.',
|
|
608
|
+
section: 'edit',
|
|
609
|
+
returnType: 'string',
|
|
610
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-extractUrlPath',
|
|
611
|
+
examples: [
|
|
612
|
+
{ example: '"http://n8n.io/workflows".extractUrlPath()', evaluated: "'/workflows'" },
|
|
613
|
+
{
|
|
614
|
+
example: '"Check out http://n8n.io/workflows".extractUrl().extractUrlPath()',
|
|
615
|
+
evaluated: "'/workflows'",
|
|
616
|
+
},
|
|
617
|
+
],
|
|
618
|
+
};
|
|
619
|
+
hash.doc = {
|
|
620
|
+
name: 'hash',
|
|
621
|
+
description: 'Returns the string hashed with the given algorithm. Defaults to md5 if not specified.',
|
|
622
|
+
section: 'edit',
|
|
623
|
+
returnType: 'string',
|
|
624
|
+
args: [
|
|
625
|
+
{
|
|
626
|
+
name: 'algo',
|
|
627
|
+
optional: true,
|
|
628
|
+
description: 'The hashing algorithm to use. One of <code>md5</code>, <code>base64</code>, <code>sha1</code>, <code>sha224</code>, <code>sha256</code>, <code>sha384</code>, <code>sha512</code>, <code>sha3</code>, <code>ripemd160</code>\n ',
|
|
629
|
+
default: '"md5"',
|
|
630
|
+
type: 'string',
|
|
631
|
+
},
|
|
632
|
+
],
|
|
633
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-hash',
|
|
634
|
+
examples: [{ example: '"hello".hash()', evaluated: "'5d41402abc4b2a76b9719d911017c592'" }],
|
|
635
|
+
};
|
|
636
|
+
quote.doc = {
|
|
637
|
+
name: 'quote',
|
|
638
|
+
description: 'Wraps a string in quotation marks, and escapes any quotation marks already in the string. Useful when constructing JSON, SQL, etc.',
|
|
639
|
+
section: 'edit',
|
|
640
|
+
returnType: 'string',
|
|
641
|
+
args: [
|
|
642
|
+
{
|
|
643
|
+
name: 'mark',
|
|
644
|
+
optional: true,
|
|
645
|
+
description: 'The type of quotation mark to use',
|
|
646
|
+
default: '"',
|
|
647
|
+
type: 'string',
|
|
648
|
+
},
|
|
649
|
+
],
|
|
650
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-quote',
|
|
651
|
+
examples: [{ example: '\'Nathan says "hi"\'.quote()', evaluated: '\'"Nathan says \\"hi\\""\'' }],
|
|
652
|
+
};
|
|
653
|
+
parseJson.doc = {
|
|
654
|
+
name: 'parseJson',
|
|
655
|
+
aliases: ['fromJson'],
|
|
656
|
+
description: "Returns the JavaScript value or object represented by the string, or <code>undefined</code> if the string isn't valid JSON. Single-quoted JSON is not supported.",
|
|
657
|
+
section: 'cast',
|
|
658
|
+
returnType: 'any',
|
|
659
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-parseJson',
|
|
660
|
+
examples: [
|
|
661
|
+
{ example: '\'{"name":"Nathan"}\'.parseJson()', evaluated: '\'{"name":"Nathan"}\'' },
|
|
662
|
+
{ example: "\"{'name':'Nathan'}\".parseJson()", evaluated: 'undefined' },
|
|
663
|
+
{ example: "'hello'.parseJson()", evaluated: 'undefined' },
|
|
664
|
+
],
|
|
665
|
+
};
|
|
666
|
+
base64Encode.doc = {
|
|
667
|
+
name: 'base64Encode',
|
|
668
|
+
aliases: ['toBase64'],
|
|
669
|
+
description: 'Converts plain text to a base64-encoded string',
|
|
670
|
+
examples: [{ example: '"hello".base64Encode()', evaluated: '"aGVsbG8="' }],
|
|
671
|
+
section: 'edit',
|
|
672
|
+
returnType: 'string',
|
|
673
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-base64Encode',
|
|
674
|
+
};
|
|
675
|
+
base64Decode.doc = {
|
|
676
|
+
name: 'base64Decode',
|
|
677
|
+
aliases: ['fromBase64'],
|
|
678
|
+
description: 'Converts a base64-encoded string to plain text',
|
|
679
|
+
examples: [{ example: '"aGVsbG8=".base64Decode()', evaluated: '"hello"' }],
|
|
680
|
+
section: 'edit',
|
|
681
|
+
returnType: 'string',
|
|
682
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-base64Decode',
|
|
683
|
+
};
|
|
684
|
+
toNumber.doc = {
|
|
685
|
+
name: 'toNumber',
|
|
686
|
+
description: "Converts a string representing a number to a number. Errors if the string doesn't start with a valid number.",
|
|
687
|
+
section: 'cast',
|
|
688
|
+
returnType: 'number',
|
|
689
|
+
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/strings/#string-toNumber',
|
|
690
|
+
examples: [
|
|
691
|
+
{ example: '"123".toNumber()', evaluated: '123' },
|
|
692
|
+
{ example: '"1.23E10".toNumber()', evaluated: '12300000000' },
|
|
693
|
+
],
|
|
694
|
+
};
|
|
695
|
+
const toDecimalNumber = toFloat.bind({});
|
|
696
|
+
const toWholeNumber = toInt.bind({});
|
|
697
|
+
export const stringExtensions = {
|
|
698
|
+
typeName: 'String',
|
|
699
|
+
functions: {
|
|
700
|
+
hash,
|
|
701
|
+
removeMarkdown,
|
|
702
|
+
removeTags,
|
|
703
|
+
toDate,
|
|
704
|
+
toDateTime,
|
|
705
|
+
toBoolean,
|
|
706
|
+
toDecimalNumber,
|
|
707
|
+
toNumber,
|
|
708
|
+
toFloat,
|
|
709
|
+
toInt,
|
|
710
|
+
toWholeNumber,
|
|
711
|
+
toSentenceCase,
|
|
712
|
+
toSnakeCase,
|
|
713
|
+
toTitleCase,
|
|
714
|
+
urlDecode,
|
|
715
|
+
urlEncode,
|
|
716
|
+
quote,
|
|
717
|
+
replaceSpecialChars,
|
|
718
|
+
length,
|
|
719
|
+
isDomain,
|
|
720
|
+
isEmail,
|
|
721
|
+
isNumeric,
|
|
722
|
+
isUrl,
|
|
723
|
+
isEmpty,
|
|
724
|
+
isNotEmpty,
|
|
725
|
+
toJsonString,
|
|
726
|
+
extractEmail,
|
|
727
|
+
extractDomain,
|
|
728
|
+
extractUrl,
|
|
729
|
+
extractUrlPath,
|
|
730
|
+
parseJson,
|
|
731
|
+
base64Encode,
|
|
732
|
+
base64Decode,
|
|
733
|
+
},
|
|
734
|
+
};
|
|
735
|
+
//# sourceMappingURL=string-extensions.js.map
|