@whenis/booking 0.2.0 → 0.4.0
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.cjs +50 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -121,6 +121,28 @@ var weekendThisRule = {
|
|
|
121
121
|
convention: "checkout"
|
|
122
122
|
})
|
|
123
123
|
};
|
|
124
|
+
var weekendLastOfMonthRule = {
|
|
125
|
+
name: "booking-weekend-last-of-month",
|
|
126
|
+
priority: 82,
|
|
127
|
+
pattern: [
|
|
128
|
+
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "last") },
|
|
129
|
+
{ kind: "tag", tag: "Literal", predicate: (t) => /вихідн/i.test(t.text) },
|
|
130
|
+
{ kind: "tag", tag: "Connector", predicate: (t) => t.tags.some((x) => x.kind === "Connector" && x.conn === "in"), optional: true },
|
|
131
|
+
{ kind: "tag", tag: "MonthName", optional: true }
|
|
132
|
+
],
|
|
133
|
+
produce: (matched) => {
|
|
134
|
+
const monthTok = matched[3];
|
|
135
|
+
const mTag = monthTok?.tags.find((t) => t.kind === "MonthName");
|
|
136
|
+
const month = mTag && mTag.kind === "MonthName" ? mTag.month : void 0;
|
|
137
|
+
const start = month !== void 0 ? { type: "last_weekday_in_month", weekday: 6, month } : { type: "last_weekday_in_month", weekday: 6 };
|
|
138
|
+
return {
|
|
139
|
+
type: "range",
|
|
140
|
+
start,
|
|
141
|
+
end: { type: "offset_from", base: start, days: 1 },
|
|
142
|
+
convention: "checkout"
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
};
|
|
124
146
|
var holidayPislyaRule = {
|
|
125
147
|
name: "booking-holiday-pislya",
|
|
126
148
|
priority: 90,
|
|
@@ -149,12 +171,36 @@ var holidayNaRule = {
|
|
|
149
171
|
reason: "holiday_ref"
|
|
150
172
|
})
|
|
151
173
|
};
|
|
174
|
+
var bookingDateWithNightsRule = {
|
|
175
|
+
name: "booking-date-with-nights",
|
|
176
|
+
priority: 80,
|
|
177
|
+
pattern: [
|
|
178
|
+
{ kind: "tag", tag: "Connector", predicate: (t) => t.tags.some((x) => x.kind === "Connector" && x.conn === "from"), optional: true },
|
|
179
|
+
{ kind: "node", node: "absolute" },
|
|
180
|
+
{ kind: "node", node: "duration" }
|
|
181
|
+
],
|
|
182
|
+
produce: (matched) => {
|
|
183
|
+
const a = matched[1];
|
|
184
|
+
const d = matched[2];
|
|
185
|
+
if (a.type !== "absolute" || d.type !== "duration") return null;
|
|
186
|
+
const nights = d.nights;
|
|
187
|
+
if (nights === void 0) return null;
|
|
188
|
+
return {
|
|
189
|
+
type: "range",
|
|
190
|
+
start: a,
|
|
191
|
+
end: { type: "offset_from", base: a, days: nights },
|
|
192
|
+
convention: "checkout"
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
};
|
|
152
196
|
var bookingRules = [
|
|
153
197
|
windowWithinNRule,
|
|
154
198
|
windowWithinNWithPrefixRule,
|
|
199
|
+
bookingDateWithNightsRule,
|
|
155
200
|
stayDurationRule,
|
|
156
201
|
weekendNextRule,
|
|
157
202
|
weekendThisRule,
|
|
203
|
+
weekendLastOfMonthRule,
|
|
158
204
|
holidayPislyaRule,
|
|
159
205
|
holidayNaRule
|
|
160
206
|
];
|
|
@@ -162,8 +208,8 @@ var bookingTags = /* @__PURE__ */ new Map([
|
|
|
162
208
|
["\u0432\u043F\u0440\u043E\u0434\u043E\u0432\u0436", [{ kind: "Grabber", modifier: "within" }]],
|
|
163
209
|
["\u043D\u0430\u0439\u0431\u043B\u0438\u0436\u0447\u0456", [{ kind: "Grabber", modifier: "within" }]],
|
|
164
210
|
["\u043D\u0430\u0439\u0431\u043B\u0438\u0436\u0447\u0438\u0445", [{ kind: "Grabber", modifier: "within" }]],
|
|
165
|
-
["\u0443", [{ kind: "Connector", conn: "
|
|
166
|
-
["\u0432", [{ kind: "Connector", conn: "
|
|
211
|
+
["\u0443", [{ kind: "Connector", conn: "in" }]],
|
|
212
|
+
["\u0432", [{ kind: "Connector", conn: "in" }]],
|
|
167
213
|
["\u043D\u0430", [{ kind: "Connector", conn: "from" }]]
|
|
168
214
|
]);
|
|
169
215
|
|
|
@@ -174,7 +220,9 @@ var mostlyPastEnricher = {
|
|
|
174
220
|
apply(candidate, ctx) {
|
|
175
221
|
if (candidate.type !== "fuzzy") return candidate;
|
|
176
222
|
if (candidate.granularity !== "month") return candidate;
|
|
223
|
+
if (candidate.ref?.month === void 0) return candidate;
|
|
177
224
|
const ref = import_luxon.DateTime.fromJSDate(ctx.reference, { zone: ctx.timezone });
|
|
225
|
+
if (candidate.ref.month !== ref.month) return candidate;
|
|
178
226
|
const elapsed = ref.day / (ref.daysInMonth ?? 30);
|
|
179
227
|
if (elapsed < DEFAULT_THRESHOLD) return candidate;
|
|
180
228
|
return {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/rules.ts","../src/enrichers.ts"],"sourcesContent":["import type { Plugin } from '@whenis/core';\nimport { bookingRules, bookingTags } from './rules';\nimport { mostlyPastEnricher } from './enrichers';\n\nexport const booking: Plugin = {\n name: '@whenis/booking',\n tags: bookingTags,\n rules: bookingRules,\n enrichers: [mostlyPastEnricher],\n};\n","import type { Rule, Token, Tag, IRNode } from '@whenis/core';\n\nconst findTag = (t: Token, kind: string) => t.tags.find(x => x.kind === kind);\n\nfunction makeWindow(n: number, unit: 'day' | 'week'): IRNode {\n const days = unit === 'week' ? n * 7 : n;\n return {\n type: 'window',\n from: { type: 'relative', offset: { days: 0 }, direction: 'this' },\n to: { type: 'relative', offset: { days: days - 1 }, direction: 'future' },\n };\n}\n\n// \"впродовж 7 днів\" — also matches \"впродовж наступних 7 днів\" via optional next-filler\nexport const windowWithinNRule: Rule = {\n name: 'booking-window-within',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[2] as Token, 'Numeral');\n const u = findTag(matched[3] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\n// \"у найближчі 5 днів\" — also matches \"у наступні найближчі 5 днів\" via optional next-filler\nexport const windowWithinNWithPrefixRule: Rule = {\n name: 'booking-window-within-prefixed',\n priority: 76,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^[ув]$/i.test(t.text) },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[3] as Token, 'Numeral');\n const u = findTag(matched[4] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\nexport const stayDurationRule: Rule = {\n name: 'booking-stay-duration',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[1] as Token, 'Numeral');\n const u = findTag(matched[2] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n switch (u.unit) {\n case 'night': return { type: 'duration', nights: n.value };\n case 'day': return { type: 'duration', nights: n.value };\n case 'week': return { type: 'duration', nights: n.value * 7 };\n default: return null;\n }\n },\n};\n\nexport const weekendNextRule: Rule = {\n name: 'booking-weekend-next',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'next' },\n end: { type: 'weekday', weekday: 7, modifier: 'next' },\n convention: 'checkout',\n }),\n};\n\nexport const weekendThisRule: Rule = {\n name: 'booking-weekend-this',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Pointer', predicate: (t) => t.tags.some(x => x.kind === 'Pointer' && x.direction === 'this') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'this' },\n end: { type: 'weekday', weekday: 7, modifier: 'this' },\n convention: 'checkout',\n }),\n};\n\n// \"після свят\" — neither word has a tag in default UA lexicon, both arrive as Literal.\nexport const holidayPislyaRule: Rule = {\n name: 'booking-holiday-pislya',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^після$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\n// \"на свята\" — «на» is tagged by booking as Connector; «свят*» arrives as Literal.\nexport const holidayNaRule: Rule = {\n name: 'booking-holiday-na',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\nexport const bookingRules: Rule[] = [\n windowWithinNRule,\n windowWithinNWithPrefixRule,\n stayDurationRule,\n weekendNextRule,\n weekendThisRule,\n holidayPislyaRule,\n holidayNaRule,\n];\n\n// Tags the booking plugin contributes to ANY locale that uses it.\nexport const bookingTags = new Map<string, Tag[]>([\n ['впродовж', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчі', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчих', [{ kind: 'Grabber', modifier: 'within' }]],\n ['у', [{ kind: 'Connector', conn: 'from' }]],\n ['в', [{ kind: 'Connector', conn: 'from' }]],\n ['на', [{ kind: 'Connector', conn: 'from' }]],\n]);\n","import { DateTime } from 'luxon';\nimport type { Enricher, ResolverCtx, ResolvedDate } from '@whenis/core';\n\nconst DEFAULT_THRESHOLD = 0.75;\n\nexport const mostlyPastEnricher: Enricher = {\n apply(candidate: ResolvedDate, ctx: ResolverCtx): ResolvedDate {\n if (candidate.type !== 'fuzzy') return candidate;\n if (candidate.granularity !== 'month') return candidate;\n const ref = DateTime.fromJSDate(ctx.reference, { zone: ctx.timezone });\n const elapsed = ref.day / (ref.daysInMonth ?? 30);\n if (elapsed < DEFAULT_THRESHOLD) return candidate;\n return {\n ...candidate,\n metadata: { ...(candidate.metadata ?? {}), suggest_next_month: true },\n };\n },\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/rules.ts","../src/enrichers.ts"],"sourcesContent":["import type { Plugin } from '@whenis/core';\nimport { bookingRules, bookingTags } from './rules';\nimport { mostlyPastEnricher } from './enrichers';\n\nexport const booking: Plugin = {\n name: '@whenis/booking',\n tags: bookingTags,\n rules: bookingRules,\n enrichers: [mostlyPastEnricher],\n};\n","import type { Rule, Token, Tag, IRNode } from '@whenis/core';\n\nconst findTag = (t: Token, kind: string) => t.tags.find(x => x.kind === kind);\n\nfunction makeWindow(n: number, unit: 'day' | 'week'): IRNode {\n const days = unit === 'week' ? n * 7 : n;\n return {\n type: 'window',\n from: { type: 'relative', offset: { days: 0 }, direction: 'this' },\n to: { type: 'relative', offset: { days: days - 1 }, direction: 'future' },\n };\n}\n\n// \"впродовж 7 днів\" — also matches \"впродовж наступних 7 днів\" via optional next-filler\nexport const windowWithinNRule: Rule = {\n name: 'booking-window-within',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[2] as Token, 'Numeral');\n const u = findTag(matched[3] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\n// \"у найближчі 5 днів\" — also matches \"у наступні найближчі 5 днів\" via optional next-filler\nexport const windowWithinNWithPrefixRule: Rule = {\n name: 'booking-window-within-prefixed',\n priority: 76,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^[ув]$/i.test(t.text) },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[3] as Token, 'Numeral');\n const u = findTag(matched[4] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\nexport const stayDurationRule: Rule = {\n name: 'booking-stay-duration',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[1] as Token, 'Numeral');\n const u = findTag(matched[2] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n switch (u.unit) {\n case 'night': return { type: 'duration', nights: n.value };\n case 'day': return { type: 'duration', nights: n.value };\n case 'week': return { type: 'duration', nights: n.value * 7 };\n default: return null;\n }\n },\n};\n\nexport const weekendNextRule: Rule = {\n name: 'booking-weekend-next',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'next' },\n end: { type: 'weekday', weekday: 7, modifier: 'next' },\n convention: 'checkout',\n }),\n};\n\nexport const weekendThisRule: Rule = {\n name: 'booking-weekend-this',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Pointer', predicate: (t) => t.tags.some(x => x.kind === 'Pointer' && x.direction === 'this') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'this' },\n end: { type: 'weekday', weekday: 7, modifier: 'this' },\n convention: 'checkout',\n }),\n};\n\n// \"останні вихідні [в/у] [травня]\" — last Saturday-Sunday pair of the named (or current) month.\n// The 'в'/'у' filler (Connector:in) between the weekend literal and the month name is optional.\nexport const weekendLastOfMonthRule: Rule = {\n name: 'booking-weekend-last-of-month',\n priority: 82,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'last') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n { kind: 'tag', tag: 'Connector', predicate: (t) => t.tags.some(x => x.kind === 'Connector' && x.conn === 'in'), optional: true },\n { kind: 'tag', tag: 'MonthName', optional: true },\n ],\n produce: (matched) => {\n // matched[2] is the optional Connector:in filler (null if absent)\n // matched[3] is the optional MonthName (null if absent)\n const monthTok = matched[3] as Token | null;\n const mTag = monthTok?.tags.find(t => t.kind === 'MonthName');\n const month = mTag && mTag.kind === 'MonthName' ? mTag.month : undefined;\n const start: IRNode = month !== undefined\n ? { type: 'last_weekday_in_month', weekday: 6, month }\n : { type: 'last_weekday_in_month', weekday: 6 };\n return {\n type: 'range',\n start,\n end: { type: 'offset_from', base: start, days: 1 },\n convention: 'checkout',\n };\n },\n};\n\n// \"після свят\" — neither word has a tag in default UA lexicon, both arrive as Literal.\nexport const holidayPislyaRule: Rule = {\n name: 'booking-holiday-pislya',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^після$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\n// \"на свята\" — «на» is tagged by booking as Connector; «свят*» arrives as Literal.\nexport const holidayNaRule: Rule = {\n name: 'booking-holiday-na',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\n// \"[з] 5 червня на 3 ночі\" — combine a previously-emitted absolute date with a\n// duration into a single range. Both sub-IRs are produced by their own rules\n// at lower priority (60 / 75); this rule fires next, gluing them together.\nexport const bookingDateWithNightsRule: Rule = {\n name: 'booking-date-with-nights',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => t.tags.some(x => x.kind === 'Connector' && x.conn === 'from'), optional: true },\n { kind: 'node', node: 'absolute' },\n { kind: 'node', node: 'duration' },\n ],\n produce: (matched) => {\n const a = matched[1] as IRNode;\n const d = matched[2] as IRNode;\n if (a.type !== 'absolute' || d.type !== 'duration') return null;\n const nights = d.nights;\n if (nights === undefined) return null;\n return {\n type: 'range',\n start: a,\n end: { type: 'offset_from', base: a, days: nights },\n convention: 'checkout',\n };\n },\n};\n\nexport const bookingRules: Rule[] = [\n windowWithinNRule,\n windowWithinNWithPrefixRule,\n bookingDateWithNightsRule,\n stayDurationRule,\n weekendNextRule,\n weekendThisRule,\n weekendLastOfMonthRule,\n holidayPislyaRule,\n holidayNaRule,\n];\n\n// Tags the booking plugin contributes to ANY locale that uses it.\nexport const bookingTags = new Map<string, Tag[]>([\n ['впродовж', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчі', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчих', [{ kind: 'Grabber', modifier: 'within' }]],\n ['у', [{ kind: 'Connector', conn: 'in' }]],\n ['в', [{ kind: 'Connector', conn: 'in' }]],\n ['на', [{ kind: 'Connector', conn: 'from' }]],\n]);\n","import { DateTime } from 'luxon';\nimport type { Enricher, ResolverCtx, ResolvedDate } from '@whenis/core';\n\nconst DEFAULT_THRESHOLD = 0.75;\n\nexport const mostlyPastEnricher: Enricher = {\n apply(candidate: ResolvedDate, ctx: ResolverCtx): ResolvedDate {\n if (candidate.type !== 'fuzzy') return candidate;\n if (candidate.granularity !== 'month') return candidate;\n if (candidate.ref?.month === undefined) return candidate;\n const ref = DateTime.fromJSDate(ctx.reference, { zone: ctx.timezone });\n if (candidate.ref.month !== ref.month) return candidate;\n const elapsed = ref.day / (ref.daysInMonth ?? 30);\n if (elapsed < DEFAULT_THRESHOLD) return candidate;\n return {\n ...candidate,\n metadata: { ...(candidate.metadata ?? {}), suggest_next_month: true },\n };\n },\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -95,6 +95,28 @@ var weekendThisRule = {
|
|
|
95
95
|
convention: "checkout"
|
|
96
96
|
})
|
|
97
97
|
};
|
|
98
|
+
var weekendLastOfMonthRule = {
|
|
99
|
+
name: "booking-weekend-last-of-month",
|
|
100
|
+
priority: 82,
|
|
101
|
+
pattern: [
|
|
102
|
+
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "last") },
|
|
103
|
+
{ kind: "tag", tag: "Literal", predicate: (t) => /вихідн/i.test(t.text) },
|
|
104
|
+
{ kind: "tag", tag: "Connector", predicate: (t) => t.tags.some((x) => x.kind === "Connector" && x.conn === "in"), optional: true },
|
|
105
|
+
{ kind: "tag", tag: "MonthName", optional: true }
|
|
106
|
+
],
|
|
107
|
+
produce: (matched) => {
|
|
108
|
+
const monthTok = matched[3];
|
|
109
|
+
const mTag = monthTok?.tags.find((t) => t.kind === "MonthName");
|
|
110
|
+
const month = mTag && mTag.kind === "MonthName" ? mTag.month : void 0;
|
|
111
|
+
const start = month !== void 0 ? { type: "last_weekday_in_month", weekday: 6, month } : { type: "last_weekday_in_month", weekday: 6 };
|
|
112
|
+
return {
|
|
113
|
+
type: "range",
|
|
114
|
+
start,
|
|
115
|
+
end: { type: "offset_from", base: start, days: 1 },
|
|
116
|
+
convention: "checkout"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
};
|
|
98
120
|
var holidayPislyaRule = {
|
|
99
121
|
name: "booking-holiday-pislya",
|
|
100
122
|
priority: 90,
|
|
@@ -123,12 +145,36 @@ var holidayNaRule = {
|
|
|
123
145
|
reason: "holiday_ref"
|
|
124
146
|
})
|
|
125
147
|
};
|
|
148
|
+
var bookingDateWithNightsRule = {
|
|
149
|
+
name: "booking-date-with-nights",
|
|
150
|
+
priority: 80,
|
|
151
|
+
pattern: [
|
|
152
|
+
{ kind: "tag", tag: "Connector", predicate: (t) => t.tags.some((x) => x.kind === "Connector" && x.conn === "from"), optional: true },
|
|
153
|
+
{ kind: "node", node: "absolute" },
|
|
154
|
+
{ kind: "node", node: "duration" }
|
|
155
|
+
],
|
|
156
|
+
produce: (matched) => {
|
|
157
|
+
const a = matched[1];
|
|
158
|
+
const d = matched[2];
|
|
159
|
+
if (a.type !== "absolute" || d.type !== "duration") return null;
|
|
160
|
+
const nights = d.nights;
|
|
161
|
+
if (nights === void 0) return null;
|
|
162
|
+
return {
|
|
163
|
+
type: "range",
|
|
164
|
+
start: a,
|
|
165
|
+
end: { type: "offset_from", base: a, days: nights },
|
|
166
|
+
convention: "checkout"
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
};
|
|
126
170
|
var bookingRules = [
|
|
127
171
|
windowWithinNRule,
|
|
128
172
|
windowWithinNWithPrefixRule,
|
|
173
|
+
bookingDateWithNightsRule,
|
|
129
174
|
stayDurationRule,
|
|
130
175
|
weekendNextRule,
|
|
131
176
|
weekendThisRule,
|
|
177
|
+
weekendLastOfMonthRule,
|
|
132
178
|
holidayPislyaRule,
|
|
133
179
|
holidayNaRule
|
|
134
180
|
];
|
|
@@ -136,8 +182,8 @@ var bookingTags = /* @__PURE__ */ new Map([
|
|
|
136
182
|
["\u0432\u043F\u0440\u043E\u0434\u043E\u0432\u0436", [{ kind: "Grabber", modifier: "within" }]],
|
|
137
183
|
["\u043D\u0430\u0439\u0431\u043B\u0438\u0436\u0447\u0456", [{ kind: "Grabber", modifier: "within" }]],
|
|
138
184
|
["\u043D\u0430\u0439\u0431\u043B\u0438\u0436\u0447\u0438\u0445", [{ kind: "Grabber", modifier: "within" }]],
|
|
139
|
-
["\u0443", [{ kind: "Connector", conn: "
|
|
140
|
-
["\u0432", [{ kind: "Connector", conn: "
|
|
185
|
+
["\u0443", [{ kind: "Connector", conn: "in" }]],
|
|
186
|
+
["\u0432", [{ kind: "Connector", conn: "in" }]],
|
|
141
187
|
["\u043D\u0430", [{ kind: "Connector", conn: "from" }]]
|
|
142
188
|
]);
|
|
143
189
|
|
|
@@ -148,7 +194,9 @@ var mostlyPastEnricher = {
|
|
|
148
194
|
apply(candidate, ctx) {
|
|
149
195
|
if (candidate.type !== "fuzzy") return candidate;
|
|
150
196
|
if (candidate.granularity !== "month") return candidate;
|
|
197
|
+
if (candidate.ref?.month === void 0) return candidate;
|
|
151
198
|
const ref = DateTime.fromJSDate(ctx.reference, { zone: ctx.timezone });
|
|
199
|
+
if (candidate.ref.month !== ref.month) return candidate;
|
|
152
200
|
const elapsed = ref.day / (ref.daysInMonth ?? 30);
|
|
153
201
|
if (elapsed < DEFAULT_THRESHOLD) return candidate;
|
|
154
202
|
return {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rules.ts","../src/enrichers.ts","../src/index.ts"],"sourcesContent":["import type { Rule, Token, Tag, IRNode } from '@whenis/core';\n\nconst findTag = (t: Token, kind: string) => t.tags.find(x => x.kind === kind);\n\nfunction makeWindow(n: number, unit: 'day' | 'week'): IRNode {\n const days = unit === 'week' ? n * 7 : n;\n return {\n type: 'window',\n from: { type: 'relative', offset: { days: 0 }, direction: 'this' },\n to: { type: 'relative', offset: { days: days - 1 }, direction: 'future' },\n };\n}\n\n// \"впродовж 7 днів\" — also matches \"впродовж наступних 7 днів\" via optional next-filler\nexport const windowWithinNRule: Rule = {\n name: 'booking-window-within',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[2] as Token, 'Numeral');\n const u = findTag(matched[3] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\n// \"у найближчі 5 днів\" — also matches \"у наступні найближчі 5 днів\" via optional next-filler\nexport const windowWithinNWithPrefixRule: Rule = {\n name: 'booking-window-within-prefixed',\n priority: 76,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^[ув]$/i.test(t.text) },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[3] as Token, 'Numeral');\n const u = findTag(matched[4] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\nexport const stayDurationRule: Rule = {\n name: 'booking-stay-duration',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[1] as Token, 'Numeral');\n const u = findTag(matched[2] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n switch (u.unit) {\n case 'night': return { type: 'duration', nights: n.value };\n case 'day': return { type: 'duration', nights: n.value };\n case 'week': return { type: 'duration', nights: n.value * 7 };\n default: return null;\n }\n },\n};\n\nexport const weekendNextRule: Rule = {\n name: 'booking-weekend-next',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'next' },\n end: { type: 'weekday', weekday: 7, modifier: 'next' },\n convention: 'checkout',\n }),\n};\n\nexport const weekendThisRule: Rule = {\n name: 'booking-weekend-this',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Pointer', predicate: (t) => t.tags.some(x => x.kind === 'Pointer' && x.direction === 'this') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'this' },\n end: { type: 'weekday', weekday: 7, modifier: 'this' },\n convention: 'checkout',\n }),\n};\n\n// \"після свят\" — neither word has a tag in default UA lexicon, both arrive as Literal.\nexport const holidayPislyaRule: Rule = {\n name: 'booking-holiday-pislya',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^після$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\n// \"на свята\" — «на» is tagged by booking as Connector; «свят*» arrives as Literal.\nexport const holidayNaRule: Rule = {\n name: 'booking-holiday-na',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\nexport const bookingRules: Rule[] = [\n windowWithinNRule,\n windowWithinNWithPrefixRule,\n stayDurationRule,\n weekendNextRule,\n weekendThisRule,\n holidayPislyaRule,\n holidayNaRule,\n];\n\n// Tags the booking plugin contributes to ANY locale that uses it.\nexport const bookingTags = new Map<string, Tag[]>([\n ['впродовж', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчі', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчих', [{ kind: 'Grabber', modifier: 'within' }]],\n ['у', [{ kind: 'Connector', conn: 'from' }]],\n ['в', [{ kind: 'Connector', conn: 'from' }]],\n ['на', [{ kind: 'Connector', conn: 'from' }]],\n]);\n","import { DateTime } from 'luxon';\nimport type { Enricher, ResolverCtx, ResolvedDate } from '@whenis/core';\n\nconst DEFAULT_THRESHOLD = 0.75;\n\nexport const mostlyPastEnricher: Enricher = {\n apply(candidate: ResolvedDate, ctx: ResolverCtx): ResolvedDate {\n if (candidate.type !== 'fuzzy') return candidate;\n if (candidate.granularity !== 'month') return candidate;\n const ref = DateTime.fromJSDate(ctx.reference, { zone: ctx.timezone });\n const elapsed = ref.day / (ref.daysInMonth ?? 30);\n if (elapsed < DEFAULT_THRESHOLD) return candidate;\n return {\n ...candidate,\n metadata: { ...(candidate.metadata ?? {}), suggest_next_month: true },\n };\n },\n};\n","import type { Plugin } from '@whenis/core';\nimport { bookingRules, bookingTags } from './rules';\nimport { mostlyPastEnricher } from './enrichers';\n\nexport const booking: Plugin = {\n name: '@whenis/booking',\n tags: bookingTags,\n rules: bookingRules,\n enrichers: [mostlyPastEnricher],\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/rules.ts","../src/enrichers.ts","../src/index.ts"],"sourcesContent":["import type { Rule, Token, Tag, IRNode } from '@whenis/core';\n\nconst findTag = (t: Token, kind: string) => t.tags.find(x => x.kind === kind);\n\nfunction makeWindow(n: number, unit: 'day' | 'week'): IRNode {\n const days = unit === 'week' ? n * 7 : n;\n return {\n type: 'window',\n from: { type: 'relative', offset: { days: 0 }, direction: 'this' },\n to: { type: 'relative', offset: { days: days - 1 }, direction: 'future' },\n };\n}\n\n// \"впродовж 7 днів\" — also matches \"впродовж наступних 7 днів\" via optional next-filler\nexport const windowWithinNRule: Rule = {\n name: 'booking-window-within',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[2] as Token, 'Numeral');\n const u = findTag(matched[3] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\n// \"у найближчі 5 днів\" — also matches \"у наступні найближчі 5 днів\" via optional next-filler\nexport const windowWithinNWithPrefixRule: Rule = {\n name: 'booking-window-within-prefixed',\n priority: 76,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^[ув]$/i.test(t.text) },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'within') },\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next'), optional: true },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[3] as Token, 'Numeral');\n const u = findTag(matched[4] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\nexport const stayDurationRule: Rule = {\n name: 'booking-stay-duration',\n priority: 75,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Numeral' },\n { kind: 'tag', tag: 'TimeUnit' },\n ],\n produce: (matched) => {\n const n = findTag(matched[1] as Token, 'Numeral');\n const u = findTag(matched[2] as Token, 'TimeUnit');\n if (!n || n.kind !== 'Numeral' || !u || u.kind !== 'TimeUnit') return null;\n switch (u.unit) {\n case 'night': return { type: 'duration', nights: n.value };\n case 'day': return { type: 'duration', nights: n.value };\n case 'week': return { type: 'duration', nights: n.value * 7 };\n default: return null;\n }\n },\n};\n\nexport const weekendNextRule: Rule = {\n name: 'booking-weekend-next',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'next') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'next' },\n end: { type: 'weekday', weekday: 7, modifier: 'next' },\n convention: 'checkout',\n }),\n};\n\nexport const weekendThisRule: Rule = {\n name: 'booking-weekend-this',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Pointer', predicate: (t) => t.tags.some(x => x.kind === 'Pointer' && x.direction === 'this') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n ],\n produce: () => ({\n type: 'range',\n start: { type: 'weekday', weekday: 6, modifier: 'this' },\n end: { type: 'weekday', weekday: 7, modifier: 'this' },\n convention: 'checkout',\n }),\n};\n\n// \"останні вихідні [в/у] [травня]\" — last Saturday-Sunday pair of the named (or current) month.\n// The 'в'/'у' filler (Connector:in) between the weekend literal and the month name is optional.\nexport const weekendLastOfMonthRule: Rule = {\n name: 'booking-weekend-last-of-month',\n priority: 82,\n pattern: [\n { kind: 'tag', tag: 'Grabber', predicate: (t) => t.tags.some(x => x.kind === 'Grabber' && x.modifier === 'last') },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /вихідн/i.test(t.text) },\n { kind: 'tag', tag: 'Connector', predicate: (t) => t.tags.some(x => x.kind === 'Connector' && x.conn === 'in'), optional: true },\n { kind: 'tag', tag: 'MonthName', optional: true },\n ],\n produce: (matched) => {\n // matched[2] is the optional Connector:in filler (null if absent)\n // matched[3] is the optional MonthName (null if absent)\n const monthTok = matched[3] as Token | null;\n const mTag = monthTok?.tags.find(t => t.kind === 'MonthName');\n const month = mTag && mTag.kind === 'MonthName' ? mTag.month : undefined;\n const start: IRNode = month !== undefined\n ? { type: 'last_weekday_in_month', weekday: 6, month }\n : { type: 'last_weekday_in_month', weekday: 6 };\n return {\n type: 'range',\n start,\n end: { type: 'offset_from', base: start, days: 1 },\n convention: 'checkout',\n };\n },\n};\n\n// \"після свят\" — neither word has a tag in default UA lexicon, both arrive as Literal.\nexport const holidayPislyaRule: Rule = {\n name: 'booking-holiday-pislya',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^після$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\n// \"на свята\" — «на» is tagged by booking as Connector; «свят*» arrives as Literal.\nexport const holidayNaRule: Rule = {\n name: 'booking-holiday-na',\n priority: 90,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => /^на$/i.test(t.text) },\n { kind: 'tag', tag: 'Literal', predicate: (t) => /^свят/i.test(t.text) },\n ],\n produce: () => ({\n type: 'fuzzy',\n granularity: 'month',\n ref: { type: 'absolute' },\n reason: 'holiday_ref',\n }),\n};\n\n// \"[з] 5 червня на 3 ночі\" — combine a previously-emitted absolute date with a\n// duration into a single range. Both sub-IRs are produced by their own rules\n// at lower priority (60 / 75); this rule fires next, gluing them together.\nexport const bookingDateWithNightsRule: Rule = {\n name: 'booking-date-with-nights',\n priority: 80,\n pattern: [\n { kind: 'tag', tag: 'Connector', predicate: (t) => t.tags.some(x => x.kind === 'Connector' && x.conn === 'from'), optional: true },\n { kind: 'node', node: 'absolute' },\n { kind: 'node', node: 'duration' },\n ],\n produce: (matched) => {\n const a = matched[1] as IRNode;\n const d = matched[2] as IRNode;\n if (a.type !== 'absolute' || d.type !== 'duration') return null;\n const nights = d.nights;\n if (nights === undefined) return null;\n return {\n type: 'range',\n start: a,\n end: { type: 'offset_from', base: a, days: nights },\n convention: 'checkout',\n };\n },\n};\n\nexport const bookingRules: Rule[] = [\n windowWithinNRule,\n windowWithinNWithPrefixRule,\n bookingDateWithNightsRule,\n stayDurationRule,\n weekendNextRule,\n weekendThisRule,\n weekendLastOfMonthRule,\n holidayPislyaRule,\n holidayNaRule,\n];\n\n// Tags the booking plugin contributes to ANY locale that uses it.\nexport const bookingTags = new Map<string, Tag[]>([\n ['впродовж', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчі', [{ kind: 'Grabber', modifier: 'within' }]],\n ['найближчих', [{ kind: 'Grabber', modifier: 'within' }]],\n ['у', [{ kind: 'Connector', conn: 'in' }]],\n ['в', [{ kind: 'Connector', conn: 'in' }]],\n ['на', [{ kind: 'Connector', conn: 'from' }]],\n]);\n","import { DateTime } from 'luxon';\nimport type { Enricher, ResolverCtx, ResolvedDate } from '@whenis/core';\n\nconst DEFAULT_THRESHOLD = 0.75;\n\nexport const mostlyPastEnricher: Enricher = {\n apply(candidate: ResolvedDate, ctx: ResolverCtx): ResolvedDate {\n if (candidate.type !== 'fuzzy') return candidate;\n if (candidate.granularity !== 'month') return candidate;\n if (candidate.ref?.month === undefined) return candidate;\n const ref = DateTime.fromJSDate(ctx.reference, { zone: ctx.timezone });\n if (candidate.ref.month !== ref.month) return candidate;\n const elapsed = ref.day / (ref.daysInMonth ?? 30);\n if (elapsed < DEFAULT_THRESHOLD) return candidate;\n return {\n ...candidate,\n metadata: { ...(candidate.metadata ?? {}), suggest_next_month: true },\n };\n },\n};\n","import type { Plugin } from '@whenis/core';\nimport { bookingRules, bookingTags } from './rules';\nimport { mostlyPastEnricher } from './enrichers';\n\nexport const booking: Plugin = {\n name: '@whenis/booking',\n tags: bookingTags,\n rules: bookingRules,\n enrichers: [mostlyPastEnricher],\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whenis/booking",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Booking-domain plugin for whenis — search windows, stay durations, weekend semantics, holiday references, mostly-past month enricher.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"date",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/luxon": "^3.4.0",
|
|
63
|
-
"@whenis/core": "0.
|
|
63
|
+
"@whenis/core": "0.4.0"
|
|
64
64
|
},
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|