gtfs 3.1.2 → 3.2.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.
Files changed (111) hide show
  1. package/.eslintrc.json +14 -19
  2. package/.husky/pre-commit +4 -0
  3. package/@types/index.d.ts +269 -0
  4. package/@types/tests.ts +26 -0
  5. package/@types/tsconfig.json +17 -0
  6. package/CHANGELOG.md +181 -0
  7. package/README.md +168 -149
  8. package/bin/gtfs-export.js +4 -5
  9. package/bin/gtfs-import.js +6 -7
  10. package/config-sample-full.json +2 -7
  11. package/docs/images/node-gtfs-logo.svg +18 -0
  12. package/lib/db.js +64 -13
  13. package/lib/export.js +27 -13
  14. package/lib/file-utils.js +26 -9
  15. package/lib/geojson-utils.js +51 -38
  16. package/lib/gtfs/agencies.js +15 -4
  17. package/lib/gtfs/attributions.js +15 -4
  18. package/lib/gtfs/calendar-dates.js +15 -4
  19. package/lib/gtfs/calendars.js +15 -4
  20. package/lib/gtfs/fare-attributes.js +15 -4
  21. package/lib/gtfs/fare-rules.js +15 -4
  22. package/lib/gtfs/feed-info.js +15 -4
  23. package/lib/gtfs/frequencies.js +15 -4
  24. package/lib/gtfs/levels.js +15 -4
  25. package/lib/gtfs/pathways.js +15 -4
  26. package/lib/gtfs/routes.js +22 -6
  27. package/lib/gtfs/shapes.js +59 -23
  28. package/lib/gtfs/stop-times.js +15 -4
  29. package/lib/gtfs/stops.js +57 -23
  30. package/lib/gtfs/transfers.js +15 -4
  31. package/lib/gtfs/translations.js +15 -4
  32. package/lib/gtfs/trips.js +15 -4
  33. package/lib/gtfs-ride/board-alights.js +15 -4
  34. package/lib/gtfs-ride/ride-feed-infos.js +15 -4
  35. package/lib/gtfs-ride/rider-trips.js +15 -4
  36. package/lib/gtfs-ride/riderships.js +15 -4
  37. package/lib/gtfs-ride/trip-capacities.js +15 -4
  38. package/lib/import.js +201 -126
  39. package/lib/log-utils.js +8 -4
  40. package/lib/non-standard/directions.js +15 -4
  41. package/lib/non-standard/stop-attributes.js +15 -4
  42. package/lib/non-standard/timetable-notes-references.js +15 -4
  43. package/lib/non-standard/timetable-notes.js +15 -4
  44. package/lib/non-standard/timetable-pages.js +15 -4
  45. package/lib/non-standard/timetable-stop-order.js +15 -4
  46. package/lib/non-standard/timetables.js +15 -4
  47. package/lib/utils.js +26 -12
  48. package/models/gtfs/agency.js +11 -11
  49. package/models/gtfs/attributions.js +14 -14
  50. package/models/gtfs/calendar-dates.js +7 -7
  51. package/models/gtfs/calendar.js +12 -12
  52. package/models/gtfs/fare-attributes.js +9 -9
  53. package/models/gtfs/fare-rules.js +8 -8
  54. package/models/gtfs/feed-info.js +12 -12
  55. package/models/gtfs/frequencies.js +10 -10
  56. package/models/gtfs/levels.js +5 -5
  57. package/models/gtfs/pathways.js +14 -14
  58. package/models/gtfs/routes.js +14 -14
  59. package/models/gtfs/shapes.js +8 -8
  60. package/models/gtfs/stop-times.js +17 -17
  61. package/models/gtfs/stops.js +17 -17
  62. package/models/gtfs/transfers.js +7 -7
  63. package/models/gtfs/translations.js +10 -10
  64. package/models/gtfs/trips.js +12 -12
  65. package/models/gtfs-ride/board-alight.js +24 -24
  66. package/models/gtfs-ride/ride-feed-info.js +8 -8
  67. package/models/gtfs-ride/rider-trip.js +21 -21
  68. package/models/gtfs-ride/ridership.js +23 -23
  69. package/models/gtfs-ride/trip-capacity.js +10 -10
  70. package/models/models.js +1 -1
  71. package/models/non-standard/directions.js +6 -6
  72. package/models/non-standard/stop-attributes.js +5 -5
  73. package/models/non-standard/timetable-notes-references.js +9 -9
  74. package/models/non-standard/timetable-notes.js +5 -5
  75. package/models/non-standard/timetable-pages.js +5 -5
  76. package/models/non-standard/timetable-stop-order.js +6 -6
  77. package/models/non-standard/timetables.js +27 -27
  78. package/package.json +34 -12
  79. package/test/mocha/export-gtfs.js +74 -44
  80. package/test/mocha/get-agencies.js +20 -14
  81. package/test/mocha/get-attributions.js +10 -4
  82. package/test/mocha/get-board-alights.js +10 -4
  83. package/test/mocha/get-calendar-dates.js +31 -24
  84. package/test/mocha/get-calendars.js +17 -11
  85. package/test/mocha/get-db.js +71 -5
  86. package/test/mocha/get-directions.js +10 -4
  87. package/test/mocha/get-fare-attributes.js +12 -6
  88. package/test/mocha/get-fare-rules.js +17 -13
  89. package/test/mocha/get-feed-info.js +10 -4
  90. package/test/mocha/get-frequencies.js +10 -4
  91. package/test/mocha/get-levels.js +4 -4
  92. package/test/mocha/get-pathways.js +10 -4
  93. package/test/mocha/get-ride-feed-infos.js +9 -3
  94. package/test/mocha/get-rider-trips.js +10 -4
  95. package/test/mocha/get-riderships.js +10 -4
  96. package/test/mocha/get-routes.js +12 -16
  97. package/test/mocha/get-shapes-as-geojson.js +12 -6
  98. package/test/mocha/get-shapes.js +31 -39
  99. package/test/mocha/get-stop-attributes.js +10 -4
  100. package/test/mocha/get-stops-as-geojson.js +11 -5
  101. package/test/mocha/get-stops.js +62 -51
  102. package/test/mocha/get-stoptimes.js +18 -10
  103. package/test/mocha/get-timetable-pages.js +10 -4
  104. package/test/mocha/get-timetable-stop-orders.js +10 -4
  105. package/test/mocha/get-timetables.js +10 -4
  106. package/test/mocha/get-transfers.js +10 -4
  107. package/test/mocha/get-translations.js +10 -4
  108. package/test/mocha/get-trip-capacities.js +10 -4
  109. package/test/mocha/get-trips.js +6 -6
  110. package/test/mocha/import-gtfs.js +63 -46
  111. package/test/test-config.js +9 -4
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import fareAttributes from '../../models/gtfs/fare-attributes.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all fare attributes that match the query parameters.
10
14
  */
