Favivon - Correção

This commit is contained in:
2026-05-30 19:59:39 -03:00
parent 76ddaa815d
commit d7dfd221f0
32859 changed files with 5459654 additions and 404 deletions
+16
View File
@@ -0,0 +1,16 @@
import { type DateLib } from "../classes/DateLib.js";
import type { DateRange } from "../types/index.js";
/**
* Adds a date to an existing range, considering constraints like minimum and
* maximum range size.
*
* @param date - The date to add to the range.
* @param initialRange - The initial range to which the date will be added.
* @param min - The minimum number of days in the range.
* @param max - The maximum number of days in the range.
* @param required - Whether the range must always include at least one date.
* @param dateLib - The date utility library instance.
* @returns The updated date range, or `undefined` if the range is cleared.
* @group Utilities
*/
export declare function addToRange(date: Date, initialRange: DateRange | undefined, min?: number, max?: number, required?: boolean, dateLib?: DateLib): DateRange | undefined;
+92
View File
@@ -0,0 +1,92 @@
import { defaultDateLib } from "../classes/DateLib.js";
/**
* Adds a date to an existing range, considering constraints like minimum and
* maximum range size.
*
* @param date - The date to add to the range.
* @param initialRange - The initial range to which the date will be added.
* @param min - The minimum number of days in the range.
* @param max - The maximum number of days in the range.
* @param required - Whether the range must always include at least one date.
* @param dateLib - The date utility library instance.
* @returns The updated date range, or `undefined` if the range is cleared.
* @group Utilities
*/
export function addToRange(date, initialRange, min = 0, max = 0, required = false, dateLib = defaultDateLib) {
const { from, to } = initialRange || {};
const { isSameDay, isAfter, isBefore } = dateLib;
let range;
if (!from && !to) {
// the range is empty, add the date
range = { from: date, to: min > 0 ? undefined : date };
}
else if (from && !to) {
// adding date to an incomplete range
if (isSameDay(from, date)) {
// adding a date equal to the start of the range
if (min === 0) {
range = { from, to: date };
}
else if (required) {
range = { from, to: undefined };
}
else {
range = undefined;
}
}
else if (isBefore(date, from)) {
// adding a date before the start of the range
range = { from: date, to: from };
}
else {
// adding a date after the start of the range
range = { from, to: date };
}
}
else if (from && to) {
// adding date to a complete range
if (isSameDay(from, date) && isSameDay(to, date)) {
// adding a date that is equal to both start and end of the range
if (required) {
range = { from, to };
}
else {
range = undefined;
}
}
else if (isSameDay(from, date)) {
// adding a date equal to the the start of the range
range = { from, to: min > 0 ? undefined : date };
}
else if (isSameDay(to, date)) {
// adding a dare equal to the end of the range
range = { from: date, to: min > 0 ? undefined : date };
}
else if (isBefore(date, from)) {
// adding a date before the start of the range
range = { from: date, to: to };
}
else if (isAfter(date, from)) {
// adding a date after the start of the range
range = { from, to: date };
}
else if (isAfter(date, to)) {
// adding a date after the end of the range
range = { from, to: date };
}
else {
throw new Error("Invalid range");
}
}
// check for min / max
if (range?.from && range?.to) {
const diff = dateLib.differenceInCalendarDays(range.to, range.from);
if (max > 0 && diff > max) {
range = { from: date, to: undefined };
}
else if (min > 1 && diff < min) {
range = { from: date, to: undefined };
}
}
return range;
}
@@ -0,0 +1,10 @@
import type { Matcher } from "../types/index.js";
/**
* Convert any {@link Matcher} or array of matchers to the specified time zone.
*
* @param matchers - The matcher or matchers to convert.
* @param timeZone - The target IANA time zone.
* @returns The converted matcher(s).
* @group Utilities
*/
export declare function convertMatchersToTimeZone(matchers: Matcher | Matcher[] | undefined, timeZone: string, noonSafe?: boolean): Matcher | Matcher[] | undefined;
@@ -0,0 +1,62 @@
import { TZDate } from "@date-fns/tz";
import { toTimeZone } from "./toTimeZone.js";
import { isDateAfterType, isDateBeforeType, isDateInterval, isDateRange, } from "./typeguards.js";
function toZoneNoon(date, timeZone, noonSafe) {
if (!noonSafe)
return toTimeZone(date, timeZone);
const zoned = toTimeZone(date, timeZone);
const noonZoned = new TZDate(zoned.getFullYear(), zoned.getMonth(), zoned.getDate(), 12, 0, 0, timeZone);
return new Date(noonZoned.getTime());
}
function convertMatcher(matcher, timeZone, noonSafe) {
if (typeof matcher === "boolean" || typeof matcher === "function") {
return matcher;
}
if (matcher instanceof Date) {
return toZoneNoon(matcher, timeZone, noonSafe);
}
if (Array.isArray(matcher)) {
return matcher.map((value) => value instanceof Date ? toZoneNoon(value, timeZone, noonSafe) : value);
}
if (isDateRange(matcher)) {
return {
...matcher,
from: matcher.from ? toTimeZone(matcher.from, timeZone) : matcher.from,
to: matcher.to ? toTimeZone(matcher.to, timeZone) : matcher.to,
};
}
if (isDateInterval(matcher)) {
return {
before: toZoneNoon(matcher.before, timeZone, noonSafe),
after: toZoneNoon(matcher.after, timeZone, noonSafe),
};
}
if (isDateAfterType(matcher)) {
return {
after: toZoneNoon(matcher.after, timeZone, noonSafe),
};
}
if (isDateBeforeType(matcher)) {
return {
before: toZoneNoon(matcher.before, timeZone, noonSafe),
};
}
return matcher;
}
/**
* Convert any {@link Matcher} or array of matchers to the specified time zone.
*
* @param matchers - The matcher or matchers to convert.
* @param timeZone - The target IANA time zone.
* @returns The converted matcher(s).
* @group Utilities
*/
export function convertMatchersToTimeZone(matchers, timeZone, noonSafe) {
if (!matchers) {
return matchers;
}
if (Array.isArray(matchers)) {
return matchers.map((matcher) => convertMatcher(matcher, timeZone, noonSafe));
}
return convertMatcher(matchers, timeZone, noonSafe);
}
+17
View File
@@ -0,0 +1,17 @@
import { type DateLib } from "../classes/DateLib.js";
import type { Matcher } from "../types/index.js";
/**
* Checks if a given date matches at least one of the specified {@link Matcher}.
*
* @param date - The date to check.
* @param matchers - The matchers to check against.
* @param dateLib - The date utility library instance.
* @returns `true` if the date matches any of the matchers, otherwise `false`.
* @group Utilities
*/
export declare function dateMatchModifiers(date: Date, matchers: Matcher | Matcher[], dateLib?: DateLib): boolean;
/**
* @private
* @deprecated Use {@link dateMatchModifiers} instead.
*/
export declare const isMatch: typeof dateMatchModifiers;
+64
View File
@@ -0,0 +1,64 @@
import { defaultDateLib } from "../classes/DateLib.js";
import { rangeIncludesDate } from "./rangeIncludesDate.js";
import { isDateAfterType, isDateBeforeType, isDateInterval, isDateRange, isDatesArray, isDayOfWeekType, } from "./typeguards.js";
/**
* Checks if a given date matches at least one of the specified {@link Matcher}.
*
* @param date - The date to check.
* @param matchers - The matchers to check against.
* @param dateLib - The date utility library instance.
* @returns `true` if the date matches any of the matchers, otherwise `false`.
* @group Utilities
*/
export function dateMatchModifiers(date, matchers, dateLib = defaultDateLib) {
const matchersArr = !Array.isArray(matchers) ? [matchers] : matchers;
const { isSameDay, differenceInCalendarDays, isAfter } = dateLib;
return matchersArr.some((matcher) => {
if (typeof matcher === "boolean") {
return matcher;
}
if (dateLib.isDate(matcher)) {
return isSameDay(date, matcher);
}
if (isDatesArray(matcher, dateLib)) {
return matcher.some((matcherDate) => isSameDay(date, matcherDate));
}
if (isDateRange(matcher)) {
return rangeIncludesDate(matcher, date, false, dateLib);
}
if (isDayOfWeekType(matcher)) {
if (!Array.isArray(matcher.dayOfWeek)) {
return matcher.dayOfWeek === date.getDay();
}
return matcher.dayOfWeek.includes(date.getDay());
}
if (isDateInterval(matcher)) {
const diffBefore = differenceInCalendarDays(matcher.before, date);
const diffAfter = differenceInCalendarDays(matcher.after, date);
const isDayBefore = diffBefore > 0;
const isDayAfter = diffAfter < 0;
const isClosedInterval = isAfter(matcher.before, matcher.after);
if (isClosedInterval) {
return isDayAfter && isDayBefore;
}
else {
return isDayBefore || isDayAfter;
}
}
if (isDateAfterType(matcher)) {
return differenceInCalendarDays(date, matcher.after) > 0;
}
if (isDateBeforeType(matcher)) {
return differenceInCalendarDays(matcher.before, date) > 0;
}
if (typeof matcher === "function") {
return matcher(date);
}
return false;
});
}
/**
* @private
* @deprecated Use {@link dateMatchModifiers} instead.
*/
export const isMatch = dateMatchModifiers;
+7
View File
@@ -0,0 +1,7 @@
export * from "./addToRange.js";
export * from "./dateMatchModifiers.js";
export * from "./rangeContainsDayOfWeek.js";
export * from "./rangeContainsModifiers.js";
export * from "./rangeIncludesDate.js";
export * from "./rangeOverlaps.js";
export * from "./typeguards.js";
+7
View File
@@ -0,0 +1,7 @@
export * from "./addToRange.js";
export * from "./dateMatchModifiers.js";
export * from "./rangeContainsDayOfWeek.js";
export * from "./rangeContainsModifiers.js";
export * from "./rangeIncludesDate.js";
export * from "./rangeOverlaps.js";
export * from "./typeguards.js";
@@ -0,0 +1,17 @@
import { type DateLib } from "../classes/DateLib.js";
/**
* Checks if a date range contains one or more specified days of the week.
*
* @since 9.2.2
* @param range - The date range to check.
* @param dayOfWeek - The day(s) of the week to check for (`0-6`, where `0` is
* Sunday).
* @param dateLib - The date utility library instance.
* @returns `true` if the range contains the specified day(s) of the week,
* otherwise `false`.
* @group Utilities
*/
export declare function rangeContainsDayOfWeek(range: {
from: Date;
to: Date;
}, dayOfWeek: number | number[], dateLib?: DateLib): boolean;
+27
View File
@@ -0,0 +1,27 @@
import { defaultDateLib } from "../classes/DateLib.js";
/**
* Checks if a date range contains one or more specified days of the week.
*
* @since 9.2.2
* @param range - The date range to check.
* @param dayOfWeek - The day(s) of the week to check for (`0-6`, where `0` is
* Sunday).
* @param dateLib - The date utility library instance.
* @returns `true` if the range contains the specified day(s) of the week,
* otherwise `false`.
* @group Utilities
*/
export function rangeContainsDayOfWeek(range, dayOfWeek, dateLib = defaultDateLib) {
const dayOfWeekArr = !Array.isArray(dayOfWeek) ? [dayOfWeek] : dayOfWeek;
let date = range.from;
const totalDays = dateLib.differenceInCalendarDays(range.to, range.from);
// iterate at maximum one week or the total days if the range is shorter than one week
const totalDaysLimit = Math.min(totalDays, 6);
for (let i = 0; i <= totalDaysLimit; i++) {
if (dayOfWeekArr.includes(date.getDay())) {
return true;
}
date = dateLib.addDays(date, 1);
}
return false;
}
@@ -0,0 +1,16 @@
import { type DateLib } from "../classes/DateLib.js";
import type { Matcher } from "../types/index.js";
/**
* Checks if a date range contains dates that match the given modifiers.
*
* @since 9.2.2
* @param range - The date range to check.
* @param modifiers - The modifiers to match against.
* @param dateLib - The date utility library instance.
* @returns `true` if the range contains matching dates, otherwise `false`.
* @group Utilities
*/
export declare function rangeContainsModifiers(range: {
from: Date;
to: Date;
}, modifiers: Matcher | Matcher[], dateLib?: DateLib): boolean;
+71
View File
@@ -0,0 +1,71 @@
import { defaultDateLib } from "../classes/DateLib.js";
import { dateMatchModifiers } from "./dateMatchModifiers.js";
import { rangeContainsDayOfWeek } from "./rangeContainsDayOfWeek.js";
import { rangeIncludesDate } from "./rangeIncludesDate.js";
import { rangeOverlaps } from "./rangeOverlaps.js";
import { isDateAfterType, isDateBeforeType, isDateInterval, isDateRange, isDatesArray, isDayOfWeekType, } from "./typeguards.js";
/**
* Checks if a date range contains dates that match the given modifiers.
*
* @since 9.2.2
* @param range - The date range to check.
* @param modifiers - The modifiers to match against.
* @param dateLib - The date utility library instance.
* @returns `true` if the range contains matching dates, otherwise `false`.
* @group Utilities
*/
export function rangeContainsModifiers(range, modifiers, dateLib = defaultDateLib) {
const matchers = Array.isArray(modifiers) ? modifiers : [modifiers];
// Defer function matchers evaluation as they are the least performant.
const nonFunctionMatchers = matchers.filter((matcher) => typeof matcher !== "function");
const nonFunctionMatchersResult = nonFunctionMatchers.some((matcher) => {
if (typeof matcher === "boolean")
return matcher;
if (dateLib.isDate(matcher)) {
return rangeIncludesDate(range, matcher, false, dateLib);
}
if (isDatesArray(matcher, dateLib)) {
return matcher.some((date) => rangeIncludesDate(range, date, false, dateLib));
}
if (isDateRange(matcher)) {
if (matcher.from && matcher.to) {
return rangeOverlaps(range, { from: matcher.from, to: matcher.to }, dateLib);
}
return false;
}
if (isDayOfWeekType(matcher)) {
return rangeContainsDayOfWeek(range, matcher.dayOfWeek, dateLib);
}
if (isDateInterval(matcher)) {
const isClosedInterval = dateLib.isAfter(matcher.before, matcher.after);
if (isClosedInterval) {
return rangeOverlaps(range, {
from: dateLib.addDays(matcher.after, 1),
to: dateLib.addDays(matcher.before, -1),
}, dateLib);
}
return (dateMatchModifiers(range.from, matcher, dateLib) ||
dateMatchModifiers(range.to, matcher, dateLib));
}
if (isDateAfterType(matcher) || isDateBeforeType(matcher)) {
return (dateMatchModifiers(range.from, matcher, dateLib) ||
dateMatchModifiers(range.to, matcher, dateLib));
}
return false;
});
if (nonFunctionMatchersResult) {
return true;
}
const functionMatchers = matchers.filter((matcher) => typeof matcher === "function");
if (functionMatchers.length) {
let date = range.from;
const totalDays = dateLib.differenceInCalendarDays(range.to, range.from);
for (let i = 0; i <= totalDays; i++) {
if (functionMatchers.some((matcher) => matcher(date))) {
return true;
}
date = dateLib.addDays(date, 1);
}
}
return false;
}
+18
View File
@@ -0,0 +1,18 @@
import type { DateRange } from "../types/index.js";
/**
* Checks if a given date is within a specified date range.
*
* @since 9.0.0
* @param range - The date range to check against.
* @param date - The date to check.
* @param excludeEnds - If `true`, the range's start and end dates are excluded.
* @param dateLib - The date utility library instance.
* @returns `true` if the date is within the range, otherwise `false`.
* @group Utilities
*/
export declare function rangeIncludesDate(range: DateRange, date: Date, excludeEnds?: boolean, dateLib?: import("../classes/DateLib.js").DateLib): boolean;
/**
* @private
* @deprecated Use {@link rangeIncludesDate} instead.
*/
export declare const isDateInRange: (range: DateRange, date: Date) => boolean;
+37
View File
@@ -0,0 +1,37 @@
import { defaultDateLib } from "../classes/index.js";
/**
* Checks if a given date is within a specified date range.
*
* @since 9.0.0
* @param range - The date range to check against.
* @param date - The date to check.
* @param excludeEnds - If `true`, the range's start and end dates are excluded.
* @param dateLib - The date utility library instance.
* @returns `true` if the date is within the range, otherwise `false`.
* @group Utilities
*/
export function rangeIncludesDate(range, date, excludeEnds = false, dateLib = defaultDateLib) {
let { from, to } = range;
const { differenceInCalendarDays, isSameDay } = dateLib;
if (from && to) {
const isRangeInverted = differenceInCalendarDays(to, from) < 0;
if (isRangeInverted) {
[from, to] = [to, from];
}
const isInRange = differenceInCalendarDays(date, from) >= (excludeEnds ? 1 : 0) &&
differenceInCalendarDays(to, date) >= (excludeEnds ? 1 : 0);
return isInRange;
}
if (!excludeEnds && to) {
return isSameDay(to, date);
}
if (!excludeEnds && from) {
return isSameDay(from, date);
}
return false;
}
/**
* @private
* @deprecated Use {@link rangeIncludesDate} instead.
*/
export const isDateInRange = (range, date) => rangeIncludesDate(range, date, false, defaultDateLib);
+17
View File
@@ -0,0 +1,17 @@
/**
* Determines if two date ranges overlap.
*
* @since 9.2.2
* @param rangeLeft - The first date range.
* @param rangeRight - The second date range.
* @param dateLib - The date utility library instance.
* @returns `true` if the ranges overlap, otherwise `false`.
* @group Utilities
*/
export declare function rangeOverlaps(rangeLeft: {
from: Date;
to: Date;
}, rangeRight: {
from: Date;
to: Date;
}, dateLib?: import("../classes/DateLib.js").DateLib): boolean;
+18
View File
@@ -0,0 +1,18 @@
import { defaultDateLib } from "../classes/index.js";
import { rangeIncludesDate } from "./rangeIncludesDate.js";
/**
* Determines if two date ranges overlap.
*
* @since 9.2.2
* @param rangeLeft - The first date range.
* @param rangeRight - The second date range.
* @param dateLib - The date utility library instance.
* @returns `true` if the ranges overlap, otherwise `false`.
* @group Utilities
*/
export function rangeOverlaps(rangeLeft, rangeRight, dateLib = defaultDateLib) {
return (rangeIncludesDate(rangeLeft, rangeRight.from, false, dateLib) ||
rangeIncludesDate(rangeLeft, rangeRight.to, false, dateLib) ||
rangeIncludesDate(rangeRight, rangeLeft.from, false, dateLib) ||
rangeIncludesDate(rangeRight, rangeLeft.to, false, dateLib));
}
+7
View File
@@ -0,0 +1,7 @@
import { TZDate } from "@date-fns/tz";
/**
* Convert a {@link Date} or {@link TZDate} instance to the given time zone.
* Reuses the same instance when it is already a {@link TZDate} using the target
* time zone to avoid extra allocations.
*/
export declare function toTimeZone(date: Date, timeZone: string): TZDate;
+12
View File
@@ -0,0 +1,12 @@
import { TZDate } from "@date-fns/tz";
/**
* Convert a {@link Date} or {@link TZDate} instance to the given time zone.
* Reuses the same instance when it is already a {@link TZDate} using the target
* time zone to avoid extra allocations.
*/
export function toTimeZone(date, timeZone) {
if (date instanceof TZDate && date.timeZone === timeZone) {
return date;
}
return new TZDate(date, timeZone);
}
+51
View File
@@ -0,0 +1,51 @@
import type { DateLib } from "../classes/DateLib.js";
import type { DateAfter, DateBefore, DateInterval, DateRange, DayOfWeek } from "../types/index.js";
/**
* Checks if the given value is of type {@link DateInterval}.
*
* @param matcher - The value to check.
* @returns `true` if the value is a {@link DateInterval}, otherwise `false`.
* @group Utilities
*/
export declare function isDateInterval(matcher: unknown): matcher is DateInterval;
/**
* Checks if the given value is of type {@link DateRange}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateRange}, otherwise `false`.
* @group Utilities
*/
export declare function isDateRange(value: unknown): value is DateRange;
/**
* Checks if the given value is of type {@link DateAfter}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateAfter}, otherwise `false`.
* @group Utilities
*/
export declare function isDateAfterType(value: unknown): value is DateAfter;
/**
* Checks if the given value is of type {@link DateBefore}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateBefore}, otherwise `false`.
* @group Utilities
*/
export declare function isDateBeforeType(value: unknown): value is DateBefore;
/**
* Checks if the given value is of type {@link DayOfWeek}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DayOfWeek}, otherwise `false`.
* @group Utilities
*/
export declare function isDayOfWeekType(value: unknown): value is DayOfWeek;
/**
* Checks if the given value is an array of valid dates.
*
* @private
* @param value - The value to check.
* @param dateLib - The date utility library instance.
* @returns `true` if the value is an array of valid dates, otherwise `false`.
*/
export declare function isDatesArray(value: unknown, dateLib: DateLib): value is Date[];
+64
View File
@@ -0,0 +1,64 @@
/**
* Checks if the given value is of type {@link DateInterval}.
*
* @param matcher - The value to check.
* @returns `true` if the value is a {@link DateInterval}, otherwise `false`.
* @group Utilities
*/
export function isDateInterval(matcher) {
return Boolean(matcher &&
typeof matcher === "object" &&
"before" in matcher &&
"after" in matcher);
}
/**
* Checks if the given value is of type {@link DateRange}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateRange}, otherwise `false`.
* @group Utilities
*/
export function isDateRange(value) {
return Boolean(value && typeof value === "object" && "from" in value);
}
/**
* Checks if the given value is of type {@link DateAfter}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateAfter}, otherwise `false`.
* @group Utilities
*/
export function isDateAfterType(value) {
return Boolean(value && typeof value === "object" && "after" in value);
}
/**
* Checks if the given value is of type {@link DateBefore}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateBefore}, otherwise `false`.
* @group Utilities
*/
export function isDateBeforeType(value) {
return Boolean(value && typeof value === "object" && "before" in value);
}
/**
* Checks if the given value is of type {@link DayOfWeek}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DayOfWeek}, otherwise `false`.
* @group Utilities
*/
export function isDayOfWeekType(value) {
return Boolean(value && typeof value === "object" && "dayOfWeek" in value);
}
/**
* Checks if the given value is an array of valid dates.
*
* @private
* @param value - The value to check.
* @param dateLib - The date utility library instance.
* @returns `true` if the value is an array of valid dates, otherwise `false`.
*/
export function isDatesArray(value, dateLib) {
return Array.isArray(value) && value.every(dateLib.isDate);
}