@vendure/elasticsearch-plugin 1.2.2 → 1.3.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/lib/src/{graphql-schema-extensions.d.ts → api/api-extensions.d.ts} +1 -1
- package/lib/src/{graphql-schema-extensions.js → api/api-extensions.js} +107 -56
- package/lib/src/api/api-extensions.js.map +1 -0
- package/lib/src/{custom-mappings.resolver.d.ts → api/custom-mappings.resolver.d.ts} +1 -1
- package/lib/src/{custom-mappings.resolver.js → api/custom-mappings.resolver.js} +1 -1
- package/lib/src/api/custom-mappings.resolver.js.map +1 -0
- package/lib/src/api/custom-script-fields.resolver.d.ts +12 -0
- package/lib/src/api/custom-script-fields.resolver.js +50 -0
- package/lib/src/api/custom-script-fields.resolver.js.map +1 -0
- package/lib/src/{elasticsearch-resolver.d.ts → api/elasticsearch-resolver.d.ts} +9 -6
- package/lib/src/{elasticsearch-resolver.js → api/elasticsearch-resolver.js} +27 -3
- package/lib/src/api/elasticsearch-resolver.js.map +1 -0
- package/lib/src/build-elastic-body.js +56 -41
- package/lib/src/build-elastic-body.js.map +1 -1
- package/lib/src/constants.d.ts +0 -1
- package/lib/src/constants.js +1 -2
- package/lib/src/constants.js.map +1 -1
- package/lib/src/elasticsearch.service.d.ts +11 -2
- package/lib/src/elasticsearch.service.js +139 -68
- package/lib/src/elasticsearch.service.js.map +1 -1
- package/lib/src/{elasticsearch-index.service.d.ts → indexing/elasticsearch-index.service.d.ts} +1 -1
- package/lib/src/{elasticsearch-index.service.js → indexing/elasticsearch-index.service.js} +0 -0
- package/lib/src/indexing/elasticsearch-index.service.js.map +1 -0
- package/lib/src/{indexer.controller.d.ts → indexing/indexer.controller.d.ts} +24 -10
- package/lib/src/{indexer.controller.js → indexing/indexer.controller.js} +221 -266
- package/lib/src/indexing/indexer.controller.js.map +1 -0
- package/lib/src/{indexing-utils.d.ts → indexing/indexing-utils.d.ts} +2 -2
- package/lib/src/{indexing-utils.js → indexing/indexing-utils.js} +3 -59
- package/lib/src/indexing/indexing-utils.js.map +1 -0
- package/lib/src/options.d.ts +203 -32
- package/lib/src/options.js +5 -0
- package/lib/src/options.js.map +1 -1
- package/lib/src/plugin.d.ts +4 -2
- package/lib/src/plugin.js +31 -11
- package/lib/src/plugin.js.map +1 -1
- package/lib/src/types.d.ts +51 -13
- package/package.json +4 -4
- package/lib/src/custom-mappings.resolver.js.map +0 -1
- package/lib/src/elasticsearch-index.service.js.map +0 -1
- package/lib/src/elasticsearch-resolver.js.map +0 -1
- package/lib/src/graphql-schema-extensions.js.map +0 -1
- package/lib/src/indexer.controller.js.map +0 -1
- package/lib/src/indexing-utils.js.map +0 -1
|
@@ -11,14 +11,15 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
12
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
13
|
};
|
|
14
|
+
var ElasticsearchIndexerController_1;
|
|
14
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.ElasticsearchIndexerController = exports.
|
|
16
|
+
exports.ElasticsearchIndexerController = exports.defaultVariantRelations = exports.defaultProductRelations = void 0;
|
|
16
17
|
const common_1 = require("@nestjs/common");
|
|
17
18
|
const unique_1 = require("@vendure/common/lib/unique");
|
|
18
19
|
const core_1 = require("@vendure/core");
|
|
19
|
-
const constants_1 = require("
|
|
20
|
+
const constants_1 = require("../constants");
|
|
20
21
|
const indexing_utils_1 = require("./indexing-utils");
|
|
21
|
-
exports.
|
|
22
|
+
exports.defaultProductRelations = [
|
|
22
23
|
'variants',
|
|
23
24
|
'featuredAsset',
|
|
24
25
|
'facetValues',
|
|
@@ -26,7 +27,7 @@ exports.productRelations = [
|
|
|
26
27
|
'channels',
|
|
27
28
|
'channels.defaultTaxZone',
|
|
28
29
|
];
|
|
29
|
-
exports.
|
|
30
|
+
exports.defaultVariantRelations = [
|
|
30
31
|
'featuredAsset',
|
|
31
32
|
'facetValues',
|
|
32
33
|
'facetValues.facet',
|
|
@@ -35,16 +36,20 @@ exports.variantRelations = [
|
|
|
35
36
|
'channels',
|
|
36
37
|
'channels.defaultTaxZone',
|
|
37
38
|
];
|
|
38
|
-
let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
39
|
-
constructor(connection, options, productVariantService,
|
|
39
|
+
let ElasticsearchIndexerController = ElasticsearchIndexerController_1 = class ElasticsearchIndexerController {
|
|
40
|
+
constructor(connection, options, productPriceApplicator, configService, productVariantService, requestContextCache) {
|
|
40
41
|
this.connection = connection;
|
|
41
42
|
this.options = options;
|
|
42
|
-
this.
|
|
43
|
+
this.productPriceApplicator = productPriceApplicator;
|
|
43
44
|
this.configService = configService;
|
|
45
|
+
this.productVariantService = productVariantService;
|
|
46
|
+
this.requestContextCache = requestContextCache;
|
|
44
47
|
this.asyncQueue = new core_1.AsyncQueue('elasticsearch-indexer', 5);
|
|
45
48
|
}
|
|
46
49
|
onModuleInit() {
|
|
47
50
|
this.client = indexing_utils_1.getClient(this.options);
|
|
51
|
+
this.productRelations = this.getReindexRelationsRelations(exports.defaultProductRelations, this.options.hydrateProductRelations);
|
|
52
|
+
this.variantRelations = this.getReindexRelationsRelations(exports.defaultVariantRelations, this.options.hydrateProductVariantRelations);
|
|
48
53
|
}
|
|
49
54
|
onModuleDestroy() {
|
|
50
55
|
return this.client.close();
|
|
@@ -137,27 +142,17 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
137
142
|
const timeStart = Date.now();
|
|
138
143
|
const operations = [];
|
|
139
144
|
const reindexTempName = new Date().getTime();
|
|
140
|
-
const productIndexName = this.options.indexPrefix + constants_1.PRODUCT_INDEX_NAME;
|
|
141
145
|
const variantIndexName = this.options.indexPrefix + constants_1.VARIANT_INDEX_NAME;
|
|
142
|
-
const reindexProductAliasName = productIndexName + `-reindex-${reindexTempName}`;
|
|
143
146
|
const reindexVariantAliasName = variantIndexName + `-reindex-${reindexTempName}`;
|
|
144
147
|
try {
|
|
145
|
-
await indexing_utils_1.createIndices(this.client, this.options.indexPrefix, this.options.indexSettings, this.options.indexMappingProperties,
|
|
146
|
-
const reindexProductIndexName = await indexing_utils_1.getIndexNameByAlias(this.client, reindexProductAliasName);
|
|
148
|
+
await indexing_utils_1.createIndices(this.client, this.options.indexPrefix, this.options.indexSettings, this.options.indexMappingProperties, true, `-reindex-${reindexTempName}`);
|
|
147
149
|
const reindexVariantIndexName = await indexing_utils_1.getIndexNameByAlias(this.client, reindexVariantAliasName);
|
|
148
|
-
const originalProductAliasExist = await this.client.indices.existsAlias({
|
|
149
|
-
name: productIndexName,
|
|
150
|
-
});
|
|
151
150
|
const originalVariantAliasExist = await this.client.indices.existsAlias({
|
|
152
151
|
name: variantIndexName,
|
|
153
152
|
});
|
|
154
|
-
const originalProductIndexExist = await this.client.indices.exists({
|
|
155
|
-
index: productIndexName,
|
|
156
|
-
});
|
|
157
153
|
const originalVariantIndexExist = await this.client.indices.exists({
|
|
158
154
|
index: variantIndexName,
|
|
159
155
|
});
|
|
160
|
-
const originalProductIndexName = await indexing_utils_1.getIndexNameByAlias(this.client, productIndexName);
|
|
161
156
|
const originalVariantIndexName = await indexing_utils_1.getIndexNameByAlias(this.client, variantIndexName);
|
|
162
157
|
if (originalVariantAliasExist.body || originalVariantIndexExist.body) {
|
|
163
158
|
await this.client.reindex({
|
|
@@ -172,19 +167,6 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
172
167
|
},
|
|
173
168
|
});
|
|
174
169
|
}
|
|
175
|
-
if (originalProductAliasExist.body || originalProductIndexExist.body) {
|
|
176
|
-
await this.client.reindex({
|
|
177
|
-
refresh: true,
|
|
178
|
-
body: {
|
|
179
|
-
source: {
|
|
180
|
-
index: productIndexName,
|
|
181
|
-
},
|
|
182
|
-
dest: {
|
|
183
|
-
index: reindexProductAliasName,
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
170
|
const actions = [
|
|
189
171
|
{
|
|
190
172
|
remove: {
|
|
@@ -192,38 +174,13 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
192
174
|
alias: reindexVariantAliasName,
|
|
193
175
|
},
|
|
194
176
|
},
|
|
195
|
-
{
|
|
196
|
-
remove: {
|
|
197
|
-
index: reindexProductIndexName,
|
|
198
|
-
alias: reindexProductAliasName,
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
177
|
{
|
|
202
178
|
add: {
|
|
203
179
|
index: reindexVariantIndexName,
|
|
204
180
|
alias: variantIndexName,
|
|
205
181
|
},
|
|
206
182
|
},
|
|
207
|
-
{
|
|
208
|
-
add: {
|
|
209
|
-
index: reindexProductIndexName,
|
|
210
|
-
alias: productIndexName,
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
183
|
];
|
|
214
|
-
if (originalProductAliasExist.body) {
|
|
215
|
-
actions.push({
|
|
216
|
-
remove: {
|
|
217
|
-
index: originalProductIndexName,
|
|
218
|
-
alias: productIndexName,
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
else if (originalProductIndexExist.body) {
|
|
223
|
-
await this.client.indices.delete({
|
|
224
|
-
index: [productIndexName],
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
184
|
if (originalVariantAliasExist.body) {
|
|
228
185
|
actions.push({
|
|
229
186
|
remove: {
|
|
@@ -242,11 +199,6 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
242
199
|
actions,
|
|
243
200
|
},
|
|
244
201
|
});
|
|
245
|
-
if (originalProductAliasExist.body) {
|
|
246
|
-
await this.client.indices.delete({
|
|
247
|
-
index: [originalProductIndexName],
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
202
|
if (originalVariantAliasExist.body) {
|
|
251
203
|
await this.client.indices.delete({
|
|
252
204
|
index: [originalVariantIndexName],
|
|
@@ -270,18 +222,6 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
270
222
|
index: [reindexVariantIndexName],
|
|
271
223
|
});
|
|
272
224
|
}
|
|
273
|
-
const reindexProductAliasExist = await this.client.indices.existsAlias({
|
|
274
|
-
name: reindexProductAliasName,
|
|
275
|
-
});
|
|
276
|
-
if (reindexProductAliasExist.body) {
|
|
277
|
-
const reindexProductAliasResult = await this.client.indices.getAlias({
|
|
278
|
-
name: reindexProductAliasName,
|
|
279
|
-
});
|
|
280
|
-
const reindexProductIndexName = Object.keys(reindexProductAliasResult.body)[0];
|
|
281
|
-
await this.client.indices.delete({
|
|
282
|
-
index: [reindexProductIndexName],
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
225
|
}
|
|
286
226
|
const deletedProductIds = await this.connection
|
|
287
227
|
.getRepository(core_1.Product)
|
|
@@ -321,26 +261,18 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
321
261
|
});
|
|
322
262
|
}
|
|
323
263
|
async updateAsset(data) {
|
|
324
|
-
const
|
|
325
|
-
const result2 = await this.updateAssetFocalPointForIndex(constants_1.VARIANT_INDEX_NAME, data.asset);
|
|
264
|
+
const result = await this.updateAssetFocalPointForIndex(constants_1.VARIANT_INDEX_NAME, data.asset);
|
|
326
265
|
await this.client.indices.refresh({
|
|
327
|
-
index: [
|
|
328
|
-
this.options.indexPrefix + constants_1.PRODUCT_INDEX_NAME,
|
|
329
|
-
this.options.indexPrefix + constants_1.VARIANT_INDEX_NAME,
|
|
330
|
-
],
|
|
266
|
+
index: [this.options.indexPrefix + constants_1.VARIANT_INDEX_NAME],
|
|
331
267
|
});
|
|
332
|
-
return
|
|
268
|
+
return result;
|
|
333
269
|
}
|
|
334
270
|
async deleteAsset(data) {
|
|
335
|
-
const
|
|
336
|
-
const result2 = await this.deleteAssetForIndex(constants_1.VARIANT_INDEX_NAME, data.asset);
|
|
271
|
+
const result = await this.deleteAssetForIndex(constants_1.VARIANT_INDEX_NAME, data.asset);
|
|
337
272
|
await this.client.indices.refresh({
|
|
338
|
-
index: [
|
|
339
|
-
this.options.indexPrefix + constants_1.PRODUCT_INDEX_NAME,
|
|
340
|
-
this.options.indexPrefix + constants_1.VARIANT_INDEX_NAME,
|
|
341
|
-
],
|
|
273
|
+
index: [this.options.indexPrefix + constants_1.VARIANT_INDEX_NAME],
|
|
342
274
|
});
|
|
343
|
-
return
|
|
275
|
+
return result;
|
|
344
276
|
}
|
|
345
277
|
async updateAssetFocalPointForIndex(indexName, asset) {
|
|
346
278
|
const focalPoint = asset.focalPoint || null;
|
|
@@ -396,15 +328,22 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
396
328
|
const operations = [];
|
|
397
329
|
for (const productId of productIds) {
|
|
398
330
|
operations.push(...(await this.deleteProductOperations(productId)));
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
331
|
+
let product;
|
|
332
|
+
try {
|
|
333
|
+
product = await this.connection.getRepository(core_1.Product).findOne(productId, {
|
|
334
|
+
relations: this.productRelations,
|
|
335
|
+
where: {
|
|
336
|
+
deletedAt: null,
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
catch (e) {
|
|
341
|
+
core_1.Logger.error(e.message, constants_1.loggerCtx, e.stack);
|
|
342
|
+
throw e;
|
|
343
|
+
}
|
|
405
344
|
if (product) {
|
|
406
345
|
const updatedProductVariants = await this.connection.getRepository(core_1.ProductVariant).findByIds(product.variants.map(v => v.id), {
|
|
407
|
-
relations:
|
|
346
|
+
relations: this.variantRelations,
|
|
408
347
|
where: {
|
|
409
348
|
deletedAt: null,
|
|
410
349
|
},
|
|
@@ -412,15 +351,18 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
412
351
|
id: 'ASC',
|
|
413
352
|
},
|
|
414
353
|
});
|
|
354
|
+
// tslint:disable-next-line:no-non-null-assertion
|
|
415
355
|
updatedProductVariants.forEach(variant => (variant.product = product));
|
|
416
356
|
if (!product.enabled) {
|
|
417
357
|
updatedProductVariants.forEach(v => (v.enabled = false));
|
|
418
358
|
}
|
|
419
359
|
core_1.Logger.verbose(`Updating Product (${productId})`, constants_1.loggerCtx);
|
|
420
|
-
|
|
421
|
-
|
|
360
|
+
const languageVariants = [];
|
|
361
|
+
languageVariants.push(...product.translations.map(t => t.languageCode));
|
|
362
|
+
for (const variant of product.variants) {
|
|
363
|
+
languageVariants.push(...variant.translations.map(t => t.languageCode));
|
|
422
364
|
}
|
|
423
|
-
const
|
|
365
|
+
const uniqueLanguageVariants = unique_1.unique(languageVariants);
|
|
424
366
|
for (const channel of product.channels) {
|
|
425
367
|
const channelCtx = new core_1.RequestContext({
|
|
426
368
|
channel,
|
|
@@ -431,65 +373,73 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
431
373
|
});
|
|
432
374
|
const variantsInChannel = updatedProductVariants.filter(v => v.channels.map(c => c.id).includes(channelCtx.channelId));
|
|
433
375
|
for (const variant of variantsInChannel) {
|
|
434
|
-
await this.
|
|
376
|
+
await this.productPriceApplicator.applyChannelPriceAndTax(variant, channelCtx);
|
|
435
377
|
}
|
|
436
|
-
for (const languageCode of
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
378
|
+
for (const languageCode of uniqueLanguageVariants) {
|
|
379
|
+
if (variantsInChannel.length) {
|
|
380
|
+
for (const variant of variantsInChannel) {
|
|
381
|
+
operations.push({
|
|
382
|
+
index: constants_1.VARIANT_INDEX_NAME,
|
|
383
|
+
operation: {
|
|
384
|
+
update: {
|
|
385
|
+
_id: ElasticsearchIndexerController_1.getId(variant.id, channelCtx.channelId, languageCode),
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
}, {
|
|
389
|
+
index: constants_1.VARIANT_INDEX_NAME,
|
|
390
|
+
operation: {
|
|
391
|
+
doc: await this.createVariantIndexItem(variant, variantsInChannel, channelCtx, languageCode),
|
|
392
|
+
doc_as_upsert: true,
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
operations.push({
|
|
399
|
+
index: constants_1.VARIANT_INDEX_NAME,
|
|
400
|
+
operation: {
|
|
401
|
+
update: {
|
|
402
|
+
_id: ElasticsearchIndexerController_1.getId(-product.id, channelCtx.channelId, languageCode),
|
|
403
|
+
},
|
|
442
404
|
},
|
|
443
|
-
},
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
},
|
|
452
|
-
});
|
|
405
|
+
}, {
|
|
406
|
+
index: constants_1.VARIANT_INDEX_NAME,
|
|
407
|
+
operation: {
|
|
408
|
+
doc: this.createSyntheticProductIndexItem(product, channelCtx, languageCode),
|
|
409
|
+
doc_as_upsert: true,
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
}
|
|
453
413
|
}
|
|
454
414
|
}
|
|
455
415
|
}
|
|
456
416
|
}
|
|
457
417
|
return operations;
|
|
458
418
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
update: { _id: this.getId(variant.id, channelCtx.channelId, languageCode) },
|
|
480
|
-
},
|
|
481
|
-
}, {
|
|
482
|
-
index: constants_1.VARIANT_INDEX_NAME,
|
|
483
|
-
operation: {
|
|
484
|
-
doc: this.createVariantIndexItem(variant, channelCtx.channelId, languageCode),
|
|
485
|
-
doc_as_upsert: true,
|
|
486
|
-
},
|
|
487
|
-
});
|
|
419
|
+
/**
|
|
420
|
+
* Takes the default relations, and combines them with any extra relations specified in the
|
|
421
|
+
* `hydrateProductRelations` and `hydrateProductVariantRelations`. This method also ensures
|
|
422
|
+
* that the relation values are unique and that paths are fully expanded.
|
|
423
|
+
*
|
|
424
|
+
* This means that if a `hydrateProductRelations` value of `['assets.asset']` is specified,
|
|
425
|
+
* this method will also add `['assets']` to the relations array, otherwise TypeORM would
|
|
426
|
+
* throw an error trying to join a 2nd-level deep relation without the first level also
|
|
427
|
+
* being joined.
|
|
428
|
+
*/
|
|
429
|
+
getReindexRelationsRelations(defaultRelations, hydratedRelations) {
|
|
430
|
+
const uniqueRelations = unique_1.unique([...defaultRelations, ...hydratedRelations]);
|
|
431
|
+
for (const relation of hydratedRelations) {
|
|
432
|
+
const path = relation.split('.');
|
|
433
|
+
const pathToPart = [];
|
|
434
|
+
for (const part of path) {
|
|
435
|
+
pathToPart.push(part);
|
|
436
|
+
const joinedPath = pathToPart.join('.');
|
|
437
|
+
if (!uniqueRelations.includes(joinedPath)) {
|
|
438
|
+
uniqueRelations.push(joinedPath);
|
|
488
439
|
}
|
|
489
440
|
}
|
|
490
441
|
}
|
|
491
|
-
|
|
492
|
-
return operations;
|
|
442
|
+
return uniqueRelations;
|
|
493
443
|
}
|
|
494
444
|
async deleteProductOperations(productId) {
|
|
495
445
|
const channels = await this.connection
|
|
@@ -505,29 +455,39 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
505
455
|
}
|
|
506
456
|
core_1.Logger.verbose(`Deleting 1 Product (id: ${productId})`, constants_1.loggerCtx);
|
|
507
457
|
const operations = [];
|
|
458
|
+
const languageVariants = [];
|
|
459
|
+
languageVariants.push(...product.translations.map(t => t.languageCode));
|
|
460
|
+
for (const variant of product.variants) {
|
|
461
|
+
languageVariants.push(...variant.translations.map(t => t.languageCode));
|
|
462
|
+
}
|
|
463
|
+
const uniqueLanguageVariants = unique_1.unique(languageVariants);
|
|
508
464
|
for (const { id: channelId } of channels) {
|
|
509
|
-
const
|
|
510
|
-
for (const languageCode of languageVariants) {
|
|
465
|
+
for (const languageCode of uniqueLanguageVariants) {
|
|
511
466
|
operations.push({
|
|
512
|
-
index: constants_1.
|
|
513
|
-
operation: {
|
|
467
|
+
index: constants_1.VARIANT_INDEX_NAME,
|
|
468
|
+
operation: {
|
|
469
|
+
delete: {
|
|
470
|
+
_id: ElasticsearchIndexerController_1.getId(-product.id, channelId, languageCode),
|
|
471
|
+
},
|
|
472
|
+
},
|
|
514
473
|
});
|
|
515
474
|
}
|
|
516
475
|
}
|
|
517
|
-
operations.push(...(await this.deleteVariantsInternalOperations(product.variants, channels.map(c => c.id))));
|
|
476
|
+
operations.push(...(await this.deleteVariantsInternalOperations(product.variants, channels.map(c => c.id), uniqueLanguageVariants)));
|
|
518
477
|
return operations;
|
|
519
478
|
}
|
|
520
|
-
async deleteVariantsInternalOperations(variants, channelIds) {
|
|
479
|
+
async deleteVariantsInternalOperations(variants, channelIds, languageVariants) {
|
|
521
480
|
core_1.Logger.verbose(`Deleting ${variants.length} ProductVariants`, constants_1.loggerCtx);
|
|
522
481
|
const operations = [];
|
|
523
482
|
for (const variant of variants) {
|
|
524
483
|
for (const channelId of channelIds) {
|
|
525
|
-
const languageVariants = variant.translations.map(t => t.languageCode);
|
|
526
484
|
for (const languageCode of languageVariants) {
|
|
527
485
|
operations.push({
|
|
528
486
|
index: constants_1.VARIANT_INDEX_NAME,
|
|
529
487
|
operation: {
|
|
530
|
-
delete: {
|
|
488
|
+
delete: {
|
|
489
|
+
_id: ElasticsearchIndexerController_1.getId(variant.id, channelId, languageCode),
|
|
490
|
+
},
|
|
531
491
|
},
|
|
532
492
|
});
|
|
533
493
|
}
|
|
@@ -543,20 +503,11 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
543
503
|
return unique_1.unique(variants.map(v => v.product.id));
|
|
544
504
|
}
|
|
545
505
|
async executeBulkOperations(operations) {
|
|
546
|
-
const productOperations = [];
|
|
547
506
|
const variantOperations = [];
|
|
548
507
|
for (const operation of operations) {
|
|
549
|
-
|
|
550
|
-
productOperations.push(operation.operation);
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
variantOperations.push(operation.operation);
|
|
554
|
-
}
|
|
508
|
+
variantOperations.push(operation.operation);
|
|
555
509
|
}
|
|
556
|
-
return Promise.all([
|
|
557
|
-
this.runBulkOperationsOnIndex(constants_1.PRODUCT_INDEX_NAME, productOperations),
|
|
558
|
-
this.runBulkOperationsOnIndex(constants_1.VARIANT_INDEX_NAME, variantOperations),
|
|
559
|
-
]);
|
|
510
|
+
return Promise.all([this.runBulkOperationsOnIndex(constants_1.VARIANT_INDEX_NAME, variantOperations)]);
|
|
560
511
|
}
|
|
561
512
|
async runBulkOperationsOnIndex(indexName, operations) {
|
|
562
513
|
var _a;
|
|
@@ -594,127 +545,129 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
594
545
|
core_1.Logger.error('Error details: ' + JSON.stringify((_a = e.body) === null || _a === void 0 ? void 0 : _a.error, null, 2), constants_1.loggerCtx);
|
|
595
546
|
}
|
|
596
547
|
}
|
|
597
|
-
createVariantIndexItem(v,
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
548
|
+
async createVariantIndexItem(v, variants, ctx, languageCode) {
|
|
549
|
+
try {
|
|
550
|
+
const productAsset = v.product.featuredAsset;
|
|
551
|
+
const variantAsset = v.featuredAsset;
|
|
552
|
+
const productTranslation = this.getTranslation(v.product, languageCode);
|
|
553
|
+
const variantTranslation = this.getTranslation(v, languageCode);
|
|
554
|
+
const collectionTranslations = v.collections.map(c => this.getTranslation(c, languageCode));
|
|
555
|
+
const productCollectionTranslations = variants.reduce((translations, variant) => [
|
|
556
|
+
...translations,
|
|
557
|
+
...variant.collections.map(c => this.getTranslation(c, languageCode)),
|
|
558
|
+
], []);
|
|
559
|
+
const prices = variants.map(variant => variant.price);
|
|
560
|
+
const pricesWithTax = variants.map(variant => variant.priceWithTax);
|
|
561
|
+
const item = {
|
|
562
|
+
channelId: ctx.channelId,
|
|
563
|
+
languageCode,
|
|
564
|
+
productVariantId: v.id,
|
|
565
|
+
sku: v.sku,
|
|
566
|
+
slug: productTranslation.slug,
|
|
567
|
+
productId: v.product.id,
|
|
568
|
+
productName: productTranslation.name,
|
|
569
|
+
productAssetId: productAsset ? productAsset.id : undefined,
|
|
570
|
+
productPreview: productAsset ? productAsset.preview : '',
|
|
571
|
+
productPreviewFocalPoint: productAsset ? productAsset.focalPoint || undefined : undefined,
|
|
572
|
+
productVariantName: variantTranslation.name,
|
|
573
|
+
productVariantAssetId: variantAsset ? variantAsset.id : undefined,
|
|
574
|
+
productVariantPreview: variantAsset ? variantAsset.preview : '',
|
|
575
|
+
productVariantPreviewFocalPoint: variantAsset
|
|
576
|
+
? variantAsset.focalPoint || undefined
|
|
577
|
+
: undefined,
|
|
578
|
+
price: v.price,
|
|
579
|
+
priceWithTax: v.priceWithTax,
|
|
580
|
+
currencyCode: v.currencyCode,
|
|
581
|
+
description: productTranslation.description,
|
|
582
|
+
facetIds: this.getFacetIds([v]),
|
|
583
|
+
channelIds: v.channels.map(c => c.id),
|
|
584
|
+
facetValueIds: this.getFacetValueIds([v]),
|
|
585
|
+
collectionIds: v.collections.map(c => c.id.toString()),
|
|
586
|
+
collectionSlugs: collectionTranslations.map(c => c.slug),
|
|
587
|
+
enabled: v.enabled && v.product.enabled,
|
|
588
|
+
productEnabled: variants.some(variant => variant.enabled) && v.product.enabled,
|
|
589
|
+
productPriceMin: Math.min(...prices),
|
|
590
|
+
productPriceMax: Math.max(...prices),
|
|
591
|
+
productPriceWithTaxMin: Math.min(...pricesWithTax),
|
|
592
|
+
productPriceWithTaxMax: Math.max(...pricesWithTax),
|
|
593
|
+
productFacetIds: this.getFacetIds(variants),
|
|
594
|
+
productFacetValueIds: this.getFacetValueIds(variants),
|
|
595
|
+
productCollectionIds: unique_1.unique(variants.reduce((ids, variant) => [...ids, ...variant.collections.map(c => c.id)], [])),
|
|
596
|
+
productCollectionSlugs: unique_1.unique(productCollectionTranslations.map(c => c.slug)),
|
|
597
|
+
productChannelIds: v.product.channels.map(c => c.id),
|
|
598
|
+
inStock: 0 < (await this.productVariantService.getSaleableStockLevel(ctx, v)),
|
|
599
|
+
productInStock: await this.getProductInStockValue(ctx, variants),
|
|
600
|
+
};
|
|
601
|
+
const variantCustomMappings = Object.entries(this.options.customProductVariantMappings);
|
|
602
|
+
for (const [name, def] of variantCustomMappings) {
|
|
603
|
+
item[`variant-${name}`] = def.valueFn(v, languageCode);
|
|
604
|
+
}
|
|
605
|
+
const productCustomMappings = Object.entries(this.options.customProductMappings);
|
|
606
|
+
for (const [name, def] of productCustomMappings) {
|
|
607
|
+
item[`product-${name}`] = def.valueFn(v.product, variants, languageCode);
|
|
608
|
+
}
|
|
609
|
+
return item;
|
|
632
610
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
const first = variants[0];
|
|
637
|
-
const prices = variants.map(v => v.price);
|
|
638
|
-
const pricesWithTax = variants.map(v => v.priceWithTax);
|
|
639
|
-
const productAsset = first.product.featuredAsset;
|
|
640
|
-
const variantAsset = variants.filter(v => v.featuredAsset).length
|
|
641
|
-
? variants.filter(v => v.featuredAsset)[0].featuredAsset
|
|
642
|
-
: null;
|
|
643
|
-
const productTranslation = this.getTranslation(first.product, languageCode);
|
|
644
|
-
const variantTranslation = this.getTranslation(first, languageCode);
|
|
645
|
-
const collectionTranslations = variants.reduce((translations, variant) => [
|
|
646
|
-
...translations,
|
|
647
|
-
...variant.collections.map(c => this.getTranslation(c, languageCode)),
|
|
648
|
-
], []);
|
|
649
|
-
const item = {
|
|
650
|
-
channelId,
|
|
651
|
-
languageCode,
|
|
652
|
-
sku: first.sku,
|
|
653
|
-
slug: productTranslation.slug,
|
|
654
|
-
productId: first.product.id,
|
|
655
|
-
productName: productTranslation.name,
|
|
656
|
-
productAssetId: productAsset ? productAsset.id : undefined,
|
|
657
|
-
productPreview: productAsset ? productAsset.preview : '',
|
|
658
|
-
productPreviewFocalPoint: productAsset ? productAsset.focalPoint || undefined : undefined,
|
|
659
|
-
productVariantId: first.id,
|
|
660
|
-
productVariantName: variantTranslation.name,
|
|
661
|
-
productVariantAssetId: variantAsset ? variantAsset.id : undefined,
|
|
662
|
-
productVariantPreview: variantAsset ? variantAsset.preview : '',
|
|
663
|
-
productVariantPreviewFocalPoint: productAsset ? productAsset.focalPoint || undefined : undefined,
|
|
664
|
-
priceMin: Math.min(...prices),
|
|
665
|
-
priceMax: Math.max(...prices),
|
|
666
|
-
priceWithTaxMin: Math.min(...pricesWithTax),
|
|
667
|
-
priceWithTaxMax: Math.max(...pricesWithTax),
|
|
668
|
-
currencyCode: first.currencyCode,
|
|
669
|
-
description: productTranslation.description,
|
|
670
|
-
facetIds: this.getFacetIds(variants),
|
|
671
|
-
facetValueIds: this.getFacetValueIds(variants),
|
|
672
|
-
collectionIds: variants.reduce((ids, v) => [...ids, ...v.collections.map(c => c.id)], []),
|
|
673
|
-
collectionSlugs: collectionTranslations.map(c => c.slug),
|
|
674
|
-
channelIds: first.product.channels.map(c => c.id),
|
|
675
|
-
enabled: variants.some(v => v.enabled) && first.product.enabled,
|
|
676
|
-
};
|
|
677
|
-
const customMappings = Object.entries(this.options.customProductMappings);
|
|
678
|
-
for (const [name, def] of customMappings) {
|
|
679
|
-
item[name] = def.valueFn(variants[0].product, variants, languageCode);
|
|
611
|
+
catch (err) {
|
|
612
|
+
core_1.Logger.error(err.toString());
|
|
613
|
+
throw Error(`Error while reindexing!`);
|
|
680
614
|
}
|
|
681
|
-
|
|
615
|
+
}
|
|
616
|
+
async getProductInStockValue(ctx, variants) {
|
|
617
|
+
const stockLevels = await Promise.all(variants.map(variant => this.productVariantService.getSaleableStockLevel(ctx, variant)));
|
|
618
|
+
return stockLevels.some(stockLevel => 0 < stockLevel);
|
|
682
619
|
}
|
|
683
620
|
/**
|
|
684
621
|
* If a Product has no variants, we create a synthetic variant for the purposes
|
|
685
622
|
* of making that product visible via the search query.
|
|
686
623
|
*/
|
|
687
|
-
createSyntheticProductIndexItem(
|
|
688
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
689
|
-
const productTranslation = this.getTranslation(product,
|
|
690
|
-
|
|
624
|
+
createSyntheticProductIndexItem(product, ctx, languageCode) {
|
|
625
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
626
|
+
const productTranslation = this.getTranslation(product, languageCode);
|
|
627
|
+
const productAsset = product.featuredAsset;
|
|
628
|
+
const item = {
|
|
691
629
|
channelId: ctx.channelId,
|
|
692
630
|
languageCode,
|
|
631
|
+
productVariantId: 0,
|
|
693
632
|
sku: '',
|
|
694
633
|
slug: productTranslation.slug,
|
|
695
634
|
productId: product.id,
|
|
696
635
|
productName: productTranslation.name,
|
|
697
|
-
productAssetId:
|
|
698
|
-
productPreview:
|
|
699
|
-
productPreviewFocalPoint:
|
|
700
|
-
productVariantId: 0,
|
|
636
|
+
productAssetId: productAsset ? productAsset.id : undefined,
|
|
637
|
+
productPreview: productAsset ? productAsset.preview : '',
|
|
638
|
+
productPreviewFocalPoint: productAsset ? productAsset.focalPoint || undefined : undefined,
|
|
701
639
|
productVariantName: productTranslation.name,
|
|
702
640
|
productVariantAssetId: undefined,
|
|
703
641
|
productVariantPreview: '',
|
|
704
642
|
productVariantPreviewFocalPoint: undefined,
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
priceWithTaxMin: 0,
|
|
708
|
-
priceWithTaxMax: 0,
|
|
643
|
+
price: 0,
|
|
644
|
+
priceWithTax: 0,
|
|
709
645
|
currencyCode: ctx.channel.currencyCode,
|
|
710
646
|
description: productTranslation.description,
|
|
711
|
-
facetIds: (
|
|
712
|
-
|
|
647
|
+
facetIds: (_b = (_a = product.facetValues) === null || _a === void 0 ? void 0 : _a.map(fv => fv.facet.id.toString())) !== null && _b !== void 0 ? _b : [],
|
|
648
|
+
channelIds: [ctx.channelId],
|
|
649
|
+
facetValueIds: (_d = (_c = product.facetValues) === null || _c === void 0 ? void 0 : _c.map(fv => fv.id.toString())) !== null && _d !== void 0 ? _d : [],
|
|
713
650
|
collectionIds: [],
|
|
714
651
|
collectionSlugs: [],
|
|
715
|
-
channelIds: [ctx.channelId],
|
|
716
652
|
enabled: false,
|
|
653
|
+
productEnabled: false,
|
|
654
|
+
productPriceMin: 0,
|
|
655
|
+
productPriceMax: 0,
|
|
656
|
+
productPriceWithTaxMin: 0,
|
|
657
|
+
productPriceWithTaxMax: 0,
|
|
658
|
+
productFacetIds: (_f = (_e = product.facetValues) === null || _e === void 0 ? void 0 : _e.map(fv => fv.facet.id.toString())) !== null && _f !== void 0 ? _f : [],
|
|
659
|
+
productFacetValueIds: (_h = (_g = product.facetValues) === null || _g === void 0 ? void 0 : _g.map(fv => fv.id.toString())) !== null && _h !== void 0 ? _h : [],
|
|
660
|
+
productCollectionIds: [],
|
|
661
|
+
productCollectionSlugs: [],
|
|
662
|
+
productChannelIds: product.channels.map(c => c.id),
|
|
663
|
+
inStock: false,
|
|
664
|
+
productInStock: false,
|
|
717
665
|
};
|
|
666
|
+
const productCustomMappings = Object.entries(this.options.customProductMappings);
|
|
667
|
+
for (const [name, def] of productCustomMappings) {
|
|
668
|
+
item[`product-${name}`] = def.valueFn(product, [], languageCode);
|
|
669
|
+
}
|
|
670
|
+
return item;
|
|
718
671
|
}
|
|
719
672
|
getTranslation(translatable, languageCode) {
|
|
720
673
|
return (translatable.translations.find(t => t.languageCode === languageCode) ||
|
|
@@ -733,15 +686,17 @@ let ElasticsearchIndexerController = class ElasticsearchIndexerController {
|
|
|
733
686
|
const productFacetValueIds = variants[0].product.facetValues.map(facetValueIds);
|
|
734
687
|
return unique_1.unique([...variantFacetValueIds, ...productFacetValueIds]);
|
|
735
688
|
}
|
|
736
|
-
getId(entityId, channelId, languageCode) {
|
|
689
|
+
static getId(entityId, channelId, languageCode) {
|
|
737
690
|
return `${channelId.toString()}_${entityId.toString()}_${languageCode}`;
|
|
738
691
|
}
|
|
739
692
|
};
|
|
740
|
-
ElasticsearchIndexerController = __decorate([
|
|
693
|
+
ElasticsearchIndexerController = ElasticsearchIndexerController_1 = __decorate([
|
|
741
694
|
common_1.Injectable(),
|
|
742
695
|
__param(1, common_1.Inject(constants_1.ELASTIC_SEARCH_OPTIONS)),
|
|
743
|
-
__metadata("design:paramtypes", [core_1.TransactionalConnection, Object, core_1.
|
|
744
|
-
core_1.ConfigService
|
|
696
|
+
__metadata("design:paramtypes", [core_1.TransactionalConnection, Object, core_1.ProductPriceApplicator,
|
|
697
|
+
core_1.ConfigService,
|
|
698
|
+
core_1.ProductVariantService,
|
|
699
|
+
core_1.RequestContextCacheService])
|
|
745
700
|
], ElasticsearchIndexerController);
|
|
746
701
|
exports.ElasticsearchIndexerController = ElasticsearchIndexerController;
|
|
747
702
|
//# sourceMappingURL=indexer.controller.js.map
|