@glatam/calendar-core 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/strategies/date-range.strategy.d.ts.map +1 -1
- package/dist/strategies/date-range.strategy.js +3 -0
- package/dist/strategies/date-range.strategy.js.map +1 -1
- package/dist/strategies/weekly.strategy.d.ts.map +1 -1
- package/dist/strategies/weekly.strategy.js +3 -0
- package/dist/strategies/weekly.strategy.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/date-utils.d.ts.map +1 -1
- package/dist/utils/date-utils.js +6 -2
- package/dist/utils/date-utils.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAqB,MAAM,YAAY,CAAC;AAIpF,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AAExC;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,GAAG,SAAS,CAUvH;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAEpG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,YAAY,EAAE,EACrB,WAAW,GAAE,QAAQ,EAAO,EAC5B,cAAc,SAAI,GACjB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAqB,MAAM,YAAY,CAAC;AAIpF,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AAExC;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,GAAG,SAAS,CAUvH;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAEpG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,YAAY,EAAE,EACrB,WAAW,GAAE,QAAQ,EAAO,EAC5B,cAAc,SAAI,GACjB,WAAW,EAAE,CAsCf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,IAAI,EACnB,KAAK,EAAE,YAAY,EAAE,EACrB,WAAW,GAAE,QAAQ,EAAO,EAC5B,cAAc,SAAI,GACjB,WAAW,EAAE,CAgCf"}
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,9 @@ export function generateMonthDays(year, month, rules, slotsPerDay = [], startOfW
|
|
|
35
35
|
const days = [];
|
|
36
36
|
const currentDate = new Date(startGridDate);
|
|
37
37
|
for (let i = 0; i < 42; i++) {
|
|
38
|
+
if (i >= 28 && i % 7 === 0 && currentDate.getMonth() !== month && currentDate > firstDayOfMonth) {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
38
41
|
const dateCopy = new Date(currentDate);
|
|
39
42
|
const dateString = formatISODate(dateCopy);
|
|
40
43
|
const evaluatedSlots = slotsPerDay.map((slot) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockingRule, CalendarDay, TimeSlot, EvaluatedTimeSlot } from './types.js';\nimport { BlockingStrategyFactory } from './strategies/factory.js';\nimport { formatISODate, getStartOfWeek } from './utils/date-utils.js';\n\nexport * from './types.js';\nexport * from './utils/date-utils.js';\nexport * from './strategies/strategy.interface.js';\nexport * from './strategies/weekly.strategy.js';\nexport * from './strategies/date-range.strategy.js';\nexport * from './strategies/factory.js';\n\n/**\n * Checks if a specific date or time slot is blocked and returns the matching rule.\n */\nexport function getBlockingRule(date: Date, slot: TimeSlot | undefined, rules: BlockingRule[]): BlockingRule | undefined {\n for (const rule of rules) {\n const strategy = BlockingStrategyFactory.getStrategy(rule.type);\n if (slot) {\n if (strategy.isSlotBlocked(date, slot, rule)) return rule;\n } else {\n if (strategy.isDateBlocked(date, rule)) return rule;\n }\n }\n return undefined;\n}\n\nexport function isTimeBlocked(date: Date, slot: TimeSlot | undefined, rules: BlockingRule[]): boolean {\n return !!getBlockingRule(date, slot, rules);\n}\n\n/**\n * Generates an array of CalendarDay items representing a monthly calendar grid.\n */\nexport function generateMonthDays(\n year: number,\n month: number,\n rules: BlockingRule[],\n slotsPerDay: TimeSlot[] = [],\n startOfWeekDay = 0\n): CalendarDay[] {\n const firstDayOfMonth = new Date(year, month, 1);\n const startGridDate = getStartOfWeek(firstDayOfMonth, startOfWeekDay);\n\n const days: CalendarDay[] = [];\n const currentDate = new Date(startGridDate);\n\n for (let i = 0; i < 42; i++) {\n const dateCopy = new Date(currentDate);\n const dateString = formatISODate(dateCopy);\n\n const evaluatedSlots: EvaluatedTimeSlot[] = slotsPerDay.map((slot) => {\n const match = getBlockingRule(dateCopy, slot, rules);\n return { ...slot, isBlocked: !!match, rule: match };\n });\n\n const dayRule = getBlockingRule(dateCopy, undefined, rules);\n const isDayFullyBlocked = !!dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked));\n\n days.push({\n dateString,\n date: dateCopy,\n isBlocked: isDayFullyBlocked,\n rule: dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked) ? evaluatedSlots[0].rule : undefined),\n dayOfWeek: dateCopy.getDay(),\n dayNumber: dateCopy.getDate(),\n isCurrentMonth: dateCopy.getMonth() === month,\n slots: evaluatedSlots,\n });\n\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return days;\n}\n\n/**\n * Generates an array of 7 CalendarDay items representing a single week view.\n */\nexport function generateWeekDays(\n referenceDate: Date,\n rules: BlockingRule[],\n slotsPerDay: TimeSlot[] = [],\n startOfWeekDay = 0\n): CalendarDay[] {\n const startOfWeek = getStartOfWeek(referenceDate, startOfWeekDay);\n const days: CalendarDay[] = [];\n const currentDate = new Date(startOfWeek);\n\n for (let i = 0; i < 7; i++) {\n const dateCopy = new Date(currentDate);\n const dateString = formatISODate(dateCopy);\n\n const evaluatedSlots: EvaluatedTimeSlot[] = slotsPerDay.map((slot) => {\n const match = getBlockingRule(dateCopy, slot, rules);\n return { ...slot, isBlocked: !!match, rule: match };\n });\n\n const dayRule = getBlockingRule(dateCopy, undefined, rules);\n const isDayFullyBlocked = !!dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked));\n\n days.push({\n dateString,\n date: dateCopy,\n isBlocked: isDayFullyBlocked,\n rule: dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked) ? evaluatedSlots[0].rule : undefined),\n dayOfWeek: dateCopy.getDay(),\n dayNumber: dateCopy.getDate(),\n isCurrentMonth: true,\n slots: evaluatedSlots,\n });\n\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return days;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockingRule, CalendarDay, TimeSlot, EvaluatedTimeSlot } from './types.js';\nimport { BlockingStrategyFactory } from './strategies/factory.js';\nimport { formatISODate, getStartOfWeek } from './utils/date-utils.js';\n\nexport * from './types.js';\nexport * from './utils/date-utils.js';\nexport * from './strategies/strategy.interface.js';\nexport * from './strategies/weekly.strategy.js';\nexport * from './strategies/date-range.strategy.js';\nexport * from './strategies/factory.js';\n\n/**\n * Checks if a specific date or time slot is blocked and returns the matching rule.\n */\nexport function getBlockingRule(date: Date, slot: TimeSlot | undefined, rules: BlockingRule[]): BlockingRule | undefined {\n for (const rule of rules) {\n const strategy = BlockingStrategyFactory.getStrategy(rule.type);\n if (slot) {\n if (strategy.isSlotBlocked(date, slot, rule)) return rule;\n } else {\n if (strategy.isDateBlocked(date, rule)) return rule;\n }\n }\n return undefined;\n}\n\nexport function isTimeBlocked(date: Date, slot: TimeSlot | undefined, rules: BlockingRule[]): boolean {\n return !!getBlockingRule(date, slot, rules);\n}\n\n/**\n * Generates an array of CalendarDay items representing a monthly calendar grid.\n */\nexport function generateMonthDays(\n year: number,\n month: number,\n rules: BlockingRule[],\n slotsPerDay: TimeSlot[] = [],\n startOfWeekDay = 0\n): CalendarDay[] {\n const firstDayOfMonth = new Date(year, month, 1);\n const startGridDate = getStartOfWeek(firstDayOfMonth, startOfWeekDay);\n\n const days: CalendarDay[] = [];\n const currentDate = new Date(startGridDate);\n\n for (let i = 0; i < 42; i++) {\n if (i >= 28 && i % 7 === 0 && currentDate.getMonth() !== month && currentDate > firstDayOfMonth) {\n break;\n }\n\n const dateCopy = new Date(currentDate);\n const dateString = formatISODate(dateCopy);\n\n const evaluatedSlots: EvaluatedTimeSlot[] = slotsPerDay.map((slot) => {\n const match = getBlockingRule(dateCopy, slot, rules);\n return { ...slot, isBlocked: !!match, rule: match };\n });\n\n const dayRule = getBlockingRule(dateCopy, undefined, rules);\n const isDayFullyBlocked = !!dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked));\n\n days.push({\n dateString,\n date: dateCopy,\n isBlocked: isDayFullyBlocked,\n rule: dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked) ? evaluatedSlots[0].rule : undefined),\n dayOfWeek: dateCopy.getDay(),\n dayNumber: dateCopy.getDate(),\n isCurrentMonth: dateCopy.getMonth() === month,\n slots: evaluatedSlots,\n });\n\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return days;\n}\n\n/**\n * Generates an array of 7 CalendarDay items representing a single week view.\n */\nexport function generateWeekDays(\n referenceDate: Date,\n rules: BlockingRule[],\n slotsPerDay: TimeSlot[] = [],\n startOfWeekDay = 0\n): CalendarDay[] {\n const startOfWeek = getStartOfWeek(referenceDate, startOfWeekDay);\n const days: CalendarDay[] = [];\n const currentDate = new Date(startOfWeek);\n\n for (let i = 0; i < 7; i++) {\n const dateCopy = new Date(currentDate);\n const dateString = formatISODate(dateCopy);\n\n const evaluatedSlots: EvaluatedTimeSlot[] = slotsPerDay.map((slot) => {\n const match = getBlockingRule(dateCopy, slot, rules);\n return { ...slot, isBlocked: !!match, rule: match };\n });\n\n const dayRule = getBlockingRule(dateCopy, undefined, rules);\n const isDayFullyBlocked = !!dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked));\n\n days.push({\n dateString,\n date: dateCopy,\n isBlocked: isDayFullyBlocked,\n rule: dayRule || (evaluatedSlots.length > 0 && evaluatedSlots.every((s) => s.isBlocked) ? evaluatedSlots[0].rule : undefined),\n dayOfWeek: dateCopy.getDay(),\n dayNumber: dateCopy.getDate(),\n isCurrentMonth: true,\n slots: evaluatedSlots,\n });\n\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return days;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-range.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/date-range.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,qBAAa,iBAAkB,YAAW,gBAAgB;IACxD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IAQtD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IActE,OAAO,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"date-range.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/date-range.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,qBAAa,iBAAkB,YAAW,gBAAgB;IACxD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IAQtD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IActE,OAAO,CAAC,gBAAgB;CAiBzB"}
|
|
@@ -20,6 +20,9 @@ export class DateRangeStrategy {
|
|
|
20
20
|
}
|
|
21
21
|
matchesDateRange(date, rule) {
|
|
22
22
|
const dateStr = formatISODate(date);
|
|
23
|
+
if (rule.exceptions && rule.exceptions.includes(dateStr)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
23
26
|
if (rule.startDate && dateStr < rule.startDate) {
|
|
24
27
|
return false;
|
|
25
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-range.strategy.js","sourceRoot":"","sources":["../../src/strategies/date-range.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE1E,MAAM,OAAO,iBAAiB;IAC5B,aAAa,CAAC,IAAU,EAAE,IAAkB;QAC1C,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,sDAAsD;QACtD,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,aAAa,CAAC,IAAU,EAAE,IAAc,EAAE,IAAkB;QAC1D,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAChF,CAAC;IAEO,gBAAgB,CAAC,IAAU,EAAE,IAAkB;QACrD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { BlockingRule, TimeSlot } from '../types.js';\nimport { BlockingStrategy } from './strategy.interface.js';\nimport { formatISODate, isTimeOverlapping } from '../utils/date-utils.js';\n\nexport class DateRangeStrategy implements BlockingStrategy {\n isDateBlocked(date: Date, rule: BlockingRule): boolean {\n if (!this.matchesDateRange(date, rule)) {\n return false;\n }\n // If no slots are defined, the entire day is blocked.\n return !rule.slots || rule.slots.length === 0;\n }\n\n isSlotBlocked(date: Date, slot: TimeSlot, rule: BlockingRule): boolean {\n if (!this.matchesDateRange(date, rule)) {\n return false;\n }\n\n // If no slots are defined, the entire day is blocked, so the slot is blocked.\n if (!rule.slots || rule.slots.length === 0) {\n return true;\n }\n\n // Check if the slot overlaps with any blocked slots in the rule\n return rule.slots.some((blockedSlot) => isTimeOverlapping(slot, blockedSlot));\n }\n\n private matchesDateRange(date: Date, rule: BlockingRule): boolean {\n const dateStr = formatISODate(date);\n\n if (rule.startDate && dateStr < rule.startDate) {\n return false;\n }\n\n if (rule.endDate && dateStr > rule.endDate) {\n return false;\n }\n\n return true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"date-range.strategy.js","sourceRoot":"","sources":["../../src/strategies/date-range.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE1E,MAAM,OAAO,iBAAiB;IAC5B,aAAa,CAAC,IAAU,EAAE,IAAkB;QAC1C,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,sDAAsD;QACtD,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,aAAa,CAAC,IAAU,EAAE,IAAc,EAAE,IAAkB;QAC1D,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAChF,CAAC;IAEO,gBAAgB,CAAC,IAAU,EAAE,IAAkB;QACrD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { BlockingRule, TimeSlot } from '../types.js';\nimport { BlockingStrategy } from './strategy.interface.js';\nimport { formatISODate, isTimeOverlapping } from '../utils/date-utils.js';\n\nexport class DateRangeStrategy implements BlockingStrategy {\n isDateBlocked(date: Date, rule: BlockingRule): boolean {\n if (!this.matchesDateRange(date, rule)) {\n return false;\n }\n // If no slots are defined, the entire day is blocked.\n return !rule.slots || rule.slots.length === 0;\n }\n\n isSlotBlocked(date: Date, slot: TimeSlot, rule: BlockingRule): boolean {\n if (!this.matchesDateRange(date, rule)) {\n return false;\n }\n\n // If no slots are defined, the entire day is blocked, so the slot is blocked.\n if (!rule.slots || rule.slots.length === 0) {\n return true;\n }\n\n // Check if the slot overlaps with any blocked slots in the rule\n return rule.slots.some((blockedSlot) => isTimeOverlapping(slot, blockedSlot));\n }\n\n private matchesDateRange(date: Date, rule: BlockingRule): boolean {\n const dateStr = formatISODate(date);\n\n if (rule.exceptions && rule.exceptions.includes(dateStr)) {\n return false;\n }\n\n if (rule.startDate && dateStr < rule.startDate) {\n return false;\n }\n\n if (rule.endDate && dateStr > rule.endDate) {\n return false;\n }\n\n return true;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weekly.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/weekly.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,qBAAa,cAAe,YAAW,gBAAgB;IACrD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IAQtD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IActE,OAAO,CAAC,iBAAiB;
|
|
1
|
+
{"version":3,"file":"weekly.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/weekly.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,qBAAa,cAAe,YAAW,gBAAgB;IACrD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IAQtD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO;IActE,OAAO,CAAC,iBAAiB;CAsB1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weekly.strategy.js","sourceRoot":"","sources":["../../src/strategies/weekly.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE1E,MAAM,OAAO,cAAc;IACzB,aAAa,CAAC,IAAU,EAAE,IAAkB;QAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,sDAAsD;QACtD,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,aAAa,CAAC,IAAU,EAAE,IAAc,EAAE,IAAkB;QAC1D,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAChF,CAAC;IAEO,iBAAiB,CAAC,IAAU,EAAE,IAAkB;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { BlockingRule, TimeSlot } from '../types.js';\nimport { BlockingStrategy } from './strategy.interface.js';\nimport { formatISODate, isTimeOverlapping } from '../utils/date-utils.js';\n\nexport class WeeklyStrategy implements BlockingStrategy {\n isDateBlocked(date: Date, rule: BlockingRule): boolean {\n if (!this.matchesDateAndDay(date, rule)) {\n return false;\n }\n // If no slots are defined, the entire day is blocked.\n return !rule.slots || rule.slots.length === 0;\n }\n\n isSlotBlocked(date: Date, slot: TimeSlot, rule: BlockingRule): boolean {\n if (!this.matchesDateAndDay(date, rule)) {\n return false;\n }\n\n // If no slots are defined, the entire day is blocked, so the slot is blocked.\n if (!rule.slots || rule.slots.length === 0) {\n return true;\n }\n\n // Check if the slot overlaps with any blocked slots in the rule\n return rule.slots.some((blockedSlot) => isTimeOverlapping(slot, blockedSlot));\n }\n\n private matchesDateAndDay(date: Date, rule: BlockingRule): boolean {\n const dayOfWeek = date.getDay();\n if (!rule.daysOfWeek || !rule.daysOfWeek.includes(dayOfWeek)) {\n return false;\n }\n\n const dateStr = formatISODate(date);\n\n if (rule.startDate && dateStr < rule.startDate) {\n return false;\n }\n\n if (rule.endDate && dateStr > rule.endDate) {\n return false;\n }\n\n return true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"weekly.strategy.js","sourceRoot":"","sources":["../../src/strategies/weekly.strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE1E,MAAM,OAAO,cAAc;IACzB,aAAa,CAAC,IAAU,EAAE,IAAkB;QAC1C,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,sDAAsD;QACtD,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,aAAa,CAAC,IAAU,EAAE,IAAc,EAAE,IAAkB;QAC1D,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAChF,CAAC;IAEO,iBAAiB,CAAC,IAAU,EAAE,IAAkB;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { BlockingRule, TimeSlot } from '../types.js';\nimport { BlockingStrategy } from './strategy.interface.js';\nimport { formatISODate, isTimeOverlapping } from '../utils/date-utils.js';\n\nexport class WeeklyStrategy implements BlockingStrategy {\n isDateBlocked(date: Date, rule: BlockingRule): boolean {\n if (!this.matchesDateAndDay(date, rule)) {\n return false;\n }\n // If no slots are defined, the entire day is blocked.\n return !rule.slots || rule.slots.length === 0;\n }\n\n isSlotBlocked(date: Date, slot: TimeSlot, rule: BlockingRule): boolean {\n if (!this.matchesDateAndDay(date, rule)) {\n return false;\n }\n\n // If no slots are defined, the entire day is blocked, so the slot is blocked.\n if (!rule.slots || rule.slots.length === 0) {\n return true;\n }\n\n // Check if the slot overlaps with any blocked slots in the rule\n return rule.slots.some((blockedSlot) => isTimeOverlapping(slot, blockedSlot));\n }\n\n private matchesDateAndDay(date: Date, rule: BlockingRule): boolean {\n const dayOfWeek = date.getDay();\n if (!rule.daysOfWeek || !rule.daysOfWeek.includes(dayOfWeek)) {\n return false;\n }\n\n const dateStr = formatISODate(date);\n\n if (rule.exceptions && rule.exceptions.includes(dateStr)) {\n return false;\n }\n\n if (rule.startDate && dateStr < rule.startDate) {\n return false;\n }\n\n if (rule.endDate && dateStr > rule.endDate) {\n return false;\n }\n\n return true;\n }\n}\n"]}
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface TimeSlot {\n start: string;\n end: string;\n}\n\nexport type BlockingRuleType = 'weekly' | 'date-range';\n\nexport interface BlockingRule {\n id: string;\n type: BlockingRuleType;\n startDate?: string;\n endDate?: string;\n daysOfWeek?: number[];\n slots?: TimeSlot[];\n description?: string; // Descriptive title/notes for the task/block\n [key: string]:
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface TimeSlot {\n start: string;\n end: string;\n}\n\nexport type BlockingRuleType = 'weekly' | 'date-range';\n\nexport interface BlockingRule {\n id: string;\n type: BlockingRuleType;\n startDate?: string;\n endDate?: string;\n daysOfWeek?: number[];\n slots?: TimeSlot[];\n description?: string; // Descriptive title/notes for the task/block\n exceptions?: string[]; // Array of YYYY-MM-DD strings for dates where this rule is overridden / unblocked\n [key: string]: unknown; // Allow custom metadata (assignees, status, priority)\n}\n\nexport interface CalendarDay {\n dateString: string;\n date: Date;\n isBlocked: boolean;\n rule?: BlockingRule; // The rule blocking the whole day\n dayOfWeek: number;\n dayNumber: number;\n isCurrentMonth: boolean;\n slots: EvaluatedTimeSlot[];\n}\n\nexport interface EvaluatedTimeSlot {\n start: string;\n end: string;\n isBlocked: boolean;\n rule?: BlockingRule; // The rule that caused the block\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-utils.d.ts","sourceRoot":"","sources":["../../src/utils/date-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CASlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAKhD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"date-utils.d.ts","sourceRoot":"","sources":["../../src/utils/date-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CASlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAKhD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAU3E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,SAAI,GAAG,IAAI,CAMnE"}
|
package/dist/utils/date-utils.js
CHANGED
|
@@ -33,9 +33,13 @@ export function timeToMinutes(timeStr) {
|
|
|
33
33
|
*/
|
|
34
34
|
export function isTimeOverlapping(slot1, slot2) {
|
|
35
35
|
const start1 = timeToMinutes(slot1.start);
|
|
36
|
-
|
|
36
|
+
let end1 = timeToMinutes(slot1.end);
|
|
37
|
+
if (end1 === 0 || slot1.end === '24:00' || end1 <= start1)
|
|
38
|
+
end1 = 1440;
|
|
37
39
|
const start2 = timeToMinutes(slot2.start);
|
|
38
|
-
|
|
40
|
+
let end2 = timeToMinutes(slot2.end);
|
|
41
|
+
if (end2 === 0 || slot2.end === '24:00' || end2 <= start2)
|
|
42
|
+
end2 = 1440;
|
|
39
43
|
return start1 < end2 && start2 < end1;
|
|
40
44
|
}
|
|
41
45
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-utils.js","sourceRoot":"","sources":["../../src/utils/date-utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY;IACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAe,EAAE,KAAe;IAChE,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,
|
|
1
|
+
{"version":3,"file":"date-utils.js","sourceRoot":"","sources":["../../src/utils/date-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { TimeSlot } from '../types.js';\n\n/**\n * Parses an ISO date string (YYYY-MM-DD) into a local Date object.\n * Prevents timezone shifting issues.\n */\nexport function parseISODate(dateStr: string): Date {\n const parts = dateStr.split('T')[0].split('-');\n if (parts.length !== 3) {\n return new Date(dateStr);\n }\n const year = parseInt(parts[0], 10);\n const month = parseInt(parts[1], 10) - 1; // 0-indexed\n const day = parseInt(parts[2], 10);\n return new Date(year, month, day);\n}\n\n/**\n * Formats a Date object to YYYY-MM-DD in the local timezone.\n */\nexport function formatISODate(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\n/**\n * Converts a time string \"HH:MM\" to minutes from midnight.\n */\nexport function timeToMinutes(timeStr: string): number {\n const [hours, minutes] = timeStr.split(':').map(Number);\n return (hours || 0) * 60 + (minutes || 0);\n}\n\n/**\n * Checks if two time slots overlap.\n */\nexport function isTimeOverlapping(slot1: TimeSlot, slot2: TimeSlot): boolean {\n const start1 = timeToMinutes(slot1.start);\n let end1 = timeToMinutes(slot1.end);\n if (end1 === 0 || slot1.end === '24:00' || end1 <= start1) end1 = 1440;\n\n const start2 = timeToMinutes(slot2.start);\n let end2 = timeToMinutes(slot2.end);\n if (end2 === 0 || slot2.end === '24:00' || end2 <= start2) end2 = 1440;\n\n return start1 < end2 && start2 < end1;\n}\n\n/**\n * Gets the start of the week for a given date.\n * @param date The date reference.\n * @param startOfWeekDay The day the week starts (0 = Sunday, 1 = Monday). Default is 0.\n */\nexport function getStartOfWeek(date: Date, startOfWeekDay = 0): Date {\n const result = new Date(date.getFullYear(), date.getMonth(), date.getDate());\n const day = result.getDay();\n const diff = (day < startOfWeekDay ? 7 : 0) + day - startOfWeekDay;\n result.setDate(result.getDate() - diff);\n return result;\n}\n"]}
|