@whenis/booking 0.1.1 → 0.3.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 +51 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +51 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -39,12 +39,13 @@ var windowWithinNRule = {
|
|
|
39
39
|
priority: 75,
|
|
40
40
|
pattern: [
|
|
41
41
|
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "within") },
|
|
42
|
+
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "next"), optional: true },
|
|
42
43
|
{ kind: "tag", tag: "Numeral" },
|
|
43
44
|
{ kind: "tag", tag: "TimeUnit" }
|
|
44
45
|
],
|
|
45
46
|
produce: (matched) => {
|
|
46
|
-
const n = findTag(matched[
|
|
47
|
-
const u = findTag(matched[
|
|
47
|
+
const n = findTag(matched[2], "Numeral");
|
|
48
|
+
const u = findTag(matched[3], "TimeUnit");
|
|
48
49
|
if (!n || n.kind !== "Numeral" || !u || u.kind !== "TimeUnit") return null;
|
|
49
50
|
if (u.unit !== "day" && u.unit !== "week") return null;
|
|
50
51
|
return makeWindow(n.value, u.unit);
|
|
@@ -56,12 +57,13 @@ var windowWithinNWithPrefixRule = {
|
|
|
56
57
|
pattern: [
|
|
57
58
|
{ kind: "tag", tag: "Connector", predicate: (t) => /^[ув]$/i.test(t.text) },
|
|
58
59
|
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "within") },
|
|
60
|
+
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "next"), optional: true },
|
|
59
61
|
{ kind: "tag", tag: "Numeral" },
|
|
60
62
|
{ kind: "tag", tag: "TimeUnit" }
|
|
61
63
|
],
|
|
62
64
|
produce: (matched) => {
|
|
63
|
-
const n = findTag(matched[
|
|
64
|
-
const u = findTag(matched[
|
|
65
|
+
const n = findTag(matched[3], "Numeral");
|
|
66
|
+
const u = findTag(matched[4], "TimeUnit");
|
|
65
67
|
if (!n || n.kind !== "Numeral" || !u || u.kind !== "TimeUnit") return null;
|
|
66
68
|
if (u.unit !== "day" && u.unit !== "week") return null;
|
|
67
69
|
return makeWindow(n.value, u.unit);
|
|
@@ -119,6 +121,27 @@ var weekendThisRule = {
|
|
|
119
121
|
convention: "checkout"
|
|
120
122
|
})
|
|
121
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: "MonthName", optional: true }
|
|
131
|
+
],
|
|
132
|
+
produce: (matched) => {
|
|
133
|
+
const monthTok = matched[2];
|
|
134
|
+
const mTag = monthTok?.tags.find((t) => t.kind === "MonthName");
|
|
135
|
+
const month = mTag && mTag.kind === "MonthName" ? mTag.month : void 0;
|
|
136
|
+
const start = month !== void 0 ? { type: "last_weekday_in_month", weekday: 6, month } : { type: "last_weekday_in_month", weekday: 6 };
|
|
137
|
+
return {
|
|
138
|
+
type: "range",
|
|
139
|
+
start,
|
|
140
|
+
end: { type: "offset_from", base: start, days: 1 },
|
|
141
|
+
convention: "checkout"
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
};
|
|
122
145
|
var holidayPislyaRule = {
|
|
123
146
|
name: "booking-holiday-pislya",
|
|
124
147
|
priority: 90,
|
|
@@ -147,12 +170,36 @@ var holidayNaRule = {
|
|
|
147
170
|
reason: "holiday_ref"
|
|
148
171
|
})
|
|
149
172
|
};
|
|
173
|
+
var bookingDateWithNightsRule = {
|
|
174
|
+
name: "booking-date-with-nights",
|
|
175
|
+
priority: 80,
|
|
176
|
+
pattern: [
|
|
177
|
+
{ kind: "tag", tag: "Connector", predicate: (t) => t.tags.some((x) => x.kind === "Connector" && x.conn === "from"), optional: true },
|
|
178
|
+
{ kind: "node", node: "absolute" },
|
|
179
|
+
{ kind: "node", node: "duration" }
|
|
180
|
+
],
|
|
181
|
+
produce: (matched) => {
|
|
182
|
+
const a = matched[1];
|
|
183
|
+
const d = matched[2];
|
|
184
|
+
if (a.type !== "absolute" || d.type !== "duration") return null;
|
|
185
|
+
const nights = d.nights;
|
|
186
|
+
if (nights === void 0) return null;
|
|
187
|
+
return {
|
|
188
|
+
type: "range",
|
|
189
|
+
start: a,
|
|
190
|
+
end: { type: "offset_from", base: a, days: nights },
|
|
191
|
+
convention: "checkout"
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
150
195
|
var bookingRules = [
|
|
151
196
|
windowWithinNRule,
|
|
152
197
|
windowWithinNWithPrefixRule,
|
|
198
|
+
bookingDateWithNightsRule,
|
|
153
199
|
stayDurationRule,
|
|
154
200
|
weekendNextRule,
|
|
155
201
|
weekendThisRule,
|
|
202
|
+
weekendLastOfMonthRule,
|
|
156
203
|
holidayPislyaRule,
|
|
157
204
|
holidayNaRule
|
|
158
205
|
];
|
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 днів\" — 3-token form\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: '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 if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\n// \"у найближчі 5 днів\" — 4-token form with leading «у/в» Connector\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: '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\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAM,UAAU,CAAC,GAAU,SAAiB,EAAE,KAAK,KAAK,OAAK,EAAE,SAAS,IAAI;AAE5E,SAAS,WAAW,GAAW,MAA8B;AAC3D,QAAM,OAAO,SAAS,SAAS,IAAI,IAAI;AACvC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,EAAE,MAAM,YAAY,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,OAAO;AAAA,IACjE,IAAM,EAAE,MAAM,YAAY,QAAQ,EAAE,MAAM,OAAO,EAAE,GAAG,WAAW,SAAS;AAAA,EAC5E;AACF;AAGO,IAAM,oBAA0B;AAAA,EACrC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,EAAE,KAAK,KAAK,OAAK,EAAE,SAAS,aAAa,EAAE,aAAa,QAAQ,EAAE;AAAA,IACnH,EAAE,MAAM,OAAO,KAAK,UAAU;AAAA,IAC9B,EAAE,MAAM,OAAO,KAAK,WAAW;AAAA,EACjC;AAAA,EACA,SAAS,CAAC,YAAY;AACpB,UAAM,IAAI,QAAQ,QAAQ,CAAC,GAAY,SAAS;AAChD,UAAM,IAAI,QAAQ,QAAQ,CAAC,GAAY,UAAU;AACjD,QAAI,CAAC,KAAK,EAAE,SAAS,aAAa,CAAC,KAAK,EAAE,SAAS,WAAY,QAAO;AACtE,QAAI,EAAE,SAAS,SAAS,EAAE,SAAS,OAAQ,QAAO;AAClD,WAAO,WAAW,EAAE,OAAO,EAAE,IAAI;AAAA,EACnC;AACF;AAGO,IAAM,8BAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,aAAa,WAAW,CAAC,MAAM,UAAU,KAAK,EAAE,IAAI,EAAE;AAAA,IAC1E,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,EAAE,KAAK,KAAK,OAAK,EAAE,SAAS,aAAa,EAAE,aAAa,QAAQ,EAAE;AAAA,IACnH,EAAE,MAAM,OAAO,KAAK,UAAU;AAAA,IAC9B,EAAE,MAAM,OAAO,KAAK,WAAW;AAAA,EACjC;AAAA,EACA,SAAS,CAAC,YAAY;AACpB,UAAM,IAAI,QAAQ,QAAQ,CAAC,GAAY,SAAS;AAChD,UAAM,IAAI,QAAQ,QAAQ,CAAC,GAAY,UAAU;AACjD,QAAI,CAAC,KAAK,EAAE,SAAS,aAAa,CAAC,KAAK,EAAE,SAAS,WAAY,QAAO;AACtE,QAAI,EAAE,SAAS,SAAS,EAAE,SAAS,OAAQ,QAAO;AAClD,WAAO,WAAW,EAAE,OAAO,EAAE,IAAI;AAAA,EACnC;AACF;AAEO,IAAM,mBAAyB;AAAA,EACpC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,aAAa,WAAW,CAAC,MAAM,QAAQ,KAAK,EAAE,IAAI,EAAE;AAAA,IACxE,EAAE,MAAM,OAAO,KAAK,UAAU;AAAA,IAC9B,EAAE,MAAM,OAAO,KAAK,WAAW;AAAA,EACjC;AAAA,EACA,SAAS,CAAC,YAAY;AACpB,UAAM,IAAI,QAAQ,QAAQ,CAAC,GAAY,SAAS;AAChD,UAAM,IAAI,QAAQ,QAAQ,CAAC,GAAY,UAAU;AACjD,QAAI,CAAC,KAAK,EAAE,SAAS,aAAa,CAAC,KAAK,EAAE,SAAS,WAAY,QAAO;AACtE,YAAQ,EAAE,MAAM;AAAA,MACd,KAAK;AAAS,eAAO,EAAE,MAAM,YAAY,QAAQ,EAAE,MAAM;AAAA,MACzD,KAAK;AAAS,eAAO,EAAE,MAAM,YAAY,QAAQ,EAAE,MAAM;AAAA,MACzD,KAAK;AAAS,eAAO,EAAE,MAAM,YAAY,QAAQ,EAAE,QAAQ,EAAE;AAAA,MAC7D;AAAc,eAAO;AAAA,IACvB;AAAA,EACF;AACF;AAEO,IAAM,kBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,EAAE,KAAK,KAAK,OAAK,EAAE,SAAS,aAAa,EAAE,aAAa,MAAM,EAAE;AAAA,IACjH,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,UAAU,KAAK,EAAE,IAAI,EAAE;AAAA,EAC1E;AAAA,EACA,SAAS,OAAO;AAAA,IACd,MAAM;AAAA,IACN,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,UAAU,OAAO;AAAA,IACvD,KAAO,EAAE,MAAM,WAAW,SAAS,GAAG,UAAU,OAAO;AAAA,IACvD,YAAY;AAAA,EACd;AACF;AAEO,IAAM,kBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,EAAE,KAAK,KAAK,OAAK,EAAE,SAAS,aAAa,EAAE,cAAc,MAAM,EAAE;AAAA,IAClH,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,UAAU,KAAK,EAAE,IAAI,EAAE;AAAA,EAC1E;AAAA,EACA,SAAS,OAAO;AAAA,IACd,MAAM;AAAA,IACN,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,UAAU,OAAO;AAAA,IACvD,KAAO,EAAE,MAAM,WAAW,SAAS,GAAG,UAAU,OAAO;AAAA,IACvD,YAAY;AAAA,EACd;AACF;AAGO,IAAM,oBAA0B;AAAA,EACrC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,WAAW,KAAK,EAAE,IAAI,EAAE;AAAA,IACzE,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,SAAS,KAAK,EAAE,IAAI,EAAE;AAAA,EACzE;AAAA,EACA,SAAS,OAAO;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,KAAK,EAAE,MAAM,WAAW;AAAA,IACxB,QAAQ;AAAA,EACV;AACF;AAGO,IAAM,gBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,IACP,EAAE,MAAM,OAAO,KAAK,aAAa,WAAW,CAAC,MAAM,QAAQ,KAAK,EAAE,IAAI,EAAE;AAAA,IACxE,EAAE,MAAM,OAAO,KAAK,WAAW,WAAW,CAAC,MAAM,SAAS,KAAK,EAAE,IAAI,EAAE;AAAA,EACzE;AAAA,EACA,SAAS,OAAO;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,KAAK,EAAE,MAAM,WAAW;AAAA,IACxB,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,eAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,cAAc,oBAAI,IAAmB;AAAA,EAChD,CAAC,oDAAY,CAAC,EAAE,MAAM,WAAW,UAAU,SAAS,CAAC,CAAC;AAAA,EACtD,CAAC,0DAAa,CAAC,EAAE,MAAM,WAAW,UAAU,SAAS,CAAC,CAAC;AAAA,EACvD,CAAC,gEAAc,CAAC,EAAE,MAAM,WAAW,UAAU,SAAS,CAAC,CAAC;AAAA,EACxD,CAAC,UAAK,CAAC,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC,CAAC;AAAA,EAC3C,CAAC,UAAK,CAAC,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC,CAAC;AAAA,EAC3C,CAAC,gBAAM,CAAC,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC,CAAC;AAC9C,CAAC;;;ACvJD,mBAAyB;AAGzB,IAAM,oBAAoB;AAEnB,IAAM,qBAA+B;AAAA,EAC1C,MAAM,WAAyB,KAAgC;AAC7D,QAAI,UAAU,SAAS,QAAS,QAAO;AACvC,QAAI,UAAU,gBAAgB,QAAS,QAAO;AAC9C,UAAM,MAAM,sBAAS,WAAW,IAAI,WAAW,EAAE,MAAM,IAAI,SAAS,CAAC;AACrE,UAAM,UAAU,IAAI,OAAO,IAAI,eAAe;AAC9C,QAAI,UAAU,kBAAmB,QAAO;AACxC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,EAAE,GAAI,UAAU,YAAY,CAAC,GAAI,oBAAoB,KAAK;AAAA,IACtE;AAAA,EACF;AACF;;;AFbO,IAAM,UAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW,CAAC,kBAAkB;AAChC;","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.\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: 'MonthName', optional: true },\n ],\n produce: (matched) => {\n const monthTok = matched[2] 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: '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":[]}
|
package/dist/index.js
CHANGED
|
@@ -13,12 +13,13 @@ var windowWithinNRule = {
|
|
|
13
13
|
priority: 75,
|
|
14
14
|
pattern: [
|
|
15
15
|
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "within") },
|
|
16
|
+
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "next"), optional: true },
|
|
16
17
|
{ kind: "tag", tag: "Numeral" },
|
|
17
18
|
{ kind: "tag", tag: "TimeUnit" }
|
|
18
19
|
],
|
|
19
20
|
produce: (matched) => {
|
|
20
|
-
const n = findTag(matched[
|
|
21
|
-
const u = findTag(matched[
|
|
21
|
+
const n = findTag(matched[2], "Numeral");
|
|
22
|
+
const u = findTag(matched[3], "TimeUnit");
|
|
22
23
|
if (!n || n.kind !== "Numeral" || !u || u.kind !== "TimeUnit") return null;
|
|
23
24
|
if (u.unit !== "day" && u.unit !== "week") return null;
|
|
24
25
|
return makeWindow(n.value, u.unit);
|
|
@@ -30,12 +31,13 @@ var windowWithinNWithPrefixRule = {
|
|
|
30
31
|
pattern: [
|
|
31
32
|
{ kind: "tag", tag: "Connector", predicate: (t) => /^[ув]$/i.test(t.text) },
|
|
32
33
|
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "within") },
|
|
34
|
+
{ kind: "tag", tag: "Grabber", predicate: (t) => t.tags.some((x) => x.kind === "Grabber" && x.modifier === "next"), optional: true },
|
|
33
35
|
{ kind: "tag", tag: "Numeral" },
|
|
34
36
|
{ kind: "tag", tag: "TimeUnit" }
|
|
35
37
|
],
|
|
36
38
|
produce: (matched) => {
|
|
37
|
-
const n = findTag(matched[
|
|
38
|
-
const u = findTag(matched[
|
|
39
|
+
const n = findTag(matched[3], "Numeral");
|
|
40
|
+
const u = findTag(matched[4], "TimeUnit");
|
|
39
41
|
if (!n || n.kind !== "Numeral" || !u || u.kind !== "TimeUnit") return null;
|
|
40
42
|
if (u.unit !== "day" && u.unit !== "week") return null;
|
|
41
43
|
return makeWindow(n.value, u.unit);
|
|
@@ -93,6 +95,27 @@ var weekendThisRule = {
|
|
|
93
95
|
convention: "checkout"
|
|
94
96
|
})
|
|
95
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: "MonthName", optional: true }
|
|
105
|
+
],
|
|
106
|
+
produce: (matched) => {
|
|
107
|
+
const monthTok = matched[2];
|
|
108
|
+
const mTag = monthTok?.tags.find((t) => t.kind === "MonthName");
|
|
109
|
+
const month = mTag && mTag.kind === "MonthName" ? mTag.month : void 0;
|
|
110
|
+
const start = month !== void 0 ? { type: "last_weekday_in_month", weekday: 6, month } : { type: "last_weekday_in_month", weekday: 6 };
|
|
111
|
+
return {
|
|
112
|
+
type: "range",
|
|
113
|
+
start,
|
|
114
|
+
end: { type: "offset_from", base: start, days: 1 },
|
|
115
|
+
convention: "checkout"
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
};
|
|
96
119
|
var holidayPislyaRule = {
|
|
97
120
|
name: "booking-holiday-pislya",
|
|
98
121
|
priority: 90,
|
|
@@ -121,12 +144,36 @@ var holidayNaRule = {
|
|
|
121
144
|
reason: "holiday_ref"
|
|
122
145
|
})
|
|
123
146
|
};
|
|
147
|
+
var bookingDateWithNightsRule = {
|
|
148
|
+
name: "booking-date-with-nights",
|
|
149
|
+
priority: 80,
|
|
150
|
+
pattern: [
|
|
151
|
+
{ kind: "tag", tag: "Connector", predicate: (t) => t.tags.some((x) => x.kind === "Connector" && x.conn === "from"), optional: true },
|
|
152
|
+
{ kind: "node", node: "absolute" },
|
|
153
|
+
{ kind: "node", node: "duration" }
|
|
154
|
+
],
|
|
155
|
+
produce: (matched) => {
|
|
156
|
+
const a = matched[1];
|
|
157
|
+
const d = matched[2];
|
|
158
|
+
if (a.type !== "absolute" || d.type !== "duration") return null;
|
|
159
|
+
const nights = d.nights;
|
|
160
|
+
if (nights === void 0) return null;
|
|
161
|
+
return {
|
|
162
|
+
type: "range",
|
|
163
|
+
start: a,
|
|
164
|
+
end: { type: "offset_from", base: a, days: nights },
|
|
165
|
+
convention: "checkout"
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
};
|
|
124
169
|
var bookingRules = [
|
|
125
170
|
windowWithinNRule,
|
|
126
171
|
windowWithinNWithPrefixRule,
|
|
172
|
+
bookingDateWithNightsRule,
|
|
127
173
|
stayDurationRule,
|
|
128
174
|
weekendNextRule,
|
|
129
175
|
weekendThisRule,
|
|
176
|
+
weekendLastOfMonthRule,
|
|
130
177
|
holidayPislyaRule,
|
|
131
178
|
holidayNaRule
|
|
132
179
|
];
|
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 днів\" — 3-token form\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: '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 if (u.unit !== 'day' && u.unit !== 'week') return null;\n return makeWindow(n.value, u.unit);\n },\n};\n\n// \"у найближчі 5 днів\" — 4-token form with leading «у/в» Connector\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: '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\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.\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: 'MonthName', optional: true },\n ],\n produce: (matched) => {\n const monthTok = matched[2] 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: '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":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whenis/booking",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.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",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"node": ">=18"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@whenis/core": "
|
|
56
|
+
"@whenis/core": ">=0.1.1 <1.0.0"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"luxon": "^3.5.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/luxon": "^3.4.0",
|
|
63
|
-
"@whenis/core": "0.
|
|
63
|
+
"@whenis/core": "0.3.0"
|
|
64
64
|
},
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|