gtfs 4.13.0 → 4.13.2

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/index.d.ts CHANGED
@@ -43,7 +43,10 @@ declare function updateGtfsRealtime(initialConfig: IConfig): Promise<void>;
43
43
 
44
44
  declare const exportGtfs: (initialConfig: IConfig) => Promise<void>;
45
45
 
46
- declare function openDb(config?: IConfig | null): Database.Database;
46
+ declare function openDb(config?: {
47
+ db?: Database.Database;
48
+ sqlitePath?: string;
49
+ } | null): Database.Database;
47
50
  declare function closeDb(db?: Database.Database | null): void;
48
51
  declare function deleteDb(db?: Database.Database | null): void;
49
52
 
package/dist/index.js CHANGED
@@ -89,8 +89,6 @@ var model3 = {
89
89
  {
90
90
  name: "attribution_id",
91
91
  type: "text",
92
- primary: true,
93
- required: true,
94
92
  prefix: true
95
93
  },
96
94
  {
@@ -257,7 +255,7 @@ var model5 = {
257
255
  },
258
256
  {
259
257
  name: "date",
260
- type: "integer",
258
+ type: "date",
261
259
  required: true,
262
260
  primary: true
263
261
  },
@@ -341,13 +339,13 @@ var model6 = {
341
339
  },
342
340
  {
343
341
  name: "start_date",
344
- type: "integer",
342
+ type: "date",
345
343
  required: true,
346
344
  index: true
347
345
  },
348
346
  {
349
347
  name: "end_date",
350
- type: "integer",
348
+ type: "date",
351
349
  required: true,
352
350
  index: true
353
351
  }
@@ -643,11 +641,11 @@ var model13 = {
643
641
  },
644
642
  {
645
643
  name: "feed_start_date",
646
- type: "integer"
644
+ type: "date"
647
645
  },
648
646
  {
649
647
  name: "feed_end_date",
650
- type: "integer"
648
+ type: "date"
651
649
  },
652
650
  {
653
651
  name: "feed_version",
@@ -1500,11 +1498,11 @@ var model31 = {
1500
1498
  },
1501
1499
  {
1502
1500
  name: "start_date",
1503
- type: "integer"
1501
+ type: "date"
1504
1502
  },
1505
1503
  {
1506
1504
  name: "end_date",
1507
- type: "integer"
1505
+ type: "date"
1508
1506
  },
1509
1507
  {
1510
1508
  name: "monday",
@@ -2009,7 +2007,7 @@ var model41 = {
2009
2007
  },
2010
2008
  {
2011
2009
  name: "service_date",
2012
- type: "integer",
2010
+ type: "date",
2013
2011
  index: true
2014
2012
  },
2015
2013
  {
@@ -2091,7 +2089,7 @@ var model42 = {
2091
2089
  },
2092
2090
  {
2093
2091
  name: "service_date",
2094
- type: "integer",
2092
+ type: "date",
2095
2093
  index: true
2096
2094
  },
2097
2095
  {
@@ -2175,12 +2173,12 @@ var model43 = {
2175
2173
  },
2176
2174
  {
2177
2175
  name: "ridership_start_date",
2178
- type: "integer",
2176
+ type: "date",
2179
2177
  index: true
2180
2178
  },
2181
2179
  {
2182
2180
  name: "ridership_end_date",
2183
- type: "integer",
2181
+ type: "date",
2184
2182
  index: true
2185
2183
  },
2186
2184
  {
@@ -2303,7 +2301,7 @@ var model44 = {
2303
2301
  },
2304
2302
  {
2305
2303
  name: "service_date",
2306
- type: "integer",
2304
+ type: "date",
2307
2305
  index: true
2308
2306
  },
2309
2307
  {
@@ -2350,17 +2348,17 @@ var model45 = {
2350
2348
  },
2351
2349
  {
2352
2350
  name: "ride_start_date",
2353
- type: "integer",
2351
+ type: "date",
2354
2352
  index: true
2355
2353
  },
2356
2354
  {
2357
2355
  name: "ride_end_date",
2358
- type: "integer",
2356
+ type: "date",
2359
2357
  index: true
2360
2358
  },
2361
2359
  {
2362
2360
  name: "gtfs_feed_date",
2363
- type: "integer",
2361
+ type: "date",
2364
2362
  index: true
2365
2363
  },
2366
2364
  {
@@ -3151,124 +3149,6 @@ var models_default = models;
3151
3149
  import fs from "fs";
3152
3150
  import Database from "better-sqlite3";
3153
3151
  import untildify from "untildify";
3154
-
3155
- // src/lib/utils.ts
3156
- import sqlString from "sqlstring-sqlite";
3157
- import Long from "long";
3158
- function validateConfigForImport(config) {
3159
- if (!config.agencies || config.agencies.length === 0) {
3160
- throw new Error("No `agencies` specified in config");
3161
- }
3162
- for (const [index, agency] of config.agencies.entries()) {
3163
- if (!agency.path && !agency.url) {
3164
- throw new Error(
3165
- `No Agency \`url\` or \`path\` specified in config for agency index ${index}.`
3166
- );
3167
- }
3168
- }
3169
- return config;
3170
- }
3171
- function setDefaultConfig(initialConfig) {
3172
- const defaults = {
3173
- sqlitePath: ":memory:",
3174
- ignoreDuplicates: false,
3175
- gtfsRealtimeExpirationSeconds: 0
3176
- };
3177
- return {
3178
- ...defaults,
3179
- ...initialConfig
3180
- };
3181
- }
3182
- function convertLongTimeToDate(longDate) {
3183
- const { high, low, unsigned } = longDate;
3184
- return new Date(new Long(low, high, unsigned).toInt() * 1e3).toISOString();
3185
- }
3186
- function calculateSecondsFromMidnight(time) {
3187
- const split = time.split(":").map((d) => Number.parseInt(d, 10));
3188
- if (split.length !== 3) {
3189
- return null;
3190
- }
3191
- return split[0] * 3600 + split[1] * 60 + split[2];
3192
- }
3193
- function padLeadingZeros(time) {
3194
- const split = time.split(":").map((d) => String(Number(d)).padStart(2, "0"));
3195
- if (split.length !== 3) {
3196
- return null;
3197
- }
3198
- return split.join(":");
3199
- }
3200
- function formatSelectClause(fields) {
3201
- if (Array.isArray(fields)) {
3202
- const selectItem2 = fields.length > 0 ? fields.map((fieldName) => sqlString.escapeId(fieldName)).join(", ") : "*";
3203
- return `SELECT ${selectItem2}`;
3204
- }
3205
- const selectItem = Object.entries(fields).map(
3206
- (key) => `${sqlString.escapeId(key[0])} AS ${sqlString.escapeId(key[1])}`
3207
- ).join(", ");
3208
- return `SELECT ${selectItem}`;
3209
- }
3210
- function formatJoinClause(joinObject) {
3211
- return joinObject.map(
3212
- (data) => `${data.type ? data.type + " JOIN" : "INNER JOIN"} ${sqlString.escapeId(
3213
- data.table
3214
- )} ON ${data.on}`
3215
- ).join(" ");
3216
- }
3217
- function degree2radian(angle) {
3218
- return angle * Math.PI / 180;
3219
- }
3220
- function radian2degree(angle) {
3221
- return angle / Math.PI * 180;
3222
- }
3223
- function formatWhereClauseBoundingBox(latitudeDegree, longitudeDegree, boundingBoxSideMeters) {
3224
- const earthRadius = 6371e3;
3225
- latitudeDegree = typeof latitudeDegree === "string" ? parseFloat(latitudeDegree) : latitudeDegree;
3226
- longitudeDegree = typeof longitudeDegree === "string" ? parseFloat(longitudeDegree) : longitudeDegree;
3227
- const latitudeRadian = degree2radian(latitudeDegree);
3228
- const radiusFromLatitude = Math.cos(latitudeRadian) * earthRadius;
3229
- const deltaLatitude = radian2degree(boundingBoxSideMeters / 2 / earthRadius);
3230
- const deltaLongitude = radian2degree(
3231
- boundingBoxSideMeters / 2 / radiusFromLatitude
3232
- );
3233
- let query = `stop_lat BETWEEN ${latitudeDegree - deltaLatitude} AND ${latitudeDegree + deltaLatitude}`;
3234
- query += ` AND stop_lon BETWEEN ${longitudeDegree - deltaLongitude} AND ${longitudeDegree + deltaLongitude}`;
3235
- return query;
3236
- }
3237
- function formatWhereClause(key, value) {
3238
- if (Array.isArray(value)) {
3239
- let whereClause = `${sqlString.escapeId(key)} IN (${value.filter((v) => v !== null).map((v) => sqlString.escape(v)).join(", ")})`;
3240
- if (value.includes(null)) {
3241
- whereClause = `(${whereClause} OR ${sqlString.escapeId(key)} IS NULL)`;
3242
- }
3243
- return whereClause;
3244
- }
3245
- if (value === null) {
3246
- return `${sqlString.escapeId(key)} IS NULL`;
3247
- }
3248
- return `${sqlString.escapeId(key)} = ${sqlString.escape(value)}`;
3249
- }
3250
- function formatWhereClauses(query) {
3251
- if (Object.keys(query).length === 0) {
3252
- return "";
3253
- }
3254
- const whereClauses = Object.entries(query).map(
3255
- ([key, value]) => formatWhereClause(key, value)
3256
- );
3257
- return `WHERE ${whereClauses.join(" AND ")}`;
3258
- }
3259
- function formatOrderByClause(orderBy2) {
3260
- let orderByClause = "";
3261
- if (orderBy2.length > 0) {
3262
- orderByClause += "ORDER BY ";
3263
- orderByClause += orderBy2.map(([key, value]) => {
3264
- const direction = value === "DESC" ? "DESC" : "ASC";
3265
- return `${sqlString.escapeId(key)} ${direction}`;
3266
- }).join(", ");
3267
- }
3268
- return orderByClause;
3269
- }
3270
-
3271
- // src/lib/db.ts
3272
3152
  var dbs = {};
3273
3153
  function setupDb(sqlitePath) {
3274
3154
  const db = new Database(untildify(sqlitePath));
@@ -3280,7 +3160,7 @@ function setupDb(sqlitePath) {
3280
3160
  }
3281
3161
  function openDb(config = null) {
3282
3162
  if (config) {
3283
- const { sqlitePath, db } = setDefaultConfig(config);
3163
+ const { sqlitePath = ":memory:", db } = config;
3284
3164
  if (db) {
3285
3165
  return db;
3286
3166
  }
@@ -3289,6 +3169,9 @@ function openDb(config = null) {
3289
3169
  }
3290
3170
  return setupDb(sqlitePath);
3291
3171
  }
3172
+ if (Object.keys(dbs).length === 0) {
3173
+ return setupDb(":memory:");
3174
+ }
3292
3175
  if (Object.keys(dbs).length === 1) {
3293
3176
  const filename = Object.keys(dbs)[0];
3294
3177
  return dbs[filename];
@@ -3524,6 +3407,122 @@ function formatError(error) {
3524
3407
  return colors.red(errorMessage);
3525
3408
  }
3526
3409
 
3410
+ // src/lib/utils.ts
3411
+ import sqlString from "sqlstring-sqlite";
3412
+ import Long from "long";
3413
+ function validateConfigForImport(config) {
3414
+ if (!config.agencies || config.agencies.length === 0) {
3415
+ throw new Error("No `agencies` specified in config");
3416
+ }
3417
+ for (const [index, agency] of config.agencies.entries()) {
3418
+ if (!agency.path && !agency.url) {
3419
+ throw new Error(
3420
+ `No Agency \`url\` or \`path\` specified in config for agency index ${index}.`
3421
+ );
3422
+ }
3423
+ }
3424
+ return config;
3425
+ }
3426
+ function setDefaultConfig(initialConfig) {
3427
+ const defaults = {
3428
+ sqlitePath: ":memory:",
3429
+ ignoreDuplicates: false,
3430
+ gtfsRealtimeExpirationSeconds: 0
3431
+ };
3432
+ return {
3433
+ ...defaults,
3434
+ ...initialConfig
3435
+ };
3436
+ }
3437
+ function convertLongTimeToDate(longDate) {
3438
+ const { high, low, unsigned } = longDate;
3439
+ return new Date(new Long(low, high, unsigned).toInt() * 1e3).toISOString();
3440
+ }
3441
+ function calculateSecondsFromMidnight(time) {
3442
+ const split = time.split(":").map((d) => Number.parseInt(d, 10));
3443
+ if (split.length !== 3) {
3444
+ return null;
3445
+ }
3446
+ return split[0] * 3600 + split[1] * 60 + split[2];
3447
+ }
3448
+ function padLeadingZeros(time) {
3449
+ const split = time.split(":").map((d) => String(Number(d)).padStart(2, "0"));
3450
+ if (split.length !== 3) {
3451
+ return null;
3452
+ }
3453
+ return split.join(":");
3454
+ }
3455
+ function formatSelectClause(fields) {
3456
+ if (Array.isArray(fields)) {
3457
+ const selectItem2 = fields.length > 0 ? fields.map((fieldName) => sqlString.escapeId(fieldName)).join(", ") : "*";
3458
+ return `SELECT ${selectItem2}`;
3459
+ }
3460
+ const selectItem = Object.entries(fields).map(
3461
+ (key) => `${sqlString.escapeId(key[0])} AS ${sqlString.escapeId(key[1])}`
3462
+ ).join(", ");
3463
+ return `SELECT ${selectItem}`;
3464
+ }
3465
+ function formatJoinClause(joinObject) {
3466
+ return joinObject.map(
3467
+ (data) => `${data.type ? data.type + " JOIN" : "INNER JOIN"} ${sqlString.escapeId(
3468
+ data.table
3469
+ )} ON ${data.on}`
3470
+ ).join(" ");
3471
+ }
3472
+ function degree2radian(angle) {
3473
+ return angle * Math.PI / 180;
3474
+ }
3475
+ function radian2degree(angle) {
3476
+ return angle / Math.PI * 180;
3477
+ }
3478
+ function formatWhereClauseBoundingBox(latitudeDegree, longitudeDegree, boundingBoxSideMeters) {
3479
+ const earthRadius = 6371e3;
3480
+ latitudeDegree = typeof latitudeDegree === "string" ? parseFloat(latitudeDegree) : latitudeDegree;
3481
+ longitudeDegree = typeof longitudeDegree === "string" ? parseFloat(longitudeDegree) : longitudeDegree;
3482
+ const latitudeRadian = degree2radian(latitudeDegree);
3483
+ const radiusFromLatitude = Math.cos(latitudeRadian) * earthRadius;
3484
+ const deltaLatitude = radian2degree(boundingBoxSideMeters / 2 / earthRadius);
3485
+ const deltaLongitude = radian2degree(
3486
+ boundingBoxSideMeters / 2 / radiusFromLatitude
3487
+ );
3488
+ let query = `stop_lat BETWEEN ${latitudeDegree - deltaLatitude} AND ${latitudeDegree + deltaLatitude}`;
3489
+ query += ` AND stop_lon BETWEEN ${longitudeDegree - deltaLongitude} AND ${longitudeDegree + deltaLongitude}`;
3490
+ return query;
3491
+ }
3492
+ function formatWhereClause(key, value) {
3493
+ if (Array.isArray(value)) {
3494
+ let whereClause = `${sqlString.escapeId(key)} IN (${value.filter((v) => v !== null).map((v) => sqlString.escape(v)).join(", ")})`;
3495
+ if (value.includes(null)) {
3496
+ whereClause = `(${whereClause} OR ${sqlString.escapeId(key)} IS NULL)`;
3497
+ }
3498
+ return whereClause;
3499
+ }
3500
+ if (value === null) {
3501
+ return `${sqlString.escapeId(key)} IS NULL`;
3502
+ }
3503
+ return `${sqlString.escapeId(key)} = ${sqlString.escape(value)}`;
3504
+ }
3505
+ function formatWhereClauses(query) {
3506
+ if (Object.keys(query).length === 0) {
3507
+ return "";
3508
+ }
3509
+ const whereClauses = Object.entries(query).map(
3510
+ ([key, value]) => formatWhereClause(key, value)
3511
+ );
3512
+ return `WHERE ${whereClauses.join(" AND ")}`;
3513
+ }
3514
+ function formatOrderByClause(orderBy2) {
3515
+ let orderByClause = "";
3516
+ if (orderBy2.length > 0) {
3517
+ orderByClause += "ORDER BY ";
3518
+ orderByClause += orderBy2.map(([key, value]) => {
3519
+ const direction = value === "DESC" ? "DESC" : "ASC";
3520
+ return `${sqlString.escapeId(key)} ${direction}`;
3521
+ }).join(", ");
3522
+ }
3523
+ return orderByClause;
3524
+ }
3525
+
3527
3526
  // src/lib/import.ts
3528
3527
  var downloadFiles = async (task) => {
3529
3528
  task.log(`Downloading GTFS from ${task.agency_url}`);
@@ -3635,8 +3634,7 @@ var updateRealtimeData = async (task) => {
3635
3634
  return;
3636
3635
  }
3637
3636
  const db = openDb({
3638
- sqlitePath: task.sqlitePath,
3639
- agencies: []
3637
+ sqlitePath: task.sqlitePath
3640
3638
  });
3641
3639
  const vehiclePositionsModel = models_default.find(
3642
3640
  (x) => x.filenameBase === "vehicle_positions"
@@ -3827,7 +3825,17 @@ var formatLine = (line, model56, totalLineCount) => {
3827
3825
  const formattedLine = {};
3828
3826
  for (const columnSchema of model56.schema) {
3829
3827
  const lineValue = line[columnSchema.name];
3830
- if (columnSchema.type === "integer") {
3828
+ if (columnSchema.type === "date") {
3829
+ if (lineValue !== "" && lineValue !== void 0) {
3830
+ const dateValue = lineValue.replace(/-/g, "");
3831
+ if (dateValue.length !== 8) {
3832
+ throw new Error(
3833
+ `Invalid date in ${model56.filenameBase}.${model56.filenameExtension} for ${columnSchema.name} on line ${lineNumber}.`
3834
+ );
3835
+ }
3836
+ formattedLine[columnSchema.name] = Number.parseInt(dateValue, 10);
3837
+ }
3838
+ } else if (columnSchema.type === "integer") {
3831
3839
  formattedLine[columnSchema.name] = Number.parseInt(lineValue, 10);
3832
3840
  } else if (columnSchema.type === "real") {
3833
3841
  formattedLine[columnSchema.name] = Number.parseFloat(lineValue);
@@ -3877,8 +3885,7 @@ var formatLine = (line, model56, totalLineCount) => {
3877
3885
  };
3878
3886
  var importLines = (task, lines, model56, totalLineCount) => {
3879
3887
  const db = openDb({
3880
- sqlitePath: task.sqlitePath,
3881
- agencies: []
3888
+ sqlitePath: task.sqlitePath
3882
3889
  });
3883
3890
  if (lines.length === 0) {
3884
3891
  return;