sbb-mcp 0.4.3 → 0.5.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/LICENSE +50 -57
- package/README.md +25 -214
- package/dist/index.js +47 -19
- package/package.json +10 -33
- package/dist/auth.d.ts +0 -2
- package/dist/auth.js +0 -44
- package/dist/auth.js.map +0 -1
- package/dist/cache.d.ts +0 -14
- package/dist/cache.js +0 -62
- package/dist/cache.js.map +0 -1
- package/dist/client.d.ts +0 -17
- package/dist/client.js +0 -70
- package/dist/client.js.map +0 -1
- package/dist/formatters.d.ts +0 -35
- package/dist/formatters.js +0 -285
- package/dist/formatters.js.map +0 -1
- package/dist/http.d.ts +0 -2
- package/dist/http.js +0 -117
- package/dist/http.js.map +0 -1
- package/dist/i18n.d.ts +0 -22
- package/dist/i18n.js +0 -36
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/journey.d.ts +0 -5
- package/dist/journey.js +0 -67
- package/dist/journey.js.map +0 -1
- package/dist/look2book.d.ts +0 -98
- package/dist/look2book.js +0 -212
- package/dist/look2book.js.map +0 -1
- package/dist/prices.d.ts +0 -3
- package/dist/prices.js +0 -51
- package/dist/prices.js.map +0 -1
- package/dist/profile.d.ts +0 -16
- package/dist/profile.js +0 -84
- package/dist/profile.js.map +0 -1
- package/dist/rate-limit.d.ts +0 -5
- package/dist/rate-limit.js +0 -44
- package/dist/rate-limit.js.map +0 -1
- package/dist/shortlink.d.ts +0 -60
- package/dist/shortlink.js +0 -122
- package/dist/shortlink.js.map +0 -1
- package/dist/structured.d.ts +0 -125
- package/dist/structured.js +0 -134
- package/dist/structured.js.map +0 -1
- package/dist/swisstrip.d.ts +0 -41
- package/dist/swisstrip.js +0 -135
- package/dist/swisstrip.js.map +0 -1
- package/dist/tools.d.ts +0 -40
- package/dist/tools.js +0 -509
- package/dist/tools.js.map +0 -1
- package/dist/transport/index.d.ts +0 -10
- package/dist/transport/index.js +0 -13
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/setup.d.ts +0 -1
- package/dist/transport/setup.js +0 -59
- package/dist/transport/setup.js.map +0 -1
- package/dist/transport/smapi-auth.d.ts +0 -14
- package/dist/transport/smapi-auth.js +0 -89
- package/dist/transport/smapi-auth.js.map +0 -1
- package/dist/transport/smapi-client.d.ts +0 -46
- package/dist/transport/smapi-client.js +0 -186
- package/dist/transport/smapi-client.js.map +0 -1
- package/dist/transport/smapi-journey.d.ts +0 -29
- package/dist/transport/smapi-journey.js +0 -91
- package/dist/transport/smapi-journey.js.map +0 -1
- package/dist/transport/smapi-mock.d.ts +0 -9
- package/dist/transport/smapi-mock.js +0 -151
- package/dist/transport/smapi-mock.js.map +0 -1
- package/dist/transport/smapi-prices.d.ts +0 -48
- package/dist/transport/smapi-prices.js +0 -144
- package/dist/transport/smapi-prices.js.map +0 -1
- package/dist/transport/smapi-types.d.ts +0 -181
- package/dist/transport/smapi-types.js +0 -2
- package/dist/transport/smapi-types.js.map +0 -1
- package/dist/types.d.ts +0 -139
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/widgets.d.ts +0 -60
- package/dist/widgets.js +0 -184
- package/dist/widgets.js.map +0 -1
- package/web/dist/widgets.css +0 -1
- package/web/dist/widgets.js +0 -1
package/dist/rate-limit.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple in-memory rate limiter per IP.
|
|
3
|
-
* 60 requests per minute per IP. Max 50k tracked IPs.
|
|
4
|
-
*/
|
|
5
|
-
const requests = new Map();
|
|
6
|
-
const WINDOW_MS = 60 * 1000; // 1 minute
|
|
7
|
-
const MAX_REQUESTS = 60; // per window
|
|
8
|
-
const MAX_IPS = 50000; // max tracked IPs
|
|
9
|
-
export function isRateLimited(ip) {
|
|
10
|
-
const now = Date.now();
|
|
11
|
-
const entry = requests.get(ip);
|
|
12
|
-
if (!entry || now >= entry.resetAt) {
|
|
13
|
-
// Evict if map is too large
|
|
14
|
-
if (requests.size >= MAX_IPS) {
|
|
15
|
-
for (const [k, v] of requests) {
|
|
16
|
-
if (now >= v.resetAt)
|
|
17
|
-
requests.delete(k);
|
|
18
|
-
}
|
|
19
|
-
// If still too large after cleanup, drop oldest entries
|
|
20
|
-
if (requests.size >= MAX_IPS) {
|
|
21
|
-
let toDrop = Math.floor(MAX_IPS * 0.1);
|
|
22
|
-
for (const k of requests.keys()) {
|
|
23
|
-
if (toDrop-- <= 0)
|
|
24
|
-
break;
|
|
25
|
-
requests.delete(k);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
requests.set(ip, { count: 1, resetAt: now + WINDOW_MS });
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
entry.count++;
|
|
33
|
-
return entry.count > MAX_REQUESTS;
|
|
34
|
-
}
|
|
35
|
-
// Cleanup old entries every 5 minutes
|
|
36
|
-
setInterval(() => {
|
|
37
|
-
const now = Date.now();
|
|
38
|
-
for (const [ip, entry] of requests) {
|
|
39
|
-
if (now >= entry.resetAt) {
|
|
40
|
-
requests.delete(ip);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}, 5 * 60 * 1000).unref();
|
|
44
|
-
//# sourceMappingURL=rate-limit.js.map
|
package/dist/rate-limit.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8C,CAAA;AAEtE,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAA,CAAE,WAAW;AACxC,MAAM,YAAY,GAAG,EAAE,CAAA,CAAO,aAAa;AAC3C,MAAM,OAAO,GAAG,KAAK,CAAA,CAAS,kBAAkB;AAEhD,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAE9B,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,4BAA4B;QAC5B,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;YAC7B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC9B,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO;oBAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YAC1C,CAAC;YACD,wDAAwD;YACxD,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,CAAA;gBACtC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;oBAChC,IAAI,MAAM,EAAE,IAAI,CAAC;wBAAE,MAAK;oBACxB,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;gBACpB,CAAC;YACH,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,SAAS,EAAE,CAAC,CAAA;QACxD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,CAAC,KAAK,EAAE,CAAA;IACb,OAAO,KAAK,CAAC,KAAK,GAAG,YAAY,CAAA;AACnC,CAAC;AAED,sCAAsC;AACtC,WAAW,CAAC,GAAG,EAAE;IACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACnC,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;AACH,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,CAAA"}
|
package/dist/shortlink.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { Lang } from './i18n.js';
|
|
2
|
-
/** Current token schema version — bump if the payload shape changes. */
|
|
3
|
-
export declare const SHORTLINK_VERSION = 1;
|
|
4
|
-
export interface ShortlinkPayload {
|
|
5
|
-
/** Schema version. Decoder rejects unknown versions. */
|
|
6
|
-
v: number;
|
|
7
|
-
/** SMAPI trip ID — used for click-to-booking attribution in logs. */
|
|
8
|
-
tid: string;
|
|
9
|
-
/** Origin station SBB ID (e.g. "8503000"). */
|
|
10
|
-
o: string;
|
|
11
|
-
/** Origin station display name. */
|
|
12
|
-
on: string;
|
|
13
|
-
/** Destination station SBB ID. */
|
|
14
|
-
d: string;
|
|
15
|
-
/** Destination station display name. */
|
|
16
|
-
dn: string;
|
|
17
|
-
/** YYYY-MM-DD, Europe/Zurich calendar date. */
|
|
18
|
-
dt: string;
|
|
19
|
-
/** HH:MM 24h, Europe/Zurich local time. */
|
|
20
|
-
t: string;
|
|
21
|
-
/** Language for the resolved sbb.ch URL. */
|
|
22
|
-
l: Lang;
|
|
23
|
-
}
|
|
24
|
-
export interface BuildShortLinkInput {
|
|
25
|
-
tripId: string;
|
|
26
|
-
fromId: string;
|
|
27
|
-
fromName: string;
|
|
28
|
-
toId: string;
|
|
29
|
-
toName: string;
|
|
30
|
-
date: string;
|
|
31
|
-
time: string;
|
|
32
|
-
lang?: Lang;
|
|
33
|
-
/** Override the public base URL. Defaults to env or mcp.swisstrip.app. */
|
|
34
|
-
baseUrl?: string;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Return the public base URL for redirect links.
|
|
38
|
-
*
|
|
39
|
-
* Precedence:
|
|
40
|
-
* 1. Explicit `baseUrl` argument to `buildShortLink()`
|
|
41
|
-
* 2. `SBB_MCP_PUBLIC_BASE_URL` env var (Railway / self-hosted)
|
|
42
|
-
* 3. `https://mcp.swisstrip.app` (our canonical hosted redirect)
|
|
43
|
-
*
|
|
44
|
-
* Always returns without a trailing slash so callers can safely append `/r/...`.
|
|
45
|
-
*/
|
|
46
|
-
export declare function resolvePublicBaseUrl(override?: string): string;
|
|
47
|
-
export declare function encodeShortlink(payload: ShortlinkPayload): string;
|
|
48
|
-
export declare function decodeShortlink(token: string): ShortlinkPayload;
|
|
49
|
-
/**
|
|
50
|
-
* Build a redirect URL that, when fetched, logs a click and 302s to sbb.ch.
|
|
51
|
-
*
|
|
52
|
-
* Always populates — never throws, never returns an empty string. Callers can
|
|
53
|
-
* rely on `bookingUrl` being a valid `https://…/r/…` URL for every connection.
|
|
54
|
-
*/
|
|
55
|
-
export declare function buildShortLink(input: BuildShortLinkInput): string;
|
|
56
|
-
/**
|
|
57
|
-
* Resolve a shortlink payload back into the real sbb.ch deep link.
|
|
58
|
-
* Used by the `/r/:token` redirect handler.
|
|
59
|
-
*/
|
|
60
|
-
export declare function resolveTargetUrl(payload: ShortlinkPayload): string;
|
package/dist/shortlink.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Short-link encoder/decoder for SBB booking redirects.
|
|
3
|
-
*
|
|
4
|
-
* Why: raw sbb.ch deep links are 300+ chars because they encode a JSON blob of
|
|
5
|
-
* stops in the query string. That renders badly in ChatGPT (exposed as raw
|
|
6
|
-
* URLs in prose) and gives us zero click-tracking — meaning no Look2Book
|
|
7
|
-
* telemetry, which we need to comply with SBB's contractual ratio caps
|
|
8
|
-
* (100:1 for trips, 50:1 for offers) once SMAPI credentials go live.
|
|
9
|
-
*
|
|
10
|
-
* Solution: wrap every booking URL behind `{PUBLIC_BASE}/r/{token}`, where
|
|
11
|
-
* `token` is a base64url-encoded JSON payload carrying everything the
|
|
12
|
-
* redirect handler needs to reconstruct the real sbb.ch URL. Stateless —
|
|
13
|
-
* no DB lookup required, so Railway restarts don't invalidate old links.
|
|
14
|
-
*
|
|
15
|
-
* Payload is intentionally un-signed: everything inside is already public
|
|
16
|
-
* (station IDs, dates) and tamper-resistant traffic has no value here. If
|
|
17
|
-
* a user hand-crafts a token to jump to an arbitrary sbb.ch page, that's
|
|
18
|
-
* fine — sbb.ch is the legitimate destination.
|
|
19
|
-
*/
|
|
20
|
-
import { buildSbbDeepLink } from './formatters.js';
|
|
21
|
-
/** Current token schema version — bump if the payload shape changes. */
|
|
22
|
-
export const SHORTLINK_VERSION = 1;
|
|
23
|
-
/**
|
|
24
|
-
* Return the public base URL for redirect links.
|
|
25
|
-
*
|
|
26
|
-
* Precedence:
|
|
27
|
-
* 1. Explicit `baseUrl` argument to `buildShortLink()`
|
|
28
|
-
* 2. `SBB_MCP_PUBLIC_BASE_URL` env var (Railway / self-hosted)
|
|
29
|
-
* 3. `https://mcp.swisstrip.app` (our canonical hosted redirect)
|
|
30
|
-
*
|
|
31
|
-
* Always returns without a trailing slash so callers can safely append `/r/...`.
|
|
32
|
-
*/
|
|
33
|
-
export function resolvePublicBaseUrl(override) {
|
|
34
|
-
const raw = override ?? process.env.SBB_MCP_PUBLIC_BASE_URL ?? 'https://mcp.swisstrip.app';
|
|
35
|
-
return raw.replace(/\/+$/, '');
|
|
36
|
-
}
|
|
37
|
-
/** Base64url encode without padding, Node-safe (no atob/btoa). */
|
|
38
|
-
function base64urlEncode(input) {
|
|
39
|
-
return Buffer.from(input, 'utf8')
|
|
40
|
-
.toString('base64')
|
|
41
|
-
.replace(/\+/g, '-')
|
|
42
|
-
.replace(/\//g, '_')
|
|
43
|
-
.replace(/=+$/, '');
|
|
44
|
-
}
|
|
45
|
-
/** Base64url decode back to a UTF-8 string. Throws on invalid input. */
|
|
46
|
-
function base64urlDecode(token) {
|
|
47
|
-
// Restore standard base64 alphabet and padding.
|
|
48
|
-
const padded = token.replace(/-/g, '+').replace(/_/g, '/');
|
|
49
|
-
const padLen = (4 - (padded.length % 4)) % 4;
|
|
50
|
-
return Buffer.from(padded + '='.repeat(padLen), 'base64').toString('utf8');
|
|
51
|
-
}
|
|
52
|
-
export function encodeShortlink(payload) {
|
|
53
|
-
return base64urlEncode(JSON.stringify(payload));
|
|
54
|
-
}
|
|
55
|
-
export function decodeShortlink(token) {
|
|
56
|
-
let json;
|
|
57
|
-
try {
|
|
58
|
-
json = base64urlDecode(token);
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
throw new Error('Invalid shortlink token: not base64url');
|
|
62
|
-
}
|
|
63
|
-
let parsed;
|
|
64
|
-
try {
|
|
65
|
-
parsed = JSON.parse(json);
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
throw new Error('Invalid shortlink token: not JSON');
|
|
69
|
-
}
|
|
70
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
71
|
-
throw new Error('Invalid shortlink token: not an object');
|
|
72
|
-
}
|
|
73
|
-
const p = parsed;
|
|
74
|
-
const requiredStrings = ['tid', 'o', 'on', 'd', 'dn', 'dt', 't', 'l'];
|
|
75
|
-
for (const key of requiredStrings) {
|
|
76
|
-
if (typeof p[key] !== 'string' || !p[key].length) {
|
|
77
|
-
throw new Error(`Invalid shortlink token: missing/empty field "${key}"`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (p.v !== SHORTLINK_VERSION) {
|
|
81
|
-
throw new Error(`Unsupported shortlink version: ${String(p.v)} (expected ${SHORTLINK_VERSION})`);
|
|
82
|
-
}
|
|
83
|
-
return parsed;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Build a redirect URL that, when fetched, logs a click and 302s to sbb.ch.
|
|
87
|
-
*
|
|
88
|
-
* Always populates — never throws, never returns an empty string. Callers can
|
|
89
|
-
* rely on `bookingUrl` being a valid `https://…/r/…` URL for every connection.
|
|
90
|
-
*/
|
|
91
|
-
export function buildShortLink(input) {
|
|
92
|
-
const payload = {
|
|
93
|
-
v: SHORTLINK_VERSION,
|
|
94
|
-
tid: input.tripId,
|
|
95
|
-
o: input.fromId,
|
|
96
|
-
on: input.fromName,
|
|
97
|
-
d: input.toId,
|
|
98
|
-
dn: input.toName,
|
|
99
|
-
dt: input.date,
|
|
100
|
-
t: input.time,
|
|
101
|
-
l: input.lang ?? 'en',
|
|
102
|
-
};
|
|
103
|
-
const token = encodeShortlink(payload);
|
|
104
|
-
const base = resolvePublicBaseUrl(input.baseUrl);
|
|
105
|
-
return `${base}/r/${token}`;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Resolve a shortlink payload back into the real sbb.ch deep link.
|
|
109
|
-
* Used by the `/r/:token` redirect handler.
|
|
110
|
-
*/
|
|
111
|
-
export function resolveTargetUrl(payload) {
|
|
112
|
-
return buildSbbDeepLink({
|
|
113
|
-
fromName: payload.on,
|
|
114
|
-
fromId: payload.o,
|
|
115
|
-
toName: payload.dn,
|
|
116
|
-
toId: payload.d,
|
|
117
|
-
date: payload.dt,
|
|
118
|
-
time: payload.t,
|
|
119
|
-
lang: payload.l,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
//# sourceMappingURL=shortlink.js.map
|
package/dist/shortlink.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shortlink.js","sourceRoot":"","sources":["../src/shortlink.ts"],"names":[],"mappings":"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"}
|
package/dist/structured.d.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure extractors from SMAPI types to widget-friendly DTOs.
|
|
3
|
-
* Shape must stay in sync with web/src/types.ts.
|
|
4
|
-
*
|
|
5
|
-
* Keep these side-effect free. They're tested in unit tests and run on
|
|
6
|
-
* every tool invocation to populate `structuredContent` on responses.
|
|
7
|
-
*/
|
|
8
|
-
import type { SmapiPlace, SmapiTrip, SmapiTripsCollection, SmapiPriceResult } from './transport/smapi-types.js';
|
|
9
|
-
import type { Lang } from './i18n.js';
|
|
10
|
-
export interface StationDTO {
|
|
11
|
-
id: string;
|
|
12
|
-
name: string;
|
|
13
|
-
lat?: number;
|
|
14
|
-
lon?: number;
|
|
15
|
-
}
|
|
16
|
-
export interface StationsListDTO {
|
|
17
|
-
query: string;
|
|
18
|
-
stations: StationDTO[];
|
|
19
|
-
}
|
|
20
|
-
export interface LegDTO {
|
|
21
|
-
type: 'train' | 'walk';
|
|
22
|
-
line?: string;
|
|
23
|
-
platform?: string;
|
|
24
|
-
minutes: number;
|
|
25
|
-
}
|
|
26
|
-
export interface ConnectionDTO {
|
|
27
|
-
tripId: string;
|
|
28
|
-
departureTime: string;
|
|
29
|
-
arrivalTime: string;
|
|
30
|
-
durationMinutes: number;
|
|
31
|
-
transfers: number;
|
|
32
|
-
legs: LegDTO[];
|
|
33
|
-
}
|
|
34
|
-
export interface ConnectionListDTO {
|
|
35
|
-
origin: StationDTO;
|
|
36
|
-
destination: StationDTO;
|
|
37
|
-
date: string;
|
|
38
|
-
collectionId: string;
|
|
39
|
-
connections: ConnectionDTO[];
|
|
40
|
-
weather?: {
|
|
41
|
-
summary: string;
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* Request language — widgets rebuild the booking shortlink client-side
|
|
45
|
-
* and use this to set the locale on the resolved sbb.ch page.
|
|
46
|
-
*/
|
|
47
|
-
lang?: Lang;
|
|
48
|
-
}
|
|
49
|
-
export interface TripStopDTO {
|
|
50
|
-
name: string;
|
|
51
|
-
arrivalTime?: string;
|
|
52
|
-
departureTime?: string;
|
|
53
|
-
}
|
|
54
|
-
export interface TripLegDTO {
|
|
55
|
-
type: 'train' | 'walk';
|
|
56
|
-
line?: string;
|
|
57
|
-
operator?: string;
|
|
58
|
-
durationMinutes: number;
|
|
59
|
-
from?: {
|
|
60
|
-
name: string;
|
|
61
|
-
time: string;
|
|
62
|
-
platform?: string;
|
|
63
|
-
};
|
|
64
|
-
to?: {
|
|
65
|
-
name: string;
|
|
66
|
-
time: string;
|
|
67
|
-
platform?: string;
|
|
68
|
-
};
|
|
69
|
-
intermediateStops?: TripStopDTO[];
|
|
70
|
-
occupancy?: {
|
|
71
|
-
firstClass?: string;
|
|
72
|
-
secondClass?: string;
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
export interface TripDetailsDTO {
|
|
76
|
-
tripId: string;
|
|
77
|
-
origin: StationDTO;
|
|
78
|
-
destination: StationDTO;
|
|
79
|
-
departureTime: string;
|
|
80
|
-
arrivalTime: string;
|
|
81
|
-
durationMinutes: number;
|
|
82
|
-
transfers: number;
|
|
83
|
-
status: string;
|
|
84
|
-
legs: TripLegDTO[];
|
|
85
|
-
}
|
|
86
|
-
export interface PriceDTO {
|
|
87
|
-
tripId: string;
|
|
88
|
-
secondClass?: {
|
|
89
|
-
amount: number;
|
|
90
|
-
currency: string;
|
|
91
|
-
};
|
|
92
|
-
firstClass?: {
|
|
93
|
-
amount: number;
|
|
94
|
-
currency: string;
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
export interface PricesTableDTO {
|
|
98
|
-
prices: PriceDTO[];
|
|
99
|
-
}
|
|
100
|
-
export interface TicketCardDTO {
|
|
101
|
-
tripId: string;
|
|
102
|
-
origin: StationDTO;
|
|
103
|
-
destination: StationDTO;
|
|
104
|
-
departureTime: string;
|
|
105
|
-
arrivalTime: string;
|
|
106
|
-
primaryLink: string;
|
|
107
|
-
affiliateLink?: string;
|
|
108
|
-
}
|
|
109
|
-
export declare function toStationsListDTO(query: string, places: SmapiPlace[]): StationsListDTO;
|
|
110
|
-
export declare function toConnectionListDTO(collection: SmapiTripsCollection, weather?: {
|
|
111
|
-
summary: string;
|
|
112
|
-
}, lang?: Lang): ConnectionListDTO;
|
|
113
|
-
export declare function toTripDetailsDTO(trip: SmapiTrip): TripDetailsDTO;
|
|
114
|
-
export declare function toPricesTableDTO(results: SmapiPriceResult[]): PricesTableDTO;
|
|
115
|
-
export declare function toTicketCardDTO(params: {
|
|
116
|
-
tripId: string;
|
|
117
|
-
fromName: string;
|
|
118
|
-
fromId: string;
|
|
119
|
-
toName: string;
|
|
120
|
-
toId: string;
|
|
121
|
-
departureTime: string;
|
|
122
|
-
arrivalTime: string;
|
|
123
|
-
primaryLink: string;
|
|
124
|
-
affiliateLink?: string;
|
|
125
|
-
}): TicketCardDTO;
|
package/dist/structured.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure extractors from SMAPI types to widget-friendly DTOs.
|
|
3
|
-
* Shape must stay in sync with web/src/types.ts.
|
|
4
|
-
*
|
|
5
|
-
* Keep these side-effect free. They're tested in unit tests and run on
|
|
6
|
-
* every tool invocation to populate `structuredContent` on responses.
|
|
7
|
-
*/
|
|
8
|
-
// ──────────────────────────────────────────────────────────────────────
|
|
9
|
-
function toStation(p) {
|
|
10
|
-
return {
|
|
11
|
-
id: p.id,
|
|
12
|
-
name: p.name,
|
|
13
|
-
lat: p.geoPosition?.latitude,
|
|
14
|
-
lon: p.geoPosition?.longitude,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
function parseIsoDurationMinutes(iso) {
|
|
18
|
-
const m = iso.match(/PT(?:(\d+)H)?(?:(\d+)M)?/);
|
|
19
|
-
if (!m)
|
|
20
|
-
return 0;
|
|
21
|
-
return parseInt(m[1] ?? '0', 10) * 60 + parseInt(m[2] ?? '0', 10);
|
|
22
|
-
}
|
|
23
|
-
function legToDTO(leg) {
|
|
24
|
-
if (leg.type === 'timed') {
|
|
25
|
-
const tl = leg;
|
|
26
|
-
return {
|
|
27
|
-
type: 'train',
|
|
28
|
-
line: tl.service.publishedLineName,
|
|
29
|
-
platform: tl.board.platform,
|
|
30
|
-
minutes: parseIsoDurationMinutes(tl.duration),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
if (leg.type === 'transfer') {
|
|
34
|
-
const tr = leg;
|
|
35
|
-
return { type: 'walk', minutes: parseIsoDurationMinutes(tr.duration) };
|
|
36
|
-
}
|
|
37
|
-
return { type: 'walk', minutes: parseIsoDurationMinutes(leg.duration) };
|
|
38
|
-
}
|
|
39
|
-
export function toStationsListDTO(query, places) {
|
|
40
|
-
return { query, stations: places.map(toStation) };
|
|
41
|
-
}
|
|
42
|
-
export function toConnectionListDTO(collection, weather, lang = 'en') {
|
|
43
|
-
const first = collection.trips[0];
|
|
44
|
-
const fallbackStation = { id: '', name: '—' };
|
|
45
|
-
return {
|
|
46
|
-
origin: first ? toStation(first.origin) : fallbackStation,
|
|
47
|
-
destination: first ? toStation(first.destination) : fallbackStation,
|
|
48
|
-
date: first?.startTime ?? '',
|
|
49
|
-
collectionId: collection.id,
|
|
50
|
-
connections: collection.trips.map((t) => ({
|
|
51
|
-
tripId: t.id,
|
|
52
|
-
departureTime: t.startTime,
|
|
53
|
-
arrivalTime: t.endTime,
|
|
54
|
-
durationMinutes: parseIsoDurationMinutes(t.duration),
|
|
55
|
-
transfers: t.transfers,
|
|
56
|
-
legs: t.legs.map(legToDTO),
|
|
57
|
-
})),
|
|
58
|
-
...(weather ? { weather } : {}),
|
|
59
|
-
lang,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
export function toTripDetailsDTO(trip) {
|
|
63
|
-
return {
|
|
64
|
-
tripId: trip.id,
|
|
65
|
-
origin: toStation(trip.origin),
|
|
66
|
-
destination: toStation(trip.destination),
|
|
67
|
-
departureTime: trip.startTime,
|
|
68
|
-
arrivalTime: trip.endTime,
|
|
69
|
-
durationMinutes: parseIsoDurationMinutes(trip.duration),
|
|
70
|
-
transfers: trip.transfers,
|
|
71
|
-
status: trip.tripStatus,
|
|
72
|
-
legs: trip.legs.map((leg) => {
|
|
73
|
-
if (leg.type === 'timed') {
|
|
74
|
-
const tl = leg;
|
|
75
|
-
return {
|
|
76
|
-
type: 'train',
|
|
77
|
-
line: tl.service.publishedLineName,
|
|
78
|
-
operator: tl.service.operatorName,
|
|
79
|
-
durationMinutes: parseIsoDurationMinutes(tl.duration),
|
|
80
|
-
from: {
|
|
81
|
-
name: tl.board.stopPlace.name,
|
|
82
|
-
time: tl.board.departureTime,
|
|
83
|
-
platform: tl.board.platform,
|
|
84
|
-
},
|
|
85
|
-
to: {
|
|
86
|
-
name: tl.alight.stopPlace.name,
|
|
87
|
-
time: tl.alight.arrivalTime,
|
|
88
|
-
platform: tl.alight.platform,
|
|
89
|
-
},
|
|
90
|
-
intermediateStops: tl.intermediateStops?.map((s) => ({
|
|
91
|
-
name: s.stopPlace.name,
|
|
92
|
-
arrivalTime: s.arrivalTime,
|
|
93
|
-
departureTime: s.departureTime,
|
|
94
|
-
})),
|
|
95
|
-
occupancy: tl.occupancy
|
|
96
|
-
? {
|
|
97
|
-
firstClass: tl.occupancy.firstClass,
|
|
98
|
-
secondClass: tl.occupancy.secondClass,
|
|
99
|
-
}
|
|
100
|
-
: undefined,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
type: 'walk',
|
|
105
|
-
durationMinutes: parseIsoDurationMinutes(leg.duration),
|
|
106
|
-
};
|
|
107
|
-
}),
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
export function toPricesTableDTO(results) {
|
|
111
|
-
return {
|
|
112
|
-
prices: results.map((r) => {
|
|
113
|
-
const second = r.prices.find((p) => p.class === '2');
|
|
114
|
-
const first = r.prices.find((p) => p.class === '1');
|
|
115
|
-
return {
|
|
116
|
-
tripId: r.tripId,
|
|
117
|
-
...(second ? { secondClass: { amount: second.amount, currency: second.currency } } : {}),
|
|
118
|
-
...(first ? { firstClass: { amount: first.amount, currency: first.currency } } : {}),
|
|
119
|
-
};
|
|
120
|
-
}),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
export function toTicketCardDTO(params) {
|
|
124
|
-
return {
|
|
125
|
-
tripId: params.tripId,
|
|
126
|
-
origin: { id: params.fromId, name: params.fromName },
|
|
127
|
-
destination: { id: params.toId, name: params.toName },
|
|
128
|
-
departureTime: params.departureTime,
|
|
129
|
-
arrivalTime: params.arrivalTime,
|
|
130
|
-
primaryLink: params.primaryLink,
|
|
131
|
-
...(params.affiliateLink ? { affiliateLink: params.affiliateLink } : {}),
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
//# sourceMappingURL=structured.js.map
|
package/dist/structured.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"structured.js","sourceRoot":"","sources":["../src/structured.ts"],"names":[],"mappings":"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"}
|
package/dist/swisstrip.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SwissTrip API client for sbb-mcp (Layer 3)
|
|
3
|
-
*
|
|
4
|
-
* When SWISSTRIP_TOKEN is set, sbb-mcp fetches traveler profiles from the
|
|
5
|
-
* SwissTrip cloud API instead of (or in addition to) the local file.
|
|
6
|
-
* This enables cloud-synced profiles and multi-traveler support (partner, kids).
|
|
7
|
-
*/
|
|
8
|
-
import type { SmapiTraveler } from './transport/smapi-types.js';
|
|
9
|
-
export type SwissTripProfile = {
|
|
10
|
-
id: string;
|
|
11
|
-
email: string;
|
|
12
|
-
travel_first_name: string | null;
|
|
13
|
-
travel_last_name: string | null;
|
|
14
|
-
travel_date_of_birth: string | null;
|
|
15
|
-
travel_reduction_card: string | null;
|
|
16
|
-
travel_reduction_card_valid_until: string | null;
|
|
17
|
-
locale: string | null;
|
|
18
|
-
preferred_currency: string | null;
|
|
19
|
-
};
|
|
20
|
-
export type SwissTripTraveler = {
|
|
21
|
-
id: string;
|
|
22
|
-
user_id: string;
|
|
23
|
-
label: string | null;
|
|
24
|
-
first_name: string | null;
|
|
25
|
-
last_name: string | null;
|
|
26
|
-
date_of_birth: string | null;
|
|
27
|
-
reduction_card: string | null;
|
|
28
|
-
reduction_card_valid_until: string | null;
|
|
29
|
-
is_primary: boolean;
|
|
30
|
-
created_at: string;
|
|
31
|
-
updated_at: string;
|
|
32
|
-
};
|
|
33
|
-
export declare function isSwissTripConfigured(): boolean;
|
|
34
|
-
export declare function fetchProfile(): Promise<SwissTripProfile>;
|
|
35
|
-
export declare function fetchTravelers(): Promise<SwissTripTraveler[]>;
|
|
36
|
-
/** Convert a SwissTrip traveler to an SMAPI traveler for pricing/offers */
|
|
37
|
-
export declare function toSmapiTraveler(t: SwissTripTraveler, index: number): SmapiTraveler;
|
|
38
|
-
/** Convert the primary profile (from /api/mcp/profile) to an SMAPI traveler */
|
|
39
|
-
export declare function profileToSmapiTraveler(p: SwissTripProfile): SmapiTraveler;
|
|
40
|
-
export declare function formatTravelersList(travelers: SwissTripTraveler[]): string;
|
|
41
|
-
export declare function formatCloudProfile(profile: SwissTripProfile): string;
|