UNPKG

@kermank/nldp

Version:

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

139 lines 6.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.relativeDaysRule = void 0; const luxon_1 = require("luxon"); function createDateComponent(date, span, originalText, preferences, isRelative = false) { // If timezone is specified, convert to that timezone // If no timezone is specified, use UTC const targetZone = preferences.timeZone || 'UTC'; // Convert to target timezone preserving the absolute time let result = date.setZone(targetZone); return { type: 'date', span, value: result, confidence: 1, metadata: { originalText, dateType: isRelative ? 'relative' : 'absolute' } }; } const WEEKDAYS = { 'sunday': 7, 'sun': 7, 'monday': 1, 'mon': 1, 'tuesday': 2, 'tue': 2, 'wednesday': 3, 'wed': 3, 'thursday': 4, 'thu': 4, 'friday': 5, 'fri': 5, 'saturday': 6, 'sat': 6 }; const patterns = [ { regex: /(?:^|\s)today(?:\s|$)/i, parse: (matches, preferences) => { const date = preferences.referenceDate || luxon_1.DateTime.now(); const matchStart = matches.index + (matches[0].startsWith(' ') ? 1 : 0); const matchEnd = matchStart + matches[0].trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, matches[0].trim(), preferences, true); } }, { regex: /(?:^|\s)tomorrow(?:\s|$)/i, parse: (matches, preferences) => { const date = (preferences.referenceDate || luxon_1.DateTime.now()).plus({ days: 1 }); const matchStart = matches.index + (matches[0].startsWith(' ') ? 1 : 0); const matchEnd = matchStart + matches[0].trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, matches[0].trim(), preferences, true); } }, { regex: /(?:^|\s)yesterday(?:\s|$)/i, parse: (matches, preferences) => { const date = (preferences.referenceDate || luxon_1.DateTime.now()).minus({ days: 1 }); const matchStart = matches.index + (matches[0].startsWith(' ') ? 1 : 0); const matchEnd = matchStart + matches[0].trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, matches[0].trim(), preferences, true); } }, { regex: /(?:^|\s)(\d+)\s+days?\s+from\s+(?:now|today)(?:\s|$)/i, parse: (matches, preferences) => { const [fullMatch, days] = matches; const date = (preferences.referenceDate || luxon_1.DateTime.now()).plus({ days: parseInt(days) }); const matchStart = matches.index + (fullMatch.startsWith(' ') ? 1 : 0); const matchEnd = matchStart + fullMatch.trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, fullMatch.trim(), preferences, true); } }, { regex: /(?:^|\s)(\d+)\s+days?\s+ago(?:\s|$)/i, parse: (matches, preferences) => { const [fullMatch, days] = matches; const date = (preferences.referenceDate || luxon_1.DateTime.now()).minus({ days: parseInt(days) }); const matchStart = matches.index + (fullMatch.startsWith(' ') ? 1 : 0); const matchEnd = matchStart + fullMatch.trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, fullMatch.trim(), preferences, true); } }, { regex: /(?:^|\s)(the day after tomorrow|2 days from (?:now|today))(?:\s|$)/i, parse: (_, preferences) => { const date = (preferences.referenceDate || luxon_1.DateTime.now()).plus({ days: 2 }); const matchStart = _.index + (_[0].startsWith(' ') ? 1 : 0); const matchEnd = matchStart + _[0].trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, _[0].trim(), preferences, true); } }, { regex: /(?:^|\s)(the day before yesterday|2 days ago)(?:\s|$)/i, parse: (_, preferences) => { const date = (preferences.referenceDate || luxon_1.DateTime.now()).minus({ days: 2 }); const matchStart = _.index + (_[0].startsWith(' ') ? 1 : 0); const matchEnd = matchStart + _[0].trim().length; return createDateComponent(date, { start: matchStart, end: matchEnd }, _[0].trim(), preferences, true); } }, { regex: /(?:^|\s)upcoming\s+(sunday|monday|tuesday|wednesday|thursday|friday|saturday|sun|mon|tue|wed|thu|fri|sat)(?:\s|$)/i, parse: (matches, preferences) => { const [fullMatch, weekday] = matches; const targetDay = WEEKDAYS[weekday.toLowerCase()]; const date = (preferences.referenceDate || luxon_1.DateTime.now()); // Get the next occurrence of the target weekday let result = date.set({ weekday: targetDay }); // For "upcoming", if the target day is more than 3 days away, // we want the immediate occurrence, even if it's in the past // This handles cases like "upcoming Tuesday" on a Monday if (result > date && result.diff(date, 'days').days > 3) { result = result.minus({ weeks: 1 }); } else if (result <= date) { result = result.plus({ weeks: 1 }); } const matchStart = matches.index + (fullMatch.startsWith(' ') ? 1 : 0); const matchEnd = matchStart + fullMatch.trim().length; return createDateComponent(result, { start: matchStart, end: matchEnd }, fullMatch.trim(), preferences, true); } }, { regex: /(?:^|\s)next\s+(sunday|monday|tuesday|wednesday|thursday|friday|saturday|sun|mon|tue|wed|thu|fri|sat)(?:\s|$)/i, parse: (matches, preferences) => { const [fullMatch, weekday] = matches; const targetDay = WEEKDAYS[weekday.toLowerCase()]; const date = (preferences.referenceDate || luxon_1.DateTime.now()); // Get the next occurrence of the target weekday let result = date.set({ weekday: targetDay }); // For "next", we always want next week's occurrence result = result.plus({ weeks: 1 }); const matchStart = matches.index + (fullMatch.startsWith(' ') ? 1 : 0); const matchEnd = matchStart + fullMatch.trim().length; return createDateComponent(result, { start: matchStart, end: matchEnd }, fullMatch.trim(), preferences, true); } } ]; exports.relativeDaysRule = { name: 'relative-days', patterns }; //# sourceMappingURL=relative-days.js.map