gtfs 4.17.6 → 4.17.7

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.js CHANGED
@@ -9,11 +9,8 @@ import path2 from "path";
9
9
  import { createReadStream, existsSync as existsSync2, lstatSync } from "fs";
10
10
  import { cp, readdir, rename, readFile as readFile2, rm as rm2, writeFile } from "fs/promises";
11
11
  import { parse } from "csv-parse";
12
- import pluralize2 from "pluralize";
13
12
  import stripBomStream from "strip-bom-stream";
14
13
  import { temporaryDirectory } from "tempy";
15
- import Timer from "timer-machine";
16
- import untildify3 from "untildify";
17
14
  import mapSeries2 from "promise-map-series";
18
15
 
19
16
  // src/models/models.ts
@@ -3976,84 +3973,14 @@ var vehicles = {
3976
3973
  // src/lib/db.ts
3977
3974
  import fs from "fs";
3978
3975
  import Database from "better-sqlite3";
3979
- import untildify from "untildify";
3980
- var dbs = {};
3981
- function setupDb(sqlitePath) {
3982
- const db = new Database(untildify(sqlitePath));
3983
- db.pragma("journal_mode = OFF");
3984
- db.pragma("synchronous = OFF");
3985
- db.pragma("temp_store = MEMORY");
3986
- dbs[sqlitePath] = db;
3987
- return db;
3988
- }
3989
- function openDb(config = null) {
3990
- if (config) {
3991
- const { sqlitePath = ":memory:", db } = config;
3992
- if (db) {
3993
- return db;
3994
- }
3995
- if (dbs[sqlitePath]) {
3996
- return dbs[sqlitePath];
3997
- }
3998
- return setupDb(sqlitePath);
3999
- }
4000
- if (Object.keys(dbs).length === 0) {
4001
- return setupDb(":memory:");
4002
- }
4003
- if (Object.keys(dbs).length === 1) {
4004
- const filename = Object.keys(dbs)[0];
4005
- return dbs[filename];
4006
- }
4007
- if (Object.keys(dbs).length > 1) {
4008
- throw new Error(
4009
- "Multiple databases open, please specify which one to use."
4010
- );
4011
- }
4012
- throw new Error("Unable to find database connection.");
4013
- }
4014
- function closeDb(db = null) {
4015
- if (Object.keys(dbs).length === 0) {
4016
- throw new Error(
4017
- "No database connection. Call `openDb(config)` before using any methods."
4018
- );
4019
- }
4020
- if (!db) {
4021
- if (Object.keys(dbs).length > 1) {
4022
- throw new Error(
4023
- "Multiple database connections. Pass the db you want to close as a parameter to `closeDb`."
4024
- );
4025
- }
4026
- db = dbs[Object.keys(dbs)[0]];
4027
- }
4028
- db.close();
4029
- delete dbs[db.name];
4030
- }
4031
- function deleteDb(db = null) {
4032
- if (Object.keys(dbs).length === 0) {
4033
- throw new Error(
4034
- "No database connection. Call `openDb(config)` before using any methods."
4035
- );
4036
- }
4037
- if (!db) {
4038
- if (Object.keys(dbs).length > 1) {
4039
- throw new Error(
4040
- "Multiple database connections. Pass the db you want to delete as a parameter to `deleteDb`."
4041
- );
4042
- }
4043
- db = dbs[Object.keys(dbs)[0]];
4044
- }
4045
- db.close();
4046
- fs.unlinkSync(db.name);
4047
- delete dbs[db.name];
4048
- }
4049
3976
 
4050
3977
  // src/lib/file-utils.ts
4051
3978
  import path from "path";
4052
3979
  import { existsSync } from "fs";
3980
+ import { homedir } from "os";
4053
3981
  import { mkdir, readFile, rm } from "fs/promises";
4054
3982
  import { omit, snakeCase } from "lodash-es";
4055
3983
  import sanitize from "sanitize-filename";
4056
- import untildify2 from "untildify";
4057
3984
  import StreamZip from "node-stream-zip";
4058
3985
 
4059
3986
  // src/lib/log-utils.ts
@@ -4107,6 +4034,7 @@ function formatError(error) {
4107
4034
  }
4108
4035
 
4109
4036
  // src/lib/file-utils.ts
4037
+ var homeDirectory = homedir();
4110
4038
  async function prepDirectory(exportPath) {
4111
4039
  await rm(exportPath, { recursive: true, force: true });
4112
4040
  await mkdir(exportPath, { recursive: true });
@@ -4128,6 +4056,80 @@ function generateFolderName(folderName) {
4128
4056
  }
4129
4057
  return snakeCase(sanitize(folderName));
4130
4058
  }
4059
+ function untildify(pathWithTilde) {
4060
+ return homeDirectory ? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) : pathWithTilde;
4061
+ }
4062
+
4063
+ // src/lib/db.ts
4064
+ var dbs = {};
4065
+ function setupDb(sqlitePath) {
4066
+ const db = new Database(untildify(sqlitePath));
4067
+ db.pragma("journal_mode = OFF");
4068
+ db.pragma("synchronous = OFF");
4069
+ db.pragma("temp_store = MEMORY");
4070
+ dbs[sqlitePath] = db;
4071
+ return db;
4072
+ }
4073
+ function openDb(config = null) {
4074
+ if (config) {
4075
+ const { sqlitePath = ":memory:", db } = config;
4076
+ if (db) {
4077
+ return db;
4078
+ }
4079
+ if (dbs[sqlitePath]) {
4080
+ return dbs[sqlitePath];
4081
+ }
4082
+ return setupDb(sqlitePath);
4083
+ }
4084
+ if (Object.keys(dbs).length === 0) {
4085
+ return setupDb(":memory:");
4086
+ }
4087
+ if (Object.keys(dbs).length === 1) {
4088
+ const filename = Object.keys(dbs)[0];
4089
+ return dbs[filename];
4090
+ }
4091
+ if (Object.keys(dbs).length > 1) {
4092
+ throw new Error(
4093
+ "Multiple databases open, please specify which one to use."
4094
+ );
4095
+ }
4096
+ throw new Error("Unable to find database connection.");
4097
+ }
4098
+ function closeDb(db = null) {
4099
+ if (Object.keys(dbs).length === 0) {
4100
+ throw new Error(
4101
+ "No database connection. Call `openDb(config)` before using any methods."
4102
+ );
4103
+ }
4104
+ if (!db) {
4105
+ if (Object.keys(dbs).length > 1) {
4106
+ throw new Error(
4107
+ "Multiple database connections. Pass the db you want to close as a parameter to `closeDb`."
4108
+ );
4109
+ }
4110
+ db = dbs[Object.keys(dbs)[0]];
4111
+ }
4112
+ db.close();
4113
+ delete dbs[db.name];
4114
+ }
4115
+ function deleteDb(db = null) {
4116
+ if (Object.keys(dbs).length === 0) {
4117
+ throw new Error(
4118
+ "No database connection. Call `openDb(config)` before using any methods."
4119
+ );
4120
+ }
4121
+ if (!db) {
4122
+ if (Object.keys(dbs).length > 1) {
4123
+ throw new Error(
4124
+ "Multiple database connections. Pass the db you want to delete as a parameter to `deleteDb`."
4125
+ );
4126
+ }
4127
+ db = dbs[Object.keys(dbs)[0]];
4128
+ }
4129
+ db.close();
4130
+ fs.unlinkSync(db.name);
4131
+ delete dbs[db.name];
4132
+ }
4131
4133
 
