gtfs 4.15.4 → 4.15.6
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/bin/gtfs-export.js +32 -54
- package/dist/bin/gtfs-export.js.map +1 -1
- package/dist/bin/gtfs-import.js +50 -63
- package/dist/bin/gtfs-import.js.map +1 -1
- package/dist/bin/gtfsrealtime-update.js +32 -55
- package/dist/bin/gtfsrealtime-update.js.map +1 -1
- package/dist/index.d.ts +332 -58
- package/dist/index.js +84 -69
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/bin/gtfs-import.js
CHANGED
|
@@ -21,64 +21,49 @@ import StreamZip from "node-stream-zip";
|
|
|
21
21
|
async function getConfig(argv2) {
|
|
22
22
|
let config;
|
|
23
23
|
let data;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Cannot find configuration file at \`${argv2.configPath}\`. Use config-sample.json as a starting point.`
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
try {
|
|
24
|
+
try {
|
|
25
|
+
if (argv2.configPath) {
|
|
26
|
+
const configPath = path.resolve(untildify(argv2.configPath));
|
|
27
|
+
data = await readFile(configPath, "utf8");
|
|
33
28
|
config = Object.assign(JSON.parse(data), argv2);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
if (argv2.gtfsUrl) {
|
|
47
|
-
agencies.push({
|
|
48
|
-
url: argv2.gtfsUrl
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
config = {
|
|
52
|
-
agencies,
|
|
53
|
-
...omit(argv2, ["path", "url"])
|
|
54
|
-
};
|
|
55
|
-
} else if (existsSync(path.resolve("./config.json"))) {
|
|
56
|
-
try {
|
|
29
|
+
} else if (argv2.gtfsPath || argv2.gtfsUrl || argv2.sqlitePath) {
|
|
30
|
+
const agencies = [
|
|
31
|
+
...argv2.gtfsPath ? [{ path: argv2.gtfsPath }] : [],
|
|
32
|
+
...argv2.gtfsUrl ? [{ url: argv2.gtfsUrl }] : []
|
|
33
|
+
];
|
|
34
|
+
config = {
|
|
35
|
+
agencies,
|
|
36
|
+
...omit(argv2, ["path", "url"])
|
|
37
|
+
};
|
|
38
|
+
} else if (existsSync(path.resolve("./config.json"))) {
|
|
57
39
|
data = await readFile(path.resolve("./config.json"), "utf8");
|
|
58
|
-
|
|
40
|
+
config = Object.assign(JSON.parse(data), argv2);
|
|
41
|
+
console.log("Using configuration from ./config.json");
|
|
42
|
+
} else {
|
|
59
43
|
throw new Error(
|
|
60
|
-
|
|
44
|
+
"Cannot find configuration file. Use config-sample.json as a starting point, pass --configPath option."
|
|
61
45
|
);
|
|
62
46
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} catch (error) {
|
|
47
|
+
return config;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error instanceof SyntaxError) {
|
|
67
50
|
throw new Error(
|
|
68
|
-
`Cannot parse configuration file
|
|
51
|
+
`Cannot parse configuration file. Check to ensure that it is valid JSON. Error: ${error.message}`
|
|
69
52
|
);
|
|
70
53
|
}
|
|
71
|
-
|
|
72
|
-
throw new Error(
|
|
73
|
-
"Cannot find configuration file. Use config-sample.json as a starting point, pass --configPath option."
|
|
74
|
-
);
|
|
54
|
+
throw error;
|
|
75
55
|
}
|
|
76
|
-
return config;
|
|
77
56
|
}
|
|
78
57
|
async function unzip(zipfilePath, exportPath) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
58
|
+
try {
|
|
59
|
+
const zip = new StreamZip.async({ file: zipfilePath });
|
|
60
|
+
await zip.extract(null, exportPath);
|
|
61
|
+
await zip.close();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Failed to extract zip file: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
82
67
|
}
|
|
83
68
|
|
|
84
69
|
// src/lib/log-utils.ts
|
|
@@ -86,14 +71,14 @@ import { clearLine, cursorTo } from "node:readline";
|
|
|
86
71
|
import { noop } from "lodash-es";
|
|
87
72
|
import * as colors from "yoctocolors";
|
|
88
73
|
function log(config) {
|
|
89
|
-
if (config.verbose
|
|
74
|
+
if (!config.verbose) {
|
|
90
75
|
return noop;
|
|
91
76
|
}
|
|
92
77
|
if (config.logFunction) {
|
|
93
78
|
return config.logFunction;
|
|
94
79
|
}
|
|
95
|
-
return (text, overwrite) => {
|
|
96
|
-
if (overwrite
|
|
80
|
+
return (text, overwrite = false) => {
|
|
81
|
+
if (overwrite && process.stdout.isTTY) {
|
|
97
82
|
clearLine(process.stdout, 0);
|
|
98
83
|
cursorTo(process.stdout, 0);
|
|
99
84
|
} else {
|
|
@@ -123,16 +108,12 @@ ${formatError(text)}
|
|
|
123
108
|
};
|
|
124
109
|
}
|
|
125
110
|
function formatWarning(text) {
|
|
126
|
-
|
|
127
|
-
return colors.yellow(warningMessage);
|
|
111
|
+
return colors.yellow(`${colors.underline("Warning")}: ${text}`);
|
|
128
112
|
}
|
|
129
113
|
function formatError(error) {
|
|
130
114
|
const messageText = error instanceof Error ? error.message : error;
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
""
|
|
134
|
-
)}`;
|
|
135
|
-
return colors.red(errorMessage);
|
|
115
|
+
const cleanMessage = messageText.replace(/^Error:\s*/i, "");
|
|
116
|
+
return colors.red(`${colors.underline("Error")}: ${cleanMessage}`);
|
|
136
117
|
}
|
|
137
118
|
|
|
138
119
|
// src/lib/import-gtfs.ts
|
|
@@ -3291,10 +3272,10 @@ import { feature, featureCollection } from "@turf/helpers";
|
|
|
3291
3272
|
function isValidJSON(string) {
|
|
3292
3273
|
try {
|
|
3293
3274
|
JSON.parse(string);
|
|
3275
|
+
return true;
|
|
3294
3276
|
} catch (error) {
|
|
3295
3277
|
return false;
|
|
3296
3278
|
}
|
|
3297
|
-
return true;
|
|
3298
3279
|
}
|
|
3299
3280
|
|
|
3300
3281
|
// src/lib/import-gtfs-realtime.ts
|
|
@@ -3333,14 +3314,17 @@ function setDefaultConfig(initialConfig) {
|
|
|
3333
3314
|
}
|
|
3334
3315
|
function convertLongTimeToDate(longDate) {
|
|
3335
3316
|
const { high, low, unsigned } = longDate;
|
|
3336
|
-
return new Date(
|
|
3317
|
+
return new Date(
|
|
3318
|
+
Long.fromBits(low, high, unsigned).toNumber() * 1e3
|
|
3319
|
+
).toISOString();
|
|
3337
3320
|
}
|
|
3338
3321
|
function calculateSecondsFromMidnight(time) {
|
|
3339
|
-
|
|
3340
|
-
|
|
3322
|
+
if (!time || typeof time !== "string") return null;
|
|
3323
|
+
const [hours, minutes, seconds] = time.split(":").map(Number);
|
|
3324
|
+
if ([hours, minutes, seconds].some(isNaN) || hours >= 24 || minutes >= 60 || seconds >= 60) {
|
|
3341
3325
|
return null;
|
|
3342
3326
|
}
|
|
3343
|
-
return
|
|
3327
|
+
return hours * 3600 + minutes * 60 + seconds;
|
|
3344
3328
|
}
|
|
3345
3329
|
function padLeadingZeros(time) {
|
|
3346
3330
|
const split = time.split(":").map((d) => String(Number(d)).padStart(2, "0"));
|
|
@@ -3793,6 +3777,9 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
3793
3777
|
task.log(`Importing - ${filename}\r`);
|
|
3794
3778
|
const columns = model.schema.filter((column) => column.name !== "id");
|
|
3795
3779
|
const placeholder = columns.map(({ name }) => `@${name}`).join(", ");
|
|
3780
|
+
const prefixedColumns = new Set(
|
|
3781
|
+
columns.filter((col) => col.prefix).map((col) => col.name)
|
|
3782
|
+
);
|
|
3796
3783
|
const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${columns.map((column) => column.name).join(", ")}) VALUES (${placeholder})`;
|
|
3797
3784
|
const insert = db.prepare(prepareStatement);
|
|
3798
3785
|
const insertLines = db.transaction((lines) => {
|
|
@@ -3806,7 +3793,7 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
3806
3793
|
line
|
|
3807
3794
|
).map(([columnName, value]) => [
|
|
3808
3795
|
columnName,
|
|
3809
|
-
|
|
3796
|
+
prefixedColumns.has(columnName) && value !== null ? `${task.prefix}${value}` : value
|
|
3810
3797
|
])
|
|
3811
3798
|
);
|
|
3812
3799
|
insert.run(prefixedLine);
|