11
- export async function getFareAttributes(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getFareAttributes(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(fareAttributes.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import fareRules from '../../models/gtfs/fare-rules.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all fare rules that match the query parameters.
10
14
  */
11
- export async function getFareRules(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getFareRules(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(fareRules.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import feedInfo from '../../models/gtfs/feed-info.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all feed info that match the query parameters.
10
14
  */
11
- export async function getFeedInfo(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getFeedInfo(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(feedInfo.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import frequencies from '../../models/gtfs/frequencies.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all frequencies that match the query parameters.
10
14
  */
11
- export async function getFrequencies(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getFrequencies(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(frequencies.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import levels from '../../models/gtfs/levels.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all levels that match the query parameters.
10
14
  */
11
- export async function getLevels(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getLevels(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(levels.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import pathways from '../../models/gtfs/pathways.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all pathways that match the query parameters.
10
14
  */
11
- export async function getPathways(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getPathways(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(pathways.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -3,7 +3,12 @@ import sqlString from 'sqlstring-sqlite';
3
3
 
4
4
  import { getDb } from '../db.js';
5
5
 
6
- import { formatOrderByClause, formatSelectClause, formatWhereClause, formatWhereClauses } from '../utils.js';
6
+ import {
7
+ formatOrderByClause,
8
+ formatSelectClause,
9
+ formatWhereClause,
10
+ formatWhereClauses,
11
+ } from '../utils.js';
7
12
  import routes from '../../models/gtfs/routes.js';
8
13
 
9
14
  function buildStoptimeSubquery(query) {
@@ -12,15 +17,22 @@ function buildStoptimeSubquery(query) {
12
17
  }
13
18
 
14
19
  function buildTripSubquery(query) {
15
- return `SELECT DISTINCT route_id FROM trips WHERE trip_id IN (${buildStoptimeSubquery(query)})`;
20
+ return `SELECT DISTINCT route_id FROM trips WHERE trip_id IN (${buildStoptimeSubquery(
21
+ query
22
+ )})`;
16
23
  }
17
24
 
18
25
  /*
19
26
  * Returns an array of routes that match the query parameters. A `stop_id`
20
27
  * query parameter may be passed to find all routes that contain that stop.
21
28
  */
22
- export async function getRoutes(query = {}, fields = [], orderBy = []) {
23
- const db = await getDb();
29
+ export async function getRoutes(
30
+ query = {},
31
+ fields = [],
32
+ orderBy = [],
33
+ options = {}
34
+ ) {
35
+ const db = options.db ?? (await getDb());
24
36
  const tableName = sqlString.escapeId(routes.filenameBase);
25
37
  const selectClause = formatSelectClause(fields);
26
38
  let whereClause = '';
@@ -29,7 +41,9 @@ export async function getRoutes(query = {}, fields = [], orderBy = []) {
29
41
  const routeQuery = omit(query, ['stop_id']);
30
42
  const stoptimeQuery = pick(query, ['stop_id']);
31
43
 
32
- const whereClauses = Object.entries(routeQuery).map(([key, value]) => formatWhereClause(key, value));
44
+ const whereClauses = Object.entries(routeQuery).map(([key, value]) =>
45
+ formatWhereClause(key, value)
46
+ );
33
47
 
34
48
  if (Object.values(stoptimeQuery).length > 0) {
35
49
  whereClauses.push(`route_id IN (${buildTripSubquery(stoptimeQuery)})`);
@@ -39,5 +53,7 @@ export async function getRoutes(query = {}, fields = [], orderBy = []) {
39
53
  whereClause = `WHERE ${whereClauses.join(' AND ')}`;
40
54
  }
41
55
 
42
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
56
+ return db.all(
57
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
58
+ );
43
59
  }
@@ -4,7 +4,12 @@ import { featureCollection } from '@turf/helpers';
4
4
 
5
5
  import { getDb } from '../db.js';
6
6
 
7
- import { formatOrderByClause, formatSelectClause, formatWhereClause, formatWhereClauses } from '../utils.js';
7
+ import {
8
+ formatOrderByClause,
9
+ formatSelectClause,
10
+ formatWhereClause,
11
+ formatWhereClauses,
12
+ } from '../utils.js';
8
13
  import { shapesToGeoJSONFeatures } from '../geojson-utils.js';
9
14
  import shapes from '../../models/gtfs/shapes.js';
10
15
  import { getAgencies } from './agencies.js';
@@ -21,17 +26,34 @@ function buildTripSubquery(query) {
21
26
  * query parameter may be passed to find all shapes for a trip. A
22
27
  * `direction_id` query parameter may be passed to find all shapes for a direction.
23
28
  */
24
- export async function getShapes(query = {}, fields = [], orderBy = []) {
25
- const db = await getDb();
29
+ export async function getShapes(
30
+ query = {},
31
+ fields = [],
32
+ orderBy = [],
33
+ options = {}
34
+ ) {
35
+ const db = options.db ?? (await getDb());
26
36
  const tableName = sqlString.escapeId(shapes.filenameBase);
27
37
  const selectClause = formatSelectClause(fields);
28
38
  let whereClause = '';
29
39
  const orderByClause = formatOrderByClause(orderBy);
30
40
 
31
- const shapeQuery = omit(query, ['route_id', 'trip_id', 'service_id', 'direction_id']);
32
- const tripQuery = pick(query, ['route_id', 'trip_id', 'service_id', 'direction_id']);
33
-
34
- const whereClauses = Object.entries(shapeQuery).map(([key, value]) => formatWhereClause(key, value));
41
+ const shapeQuery = omit(query, [
42
+ 'route_id',
43
+ 'trip_id',
44
+ 'service_id',
45
+ 'direction_id',
46
+ ]);
47
+ const tripQuery = pick(query, [
48
+ 'route_id',
49
+ 'trip_id',
50
+ 'service_id',
51
+ 'direction_id',
52
+ ]);
53
+
54
+ const whereClauses = Object.entries(shapeQuery).map(([key, value]) =>
55
+ formatWhereClause(key, value)
56
+ );
35
57
 
36
58
  if (Object.values(tripQuery).length > 0) {
37
59
  whereClauses.push(`shape_id IN (${buildTripSubquery(tripQuery)})`);
@@ -41,15 +63,17 @@ export async function getShapes(query = {}, fields = [], orderBy = []) {
41
63
  whereClause = `WHERE ${whereClauses.join(' AND ')}`;
42
64
  }
43
65
 
44
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
66
+ return db.all(
67
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
68
+ );
45
69
  }
46
70
 
47
71
  /*
48
72
  * Returns geoJSON of the shapes that match the query parameters. A `route_id`
49
73
  * query parameter may be passed to find all shapes for a route.
50
74
  */
51
- export async function getShapesAsGeoJSON(query = {}) {
52
- const agencies = await getAgencies();
75
+ export async function getShapesAsGeoJSON(query = {}, options = {}) {
76
+ const agencies = await getAgencies({}, [], [], options);
53
77
 
54
78
  const routeQuery = {};
55
79
 
@@ -57,21 +81,33 @@ export async function getShapesAsGeoJSON(query = {}) {
57
81
  routeQuery.route_id = query.route_id;
58
82
  }
59
83
 
60
- const routes = await getRoutes(routeQuery);
84
+ const routes = await getRoutes(routeQuery, [], [], options);
61
85
  const features = [];
62
86
 
63
- await Promise.all(routes.map(async route => {
64
- const shapeQuery = { route_id: route.route_id, ...omit(query, 'route_id') };
65
- const shapes = await getShapes(shapeQuery, ['shape_id', 'shape_pt_sequence', 'shape_pt_lon', 'shape_pt_lat']);
66
-
67
- const agency = agencies.find(agency => agency.agency_id === route.agency_id);
68
-
69
- const routeProperties = {
70
- agency_name: agency ? agency.agency_name : undefined,
71
- ...route
72
- };
73
- features.push(...shapesToGeoJSONFeatures(shapes, routeProperties));
74
- }));
87
+ await Promise.all(
88
+ routes.map(async (route) => {
89
+ const shapeQuery = {
90
+ route_id: route.route_id,
91
+ ...omit(query, 'route_id'),
92
+ };
93
+ const shapes = await getShapes(
94
+ shapeQuery,
95
+ ['shape_id', 'shape_pt_sequence', 'shape_pt_lon', 'shape_pt_lat'],
96
+ [],
97
+ options
98
+ );
99
+
100
+ const agency = agencies.find(
101
+ (agency) => agency.agency_id === route.agency_id
102
+ );
103
+
104
+ const routeProperties = {
105
+ agency_name: agency ? agency.agency_name : undefined,
106
+ ...route,
107
+ };
108
+ features.push(...shapesToGeoJSONFeatures(shapes, routeProperties));
109
+ })
110
+ );
75
111
 
76
112
  return featureCollection(features);
77
113
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import stopTimes from '../../models/gtfs/stop-times.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of stoptimes that match the query parameters.
10
14
  */
11
- export async function getStoptimes(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getStoptimes(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(stopTimes.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
package/lib/gtfs/stops.js CHANGED
@@ -3,7 +3,12 @@ import sqlString from 'sqlstring-sqlite';
3
3
 
4
4
  import { getDb } from '../db.js';
5
5
 
6
- import { formatOrderByClause, formatSelectClause, formatWhereClause, formatWhereClauses } from '../utils.js';
6
+ import {
7
+ formatOrderByClause,
8
+ formatSelectClause,
9
+ formatWhereClause,
10
+ formatWhereClauses,
11
+ } from '../utils.js';
7
12
  import { stopsToGeoJSON } from '../geojson-utils.js';
8
13
  import stops from '../../models/gtfs/stops.js';
9
14
  import { getAgencies } from './agencies.js';
@@ -14,7 +19,9 @@ function buildTripSubquery(query) {
14
19
  }
15
20
 
16
21
  function buildStoptimeSubquery(query) {
17
- return `SELECT DISTINCT stop_id FROM stop_times WHERE trip_id IN (${buildTripSubquery(query)})`;
22
+ return `SELECT DISTINCT stop_id FROM stop_times WHERE trip_id IN (${buildTripSubquery(
23
+ query
24
+ )})`;
18
25
  }
19
26
 
20
27
  /*
@@ -23,17 +30,34 @@ function buildStoptimeSubquery(query) {
23
30
  * query parameter may be passed to find all shapes for a trip. A
24
31
  * `direction_id` query parameter may be passed to find all shapes for a direction.
25
32
  */
26
- export async function getStops(query = {}, fields = [], orderBy = []) {
27
- const db = await getDb();
33
+ export async function getStops(
34
+ query = {},
35
+ fields = [],
36
+ orderBy = [],
37
+ options = {}
38
+ ) {
39
+ const db = options.db ?? (await getDb());
28
40
  const tableName = sqlString.escapeId(stops.filenameBase);
29
41
  const selectClause = formatSelectClause(fields);
30
42
  let whereClause = '';
31
43
  const orderByClause = formatOrderByClause(orderBy);
32
44
 
33
- const stopQuery = omit(query, ['route_id', 'trip_id', 'service_id', 'direction_id']);
34
- const tripQuery = pick(query, ['route_id', 'trip_id', 'service_id', 'direction_id']);
35
-
36
- const whereClauses = Object.entries(stopQuery).map(([key, value]) => formatWhereClause(key, value));
45
+ const stopQuery = omit(query, [
46
+ 'route_id',
47
+ 'trip_id',
48
+ 'service_id',
49
+ 'direction_id',
50
+ ]);
51
+ const tripQuery = pick(query, [
52
+ 'route_id',
53
+ 'trip_id',
54
+ 'service_id',
55
+ 'direction_id',
56
+ ]);
57
+
58
+ const whereClauses = Object.entries(stopQuery).map(([key, value]) =>
59
+ formatWhereClause(key, value)
60
+ );
37
61
 
38
62
  if (Object.values(tripQuery).length > 0) {
39
63
  whereClauses.push(`stop_id IN (${buildStoptimeSubquery(tripQuery)})`);
@@ -43,29 +67,39 @@ export async function getStops(query = {}, fields = [], orderBy = []) {
43
67
  whereClause = `WHERE ${whereClauses.join(' AND ')}`;
44
68
  }
45
69
 
46
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
70
+ return db.all(
71
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
72
+ );
47
73
  }
48
74
 
49
75
  /*
50
76
  * Returns geoJSON with stops for the `agencyKey` specified, optionally limited
51
77
  * to the `stopIds` specified
52
78
  */
53
- export async function getStopsAsGeoJSON(query = {}) {
54
- const db = await getDb();
55
- const stops = await getStops(query);
79
+ export async function getStopsAsGeoJSON(query = {}, options = {}) {
80
+ const db = options.db ?? (await getDb());
81
+ const stops = await getStops(query, [], [], options);
56
82
 
57
83
  // Get all agencies for reference
58
- const agencies = await getAgencies();
59
-
60
- const preparedStops = await Promise.all(stops.map(async stop => {
61
- const routeSubquery = 'SELECT DISTINCT route_id FROM trips WHERE trip_id IN (SELECT DISTINCT trip_id FROM stop_times WHERE stop_id = ?)';
62
- const routes = await db.all(`SELECT * FROM routes WHERE route_id IN (${routeSubquery})`, [stop.stop_id]);
63
-
64
- stop.routes = orderBy(routes, route => Number.parseInt(route.route_short_name, 10));
65
- stop.agency_name = agencies[0].agency_name;
66
-
67
- return stop;
68
- }));
84
+ const agencies = await getAgencies({}, [], [], options);
85
+
86
+ const preparedStops = await Promise.all(
87
+ stops.map(async (stop) => {
88
+ const routeSubquery =
89
+ 'SELECT DISTINCT route_id FROM trips WHERE trip_id IN (SELECT DISTINCT trip_id FROM stop_times WHERE stop_id = ?)';
90
+ const routes = await db.all(
91
+ `SELECT * FROM routes WHERE route_id IN (${routeSubquery})`,
92
+ [stop.stop_id]
93
+ );
94
+
95
+ stop.routes = orderBy(routes, (route) =>
96
+ Number.parseInt(route.route_short_name, 10)
97
+ );
98
+ stop.agency_name = agencies[0].agency_name;
99
+
100
+ return stop;
101
+ })
102
+ );
69
103
 
70
104
  return stopsToGeoJSON(preparedStops);
71
105
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import transfers from '../../models/gtfs/transfers.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all transfers that match the query parameters.
10
14
  */
11
- export async function getTransfers(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getTransfers(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(transfers.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import translations from '../../models/gtfs/translations.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all translations that match the query parameters.
10
14
  */
11
- export async function getTranslations(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getTranslations(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(translations.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }
package/lib/gtfs/trips.js CHANGED
@@ -2,18 +2,29 @@ import sqlString from 'sqlstring-sqlite';
2
2
 
3
3
  import { getDb } from '../db.js';
4
4
 
5
- import { formatOrderByClause, formatSelectClause, formatWhereClauses } from '../utils.js';
5
+ import {
6
+ formatOrderByClause,
7
+ formatSelectClause,
8
+ formatWhereClauses,
9
+ } from '../utils.js';
6
10
  import trips from '../../models/gtfs/trips.js';
7
11
 
8
12
  /*
9
13
  * Returns an array of all trips that match the query parameters.
10
14
  */
11
- export async function getTrips(query = {}, fields = [], orderBy = []) {
12
- const db = await getDb();
15
+ export async function getTrips(
16
+ query = {},
17
+ fields = [],
18
+ orderBy = [],
19
+ options = {}
20
+ ) {
21
+ const db = options.db ?? (await getDb());
13
22
  const tableName = sqlString.escapeId(trips.filenameBase);
14
23
  const selectClause = formatSelectClause(fields);
15
24
  const whereClause = formatWhereClauses(query);
16
25
  const orderByClause = formatOrderByClause(orderBy);
17
26
 
18
- return db.all(`${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`);
27
+ return db.all(
28
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
29
+ );
19
30
  }