refactor: Run lintfix (no-changelog) (#7537)

- Fix autofixable violations
- Remove unused directives
- Allow for PascalCased variables - needed for dynamically imported or
assigned classes, decorators, routers, etc.
This commit is contained in:
Iván Ovejero 2023-10-27 14:15:02 +02:00 committed by GitHub
parent 1c4ac02db5
commit 62c096710f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
477 changed files with 706 additions and 1003 deletions

View file

@ -231,7 +231,7 @@ const config = (module.exports = {
},
{
selector: 'variable',
format: ['camelCase', 'snake_case', 'UPPER_CASE'],
format: ['camelCase', 'snake_case', 'UPPER_CASE', 'PascalCase'],
leadingUnderscore: 'allowSingleOrDouble',
trailingUnderscore: 'allowSingleOrDouble',
},

View file

@ -23,7 +23,7 @@ export const initErrorHandling = async () => {
const { N8N_VERSION: release, ENVIRONMENT: environment } = process.env;
const { init, captureException, addGlobalEventProcessor } = await import('@sentry/node');
// eslint-disable-next-line @typescript-eslint/naming-convention
const { RewriteFrames } = await import('@sentry/integrations');
init({

View file

@ -316,7 +316,7 @@ export class LoadNodesAndCredentials {
const { default: debounce } = await import('lodash/debounce');
// eslint-disable-next-line import/no-extraneous-dependencies
const { watch } = await import('chokidar');
// eslint-disable-next-line @typescript-eslint/naming-convention
const { Push } = await import('@/push');
const push = Container.get(Push);

View file

@ -43,9 +43,9 @@ export class Queue {
const prefix = getRedisPrefix(bullPrefix);
const clusterNodes = getRedisClusterNodes();
const usesRedisCluster = clusterNodes.length > 0;
// eslint-disable-next-line @typescript-eslint/naming-convention
const { default: Bull } = await import('bull');
// eslint-disable-next-line @typescript-eslint/naming-convention
const { default: Redis } = await import('ioredis');
// Disabling ready check is necessary as it allows worker to
// quickly reconnect to Redis if Redis crashes or is unreachable

View file

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
/* eslint-disable prefer-const */
/* eslint-disable @typescript-eslint/no-shadow */
@ -335,7 +335,6 @@ export class Server extends AbstractServer {
}
if (config.getEnv('nodes.communityPackages.enabled')) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { CommunityPackagesController } = await import(
'@/controllers/communityPackages.controller'
);
@ -343,7 +342,6 @@ export class Server extends AbstractServer {
}
if (inE2ETests) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { E2EController } = await import('./controllers/e2e.controller');
controllers.push(Container.get(E2EController));
}
@ -357,7 +355,6 @@ export class Server extends AbstractServer {
async configure(): Promise<void> {
if (config.getEnv('endpoints.metrics.enable')) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { MetricsService } = await import('@/services/metrics.service');
await Container.get(MetricsService).configureMetrics(this.app);
}

View file

@ -964,7 +964,7 @@ async function executeWorkflow(
activeExecutions.remove(executionId, data);
// Workflow did fail
const { error } = data.data.resultData;
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw objectToError(
{
...error,

View file

@ -37,7 +37,7 @@ import type {
} from '@/Interfaces';
import { NodeTypes } from '@/NodeTypes';
import type { Job, JobData, JobResponse } from '@/Queue';
// eslint-disable-next-line import/no-cycle
import { Queue } from '@/Queue';
import { decodeWebhookResponse } from '@/helpers/decodeWebhookResponse';
// eslint-disable-next-line import/no-cycle

View file

@ -178,7 +178,7 @@ class WorkflowRunnerProcess {
additionalData.setExecutionStatus = WorkflowExecuteAdditionalData.setExecutionStatus.bind({
executionId: inputData.executionId,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
additionalData.sendDataToUI = async (type: string, data: IDataObject | IDataObject[]) => {
if (workflowRunner.data!.executionMode !== 'manual') {
return;

View file

@ -17,7 +17,6 @@ import type { Risk } from '@/audit/types';
async function getCommunityNodeDetails() {
if (!config.getEnv('nodes.communityPackages.enabled')) return [];
// eslint-disable-next-line @typescript-eslint/naming-convention
const { CommunityPackagesService } = await import('@/services/communityPackages.service');
const installedPackages = await Container.get(CommunityPackagesService).getAllInstalledPackages();

View file

@ -7,7 +7,6 @@ export class Reset extends BaseCommand {
static description = '\nResets the database to the default ldap state';
async run(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { AuthIdentity, AuthProviderSyncHistory, Settings, User } = Db.collections;
const ldapIdentities = await AuthIdentity.find({
where: { providerType: 'ldap' },

View file

@ -248,7 +248,6 @@ export class Start extends BaseCommand {
const areCommunityPackagesEnabled = config.getEnv('nodes.communityPackages.enabled');
if (areCommunityPackagesEnabled) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { CommunityPackagesService } = await import('@/services/communityPackages.service');
await Container.get(CommunityPackagesService).setMissingPackages({
reinstallMissingPackages: flags.reinstallMissingPackages,

View file

@ -12,7 +12,6 @@ import { Container } from 'typedi';
import { InternalHooks } from '@/InternalHooks';
import type { CredentialsEntity } from '@/databases/entities/CredentialsEntity';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const EECredentialsController = express.Router();
EECredentialsController.use((req, res, next) => {

View file

@ -61,7 +61,7 @@ function mixinTimestamps<T extends Constructor<{}>>(base: T) {
}
class BaseEntity {}
/* eslint-disable @typescript-eslint/naming-convention */
export const WithStringId = mixinStringId(BaseEntity);
export const WithTimestamps = mixinTimestamps(BaseEntity);
export const WithTimestampsAndStringId = mixinStringId(WithTimestamps);

View file

@ -1,7 +1,6 @@
import { CONTROLLER_MIDDLEWARES } from './constants';
import type { MiddlewareMetadata } from './types';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const Middleware = (): MethodDecorator => (target, handlerName) => {
const controllerClass = target.constructor;
const middlewares = (Reflect.getMetadata(CONTROLLER_MIDDLEWARES, controllerClass) ??

View file

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { CONTROLLER_BASE_PATH } from './constants';
export const RestController =

View file

@ -6,7 +6,6 @@ interface RouteOptions {
middlewares?: RequestHandler[];
}
/* eslint-disable @typescript-eslint/naming-convention */
const RouteFactory =
(method: Method) =>
(path: `/${string}`, options: RouteOptions = {}): MethodDecorator =>

View file

@ -11,7 +11,6 @@ import {
import { isVariablesEnabled } from './enviromentHelpers';
import { Logger } from '@/Logger';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const EEVariablesController = express.Router();
EEVariablesController.use((req, res, next) => {

View file

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import express from 'express';
import { isEventMessageOptions } from './EventMessageClasses/AbstractEventMessage';
import { EventMessageGeneric } from './EventMessageClasses/EventMessageGeneric';

View file

@ -9,7 +9,6 @@ import * as ResponseHelper from '@/ResponseHelper';
import { isSharingEnabled } from '@/UserManagement/UserManagementHelper';
import { EEExecutionsService } from './executions.service.ee';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const EEExecutionsController = express.Router();
EEExecutionsController.use((req, res, next) => {

View file

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
import * as ResponseHelper from '@/ResponseHelper';
import { WorkflowFilter } from './dtos/workflow.filter.dto';
import { CredentialsFilter } from './dtos/credentials.filter.dto';

View file

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { WorkflowSelect } from './dtos/workflow.select.dto';
import { UserSelect } from './dtos/user.select.dto';
import { CredentialsSelect } from './dtos/credentials.select.dto';

View file

@ -17,7 +17,6 @@ export class PostHogClient {
return;
}
// eslint-disable-next-line @typescript-eslint/naming-convention
const { PostHog } = await import('posthog-node');
this.postHog = new PostHog(config.getEnv('diagnostics.config.posthog.apiKey'), {
host: config.getEnv('diagnostics.config.posthog.apiHost'),

View file

@ -143,7 +143,6 @@ export async function getDefaultRedisClient(
additionalRedisOptions?: RedisOptions,
redisType?: RedisClientType,
): Promise<Redis | Cluster> {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { default: Redis } = await import('ioredis');
const clusterNodes = getRedisClusterNodes();
const usesRedisCluster = clusterNodes.length > 0;

View file

@ -56,7 +56,6 @@ export class Telemetry {
const logLevel = config.getEnv('logs.level');
// eslint-disable-next-line @typescript-eslint/naming-convention
const { default: RudderStack } = await import('@rudderstack/rudder-sdk-node');
this.rudderStack = new RudderStack(key, url, { logLevel });

View file

@ -24,7 +24,6 @@ import { TagService } from '@/services/tag.service';
import { Logger } from '@/Logger';
import { WorkflowHistoryService } from './workflowHistory/workflowHistory.service.ee';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const EEWorkflowController = express.Router();
EEWorkflowController.use((req, res, next) => {

View file

@ -506,7 +506,6 @@ export class WorkflowsService {
if (isWorkflowIdValid(workflow.id)) {
// Workflow is saved so update in database
try {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
await WorkflowsService.saveStaticDataById(workflow.id, workflow.staticData);
workflow.staticData.__dataChanged = false;
} catch (error) {

View file

@ -8,7 +8,6 @@ import type { User } from '@db/entities/User';
import type { BooleanLicenseFeature, ICredentialsDb, IDatabaseCollections } from '@/Interfaces';
import type { DataSource, Repository } from 'typeorm';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type CollectionName =
| keyof IDatabaseCollections
| { new (dataSource: DataSource): Repository<any> };

View file

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { readFile, stat } from 'node:fs/promises';
import prettyBytes from 'pretty-bytes';
import Container, { Service } from 'typedi';

View file

@ -274,7 +274,6 @@ export class WorkflowExecute {
}
// Only run the parent nodes and no others
// eslint-disable-next-line prefer-const
runNodeFilter = workflow
.getParentNodes(destinationNode)
.filter((parentNodeName) => !workflow.getNode(parentNodeName)?.disabled);

View file

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */

View file

@ -3,7 +3,6 @@ import { defineComponent, h } from 'vue';
import type { DatatableRow } from '../../../types';
import N8nButton from '../../N8nButton';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const ActionComponent = defineComponent({
props: {
row: {

View file

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { Plugin } from 'vue';
import {
N8nActionBox,

View file

@ -18,9 +18,7 @@ export function routesForSSO(server: Server) {
});
server.post('/rest/sso/saml/config', (schema: AppSchema, request: Request) => {
const requestBody = jsonParse(request.requestBody) as Partial<
SamlPreferences & SamlPreferencesExtractedData
>;
const requestBody = jsonParse(request.requestBody);
samlConfig = {
...samlConfig,

View file

@ -288,7 +288,7 @@ export const jsonFieldCompletions = defineComponent({
const pinData: IPinData | undefined = this.workflowsStore.getPinData;
const nodePinData = pinData && pinData[nodeName];
const nodePinData = pinData?.[nodeName];
if (nodePinData) {
try {

View file

@ -112,11 +112,9 @@ export default defineComponent({
},
// Returns all the options which did not get added already
parameterOptions(): Array<INodePropertyOptions | INodeProperties> {
return (this.filteredOptions as Array<INodePropertyOptions | INodeProperties>).filter(
(option) => {
return !this.propertyNames.includes(option.name);
},
);
return this.filteredOptions.filter((option) => {
return !this.propertyNames.includes(option.name);
});
},
propertyNames(): string[] {
if (this.values) {

View file

@ -13,7 +13,7 @@ import type { INodeProperties, INodeTypeDescription, NodeParameterValue } from '
import { computed, onMounted, ref } from 'vue';
export interface Props {
credentialType: Object;
credentialType: object;
}
const emit = defineEmits<{
@ -87,7 +87,7 @@ function shouldShowAuthOption(option: NodeAuthenticationOption): boolean {
let shouldDisplay = false;
Object.keys(authRelatedFieldsValues.value).forEach((fieldName) => {
if (option.displayOptions && option.displayOptions.show) {
if (option.displayOptions?.show) {
if (
option.displayOptions.show[fieldName]?.includes(authRelatedFieldsValues.value[fieldName])
) {

View file

@ -288,7 +288,7 @@ export default defineComponent({
const activeNode = this.ndvStore.activeNode;
const isCommunityNode = activeNode ? isCommunityPackageName(activeNode.type) : false;
const documentationUrl = type && type.documentationUrl;
const documentationUrl = type?.documentationUrl;
if (!documentationUrl) {
return '';

View file

@ -125,6 +125,7 @@ import type {
INodeProperties,
INodeTypeDescription,
ITelemetryTrackProperties,
IDataObject,
} from 'n8n-workflow';
import { NodeHelpers } from 'n8n-workflow';
import CredentialIcon from '@/components/CredentialIcon.vue';
@ -139,7 +140,6 @@ import SaveButton from '@/components/SaveButton.vue';
import Modal from '@/components/Modal.vue';
import InlineNameEdit from '@/components/InlineNameEdit.vue';
import { CREDENTIAL_EDIT_MODAL_KEY, EnterpriseEditionFeature, MODAL_CONFIRM } from '@/constants';
import type { IDataObject } from 'n8n-workflow';
import FeatureComingSoon from '@/components/FeatureComingSoon.vue';
import type { IPermissions } from '@/permissions';
import { getCredentialPermissions } from '@/permissions';
@ -270,7 +270,7 @@ export default defineComponent({
setTimeout(async () => {
if (this.credentialId) {
if (!this.requiredPropertiesFilled && this.credentialPermissions.isOwner === true) {
if (!this.requiredPropertiesFilled && this.credentialPermissions.isOwner) {
// sharees can't see properties, so this check would always fail for them
// if the credential contains required fields.
this.showValidationWarning = true;
@ -364,7 +364,7 @@ export default defineComponent({
},
isCredentialTestable(): boolean {
// Sharees can always test since they can't see the data.
if (this.credentialPermissions.isOwner === false) {
if (!this.credentialPermissions.isOwner) {
return true;
}
if (this.isOAuthType || !this.requiredPropertiesFilled) {
@ -495,7 +495,7 @@ export default defineComponent({
defaultCredentialTypeName(): string {
let credentialTypeName = this.credentialTypeName;
if (!credentialTypeName || credentialTypeName === 'null') {
if (this.activeNodeType && this.activeNodeType.credentials) {
if (this.activeNodeType?.credentials) {
credentialTypeName = this.activeNodeType.credentials[0].name;
}
}
@ -701,7 +701,7 @@ export default defineComponent({
getParentTypes(name: string): string[] {
const credentialType = this.credentialsStore.getCredentialTypeByName(name);
if (credentialType === undefined || credentialType.extends === undefined) {
if (credentialType?.extends === undefined) {
return [];
}
@ -828,7 +828,7 @@ export default defineComponent({
this.isSaving = false;
if (credential) {
this.credentialId = credential.id as string;
this.credentialId = credential.id;
if (this.isCredentialTestable) {
this.isTesting = true;

View file

@ -122,7 +122,7 @@ export default defineComponent({
},
focusOnNameInput() {
const inputRef = this.$refs.nameInput as HTMLElement | undefined;
if (inputRef && inputRef.focus) {
if (inputRef?.focus) {
inputRef.focus();
}
},

View file

@ -170,7 +170,7 @@ export default defineComponent({
.replace(/%%PARAMETER_FULL%%/g, parameterFullName);
},
getErrorDescription(): string {
if (!this.error.context || !this.error.context.descriptionTemplate) {
if (!this.error.context?.descriptionTemplate) {
return sanitizeHtml(this.error.description);
}
@ -182,7 +182,7 @@ export default defineComponent({
getErrorMessage(): string {
const baseErrorMessage = this.$locale.baseText('nodeErrorView.error') + ': ';
if (!this.error.context || !this.error.context.messageTemplate) {
if (!this.error.context?.messageTemplate) {
return baseErrorMessage + this.error.message;
}
@ -200,7 +200,7 @@ export default defineComponent({
throw new Error();
}
if (fullPath === false) {
if (!fullPath) {
return parameters.pop()!.displayName;
}
return parameters.map((parameter) => parameter.displayName).join(' > ');

View file

@ -89,7 +89,7 @@ export default defineComponent({
},
computed: {
...mapStores(useRootStore, useSettingsStore, useUIStore, useWorkflowsStore),
accordionItems(): Object[] {
accordionItems(): object[] {
return [
{
id: 'productionExecutions',
@ -114,7 +114,7 @@ export default defineComponent({
];
},
shouldExpandAccordion(): boolean {
if (this.initiallyExpanded === false) {
if (!this.initiallyExpanded) {
return false;
}
return (

View file

@ -98,8 +98,7 @@ export default defineComponent({
...mapStores(useTagsStore, useNodeTypesStore, useSettingsStore, useUIStore, useWorkflowsStore),
hidePreview(): boolean {
const activeNotPresent =
this.filterApplied &&
!(this.executions as IExecutionsSummary[]).find((ex) => ex.id === this.activeExecution?.id);
this.filterApplied && !this.executions.find((ex) => ex.id === this.activeExecution?.id);
return this.loading || !this.executions.length || activeNotPresent;
},
filterApplied(): boolean {
@ -193,7 +192,7 @@ export default defineComponent({
}
}
this.autoRefresh = this.uiStore.executionSidebarAutoRefresh === true;
this.autoRefresh = this.uiStore.executionSidebarAutoRefresh;
void this.startAutoRefreshInterval();
document.addEventListener('visibilitychange', this.onDocumentVisibilityChange);
@ -581,7 +580,7 @@ export default defineComponent({
this.uiStore.stateIsDirty = false;
},
async addNodes(nodes: INodeUi[], connections?: IConnections) {
if (!nodes || !nodes.length) {
if (!nodes?.length) {
return;
}
@ -723,7 +722,7 @@ export default defineComponent({
loadWorkflow,
);
if (retrySuccessful === true) {
if (retrySuccessful) {
this.showMessage({
title: this.$locale.baseText('executionsList.showMessage.retrySuccessfulTrue.title'),
type: 'success',

View file

@ -145,7 +145,7 @@ export default defineComponent({
}
}
},
onRetryExecution(payload: Object) {
onRetryExecution(payload: object) {
this.$emit('retryExecution', payload);
},
onRefresh(): void {

View file

@ -124,7 +124,7 @@ export default defineComponent({
this.latestValue = value;
this.segments = segments;
if (forceUpdate === true) {
if (forceUpdate) {
this.updateDisplayValue();
this.$emit('update:modelValue', this.latestValue);
} else {

View file

@ -51,7 +51,7 @@ const canConnect = computed(() => {
});
const formattedDate = computed((provider: ExternalSecretsProvider) => {
return DateTime.fromISO(props.provider.connectedAt!).toFormat('dd LLL yyyy');
return DateTime.fromISO(props.provider.connectedAt).toFormat('dd LLL yyyy');
});
onMounted(() => {

View file

@ -9,12 +9,15 @@ import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
import { useUIStore } from '@/stores';
import { useRoute } from 'vue-router';
import ParameterInputExpanded from '@/components/ParameterInputExpanded.vue';
import type { IUpdateInformation, ExternalSecretsProviderData } from '@/Interface';
import type {
IUpdateInformation,
ExternalSecretsProviderData,
ExternalSecretsProvider,
} from '@/Interface';
import type { IParameterLabel } from 'n8n-workflow';
import ExternalSecretsProviderImage from '@/components/ExternalSecretsProviderImage.ee.vue';
import ExternalSecretsProviderConnectionSwitch from '@/components/ExternalSecretsProviderConnectionSwitch.ee.vue';
import { createEventBus } from 'n8n-design-system/utils';
import type { ExternalSecretsProvider } from '@/Interface';
const props = defineProps({
data: {

View file

@ -84,7 +84,7 @@ export default defineComponent({
},
iconStyleData(): object {
const nodeType = this.nodeType as ITemplatesNode | null;
const color = nodeType ? nodeType.defaults && nodeType!.defaults.color : '';
const color = nodeType ? nodeType.defaults && nodeType.defaults.color : '';
if (!this.size) {
return { color };
}

View file

@ -16,7 +16,7 @@ type Props = {
createNodeActive?: boolean;
};
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unsafe-assignment
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const NodeCreator = defineAsyncComponent(
async () => import('@/components/Node/NodeCreator/NodeCreator.vue'),
);

View file

@ -104,7 +104,7 @@ const containsAPIAction = computed(() => {
return ((p as ActionCreateElement).properties.actionKey ?? '') === CUSTOM_API_CALL_KEY;
});
return result === true;
return result;
});
const isTriggerRootView = computed(() => rootView.value === TRIGGER_NODE_CREATOR_VIEW);

View file

@ -110,7 +110,7 @@ function onDrop(event: DragEvent) {
watch(
() => props.active,
(isActive) => {
if (isActive === false) {
if (!isActive) {
setShowScrim(false);
resetViewStacks();
}

View file

@ -5,10 +5,10 @@ import {
mockSubcategoryCreateElement,
mockLabelCreateElement,
mockNodeCreateElement,
mockActionCreateElement,
mockViewCreateElement,
} from './utils';
import ItemsRenderer from '../Renderers/ItemsRenderer.vue';
import { mockActionCreateElement } from './utils';
import { mockViewCreateElement } from './utils';
import { createComponentRenderer } from '@/__tests__/render';
const renderComponent = createComponentRenderer(ItemsRenderer);

View file

@ -145,7 +145,7 @@ export const useActions = () => {
return {
name: actionItem.displayName,
key: actionItem.name as string,
key: actionItem.name,
value: { ...actionItem.values, ...displayConditions } as INodeParameters,
};
}

View file

@ -70,7 +70,7 @@ function operationsCategory(nodeTypeDescription: INodeTypeDescription): ActionTy
(property) => property.name?.toLowerCase() === 'operation',
);
if (!matchedProperty || !matchedProperty.options) return [];
if (!matchedProperty?.options) return [];
const filteredOutItems = (matchedProperty.options as INodePropertyOptions[]).filter(
(categoryItem: INodePropertyOptions) => !['*', '', ' '].includes(categoryItem.name),
@ -104,7 +104,7 @@ function triggersCategory(nodeTypeDescription: INodeTypeDescription): ActionType
// Inject placeholder action if no events are available
// so user is able to add node to the canvas from the actions panel
if (!matchedProperty || !matchedProperty.options) {
if (!matchedProperty?.options) {
return [
{
...getNodeTypeBase(nodeTypeDescription),
@ -191,7 +191,7 @@ function resourceCategories(nodeTypeDescription: INodeTypeDescription): ActionTy
// We need to manually populate displayOptions as they are not present in the node description
// if the resource has only one option
const displayOptions = isSingleResource
? { show: { resource: [(options as INodePropertyOptions[])[0]?.value] } }
? { show: { resource: [options[0]?.value] } }
: operations?.displayOptions;
return {

View file

@ -236,7 +236,7 @@ export default defineComponent({
if (this.nodeType && this.node) {
const workflow = this.workflowsStore.getCurrentWorkflow();
const workflowNode = workflow.getNode(this.node.name);
const inputs = NodeHelpers.getNodeInputs(workflow, workflowNode!, this.nodeType!);
const inputs = NodeHelpers.getNodeInputs(workflow, workflowNode!, this.nodeType);
const inputNames = NodeHelpers.getConnectionTypes(inputs);
if (!inputNames.includes(NodeConnectionType.Main) && !this.isTriggerNode) {

View file

@ -632,7 +632,7 @@ export default defineComponent({
return this.i18n.baseText('parameterInput.parameter', interpolation);
},
displayValue(): string | number | boolean | null {
if (this.remoteParameterOptionsLoading === true) {
if (this.remoteParameterOptionsLoading) {
// If it is loading options from server display
// to user that the data is loading. If not it would
// display the user the key instead of the value it
@ -646,7 +646,7 @@ export default defineComponent({
}
let returnValue;
if (this.isValueExpression === false) {
if (!this.isValueExpression) {
returnValue = this.isResourceLocatorParameter
? isResourceLocatorValue(this.modelValue)
? this.modelValue.value
@ -706,7 +706,7 @@ export default defineComponent({
return 'text';
},
getIssues(): string[] {
if (this.hideIssues === true || this.node === null) {
if (this.hideIssues || this.node === null) {
return [];
}
@ -728,7 +728,7 @@ export default defineComponent({
issues.parameters[this.parameter.name] = [issue];
} else if (
['options', 'multiOptions'].includes(this.parameter.type) &&
this.remoteParameterOptionsLoading === false &&
!this.remoteParameterOptionsLoading &&
this.remoteParameterOptionsLoadingIssues === null &&
this.parameterOptions
) {
@ -772,11 +772,7 @@ export default defineComponent({
];
}
if (
issues !== undefined &&
issues.parameters !== undefined &&
issues.parameters[this.parameter.name] !== undefined
) {
if (issues?.parameters?.[this.parameter.name] !== undefined) {
return issues.parameters[this.parameter.name];
}
@ -792,7 +788,7 @@ export default defineComponent({
parameterOptions():
| Array<INodePropertyOptions | INodeProperties | INodePropertyCollection>
| undefined {
if (this.hasRemoteMethod === false) {
if (!this.hasRemoteMethod) {
// Options are already given
return this.parameter.options;
}
@ -909,7 +905,7 @@ export default defineComponent({
async loadRemoteParameterOptions() {
if (
this.node === null ||
this.hasRemoteMethod === false ||
!this.hasRemoteMethod ||
this.remoteParameterOptionsLoading ||
!this.parameter
) {
@ -965,7 +961,7 @@ export default defineComponent({
return;
}
if ((this.node.type as string).startsWith('n8n-nodes-base')) {
if (this.node.type.startsWith('n8n-nodes-base')) {
this.$telemetry.track('User opened Expression Editor', {
node_type: this.node.type,
parameter_name: this.parameter.displayName,
@ -1062,9 +1058,7 @@ export default defineComponent({
},
rgbaToHex(value: string): string | null {
// Convert rgba to hex from: https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
const valueMatch = (value as string).match(
/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)$/,
);
const valueMatch = value.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)$/);
if (valueMatch === null) {
// TODO: Display something if value is not valid
return null;
@ -1245,7 +1239,7 @@ export default defineComponent({
}
}
if (this.hasRemoteMethod === true && this.node !== null) {
if (this.hasRemoteMethod && this.node !== null) {
// Make sure to load the parameter options
// directly and whenever the credentials change
this.$watch(
@ -1259,7 +1253,7 @@ export default defineComponent({
void this.$externalHooks().run('parameterInput.mount', {
parameter: this.parameter,
inputFieldRef: this.$refs['inputField'],
inputFieldRef: this.$refs.inputField,
});
},
beforeUnmount() {

View file

@ -162,7 +162,7 @@ export default defineComponent({
if (this.isValueExpression) {
return undefined;
}
if (this.selectedRLMode && this.selectedRLMode.hint) {
if (this.selectedRLMode?.hint) {
return this.selectedRLMode.hint;
}

View file

@ -100,7 +100,7 @@ export default defineComponent({
return this.parameter.noDataExpression !== true && this.showExpressionSelector;
},
shouldShowOptions(): boolean {
if (this.isReadOnly === true) {
if (this.isReadOnly) {
return false;
}
@ -112,7 +112,7 @@ export default defineComponent({
return false;
}
if (this.showOptions === true) {
if (this.showOptions) {
return true;
}

View file

@ -303,7 +303,7 @@ export default defineComponent({
if (!node) {
return false;
}
return !!(node && node.credentials && Object.keys(node.credentials).length === 1);
return !!(node?.credentials && Object.keys(node.credentials).length === 1);
},
credentialsNotSet(): boolean {
const nodeType = this.nodeTypesStore.getNodeType(this.node?.type);
@ -350,7 +350,7 @@ export default defineComponent({
},
urlValue(): string | null {
if (this.isListMode && typeof this.modelValue === 'object') {
return (this.modelValue && this.modelValue.cachedResultUrl) || null;
return this.modelValue?.cachedResultUrl || null;
}
if (this.selectedMode === 'url') {
@ -394,7 +394,7 @@ export default defineComponent({
const cacheKeys = { ...this.currentRequestParams };
cacheKeys.parameters = Object.keys(this.node ? this.node.parameters : {}).reduce(
(accu: INodeParameters, param) => {
if (param !== this.parameter.name && this.node && this.node.parameters) {
if (param !== this.parameter.name && this.node?.parameters) {
accu[param] = this.node.parameters[param];
}
@ -418,7 +418,7 @@ export default defineComponent({
);
},
currentQueryHasMore(): boolean {
return !!(this.currentResponse && this.currentResponse.nextPageToken);
return !!this.currentResponse?.nextPageToken;
},
currentQueryLoading(): boolean {
if (this.requiresSearchFilter && this.searchFilter === '') {
@ -449,14 +449,13 @@ export default defineComponent({
}
},
isValueExpression(newValue: boolean) {
if (newValue === true) {
if (newValue) {
this.switchFromListMode();
}
},
currentMode(mode: INodePropertyMode) {
if (
mode.extractValue &&
mode.extractValue.regex &&
mode.extractValue?.regex &&
isResourceLocatorValue(this.modelValue) &&
this.modelValue.__regex !== mode.extractValue.regex
) {
@ -546,7 +545,7 @@ export default defineComponent({
},
openCredential(): void {
const node = this.ndvStore.activeNode;
if (!node || !node.credentials) {
if (!node?.credentials) {
return;
}
const credentialKey = Object.keys(node.credentials)[0];
@ -585,11 +584,11 @@ export default defineComponent({
const params: INodeParameterResourceLocator = { __rl: true, value, mode: this.selectedMode };
if (this.isListMode) {
const resource = this.currentQueryResults.find((resource) => resource.value === value);
if (resource && resource.name) {
if (resource?.name) {
params.cachedResultName = resource.name;
}
if (resource && resource.url) {
if (resource?.url) {
params.cachedResultUrl = resource.url;
}
}
@ -598,7 +597,7 @@ export default defineComponent({
onModeSelected(value: string): void {
if (typeof this.modelValue !== 'object') {
this.$emit('update:modelValue', { __rl: true, value: this.modelValue, mode: value });
} else if (value === 'url' && this.modelValue && this.modelValue.cachedResultUrl) {
} else if (value === 'url' && this.modelValue?.cachedResultUrl) {
this.$emit('update:modelValue', {
__rl: true,
mode: value,
@ -621,9 +620,9 @@ export default defineComponent({
this.$telemetry.track(event, {
instance_id: this.rootStore.instanceId,
workflow_id: this.workflowsStore.workflowId,
node_type: this.node && this.node.type,
resource: this.node && this.node.parameters && this.node.parameters.resource,
operation: this.node && this.node.parameters && this.node.parameters.operation,
node_type: this.node?.type,
resource: this.node?.parameters && this.node.parameters.resource,
operation: this.node?.parameters && this.node.parameters.operation,
field_name: this.parameter.name,
...params,
});

View file

@ -65,7 +65,7 @@ function markAsReadOnly(field: ResourceMapperField): boolean {
const fieldsUi = computed<Array<Partial<INodeProperties> & { readOnly?: boolean }>>(() => {
return props.fieldsToMap
.filter((field) => field.display !== false && field.removed !== true)
.filter((field) => field.display && field.removed !== true)
.map((field) => {
return {
displayName: getFieldLabel(field),
@ -98,7 +98,7 @@ const orderedFields = computed<Array<Partial<INodeProperties> & { readOnly?: boo
});
const removedFields = computed<ResourceMapperField[]>(() => {
return props.fieldsToMap.filter((field) => field.removed === true && field.display !== false);
return props.fieldsToMap.filter((field) => field.removed === true && field.display);
});
const addFieldOptions = computed<Array<{ name: string; value: string; disabled?: boolean }>>(() => {
@ -132,7 +132,7 @@ const parameterActions = computed<Array<{ label: string; value: string; disabled
interpolate: { fieldWord: pluralFieldWordCapitalized.value },
}),
value: 'removeAllFields',
disabled: isRemoveAllAvailable.value === false,
disabled: !isRemoveAllAvailable.value,
},
];
},
@ -229,8 +229,8 @@ function getFieldIssues(field: INodeProperties): string[] {
let fieldIssues: string[] = [];
const key = `${props.parameter.name}.${fieldName}`;
if (nodeIssues['parameters'] && key in nodeIssues['parameters']) {
fieldIssues = fieldIssues.concat(nodeIssues['parameters'][key]);
if (nodeIssues.parameters && key in nodeIssues.parameters) {
fieldIssues = fieldIssues.concat(nodeIssues.parameters[key]);
}
return fieldIssues;
}

View file

@ -59,7 +59,7 @@ const emit = defineEmits<{
const availableMatchingFields = computed<ResourceMapperField[]>(() => {
return props.fieldsToMap.filter((field) => {
return (field.canBeUsedToMatch || field.defaultMatch) && field.display !== false;
return (field.canBeUsedToMatch || field.defaultMatch) && field.display;
});
});

View file

@ -173,9 +173,7 @@ const hasAvailableMatchingColumns = computed<boolean>(() => {
return (
state.paramValue.schema.filter(
(field) =>
(field.canBeUsedToMatch || field.defaultMatch) &&
field.display !== false &&
field.removed !== true,
(field.canBeUsedToMatch || field.defaultMatch) && field.display && field.removed !== true,
).length > 0
);
}

View file

@ -35,7 +35,7 @@ const schema = computed(() => getSchemaForExecutionData(props.data));
const isDataEmpty = computed(() => isEmpty(props.data));
const onDragStart = (el: HTMLElement) => {
if (el && el.dataset?.path) {
if (el?.dataset?.path) {
draggingPath.value = el.dataset.path;
}

View file

@ -160,10 +160,9 @@ import { defineComponent } from 'vue';
import type { PropType } from 'vue';
import { mapStores } from 'pinia';
import type { INodeUi, ITableData, NDVState } from '@/Interface';
import { getPairedItemId } from '@/utils';
import { getPairedItemId, shorten } from '@/utils';
import type { GenericValue, IDataObject, INodeExecutionData } from 'n8n-workflow';
import Draggable from './Draggable.vue';
import { shorten } from '@/utils';
import { externalHooks } from '@/mixins/externalHooks';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
@ -384,7 +383,7 @@ export default defineComponent({
this.ndvStore.resetMappingTelemetry();
},
onCellDragStart(el: HTMLElement) {
if (el && el.dataset.value) {
if (el?.dataset.value) {
this.draggingPath = el.dataset.value;
}

View file

@ -244,9 +244,7 @@ export default defineComponent({
showRemoveConfirm: false,
typeSelectValue: '',
typeSelectPlaceholder: 'Destination Type',
nodeParameters: deepCopy(
defaultMessageEventBusDestinationOptions,
) as MessageEventBusDestinationOptions,
nodeParameters: deepCopy(defaultMessageEventBusDestinationOptions),
webhookDescription: webhookModalDescription,
sentryDescription: sentryModalDescription,
syslogDescription: syslogModalDescription,
@ -466,7 +464,7 @@ export default defineComponent({
return;
}
const saveResult = await this.logStreamingStore.saveDestination(this.nodeParameters);
if (saveResult === true) {
if (saveResult) {
this.hasOnceBeenSaved = true;
this.testMessageSent = false;
this.unchanged = true;

View file

@ -16,8 +16,7 @@ import { acceptCompletion, autocompletion, ifNotIn } from '@codemirror/autocompl
import { indentWithTab, history, redo, toggleComment } from '@codemirror/commands';
import { bracketMatching, foldGutter, indentOnInput, LanguageSupport } from '@codemirror/language';
import { EditorState } from '@codemirror/state';
import type { Line } from '@codemirror/state';
import type { Extension } from '@codemirror/state';
import type { Line, Extension } from '@codemirror/state';
import {
dropCursor,
EditorView,

View file

@ -243,7 +243,7 @@ export default defineComponent({
this.workflowsStore.updateNodeProperties(updateInformation);
},
touchStart() {
if (this.isTouchDevice === true && this.isMacOs === false && this.isTouchActive === false) {
if (this.isTouchDevice === true && !this.isMacOs && !this.isTouchActive) {
this.isTouchActive = true;
setTimeout(() => {
this.isTouchActive = false;

View file

@ -68,9 +68,8 @@ import { MAX_TAG_NAME_LENGTH, TAGS_MANAGER_MODAL_KEY } from '@/constants';
import { useI18n, useToast } from '@/composables';
import { useUIStore } from '@/stores/ui.store';
import { useTagsStore } from '@/stores/tags.store';
import type { EventBus } from 'n8n-design-system';
import type { EventBus, N8nOption, N8nSelect } from 'n8n-design-system';
import type { PropType } from 'vue';
import type { N8nOption, N8nSelect } from 'n8n-design-system';
import { storeToRefs } from 'pinia';
type SelectRef = InstanceType<typeof N8nSelect>;

View file

@ -180,7 +180,7 @@ export default defineComponent({
focusOnInput(): void {
setTimeout(() => {
const inputRef = this.$refs.nameInput as N8nInputRef | undefined;
if (inputRef && inputRef.focus) {
if (inputRef?.focus) {
inputRef.focus();
}
}, INPUT_TRANSITION_TIMEOUT);
@ -189,7 +189,7 @@ export default defineComponent({
focusOnDelete(): void {
setTimeout(() => {
const inputRef = this.$refs.deleteHiddenInput as N8nInputRef | undefined;
if (inputRef && inputRef.focus) {
if (inputRef?.focus) {
inputRef.focus();
}
}, DELETE_TRANSITION_TIMEOUT);
@ -206,7 +206,7 @@ export default defineComponent({
},
watch: {
rows(newValue: ITagRow[] | undefined) {
if (newValue && newValue[0] && newValue[0].create) {
if (newValue?.[0] && newValue[0].create) {
this.focusOnCreate();
}
},

View file

@ -25,9 +25,7 @@ export default defineComponent({
return this.usersStore.currentUserId || '';
},
isTelemetryEnabledOnRoute(): boolean {
return this.$route.meta && this.$route.meta.telemetry
? !this.$route.meta.telemetry.disabled
: true;
return this.$route.meta?.telemetry ? !this.$route.meta.telemetry.disabled : true;
},
telemetry(): ITelemetrySettings {
return this.settingsStore.telemetry;

View file

@ -135,7 +135,7 @@ export default defineComponent({
return newItems;
}
if (inputData && inputData.options) {
if (inputData?.options) {
const newOptions = this.removeEmptyEntries(inputData.options);
if (Array.isArray(newOptions) && newOptions.length) {
// Has still options left so return
@ -391,7 +391,7 @@ export default defineComponent({
// Get json data
if (outputData.hasOwnProperty('json')) {
const jsonPropertyPrefix = useShort === true ? '$json' : `$('${nodeName}').item.json`;
const jsonPropertyPrefix = useShort ? '$json' : `$('${nodeName}').item.json`;
const jsonDataOptions: IVariableSelectorOption[] = [];
for (const propertyName of Object.keys(outputData.json)) {
@ -416,7 +416,7 @@ export default defineComponent({
// Get binary data
if (outputData.hasOwnProperty('binary')) {
const binaryPropertyPrefix = useShort === true ? '$binary' : `$('${nodeName}').item.binary`;
const binaryPropertyPrefix = useShort ? '$binary' : `$('${nodeName}').item.binary`;
const binaryData = [];
let binaryPropertyData = [];
@ -610,7 +610,7 @@ export default defineComponent({
let tempOptions: IVariableSelectorOption[];
if (executionData !== null && executionData.data !== undefined) {
if (executionData?.data !== undefined) {
const runExecutionData: IRunExecutionData = executionData.data;
tempOptions = this.getNodeContext(
@ -791,7 +791,7 @@ export default defineComponent({
} as IVariableSelectorOption,
];
if (executionData !== null && executionData.data !== undefined) {
if (executionData?.data !== undefined) {
const runExecutionData: IRunExecutionData = executionData.data;
parentNode = this.workflow.getParentNodes(nodeName, inputName, 1);

View file

@ -52,8 +52,7 @@ import NodeIcon from './NodeIcon.vue';
import TimeAgo from './TimeAgo.vue';
import Badge from './Badge.vue';
import WarningTooltip from './WarningTooltip.vue';
import type { IVersionNode } from '@/Interface';
import type { IVersion } from '@/Interface';
import type { IVersionNode, IVersion } from '@/Interface';
export default defineComponent({
name: 'VersionCard',

View file

@ -82,7 +82,7 @@ export default defineComponent({
return this.workflowActive === true && this.isWorkflowActive !== this.workflowActive;
},
getActiveColor(): string {
if (this.couldNotBeStarted === true) {
if (this.couldNotBeStarted) {
return '#ff4949';
}
return '#13ce66';

View file

@ -221,9 +221,7 @@ export default defineComponent({
return (
[
{
...(this.workflow && this.workflow.ownedBy
? this.workflow.ownedBy
: this.usersStore.currentUser),
...(this.workflow?.ownedBy ? this.workflow.ownedBy : this.usersStore.currentUser),
isOwner: true,
},
] as Array<Partial<IUser>>
@ -357,8 +355,8 @@ export default defineComponent({
(workflowSharee) => workflowSharee.id === sharee.id,
);
}) &&
!this.workflow.sharedWith!.find(
(workflowSharee) => workflowSharee.id === credential.ownedBy!.id,
!this.workflow.sharedWith.find(
(workflowSharee) => workflowSharee.id === credential.ownedBy.id,
);
}

View file

@ -109,7 +109,7 @@ export default defineComponent({
filtersLength(): number {
let length = 0;
(this.keys as string[]).forEach((key) => {
this.keys.forEach((key) => {
if (key === 'search') {
return;
}
@ -144,7 +144,7 @@ export default defineComponent({
} else {
const filters = { ...this.modelValue };
(this.keys as string[]).forEach((key) => {
this.keys.forEach((key) => {
filters[key] = Array.isArray(this.modelValue[key]) ? [] : '';
});

View file

@ -193,8 +193,7 @@ import ResourceOwnershipSelect from '@/components/forms/ResourceOwnershipSelect.
import ResourceFiltersDropdown from '@/components/forms/ResourceFiltersDropdown.vue';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import type { N8nInput } from 'n8n-design-system';
import type { DatatableColumn } from 'n8n-design-system';
import type { N8nInput, DatatableColumn } from 'n8n-design-system';
import { useI18n } from '@/composables';
export interface IResource {
@ -338,10 +337,7 @@ export default defineComponent({
if (this.filtersModel.sharedWith) {
matches =
matches &&
!!(
resource.sharedWith &&
resource.sharedWith.find((sharee) => sharee.id === this.filtersModel.sharedWith)
);
!!resource.sharedWith?.find((sharee) => sharee.id === this.filtersModel.sharedWith);
}
if (this.filtersModel.search) {
@ -360,20 +356,20 @@ export default defineComponent({
return filtered.sort((a, b) => {
switch (this.sortBy) {
case 'lastUpdated':
return this.sortFns['lastUpdated']
? this.sortFns['lastUpdated'](a, b)
return this.sortFns.lastUpdated
? this.sortFns.lastUpdated(a, b)
: new Date(b.updatedAt).valueOf() - new Date(a.updatedAt).valueOf();
case 'lastCreated':
return this.sortFns['lastCreated']
? this.sortFns['lastCreated'](a, b)
return this.sortFns.lastCreated
? this.sortFns.lastCreated(a, b)
: new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
case 'nameAsc':
return this.sortFns['nameAsc']
? this.sortFns['nameAsc'](a, b)
return this.sortFns.nameAsc
? this.sortFns.nameAsc(a, b)
: this.displayName(a).trim().localeCompare(this.displayName(b).trim());
case 'nameDesc':
return this.sortFns['nameDesc']
? this.sortFns['nameDesc'](a, b)
return this.sortFns.nameDesc
? this.sortFns.nameDesc(a, b)
: this.displayName(b).trim().localeCompare(this.displayName(a).trim());
default:
return this.sortFns[this.sortBy] ? this.sortFns[this.sortBy](a, b) : 0;

View file

@ -284,7 +284,7 @@ describe('useDataSchema', () => {
it('should return the correct data when using the generated json path on an object', () => {
const input = { people: ['Joe', 'John'] };
const schema = getSchema(input) as Schema;
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${((schema.value as Schema[])[0].value as Schema[])[0].path}`,
@ -297,7 +297,7 @@ describe('useDataSchema', () => {
{ name: 'John', age: 22, hobbies: ['surfing', 'traveling'] },
{ name: 'Joe', age: 33, hobbies: ['skateboarding', 'gaming'] },
];
const schema = getSchema(input) as Schema;
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${(((schema.value as Schema[])[0].value as Schema[])[2].value as Schema[])[1].path}`,
@ -307,7 +307,7 @@ describe('useDataSchema', () => {
it('should return the correct data when using the generated json path on a list of list', () => {
const input = [[1, 2]];
const schema = getSchema(input) as Schema;
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${((schema.value as Schema[])[0].value as Schema[])[1].path}`,
@ -322,7 +322,7 @@ describe('useDataSchema', () => {
{ name: 'Joe', age: 33 },
],
];
const schema = getSchema(input) as Schema;
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${(((schema.value as Schema[])[0].value as Schema[])[1].value as Schema[])[1].path}`,
@ -339,7 +339,7 @@ describe('useDataSchema', () => {
],
},
];
const schema = getSchema(input) as Schema;
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${

View file

@ -127,8 +127,8 @@ export default function useCanvasMouseSelect() {
}
function mouseUpMouseSelect(e: MouseEvent) {
if (selectActive.value === false) {
if (isTouchDevice === true && e.target instanceof HTMLElement) {
if (!selectActive.value) {
if (isTouchDevice && e.target instanceof HTMLElement) {
if (e.target && e.target.id.includes('node-view')) {
// Deselect all nodes
deselectAllNodes();
@ -156,7 +156,7 @@ export default function useCanvasMouseSelect() {
_hideSelectBox();
}
function mouseDownMouseSelect(e: MouseEvent, moveButtonPressed: boolean) {
if (isCtrlKeyPressed(e) === true || moveButtonPressed) {
if (isCtrlKeyPressed(e) || moveButtonPressed) {
// We only care about it when the ctrl key is not pressed at the same time.
// So we exit when it is pressed.
return;

View file

@ -19,7 +19,7 @@ export default function useDeviceSupportHelpers(): DeviceSupportHelpers {
const controlKeyCode = ref(isMacOs.value ? 'Meta' : 'Control');
function isCtrlKeyPressed(e: MouseEvent | KeyboardEvent): boolean {
if (isTouchDevice.value === true && e instanceof MouseEvent) {
if (isTouchDevice.value && e instanceof MouseEvent) {
return true;
}
if (isMacOs.value) {

View file

@ -1,12 +1,11 @@
import { MAIN_HEADER_TABS } from '@/constants';
import { useNDVStore } from '@/stores/ndv.store';
import type { Undoable } from '@/models/history';
import { BulkCommand } from '@/models/history';
import { BulkCommand, Command } from '@/models/history';
import { useHistoryStore } from '@/stores/history.store';
import { useUIStore } from '@/stores/ui.store';
import { ref, onMounted, onUnmounted, nextTick, getCurrentInstance } from 'vue';
import { Command } from '@/models/history';
import { useDebounceHelper } from './useDebounce';
import useDeviceSupportHelpers from './useDeviceSupport';
import { getNodeViewTab } from '@/utils';

View file

@ -219,9 +219,8 @@ export const REQUEST_NODE_FORM_URL = 'https://n8n-community.typeform.com/to/K1fB
// Node Connection Types
export const NODE_CONNECTION_TYPE_ALLOW_MULTIPLE: NodeConnectionType[] = [
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
NodeConnectionType.AiTool,
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
NodeConnectionType.Main,
];

View file

@ -15,7 +15,7 @@ export const copyPaste = defineComponent({
};
},
mounted() {
if (this.copyPasteElementsGotCreated === true) {
if (this.copyPasteElementsGotCreated) {
return;
}
@ -111,7 +111,7 @@ export const copyPaste = defineComponent({
// Check if the event got emitted from a message box or from something
// else which should ignore the copy/paste
// @ts-ignore
const path = e.path || (e.composedPath && e.composedPath());
const path = e.path || e.composedPath?.();
for (let index = 0; index < path.length; index++) {
if (
path[index].className &&

View file

@ -30,7 +30,7 @@ export const moveNodeWorkflow = defineComponent({
this.moveLastPosition[1] = y;
},
mouseDownMoveWorkflow(e: MouseEvent, moveButtonPressed: boolean) {
if (this.isCtrlKeyPressed(e) === false && !moveButtonPressed) {
if (!this.isCtrlKeyPressed(e) && !moveButtonPressed) {
// We only care about it when the ctrl key is pressed at the same time.
// So we exit when it is not pressed.
return;
@ -55,7 +55,7 @@ export const moveNodeWorkflow = defineComponent({
this.$el.addEventListener('mousemove', this.mouseMoveNodeWorkflow);
},
mouseUpMoveWorkflow(e: MouseEvent) {
if (this.uiStore.nodeViewMoveInProgress === false) {
if (!this.uiStore.nodeViewMoveInProgress) {
// If it is not active return directly.
// Else normal node dragging will not work.
return;

View file

@ -284,7 +284,7 @@ export const pushConnection = defineComponent({
// The workflow finished executing
let pushData: IPushDataExecutionFinished;
if (receivedData.type === 'executionRecovered' && recoveredPushData !== undefined) {
pushData = recoveredPushData as IPushDataExecutionFinished;
pushData = recoveredPushData;
} else {
pushData = receivedData.data as IPushDataExecutionFinished;
}
@ -329,12 +329,7 @@ export const pushConnection = defineComponent({
);
}
const lineNumber =
runDataExecuted &&
runDataExecuted.data &&
runDataExecuted.data.resultData &&
runDataExecuted.data.resultData.error &&
runDataExecuted.data.resultData.error.lineNumber;
const lineNumber = runDataExecuted?.data?.resultData?.error?.lineNumber;
codeNodeEditorEventBus.emit('error-line-number', lineNumber || 'final');
@ -449,16 +444,13 @@ export const pushConnection = defineComponent({
this.titleSet(workflow.name as string, 'IDLE');
const execution = this.workflowsStore.getWorkflowExecution;
if (execution && execution.executedNode) {
if (execution?.executedNode) {
const node = this.workflowsStore.getNodeByName(execution.executedNode);
const nodeType = node && this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
const nodeOutput =
execution &&
execution.executedNode &&
execution.data &&
execution.data.resultData &&
execution.data.resultData.runData &&
execution.data.resultData.runData[execution.executedNode];
execution.data?.resultData?.runData?.[execution.executedNode];
if (nodeType && nodeType.polling && !nodeOutput) {
this.showMessage({
title: this.$locale.baseText('pushConnection.pollingNode.dataNotFound', {
@ -507,12 +499,11 @@ export const pushConnection = defineComponent({
let itemsCount = 0;
if (
lastNodeExecuted &&
runDataExecuted.data.resultData.runData[lastNodeExecuted as string] &&
runDataExecuted.data.resultData.runData[lastNodeExecuted] &&
!runDataExecutedErrorMessage
) {
itemsCount =
runDataExecuted.data.resultData.runData[lastNodeExecuted as string][0].data!.main[0]!
.length;
runDataExecuted.data.resultData.runData[lastNodeExecuted][0].data!.main[0]!.length;
}
void this.$externalHooks().run('pushConnection.executionFinished', {
@ -596,7 +587,7 @@ export const pushConnection = defineComponent({
interpolate: { error: '!' },
});
if (error && error.message) {
if (error?.message) {
let nodeName: string | undefined;
if ('node' in error) {
nodeName = typeof error.node === 'string' ? error.node : error.node!.name;

View file

@ -17,7 +17,7 @@ export const userHelpers = defineComponent({
},
canUserAccessRoute(route: RouteLocation): boolean {
const permissions: IPermissions = route.meta && route.meta.permissions;
const permissions: IPermissions = route.meta?.permissions;
const usersStore = useUsersStore();
const currentUser = usersStore.currentUser;

View file

@ -40,7 +40,7 @@ export const workflowActivate = defineComponent({
telemetrySource?: string,
) {
this.updatingWorkflowActivation = true;
const nodesIssuesExist = this.workflowsStore.nodesIssuesExist as boolean;
const nodesIssuesExist = this.workflowsStore.nodesIssuesExist;
let currWorkflowId: string | undefined = workflowId;
if (!currWorkflowId || currWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
@ -49,7 +49,7 @@ export const workflowActivate = defineComponent({
this.updatingWorkflowActivation = false;
return;
}
currWorkflowId = this.workflowsStore.workflowId as string;
currWorkflowId = this.workflowsStore.workflowId;
}
const isCurrentWorkflow = currWorkflowId === this.workflowsStore.workflowId;
@ -76,7 +76,7 @@ export const workflowActivate = defineComponent({
return;
}
if (isCurrentWorkflow && nodesIssuesExist && newActiveState === true) {
if (isCurrentWorkflow && nodesIssuesExist && newActiveState) {
this.showMessage({
title: this.$locale.baseText(
'workflowActivator.showMessage.activeChangedNodesIssuesExistTrue.title',
@ -96,7 +96,7 @@ export const workflowActivate = defineComponent({
!this.uiStore.stateIsDirty,
);
} catch (error) {
const newStateName = newActiveState === true ? 'activated' : 'deactivated';
const newStateName = newActiveState ? 'activated' : 'deactivated';
this.showError(
error,
this.$locale.baseText('workflowActivator.showError.title', {

View file

@ -1,6 +1,5 @@
import type { INodeUi } from '@/Interface';
import type { INodeUi, XYPosition } from '@/Interface';
import type { IConnection } from 'n8n-workflow';
import type { XYPosition } from '../Interface';
import { createEventBus } from 'n8n-design-system/utils';
// Command names don't serve any particular purpose in the app
@ -48,7 +47,9 @@ export class BulkCommand extends Undoable {
export class MoveNodeCommand extends Command {
nodeName: string;
oldPosition: XYPosition;
newPosition: XYPosition;
constructor(nodeName: string, oldPosition: XYPosition, newPosition: XYPosition) {
@ -196,7 +197,9 @@ export class RemoveConnectionCommand extends Command {
export class EnableNodeToggleCommand extends Command {
nodeName: string;
oldState: boolean;
newState: boolean;
constructor(nodeName: string, oldState: boolean, newState: boolean) {
@ -229,6 +232,7 @@ export class EnableNodeToggleCommand extends Command {
export class RenameNodeCommand extends Command {
currentName: string;
newName: string;
constructor(currentName: string, newName: string) {

View file

@ -61,17 +61,11 @@ export const getCredentialPermissions = (user: IUser | null, credential: ICreden
{
name: UserRole.ResourceOwner,
test: () =>
!!(credential && credential.ownedBy && credential.ownedBy.id === user?.id) ||
!isSharingEnabled,
!!(credential?.ownedBy && credential.ownedBy.id === user?.id) || !isSharingEnabled,
},
{
name: UserRole.ResourceSharee,
test: () =>
!!(
credential &&
credential.sharedWith &&
credential.sharedWith.find((sharee) => sharee.id === user?.id)
),
test: () => !!credential?.sharedWith?.find((sharee) => sharee.id === user?.id),
},
{
name: 'read',
@ -100,17 +94,12 @@ export const getWorkflowPermissions = (user: IUser | null, workflow: IWorkflowDb
{
name: UserRole.ResourceOwner,
test: () =>
!!(isNewWorkflow || (workflow && workflow.ownedBy && workflow.ownedBy.id === user?.id)) ||
!!(isNewWorkflow || (workflow?.ownedBy && workflow.ownedBy.id === user?.id)) ||
!isSharingEnabled,
},
{
name: UserRole.ResourceSharee,
test: () =>
!!(
workflow &&
workflow.sharedWith &&
workflow.sharedWith.find((sharee) => sharee.id === user?.id)
),
test: () => !!workflow?.sharedWith?.find((sharee) => sharee.id === user?.id),
},
{
name: 'read',

View file

@ -291,7 +291,7 @@ const executeData: IExecuteData = {
data: runExecutionData.resultData.runData[lastNodeName][0].data!,
node: nodes.find((node) => node.name === lastNodeName) as INode,
source: {
main: runExecutionData.resultData.runData[lastNodeName][0].source!,
main: runExecutionData.resultData.runData[lastNodeName][0].source,
},
};

View file

@ -1,6 +1,5 @@
import type { IDataObject, DocMetadata, NativeDoc } from 'n8n-workflow';
import { Expression } from 'n8n-workflow';
import { ExpressionExtensions, NativeMethods } from 'n8n-workflow';
import { Expression, ExpressionExtensions, NativeMethods } from 'n8n-workflow';
import { DateTime } from 'luxon';
import { i18n } from '@/plugins/i18n';
import { resolveParameter } from '@/mixins/workflowHelpers';
@ -196,7 +195,7 @@ const createCompletionOption = (
const descriptionLink = document.createElement('a');
descriptionLink.setAttribute('target', '_blank');
descriptionLink.setAttribute('href', docInfo.doc.docURL);
descriptionLink.innerText = i18n.autocompleteUIValues['docLinkLabel'] || 'Learn more';
descriptionLink.innerText = i18n.autocompleteUIValues.docLinkLabel || 'Learn more';
descriptionLink.addEventListener('mousedown', (event: MouseEvent) => {
// This will prevent documentation popup closing before click
// event gets to links

View file

@ -2,8 +2,7 @@ import type { Plugin } from 'vue';
import 'regenerator-runtime/runtime';
import ElementPlus from 'element-plus';
import { ElLoading, ElMessageBox } from 'element-plus';
import ElementPlus, { ElLoading, ElMessageBox } from 'element-plus';
import { N8nPlugin } from 'n8n-design-system';
import { useMessage } from '@/composables/useMessage';
import EnterpriseEdition from '@/components/EnterpriseEdition.ee.vue';

View file

@ -14,7 +14,7 @@ import { BezierSegment } from '@jsplumb/connector-bezier';
import { isArray } from 'lodash-es';
import { deepCopy } from 'n8n-workflow';
export interface N8nConnectorOptions extends ConnectorOptions {}
export type N8nConnectorOptions = ConnectorOptions;
interface N8nConnectorPaintGeometry extends PaintGeometry {
sourceEndpoint: Endpoint;
targetEndpoint: Endpoint;
@ -140,22 +140,37 @@ const stubCalculators = {
export class N8nConnector extends AbstractConnector {
static type = 'N8nConnector';
type = N8nConnector.type;
majorAnchor: number;
minorAnchor: number;
midpoint: number;
alwaysRespectStubs: boolean;
loopbackVerticalLength: number;
lastx: number | null;
lasty: number | null;
cornerRadius: number;
loopbackMinimum: number;
curvinessCoefficient: number;
zBezierOffset: number;
targetGap: number;
overrideTargetEndpoint: Endpoint | null;
getEndpointOffset: Function | null;
private internalSegments: FlowchartSegment[] = [];
constructor(
@ -340,7 +355,7 @@ export class N8nConnector extends AbstractConnector {
}
calculateStubSegment(paintInfo: PaintGeometry): StubPositions {
return stubCalculators['opposite'](paintInfo, {
return stubCalculators.opposite(paintInfo, {
axis: paintInfo.sourceAxis,
alwaysRespectStubs: this.alwaysRespectStubs,
});
@ -366,7 +381,7 @@ export class N8nConnector extends AbstractConnector {
// original flowchart behavior
midy = paintInfo.startStubY + (paintInfo.endStubY - paintInfo.startStubY) * this.midpoint;
}
return lineCalculators['opposite'](paintInfo, { axis, startStub, endStub, idx, midx, midy });
return lineCalculators.opposite(paintInfo, { axis, startStub, endStub, idx, midx, midy });
}
_getPaintInfo(params: ConnectorComputeParams): N8nConnectorPaintGeometry {
@ -494,6 +509,7 @@ export class N8nConnector extends AbstractConnector {
}
} catch (error) {}
}
/**
* Set target endpoint
* (to override default behavior tracking mouse when dragging mouse)
@ -502,9 +518,11 @@ export class N8nConnector extends AbstractConnector {
setTargetEndpoint(endpoint: Endpoint) {
this.overrideTargetEndpoint = endpoint;
}
resetTargetEndpoint() {
this.overrideTargetEndpoint = null;
}
_computeBezier(paintInfo: N8nConnectorPaintGeometry) {
const sp = paintInfo.sourcePos;
const tp = paintInfo.targetPos;

View file

@ -51,10 +51,10 @@ export class I18nClass {
options?: { adjustToNumber?: number; interpolate?: { [key: string]: string } },
): string {
if (options?.adjustToNumber !== undefined) {
return this.i18n.tc(key, options.adjustToNumber, options && options.interpolate).toString();
return this.i18n.tc(key, options.adjustToNumber, options?.interpolate).toString();
}
return this.i18n.t(key, options && options.interpolate).toString();
return this.i18n.t(key, options?.interpolate).toString();
}
/**
@ -164,7 +164,7 @@ export class I18nClass {
nodeText() {
const ndvStore = useNDVStore();
const activeNode = ndvStore.activeNode;
const nodeType = activeNode ? this.shortNodeType(activeNode.type as string) : ''; // unused in eventTriggerDescription
const nodeType = activeNode ? this.shortNodeType(activeNode.type) : ''; // unused in eventTriggerDescription
const initialKey = `n8n-nodes-base.nodes.${nodeType}.nodeView`;
const context = this;

View file

@ -30,18 +30,22 @@ export class N8nAddInputEndpoint extends EndpointRepresentation<ComputedN8nAddIn
}
static type = N8nAddInputEndpointType;
type = N8nAddInputEndpoint.type;
setupOverlays() {
this.endpoint.instance.setSuspendDrawing(true);
this.endpoint.instance.setSuspendDrawing(false);
}
bindEvents() {
this.instance.bind(EVENT_ENDPOINT_CLICK, this.fireClickEvent);
}
unbindEvents() {
this.instance.unbind(EVENT_ENDPOINT_CLICK, this.fireClickEvent);
}
fireClickEvent = (endpoint: Endpoint) => {
if (endpoint === this.endpoint) {
this.instance.fire(EVENT_ADD_INPUT_ENDPOINT_CLICK, this.endpoint);

View file

@ -250,8 +250,8 @@ export const useCanvasStore = defineStore('canvas', () => {
}
newNodePosition = [
parseInt(element.style.left!.slice(0, -2), 10),
parseInt(element.style.top!.slice(0, -2), 10),
parseInt(element.style.left.slice(0, -2), 10),
parseInt(element.style.top.slice(0, -2), 10),
];
const updateInformation = {

View file

@ -58,8 +58,7 @@ export const useSegment = defineStore('segment', () => {
const node = workflowsStore.getNodeByName(nodeName);
const nodeTypeName = node ? node.type : 'unknown';
if (
nodeRunData[0].data &&
nodeRunData[0].data.main &&
nodeRunData[0].data?.main &&
nodeRunData[0].data.main.some((out) => out && out?.length > 1)
) {
multipleOutputNodes.add(nodeTypeName);

View file

@ -4,9 +4,8 @@ import { EnterpriseEditionFeature } from '@/constants';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useSettingsStore } from '@/stores/settings.store';
import * as ssoApi from '@/api/sso';
import type { SamlPreferences } from '@/Interface';
import type { SamlPreferences, SamlPreferencesExtractedData } from '@/Interface';
import { updateCurrentUser } from '@/api/users';
import type { SamlPreferencesExtractedData } from '@/Interface';
import { useUsersStore } from '@/stores/users.store';
export const useSSOStore = defineStore('sso', () => {

View file

@ -102,7 +102,7 @@ export const useUsersStore = defineStore(STORES.USERS, {
return false;
},
personalizedNodeTypes(): string[] {
const user = this.currentUser as IUser | null;
const user = this.currentUser;
if (!user) {
return [];
}

View file

@ -18,7 +18,7 @@ export const useWorkflowsEEStore = defineStore(STORES.WORKFLOWS_EE, {
fallback = i18n.baseText('workflows.shareModal.info.sharee.fallback'),
): string => {
const workflow = useWorkflowsStore().getWorkflowById(workflowId);
return workflow && workflow.ownedBy && workflow.ownedBy.firstName
return workflow?.ownedBy?.firstName
? `${workflow.ownedBy.firstName} ${workflow.ownedBy.lastName} (${workflow.ownedBy.email})`
: fallback;
};

View file

@ -1,12 +1,7 @@
import type { AxiosRequestConfig, Method } from 'axios';
import axios from 'axios';
import type { IDataObject } from 'n8n-workflow';
import type {
IExecutionFlattedResponse,
IExecutionResponse,
IRestApiContext,
IWorkflowDb,
} from '@/Interface';
import type { IExecutionFlattedResponse, IExecutionResponse, IRestApiContext } from '@/Interface';
import { parse } from 'flatted';
export const NO_NETWORK_ERROR_CODE = 999;
@ -150,7 +145,7 @@ export function unflattenExecutionData(
// Unflatten the data
const returnData: IExecutionResponse = {
...fullExecutionData,
workflowData: fullExecutionData.workflowData as IWorkflowDb,
workflowData: fullExecutionData.workflowData,
data: parse(fullExecutionData.data),
};

View file

@ -23,7 +23,7 @@ export function getSourceItems(data: IExecutionResponse, target: TargetItem): Ta
}
const item = taskData?.data?.main?.[target.outputIndex]?.[target.itemIndex];
if (!item || item.pairedItem === undefined) {
if (item?.pairedItem === undefined) {
return [];
}

Some files were not shown because too many files have changed in this diff Show more