@voyantjs/pricing 0.26.8 → 0.26.9
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/service-public.d.ts.map +1 -1
- package/dist/service-public.js +68 -2
- package/dist/service-rule-resolver.d.ts +44 -0
- package/dist/service-rule-resolver.d.ts.map +1 -0
- package/dist/service-rule-resolver.js +172 -0
- package/dist/validation-public.d.ts +2 -0
- package/dist/validation-public.d.ts.map +1 -1
- package/dist/validation-public.js +2 -0
- package/package.json +9 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAWjE,OAAO,KAAK,EACV,+BAA+B,EAC/B,yBAAyB,EAC1B,MAAM,wBAAwB,CAAA;AA+J/B,eAAO,MAAM,oBAAoB;kCAEzB,kBAAkB,aACX,MAAM,SACV,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA+R5B,kBAAkB,aACX,MAAM,SACV,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;CAgGzC,CAAA"}
|
package/dist/service-public.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { availabilitySlots, availabilityStartTimes } from "@voyantjs/availability/schema";
|
|
2
2
|
import { optionUnits, productOptions, products } from "@voyantjs/products/schema";
|
|
3
3
|
import { and, asc, desc, eq, gte, inArray, lte, ne, or, sql } from "drizzle-orm";
|
|
4
|
-
import { optionPriceRules, optionStartTimeRules, optionUnitPriceRules, optionUnitTiers, priceCatalogs, } from "./schema.js";
|
|
4
|
+
import { optionPriceRules, optionStartTimeRules, optionUnitPriceRules, optionUnitTiers, priceCatalogs, priceSchedules, } from "./schema.js";
|
|
5
|
+
import { pickRulesForDate } from "./service-rule-resolver.js";
|
|
5
6
|
function normalizeDate(value) {
|
|
6
7
|
if (!value) {
|
|
7
8
|
return null;
|
|
@@ -48,6 +49,68 @@ async function resolvePublicCatalog(db, input) {
|
|
|
48
49
|
.limit(1);
|
|
49
50
|
return catalog ?? null;
|
|
50
51
|
}
|
|
52
|
+
async function resolveQueryDate(db, query) {
|
|
53
|
+
if (query.date)
|
|
54
|
+
return query.date;
|
|
55
|
+
if (!query.departureId)
|
|
56
|
+
return null;
|
|
57
|
+
const [slot] = await db
|
|
58
|
+
.select({ dateLocal: availabilitySlots.dateLocal })
|
|
59
|
+
.from(availabilitySlots)
|
|
60
|
+
.where(eq(availabilitySlots.id, query.departureId))
|
|
61
|
+
.limit(1);
|
|
62
|
+
return slot?.dateLocal ?? null;
|
|
63
|
+
}
|
|
64
|
+
async function narrowRulesByDate(db, rules, isoDate) {
|
|
65
|
+
if (rules.length === 0)
|
|
66
|
+
return rules;
|
|
67
|
+
const scheduleIds = Array.from(new Set(rules.map((r) => r.priceScheduleId).filter((id) => id !== null)));
|
|
68
|
+
const schedules = scheduleIds.length > 0
|
|
69
|
+
? await db
|
|
70
|
+
.select({
|
|
71
|
+
id: priceSchedules.id,
|
|
72
|
+
active: priceSchedules.active,
|
|
73
|
+
priority: priceSchedules.priority,
|
|
74
|
+
recurrenceRule: priceSchedules.recurrenceRule,
|
|
75
|
+
validFrom: priceSchedules.validFrom,
|
|
76
|
+
validTo: priceSchedules.validTo,
|
|
77
|
+
weekdays: priceSchedules.weekdays,
|
|
78
|
+
timezone: priceSchedules.timezone,
|
|
79
|
+
})
|
|
80
|
+
.from(priceSchedules)
|
|
81
|
+
.where(inArray(priceSchedules.id, scheduleIds))
|
|
82
|
+
: [];
|
|
83
|
+
const scheduleMap = new Map(schedules.map((s) => [
|
|
84
|
+
s.id,
|
|
85
|
+
{
|
|
86
|
+
id: s.id,
|
|
87
|
+
active: s.active,
|
|
88
|
+
priority: s.priority,
|
|
89
|
+
recurrenceRule: s.recurrenceRule,
|
|
90
|
+
validFrom: s.validFrom,
|
|
91
|
+
validTo: s.validTo,
|
|
92
|
+
weekdays: s.weekdays ?? null,
|
|
93
|
+
timezone: s.timezone,
|
|
94
|
+
},
|
|
95
|
+
]));
|
|
96
|
+
const rulesByOption = new Map();
|
|
97
|
+
for (const r of rules) {
|
|
98
|
+
const existing = rulesByOption.get(r.optionId) ?? [];
|
|
99
|
+
existing.push(r);
|
|
100
|
+
rulesByOption.set(r.optionId, existing);
|
|
101
|
+
}
|
|
102
|
+
const winners = [];
|
|
103
|
+
for (const [, candidateRules] of rulesByOption) {
|
|
104
|
+
const picked = pickRulesForDate(candidateRules, scheduleMap, isoDate);
|
|
105
|
+
const winnerId = picked[0]?.id;
|
|
106
|
+
if (!winnerId)
|
|
107
|
+
continue;
|
|
108
|
+
const winner = candidateRules.find((r) => r.id === winnerId);
|
|
109
|
+
if (winner)
|
|
110
|
+
winners.push(winner);
|
|
111
|
+
}
|
|
112
|
+
return winners;
|
|
113
|
+
}
|
|
51
114
|
export const publicPricingService = {
|
|
52
115
|
async getProductPricingSnapshot(db, productId, query) {
|
|
53
116
|
const product = await ensurePublicProduct(db, productId);
|
|
@@ -87,7 +150,8 @@ export const publicPricingService = {
|
|
|
87
150
|
};
|
|
88
151
|
}
|
|
89
152
|
const optionIds = options.map((option) => option.id);
|
|
90
|
-
const
|
|
153
|
+
const resolvedDate = await resolveQueryDate(db, query);
|
|
154
|
+
const [units, allRules] = await Promise.all([
|
|
91
155
|
db
|
|
92
156
|
.select({
|
|
93
157
|
id: optionUnits.id,
|
|
@@ -112,11 +176,13 @@ export const publicPricingService = {
|
|
|
112
176
|
maxPerBooking: optionPriceRules.maxPerBooking,
|
|
113
177
|
isDefault: optionPriceRules.isDefault,
|
|
114
178
|
cancellationPolicyId: optionPriceRules.cancellationPolicyId,
|
|
179
|
+
priceScheduleId: optionPriceRules.priceScheduleId,
|
|
115
180
|
})
|
|
116
181
|
.from(optionPriceRules)
|
|
117
182
|
.where(and(eq(optionPriceRules.productId, productId), inArray(optionPriceRules.optionId, optionIds), eq(optionPriceRules.priceCatalogId, catalog.id), eq(optionPriceRules.active, true)))
|
|
118
183
|
.orderBy(desc(optionPriceRules.isDefault), asc(optionPriceRules.name)),
|
|
119
184
|
]);
|
|
185
|
+
const rules = resolvedDate ? await narrowRulesByDate(db, allRules, resolvedDate) : allRules;
|
|
120
186
|
const ruleIds = rules.map((rule) => rule.id);
|
|
121
187
|
const [unitPrices, startTimeAdjustments] = await Promise.all([
|
|
122
188
|
ruleIds.length > 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
export interface ResolverRuleInput {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
isDefault: boolean;
|
|
6
|
+
priceScheduleId: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface ResolverScheduleInput {
|
|
9
|
+
id: string;
|
|
10
|
+
active: boolean;
|
|
11
|
+
priority: number;
|
|
12
|
+
recurrenceRule: string;
|
|
13
|
+
validFrom: string | null;
|
|
14
|
+
validTo: string | null;
|
|
15
|
+
weekdays: string[] | null;
|
|
16
|
+
timezone: string | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pick the option price rule that applies to a given date, given a set of
|
|
20
|
+
* candidate rules and their schedules.
|
|
21
|
+
*
|
|
22
|
+
* - Rules with a matching schedule beat rules without one.
|
|
23
|
+
* - Among scheduled matches, highest `priority` wins. Ties: `isDefault` first,
|
|
24
|
+
* then alphabetic by `name`.
|
|
25
|
+
* - When no schedule matches, a rule with `isDefault=true` and no schedule acts
|
|
26
|
+
* as the fallback. Without one, returns an empty array.
|
|
27
|
+
*/
|
|
28
|
+
export declare function pickRulesForDate(rules: ResolverRuleInput[], schedules: Map<string, ResolverScheduleInput>, isoDate: string): ResolverRuleInput[];
|
|
29
|
+
export interface ResolveOptionPriceRulesParams {
|
|
30
|
+
productId: string;
|
|
31
|
+
optionIds: string[];
|
|
32
|
+
catalogId: string;
|
|
33
|
+
date: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* DB-backed wrapper around `pickRulesForDate`. Fetches active rules for the
|
|
37
|
+
* product/option/catalog plus their schedules, then picks the winning rule
|
|
38
|
+
* per option for the given date.
|
|
39
|
+
*
|
|
40
|
+
* Returns a Map keyed by optionId. Options whose rules don't match the date
|
|
41
|
+
* (and have no default) are absent from the map.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveOptionPriceRulesForDate(db: PostgresJsDatabase, params: ResolveOptionPriceRulesParams): Promise<Map<string, ResolverRuleInput>>;
|
|
44
|
+
//# sourceMappingURL=service-rule-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-rule-resolver.d.ts","sourceRoot":"","sources":["../src/service-rule-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAMjE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAoED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,iBAAiB,EAAE,EAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAC7C,OAAO,EAAE,MAAM,GACd,iBAAiB,EAAE,CAgCrB;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;GAOG;AACH,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,kBAAkB,EACtB,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CA8EzC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { and, eq, inArray } from "drizzle-orm";
|
|
2
|
+
import { rrulestr } from "rrule";
|
|
3
|
+
import { priceSchedules } from "./schema-catalogs.js";
|
|
4
|
+
import { optionPriceRules } from "./schema-option-rules.js";
|
|
5
|
+
const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
6
|
+
const WEEKDAY_CODES = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
|
|
7
|
+
function weekdayCode(isoDate) {
|
|
8
|
+
const d = new Date(`${isoDate}T00:00:00Z`);
|
|
9
|
+
return WEEKDAY_CODES[d.getUTCDay()] ?? "MO";
|
|
10
|
+
}
|
|
11
|
+
function dateInWindow(isoDate, from, to) {
|
|
12
|
+
if (from && isoDate < from)
|
|
13
|
+
return false;
|
|
14
|
+
if (to && isoDate > to)
|
|
15
|
+
return false;
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function rruleMatchesDate(ruleString, isoDate, anchor) {
|
|
19
|
+
const trimmed = ruleString.trim();
|
|
20
|
+
if (trimmed === "")
|
|
21
|
+
return true;
|
|
22
|
+
const dtstart = `${anchor.replace(/-/g, "")}T000000Z`;
|
|
23
|
+
const hasDtstart = /(?:^|\n)DTSTART[:;]/.test(trimmed);
|
|
24
|
+
const hasRrule = /(?:^|\n)RRULE[:;]/.test(trimmed);
|
|
25
|
+
const body = hasRrule ? trimmed : `RRULE:${trimmed}`;
|
|
26
|
+
const fullRule = hasDtstart ? body : `DTSTART:${dtstart}\n${body}`;
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
parsed = rrulestr(fullRule);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const start = new Date(`${isoDate}T00:00:00Z`);
|
|
35
|
+
const end = new Date(start.getTime() + 24 * 60 * 60 * 1000);
|
|
36
|
+
const occurrences = parsed.between(start, end, true);
|
|
37
|
+
return occurrences.some((occ) => occ.toISOString().slice(0, 10) === isoDate);
|
|
38
|
+
}
|
|
39
|
+
function scheduleMatchesDate(s, isoDate) {
|
|
40
|
+
if (!s.active)
|
|
41
|
+
return false;
|
|
42
|
+
if (!dateInWindow(isoDate, s.validFrom, s.validTo))
|
|
43
|
+
return false;
|
|
44
|
+
if (s.weekdays && s.weekdays.length > 0) {
|
|
45
|
+
if (!s.weekdays.includes(weekdayCode(isoDate)))
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const anchor = s.validFrom ?? "2000-01-01";
|
|
49
|
+
if (!rruleMatchesDate(s.recurrenceRule, isoDate, anchor))
|
|
50
|
+
return false;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
function compareMatches(a, b) {
|
|
54
|
+
if (b.priority !== a.priority)
|
|
55
|
+
return b.priority - a.priority;
|
|
56
|
+
const aDef = a.rule.isDefault ? 1 : 0;
|
|
57
|
+
const bDef = b.rule.isDefault ? 1 : 0;
|
|
58
|
+
if (aDef !== bDef)
|
|
59
|
+
return bDef - aDef;
|
|
60
|
+
return a.rule.name.localeCompare(b.rule.name);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Pick the option price rule that applies to a given date, given a set of
|
|
64
|
+
* candidate rules and their schedules.
|
|
65
|
+
*
|
|
66
|
+
* - Rules with a matching schedule beat rules without one.
|
|
67
|
+
* - Among scheduled matches, highest `priority` wins. Ties: `isDefault` first,
|
|
68
|
+
* then alphabetic by `name`.
|
|
69
|
+
* - When no schedule matches, a rule with `isDefault=true` and no schedule acts
|
|
70
|
+
* as the fallback. Without one, returns an empty array.
|
|
71
|
+
*/
|
|
72
|
+
export function pickRulesForDate(rules, schedules, isoDate) {
|
|
73
|
+
if (!ISO_DATE_RE.test(isoDate)) {
|
|
74
|
+
throw new Error(`pickRulesForDate: expected ISO yyyy-mm-dd, got "${isoDate}"`);
|
|
75
|
+
}
|
|
76
|
+
const matches = [];
|
|
77
|
+
for (const rule of rules) {
|
|
78
|
+
if (rule.priceScheduleId === null) {
|
|
79
|
+
if (rule.isDefault) {
|
|
80
|
+
matches.push({ rule, priority: Number.NEGATIVE_INFINITY, scheduled: false });
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const schedule = schedules.get(rule.priceScheduleId);
|
|
85
|
+
if (!schedule)
|
|
86
|
+
continue;
|
|
87
|
+
if (!scheduleMatchesDate(schedule, isoDate))
|
|
88
|
+
continue;
|
|
89
|
+
matches.push({ rule, priority: schedule.priority, scheduled: true });
|
|
90
|
+
}
|
|
91
|
+
if (matches.length === 0)
|
|
92
|
+
return [];
|
|
93
|
+
const scheduled = matches.filter((m) => m.scheduled);
|
|
94
|
+
if (scheduled.length > 0) {
|
|
95
|
+
scheduled.sort(compareMatches);
|
|
96
|
+
const winner = scheduled[0];
|
|
97
|
+
return winner ? [winner.rule] : [];
|
|
98
|
+
}
|
|
99
|
+
matches.sort(compareMatches);
|
|
100
|
+
const winner = matches[0];
|
|
101
|
+
return winner ? [winner.rule] : [];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* DB-backed wrapper around `pickRulesForDate`. Fetches active rules for the
|
|
105
|
+
* product/option/catalog plus their schedules, then picks the winning rule
|
|
106
|
+
* per option for the given date.
|
|
107
|
+
*
|
|
108
|
+
* Returns a Map keyed by optionId. Options whose rules don't match the date
|
|
109
|
+
* (and have no default) are absent from the map.
|
|
110
|
+
*/
|
|
111
|
+
export async function resolveOptionPriceRulesForDate(db, params) {
|
|
112
|
+
if (params.optionIds.length === 0)
|
|
113
|
+
return new Map();
|
|
114
|
+
const rules = await db
|
|
115
|
+
.select({
|
|
116
|
+
id: optionPriceRules.id,
|
|
117
|
+
optionId: optionPriceRules.optionId,
|
|
118
|
+
name: optionPriceRules.name,
|
|
119
|
+
isDefault: optionPriceRules.isDefault,
|
|
120
|
+
priceScheduleId: optionPriceRules.priceScheduleId,
|
|
121
|
+
})
|
|
122
|
+
.from(optionPriceRules)
|
|
123
|
+
.where(and(eq(optionPriceRules.productId, params.productId), inArray(optionPriceRules.optionId, params.optionIds), eq(optionPriceRules.priceCatalogId, params.catalogId), eq(optionPriceRules.active, true)));
|
|
124
|
+
const scheduleIds = Array.from(new Set(rules.map((r) => r.priceScheduleId).filter((id) => id !== null)));
|
|
125
|
+
const schedules = scheduleIds.length > 0
|
|
126
|
+
? await db
|
|
127
|
+
.select({
|
|
128
|
+
id: priceSchedules.id,
|
|
129
|
+
active: priceSchedules.active,
|
|
130
|
+
priority: priceSchedules.priority,
|
|
131
|
+
recurrenceRule: priceSchedules.recurrenceRule,
|
|
132
|
+
validFrom: priceSchedules.validFrom,
|
|
133
|
+
validTo: priceSchedules.validTo,
|
|
134
|
+
weekdays: priceSchedules.weekdays,
|
|
135
|
+
timezone: priceSchedules.timezone,
|
|
136
|
+
})
|
|
137
|
+
.from(priceSchedules)
|
|
138
|
+
.where(inArray(priceSchedules.id, scheduleIds))
|
|
139
|
+
: [];
|
|
140
|
+
const scheduleMap = new Map(schedules.map((s) => [
|
|
141
|
+
s.id,
|
|
142
|
+
{
|
|
143
|
+
id: s.id,
|
|
144
|
+
active: s.active,
|
|
145
|
+
priority: s.priority,
|
|
146
|
+
recurrenceRule: s.recurrenceRule,
|
|
147
|
+
validFrom: s.validFrom,
|
|
148
|
+
validTo: s.validTo,
|
|
149
|
+
weekdays: s.weekdays ?? null,
|
|
150
|
+
timezone: s.timezone,
|
|
151
|
+
},
|
|
152
|
+
]));
|
|
153
|
+
const rulesByOption = new Map();
|
|
154
|
+
for (const r of rules) {
|
|
155
|
+
const existing = rulesByOption.get(r.optionId) ?? [];
|
|
156
|
+
existing.push({
|
|
157
|
+
id: r.id,
|
|
158
|
+
name: r.name,
|
|
159
|
+
isDefault: r.isDefault,
|
|
160
|
+
priceScheduleId: r.priceScheduleId,
|
|
161
|
+
});
|
|
162
|
+
rulesByOption.set(r.optionId, existing);
|
|
163
|
+
}
|
|
164
|
+
const result = new Map();
|
|
165
|
+
for (const [optionId, candidateRules] of rulesByOption) {
|
|
166
|
+
const picked = pickRulesForDate(candidateRules, scheduleMap, params.date);
|
|
167
|
+
const first = picked[0];
|
|
168
|
+
if (first)
|
|
169
|
+
result.set(optionId, first);
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
@@ -2,6 +2,8 @@ import { z } from "zod";
|
|
|
2
2
|
export declare const publicProductPricingQuerySchema: z.ZodObject<{
|
|
3
3
|
catalogId: z.ZodOptional<z.ZodString>;
|
|
4
4
|
optionId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
date: z.ZodOptional<z.ZodString>;
|
|
6
|
+
departureId: z.ZodOptional<z.ZodString>;
|
|
5
7
|
}, z.core.$strip>;
|
|
6
8
|
export declare const publicAvailabilitySnapshotQuerySchema: z.ZodObject<{
|
|
7
9
|
optionId: z.ZodOptional<z.ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-public.d.ts","sourceRoot":"","sources":["../src/validation-public.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,eAAO,MAAM,+BAA+B
|
|
1
|
+
{"version":3,"file":"validation-public.d.ts","sourceRoot":"","sources":["../src/validation-public.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,eAAO,MAAM,+BAA+B;;;;;iBAK1C,CAAA;AAEF,eAAO,MAAM,qCAAqC;;;;;;;;;;;;iBAOhD,CAAA;AAEF,eAAO,MAAM,wBAAwB;;;;;iBAKnC,CAAA;AAEF,eAAO,MAAM,uBAAuB;;;;;;iBAMlC,CAAA;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAYtC,CAAA;AAEF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;iBAS1C,CAAA;AAEF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAYxC,CAAA;AAEF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBASnC,CAAA;AAEF,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAI7C,CAAA;AAEF,eAAO,MAAM,iCAAiC;;;;;iBAK5C,CAAA;AAEF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;iBAcvC,CAAA;AAEF,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAM3C,CAAA;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAA;AACvF,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAA"}
|
|
@@ -6,6 +6,8 @@ const isoDateSchema = z.string().date();
|
|
|
6
6
|
export const publicProductPricingQuerySchema = z.object({
|
|
7
7
|
catalogId: z.string().optional(),
|
|
8
8
|
optionId: z.string().optional(),
|
|
9
|
+
date: isoDateSchema.optional(),
|
|
10
|
+
departureId: z.string().optional(),
|
|
9
11
|
});
|
|
10
12
|
export const publicAvailabilitySnapshotQuerySchema = z.object({
|
|
11
13
|
optionId: z.string().optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/pricing",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.9",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -38,17 +38,18 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"drizzle-orm": "^0.45.2",
|
|
40
40
|
"hono": "^4.12.10",
|
|
41
|
+
"rrule": "^2.8.1",
|
|
41
42
|
"zod": "^4.3.6",
|
|
42
|
-
"@voyantjs/availability": "0.26.
|
|
43
|
-
"@voyantjs/core": "0.26.
|
|
44
|
-
"@voyantjs/db": "0.26.
|
|
45
|
-
"@voyantjs/hono": "0.26.
|
|
46
|
-
"@voyantjs/products": "0.26.
|
|
43
|
+
"@voyantjs/availability": "0.26.9",
|
|
44
|
+
"@voyantjs/core": "0.26.9",
|
|
45
|
+
"@voyantjs/db": "0.26.9",
|
|
46
|
+
"@voyantjs/hono": "0.26.9",
|
|
47
|
+
"@voyantjs/products": "0.26.9"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"typescript": "^6.0.2",
|
|
50
|
-
"@voyantjs/extras": "0.26.
|
|
51
|
-
"@voyantjs/facilities": "0.26.
|
|
51
|
+
"@voyantjs/extras": "0.26.9",
|
|
52
|
+
"@voyantjs/facilities": "0.26.9",
|
|
52
53
|
"@voyantjs/voyant-typescript-config": "0.1.0"
|
|
53
54
|
},
|
|
54
55
|
"files": [
|