feat(editor): Add most important native props and methods to autocomplete (#5486)

*  Implemented support for documentation links in autocomplete tooltips
*  Added support for arguments and code stying in autocomplete documentation. Added build-in string functions docs.
*  Added support for args without types in autocomplete, Added array native functions.
*  Added native Number and Object methods to autocomplete
*  Added support for native properties in autocomplete
* 📚 Added comment for next phase
* ✔️ Updating tests to account for native autocomplete options. Fixing lint errros.
* 👌 Addressing design review comments
* 🎨 Using design-system tokens instead of colors for autocomplete
This commit is contained in:
Milorad FIlipović 2023-02-16 12:47:19 +01:00 committed by GitHub
parent af703371fc
commit 6592d144d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 673 additions and 56 deletions

View file

@ -10,6 +10,7 @@ import 'vue-json-pretty/lib/styles.css';
import '@jsplumb/browser-ui/css/jsplumbtoolkit.css'; import '@jsplumb/browser-ui/css/jsplumbtoolkit.css';
import 'n8n-design-system/css/index.scss'; import 'n8n-design-system/css/index.scss';
import './n8n-theme.scss'; import './n8n-theme.scss';
import './styles/autocomplete-theme.scss';
import '@fontsource/open-sans/latin-400.css'; import '@fontsource/open-sans/latin-400.css';
import '@fontsource/open-sans/latin-600.css'; import '@fontsource/open-sans/latin-600.css';

View file

@ -172,7 +172,7 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completions'); if (!found) throw new Error('Expected to find completions');
expect(found).toHaveLength(extensions('string').length); expect(found).toHaveLength(extensions('string').length + natives('string').length);
expect(found.map((c) => c.label).every((l) => !l.endsWith('()'))); expect(found.map((c) => c.label).every((l) => !l.endsWith('()')));
}); });
@ -183,7 +183,7 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completions'); if (!found) throw new Error('Expected to find completions');
expect(found).toHaveLength(extensions('number').length); expect(found).toHaveLength(extensions('number').length + natives('number').length);
expect(found.map((c) => c.label).every((l) => !l.endsWith('()'))); expect(found.map((c) => c.label).every((l) => !l.endsWith('()')));
}); });
@ -194,7 +194,7 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completions'); if (!found) throw new Error('Expected to find completions');
expect(found).toHaveLength(extensions('array').length); expect(found).toHaveLength(extensions('array').length + natives('array').length);
expect(found.map((c) => c.label).every((l) => !l.endsWith('()'))); expect(found.map((c) => c.label).every((l) => !l.endsWith('()')));
}); });
}); });
@ -206,14 +206,16 @@ describe('Resolution-based completions', () => {
test('should return completions for: {{ $input.| }}', () => { test('should return completions for: {{ $input.| }}', () => {
resolveParameterSpy.mockReturnValue($input); resolveParameterSpy.mockReturnValue($input);
expect(completions('{{ $input.| }}')).toHaveLength(Reflect.ownKeys($input).length); expect(completions('{{ $input.| }}')).toHaveLength(
Reflect.ownKeys($input).length + natives('object').length,
);
}); });
test("should return completions for: {{ $('nodeName').| }}", () => { test("should return completions for: {{ $('nodeName').| }}", () => {
resolveParameterSpy.mockReturnValue($('Rename')); resolveParameterSpy.mockReturnValue($('Rename'));
expect(completions('{{ $("Rename").| }}')).toHaveLength( expect(completions('{{ $("Rename").| }}')).toHaveLength(
Reflect.ownKeys($('Rename')).length - ['pairedItem'].length, Reflect.ownKeys($('Rename')).length + natives('object').length - ['pairedItem'].length,
); );
}); });
@ -224,7 +226,7 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completion'); if (!found) throw new Error('Expected to find completion');
expect(found).toHaveLength(1); expect(found).toHaveLength(3);
expect(found[0].label).toBe('json'); expect(found[0].label).toBe('json');
}); });
@ -235,7 +237,7 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completion'); if (!found) throw new Error('Expected to find completion');
expect(found).toHaveLength(1); expect(found).toHaveLength(3);
expect(found[0].label).toBe('json'); expect(found[0].label).toBe('json');
}); });
@ -246,7 +248,7 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completion'); if (!found) throw new Error('Expected to find completion');
expect(found).toHaveLength(1); expect(found).toHaveLength(3);
expect(found[0].label).toBe('json'); expect(found[0].label).toBe('json');
}); });
@ -261,7 +263,8 @@ describe('Resolution-based completions', () => {
resolveParameterSpy.mockReturnValue($input.item.json); resolveParameterSpy.mockReturnValue($input.item.json);
expect(completions('{{ $input.item.| }}')).toHaveLength( expect(completions('{{ $input.item.| }}')).toHaveLength(
Object.keys($input.item.json).length + extensions('object').length, Object.keys($input.item.json).length +
(extensions('object').length + natives('object').length),
); );
}); });
@ -269,7 +272,8 @@ describe('Resolution-based completions', () => {
resolveParameterSpy.mockReturnValue($input.first().json); resolveParameterSpy.mockReturnValue($input.first().json);
expect(completions('{{ $input.first().| }}')).toHaveLength( expect(completions('{{ $input.first().| }}')).toHaveLength(
Object.keys($input.first().json).length + extensions('object').length, Object.keys($input.first().json).length +
(extensions('object').length + natives('object').length),
); );
}); });
@ -277,7 +281,8 @@ describe('Resolution-based completions', () => {
resolveParameterSpy.mockReturnValue($input.last().json); resolveParameterSpy.mockReturnValue($input.last().json);
expect(completions('{{ $input.last().| }}')).toHaveLength( expect(completions('{{ $input.last().| }}')).toHaveLength(
Object.keys($input.last().json).length + extensions('object').length, Object.keys($input.last().json).length +
(extensions('object').length + natives('object').length),
); );
}); });
@ -285,33 +290,41 @@ describe('Resolution-based completions', () => {
resolveParameterSpy.mockReturnValue($input.all()[0].json); resolveParameterSpy.mockReturnValue($input.all()[0].json);
expect(completions('{{ $input.all()[0].| }}')).toHaveLength( expect(completions('{{ $input.all()[0].| }}')).toHaveLength(
Object.keys($input.all()[0].json).length + extensions('object').length, Object.keys($input.all()[0].json).length +
(extensions('object').length + natives('object').length),
); );
}); });
test('should return completions for: {{ $input.item.json.str.| }}', () => { test('should return completions for: {{ $input.item.json.str.| }}', () => {
resolveParameterSpy.mockReturnValue($input.item.json.str); resolveParameterSpy.mockReturnValue($input.item.json.str);
expect(completions('{{ $input.item.json.str.| }}')).toHaveLength(extensions('string').length); expect(completions('{{ $input.item.json.str.| }}')).toHaveLength(
extensions('string').length + natives('string').length,
);
}); });
test('should return completions for: {{ $input.item.json.num.| }}', () => { test('should return completions for: {{ $input.item.json.num.| }}', () => {
resolveParameterSpy.mockReturnValue($input.item.json.num); resolveParameterSpy.mockReturnValue($input.item.json.num);
expect(completions('{{ $input.item.json.num.| }}')).toHaveLength(extensions('number').length); expect(completions('{{ $input.item.json.num.| }}')).toHaveLength(
extensions('number').length + natives('number').length,
);
}); });
test('should return completions for: {{ $input.item.json.arr.| }}', () => { test('should return completions for: {{ $input.item.json.arr.| }}', () => {
resolveParameterSpy.mockReturnValue($input.item.json.arr); resolveParameterSpy.mockReturnValue($input.item.json.arr);
expect(completions('{{ $input.item.json.arr.| }}')).toHaveLength(extensions('array').length); expect(completions('{{ $input.item.json.arr.| }}')).toHaveLength(
extensions('array').length + natives('array').length,
);
}); });
test('should return completions for: {{ $input.item.json.obj.| }}', () => { test('should return completions for: {{ $input.item.json.obj.| }}', () => {
resolveParameterSpy.mockReturnValue($input.item.json.obj); resolveParameterSpy.mockReturnValue($input.item.json.obj);
expect(completions('{{ $input.item.json.obj.| }}')).toHaveLength( expect(completions('{{ $input.item.json.obj.| }}')).toHaveLength(
Object.keys($input.item.json.obj).length + extensions('object').length, Object.keys($input.item.json.obj).length +
(extensions('object').length + natives('object').length),
); );
}); });
}); });