4132
4134
  // src/lib/geojson-utils.ts
4133
4135
  import {
@@ -4249,7 +4251,6 @@ function stopsToGeoJSONFeatureCollection(stops2) {
4249
4251
  }
4250
4252
 
4251
4253
  // src/lib/import-gtfs-realtime.ts
4252
- import pluralize from "pluralize";
4253
4254
  import GtfsRealtimeBindings from "gtfs-realtime-bindings";
4254
4255
  import mapSeries from "promise-map-series";
4255
4256
  import { get } from "lodash-es";
@@ -4419,6 +4420,9 @@ function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
4419
4420
  }
4420
4421
  return `${prefix}${value}`;
4421
4422
  }
4423
+ function pluralize(singularWord, pluralWord, count) {
4424
+ return count === 1 ? singularWord : pluralWord;
4425
+ }
4422
4426
 
4423
4427
  // src/lib/import-gtfs-realtime.ts
4424
4428
  async function fetchGtfsRealtimeData(urlConfig, task) {
@@ -4653,9 +4657,9 @@ async function updateGtfsRealtime(initialConfig) {
4653
4657
  const agencyCount = config.agencies.length;
4654
4658
  log(config)(
4655
4659
  `Starting GTFS-Realtime refresh for ${pluralize(
4660
+ "agency",
4656
4661
  "agencies",
4657
- agencyCount,
4658
- true
4662
+ agencyCount
4659
4663
  )} using SQLite database at ${config.sqlitePath}`
4660
4664
  );
4661
4665
  removeExpiredRealtimeData(config);
@@ -4686,9 +4690,9 @@ async function updateGtfsRealtime(initialConfig) {
4686
4690
  });
4687
4691
  log(config)(
4688
4692
  `Completed GTFS-Realtime refresh for ${pluralize(
4693
+ "agency",
4689
4694
  "agencies",
4690
- agencyCount,
4691
- true
4695
+ agencyCount
4692
4696
  )}
4693
4697
  `
4694
4698
  );
@@ -4731,7 +4735,7 @@ var extractGtfsFiles = async (task) => {
4731
4735
  if (!task.path) {
4732
4736
  throw new Error("No `path` specified in config");
4733
4737
  }
4734
- const gtfsPath = untildify3(task.path);
4738
+ const gtfsPath = untildify(task.path);
4735
4739
  task.log(`Importing GTFS from ${task.path}\r`);
4736
4740
  if (path2.extname(gtfsPath) === ".zip") {
4737
4741
  try {
@@ -4983,7 +4987,12 @@ var importGtfsFiles = (db, task) => mapSeries2(
4983
4987
  }
4984
4988
  }
4985
4989
  } catch (error) {
4986
- reject(error);
4990
+ if (task.ignoreErrors) {
4991
+ task.logError(`Error processing ${filename}: ${error.message}`);
4992
+ resolve();
4993
+ } else {
4994
+ reject(error);
4995
+ }
4987
4996
  }
4988
4997
  });
