@pvh-afl/core 1.0.15 → 1.0.17
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/integrations/index.d.ts +2 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +4 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/integrations.module.d.ts.map +1 -1
- package/dist/integrations/integrations.module.js +10 -0
- package/dist/integrations/integrations.module.js.map +1 -1
- package/dist/integrations/reviews/index.d.ts +3 -0
- package/dist/integrations/reviews/index.d.ts.map +1 -0
- package/dist/integrations/reviews/index.js +6 -0
- package/dist/integrations/reviews/index.js.map +1 -0
- package/dist/integrations/reviews/judgeme.service.d.ts +86 -0
- package/dist/integrations/reviews/judgeme.service.d.ts.map +1 -0
- package/dist/integrations/reviews/judgeme.service.js +448 -0
- package/dist/integrations/reviews/judgeme.service.js.map +1 -0
- package/dist/integrations/reviews/judgeme.types.d.ts +127 -0
- package/dist/integrations/reviews/judgeme.types.d.ts.map +1 -0
- package/dist/integrations/reviews/judgeme.types.js +9 -0
- package/dist/integrations/reviews/judgeme.types.js.map +1 -0
- package/dist/integrations/search/search.mapper.d.ts.map +1 -1
- package/dist/integrations/search/search.mapper.js +1 -0
- package/dist/integrations/search/search.mapper.js.map +1 -1
- package/dist/integrations/search/search.types.d.ts +3 -1
- package/dist/integrations/search/search.types.d.ts.map +1 -1
- package/dist/integrations/search/search.types.js.map +1 -1
- package/dist/integrations/search/wizzy.service.d.ts.map +1 -1
- package/dist/integrations/search/wizzy.service.js +8 -1
- package/dist/integrations/search/wizzy.service.js.map +1 -1
- package/dist/integrations/search/wizzy.types.d.ts +18 -0
- package/dist/integrations/search/wizzy.types.d.ts.map +1 -1
- package/dist/integrations/swish/index.d.ts +3 -0
- package/dist/integrations/swish/index.d.ts.map +1 -0
- package/dist/integrations/swish/index.js +6 -0
- package/dist/integrations/swish/index.js.map +1 -0
- package/dist/integrations/swish/swish.service.d.ts +87 -0
- package/dist/integrations/swish/swish.service.d.ts.map +1 -0
- package/dist/integrations/swish/swish.service.js +463 -0
- package/dist/integrations/swish/swish.service.js.map +1 -0
- package/dist/integrations/swish/swish.types.d.ts +108 -0
- package/dist/integrations/swish/swish.types.d.ts.map +1 -0
- package/dist/integrations/swish/swish.types.js +9 -0
- package/dist/integrations/swish/swish.types.js.map +1 -0
- package/package.json +1 -1
|
@@ -5,6 +5,8 @@ export * from './oms';
|
|
|
5
5
|
export * from './loyalty';
|
|
6
6
|
export * from './shopify-theme';
|
|
7
7
|
export * from './search';
|
|
8
|
+
export * from './reviews';
|
|
9
|
+
export * from './swish';
|
|
8
10
|
export * from './integration.factory';
|
|
9
11
|
export * from './integrations.module';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,YAAY,CAAC;AAG3B,cAAc,OAAO,CAAC;AAGtB,cAAc,WAAW,CAAC;AAG1B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,UAAU,CAAC;AAGzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,YAAY,CAAC;AAG3B,cAAc,OAAO,CAAC;AAGtB,cAAc,WAAW,CAAC;AAG1B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AAGxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|
|
@@ -14,6 +14,10 @@ tslib_1.__exportStar(require("./loyalty"), exports);
|
|
|
14
14
|
tslib_1.__exportStar(require("./shopify-theme"), exports);
|
|
15
15
|
// Search integrations (Wizzy)
|
|
16
16
|
tslib_1.__exportStar(require("./search"), exports);
|
|
17
|
+
// Reviews integrations (Judge.me)
|
|
18
|
+
tslib_1.__exportStar(require("./reviews"), exports);
|
|
19
|
+
// Wishlist integrations (Swish)
|
|
20
|
+
tslib_1.__exportStar(require("./swish"), exports);
|
|
17
21
|
// Integration factory and module
|
|
18
22
|
tslib_1.__exportStar(require("./integration.factory"), exports);
|
|
19
23
|
tslib_1.__exportStar(require("./integrations.module"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":";;;AAAA,sCAAsC;AACtC,8DAAoC;AACpC,qEAA2C;AAE3C,kCAAkC;AAClC,qDAA2B;AAE3B,2BAA2B;AAC3B,gDAAsB;AAEtB,mCAAmC;AACnC,oDAA0B;AAE1B,oBAAoB;AACpB,0DAAgC;AAEhC,8BAA8B;AAC9B,mDAAyB;AAEzB,iCAAiC;AACjC,gEAAsC;AACtC,gEAAsC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":";;;AAAA,sCAAsC;AACtC,8DAAoC;AACpC,qEAA2C;AAE3C,kCAAkC;AAClC,qDAA2B;AAE3B,2BAA2B;AAC3B,gDAAsB;AAEtB,mCAAmC;AACnC,oDAA0B;AAE1B,oBAAoB;AACpB,0DAAgC;AAEhC,8BAA8B;AAC9B,mDAAyB;AAEzB,kCAAkC;AAClC,oDAA0B;AAE1B,gCAAgC;AAChC,kDAAwB;AAExB,iCAAiC;AACjC,gEAAsC;AACtC,gEAAsC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrations.module.d.ts","sourceRoot":"","sources":["../../src/integrations/integrations.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"integrations.module.d.ts","sourceRoot":"","sources":["../../src/integrations/integrations.module.ts"],"names":[],"mappings":"AAsBA,qBAmCa,kBAAkB;CAAG"}
|
|
@@ -16,6 +16,10 @@ const capillary_auth_service_1 = require("./loyalty/capillary-auth.service");
|
|
|
16
16
|
const capillary_coupon_service_1 = require("./loyalty/capillary-coupon.service");
|
|
17
17
|
// Search
|
|
18
18
|
const wizzy_service_1 = require("./search/wizzy.service");
|
|
19
|
+
// Reviews
|
|
20
|
+
const judgeme_service_1 = require("./reviews/judgeme.service");
|
|
21
|
+
// Wishlist
|
|
22
|
+
const swish_service_1 = require("./swish/swish.service");
|
|
19
23
|
// CacheModule and ConfigModule are @Global() so no import needed
|
|
20
24
|
let IntegrationsModule = class IntegrationsModule {
|
|
21
25
|
};
|
|
@@ -37,6 +41,10 @@ exports.IntegrationsModule = IntegrationsModule = tslib_1.__decorate([
|
|
|
37
41
|
capillary_coupon_service_1.CapillaryCouponService,
|
|
38
42
|
// Search
|
|
39
43
|
wizzy_service_1.WizzyService,
|
|
44
|
+
// Reviews
|
|
45
|
+
judgeme_service_1.JudgeMeService,
|
|
46
|
+
// Wishlist
|
|
47
|
+
swish_service_1.SwishService,
|
|
40
48
|
],
|
|
41
49
|
exports: [
|
|
42
50
|
integration_factory_1.IntegrationFactory,
|
|
@@ -48,6 +56,8 @@ exports.IntegrationsModule = IntegrationsModule = tslib_1.__decorate([
|
|
|
48
56
|
capillary_auth_service_1.CapillaryAuthService,
|
|
49
57
|
capillary_coupon_service_1.CapillaryCouponService,
|
|
50
58
|
wizzy_service_1.WizzyService,
|
|
59
|
+
judgeme_service_1.JudgeMeService,
|
|
60
|
+
swish_service_1.SwishService,
|
|
51
61
|
],
|
|
52
62
|
})
|
|
53
63
|
], IntegrationsModule);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrations.module.js","sourceRoot":"","sources":["../../src/integrations/integrations.module.ts"],"names":[],"mappings":";;;;AAAA,2CAAwC;AACxC,+DAA2D;AAC3D,yEAAoE;AAEpE,8BAA8B;AAC9B,gEAAoE;AACpE,4EAAuE;AACvE,kFAA6E;AAC7E,iEAA4D;AAC5D,uDAAmD;AACnD,oBAAoB;AACpB,6EAAwE;AACxE,iFAA4E;AAC5E,SAAS;AACT,0DAAsD;
|
|
1
|
+
{"version":3,"file":"integrations.module.js","sourceRoot":"","sources":["../../src/integrations/integrations.module.ts"],"names":[],"mappings":";;;;AAAA,2CAAwC;AACxC,+DAA2D;AAC3D,yEAAoE;AAEpE,8BAA8B;AAC9B,gEAAoE;AACpE,4EAAuE;AACvE,kFAA6E;AAC7E,iEAA4D;AAC5D,uDAAmD;AACnD,oBAAoB;AACpB,6EAAwE;AACxE,iFAA4E;AAC5E,SAAS;AACT,0DAAsD;AACtD,UAAU;AACV,+DAA2D;AAC3D,WAAW;AACX,yDAAqD;AAErD,iEAAiE;AAqC1D,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;CAAG,CAAA;AAArB,gDAAkB;6BAAlB,kBAAkB;IAnC9B,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,wCAAkB;YAClB,iDAAsB;YACtB,WAAW;YACX,wCAAsB;YACtB,2CAAmB;YACnB,iDAAsB;YACtB,MAAM;YACN,qCAAgB;YAChB,4BAAY;YACZ,UAAU;YACV,6CAAoB;YACpB,iDAAsB;YACtB,SAAS;YACT,4BAAY;YACZ,UAAU;YACV,gCAAc;YACd,WAAW;YACX,4BAAY;SACb;QACD,OAAO,EAAE;YACP,wCAAkB;YAClB,gEAAgE;YAChE,wCAAsB;YACtB,2CAAmB;YACnB,iDAAsB;YACtB,4BAAY;YACZ,6CAAoB;YACpB,iDAAsB;YACtB,4BAAY;YACZ,gCAAc;YACd,4BAAY;SACb;KACF,CAAC;GACW,kBAAkB,CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/reviews/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./judgeme.types"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./judgeme.service"), exports);
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/reviews/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,4DAAkC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { IntegrationResponse } from '../integration.types';
|
|
2
|
+
import { JudgeMeConfig, JudgeMeReviewsResponse, JudgeMeReview, JudgeMeGetReviewsRequest, JudgeMeSubmitRequest, IReviewsService } from './judgeme.types';
|
|
3
|
+
/**
|
|
4
|
+
* Judge.me Reviews Service
|
|
5
|
+
*
|
|
6
|
+
* Provides integration with Judge.me's REST API for:
|
|
7
|
+
* - Resolving Shopify product ID to Judge.me internal product ID
|
|
8
|
+
* - Fetching reviews (GET /api/v1/reviews)
|
|
9
|
+
* - Submitting reviews (POST /api/v1/reviews)
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT:
|
|
12
|
+
* - Judge.me uses its own internal product IDs, not Shopify product IDs directly
|
|
13
|
+
* - Private token must be sent via X-Api-Token header
|
|
14
|
+
* - Review submissions are single-attempt only (no idempotency key)
|
|
15
|
+
*
|
|
16
|
+
* @see https://judge.me/api/docs
|
|
17
|
+
*/
|
|
18
|
+
export declare class JudgeMeService implements IReviewsService {
|
|
19
|
+
private config;
|
|
20
|
+
private brand;
|
|
21
|
+
private readonly defaultTimeout;
|
|
22
|
+
private productIdCache;
|
|
23
|
+
/**
|
|
24
|
+
* Configure the service for a specific brand
|
|
25
|
+
*/
|
|
26
|
+
configure(brand: string, config: JudgeMeConfig): void;
|
|
27
|
+
/**
|
|
28
|
+
* Check if the service is configured
|
|
29
|
+
*/
|
|
30
|
+
isConfigured(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Set cached product ID (for external cache integration)
|
|
33
|
+
*/
|
|
34
|
+
setCachedProductId(shopifyProductId: string, judgeMeProductId: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get cached product ID (for external cache integration)
|
|
37
|
+
*/
|
|
38
|
+
getCachedProductId(shopifyProductId: string): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve Shopify product ID to Judge.me internal product ID.
|
|
41
|
+
*
|
|
42
|
+
* Judge.me maintains its own product catalog. Before listing reviews or
|
|
43
|
+
* submitting, we need to resolve the Shopify external_id to Judge.me's
|
|
44
|
+
* internal product.id.
|
|
45
|
+
*/
|
|
46
|
+
resolveProductId(shopifyProductId: string): Promise<IntegrationResponse<string>>;
|
|
47
|
+
/**
|
|
48
|
+
* Get reviews for a product.
|
|
49
|
+
*
|
|
50
|
+
* Uses private token via X-Api-Token header.
|
|
51
|
+
* Returns all reviews including unpublished - caller must filter.
|
|
52
|
+
*/
|
|
53
|
+
getReviews(params: JudgeMeGetReviewsRequest): Promise<IntegrationResponse<JudgeMeReviewsResponse>>;
|
|
54
|
+
/**
|
|
55
|
+
* Get review count for a product.
|
|
56
|
+
*/
|
|
57
|
+
getReviewCount(shopifyProductId: string): Promise<IntegrationResponse<number>>;
|
|
58
|
+
/**
|
|
59
|
+
* Submit a review.
|
|
60
|
+
*
|
|
61
|
+
* CRITICAL:
|
|
62
|
+
* - NO idempotency key - retried POST creates DUPLICATE review
|
|
63
|
+
* - Single attempt only
|
|
64
|
+
* - Reviews are created UNPUBLISHED and UNVERIFIED
|
|
65
|
+
* - Cannot be deleted via API
|
|
66
|
+
* - Name/email should be derived server-side, NOT from client
|
|
67
|
+
*/
|
|
68
|
+
submitReview(params: JudgeMeSubmitRequest): Promise<IntegrationResponse<JudgeMeReview>>;
|
|
69
|
+
/**
|
|
70
|
+
* Map sort parameter to Judge.me API parameter.
|
|
71
|
+
*/
|
|
72
|
+
static mapSortParam(sort: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Return not configured error
|
|
75
|
+
*/
|
|
76
|
+
private notConfiguredError;
|
|
77
|
+
/**
|
|
78
|
+
* Extract numeric ID from Shopify GID or return as-is if already numeric.
|
|
79
|
+
*/
|
|
80
|
+
private extractNumericId;
|
|
81
|
+
/**
|
|
82
|
+
* Normalize error responses
|
|
83
|
+
*/
|
|
84
|
+
private normalizeError;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=judgeme.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judgeme.service.d.ts","sourceRoot":"","sources":["../../../src/integrations/reviews/judgeme.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAoB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,oBAAoB,EACpB,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;GAcG;AACH,qBACa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAGxC,OAAO,CAAC,cAAc,CAAkC;IAExD;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI;IASrD;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAI5E;;OAEG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIhE;;;;;;OAMG;IACG,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IA6EtF;;;;;OAKG;IACG,UAAU,CACd,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,sBAAsB,CAAC,CAAC;IA2EvD;;OAEG;IACG,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IA2DpF;;;;;;;;;OASG;IACG,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAuJ7F;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAmBzC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACH,OAAO,CAAC,cAAc;CA8BvB"}
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JudgeMeService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const logger_1 = require("../../common/logger");
|
|
7
|
+
/**
|
|
8
|
+
* Judge.me Reviews Service
|
|
9
|
+
*
|
|
10
|
+
* Provides integration with Judge.me's REST API for:
|
|
11
|
+
* - Resolving Shopify product ID to Judge.me internal product ID
|
|
12
|
+
* - Fetching reviews (GET /api/v1/reviews)
|
|
13
|
+
* - Submitting reviews (POST /api/v1/reviews)
|
|
14
|
+
*
|
|
15
|
+
* IMPORTANT:
|
|
16
|
+
* - Judge.me uses its own internal product IDs, not Shopify product IDs directly
|
|
17
|
+
* - Private token must be sent via X-Api-Token header
|
|
18
|
+
* - Review submissions are single-attempt only (no idempotency key)
|
|
19
|
+
*
|
|
20
|
+
* @see https://judge.me/api/docs
|
|
21
|
+
*/
|
|
22
|
+
let JudgeMeService = class JudgeMeService {
|
|
23
|
+
config = null;
|
|
24
|
+
brand = '';
|
|
25
|
+
defaultTimeout = 10000;
|
|
26
|
+
// In-memory cache for product ID resolution (populated by consuming app's cache service)
|
|
27
|
+
productIdCache = new Map();
|
|
28
|
+
/**
|
|
29
|
+
* Configure the service for a specific brand
|
|
30
|
+
*/
|
|
31
|
+
configure(brand, config) {
|
|
32
|
+
this.brand = brand;
|
|
33
|
+
this.config = {
|
|
34
|
+
timeout: this.defaultTimeout,
|
|
35
|
+
...config,
|
|
36
|
+
};
|
|
37
|
+
logger_1.logger.info('JudgeMe reviews service configured', { brand });
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if the service is configured
|
|
41
|
+
*/
|
|
42
|
+
isConfigured() {
|
|
43
|
+
return this.config !== null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Set cached product ID (for external cache integration)
|
|
47
|
+
*/
|
|
48
|
+
setCachedProductId(shopifyProductId, judgeMeProductId) {
|
|
49
|
+
this.productIdCache.set(shopifyProductId, judgeMeProductId);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get cached product ID (for external cache integration)
|
|
53
|
+
*/
|
|
54
|
+
getCachedProductId(shopifyProductId) {
|
|
55
|
+
return this.productIdCache.get(shopifyProductId);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve Shopify product ID to Judge.me internal product ID.
|
|
59
|
+
*
|
|
60
|
+
* Judge.me maintains its own product catalog. Before listing reviews or
|
|
61
|
+
* submitting, we need to resolve the Shopify external_id to Judge.me's
|
|
62
|
+
* internal product.id.
|
|
63
|
+
*/
|
|
64
|
+
async resolveProductId(shopifyProductId) {
|
|
65
|
+
if (!this.config) {
|
|
66
|
+
return this.notConfiguredError();
|
|
67
|
+
}
|
|
68
|
+
// Check in-memory cache first
|
|
69
|
+
const cached = this.productIdCache.get(shopifyProductId);
|
|
70
|
+
if (cached) {
|
|
71
|
+
return { success: true, data: cached };
|
|
72
|
+
}
|
|
73
|
+
const numericId = this.extractNumericId(shopifyProductId);
|
|
74
|
+
const url = new URL(`${this.config.baseUrl}/products/-1`);
|
|
75
|
+
url.searchParams.set('shop_domain', this.config.shopDomain);
|
|
76
|
+
url.searchParams.set('api_token', this.config.privateToken);
|
|
77
|
+
url.searchParams.set('external_id', numericId);
|
|
78
|
+
try {
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout ?? this.defaultTimeout);
|
|
81
|
+
const response = await fetch(url.toString(), {
|
|
82
|
+
method: 'GET',
|
|
83
|
+
headers: { 'Content-Type': 'application/json' },
|
|
84
|
+
signal: controller.signal,
|
|
85
|
+
});
|
|
86
|
+
clearTimeout(timeoutId);
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
const errorText = await response.text();
|
|
89
|
+
logger_1.logger.error('Failed to resolve Judge.me product ID', {
|
|
90
|
+
brand: this.brand,
|
|
91
|
+
shopifyProductId,
|
|
92
|
+
status: response.status,
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
error: this.normalizeError(response.status, errorText),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const data = (await response.json());
|
|
100
|
+
const judgeMeProductId = data.product.id.toString();
|
|
101
|
+
// Cache the mapping
|
|
102
|
+
this.productIdCache.set(shopifyProductId, judgeMeProductId);
|
|
103
|
+
logger_1.logger.info('Resolved Judge.me product ID', {
|
|
104
|
+
brand: this.brand,
|
|
105
|
+
shopifyProductId,
|
|
106
|
+
judgeMeProductId,
|
|
107
|
+
});
|
|
108
|
+
return { success: true, data: judgeMeProductId };
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger_1.logger.error('Judge.me product resolution failed', {
|
|
112
|
+
brand: this.brand,
|
|
113
|
+
shopifyProductId,
|
|
114
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
success: false,
|
|
118
|
+
error: {
|
|
119
|
+
code: 'REQUEST_FAILED',
|
|
120
|
+
message: error instanceof Error ? error.message : 'Request failed',
|
|
121
|
+
details: error,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get reviews for a product.
|
|
128
|
+
*
|
|
129
|
+
* Uses private token via X-Api-Token header.
|
|
130
|
+
* Returns all reviews including unpublished - caller must filter.
|
|
131
|
+
*/
|
|
132
|
+
async getReviews(params) {
|
|
133
|
+
if (!this.config) {
|
|
134
|
+
return this.notConfiguredError();
|
|
135
|
+
}
|
|
136
|
+
const { shopifyProductId, page = 1, perPage = 10, sortBy = 'created_at', } = params;
|
|
137
|
+
// Resolve to Judge.me internal product ID
|
|
138
|
+
const productIdResult = await this.resolveProductId(shopifyProductId);
|
|
139
|
+
if (!productIdResult.success) {
|
|
140
|
+
return { success: false, error: productIdResult.error };
|
|
141
|
+
}
|
|
142
|
+
const url = new URL(`${this.config.baseUrl}/reviews`);
|
|
143
|
+
url.searchParams.set('shop_domain', this.config.shopDomain);
|
|
144
|
+
url.searchParams.set('product_id', productIdResult.data);
|
|
145
|
+
url.searchParams.set('page', page.toString());
|
|
146
|
+
url.searchParams.set('per_page', perPage.toString());
|
|
147
|
+
url.searchParams.set('sort_by', sortBy);
|
|
148
|
+
try {
|
|
149
|
+
const controller = new AbortController();
|
|
150
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout ?? this.defaultTimeout);
|
|
151
|
+
const response = await fetch(url.toString(), {
|
|
152
|
+
method: 'GET',
|
|
153
|
+
headers: {
|
|
154
|
+
'Content-Type': 'application/json',
|
|
155
|
+
'X-Api-Token': this.config.privateToken,
|
|
156
|
+
},
|
|
157
|
+
signal: controller.signal,
|
|
158
|
+
});
|
|
159
|
+
clearTimeout(timeoutId);
|
|
160
|
+
if (!response.ok) {
|
|
161
|
+
const errorText = await response.text();
|
|
162
|
+
return {
|
|
163
|
+
success: false,
|
|
164
|
+
error: this.normalizeError(response.status, errorText),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const data = (await response.json());
|
|
168
|
+
// Filter to only published reviews (API may return unpublished)
|
|
169
|
+
data.reviews = data.reviews.filter((r) => r.published && !r.hidden);
|
|
170
|
+
return { success: true, data };
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
logger_1.logger.error('Judge.me get reviews failed', {
|
|
174
|
+
brand: this.brand,
|
|
175
|
+
shopifyProductId,
|
|
176
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
success: false,
|
|
180
|
+
error: {
|
|
181
|
+
code: 'REQUEST_FAILED',
|
|
182
|
+
message: error instanceof Error ? error.message : 'Request failed',
|
|
183
|
+
details: error,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get review count for a product.
|
|
190
|
+
*/
|
|
191
|
+
async getReviewCount(shopifyProductId) {
|
|
192
|
+
if (!this.config) {
|
|
193
|
+
return this.notConfiguredError();
|
|
194
|
+
}
|
|
195
|
+
// Resolve to Judge.me internal product ID
|
|
196
|
+
const productIdResult = await this.resolveProductId(shopifyProductId);
|
|
197
|
+
if (!productIdResult.success) {
|
|
198
|
+
return { success: false, error: productIdResult.error };
|
|
199
|
+
}
|
|
200
|
+
const url = new URL(`${this.config.baseUrl}/reviews/count`);
|
|
201
|
+
url.searchParams.set('shop_domain', this.config.shopDomain);
|
|
202
|
+
url.searchParams.set('api_token', this.config.privateToken);
|
|
203
|
+
url.searchParams.set('product_id', productIdResult.data);
|
|
204
|
+
try {
|
|
205
|
+
const controller = new AbortController();
|
|
206
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout ?? this.defaultTimeout);
|
|
207
|
+
const response = await fetch(url.toString(), {
|
|
208
|
+
method: 'GET',
|
|
209
|
+
headers: { 'Content-Type': 'application/json' },
|
|
210
|
+
signal: controller.signal,
|
|
211
|
+
});
|
|
212
|
+
clearTimeout(timeoutId);
|
|
213
|
+
if (!response.ok) {
|
|
214
|
+
const errorText = await response.text();
|
|
215
|
+
return {
|
|
216
|
+
success: false,
|
|
217
|
+
error: this.normalizeError(response.status, errorText),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const data = (await response.json());
|
|
221
|
+
return { success: true, data: data.count };
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
logger_1.logger.error('Judge.me get count failed', {
|
|
225
|
+
brand: this.brand,
|
|
226
|
+
shopifyProductId,
|
|
227
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
228
|
+
});
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
error: {
|
|
232
|
+
code: 'REQUEST_FAILED',
|
|
233
|
+
message: error instanceof Error ? error.message : 'Request failed',
|
|
234
|
+
details: error,
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Submit a review.
|
|
241
|
+
*
|
|
242
|
+
* CRITICAL:
|
|
243
|
+
* - NO idempotency key - retried POST creates DUPLICATE review
|
|
244
|
+
* - Single attempt only
|
|
245
|
+
* - Reviews are created UNPUBLISHED and UNVERIFIED
|
|
246
|
+
* - Cannot be deleted via API
|
|
247
|
+
* - Name/email should be derived server-side, NOT from client
|
|
248
|
+
*/
|
|
249
|
+
async submitReview(params) {
|
|
250
|
+
if (!this.config) {
|
|
251
|
+
return this.notConfiguredError();
|
|
252
|
+
}
|
|
253
|
+
const { shopifyProductId, rating, title, body, reviewerName, reviewerEmail, pictureUrls = [], } = params;
|
|
254
|
+
// Extract numeric Shopify product ID (Judge.me expects external_id for POST)
|
|
255
|
+
const externalProductId = this.extractNumericId(shopifyProductId);
|
|
256
|
+
// Build URL-encoded form data
|
|
257
|
+
const formData = new URLSearchParams();
|
|
258
|
+
formData.append('shop_domain', this.config.shopDomain);
|
|
259
|
+
formData.append('platform', 'shopify');
|
|
260
|
+
formData.append('id', externalProductId);
|
|
261
|
+
formData.append('email', reviewerEmail);
|
|
262
|
+
formData.append('name', reviewerName);
|
|
263
|
+
formData.append('rating', rating.toString());
|
|
264
|
+
formData.append('title', title);
|
|
265
|
+
formData.append('body', body);
|
|
266
|
+
// Add picture URLs if provided
|
|
267
|
+
for (const pictureUrl of pictureUrls) {
|
|
268
|
+
formData.append('picture_urls[]', pictureUrl);
|
|
269
|
+
}
|
|
270
|
+
logger_1.logger.info('Submitting review to Judge.me', {
|
|
271
|
+
brand: this.brand,
|
|
272
|
+
externalProductId,
|
|
273
|
+
email: reviewerEmail,
|
|
274
|
+
});
|
|
275
|
+
try {
|
|
276
|
+
const controller = new AbortController();
|
|
277
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout ?? this.defaultTimeout);
|
|
278
|
+
const response = await fetch(`${this.config.baseUrl}/reviews`, {
|
|
279
|
+
method: 'POST',
|
|
280
|
+
headers: {
|
|
281
|
+
'X-Api-Token': this.config.privateToken,
|
|
282
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
283
|
+
},
|
|
284
|
+
body: formData.toString(),
|
|
285
|
+
signal: controller.signal,
|
|
286
|
+
});
|
|
287
|
+
clearTimeout(timeoutId);
|
|
288
|
+
logger_1.logger.info('Judge.me response', {
|
|
289
|
+
brand: this.brand,
|
|
290
|
+
status: response.status,
|
|
291
|
+
ok: response.ok,
|
|
292
|
+
});
|
|
293
|
+
if (!response.ok) {
|
|
294
|
+
const errorText = await response.text();
|
|
295
|
+
logger_1.logger.error('Judge.me submit error', {
|
|
296
|
+
brand: this.brand,
|
|
297
|
+
status: response.status,
|
|
298
|
+
errorText,
|
|
299
|
+
});
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
error: this.normalizeError(response.status, errorText),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const data = (await response.json());
|
|
306
|
+
// Judge.me may return a message for async processing instead of review object
|
|
307
|
+
if (data.message && !data.review) {
|
|
308
|
+
logger_1.logger.info('Review submitted for background processing', {
|
|
309
|
+
brand: this.brand,
|
|
310
|
+
message: data.message,
|
|
311
|
+
});
|
|
312
|
+
// Return a placeholder review object for async submissions
|
|
313
|
+
const now = new Date().toISOString();
|
|
314
|
+
return {
|
|
315
|
+
success: true,
|
|
316
|
+
data: {
|
|
317
|
+
id: 0,
|
|
318
|
+
rating: params.rating,
|
|
319
|
+
title: params.title,
|
|
320
|
+
body: params.body,
|
|
321
|
+
reviewer: {
|
|
322
|
+
id: 0,
|
|
323
|
+
email: params.reviewerEmail,
|
|
324
|
+
name: params.reviewerName,
|
|
325
|
+
phone: null,
|
|
326
|
+
},
|
|
327
|
+
pictures: [],
|
|
328
|
+
curated: 'ok',
|
|
329
|
+
published: false,
|
|
330
|
+
hidden: false,
|
|
331
|
+
verified: 'unknown',
|
|
332
|
+
featured: false,
|
|
333
|
+
created_at: now,
|
|
334
|
+
updated_at: now,
|
|
335
|
+
has_published_pictures: false,
|
|
336
|
+
ip_address: null,
|
|
337
|
+
reviewer_name_format: 'full_name',
|
|
338
|
+
source: 'api',
|
|
339
|
+
reply: null,
|
|
340
|
+
replied_at: null,
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
if (!data.review) {
|
|
345
|
+
return {
|
|
346
|
+
success: false,
|
|
347
|
+
error: {
|
|
348
|
+
code: 'INVALID_RESPONSE',
|
|
349
|
+
message: 'Judge.me returned unexpected response format',
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
return { success: true, data: data.review };
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
logger_1.logger.error('Judge.me submit failed', {
|
|
357
|
+
brand: this.brand,
|
|
358
|
+
shopifyProductId,
|
|
359
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
360
|
+
});
|
|
361
|
+
return {
|
|
362
|
+
success: false,
|
|
363
|
+
error: {
|
|
364
|
+
code: 'REQUEST_FAILED',
|
|
365
|
+
message: error instanceof Error ? error.message : 'Request failed',
|
|
366
|
+
details: error,
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Map sort parameter to Judge.me API parameter.
|
|
373
|
+
*/
|
|
374
|
+
static mapSortParam(sort) {
|
|
375
|
+
switch (sort) {
|
|
376
|
+
case 'recent':
|
|
377
|
+
return 'created_at';
|
|
378
|
+
case 'highest':
|
|
379
|
+
return 'rating_desc';
|
|
380
|
+
case 'lowest':
|
|
381
|
+
return 'rating_asc';
|
|
382
|
+
case 'most_helpful':
|
|
383
|
+
return 'most_helpful';
|
|
384
|
+
default:
|
|
385
|
+
return 'created_at';
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
// ===========================================================================
|
|
389
|
+
// Private Methods
|
|
390
|
+
// ===========================================================================
|
|
391
|
+
/**
|
|
392
|
+
* Return not configured error
|
|
393
|
+
*/
|
|
394
|
+
notConfiguredError() {
|
|
395
|
+
return {
|
|
396
|
+
success: false,
|
|
397
|
+
error: {
|
|
398
|
+
code: 'NOT_CONFIGURED',
|
|
399
|
+
message: 'JudgeMe service is not configured',
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Extract numeric ID from Shopify GID or return as-is if already numeric.
|
|
405
|
+
*/
|
|
406
|
+
extractNumericId(id) {
|
|
407
|
+
if (id.startsWith('gid://')) {
|
|
408
|
+
const parts = id.split('/');
|
|
409
|
+
return parts[parts.length - 1];
|
|
410
|
+
}
|
|
411
|
+
return id;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Normalize error responses
|
|
415
|
+
*/
|
|
416
|
+
normalizeError(status, body) {
|
|
417
|
+
let parsed;
|
|
418
|
+
try {
|
|
419
|
+
parsed = JSON.parse(body);
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
parsed = { message: body };
|
|
423
|
+
}
|
|
424
|
+
const errorMap = {
|
|
425
|
+
400: 'BAD_REQUEST',
|
|
426
|
+
401: 'UNAUTHORIZED',
|
|
427
|
+
403: 'FORBIDDEN',
|
|
428
|
+
404: 'NOT_FOUND',
|
|
429
|
+
429: 'RATE_LIMITED',
|
|
430
|
+
500: 'INTERNAL_ERROR',
|
|
431
|
+
};
|
|
432
|
+
const message = typeof parsed === 'object' && parsed !== null
|
|
433
|
+
? parsed.message ||
|
|
434
|
+
parsed.error ||
|
|
435
|
+
`HTTP ${status}`
|
|
436
|
+
: `HTTP ${status}`;
|
|
437
|
+
return {
|
|
438
|
+
code: errorMap[status] ?? 'UNKNOWN_ERROR',
|
|
439
|
+
message: String(message),
|
|
440
|
+
details: parsed,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
exports.JudgeMeService = JudgeMeService;
|
|
445
|
+
exports.JudgeMeService = JudgeMeService = tslib_1.__decorate([
|
|
446
|
+
(0, common_1.Injectable)()
|
|
447
|
+
], JudgeMeService);
|
|
448
|
+
//# sourceMappingURL=judgeme.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judgeme.service.js","sourceRoot":"","sources":["../../../src/integrations/reviews/judgeme.service.ts"],"names":[],"mappings":"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"}
|