store-scrapper-js-common 1.0.86 → 1.0.90

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.
Files changed (48) hide show
  1. package/dist/dto/telegram-queue-command.dto.d.ts +17 -0
  2. package/dist/dto/telegram-queue-command.dto.js +7 -0
  3. package/dist/dto/telegram-queue-command.dto.js.map +1 -0
  4. package/dist/entities/price.d.ts +2 -0
  5. package/dist/entities/price.js +8 -0
  6. package/dist/entities/price.js.map +1 -1
  7. package/dist/entities/product.d.ts +8 -2
  8. package/dist/entities/product.js +7 -1
  9. package/dist/entities/product.js.map +1 -1
  10. package/dist/enums/index.d.ts +3 -1
  11. package/dist/enums/index.js +5 -1
  12. package/dist/enums/index.js.map +1 -1
  13. package/dist/enums/telegram-client.enum.d.ts +4 -0
  14. package/dist/enums/telegram-client.enum.js +9 -0
  15. package/dist/enums/telegram-client.enum.js.map +1 -0
  16. package/dist/enums/telegram-queue-command.enum.d.ts +3 -0
  17. package/dist/enums/telegram-queue-command.enum.js +8 -0
  18. package/dist/enums/telegram-queue-command.enum.js.map +1 -0
  19. package/dist/enums/telegram-queue.enum.d.ts +8 -0
  20. package/dist/enums/telegram-queue.enum.js +13 -0
  21. package/dist/enums/telegram-queue.enum.js.map +1 -0
  22. package/dist/utils/array-utils.d.ts +3 -0
  23. package/dist/utils/array-utils.js +22 -0
  24. package/dist/utils/array-utils.js.map +1 -0
  25. package/dist/utils/number-utils.d.ts +1 -0
  26. package/dist/utils/number-utils.js +8 -1
  27. package/dist/utils/number-utils.js.map +1 -1
  28. package/dist/utils/product.utils.d.ts +3 -0
  29. package/dist/utils/product.utils.js +16 -0
  30. package/dist/utils/product.utils.js.map +1 -0
  31. package/dist/utils/string-formatter.d.ts +4 -0
  32. package/dist/utils/string-formatter.js +64 -0
  33. package/dist/utils/string-formatter.js.map +1 -0
  34. package/package.json +2 -1
  35. package/src/dto/telegram-queue-command.dto.ts +23 -0
  36. package/src/entities/price.ts +6 -0
  37. package/src/entities/product.ts +9 -1
  38. package/src/enums/index.ts +3 -1
  39. package/src/enums/telegram-client.enum.ts +4 -0
  40. package/src/enums/telegram-queue-command.enum.ts +3 -0
  41. package/src/enums/telegram-queue.enum.ts +8 -0
  42. package/src/utils/array-utils.ts +23 -0
  43. package/src/utils/number-utils.ts +10 -0
  44. package/src/utils/product.utils.ts +18 -0
  45. package/src/utils/string-formatter.ts +49 -0
  46. package/tests/utils/array-utils.test.ts +34 -0
  47. package/tests/utils/product-utils.test.ts +21 -0
  48. package/tests/utils/string-formatter.test.ts +37 -0