4989
4998
  parser.on("end", () => {
@@ -4992,7 +5001,16 @@ var importGtfsFiles = (db, task) => mapSeries2(
4992
5001
  try {
4993
5002
  insertLines(lines);
4994
5003
  } catch (error) {
4995
- reject(error);
5004
+ if (task.ignoreErrors) {
5005
+ task.logError(
5006
+ `Error inserting data for ${filename}: ${error.message}`
5007
+ );
5008
+ resolve();
5009
+ return;
5010
+ } else {
5011
+ reject(error);
5012
+ return;
5013
+ }
4996
5014
  }
4997
5015
  }
4998
5016
  task.log(
@@ -5001,15 +5019,34 @@ var importGtfsFiles = (db, task) => mapSeries2(
5001
5019
  );
5002
5020
  resolve();
5003
5021
  } catch (error) {
5022
+ if (task.ignoreErrors) {
5023
+ task.logError(`Error finalizing ${filename}: ${error.message}`);
5024
+ resolve();
5025
+ } else {
5026
+ reject(error);
5027
+ }
5028
+ }
5029
+ });
5030
+ parser.on("error", (error) => {
5031
+ if (task.ignoreErrors) {
5032
+ task.logError(`Parser error for ${filename}: ${error.message}`);
5033
+ resolve();
5034
+ } else {
5004
5035
  reject(error);
5005
5036
  }
5006
5037
  });
5007
- parser.on("error", reject);
5008
5038
  createReadStream(filepath).pipe(stripBomStream()).pipe(parser);
5009
5039
  } else if (model.filenameExtension === "geojson") {
5010
5040
  readFile2(filepath, "utf8").then((data) => {
5011
5041
  if (isValidJSON(data) === false) {
5012
- reject(new Error(`Invalid JSON in ${filename}`));
5042
+ if (task.ignoreErrors) {
5043
+ task.logError(`Invalid JSON in ${filename}`);
5044
+ resolve();
5045
+ return;
5046
+ } else {
5047
+ reject(new Error(`Invalid JSON in ${filename}`));
5048
+ return;
5049
+ }
5013
5050
  }
5014
5051
  totalLineCount += 1;
5015
5052
  const line = formatGtfsLine(
@@ -5017,30 +5054,54 @@ var importGtfsFiles = (db, task) => mapSeries2(
5017
5054
  model,
5018
5055
  totalLineCount
5019
5056
  );
5020
- insertLines([line]);
5021
- task.log(
5022
- `Importing - ${filename} - ${totalLineCount} lines imported\r`,
5023
- true
5057
+ try {
5058
+ insertLines([line]);
5059
+ task.log(
5060
+ `Importing - ${filename} - ${totalLineCount} lines imported\r`,
5061
+ true
5062
+ );
5063
+ resolve();
5064
+ } catch (error) {
5065
+ if (task.ignoreErrors) {
5066
+ task.logError(
5067
+ `Error inserting data for ${filename}: ${error.message}`
5068
+ );
5069
+ resolve();
5070
+ } else {
5071
+ reject(error);
5072
+ }
5073
+ }
5074
+ }).catch((error) => {
5075
+ if (task.ignoreErrors) {
5076
+ task.logError(`Error reading ${filename}: ${error.message}`);
5077
+ resolve();
5078
+ } else {
5079
+ reject(error);
5080
+ }
5081
+ });
5082
+ } else {
5083
+ if (task.ignoreErrors) {
5084
+ task.logError(
5085
+ `Unsupported file type: ${model.filenameExtension} for ${filename}`
5024
5086
  );
5025
5087
  resolve();
5026
- }).catch(reject);
5027
- } else {
5028
- reject(
5029
- new Error(`Unsupported file type: ${model.filenameExtension}`)
5030
- );
5088
+ } else {
5089
+ reject(
5090
+ new Error(`Unsupported file type: ${model.filenameExtension}`)
5091
+ );
5092
+ }
5031
5093
  }
