UNPKG

@kermank/nldp

Version:

A modular date/time parser for converting natural language into dates and times

121 lines 5.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.relativeWeeksRule = void 0; const luxon_1 = require("luxon"); function createWeekComponent(start, end, span, originalText, preferences) { // Use the timezone from preferences, or keep the original timezone if none specified const targetZone = preferences.timeZone || (start.zoneName || 'UTC'); // Only convert if target timezone is different from current let startResult = start.zoneName !== targetZone ? start.setZone(targetZone) : start; let endResult = end.zoneName !== targetZone ? end.setZone(targetZone) : end; return { type: 'range', span, value: { start: startResult, end: endResult }, confidence: 1, metadata: { originalText, dateType: 'relative', rangeType: 'relativeWeek' } }; } function getWeekRange(date, weekStartsOn = 1, preferences) { // First, ensure we're in the right timezone const targetZone = preferences.timeZone || (date.zoneName || 'UTC'); const operationalDate = date.zoneName !== targetZone ? date.setZone(targetZone) : date; // Convert weekStartsOn from 0-6 (Sunday=0) to 1-7 (Monday=1) for Luxon const luxonWeekStart = weekStartsOn === 0 ? 7 : weekStartsOn; // Use Luxon's built-in startOf('week') with the correct weekday const start = operationalDate.set({ weekday: luxonWeekStart }).startOf('day'); const end = start.plus({ days: 6 }).endOf('day'); // If we're past the week start, move to next week if (operationalDate.weekday < luxonWeekStart) { return { start: start.minus({ weeks: 1 }), end: end.minus({ weeks: 1 }) }; } return { start, end }; } function getNextWeekRange(date, weekStartsOn = 1, preferences) { const { start } = getWeekRange(date, weekStartsOn, preferences); // Simply add 7 days to both start and end of current week const nextStart = start.plus({ weeks: 1 }); const nextEnd = nextStart.plus({ days: 6 }).endOf('day'); return { start: nextStart, end: nextEnd }; } function getLastWeekRange(date, weekStartsOn = 1, preferences) { const { start } = getWeekRange(date, weekStartsOn, preferences); // Simply subtract 7 days from both start and end of current week const lastStart = start.minus({ weeks: 1 }); const lastEnd = lastStart.plus({ days: 6 }).endOf('day'); return { start: lastStart, end: lastEnd }; } const patterns = [ { regex: /(?:^|\s)(this|next|last)\s+week(?:\s+|$)/i, parse: (matches, preferences) => { const [fullMatch, weekModifier] = matches; const referenceDate = preferences.referenceDate || luxon_1.DateTime.now(); const weekStartsOn = preferences.weekStartsOn; let range; switch (weekModifier.toLowerCase()) { case 'next': range = getNextWeekRange(referenceDate, weekStartsOn, preferences); break; case 'last': range = getLastWeekRange(referenceDate, weekStartsOn, preferences); break; default: range = getWeekRange(referenceDate, weekStartsOn, preferences); } const matchStart = matches.index + (fullMatch.startsWith(' ') ? 1 : 0); const matchEnd = matchStart + fullMatch.trim().length; return createWeekComponent(range.start, range.end, { start: matchStart, end: matchEnd }, fullMatch.trim(), preferences); } }, { regex: /^(the\s+)?week\s+after\s+next$/i, parse: (matches, preferences) => { const [fullMatch] = matches; const referenceDate = preferences.referenceDate || luxon_1.DateTime.now(); const weekStartsOn = preferences.weekStartsOn; const nextWeek = getNextWeekRange(referenceDate, weekStartsOn, preferences); const weekAfterNext = getNextWeekRange(nextWeek.start, weekStartsOn, preferences); return createWeekComponent(weekAfterNext.start, weekAfterNext.end, { start: 0, end: fullMatch.length }, fullMatch, preferences); } }, { regex: /^(\d+)\s+weeks?\s+(from\s+now|ago)$/i, parse: (matches, preferences) => { const [fullMatch, count, direction] = matches; const weeks = parseInt(count); if (isNaN(weeks)) return null; const referenceDate = preferences.referenceDate || luxon_1.DateTime.now(); const weekStartsOn = preferences.weekStartsOn; const currentWeek = getWeekRange(referenceDate, weekStartsOn, preferences); const targetDate = direction.includes('ago') ? currentWeek.start.minus({ days: weeks * 7 }) : currentWeek.start.plus({ days: weeks * 7 }); const range = getWeekRange(targetDate, weekStartsOn, preferences); return createWeekComponent(range.start, range.end, { start: 0, end: fullMatch.length }, fullMatch, preferences); } }, { regex: /^upcoming\s+week$/i, parse: (matches, preferences) => { const [fullMatch] = matches; const referenceDate = preferences.referenceDate || luxon_1.DateTime.now(); const weekStartsOn = preferences.weekStartsOn; const range = getNextWeekRange(referenceDate, weekStartsOn, preferences); return createWeekComponent(range.start, range.end, { start: 0, end: fullMatch.length }, fullMatch, preferences); } } ]; exports.relativeWeeksRule = { name: 'relative-weeks', patterns }; //# sourceMappingURL=relative-weeks.js.map