@meterapp/vehicle-db 1.0.0 → 2.0.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/README.md +65 -73
- package/data/compact.json +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -82
- package/dist/index.js.map +1 -1
- package/package.json +5 -8
- package/data/nhtsa.db +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare function getModels(options?: GetModelsOptions): Model[];
|
|
|
40
40
|
*/
|
|
41
41
|
export declare function getAvailableYears(): number[];
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* Clear cached data (optional cleanup, frees memory).
|
|
44
44
|
*/
|
|
45
45
|
export declare function close(): void;
|
|
46
46
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA8CD;;GAEG;AACH,wBAAgB,eAAe,IAAI,WAAW,EAAE,CAK/C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,IAAI,EAAE,CAmB9D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,KAAK,EAAE,CAsBjE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAM5C;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,IAAI,CAI5B"}
|
package/dist/index.js
CHANGED
|
@@ -8,18 +8,32 @@ exports.getMakes = getMakes;
|
|
|
8
8
|
exports.getModels = getModels;
|
|
9
9
|
exports.getAvailableYears = getAvailableYears;
|
|
10
10
|
exports.close = close;
|
|
11
|
-
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
12
11
|
const path_1 = __importDefault(require("path"));
|
|
13
|
-
const
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const DATA_PATH = path_1.default.join(__dirname, "..", "data", "compact.json");
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
|
-
//
|
|
15
|
+
// Lazy-loaded singleton
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
let _data = null;
|
|
18
|
+
let _makeMap = null;
|
|
19
|
+
let _typeMap = null;
|
|
20
|
+
function getData() {
|
|
21
|
+
if (!_data) {
|
|
22
|
+
_data = JSON.parse(fs_1.default.readFileSync(DATA_PATH, "utf-8"));
|
|
21
23
|
}
|
|
22
|
-
return
|
|
24
|
+
return _data;
|
|
25
|
+
}
|
|
26
|
+
function getMakeMap() {
|
|
27
|
+
if (!_makeMap) {
|
|
28
|
+
_makeMap = new Map(getData().makes.map((m) => [m.make_id, m.make_name]));
|
|
29
|
+
}
|
|
30
|
+
return _makeMap;
|
|
31
|
+
}
|
|
32
|
+
function getTypeMap() {
|
|
33
|
+
if (!_typeMap) {
|
|
34
|
+
_typeMap = new Map(getData().vehicleTypes.map((t) => [t.vehicle_type_id, t.vehicle_type_name]));
|
|
35
|
+
}
|
|
36
|
+
return _typeMap;
|
|
23
37
|
}
|
|
24
38
|
// ---------------------------------------------------------------------------
|
|
25
39
|
// Public API
|
|
@@ -28,102 +42,76 @@ function getDb() {
|
|
|
28
42
|
* Returns all vehicle types in the database.
|
|
29
43
|
*/
|
|
30
44
|
function getVehicleTypes() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.
|
|
34
|
-
.all();
|
|
35
|
-
return rows.map((r) => ({
|
|
36
|
-
vehicleTypeId: r.vehicle_type_id,
|
|
37
|
-
vehicleTypeName: r.vehicle_type_name,
|
|
45
|
+
return getData().vehicleTypes.map((t) => ({
|
|
46
|
+
vehicleTypeId: t.vehicle_type_id,
|
|
47
|
+
vehicleTypeName: t.vehicle_type_name,
|
|
38
48
|
}));
|
|
39
49
|
}
|
|
40
50
|
/**
|
|
41
51
|
* Returns makes, optionally filtered by year and/or vehicle type.
|
|
42
52
|
*/
|
|
43
53
|
function getMakes(options = {}) {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
conditions.push("m.year = ?");
|
|
49
|
-
params.push(options.year);
|
|
50
|
-
}
|
|
51
|
-
if (options.vehicleTypeId != null) {
|
|
52
|
-
conditions.push("m.vehicle_type_id = ?");
|
|
53
|
-
params.push(options.vehicleTypeId);
|
|
54
|
-
}
|
|
55
|
-
let sql;
|
|
56
|
-
if (conditions.length > 0) {
|
|
57
|
-
sql = `SELECT DISTINCT mk.make_id, mk.make_name
|
|
58
|
-
FROM models m
|
|
59
|
-
JOIN makes mk USING (make_id)
|
|
60
|
-
WHERE ${conditions.join(" AND ")}
|
|
61
|
-
ORDER BY mk.make_name`;
|
|
54
|
+
const data = getData();
|
|
55
|
+
const { year, vehicleTypeId } = options;
|
|
56
|
+
if (year == null && vehicleTypeId == null) {
|
|
57
|
+
return data.makes.map((m) => ({ makeId: m.make_id, makeName: m.make_name }));
|
|
62
58
|
}
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
const makeIds = new Set();
|
|
60
|
+
for (const m of data.models) {
|
|
61
|
+
if (year != null && m[0] !== year)
|
|
62
|
+
continue;
|
|
63
|
+
if (vehicleTypeId != null && m[4] !== vehicleTypeId)
|
|
64
|
+
continue;
|
|
65
|
+
makeIds.add(m[1]);
|
|
65
66
|
}
|
|
66
|
-
const
|
|
67
|
-
return
|
|
68
|
-
makeId:
|
|
69
|
-
makeName:
|
|
70
|
-
}));
|
|
67
|
+
const makeMap = getMakeMap();
|
|
68
|
+
return [...makeIds]
|
|
69
|
+
.map((id) => ({ makeId: id, makeName: makeMap.get(id) }))
|
|
70
|
+
.sort((a, b) => (a.makeName >= b.makeName ? 1 : -1));
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
73
|
* Returns models, optionally filtered by year, vehicle type, and/or make.
|
|
74
74
|
*/
|
|
75
75
|
function getModels(options = {}) {
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
const data = getData();
|
|
77
|
+
const makeMap = getMakeMap();
|
|
78
|
+
const typeMap = getTypeMap();
|
|
79
|
+
const { year, vehicleTypeId, makeId } = options;
|
|
80
|
+
const results = [];
|
|
81
|
+
for (const m of data.models) {
|
|
82
|
+
if (year != null && m[0] !== year)
|
|
83
|
+
continue;
|
|
84
|
+
if (makeId != null && m[1] !== makeId)
|
|
85
|
+
continue;
|
|
86
|
+
if (vehicleTypeId != null && m[4] !== vehicleTypeId)
|
|
87
|
+
continue;
|
|
88
|
+
results.push({
|
|
89
|
+
modelId: m[2],
|
|
90
|
+
modelName: data.modelNames[m[3]],
|
|
91
|
+
makeId: m[1],
|
|
92
|
+
makeName: makeMap.get(m[1]),
|
|
93
|
+
vehicleTypeId: m[4],
|
|
94
|
+
vehicleTypeName: typeMap.get(m[4]),
|
|
95
|
+
});
|
|
90
96
|
}
|
|
91
|
-
|
|
92
|
-
const sql = `
|
|
93
|
-
SELECT m.model_id, m.model_name, mk.make_id, mk.make_name,
|
|
94
|
-
vt.vehicle_type_id, vt.vehicle_type_name
|
|
95
|
-
FROM models m
|
|
96
|
-
JOIN makes mk USING (make_id)
|
|
97
|
-
JOIN vehicle_types vt USING (vehicle_type_id)
|
|
98
|
-
${where}
|
|
99
|
-
ORDER BY m.model_name`;
|
|
100
|
-
const rows = db.prepare(sql).all(...params);
|
|
101
|
-
return rows.map((r) => ({
|
|
102
|
-
modelId: r.model_id,
|
|
103
|
-
modelName: r.model_name,
|
|
104
|
-
makeId: r.make_id,
|
|
105
|
-
makeName: r.make_name,
|
|
106
|
-
vehicleTypeId: r.vehicle_type_id,
|
|
107
|
-
vehicleTypeName: r.vehicle_type_name,
|
|
108
|
-
}));
|
|
97
|
+
return results.sort((a, b) => (a.modelName >= b.modelName ? 1 : -1));
|
|
109
98
|
}
|
|
110
99
|
/**
|
|
111
100
|
* Get all available years in the database.
|
|
112
101
|
*/
|
|
113
102
|
function getAvailableYears() {
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
.
|
|
117
|
-
|
|
118
|
-
return
|
|
103
|
+
const years = new Set();
|
|
104
|
+
for (const m of getData().models) {
|
|
105
|
+
years.add(m[0]);
|
|
106
|
+
}
|
|
107
|
+
return [...years].sort((a, b) => a - b);
|
|
119
108
|
}
|
|
120
109
|
/**
|
|
121
|
-
*
|
|
110
|
+
* Clear cached data (optional cleanup, frees memory).
|
|
122
111
|
*/
|
|
123
112
|
function close() {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
113
|
+
_data = null;
|
|
114
|
+
_makeMap = null;
|
|
115
|
+
_typeMap = null;
|
|
128
116
|
}
|
|
129
117
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meterapp/vehicle-db",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Offline NHTSA vehicle makes/models database
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Offline NHTSA vehicle makes/models database — zero dependencies",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
|
-
"data/
|
|
9
|
+
"data/compact.json"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build:db": "tsx scripts/build-db.ts",
|
|
@@ -20,18 +20,15 @@
|
|
|
20
20
|
"vehicles",
|
|
21
21
|
"makes",
|
|
22
22
|
"models",
|
|
23
|
-
"offline"
|
|
24
|
-
"sqlite"
|
|
23
|
+
"offline"
|
|
25
24
|
],
|
|
26
25
|
"author": "",
|
|
27
26
|
"license": "ISC",
|
|
28
27
|
"type": "commonjs",
|
|
29
|
-
"dependencies": {
|
|
30
|
-
"better-sqlite3": "^12.6.2"
|
|
31
|
-
},
|
|
32
28
|
"devDependencies": {
|
|
33
29
|
"@types/better-sqlite3": "^7.6.13",
|
|
34
30
|
"@types/node": "^25.4.0",
|
|
31
|
+
"better-sqlite3": "^12.6.2",
|
|
35
32
|
"tsx": "^4.21.0",
|
|
36
33
|
"typescript": "^5.9.3",
|
|
37
34
|
"vitest": "^4.0.18"
|
package/data/nhtsa.db
DELETED
|
Binary file
|