fix(workflow): remove a few ts-ignore and eslint-disable (#3958)

fix(workflow): remove a few `ts-ignore` and `eslint-disable`. improve typing
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2022-09-09 16:34:50 +02:00 committed by GitHub
parent 712924cbc3
commit a73ac1d94f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 83 deletions

View file

@ -1,5 +1,3 @@
/* eslint-disable id-denylist */
// @ts-ignore
import * as tmpl from '@n8n_io/riot-tmpl';
import { DateTime, Duration, Interval } from 'luxon';
@ -12,20 +10,17 @@ import {
INodeParameters,
IRunExecutionData,
IWorkflowDataProxyAdditionalKeys,
IWorkflowDataProxyData,
NodeParameterValue,
Workflow,
WorkflowDataProxy,
WorkflowExecuteMode,
} from '.';
// @ts-ignore
// Set it to use double curly brackets instead of single ones
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
tmpl.brackets.set('{{ }}');
// Make sure that error get forwarded
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
tmpl.tmpl.errorHandler = (error: Error) => {
if (error instanceof ExpressionError) {
if (error.context.failExecution) {
@ -114,7 +109,6 @@ export class Expression {
const data = dataProxy.getDataProxy();
// Support only a subset of process properties
// @ts-ignore
data.process = {
arch: process.arch,
env: process.env,
@ -130,7 +124,6 @@ export class Expression {
* Denylist
*/
// @ts-ignore
data.document = {};
data.global = {};
data.window = {};
@ -223,11 +216,13 @@ export class Expression {
data.Intl = typeof Intl !== 'undefined' ? Intl : {};
// Text
// eslint-disable-next-line id-denylist
data.String = String;
data.RegExp = RegExp;
// Math
data.Math = Math;
// eslint-disable-next-line id-denylist
data.Number = Number;
data.BigInt = typeof BigInt !== 'undefined' ? BigInt : {};
data.Infinity = Infinity;
@ -250,15 +245,28 @@ export class Expression {
data.decodeURIComponent = decodeURIComponent;
// Other
// eslint-disable-next-line id-denylist
data.Boolean = Boolean;
data.Symbol = Symbol;
// Execute the expression
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let returnValue;
const returnValue = this.renderExpression(parameterValue, data);
if (typeof returnValue === 'function') {
throw new Error('Expression resolved to a function. Please add "()"');
} else if (typeof returnValue === 'string') {
return returnValue;
} else if (returnValue !== null && typeof returnValue === 'object') {
if (returnObjectAsString) {
return this.convertObjectValueToString(returnValue);
}
}
return returnValue;
}
private renderExpression(expression: string, data: IWorkflowDataProxyData): tmpl.ReturnValue {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
returnValue = tmpl.tmpl(parameterValue, data);
return tmpl.tmpl(expression, data);
} catch (error) {
if (error instanceof ExpressionError) {
// Ignore all errors except if they are ExpressionErrors and they are supposed
@ -268,18 +276,7 @@ export class Expression {
}
}
}
if (typeof returnValue === 'function') {
throw new Error('Expression resolved to a function. Please add "()"');
} else if (returnValue !== null && typeof returnValue === 'object') {
if (returnObjectAsString) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
return this.convertObjectValueToString(returnValue);
}
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return returnValue;
return null;
}
/**
@ -495,33 +492,25 @@ export class Expression {
}
// The parameter value is complex so resolve depending on type
if (Array.isArray(parameterValue)) {
// Data is an array
const returnData = [];
// eslint-disable-next-line no-restricted-syntax
for (const item of parameterValue) {
returnData.push(resolveParameterValue(item, {}));
}
if (returnObjectAsString && typeof returnData === 'object') {
return this.convertObjectValueToString(returnData);
}
const returnData = parameterValue.map((item) => resolveParameterValue(item, {}));
return returnData as NodeParameterValue[] | INodeParameters[];
}
if (parameterValue === null || parameterValue === undefined) {
return parameterValue;
}
if (typeof parameterValue !== 'object') {
return {};
}
// Data is an object
const returnData: INodeParameters = {};
// eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(parameterValue)) {
returnData[key] = resolveParameterValue(
(parameterValue as INodeParameters)[key],
parameterValue as INodeParameters,
);
for (const [key, value] of Object.entries(parameterValue)) {
returnData[key] = resolveParameterValue(value, parameterValue);
}
if (returnObjectAsString && typeof returnData === 'object') {

View file

@ -90,8 +90,7 @@ export abstract class ICredentials {
nodesAccess: ICredentialNodeAccess[],
data?: string,
) {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
this.id = nodeCredentials.id || undefined;
this.id = nodeCredentials.id ?? undefined;
this.name = nodeCredentials.name;
this.type = type;
this.nodesAccess = nodesAccess;

View file

@ -76,9 +76,8 @@ export abstract class ExecutionBaseError extends Error {
this.message = error.message as string;
}
if (Object.prototype.hasOwnProperty.call(error, 'context')) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.context = (error as any).context;
if (error instanceof ExecutionBaseError) {
this.context = error.context;
}
}
}
@ -130,14 +129,12 @@ abstract class NodeError extends ExecutionBaseError {
): string | null {
// eslint-disable-next-line no-restricted-syntax
for (const key of potentialKeys) {
if (error[key]) {
if (typeof error[key] === 'string') return error[key] as string;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (typeof error[key] === 'number') return error[key]!.toString();
if (Array.isArray(error[key])) {
// @ts-ignore
const resolvedErrors: string[] = error[key]
// @ts-ignore
const value = error[key];
if (value) {
if (typeof value === 'string') return value;
if (typeof value === 'number') return value.toString();
if (Array.isArray(value)) {
const resolvedErrors: string[] = value
.map((error) => {
if (typeof error === 'string') return error;
if (typeof error === 'number') return error.toString();
@ -146,15 +143,15 @@ abstract class NodeError extends ExecutionBaseError {
}
return null;
})
.filter((errorValue: string | null) => errorValue !== null);
.filter((errorValue): errorValue is string => errorValue !== null);
if (resolvedErrors.length === 0) {
return null;
}
return resolvedErrors.join(' | ');
}
if (this.isTraversableObject(error[key])) {
const property = this.findProperty(error[key] as JsonObject, potentialKeys);
if (this.isTraversableObject(value)) {
const property = this.findProperty(value, potentialKeys);
if (property) {
return property;
}
@ -164,8 +161,9 @@ abstract class NodeError extends ExecutionBaseError {
// eslint-disable-next-line no-restricted-syntax
for (const key of traversalKeys) {
if (this.isTraversableObject(error[key])) {
const property = this.findProperty(error[key] as JsonObject, potentialKeys, traversalKeys);
const value = error[key];
if (this.isTraversableObject(value)) {
const property = this.findProperty(value, potentialKeys, traversalKeys);
if (property) {
return property;
}

View file

@ -427,26 +427,26 @@ export function getParamterDependencies(
): IParameterDependencies {
const dependencies: IParameterDependencies = {};
let displayRule: string;
let parameterName: string;
for (const nodeProperties of nodePropertiesArray) {
if (dependencies[nodeProperties.name] === undefined) {
dependencies[nodeProperties.name] = [];
const { name, displayOptions } = nodeProperties;
if (!dependencies[name]) {
dependencies[name] = [];
}
if (nodeProperties.displayOptions === undefined) {
if (!displayOptions) {
// Does not have any dependencies
continue;
}
for (displayRule of Object.keys(nodeProperties.displayOptions)) {
// @ts-ignore
for (parameterName of Object.keys(nodeProperties.displayOptions[displayRule])) {
if (!dependencies[nodeProperties.name].includes(parameterName)) {
for (const displayRule of Object.values(displayOptions)) {
for (const parameterName of Object.keys(displayRule)) {
if (!dependencies[name].includes(parameterName)) {
if (parameterName.charAt(0) === '@') {
// Is a special parameter so can be skipped
continue;
}
dependencies[nodeProperties.name].push(parameterName);
dependencies[name].push(parameterName);
}
}
}

View file

@ -352,7 +352,7 @@ export class WorkflowDataProxy {
}
return new Proxy(
{},
{ binary: undefined, data: undefined, json: undefined },
{
get(target, name, receiver) {
name = name.toString();
@ -472,8 +472,7 @@ export class WorkflowDataProxy {
throw new Error(`The key "${name.toString()}" is not supported!`);
}
// @ts-ignore
return that.workflow[name.toString()];
return that.workflow[name as keyof typeof target];
},
},
);
@ -1004,12 +1003,10 @@ export class WorkflowDataProxy {
return new Proxy(base, {
get(target, name, receiver) {
if (['$data', '$json'].includes(name as string)) {
// @ts-ignore
return that.nodeDataGetter(that.activeNodeName, true).json;
return that.nodeDataGetter(that.activeNodeName, true)?.json;
}
if (name === '$binary') {
// @ts-ignore
return that.nodeDataGetter(that.activeNodeName, true).binary;
return that.nodeDataGetter(that.activeNodeName, true)?.binary;
}
return Reflect.get(target, name, receiver);

14
packages/workflow/src/types.d.ts vendored Normal file
View file

@ -0,0 +1,14 @@
declare module '@n8n_io/riot-tmpl' {
interface Brackets {
set(token: string): void;
}
type ReturnValue = string | null | (() => unknown);
type TmplFn = (value: string, data: unknown) => ReturnValue;
interface Tmpl extends TmplFn {
errorHandler?(error: Error): void;
}
let brackets: Brackets;
let tmpl: Tmpl;
}

View file

@ -634,8 +634,6 @@ describe('RoutingNode', () => {
for (const testData of tests) {
test(testData.description, () => {
node.parameters = testData.input.nodeParameters;
// @ts-ignore
nodeType.description.properties = [testData.input.nodeTypeProperties];
const workflow = new Workflow({

View file

@ -1022,7 +1022,6 @@ describe('Workflow', () => {
},
{
name: 'Node3',
// @ts-ignore
parameters: testData.input.hasOwnProperty('Node3')
? // @ts-ignore
testData.input.Node3.parameters
@ -1034,7 +1033,6 @@ describe('Workflow', () => {
},
{
name: 'Node 4 with spaces',
// @ts-ignore
parameters: testData.input.hasOwnProperty('Node4')
? // @ts-ignore
testData.input.Node4.parameters
@ -1080,12 +1078,10 @@ describe('Workflow', () => {
{
startTime: 1,
executionTime: 1,
// @ts-ignore
data: {
main: [
[
{
// @ts-ignore
json: testData.input.Node1.outputJson || testData.input.Node1.parameters,
// @ts-ignore
binary: testData.input.Node1.outputBinary,

View file

@ -75,7 +75,6 @@ describe('WorkflowDataProxy', () => {
{
startTime: 1,
executionTime: 1,
// @ts-ignore
data: {
main: [
[
@ -104,7 +103,6 @@ describe('WorkflowDataProxy', () => {
{
startTime: 1,
executionTime: 1,
// @ts-ignore
data: {
main: [
[