UNPKG

tfl-ts

Version:

🚇 Fully-typed TypeScript client for Transport for London (TfL) API • Zero dependencies • Auto-generated types • Real-time arrivals • Journey planning • Universal compatibility

283 lines (282 loc) • 10 kB
"use strict"; /** * Mode API Module * * Provides access to transport mode information, active service types, and mode-specific arrivals. * Transport modes include tube, bus, dlr, overground, tram, cable-car, cycle-hire, and more. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Modes = exports.Mode = void 0; // Import generated metadata (NEVER hardcode!) const Meta_1 = require("./generated/meta/Meta"); Object.defineProperty(exports, "Modes", { enumerable: true, get: function () { return Meta_1.Modes; } }); const stripTypes_1 = require("./utils/stripTypes"); /** * Mode API client for transport mode information and arrivals * * The Mode API provides information about transport modes available in the TfL network, * including service types and real-time arrival predictions for all stops of a given mode. * * @example * ```typescript * // Get all active service types (currently only supports tube) * const serviceTypes = await client.mode.getActiveServiceTypes(); * * // Get arrivals for all tube stops * const tubeArrivals = await client.mode.getArrivals({ mode: 'tube', count: 5 }); * * // Validate mode names * const isValidMode = client.mode.MODE_NAMES.includes('elizabeth-line'); * ``` */ class Mode { constructor(api) { this.api = api; // 🚨 ALWAYS use generated metadata (never hardcode!) this.MODE_NAMES = Meta_1.Modes.map(m => m.modeName); this.SERVICE_TYPES = Meta_1.ServiceTypes; this.DISRUPTION_CATEGORIES = Meta_1.DisruptionCategories; this.PLACE_TYPES = Meta_1.PlaceTypes; this.SEARCH_PROVIDERS = Meta_1.SearchProviders; this.SORT_OPTIONS = Meta_1.Sorts; this.STOP_TYPES = Meta_1.StopTypes; this.CATEGORIES = Meta_1.Categories; this.ALL_SEVERITY = Meta_1.Severity; // Build derived metadata from generated data this.MODES_BY_TYPE = this.buildModesByType(); this.TFL_OPERATED_MODES = this.buildTflOperatedModes(); this.FARE_PAYING_MODES = this.buildFarePayingModes(); this.SCHEDULED_SERVICE_MODES = this.buildScheduledServiceModes(); } /** * Gets the active service types for transport modes * * Returns the service type active for a mode. Currently only supports tube mode. * * @param options - Query options for getting active service types * @returns Promise resolving to array of active service types * * @example * ```typescript * // Get all active service types * const serviceTypes = await client.mode.getActiveServiceTypes(); * console.log(serviceTypes); * // Output: [{ name: 'Regular', uri: '/Line/Route?serviceTypes=Regular' }, ...] * * // Check if service types are available * if (serviceTypes.length > 0) { * console.log('Active service types available'); * } * ``` */ async getActiveServiceTypes(options = {}) { const { keepTflTypes = false } = options; return this.api.mode.modeGetActiveServiceTypes().then(response => (0, stripTypes_1.stripTypeFields)(response.data, keepTflTypes)); } /** * Gets arrival predictions for all stops of a given mode * * Returns the next arrival predictions for all stops that serve the specified transport mode. * This is useful for getting a comprehensive view of arrivals across an entire mode network. * * @param options - Query options including mode and count * @returns Promise resolving to array of arrival predictions * * @example * ```typescript * // Get next 3 arrivals for all tube stops * const tubeArrivals = await client.mode.getArrivals({ * mode: 'tube', * count: 3 * }); * * // Get all available arrivals for DLR * const dlrArrivals = await client.mode.getArrivals({ * mode: 'dlr', * count: -1 * }); * * // Validate mode before making request * const modeName = 'elizabeth-line'; * if (client.mode.MODE_NAMES.includes(modeName)) { * const arrivals = await client.mode.getArrivals({ mode: modeName }); * } else { * throw new Error(`Invalid mode: ${modeName}`); * } * * // Filter arrivals by destination * const filteredArrivals = tubeArrivals.filter(arrival => * arrival.towards?.includes('Central London') * ); * ``` */ async getArrivals(options) { const { mode, count, keepTflTypes = false } = options; const params = { mode, ...(count !== undefined && { count }) }; return this.api.mode.modeArrivals(params).then(response => (0, stripTypes_1.stripTypeFields)(response.data, keepTflTypes)); } // 🚨 Build derived metadata from generated data buildModesByType() { const modesByType = { tflOperated: [], farePaying: [], scheduled: [], nonTfl: [] }; Meta_1.Modes.forEach(mode => { if (mode.isTflService) { modesByType.tflOperated.push(mode.modeName); } else { modesByType.nonTfl.push(mode.modeName); } if (mode.isFarePaying) { modesByType.farePaying.push(mode.modeName); } if (mode.isScheduledService) { modesByType.scheduled.push(mode.modeName); } }); return modesByType; } buildTflOperatedModes() { return Meta_1.Modes .filter(mode => mode.isTflService) .map(mode => mode.modeName); } buildFarePayingModes() { return Meta_1.Modes .filter(mode => mode.isFarePaying) .map(mode => mode.modeName); } buildScheduledServiceModes() { return Meta_1.Modes .filter(mode => mode.isScheduledService) .map(mode => mode.modeName); } // Utility methods /** * Validates if a mode name is valid * * @param modeName - The mode name to validate * @returns True if the mode is valid, false otherwise * * @example * ```typescript * const isValid = client.mode.isValidMode('tube'); // true * const isInvalid = client.mode.isValidMode('invalid-mode'); // false * ``` */ isValidMode(modeName) { return this.MODE_NAMES.includes(modeName); } /** * Checks if a mode is operated by TfL * * @param modeName - The mode name to check * @returns True if the mode is TfL operated, false otherwise * * @example * ```typescript * const isTflOperated = client.mode.isTflOperated('tube'); // true * const isNotTflOperated = client.mode.isTflOperated('national-rail'); // false * ``` */ isTflOperated(modeName) { return this.TFL_OPERATED_MODES.includes(modeName); } /** * Checks if a mode requires fare payment * * @param modeName - The mode name to check * @returns True if the mode requires fare payment, false otherwise * * @example * ```typescript * const requiresFare = client.mode.requiresFare('bus'); // true * const isFree = client.mode.requiresFare('walking'); // false * ``` */ requiresFare(modeName) { return this.FARE_PAYING_MODES.includes(modeName); } /** * Checks if a mode operates on a scheduled service * * @param modeName - The mode name to check * @returns True if the mode operates on a schedule, false otherwise * * @example * ```typescript * const isScheduled = client.mode.isScheduledService('tube'); // true * const isNotScheduled = client.mode.isScheduledService('walking'); // false * ``` */ isScheduledService(modeName) { return this.SCHEDULED_SERVICE_MODES.includes(modeName); } /** * Gets mode information by name * * @param modeName - The mode name to get information for * @returns Mode information or undefined if not found * * @example * ```typescript * const modeInfo = client.mode.getModeInfo('tube'); * console.log(modeInfo); * // Output: { isTflService: true, isFarePaying: true, isScheduledService: true, modeName: 'tube' } * ``` */ getModeInfo(modeName) { return Meta_1.Modes.find(mode => mode.modeName === modeName); } /** * Gets all modes that match specific criteria * * @param criteria - Filter criteria for modes * @returns Array of mode names matching the criteria * * @example * ```typescript * // Get all TfL operated modes * const tflModes = client.mode.getModesByCriteria({ isTflService: true }); * * // Get all free modes * const freeModes = client.mode.getModesByCriteria({ isFarePaying: false }); * * // Get all scheduled TfL services * const scheduledTfl = client.mode.getModesByCriteria({ * isTflService: true, * isScheduledService: true * }); * ``` */ getModesByCriteria(criteria) { return Meta_1.Modes .filter(mode => { if (criteria.isTflService !== undefined && mode.isTflService !== criteria.isTflService) { return false; } if (criteria.isFarePaying !== undefined && mode.isFarePaying !== criteria.isFarePaying) { return false; } if (criteria.isScheduledService !== undefined && mode.isScheduledService !== criteria.isScheduledService) { return false; } return true; }) .map(mode => mode.modeName); } } exports.Mode = Mode; // Static metadata for API documentation Mode.API_NAME = 'Mode API'; Mode.DESCRIPTION = 'Transport mode information and arrivals'; Mode.ENDPOINTS = { getActiveServiceTypes: '/Mode/ActiveServiceTypes', getArrivals: '/Mode/{mode}/Arrivals' };