5032
5094
  })
5033
5095
  );
5034
5096
  async function importGtfs(initialConfig) {
5035
- const timer = new Timer();
5036
- timer.start();
5097
+ const startTime = process.hrtime.bigint();
5037
5098
  const config = setDefaultConfig(initialConfig);
5038
5099
  validateConfigForImport(config);
5039
5100
  try {
5040
5101
  const db = openDb(config);
5041
5102
  const agencyCount = config.agencies.length;
5042
5103
  log(config)(
5043
- `Starting GTFS import for ${pluralize2("file", agencyCount, true)} using SQLite database at ${config.sqlitePath}`
5104
+ `Starting GTFS import for ${pluralize("file", "files", agencyCount)} using SQLite database at ${config.sqlitePath}`
5044
5105
  );
5045
5106
  createGtfsTables(db);
5046
5107
  await mapSeries2(config.agencies, async (agency2) => {
@@ -5084,10 +5145,10 @@ async function importGtfs(initialConfig) {
5084
5145
  });
5085
5146
  log(config)(`Creating DB indexes`);
5086
5147
  createGtfsIndexes(db);
5087
- const seconds = Math.round(timer.time() / 1e3);
5088
- timer.stop();
5148
+ const endTime = process.hrtime.bigint();
5149
+ const elapsedSeconds = Number(endTime - startTime) / 1e9;
5089
5150
  log(config)(
5090
- `Completed GTFS import for ${pluralize2("agency", agencyCount, true)} in ${seconds} seconds
5151
+ `Completed GTFS import in ${elapsedSeconds.toFixed(1)} seconds
5091
5152
  `
5092
5153
  );
5093
5154
  } catch (error) {
@@ -5104,11 +5165,9 @@ async function importGtfs(initialConfig) {
5104
5165
  import path3 from "path";
5105
5166
  import { writeFile as writeFile2 } from "fs/promises";
5106
5167
  import { without, compact as compact2 } from "lodash-es";
5107
- import pluralize3 from "pluralize";
5108
5168
  import { stringify } from "csv-stringify";
5109
5169
  import sqlString2 from "sqlstring-sqlite";
5110
5170
  import mapSeries3 from "promise-map-series";
5111
- import untildify4 from "untildify";
5112
5171
  var getAgencies = (db, config) => {
5113
5172
  try {
5114
5173
  return db.prepare("SELECT agency_name FROM agency;").all();
@@ -5138,15 +5197,15 @@ var exportGtfs = async (initialConfig) => {
5138
5197
  );
5139
5198
  }
5140
5199
  log(config)(
5141
- `Starting GTFS export for ${pluralize3(
5200
+ `Starting GTFS export for ${pluralize(
5142
5201
  "agency",
5143
- agencyCount,
5144
- true
5202
+ "agencies",
5203
+ agencyCount
5145
5204
  )} using SQLite database at ${config.sqlitePath}`
5146
5205
  );
5147
5206
  const folderName = generateFolderName(agencies[0].agency_name);
5148
5207
  const defaultExportPath = path3.join(process.cwd(), "gtfs-export", folderName);
5149
- const exportPath = untildify4(config.exportPath || defaultExportPath);
5208
+ const exportPath = untildify(config.exportPath || defaultExportPath);
5150
5209
  await prepDirectory(exportPath);
5151
5210
  const modelsToExport = Object.values(models_exports).filter(
5152
5211
  (model) => model.extension !== "gtfs-realtime"
@@ -5214,7 +5273,7 @@ var exportGtfs = async (initialConfig) => {
5214
5273
  }
5215
5274
  log(config)(`Completed GTFS export to ${exportPath}`);
5216
5275
  log(config)(
5217
- `Completed GTFS export for ${pluralize3("agency", agencyCount, true)}
5276
+ `Completed GTFS export for ${pluralize("agency", "agencies", agencyCount)}
5218
5277
  `
5219
5278
  );
5220
5279
  };