n8n/packages/workflow/src/Extensions/DateExtensions.ts

284 lines
7.3 KiB
TypeScript
Raw Normal View History

feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/explicit-member-accessibility */
import {
DateTime,
DateTimeFormatOptions,
DateTimeUnit,
Duration,
DurationLike,
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
DurationObjectUnits,
LocaleOptions,
} from 'luxon';
import type { ExtensionMap } from './Extensions';
type DurationUnit =
| 'milliseconds'
| 'seconds'
| 'minutes'
| 'hours'
| 'days'
| 'weeks'
| 'months'
| 'quarter'
| 'years';
type DatePart =
| 'day'
| 'month'
| 'year'
| 'hour'
| 'minute'
| 'second'
| 'millisecond'
| 'weekNumber'
| 'yearDayNumber'
| 'weekday';
const DURATION_MAP: Record<string, DurationUnit> = {
day: 'days',
month: 'months',
year: 'years',
week: 'weeks',
hour: 'hours',
minute: 'minutes',
second: 'seconds',
millisecond: 'milliseconds',
ms: 'milliseconds',
sec: 'seconds',
secs: 'seconds',
hr: 'hours',
hrs: 'hours',
min: 'minutes',
mins: 'minutes',
};
const DATETIMEUNIT_MAP: Record<string, DateTimeUnit> = {
days: 'day',
months: 'month',
years: 'year',
hours: 'hour',
minutes: 'minute',
seconds: 'second',
milliseconds: 'millisecond',
hrs: 'hour',
hr: 'hour',
mins: 'minute',
min: 'minute',
secs: 'second',
sec: 'second',
ms: 'millisecond',
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isDateTime(date: any): date is DateTime {
if (date) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
return DateTime.isDateTime(date);
}
return false;
}
function generateDurationObject(durationValue: number, unit: DurationUnit) {
const convertedUnit = DURATION_MAP[unit] || unit;
return { [`${convertedUnit}`]: durationValue } as DurationObjectUnits;
}
function beginningOf(date: Date | DateTime, extraArgs: DurationUnit[]): Date {
const [unit = 'week'] = extraArgs;
if (isDateTime(date)) {
return date.startOf(DATETIMEUNIT_MAP[unit] || unit).toJSDate();
}
let datetime = DateTime.fromJSDate(date);
if (date.getTimezoneOffset() === 0) {
datetime = datetime.setZone('UTC');
}
return datetime.startOf(DATETIMEUNIT_MAP[unit] || unit).toJSDate();
}
function endOfMonth(date: Date | DateTime): Date {
if (isDateTime(date)) {
return date.endOf('month').toJSDate();
}
return DateTime.fromJSDate(date).endOf('month').toJSDate();
}
function extract(inputDate: Date | DateTime, extraArgs: DatePart[]): number | Date {
const [part] = extraArgs;
let date = inputDate;
if (isDateTime(date)) {
date = date.toJSDate();
}
if (part === 'yearDayNumber') {
const firstDayOfTheYear = new Date(date.getFullYear(), 0, 0);
const diff =
date.getTime() -
firstDayOfTheYear.getTime() +
(firstDayOfTheYear.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000;
return Math.floor(diff / (1000 * 60 * 60 * 24));
}
return DateTime.fromJSDate(date).get((DATETIMEUNIT_MAP[part] as keyof DateTime) || part);
}
function format(date: Date | DateTime, extraArgs: unknown[]): string {
const [dateFormat, localeOpts = {}] = extraArgs as [string, LocaleOptions];
if (isDateTime(date)) {
return date.toFormat(dateFormat, { ...localeOpts });
}
return DateTime.fromJSDate(date).toFormat(dateFormat, { ...localeOpts });
}
function isBetween(date: Date | DateTime, extraArgs: unknown[]): boolean {
const [first, second] = extraArgs as string[];
const firstDate = new Date(first);
const secondDate = new Date(second);
if (firstDate > secondDate) {
return secondDate < date && date < firstDate;
}
return secondDate > date && date > firstDate;
}
function isDst(date: Date | DateTime): boolean {
if (isDateTime(date)) {
return date.isInDST;
}
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
return DateTime.fromJSDate(date).isInDST;
}
function isInLast(date: Date | DateTime, extraArgs: unknown[]): boolean {
const [durationValue = 0, unit = 'minutes'] = extraArgs as [number, DurationUnit];
const dateInThePast = DateTime.now().minus(generateDurationObject(durationValue, unit));
let thisDate = date;
if (!isDateTime(thisDate)) {
thisDate = DateTime.fromJSDate(thisDate);
}
return dateInThePast <= thisDate && thisDate <= DateTime.now();
}
function isWeekend(date: Date | DateTime): boolean {
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
enum DAYS {
saturday = 6,
sunday = 7,
}
if (isDateTime(date)) {
return [DAYS.saturday, DAYS.sunday].includes(date.weekday);
}
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
return [DAYS.saturday, DAYS.sunday].includes(DateTime.fromJSDate(date).weekday);
}
function minus(date: Date | DateTime, extraArgs: unknown[]): Date | DateTime {
if (isDateTime(date) && extraArgs.length === 1) {
return date.minus(extraArgs[0] as DurationLike);
}
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
const [durationValue = 0, unit = 'minutes'] = extraArgs as [number, DurationUnit];
if (isDateTime(date)) {
return date.minus(generateDurationObject(durationValue, unit)).toJSDate();
}
return DateTime.fromJSDate(date).minus(generateDurationObject(durationValue, unit)).toJSDate();
}
function plus(date: Date | DateTime, extraArgs: unknown[]): Date | DateTime {
if (isDateTime(date) && extraArgs.length === 1) {
return date.plus(extraArgs[0] as DurationLike);
}
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
const [durationValue = 0, unit = 'minutes'] = extraArgs as [number, DurationUnit];
if (isDateTime(date)) {
return date.plus(generateDurationObject(durationValue, unit)).toJSDate();
}
return DateTime.fromJSDate(date).plus(generateDurationObject(durationValue, unit)).toJSDate();
}
function toLocaleString(date: Date | DateTime, extraArgs: unknown[]): string {
const [locale, dateFormat = { timeStyle: 'short', dateStyle: 'short' }] = extraArgs as [
string | undefined,
DateTimeFormatOptions,
];
if (isDateTime(date)) {
return date.toLocaleString(dateFormat, { locale });
}
return DateTime.fromJSDate(date).toLocaleString(dateFormat, { locale });
}
function toTimeFromNow(date: Date | DateTime): string {
feat: Expression extension framework (#4372) * :zap: Introduce a framework for expression extension * :bulb: Add some inline comments * :zap: Introduce hash alias for encrypt * :zap: Introduce a manual granular level approach to shadowing/overrideing extensions * :fire: Cleanup comments * :zap: Introduce a basic method of extension for native functions * :zap: Add length to StringExtension * :zap: Add number type to extension return types * :zap: Temporarily introduce DateTime with extension * :zap: Cleanup comments * :zap: Organize imports * :recycle: Fix up some typings * :zap: Fix typings * :recycle: Remove unnecessary resolve of expression * :zap: Extensions Improvement * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Refactor EXPRESSION_EXTENSION_METHODS * :recycle: Update extraArgs types * :recycle: Fix tests * :recycle: Fix bind type issue * :recycle: Fixing duration type issue * :recycle: Refactor to allow overrides on native methods * :recycle: Temporarily remove Date Extensions to pass tests * feat(dt-functions): introduce date expression extensions (#4045) * :tada: Add Date Extensions into the mix * :sparkles: Introduce additional date extension methods * :white_check_mark: Add Date Expression Extension tests * :wrench: Add ability to debug tests * :recycle: Refactor extension for native types * :fire: Move sayHi method to String Extension class * :recycle: Update scope when binding member methods * :white_check_mark: Add String Extension tests * feat(dt-functions): introduce array expression extensions (#4044) * :sparkles: Introduce Array Extensions * :white_check_mark: Add Array Expression tests * feat(dt-functions): introduce number expression extensions (#4046) * :tada: Introduce Number Extensions * :zap: Support more shared extensions * :zap: Improve handling of name collision * :white_check_mark: Update tests * Fixed up tests * :fire: Remove remove markdown * :recylce: Replace remove-markdown dependencies with implementation * :recycle: Replace remove-markdown dependencies with implementation * :white_check_mark: Update tests * :recycle: Fix scoping and cleanup * :recycle: Update comments and errors * :recycle: Fix linting errors * :heavy_minus_sign: Remove unused dependencies * fix: expression extension not working with multiple extensions * refactor: change extension transform to be more efficient * test: update most test to work with new extend function * fix: update and fix type error in config * refactor: replace babel with recast * feat: add hashing functions to string extension * fix: removed export * test: add extension parser and transform tests * fix: vite tests breaking * refactor: remove commented out code * fix: parse dates passed from $json in extend function * refactor: review feedback changes for date extensions * refactor: review feedback changes for number extensions * fix: date extension beginningOf test * fix: broken build from merge * fix: another merge issue * refactor: address review feedback (remove ignores) * feat: new extension functions and tests * feat: non-dot notation functions * test: most of the other tests * fix: toSentenceCase for node versions below 16.6 * feat: add $if and $not expression extensions * Fix test to work on every timezone * lint: fix remaining lint issues Co-authored-by: Csaba Tuncsik <csaba@n8n.io> Co-authored-by: Omar Ajoue <krynble@gmail.com>
2023-01-10 05:06:12 -08:00
let diffObj: Duration;
if (isDateTime(date)) {
diffObj = date.diffNow();
} else {
diffObj = DateTime.fromJSDate(date).diffNow();
}
const as = (unit: DurationUnit) => {
return Math.round(Math.abs(diffObj.as(unit)));
};
if (as('years')) {
return `${as('years')} years ago`;
}
if (as('months')) {
return `${as('months')} months ago`;
}
if (as('weeks')) {
return `${as('weeks')} weeks ago`;
}
if (as('days')) {
return `${as('days')} days ago`;
}
if (as('hours')) {
return `${as('hours')} hours ago`;
}
if (as('minutes')) {
return `${as('minutes')} minutes ago`;
}
if (as('seconds') && as('seconds') > 10) {
return `${as('seconds')} seconds ago`;
}
return 'just now';
}
function timeTo(date: Date | DateTime, extraArgs: unknown[]): Duration {
const [diff = new Date().toISOString(), unit = 'seconds'] = extraArgs as [string, DurationUnit];
const diffDate = new Date(diff);
if (isDateTime(date)) {
return date.diff(DateTime.fromJSDate(diffDate), DURATION_MAP[unit] || unit);
}
return DateTime.fromJSDate(date).diff(DateTime.fromJSDate(diffDate), DURATION_MAP[unit] || unit);
}
function toDate(date: Date | DateTime) {
if (isDateTime(date)) {
return date.set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).toJSDate();
}
let datetime = DateTime.fromJSDate(date);
if (date.getTimezoneOffset() === 0) {
datetime = datetime.setZone('UTC');
}
return datetime.set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).toJSDate();
}
export const dateExtensions: ExtensionMap = {
typeName: 'Date',
functions: {
beginningOf,
endOfMonth,
extract,
isBetween,
isDst,
isInLast,
isWeekend,
minus,
plus,
toTimeFromNow,
timeTo,
format,
toLocaleString,
toDate,
},
};