@pvh-afl/core 1.0.0
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/README.md +97 -0
- package/dist/cache/cache.module.d.ts +3 -0
- package/dist/cache/cache.module.d.ts.map +1 -0
- package/dist/cache/cache.module.js +17 -0
- package/dist/cache/cache.module.js.map +1 -0
- package/dist/cache/cache.service.d.ts +38 -0
- package/dist/cache/cache.service.d.ts.map +1 -0
- package/dist/cache/cache.service.js +173 -0
- package/dist/cache/cache.service.js.map +1 -0
- package/dist/cache/index.d.ts +3 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/common/guards/tenant.guard.d.ts +8 -0
- package/dist/common/guards/tenant.guard.d.ts.map +1 -0
- package/dist/common/guards/tenant.guard.js +44 -0
- package/dist/common/guards/tenant.guard.js.map +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +6 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/logger.d.ts +7 -0
- package/dist/common/logger.d.ts.map +1 -0
- package/dist/common/logger.js +28 -0
- package/dist/common/logger.js.map +1 -0
- package/dist/config/config.module.d.ts +3 -0
- package/dist/config/config.module.d.ts.map +1 -0
- package/dist/config/config.module.js +17 -0
- package/dist/config/config.module.js.map +1 -0
- package/dist/config/config.service.d.ts +55 -0
- package/dist/config/config.service.d.ts.map +1 -0
- package/dist/config/config.service.js +212 -0
- package/dist/config/config.service.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/base-integration.service.d.ts +59 -0
- package/dist/integrations/base-integration.service.d.ts.map +1 -0
- package/dist/integrations/base-integration.service.js +227 -0
- package/dist/integrations/base-integration.service.js.map +1 -0
- package/dist/integrations/commerce/commerce.types.d.ts +301 -0
- package/dist/integrations/commerce/commerce.types.d.ts.map +1 -0
- package/dist/integrations/commerce/commerce.types.js +9 -0
- package/dist/integrations/commerce/commerce.types.js.map +1 -0
- package/dist/integrations/commerce/index.d.ts +4 -0
- package/dist/integrations/commerce/index.d.ts.map +1 -0
- package/dist/integrations/commerce/index.js +7 -0
- package/dist/integrations/commerce/index.js.map +1 -0
- package/dist/integrations/commerce/shopify-admin.service.d.ts +35 -0
- package/dist/integrations/commerce/shopify-admin.service.d.ts.map +1 -0
- package/dist/integrations/commerce/shopify-admin.service.js +269 -0
- package/dist/integrations/commerce/shopify-admin.service.js.map +1 -0
- package/dist/integrations/commerce/shopify.service.d.ts +43 -0
- package/dist/integrations/commerce/shopify.service.d.ts.map +1 -0
- package/dist/integrations/commerce/shopify.service.js +735 -0
- package/dist/integrations/commerce/shopify.service.js.map +1 -0
- package/dist/integrations/index.d.ts +9 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +18 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/integration.factory.d.ts +23 -0
- package/dist/integrations/integration.factory.d.ts.map +1 -0
- package/dist/integrations/integration.factory.js +119 -0
- package/dist/integrations/integration.factory.js.map +1 -0
- package/dist/integrations/integration.types.d.ts +80 -0
- package/dist/integrations/integration.types.d.ts.map +1 -0
- package/dist/integrations/integration.types.js +9 -0
- package/dist/integrations/integration.types.js.map +1 -0
- package/dist/integrations/integrations.module.d.ts +3 -0
- package/dist/integrations/integrations.module.d.ts.map +1 -0
- package/dist/integrations/integrations.module.js +46 -0
- package/dist/integrations/integrations.module.js.map +1 -0
- package/dist/integrations/loyalty/capillary-auth.service.d.ts +30 -0
- package/dist/integrations/loyalty/capillary-auth.service.d.ts.map +1 -0
- package/dist/integrations/loyalty/capillary-auth.service.js +112 -0
- package/dist/integrations/loyalty/capillary-auth.service.js.map +1 -0
- package/dist/integrations/loyalty/capillary-coupon.service.d.ts +24 -0
- package/dist/integrations/loyalty/capillary-coupon.service.d.ts.map +1 -0
- package/dist/integrations/loyalty/capillary-coupon.service.js +383 -0
- package/dist/integrations/loyalty/capillary-coupon.service.js.map +1 -0
- package/dist/integrations/loyalty/capillary.types.d.ts +218 -0
- package/dist/integrations/loyalty/capillary.types.d.ts.map +1 -0
- package/dist/integrations/loyalty/capillary.types.js +21 -0
- package/dist/integrations/loyalty/capillary.types.js.map +1 -0
- package/dist/integrations/loyalty/index.d.ts +4 -0
- package/dist/integrations/loyalty/index.d.ts.map +1 -0
- package/dist/integrations/loyalty/index.js +7 -0
- package/dist/integrations/loyalty/index.js.map +1 -0
- package/dist/integrations/oms/index.d.ts +4 -0
- package/dist/integrations/oms/index.d.ts.map +1 -0
- package/dist/integrations/oms/index.js +7 -0
- package/dist/integrations/oms/index.js.map +1 -0
- package/dist/integrations/oms/omuni-auth.service.d.ts +29 -0
- package/dist/integrations/oms/omuni-auth.service.d.ts.map +1 -0
- package/dist/integrations/oms/omuni-auth.service.js +164 -0
- package/dist/integrations/oms/omuni-auth.service.js.map +1 -0
- package/dist/integrations/oms/omuni.service.d.ts +17 -0
- package/dist/integrations/oms/omuni.service.d.ts.map +1 -0
- package/dist/integrations/oms/omuni.service.js +128 -0
- package/dist/integrations/oms/omuni.service.js.map +1 -0
- package/dist/integrations/oms/omuni.types.d.ts +65 -0
- package/dist/integrations/oms/omuni.types.d.ts.map +1 -0
- package/dist/integrations/oms/omuni.types.js +3 -0
- package/dist/integrations/oms/omuni.types.js.map +1 -0
- package/dist/integrations/shopify-theme/index.d.ts +3 -0
- package/dist/integrations/shopify-theme/index.d.ts.map +1 -0
- package/dist/integrations/shopify-theme/index.js +6 -0
- package/dist/integrations/shopify-theme/index.js.map +1 -0
- package/dist/integrations/shopify-theme/shopify-theme.module.d.ts +3 -0
- package/dist/integrations/shopify-theme/shopify-theme.module.d.ts.map +1 -0
- package/dist/integrations/shopify-theme/shopify-theme.module.js +16 -0
- package/dist/integrations/shopify-theme/shopify-theme.module.js.map +1 -0
- package/dist/integrations/shopify-theme/shopify-theme.service.d.ts +35 -0
- package/dist/integrations/shopify-theme/shopify-theme.service.d.ts.map +1 -0
- package/dist/integrations/shopify-theme/shopify-theme.service.js +155 -0
- package/dist/integrations/shopify-theme/shopify-theme.service.js.map +1 -0
- package/dist/queue/index.d.ts +3 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +8 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.module.d.ts +3 -0
- package/dist/queue/queue.module.d.ts.map +1 -0
- package/dist/queue/queue.module.js +17 -0
- package/dist/queue/queue.module.js.map +1 -0
- package/dist/queue/queue.service.d.ts +20 -0
- package/dist/queue/queue.service.d.ts.map +1 -0
- package/dist/queue/queue.service.js +119 -0
- package/dist/queue/queue.service.js.map +1 -0
- package/dist/theme/header-content.service.d.ts +142 -0
- package/dist/theme/header-content.service.d.ts.map +1 -0
- package/dist/theme/header-content.service.js +626 -0
- package/dist/theme/header-content.service.js.map +1 -0
- package/dist/theme/index.d.ts +5 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +17 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-content.interfaces.d.ts +79 -0
- package/dist/theme/theme-content.interfaces.d.ts.map +1 -0
- package/dist/theme/theme-content.interfaces.js +14 -0
- package/dist/theme/theme-content.interfaces.js.map +1 -0
- package/dist/theme/theme-content.service.d.ts +125 -0
- package/dist/theme/theme-content.service.d.ts.map +1 -0
- package/dist/theme/theme-content.service.js +738 -0
- package/dist/theme/theme-content.service.js.map +1 -0
- package/dist/theme/theme.module.d.ts +46 -0
- package/dist/theme/theme.module.d.ts.map +1 -0
- package/dist/theme/theme.module.js +76 -0
- package/dist/theme/theme.module.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
7
|
+
const path = tslib_1.__importStar(require("path"));
|
|
8
|
+
let ConfigService = class ConfigService {
|
|
9
|
+
brands = new Map();
|
|
10
|
+
activeBrand = null;
|
|
11
|
+
singleBrandMode = false;
|
|
12
|
+
brandConfigPath = null;
|
|
13
|
+
/**
|
|
14
|
+
* Set custom brand config path (for brand repos)
|
|
15
|
+
*/
|
|
16
|
+
setBrandConfigPath(configPath) {
|
|
17
|
+
this.brandConfigPath = configPath;
|
|
18
|
+
}
|
|
19
|
+
onModuleInit() {
|
|
20
|
+
this.loadBrands();
|
|
21
|
+
this.initializeMode();
|
|
22
|
+
}
|
|
23
|
+
initializeMode() {
|
|
24
|
+
const brandEnv = process.env.BRAND;
|
|
25
|
+
if (brandEnv) {
|
|
26
|
+
// Single-brand deployment mode
|
|
27
|
+
if (!this.brands.has(brandEnv)) {
|
|
28
|
+
throw new Error(`BRAND env var set to "${brandEnv}" but no config found for this brand`);
|
|
29
|
+
}
|
|
30
|
+
this.activeBrand = brandEnv;
|
|
31
|
+
this.singleBrandMode = true;
|
|
32
|
+
console.log(`Running in single-brand mode: ${brandEnv}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// Multi-brand mode (header-based)
|
|
36
|
+
this.singleBrandMode = false;
|
|
37
|
+
console.log(`Running in multi-brand mode. Available brands: ${this.getAllBrands().join(', ')}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
loadBrands() {
|
|
41
|
+
// Use custom path if set, otherwise look for brands directory
|
|
42
|
+
const brandsDir = this.brandConfigPath || path.join(process.cwd(), 'src', 'config', 'brands');
|
|
43
|
+
// Check if brands directory exists
|
|
44
|
+
if (!fs.existsSync(brandsDir)) {
|
|
45
|
+
// Try alternative path for brand repos (config in src/config/)
|
|
46
|
+
const altBrandsDir = path.join(process.cwd(), 'src', 'config');
|
|
47
|
+
if (fs.existsSync(altBrandsDir)) {
|
|
48
|
+
this.loadBrandsFromDirectory(altBrandsDir);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.warn('No brands directory found, using environment variables');
|
|
52
|
+
this.loadFromEnv();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.loadBrandsFromDirectory(brandsDir);
|
|
56
|
+
}
|
|
57
|
+
loadBrandsFromDirectory(brandsDir) {
|
|
58
|
+
// Load all brand config files (skip templates and feature files)
|
|
59
|
+
const files = fs
|
|
60
|
+
.readdirSync(brandsDir)
|
|
61
|
+
.filter(f => f.endsWith('.json') && !f.startsWith('_') && !f.includes('.features.'));
|
|
62
|
+
for (const file of files) {
|
|
63
|
+
const filePath = path.join(brandsDir, file);
|
|
64
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
65
|
+
const config = JSON.parse(content);
|
|
66
|
+
// Resolve environment variables (format: "env:VAR_NAME")
|
|
67
|
+
this.resolveEnvVars(config);
|
|
68
|
+
// Load features file if exists
|
|
69
|
+
const featuresPath = path.join(brandsDir, `${config.slug}.features.json`);
|
|
70
|
+
if (fs.existsSync(featuresPath)) {
|
|
71
|
+
const featuresContent = fs.readFileSync(featuresPath, 'utf-8');
|
|
72
|
+
config.features = JSON.parse(featuresContent);
|
|
73
|
+
this.resolveEnvVars(config.features);
|
|
74
|
+
console.log(`Loaded features for brand: ${config.slug}`);
|
|
75
|
+
}
|
|
76
|
+
this.brands.set(config.slug, config);
|
|
77
|
+
console.log(`Loaded brand config: ${config.slug}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
loadFromEnv() {
|
|
81
|
+
// Fallback: load tommy from environment variables
|
|
82
|
+
const graphqlUrl = process.env.TOMMY_SHOPIFY_GRAPHQL_URL;
|
|
83
|
+
const storefrontToken = process.env.TOMMY_SHOPIFY_STOREFRONT_TOKEN;
|
|
84
|
+
if (graphqlUrl && storefrontToken) {
|
|
85
|
+
const tommyConfig = {
|
|
86
|
+
slug: 'tommy',
|
|
87
|
+
integrations: {
|
|
88
|
+
commerce: {
|
|
89
|
+
provider: 'shopify',
|
|
90
|
+
baseUrl: graphqlUrl,
|
|
91
|
+
apiKey: storefrontToken,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
this.brands.set('tommy', tommyConfig);
|
|
96
|
+
console.log('Loaded tommy brand from environment variables');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
resolveEnvVars(obj) {
|
|
100
|
+
for (const key of Object.keys(obj)) {
|
|
101
|
+
const value = obj[key];
|
|
102
|
+
if (typeof value === 'string' && value.startsWith('env:')) {
|
|
103
|
+
const envVar = value.slice(4);
|
|
104
|
+
obj[key] = process.env[envVar] ?? '';
|
|
105
|
+
}
|
|
106
|
+
else if (typeof value === 'object' && value !== null) {
|
|
107
|
+
this.resolveEnvVars(value);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
getBrand(slug) {
|
|
112
|
+
return this.brands.get(slug);
|
|
113
|
+
}
|
|
114
|
+
getAllBrands() {
|
|
115
|
+
return Array.from(this.brands.keys());
|
|
116
|
+
}
|
|
117
|
+
// Single-brand mode helpers
|
|
118
|
+
isSingleBrandMode() {
|
|
119
|
+
return this.singleBrandMode;
|
|
120
|
+
}
|
|
121
|
+
getActiveBrand() {
|
|
122
|
+
return this.activeBrand;
|
|
123
|
+
}
|
|
124
|
+
getActiveBrandConfig() {
|
|
125
|
+
if (!this.activeBrand)
|
|
126
|
+
return undefined;
|
|
127
|
+
return this.brands.get(this.activeBrand);
|
|
128
|
+
}
|
|
129
|
+
// Feature flags helpers
|
|
130
|
+
isFeatureEnabled(brand, featurePath) {
|
|
131
|
+
const value = this.getFeature(brand, featurePath);
|
|
132
|
+
return value === true;
|
|
133
|
+
}
|
|
134
|
+
getFeature(brand, featurePath) {
|
|
135
|
+
const config = this.brands.get(brand);
|
|
136
|
+
if (!config?.features)
|
|
137
|
+
return undefined;
|
|
138
|
+
const parts = featurePath.split('.');
|
|
139
|
+
let current = config.features;
|
|
140
|
+
for (const part of parts) {
|
|
141
|
+
if (current && typeof current === 'object' && part in current) {
|
|
142
|
+
current = current[part];
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return current;
|
|
149
|
+
}
|
|
150
|
+
// Brand-aware Shopify config getters
|
|
151
|
+
getShopifyAdminToken(brand) {
|
|
152
|
+
const slug = brand || this.activeBrand;
|
|
153
|
+
if (!slug)
|
|
154
|
+
return process.env.TOMMY_SHOPIFY_ADMIN_TOKEN;
|
|
155
|
+
const envKey = `${slug.toUpperCase()}_SHOPIFY_ADMIN_TOKEN`;
|
|
156
|
+
return process.env[envKey];
|
|
157
|
+
}
|
|
158
|
+
getShopifyThemeId(brand) {
|
|
159
|
+
const slug = brand || this.activeBrand;
|
|
160
|
+
if (!slug)
|
|
161
|
+
return process.env.TOMMY_SHOPIFY_THEME_ID;
|
|
162
|
+
const envKey = `${slug.toUpperCase()}_SHOPIFY_THEME_ID`;
|
|
163
|
+
return process.env[envKey];
|
|
164
|
+
}
|
|
165
|
+
getShopifyStoreDomain(brand) {
|
|
166
|
+
const slug = brand || this.activeBrand;
|
|
167
|
+
if (!slug)
|
|
168
|
+
return process.env.TOMMY_SHOPIFY_STORE_DOMAIN;
|
|
169
|
+
const envKey = `${slug.toUpperCase()}_SHOPIFY_STORE_DOMAIN`;
|
|
170
|
+
return process.env[envKey];
|
|
171
|
+
}
|
|
172
|
+
getShopifyGraphqlUrl(brand) {
|
|
173
|
+
const slug = brand || this.activeBrand;
|
|
174
|
+
if (!slug)
|
|
175
|
+
return process.env.TOMMY_SHOPIFY_GRAPHQL_URL;
|
|
176
|
+
const envKey = `${slug.toUpperCase()}_SHOPIFY_GRAPHQL_URL`;
|
|
177
|
+
return process.env[envKey];
|
|
178
|
+
}
|
|
179
|
+
getShopifyStorefrontToken(brand) {
|
|
180
|
+
const slug = brand || this.activeBrand;
|
|
181
|
+
if (!slug)
|
|
182
|
+
return process.env.TOMMY_SHOPIFY_STOREFRONT_TOKEN;
|
|
183
|
+
const envKey = `${slug.toUpperCase()}_SHOPIFY_STOREFRONT_TOKEN`;
|
|
184
|
+
return process.env[envKey];
|
|
185
|
+
}
|
|
186
|
+
getRedisUrl() {
|
|
187
|
+
return process.env.REDIS_URL ?? 'redis://localhost:6379';
|
|
188
|
+
}
|
|
189
|
+
// Cache TTL helpers
|
|
190
|
+
getCacheTTL(brand) {
|
|
191
|
+
const slug = brand || this.activeBrand;
|
|
192
|
+
const config = slug ? this.brands.get(slug) : undefined;
|
|
193
|
+
return {
|
|
194
|
+
defaultTTL: config?.cache?.defaultTTL ?? 300,
|
|
195
|
+
staleTTL: config?.cache?.staleTTL ?? 60,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
getLandingPageCacheTTL(brand) {
|
|
199
|
+
const slug = brand || this.activeBrand;
|
|
200
|
+
const config = slug ? this.brands.get(slug) : undefined;
|
|
201
|
+
const baseTTL = this.getCacheTTL(brand);
|
|
202
|
+
return {
|
|
203
|
+
defaultTTL: baseTTL.defaultTTL,
|
|
204
|
+
staleTTL: config?.cache?.landingPage?.staleTTL ?? baseTTL.staleTTL,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
exports.ConfigService = ConfigService;
|
|
209
|
+
exports.ConfigService = ConfigService = tslib_1.__decorate([
|
|
210
|
+
(0, common_1.Injectable)()
|
|
211
|
+
], ConfigService);
|
|
212
|
+
//# sourceMappingURL=config.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.service.js","sourceRoot":"","sources":["../../src/config/config.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,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("./config.module"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./config.service"), exports);
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,2DAAiC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @afl/core
|
|
3
|
+
*
|
|
4
|
+
* Core shared services and utilities for the AFL multi-brand commerce platform.
|
|
5
|
+
*/
|
|
6
|
+
export * from './cache';
|
|
7
|
+
export * from './config';
|
|
8
|
+
export * from './common';
|
|
9
|
+
export * from './integrations';
|
|
10
|
+
export * from './queue';
|
|
11
|
+
export * from './theme';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,UAAU,CAAC;AAGzB,cAAc,gBAAgB,CAAC;AAG/B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @afl/core
|
|
4
|
+
*
|
|
5
|
+
* Core shared services and utilities for the AFL multi-brand commerce platform.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
// Cache
|
|
10
|
+
tslib_1.__exportStar(require("./cache"), exports);
|
|
11
|
+
// Config
|
|
12
|
+
tslib_1.__exportStar(require("./config"), exports);
|
|
13
|
+
// Common utilities
|
|
14
|
+
tslib_1.__exportStar(require("./common"), exports);
|
|
15
|
+
// Integrations
|
|
16
|
+
tslib_1.__exportStar(require("./integrations"), exports);
|
|
17
|
+
// Queue (placeholder)
|
|
18
|
+
tslib_1.__exportStar(require("./queue"), exports);
|
|
19
|
+
// Theme (placeholder)
|
|
20
|
+
tslib_1.__exportStar(require("./theme"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,QAAQ;AACR,kDAAwB;AAExB,SAAS;AACT,mDAAyB;AAEzB,mBAAmB;AACnB,mDAAyB;AAEzB,eAAe;AACf,yDAA+B;AAE/B,sBAAsB;AACtB,kDAAwB;AAExB,sBAAsB;AACtB,kDAAwB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { IntegrationConfig, IntegrationResponse, IntegrationError, IntegrationHealth } from './integration.types';
|
|
2
|
+
/**
|
|
3
|
+
* Base Integration Service
|
|
4
|
+
*
|
|
5
|
+
* Provides common functionality for all third-party integrations:
|
|
6
|
+
* - HTTP request handling with retries
|
|
7
|
+
* - Error normalization
|
|
8
|
+
* - Health checks
|
|
9
|
+
* - Logging
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* 1. Create a new service that extends this class
|
|
13
|
+
* 2. Implement the abstract methods
|
|
14
|
+
* 3. Use this.request() for API calls
|
|
15
|
+
*
|
|
16
|
+
* Example:
|
|
17
|
+
* ```typescript
|
|
18
|
+
* @Injectable()
|
|
19
|
+
* export class LoyaltyService extends BaseIntegrationService {
|
|
20
|
+
* readonly name = 'loyalty';
|
|
21
|
+
*
|
|
22
|
+
* async getPoints(customerId: string): Promise<IntegrationResponse<number>> {
|
|
23
|
+
* return this.request<number>('GET', `/customers/${customerId}/points`);
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class BaseIntegrationService {
|
|
29
|
+
protected config: IntegrationConfig | null;
|
|
30
|
+
protected brand: string;
|
|
31
|
+
/** Integration name for logging */
|
|
32
|
+
readonly name: string;
|
|
33
|
+
private defaultRetryOptions;
|
|
34
|
+
/**
|
|
35
|
+
* Configure the integration for a specific brand
|
|
36
|
+
*/
|
|
37
|
+
configure(brand: string, config: IntegrationConfig): void;
|
|
38
|
+
/**
|
|
39
|
+
* Make an HTTP request to the integration API
|
|
40
|
+
*/
|
|
41
|
+
protected request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH', path: string, body?: unknown, options?: {
|
|
42
|
+
skipRetry?: boolean;
|
|
43
|
+
}): Promise<IntegrationResponse<T>>;
|
|
44
|
+
/**
|
|
45
|
+
* Execute a function with exponential backoff retry
|
|
46
|
+
*/
|
|
47
|
+
private executeWithRetry;
|
|
48
|
+
/**
|
|
49
|
+
* Normalize error responses from different providers
|
|
50
|
+
*/
|
|
51
|
+
protected normalizeError(status: number, body: string): IntegrationError;
|
|
52
|
+
private extractErrorMessage;
|
|
53
|
+
/**
|
|
54
|
+
* Check if the integration is healthy
|
|
55
|
+
*/
|
|
56
|
+
healthCheck(): Promise<IntegrationHealth>;
|
|
57
|
+
private sleep;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=base-integration.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-integration.service.d.ts","sourceRoot":"","sources":["../../src/integrations/base-integration.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBACa,sBAAsB;IACjC,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAClD,SAAS,CAAC,KAAK,EAAE,MAAM,CAAM;IAE7B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAU;IAE/B,OAAO,CAAC,mBAAmB,CAIzB;IAEF;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAUzD;;OAEG;cACa,OAAO,CAAC,CAAC,EACvB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,EACnD,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAkFlC;;OAEG;YACW,gBAAgB;IAiC9B;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB;IA0BxE,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAiC/C,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseIntegrationService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const logger_1 = require("../common/logger");
|
|
7
|
+
/**
|
|
8
|
+
* Base Integration Service
|
|
9
|
+
*
|
|
10
|
+
* Provides common functionality for all third-party integrations:
|
|
11
|
+
* - HTTP request handling with retries
|
|
12
|
+
* - Error normalization
|
|
13
|
+
* - Health checks
|
|
14
|
+
* - Logging
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* 1. Create a new service that extends this class
|
|
18
|
+
* 2. Implement the abstract methods
|
|
19
|
+
* 3. Use this.request() for API calls
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* @Injectable()
|
|
24
|
+
* export class LoyaltyService extends BaseIntegrationService {
|
|
25
|
+
* readonly name = 'loyalty';
|
|
26
|
+
*
|
|
27
|
+
* async getPoints(customerId: string): Promise<IntegrationResponse<number>> {
|
|
28
|
+
* return this.request<number>('GET', `/customers/${customerId}/points`);
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
let BaseIntegrationService = class BaseIntegrationService {
|
|
34
|
+
config = null;
|
|
35
|
+
brand = '';
|
|
36
|
+
/** Integration name for logging */
|
|
37
|
+
name = 'base';
|
|
38
|
+
defaultRetryOptions = {
|
|
39
|
+
maxRetries: 3,
|
|
40
|
+
baseDelayMs: 1000,
|
|
41
|
+
maxDelayMs: 10000,
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Configure the integration for a specific brand
|
|
45
|
+
*/
|
|
46
|
+
configure(brand, config) {
|
|
47
|
+
this.brand = brand;
|
|
48
|
+
this.config = {
|
|
49
|
+
timeout: 10000,
|
|
50
|
+
retryEnabled: true,
|
|
51
|
+
maxRetries: 3,
|
|
52
|
+
...config,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Make an HTTP request to the integration API
|
|
57
|
+
*/
|
|
58
|
+
async request(method, path, body, options) {
|
|
59
|
+
if (!this.config) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: {
|
|
63
|
+
code: 'NOT_CONFIGURED',
|
|
64
|
+
message: `Integration ${this.name} is not configured for brand ${this.brand}`,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const url = `${this.config.baseUrl}${path}`;
|
|
69
|
+
const headers = {
|
|
70
|
+
'Content-Type': 'application/json',
|
|
71
|
+
...this.config.headers,
|
|
72
|
+
};
|
|
73
|
+
// Only add default Authorization header if no custom auth headers provided
|
|
74
|
+
const hasCustomAuth = Object.keys(this.config.headers ?? {}).some((key) => key.toLowerCase().includes('authorization') || key.toLowerCase().includes('token'));
|
|
75
|
+
if (!hasCustomAuth && this.config.apiKey) {
|
|
76
|
+
headers['Authorization'] = `Bearer ${this.config.apiKey}`;
|
|
77
|
+
}
|
|
78
|
+
const shouldRetry = this.config.retryEnabled && !options?.skipRetry;
|
|
79
|
+
try {
|
|
80
|
+
const response = await this.executeWithRetry(async () => {
|
|
81
|
+
const controller = new AbortController();
|
|
82
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
83
|
+
try {
|
|
84
|
+
const res = await fetch(url, {
|
|
85
|
+
method,
|
|
86
|
+
headers,
|
|
87
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
88
|
+
signal: controller.signal,
|
|
89
|
+
});
|
|
90
|
+
clearTimeout(timeoutId);
|
|
91
|
+
return res;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
clearTimeout(timeoutId);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}, shouldRetry ? this.defaultRetryOptions : { maxRetries: 0, baseDelayMs: 0, maxDelayMs: 0 });
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
const errorBody = await response.text();
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: this.normalizeError(response.status, errorBody),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
return { success: true, data: data };
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
logger_1.logger.error(`${this.name} integration request failed`, {
|
|
110
|
+
brand: this.brand,
|
|
111
|
+
method,
|
|
112
|
+
path,
|
|
113
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
error: {
|
|
118
|
+
code: 'REQUEST_FAILED',
|
|
119
|
+
message: error instanceof Error ? error.message : 'Request failed',
|
|
120
|
+
details: error,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Execute a function with exponential backoff retry
|
|
127
|
+
*/
|
|
128
|
+
async executeWithRetry(fn, options) {
|
|
129
|
+
let lastError = null;
|
|
130
|
+
for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
|
|
131
|
+
try {
|
|
132
|
+
return await fn();
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
136
|
+
if (attempt < options.maxRetries) {
|
|
137
|
+
const delay = Math.min(options.baseDelayMs * Math.pow(2, attempt), options.maxDelayMs);
|
|
138
|
+
logger_1.logger.warn(`${this.name} request failed, retrying`, {
|
|
139
|
+
brand: this.brand,
|
|
140
|
+
attempt: attempt + 1,
|
|
141
|
+
maxRetries: options.maxRetries,
|
|
142
|
+
delayMs: delay,
|
|
143
|
+
});
|
|
144
|
+
await this.sleep(delay);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
throw lastError;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Normalize error responses from different providers
|
|
152
|
+
*/
|
|
153
|
+
normalizeError(status, body) {
|
|
154
|
+
let parsed;
|
|
155
|
+
try {
|
|
156
|
+
parsed = JSON.parse(body);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
parsed = { message: body };
|
|
160
|
+
}
|
|
161
|
+
const errorMap = {
|
|
162
|
+
400: 'BAD_REQUEST',
|
|
163
|
+
401: 'UNAUTHORIZED',
|
|
164
|
+
403: 'FORBIDDEN',
|
|
165
|
+
404: 'NOT_FOUND',
|
|
166
|
+
429: 'RATE_LIMITED',
|
|
167
|
+
500: 'INTERNAL_ERROR',
|
|
168
|
+
502: 'BAD_GATEWAY',
|
|
169
|
+
503: 'SERVICE_UNAVAILABLE',
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
code: errorMap[status] ?? 'UNKNOWN_ERROR',
|
|
173
|
+
message: this.extractErrorMessage(parsed) ?? `HTTP ${status}`,
|
|
174
|
+
details: parsed,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
extractErrorMessage(error) {
|
|
178
|
+
if (typeof error === 'object' && error !== null) {
|
|
179
|
+
const obj = error;
|
|
180
|
+
return (obj.message ??
|
|
181
|
+
obj.error ??
|
|
182
|
+
obj.error_description);
|
|
183
|
+
}
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Check if the integration is healthy
|
|
188
|
+
*/
|
|
189
|
+
async healthCheck() {
|
|
190
|
+
if (!this.config) {
|
|
191
|
+
return {
|
|
192
|
+
name: this.name,
|
|
193
|
+
healthy: false,
|
|
194
|
+
error: 'Not configured',
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const start = Date.now();
|
|
198
|
+
try {
|
|
199
|
+
// Override this in subclasses for specific health check endpoints
|
|
200
|
+
const response = await this.request('GET', '/health', undefined, {
|
|
201
|
+
skipRetry: true,
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
name: this.name,
|
|
205
|
+
healthy: response.success,
|
|
206
|
+
latencyMs: Date.now() - start,
|
|
207
|
+
error: response.error?.message,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
return {
|
|
212
|
+
name: this.name,
|
|
213
|
+
healthy: false,
|
|
214
|
+
latencyMs: Date.now() - start,
|
|
215
|
+
error: error instanceof Error ? error.message : 'Health check failed',
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
sleep(ms) {
|
|
220
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
exports.BaseIntegrationService = BaseIntegrationService;
|
|
224
|
+
exports.BaseIntegrationService = BaseIntegrationService = tslib_1.__decorate([
|
|
225
|
+
(0, common_1.Injectable)()
|
|
226
|
+
], BaseIntegrationService);
|
|
227
|
+
//# sourceMappingURL=base-integration.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-integration.service.js","sourceRoot":"","sources":["../../src/integrations/base-integration.service.ts"],"names":[],"mappings":"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"}
|