railkit 4.0.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/.claude/settings.local.json +10 -0
- package/README.md +775 -0
- package/index.d.ts +116 -0
- package/index.obfuscated.js +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
# RailKit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/irctc-connect)
|
|
4
|
+
[](https://www.npmjs.com/package/irctc-connect)
|
|
5
|
+
[](https://github.com/RAJIV81205/irctc-connect/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
<img width="1536" height="657" alt="IRCTC Connect Banner" src="https://github.com/user-attachments/assets/39c770a2-639c-443c-93b6-4e78889e78b0" />
|
|
8
|
+
|
|
9
|
+
A comprehensive Node.js SDK for Indian Railways. Get real-time PNR status, train information, live tracking, station updates, train search, and seat availability — all through a single, clean API.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
- 🎫 **PNR Status** — Real-time PNR status with full passenger details
|
|
16
|
+
- 🚂 **Train Information** — Complete train details with station-by-station route
|
|
17
|
+
- 📍 **Live Train Tracking** — Real-time position and delay info for any train
|
|
18
|
+
- 🚉 **Live Station Board** — Upcoming trains at any station right now
|
|
19
|
+
- 🔍 **Train Search** — Find all direct trains between two stations
|
|
20
|
+
- 💺 **Seat Availability** — Check availability and fare for any class and quota
|
|
21
|
+
- 💰 **Fare Lookup** — Full fare breakdown for any train, class, and quota
|
|
22
|
+
- ⚡ **Fast & Reliable** — Built-in timeout handling, input validation, and caching
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 📦 Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install irctc-connect
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🔑 Getting an API Key
|
|
35
|
+
|
|
36
|
+
1. Visit **[irctc.rajivdubey.dev](https://irctc.rajivdubey.dev)**
|
|
37
|
+
2. Sign up and navigate to your Dashboard
|
|
38
|
+
3. Generate an API key from the **API Keys** section
|
|
39
|
+
4. Copy the key — you'll use it in the next step
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 🚀 Quick Start
|
|
44
|
+
|
|
45
|
+
### Step 1 — Add your API key to `.env`
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# .env
|
|
49
|
+
IRCTC_API_KEY=your_api_key_here
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Step 2 — Configure the SDK once at startup
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
import { configure } from 'irctc-connect';
|
|
56
|
+
|
|
57
|
+
configure(process.env.IRCTC_API_KEY);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Call `configure()` **once** at the top of your app before using any other function. It stores your key globally for all subsequent calls.
|
|
61
|
+
|
|
62
|
+
### Step 3 — Use any function
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
import {
|
|
66
|
+
configure,
|
|
67
|
+
checkPNRStatus,
|
|
68
|
+
getTrainInfo,
|
|
69
|
+
trackTrain,
|
|
70
|
+
liveAtStation,
|
|
71
|
+
searchTrainBetweenStations,
|
|
72
|
+
getAvailability,
|
|
73
|
+
fareLookup,
|
|
74
|
+
} from 'irctc-connect';
|
|
75
|
+
|
|
76
|
+
// Configure once
|
|
77
|
+
configure(process.env.IRCTC_API_KEY);
|
|
78
|
+
|
|
79
|
+
// Check PNR status
|
|
80
|
+
const pnrResult = await checkPNRStatus('1234567890');
|
|
81
|
+
|
|
82
|
+
// Get train information
|
|
83
|
+
const trainResult = await getTrainInfo('12301');
|
|
84
|
+
|
|
85
|
+
// Track live train status (date optional, defaults to today)
|
|
86
|
+
const trackResult = await trackTrain('12301', '31-03-2026');
|
|
87
|
+
|
|
88
|
+
// Get live trains at a station
|
|
89
|
+
const stationResult = await liveAtStation('NDLS');
|
|
90
|
+
|
|
91
|
+
// Search trains between stations
|
|
92
|
+
const searchResult = await searchTrainBetweenStations('NDLS', 'BCT');
|
|
93
|
+
|
|
94
|
+
// Get seat availability with fare breakdown
|
|
95
|
+
const availResult = await getAvailability('12496', 'ASN', 'DDU', '27-12-2025', '2A', 'GN');
|
|
96
|
+
|
|
97
|
+
// Get fare for a journey
|
|
98
|
+
const fareResult = await fareLookup('12313', 'ASN', 'NDLS', '06-06-2026', '3A', 'GN');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 📖 API Reference
|
|
104
|
+
|
|
105
|
+
### `configure(apiKey)`
|
|
106
|
+
|
|
107
|
+
Configure the SDK with your API key. **Must be called once before any other function.**
|
|
108
|
+
|
|
109
|
+
| Parameter | Type | Description |
|
|
110
|
+
|-----------|------|-------------|
|
|
111
|
+
| `apiKey` | string | Your API key from the dashboard |
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
import { configure } from 'irctc-connect';
|
|
115
|
+
|
|
116
|
+
configure(process.env.IRCTC_API_KEY);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### 1. `checkPNRStatus(pnr)`
|
|
122
|
+
|
|
123
|
+
Get comprehensive PNR status with passenger details, journey information, chart status, and booking fare.
|
|
124
|
+
|
|
125
|
+
**Parameters:**
|
|
126
|
+
|
|
127
|
+
| Parameter | Type | Description |
|
|
128
|
+
|-----------|------|-------------|
|
|
129
|
+
| `pnr` | string | 10-digit PNR number |
|
|
130
|
+
|
|
131
|
+
**Example:**
|
|
132
|
+
```javascript
|
|
133
|
+
const result = await checkPNRStatus('5827194603');
|
|
134
|
+
|
|
135
|
+
if (result.success) {
|
|
136
|
+
console.log('PNR:', result.data.pnr);
|
|
137
|
+
console.log('Train:', result.data.train.name, `(${result.data.train.number})`);
|
|
138
|
+
console.log('Journey:', `${result.data.journey.source.name} → ${result.data.journey.destination.name}`);
|
|
139
|
+
console.log('Class:', result.data.journey.class, '| Quota:', result.data.journey.quota);
|
|
140
|
+
console.log('Fare:', `₹${result.data.booking.fare}`);
|
|
141
|
+
|
|
142
|
+
result.data.passengers.forEach(p => {
|
|
143
|
+
console.log(`${p.serialNumber}: booking ${p.booking.details} → current ${p.current.details}`);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Response:**
|
|
149
|
+
```javascript
|
|
150
|
+
{
|
|
151
|
+
success: true,
|
|
152
|
+
data: {
|
|
153
|
+
pnr: "5827194603",
|
|
154
|
+
train: {
|
|
155
|
+
number: "12987",
|
|
156
|
+
name: "SAMPURN K RAJDHANI"
|
|
157
|
+
},
|
|
158
|
+
journey: {
|
|
159
|
+
dateOfJourney: "22 Aug 2026, 04:35:00 pm",
|
|
160
|
+
class: "3A",
|
|
161
|
+
quota: "GN",
|
|
162
|
+
source: { code: "JP", name: "JAIPUR JN" },
|
|
163
|
+
destination: { code: "NDLS", name: "NEW DELHI" },
|
|
164
|
+
boardingPoint: { code: "JP", name: "JAIPUR JN" },
|
|
165
|
+
distance: 471,
|
|
166
|
+
arrivalDate: "22 Aug 2026, 10:20:00 pm"
|
|
167
|
+
},
|
|
168
|
+
chart: { status: "Chart Prepared" },
|
|
169
|
+
booking: {
|
|
170
|
+
fare: 1845,
|
|
171
|
+
ticketFare: 1795,
|
|
172
|
+
bookingDate: "20 Aug 2026, 11:14:32 am"
|
|
173
|
+
},
|
|
174
|
+
passengers: [
|
|
175
|
+
{
|
|
176
|
+
serialNumber: "Passenger 1",
|
|
177
|
+
coachPosition: 0,
|
|
178
|
+
booking: {
|
|
179
|
+
status: "CNF",
|
|
180
|
+
coach: "B5",
|
|
181
|
+
berthNo: 22,
|
|
182
|
+
berthCode: "LB",
|
|
183
|
+
details: "CNF/B5/22/LB"
|
|
184
|
+
},
|
|
185
|
+
current: {
|
|
186
|
+
status: "CNF",
|
|
187
|
+
coach: "B5",
|
|
188
|
+
berthNo: 22,
|
|
189
|
+
berthCode: "LB",
|
|
190
|
+
details: "CNF , B5 - 22 [LB]"
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
serialNumber: "Passenger 2",
|
|
195
|
+
coachPosition: 0,
|
|
196
|
+
booking: {
|
|
197
|
+
status: "RAC",
|
|
198
|
+
coach: null,
|
|
199
|
+
berthNo: 7,
|
|
200
|
+
berthCode: null,
|
|
201
|
+
details: "RAC/7"
|
|
202
|
+
},
|
|
203
|
+
current: {
|
|
204
|
+
status: "CNF",
|
|
205
|
+
coach: "B5",
|
|
206
|
+
berthNo: 31,
|
|
207
|
+
berthCode: "UB",
|
|
208
|
+
details: "CNF , B5 - 31 [UB]"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
### 2. `getTrainInfo(trainNumber)`
|
|
219
|
+
|
|
220
|
+
Get detailed train information including complete route with station coordinates.
|
|
221
|
+
|
|
222
|
+
**Parameters:**
|
|
223
|
+
|
|
224
|
+
| Parameter | Type | Description |
|
|
225
|
+
|-----------|------|-------------|
|
|
226
|
+
| `trainNumber` | string | 5-digit train number |
|
|
227
|
+
|
|
228
|
+
**Example:**
|
|
229
|
+
```javascript
|
|
230
|
+
const result = await getTrainInfo('12301');
|
|
231
|
+
|
|
232
|
+
if (result.success) {
|
|
233
|
+
const { trainInfo, route } = result.data;
|
|
234
|
+
|
|
235
|
+
console.log(`🚂 ${trainInfo.train_name} (${trainInfo.train_no})`);
|
|
236
|
+
console.log(`📍 ${trainInfo.from_stn_name} → ${trainInfo.to_stn_name}`);
|
|
237
|
+
console.log(`⏱️ ${trainInfo.from_time} → ${trainInfo.to_time} (${trainInfo.travel_time})`);
|
|
238
|
+
console.log(`📅 Running days: ${trainInfo.running_days}`);
|
|
239
|
+
|
|
240
|
+
route.slice(0, 5).forEach(stn => {
|
|
241
|
+
console.log(` ${stn.stnName} (${stn.stnCode}) — dep: ${stn.departure}`);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Response:**
|
|
247
|
+
```javascript
|
|
248
|
+
{
|
|
249
|
+
success: true,
|
|
250
|
+
data: {
|
|
251
|
+
trainInfo: {
|
|
252
|
+
train_no: "12301",
|
|
253
|
+
train_name: "HOWRAH RAJDHANI",
|
|
254
|
+
from_stn_name: "NEW DELHI",
|
|
255
|
+
from_stn_code: "NDLS",
|
|
256
|
+
to_stn_name: "HOWRAH JN",
|
|
257
|
+
to_stn_code: "HWH",
|
|
258
|
+
from_time: "17:00",
|
|
259
|
+
to_time: "09:55",
|
|
260
|
+
travel_time: "16:55 hrs",
|
|
261
|
+
running_days: "1111111",
|
|
262
|
+
type: "RAJDHANI"
|
|
263
|
+
},
|
|
264
|
+
route: [
|
|
265
|
+
{
|
|
266
|
+
stnCode: "NDLS", stnName: "NEW DELHI",
|
|
267
|
+
arrival: "--", departure: "17:00",
|
|
268
|
+
halt: "0 min", distance: "0", day: "1",
|
|
269
|
+
coordinates: { latitude: 28.6431, longitude: 77.2201 }
|
|
270
|
+
}
|
|
271
|
+
// ... more stations
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### 3. `trackTrain(trainNumber, date?)`
|
|
280
|
+
|
|
281
|
+
Get real-time live status of a train with a unified station timeline (stoppages + intermediate stations in route order).
|
|
282
|
+
|
|
283
|
+
**Parameters:**
|
|
284
|
+
|
|
285
|
+
| Parameter | Type | Description |
|
|
286
|
+
|-----------|------|-------------|
|
|
287
|
+
| `trainNumber` | string | 5-digit train number |
|
|
288
|
+
| `date` | string *(optional)* | Date in `DD-MM-YYYY` format. Defaults to today if omitted. |
|
|
289
|
+
|
|
290
|
+
**Example:**
|
|
291
|
+
```javascript
|
|
292
|
+
const result = await trackTrain('12301', '31-03-2026');
|
|
293
|
+
|
|
294
|
+
if (result.success) {
|
|
295
|
+
const { trainNo, trainName, statusNote, currentStationCode, timeline } = result.data;
|
|
296
|
+
|
|
297
|
+
console.log(`🚂 ${trainName} (${trainNo})`);
|
|
298
|
+
console.log(`📍 Status: ${statusNote}`);
|
|
299
|
+
console.log(`🎯 Current station code: ${currentStationCode}`);
|
|
300
|
+
|
|
301
|
+
timeline.forEach(point => {
|
|
302
|
+
console.log(`\n🚉 ${point.stationName} (${point.stationCode})`);
|
|
303
|
+
console.log(` Type: ${point.type} | Status: ${point.status}`);
|
|
304
|
+
|
|
305
|
+
if (point.type === 'stoppage') {
|
|
306
|
+
console.log(` PF: ${point.platform || '-'}`);
|
|
307
|
+
console.log(` Arr: ${point.arrival.scheduled} → ${point.arrival.actual} ${point.arrival.delay}`);
|
|
308
|
+
console.log(` Dep: ${point.departure.scheduled} → ${point.departure.actual} ${point.departure.delay}`);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Response:**
|
|
315
|
+
```javascript
|
|
316
|
+
{
|
|
317
|
+
success: true,
|
|
318
|
+
data: {
|
|
319
|
+
trainNo: "12301",
|
|
320
|
+
trainName: "HOWRAH RAJDHANI",
|
|
321
|
+
date: "31-Mar-2026",
|
|
322
|
+
statusNote: "Arrived at HOWRAH JN(HWH) — On Time",
|
|
323
|
+
lastUpdate: "31-Mar-2026 10:01",
|
|
324
|
+
totalStations: 8, // stoppage count from source
|
|
325
|
+
currentStationCode: "HWH",
|
|
326
|
+
timeline: [
|
|
327
|
+
{
|
|
328
|
+
type: "stoppage", // stoppage | intermediate
|
|
329
|
+
status: "passed", // passed | current | upcoming
|
|
330
|
+
stationCode: "NDLS", stationName: "NEW DELHI",
|
|
331
|
+
platform: "16", distanceKm: "0",
|
|
332
|
+
arrival: { scheduled: "SRC", actual: "SRC", delay: "" },
|
|
333
|
+
departure: { scheduled: "17:00", actual: "17:00", delay: "On Time" },
|
|
334
|
+
coachPosition: [
|
|
335
|
+
{ type: "ENG", number: "ENG", position: "0" },
|
|
336
|
+
{ type: "3A", number: "B1", position: "5" }
|
|
337
|
+
// ...
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
type: "intermediate",
|
|
342
|
+
status: "current",
|
|
343
|
+
stationCode: "SZM",
|
|
344
|
+
stationName: "SUBZI MANDI"
|
|
345
|
+
}
|
|
346
|
+
// ... more timeline points
|
|
347
|
+
]
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
### 4. `getTrainHistory(trainNumber, journeyDate)`
|
|
355
|
+
|
|
356
|
+
Get the completed journey history of a train for a specific journey date. The backend persists a `TrainHistory` record once a train has reached its destination, including the full station-by-station timeline, per-stop delays, and the final coach position.
|
|
357
|
+
|
|
358
|
+
**Parameters:**
|
|
359
|
+
|
|
360
|
+
| Parameter | Type | Description |
|
|
361
|
+
|-----------|------|-------------|
|
|
362
|
+
| `trainNumber` | string | 5-digit train number |
|
|
363
|
+
| `journeyDate` | string | Journey date in `DD-MM-YYYY` format |
|
|
364
|
+
|
|
365
|
+
**Example:**
|
|
366
|
+
```javascript
|
|
367
|
+
const result = await getTrainHistory('12301', '15-04-2025');
|
|
368
|
+
|
|
369
|
+
if (result.success) {
|
|
370
|
+
const { trainNo, trainName, journeyDate, stations, coachPosition } = result.data;
|
|
371
|
+
|
|
372
|
+
console.log(`🚂 ${trainName} (${trainNo}) — ${journeyDate}`);
|
|
373
|
+
|
|
374
|
+
stations.forEach((stop) => {
|
|
375
|
+
console.log(`\n🚉 ${stop.stationName} (${stop.stationCode})`);
|
|
376
|
+
console.log(` PF: ${stop.platform || '-'}`);
|
|
377
|
+
console.log(` Arr: ${stop.arrival.scheduled} → ${stop.arrival.actual} (${stop.arrival.delay} min)`);
|
|
378
|
+
console.log(` Dep: ${stop.departure.scheduled} → ${stop.departure.actual} (${stop.departure.delay} min)`);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Response:**
|
|
384
|
+
```javascript
|
|
385
|
+
{
|
|
386
|
+
success: true,
|
|
387
|
+
data: {
|
|
388
|
+
historyKey: "12301:15-04-2025",
|
|
389
|
+
trainNo: "12301",
|
|
390
|
+
trainName: "HOWRAH RAJDHANI",
|
|
391
|
+
journeyDate: "15-04-2025",
|
|
392
|
+
sourceStationCode: "NDLS",
|
|
393
|
+
sourceStationName: "NEW DELHI",
|
|
394
|
+
destinationStationCode: "HWH",
|
|
395
|
+
destinationStationName: "HOWRAH JN",
|
|
396
|
+
stations: [
|
|
397
|
+
{
|
|
398
|
+
stationCode: "NDLS",
|
|
399
|
+
stationName: "NEW DELHI",
|
|
400
|
+
platform: "16",
|
|
401
|
+
distanceKm: 0,
|
|
402
|
+
arrival: { scheduled: "SRC", actual: "SRC", delay: 0 },
|
|
403
|
+
departure: { scheduled: "17:00", actual: "17:00", delay: 0 }
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
stationCode: "HWH",
|
|
407
|
+
stationName: "HOWRAH JN",
|
|
408
|
+
platform: "9",
|
|
409
|
+
distanceKm: 1447,
|
|
410
|
+
arrival: { scheduled: "09:55", actual: "09:55", delay: 0 },
|
|
411
|
+
departure: { scheduled: "10:00", actual: "10:00", delay: 0 }
|
|
412
|
+
}
|
|
413
|
+
],
|
|
414
|
+
coachPosition: [
|
|
415
|
+
{ type: "ENG", number: "ENG", position: "0" },
|
|
416
|
+
{ type: "3A", number: "B1", position: "5" }
|
|
417
|
+
],
|
|
418
|
+
lastUpdate: "2025-04-16T10:05:00.000Z"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
> The endpoint returns `404` with `{ success: false, error: "Train history record not found" }` for dates where the train has not yet reached its destination.
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
### 5. `liveAtStation(stnCode, hours?)`
|
|
428
|
+
|
|
429
|
+
Get the list of upcoming and passing trains at a station in real time, with arrival/departure times, delays, and platform info.
|
|
430
|
+
|
|
431
|
+
**Parameters:**
|
|
432
|
+
|
|
433
|
+
| Parameter | Type | Description |
|
|
434
|
+
|-----------|------|-------------|
|
|
435
|
+
| `stnCode` | string | Station code (e.g., `'NDLS'`, `'BCT'`, `'HWH'`) |
|
|
436
|
+
| `hours` | number | Time window — `2`, `4`, or `8` (default `2`) |
|
|
437
|
+
|
|
438
|
+
**Example:**
|
|
439
|
+
```javascript
|
|
440
|
+
const result = await liveAtStation('NDLS', 2);
|
|
441
|
+
|
|
442
|
+
if (result.success) {
|
|
443
|
+
console.log(result.data.summary);
|
|
444
|
+
console.log(`Total trains: ${result.data.totalTrains}`);
|
|
445
|
+
|
|
446
|
+
result.data.trains.forEach(train => {
|
|
447
|
+
console.log(`🚂 ${train.trainNo} — ${train.trainName}`);
|
|
448
|
+
console.log(` 📍 ${train.sourceName} → ${train.destName} | PF ${train.platform}`);
|
|
449
|
+
console.log(` ⏰ Arr ${train.arrival.actual} (scheduled ${train.arrival.scheduled}, delay ${train.arrival.delay}m)`);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
**Response:**
|
|
455
|
+
```javascript
|
|
456
|
+
{
|
|
457
|
+
success: true,
|
|
458
|
+
data: {
|
|
459
|
+
summary: "20 Trains departing from/arriving at NDLS - NEW DELHI. in next 2 Hrs.",
|
|
460
|
+
totalTrains: 2,
|
|
461
|
+
trains: [
|
|
462
|
+
{
|
|
463
|
+
trainNo: "12987",
|
|
464
|
+
trainName: "SAMPURN K RAJDHANI",
|
|
465
|
+
source: "JP",
|
|
466
|
+
sourceName: "JAIPUR JN",
|
|
467
|
+
dest: "NDLS",
|
|
468
|
+
destName: "NEW DELHI",
|
|
469
|
+
trainType: "Rajdhani",
|
|
470
|
+
classes: "1A, 2A, 3A",
|
|
471
|
+
runDate: "22-Aug-2026",
|
|
472
|
+
platform: "9",
|
|
473
|
+
cancelled: false,
|
|
474
|
+
arrival: { actual: "10:18", scheduled: "10:20", delay: 0, delayed: false },
|
|
475
|
+
departure: { actual: "10:25", scheduled: "10:25", delay: 5, delayed: true }
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
trainNo: "12309",
|
|
479
|
+
trainName: "RAJDHANI EXPRESS",
|
|
480
|
+
source: "HWH",
|
|
481
|
+
sourceName: "HOWRAH JN",
|
|
482
|
+
dest: "NDLS",
|
|
483
|
+
destName: "NEW DELHI",
|
|
484
|
+
trainType: "Rajdhani",
|
|
485
|
+
classes: "1A, 2A, 3A",
|
|
486
|
+
runDate: "22-Aug-2026",
|
|
487
|
+
platform: "3",
|
|
488
|
+
cancelled: false,
|
|
489
|
+
arrival: { actual: "11:05", scheduled: "11:00", delay: 5, delayed: true },
|
|
490
|
+
departure: { actual: "11:12", scheduled: "11:10", delay: 2, delayed: true }
|
|
491
|
+
}
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
### 6. `searchTrainBetweenStations(fromStnCode, toStnCode)`
|
|
500
|
+
|
|
501
|
+
Find all direct trains running between two stations.
|
|
502
|
+
|
|
503
|
+
**Parameters:**
|
|
504
|
+
|
|
505
|
+
| Parameter | Type | Description |
|
|
506
|
+
|-----------|------|-------------|
|
|
507
|
+
| `fromStnCode` | string | Origin station code |
|
|
508
|
+
| `toStnCode` | string | Destination station code |
|
|
509
|
+
|
|
510
|
+
**Example:**
|
|
511
|
+
```javascript
|
|
512
|
+
const result = await searchTrainBetweenStations('NDLS', 'BCT');
|
|
513
|
+
|
|
514
|
+
if (result.success) {
|
|
515
|
+
console.log(`Found ${result.data.length} trains\n`);
|
|
516
|
+
|
|
517
|
+
result.data.forEach(train => {
|
|
518
|
+
console.log(`🚂 ${train.train_name} (${train.train_no})`);
|
|
519
|
+
console.log(` 📍 ${train.from_stn_name} → ${train.to_stn_name}`);
|
|
520
|
+
console.log(` ⏰ ${train.from_time} → ${train.to_time} (${train.travel_time})`);
|
|
521
|
+
console.log(` 📏 Distance: ${train.distance} km`);
|
|
522
|
+
console.log(` 📅 Days: ${train.running_days}`);
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Response:**
|
|
528
|
+
```javascript
|
|
529
|
+
{
|
|
530
|
+
success: true,
|
|
531
|
+
data: [
|
|
532
|
+
{
|
|
533
|
+
train_no: "12951",
|
|
534
|
+
train_name: "MUMBAI RAJDHANI",
|
|
535
|
+
source_stn_name: "NEW DELHI",
|
|
536
|
+
source_stn_code: "NDLS",
|
|
537
|
+
dstn_stn_name: "MUMBAI CENTRAL",
|
|
538
|
+
dstn_stn_code: "BCT",
|
|
539
|
+
from_stn_name: "NEW DELHI",
|
|
540
|
+
from_stn_code: "NDLS",
|
|
541
|
+
to_stn_name: "MUMBAI CENTRAL",
|
|
542
|
+
to_stn_code: "BCT",
|
|
543
|
+
from_time: "16:55",
|
|
544
|
+
to_time: "08:35",
|
|
545
|
+
travel_time: "15:40 hrs",
|
|
546
|
+
running_days: "1111111",
|
|
547
|
+
distance: "1384",
|
|
548
|
+
halts: 8
|
|
549
|
+
}
|
|
550
|
+
// ... more trains (sorted by departure time)
|
|
551
|
+
]
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
### 7. `getAvailability(trainNo, fromStnCode, toStnCode, date, coach, quota)`
|
|
558
|
+
|
|
559
|
+
Check seat availability and fare breakdown for a specific train, class, and date.
|
|
560
|
+
|
|
561
|
+
**Parameters:**
|
|
562
|
+
|
|
563
|
+
| Parameter | Type | Description |
|
|
564
|
+
|-----------|------|-------------|
|
|
565
|
+
| `trainNo` | string | 5-digit train number |
|
|
566
|
+
| `fromStnCode` | string | Origin station code (e.g., `'NDLS'`) |
|
|
567
|
+
| `toStnCode` | string | Destination station code (e.g., `'BCT'`) |
|
|
568
|
+
| `date` | string | Journey date in `DD-MM-YYYY` format |
|
|
569
|
+
| `coach` | string | Coach/class code — see [Class & Quota Reference](#-class--quota-reference) |
|
|
570
|
+
| `quota` | string | Quota code — see [Class & Quota Reference](#-class--quota-reference) |
|
|
571
|
+
|
|
572
|
+
**Example:**
|
|
573
|
+
```javascript
|
|
574
|
+
const result = await getAvailability('12301', 'NDLS', 'HWH', '27-12-2025', '3A', 'GN');
|
|
575
|
+
|
|
576
|
+
if (result.success) {
|
|
577
|
+
const { train, fare, availability } = result.data;
|
|
578
|
+
|
|
579
|
+
console.log(`🚂 ${train.trainName} (${train.trainNo})`);
|
|
580
|
+
console.log(`📍 ${train.fromStationName} → ${train.toStationName}`);
|
|
581
|
+
|
|
582
|
+
console.log('\n💰 Fare Breakdown:');
|
|
583
|
+
console.log(` Base Fare: ₹${fare.baseFare}`);
|
|
584
|
+
console.log(` Reservation: ₹${fare.reservationCharge}`);
|
|
585
|
+
console.log(` Superfast: ₹${fare.superfastCharge}`);
|
|
586
|
+
console.log(` Total: ₹${fare.totalFare}`);
|
|
587
|
+
|
|
588
|
+
console.log('\n📅 Availability:');
|
|
589
|
+
availability.forEach(day => {
|
|
590
|
+
console.log(` ${day.date}: ${day.availabilityText} — ${day.prediction}`);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
### 8. `fareLookup(trainNo, fromStnCode, toStnCode, date, travelClass, quota)`
|
|
598
|
+
|
|
599
|
+
Get the full fare breakdown for a journey — base fare, reservation, superfast, catering, GST, dynamic fare, and total.
|
|
600
|
+
|
|
601
|
+
**Parameters:**
|
|
602
|
+
|
|
603
|
+
| Parameter | Type | Description |
|
|
604
|
+
|-----------|------|-------------|
|
|
605
|
+
| `trainNo` | string | 5-digit train number |
|
|
606
|
+
| `fromStnCode` | string | Origin station code (e.g., `'ASN'`) |
|
|
607
|
+
| `toStnCode` | string | Destination station code (e.g., `'NDLS'`) |
|
|
608
|
+
| `date` | string | Journey date in `DD-MM-YYYY` format |
|
|
609
|
+
| `travelClass` | string | See class codes below |
|
|
610
|
+
| `quota` | string | See quota codes below |
|
|
611
|
+
|
|
612
|
+
**Class Codes:** see [Class & Quota Reference](#-class--quota-reference)
|
|
613
|
+
|
|
614
|
+
**Quota Codes:** see [Class & Quota Reference](#-class--quota-reference)
|
|
615
|
+
|
|
616
|
+
**Example:**
|
|
617
|
+
```javascript
|
|
618
|
+
const result = await fareLookup('12313', 'ASN', 'NDLS', '06-06-2026', '3A', 'GN');
|
|
619
|
+
|
|
620
|
+
if (result.success) {
|
|
621
|
+
const d = result.data;
|
|
622
|
+
console.log(`🚂 ${d.trainName} (${d.trainNo})`);
|
|
623
|
+
console.log(`📍 ${d.from} → ${d.to} | ${d.distance} km`);
|
|
624
|
+
console.log(`\n💰 Fare Breakdown:`);
|
|
625
|
+
console.log(` Base Fare: ₹${d.baseFare}`);
|
|
626
|
+
console.log(` Reservation: ₹${d.reservation}`);
|
|
627
|
+
console.log(` Superfast: ₹${d.superfast}`);
|
|
628
|
+
console.log(` Catering: ₹${d.catering}`);
|
|
629
|
+
console.log(` Dynamic Fare: ₹${d.dynamicFare}`);
|
|
630
|
+
console.log(` GST: ₹${d.gst}`);
|
|
631
|
+
console.log(` ─────────────────`);
|
|
632
|
+
console.log(` Total: ₹${d.totalFare}`);
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**Response:**
|
|
637
|
+
```javascript
|
|
638
|
+
{
|
|
639
|
+
success: true,
|
|
640
|
+
data: {
|
|
641
|
+
trainNo: "12313",
|
|
642
|
+
trainName: "RAJDHANI EXPRES",
|
|
643
|
+
from: "ASN",
|
|
644
|
+
to: "NDLS",
|
|
645
|
+
class: "3A",
|
|
646
|
+
distance: 1249,
|
|
647
|
+
baseFare: 1617,
|
|
648
|
+
reservation: 40,
|
|
649
|
+
superfast: 45,
|
|
650
|
+
catering: 310,
|
|
651
|
+
dynamicFare: 647,
|
|
652
|
+
gst: 118,
|
|
653
|
+
totalFare: 2780,
|
|
654
|
+
tatkalFare: 0,
|
|
655
|
+
concession: 0
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
## ⚠️ Error Handling
|
|
663
|
+
|
|
664
|
+
All functions return a consistent response structure. Always check `success` before accessing `data`.
|
|
665
|
+
|
|
666
|
+
```javascript
|
|
667
|
+
// ✅ Success
|
|
668
|
+
{ success: true, data: { /* ... */ } }
|
|
669
|
+
|
|
670
|
+
// ❌ Failure
|
|
671
|
+
{ success: false, error: "Description of what went wrong" }
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Common error scenarios:**
|
|
675
|
+
|
|
676
|
+
| Error | Cause |
|
|
677
|
+
|-------|-------|
|
|
678
|
+
| `irctc-connect is not configured` | `configure()` was not called |
|
|
679
|
+
| `Invalid API key` (401) | Key doesn't exist in the system |
|
|
680
|
+
| `API key is inactive` (403) | Key has been deactivated |
|
|
681
|
+
| `Usage limit exceeded` (429) | Monthly request quota reached |
|
|
682
|
+
| `PNR number must be exactly 10 digits` | Bad input |
|
|
683
|
+
| `Invalid train number` | Train number not 5 digits |
|
|
684
|
+
| `Invalid date format. Use DD-MM-YYYY.` | Wrong date format |
|
|
685
|
+
| `Request timed out` | Upstream service too slow |
|
|
686
|
+
|
|
687
|
+
---
|
|
688
|
+
|
|
689
|
+
## 🛡️ Input Validation
|
|
690
|
+
|
|
691
|
+
The SDK validates inputs locally before making any network call:
|
|
692
|
+
|
|
693
|
+
- **PNR** — must be exactly 10 digits (non-numerics auto-stripped)
|
|
694
|
+
- **Train number** — must be exactly 5 characters
|
|
695
|
+
- **Station codes** — must be uppercase alphabetic, 1–5 chars
|
|
696
|
+
- **Date** — must be `DD-MM-YYYY`, validated for real calendar dates
|
|
697
|
+
- **Coach / Class** — see [Class & Quota Reference](#-class--quota-reference)
|
|
698
|
+
- **Quota** — see [Class & Quota Reference](#-class--quota-reference)
|
|
699
|
+
|
|
700
|
+
---
|
|
701
|
+
|
|
702
|
+
## 📊 PNR Status Codes
|
|
703
|
+
|
|
704
|
+
| Code | Meaning |
|
|
705
|
+
|------|---------|
|
|
706
|
+
| `CNF` | Confirmed |
|
|
707
|
+
| `WL` | Waiting List |
|
|
708
|
+
| `RAC` | Reservation Against Cancellation |
|
|
709
|
+
| `CAN` | Cancelled |
|
|
710
|
+
| `PQWL` | Pooled Quota Waiting List |
|
|
711
|
+
| `TQWL` | Tatkal Quota Waiting List |
|
|
712
|
+
| `GNWL` | General Waiting List |
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## 🚃 Class & Quota Reference
|
|
717
|
+
|
|
718
|
+
Used by both `getAvailability` and `fareLookup`.
|
|
719
|
+
|
|
720
|
+
### Coach / Travel Class
|
|
721
|
+
|
|
722
|
+
| Code | Class | Functions |
|
|
723
|
+
|------|-------|-----------|
|
|
724
|
+
| `SL` | Sleeper Class | both |
|
|
725
|
+
| `2S` | Second Seating | both |
|
|
726
|
+
| `3A` | Third AC | both |
|
|
727
|
+
| `3E` | Third AC Economy | both |
|
|
728
|
+
| `2A` | Second AC | both |
|
|
729
|
+
| `1A` | First AC | both |
|
|
730
|
+
| `CC` | AC Chair Car | both |
|
|
731
|
+
| `EC` | Executive Class | both |
|
|
732
|
+
| `EA` | Executive Anubhuti | `fareLookup` |
|
|
733
|
+
| `FC` | First Class | `fareLookup` |
|
|
734
|
+
| `VS` | Vistadome Non AC | `fareLookup` |
|
|
735
|
+
| `CH` | Chair Car High Capacity | `fareLookup` |
|
|
736
|
+
| `HS` | Sleeper High Capacity | `fareLookup` |
|
|
737
|
+
| `VC` | Vistadome CC | `fareLookup` |
|
|
738
|
+
| `VA` | Vistadome AC | `fareLookup` |
|
|
739
|
+
|
|
740
|
+
### Quota
|
|
741
|
+
|
|
742
|
+
| Code | Quota | Functions |
|
|
743
|
+
|------|-------|-----------|
|
|
744
|
+
| `GN` | General | both |
|
|
745
|
+
| `TQ` | Tatkal | both |
|
|
746
|
+
| `LD` | Ladies | both |
|
|
747
|
+
| `SS` | Senior Citizen | both |
|
|
748
|
+
| `PT` | Premium Tatkal | `fareLookup` |
|
|
749
|
+
| `DF` | Defence | `fareLookup` |
|
|
750
|
+
| `FT` | Foreign Tourist | `fareLookup` |
|
|
751
|
+
| `LB` | Lower Berth | `fareLookup` |
|
|
752
|
+
| `YU` | Yuva | `fareLookup` |
|
|
753
|
+
| `DP` | Duty Pass | `fareLookup` |
|
|
754
|
+
| `HP` | Handicapped | `fareLookup` |
|
|
755
|
+
| `PH` | Parliament House | `fareLookup` |
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
## 🔧 Requirements
|
|
760
|
+
|
|
761
|
+
- Node.js 18+ (native `fetch` required)
|
|
762
|
+
- Internet connection for API calls
|
|
763
|
+
- A valid IRCTC Connect API key
|
|
764
|
+
|
|
765
|
+
---
|
|
766
|
+
|
|
767
|
+
## 🙋 Support
|
|
768
|
+
|
|
769
|
+
- **Issues:** [GitHub Issues](https://github.com/RAJIV81205/irctc-connect/issues)
|
|
770
|
+
- **Docs:** [irctc.rajivdubey.dev/docs](https://irctc.rajivdubey.dev/docs)
|
|
771
|
+
- **Discussions:** [GitHub Discussions](https://github.com/RAJIV81205/irctc-connect/discussions)
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
*Built with ❤️ for Indian Railways enthusiasts. Happy journey! 🚂*
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configure the SDK with your API key before using any other function.
|
|
3
|
+
* The backend URL is managed by the package - you only need your API key.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* configure('your-api-key-here');
|
|
7
|
+
*/
|
|
8
|
+
export function configure(apiKey: string): void;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Check the PNR status for a given 10-digit PNR number.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const result = await checkPNRStatus('1234567890');
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
export function checkPNRStatus(pnr: string): Promise<any>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get detailed information and route for a given 5-digit train number.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const result = await getTrainInfo('12301');
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
export function getTrainInfo(trainNumber: string): Promise<any>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the live running status of a train.
|
|
30
|
+
* @param date - Journey date in DD-MM-YYYY format (optional, defaults to today)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const result = await trackTrain('12301', '15-04-2025');
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
export function trackTrain(trainNumber: string, date?: string): Promise<any>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get the completed journey history of a train for a specific journey date.
|
|
40
|
+
* Returns the persisted TrainHistory record once the train has reached its
|
|
41
|
+
* destination, including the full station-by-station timeline, per-stop delays,
|
|
42
|
+
* and the final coach position.
|
|
43
|
+
*
|
|
44
|
+
* @param trainNumber - 5-digit train number
|
|
45
|
+
* @param journeyDate - Journey date in DD-MM-YYYY format
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const result = await getTrainHistory('12301', '15-04-2025');
|
|
49
|
+
*/
|
|
50
|
+
export function getTrainHistory(trainNumber: string, journeyDate: string): Promise<any>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get the list of upcoming trains at a station.
|
|
54
|
+
* @param stationCode - Station Code (e.g., 'NDLS' for New Delhi)
|
|
55
|
+
* @param hours - Time window in hours: 2, 4, or 8 (default 2)
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const result = await liveAtStation('NDLS', 2);
|
|
59
|
+
*/
|
|
60
|
+
export function liveAtStation(stationCode: string, hours?: 2 | 4 | 8): Promise<any>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Search for all direct trains between two stations.
|
|
64
|
+
* @param fromStnCode - Source station code
|
|
65
|
+
* @param toStnCode - Destination station code
|
|
66
|
+
* @param date - Journey date in DD-MM-YYYY format (optional)
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* const result = await searchTrainBetweenStations('NDLS', 'BCT', '15-04-2025');
|
|
70
|
+
*/
|
|
71
|
+
export function searchTrainBetweenStations(fromStnCode: string, toStnCode: string, date?: string): Promise<any>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Check seat availability for a specific train, class, and date.
|
|
75
|
+
* @param trainNo - 5-digit train number
|
|
76
|
+
* @param fromStnCode - Source station code
|
|
77
|
+
* @param toStnCode - Destination station code
|
|
78
|
+
* @param date - Journey date in DD-MM-YYYY format
|
|
79
|
+
* @param coach - '2S' | 'SL' | '3A' | '3E' | '2A' | '1A' | 'CC' | 'EC'
|
|
80
|
+
* @param quota - 'GN' | 'LD' | 'SS' | 'TQ'
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* const result = await getAvailability('12301', 'NDLS', 'HWH', '15-04-2025', '3A', 'GN');
|
|
84
|
+
*
|
|
85
|
+
*/
|
|
86
|
+
export function getAvailability(
|
|
87
|
+
trainNo: string,
|
|
88
|
+
fromStnCode: string,
|
|
89
|
+
toStnCode: string,
|
|
90
|
+
date: string,
|
|
91
|
+
coach: string,
|
|
92
|
+
quota: string
|
|
93
|
+
): Promise<any>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get the fare breakdown for a train journey.
|
|
97
|
+
* Returns baseFare, reservation, superfast, catering, GST, dynamicFare and totalFare.
|
|
98
|
+
*
|
|
99
|
+
* @param trainNo - 5-digit train number
|
|
100
|
+
* @param fromStnCode - Source station code
|
|
101
|
+
* @param toStnCode - Destination station code
|
|
102
|
+
* @param date - Journey date in DD-MM-YYYY format
|
|
103
|
+
* @param travelClass - '1A' | '2A' | '3A' | '3E' | 'CC' | 'EC' | 'EA' | 'FC' | 'SL' | '2S' | 'VS' | 'CH' | 'HS' | 'VC' | 'VA'
|
|
104
|
+
* @param quota - 'GN' | 'TQ' | 'LD' | 'DF' | 'FT' | 'LB' | 'PT' | 'YU' | 'DP' | 'HP' | 'PH' | 'SS'
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* const result = await fareLookup('12313', 'ASN', 'NDLS', '06-06-2026', '3A', 'GN');
|
|
108
|
+
*/
|
|
109
|
+
export function fareLookup(
|
|
110
|
+
trainNo: string,
|
|
111
|
+
fromStnCode: string,
|
|
112
|
+
toStnCode: string,
|
|
113
|
+
date: string,
|
|
114
|
+
travelClass: string,
|
|
115
|
+
quota: string
|
|
116
|
+
): Promise<any>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a0_0x11c2ee=a0_0x5187;(function(_0x287da6,_0x1d0872){const _0x6f81cf=a0_0x5187,_0x59cea5=_0x287da6();while(!![]){try{const _0x146809=parseInt(_0x6f81cf(0x203))/0x1*(parseInt(_0x6f81cf(0x20c))/0x2)+-parseInt(_0x6f81cf(0x1f7))/0x3+parseInt(_0x6f81cf(0x20e))/0x4+-parseInt(_0x6f81cf(0x21d))/0x5*(parseInt(_0x6f81cf(0x1fa))/0x6)+parseInt(_0x6f81cf(0x211))/0x7+parseInt(_0x6f81cf(0x200))/0x8+parseInt(_0x6f81cf(0x21a))/0x9*(-parseInt(_0x6f81cf(0x214))/0xa);if(_0x146809===_0x1d0872)break;else _0x59cea5['push'](_0x59cea5['shift']());}catch(_0x4ac069){_0x59cea5['push'](_0x59cea5['shift']());}}}(a0_0x148b,0xb087b));import{createHash,createHmac,randomBytes}from'node:crypto';const _baseUrl=a0_0x11c2ee(0x212),_sdkVersion='1',_defaultSdkSigningSecret='97c56e08b27b161124f88acd4f24d1bd50f48075f11dc23b9ea6c0bc9b2f8794';let _apiKey='',_sdkSigningSecret=_defaultSdkSigningSecret;function configure(_0x36ca5e){const _0x336536=a0_0x11c2ee;if(!_0x36ca5e||typeof _0x36ca5e!=='string')throw new Error('[irctc-connect]\x20configure()\x20requires\x20a\x20valid\x20API\x20key\x20string.');_apiKey=_0x36ca5e[_0x336536(0x218)]();}function a0_0x5187(_0x1191e5,_0x4d3da9){_0x1191e5=_0x1191e5-0x1f3;const _0x148b8b=a0_0x148b();let _0x5187fc=_0x148b8b[_0x1191e5];if(a0_0x5187['eQMwOV']===undefined){var _0x517689=function(_0x18d513){const _0x3b6442='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x36ca5e='',_0x3e2880='';for(let _0x21e8db=0x0,_0x322892,_0x12a17b,_0x954c72=0x0;_0x12a17b=_0x18d513['charAt'](_0x954c72++);~_0x12a17b&&(_0x322892=_0x21e8db%0x4?_0x322892*0x40+_0x12a17b:_0x12a17b,_0x21e8db++%0x4)?_0x36ca5e+=String['fromCharCode'](0xff&_0x322892>>(-0x2*_0x21e8db&0x6)):0x0){_0x12a17b=_0x3b6442['indexOf'](_0x12a17b);}for(let _0x2bd8af=0x0,_0x1619d3=_0x36ca5e['length'];_0x2bd8af<_0x1619d3;_0x2bd8af++){_0x3e2880+='%'+('00'+_0x36ca5e['charCodeAt'](_0x2bd8af)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3e2880);};a0_0x5187['trkuZY']=_0x517689,a0_0x5187['FdTZhD']={},a0_0x5187['eQMwOV']=!![];}const _0x46d692=_0x148b8b[0x0],_0x30a334=_0x1191e5+_0x46d692,_0x577ba5=a0_0x5187['FdTZhD'][_0x30a334];return!_0x577ba5?(_0x5187fc=a0_0x5187['trkuZY'](_0x5187fc),a0_0x5187['FdTZhD'][_0x30a334]=_0x5187fc):_0x5187fc=_0x577ba5,_0x5187fc;}function _hashPayload(_0x3e2880){const _0x2fc469=a0_0x11c2ee;return createHash(_0x2fc469(0x20d))['update'](_0x3e2880)[_0x2fc469(0x20f)](_0x2fc469(0x1f3));}function _buildSignature({method:_0x21e8db,path:_0x322892,timestamp:_0x12a17b,nonce:_0x954c72,payloadHash:_0x2bd8af}){const _0x457d89=a0_0x11c2ee,_0x1619d3=[_0x21e8db[_0x457d89(0x209)](),_0x322892,_0x12a17b,_0x954c72,_0x2bd8af,_apiKey][_0x457d89(0x201)]('\x0a');return createHmac(_0x457d89(0x20d),_sdkSigningSecret)[_0x457d89(0x213)](_0x1619d3)[_0x457d89(0x20f)]('hex');}function _getSdkSecurityHeaders(_0x1f4eda,_0xdf8ea3,_0x47513b=''){const _0x18c1be=a0_0x11c2ee,_0xa739e8=String(Date[_0x18c1be(0x1ff)]()),_0x9cdad1=randomBytes(0x20)[_0x18c1be(0x216)]('hex'),_0x46fcc5=_hashPayload(_0x47513b),_0x35fb33=_buildSignature({'method':_0x1f4eda,'path':_0xdf8ea3,'timestamp':_0xa739e8,'nonce':_0x9cdad1,'payloadHash':_0x46fcc5});return{'x-irctc-sdk-ts':_0xa739e8,'x-irctc-sdk-nonce':_0x9cdad1,'x-irctc-sdk-payload-sha256':_0x46fcc5,'x-irctc-sdk-signature':_0x35fb33,'x-irctc-sdk-version':_sdkVersion};}async function _get(_0x4b5371){const _0x436211=a0_0x11c2ee;if(!_apiKey)return{'success':![],'error':_0x436211(0x20b)};try{const _0x5e8a6e=_getSdkSecurityHeaders(_0x436211(0x206),_0x4b5371,''),_0x5e0f39=await fetch(''+_baseUrl+_0x4b5371,{'method':'GET','headers':{'x-api-key':_apiKey,'Accept':_0x436211(0x20a),..._0x5e8a6e}}),_0x83e93a=await _0x5e0f39[_0x436211(0x1f4)]();return _0x83e93a;}catch(_0x5b561b){return{'success':![],'error':_0x436211(0x1f9)+_0x5b561b[_0x436211(0x205)]};}}async function checkPNRStatus(_0x3190ac){const _0x8371a7=a0_0x11c2ee;if(!_0x3190ac||typeof _0x3190ac!==_0x8371a7(0x1f6))return{'success':![],'error':_0x8371a7(0x21c)};const _0x21dcd3=_0x3190ac['trim']()['replace'](/\D/g,'');if(_0x21dcd3[_0x8371a7(0x1fb)]!==0xa)return{'success':![],'error':_0x8371a7(0x204)};return _get(_0x8371a7(0x217)+_0x21dcd3);}async function getTrainInfo(_0x278d77){const _0x5abe2c=a0_0x11c2ee;if(!_0x278d77||typeof _0x278d77!==_0x5abe2c(0x1f6)||_0x278d77[_0x5abe2c(0x218)]()[_0x5abe2c(0x1fb)]!==0x5)return{'success':![],'error':'Invalid\x20train\x20number.\x20It\x20must\x20be\x20a\x205-character\x20string.'};return _get('/api/getTrainInfo/'+_0x278d77[_0x5abe2c(0x218)]());}async function trackTrain(_0x5a12d7,_0x59245c){const _0x5a89b8=a0_0x11c2ee;if(!_0x5a12d7||typeof _0x5a12d7!==_0x5a89b8(0x1f6)||_0x5a12d7[_0x5a89b8(0x218)]()[_0x5a89b8(0x1fb)]!==0x5)return{'success':![],'error':_0x5a89b8(0x1fd)};const _0x5108fb=_0x59245c?_0x5a89b8(0x215)+_0x5a12d7['trim']()+'/'+encodeURIComponent(_0x59245c[_0x5a89b8(0x218)]()):_0x5a89b8(0x215)+_0x5a12d7['trim']()+_0x5a89b8(0x210);return _get(_0x5108fb);}function a0_0x148b(){const _0x222e37=['ntyYnJyYngjMu0fksa','zgLNzxn0','l3rVzgf5','odeYmJeZnunJse9WEq','Ahr0Chm6lY9YywLSA2L0lwfWAs5YywPPDMr1yMv5lMrLDG','DxbKyxrL','mJC1mty4nZb6vxvyC1q','l2fWAs90CMfJA1rYywLUlW','Dg9tDhjPBMC','l2fWAs9JAgvJA1bouLn0yxr1CY8','DhjPBq','l2fWAs90CMfPBKHPC3rVCNKV','ovLMyu5rEa','sM91CM5LEsbKyxrLigLZihjLCxvPCMvKigfUzcbTDxn0igjLigLUierelu1nlvLzwvKGzM9YBwf0lG','ue5sig51BwjLCIbPCYbYzxf1AxjLzcbHBMqGBxvZDcbIzsbHihn0CMLUzY4','oty2nwLjAMfvvG','Agv4','ANnVBG','l2fWAs9ZzwfYy2HuCMfPBKjLDhDLzw5tDgf0Aw9UCY8','C3rYAw5N','mtC2otKYnvjbswzoyW','qM90AcbMCM9TigfUzcb0BYbZDgf0Aw9UignVzgvZigfYzsbYzxf1AxjLzcbHBMqGBxvZDcbIzsbZDhjPBMDZlG','uMvXDwvZDcbMywLSzwq6ia','mJu4nNzIEMzvzq','BgvUz3rO','Aw5JBhvKzxm','sw52ywXPzcb0CMfPBIbUDw1IzxiUieL0ig11C3qGyMuGysa1lwnOyxjHy3rLCIbZDhjPBMCU','p2HYCZ0','BM93','mteXntKZmJHqAhbeBuO','AM9PBG','DgvZDa','murcswrREa','ue5sig51BwjLCIbTDxn0igjLigv4ywn0BhKGmtaGzgLNAxrZlG','BwvZC2fNzq','r0vu','l2fWAs9MyxjLtg9VA3vWlW','sw5JB21WBgv0zsbKyxrHlIbqBgvHC2uGChjVDMLKzsbHBgWGCMvXDwLYzwqGzMLLBgrZlG','Dg9vChbLCKnHC2u','yxbWBgLJyxrPB24VANnVBG','AxjJDgmTy29UBMvJDcbPCYbUB3qGy29UzMLNDxjLzc4Gq2fSBcbJB25MAwD1CMuOyxbPs2v5ksbMAxjZDc4','mtG3mtK1mg13z0TUEq','C2HHmJu2'];a0_0x148b=function(){return _0x222e37;};return a0_0x148b();}async function getTrainHistory(_0x98dcf5,_0x3c9319){const _0x3c2b35=a0_0x11c2ee;if(!_0x98dcf5||typeof _0x98dcf5!==_0x3c2b35(0x1f6)||_0x98dcf5['trim']()['length']!==0x5)return{'success':![],'error':_0x3c2b35(0x1fd)};if(!_0x3c9319||typeof _0x3c9319!==_0x3c2b35(0x1f6)||!/^\d{2}-\d{2}-\d{4}$/[_0x3c2b35(0x202)](_0x3c9319['trim']()))return{'success':![],'error':_0x3c2b35(0x21b)};return _get(_0x3c2b35(0x219)+_0x98dcf5[_0x3c2b35(0x218)]()+'/'+encodeURIComponent(_0x3c9319[_0x3c2b35(0x218)]()));}async function liveAtStation(_0x4694ee,_0x42c4ae){const _0x4af69c=a0_0x11c2ee;if(!_0x4694ee||typeof _0x4694ee!==_0x4af69c(0x1f6))return{'success':![],'error':'Station\x20code\x20is\x20required\x20and\x20must\x20be\x20a\x20string.'};let _0x2e8909='';if(_0x42c4ae!==undefined&&_0x42c4ae!==null){const _0x7b3901=Number(_0x42c4ae);if(![0x2,0x4,0x8][_0x4af69c(0x1fc)](_0x7b3901))return{'success':![],'error':'Invalid\x20\x27hours\x27\x20value.\x20Allowed\x20values:\x202,\x204,\x208.'};_0x2e8909=_0x4af69c(0x1fe)+_0x7b3901;}return _get('/api/liveAtStation/'+_0x4694ee[_0x4af69c(0x218)]()['toUpperCase']()+_0x2e8909);}async function searchTrainBetweenStations(_0x1ca1be,_0x201c3e,_0x1ec638){const _0x553fde=a0_0x11c2ee;if(!_0x1ca1be||typeof _0x1ca1be!==_0x553fde(0x1f6)||!_0x201c3e||typeof _0x201c3e!==_0x553fde(0x1f6)||_0x1ec638&&typeof _0x1ec638!==_0x553fde(0x1f6))return{'success':![],'error':_0x553fde(0x1f8)};let _0x285d91=_0x553fde(0x1f5)+_0x1ca1be[_0x553fde(0x218)]()['toUpperCase']()+'/'+_0x201c3e[_0x553fde(0x218)]()[_0x553fde(0x209)]();return _0x1ec638&&(_0x285d91+='?date='+encodeURIComponent(_0x1ec638[_0x553fde(0x218)]())),_get(_0x285d91);}async function getAvailability(_0x2ff60d,_0x50bddc,_0x588c27,_0x256eb4,_0x15d3cc,_0x358d88){const _0x2f1758=a0_0x11c2ee;if(!_0x2ff60d||!_0x50bddc||!_0x588c27||!_0x256eb4||!_0x15d3cc||!_0x358d88)return{'success':![],'error':_0x2f1758(0x208)};const _0x10589f=_0x50bddc[_0x2f1758(0x218)]()[_0x2f1758(0x209)](),_0x317545=_0x588c27[_0x2f1758(0x218)]()[_0x2f1758(0x209)](),_0x39d99c=_0x15d3cc[_0x2f1758(0x218)]()[_0x2f1758(0x209)](),_0x498cb1=_0x358d88[_0x2f1758(0x218)]()[_0x2f1758(0x209)](),_0x514c6e=_0x2ff60d['trim']();return _get('/api/getAvailability/'+_0x514c6e+'/'+_0x10589f+'/'+_0x317545+'/'+encodeURIComponent(_0x256eb4[_0x2f1758(0x218)]())+'/'+_0x39d99c+'/'+_0x498cb1);}async function fareLookup(_0xd642ea,_0x47c6f9,_0x36e7c7,_0x5bcdf6,_0x398f3d,_0x359adf){const _0x1386d5=a0_0x11c2ee;if(!_0xd642ea||!_0x47c6f9||!_0x36e7c7||!_0x5bcdf6||!_0x398f3d||!_0x359adf)return{'success':![],'error':_0x1386d5(0x208)};const _0x54e1b8=_0x47c6f9[_0x1386d5(0x218)]()[_0x1386d5(0x209)](),_0x3b6cbd=_0x36e7c7['trim']()[_0x1386d5(0x209)](),_0x100ee9=_0x398f3d[_0x1386d5(0x218)]()[_0x1386d5(0x209)](),_0x6cd574=_0x359adf[_0x1386d5(0x218)]()[_0x1386d5(0x209)](),_0x1651fb=_0xd642ea[_0x1386d5(0x218)]();return _get(_0x1386d5(0x207)+_0x1651fb+'/'+encodeURIComponent(_0x5bcdf6[_0x1386d5(0x218)]())+'/'+_0x54e1b8+'/'+_0x3b6cbd+'/'+_0x100ee9+'/'+_0x6cd574);}export{configure,checkPNRStatus,getTrainInfo,trackTrain,getTrainHistory,liveAtStation,searchTrainBetweenStations,getAvailability,fareLookup};
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "railkit",
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"description": "🚂 Complete Node.js SDK for Indian Railways - Check PNR status, train schedules, live running status, seat availability, station information and more. Promise-based API with TypeScript support.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"railkit",
|
|
7
|
+
"railway",
|
|
8
|
+
"indian-railways",
|
|
9
|
+
"irctc",
|
|
10
|
+
"pnr-status",
|
|
11
|
+
"train",
|
|
12
|
+
"train-status",
|
|
13
|
+
"live-train-status",
|
|
14
|
+
"railway-api",
|
|
15
|
+
"railway-sdk",
|
|
16
|
+
"rail-api",
|
|
17
|
+
"train-schedules",
|
|
18
|
+
"station-codes",
|
|
19
|
+
"seat-availability",
|
|
20
|
+
"nodejs",
|
|
21
|
+
"typescript",
|
|
22
|
+
"sdk",
|
|
23
|
+
"api-wrapper",
|
|
24
|
+
"india"
|
|
25
|
+
],
|
|
26
|
+
"homepage": "https://railkit.rajivdubey.dev/",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/RAJIV81205/railkit/issues"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/RAJIV81205/railkit.git"
|
|
33
|
+
},
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"author": "Rajiv Dubey",
|
|
36
|
+
"type": "module",
|
|
37
|
+
"main": "index.obfuscated.js",
|
|
38
|
+
"types": "index.d.ts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./index.d.ts",
|
|
42
|
+
"import": "./index.obfuscated.js",
|
|
43
|
+
"default": "./index.obfuscated.js"
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
49
|
+
"dev": "nodemon index.js",
|
|
50
|
+
"obfuscate": "npx javascript-obfuscator index.js --output index.obfuscated.js --compact true --string-array true --string-array-encoding base64 --rename-globals false --control-flow-flattening false --dead-code-injection false"
|
|
51
|
+
}
|
|
52
|
+
}
|