gtfs 4.7.2 → 4.9.0
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/@types/index.d.ts +15 -0
- package/CHANGELOG.md +14 -0
- package/README.md +80 -8
- package/bin/gtfs-import.js +6 -1
- package/config-sample-full.json +2 -0
- package/lib/db.js +7 -4
- package/lib/import.js +27 -11
- package/package.json +3 -2
- package/test/mocha/import-gtfs.js +16 -4
- package/test/mocha/open-db.js +46 -7
package/@types/index.d.ts
CHANGED
|
@@ -63,6 +63,11 @@ export interface DbConfig {
|
|
|
63
63
|
* A path to a SQLite database. Defaults to using an in-memory database.
|
|
64
64
|
*/
|
|
65
65
|
sqlitePath?: string;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A better-sqlite3 database object. If provided, sqlitePath will be ignored.
|
|
69
|
+
*/
|
|
70
|
+
db?: Database.Database;
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
export interface ExportConfig extends DbConfig, VerboseConfig {
|
|
@@ -114,6 +119,16 @@ export interface ImportConfig extends DbConfig, VerboseConfig {
|
|
|
114
119
|
* Options passed to csv-parse for parsing GTFS CSV files.
|
|
115
120
|
*/
|
|
116
121
|
csvOptions?: CsvParse.Options;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* A timeout in milliseconds for downloading GTFS files. Defaults to no timeout.
|
|
125
|
+
*/
|
|
126
|
+
downloadTimeout?: number;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Whether or not to ignore errors during import. Defaults to false.
|
|
130
|
+
*/
|
|
131
|
+
ignoreErrors?: boolean;
|
|
117
132
|
}
|
|
118
133
|
|
|
119
134
|
export interface QueryOptions {
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ 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.9.0] - 2024-03-12
|
|
9
|
+
|
|
10
|
+
### Updated
|
|
11
|
+
|
|
12
|
+
- Close DB if not :memory: from CLI after import
|
|
13
|
+
|
|
14
|
+
## [4.8.0] - 2024-03-10
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `ignoreErrors` config option
|
|
19
|
+
- `downloadTimeout` config option
|
|
20
|
+
- `db` config option
|
|
21
|
+
|
|
8
22
|
## [4.7.2] - 2024-03-05
|
|
9
23
|
|
|
10
24
|
### Updated
|
package/README.md
CHANGED
|
@@ -161,14 +161,17 @@ Copy `config-sample.json` to `config.json` and then add your projects configurat
|
|
|
161
161
|
|
|
162
162
|
cp config-sample.json config.json
|
|
163
163
|
|
|
164
|
-
| option | type
|
|
165
|
-
| --------------------------------------- |
|
|
166
|
-
| [`agencies`](#agencies) | array
|
|
167
|
-
| [`csvOptions`](#csvOptions) | object
|
|
168
|
-
| [`
|
|
169
|
-
| [`
|
|
170
|
-
| [`
|
|
171
|
-
| [`
|
|
164
|
+
| option | type | description |
|
|
165
|
+
| --------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
166
|
+
| [`agencies`](#agencies) | array | An array of GTFS files to be imported, and which files to exclude. |
|
|
167
|
+
| [`csvOptions`](#csvOptions) | object | Options passed to `csv-parse` for parsing GTFS CSV files. Optional. |
|
|
168
|
+
| [`db`](#db) | database instance | An existing database instance to use instead of relying on node-gtfs to connect. Optional. |
|
|
169
|
+
| [`downloadTimeout`](#downloadtimeout) | integer | The number of milliseconds to wait before throwing an error when downloading GTFS. Optional. |
|
|
170
|
+
| [`exportPath`](#exportPath) | string | A path to a directory to put exported GTFS files. Optional, defaults to `gtfs-export/<agency_name>`. |
|
|
171
|
+
| [`ignoreDuplicates`](#ignoreduplicates) | boolean | Whether or not to ignore unique constraints on ids when importing GTFS, such as `trip_id`, `calendar_id`. Optional, defaults to false. |
|
|
172
|
+
| [`ignoreErrors`](#ignoreerrors) | boolean | Whether or not to ignore errors during the import process. If true, when importing multiple agencies, failed agencies will be skipped. Optional, defaults to false. |
|
|
173
|
+
| [`sqlitePath`](#sqlitePath) | string | A path to an SQLite database. Optional, defaults to using an in-memory database. |
|
|
174
|
+
| [`verbose`](#verbose) | boolean | Whether or not to print output to the console. Optional, defaults to true. |
|
|
172
175
|
|
|
173
176
|
### agencies
|
|
174
177
|
|
|
@@ -320,6 +323,60 @@ For instance, if you wanted to skip importing invalid lines in the GTFS file:
|
|
|
320
323
|
|
|
321
324
|
See [full list of options](https://csv.js.org/parse/options/).
|
|
322
325
|
|
|
326
|
+
### db
|
|
327
|
+
|
|
328
|
+
{Database Instance} When passing configuration to `importGtfs` in javascript, you can pass a `db` parameter with an existing database instance. This is not possible using a json configuration file Optional.
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
// Using better-sqlite3 to open database
|
|
332
|
+
import { importGtfs } from 'gtfs';
|
|
333
|
+
import Database from 'better-sqlite3';
|
|
334
|
+
|
|
335
|
+
const db = new Database('/path/to/database');
|
|
336
|
+
|
|
337
|
+
importGtfs({
|
|
338
|
+
agencies: [
|
|
339
|
+
{
|
|
340
|
+
path: '/path/to/the/unzipped/gtfs/',
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
db: db,
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
```js
|
|
348
|
+
// Using `openDb` from node-gtfs to open database
|
|
349
|
+
import { importGtfs, openDb } from 'gtfs';
|
|
350
|
+
|
|
351
|
+
const db = openDb({
|
|
352
|
+
sqlitePath: '/path/to/database',
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
importGtfs({
|
|
356
|
+
agencies: [
|
|
357
|
+
{
|
|
358
|
+
path: '/path/to/the/unzipped/gtfs/',
|
|
359
|
+
},
|
|
360
|
+
],
|
|
361
|
+
db: db,
|
|
362
|
+
});
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### downloadTimeout
|
|
366
|
+
|
|
367
|
+
{Integer} A number of milliseconds to wait when downloading GTFS before throwing an error. Optional.
|
|
368
|
+
|
|
369
|
+
```json
|
|
370
|
+
{
|
|
371
|
+
"agencies": [
|
|
372
|
+
{
|
|
373
|
+
"path": "/path/to/the/unzipped/gtfs/"
|
|
374
|
+
}
|
|
375
|
+
],
|
|
376
|
+
"downloadTimeout": 5000
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
323
380
|
### exportPath
|
|
324
381
|
|
|
325
382
|
{String} A path to a directory to put exported GTFS files. If the directory does not exist, it will be created. Used when running `gtfs-export` script or `exportGtfs()`. Optional, defaults to `gtfs-export/<agency_name>` where `<agency_name>` is a sanitized, [snake-cased](https://en.wikipedia.org/wiki/Snake_case) version of the first `agency_name` in `agency.txt`.
|
|
@@ -350,6 +407,21 @@ See [full list of options](https://csv.js.org/parse/options/).
|
|
|
350
407
|
}
|
|
351
408
|
```
|
|
352
409
|
|
|
410
|
+
### ignoreErrors
|
|
411
|
+
|
|
412
|
+
{Boolean} When importing GTFS from multiple agencies, if you don't want node-GTFS to throw an error and instead skip failed GTFS importants proceed to the next agency. Defaults to `false`.
|
|
413
|
+
|
|
414
|
+
```json
|
|
415
|
+
{
|
|
416
|
+
"agencies": [
|
|
417
|
+
{
|
|
418
|
+
"path": "/path/to/the/unzipped/gtfs/"
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"ignoreErrors": true
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
353
425
|
### sqlitePath
|
|
354
426
|
|
|
355
427
|
{String} A path to an SQLite database. Optional, defaults to using an in-memory database with a value of `:memory:`.
|
package/bin/gtfs-import.js
CHANGED
|
@@ -5,7 +5,7 @@ import { hideBin } from 'yargs/helpers';
|
|
|
5
5
|
|
|
6
6
|
import { getConfig } from '../lib/file-utils.js';
|
|
7
7
|
import { formatError } from '../lib/log-utils.js';
|
|
8
|
-
import { importGtfs } from '../lib/gtfs.js';
|
|
8
|
+
import { closeDb, importGtfs, openDb } from '../lib/gtfs.js';
|
|
9
9
|
|
|
10
10
|
const { argv } = yargs(hideBin(process.argv))
|
|
11
11
|
.usage('Usage: $0 --configPath ./config.json')
|
|
@@ -38,6 +38,11 @@ const handleError = (error) => {
|
|
|
38
38
|
const setupImport = async () => {
|
|
39
39
|
const config = await getConfig(argv);
|
|
40
40
|
await importGtfs(config);
|
|
41
|
+
|
|
42
|
+
const db = openDb(config);
|
|
43
|
+
if (db.name !== ':memory:') {
|
|
44
|
+
closeDb(db);
|
|
45
|
+
}
|
|
41
46
|
process.exit();
|
|
42
47
|
};
|
|
43
48
|
|
package/config-sample-full.json
CHANGED
package/lib/db.js
CHANGED
|
@@ -17,7 +17,10 @@ function setupDb(sqlitePath) {
|
|
|
17
17
|
export function openDb(config) {
|
|
18
18
|
// If config is passed, use that to open or return db
|
|
19
19
|
if (config) {
|
|
20
|
-
const { sqlitePath } = setDefaultConfig(config);
|
|
20
|
+
const { sqlitePath, db } = setDefaultConfig(config);
|
|
21
|
+
if (db) {
|
|
22
|
+
return db;
|
|
23
|
+
}
|
|
21
24
|
|
|
22
25
|
if (dbs[sqlitePath]) {
|
|
23
26
|
return dbs[sqlitePath];
|
|
@@ -34,7 +37,7 @@ export function openDb(config) {
|
|
|
34
37
|
|
|
35
38
|
if (Object.keys(dbs).length > 1) {
|
|
36
39
|
throw new Error(
|
|
37
|
-
'Multiple databases open, please specify which one to use.'
|
|
40
|
+
'Multiple databases open, please specify which one to use.',
|
|
38
41
|
);
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -44,14 +47,14 @@ export function openDb(config) {
|
|
|
44
47
|
export function closeDb(db) {
|
|
45
48
|
if (Object.keys(dbs).length === 0) {
|
|
46
49
|
throw new Error(
|
|
47
|
-
'No database connection. Call `openDb(config)` before using any methods.'
|
|
50
|
+
'No database connection. Call `openDb(config)` before using any methods.',
|
|
48
51
|
);
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
if (!db) {
|
|
52
55
|
if (Object.keys(dbs).length > 1) {
|
|
53
56
|
throw new Error(
|
|
54
|
-
'Multiple database connections. Pass the db you want to close as a parameter to `closeDb`.'
|
|
57
|
+
'Multiple database connections. Pass the db you want to close as a parameter to `closeDb`.',
|
|
55
58
|
);
|
|
56
59
|
}
|
|
57
60
|
|
package/lib/import.js
CHANGED
|
@@ -36,6 +36,9 @@ const downloadFiles = async (task) => {
|
|
|
36
36
|
const response = await fetch(task.agency_url, {
|
|
37
37
|
method: 'GET',
|
|
38
38
|
headers: task.headers || {},
|
|
39
|
+
signal: task.downloadTimeout
|
|
40
|
+
? AbortSignal.timeout(task.downloadTimeout)
|
|
41
|
+
: undefined,
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
if (response.status !== 200) {
|
|
@@ -594,8 +597,12 @@ const importFiles = (task) =>
|
|
|
594
597
|
});
|
|
595
598
|
|
|
596
599
|
parser.on('end', () => {
|
|
597
|
-
|
|
598
|
-
|
|
600
|
+
try {
|
|
601
|
+
// Insert all remaining lines
|
|
602
|
+
importLines(task, lines, model, totalLineCount);
|
|
603
|
+
} catch (error) {
|
|
604
|
+
reject(error);
|
|
605
|
+
}
|
|
599
606
|
resolve();
|
|
600
607
|
});
|
|
601
608
|
|
|
@@ -635,6 +642,7 @@ export async function importGtfs(initialConfig) {
|
|
|
635
642
|
realtime_headers: agency.realtimeHeaders || false,
|
|
636
643
|
realtime_urls: agency.realtimeUrls || false,
|
|
637
644
|
downloadDir: path,
|
|
645
|
+
downloadTimeout: config.downloadTimeout,
|
|
638
646
|
path: agency.path,
|
|
639
647
|
csvOptions: config.csvOptions || {},
|
|
640
648
|
ignoreDuplicates: config.ignoreDuplicates,
|
|
@@ -645,18 +653,26 @@ export async function importGtfs(initialConfig) {
|
|
|
645
653
|
error: logError,
|
|
646
654
|
};
|
|
647
655
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
656
|
+
try {
|
|
657
|
+
if (task.agency_url) {
|
|
658
|
+
await downloadFiles(task);
|
|
659
|
+
}
|
|
651
660
|
|
|
652
|
-
|
|
653
|
-
|
|
661
|
+
await readFiles(task);
|
|
662
|
+
await importFiles(task);
|
|
654
663
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
664
|
+
if (task.realtime_urls) {
|
|
665
|
+
await updateRealtimeData(task);
|
|
666
|
+
}
|
|
658
667
|
|
|
659
|
-
|
|
668
|
+
cleanup();
|
|
669
|
+
} catch (error) {
|
|
670
|
+
if (config.ignoreErrors) {
|
|
671
|
+
logError(error.message);
|
|
672
|
+
} else {
|
|
673
|
+
throw error;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
660
676
|
});
|
|
661
677
|
|
|
662
678
|
log(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtfs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0",
|
|
4
4
|
"description": "Import GTFS transit data into SQLite and query routes, stops, times, fares and more",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"transit",
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
"David Abell",
|
|
61
61
|
"Matthias Feist <matze@matf.de>",
|
|
62
62
|
"Oliv4945",
|
|
63
|
-
"Kyle Ramey"
|
|
63
|
+
"Kyle Ramey",
|
|
64
|
+
"Anton Bracke"
|
|
64
65
|
],
|
|
65
66
|
"type": "module",
|
|
66
67
|
"main": "index.js",
|
|
@@ -30,7 +30,7 @@ const agenciesFixturesLocal = [
|
|
|
30
30
|
{
|
|
31
31
|
path: path.join(
|
|
32
32
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
33
|
-
'../fixture/caltrain_20160406.zip'
|
|
33
|
+
'../fixture/caltrain_20160406.zip',
|
|
34
34
|
),
|
|
35
35
|
},
|
|
36
36
|
];
|
|
@@ -58,6 +58,18 @@ describe('importGtfs():', function () {
|
|
|
58
58
|
routes.length.should.equal(4);
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
it('should be able to download and import from HTTP with a downloadTimeout', async () => {
|
|
62
|
+
try {
|
|
63
|
+
await importGtfs({
|
|
64
|
+
...config,
|
|
65
|
+
agencies: agenciesFixturesRemote,
|
|
66
|
+
downloadTimeout: 1,
|
|
67
|
+
});
|
|
68
|
+
} catch (error) {
|
|
69
|
+
error.name.should.equal('AbortError');
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
61
73
|
it('should be able to download and import from local filesystem', async () => {
|
|
62
74
|
await importGtfs({
|
|
63
75
|
...config,
|
|
@@ -105,7 +117,7 @@ describe('importGtfs():', function () {
|
|
|
105
117
|
const countData = {};
|
|
106
118
|
const temporaryDir = path.join(
|
|
107
119
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
108
|
-
'../fixture/tmp/'
|
|
120
|
+
'../fixture/tmp/',
|
|
109
121
|
);
|
|
110
122
|
|
|
111
123
|
before(async () => {
|
|
@@ -135,7 +147,7 @@ describe('importGtfs():', function () {
|
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
countData[model.filenameBase] = data.length;
|
|
138
|
-
}
|
|
150
|
+
},
|
|
139
151
|
);
|
|
140
152
|
|
|
141
153
|
return createReadStream(filePath)
|
|
@@ -144,7 +156,7 @@ describe('importGtfs():', function () {
|
|
|
144
156
|
countData[model.collection] = 0;
|
|
145
157
|
throw new Error(error);
|
|
146
158
|
});
|
|
147
|
-
})
|
|
159
|
+
}),
|
|
148
160
|
);
|
|
149
161
|
|
|
150
162
|
await importGtfs({
|
package/test/mocha/open-db.js
CHANGED
|
@@ -7,14 +7,25 @@ import config from '../test-config.js';
|
|
|
7
7
|
import { openDb, closeDb, importGtfs, getShapes } from '../../index.js';
|
|
8
8
|
|
|
9
9
|
const db2Config = {
|
|
10
|
-
...config,
|
|
11
10
|
agencies: [
|
|
12
11
|
{
|
|
13
12
|
...config.agencies[0],
|
|
14
13
|
exclude: ['shapes'],
|
|
15
14
|
},
|
|
16
15
|
],
|
|
17
|
-
|
|
16
|
+
verbose: false,
|
|
17
|
+
sqlitePath: './tmpdb2',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const db3Config = {
|
|
21
|
+
agencies: [
|
|
22
|
+
{
|
|
23
|
+
...config.agencies[0],
|
|
24
|
+
exclude: ['shapes'],
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
verbose: false,
|
|
28
|
+
sqlitePath: './tmpdb3',
|
|
18
29
|
};
|
|
19
30
|
|
|
20
31
|
describe('openDb():', () => {
|
|
@@ -31,6 +42,11 @@ describe('openDb():', () => {
|
|
|
31
42
|
const db2 = openDb(db2Config);
|
|
32
43
|
closeDb(db2);
|
|
33
44
|
fs.unlinkSync(db2Config.sqlitePath);
|
|
45
|
+
|
|
46
|
+
// Close db3 and then delete it
|
|
47
|
+
const db3 = openDb(db3Config);
|
|
48
|
+
closeDb(db3);
|
|
49
|
+
fs.unlinkSync(db3Config.sqlitePath);
|
|
34
50
|
});
|
|
35
51
|
|
|
36
52
|
it('should allow raw db queries: calendar_dates', () => {
|
|
@@ -40,7 +56,7 @@ describe('openDb():', () => {
|
|
|
40
56
|
.prepare(
|
|
41
57
|
`SELECT * FROM calendar_dates WHERE exception_type = 1 AND service_id NOT IN (${serviceIds
|
|
42
58
|
.map((serviceId) => `'${serviceId}'`)
|
|
43
|
-
.join(', ')})
|
|
59
|
+
.join(', ')})`,
|
|
44
60
|
)
|
|
45
61
|
.all();
|
|
46
62
|
|
|
@@ -55,7 +71,7 @@ describe('openDb():', () => {
|
|
|
55
71
|
const db = openDb();
|
|
56
72
|
const results = db
|
|
57
73
|
.prepare(
|
|
58
|
-
'SELECT * from trips where trips.trip_id IN (SELECT start_stop_times.trip_id FROM stop_times as start_stop_times WHERE stop_id = ? AND start_stop_times.stop_sequence < (SELECT end_stop_times.stop_sequence FROM stop_times as end_stop_times WHERE end_stop_times.stop_sequence > start_stop_times.stop_sequence AND end_stop_times.trip_id = start_stop_times.trip_id AND end_stop_times.stop_id = ? ))'
|
|
74
|
+
'SELECT * from trips where trips.trip_id IN (SELECT start_stop_times.trip_id FROM stop_times as start_stop_times WHERE stop_id = ? AND start_stop_times.stop_sequence < (SELECT end_stop_times.stop_sequence FROM stop_times as end_stop_times WHERE end_stop_times.stop_sequence > start_stop_times.stop_sequence AND end_stop_times.trip_id = start_stop_times.trip_id AND end_stop_times.stop_id = ? ))',
|
|
59
75
|
)
|
|
60
76
|
.all(startStopId, endStopId);
|
|
61
77
|
should.exists(results);
|
|
@@ -69,7 +85,7 @@ describe('openDb():', () => {
|
|
|
69
85
|
const db1 = openDb(config);
|
|
70
86
|
|
|
71
87
|
db1.name.should.equal(':memory:');
|
|
72
|
-
db2.name.should.equal('./
|
|
88
|
+
db2.name.should.equal('./tmpdb2');
|
|
73
89
|
|
|
74
90
|
// Query db1 for shapes
|
|
75
91
|
const shapeId = 'cal_sf_tam';
|
|
@@ -79,7 +95,7 @@ describe('openDb():', () => {
|
|
|
79
95
|
},
|
|
80
96
|
[],
|
|
81
97
|
[],
|
|
82
|
-
{ db: db1 }
|
|
98
|
+
{ db: db1 },
|
|
83
99
|
);
|
|
84
100
|
|
|
85
101
|
const expectedResult = {
|
|
@@ -101,10 +117,33 @@ describe('openDb():', () => {
|
|
|
101
117
|
},
|
|
102
118
|
[],
|
|
103
119
|
[],
|
|
104
|
-
{ db: db2 }
|
|
120
|
+
{ db: db2 },
|
|
105
121
|
);
|
|
106
122
|
|
|
107
123
|
should.exist(results2);
|
|
108
124
|
results2.length.should.equal(0);
|
|
109
125
|
});
|
|
126
|
+
|
|
127
|
+
it('should allow `db` configuration option', async () => {
|
|
128
|
+
const db3 = openDb(db3Config);
|
|
129
|
+
|
|
130
|
+
await importGtfs({
|
|
131
|
+
...db3Config,
|
|
132
|
+
db: db3,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Query db3 for shapes, none should exist
|
|
136
|
+
const shapeId = 'cal_sf_tam';
|
|
137
|
+
const results = getShapes(
|
|
138
|
+
{
|
|
139
|
+
shape_id: shapeId,
|
|
140
|
+
},
|
|
141
|
+
[],
|
|
142
|
+
[],
|
|
143
|
+
{ db: db3 },
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
should.exist(results);
|
|
147
|
+
results.length.should.equal(0);
|
|
148
|
+
});
|
|
110
149
|
});
|