View file

@ -1,4 +1,4 @@
import { ExpressionExtensions, NativeMethods, IDataObject } from 'n8n-workflow'; import { ExpressionExtensions, NativeMethods, IDataObject, DocMetadata } from 'n8n-workflow';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { i18n } from '@/plugins/i18n'; import { i18n } from '@/plugins/i18n';
import { resolveParameter } from '@/mixins/workflowHelpers'; import { resolveParameter } from '@/mixins/workflowHelpers';
@ -15,6 +15,10 @@ import {
} from './utils'; } from './utils';
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete'; import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
import type { ExtensionTypeName, FnToDoc, Resolved } from './types'; import type { ExtensionTypeName, FnToDoc, Resolved } from './types';
import { sanitizeHtml } from '@/utils';
import { NativeDoc } from 'n8n-workflow/src/Extensions/Extensions';
type AutocompleteOptionType = 'function' | 'keyword';
/** /**
* Resolution-based completions offered according to datatype. * Resolution-based completions offered according to datatype.
@ -111,11 +115,14 @@ function datatypeOptions(resolved: Resolved, toResolve: string) {
} }
export const natives = (typeName: ExtensionTypeName): Completion[] => { export const natives = (typeName: ExtensionTypeName): Completion[] => {
const natives = NativeMethods.find((ee) => ee.typeName.toLowerCase() === typeName); const natives: NativeDoc = NativeMethods.find((ee) => ee.typeName.toLowerCase() === typeName);
if (!natives) return []; if (!natives) return [];
return toOptions(natives.functions, typeName); const nativeProps = natives.properties ? toOptions(natives.properties, typeName, 'keyword') : [];
const nativeMethods = toOptions(natives.functions, typeName, 'function');
return [...nativeProps, ...nativeMethods];
}; };
export const extensions = (typeName: ExtensionTypeName) => { export const extensions = (typeName: ExtensionTypeName) => {
@ -132,44 +139,53 @@ export const extensions = (typeName: ExtensionTypeName) => {
return toOptions(fnToDoc, typeName); return toOptions(fnToDoc, typeName);
}; };
export const toOptions = (fnToDoc: FnToDoc, typeName: ExtensionTypeName) => { export const toOptions = (
fnToDoc: FnToDoc,
typeName: ExtensionTypeName,
optionType: AutocompleteOptionType = 'function',
) => {
return Object.entries(fnToDoc) return Object.entries(fnToDoc)
.sort((a, b) => a[0].localeCompare(b[0])) .sort((a, b) => a[0].localeCompare(b[0]))
.map(([fnName, fn]) => { .map(([fnName, fn]) => {
const option: Completion = { const option: Completion = {
label: fnName + '()', label: optionType === 'function' ? fnName + '()' : fnName,
type: 'function', type: optionType,
}; };
option.info = () => { option.info = () => {
const tooltipContainer = document.createElement('div'); const tooltipContainer = document.createElement('div');
tooltipContainer.classList.add('autocomplete-info-container');
if (!fn.doc?.description) return null; if (!fn.doc?.description) return null;
tooltipContainer.style.display = 'flex'; const header =
tooltipContainer.style.flexDirection = 'column'; optionType === 'function'
tooltipContainer.style.paddingTop = 'var(--spacing-4xs)'; ? createFunctionHeader(typeName, fn)
tooltipContainer.style.paddingBottom = 'var(--spacing-4xs)'; : createPropHeader(typeName, fn);
header.classList.add('autocomplete-info-header');
const header = document.createElement('div');
header.style.marginBottom = 'var(--spacing-2xs)';
const typeNameSpan = document.createElement('span');
typeNameSpan.innerHTML = typeName.slice(0, 1).toUpperCase() + typeName.slice(1) + '.';
const functionNameSpan = document.createElement('span');
functionNameSpan.innerHTML = fn.doc.name + '()';
functionNameSpan.style.fontWeight = 'var(--font-weight-bold)';
const returnTypeSpan = document.createElement('span');
returnTypeSpan.innerHTML = ': ' + fn.doc.returnType;
header.appendChild(typeNameSpan);
header.appendChild(functionNameSpan);
header.appendChild(returnTypeSpan);
tooltipContainer.appendChild(header); tooltipContainer.appendChild(header);
tooltipContainer.appendChild(document.createTextNode(fn.doc.description));
const descriptionBody = document.createElement('div');
descriptionBody.classList.add('autocomplete-info-description');
const descriptionText = document.createElement('p');
descriptionText.innerHTML = sanitizeHtml(
fn.doc.description.replace(/`(.*?)`/g, '<code>$1</code>'),
);
descriptionBody.appendChild(descriptionText);
if (fn.doc.docURL) {
const descriptionLink = document.createElement('a');
descriptionLink.setAttribute('target', '_blank');
descriptionLink.setAttribute('href', fn.doc.docURL);
descriptionLink.innerText = i18n.autocompleteUIValues['docLinkLabel'] || 'Learn more';
descriptionLink.addEventListener('mousedown', (event: MouseEvent) => {
// This will prevent documentation popup closing before click
// event gets to links
event.preventDefault();
});
descriptionLink.classList.add('autocomplete-info-doc-link');
descriptionBody.appendChild(descriptionLink);
}
tooltipContainer.appendChild(descriptionBody);
return tooltipContainer; return tooltipContainer;
}; };
@ -178,6 +194,63 @@ export const toOptions = (fnToDoc: FnToDoc, typeName: ExtensionTypeName) => {
}); });
}; };
const createFunctionHeader = (typeName: string, fn: { doc?: DocMetadata | undefined }) => {
const header = document.createElement('div');
if (fn.doc) {
const typeNameSpan = document.createElement('span');
typeNameSpan.innerHTML = typeName.slice(0, 1).toUpperCase() + typeName.slice(1) + '.';
const functionNameSpan = document.createElement('span');
functionNameSpan.classList.add('autocomplete-info-name');
functionNameSpan.innerHTML = `${fn.doc.name}`;
let functionArgs = '(';
if (fn.doc.args) {
functionArgs += fn.doc.args
.map((arg) => {
let argString = `${arg.name}`;
if (arg.type) {
argString += `: ${arg.type}`;
}
return argString;
})
.join(', ');
}
functionArgs += ')';
const argsSpan = document.createElement('span');
argsSpan.classList.add('autocomplete-info-name-args');
argsSpan.innerText = functionArgs;
const returnTypeSpan = document.createElement('span');
returnTypeSpan.innerHTML = ': ' + fn.doc.returnType;
header.appendChild(typeNameSpan);
header.appendChild(functionNameSpan);
header.appendChild(argsSpan);
header.appendChild(returnTypeSpan);
}
return header;
};
const createPropHeader = (typeName: string, property: { doc?: DocMetadata | undefined }) => {
const header = document.createElement('div');
if (property.doc) {
const typeNameSpan = document.createElement('span');
typeNameSpan.innerHTML = typeName.slice(0, 1).toUpperCase() + typeName.slice(1) + '.';
const propNameSpan = document.createElement('span');
propNameSpan.classList.add('autocomplete-info-name');
propNameSpan.innerText = property.doc.name;
const returnTypeSpan = document.createElement('span');
returnTypeSpan.innerHTML = ': ' + property.doc.returnType;
header.appendChild(typeNameSpan);
header.appendChild(propNameSpan);
header.appendChild(returnTypeSpan);
}
return header;
};
const objectOptions = (toResolve: string, resolved: IDataObject) => { const objectOptions = (toResolve: string, resolved: IDataObject) => {
const rank = setRank(['item', 'all', 'first', 'last']); const rank = setRank(['item', 'all', 'first', 'last']);
const SKIP = new Set(['__ob__', 'pairedItem']); const SKIP = new Set(['__ob__', 'pairedItem']);

View file

@ -480,6 +480,10 @@ export class I18nClass {
invalid: this.baseText('codeNodeEditor.completer.luxon.dateTimeStaticMethods.invalid'), invalid: this.baseText('codeNodeEditor.completer.luxon.dateTimeStaticMethods.invalid'),
isDateTime: this.baseText('codeNodeEditor.completer.luxon.dateTimeStaticMethods.isDateTime'), isDateTime: this.baseText('codeNodeEditor.completer.luxon.dateTimeStaticMethods.isDateTime'),
}; };
autocompleteUIValues: Record<string, string | undefined> = {
docLinkLabel: this.baseText('expressionEdit.learnMore'),
};
} }
export const i18nInstance = new VueI18n({ export const i18nInstance = new VueI18n({

View file

@ -0,0 +1,45 @@
.cm-tooltip-autocomplete {
background-color: var(--color-background-xlight) !important;
li .cm-completionLabel {
color: var(--color-success);
}
}
.ͼ2 .cm-tooltip-autocomplete ul li[aria-selected] .cm-completionLabel {
color: var(--color-text-xlight) !important;
font-weight: 600;
}
.autocomplete-info-container {
display: flex;
flex-direction: column;
padding: var(--spacing-4xs) 0;
}
.cm-completionInfo {
background-color: var(--color-background-xlight) !important;
.autocomplete-info-header {
color: var(--color-text-dark);
line-height: var(--font-line-height-compact);
margin-bottom: var(--spacing-2xs);
}
.autocomplete-info-name {
color: var(--color-success);
font-weight: var(--font-weight-bold);
}
.autocomplete-info-description {
code {
background-color: var(--color-background-base);
padding: 0 2px;
}
p {
line-height: var(--font-line-height-compact);
margin-top: 0;
margin-bottom: var(--spacing-4xs);
}
}
}

View file

@ -4,10 +4,17 @@ export interface ExtensionMap {
functions: Record<string, Function & { doc?: DocMetadata }>; functions: Record<string, Function & { doc?: DocMetadata }>;
} }
export type NativeDoc = {
typeName: string;
properties?: Record<string, { doc?: DocMetadata }>;
functions: Record<string, { doc?: DocMetadata }>;
};
export type DocMetadata = { export type DocMetadata = {
name: string; name: string;
returnType: string; returnType: string;
description?: string; description?: string;
aliases?: string[]; aliases?: string[];
args?: unknown[]; args?: Array<{ name: string; type?: string }>;
docURL?: string;
}; };

View file

@ -0,0 +1,205 @@
import type { NativeDoc } from '@/Extensions/Extensions';
export const arrayMethods: NativeDoc = {
typeName: 'Array',
properties: {
length: {
doc: {
name: 'length',
description: 'Returns the number of elements in the Array.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length',
returnType: 'number',
},
},
},
functions: {
concat: {
doc: {
name: 'concat',
description: 'Merges two or more arrays into one array.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat',
returnType: 'Array',
args: [
{ name: 'arr1', type: 'Array' },
{ name: 'arr2', type: 'Array' },
{ name: '...' },
{ name: 'arrN', type: 'Array' },
],
},
},
filter: {
doc: {
name: 'filter',
description: 'Returns an array only containing the elements that pass the test `fn`.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter',
returnType: 'Array',
args: [{ name: 'fn', type: 'Function' }],
},
},
find: {
doc: {
name: 'find',
description:
'Returns the first element in the provided array that passes the test `fn`. If no values satisfy the testing function, `undefined` is returned.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find',
returnType: 'Array|undefined',
args: [{ name: 'fn', type: 'Function' }],
},
},
findIndex: {
doc: {
name: 'findIndex',
description:
'Returns the index of the first element in an array that passes the test `fn`. If none are found, -1 is returned.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex',
returnType: 'number',
args: [{ name: 'fn', type: 'Function' }],
},
},
findLast: {
doc: {
name: 'findLast',
description: 'Returns the value of the last element that passes the test `fn`.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLast',
returnType: 'Element|undefined',
args: [{ name: 'fn', type: 'Function' }],
},
},
findLastIndex: {
doc: {
name: 'findLastIndex',
description:
'Returns the index of the last element that satisfies the provided testing function. If none are found, -1 is returned.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex',
returnType: 'number',
args: [{ name: 'fn', type: 'Function' }],
},
},
indexOf: {
doc: {
name: 'indexOf',
description:
'Returns the first index at which a given element can be found in the array, or -1 if it is not present.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf',
returnType: 'number',
args: [
{ name: 'searchElement', type: 'string|number' },
{ name: 'fromIndex?', type: 'number' },
],
},
},
includes: {
doc: {
name: 'includes',
description: 'Checks if an array includes a certain value among its entries.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes',
returnType: 'boolean',
args: [
{ name: 'searchElement', type: 'Element' },
{ name: 'fromIndex?', type: 'number' },
],
},
},
join: {
doc: {
name: 'join',
description:
'Returns a string that concatenates all of the elements in an array, separated by `separator`, which defaults to comma.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join',
returnType: 'Array',
args: [{ name: 'separator?', type: 'string' }],
},
},
map: {
doc: {
name: 'map',
description: 'Returns an array containing the results of calling `fn` on every element.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map',
returnType: 'Array',
args: [{ name: 'fn', type: 'Function' }],
},
},
reverse: {
doc: {
name: 'reverse',
description:
'Reverses an array and returns it. The first array element now becomes the last, and the last array element becomes the first.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse',
returnType: 'Array',
},
},
reduce: {
doc: {
name: 'reduce',
description:
'Executes a "reducer" function `fn` on each element of the array. Passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce',
returnType: 'any',
args: [{ name: 'fn', type: 'Function' }],
},
},
slice: {
doc: {
name: 'slice',
description:
'Returns a section of an Array. `end` defaults to the length of the Array if not given.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice',
returnType: 'Array',
args: [
{ name: 'start', type: 'number' },
{ name: 'end?', type: 'number' },
],
},
},
sort: {
doc: {
name: 'sort',
description:
'Returns a sorted array. The default sort order is ascending, built upon converting the elements into strings.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort',
returnType: 'Array',
args: [{ name: 'fn?', type: 'Function' }],
},
},
splice: {
doc: {
name: 'splice',
description: 'Changes the contents of an array by removing or replacing existing elements.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice',
returnType: 'Array',
args: [
{ name: 'start', type: 'number' },
{ name: 'deleteCount?', type: 'number' },
{ name: 'item1?', type: 'Element' },
{ name: '...' },
{ name: 'itemN?', type: 'Element' },
],
},
},
toString: {
doc: {
name: 'toString',
description: 'Returns a string representing the specified array and its elements.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString',
returnType: 'string',
},
},
},
};

View file

@ -0,0 +1,28 @@
import type { NativeDoc } from '@/Extensions/Extensions';
export const numberMethods: NativeDoc = {
typeName: 'Number',
functions: {
toFixed: {
doc: {
name: 'toFixed',
description:
'Formats a number using fixed-point notation. `digits` defaults to null if not given.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed',
returnType: 'string',
args: [{ name: 'digits?', type: 'number' }],
},
},
toPrecision: {
doc: {
name: 'toPrecision',
description: 'Returns a string representing the number to the specified precision.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision',
returnType: 'string',
args: [{ name: 'precision?', type: 'number' }],
},
},
},
};

View file

@ -0,0 +1,27 @@
import type { NativeDoc } from '@/Extensions/Extensions';
export const objectMethods: NativeDoc = {
typeName: 'Object',
functions: {
keys: {
doc: {
name: 'keys',
description:
"Returns an array of a given object's own enumerable string-keyed property names.",
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys',
returnType: 'Array',
},
},
values: {
doc: {
name: 'values',
description:
"Returns an array of a given object's own enumerable string-keyed property values.",
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values',
returnType: 'Array',
},
},
},
};

View file

@ -1,13 +1,223 @@
export const stringMethods = { import type { NativeDoc } from '@/Extensions/Extensions';
export const stringMethods: NativeDoc = {
typeName: 'String', typeName: 'String',
properties: {
length: {
doc: {
name: 'length',
description: 'Returns the number of characters in the string.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length',
returnType: 'number',
},
},
},
functions: { functions: {
// @TODO_NEXT_PHASE: Populate below and cover other datatypes concat: {
// trim: { doc: {
// doc: { name: 'concat',
// name: 'trim', description: 'Concatenates the string arguments to the calling string.',
// description: 'Removes whitespace from both ends of a string and returns a new string', docURL:
// returnType: 'string', 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat',
// }, returnType: 'string',
// }, },
},
endsWith: {
doc: {
name: 'endsWith',
description: 'Checks if a string ends with `searchString`.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith',
returnType: 'boolean',
args: [{ name: 'searchString', type: 'string' }],
},
},
indexOf: {
doc: {
name: 'indexOf',
description: 'Returns the index of the first occurrence of `searchString`',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf',
returnType: 'number',
args: [
{ name: 'searchString', type: 'string' },
{ name: 'position?', type: 'number' },
],
},
},
lastIndexOf: {
doc: {
name: 'lastIndexOf',
description: 'Returns the index of the last occurrence of `searchString`',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf',
returnType: 'number',
args: [
{ name: 'searchString', type: 'string' },
{ name: 'position?', type: 'number' },
],
},
},
match: {
doc: {
name: 'match',
description: 'Retrieves the result of matching a string against a regular expression.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match',
returnType: 'Array',
args: [{ name: 'regexp', type: 'string|RegExp' }],
},
},
includes: {
doc: {
name: 'includes',
description: 'Checks if `searchString` may be found within the calling string.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes',
returnType: 'boolean',
args: [
{ name: 'searchString', type: 'string' },
{ name: 'position?', type: 'number' },
],
},
},
replace: {
doc: {
name: 'replace',
description:
'Returns a string with matches of a `pattern` replaced by a `replacement`. If `pattern` is a string, only the first occurrence will be replaced.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace',
returnType: 'string',
args: [
{ name: 'pattern', type: 'string|RegExp' },
{ name: 'replacement', type: 'string' },
],
},
},
replaceAll: {
doc: {
name: 'replaceAll',
description: 'Returns a string with matches of a `pattern` replaced by a `replacement`.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll',
returnType: 'string',
args: [
{ name: 'pattern', type: 'string|RegExp' },
{ name: 'replacement', type: 'string' },
],
},
},
search: {
doc: {
name: 'search',
description: 'Returns a string that matches `pattern` within the given string.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search',
returnType: 'string',
args: [{ name: 'pattern', type: 'string|RegExp' }],
},
},
slice: {
doc: {
name: 'slice',
description:
'Returns a section of a string. `indexEnd` defaults to the length of the string if not given.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice',
returnType: 'string',
args: [
{ name: 'indexStart', type: 'number' },
{ name: 'indexEnd?', type: 'number' },
],
},
},
split: {
doc: {
name: 'split',
description:
'Returns the substrings that result from dividing the given string with `separator`.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split',
returnType: 'Array',
args: [
{ name: 'separator', type: 'string|RegExp' },
{ name: 'limit?', type: 'number' },
],
},
},
startsWith: {
doc: {
name: 'startsWith',
description: 'Checks if the string begins with `searchString`.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith',
returnType: 'boolean',
args: [
{ name: 'searchString', type: 'string' },
{ name: 'position?', type: 'number' },
],
},
},
substring: {
doc: {
name: 'substring',
description:
'Returns the part of the string from the start index up to and excluding the end index, or to the end of the string if no end index is supplied.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring',
returnType: 'string',
args: [
{ name: 'indexStart', type: 'number' },
{ name: 'indexEnd?', type: 'number' },
],
},
},
toLowerCase: {
doc: {
name: 'toLowerCase',
description: 'Formats a string to lowercase. Example: "this is lowercase”.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase',
returnType: 'string',
},
},
toUpperCase: {
doc: {
name: 'toUpperCase',
description: 'Formats a string to lowercase. Example: "THIS IS UPPERCASE”.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase',
returnType: 'string',
},
},
trim: {
doc: {
name: 'trim',
description: 'Removes whitespace from both ends of a string and returns a new string.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim',
returnType: 'string',
},
},
trimEnd: {
doc: {
name: 'trimEnd',
description: 'Removes whitespace from the end of a string and returns a new string.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd',
returnType: 'string',
},
},
trimStart: {
doc: {
name: 'trimStart',
description: 'Removes whitespace from the beginning of a string and returns a new string.',
docURL:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart',
returnType: 'string',
},
},
}, },
}; };

View file

@ -1,5 +1,9 @@
import { stringMethods } from './String.methods'; import { stringMethods } from './String.methods';
import { arrayMethods } from './Array.methods';
import { numberMethods } from './Number.methods';
import { objectMethods } from './Object.Methods';
import type { NativeDoc } from '@/Extensions/Extensions';
const NATIVE_METHODS = [stringMethods]; const NATIVE_METHODS: NativeDoc[] = [stringMethods, arrayMethods, numberMethods, objectMethods];
export { NATIVE_METHODS as NativeMethods }; export { NATIVE_METHODS as NativeMethods };