@@ -0,0 +1,17 @@
1
+ import { ObjectLiteral } from '../classes';
2
+ import { TelegramQueueCommandEnum } from '../enums/telegram-queue-command.enum';
3
+ export declare const enum TelegramMessageType {
4
+ MESSAGE = "message",
5
+ IMAGE = "image"
6
+ }
7
+ export declare class TelegramQueueCommandDto {
8
+ message: string;
9
+ telegramChatId: string | number;
10
+ options?: {
11
+ [key: string]: any;
12
+ };
13
+ namedJob?: TelegramQueueCommandEnum;
14
+ telegramClientId: string;
15
+ type?: TelegramMessageType;
16
+ imageOpts?: ObjectLiteral;
17
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelegramQueueCommandDto = void 0;
4
+ class TelegramQueueCommandDto {
5
+ }
6
+ exports.TelegramQueueCommandDto = TelegramQueueCommandDto;
7
+ //# sourceMappingURL=telegram-queue-command.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-queue-command.dto.js","sourceRoot":"/","sources":["dto/telegram-queue-command.dto.ts"],"names":[],"mappings":";;;AAQA,MAAa,uBAAuB;CAcnC;AAdD,0DAcC","sourcesContent":["import { ObjectLiteral } from '../classes';\nimport { TelegramQueueCommandEnum } from '../enums/telegram-queue-command.enum';\n\nexport const enum TelegramMessageType {\n MESSAGE = 'message',\n IMAGE = 'image',\n}\n\nexport class TelegramQueueCommandDto {\n message: string;\n\n telegramChatId: string | number;\n\n options?: { [key: string]: any };\n\n namedJob?: TelegramQueueCommandEnum;\n\n telegramClientId: string;\n\n type?: TelegramMessageType;\n\n imageOpts?: ObjectLiteral;\n}\n"]}
@@ -14,5 +14,7 @@ export declare class Price extends AbstractBase {
14
14
  sourceUrl?: string;
15
15
  unitMultiplier?: number;
16
16
  measurementUnit?: MeasurementUnitEnum;
17
+ validFrom?: Date;
18
+ validTo?: Date;
17
19
  createdAt?: Date;
18
20
  }
@@ -62,6 +62,14 @@ __decorate([
62
62
  class_validator_1.IsOptional(),
63
63
  __metadata("design:type", String)
64
64
  ], Price.prototype, "measurementUnit", void 0);
65
+ __decorate([
66
+ typeorm_1.Column(),
67
+ __metadata("design:type", Date)
68
+ ], Price.prototype, "validFrom", void 0);
69
+ __decorate([
70
+ typeorm_1.Column(),
71
+ __metadata("design:type", Date)
72
+ ], Price.prototype, "validTo", void 0);
65
73
  __decorate([
66
74
  typeorm_1.CreateDateColumn(),
67
75
  typeorm_1.Index(),
@@ -1 +1 @@
1
- {"version":3,"file":"price.js","sourceRoot":"/","sources":["entities/price.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAEiB;AACjB,qDAAmE;AACnE,mDAA+C;AAE/C,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC3B,gCAAS,CAAA;IACT,8BAAO,CAAA;IACP,8BAAO,CAAA;IACP,gCAAS,CAAA;IACT,oCAAa,CAAA;AACjB,CAAC,EANW,mBAAmB,GAAnB,2BAAmB,KAAnB,2BAAmB,QAM9B;AAGD,IAAa,KAAK,GAAlB,MAAa,KAAM,SAAQ,4BAAY;CAoCtC,CAAA;AAhCG;IAHC,gBAAM,EAAE;IACR,4BAAU,EAAE;IACZ,eAAK,EAAE;;yCACW;AAKnB;IAHC,gBAAM,EAAE;IACR,0BAAQ,EAAE;IACV,4BAAU,EAAE;;0CACQ;AAKrB;IAHC,gBAAM,EAAE;IACR,0BAAQ,EAAE;IACV,4BAAU,EAAE;;yCACO;AAKpB;IAHC,gBAAM,EAAE;IACR,0BAAQ,EAAE;IACV,4BAAU,EAAE;;wCACM;AAInB;IAFC,gBAAM,EAAE;IACR,4BAAU,EAAE;;wCACM;AAInB;IAFC,gBAAM,EAAE;IACR,4BAAU,EAAE;;6CACW;AAIxB;IAFC,gBAAM,EAAE;IACR,4BAAU,EAAE;;8CACyB;AAItC;IAFC,0BAAgB,EAAE;IAClB,eAAK,EAAE;8BACI,IAAI;wCAAC;AAnCR,KAAK;IADjB,gBAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;GACd,KAAK,CAoCjB;AApCY,sBAAK","sourcesContent":["import {\n Column, CreateDateColumn, Entity, Index,\n} from 'typeorm';\nimport { IsNotEmpty, IsNumber, IsOptional } from 'class-validator';\nimport { AbstractBase } from './abstract-base';\n\nexport enum MeasurementUnitEnum {\n KG = 'kg',\n G = 'g',\n L = 'l',\n ML = 'ml',\n UNIT = 'unit'\n}\n\n@Entity({ name: 'prices' })\nexport class Price extends AbstractBase {\n @Column()\n @IsNotEmpty()\n @Index()\n productRef: string;\n\n @Column()\n @IsNumber()\n @IsOptional()\n normalPrice?: number;\n\n @Column()\n @IsNumber()\n @IsOptional()\n offerPrice?: number;\n\n @Column()\n @IsNumber()\n @IsOptional()\n cardPrice?: number;\n\n @Column()\n @IsOptional()\n sourceUrl?: string;\n\n @Column()\n @IsOptional()\n unitMultiplier?: number;\n\n @Column()\n @IsOptional()\n measurementUnit?: MeasurementUnitEnum;\n\n @CreateDateColumn()\n @Index()\n createdAt?: Date;\n}\n"]}
1
+ {"version":3,"file":"price.js","sourceRoot":"/","sources":["entities/price.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAEiB;AACjB,qDAAmE;AACnE,mDAA+C;AAE/C,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC3B,gCAAS,CAAA;IACT,8BAAO,CAAA;IACP,8BAAO,CAAA;IACP,gCAAS,CAAA;IACT,oCAAa,CAAA;AACjB,CAAC,EANW,mBAAmB,GAAnB,2BAAmB,KAAnB,2BAAmB,QAM9B;AAGD,IAAa,KAAK,GAAlB,MAAa,KAAM,SAAQ,4BAAY;CA0CtC,CAAA;AAtCG;IAHC,gBAAM,EAAE;IACR,4BAAU,EAAE;IACZ,eAAK,EAAE;;yCACW;AAKnB;IAHC,gBAAM,EAAE;IACR,0BAAQ,EAAE;IACV,4BAAU,EAAE;;0CACQ;AAKrB;IAHC,gBAAM,EAAE;IACR,0BAAQ,EAAE;IACV,4BAAU,EAAE;;yCACO;AAKpB;IAHC,gBAAM,EAAE;IACR,0BAAQ,EAAE;IACV,4BAAU,EAAE;;wCACM;AAInB;IAFC,gBAAM,EAAE;IACR,4BAAU,EAAE;;wCACM;AAInB;IAFC,gBAAM,EAAE;IACR,4BAAU,EAAE;;6CACW;AAIxB;IAFC,gBAAM,EAAE;IACR,4BAAU,EAAE;;8CACyB;AAGtC;IADC,gBAAM,EAAE;8BACG,IAAI;wCAAC;AAGjB;IADC,gBAAM,EAAE;8BACC,IAAI;sCAAC;AAIf;IAFC,0BAAgB,EAAE;IAClB,eAAK,EAAE;8BACI,IAAI;wCAAC;AAzCR,KAAK;IADjB,gBAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;GACd,KAAK,CA0CjB;AA1CY,sBAAK","sourcesContent":["import {\n Column, CreateDateColumn, Entity, Index,\n} from 'typeorm';\nimport { IsNotEmpty, IsNumber, IsOptional } from 'class-validator';\nimport { AbstractBase } from './abstract-base';\n\nexport enum MeasurementUnitEnum {\n KG = 'kg',\n G = 'g',\n L = 'l',\n ML = 'ml',\n UNIT = 'unit'\n}\n\n@Entity({ name: 'prices' })\nexport class Price extends AbstractBase {\n @Column()\n @IsNotEmpty()\n @Index()\n productRef: string;\n\n @Column()\n @IsNumber()\n @IsOptional()\n normalPrice?: number;\n\n @Column()\n @IsNumber()\n @IsOptional()\n offerPrice?: number;\n\n @Column()\n @IsNumber()\n @IsOptional()\n cardPrice?: number;\n\n @Column()\n @IsOptional()\n sourceUrl?: string;\n\n @Column()\n @IsOptional()\n unitMultiplier?: number;\n\n @Column()\n @IsOptional()\n measurementUnit?: MeasurementUnitEnum;\n\n @Column()\n validFrom?: Date;\n\n @Column()\n validTo?: Date;\n\n @CreateDateColumn()\n @Index()\n createdAt?: Date;\n}\n"]}
@@ -21,8 +21,10 @@ export declare enum UpdateReasonEnum {
21
21
  NEW_CONDITIONAL_PRICE = "new_conditional_price",
22
22
  NEW_NAME = "new_name",
23
23
  NEW_LISTING = "new_listing",
24
+ NEW_STOCK = "new_stock",
24
25
  MISSING_DATA = "missing_data",
25
- FIX_DATA = "fix_data"
26
+ FIX_DATA = "fix_data",
27
+ RE_LISTING = "re_listing"
26
28
  }
27
29
  export interface ProductAttributes {
28
30
  stock?: number;
@@ -61,6 +63,10 @@ export declare class Product extends AbstractBase {
61
63
  category?: string;
62
64
  categoryPath?: string;
63
65
  attributes?: ProductAttributes;
66
+ stockHistory?: {
67
+ stock: number;
68
+ updatedAt: string;
69
+ }[];
64
70
  homeDeliveryShipping?: boolean;
65
71
  pickUpFromStoreShipping?: boolean;
66
72
  fastDelivery?: boolean;
@@ -74,7 +80,7 @@ export declare class Product extends AbstractBase {
74
80
  isMarketplace?: boolean;
75
81
  addToCartLink?: string;
76
82
  currency?: CurrencyEnum;
77
- updateReason?: UpdateReasonEnum;
83
+ updateReason?: UpdateReasonEnum[];
78
84
  nameHistory?: {
79
85
  name: string;
80
86
  updatedAt: string;
@@ -36,8 +36,10 @@ var UpdateReasonEnum;
36
36
  UpdateReasonEnum["NEW_CONDITIONAL_PRICE"] = "new_conditional_price";
37
37
  UpdateReasonEnum["NEW_NAME"] = "new_name";
38
38
  UpdateReasonEnum["NEW_LISTING"] = "new_listing";
39
+ UpdateReasonEnum["NEW_STOCK"] = "new_stock";
39
40
  UpdateReasonEnum["MISSING_DATA"] = "missing_data";
40
41
  UpdateReasonEnum["FIX_DATA"] = "fix_data";
42
+ UpdateReasonEnum["RE_LISTING"] = "re_listing";
41
43
  })(UpdateReasonEnum = exports.UpdateReasonEnum || (exports.UpdateReasonEnum = {}));
42
44
  let Product = class Product extends abstract_base_1.AbstractBase {
43
45
  };
@@ -143,6 +145,10 @@ __decorate([
143
145
  typeorm_1.Column(),
144
146
  __metadata("design:type", Object)
145
147
  ], Product.prototype, "attributes", void 0);
148
+ __decorate([
149
+ typeorm_1.Column(),
150
+ __metadata("design:type", Array)
151
+ ], Product.prototype, "stockHistory", void 0);
146
152
  __decorate([
147
153
  typeorm_1.Column(),
148
154
  __metadata("design:type", Boolean)
@@ -200,7 +206,7 @@ __decorate([
200
206
  ], Product.prototype, "currency", void 0);
201
207
  __decorate([
202
208
  typeorm_1.Column(),
203
- __metadata("design:type", String)
209
+ __metadata("design:type", Array)
204
210
  ], Product.prototype, "updateReason", void 0);
205
211
  __decorate([
206
212
  typeorm_1.Column(),
@@ -1 +1 @@
1
- {"version":3,"file":"product.js","sourceRoot":"/","sources":["entities/product.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Column,\n Entity, Index, Unique,\n} from 'typeorm';\nimport { IsNotEmpty } from 'class-validator';\nimport { AbstractBase } from './abstract-base';\nimport { Price } from './price';\nimport { PricesStats } from './prices-stats';\nimport { Keyword } from './keyword';\nimport { HttpRequest } from '../classes/http-request';\n\nexport enum CurrencyEnum {\n CLP = 'clp',\n CMR_PTS = 'cmr_pts',\n PARIS_PTS = 'paris_pts',\n RIPLEY_PTS = 'ripley_pts',\n GENERAL_POINTS = 'general_pts',\n BRL = 'brl',\n PEN = 'PEN',\n ARS = 'ars',\n EUR = 'eur',\n USD = 'usd',\n}\n\nexport enum UpdateReasonEnum {\n TIME = 'time',\n NEW_PRICE = 'new_price',\n NEW_CONDITIONAL_PRICE = 'new_conditional_price',\n NEW_NAME = 'new_name',\n NEW_LISTING = 'new_listing',\n MISSING_DATA = 'missing_data',\n FIX_DATA = 'fix_data',\n}\n\nexport interface ProductAttributes {\n stock?: number;\n\n // TODO: Add enum\n color?: string;\n\n // TODO: Add enum\n size?: string;\n\n [key: string]: any;\n}\n\nexport interface ConditionalPrice {\n minAmount?: number;\n price?:number;\n cardRequired?: boolean;\n createdAt?: Date;\n}\n\n@Entity({ name: 'products' })\n@Unique('store_ref_sku', ['storeRef', 'sku'])\nexport class Product extends AbstractBase {\n @Column()\n name: string;\n\n @Column()\n brandName?: string;\n\n @Column()\n normalizedBrandName?: string;\n\n @Column()\n modelName?: string;\n\n @Column()\n @IsNotEmpty()\n @Index()\n sku: string;\n\n @Column()\n internalId?: string;\n\n @Column()\n ean?: string;\n\n @Column()\n @IsNotEmpty()\n url: string;\n\n @Column()\n @IsNotEmpty()\n @Index()\n storeRef: string;\n\n @Column()\n storeName?: string;\n\n @Column()\n branchStoreName?: string;\n\n @Column()\n sellerName?: string;\n\n @Column()\n normalizedSellerName?: string;\n\n @Column()\n @IsNotEmpty()\n price?: Price;\n\n @Column()\n conditionalPrice?: ConditionalPrice;\n\n @Column()\n previousPrice?: Price;\n\n @Column()\n bestPrice?: Price;\n\n @Column()\n priceStats?: PricesStats;\n\n @Column()\n priceHistory?: Price[];\n\n @Column()\n rank?: number;\n\n @Column()\n image?: string;\n\n @Column()\n category?: string;\n\n @Column()\n categoryPath?: string;\n\n @Column()\n attributes?: ProductAttributes;\n\n @Column()\n homeDeliveryShipping?: boolean;\n\n @Column()\n pickUpFromStoreShipping?: boolean;\n\n @Column()\n fastDelivery?: boolean;\n\n @Column()\n enabled?: boolean;\n\n @Column()\n sourceUrl?: string;\n\n @Column()\n request? : HttpRequest;\n\n @Column()\n @Index()\n updatedAt?: Date;\n\n @Column()\n @Index()\n categoryKeywordNames?: string[];\n\n @Column()\n categoryKeywords?: Keyword[];\n\n @Column()\n @Index()\n processedPricesAt?: Date;\n\n @Column()\n isMarketplace?: boolean;\n\n @Column()\n addToCartLink?: string;\n\n @Column()\n currency?: CurrencyEnum;\n\n @Column()\n updateReason?: UpdateReasonEnum;\n\n @Column()\n nameHistory?: {\n name: string,\n updatedAt: string,\n }[];\n\n @Column()\n parentProductIdRef?: string;\n\n @Column()\n parentProductSkuRef?: string;\n}\n"]}
1
+ {"version":3,"file":"product.js","sourceRoot":"/","sources":["entities/product.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Column,\n Entity, Index, Unique,\n} from 'typeorm';\nimport { IsNotEmpty } from 'class-validator';\nimport { AbstractBase } from './abstract-base';\nimport { Price } from './price';\nimport { PricesStats } from './prices-stats';\nimport { Keyword } from './keyword';\nimport { HttpRequest } from '../classes/http-request';\n\nexport enum CurrencyEnum {\n CLP = 'clp',\n CMR_PTS = 'cmr_pts',\n PARIS_PTS = 'paris_pts',\n RIPLEY_PTS = 'ripley_pts',\n GENERAL_POINTS = 'general_pts',\n BRL = 'brl',\n PEN = 'PEN',\n ARS = 'ars',\n EUR = 'eur',\n USD = 'usd',\n}\n\nexport enum UpdateReasonEnum {\n TIME = 'time',\n NEW_PRICE = 'new_price',\n NEW_CONDITIONAL_PRICE = 'new_conditional_price',\n NEW_NAME = 'new_name',\n NEW_LISTING = 'new_listing',\n NEW_STOCK = 'new_stock',\n MISSING_DATA = 'missing_data',\n FIX_DATA = 'fix_data',\n RE_LISTING = 're_listing',\n}\n\nexport interface ProductAttributes {\n stock?: number;\n\n // TODO: Add enum\n color?: string;\n\n // TODO: Add enum\n size?: string;\n\n [key: string]: any;\n}\n\nexport interface ConditionalPrice {\n minAmount?: number;\n price?:number;\n cardRequired?: boolean;\n createdAt?: Date;\n}\n\n@Entity({ name: 'products' })\n@Unique('store_ref_sku', ['storeRef', 'sku'])\nexport class Product extends AbstractBase {\n @Column()\n name: string;\n\n @Column()\n brandName?: string;\n\n @Column()\n normalizedBrandName?: string;\n\n @Column()\n modelName?: string;\n\n @Column()\n @IsNotEmpty()\n @Index()\n sku: string;\n\n @Column()\n internalId?: string;\n\n @Column()\n ean?: string;\n\n @Column()\n @IsNotEmpty()\n url: string;\n\n @Column()\n @IsNotEmpty()\n @Index()\n storeRef: string;\n\n @Column()\n storeName?: string;\n\n @Column()\n branchStoreName?: string;\n\n @Column()\n sellerName?: string;\n\n @Column()\n normalizedSellerName?: string;\n\n @Column()\n @IsNotEmpty()\n price?: Price;\n\n @Column()\n conditionalPrice?: ConditionalPrice;\n\n @Column()\n previousPrice?: Price;\n\n @Column()\n bestPrice?: Price;\n\n @Column()\n priceStats?: PricesStats;\n\n @Column()\n priceHistory?: Price[];\n\n @Column()\n rank?: number;\n\n @Column()\n image?: string;\n\n @Column()\n category?: string;\n\n @Column()\n categoryPath?: string;\n\n @Column()\n attributes?: ProductAttributes;\n\n @Column()\n stockHistory?: {\n stock: number,\n updatedAt: string,\n }[];\n\n @Column()\n homeDeliveryShipping?: boolean;\n\n @Column()\n pickUpFromStoreShipping?: boolean;\n\n @Column()\n fastDelivery?: boolean;\n\n @Column()\n enabled?: boolean;\n\n @Column()\n sourceUrl?: string;\n\n @Column()\n request? : HttpRequest;\n\n @Column()\n @Index()\n updatedAt?: Date;\n\n @Column()\n @Index()\n categoryKeywordNames?: string[];\n\n @Column()\n categoryKeywords?: Keyword[];\n\n @Column()\n @Index()\n processedPricesAt?: Date;\n\n @Column()\n isMarketplace?: boolean;\n\n @Column()\n addToCartLink?: string;\n\n @Column()\n currency?: CurrencyEnum;\n\n @Column()\n updateReason?: UpdateReasonEnum[];\n\n @Column()\n nameHistory?: {\n name: string,\n updatedAt: string,\n }[];\n\n @Column()\n parentProductIdRef?: string;\n\n @Column()\n parentProductSkuRef?: string;\n}\n"]}
@@ -1,2 +1,4 @@
1
1
  import { RequestTypeEnum } from './request-type.enum';
2
- export { RequestTypeEnum };
2
+ import { TelegramClientEnum } from './telegram-client.enum';
3
+ import { TelegramQueueEnum } from './telegram-queue.enum';
4
+ export { RequestTypeEnum, TelegramClientEnum, TelegramQueueEnum };
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RequestTypeEnum = void 0;
3
+ exports.TelegramQueueEnum = exports.TelegramClientEnum = exports.RequestTypeEnum = void 0;
4
4
  const request_type_enum_1 = require("./request-type.enum");
5
5
  Object.defineProperty(exports, "RequestTypeEnum", { enumerable: true, get: function () { return request_type_enum_1.RequestTypeEnum; } });
6
+ const telegram_client_enum_1 = require("./telegram-client.enum");
7
+ Object.defineProperty(exports, "TelegramClientEnum", { enumerable: true, get: function () { return telegram_client_enum_1.TelegramClientEnum; } });
8
+ const telegram_queue_enum_1 = require("./telegram-queue.enum");
9
+ Object.defineProperty(exports, "TelegramQueueEnum", { enumerable: true, get: function () { return telegram_queue_enum_1.TelegramQueueEnum; } });
6
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["enums/index.ts"],"names":[],"mappings":";;;AAAA,2DAAsD;AAE7C,gGAFA,mCAAe,OAEA","sourcesContent":["import { RequestTypeEnum } from './request-type.enum';\n\nexport { RequestTypeEnum };\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"/","sources":["enums/index.ts"],"names":[],"mappings":";;;AAAA,2DAAsD;AAI7C,gGAJA,mCAAe,OAIA;AAHxB,iEAA4D;AAGlC,mGAHjB,yCAAkB,OAGiB;AAF5C,+DAA0D;AAEZ,kGAFrC,uCAAiB,OAEqC","sourcesContent":["import { RequestTypeEnum } from './request-type.enum';\nimport { TelegramClientEnum } from './telegram-client.enum';\nimport { TelegramQueueEnum } from './telegram-queue.enum';\n\nexport { RequestTypeEnum, TelegramClientEnum, TelegramQueueEnum };\n"]}
@@ -0,0 +1,4 @@
1
+ export declare enum TelegramClientEnum {
2
+ SEND_ALERT_MESSAGE = "send_alert_message",
3
+ SEND_ALERT_MESSAGE_PUBLIC = "send_alert_message_public"
4
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelegramClientEnum = void 0;
4
+ var TelegramClientEnum;
5
+ (function (TelegramClientEnum) {
6
+ TelegramClientEnum["SEND_ALERT_MESSAGE"] = "send_alert_message";
7
+ TelegramClientEnum["SEND_ALERT_MESSAGE_PUBLIC"] = "send_alert_message_public";
8
+ })(TelegramClientEnum = exports.TelegramClientEnum || (exports.TelegramClientEnum = {}));
9
+ //# sourceMappingURL=telegram-client.enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-client.enum.js","sourceRoot":"/","sources":["enums/telegram-client.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC5B,+DAAyC,CAAA;IACzC,6EAAuD,CAAA;AACzD,CAAC,EAHW,kBAAkB,GAAlB,0BAAkB,KAAlB,0BAAkB,QAG7B","sourcesContent":["export enum TelegramClientEnum {\n SEND_ALERT_MESSAGE = 'send_alert_message',\n SEND_ALERT_MESSAGE_PUBLIC = 'send_alert_message_public',\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare enum TelegramQueueCommandEnum {
2
+ SEND_MESSAGE = "send_message"
3
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelegramQueueCommandEnum = void 0;
4
+ var TelegramQueueCommandEnum;
5
+ (function (TelegramQueueCommandEnum) {
6
+ TelegramQueueCommandEnum["SEND_MESSAGE"] = "send_message";
7
+ })(TelegramQueueCommandEnum = exports.TelegramQueueCommandEnum || (exports.TelegramQueueCommandEnum = {}));
8
+ //# sourceMappingURL=telegram-queue-command.enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-queue-command.enum.js","sourceRoot":"/","sources":["enums/telegram-queue-command.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,wBAEX;AAFD,WAAY,wBAAwB;IAClC,yDAA6B,CAAA;AAC/B,CAAC,EAFW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAEnC","sourcesContent":["export enum TelegramQueueCommandEnum {\n SEND_MESSAGE = 'send_message',\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export declare enum TelegramQueueEnum {
2
+ TELEGRAM_ALERT = "telegram_alert",
3
+ TELEGRAM_ALERT_PUBLIC_1 = "telegram_alert_public",
4
+ TELEGRAM_ALERT_PUBLIC_2 = "telegram_alert_public_non_vip",
5
+ TELEGRAM_ALERT_PUBLIC_3 = "telegram_alert_public_non_vip_60",
6
+ TELEGRAM_ALERT_PUBLIC_4 = "telegram_alert_public_60",
7
+ TELEGRAM_STOCK_ALERT_PUBLIC = "telegram_stock_alert_public"
8
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelegramQueueEnum = void 0;
4
+ var TelegramQueueEnum;
5
+ (function (TelegramQueueEnum) {
6
+ TelegramQueueEnum["TELEGRAM_ALERT"] = "telegram_alert";
7
+ TelegramQueueEnum["TELEGRAM_ALERT_PUBLIC_1"] = "telegram_alert_public";
8
+ TelegramQueueEnum["TELEGRAM_ALERT_PUBLIC_2"] = "telegram_alert_public_non_vip";
9
+ TelegramQueueEnum["TELEGRAM_ALERT_PUBLIC_3"] = "telegram_alert_public_non_vip_60";
10
+ TelegramQueueEnum["TELEGRAM_ALERT_PUBLIC_4"] = "telegram_alert_public_60";
11
+ TelegramQueueEnum["TELEGRAM_STOCK_ALERT_PUBLIC"] = "telegram_stock_alert_public";
12
+ })(TelegramQueueEnum = exports.TelegramQueueEnum || (exports.TelegramQueueEnum = {}));
13
+ //# sourceMappingURL=telegram-queue.enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-queue.enum.js","sourceRoot":"/","sources":["enums/telegram-queue.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,iBAOX;AAPD,WAAY,iBAAiB;IAC3B,sDAAiC,CAAA;IACjC,sEAAiD,CAAA;IACjD,8EAAyD,CAAA;IACzD,iFAA4D,CAAA;IAC5D,yEAAoD,CAAA;IACpD,gFAA2D,CAAA;AAC7D,CAAC,EAPW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAO5B","sourcesContent":["export enum TelegramQueueEnum {\n TELEGRAM_ALERT = 'telegram_alert',\n TELEGRAM_ALERT_PUBLIC_1 = 'telegram_alert_public',\n TELEGRAM_ALERT_PUBLIC_2 = 'telegram_alert_public_non_vip',\n TELEGRAM_ALERT_PUBLIC_3 = 'telegram_alert_public_non_vip_60',\n TELEGRAM_ALERT_PUBLIC_4 = 'telegram_alert_public_60',\n TELEGRAM_STOCK_ALERT_PUBLIC = 'telegram_stock_alert_public',\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const isArrayEmpty: <T>(arr: T[]) => boolean;
2
+ export declare const hasElementInArray: <T>(elements: T[], searchElements: T[]) => boolean;
3
+ export declare const stringToArray: (str: string, splitBy?: string) => string[];
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stringToArray = exports.hasElementInArray = exports.isArrayEmpty = void 0;
4
+ exports.isArrayEmpty = (arr) => {
5
+ if (arr && !Array.isArray(arr)) {
6
+ throw Error('Element is not an array');
7
+ }
8
+ return !arr || arr.length === 0;
9
+ };
10
+ exports.hasElementInArray = (elements, searchElements) => {
11
+ if (exports.isArrayEmpty(elements) || exports.isArrayEmpty(searchElements)) {
12
+ return false;
13
+ }
14
+ return elements.some((updateReason) => searchElements.some((searchUpdateReason) => updateReason === searchUpdateReason));
15
+ };
16
+ exports.stringToArray = (str, splitBy = ',') => {
17
+ if (!str) {
18
+ return null;
19
+ }
20
+ return str.split(splitBy).filter((e) => e);
21
+ };
22
+ //# sourceMappingURL=array-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-utils.js","sourceRoot":"/","sources":["utils/array-utils.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG,CAAI,GAAQ,EAAW,EAAE;IACnD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC9B,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;KACxC;IAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC;AAEW,QAAA,iBAAiB,GAAG,CAAI,QAAa,EAAE,cAAmB,EAAW,EAAE;IAClF,IAAI,oBAAY,CAAC,QAAQ,CAAC,IAAI,oBAAY,CAAC,cAAc,CAAC,EAAE;QAC1D,OAAO,KAAK,CAAC;KACd;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC,YAAY,KAAK,kBAAkB,CAAC,CAAC,CAAC;AAC3H,CAAC,CAAC;AAEW,QAAA,aAAa,GAAG,CAAC,GAAW,EAAE,OAAO,GAAG,GAAG,EAAY,EAAE;IACpE,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,IAAI,CAAC;KACb;IAED,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC","sourcesContent":["export const isArrayEmpty = <T>(arr: T[]): boolean => {\n if (arr && !Array.isArray(arr)) {\n throw Error('Element is not an array');\n }\n\n return !arr || arr.length === 0;\n};\n\nexport const hasElementInArray = <T>(elements: T[], searchElements: T[]): boolean => {\n if (isArrayEmpty(elements) || isArrayEmpty(searchElements)) {\n return false;\n }\n\n return elements.some((updateReason) => searchElements.some((searchUpdateReason) => updateReason === searchUpdateReason));\n};\n\nexport const stringToArray = (str: string, splitBy = ','): string[] => {\n if (!str) {\n return null;\n }\n\n return str.split(splitBy).filter((e) => e);\n};\n"]}
@@ -1,2 +1,3 @@
1
1
  export declare const calculateAverage: (sum: number, quantity: number) => number;
2
2
  export declare const roundNumber: (nmb: number, decimals?: number) => number;
3
+ export declare const getPercentageDiff: (minPrice: number, compareToPrice: number) => number;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.roundNumber = exports.calculateAverage = void 0;
3
+ exports.getPercentageDiff = exports.roundNumber = exports.calculateAverage = void 0;
4
+ const lodash_1 = require("lodash");
4
5
  exports.calculateAverage = (sum, quantity) => {
5
6
  if (!sum || !quantity) {
6
7
  return null;
@@ -22,4 +23,10 @@ exports.roundNumber = (nmb, decimals) => {
22
23
  }
23
24
  return Number(nmb.toFixed(decimals));
24
25
  };
26
+ exports.getPercentageDiff = (minPrice, compareToPrice) => {
27
+ if (lodash_1.isNumber(minPrice) && lodash_1.isNumber(compareToPrice)) {
28
+ return exports.roundNumber(100 - (minPrice * 100) / compareToPrice, 2);
29
+ }
30
+ return null;
31
+ };
25
32
  //# sourceMappingURL=number-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"number-utils.js","sourceRoot":"/","sources":["utils/number-utils.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,CAAC,GAAW,EAAE,QAAgB,EAAU,EAAE;IACxE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;QACrB,OAAO,IAAI,CAAC;KACb;IAED,IAAI,GAAG,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,EAAE;QAC/B,OAAO,IAAI,CAAC;KACb;IAED,OAAO,GAAG,GAAG,QAAQ,CAAC;AACxB,CAAC,CAAC;AAEW,QAAA,WAAW,GAAG,CAAC,GAAW,EAAE,QAAiB,EAAU,EAAE;IACpE,IAAI,GAAG,KAAK,CAAC,EAAE;QACb,OAAO,GAAG,CAAC;KACZ;IAED,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,IAAI,CAAC;KACb;IAED,IAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG,CAAC,EAAE;QAC7B,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/B;IAED,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC","sourcesContent":["export const calculateAverage = (sum: number, quantity: number): number => {\n if (!sum || !quantity) {\n return null;\n }\n\n if (sum === 0 || quantity === 0) {\n return null;\n }\n\n return sum / quantity;\n};\n\nexport const roundNumber = (nmb: number, decimals?: number): number => {\n if (nmb === 0) {\n return nmb;\n }\n\n if (!nmb) {\n return null;\n }\n\n if (!decimals || decimals < 0) {\n return Number(nmb.toFixed(0));\n }\n\n return Number(nmb.toFixed(decimals));\n};\n"]}
1
+ {"version":3,"file":"number-utils.js","sourceRoot":"/","sources":["utils/number-utils.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAErB,QAAA,gBAAgB,GAAG,CAAC,GAAW,EAAE,QAAgB,EAAU,EAAE;IACxE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;QACrB,OAAO,IAAI,CAAC;KACb;IAED,IAAI,GAAG,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,EAAE;QAC/B,OAAO,IAAI,CAAC;KACb;IAED,OAAO,GAAG,GAAG,QAAQ,CAAC;AACxB,CAAC,CAAC;AAEW,QAAA,WAAW,GAAG,CAAC,GAAW,EAAE,QAAiB,EAAU,EAAE;IACpE,IAAI,GAAG,KAAK,CAAC,EAAE;QACb,OAAO,GAAG,CAAC;KACZ;IAED,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,IAAI,CAAC;KACb;IAED,IAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG,CAAC,EAAE;QAC7B,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/B;IAED,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC;AAEW,QAAA,iBAAiB,GAAG,CAAC,QAAgB,EAAE,cAAsB,EAAU,EAAE;IACpF,IAAI,iBAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAQ,CAAC,cAAc,CAAC,EAAE;QAClD,OAAO,mBAAW,CAAC,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC;KAChE;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC","sourcesContent":["import { isNumber } from 'lodash';\n\nexport const calculateAverage = (sum: number, quantity: number): number => {\n if (!sum || !quantity) {\n return null;\n }\n\n if (sum === 0 || quantity === 0) {\n return null;\n }\n\n return sum / quantity;\n};\n\nexport const roundNumber = (nmb: number, decimals?: number): number => {\n if (nmb === 0) {\n return nmb;\n }\n\n if (!nmb) {\n return null;\n }\n\n if (!decimals || decimals < 0) {\n return Number(nmb.toFixed(0));\n }\n\n return Number(nmb.toFixed(decimals));\n};\n\nexport const getPercentageDiff = (minPrice: number, compareToPrice: number): number => {\n if (isNumber(minPrice) && isNumber(compareToPrice)) {\n return roundNumber(100 - (minPrice * 100) / compareToPrice, 2);\n }\n\n return null;\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import { Product, Store, UpdateReasonEnum } from '../entities';
2
+ export declare const getStoreName: (product: Product, stores: Store[]) => string;
3
+ export declare const hasUpdateReason: (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]) => boolean;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasUpdateReason = exports.getStoreName = void 0;
4
+ const array_utils_1 = require("./array-utils");
5
+ exports.getStoreName = (product, stores) => {
6
+ if ((!stores || stores.length === 0) && product) {
7
+ return product.storeName;
8
+ }
9
+ const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);
10
+ if (store) {
11
+ return store.displayName || store.name;
12
+ }
13
+ return null;
14
+ };
15
+ exports.hasUpdateReason = (enums, search) => array_utils_1.hasElementInArray(enums, search);
16
+ //# sourceMappingURL=product.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product.utils.js","sourceRoot":"/","sources":["utils/product.utils.ts"],"names":[],"mappings":";;;AAAA,+CAAkD;AAGrC,QAAA,YAAY,GAAG,CAAC,OAAgB,EAAE,MAAe,EAAU,EAAE;IACxE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,OAAO,EAAE;QAC/C,OAAO,OAAO,CAAC,SAAS,CAAC;KAC1B;IAGD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9F,IAAI,KAAK,EAAE;QACT,OAAO,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC;KACxC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEW,QAAA,eAAe,GAAG,CAAC,KAAyB,EAAE,MAA0B,EAAW,EAAE,CAAC,+BAAiB,CAAmB,KAAK,EAAE,MAAM,CAAC,CAAC","sourcesContent":["import { hasElementInArray } from './array-utils';\nimport { Product, Store, UpdateReasonEnum } from '../entities';\n\nexport const getStoreName = (product: Product, stores: Store[]): string => {\n if ((!stores || stores.length === 0) && product) {\n return product.storeName;\n }\n\n // eslint-disable-next-line no-underscore-dangle\n const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);\n if (store) {\n return store.displayName || store.name;\n }\n\n return null;\n};\n\nexport const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);\n"]}
@@ -0,0 +1,4 @@
1
+ import { CurrencyEnum } from '../entities';
2
+ export declare const formatMoney: (money: number | string, currency?: CurrencyEnum) => string;
3
+ export declare const formatDate: (str: string) => string;
4
+ export declare const formatPct: (pct: number | string) => string;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.formatPct = exports.formatDate = exports.formatMoney = void 0;
23
+ const moment = __importStar(require("moment-timezone"));
24
+ const entities_1 = require("../entities");
25
+ const addThousandSeparator = (str) => {
26
+ const nStr = (`${str}`);
27
+ const x = nStr.split('.');
28
+ let x1 = x[0];
29
+ const x2 = x.length > 1 ? `.${x[1]}` : '';
30
+ const rgx = /(\d+)(\d{3})/;
31
+ while (rgx.test(x1)) {
32
+ x1 = x1.replace(rgx, '$1.$2');
33
+ }
34
+ return x1 + x2;
35
+ };
36
+ exports.formatMoney = (money, currency) => {
37
+ if (!money) {
38
+ return '';
39
+ }
40
+ let prependSign = '';
41
+ if (!currency || !currency.toLowerCase().includes('pts')) {
42
+ if (currency === entities_1.CurrencyEnum.USD) {
43
+ prependSign = 'U$';
44
+ }
45
+ else {
46
+ prependSign = '$';
47
+ }
48
+ }
49
+ const appendSign = currency && currency.toLowerCase().includes('pts') ? ' (pts)' : '';
50
+ return prependSign + addThousandSeparator(money.toString()) + appendSign;
51
+ };
52
+ exports.formatDate = (str) => {
53
+ if (!str) {
54
+ return '';
55
+ }
56
+ return moment.tz(new Date(str), 'America/Santiago').format('DD-MM-YYYY HH:mm:ss');
57
+ };
58
+ exports.formatPct = (pct) => {
59
+ if (!pct) {
60
+ return '';
61
+ }
62
+ return `${pct}%`.replace('.', ',');
63
+ };
64
+ //# sourceMappingURL=string-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-formatter.js","sourceRoot":"/","sources":["utils/string-formatter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,wDAA0C;AAC1C,0CAA2C;AAE3C,MAAM,oBAAoB,GAAG,CAAC,GAAW,EAAE,EAAE;IAC3C,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IACxB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACd,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,cAAc,CAAC;IAC3B,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QACnB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;KAC/B;IACD,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC,CAAC;AAEW,QAAA,WAAW,GAAG,CAAC,KAAsB,EAAE,QAAuB,EAAU,EAAE;IACrF,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,EAAE,CAAC;KACX;IAED,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QACxD,IAAI,QAAQ,KAAK,uBAAY,CAAC,GAAG,EAAE;YACjC,WAAW,GAAG,IAAI,CAAC;SACpB;aAAM;YACL,WAAW,GAAG,GAAG,CAAC;SACnB;KACF;IAED,MAAM,UAAU,GAAG,QAAQ,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtF,OAAO,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,UAAU,CAAC;AAC3E,CAAC,CAAC;AAEW,QAAA,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;IAChD,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,EAAE,CAAC;KACX;IAED,OAAO,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;AACpF,CAAC,CAAC;AAEW,QAAA,SAAS,GAAG,CAAC,GAAoB,EAAU,EAAE;IACxD,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,EAAE,CAAC;KACX;IAED,OAAO,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC,CAAC","sourcesContent":["import * as moment from 'moment-timezone';\nimport { CurrencyEnum } from '../entities';\n\nconst addThousandSeparator = (str: string) => {\n const nStr = (`${str}`);\n const x = nStr.split('.');\n let x1 = x[0];\n const x2 = x.length > 1 ? `.${x[1]}` : '';\n const rgx = /(\\d+)(\\d{3})/;\n while (rgx.test(x1)) {\n x1 = x1.replace(rgx, '$1.$2');\n }\n return x1 + x2;\n};\n\nexport const formatMoney = (money: number | string, currency?: CurrencyEnum): string => {\n if (!money) {\n return '';\n }\n\n let prependSign = '';\n if (!currency || !currency.toLowerCase().includes('pts')) {\n if (currency === CurrencyEnum.USD) {\n prependSign = 'U$';\n } else {\n prependSign = '$';\n }\n }\n\n const appendSign = currency && currency.toLowerCase().includes('pts') ? ' (pts)' : '';\n\n return prependSign + addThousandSeparator(money.toString()) + appendSign;\n};\n\nexport const formatDate = (str: string): string => {\n if (!str) {\n return '';\n }\n\n return moment.tz(new Date(str), 'America/Santiago').format('DD-MM-YYYY HH:mm:ss');\n};\n\nexport const formatPct = (pct: number | string): string => {\n if (!pct) {\n return '';\n }\n\n return `${pct}%`.replace('.', ',');\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "store-scrapper-js-common",
3
- "version": "1.0.86",
3
+ "version": "1.0.90",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,6 +18,7 @@
18
18
  "dependencies": {
19
19
  "class-validator": "^0.12.2",
20
20
  "lodash": "^4.17.20",
21
+ "moment-timezone": "^0.5.34",
21
22
  "rimraf": "^3.0.2",
22
23
  "typeorm": "^0.2.28"
23
24
  },
@@ -0,0 +1,23 @@
1
+ import { ObjectLiteral } from '../classes';
2
+ import { TelegramQueueCommandEnum } from '../enums/telegram-queue-command.enum';
3
+
4
+ export const enum TelegramMessageType {
5
+ MESSAGE = 'message',
6
+ IMAGE = 'image',
7
+ }
8
+
9
+ export class TelegramQueueCommandDto {
10
+ message: string;
11
+
12
+ telegramChatId: string | number;
13
+
14
+ options?: { [key: string]: any };
15
+
16
+ namedJob?: TelegramQueueCommandEnum;
17
+
18
+ telegramClientId: string;
19
+
20
+ type?: TelegramMessageType;
21
+
22
+ imageOpts?: ObjectLiteral;
23
+ }
@@ -46,6 +46,12 @@ export class Price extends AbstractBase {
46
46
  @IsOptional()
47
47
  measurementUnit?: MeasurementUnitEnum;
48
48
 
49
+ @Column()
50
+ validFrom?: Date;
51
+
52
+ @Column()
53
+ validTo?: Date;
54
+
49
55
  @CreateDateColumn()
50
56
  @Index()
51
57
  createdAt?: Date;
@@ -28,8 +28,10 @@ export enum UpdateReasonEnum {
28
28
  NEW_CONDITIONAL_PRICE = 'new_conditional_price',
29
29
  NEW_NAME = 'new_name',
30
30
  NEW_LISTING = 'new_listing',
31
+ NEW_STOCK = 'new_stock',
31
32
  MISSING_DATA = 'missing_data',
32
33
  FIX_DATA = 'fix_data',
34
+ RE_LISTING = 're_listing',
33
35
  }
34
36
 
35
37
  export interface ProductAttributes {
@@ -132,6 +134,12 @@ export class Product extends AbstractBase {
132
134
  @Column()
133
135
  attributes?: ProductAttributes;
134
136
 
137
+ @Column()
138
+ stockHistory?: {
139
+ stock: number,
140
+ updatedAt: string,
141
+ }[];
142
+
135
143
  @Column()
136
144
  homeDeliveryShipping?: boolean;
137
145
 
@@ -175,7 +183,7 @@ export class Product extends AbstractBase {
175
183
  currency?: CurrencyEnum;
176
184
 
177
185
  @Column()
178
- updateReason?: UpdateReasonEnum;
186
+ updateReason?: UpdateReasonEnum[];
179
187
 
180
188
  @Column()
181
189
  nameHistory?: {
@@ -1,3 +1,5 @@
1
1
  import { RequestTypeEnum } from './request-type.enum';
2
+ import { TelegramClientEnum } from './telegram-client.enum';
3
+ import { TelegramQueueEnum } from './telegram-queue.enum';
2
4
 
3
- export { RequestTypeEnum };
5
+ export { RequestTypeEnum, TelegramClientEnum, TelegramQueueEnum };
@@ -0,0 +1,4 @@
1
+ export enum TelegramClientEnum {
2
+ SEND_ALERT_MESSAGE = 'send_alert_message',
3
+ SEND_ALERT_MESSAGE_PUBLIC = 'send_alert_message_public',
4
+ }
@@ -0,0 +1,3 @@
1
+ export enum TelegramQueueCommandEnum {
2
+ SEND_MESSAGE = 'send_message',
3
+ }
@@ -0,0 +1,8 @@
1
+ export enum TelegramQueueEnum {
2
+ TELEGRAM_ALERT = 'telegram_alert',
3
+ TELEGRAM_ALERT_PUBLIC_1 = 'telegram_alert_public',
4
+ TELEGRAM_ALERT_PUBLIC_2 = 'telegram_alert_public_non_vip',
5
+ TELEGRAM_ALERT_PUBLIC_3 = 'telegram_alert_public_non_vip_60',
6
+ TELEGRAM_ALERT_PUBLIC_4 = 'telegram_alert_public_60',
7
+ TELEGRAM_STOCK_ALERT_PUBLIC = 'telegram_stock_alert_public',
8
+ }
@@ -0,0 +1,23 @@
1
+ export const isArrayEmpty = <T>(arr: T[]): boolean => {
2
+ if (arr && !Array.isArray(arr)) {
3
+ throw Error('Element is not an array');
4
+ }
5
+
6
+ return !arr || arr.length === 0;
7
+ };
8
+
9
+ export const hasElementInArray = <T>(elements: T[], searchElements: T[]): boolean => {
10
+ if (isArrayEmpty(elements) || isArrayEmpty(searchElements)) {
11
+ return false;
12
+ }
13
+
14
+ return elements.some((updateReason) => searchElements.some((searchUpdateReason) => updateReason === searchUpdateReason));
15
+ };
16
+
17
+ export const stringToArray = (str: string, splitBy = ','): string[] => {
18
+ if (!str) {
19
+ return null;
20
+ }
21
+
22
+ return str.split(splitBy).filter((e) => e);
23
+ };
@@ -1,3 +1,5 @@
1
+ import { isNumber } from 'lodash';
2
+
1
3
  export const calculateAverage = (sum: number, quantity: number): number => {
2
4
  if (!sum || !quantity) {
3
5
  return null;
@@ -25,3 +27,11 @@ export const roundNumber = (nmb: number, decimals?: number): number => {
25
27
 
26
28
  return Number(nmb.toFixed(decimals));
27
29
  };
30
+
31
+ export const getPercentageDiff = (minPrice: number, compareToPrice: number): number => {
32
+ if (isNumber(minPrice) && isNumber(compareToPrice)) {
33
+ return roundNumber(100 - (minPrice * 100) / compareToPrice, 2);
34
+ }
35
+
36
+ return null;
37
+ };
@@ -0,0 +1,18 @@
1
+ import { hasElementInArray } from './array-utils';
2
+ import { Product, Store, UpdateReasonEnum } from '../entities';
3
+
4
+ export const getStoreName = (product: Product, stores: Store[]): string => {
5
+ if ((!stores || stores.length === 0) && product) {
6
+ return product.storeName;
7
+ }
8
+
9
+ // eslint-disable-next-line no-underscore-dangle
10
+ const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);
11
+ if (store) {
12
+ return store.displayName || store.name;
13
+ }
14
+
15
+ return null;
16
+ };
17
+
18
+ export const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);
@@ -0,0 +1,49 @@
1
+ import * as moment from 'moment-timezone';
2
+ import { CurrencyEnum } from '../entities';
3
+
4
+ const addThousandSeparator = (str: string) => {
5
+ const nStr = (`${str}`);
6
+ const x = nStr.split('.');
7
+ let x1 = x[0];
8
+ const x2 = x.length > 1 ? `.${x[1]}` : '';
9
+ const rgx = /(\d+)(\d{3})/;
10
+ while (rgx.test(x1)) {
11
+ x1 = x1.replace(rgx, '$1.$2');
12
+ }
13
+ return x1 + x2;
14
+ };
15
+
16
+ export const formatMoney = (money: number | string, currency?: CurrencyEnum): string => {
17
+ if (!money) {
18
+ return '';
19
+ }
20
+
21
+ let prependSign = '';
22
+ if (!currency || !currency.toLowerCase().includes('pts')) {
23
+ if (currency === CurrencyEnum.USD) {
24
+ prependSign = 'U$';
25
+ } else {
26
+ prependSign = '$';
27
+ }
28
+ }
29
+
30
+ const appendSign = currency && currency.toLowerCase().includes('pts') ? ' (pts)' : '';
31
+
32
+ return prependSign + addThousandSeparator(money.toString()) + appendSign;
33
+ };
34
+
35
+ export const formatDate = (str: string): string => {
36
+ if (!str) {
37
+ return '';
38
+ }
39
+
40
+ return moment.tz(new Date(str), 'America/Santiago').format('DD-MM-YYYY HH:mm:ss');
41
+ };
42
+
43
+ export const formatPct = (pct: number | string): string => {
44
+ if (!pct) {
45
+ return '';
46
+ }
47
+
48
+ return `${pct}%`.replace('.', ',');
49
+ };
@@ -0,0 +1,34 @@
1
+ import { hasElementInArray, isArrayEmpty, stringToArray } from '../../src/utils/array-utils';
2
+
3
+ describe('array utils test', () => {
4
+ it('should return true if array contains elements', () => {
5
+ expect.hasAssertions();
6
+
7
+ expect(isArrayEmpty(null)).toStrictEqual(true);
8
+ expect(isArrayEmpty([])).toStrictEqual(true);
9
+
10
+ expect(isArrayEmpty([1])).toStrictEqual(false);
11
+ expect(isArrayEmpty(['a', 'b'])).toStrictEqual(false);
12
+ expect(isArrayEmpty([{}])).toStrictEqual(false);
13
+ });
14
+
15
+ it('should return true if array contains search elements', () => {
16
+ expect.hasAssertions();
17
+
18
+ expect(hasElementInArray([], [])).toStrictEqual(false);
19
+ expect(hasElementInArray<string>(['a', 'b'], ['c'])).toStrictEqual(false);
20
+
21
+ expect(hasElementInArray<string>(['a', 'b', 'c'], ['c'])).toStrictEqual(true);
22
+ expect(hasElementInArray<number>([1, 2, 3], [2])).toStrictEqual(true);
23
+ });
24
+
25
+ it('should return string split if not empty', () => {
26
+ expect.hasAssertions();
27
+
28
+ expect(stringToArray('', ',')).toBeNull();
29
+ expect(stringToArray(null, ',')).toBeNull();
30
+
31
+ expect(stringToArray('abc', ',')).toStrictEqual(['abc']);
32
+ expect(stringToArray('a,b,c,d,', ',')).toStrictEqual(['a', 'b', 'c', 'd']);
33
+ });
34
+ });
@@ -0,0 +1,21 @@
1
+ import { hasUpdateReason } from '../../src/utils/product.utils';
2
+ import { UpdateReasonEnum } from '../../src';
3
+
4
+ describe('product utils spec', () => {
5
+ it('should return true if product update reason contains search element', () => {
6
+ expect.hasAssertions();
7
+
8
+ expect(hasUpdateReason([UpdateReasonEnum.TIME], [])).toStrictEqual(false);
9
+ expect(hasUpdateReason([], [UpdateReasonEnum.NEW_STOCK])).toStrictEqual(false);
10
+ expect(
11
+ hasUpdateReason([UpdateReasonEnum.TIME, UpdateReasonEnum.MISSING_DATA], [UpdateReasonEnum.NEW_STOCK]),
12
+ ).toStrictEqual(false);
13
+
14
+ expect(
15
+ hasUpdateReason(
16
+ [UpdateReasonEnum.TIME, UpdateReasonEnum.NEW_STOCK, UpdateReasonEnum.RE_LISTING],
17
+ [UpdateReasonEnum.NEW_STOCK],
18
+ ),
19
+ ).toStrictEqual(true);
20
+ });
21
+ });
@@ -0,0 +1,37 @@
1
+ import { formatDate, formatMoney, formatPct } from '../../src/utils/string-formatter';
2
+ import { CurrencyEnum } from '../../src/entities';
3
+
4
+ describe('string formatter', () => {
5
+ it('should return number as a formatted CLP Money Currency', () => {
6
+ expect.hasAssertions();
7
+
8
+ expect(formatMoney(null)).toStrictEqual('');
9
+ expect(formatMoney(100)).toStrictEqual('$100');
10
+ expect(formatMoney(1000)).toStrictEqual('$1.000');
11
+ expect(formatMoney(10000)).toStrictEqual('$10.000');
12
+ expect(formatMoney(100000)).toStrictEqual('$100.000');
13
+ expect(formatMoney(1000000)).toStrictEqual('$1.000.000');
14
+
15
+ expect(formatMoney(1000, CurrencyEnum.CMR_PTS)).toStrictEqual('1.000 (pts)');
16
+ expect(formatMoney(1000000, CurrencyEnum.CMR_PTS)).toStrictEqual('1.000.000 (pts)');
17
+
18
+ expect(formatMoney(1000, CurrencyEnum.USD)).toStrictEqual('U$1.000');
19
+ expect(formatMoney(1000000, CurrencyEnum.USD)).toStrictEqual('U$1.000.000');
20
+ });
21
+
22
+ it('should return date as a formatted CLP Date', () => {
23
+ expect.hasAssertions();
24
+
25
+ const date = '2021-01-16T21:35:15.945Z';
26
+
27
+ expect(formatDate(null)).toStrictEqual('');
28
+ expect(formatDate(date)).toStrictEqual('16-01-2021 18:35:15');
29
+ });
30
+
31
+ it('should return number as a percentage string', () => {
32
+ expect.hasAssertions();
33
+
34
+ expect(formatPct(10)).toStrictEqual('10%');
35
+ expect(formatPct(10.2)).toStrictEqual('10,2%');
36
+ });
37
+ });