@bytebrand/export-cars 1.26.16 → 1.26.18
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/configs/config.d.ts +1 -0
- package/dist/configs/config.js +1 -0
- package/dist/configs/config.js.map +1 -1
- package/dist/configs/facebook-shop.config.js +2 -0
- package/dist/configs/facebook-shop.config.js.map +1 -1
- package/dist/configs/fb.config.js +2 -0
- package/dist/configs/fb.config.js.map +1 -1
- package/dist/configs/google.config.js +2 -0
- package/dist/configs/google.config.js.map +1 -1
- package/dist/constants/feed-price.constants.d.ts +1 -0
- package/dist/constants/feed-price.constants.js +5 -0
- package/dist/constants/feed-price.constants.js.map +1 -0
- package/dist/exporters/facebook-shop.exporter.js +1 -1
- package/dist/exporters/facebook-shop.exporter.js.map +1 -1
- package/dist/services/car.service.d.ts +3 -1
- package/dist/services/car.service.js +14 -2
- package/dist/services/car.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +62 -62
- package/src/configs/config.ts +4 -0
- package/src/configs/facebook-shop.config.ts +2 -0
- package/src/configs/fb.config.ts +2 -0
- package/src/configs/google.config.ts +2 -0
- package/src/constants/feed-price.constants.ts +4 -0
- package/src/exporters/facebook-shop.exporter.ts +3 -1
- package/src/services/car.service.ts +13 -0
- package/src/transformers/facebook-shop.transformer.ts +3 -3
package/package.json
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
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
|
-
},
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@bytebrand/autode-request": "^1.19.2",
|
|
17
|
-
"@bytebrand/car-basic-data-scope": "^9.11.24",
|
|
18
|
-
"@bytebrand/car-description": "^1.17.20",
|
|
19
|
-
"@bytebrand/car-schema": "^3.14.15",
|
|
20
|
-
"@bytebrand/chunkable": "^5.19.8",
|
|
21
|
-
"@bytebrand/cronicle-helper": "^1.21.8",
|
|
22
|
-
"@bytebrand/fe-financing": "^5.14.19",
|
|
23
|
-
"@bytebrand/i18n-dictionaries": "^1.5.0",
|
|
24
|
-
"@bytebrand/import-helper": "^0.45.0",
|
|
25
|
-
"@bytebrand/schema-tools": "^3.18.8",
|
|
26
|
-
"@bytebrand/zipper": "^2.2.0",
|
|
27
|
-
"@nestjs/cache-manager": "^2.1.0",
|
|
28
|
-
"@nestjs/common": "^10.2.7",
|
|
29
|
-
"@nestjs/core": "^10.2.7",
|
|
30
|
-
"axios": "^1.5.1",
|
|
31
|
-
"bottleneck": "^2.19.5",
|
|
32
|
-
"cache-manager": "^5.2.4",
|
|
33
|
-
"csv-write-stream": "^2.0.0",
|
|
34
|
-
"google-spreadsheet": "^3.3.0",
|
|
35
|
-
"lodash": "^4.17.21",
|
|
36
|
-
"moment": "^2.29.4",
|
|
37
|
-
"nest-commander": "~3.15.0",
|
|
38
|
-
"reflect-metadata": "^0.1.13",
|
|
39
|
-
"vin-generator": "^1.0.1"
|
|
40
|
-
},
|
|
41
|
-
"devDependencies": {
|
|
42
|
-
"@nestjs/cli": "^10.1.18",
|
|
43
|
-
"@types/google-spreadsheet": "^3.3.0",
|
|
44
|
-
"@types/inquirer": "^8.2.4",
|
|
45
|
-
"@types/lodash": "^4.14.186",
|
|
46
|
-
"@types/node": "^16.18.58",
|
|
47
|
-
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
48
|
-
"@typescript-eslint/parser": "^6.8.0",
|
|
49
|
-
"eslint": "^8.0.1",
|
|
50
|
-
"eslint-config-prettier": "^8.3.0",
|
|
51
|
-
"eslint-plugin-prettier": "^4.0.0",
|
|
52
|
-
"gts": "^3.1.1",
|
|
53
|
-
"prettier": "^2.3.2",
|
|
54
|
-
"ts-node": "^10.0.0",
|
|
55
|
-
"tsconfig-paths": "4.1.0",
|
|
56
|
-
"typescript": "^5.2.2"
|
|
57
|
-
},
|
|
58
|
-
"engines": {
|
|
59
|
-
"node": ">=14.0.0"
|
|
60
|
-
},
|
|
61
|
-
"gitHead": "e827f35865032821bf3a081f03a026d3d3f8a540"
|
|
62
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@bytebrand/export-cars",
|
|
3
|
+
"version": "1.26.18",
|
|
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
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@bytebrand/autode-request": "^1.19.2",
|
|
17
|
+
"@bytebrand/car-basic-data-scope": "^9.11.24",
|
|
18
|
+
"@bytebrand/car-description": "^1.17.20",
|
|
19
|
+
"@bytebrand/car-schema": "^3.14.15",
|
|
20
|
+
"@bytebrand/chunkable": "^5.19.8",
|
|
21
|
+
"@bytebrand/cronicle-helper": "^1.21.8",
|
|
22
|
+
"@bytebrand/fe-financing": "^5.14.19",
|
|
23
|
+
"@bytebrand/i18n-dictionaries": "^1.5.0",
|
|
24
|
+
"@bytebrand/import-helper": "^0.45.0",
|
|
25
|
+
"@bytebrand/schema-tools": "^3.18.8",
|
|
26
|
+
"@bytebrand/zipper": "^2.2.0",
|
|
27
|
+
"@nestjs/cache-manager": "^2.1.0",
|
|
28
|
+
"@nestjs/common": "^10.2.7",
|
|
29
|
+
"@nestjs/core": "^10.2.7",
|
|
30
|
+
"axios": "^1.5.1",
|
|
31
|
+
"bottleneck": "^2.19.5",
|
|
32
|
+
"cache-manager": "^5.2.4",
|
|
33
|
+
"csv-write-stream": "^2.0.0",
|
|
34
|
+
"google-spreadsheet": "^3.3.0",
|
|
35
|
+
"lodash": "^4.17.21",
|
|
36
|
+
"moment": "^2.29.4",
|
|
37
|
+
"nest-commander": "~3.15.0",
|
|
38
|
+
"reflect-metadata": "^0.1.13",
|
|
39
|
+
"vin-generator": "^1.0.1"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@nestjs/cli": "^10.1.18",
|
|
43
|
+
"@types/google-spreadsheet": "^3.3.0",
|
|
44
|
+
"@types/inquirer": "^8.2.4",
|
|
45
|
+
"@types/lodash": "^4.14.186",
|
|
46
|
+
"@types/node": "^16.18.58",
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
48
|
+
"@typescript-eslint/parser": "^6.8.0",
|
|
49
|
+
"eslint": "^8.0.1",
|
|
50
|
+
"eslint-config-prettier": "^8.3.0",
|
|
51
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
52
|
+
"gts": "^3.1.1",
|
|
53
|
+
"prettier": "^2.3.2",
|
|
54
|
+
"ts-node": "^10.0.0",
|
|
55
|
+
"tsconfig-paths": "4.1.0",
|
|
56
|
+
"typescript": "^5.2.2"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=14.0.0"
|
|
60
|
+
},
|
|
61
|
+
"gitHead": "e827f35865032821bf3a081f03a026d3d3f8a540"
|
|
62
|
+
}
|
package/src/configs/config.ts
CHANGED
|
@@ -23,6 +23,10 @@ export class Config {
|
|
|
23
23
|
numberIN: string;
|
|
24
24
|
dateIN: string;
|
|
25
25
|
};
|
|
26
|
+
// When set, CarService.filterCar exports a car only if price.currentSalesPrice
|
|
27
|
+
// is a valid number in (0, maxCurrentSalesPrice] — missing/invalid price means
|
|
28
|
+
// the car is not exported. Unset = no price cap for this export type.
|
|
29
|
+
maxCurrentSalesPrice?: number;
|
|
26
30
|
pathesConfig: {
|
|
27
31
|
localDirectory: string;
|
|
28
32
|
localConvertedDirectory: string;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Params } from '../interfaces/params.interface';
|
|
2
2
|
import { Config } from './config';
|
|
3
3
|
import { ExportType, FileType } from '../enums';
|
|
4
|
+
import { MAX_FEED_SALES_PRICE_EUR } from '../constants/feed-price.constants';
|
|
4
5
|
|
|
5
6
|
export class FacebookShopConfig extends Config {
|
|
6
7
|
constructor(params: Params) {
|
|
7
8
|
super(params);
|
|
8
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.FACEBOOK_SHOP}-export`;
|
|
10
|
+
this.maxCurrentSalesPrice = MAX_FEED_SALES_PRICE_EUR;
|
|
9
11
|
this.imageUrl = this.environmentConfig[params.environment].baseImageUrl;
|
|
10
12
|
this.outputFiles = [
|
|
11
13
|
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.FACEBOOK_SHOP}.${FileType.XML}`,
|
package/src/configs/fb.config.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExportType, FileType, ImageType } from 'src/enums';
|
|
2
|
+
import { MAX_FEED_SALES_PRICE_EUR } from '../constants/feed-price.constants';
|
|
2
3
|
import { Params } from '../interfaces/params.interface';
|
|
3
4
|
import { Config } from './config';
|
|
4
5
|
|
|
@@ -6,6 +7,7 @@ export class FbConfig extends Config {
|
|
|
6
7
|
constructor(params: Params) {
|
|
7
8
|
super(params);
|
|
8
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.FB}-export`;
|
|
10
|
+
this.maxCurrentSalesPrice = MAX_FEED_SALES_PRICE_EUR;
|
|
9
11
|
this.imageUrl = this.environmentConfig[params.environment].imageUrl;
|
|
10
12
|
this.imageType = ImageType.marketing;
|
|
11
13
|
this.marketingImageConfigId = this.environmentConfig[params.environment].fbMarketingImageId;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExportType, FileType, ImageType } from 'src/enums';
|
|
2
|
+
import { MAX_FEED_SALES_PRICE_EUR } from '../constants/feed-price.constants';
|
|
2
3
|
import { Params } from '../interfaces/params.interface';
|
|
3
4
|
import { Config } from './config';
|
|
4
5
|
|
|
@@ -7,6 +8,7 @@ export class GoogleConfig extends Config {
|
|
|
7
8
|
super(params);
|
|
8
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.GOOGLE}-export`;
|
|
9
10
|
this.imageType = ImageType.default;
|
|
11
|
+
this.maxCurrentSalesPrice = MAX_FEED_SALES_PRICE_EUR;
|
|
10
12
|
this.outputFiles = [
|
|
11
13
|
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.GOOGLE}.${FileType.XML}`,
|
|
12
14
|
];
|
|
@@ -35,7 +35,9 @@ export class FacebookShopExporter implements Exporter {
|
|
|
35
35
|
const chunkData = chunk.data.filter(car => this.carService.filterCar(car, this.rulesService.rules));
|
|
36
36
|
|
|
37
37
|
for (let i = 0; i < chunkData.length; i += 1) {
|
|
38
|
-
|
|
38
|
+
// chunkData, not chunk.data: indexing the unfiltered array here used to
|
|
39
|
+
// re-admit cars that filterCar had just rejected (and drop valid ones).
|
|
40
|
+
const data = chunkData[i];
|
|
39
41
|
|
|
40
42
|
// console.time(`Transform ${data.car._id}`);
|
|
41
43
|
const items = await facebookShopTransformer.transform(data);
|
|
@@ -3,7 +3,9 @@ import { Inject, Injectable } from '@nestjs/common';
|
|
|
3
3
|
import { DataSchemes } from '@bytebrand/car-schema';
|
|
4
4
|
import { Cache } from 'cache-manager';
|
|
5
5
|
import Bottleneck from 'bottleneck';
|
|
6
|
+
import { get, toNumber } from 'lodash';
|
|
6
7
|
import { RequestService } from './request.service';
|
|
8
|
+
import { ConfigService } from './config.service';
|
|
7
9
|
import { DateRule } from '../rules/date.rule';
|
|
8
10
|
import { NumberRule } from '../rules/number.rule';
|
|
9
11
|
import { StringRule } from '../rules/string.rule';
|
|
@@ -17,6 +19,7 @@ export class CarService {
|
|
|
17
19
|
constructor(
|
|
18
20
|
@Inject(CACHE_MANAGER) private cacheManager: Cache,
|
|
19
21
|
private requestService: RequestService,
|
|
22
|
+
private configService: ConfigService,
|
|
20
23
|
) { }
|
|
21
24
|
|
|
22
25
|
private _counter: CarsCounter;
|
|
@@ -33,6 +36,16 @@ export class CarService {
|
|
|
33
36
|
if (!((car?.metaData?.imagesCount ?? 0) > 0)) {
|
|
34
37
|
return false;
|
|
35
38
|
}
|
|
39
|
+
// Shared price cap for export types that set maxCurrentSalesPrice (Google
|
|
40
|
+
// Vehicle Ads, Meta AIA/AMA): the end-customer selling price must be a valid
|
|
41
|
+
// number ≤ the cap; a missing/invalid/non-positive price also excludes the car.
|
|
42
|
+
const maxPrice = this.configService.config.maxCurrentSalesPrice;
|
|
43
|
+
if (maxPrice) {
|
|
44
|
+
const price = toNumber(get(car, 'price.currentSalesPrice', null));
|
|
45
|
+
if (!isFinite(price) || price <= 0 || price > maxPrice) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
36
49
|
return rules.every(e => e.applyRule(car));
|
|
37
50
|
}
|
|
38
51
|
|
|
@@ -98,9 +98,9 @@ export class FacebookShopTransformer {
|
|
|
98
98
|
|
|
99
99
|
return offers.map((offer): FacebookShopItem => ({
|
|
100
100
|
...base,
|
|
101
|
-
// Plain long auto.de ID � the `_${offerType}` suffix (ADV-160, one item per offer) broke
|
|
102
|
-
// matching once only the financing offer is exported; re-add a suffix ONLY if multiple
|
|
103
|
-
// offer types per vehicle are ever exported again.
|
|
101
|
+
// Plain long auto.de ID � the `_${offerType}` suffix (ADV-160, one item per offer) broke
|
|
102
|
+
// matching once only the financing offer is exported; re-add a suffix ONLY if multiple
|
|
103
|
+
// offer types per vehicle are ever exported again.
|
|
104
104
|
vehicle_offer_id: vehicleId,
|
|
105
105
|
title: offer.title,
|
|
106
106
|
offer_description: offer.description,
|