@mseep/wanderlog-mcp 0.3.1

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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +282 -0
  3. package/dist/cache/trip-cache.js +87 -0
  4. package/dist/cache/trip-cache.js.map +1 -0
  5. package/dist/config.js +38 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/context.js +12 -0
  8. package/dist/context.js.map +1 -0
  9. package/dist/errors.js +93 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/formatters/trip-summary.js +296 -0
  12. package/dist/formatters/trip-summary.js.map +1 -0
  13. package/dist/http.js +165 -0
  14. package/dist/http.js.map +1 -0
  15. package/dist/index.js +48 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/ot/apply.js +282 -0
  18. package/dist/ot/apply.js.map +1 -0
  19. package/dist/resolvers/day.js +83 -0
  20. package/dist/resolvers/day.js.map +1 -0
  21. package/dist/resolvers/place-ref.js +194 -0
  22. package/dist/resolvers/place-ref.js.map +1 -0
  23. package/dist/server.js +164 -0
  24. package/dist/server.js.map +1 -0
  25. package/dist/tools/add-checklist.js +59 -0
  26. package/dist/tools/add-checklist.js.map +1 -0
  27. package/dist/tools/add-expense.js +127 -0
  28. package/dist/tools/add-expense.js.map +1 -0
  29. package/dist/tools/add-hotel.js +92 -0
  30. package/dist/tools/add-hotel.js.map +1 -0
  31. package/dist/tools/add-note.js +63 -0
  32. package/dist/tools/add-note.js.map +1 -0
  33. package/dist/tools/add-place.js +151 -0
  34. package/dist/tools/add-place.js.map +1 -0
  35. package/dist/tools/annotate-place.js +114 -0
  36. package/dist/tools/annotate-place.js.map +1 -0
  37. package/dist/tools/create-trip.js +85 -0
  38. package/dist/tools/create-trip.js.map +1 -0
  39. package/dist/tools/edit-note.js +217 -0
  40. package/dist/tools/edit-note.js.map +1 -0
  41. package/dist/tools/get-guide.js +42 -0
  42. package/dist/tools/get-guide.js.map +1 -0
  43. package/dist/tools/get-trip-url.js +52 -0
  44. package/dist/tools/get-trip-url.js.map +1 -0
  45. package/dist/tools/get-trip.js +43 -0
  46. package/dist/tools/get-trip.js.map +1 -0
  47. package/dist/tools/list-trips.js +32 -0
  48. package/dist/tools/list-trips.js.map +1 -0
  49. package/dist/tools/remove-note.js +107 -0
  50. package/dist/tools/remove-note.js.map +1 -0
  51. package/dist/tools/remove-place.js +95 -0
  52. package/dist/tools/remove-place.js.map +1 -0
  53. package/dist/tools/rename-day.js +64 -0
  54. package/dist/tools/rename-day.js.map +1 -0
  55. package/dist/tools/search-guides.js +172 -0
  56. package/dist/tools/search-guides.js.map +1 -0
  57. package/dist/tools/search-places.js +81 -0
  58. package/dist/tools/search-places.js.map +1 -0
  59. package/dist/tools/shared.js +216 -0
  60. package/dist/tools/shared.js.map +1 -0
  61. package/dist/tools/update-trip-dates.js +211 -0
  62. package/dist/tools/update-trip-dates.js.map +1 -0
  63. package/dist/transport/rest.js +152 -0
  64. package/dist/transport/rest.js.map +1 -0
  65. package/dist/transport/sharedb.js +323 -0
  66. package/dist/transport/sharedb.js.map +1 -0
  67. package/dist/types.js +7 -0
  68. package/dist/types.js.map +1 -0
  69. package/package.json +61 -0
