gtfs 4.17.2 → 4.17.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/gtfs-export.js +859 -11
- package/dist/bin/gtfs-export.js.map +1 -1
- package/dist/bin/gtfs-import.js +985 -168
- package/dist/bin/gtfs-import.js.map +1 -1
- package/dist/bin/gtfsrealtime-update.js +9 -4
- package/dist/bin/gtfsrealtime-update.js.map +1 -1
- package/dist/index.js +1006 -179
- package/dist/index.js.map +1 -1
- package/dist/models/models.d.ts +312 -8
- package/dist/models/models.js +846 -1
- package/dist/models/models.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/lib/import-gtfs.ts
|
|
8
|
-
import
|
|
9
|
-
import { createReadStream, existsSync, lstatSync } from "
|
|
10
|
-
import { cp, readdir, rename, readFile as readFile2, rm as rm2, writeFile } from "
|
|
8
|
+
import path2 from "path";
|
|
9
|
+
import { createReadStream, existsSync as existsSync2, lstatSync } from "fs";
|
|
10
|
+
import { cp, readdir, rename, readFile as readFile2, rm as rm2, writeFile } from "fs/promises";
|
|
11
11
|
import { parse } from "csv-parse";
|
|
12
12
|
import pluralize2 from "pluralize";
|
|
13
13
|
import stripBomStream from "strip-bom-stream";
|
|
@@ -29,12 +29,14 @@ __export(models_exports, {
|
|
|
29
29
|
calendarDates: () => calendarDates,
|
|
30
30
|
deadheadTimes: () => deadheadTimes,
|
|
31
31
|
deadheads: () => deadheads,
|
|
32
|
+
devices: () => devices,
|
|
32
33
|
directions: () => directions,
|
|
33
34
|
fareAttributes: () => fareAttributes,
|
|
34
35
|
fareLegRules: () => fareLegRules,
|
|
35
36
|
fareMedia: () => fareMedia,
|
|
36
37
|
fareProducts: () => fareProducts,
|
|
37
38
|
fareRules: () => fareRules,
|
|
39
|
+
fareTransactions: () => fareTransactions,
|
|
38
40
|
fareTransferRules: () => fareTransferRules,
|
|
39
41
|
feedInfo: () => feedInfo,
|
|
40
42
|
frequencies: () => frequencies,
|
|
@@ -43,7 +45,9 @@ __export(models_exports, {
|
|
|
43
45
|
locationGroups: () => locationGroups,
|
|
44
46
|
locations: () => locations,
|
|
45
47
|
networks: () => networks,
|
|
48
|
+
operators: () => operators,
|
|
46
49
|
opsLocations: () => opsLocations,
|
|
50
|
+
passengerEvents: () => passengerEvents,
|
|
47
51
|
pathways: () => pathways,
|
|
48
52
|
rideFeedInfo: () => rideFeedInfo,
|
|
49
53
|
riderCategories: () => riderCategories,
|
|
@@ -57,10 +61,12 @@ __export(models_exports, {
|
|
|
57
61
|
serviceAlertInformedEntities: () => serviceAlertInformedEntities,
|
|
58
62
|
serviceAlerts: () => serviceAlerts,
|
|
59
63
|
shapes: () => shapes,
|
|
64
|
+
stationActivities: () => stationActivities,
|
|
60
65
|
stopAreas: () => stopAreas,
|
|
61
66
|
stopAttributes: () => stopAttributes,
|
|
62
67
|
stopTimeUpdates: () => stopTimeUpdates,
|
|
63
68
|
stopTimes: () => stopTimes,
|
|
69
|
+
stopVisits: () => stopVisits,
|
|
64
70
|
stops: () => stops,
|
|
65
71
|
timeframes: () => timeframes,
|
|
66
72
|
timetableNotes: () => timetableNotes,
|
|
@@ -68,13 +74,18 @@ __export(models_exports, {
|
|
|
68
74
|
timetablePages: () => timetablePages,
|
|
69
75
|
timetableStopOrder: () => timetableStopOrder,
|
|
70
76
|
timetables: () => timetables,
|
|
77
|
+
trainCars: () => trainCars,
|
|
71
78
|
transfers: () => transfers,
|
|
72
79
|
translations: () => translations,
|
|
73
80
|
tripCapacity: () => tripCapacity,
|
|
74
81
|
tripUpdates: () => tripUpdates,
|
|
75
82
|
trips: () => trips,
|
|
76
83
|
tripsDatedVehicleJourney: () => tripsDatedVehicleJourney,
|
|
77
|
-
|
|
84
|
+
tripsPerformed: () => tripsPerformed,
|
|
85
|
+
vehicleLocations: () => vehicleLocations,
|
|
86
|
+
vehiclePositions: () => vehiclePositions,
|
|
87
|
+
vehicleTrainCars: () => vehicleTrainCars,
|
|
88
|
+
vehicles: () => vehicles
|
|
78
89
|
});
|
|
79
90
|
|
|
80
91
|
// src/models/gtfs/agency.ts
|
|
@@ -548,6 +559,7 @@ var fareProducts = {
|
|
|
548
559
|
{
|
|
549
560
|
name: "rider_category_id",
|
|
550
561
|
type: "text",
|
|
562
|
+
primary: true,
|
|
551
563
|
prefix: true
|
|
552
564
|
},
|
|
553
565
|
{
|
|
@@ -3122,143 +3134,978 @@ var runsPieces = {
|
|
|
3122
3134
|
]
|
|
3123
3135
|
};
|
|
3124
3136
|
|
|
3125
|
-
// src/
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
}
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
throw new Error(
|
|
3166
|
-
"No database connection. Call `openDb(config)` before using any methods."
|
|
3167
|
-
);
|
|
3168
|
-
}
|
|
3169
|
-
if (!db) {
|
|
3170
|
-
if (Object.keys(dbs).length > 1) {
|
|
3171
|
-
throw new Error(
|
|
3172
|
-
"Multiple database connections. Pass the db you want to close as a parameter to `closeDb`."
|
|
3173
|
-
);
|
|
3174
|
-
}
|
|
3175
|
-
db = dbs[Object.keys(dbs)[0]];
|
|
3176
|
-
}
|
|
3177
|
-
db.close();
|
|
3178
|
-
delete dbs[db.name];
|
|
3179
|
-
}
|
|
3180
|
-
function deleteDb(db = null) {
|
|
3181
|
-
if (Object.keys(dbs).length === 0) {
|
|
3182
|
-
throw new Error(
|
|
3183
|
-
"No database connection. Call `openDb(config)` before using any methods."
|
|
3184
|
-
);
|
|
3185
|
-
}
|
|
3186
|
-
if (!db) {
|
|
3187
|
-
if (Object.keys(dbs).length > 1) {
|
|
3188
|
-
throw new Error(
|
|
3189
|
-
"Multiple database connections. Pass the db you want to delete as a parameter to `deleteDb`."
|
|
3190
|
-
);
|
|
3137
|
+
// src/models/tides/devices.ts
|
|
3138
|
+
var devices = {
|
|
3139
|
+
filenameBase: "devices",
|
|
3140
|
+
filenameExtension: "txt",
|
|
3141
|
+
nonstandard: true,
|
|
3142
|
+
extension: "tides",
|
|
3143
|
+
schema: [
|
|
3144
|
+
{
|
|
3145
|
+
name: "device_id",
|
|
3146
|
+
type: "text",
|
|
3147
|
+
required: true,
|
|
3148
|
+
primary: true
|
|
3149
|
+
},
|
|
3150
|
+
{
|
|
3151
|
+
name: "stop_id",
|
|
3152
|
+
type: "text"
|
|
3153
|
+
},
|
|
3154
|
+
{
|
|
3155
|
+
name: "vehicle_id",
|
|
3156
|
+
type: "text"
|
|
3157
|
+
},
|
|
3158
|
+
{
|
|
3159
|
+
name: "train_car_id",
|
|
3160
|
+
type: "text"
|
|
3161
|
+
},
|
|
3162
|
+
{
|
|
3163
|
+
name: "device_type",
|
|
3164
|
+
type: "text"
|
|
3165
|
+
},
|
|
3166
|
+
{
|
|
3167
|
+
name: "device_vendor",
|
|
3168
|
+
type: "text"
|
|
3169
|
+
},
|
|
3170
|
+
{
|
|
3171
|
+
name: "device_model",
|
|
3172
|
+
type: "text"
|
|
3173
|
+
},
|
|
3174
|
+
{
|
|
3175
|
+
name: "device_location",
|
|
3176
|
+
type: "text"
|
|
3191
3177
|
}
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
db.close();
|
|
3195
|
-
fs.unlinkSync(db.name);
|
|
3196
|
-
delete dbs[db.name];
|
|
3197
|
-
}
|
|
3198
|
-
|
|
3199
|
-
// src/lib/file-utils.ts
|
|
3200
|
-
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
3201
|
-
import { omit, snakeCase } from "lodash-es";
|
|
3202
|
-
import sanitize from "sanitize-filename";
|
|
3203
|
-
import untildify2 from "untildify";
|
|
3204
|
-
import StreamZip from "node-stream-zip";
|
|
3178
|
+
]
|
|
3179
|
+
};
|
|
3205
3180
|
|
|
3206
|
-
// src/
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3181
|
+
// src/models/tides/fare-transactions.ts
|
|
3182
|
+
var fareTransactions = {
|
|
3183
|
+
filenameBase: "fare_transactions",
|
|
3184
|
+
filenameExtension: "txt",
|
|
3185
|
+
nonstandard: true,
|
|
3186
|
+
extension: "tides",
|
|
3187
|
+
schema: [
|
|
3188
|
+
{
|
|
3189
|
+
name: "transaction_id",
|
|
3190
|
+
type: "text",
|
|
3191
|
+
required: true,
|
|
3192
|
+
index: true
|
|
3193
|
+
},
|
|
3194
|
+
{
|
|
3195
|
+
name: "service_date",
|
|
3196
|
+
type: "date",
|
|
3197
|
+
required: true
|
|
3198
|
+
},
|
|
3199
|
+
{
|
|
3200
|
+
name: "event_timestamp",
|
|
3201
|
+
type: "text",
|
|
3202
|
+
required: true
|
|
3203
|
+
},
|
|
3204
|
+
{
|
|
3205
|
+
name: "location_ping_id",
|
|
3206
|
+
type: "text"
|
|
3207
|
+
},
|
|
3208
|
+
{
|
|
3209
|
+
name: "amount",
|
|
3210
|
+
type: "real",
|
|
3211
|
+
required: true
|
|
3212
|
+
},
|
|
3213
|
+
{
|
|
3214
|
+
name: "currency_type",
|
|
3215
|
+
type: "text"
|
|
3216
|
+
},
|
|
3217
|
+
{
|
|
3218
|
+
name: "fare_action",
|
|
3219
|
+
type: "text",
|
|
3220
|
+
required: true
|
|
3221
|
+
},
|
|
3222
|
+
{
|
|
3223
|
+
name: "trip_id_performed",
|
|
3224
|
+
type: "text"
|
|
3225
|
+
},
|
|
3226
|
+
{
|
|
3227
|
+
name: "trip_id_scheduled",
|
|
3228
|
+
type: "text"
|
|
3229
|
+
},
|
|
3230
|
+
{
|
|
3231
|
+
name: "pattern_id",
|
|
3232
|
+
type: "text"
|
|
3233
|
+
},
|
|
3234
|
+
{
|
|
3235
|
+
name: "trip_stop_sequence",
|
|
3236
|
+
type: "integer",
|
|
3237
|
+
min: 1
|
|
3238
|
+
},
|
|
3239
|
+
{
|
|
3240
|
+
name: "scheduled_stop_sequence",
|
|
3241
|
+
type: "integer",
|
|
3242
|
+
min: 0
|
|
3243
|
+
},
|
|
3244
|
+
{
|
|
3245
|
+
name: "vehicle_id",
|
|
3246
|
+
type: "text"
|
|
3247
|
+
},
|
|
3248
|
+
{
|
|
3249
|
+
name: "device_id",
|
|
3250
|
+
type: "text"
|
|
3251
|
+
},
|
|
3252
|
+
{
|
|
3253
|
+
name: "fare_id",
|
|
3254
|
+
type: "text"
|
|
3255
|
+
},
|
|
3256
|
+
{
|
|
3257
|
+
name: "stop_id",
|
|
3258
|
+
type: "text"
|
|
3259
|
+
},
|
|
3260
|
+
{
|
|
3261
|
+
name: "num_riders",
|
|
3262
|
+
type: "integer",
|
|
3263
|
+
min: 0
|
|
3264
|
+
},
|
|
3265
|
+
{
|
|
3266
|
+
name: "fare_media_id",
|
|
3267
|
+
type: "text"
|
|
3268
|
+
},
|
|
3269
|
+
{
|
|
3270
|
+
name: "rider_category",
|
|
3271
|
+
type: "text"
|
|
3272
|
+
},
|
|
3273
|
+
{
|
|
3274
|
+
name: "fare_product",
|
|
3275
|
+
type: "text"
|
|
3276
|
+
},
|
|
3277
|
+
{
|
|
3278
|
+
name: "fare_period",
|
|
3279
|
+
type: "text"
|
|
3280
|
+
},
|
|
3281
|
+
{
|
|
3282
|
+
name: "fare_capped",
|
|
3283
|
+
type: "text",
|
|
3284
|
+
required: true
|
|
3285
|
+
},
|
|
3286
|
+
{
|
|
3287
|
+
name: "token_id",
|
|
3288
|
+
type: "text"
|
|
3289
|
+
},
|
|
3290
|
+
{
|
|
3291
|
+
name: "balance",
|
|
3292
|
+
type: "real"
|
|
3223
3293
|
}
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
}
|
|
3227
|
-
function logWarning(config) {
|
|
3228
|
-
if (config.logFunction) {
|
|
3229
|
-
return config.logFunction;
|
|
3230
|
-
}
|
|
3231
|
-
return (text) => {
|
|
3232
|
-
process.stdout.write(`
|
|
3233
|
-
${formatWarning(text)}
|
|
3234
|
-
`);
|
|
3235
|
-
};
|
|
3236
|
-
}
|
|
3237
|
-
function logError(config) {
|
|
3238
|
-
if (config.logFunction) {
|
|
3239
|
-
return config.logFunction;
|
|
3240
|
-
}
|
|
3241
|
-
return (text) => {
|
|
3242
|
-
process.stdout.write(`
|
|
3243
|
-
${formatError(text)}
|
|
3244
|
-
`);
|
|
3245
|
-
};
|
|
3246
|
-
}
|
|
3247
|
-
function formatWarning(text) {
|
|
3248
|
-
return colors.yellow(`${colors.underline("Warning")}: ${text}`);
|
|
3249
|
-
}
|
|
3250
|
-
function formatError(error) {
|
|
3251
|
-
const messageText = error instanceof Error ? error.message : error;
|
|
3252
|
-
const cleanMessage = messageText.replace(/^Error:\s*/i, "");
|
|
3253
|
-
return colors.red(`${colors.underline("Error")}: ${cleanMessage}`);
|
|
3254
|
-
}
|
|
3294
|
+
]
|
|
3295
|
+
};
|
|
3255
3296
|
|
|
3256
|
-
// src/
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3297
|
+
// src/models/tides/operators.ts
|
|
3298
|
+
var operators = {
|
|
3299
|
+
filenameBase: "operators",
|
|
3300
|
+
filenameExtension: "txt",
|
|
3301
|
+
nonstandard: true,
|
|
3302
|
+
extension: "tides",
|
|
3303
|
+
schema: [
|
|
3304
|
+
{
|
|
3305
|
+
name: "operator_id",
|
|
3306
|
+
type: "text",
|
|
3307
|
+
required: true,
|
|
3308
|
+
primary: true
|
|
3309
|
+
}
|
|
3310
|
+
]
|
|
3311
|
+
};
|
|
3312
|
+
|
|
3313
|
+
// src/models/tides/passenger-events.ts
|
|
3314
|
+
var passengerEvents = {
|
|
3315
|
+
filenameBase: "passenger_events",
|
|
3316
|
+
filenameExtension: "txt",
|
|
3317
|
+
nonstandard: true,
|
|
3318
|
+
extension: "tides",
|
|
3319
|
+
schema: [
|
|
3320
|
+
{
|
|
3321
|
+
name: "passenger_event_id",
|
|
3322
|
+
type: "text",
|
|
3323
|
+
required: true,
|
|
3324
|
+
index: true
|
|
3325
|
+
},
|
|
3326
|
+
{
|
|
3327
|
+
name: "service_date",
|
|
3328
|
+
type: "date",
|
|
3329
|
+
required: true
|
|
3330
|
+
},
|
|
3331
|
+
{
|
|
3332
|
+
name: "event_timestamp",
|
|
3333
|
+
type: "text",
|
|
3334
|
+
required: true
|
|
3335
|
+
},
|
|
3336
|
+
{
|
|
3337
|
+
name: "location_ping_id",
|
|
3338
|
+
type: "text"
|
|
3339
|
+
},
|
|
3340
|
+
{
|
|
3341
|
+
name: "trip_id_performed",
|
|
3342
|
+
type: "text"
|
|
3343
|
+
},
|
|
3344
|
+
{
|
|
3345
|
+
name: "trip_id_scheduled",
|
|
3346
|
+
type: "text"
|
|
3347
|
+
},
|
|
3348
|
+
{
|
|
3349
|
+
name: "trip_stop_sequence",
|
|
3350
|
+
type: "integer",
|
|
3351
|
+
min: 1
|
|
3352
|
+
},
|
|
3353
|
+
{
|
|
3354
|
+
name: "scheduled_stop_sequence",
|
|
3355
|
+
type: "integer",
|
|
3356
|
+
min: 0
|
|
3357
|
+
},
|
|
3358
|
+
{
|
|
3359
|
+
name: "event_type",
|
|
3360
|
+
type: "text",
|
|
3361
|
+
required: true
|
|
3362
|
+
},
|
|
3363
|
+
{
|
|
3364
|
+
name: "vehicle_id",
|
|
3365
|
+
type: "text",
|
|
3366
|
+
required: true
|
|
3367
|
+
},
|
|
3368
|
+
{
|
|
3369
|
+
name: "device_id",
|
|
3370
|
+
type: "text"
|
|
3371
|
+
},
|
|
3372
|
+
{
|
|
3373
|
+
name: "train_car_id",
|
|
3374
|
+
type: "text"
|
|
3375
|
+
},
|
|
3376
|
+
{
|
|
3377
|
+
name: "stop_id",
|
|
3378
|
+
type: "text"
|
|
3379
|
+
},
|
|
3380
|
+
{
|
|
3381
|
+
name: "pattern_id",
|
|
3382
|
+
type: "text"
|
|
3383
|
+
},
|
|
3384
|
+
{
|
|
3385
|
+
name: "event_count",
|
|
3386
|
+
type: "integer",
|
|
3387
|
+
min: 0
|
|
3388
|
+
}
|
|
3389
|
+
]
|
|
3390
|
+
};
|
|
3391
|
+
|
|
3392
|
+
// src/models/tides/station-activities.ts
|
|
3393
|
+
var stationActivities = {
|
|
3394
|
+
filenameBase: "station_activities",
|
|
3395
|
+
filenameExtension: "txt",
|
|
3396
|
+
nonstandard: true,
|
|
3397
|
+
extension: "tides",
|
|
3398
|
+
schema: [
|
|
3399
|
+
{
|
|
3400
|
+
name: "service_date",
|
|
3401
|
+
type: "date",
|
|
3402
|
+
required: true,
|
|
3403
|
+
primary: true
|
|
3404
|
+
},
|
|
3405
|
+
{
|
|
3406
|
+
name: "stop_id",
|
|
3407
|
+
type: "text",
|
|
3408
|
+
required: true,
|
|
3409
|
+
primary: true
|
|
3410
|
+
},
|
|
3411
|
+
{
|
|
3412
|
+
name: "time_period_start",
|
|
3413
|
+
type: "text",
|
|
3414
|
+
required: true,
|
|
3415
|
+
primary: true
|
|
3416
|
+
},
|
|
3417
|
+
{
|
|
3418
|
+
name: "time_period_end",
|
|
3419
|
+
type: "text",
|
|
3420
|
+
required: true,
|
|
3421
|
+
primary: true
|
|
3422
|
+
},
|
|
3423
|
+
{
|
|
3424
|
+
name: "time_period_category",
|
|
3425
|
+
type: "text"
|
|
3426
|
+
},
|
|
3427
|
+
{
|
|
3428
|
+
name: "total_entries",
|
|
3429
|
+
type: "integer",
|
|
3430
|
+
min: 0
|
|
3431
|
+
},
|
|
3432
|
+
{
|
|
3433
|
+
name: "total_exits",
|
|
3434
|
+
type: "integer",
|
|
3435
|
+
min: 0
|
|
3436
|
+
},
|
|
3437
|
+
{
|
|
3438
|
+
name: "number_of_transactions",
|
|
3439
|
+
type: "integer",
|
|
3440
|
+
min: 0
|
|
3441
|
+
},
|
|
3442
|
+
{
|
|
3443
|
+
name: "bike_entries",
|
|
3444
|
+
type: "integer",
|
|
3445
|
+
min: 0
|
|
3446
|
+
},
|
|
3447
|
+
{
|
|
3448
|
+
name: "bike_exits",
|
|
3449
|
+
type: "integer",
|
|
3450
|
+
min: 0
|
|
3451
|
+
},
|
|
3452
|
+
{
|
|
3453
|
+
name: "ramp_entries",
|
|
3454
|
+
type: "integer",
|
|
3455
|
+
min: 0
|
|
3456
|
+
},
|
|
3457
|
+
{
|
|
3458
|
+
name: "ramp_exits",
|
|
3459
|
+
type: "integer",
|
|
3460
|
+
min: 0
|
|
3461
|
+
}
|
|
3462
|
+
]
|
|
3463
|
+
};
|
|
3464
|
+
|
|
3465
|
+
// src/models/tides/stop-visits.ts
|
|
3466
|
+
var stopVisits = {
|
|
3467
|
+
filenameBase: "stop_visits",
|
|
3468
|
+
filenameExtension: "txt",
|
|
3469
|
+
nonstandard: true,
|
|
3470
|
+
extension: "tides",
|
|
3471
|
+
schema: [
|
|
3472
|
+
{
|
|
3473
|
+
name: "service_date",
|
|
3474
|
+
type: "date",
|
|
3475
|
+
required: true,
|
|
3476
|
+
primary: true
|
|
3477
|
+
},
|
|
3478
|
+
{
|
|
3479
|
+
name: "trip_id_performed",
|
|
3480
|
+
type: "text",
|
|
3481
|
+
required: true,
|
|
3482
|
+
primary: true
|
|
3483
|
+
},
|
|
3484
|
+
{
|
|
3485
|
+
name: "trip_stop_sequence",
|
|
3486
|
+
type: "integer",
|
|
3487
|
+
min: 1,
|
|
3488
|
+
required: true,
|
|
3489
|
+
primary: true
|
|
3490
|
+
},
|
|
3491
|
+
{
|
|
3492
|
+
name: "scheduled_stop_sequence",
|
|
3493
|
+
type: "integer",
|
|
3494
|
+
min: 0
|
|
3495
|
+
},
|
|
3496
|
+
{
|
|
3497
|
+
name: "pattern_id",
|
|
3498
|
+
type: "text"
|
|
3499
|
+
},
|
|
3500
|
+
{
|
|
3501
|
+
name: "vehicle_id",
|
|
3502
|
+
type: "text"
|
|
3503
|
+
},
|
|
3504
|
+
{
|
|
3505
|
+
name: "dwell",
|
|
3506
|
+
type: "integer",
|
|
3507
|
+
min: 0
|
|
3508
|
+
},
|
|
3509
|
+
{
|
|
3510
|
+
name: "stop_id",
|
|
3511
|
+
type: "text"
|
|
3512
|
+
},
|
|
3513
|
+
{
|
|
3514
|
+
name: "timepoint",
|
|
3515
|
+
type: "text"
|
|
3516
|
+
},
|
|
3517
|
+
{
|
|
3518
|
+
name: "schedule_arrival_time",
|
|
3519
|
+
type: "text"
|
|
3520
|
+
},
|
|
3521
|
+
{
|
|
3522
|
+
name: "schedule_departure_time",
|
|
3523
|
+
type: "text"
|
|
3524
|
+
},
|
|
3525
|
+
{
|
|
3526
|
+
name: "actual_arrival_time",
|
|
3527
|
+
type: "text"
|
|
3528
|
+
},
|
|
3529
|
+
{
|
|
3530
|
+
name: "actual_departure_time",
|
|
3531
|
+
type: "text"
|
|
3532
|
+
},
|
|
3533
|
+
{
|
|
3534
|
+
name: "distance",
|
|
3535
|
+
type: "integer",
|
|
3536
|
+
min: 0
|
|
3537
|
+
},
|
|
3538
|
+
{
|
|
3539
|
+
name: "boarding_1",
|
|
3540
|
+
type: "integer",
|
|
3541
|
+
min: 0
|
|
3542
|
+
},
|
|
3543
|
+
{
|
|
3544
|
+
name: "alighting_1",
|
|
3545
|
+
type: "integer",
|
|
3546
|
+
min: 0
|
|
3547
|
+
},
|
|
3548
|
+
{
|
|
3549
|
+
name: "boarding_2",
|
|
3550
|
+
type: "integer",
|
|
3551
|
+
min: 0
|
|
3552
|
+
},
|
|
3553
|
+
{
|
|
3554
|
+
name: "alighting_2",
|
|
3555
|
+
type: "integer",
|
|
3556
|
+
min: 0
|
|
3557
|
+
},
|
|
3558
|
+
{
|
|
3559
|
+
name: "departure_load",
|
|
3560
|
+
type: "integer",
|
|
3561
|
+
min: 0
|
|
3562
|
+
},
|
|
3563
|
+
{
|
|
3564
|
+
name: "door_open",
|
|
3565
|
+
type: "text"
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
name: "door_close",
|
|
3569
|
+
type: "text"
|
|
3570
|
+
},
|
|
3571
|
+
{
|
|
3572
|
+
name: "door_status",
|
|
3573
|
+
type: "text"
|
|
3574
|
+
},
|
|
3575
|
+
{
|
|
3576
|
+
name: "ramp_deployed_time",
|
|
3577
|
+
type: "text"
|
|
3578
|
+
},
|
|
3579
|
+
{
|
|
3580
|
+
name: "ramp_failure",
|
|
3581
|
+
type: "text"
|
|
3582
|
+
},
|
|
3583
|
+
{
|
|
3584
|
+
name: "kneel_deployed_time",
|
|
3585
|
+
type: "integer",
|
|
3586
|
+
min: 0
|
|
3587
|
+
},
|
|
3588
|
+
{
|
|
3589
|
+
name: "lift_deployed_time",
|
|
3590
|
+
type: "integer",
|
|
3591
|
+
min: 0
|
|
3592
|
+
},
|
|
3593
|
+
{
|
|
3594
|
+
name: "bike_rack_deployed",
|
|
3595
|
+
type: "text"
|
|
3596
|
+
},
|
|
3597
|
+
{
|
|
3598
|
+
name: "bike_load",
|
|
3599
|
+
type: "integer",
|
|
3600
|
+
min: 0
|
|
3601
|
+
},
|
|
3602
|
+
{
|
|
3603
|
+
name: "revenue",
|
|
3604
|
+
type: "real"
|
|
3605
|
+
},
|
|
3606
|
+
{
|
|
3607
|
+
name: "number_of_transactions",
|
|
3608
|
+
type: "integer",
|
|
3609
|
+
min: 0
|
|
3610
|
+
},
|
|
3611
|
+
{
|
|
3612
|
+
name: "schedule_relationship",
|
|
3613
|
+
type: "text"
|
|
3614
|
+
}
|
|
3615
|
+
]
|
|
3616
|
+
};
|
|
3617
|
+
|
|
3618
|
+
// src/models/tides/train-cars.ts
|
|
3619
|
+
var trainCars = {
|
|
3620
|
+
filenameBase: "train_cars",
|
|
3621
|
+
filenameExtension: "txt",
|
|
3622
|
+
nonstandard: true,
|
|
3623
|
+
extension: "tides",
|
|
3624
|
+
schema: [
|
|
3625
|
+
{
|
|
3626
|
+
name: "train_car_id",
|
|
3627
|
+
type: "text",
|
|
3628
|
+
required: true,
|
|
3629
|
+
primary: true
|
|
3630
|
+
},
|
|
3631
|
+
{
|
|
3632
|
+
name: "model_name",
|
|
3633
|
+
type: "text"
|
|
3634
|
+
},
|
|
3635
|
+
{
|
|
3636
|
+
name: "facility_name",
|
|
3637
|
+
type: "text"
|
|
3638
|
+
},
|
|
3639
|
+
{
|
|
3640
|
+
name: "capacity_seated",
|
|
3641
|
+
type: "integer",
|
|
3642
|
+
min: 0
|
|
3643
|
+
},
|
|
3644
|
+
{
|
|
3645
|
+
name: "capacity_wheelchair",
|
|
3646
|
+
type: "integer",
|
|
3647
|
+
min: 0
|
|
3648
|
+
},
|
|
3649
|
+
{
|
|
3650
|
+
name: "capacity_bike",
|
|
3651
|
+
type: "integer",
|
|
3652
|
+
min: 0
|
|
3653
|
+
},
|
|
3654
|
+
{
|
|
3655
|
+
name: "bike_rack",
|
|
3656
|
+
type: "text"
|
|
3657
|
+
},
|
|
3658
|
+
{
|
|
3659
|
+
name: "capacity_standing",
|
|
3660
|
+
type: "integer",
|
|
3661
|
+
min: 0
|
|
3662
|
+
},
|
|
3663
|
+
{
|
|
3664
|
+
name: "train_car_type",
|
|
3665
|
+
type: "text"
|
|
3666
|
+
}
|
|
3667
|
+
]
|
|
3668
|
+
};
|
|
3669
|
+
|
|
3670
|
+
// src/models/tides/trips-performed.ts
|
|
3671
|
+
var tripsPerformed = {
|
|
3672
|
+
filenameBase: "trips_performed",
|
|
3673
|
+
filenameExtension: "txt",
|
|
3674
|
+
nonstandard: true,
|
|
3675
|
+
extension: "tides",
|
|
3676
|
+
schema: [
|
|
3677
|
+
{
|
|
3678
|
+
name: "service_date",
|
|
3679
|
+
type: "date",
|
|
3680
|
+
required: true,
|
|
3681
|
+
primary: true
|
|
3682
|
+
},
|
|
3683
|
+
{
|
|
3684
|
+
name: "trip_id_performed",
|
|
3685
|
+
type: "text",
|
|
3686
|
+
required: true,
|
|
3687
|
+
primary: true
|
|
3688
|
+
},
|
|
3689
|
+
{
|
|
3690
|
+
name: "vehicle_id",
|
|
3691
|
+
type: "text",
|
|
3692
|
+
required: true
|
|
3693
|
+
},
|
|
3694
|
+
{
|
|
3695
|
+
name: "trip_id_scheduled",
|
|
3696
|
+
type: "text"
|
|
3697
|
+
},
|
|
3698
|
+
{
|
|
3699
|
+
name: "route_id",
|
|
3700
|
+
type: "text"
|
|
3701
|
+
},
|
|
3702
|
+
{
|
|
3703
|
+
name: "route_type",
|
|
3704
|
+
type: "text"
|
|
3705
|
+
},
|
|
3706
|
+
{
|
|
3707
|
+
name: "ntd_mode",
|
|
3708
|
+
type: "text"
|
|
3709
|
+
},
|
|
3710
|
+
{
|
|
3711
|
+
name: "route_type_agency",
|
|
3712
|
+
type: "text"
|
|
3713
|
+
},
|
|
3714
|
+
{
|
|
3715
|
+
name: "shape_id",
|
|
3716
|
+
type: "text"
|
|
3717
|
+
},
|
|
3718
|
+
{
|
|
3719
|
+
name: "pattern_id",
|
|
3720
|
+
type: "text"
|
|
3721
|
+
},
|
|
3722
|
+
{
|
|
3723
|
+
name: "direction_id",
|
|
3724
|
+
type: "integer",
|
|
3725
|
+
min: 0,
|
|
3726
|
+
max: 1
|
|
3727
|
+
},
|
|
3728
|
+
{
|
|
3729
|
+
name: "operator_id",
|
|
3730
|
+
type: "text"
|
|
3731
|
+
},
|
|
3732
|
+
{
|
|
3733
|
+
name: "block_id",
|
|
3734
|
+
type: "text"
|
|
3735
|
+
},
|
|
3736
|
+
{
|
|
3737
|
+
name: "trip_start_stop_id",
|
|
3738
|
+
type: "text"
|
|
3739
|
+
},
|
|
3740
|
+
{
|
|
3741
|
+
name: "trip_end_stop_id",
|
|
3742
|
+
type: "text"
|
|
3743
|
+
},
|
|
3744
|
+
{
|
|
3745
|
+
name: "schedule_trip_start",
|
|
3746
|
+
type: "text"
|
|
3747
|
+
},
|
|
3748
|
+
{
|
|
3749
|
+
name: "schedule_trip_end",
|
|
3750
|
+
type: "text"
|
|
3751
|
+
},
|
|
3752
|
+
{
|
|
3753
|
+
name: "actual_trip_start",
|
|
3754
|
+
type: "text"
|
|
3755
|
+
},
|
|
3756
|
+
{
|
|
3757
|
+
name: "actual_trip_end",
|
|
3758
|
+
type: "text"
|
|
3759
|
+
},
|
|
3760
|
+
{
|
|
3761
|
+
name: "trip_type",
|
|
3762
|
+
type: "text"
|
|
3763
|
+
},
|
|
3764
|
+
{
|
|
3765
|
+
name: "schedule_relationship",
|
|
3766
|
+
type: "text"
|
|
3767
|
+
}
|
|
3768
|
+
]
|
|
3769
|
+
};
|
|
3770
|
+
|
|
3771
|
+
// src/models/tides/vehicle-train-cars.ts
|
|
3772
|
+
var vehicleTrainCars = {
|
|
3773
|
+
filenameBase: "vehicle_train_cars",
|
|
3774
|
+
filenameExtension: "txt",
|
|
3775
|
+
nonstandard: true,
|
|
3776
|
+
extension: "tides",
|
|
3777
|
+
schema: [
|
|
3778
|
+
{
|
|
3779
|
+
name: "vehicle_id",
|
|
3780
|
+
type: "text",
|
|
3781
|
+
required: true,
|
|
3782
|
+
primary: true
|
|
3783
|
+
},
|
|
3784
|
+
{
|
|
3785
|
+
name: "train_car_id",
|
|
3786
|
+
type: "text",
|
|
3787
|
+
required: true,
|
|
3788
|
+
primary: true
|
|
3789
|
+
},
|
|
3790
|
+
{
|
|
3791
|
+
name: "train_car_order",
|
|
3792
|
+
type: "integer",
|
|
3793
|
+
min: 0
|
|
3794
|
+
},
|
|
3795
|
+
{
|
|
3796
|
+
name: "operator_id",
|
|
3797
|
+
type: "text"
|
|
3798
|
+
}
|
|
3799
|
+
]
|
|
3800
|
+
};
|
|
3801
|
+
|
|
3802
|
+
// src/models/tides/vehicle-locations.ts
|
|
3803
|
+
var vehicleLocations = {
|
|
3804
|
+
filenameBase: "vehicle_locations",
|
|
3805
|
+
filenameExtension: "txt",
|
|
3806
|
+
nonstandard: true,
|
|
3807
|
+
extension: "tides",
|
|
3808
|
+
schema: [
|
|
3809
|
+
{
|
|
3810
|
+
name: "location_ping_id",
|
|
3811
|
+
type: "text",
|
|
3812
|
+
required: true,
|
|
3813
|
+
primary: true
|
|
3814
|
+
},
|
|
3815
|
+
{
|
|
3816
|
+
name: "service_date",
|
|
3817
|
+
type: "date"
|
|
3818
|
+
},
|
|
3819
|
+
{
|
|
3820
|
+
name: "event_timestamp",
|
|
3821
|
+
type: "text",
|
|
3822
|
+
required: true
|
|
3823
|
+
},
|
|
3824
|
+
{
|
|
3825
|
+
name: "trip_id_performed",
|
|
3826
|
+
type: "text"
|
|
3827
|
+
},
|
|
3828
|
+
{
|
|
3829
|
+
name: "trip_id_scheduled",
|
|
3830
|
+
type: "text"
|
|
3831
|
+
},
|
|
3832
|
+
{
|
|
3833
|
+
name: "trip_stop_sequence",
|
|
3834
|
+
type: "integer",
|
|
3835
|
+
min: 1
|
|
3836
|
+
},
|
|
3837
|
+
{
|
|
3838
|
+
name: "scheduled_stop_sequence",
|
|
3839
|
+
type: "integer",
|
|
3840
|
+
min: 0
|
|
3841
|
+
},
|
|
3842
|
+
{
|
|
3843
|
+
name: "vehicle_id",
|
|
3844
|
+
type: "text",
|
|
3845
|
+
required: true
|
|
3846
|
+
},
|
|
3847
|
+
{
|
|
3848
|
+
name: "device_id",
|
|
3849
|
+
type: "text"
|
|
3850
|
+
},
|
|
3851
|
+
{
|
|
3852
|
+
name: "pattern_id",
|
|
3853
|
+
type: "text"
|
|
3854
|
+
},
|
|
3855
|
+
{
|
|
3856
|
+
name: "stop_id",
|
|
3857
|
+
type: "text"
|
|
3858
|
+
},
|
|
3859
|
+
{
|
|
3860
|
+
name: "current_status",
|
|
3861
|
+
type: "text"
|
|
3862
|
+
},
|
|
3863
|
+
{
|
|
3864
|
+
name: "latitude",
|
|
3865
|
+
type: "real",
|
|
3866
|
+
min: -90,
|
|
3867
|
+
max: 90
|
|
3868
|
+
},
|
|
3869
|
+
{
|
|
3870
|
+
name: "longitude",
|
|
3871
|
+
type: "real",
|
|
3872
|
+
min: -180,
|
|
3873
|
+
max: 180
|
|
3874
|
+
},
|
|
3875
|
+
{
|
|
3876
|
+
name: "gps_quality",
|
|
3877
|
+
type: "text"
|
|
3878
|
+
},
|
|
3879
|
+
{
|
|
3880
|
+
name: "heading",
|
|
3881
|
+
type: "real",
|
|
3882
|
+
min: 0,
|
|
3883
|
+
max: 360
|
|
3884
|
+
},
|
|
3885
|
+
{
|
|
3886
|
+
name: "speed",
|
|
3887
|
+
type: "real",
|
|
3888
|
+
min: 0
|
|
3889
|
+
},
|
|
3890
|
+
{
|
|
3891
|
+
name: "odometer",
|
|
3892
|
+
type: "real",
|
|
3893
|
+
min: 0
|
|
3894
|
+
},
|
|
3895
|
+
{
|
|
3896
|
+
name: "schedule_deviation",
|
|
3897
|
+
type: "integer"
|
|
3898
|
+
},
|
|
3899
|
+
{
|
|
3900
|
+
name: "headway_deviation",
|
|
3901
|
+
type: "integer"
|
|
3902
|
+
},
|
|
3903
|
+
{
|
|
3904
|
+
name: "trip_type",
|
|
3905
|
+
type: "text"
|
|
3906
|
+
},
|
|
3907
|
+
{
|
|
3908
|
+
name: "schedule_relationship",
|
|
3909
|
+
type: "text"
|
|
3910
|
+
}
|
|
3911
|
+
]
|
|
3912
|
+
};
|
|
3913
|
+
|
|
3914
|
+
// src/models/tides/vehicles.ts
|
|
3915
|
+
var vehicles = {
|
|
3916
|
+
filenameBase: "vehicles",
|
|
3917
|
+
filenameExtension: "txt",
|
|
3918
|
+
nonstandard: true,
|
|
3919
|
+
extension: "tides",
|
|
3920
|
+
schema: [
|
|
3921
|
+
{
|
|
3922
|
+
name: "vehicle_id",
|
|
3923
|
+
type: "text",
|
|
3924
|
+
required: true,
|
|
3925
|
+
primary: true
|
|
3926
|
+
},
|
|
3927
|
+
{
|
|
3928
|
+
name: "vehicle_start",
|
|
3929
|
+
type: "text"
|
|
3930
|
+
},
|
|
3931
|
+
{
|
|
3932
|
+
name: "vehicle_end",
|
|
3933
|
+
type: "text"
|
|
3934
|
+
},
|
|
3935
|
+
{
|
|
3936
|
+
name: "model_name",
|
|
3937
|
+
type: "text"
|
|
3938
|
+
},
|
|
3939
|
+
{
|
|
3940
|
+
name: "facility_name",
|
|
3941
|
+
type: "text"
|
|
3942
|
+
},
|
|
3943
|
+
{
|
|
3944
|
+
name: "capacity_seated",
|
|
3945
|
+
type: "integer",
|
|
3946
|
+
min: 0
|
|
3947
|
+
},
|
|
3948
|
+
{
|
|
3949
|
+
name: "capacity_wheelchair",
|
|
3950
|
+
type: "integer",
|
|
3951
|
+
min: 0
|
|
3952
|
+
},
|
|
3953
|
+
{
|
|
3954
|
+
name: "capacity_bike",
|
|
3955
|
+
type: "integer",
|
|
3956
|
+
min: 0
|
|
3957
|
+
},
|
|
3958
|
+
{
|
|
3959
|
+
name: "bike_rack",
|
|
3960
|
+
type: "text"
|
|
3961
|
+
},
|
|
3962
|
+
{
|
|
3963
|
+
name: "capacity_standing",
|
|
3964
|
+
type: "integer",
|
|
3965
|
+
min: 0
|
|
3966
|
+
}
|
|
3967
|
+
]
|
|
3968
|
+
};
|
|
3969
|
+
|
|
3970
|
+
// src/lib/db.ts
|
|
3971
|
+
import fs from "fs";
|
|
3972
|
+
import Database from "better-sqlite3";
|
|
3973
|
+
import untildify from "untildify";
|
|
3974
|
+
var dbs = {};
|
|
3975
|
+
function setupDb(sqlitePath) {
|
|
3976
|
+
const db = new Database(untildify(sqlitePath));
|
|
3977
|
+
db.pragma("journal_mode = OFF");
|
|
3978
|
+
db.pragma("synchronous = OFF");
|
|
3979
|
+
db.pragma("temp_store = MEMORY");
|
|
3980
|
+
dbs[sqlitePath] = db;
|
|
3981
|
+
return db;
|
|
3982
|
+
}
|
|
3983
|
+
function openDb(config = null) {
|
|
3984
|
+
if (config) {
|
|
3985
|
+
const { sqlitePath = ":memory:", db } = config;
|
|
3986
|
+
if (db) {
|
|
3987
|
+
return db;
|
|
3988
|
+
}
|
|
3989
|
+
if (dbs[sqlitePath]) {
|
|
3990
|
+
return dbs[sqlitePath];
|
|
3991
|
+
}
|
|
3992
|
+
return setupDb(sqlitePath);
|
|
3993
|
+
}
|
|
3994
|
+
if (Object.keys(dbs).length === 0) {
|
|
3995
|
+
return setupDb(":memory:");
|
|
3996
|
+
}
|
|
3997
|
+
if (Object.keys(dbs).length === 1) {
|
|
3998
|
+
const filename = Object.keys(dbs)[0];
|
|
3999
|
+
return dbs[filename];
|
|
4000
|
+
}
|
|
4001
|
+
if (Object.keys(dbs).length > 1) {
|
|
4002
|
+
throw new Error(
|
|
4003
|
+
"Multiple databases open, please specify which one to use."
|
|
4004
|
+
);
|
|
4005
|
+
}
|
|
4006
|
+
throw new Error("Unable to find database connection.");
|
|
4007
|
+
}
|
|
4008
|
+
function closeDb(db = null) {
|
|
4009
|
+
if (Object.keys(dbs).length === 0) {
|
|
4010
|
+
throw new Error(
|
|
4011
|
+
"No database connection. Call `openDb(config)` before using any methods."
|
|
4012
|
+
);
|
|
4013
|
+
}
|
|
4014
|
+
if (!db) {
|
|
4015
|
+
if (Object.keys(dbs).length > 1) {
|
|
4016
|
+
throw new Error(
|
|
4017
|
+
"Multiple database connections. Pass the db you want to close as a parameter to `closeDb`."
|
|
4018
|
+
);
|
|
4019
|
+
}
|
|
4020
|
+
db = dbs[Object.keys(dbs)[0]];
|
|
4021
|
+
}
|
|
4022
|
+
db.close();
|
|
4023
|
+
delete dbs[db.name];
|
|
4024
|
+
}
|
|
4025
|
+
function deleteDb(db = null) {
|
|
4026
|
+
if (Object.keys(dbs).length === 0) {
|
|
4027
|
+
throw new Error(
|
|
4028
|
+
"No database connection. Call `openDb(config)` before using any methods."
|
|
4029
|
+
);
|
|
4030
|
+
}
|
|
4031
|
+
if (!db) {
|
|
4032
|
+
if (Object.keys(dbs).length > 1) {
|
|
4033
|
+
throw new Error(
|
|
4034
|
+
"Multiple database connections. Pass the db you want to delete as a parameter to `deleteDb`."
|
|
4035
|
+
);
|
|
4036
|
+
}
|
|
4037
|
+
db = dbs[Object.keys(dbs)[0]];
|
|
4038
|
+
}
|
|
4039
|
+
db.close();
|
|
4040
|
+
fs.unlinkSync(db.name);
|
|
4041
|
+
delete dbs[db.name];
|
|
4042
|
+
}
|
|
4043
|
+
|
|
4044
|
+
// src/lib/file-utils.ts
|
|
4045
|
+
import path from "path";
|
|
4046
|
+
import { existsSync } from "fs";
|
|
4047
|
+
import { mkdir, readFile, rm } from "fs/promises";
|
|
4048
|
+
import { omit, snakeCase } from "lodash-es";
|
|
4049
|
+
import sanitize from "sanitize-filename";
|
|
4050
|
+
import untildify2 from "untildify";
|
|
4051
|
+
import StreamZip from "node-stream-zip";
|
|
4052
|
+
|
|
4053
|
+
// src/lib/log-utils.ts
|
|
4054
|
+
import { clearLine, cursorTo } from "readline";
|
|
4055
|
+
import { noop } from "lodash-es";
|
|
4056
|
+
import * as colors from "yoctocolors";
|
|
4057
|
+
function log(config) {
|
|
4058
|
+
if (config.verbose === false) {
|
|
4059
|
+
return noop;
|
|
4060
|
+
}
|
|
4061
|
+
if (config.logFunction) {
|
|
4062
|
+
return config.logFunction;
|
|
4063
|
+
}
|
|
4064
|
+
return (text, overwrite = false) => {
|
|
4065
|
+
if (overwrite && process.stdout.isTTY) {
|
|
4066
|
+
clearLine(process.stdout, 0);
|
|
4067
|
+
cursorTo(process.stdout, 0);
|
|
4068
|
+
} else {
|
|
4069
|
+
process.stdout.write("\n");
|
|
4070
|
+
}
|
|
4071
|
+
process.stdout.write(text);
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
function logWarning(config) {
|
|
4075
|
+
if (config.logFunction) {
|
|
4076
|
+
return config.logFunction;
|
|
4077
|
+
}
|
|
4078
|
+
return (text) => {
|
|
4079
|
+
process.stdout.write(`
|
|
4080
|
+
${formatWarning(text)}
|
|
4081
|
+
`);
|
|
4082
|
+
};
|
|
4083
|
+
}
|
|
4084
|
+
function logError(config) {
|
|
4085
|
+
if (config.logFunction) {
|
|
4086
|
+
return config.logFunction;
|
|
4087
|
+
}
|
|
4088
|
+
return (text) => {
|
|
4089
|
+
process.stdout.write(`
|
|
4090
|
+
${formatError(text)}
|
|
4091
|
+
`);
|
|
4092
|
+
};
|
|
4093
|
+
}
|
|
4094
|
+
function formatWarning(text) {
|
|
4095
|
+
return colors.yellow(`${colors.underline("Warning")}: ${text}`);
|
|
4096
|
+
}
|
|
4097
|
+
function formatError(error) {
|
|
4098
|
+
const messageText = error instanceof Error ? error.message : error;
|
|
4099
|
+
const cleanMessage = messageText.replace(/^Error:\s*/i, "");
|
|
4100
|
+
return colors.red(`${colors.underline("Error")}: ${cleanMessage}`);
|
|
4101
|
+
}
|
|
4102
|
+
|
|
4103
|
+
// src/lib/file-utils.ts
|
|
4104
|
+
async function prepDirectory(exportPath) {
|
|
4105
|
+
await rm(exportPath, { recursive: true, force: true });
|
|
4106
|
+
await mkdir(exportPath, { recursive: true });
|
|
4107
|
+
}
|
|
4108
|
+
async function unzip(zipfilePath, exportPath) {
|
|
3262
4109
|
try {
|
|
3263
4110
|
const zip = new StreamZip.async({ file: zipfilePath });
|
|
3264
4111
|
await zip.extract(null, exportPath);
|
|
@@ -3850,18 +4697,6 @@ async function updateGtfsRealtime(initialConfig) {
|
|
|
3850
4697
|
}
|
|
3851
4698
|
|
|
3852
4699
|
// src/lib/import-gtfs.ts
|
|
3853
|
-
var timeCache = {};
|
|
3854
|
-
var formatAndCacheTime = (value) => {
|
|
3855
|
-
const cached = timeCache[value];
|
|
3856
|
-
if (cached !== void 0) {
|
|
3857
|
-
return cached;
|
|
3858
|
-
}
|
|
3859
|
-
const timeAsSecondsFromMidnight = calculateSecondsFromMidnight(value);
|
|
3860
|
-
const timeAsString = padLeadingZeros(value);
|
|
3861
|
-
const computed = [timeAsSecondsFromMidnight, timeAsString];
|
|
3862
|
-
timeCache[value] = computed;
|
|
3863
|
-
return computed;
|
|
3864
|
-
};
|
|
3865
4700
|
var getTextFiles = async (folderPath) => {
|
|
3866
4701
|
const files = await readdir(folderPath);
|
|
3867
4702
|
return files.filter((filename) => filename.slice(-3) === "txt");
|
|
@@ -3892,13 +4727,13 @@ var extractGtfsFiles = async (task) => {
|
|
|
3892
4727
|
}
|
|
3893
4728
|
const gtfsPath = untildify3(task.path);
|
|
3894
4729
|
task.log(`Importing GTFS from ${task.path}\r`);
|
|
3895
|
-
if (
|
|
4730
|
+
if (path2.extname(gtfsPath) === ".zip") {
|
|
3896
4731
|
try {
|
|
3897
4732
|
await unzip(gtfsPath, task.downloadDir);
|
|
3898
4733
|
const textFiles = await getTextFiles(task.downloadDir);
|
|
3899
4734
|
if (textFiles.length === 0) {
|
|
3900
4735
|
const files = await readdir(task.downloadDir);
|
|
3901
|
-
const folders = files.filter((filename) => !["__MACOSX"].includes(filename)).map((filename) =>
|
|
4736
|
+
const folders = files.filter((filename) => !["__MACOSX"].includes(filename)).map((filename) => path2.join(task.downloadDir, filename)).filter((source) => lstatSync(source).isDirectory());
|
|
3902
4737
|
if (folders.length > 1) {
|
|
3903
4738
|
throw new Error(
|
|
3904
4739
|
`More than one subfolder found in zip file at \`${task.path}\`. Ensure that .txt files are in the top level of the zip file, or in a single subdirectory.`
|
|
@@ -3918,8 +4753,8 @@ var extractGtfsFiles = async (task) => {
|
|
|
3918
4753
|
await Promise.all(
|
|
3919
4754
|
directoryTextFiles.map(
|
|
3920
4755
|
async (fileName) => rename(
|
|
3921
|
-
|
|
3922
|
-
|
|
4756
|
+
path2.join(subfolderName, fileName),
|
|
4757
|
+
path2.join(task.downloadDir, fileName)
|
|
3923
4758
|
)
|
|
3924
4759
|
)
|
|
3925
4760
|
);
|
|
@@ -3973,7 +4808,16 @@ var createGtfsTables = (db) => {
|
|
|
3973
4808
|
);
|
|
3974
4809
|
if (column.type === "time") {
|
|
3975
4810
|
sqlColumnCreateStatements.push(
|
|
3976
|
-
`${getTimestampColumnName(column.name)} INTEGER
|
|
4811
|
+
`${getTimestampColumnName(column.name)} INTEGER GENERATED ALWAYS AS (
|
|
4812
|
+
CASE
|
|
4813
|
+
WHEN ${column.name} IS NULL OR ${column.name} = '' THEN NULL
|
|
4814
|
+
ELSE CAST(
|
|
4815
|
+
substr(${column.name}, 1, instr(${column.name}, ':') - 1) * 3600 +
|
|
4816
|
+
substr(${column.name}, instr(${column.name}, ':') + 1, 2) * 60 +
|
|
4817
|
+
substr(${column.name}, -2) AS INTEGER
|
|
4818
|
+
)
|
|
4819
|
+
END
|
|
4820
|
+
) STORED`
|
|
3977
4821
|
);
|
|
3978
4822
|
}
|
|
3979
4823
|
}
|
|
@@ -4018,9 +4862,6 @@ var formatGtfsLine = (line, model, totalLineCount) => {
|
|
|
4018
4862
|
let value = line[name];
|
|
4019
4863
|
if (value === "" || value === void 0 || value === null) {
|
|
4020
4864
|
formattedLine[name] = null;
|
|
4021
|
-
if (type === "time") {
|
|
4022
|
-
formattedLine[getTimestampColumnName(name)] = null;
|
|
4023
|
-
}
|
|
4024
4865
|
if (required) {
|
|
4025
4866
|
throw new Error(
|
|
4026
4867
|
`Missing required value in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
|
|
@@ -4036,9 +4877,7 @@ var formatGtfsLine = (line, model, totalLineCount) => {
|
|
|
4036
4877
|
);
|
|
4037
4878
|
}
|
|
4038
4879
|
} else if (type === "time") {
|
|
4039
|
-
|
|
4040
|
-
value = timeAsString;
|
|
4041
|
-
formattedLine[getTimestampColumnName(name)] = timeAsSecondsFromMidnight ?? null;
|
|
4880
|
+
value = padLeadingZeros(value);
|
|
4042
4881
|
}
|
|
4043
4882
|
if (type === "json") {
|
|
4044
4883
|
value = JSON.stringify(value);
|
|
@@ -4062,8 +4901,8 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
4062
4901
|
resolve();
|
|
4063
4902
|
return;
|
|
4064
4903
|
}
|
|
4065
|
-
const filepath =
|
|
4066
|
-
if (!
|
|
4904
|
+
const filepath = path2.join(task.downloadDir, `${filename}`);
|
|
4905
|
+
if (!existsSync2(filepath)) {
|
|
4067
4906
|
if (!model.nonstandard) {
|
|
4068
4907
|
task.log(`Importing - ${filename} - No file found\r`);
|
|
4069
4908
|
}
|
|
@@ -4071,19 +4910,7 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
4071
4910
|
return;
|
|
4072
4911
|
}
|
|
4073
4912
|
task.log(`Importing - ${filename}\r`);
|
|
4074
|
-
const columns = model.schema
|
|
4075
|
-
if (column.type === "time") {
|
|
4076
|
-
return [
|
|
4077
|
-
column,
|
|
4078
|
-
{
|
|
4079
|
-
name: getTimestampColumnName(column.name),
|
|
4080
|
-
type: "integer",
|
|
4081
|
-
index: true
|
|
4082
|
-
}
|
|
4083
|
-
];
|
|
4084
|
-
}
|
|
4085
|
-
return column;
|
|
4086
|
-
});
|
|
4913
|
+
const columns = model.schema;
|
|
4087
4914
|
const prefixedColumns = new Set(
|
|
4088
4915
|
columns.filter((column) => column.prefix).map((column) => column.name)
|
|
4089
4916
|
);
|
|
@@ -4268,8 +5095,8 @@ async function importGtfs(initialConfig) {
|
|
|
4268
5095
|
}
|
|
4269
5096
|
|
|
4270
5097
|
// src/lib/export.ts
|
|
4271
|
-
import
|
|
4272
|
-
import { writeFile as writeFile2 } from "
|
|
5098
|
+
import path3 from "path";
|
|
5099
|
+
import { writeFile as writeFile2 } from "fs/promises";
|
|
4273
5100
|
import { without, compact as compact2 } from "lodash-es";
|
|
4274
5101
|
import pluralize3 from "pluralize";
|
|
4275
5102
|
import { stringify } from "csv-stringify";
|
|
@@ -4312,7 +5139,7 @@ var exportGtfs = async (initialConfig) => {
|
|
|
4312
5139
|
)} using SQLite database at ${config.sqlitePath}`
|
|
4313
5140
|
);
|
|
4314
5141
|
const folderName = generateFolderName(agencies[0].agency_name);
|
|
4315
|
-
const defaultExportPath =
|
|
5142
|
+
const defaultExportPath = path3.join(process.cwd(), "gtfs-export", folderName);
|
|
4316
5143
|
const exportPath = untildify4(config.exportPath || defaultExportPath);
|
|
4317
5144
|
await prepDirectory(exportPath);
|
|
4318
5145
|
const modelsToExport = Object.values(models_exports).filter(
|
|
@@ -4321,7 +5148,7 @@ var exportGtfs = async (initialConfig) => {
|
|
|
4321
5148
|
const exportedFiles = await mapSeries3(
|
|
4322
5149
|
modelsToExport,
|
|
4323
5150
|
async (model) => {
|
|
4324
|
-
const filePath =
|
|
5151
|
+
const filePath = path3.join(
|
|
4325
5152
|
exportPath,
|
|
4326
5153
|
`${model.filenameBase}.${model.filenameExtension}`
|
|
4327
5154
|
);
|