n8n/packages/nodes-base/nodes/Schedule/GenericFunctions.ts
agobrech 2aef9de148
fix(Schedule Trigger Node): Follow the correct Unix cron format for month and days of the week (#6401)
* Handle conversion to correct unix format

* Fix intervals, ranges for months

* fix regex to match 10, 11, 12

---------

Co-authored-by: Marcus <marcus@n8n.io>
2023-06-13 18:57:17 +02:00

84 lines
2.8 KiB
TypeScript

import type { IDataObject } from 'n8n-workflow';
import type { IRecurencyRule } from './SchedulerInterface';
import moment from 'moment';
export function recurencyCheck(
recurrency: IRecurencyRule,
recurrencyRules: number[],
timezone: string,
): boolean {
const recurrencyRuleIndex = recurrency.index;
const intervalSize = recurrency.intervalSize;
const typeInterval = recurrency.typeInterval;
const lastExecution =
recurrencyRuleIndex !== undefined ? recurrencyRules[recurrencyRuleIndex] : undefined;
if (
intervalSize &&
recurrencyRuleIndex !== undefined &&
(typeInterval === 'weeks' || typeInterval === 'undefined')
) {
if (
lastExecution === undefined || // First time executing this rule
moment.tz(timezone).week() === (intervalSize + lastExecution) % 52 || // not first time, but minimum interval has passed
moment.tz(timezone).week() === lastExecution // Trigger on multiple days in the same week
) {
recurrencyRules[recurrencyRuleIndex] = moment.tz(timezone).week();
return true;
}
} else if (intervalSize && recurrencyRuleIndex !== undefined && typeInterval === 'days') {
if (
lastExecution === undefined ||
moment.tz(timezone).dayOfYear() === (intervalSize + lastExecution) % 365
) {
recurrencyRules[recurrencyRuleIndex] = moment.tz(timezone).dayOfYear();
return true;
}
} else if (intervalSize && recurrencyRuleIndex !== undefined && typeInterval === 'hours') {
if (
lastExecution === undefined ||
moment.tz(timezone).hour() === (intervalSize + lastExecution) % 24
) {
recurrencyRules[recurrencyRuleIndex] = moment.tz(timezone).hour();
return true;
}
} else if (intervalSize && recurrencyRuleIndex !== undefined && typeInterval === 'months') {
if (
lastExecution === undefined ||
moment.tz(timezone).month() === (intervalSize + lastExecution) % 12
) {
recurrencyRules[recurrencyRuleIndex] = moment.tz(timezone).month();
return true;
}
} else {
return true;
}
return false;
}
export function convertMonthToUnix(expression: string): string {
if (!isNaN(parseInt(expression)) || expression.includes('-') || expression.includes(',')) {
let matches = expression.match(/([0-9])+/g) as string[];
if (matches) {
matches = matches.map((match) =>
parseInt(match) !== 0 ? String(parseInt(match) - 1) : match,
);
}
expression = matches?.join(expression.includes('-') ? '-' : ',') || '';
}
return expression;
}
export function convertToUnixFormat(interval: IDataObject) {
const expression = (interval.expression as string).split(' ');
if (expression.length === 5) {
expression[3] = convertMonthToUnix(expression[3]);
expression[4] = expression[4].replace('7', '0');
} else if (expression.length === 6) {
expression[4] = convertMonthToUnix(expression[4]);
expression[5] = expression[5].replace('7', '0');
}
interval.expression = expression.join(' ');
}