next-day-of-week.ts•3.88 kB
import {
Property,
createAction,
} from '@activepieces/pieces-framework';
import {
optionalTimeFormats,
timeFormat,
timeFormatDescription,
timeZoneOptions,
getCorrectedFormat,
} from '../common';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import { z } from 'zod';
import { propsValidation } from '@activepieces/pieces-common';
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(advancedFormat);
export const nextDayofWeek = createAction({
name: 'next_day_of_week',
displayName: 'Next Day of Week',
description: 'Get the date and time of the next day of the week',
errorHandlingOptions: {
continueOnFailure: {
hide: true,
},
retryOnFailure: {
hide: true,
},
},
props: {
weekday: Property.StaticDropdown({
displayName: 'Weekday',
description:
'The weekday that you would like to get the date and time of.',
options: {
options: [
{ label: 'Sunday', value: 0 },
{ label: 'Monday', value: 1 },
{ label: 'Tuesday', value: 2 },
{ label: 'Wednesday', value: 3 },
{ label: 'Thursday', value: 4 },
{ label: 'Friday', value: 5 },
{ label: 'Saturday', value: 6 },
],
},
required: true,
}),
time: Property.ShortText({
displayName: '24h Time',
description:
'The time that you would like to get the date and time of. This must be in 24h format.',
required: false,
defaultValue: '00:00',
}),
currentTime: Property.Checkbox({
displayName: 'Use Current Time',
description:
'If checked, the current time will be used instead of the time specified above.',
required: false,
defaultValue: false,
}),
timeFormat: Property.StaticDropdown({
displayName: 'To Time Format',
description: timeFormatDescription,
options: {
options: optionalTimeFormats,
},
required: true,
defaultValue: timeFormat.format00,
}),
timeZone: Property.StaticDropdown<string>({
displayName: 'Time Zone',
options: {
options: timeZoneOptions,
},
required: true,
defaultValue: 'UTC',
}),
},
async run(context) {
await propsValidation.validateZod(context.propsValue, {
time: z.string().regex(/^\d\d:\d\d$/),
});
const timeFormat = getCorrectedFormat(context.propsValue.timeFormat);
const timeZone = context.propsValue.timeZone as string;
const dayIndex = context.propsValue.weekday as number;
const currentTime = context.propsValue.currentTime as boolean;
let time = context.propsValue.time as string;
let nextOccurrence = dayjs().tz(timeZone);
if (currentTime === true) {
time = `${nextOccurrence.hour()}:${nextOccurrence.minute()}`;
}
const [hours, minutes] = time.split(':').map(Number);
// Validate inputs
if (
dayIndex < 0 ||
dayIndex > 6 ||
hours < 0 ||
hours > 23 ||
minutes < 0 ||
minutes > 59
) {
throw new Error(
`Invalid input \ndayIndex: ${dayIndex} \nhours: ${hours} \nminutes: ${minutes}`
);
}
// Set the time
nextOccurrence = nextOccurrence.hour(hours).minute(minutes).second(0).millisecond(0);
// Calculate the day difference
let dayDiff = dayIndex - nextOccurrence.day();
if (
dayDiff < 0 ||
(dayDiff === 0 && nextOccurrence.isBefore(dayjs().tz(timeZone)))
) {
// If it's a past day in the week or today but past time, move to next week
dayDiff += 7;
}
// Set the date to the next occurrence of the given day
nextOccurrence = nextOccurrence.add(dayDiff, 'day');
return { result: nextOccurrence.format(timeFormat) };
},
});