Skip to content

Commit

Permalink
feat(editor): Add examples for number & boolean, add new methods (#9358)
Browse files Browse the repository at this point in the history
  • Loading branch information
elsmr committed May 13, 2024
1 parent da6088d commit 7b45dc3
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ describe('Resolution-based completions', () => {
);
});

test('should return completions for boolean literal: {{ true.| }}', () => {
// @ts-expect-error Spied function is mistyped
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(true);

expect(completions('{{ true.| }}')).toHaveLength(
natives({ typeName: 'boolean' }).length + extensions({ typeName: 'boolean' }).length,
);
});

test('should properly handle string that contain dollar signs', () => {
// @ts-expect-error Spied function is mistyped
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce("You 'owe' me 200$ ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ const regexes = {

numberLiteral: /\((\d+)\.?(\d*)\)\.(.*)/, // (123). or (123.4).
singleQuoteStringLiteral: /('.*')\.([^'{\s])*/, // 'abc'.
booleanLiteral: /(true|false)\.([^'{\s])*/, // true.
doubleQuoteStringLiteral: /(".*")\.([^"{\s])*/, // "abc".
dateLiteral: /\(?new Date\(\(?.*?\)\)?\.(.*)/, // new Date(). or (new Date()).
arrayLiteral: /\(?(\[.*\])\)?\.(.*)/, // [1, 2, 3].
Expand Down
26 changes: 16 additions & 10 deletions packages/workflow/src/Extensions/BooleanExtensions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ExtensionMap } from './Extensions';
import type { Extension, ExtensionMap } from './Extensions';

export function toBoolean(value: boolean) {
return value;
Expand All @@ -8,20 +8,25 @@ export function toInt(value: boolean) {
return value ? 1 : 0;
}

export function toFloat(value: boolean) {
return value ? 1 : 0;
}

export function toDateTime() {
return undefined;
}

toInt.doc = {
name: 'toInt',
description: 'Converts a boolean to an integer. `false` is 0, `true` is 1.',
const toFloat = toInt;
const toNumber: Extension = toInt.bind({});

toNumber.doc = {
name: 'toNumber',
description:
'Converts <code>true</code> to <code>1</code> and <code>false</code> to <code>0</code>.',
examples: [
{ example: 'true.toNumber()', evaluated: '1' },
{ example: 'false.toNumber()', evaluated: '0' },
],
section: 'cast',
returnType: 'boolean',
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/booleans/#boolean-toInt',
returnType: 'number',
docURL:
'https://docs.n8n.io/code/builtin/data-transformation-functions/booleans/#boolean-toNumber',
};

export const booleanExtensions: ExtensionMap = {
Expand All @@ -30,6 +35,7 @@ export const booleanExtensions: ExtensionMap = {
toBoolean,
toInt,
toFloat,
toNumber,
toDateTime,
},
};
125 changes: 112 additions & 13 deletions packages/workflow/src/Extensions/NumberExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ function ceil(value: number) {
return Math.ceil(value);
}

function abs(value: number) {
return Math.abs(value);
}

function isInteger(value: number) {
return Number.isInteger(value);
}

function round(value: number, extraArgs: number[]) {
const [decimalPlaces = 0] = extraArgs;
return +value.toFixed(decimalPlaces);
Expand Down Expand Up @@ -86,56 +94,106 @@ function toDateTime(value: number, extraArgs: [DateTimeFormat]) {

ceil.doc = {
name: 'ceil',
description: 'Rounds up a number to a whole number.',
description: 'Rounds the number up to the next whole number',
examples: [{ example: '(1.234).ceil()', evaluated: '2' }],
returnType: 'number',
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-ceil',
};

floor.doc = {
name: 'floor',
description: 'Rounds down a number to a whole number.',
description: 'Rounds the number down to the nearest whole number',
examples: [{ example: '(1.234).floor()', evaluated: '1' }],
returnType: 'number',
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-floor',
};

isEven.doc = {
name: 'isEven',
description: 'Returns true if the number is even. Only works on whole numbers.',
description:
"Returns <code>true</code> if the number is even or <code>false</code> if not. Throws an error if the number isn't a whole number.",
examples: [
{ example: '(33).isEven()', evaluated: 'false' },
{ example: '(42).isEven()', evaluated: 'true' },
],
returnType: 'boolean',
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-isEven',
};

isOdd.doc = {
name: 'isOdd',
description: 'Returns true if the number is odd. Only works on whole numbers.',
description:
"Returns <code>true</code> if the number is odd or <code>false</code> if not. Throws an error if the number isn't a whole number.",
examples: [
{ example: '(33).isOdd()', evaluated: 'true' },
{ example: '(42).isOdd()', evaluated: 'false' },
],
returnType: 'boolean',
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-isOdd',
};

format.doc = {
name: 'format',
description:
'Returns a formatted string of a number based on the given `LanguageCode` and `FormatOptions`. When no arguments are given, transforms the number in a format like `1.234`.',
'Returns a formatted string representing the number. Useful for formatting for a specific language or currency. The same as <a target="_blank" href=”https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat”><code>Intl.NumberFormat()</code></a>.',
examples: [
{ example: "(123456.789).format('de-DE')", evaluated: '123.456,789' },
{
example: "(123456.789).format('de-DE', {'style': 'currency', 'currency': 'EUR'})",
evaluated: '123.456,79 €',
},
],
returnType: 'string',
args: [
{ name: 'locales?', type: 'LanguageCode' },
{ name: 'options?', type: 'FormatOptions' },
{
name: 'locale',
optional: true,
description:
'A <a target="_blank" href=”https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument”>locale tag</a> for formatting the number, e.g. <code>fr-FR</code>, <code>en-GB</code>, <code>pr-BR</code>',
default: '"en-US"',
type: 'string',
},
{
name: 'options',
optional: true,
description:
'Configuration options for number formatting. <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat" target="_blank">More info</a>',
type: 'object',
},
],
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-format',
};

round.doc = {
name: 'round',
description:
'Returns the value of a number rounded to the nearest whole number, unless a decimal place is specified. Defaults to 0 decimal places if no argument is given.',
description: 'Rounds the number to the nearest integer (or decimal place)',
examples: [
{ example: '(1.256).round()', evaluated: '1' },
{ example: '(1.256).round(1)', evaluated: '1.3' },
{ example: '(1.256).round(2)', evaluated: '1.26' },
],
returnType: 'number',
args: [{ name: 'decimalPlaces?', type: 'number' }],
args: [
{
name: 'decimalPlaces',
optional: true,
description: 'The number of decimal places to round to',
default: '0',
type: 'number',
},
],
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-round',
};

toBoolean.doc = {
name: 'toBoolean',
description: 'Converts a number to a boolean. 0 is `false`, all other numbers are `true`.',
description:
'Returns <code>false</code> for <code>0</code> and <code>true</code> for any other number (including negative numbers).',
examples: [
{ example: '(12).toBoolean()', evaluated: 'true' },
{ example: '(0).toBoolean()', evaluated: 'false' },
{ example: '(-1.3).toBoolean()', evaluated: 'true' },
],
section: 'cast',
returnType: 'boolean',
docURL:
Expand All @@ -145,21 +203,62 @@ toBoolean.doc = {
toDateTime.doc = {
name: 'toDateTime',
description:
"Converts a number to a DateTime. Defaults to milliseconds. Format can be 'ms' (milliseconds), 's' (seconds), 'us' (microseconds) or 'excel' (Excel 1900 format).",
'Converts a numerical timestamp into a <a target="_blank" href="https://moment.github.io/luxon/api-docs/">Luxon</a> DateTime. The format of the timestamp must be specified if it\'s not in milliseconds. Uses the timezone specified in workflow settings if available; otherwise, it defaults to the timezone set for the instance.',
examples: [
{ example: "(1708695471).toDateTime('s')", evaluated: '2024-02-23T14:37:51.000+01:00' },
{ example: "(1708695471000).toDateTime('ms')", evaluated: '2024-02-23T14:37:51.000+01:00' },
{ example: "(1708695471000000).toDateTime('us')", evaluated: '2024-02-23T14:37:51.000+01:00' },
{ example: "(45345).toDateTime('excel')", evaluated: '2024-02-23T01:00:00.000+01:00' },
],
section: 'cast',
returnType: 'DateTime',
args: [{ name: 'format?', type: 'string' }],
args: [
{
name: 'format',
optional: true,
description:
'The type of timestamp to convert. 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).',
default: '"ms"',
type: 'string',
},
],
docURL:
'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-toDateTime',
};

abs.doc = {
name: 'abs',
description: "Returns the number's absolute value, i.e. removes any minus sign",
examples: [
{ example: '(-1.7).abs()', evaluated: '1.7' },
{ example: '(1.7).abs()', evaluated: '1.7' },
],
returnType: 'number',
docURL: 'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-abs',
};

isInteger.doc = {
name: 'isInteger',
description: 'Returns <code>true</code> if the number is a whole number',
examples: [
{ example: '(4).isInteger()', evaluated: 'true' },
{ example: '(4.12).isInteger()', evaluated: 'false' },
{ example: '(-4).isInteger()', evaluated: 'true' },
],
returnType: 'boolean',
docURL:
'https://docs.n8n.io/code/builtin/data-transformation-functions/numbers/#number-isInteger',
};

export const numberExtensions: ExtensionMap = {
typeName: 'Number',
functions: {
ceil,
floor,
format,
round,
abs,
isInteger,
isEven,
isOdd,
toBoolean,
Expand Down
2 changes: 1 addition & 1 deletion packages/workflow/src/Extensions/StringExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ toDate.doc = {
toDateTime.doc = {
name: 'toDateTime',
description:
'Converts the string to 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>.',
'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>.',
section: 'cast',
returnType: 'DateTime',
docURL:
Expand Down
7 changes: 6 additions & 1 deletion packages/workflow/src/NativeMethods/Boolean.methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ export const booleanMethods: NativeDoc = {
toString: {
doc: {
name: 'toString',
description: 'returns a string representing this boolean value.',
description:
"Converts <code>true</code> to the string <code>'true'</code> and <code>false</code> to the string <code>'false'</code>.",
examples: [
{ example: 'true.toString()', evaluated: "'true'" },
{ example: 'false.toString()', evaluated: "'false'" },
],
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/toString',
returnType: 'string',
Expand Down
49 changes: 47 additions & 2 deletions packages/workflow/src/NativeMethods/Number.methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,63 @@ export const numberMethods: NativeDoc = {
toString: {
doc: {
name: 'toString',
description: 'Returns a string representing this number value.',
description:
'Converts the number to a string. For more formatting options, see <code>toLocaleString()</code>.',
examples: [
{ example: '(2).toString()', evaluated: "'2'" },
{ example: '(50.125).toString()', evaluated: "'50.125'" },
{ example: '(5).toString(2)', evaluated: "'101'" },
{ example: '(412).toString(16)', evaluated: "'19c'" },
],
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString',
args: [
{
name: 'base',
optional: true,
description:
'The base to use. Must be an integer between 2 and 36. E.g. base <code>2</code> is binary and base <code>16</code> is hexadecimal.',
default: '10',
type: 'number',
},
],
returnType: 'string',
},
},
toLocaleString: {
doc: {
name: 'toLocaleString',
description: 'Returns a string with a language-sensitive representation of this number.',
description:
"Returns a localized string representing the number, i.e. in the language and format corresponding to its locale. Defaults to the system's locale if none specified.",
examples: [
{
example: '(500000.125).toLocaleString()',
evaluated: "'500,000.125' (if in US English locale)",
},
{ example: "(500000.125).toLocaleString('fr-FR')", evaluated: "'500 000,125'" },
{
example: "(500000.125).toLocaleString('fr-FR', {style:'currency', currency:'EUR'})",
evaluated: "'500 000,13 €'",
},
],
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString',
args: [
{
name: 'locale(s)',
optional: true,
description:
'The locale to use, e.g. \'en-GB\' for British English or \'pt-BR\' for Brazilian Portuguese. See <a target="_blank" href="https://www.localeplanet.com/icu/">full list</a> (unofficial). Also accepts an <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument">array of locales</a>. Defaults to the system locale if not specified.',
type: 'string | string[]',
},
{
name: 'options',
optional: true,
description:
'An object with <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#parameters">formatting options</a>',
type: 'object',
},
],
returnType: 'string',
},
},
Expand Down

0 comments on commit 7b45dc3

Please sign in to comment.