@bytebrand/export-cars 1.26.22 → 1.26.24
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/transformers/google-feed-envkv.d.ts +2 -0
- package/dist/transformers/google-feed-envkv.js +25 -3
- package/dist/transformers/google-feed-envkv.js.map +1 -1
- package/dist/transformers/google.transformer.d.ts +0 -2
- package/dist/transformers/google.transformer.js +2 -19
- package/dist/transformers/google.transformer.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +63 -63
- package/src/transformers/google-feed-envkv.ts +32 -3
- package/src/transformers/google.transformer.ts +10 -21
- package/test/google-feed-envkv.test.ts +44 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@bytebrand/export-cars",
|
|
3
|
-
"version": "1.26.
|
|
4
|
-
"description": "",
|
|
5
|
-
"author": "bytebrand",
|
|
6
|
-
"license": "UNLICENSED",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"prebuild": "rimraf dist",
|
|
9
|
-
"build": "nest build",
|
|
10
|
-
"prepublishOnly": "npm run build",
|
|
11
|
-
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
12
|
-
"lint": "eslint -c .eslintrc.js --ext .ts src/",
|
|
13
|
-
"start:dev": "nest start --watch",
|
|
14
|
-
"test": "ts-node --transpile-only test/google-feed-envkv.test.ts"
|
|
15
|
-
},
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"@bytebrand/autode-request": "^1.19.2",
|
|
18
|
-
"@bytebrand/car-basic-data-scope": "^9.11.24",
|
|
19
|
-
"@bytebrand/car-description": "^1.17.20",
|
|
20
|
-
"@bytebrand/car-schema": "^3.14.15",
|
|
21
|
-
"@bytebrand/chunkable": "^5.19.8",
|
|
22
|
-
"@bytebrand/cronicle-helper": "^1.21.8",
|
|
23
|
-
"@bytebrand/fe-financing": "^5.14.19",
|
|
24
|
-
"@bytebrand/i18n-dictionaries": "^1.5.0",
|
|
25
|
-
"@bytebrand/import-helper": "^0.45.0",
|
|
26
|
-
"@bytebrand/schema-tools": "^3.18.8",
|
|
27
|
-
"@bytebrand/zipper": "^2.2.0",
|
|
28
|
-
"@nestjs/cache-manager": "^2.1.0",
|
|
29
|
-
"@nestjs/common": "^10.2.7",
|
|
30
|
-
"@nestjs/core": "^10.2.7",
|
|
31
|
-
"axios": "^1.5.1",
|
|
32
|
-
"bottleneck": "^2.19.5",
|
|
33
|
-
"cache-manager": "^5.2.4",
|
|
34
|
-
"csv-write-stream": "^2.0.0",
|
|
35
|
-
"google-spreadsheet": "^3.3.0",
|
|
36
|
-
"lodash": "^4.17.21",
|
|
37
|
-
"moment": "^2.29.4",
|
|
38
|
-
"nest-commander": "~3.15.0",
|
|
39
|
-
"reflect-metadata": "^0.1.13",
|
|
40
|
-
"vin-generator": "^1.0.1"
|
|
41
|
-
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"@nestjs/cli": "^10.1.18",
|
|
44
|
-
"@types/google-spreadsheet": "^3.3.0",
|
|
45
|
-
"@types/inquirer": "^8.2.4",
|
|
46
|
-
"@types/lodash": "^4.14.186",
|
|
47
|
-
"@types/node": "^16.18.58",
|
|
48
|
-
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
49
|
-
"@typescript-eslint/parser": "^6.8.0",
|
|
50
|
-
"eslint": "^8.0.1",
|
|
51
|
-
"eslint-config-prettier": "^8.3.0",
|
|
52
|
-
"eslint-plugin-prettier": "^4.0.0",
|
|
53
|
-
"gts": "^3.1.1",
|
|
54
|
-
"prettier": "^2.3.2",
|
|
55
|
-
"ts-node": "^10.0.0",
|
|
56
|
-
"tsconfig-paths": "4.1.0",
|
|
57
|
-
"typescript": "^5.2.2"
|
|
58
|
-
},
|
|
59
|
-
"engines": {
|
|
60
|
-
"node": ">=14.0.0"
|
|
61
|
-
},
|
|
62
|
-
"gitHead": "e827f35865032821bf3a081f03a026d3d3f8a540"
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@bytebrand/export-cars",
|
|
3
|
+
"version": "1.26.24",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": "bytebrand",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"prebuild": "rimraf dist",
|
|
9
|
+
"build": "nest build",
|
|
10
|
+
"prepublishOnly": "npm run build",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
12
|
+
"lint": "eslint -c .eslintrc.js --ext .ts src/",
|
|
13
|
+
"start:dev": "nest start --watch",
|
|
14
|
+
"test": "ts-node --transpile-only test/google-feed-envkv.test.ts"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@bytebrand/autode-request": "^1.19.2",
|
|
18
|
+
"@bytebrand/car-basic-data-scope": "^9.11.24",
|
|
19
|
+
"@bytebrand/car-description": "^1.17.20",
|
|
20
|
+
"@bytebrand/car-schema": "^3.14.15",
|
|
21
|
+
"@bytebrand/chunkable": "^5.19.8",
|
|
22
|
+
"@bytebrand/cronicle-helper": "^1.21.8",
|
|
23
|
+
"@bytebrand/fe-financing": "^5.14.19",
|
|
24
|
+
"@bytebrand/i18n-dictionaries": "^1.5.0",
|
|
25
|
+
"@bytebrand/import-helper": "^0.45.0",
|
|
26
|
+
"@bytebrand/schema-tools": "^3.18.8",
|
|
27
|
+
"@bytebrand/zipper": "^2.2.0",
|
|
28
|
+
"@nestjs/cache-manager": "^2.1.0",
|
|
29
|
+
"@nestjs/common": "^10.2.7",
|
|
30
|
+
"@nestjs/core": "^10.2.7",
|
|
31
|
+
"axios": "^1.5.1",
|
|
32
|
+
"bottleneck": "^2.19.5",
|
|
33
|
+
"cache-manager": "^5.2.4",
|
|
34
|
+
"csv-write-stream": "^2.0.0",
|
|
35
|
+
"google-spreadsheet": "^3.3.0",
|
|
36
|
+
"lodash": "^4.17.21",
|
|
37
|
+
"moment": "^2.29.4",
|
|
38
|
+
"nest-commander": "~3.15.0",
|
|
39
|
+
"reflect-metadata": "^0.1.13",
|
|
40
|
+
"vin-generator": "^1.0.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@nestjs/cli": "^10.1.18",
|
|
44
|
+
"@types/google-spreadsheet": "^3.3.0",
|
|
45
|
+
"@types/inquirer": "^8.2.4",
|
|
46
|
+
"@types/lodash": "^4.14.186",
|
|
47
|
+
"@types/node": "^16.18.58",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
49
|
+
"@typescript-eslint/parser": "^6.8.0",
|
|
50
|
+
"eslint": "^8.0.1",
|
|
51
|
+
"eslint-config-prettier": "^8.3.0",
|
|
52
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
53
|
+
"gts": "^3.1.1",
|
|
54
|
+
"prettier": "^2.3.2",
|
|
55
|
+
"ts-node": "^10.0.0",
|
|
56
|
+
"tsconfig-paths": "4.1.0",
|
|
57
|
+
"typescript": "^5.2.2"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=14.0.0"
|
|
61
|
+
},
|
|
62
|
+
"gitHead": "e827f35865032821bf3a081f03a026d3d3f8a540"
|
|
63
|
+
}
|
|
@@ -47,17 +47,46 @@ export function googleElectricRange(car: DataSchemes.Car): string | undefined {
|
|
|
47
47
|
return range ? `${range}km` : undefined;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
// Plug-in hybrids: Google and Pkw-EnVKV (CoC 49.4) want the WEIGHTED combined values for fuel,
|
|
51
|
+
// electricity and CO2, and the fuel consumption with a DISCHARGED battery separately. In CBD those
|
|
52
|
+
// are wltpWeightedCombined, wltpWeightedPowerCombined, wltpCo2 (weighted for a plug-in) and
|
|
53
|
+
// wltpCombined (discharged for a plug-in); the legacy consumptionCombined / co2 are only a fallback.
|
|
54
|
+
|
|
50
55
|
// Missing or 0 is omitted instead of sending "0l/100km". BEVs carry no fuel consumption
|
|
51
56
|
// (CBD mirrors kWh into consumptionCombined for them).
|
|
52
57
|
export function googleFuelConsumption(car: DataSchemes.Car): string | undefined {
|
|
53
58
|
if (isBev(car)) return undefined;
|
|
54
|
-
const value =
|
|
59
|
+
const value = isPlugIn(car)
|
|
60
|
+
? positive(get(car, 'consumption.wltpWeightedCombined')) ?? positive(get(car, 'consumption.consumptionCombined'))
|
|
61
|
+
: positive(get(car, 'consumption.consumptionCombined'));
|
|
55
62
|
return value ? `${value}l/100km` : undefined;
|
|
56
63
|
}
|
|
57
64
|
|
|
58
|
-
//
|
|
65
|
+
// Plug-in only. No fallback: the legacy combined value is (close to) the weighted one, sending it
|
|
66
|
+
// here would repeat the weighted figure as the discharged one.
|
|
67
|
+
export function googleFuelConsumptionDischarged(car: DataSchemes.Car): string | undefined {
|
|
68
|
+
if (!isPlugIn(car)) return undefined;
|
|
69
|
+
const value = positive(get(car, 'consumption.wltpCombined'));
|
|
70
|
+
return value ? `${value}l/100km` : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// BEV: combined consumption. Plug-in: weighted combined. Nothing for other cars.
|
|
74
|
+
export function googleEnergyConsumption(car: DataSchemes.Car): string | undefined {
|
|
75
|
+
let value: number | undefined;
|
|
76
|
+
if (isBev(car)) {
|
|
77
|
+
value = positive(get(car, 'consumption.wltpPowerCombined')) ?? positive(get(car, 'consumption.consumptionPowerCombined'));
|
|
78
|
+
} else if (isPlugIn(car)) {
|
|
79
|
+
value = positive(get(car, 'consumption.wltpWeightedPowerCombined'));
|
|
80
|
+
}
|
|
81
|
+
return value ? `${value}kWh/100km` : undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// A BEV emits 0 g/km by definition; a plug-in sends the weighted WLTP CO2; for every other car the
|
|
85
|
+
// stored value. A missing or 0 value is omitted.
|
|
59
86
|
export function googleCo2(car: DataSchemes.Car): string | undefined {
|
|
60
87
|
if (isBev(car)) return '0g/km';
|
|
61
|
-
const value =
|
|
88
|
+
const value = isPlugIn(car)
|
|
89
|
+
? positive(get(car, 'environmentEmissions.wltpCo2')) ?? positive(get(car, 'environmentEmissions.co2'))
|
|
90
|
+
: positive(get(car, 'environmentEmissions.co2'));
|
|
62
91
|
return value ? `${value}g/km` : undefined;
|
|
63
92
|
}
|
|
@@ -8,7 +8,14 @@ import { Injectable } from '@nestjs/common';
|
|
|
8
8
|
import { ConfigService, ImagesService, MappingService, TransformerService, UserService } from '../services';
|
|
9
9
|
import { GoogleXmlItem } from '../interfaces';
|
|
10
10
|
import { isValidVin } from '../utils';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
googleCo2,
|
|
13
|
+
googleElectricRange,
|
|
14
|
+
googleEnergyConsumption,
|
|
15
|
+
googleEngine,
|
|
16
|
+
googleFuelConsumption,
|
|
17
|
+
googleFuelConsumptionDischarged,
|
|
18
|
+
} from './google-feed-envkv';
|
|
12
19
|
import {
|
|
13
20
|
META_PUSH_PRIORITY_ALLOWED_VALUES,
|
|
14
21
|
META_PUSH_PRIORITY_STANDARD,
|
|
@@ -93,9 +100,9 @@ export class GoogleTransformer {
|
|
|
93
100
|
capacity: this.getCapacity(car),
|
|
94
101
|
date_first_registered: this.getDateFirstRegistered(car),
|
|
95
102
|
fuel_consumption: googleFuelConsumption(car),
|
|
96
|
-
energy_consumption:
|
|
103
|
+
energy_consumption: googleEnergyConsumption(car),
|
|
97
104
|
electric_range: googleElectricRange(car),
|
|
98
|
-
fuel_consumption_discharged_battery:
|
|
105
|
+
fuel_consumption_discharged_battery: googleFuelConsumptionDischarged(car),
|
|
99
106
|
co2_emissions: googleCo2(car),
|
|
100
107
|
description: this.processText((await this.getDescription(car))),
|
|
101
108
|
identifier_exists: 'yes',
|
|
@@ -332,26 +339,8 @@ export class GoogleTransformer {
|
|
|
332
339
|
return certifications.length ? certifications : undefined;
|
|
333
340
|
}
|
|
334
341
|
|
|
335
|
-
private getEnergyConsumption(car: DataSchemes.Car): string | undefined {
|
|
336
|
-
const fuel = get(car, 'consumption.fuel');
|
|
337
|
-
const isElectricOrHybrid =
|
|
338
|
-
['selector_fuel_electrical', 'selector_fuel_hybridElectricalPetrol', 'selector_fuel_hybridElectricalDiesel'].includes(fuel) ||
|
|
339
|
-
!!get(car, 'engineData.hybridPlugin');
|
|
340
|
-
if (!isElectricOrHybrid) {
|
|
341
|
-
return undefined;
|
|
342
|
-
}
|
|
343
|
-
const power = get(car, 'consumption.wltpPowerCombined') || get(car, 'consumption.consumptionPowerCombined');
|
|
344
|
-
return power ? `${power}kWh/100km` : undefined;
|
|
345
|
-
}
|
|
346
342
|
|
|
347
343
|
|
|
348
|
-
private getFuelConsumptionDischargedBattery(car: DataSchemes.Car): string | undefined {
|
|
349
|
-
if (!get(car, 'engineData.hybridPlugin')) {
|
|
350
|
-
return undefined;
|
|
351
|
-
}
|
|
352
|
-
const consumption = get(car, 'consumption.consumptionCombined') || get(car, 'consumption.wltpCombined');
|
|
353
|
-
return consumption ? `${consumption}l/100km` : undefined;
|
|
354
|
-
}
|
|
355
344
|
|
|
356
345
|
private getInstallment(car: DataSchemes.Car) {
|
|
357
346
|
const monthlyInstallment = round(get(car, 'rate.monthlyInstallment', null));
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// Run: npm test (ts-node, no test framework needed)
|
|
2
2
|
import * as assert from 'node:assert/strict';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
googleCo2,
|
|
5
|
+
googleElectricRange,
|
|
6
|
+
googleEnergyConsumption,
|
|
7
|
+
googleEngine,
|
|
8
|
+
googleFuelConsumption,
|
|
9
|
+
googleFuelConsumptionDischarged,
|
|
10
|
+
} from '../src/transformers/google-feed-envkv';
|
|
4
11
|
|
|
5
12
|
const car = (fuel: string, extra: Record<string, unknown> = {}): any => ({
|
|
6
13
|
consumption: { fuel, ...(extra.consumption as object) },
|
|
@@ -56,6 +63,42 @@ const cases: Array<[string, () => void]> = [
|
|
|
56
63
|
assert.equal(googleCo2(car('selector_fuel_petrol', { environmentEmissions: { co2: 0 } })), undefined);
|
|
57
64
|
assert.equal(googleCo2(car('selector_fuel_petrol', { environmentEmissions: { co2: 144 } })), '144g/km');
|
|
58
65
|
}],
|
|
66
|
+
['plug-in: weighted fuel, discharged fuel, weighted electricity and weighted CO2', () => {
|
|
67
|
+
const phev = car('selector_fuel_hybridElectricalPetrol', {
|
|
68
|
+
hybridPlugin: true,
|
|
69
|
+
consumption: { consumptionCombined: 1.4, wltpCombined: 6.3, wltpWeightedCombined: 1.2, wltpPowerCombined: 19.3, wltpWeightedPowerCombined: 17.3 },
|
|
70
|
+
environmentEmissions: { co2: 121, wltpCo2: 28 },
|
|
71
|
+
});
|
|
72
|
+
assert.equal(googleFuelConsumption(phev), '1.2l/100km');
|
|
73
|
+
assert.equal(googleFuelConsumptionDischarged(phev), '6.3l/100km');
|
|
74
|
+
assert.equal(googleEnergyConsumption(phev), '17.3kWh/100km');
|
|
75
|
+
assert.equal(googleCo2(phev), '28g/km');
|
|
76
|
+
}],
|
|
77
|
+
['plug-in without weighted values falls back to the legacy combined ones, never the pure-electric value', () => {
|
|
78
|
+
const phev = car('selector_fuel_hybridElectricalPetrol', {
|
|
79
|
+
hybridPlugin: true,
|
|
80
|
+
consumption: { consumptionCombined: 1.4, wltpPowerCombined: 19.3 },
|
|
81
|
+
environmentEmissions: { co2: 32 },
|
|
82
|
+
});
|
|
83
|
+
assert.equal(googleFuelConsumption(phev), '1.4l/100km');
|
|
84
|
+
assert.equal(googleFuelConsumptionDischarged(phev), undefined);
|
|
85
|
+
assert.equal(googleEnergyConsumption(phev), undefined);
|
|
86
|
+
assert.equal(googleCo2(phev), '32g/km');
|
|
87
|
+
}],
|
|
88
|
+
['non-plug-in hybrids and combustion cars keep the stored values and send no electricity', () => {
|
|
89
|
+
const hev = car('selector_fuel_hybridElectricalPetrol', {
|
|
90
|
+
consumption: { consumptionCombined: 5.1, wltpCombined: 5.3, wltpWeightedCombined: 2.3, wltpWeightedPowerCombined: 21.5 },
|
|
91
|
+
environmentEmissions: { co2: 116, wltpCo2: 119 },
|
|
92
|
+
});
|
|
93
|
+
assert.equal(googleFuelConsumption(hev), '5.1l/100km');
|
|
94
|
+
assert.equal(googleFuelConsumptionDischarged(hev), undefined);
|
|
95
|
+
assert.equal(googleEnergyConsumption(hev), undefined);
|
|
96
|
+
assert.equal(googleCo2(hev), '116g/km');
|
|
97
|
+
}],
|
|
98
|
+
['BEV energy consumption is the combined value', () => {
|
|
99
|
+
assert.equal(googleEnergyConsumption(car('selector_fuel_electrical', { consumption: { wltpPowerCombined: 16.5 } })), '16.5kWh/100km');
|
|
100
|
+
assert.equal(googleEnergyConsumption(car('selector_fuel_electrical', { consumption: { consumptionPowerCombined: 18 } })), '18kWh/100km');
|
|
101
|
+
}],
|
|
59
102
|
];
|
|
60
103
|
|
|
61
104
|
let failed = 0;
|