@adtrackify/at-service-common 3.1.36 → 3.1.38
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/cjs/services/cache/product-cache-service.d.ts +2 -1
- package/dist/cjs/services/cache/product-cache-service.js +4 -2
- package/dist/cjs/services/cache/product-cache-service.js.map +1 -1
- package/dist/cjs/services/db/log-events-db-service.js +1 -1
- package/dist/cjs/services/db/shopify-products-cache-db-service.d.ts +11 -5
- package/dist/cjs/services/db/shopify-products-cache-db-service.js +27 -32
- package/dist/cjs/services/db/shopify-products-cache-db-service.js.map +1 -1
- package/dist/cjs/services/db/tracking-events-db-service.js +2 -2
- package/dist/cjs/services/shopify/products/shopify-products-serviceV2.d.ts +6 -1
- package/dist/cjs/services/shopify/products/shopify-products-serviceV2.js +21 -3
- package/dist/cjs/services/shopify/products/shopify-products-serviceV2.js.map +1 -1
- package/dist/esm/services/cache/product-cache-service.d.ts +2 -1
- package/dist/esm/services/cache/product-cache-service.js +4 -2
- package/dist/esm/services/cache/product-cache-service.js.map +1 -1
- package/dist/esm/services/db/log-events-db-service.js +1 -1
- package/dist/esm/services/db/shopify-products-cache-db-service.d.ts +11 -5
- package/dist/esm/services/db/shopify-products-cache-db-service.js +25 -33
- package/dist/esm/services/db/shopify-products-cache-db-service.js.map +1 -1
- package/dist/esm/services/db/tracking-events-db-service.js +2 -2
- package/dist/esm/services/shopify/products/shopify-products-serviceV2.d.ts +6 -1
- package/dist/esm/services/shopify/products/shopify-products-serviceV2.js +21 -3
- package/dist/esm/services/shopify/products/shopify-products-serviceV2.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,7 +10,8 @@ export interface ProductCache extends GenericCachedObject {
|
|
|
10
10
|
export declare const getProductCacheKey: (pixelId: string, productId: string) => string;
|
|
11
11
|
export declare class ProductCacheService {
|
|
12
12
|
private genericCacheService;
|
|
13
|
-
|
|
13
|
+
private redisCacheTtlInSeconds;
|
|
14
|
+
constructor(cacheLambdaFunctionArn: string, redisCacheTtlInSeconds: number);
|
|
14
15
|
getCacheKey: (pixelId: string, productId: string) => string;
|
|
15
16
|
getProductFromCache: (pixelId: string, productId: string) => Promise<InternalProduct | undefined>;
|
|
16
17
|
getProductCache: (pixelId: string, productId: string) => Promise<ProductCache | undefined>;
|
|
@@ -15,8 +15,10 @@ const getProductCacheKey = (pixelId, productId) => {
|
|
|
15
15
|
exports.getProductCacheKey = getProductCacheKey;
|
|
16
16
|
class ProductCacheService {
|
|
17
17
|
genericCacheService;
|
|
18
|
-
|
|
18
|
+
redisCacheTtlInSeconds;
|
|
19
|
+
constructor(cacheLambdaFunctionArn, redisCacheTtlInSeconds) {
|
|
19
20
|
this.genericCacheService = new generic_cache_service_1.GenericCacheService(cacheLambdaFunctionArn);
|
|
21
|
+
this.redisCacheTtlInSeconds = redisCacheTtlInSeconds || DEFAULT_TTL_IN_SECONDS;
|
|
20
22
|
}
|
|
21
23
|
getCacheKey = (pixelId, productId) => {
|
|
22
24
|
return (0, exports.getProductCacheKey)(pixelId, productId);
|
|
@@ -36,7 +38,7 @@ class ProductCacheService {
|
|
|
36
38
|
};
|
|
37
39
|
putProductInCache = async (pixelId, productId, product, ttlInSeconds) => {
|
|
38
40
|
const cacheKey = this.getCacheKey(pixelId, productId);
|
|
39
|
-
const ttl = ttlInSeconds ||
|
|
41
|
+
const ttl = ttlInSeconds || this.redisCacheTtlInSeconds;
|
|
40
42
|
const expiresAt = luxon_1.DateTime.utc().plus({ seconds: ttl }).toSeconds();
|
|
41
43
|
const cachedAtEpoch = luxon_1.DateTime.utc().toSeconds();
|
|
42
44
|
const fullSha256 = crypto_1.default.createHash('sha256').update(JSON.stringify(product)).digest('hex');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-cache-service.js","sourceRoot":"","sources":["../../../../src/services/cache/product-cache-service.ts"],"names":[],"mappings":";;;;;;AAAA,iCAAiC;AACjC,oEAA+D;AAE/D,qCAA0D;AAE1D,oDAA4B;AAE5B,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAUtC,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,EAAE;IACvE,OAAO,oBAAoB,OAAO,IAAI,SAAS,EAAE,CAAC;AACpD,CAAC,CAAA;AAFY,QAAA,kBAAkB,sBAE9B;AAED,MAAa,mBAAmB;IACtB,mBAAmB,CAAsB;
|
|
1
|
+
{"version":3,"file":"product-cache-service.js","sourceRoot":"","sources":["../../../../src/services/cache/product-cache-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -133,7 +133,7 @@ class LogEventsDbService {
|
|
|
133
133
|
putLogEvent = async (logEvent, logGroup, ttlInMinutes) => {
|
|
134
134
|
const logEventCopy = JSON.parse(JSON.stringify(logEvent));
|
|
135
135
|
delete logEventCopy?.data?.logStorage;
|
|
136
|
-
const expiredAt = luxon_1.DateTime.
|
|
136
|
+
const expiredAt = luxon_1.DateTime.utc().plus({ minutes: ttlInMinutes ?? 15 }).toSeconds();
|
|
137
137
|
const logEventRecord = {
|
|
138
138
|
eventId: logEventCopy.id,
|
|
139
139
|
eventName: logEventCopy.name,
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { InternalProduct } from '../shopify/types/product';
|
|
2
|
+
import { ProductCache } from '../cache';
|
|
3
|
+
export interface ShopifyProductDynamoDbCache extends ProductCache {
|
|
4
|
+
pixelId_productId: string;
|
|
5
|
+
pixelId: string;
|
|
6
|
+
productId: string;
|
|
7
|
+
}
|
|
2
8
|
export declare class ShopifyProductsCacheDbService {
|
|
3
9
|
TABLE_NAME: string;
|
|
4
10
|
KEY_NAME: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
private dynamoDbCacheTtlInSeconds;
|
|
12
|
+
constructor(tableName: string, keyName: string, dynamoDbCacheTtlInSeconds: number);
|
|
13
|
+
getProductFromDynamoDBCache: (pixelId: string, productId: string) => Promise<InternalProduct | undefined>;
|
|
14
|
+
putProductInDynamoDBCache: (pixelId: string, productId: string, product: InternalProduct, ttlInSeconds?: number) => Promise<import("@aws-sdk/lib-dynamodb").PutCommandOutput | null>;
|
|
9
15
|
}
|
|
@@ -1,61 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.ShopifyProductsCacheDbService = void 0;
|
|
4
7
|
const clients_1 = require("../../clients");
|
|
5
8
|
const libs_1 = require("../../libs");
|
|
6
9
|
const luxon_1 = require("luxon");
|
|
7
10
|
const helpers_1 = require("../../helpers");
|
|
11
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
12
|
+
const DEFAULT_TTL_IN_SECONDS = 7 * 24 * 3600;
|
|
8
13
|
class ShopifyProductsCacheDbService {
|
|
9
14
|
TABLE_NAME;
|
|
10
15
|
KEY_NAME;
|
|
11
|
-
|
|
16
|
+
dynamoDbCacheTtlInSeconds;
|
|
17
|
+
constructor(tableName, keyName, dynamoDbCacheTtlInSeconds) {
|
|
12
18
|
this.TABLE_NAME = tableName;
|
|
13
19
|
this.KEY_NAME = keyName;
|
|
20
|
+
this.dynamoDbCacheTtlInSeconds = dynamoDbCacheTtlInSeconds || DEFAULT_TTL_IN_SECONDS;
|
|
14
21
|
}
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const cachedShopifyProduct = await this.getShopifyProductFromCacheREST(pixelId, productId);
|
|
18
|
-
if (cachedShopifyProduct) {
|
|
19
|
-
return cachedShopifyProduct.product;
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
const productRes = await clients_1.ShopifyClient.getProductREST(shop, accessToken, productId);
|
|
23
|
-
if (productRes.status === 200 && productRes?.data?.product) {
|
|
24
|
-
const product = productRes.data.product;
|
|
25
|
-
await this.putShopifyProductCacheREST(pixelId, productId, product);
|
|
26
|
-
return product;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
helpers_1.Logger.error('Failed lookupShopifyProductCacheREST', { error });
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
getShopifyProductFromCacheREST = async (pixelId, productId) => {
|
|
22
|
+
getProductFromDynamoDBCache = async (pixelId, productId) => {
|
|
37
23
|
try {
|
|
38
24
|
const cachedProduct = await clients_1.DynamoDbClient.safeGet(this.TABLE_NAME, this.KEY_NAME, `${pixelId}_${productId}`);
|
|
39
25
|
if (cachedProduct) {
|
|
40
|
-
|
|
41
|
-
return
|
|
26
|
+
const product = (0, libs_1.decompressJSON)(cachedProduct.productCompressed);
|
|
27
|
+
return product;
|
|
42
28
|
}
|
|
43
|
-
return
|
|
29
|
+
return undefined;
|
|
44
30
|
}
|
|
45
31
|
catch (error) {
|
|
46
32
|
helpers_1.Logger.error('Failed getShopifyProductCacheREST', { keyName: this.KEY_NAME, pixelId, productId, error });
|
|
47
|
-
return
|
|
33
|
+
return undefined;
|
|
48
34
|
}
|
|
49
35
|
};
|
|
50
|
-
|
|
51
|
-
const ttl =
|
|
52
|
-
const expiresAt = luxon_1.DateTime.
|
|
36
|
+
putProductInDynamoDBCache = async (pixelId, productId, product, ttlInSeconds) => {
|
|
37
|
+
const ttl = ttlInSeconds || this.dynamoDbCacheTtlInSeconds;
|
|
38
|
+
const expiresAt = luxon_1.DateTime.utc().plus({ seconds: ttl }).toSeconds();
|
|
39
|
+
const cachedAt = (0, libs_1.getCurrentTimestamp)();
|
|
40
|
+
const cachedAtEpoch = luxon_1.DateTime.utc().toSeconds();
|
|
41
|
+
const fullSha256 = crypto_1.default.createHash('sha256').update(JSON.stringify(product)).digest('hex');
|
|
42
|
+
const noInventoryProduct = { ...product, totalInventory: undefined, variants: product?.variants?.map(variant => ({ ...variant, inventoryQuantity: undefined, inventoryItem: undefined })) };
|
|
43
|
+
const noInventorySha256 = crypto_1.default.createHash('sha256').update(JSON.stringify(noInventoryProduct)).digest('hex');
|
|
44
|
+
const productCompressed = (0, libs_1.compressJSON)(product);
|
|
53
45
|
const shopifyProductCache = {
|
|
54
46
|
pixelId_productId: `${pixelId}_${productId}`,
|
|
55
47
|
pixelId,
|
|
56
48
|
productId,
|
|
57
|
-
productCompressed
|
|
58
|
-
|
|
49
|
+
productCompressed,
|
|
50
|
+
fullSha256,
|
|
51
|
+
noInventorySha256,
|
|
52
|
+
cachedAt,
|
|
53
|
+
cachedAtEpoch,
|
|
59
54
|
expiresAt
|
|
60
55
|
};
|
|
61
56
|
return await clients_1.DynamoDbClient.safePut(this.TABLE_NAME, shopifyProductCache);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shopify-products-cache-db-service.js","sourceRoot":"","sources":["../../../../src/services/db/shopify-products-cache-db-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shopify-products-cache-db-service.js","sourceRoot":"","sources":["../../../../src/services/db/shopify-products-cache-db-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -94,7 +94,7 @@ class TrackingEventsDbService {
|
|
|
94
94
|
};
|
|
95
95
|
getTrackingEventCountByPixelId = async (indexName, pixelId, offsetInMinutes = 30) => {
|
|
96
96
|
try {
|
|
97
|
-
const pastDateTime = luxon_1.DateTime.
|
|
97
|
+
const pastDateTime = luxon_1.DateTime.utc().minus({ minutes: offsetInMinutes }).toISO();
|
|
98
98
|
const params = {
|
|
99
99
|
TableName: this.TABLE_NAME,
|
|
100
100
|
IndexName: indexName,
|
|
@@ -130,7 +130,7 @@ class TrackingEventsDbService {
|
|
|
130
130
|
const parsedPageURL = new URL(pageURL);
|
|
131
131
|
const hostname = parsedPageURL?.hostname;
|
|
132
132
|
const trackingEventsTableTTLDays = ttlInDays || 15;
|
|
133
|
-
const expiredAt = luxon_1.DateTime.
|
|
133
|
+
const expiredAt = luxon_1.DateTime.utc().plus({ days: trackingEventsTableTTLDays }).toSeconds();
|
|
134
134
|
const trackingEventRecord = {
|
|
135
135
|
eventId: trackingEventCopy.id,
|
|
136
136
|
eventName: trackingEventCopy.name,
|
|
@@ -6,7 +6,12 @@ export interface GetShopifyProductResponse extends ClientResponse<GetProductQuer
|
|
|
6
6
|
}
|
|
7
7
|
export declare class ShopifyProductsServiceV2 {
|
|
8
8
|
private productCacheService;
|
|
9
|
-
|
|
9
|
+
private shopifyProductsCacheDbService;
|
|
10
|
+
private TABLE_NAME;
|
|
11
|
+
private TABLE_KEY;
|
|
12
|
+
private redisCacheTtlInSeconds;
|
|
13
|
+
private dynamoDbCacheTtlInSeconds;
|
|
14
|
+
constructor(cacheLambdaFunctionArn: string, tableName: string, tableKey: string, redisCacheTtlInSeconds: number, dynamoDbCacheTtlInSeconds: number);
|
|
10
15
|
getShopifyProduct: (pixelId: string, shop: string, accessToken: string, productId: string, useCache?: boolean, updateCache?: boolean) => Promise<GetShopifyProductResponse | null>;
|
|
11
16
|
private getShopifyProductFromAPI;
|
|
12
17
|
}
|
|
@@ -5,27 +5,45 @@ const helpers_1 = require("../../../helpers");
|
|
|
5
5
|
const product_cache_service_1 = require("../../cache/product-cache-service");
|
|
6
6
|
const shopify_graphql_transformer_1 = require("../shopify-graphql-transformer");
|
|
7
7
|
const shopify_graphql_client_1 = require("../../../clients/third-party/shopify/shopify-graphql-client");
|
|
8
|
+
const shopify_products_cache_db_service_1 = require("../../db/shopify-products-cache-db-service");
|
|
8
9
|
class ShopifyProductsServiceV2 {
|
|
9
10
|
productCacheService;
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
shopifyProductsCacheDbService;
|
|
12
|
+
TABLE_NAME;
|
|
13
|
+
TABLE_KEY;
|
|
14
|
+
redisCacheTtlInSeconds;
|
|
15
|
+
dynamoDbCacheTtlInSeconds;
|
|
16
|
+
constructor(cacheLambdaFunctionArn, tableName, tableKey, redisCacheTtlInSeconds, dynamoDbCacheTtlInSeconds) {
|
|
17
|
+
this.TABLE_NAME = tableName;
|
|
18
|
+
this.TABLE_KEY = tableKey;
|
|
19
|
+
this.redisCacheTtlInSeconds = redisCacheTtlInSeconds;
|
|
20
|
+
this.dynamoDbCacheTtlInSeconds = dynamoDbCacheTtlInSeconds;
|
|
21
|
+
this.productCacheService = new product_cache_service_1.ProductCacheService(cacheLambdaFunctionArn, this.redisCacheTtlInSeconds);
|
|
22
|
+
this.shopifyProductsCacheDbService = new shopify_products_cache_db_service_1.ShopifyProductsCacheDbService(this.TABLE_NAME, this.TABLE_KEY, this.dynamoDbCacheTtlInSeconds);
|
|
12
23
|
}
|
|
13
24
|
getShopifyProduct = async (pixelId, shop, accessToken, productId, useCache = true, updateCache = true) => {
|
|
14
25
|
try {
|
|
15
26
|
let getShopifyProductResponse = {};
|
|
16
27
|
if (useCache) {
|
|
17
|
-
|
|
28
|
+
let product = await this.productCacheService.getProductFromCache(pixelId, productId);
|
|
18
29
|
if (product) {
|
|
19
30
|
helpers_1.Logger.debug('getShopifyProduct: Product found in cache', { pixelId, shop, productId, product });
|
|
20
31
|
getShopifyProductResponse.transformedProduct = product;
|
|
21
32
|
return getShopifyProductResponse;
|
|
22
33
|
}
|
|
34
|
+
product = await this.shopifyProductsCacheDbService.getProductFromDynamoDBCache(pixelId, productId);
|
|
35
|
+
if (product) {
|
|
36
|
+
helpers_1.Logger.debug('getShopifyProduct: Product found in dynamoDB cache', { pixelId, shop, productId, product });
|
|
37
|
+
getShopifyProductResponse.transformedProduct = product;
|
|
38
|
+
return getShopifyProductResponse;
|
|
39
|
+
}
|
|
23
40
|
}
|
|
24
41
|
getShopifyProductResponse = await this.getShopifyProductFromAPI(pixelId, shop, accessToken, productId, true);
|
|
25
42
|
if (getShopifyProductResponse?.transformedProduct && updateCache) {
|
|
26
43
|
const product = getShopifyProductResponse.transformedProduct;
|
|
27
44
|
helpers_1.Logger.debug('getShopifyProduct: Product found in ShopifyAPI, putting in cache', { pixelId, productId, product });
|
|
28
45
|
await this.productCacheService.putProductInCache(pixelId, productId, product);
|
|
46
|
+
await this.shopifyProductsCacheDbService.putProductInDynamoDBCache(pixelId, productId, product);
|
|
29
47
|
}
|
|
30
48
|
helpers_1.Logger.debug('getShopifyProduct: Returning product', { pixelId, shop, productId, product: getShopifyProductResponse?.transformedProduct });
|
|
31
49
|
return getShopifyProductResponse;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shopify-products-serviceV2.js","sourceRoot":"","sources":["../../../../../src/services/shopify/products/shopify-products-serviceV2.ts"],"names":[],"mappings":";;;AAAA,8CAA0C;AAG1C,6EAAwE;AACxE,gFAA2E;AAC3E,wGAAmG;
|
|
1
|
+
{"version":3,"file":"shopify-products-serviceV2.js","sourceRoot":"","sources":["../../../../../src/services/shopify/products/shopify-products-serviceV2.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,8 @@ export interface ProductCache extends GenericCachedObject {
|
|
|
10
10
|
export declare const getProductCacheKey: (pixelId: string, productId: string) => string;
|
|
11
11
|
export declare class ProductCacheService {
|
|
12
12
|
private genericCacheService;
|
|
13
|
-
|
|
13
|
+
private redisCacheTtlInSeconds;
|
|
14
|
+
constructor(cacheLambdaFunctionArn: string, redisCacheTtlInSeconds: number);
|
|
14
15
|
getCacheKey: (pixelId: string, productId: string) => string;
|
|
15
16
|
getProductFromCache: (pixelId: string, productId: string) => Promise<InternalProduct | undefined>;
|
|
16
17
|
getProductCache: (pixelId: string, productId: string) => Promise<ProductCache | undefined>;
|
|
@@ -8,8 +8,10 @@ export const getProductCacheKey = (pixelId, productId) => {
|
|
|
8
8
|
};
|
|
9
9
|
export class ProductCacheService {
|
|
10
10
|
genericCacheService;
|
|
11
|
-
|
|
11
|
+
redisCacheTtlInSeconds;
|
|
12
|
+
constructor(cacheLambdaFunctionArn, redisCacheTtlInSeconds) {
|
|
12
13
|
this.genericCacheService = new GenericCacheService(cacheLambdaFunctionArn);
|
|
14
|
+
this.redisCacheTtlInSeconds = redisCacheTtlInSeconds || DEFAULT_TTL_IN_SECONDS;
|
|
13
15
|
}
|
|
14
16
|
getCacheKey = (pixelId, productId) => {
|
|
15
17
|
return getProductCacheKey(pixelId, productId);
|
|
@@ -29,7 +31,7 @@ export class ProductCacheService {
|
|
|
29
31
|
};
|
|
30
32
|
putProductInCache = async (pixelId, productId, product, ttlInSeconds) => {
|
|
31
33
|
const cacheKey = this.getCacheKey(pixelId, productId);
|
|
32
|
-
const ttl = ttlInSeconds ||
|
|
34
|
+
const ttl = ttlInSeconds || this.redisCacheTtlInSeconds;
|
|
33
35
|
const expiresAt = DateTime.utc().plus({ seconds: ttl }).toSeconds();
|
|
34
36
|
const cachedAtEpoch = DateTime.utc().toSeconds();
|
|
35
37
|
const fullSha256 = crypto.createHash('sha256').update(JSON.stringify(product)).digest('hex');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-cache-service.js","sourceRoot":"","sources":["../../../../src/services/cache/product-cache-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAU7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,EAAE;IACvE,OAAO,oBAAoB,OAAO,IAAI,SAAS,EAAE,CAAC;AACpD,CAAC,CAAA;AAED,MAAM,OAAO,mBAAmB;IACtB,mBAAmB,CAAsB;
|
|
1
|
+
{"version":3,"file":"product-cache-service.js","sourceRoot":"","sources":["../../../../src/services/cache/product-cache-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAU7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,EAAE;IACvE,OAAO,oBAAoB,OAAO,IAAI,SAAS,EAAE,CAAC;AACpD,CAAC,CAAA;AAED,MAAM,OAAO,mBAAmB;IACtB,mBAAmB,CAAsB;IACzC,sBAAsB,CAAS;IAEvC,YAAY,sBAA8B,EAAE,sBAA8B;QACxE,IAAI,CAAC,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,sBAAsB,CAAC,CAAC;QAC3E,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,IAAI,sBAAsB,CAAC;IACjF,CAAC;IAEM,WAAW,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,EAAE;QAC1D,OAAO,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC,CAAA;IAEM,mBAAmB,GAAG,KAAK,EAAE,OAAe,EAAE,SAAiB,EAAwC,EAAE;QAC9G,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAClE,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE;YACvD,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YAC7D,OAAO,OAAO,CAAC;SAChB;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAA;IAEM,eAAe,GAAG,KAAK,EAAE,OAAe,EAAE,SAAiB,EAAqC,EAAE;QACvG,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAe,QAAQ,CAAC,CAAC;QACxF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAA;IAEM,iBAAiB,GAAG,KAAK,EAAE,OAAe,EAAE,SAAiB,EAAE,OAAwB,EAAE,YAAqB,EAAE,EAAE;QACvH,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,YAAY,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACxD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;QACpE,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;QACjD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7F,MAAM,kBAAkB,GAAoB,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC;QAC7M,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/G,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,CAAW,CAAC;QAC1D,MAAM,YAAY,GAAiB;YACjC,iBAAiB;YACjB,UAAU;YACV,iBAAiB;YACjB,aAAa;YACb,SAAS;SACV,CAAC;QACF,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC;IAC5E,CAAC,CAAA;IAEM,sBAAsB,GAAG,KAAK,EAAE,OAAe,EAAE,SAAiB,EAAE,EAAE;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC5D,CAAC,CAAA;IAEO,mBAAmB,GAAG,CAAC,UAAwB,EAAE,EAAE;QACzD,IAAI,UAAU,EAAE,SAAS,IAAI,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE;YAC9E,OAAO,IAAI,CAAC;SACb;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAA;CACF"}
|
|
@@ -130,7 +130,7 @@ export class LogEventsDbService {
|
|
|
130
130
|
putLogEvent = async (logEvent, logGroup, ttlInMinutes) => {
|
|
131
131
|
const logEventCopy = JSON.parse(JSON.stringify(logEvent));
|
|
132
132
|
delete logEventCopy?.data?.logStorage;
|
|
133
|
-
const expiredAt = DateTime.
|
|
133
|
+
const expiredAt = DateTime.utc().plus({ minutes: ttlInMinutes ?? 15 }).toSeconds();
|
|
134
134
|
const logEventRecord = {
|
|
135
135
|
eventId: logEventCopy.id,
|
|
136
136
|
eventName: logEventCopy.name,
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { InternalProduct } from '../shopify/types/product';
|
|
2
|
+
import { ProductCache } from '../cache';
|
|
3
|
+
export interface ShopifyProductDynamoDbCache extends ProductCache {
|
|
4
|
+
pixelId_productId: string;
|
|
5
|
+
pixelId: string;
|
|
6
|
+
productId: string;
|
|
7
|
+
}
|
|
2
8
|
export declare class ShopifyProductsCacheDbService {
|
|
3
9
|
TABLE_NAME: string;
|
|
4
10
|
KEY_NAME: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
private dynamoDbCacheTtlInSeconds;
|
|
12
|
+
constructor(tableName: string, keyName: string, dynamoDbCacheTtlInSeconds: number);
|
|
13
|
+
getProductFromDynamoDBCache: (pixelId: string, productId: string) => Promise<InternalProduct | undefined>;
|
|
14
|
+
putProductInDynamoDBCache: (pixelId: string, productId: string, product: InternalProduct, ttlInSeconds?: number) => Promise<import("@aws-sdk/lib-dynamodb").PutCommandOutput | null>;
|
|
9
15
|
}
|
|
@@ -1,58 +1,50 @@
|
|
|
1
|
-
import { DynamoDbClient
|
|
1
|
+
import { DynamoDbClient } from '../../clients';
|
|
2
2
|
import { compressJSON, decompressJSON, getCurrentTimestamp } from '../../libs';
|
|
3
3
|
import { DateTime } from 'luxon';
|
|
4
4
|
import { Logger } from '../../helpers';
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
const DEFAULT_TTL_IN_SECONDS = 7 * 24 * 3600;
|
|
5
7
|
export class ShopifyProductsCacheDbService {
|
|
6
8
|
TABLE_NAME;
|
|
7
9
|
KEY_NAME;
|
|
8
|
-
|
|
10
|
+
dynamoDbCacheTtlInSeconds;
|
|
11
|
+
constructor(tableName, keyName, dynamoDbCacheTtlInSeconds) {
|
|
9
12
|
this.TABLE_NAME = tableName;
|
|
10
13
|
this.KEY_NAME = keyName;
|
|
14
|
+
this.dynamoDbCacheTtlInSeconds = dynamoDbCacheTtlInSeconds || DEFAULT_TTL_IN_SECONDS;
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
try {
|
|
14
|
-
const cachedShopifyProduct = await this.getShopifyProductFromCacheREST(pixelId, productId);
|
|
15
|
-
if (cachedShopifyProduct) {
|
|
16
|
-
return cachedShopifyProduct.product;
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
const productRes = await ShopifyClient.getProductREST(shop, accessToken, productId);
|
|
20
|
-
if (productRes.status === 200 && productRes?.data?.product) {
|
|
21
|
-
const product = productRes.data.product;
|
|
22
|
-
await this.putShopifyProductCacheREST(pixelId, productId, product);
|
|
23
|
-
return product;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
Logger.error('Failed lookupShopifyProductCacheREST', { error });
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
getShopifyProductFromCacheREST = async (pixelId, productId) => {
|
|
16
|
+
getProductFromDynamoDBCache = async (pixelId, productId) => {
|
|
34
17
|
try {
|
|
35
18
|
const cachedProduct = await DynamoDbClient.safeGet(this.TABLE_NAME, this.KEY_NAME, `${pixelId}_${productId}`);
|
|
36
19
|
if (cachedProduct) {
|
|
37
|
-
|
|
38
|
-
return
|
|
20
|
+
const product = decompressJSON(cachedProduct.productCompressed);
|
|
21
|
+
return product;
|
|
39
22
|
}
|
|
40
|
-
return
|
|
23
|
+
return undefined;
|
|
41
24
|
}
|
|
42
25
|
catch (error) {
|
|
43
26
|
Logger.error('Failed getShopifyProductCacheREST', { keyName: this.KEY_NAME, pixelId, productId, error });
|
|
44
|
-
return
|
|
27
|
+
return undefined;
|
|
45
28
|
}
|
|
46
29
|
};
|
|
47
|
-
|
|
48
|
-
const ttl =
|
|
49
|
-
const expiresAt = DateTime.
|
|
30
|
+
putProductInDynamoDBCache = async (pixelId, productId, product, ttlInSeconds) => {
|
|
31
|
+
const ttl = ttlInSeconds || this.dynamoDbCacheTtlInSeconds;
|
|
32
|
+
const expiresAt = DateTime.utc().plus({ seconds: ttl }).toSeconds();
|
|
33
|
+
const cachedAt = getCurrentTimestamp();
|
|
34
|
+
const cachedAtEpoch = DateTime.utc().toSeconds();
|
|
35
|
+
const fullSha256 = crypto.createHash('sha256').update(JSON.stringify(product)).digest('hex');
|
|
36
|
+
const noInventoryProduct = { ...product, totalInventory: undefined, variants: product?.variants?.map(variant => ({ ...variant, inventoryQuantity: undefined, inventoryItem: undefined })) };
|
|
37
|
+
const noInventorySha256 = crypto.createHash('sha256').update(JSON.stringify(noInventoryProduct)).digest('hex');
|
|
38
|
+
const productCompressed = compressJSON(product);
|
|
50
39
|
const shopifyProductCache = {
|
|
51
40
|
pixelId_productId: `${pixelId}_${productId}`,
|
|
52
41
|
pixelId,
|
|
53
42
|
productId,
|
|
54
|
-
productCompressed
|
|
55
|
-
|
|
43
|
+
productCompressed,
|
|
44
|
+
fullSha256,
|
|
45
|
+
noInventorySha256,
|
|
46
|
+
cachedAt,
|
|
47
|
+
cachedAtEpoch,
|
|
56
48
|
expiresAt
|
|
57
49
|
};
|
|
58
50
|
return await DynamoDbClient.safePut(this.TABLE_NAME, shopifyProductCache);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shopify-products-cache-db-service.js","sourceRoot":"","sources":["../../../../src/services/db/shopify-products-cache-db-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"shopify-products-cache-db-service.js","sourceRoot":"","sources":["../../../../src/services/db/shopify-products-cache-db-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -91,7 +91,7 @@ export class TrackingEventsDbService {
|
|
|
91
91
|
};
|
|
92
92
|
getTrackingEventCountByPixelId = async (indexName, pixelId, offsetInMinutes = 30) => {
|
|
93
93
|
try {
|
|
94
|
-
const pastDateTime = DateTime.
|
|
94
|
+
const pastDateTime = DateTime.utc().minus({ minutes: offsetInMinutes }).toISO();
|
|
95
95
|
const params = {
|
|
96
96
|
TableName: this.TABLE_NAME,
|
|
97
97
|
IndexName: indexName,
|
|
@@ -127,7 +127,7 @@ export class TrackingEventsDbService {
|
|
|
127
127
|
const parsedPageURL = new URL(pageURL);
|
|
128
128
|
const hostname = parsedPageURL?.hostname;
|
|
129
129
|
const trackingEventsTableTTLDays = ttlInDays || 15;
|
|
130
|
-
const expiredAt = DateTime.
|
|
130
|
+
const expiredAt = DateTime.utc().plus({ days: trackingEventsTableTTLDays }).toSeconds();
|
|
131
131
|
const trackingEventRecord = {
|
|
132
132
|
eventId: trackingEventCopy.id,
|
|
133
133
|
eventName: trackingEventCopy.name,
|
|
@@ -6,7 +6,12 @@ export interface GetShopifyProductResponse extends ClientResponse<GetProductQuer
|
|
|
6
6
|
}
|
|
7
7
|
export declare class ShopifyProductsServiceV2 {
|
|
8
8
|
private productCacheService;
|
|
9
|
-
|
|
9
|
+
private shopifyProductsCacheDbService;
|
|
10
|
+
private TABLE_NAME;
|
|
11
|
+
private TABLE_KEY;
|
|
12
|
+
private redisCacheTtlInSeconds;
|
|
13
|
+
private dynamoDbCacheTtlInSeconds;
|
|
14
|
+
constructor(cacheLambdaFunctionArn: string, tableName: string, tableKey: string, redisCacheTtlInSeconds: number, dynamoDbCacheTtlInSeconds: number);
|
|
10
15
|
getShopifyProduct: (pixelId: string, shop: string, accessToken: string, productId: string, useCache?: boolean, updateCache?: boolean) => Promise<GetShopifyProductResponse | null>;
|
|
11
16
|
private getShopifyProductFromAPI;
|
|
12
17
|
}
|
|
@@ -2,27 +2,45 @@ import { Logger } from '../../../helpers';
|
|
|
2
2
|
import { ProductCacheService } from '../../cache/product-cache-service';
|
|
3
3
|
import { ShopifyGraphQLTransformer } from '../shopify-graphql-transformer';
|
|
4
4
|
import { ShopifyGraphQLClient } from '../../../clients/third-party/shopify/shopify-graphql-client';
|
|
5
|
+
import { ShopifyProductsCacheDbService } from '../../db/shopify-products-cache-db-service';
|
|
5
6
|
export class ShopifyProductsServiceV2 {
|
|
6
7
|
productCacheService;
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
shopifyProductsCacheDbService;
|
|
9
|
+
TABLE_NAME;
|
|
10
|
+
TABLE_KEY;
|
|
11
|
+
redisCacheTtlInSeconds;
|
|
12
|
+
dynamoDbCacheTtlInSeconds;
|
|
13
|
+
constructor(cacheLambdaFunctionArn, tableName, tableKey, redisCacheTtlInSeconds, dynamoDbCacheTtlInSeconds) {
|
|
14
|
+
this.TABLE_NAME = tableName;
|
|
15
|
+
this.TABLE_KEY = tableKey;
|
|
16
|
+
this.redisCacheTtlInSeconds = redisCacheTtlInSeconds;
|
|
17
|
+
this.dynamoDbCacheTtlInSeconds = dynamoDbCacheTtlInSeconds;
|
|
18
|
+
this.productCacheService = new ProductCacheService(cacheLambdaFunctionArn, this.redisCacheTtlInSeconds);
|
|
19
|
+
this.shopifyProductsCacheDbService = new ShopifyProductsCacheDbService(this.TABLE_NAME, this.TABLE_KEY, this.dynamoDbCacheTtlInSeconds);
|
|
9
20
|
}
|
|
10
21
|
getShopifyProduct = async (pixelId, shop, accessToken, productId, useCache = true, updateCache = true) => {
|
|
11
22
|
try {
|
|
12
23
|
let getShopifyProductResponse = {};
|
|
13
24
|
if (useCache) {
|
|
14
|
-
|
|
25
|
+
let product = await this.productCacheService.getProductFromCache(pixelId, productId);
|
|
15
26
|
if (product) {
|
|
16
27
|
Logger.debug('getShopifyProduct: Product found in cache', { pixelId, shop, productId, product });
|
|
17
28
|
getShopifyProductResponse.transformedProduct = product;
|
|
18
29
|
return getShopifyProductResponse;
|
|
19
30
|
}
|
|
31
|
+
product = await this.shopifyProductsCacheDbService.getProductFromDynamoDBCache(pixelId, productId);
|
|
32
|
+
if (product) {
|
|
33
|
+
Logger.debug('getShopifyProduct: Product found in dynamoDB cache', { pixelId, shop, productId, product });
|
|
34
|
+
getShopifyProductResponse.transformedProduct = product;
|
|
35
|
+
return getShopifyProductResponse;
|
|
36
|
+
}
|
|
20
37
|
}
|
|
21
38
|
getShopifyProductResponse = await this.getShopifyProductFromAPI(pixelId, shop, accessToken, productId, true);
|
|
22
39
|
if (getShopifyProductResponse?.transformedProduct && updateCache) {
|
|
23
40
|
const product = getShopifyProductResponse.transformedProduct;
|
|
24
41
|
Logger.debug('getShopifyProduct: Product found in ShopifyAPI, putting in cache', { pixelId, productId, product });
|
|
25
42
|
await this.productCacheService.putProductInCache(pixelId, productId, product);
|
|
43
|
+
await this.shopifyProductsCacheDbService.putProductInDynamoDBCache(pixelId, productId, product);
|
|
26
44
|
}
|
|
27
45
|
Logger.debug('getShopifyProduct: Returning product', { pixelId, shop, productId, product: getShopifyProductResponse?.transformedProduct });
|
|
28
46
|
return getShopifyProductResponse;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shopify-products-serviceV2.js","sourceRoot":"","sources":["../../../../../src/services/shopify/products/shopify-products-serviceV2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6DAA6D,CAAC;
|
|
1
|
+
{"version":3,"file":"shopify-products-serviceV2.js","sourceRoot":"","sources":["../../../../../src/services/shopify/products/shopify-products-serviceV2.ts"],"names":[],"mappings":"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"}
|