gtfs 4.4.3 → 4.5.1
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/CHANGELOG.md +18 -0
- package/README.md +2 -2
- package/config-sample.json +1 -1
- package/lib/export.js +17 -7
- package/lib/import.js +45 -45
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.5.1] - 2023-11-09
|
|
9
|
+
|
|
10
|
+
### Updated
|
|
11
|
+
|
|
12
|
+
- Dependency updates
|
|
13
|
+
- Use path to types file instead of directory in package.json
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Exclude agency_id from export if empty
|
|
18
|
+
|
|
19
|
+
## [4.5.0] - 2023-08-23
|
|
20
|
+
|
|
21
|
+
### Updated
|
|
22
|
+
|
|
23
|
+
- Increase `maxInsertVariables` to 32,000
|
|
24
|
+
- Dependency updates
|
|
25
|
+
|
|
8
26
|
## [4.4.3] - 2023-07-18
|
|
9
27
|
|
|
10
28
|
### Updated
|
package/README.md
CHANGED
|
@@ -116,8 +116,8 @@ try {
|
|
|
116
116
|
<td><a href="https://github.com/blinktaginc/gtfs-tts">GTFS-Text-to-Speech</a> app tests GTFS stop name pronunciation for text-to-speech. It uses `node-gtfs` for loading stop names from GTFS data.</td>
|
|
117
117
|
</tr>
|
|
118
118
|
<tr>
|
|
119
|
-
<td><img src="https://
|
|
120
|
-
<td><a href="https://github.com/BlinkTagInc/transit-
|
|
119
|
+
<td><img src="https://raw.githubusercontent.com/BlinkTagInc/transit-departures-widget/main/docs/images/transit-departures-widget-logo.svg" alt="Transit Departures Widget" width="200"></td>
|
|
120
|
+
<td><a href="https://github.com/BlinkTagInc/transit-departures-widget">Transit Departures Widget</a> creates a realtime transit departures widget from GTFS and GTFS-Realtime data.</td>
|
|
121
121
|
</tr>
|
|
122
122
|
</table>
|
|
123
123
|
|
package/config-sample.json
CHANGED
package/lib/export.js
CHANGED
|
@@ -20,12 +20,12 @@ const getAgencies = (db, config) => {
|
|
|
20
20
|
} catch (error) {
|
|
21
21
|
if (config.sqlitePath === ':memory:') {
|
|
22
22
|
throw new Error(
|
|
23
|
-
'No agencies found in SQLite. You are using an in-memory database - if running this from command line be sure to specify a value for `sqlitePath` in config.json other than ":memory:".'
|
|
23
|
+
'No agencies found in SQLite. You are using an in-memory database - if running this from command line be sure to specify a value for `sqlitePath` in config.json other than ":memory:".',
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
throw new Error(
|
|
28
|
-
'No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`'
|
|
28
|
+
'No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`',
|
|
29
29
|
);
|
|
30
30
|
}
|
|
31
31
|
};
|
|
@@ -42,11 +42,11 @@ const exportGtfs = async (initialConfig) => {
|
|
|
42
42
|
const agencyCount = agencies.length;
|
|
43
43
|
if (agencyCount === 0) {
|
|
44
44
|
throw new Error(
|
|
45
|
-
'No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`'
|
|
45
|
+
'No agencies found in SQLite. Be sure to first import data into SQLite using `gtfs-import` or `importGtfs(config);`',
|
|
46
46
|
);
|
|
47
47
|
} else if (agencyCount > 1) {
|
|
48
48
|
logWarning(
|
|
49
|
-
'More than one agency is defined in config.json. Export will merge all into one GTFS file.'
|
|
49
|
+
'More than one agency is defined in config.json. Export will merge all into one GTFS file.',
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -54,8 +54,8 @@ const exportGtfs = async (initialConfig) => {
|
|
|
54
54
|
`Starting GTFS export for ${pluralize(
|
|
55
55
|
'agency',
|
|
56
56
|
agencyCount,
|
|
57
|
-
true
|
|
58
|
-
)} using SQLite database at ${config.sqlitePath}
|
|
57
|
+
true,
|
|
58
|
+
)} using SQLite database at ${config.sqlitePath}`,
|
|
59
59
|
);
|
|
60
60
|
|
|
61
61
|
const folderName = generateFolderName(agencies[0].agency_name);
|
|
@@ -92,9 +92,19 @@ const exportGtfs = async (initialConfig) => {
|
|
|
92
92
|
'ridership_end_timestamp',
|
|
93
93
|
];
|
|
94
94
|
|
|
95
|
+
// If no routes have values for agency_id, add it to the excludeColumns list
|
|
96
|
+
if (model.filenameBase === 'routes') {
|
|
97
|
+
const routesWithAgencyId = db
|
|
98
|
+
.prepare('SELECT agency_id FROM routes WHERE agency_id IS NOT NULL;')
|
|
99
|
+
.all();
|
|
100
|
+
if (!routesWithAgencyId || routesWithAgencyId.length === 0) {
|
|
101
|
+
excludeColumns.push('agency_id');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
95
105
|
const columns = without(
|
|
96
106
|
model.schema.map((column) => column.name),
|
|
97
|
-
...excludeColumns
|
|
107
|
+
...excludeColumns,
|
|
98
108
|
);
|
|
99
109
|
const fileText = await stringify(lines, { columns, header: true });
|
|
100
110
|
await writeFile(filepath, fileText);
|
package/lib/import.js
CHANGED
|
@@ -112,15 +112,15 @@ const updateRealtimeData = async (task) => {
|
|
|
112
112
|
|
|
113
113
|
const model = {
|
|
114
114
|
vehicle_positions: models.find(
|
|
115
|
-
(x) => x.filenameBase === 'vehicle_positions'
|
|
115
|
+
(x) => x.filenameBase === 'vehicle_positions',
|
|
116
116
|
),
|
|
117
117
|
trip_updates: models.find((x) => x.filenameBase === 'trip_updates'),
|
|
118
118
|
stop_times_updates: models.find(
|
|
119
|
-
(x) => x.filenameBase === 'stop_times_updates'
|
|
119
|
+
(x) => x.filenameBase === 'stop_times_updates',
|
|
120
120
|
),
|
|
121
121
|
service_alerts: models.find((x) => x.filenameBase === 'service_alerts'),
|
|
122
122
|
service_alert_targets: models.find(
|
|
123
|
-
(x) => x.filenameBase === 'service_alert_targets'
|
|
123
|
+
(x) => x.filenameBase === 'service_alert_targets',
|
|
124
124
|
),
|
|
125
125
|
};
|
|
126
126
|
|
|
@@ -143,7 +143,7 @@ const updateRealtimeData = async (task) => {
|
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
task.log(
|
|
146
|
-
`Starting GTFS-Realtime import from ${task.realtime_urls.length} urls
|
|
146
|
+
`Starting GTFS-Realtime import from ${task.realtime_urls.length} urls`,
|
|
147
147
|
);
|
|
148
148
|
|
|
149
149
|
for (const realtimeUrl of task.realtime_urls) {
|
|
@@ -151,7 +151,7 @@ const updateRealtimeData = async (task) => {
|
|
|
151
151
|
// eslint-disable-next-line no-await-in-loop
|
|
152
152
|
const tripUpdateData = await downloadGtfsRealtimeData(
|
|
153
153
|
realtimeUrl,
|
|
154
|
-
task.realtime_headers
|
|
154
|
+
task.realtime_headers,
|
|
155
155
|
);
|
|
156
156
|
task.log(`Download successful`);
|
|
157
157
|
|
|
@@ -178,15 +178,15 @@ const updateRealtimeData = async (task) => {
|
|
|
178
178
|
// Do base processing
|
|
179
179
|
const fieldValues = model[gtfsRealtimeType].schema.map((column) =>
|
|
180
180
|
sqlString.escape(
|
|
181
|
-
getDescendantProp(entity, column.source, column.default)
|
|
182
|
-
)
|
|
181
|
+
getDescendantProp(entity, column.source, column.default),
|
|
182
|
+
),
|
|
183
183
|
);
|
|
184
184
|
|
|
185
185
|
try {
|
|
186
186
|
db.prepare(
|
|
187
187
|
`REPLACE INTO ${model[gtfsRealtimeType].filenameBase} (${
|
|
188
188
|
fields[gtfsRealtimeType]
|
|
189
|
-
}) VALUES (${fieldValues.join(', ')})
|
|
189
|
+
}) VALUES (${fieldValues.join(', ')})`,
|
|
190
190
|
).run();
|
|
191
191
|
} catch (error) {
|
|
192
192
|
task.warn('Import error: ' + error.message);
|
|
@@ -199,8 +199,8 @@ const updateRealtimeData = async (task) => {
|
|
|
199
199
|
stopUpdate.parent = entity;
|
|
200
200
|
const subValues = model.stop_times_updates.schema.map((column) =>
|
|
201
201
|
sqlString.escape(
|
|
202
|
-
getDescendantProp(stopUpdate, column.source, column.default)
|
|
203
|
-
)
|
|
202
|
+
getDescendantProp(stopUpdate, column.source, column.default),
|
|
203
|
+
),
|
|
204
204
|
);
|
|
205
205
|
stopUpdateArray.push(`(${subValues.join(', ')})`);
|
|
206
206
|
totalLineCount++;
|
|
@@ -210,7 +210,7 @@ const updateRealtimeData = async (task) => {
|
|
|
210
210
|
db.prepare(
|
|
211
211
|
`REPLACE INTO ${model.stop_times_updates.filenameBase} (${
|
|
212
212
|
fields.stop_times_updates
|
|
213
|
-
}) VALUES ${stopUpdateArray.join(', ')}
|
|
213
|
+
}) VALUES ${stopUpdateArray.join(', ')}`,
|
|
214
214
|
).run();
|
|
215
215
|
} catch (error) {
|
|
216
216
|
task.warn('Import error: ' + error.message);
|
|
@@ -224,8 +224,8 @@ const updateRealtimeData = async (task) => {
|
|
|
224
224
|
informedEntity.parent = entity;
|
|
225
225
|
const subValues = model.service_alert_targets.schema.map((column) =>
|
|
226
226
|
sqlString.escape(
|
|
227
|
-
getDescendantProp(informedEntity, column.source, column.default)
|
|
228
|
-
)
|
|
227
|
+
getDescendantProp(informedEntity, column.source, column.default),
|
|
228
|
+
),
|
|
229
229
|
);
|
|
230
230
|
alertTargetArray.push(`(${subValues.join(', ')})`);
|
|
231
231
|
totalLineCount++;
|
|
@@ -235,7 +235,7 @@ const updateRealtimeData = async (task) => {
|
|
|
235
235
|
db.prepare(
|
|
236
236
|
`REPLACE INTO ${model.service_alert_targets.filenameBase} (${
|
|
237
237
|
fields.service_alert_targets
|
|
238
|
-
}) VALUES ${alertTargetArray.join(', ')}
|
|
238
|
+
}) VALUES ${alertTargetArray.join(', ')}`,
|
|
239
239
|
).run();
|
|
240
240
|
} catch (error) {
|
|
241
241
|
task.warn('Import error: ' + error.message);
|
|
@@ -273,11 +273,11 @@ const readFiles = async (task) => {
|
|
|
273
273
|
|
|
274
274
|
if (folders.length > 1) {
|
|
275
275
|
throw new Error(
|
|
276
|
-
`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
|
|
276
|
+
`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.`,
|
|
277
277
|
);
|
|
278
278
|
} else if (folders.length === 0) {
|
|
279
279
|
throw new Error(
|
|
280
|
-
`No .txt files found in \`${task.path}\`. Ensure that .txt files are in the top level of the zip file, or in a single subdirectory
|
|
280
|
+
`No .txt files found in \`${task.path}\`. Ensure that .txt files are in the top level of the zip file, or in a single subdirectory.`,
|
|
281
281
|
);
|
|
282
282
|
}
|
|
283
283
|
|
|
@@ -286,7 +286,7 @@ const readFiles = async (task) => {
|
|
|
286
286
|
|
|
287
287
|
if (directoryTextFiles.length === 0) {
|
|
288
288
|
throw new Error(
|
|
289
|
-
`No .txt files found in \`${task.path}\`. Ensure that .txt files are in the top level of the zip file, or in a single subdirectory
|
|
289
|
+
`No .txt files found in \`${task.path}\`. Ensure that .txt files are in the top level of the zip file, or in a single subdirectory.`,
|
|
290
290
|
);
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -294,9 +294,9 @@ const readFiles = async (task) => {
|
|
|
294
294
|
directoryTextFiles.map(async (fileName) =>
|
|
295
295
|
rename(
|
|
296
296
|
path.join(subfolderName, fileName),
|
|
297
|
-
path.join(task.downloadDir, fileName)
|
|
298
|
-
)
|
|
299
|
-
)
|
|
297
|
+
path.join(task.downloadDir, fileName),
|
|
298
|
+
),
|
|
299
|
+
),
|
|
300
300
|
);
|
|
301
301
|
}
|
|
302
302
|
} catch (error) {
|
|
@@ -310,7 +310,7 @@ const readFiles = async (task) => {
|
|
|
310
310
|
await copy(gtfsPath, task.downloadDir);
|
|
311
311
|
} catch {
|
|
312
312
|
throw new Error(
|
|
313
|
-
`Unable to load files from path \`${gtfsPath}\` defined in configuration. Verify that path exists and contains GTFS files
|
|
313
|
+
`Unable to load files from path \`${gtfsPath}\` defined in configuration. Verify that path exists and contains GTFS files.`,
|
|
314
314
|
);
|
|
315
315
|
}
|
|
316
316
|
}
|
|
@@ -345,20 +345,20 @@ const createTables = (db) => {
|
|
|
345
345
|
columns.push(
|
|
346
346
|
`PRIMARY KEY (${primaryColumns
|
|
347
347
|
.map((column) => column.name)
|
|
348
|
-
.join(', ')})
|
|
348
|
+
.join(', ')})`,
|
|
349
349
|
);
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
db.prepare(`DROP TABLE IF EXISTS ${model.filenameBase};`).run();
|
|
353
353
|
|
|
354
354
|
db.prepare(
|
|
355
|
-
`CREATE TABLE ${model.filenameBase} (${columns.join(', ')})
|
|
355
|
+
`CREATE TABLE ${model.filenameBase} (${columns.join(', ')});`,
|
|
356
356
|
).run();
|
|
357
357
|
|
|
358
358
|
for (const column of model.schema.filter((column) => column.index)) {
|
|
359
359
|
const unique = column.index === 'unique' ? 'UNIQUE' : '';
|
|
360
360
|
db.prepare(
|
|
361
|
-
`CREATE ${unique} INDEX idx_${model.filenameBase}_${column.name} ON ${model.filenameBase} (${column.name})
|
|
361
|
+
`CREATE ${unique} INDEX idx_${model.filenameBase}_${column.name} ON ${model.filenameBase} (${column.name});`,
|
|
362
362
|
).run();
|
|
363
363
|
}
|
|
364
364
|
}
|
|
@@ -398,7 +398,7 @@ const formatLine = (line, model, totalLineCount) => {
|
|
|
398
398
|
formattedLine[columnSchema.name] === null
|
|
399
399
|
) {
|
|
400
400
|
throw new Error(
|
|
401
|
-
`Missing required value in ${model.filenameBase}.txt for ${columnSchema.name} on line ${lineNumber}
|
|
401
|
+
`Missing required value in ${model.filenameBase}.txt for ${columnSchema.name} on line ${lineNumber}.`,
|
|
402
402
|
);
|
|
403
403
|
}
|
|
404
404
|
|
|
@@ -408,7 +408,7 @@ const formatLine = (line, model, totalLineCount) => {
|
|
|
408
408
|
formattedLine[columnSchema.name] < columnSchema.min
|
|
409
409
|
) {
|
|
410
410
|
throw new Error(
|
|
411
|
-
`Invalid value in ${model.filenameBase}.txt for ${columnSchema.name} on line ${lineNumber}: below minimum value of ${columnSchema.min}
|
|
411
|
+
`Invalid value in ${model.filenameBase}.txt for ${columnSchema.name} on line ${lineNumber}: below minimum value of ${columnSchema.min}.`,
|
|
412
412
|
);
|
|
413
413
|
}
|
|
414
414
|
|
|
@@ -418,7 +418,7 @@ const formatLine = (line, model, totalLineCount) => {
|
|
|
418
418
|
formattedLine[columnSchema.name] > columnSchema.max
|
|
419
419
|
) {
|
|
420
420
|
throw new Error(
|
|
421
|
-
`Invalid value in ${model.filenameBase}.txt for ${columnSchema.name} on line ${lineNumber}: above maximum value of ${columnSchema.max}
|
|
421
|
+
`Invalid value in ${model.filenameBase}.txt for ${columnSchema.name} on line ${lineNumber}: above maximum value of ${columnSchema.max}.`,
|
|
422
422
|
);
|
|
423
423
|
}
|
|
424
424
|
}
|
|
@@ -438,7 +438,7 @@ const formatLine = (line, model, totalLineCount) => {
|
|
|
438
438
|
|
|
439
439
|
// Ensure leading zeros for time columns
|
|
440
440
|
formattedLine[timestampColumnName] = padLeadingZeros(
|
|
441
|
-
formattedLine[timestampColumnName]
|
|
441
|
+
formattedLine[timestampColumnName],
|
|
442
442
|
);
|
|
443
443
|
}
|
|
444
444
|
}
|
|
@@ -469,7 +469,7 @@ const importLines = (task, lines, model, totalLineCount) => {
|
|
|
469
469
|
}
|
|
470
470
|
|
|
471
471
|
return line[column.name];
|
|
472
|
-
})
|
|
472
|
+
}),
|
|
473
473
|
);
|
|
474
474
|
}
|
|
475
475
|
|
|
@@ -479,20 +479,20 @@ const importLines = (task, lines, model, totalLineCount) => {
|
|
|
479
479
|
model.filenameBase
|
|
480
480
|
} (${columns
|
|
481
481
|
.map((column) => column.name)
|
|
482
|
-
.join(', ')}) VALUES ${placeholders.join(',')}
|
|
482
|
+
.join(', ')}) VALUES ${placeholders.join(',')}`,
|
|
483
483
|
).run(...values);
|
|
484
484
|
} catch (error) {
|
|
485
485
|
task.warn(
|
|
486
486
|
`Check ${model.filenameBase}.txt for invalid data between lines ${
|
|
487
487
|
totalLineCount - linesToImportCount
|
|
488
|
-
} and ${totalLineCount}
|
|
488
|
+
} and ${totalLineCount}.`,
|
|
489
489
|
);
|
|
490
490
|
throw error;
|
|
491
491
|
}
|
|
492
492
|
|
|
493
493
|
task.log(
|
|
494
494
|
`Importing - ${model.filenameBase}.txt - ${totalLineCount} lines imported\r`,
|
|
495
|
-
true
|
|
495
|
+
true,
|
|
496
496
|
);
|
|
497
497
|
};
|
|
498
498
|
|
|
@@ -517,7 +517,7 @@ const importFiles = (task) =>
|
|
|
517
517
|
|
|
518
518
|
const filepath = path.join(
|
|
519
519
|
task.downloadDir,
|
|
520
|
-
`${model.filenameBase}.txt
|
|
520
|
+
`${model.filenameBase}.txt`,
|
|
521
521
|
);
|
|
522
522
|
|
|
523
523
|
if (!existsSync(filepath)) {
|
|
@@ -533,7 +533,7 @@ const importFiles = (task) =>
|
|
|
533
533
|
|
|
534
534
|
const lines = [];
|
|
535
535
|
let totalLineCount = 0;
|
|
536
|
-
const maxInsertVariables =
|
|
536
|
+
const maxInsertVariables = 32_000;
|
|
537
537
|
const parser = parse({
|
|
538
538
|
columns: true,
|
|
539
539
|
relax_quotes: true,
|
|
@@ -568,7 +568,7 @@ const importFiles = (task) =>
|
|
|
568
568
|
parser.on('error', reject);
|
|
569
569
|
|
|
570
570
|
createReadStream(filepath).pipe(stripBomStream()).pipe(parser);
|
|
571
|
-
})
|
|
571
|
+
}),
|
|
572
572
|
);
|
|
573
573
|
|
|
574
574
|
export async function importGtfs(initialConfig) {
|
|
@@ -585,8 +585,8 @@ export async function importGtfs(initialConfig) {
|
|
|
585
585
|
`Starting GTFS import for ${pluralize(
|
|
586
586
|
'file',
|
|
587
587
|
agencyCount,
|
|
588
|
-
true
|
|
589
|
-
)} using SQLite database at ${config.sqlitePath}
|
|
588
|
+
true,
|
|
589
|
+
)} using SQLite database at ${config.sqlitePath}`,
|
|
590
590
|
);
|
|
591
591
|
|
|
592
592
|
createTables(db);
|
|
@@ -626,12 +626,12 @@ export async function importGtfs(initialConfig) {
|
|
|
626
626
|
});
|
|
627
627
|
|
|
628
628
|
log(
|
|
629
|
-
`Completed GTFS import for ${pluralize('agency', agencyCount, true)}\n
|
|
629
|
+
`Completed GTFS import for ${pluralize('agency', agencyCount, true)}\n`,
|
|
630
630
|
);
|
|
631
631
|
} catch (error) {
|
|
632
632
|
if (error instanceof Error && error.code === 'SQLITE_CANTOPEN') {
|
|
633
633
|
logError(
|
|
634
|
-
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json
|
|
634
|
+
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json.`,
|
|
635
635
|
);
|
|
636
636
|
}
|
|
637
637
|
|
|
@@ -654,8 +654,8 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
654
654
|
`Starting GTFS-Realtime refresh for ${pluralize(
|
|
655
655
|
'agencies',
|
|
656
656
|
agencyCount,
|
|
657
|
-
true
|
|
658
|
-
)} using SQLite database at ${config.sqlitePath}
|
|
657
|
+
true,
|
|
658
|
+
)} using SQLite database at ${config.sqlitePath}`,
|
|
659
659
|
);
|
|
660
660
|
|
|
661
661
|
markRealtimeDataStale(config, log);
|
|
@@ -676,7 +676,7 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
676
676
|
};
|
|
677
677
|
|
|
678
678
|
await updateRealtimeData(task);
|
|
679
|
-
})
|
|
679
|
+
}),
|
|
680
680
|
);
|
|
681
681
|
|
|
682
682
|
cleanStaleRealtimeData(config, log);
|
|
@@ -684,13 +684,13 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
684
684
|
`Completed GTFS-Realtime refresh for ${pluralize(
|
|
685
685
|
'agencies',
|
|
686
686
|
agencyCount,
|
|
687
|
-
true
|
|
688
|
-
)}\n
|
|
687
|
+
true,
|
|
688
|
+
)}\n`,
|
|
689
689
|
);
|
|
690
690
|
} catch (error) {
|
|
691
691
|
if (error instanceof Error && error.code === 'SQLITE_CANTOPEN') {
|
|
692
692
|
logError(
|
|
693
|
-
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json
|
|
693
|
+
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json.`,
|
|
694
694
|
);
|
|
695
695
|
}
|
|
696
696
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtfs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"description": "Import GTFS transit data into SQLite and query routes, stops, times, fares and more",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"transit",
|
|
@@ -67,19 +67,19 @@
|
|
|
67
67
|
"gtfs-import": "bin/gtfs-import.js",
|
|
68
68
|
"gtfsrealtime-update": "bin/gtfsrealtime-update.js"
|
|
69
69
|
},
|
|
70
|
-
"types": "@types",
|
|
70
|
+
"types": "@types/index.d.ts",
|
|
71
71
|
"scripts": {
|
|
72
72
|
"test": "NODE_ENV=test mocha ./test/mocha/**/*.js --timeout 2000"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@turf/helpers": "^6.5.0",
|
|
76
|
-
"better-sqlite3": "^
|
|
77
|
-
"csv-parse": "^5.
|
|
78
|
-
"csv-stringify": "^6.4.
|
|
76
|
+
"better-sqlite3": "^9.1.1",
|
|
77
|
+
"csv-parse": "^5.5.2",
|
|
78
|
+
"csv-stringify": "^6.4.4",
|
|
79
79
|
"gtfs-realtime-bindings": "^1.1.1",
|
|
80
80
|
"lodash-es": "^4.17.21",
|
|
81
81
|
"long": "^5.2.3",
|
|
82
|
-
"node-fetch": "^3.3.
|
|
82
|
+
"node-fetch": "^3.3.2",
|
|
83
83
|
"node-stream-zip": "^1.15.0",
|
|
84
84
|
"pluralize": "^8.0.0",
|
|
85
85
|
"pretty-error": "^4.0.0",
|
|
@@ -95,9 +95,9 @@
|
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"husky": "^8.0.3",
|
|
98
|
-
"lint-staged": "^
|
|
98
|
+
"lint-staged": "^15.0.2",
|
|
99
99
|
"mocha": "^10.2.0",
|
|
100
|
-
"prettier": "^3.0.
|
|
100
|
+
"prettier": "^3.0.3",
|
|
101
101
|
"should": "^13.2.3"
|
|
102
102
|
},
|
|
103
103
|
"engines": {
|