@@ -0,0 +1,282 @@
1
+ import { WanderlogError } from "../errors.js";
2
+ function pathInvalid(path, reason) {
3
+ const rendered = path.map((p) => JSON.stringify(p)).join(", ");
4
+ throw new WanderlogError(`JSON0 op path [${rendered}] is invalid: ${reason}`, "ot_path_invalid", "Verify the op path matches the current document shape (parent containers must exist and have the correct type).");
5
+ }
6
+ function isObject(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8
+ }
9
+ function navigateParent(doc, path) {
10
+ let current = doc;
11
+ for (let i = 0; i < path.length - 1; i++) {
12
+ const key = path[i];
13
+ if (Array.isArray(current)) {
14
+ if (typeof key !== "number") {
15
+ pathInvalid(path, `expected numeric index at position ${i}, got ${typeof key}`);
16
+ }
17
+ if (key < 0 || key >= current.length) {
18
+ pathInvalid(path, `array index ${key} out of bounds at position ${i}`);
19
+ }
20
+ current = current[key];
21
+ }
22
+ else if (isObject(current)) {
23
+ if (typeof key !== "string") {
24
+ pathInvalid(path, `expected string key at position ${i}, got ${typeof key}`);
25
+ }
26
+ if (!(key in current)) {
27
+ pathInvalid(path, `key "${key}" missing on parent object at position ${i}`);
28
+ }
29
+ current = current[key];
30
+ }
31
+ else {
32
+ pathInvalid(path, `cannot traverse into non-container at position ${i}`);
33
+ }
34
+ }
35
+ if (!isObject(current) && !Array.isArray(current)) {
36
+ pathInvalid(path, "parent of target is not an object or array");
37
+ }
38
+ return current;
39
+ }
40
+ /**
41
+ * Apply a Quill Delta "rich-text" subtype op to a QuillDelta field.
42
+ *
43
+ * Quill Delta compose semantics: walk through the incoming ops in order.
44
+ * `retain(n)` skips n characters, `insert(s)` inserts text, `delete(n)`
45
+ * removes n characters. We rebuild the delta's plain-text string, then
46
+ * write back a new `{ops: [{insert: result}]}`.
47
+ *
48
+ * This is intentionally simplified — we flatten the existing delta to
49
+ * plain text, apply the transform, and produce a single-insert delta.
50
+ * Formatting attributes on the original text are lost, which is acceptable
51
+ * because our tools only create plain-text notes. Remote rich-text edits
52
+ * from the UI that carry attributes will lose formatting in our cache, but
53
+ * the server holds the authoritative version.
54
+ */
55
+ function applyRichTextOp(parent, key, payload) {
56
+ const target = Array.isArray(parent)
57
+ ? parent[key]
58
+ : parent[key];
59
+ // Extract current plain text from the QuillDelta
60
+ let current = "";
61
+ if (target && typeof target === "object" && "ops" in target) {
62
+ const ops = target.ops;
63
+ if (Array.isArray(ops)) {
64
+ current = ops
65
+ .map((op) => (typeof op.insert === "string" ? op.insert : ""))
66
+ .join("");
67
+ }
68
+ }
69
+ // Apply the delta ops to the current text
70
+ if (!Array.isArray(payload))
71
+ return;
72
+ let pos = 0;
73
+ let result = current;
74
+ for (const dop of payload) {
75
+ if (typeof dop.retain === "number") {
76
+ pos += dop.retain;
77
+ }
78
+ else if (typeof dop.insert === "string") {
79
+ result = result.slice(0, pos) + dop.insert + result.slice(pos);
80
+ pos += dop.insert.length;
81
+ }
82
+ else if (typeof dop.delete === "number") {
83
+ result = result.slice(0, pos) + result.slice(pos + dop.delete);
84
+ }
85
+ }
86
+ const newDelta = { ops: [{ insert: result }] };
87
+ if (Array.isArray(parent)) {
88
+ parent[key] = newDelta;
89
+ }
90
+ else {
91
+ parent[key] = newDelta;
92
+ }
93
+ }
94
+ function applySingleOp(doc, op) {
95
+ const { p } = op;
96
+ if (p.length === 0) {
97
+ if ("r" in op) {
98
+ pathInvalid(p, "whole-document replacement at empty path is not supported");
99
+ }
100
+ pathInvalid(p, "op path must not be empty");
101
+ }
102
+ // ShareDB subtype ops — the `t` field names the subtype, `o` is its payload.
103
+ // We support "rich-text" (Quill Delta compose); unknown subtypes are skipped
104
+ // so remote ops from the UI don't crash our cache.
105
+ if ("t" in op && op.t !== undefined) {
106
+ const parent = navigateParent(doc, p);
107
+ const last = p[p.length - 1];
108
+ if (op.t === "rich-text") {
109
+ applyRichTextOp(parent, last, op.o);
110
+ }
111
+ // Unknown subtypes: silently skip rather than crash.
112
+ return;
113
+ }
114
+ if ("r" in op) {
115
+ if (p.length === 0) {
116
+ pathInvalid(p, "replace at empty path is not supported");
117
+ }
118
+ const parent = navigateParent(doc, p);
119
+ const last = p[p.length - 1];
120
+ if (Array.isArray(parent)) {
121
+ if (typeof last !== "number") {
122
+ pathInvalid(p, "expected numeric index for replace on array");
123
+ }
124
+ if (last < 0 || last >= parent.length) {
125
+ pathInvalid(p, `array index ${last} out of bounds for replace`);
126
+ }
127
+ parent[last] = op.r;
128
+ }
129
+ else {
130
+ if (typeof last !== "string") {
131
+ pathInvalid(p, "expected string key for replace on object");
132
+ }
133
+ parent[last] = op.r;
134
+ }
135
+ return;
136
+ }
137
+ if ("na" in op && op.na !== undefined) {
138
+ const parent = navigateParent(doc, p);
139
+ const last = p[p.length - 1];
140
+ const current = Array.isArray(parent)
141
+ ? typeof last === "number"
142
+ ? parent[last]
143
+ : pathInvalid(p, "expected numeric index for na on array")
144
+ : typeof last === "string"
145
+ ? parent[last]
146
+ : pathInvalid(p, "expected string key for na on object");
147
+ if (typeof current !== "number") {
148
+ pathInvalid(p, `na target is not a number (got ${typeof current})`);
149
+ }
150
+ const next = current + op.na;
151
+ if (Array.isArray(parent)) {
152
+ parent[last] = next;
153
+ }
154
+ else {
155
+ parent[last] = next;
156
+ }
157
+ return;
158
+ }
159
+ if ("si" in op || "sd" in op) {
160
+ const idx = p[p.length - 1];
161
+ if (typeof idx !== "number") {
162
+ pathInvalid(p, "string op requires numeric index as final path element");
163
+ }
164
+ if (p.length < 2) {
165
+ pathInvalid(p, "string op path must contain at least the string key and an index");
166
+ }
167
+ const stringKey = p[p.length - 2];
168
+ const stringParent = navigateParent(doc, p.slice(0, -1));
169
+ const current = Array.isArray(stringParent)
170
+ ? typeof stringKey === "number"
171
+ ? stringParent[stringKey]
172
+ : pathInvalid(p, "expected numeric index for string container in array")
173
+ : typeof stringKey === "string"
174
+ ? stringParent[stringKey]
175
+ : pathInvalid(p, "expected string key for string container in object");
176
+ if (typeof current !== "string") {
177
+ pathInvalid(p, `string op target is not a string (got ${typeof current})`);
178
+ }
179
+ let updated = current;
180
+ if ("sd" in op && op.sd !== undefined) {
181
+ const slice = updated.slice(idx, idx + op.sd.length);
182
+ if (slice !== op.sd) {
183
+ pathInvalid(p, `sd verification failed: expected "${op.sd}" at index ${idx}, found "${slice}"`);
184
+ }
185
+ updated = updated.slice(0, idx) + updated.slice(idx + op.sd.length);
186
+ }
187
+ if ("si" in op && op.si !== undefined) {
188
+ updated = updated.slice(0, idx) + op.si + updated.slice(idx);
189
+ }
190
+ if (Array.isArray(stringParent)) {
191
+ stringParent[stringKey] = updated;
192
+ }
193
+ else {
194
+ stringParent[stringKey] = updated;
195
+ }
196
+ return;
197
+ }
198
+ const parent = navigateParent(doc, p);
199
+ const last = p[p.length - 1];
200
+ const hasLd = "ld" in op && op.ld !== undefined;
201
+ const hasLi = "li" in op && op.li !== undefined;
202
+ const hasLm = "lm" in op && op.lm !== undefined;
203
+ const hasOi = "oi" in op && op.oi !== undefined;
204
+ const hasOd = "od" in op && op.od !== undefined;
205
+ if (hasLd || hasLi || hasLm) {
206
+ if (!Array.isArray(parent)) {
207
+ pathInvalid(p, "list op target parent is not an array");
208
+ }
209
+ if (typeof last !== "number") {
210
+ pathInvalid(p, "list op requires numeric final path element");
211
+ }
212
+ if (hasLm) {
213
+ const from = last;
214
+ const to = op.lm;
215
+ if (from < 0 || from >= parent.length) {
216
+ pathInvalid(p, `lm source index ${from} out of bounds`);
217
+ }
218
+ if (to < 0 || to >= parent.length) {
219
+ pathInvalid(p, `lm destination index ${to} out of bounds`);
220
+ }
221
+ const [item] = parent.splice(from, 1);
222
+ parent.splice(to, 0, item);
223
+ return;
224
+ }
225
+ if (hasLd) {
226
+ if (last < 0 || last >= parent.length) {
227
+ pathInvalid(p, `ld index ${last} out of bounds`);
228
+ }
229
+ const existing = parent[last];
230
+ if (op.ld !== null && JSON.stringify(existing) !== JSON.stringify(op.ld)) {
231
+ throw new WanderlogError(`JSON0 ld verification failed at path [${p.join(", ")}]: existing element does not match provided ld value`, "ot_path_invalid", "The cached document drifted from the server snapshot. Refresh the trip before retrying.");
232
+ }
233
+ if (hasLi) {
234
+ parent[last] = op.li;
235
+ }
236
+ else {
237
+ parent.splice(last, 1);
238
+ }
239
+ return;
240
+ }
241
+ if (hasLi) {
242
+ if (last < 0 || last > parent.length) {
243
+ pathInvalid(p, `li index ${last} out of bounds`);
244
+ }
245
+ parent.splice(last, 0, op.li);
246
+ return;
247
+ }
248
+ }
249
+ if (hasOi || hasOd) {
250
+ if (!isObject(parent)) {
251
+ pathInvalid(p, "object op target parent is not an object");
252
+ }
253
+ if (typeof last !== "string") {
254
+ pathInvalid(p, "object op requires string final path element");
255
+ }
256
+ if (hasOd) {
257
+ if (!(last in parent)) {
258
+ pathInvalid(p, `od key "${last}" missing from parent object`);
259
+ }
260
+ if (hasOi) {
261
+ parent[last] = op.oi;
262
+ }
263
+ else {
264
+ delete parent[last];
265
+ }
266
+ return;
267
+ }
268
+ if (hasOi) {
269
+ parent[last] = op.oi;
270
+ return;
271
+ }
272
+ }
273
+ pathInvalid(p, "op contains no recognized action field");
274
+ }
275
+ export function applyOp(doc, ops) {
276
+ const next = structuredClone(doc);
277
+ for (const op of ops) {
278
+ applySingleOp(next, op);
279
+ }
280
+ return next;
281
+ }
282
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/ot/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { WanderlogValidationError } from "../errors.js";
2
+ const MONTHS = {
3
+ jan: 1, january: 1,
4
+ feb: 2, february: 2,
5
+ mar: 3, march: 3,
6
+ apr: 4, april: 4,
7
+ may: 5,
8
+ jun: 6, june: 6,
9
+ jul: 7, july: 7,
10
+ aug: 8, august: 8,
11
+ sep: 9, sept: 9, september: 9,
12
+ oct: 10, october: 10,
13
+ nov: 11, november: 11,
14
+ dec: 12, december: 12,
15
+ };
16
+ /**
17
+ * Given a trip and a natural-language day reference, returns the section
18
+ * matching that day. Accepts "day 2", "May 4", "2026-05-04".
19
+ * Throws WanderlogValidationError with helpful message if unresolvable.
20
+ */
21
+ export function resolveDay(trip, ref) {
22
+ const daySections = getDaySections(trip);
23
+ const trimmed = ref.trim().toLowerCase();
24
+ if (daySections.length === 0) {
25
+ throw new WanderlogValidationError(`Trip "${trip.title}" has no day-by-day plan`, "This trip does not yet have per-day sections to target.");
26
+ }
27
+ const isoMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(trimmed);
28
+ if (isoMatch) {
29
+ const iso = trimmed;
30
+ const section = daySections.find((s) => s.date === iso);
31
+ if (!section) {
32
+ throw outOfRange(trip, `no day matches ${iso}`);
33
+ }
34
+ return section;
35
+ }
36
+ const dayNumMatch = /^day\s*(\d+)$/.exec(trimmed);
37
+ if (dayNumMatch) {
38
+ const n = Number.parseInt(dayNumMatch[1], 10);
39
+ if (n < 1 || n > daySections.length) {
40
+ throw outOfRange(trip, `you asked for day ${n}`);
41
+ }
42
+ return daySections[n - 1];
43
+ }
44
+ const plainNum = /^\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) : null;
45
+ if (plainNum !== null) {
46
+ if (plainNum < 1 || plainNum > daySections.length) {
47
+ throw outOfRange(trip, `you asked for day ${plainNum}`);
48
+ }
49
+ return daySections[plainNum - 1];
50
+ }
51
+ const monthDayMatch = /^([a-z]+)\s+(\d{1,2})$/.exec(trimmed);
52
+ if (monthDayMatch) {
53
+ const monthName = monthDayMatch[1];
54
+ const day = Number.parseInt(monthDayMatch[2], 10);
55
+ const month = MONTHS[monthName];
56
+ if (!month) {
57
+ throw new WanderlogValidationError(`Unknown month "${monthName}" in day reference "${ref}"`, 'Try a format like "day 2", "May 4", or "2026-05-04".');
58
+ }
59
+ const year = new Date(trip.startDate).getUTCFullYear();
60
+ const iso = `${year}-${pad(month)}-${pad(day)}`;
61
+ const section = daySections.find((s) => s.date === iso);
62
+ if (!section) {
63
+ throw outOfRange(trip, `${monthName} ${day} is not in this trip`);
64
+ }
65
+ return section;
66
+ }
67
+ throw new WanderlogValidationError(`Could not understand day reference "${ref}"`, 'Try a format like "day 2", "May 4", or "2026-05-04".');
68
+ }
69
+ export function getDaySections(trip) {
70
+ return trip.itinerary.sections.filter((s) => s.mode === "dayPlan" && s.date);
71
+ }
72
+ function pad(n) {
73
+ return n < 10 ? `0${n}` : `${n}`;
74
+ }
75
+ function outOfRange(trip, detail) {
76
+ return new WanderlogValidationError(`Day reference out of range: ${detail}`, {
77
+ hint: `Trip "${trip.title}" runs ${trip.startDate} to ${trip.endDate} (${trip.days} days).`,
78
+ followUps: [
79
+ `Call wanderlog_get_trip with trip_key "${trip.key}" (no day filter) to see the available dates, then retry with a valid day.`,
80
+ ],
81
+ });
82
+ }
83
+ //# sourceMappingURL=day.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"day.js","sourceRoot":"","sources":["../../src/resolvers/day.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ import { isPlaceBlock } from "../types.js";
2
+ import { resolveDay } from "./day.js";
3
+ const MAX_AMBIGUOUS_CANDIDATES = 10;
4
+ const HOTEL_KEYWORDS = new Set(["the hotel", "hotel", "my hotel"]);
5
+ const FLIGHT_KEYWORDS = new Set(["the flight", "flight", "my flight"]);
6
+ const TRAIN_KEYWORDS = new Set(["the train", "train", "my train"]);
7
+ const WORD_ORDINALS = {
8
+ first: 1,
9
+ second: 2,
10
+ third: 3,
11
+ fourth: 4,
12
+ fifth: 5,
13
+ sixth: 6,
14
+ seventh: 7,
15
+ eighth: 8,
16
+ ninth: 9,
17
+ tenth: 10,
18
+ };
19
+ /**
20
+ * Detects an ordinal prefix on a normalized ref. Returns the 1-based position
21
+ * (or "last") and the remaining ref with the ordinal stripped. Handles:
22
+ * - numeric suffixes: "1st X", "2nd X", "3rd X", "4th X", ...
23
+ * - word ordinals: "first X", "second X", ..., "tenth X"
24
+ * - "last X"
25
+ *
26
+ * Returns null if no ordinal prefix is present.
27
+ */
28
+ export function parseOrdinal(ref) {
29
+ if (ref.startsWith("last ")) {
30
+ const rest = ref.slice(5).trim();
31
+ if (rest)
32
+ return { position: "last", rest };
33
+ }
34
+ const numMatch = /^(\d+)(?:st|nd|rd|th)\s+(.+)$/.exec(ref);
35
+ if (numMatch) {
36
+ const n = Number.parseInt(numMatch[1], 10);
37
+ if (n >= 1)
38
+ return { position: n, rest: numMatch[2].trim() };
39
+ }
40
+ const wordMatch = /^([a-z]+)\s+(.+)$/.exec(ref);
41
+ if (wordMatch) {
42
+ const word = wordMatch[1];
43
+ const n = WORD_ORDINALS[word];
44
+ if (n !== undefined)
45
+ return { position: n, rest: wordMatch[2].trim() };
46
+ }
47
+ return null;
48
+ }
49
+ /**
50
+ * Resolves a free-form natural-language reference to a block in a trip.
51
+ *
52
+ * Strategy order (short-circuits on the first stage that yields candidates):
53
+ * 0. Ordinal prefix ("1st X", "2nd X", "last X", "third X") — strips the
54
+ * ordinal, resolves the rest via the normal flow, then picks the N-th
55
+ * (or last) candidate from the resulting list. Combines with compound
56
+ * refs: "2nd Queenstown Gardens on day 4" is valid.
57
+ * 1. Compound "<thing> on <context>" — left side resolved by stages 2-4,
58
+ * then filtered to candidates whose parent section matches the context
59
+ * (currently only day references are understood on the right).
60
+ * 2. Role keywords ("the hotel", "the flight", "the train") — first block
61
+ * in the appropriate role section.
62
+ * 3. Exact (case-insensitive) match against `block.place.name`.
63
+ * 4. Substring (case-insensitive) match against `block.place.name`.
64
+ *
65
+ * Diacritics are not normalized: "Senso-ji" will not match "Sensō-ji".
66
+ * Whitespace is collapsed and trimmed before matching.
67
+ */
68
+ export function resolvePlaceRef(trip, ref) {
69
+ const normalized = normalize(ref);
70
+ if (!normalized) {
71
+ return { kind: "none" };
72
+ }
73
+ const sections = trip.itinerary.sections;
74
+ if (sections.length === 0) {
75
+ return { kind: "none" };
76
+ }
77
+ const ordinal = parseOrdinal(normalized);
78
+ const body = ordinal ? ordinal.rest : normalized;
79
+ const compound = splitCompound(body);
80
+ const candidates = compound
81
+ ? filterByContext(trip, findByLeftSide(trip, compound.left), compound.right)
82
+ : findByLeftSide(trip, body);
83
+ if (ordinal) {
84
+ if (candidates.length === 0)
85
+ return { kind: "none" };
86
+ const index = ordinal.position === "last" ? candidates.length - 1 : ordinal.position - 1;
87
+ if (index < 0 || index >= candidates.length) {
88
+ return { kind: "none" };
89
+ }
90
+ return { kind: "unique", match: candidates[index] };
91
+ }
92
+ return finalize(candidates);
93
+ }
94
+ function findByLeftSide(trip, ref) {
95
+ const roleMatches = matchRoleKeyword(trip, ref);
96
+ if (roleMatches.length > 0) {
97
+ return roleMatches;
98
+ }
99
+ const exact = matchPlaceName(trip, ref, "exact");
100
+ if (exact.length > 0) {
101
+ return exact;
102
+ }
103
+ return matchPlaceName(trip, ref, "substring");
104
+ }
105
+ function matchRoleKeyword(trip, ref) {
106
+ if (HOTEL_KEYWORDS.has(ref)) {
107
+ return firstBlockOfSectionType(trip, (s) => s.type === "hotels");
108
+ }
109
+ if (FLIGHT_KEYWORDS.has(ref)) {
110
+ return firstBlockOfSectionType(trip, (s) => s.type === "flights");
111
+ }
112
+ if (TRAIN_KEYWORDS.has(ref)) {
113
+ return firstBlockOfSectionType(trip, (s) => s.type === "transit", (b) => b.type === "train");
114
+ }
115
+ return [];
116
+ }
117
+ function firstBlockOfSectionType(trip, sectionPredicate, blockPredicate) {
118
+ const sections = trip.itinerary.sections;
119
+ for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
120
+ const section = sections[sectionIndex];
121
+ if (!sectionPredicate(section))
122
+ continue;
123
+ for (let blockIndex = 0; blockIndex < section.blocks.length; blockIndex++) {
124
+ const block = section.blocks[blockIndex];
125
+ if (blockPredicate && !blockPredicate(block))
126
+ continue;
127
+ return [{ sectionIndex, blockIndex, section, block }];
128
+ }
129
+ }
130
+ return [];
131
+ }
132
+ function matchPlaceName(trip, ref, mode) {
133
+ const matches = [];
134
+ const sections = trip.itinerary.sections;
135
+ for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
136
+ const section = sections[sectionIndex];
137
+ for (let blockIndex = 0; blockIndex < section.blocks.length; blockIndex++) {
138
+ const block = section.blocks[blockIndex];
139
+ if (!isPlaceBlock(block))
140
+ continue;
141
+ const name = normalize(block.place.name ?? "");
142
+ if (!name)
143
+ continue;
144
+ const hit = mode === "exact" ? name === ref : name.includes(ref);
145
+ if (hit) {
146
+ matches.push({ sectionIndex, blockIndex, section, block });
147
+ }
148
+ }
149
+ }
150
+ return matches;
151
+ }
152
+ function splitCompound(ref) {
153
+ const idx = ref.indexOf(" on ");
154
+ if (idx < 0)
155
+ return null;
156
+ const left = ref.slice(0, idx).trim();
157
+ const right = ref.slice(idx + 4).trim();
158
+ if (!left || !right)
159
+ return null;
160
+ return { left, right };
161
+ }
162
+ function filterByContext(trip, candidates, context) {
163
+ if (candidates.length === 0)
164
+ return candidates;
165
+ const contextSection = tryResolveDay(trip, context);
166
+ if (contextSection) {
167
+ return candidates.filter((c) => c.section === contextSection);
168
+ }
169
+ return [];
170
+ }
171
+ function tryResolveDay(trip, ref) {
172
+ try {
173
+ return resolveDay(trip, ref);
174
+ }
175
+ catch {
176
+ return null;
177
+ }
178
+ }
179
+ function finalize(candidates) {
180
+ if (candidates.length === 0)
181
+ return { kind: "none" };
182
+ if (candidates.length === 1)
183
+ return { kind: "unique", match: candidates[0] };
184
+ return {
185
+ kind: "ambiguous",
186
+ candidates: candidates.slice(0, MAX_AMBIGUOUS_CANDIDATES),
187
+ };
188
+ }
189
+ function normalize(s) {
190
+ // Collapse runs of whitespace and punctuation dashes (hyphens, en/em-dashes)
191
+ // so "Roppongi Hills - Tokyo City View" matches "Roppongi Hills Tokyo City View".
192
+ return s.replace(/[\s\-–—]+/g, " ").trim().toLowerCase();
193
+ }
194
+ //# sourceMappingURL=place-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"place-ref.js","sourceRoot":"","sources":["../../src/resolvers/place-ref.ts"],"names":[],"mappings":"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"}