@configura/web-api 3.0.0-alpha.0 → 3.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/CatalogueAPI.d.ts +68 -1
  2. package/dist/CatalogueAPI.js +184 -219
  3. package/dist/CfgMeasure.js +1 -2
  4. package/dist/CfgProduct.js +131 -159
  5. package/dist/io/CfgIOManager.js +2 -11
  6. package/dist/io/CfgIOProdConfConnector.js +14 -25
  7. package/dist/io/CfgObservableStateManager.js +1 -1
  8. package/dist/productConfiguration/CfgFeature.d.ts +5 -0
  9. package/dist/productConfiguration/CfgFeature.js +64 -54
  10. package/dist/productConfiguration/CfgOption.d.ts +44 -0
  11. package/dist/productConfiguration/CfgOption.js +107 -71
  12. package/dist/productConfiguration/CfgProductConfiguration.js +22 -34
  13. package/dist/productConfiguration/productParamsGenerator.js +43 -57
  14. package/dist/productLoader.js +2 -13
  15. package/dist/syncGroups/SyncGroupsHandler.js +60 -83
  16. package/dist/syncGroups/SyncGroupsPathHelper.js +5 -5
  17. package/dist/syncGroups/SyncGroupsState.js +4 -5
  18. package/dist/syncGroups/SyncGroupsTransaction.js +259 -303
  19. package/dist/tasks/TaskHandler.js +53 -64
  20. package/dist/tests/testData/dummyProductForTest.js +4 -1
  21. package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +18 -21
  22. package/dist/tests/testData/testDataCachedGetProduct.js +20 -20
  23. package/dist/tests/testData/testDataCachedPostValidate.js +6 -15
  24. package/dist/tests/testData/testDataProductAggregatedPrice.js +21 -21
  25. package/dist/tests/testData/testDataUpcharge.js +31 -22
  26. package/dist/utilitiesCatalogueData.js +21 -9
  27. package/dist/utilitiesCataloguePermission.js +5 -2
  28. package/dist/utilitiesConfiguration.js +21 -23
  29. package/package.json +3 -3
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  var _a;
11
2
  import { AggregatedLoadingObservable, assert, assertDefined, augmentErrorMessage, compareArrays, count, Observable, toLengthUnit, } from "@configura/web-utilities";
12
3
  import { CfgMeasureDefinition } from "./CfgMeasure.js";
@@ -18,11 +9,10 @@ import { SyncGroupsHandler } from "./syncGroups/SyncGroupsHandler.js";
18
9
  import { compareCfgProductData, correctDefaultsOnCatalogueParams, isSameCatalogueParams, isSameProductRef, makeProductKey, } from "./utilitiesCatalogueData.js";
19
10
  import { CfgProdConfParts, convertDtoProductConfToV1, isAdditionalProductConfiguration, isProductConf, } from "./utilitiesConfiguration.js";
20
11
  function completeSettings(incompleteSettings) {
21
- var _b, _c;
22
12
  return {
23
- strictSelectOneSelectionCount: (_b = incompleteSettings === null || incompleteSettings === void 0 ? void 0 : incompleteSettings.strictSelectOneSelectionCount) !== null && _b !== void 0 ? _b : false,
24
- syncGroupsApplyMode: incompleteSettings === null || incompleteSettings === void 0 ? void 0 : incompleteSettings.syncGroupsApplyMode,
25
- disableMatchOnDescription: (_c = incompleteSettings === null || incompleteSettings === void 0 ? void 0 : incompleteSettings.disableMatchOnDescription) !== null && _c !== void 0 ? _c : false,
13
+ strictSelectOneSelectionCount: incompleteSettings?.strictSelectOneSelectionCount ?? false,
14
+ syncGroupsApplyMode: incompleteSettings?.syncGroupsApplyMode,
15
+ disableMatchOnDescription: incompleteSettings?.disableMatchOnDescription ?? false,
26
16
  };
27
17
  }
28
18
  /**
@@ -55,7 +45,6 @@ function isDescriptionMatch(l, r) {
55
45
  */
56
46
  export class _CfgProductInternal {
57
47
  constructor(initSuccess, initFail, _productLoaderRaw, prodParams, settings, optional, selected, rootFeatureRefs, rawFeatures, notes, uuid, _rawUnit, _rawProductData, apiSelection, apiConstraints, loadingObservable, parent, root, _additionalProductRef, _syncGroupHandler) {
58
- var _b;
59
48
  this._productLoaderRaw = _productLoaderRaw;
60
49
  this.prodParams = prodParams;
61
50
  this.settings = settings;
@@ -72,23 +61,22 @@ export class _CfgProductInternal {
72
61
  this.changeObservable = new Observable();
73
62
  /** Mark this and its descendants as destroyed and remove all listeners */
74
63
  this.destroy = () => {
75
- var _b;
76
64
  this._destroyed = true;
77
65
  this.changeObservable.stopAllListen();
78
66
  this.configuration.stopAllListenForChange();
79
- for (const additionalProduct of (_b = this.additionalProducts) !== null && _b !== void 0 ? _b : []) {
67
+ for (const additionalProduct of this.additionalProducts ?? []) {
80
68
  additionalProduct.destroy();
81
69
  }
82
70
  };
83
71
  /**
84
72
  * Reset will reset the product to its initial state
85
73
  */
86
- this.reset = () => __awaiter(this, void 0, void 0, function* () {
74
+ this.reset = async () => {
87
75
  if (this._initialClone !== undefined) {
88
- yield this.copyFrom(this._initialClone, true);
76
+ await this.copyFrom(this._initialClone, true);
89
77
  }
90
- });
91
- this._notifyAllOfChange = (bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
78
+ };
79
+ this._notifyAllOfChange = async (bubbleMode, committed) => {
92
80
  if (bubbleMode === CfgProductBubbleMode.Stop) {
93
81
  return;
94
82
  }
@@ -96,23 +84,23 @@ export class _CfgProductInternal {
96
84
  const freshRef = CfgProduct._makeNewRefFrom(this);
97
85
  this.changeObservable.notifyAll({ freshRef, committed });
98
86
  if (parent !== undefined) {
99
- yield parent._additionalProductHasChanged(freshRef, bubbleMode === CfgProductBubbleMode.OneLevel
87
+ await parent._additionalProductHasChanged(freshRef, bubbleMode === CfgProductBubbleMode.OneLevel
100
88
  ? CfgProductBubbleMode.Stop
101
89
  : bubbleMode, committed);
102
90
  }
103
- });
91
+ };
104
92
  /** Called when a child (additional product or the configuration) has changed. */
105
- this._childHasChanged = (bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
93
+ this._childHasChanged = async (bubbleMode, committed) => {
106
94
  if (bubbleMode === CfgProductBubbleMode.ToRootAndBubbleSelected &&
107
95
  this.optional &&
108
96
  !this.selected) {
109
- yield this.setSelected(true, bubbleMode, false);
97
+ await this.setSelected(true, bubbleMode, false);
110
98
  return;
111
99
  }
112
- yield this._notifyAllOfChange(bubbleMode, committed);
113
- });
100
+ await this._notifyAllOfChange(bubbleMode, committed);
101
+ };
114
102
  /** Called by child to tell its parent that it has changed. */
115
- this._additionalProductHasChanged = (freshRef, bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
103
+ this._additionalProductHasChanged = async (freshRef, bubbleMode, committed) => {
116
104
  const i = this.additionalProducts.findIndex((a) => a.isBackedBySame(freshRef));
117
105
  if (i !== -1) {
118
106
  // Child additional product might not be found. This probably means that propagate
@@ -122,39 +110,38 @@ export class _CfgProductInternal {
122
110
  // C no longer is part of the tree. Odd, but fully permitted.
123
111
  this.additionalProducts[i] = freshRef;
124
112
  }
125
- yield this._childHasChanged(bubbleMode, committed);
126
- });
113
+ await this._childHasChanged(bubbleMode, committed);
114
+ };
127
115
  /** Called by the configuration to tell its parent that it has changed. */
128
- this._configurationHasChanged = (freshRef, bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
116
+ this._configurationHasChanged = async (freshRef, bubbleMode, committed) => {
129
117
  this._configuration = freshRef;
130
118
  switch (bubbleMode) {
131
119
  case ProductConfigurationBubbleMode.ValidateAndBubbleSelected:
132
120
  // The revalidate call will continue the bubble
133
- yield this._revalidate(CfgProductBubbleMode.ToRootAndBubbleSelected, this._productLoaderRaw, committed);
121
+ await this._revalidate(CfgProductBubbleMode.ToRootAndBubbleSelected, this._productLoaderRaw, committed);
134
122
  return;
135
123
  case ProductConfigurationBubbleMode.BubbleSelected:
136
- yield this._childHasChanged(CfgProductBubbleMode.ToRootAndBubbleSelected, committed);
124
+ await this._childHasChanged(CfgProductBubbleMode.ToRootAndBubbleSelected, committed);
137
125
  return;
138
126
  case ProductConfigurationBubbleMode.Validate:
139
127
  // The revalidate call will continue the bubble
140
- yield this._revalidate(CfgProductBubbleMode.ToRoot, this._productLoaderRaw, committed);
128
+ await this._revalidate(CfgProductBubbleMode.ToRoot, this._productLoaderRaw, committed);
141
129
  return;
142
130
  case ProductConfigurationBubbleMode.ToParentProduct:
143
131
  // Do not continue bubble as we have reached the parent CfgProduct
144
132
  return;
145
133
  case ProductConfigurationBubbleMode.OneLevel:
146
- yield this._childHasChanged(CfgProductBubbleMode.OneLevel, committed);
134
+ await this._childHasChanged(CfgProductBubbleMode.OneLevel, committed);
147
135
  return;
148
136
  case ProductConfigurationBubbleMode.Stop:
149
- yield this._childHasChanged(CfgProductBubbleMode.Stop, committed);
137
+ await this._childHasChanged(CfgProductBubbleMode.Stop, committed);
150
138
  return;
151
139
  case ProductConfigurationBubbleMode.ToRoot:
152
- yield this._childHasChanged(CfgProductBubbleMode.ToRoot, committed);
140
+ await this._childHasChanged(CfgProductBubbleMode.ToRoot, committed);
153
141
  return;
154
142
  }
155
- });
143
+ };
156
144
  this.getDtoConf = (include) => {
157
- var _b;
158
145
  const conf = {};
159
146
  const features = this.configuration._internal.getDtoConf((include & CfgProdConfParts.ExtendedData) === CfgProdConfParts.ExtendedData);
160
147
  if (0 < features.length) {
@@ -168,7 +155,7 @@ export class _CfgProductInternal {
168
155
  // so no need to store it for additional products.
169
156
  if ((include & CfgProdConfParts.SyncGroupState) === CfgProdConfParts.SyncGroupState &&
170
157
  this.parent === undefined) {
171
- conf.syncGroupState = (_b = this.syncGroupHandler) === null || _b === void 0 ? void 0 : _b.getCompactSyncGroupState();
158
+ conf.syncGroupState = this.syncGroupHandler?.getCompactSyncGroupState();
172
159
  }
173
160
  const additionalProducts = this.additionalProducts;
174
161
  if (0 < additionalProducts.length) {
@@ -185,7 +172,7 @@ export class _CfgProductInternal {
185
172
  }
186
173
  return conf;
187
174
  };
188
- this.setDtoConf = (s, doValidate, productLoaderForGroupedLoad) => __awaiter(this, void 0, void 0, function* () {
175
+ this.setDtoConf = async (s, doValidate, productLoaderForGroupedLoad) => {
189
176
  // The DtoProdConf format can contain a sync group state, but
190
177
  // not the DtoAdditionalProductConfiguration format. So we apply
191
178
  // any passed state here.
@@ -196,15 +183,11 @@ export class _CfgProductInternal {
196
183
  syncGroupHandler.setCompactSyncGroupState(newSyncGroupState);
197
184
  }
198
185
  }
199
- return yield this.setApiSelection(convertDtoProductConfToV1(s), doValidate, productLoaderForGroupedLoad);
200
- });
201
- this.setApiSelection = (s, doValidate, productLoaderForGroupedLoad) => __awaiter(this, void 0, void 0, function* () {
202
- return yield this._setApiSelectionWithOtherProduct(s, doValidate, productLoaderForGroupedLoad, undefined);
203
- });
204
- this.copyFrom = (source, doValidate, productLoaderForGroupedLoad) => __awaiter(this, void 0, void 0, function* () {
205
- return yield this._setApiSelectionWithOtherProduct(convertDtoProductConfToV1(source.getDtoConf(CfgProdConfParts.NoExtra)), doValidate, productLoaderForGroupedLoad, source);
206
- });
207
- this._setApiSelectionWithOtherProduct = (productConfiguration, doValidate, productLoaderForGroupedLoad, sourceProduct) => __awaiter(this, void 0, void 0, function* () {
186
+ return await this.setApiSelection(convertDtoProductConfToV1(s), doValidate, productLoaderForGroupedLoad);
187
+ };
188
+ this.setApiSelection = async (s, doValidate, productLoaderForGroupedLoad) => await this._setApiSelectionWithOtherProduct(s, doValidate, productLoaderForGroupedLoad, undefined);
189
+ this.copyFrom = async (source, doValidate, productLoaderForGroupedLoad) => await this._setApiSelectionWithOtherProduct(convertDtoProductConfToV1(source.getDtoConf(CfgProdConfParts.NoExtra)), doValidate, productLoaderForGroupedLoad, source);
190
+ this._setApiSelectionWithOtherProduct = async (productConfiguration, doValidate, productLoaderForGroupedLoad, sourceProduct) => {
208
191
  // Wrap with cache will make getProduct for this function call use the same server call
209
192
  // for the same product with the same params. Used for getProduct (when a new additional
210
193
  // product is loaded) and postValidate.
@@ -237,16 +220,16 @@ export class _CfgProductInternal {
237
220
  }
238
221
  }
239
222
  }
240
- const configurationChange = yield this.configuration._internal.setApiSelection(productConfiguration.selOptions, sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct._rawProductData.partsData.constrOptions, false);
223
+ const configurationChange = await this.configuration._internal.setApiSelection(productConfiguration.selOptions, sourceProduct?._rawProductData.partsData.constrOptions, false);
241
224
  if (configurationChange) {
242
225
  change = true;
243
226
  }
244
227
  if (this.optional) {
245
- if (yield this.setSelected(productConfiguration.selected !== false, CfgProductBubbleMode.Stop, false)) {
228
+ if (await this.setSelected(productConfiguration.selected !== false, CfgProductBubbleMode.Stop, false)) {
246
229
  change = true;
247
230
  }
248
231
  }
249
- yield this._syncAndLoadAdditionalProducts(productLoaderForGroupedLoad, productConfiguration);
232
+ await this._syncAndLoadAdditionalProducts(productLoaderForGroupedLoad, productConfiguration);
250
233
  const apiSelectionAdditionalProducts = productConfiguration.additionalProducts || [];
251
234
  const additionalProducts = this.additionalProducts.slice();
252
235
  const additionalProductsCount = additionalProducts.length;
@@ -254,11 +237,10 @@ export class _CfgProductInternal {
254
237
  if (apiSelectionAdditionalProductsCount !== additionalProductsCount) {
255
238
  throw new Error(`Additional products are not same length. This product: "${this.key}". This product additional products count: ${additionalProductsCount}. Passed apiSelection additional products count: ${apiSelectionAdditionalProductsCount}`);
256
239
  }
257
- const sourceProductAdditionalProducts = sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.additionalProducts;
240
+ const sourceProductAdditionalProducts = sourceProduct?.additionalProducts;
258
241
  assert(!sourceProductAdditionalProducts ||
259
242
  additionalProductsCount === sourceProductAdditionalProducts.length, `Passed sourceProduct does not have the same number of additional products as this.`);
260
- if ((yield Promise.all(apiSelectionAdditionalProducts.map((apiSelectionAdditionalProduct) => __awaiter(this, void 0, void 0, function* () {
261
- var _c;
243
+ if ((await Promise.all(apiSelectionAdditionalProducts.map(async (apiSelectionAdditionalProduct) => {
262
244
  const refKey = apiSelectionAdditionalProduct.refKey;
263
245
  assertDefined(refKey, "Additional product api configurations must have refKey.");
264
246
  const i = additionalProducts.findIndex((a) => refKey === a.refKey);
@@ -266,25 +248,25 @@ export class _CfgProductInternal {
266
248
  let sourceProductAdditionalProduct = undefined;
267
249
  if (sourceProductAdditionalProducts !== undefined) {
268
250
  sourceProductAdditionalProduct =
269
- (_c = sourceProductAdditionalProducts.find((a) => refKey === a.refKey)) === null || _c === void 0 ? void 0 : _c._internal;
251
+ sourceProductAdditionalProducts.find((a) => refKey === a.refKey)?._internal;
270
252
  assertDefined(sourceProductAdditionalProduct, "Additional product not found in sourceProduct");
271
253
  }
272
254
  const additionalProduct = additionalProducts.splice(i, 1)[0]; // Splicing like this is okay because this is done synchronous. The setCon. is what is async.
273
- return yield additionalProduct._internal._setApiSelectionWithOtherProduct(apiSelectionAdditionalProduct, doValidate, productLoaderForGroupedLoad, sourceProductAdditionalProduct);
274
- })))).some((b) => b)) {
255
+ return await additionalProduct._internal._setApiSelectionWithOtherProduct(apiSelectionAdditionalProduct, doValidate, productLoaderForGroupedLoad, sourceProductAdditionalProduct);
256
+ }))).some((b) => b)) {
275
257
  change = true;
276
258
  }
277
259
  if (doValidate && configurationChange) {
278
- yield this._revalidate(CfgProductBubbleMode.ToRoot, productLoaderForGroupedLoad, true);
260
+ await this._revalidate(CfgProductBubbleMode.ToRoot, productLoaderForGroupedLoad, true);
279
261
  }
280
262
  else if (change) {
281
263
  // As setApiSelection is done recursively each level takes care of its own notifications
282
264
  // so we only need to bubble one level to notify this and swap out the reference in the
283
265
  // parent.
284
- yield this._notifyAllOfChange(CfgProductBubbleMode.OneLevel, true);
266
+ await this._notifyAllOfChange(CfgProductBubbleMode.OneLevel, true);
285
267
  }
286
268
  return change;
287
- });
269
+ };
288
270
  this.structureCompare = (other, strictOrder = true, descriptionMatch = false) => {
289
271
  if (!this.configuration.structureCompare(other.configuration, strictOrder, descriptionMatch)) {
290
272
  return false;
@@ -292,25 +274,25 @@ export class _CfgProductInternal {
292
274
  return compareArrays(this.additionalProducts, other.additionalProducts, (l, r) => (!descriptionMatch || (descriptionMatch && isDescriptionMatch(l, r))) &&
293
275
  l.structureCompare(r, strictOrder, descriptionMatch), !descriptionMatch);
294
276
  };
295
- this.tryMatchSelection = (other, descriptionMatch = false, // Match on case insensitive description, not code
296
- productLoaderForGroupedLoad) => __awaiter(this, void 0, void 0, function* () {
277
+ this.tryMatchSelection = async (other, descriptionMatch = false, // Match on case insensitive description, not code
278
+ productLoaderForGroupedLoad) => {
297
279
  // wrap with cache will make getProduct for this function call use the same server call
298
280
  // for the same product with the same params
299
281
  productLoaderForGroupedLoad =
300
282
  productLoaderForGroupedLoad || wrapWithCache(this._productLoaderRaw);
301
283
  let change = false;
302
284
  if (this.optional && other.optional) {
303
- if (yield this.setSelected(other.selected, CfgProductBubbleMode.Stop, false)) {
285
+ if (await this.setSelected(other.selected, CfgProductBubbleMode.Stop, false)) {
304
286
  change = true;
305
287
  }
306
288
  }
307
- const configurationChange = yield this.configuration._internal.tryMatchSelection(other.configuration._internal, descriptionMatch, false);
289
+ const configurationChange = await this.configuration._internal.tryMatchSelection(other.configuration._internal, descriptionMatch, false);
308
290
  if (configurationChange) {
309
291
  change = true;
310
- yield this._revalidate(CfgProductBubbleMode.ToRootAndBubbleSelected, productLoaderForGroupedLoad, true);
292
+ await this._revalidate(CfgProductBubbleMode.ToRootAndBubbleSelected, productLoaderForGroupedLoad, true);
311
293
  }
312
294
  else if (change) {
313
- yield this._notifyAllOfChange(CfgProductBubbleMode.ToRootAndBubbleSelected, true);
295
+ await this._notifyAllOfChange(CfgProductBubbleMode.ToRootAndBubbleSelected, true);
314
296
  }
315
297
  const thisAdditionalProducts = this.additionalProducts;
316
298
  const otherAdditionalProducts = other.additionalProducts;
@@ -342,11 +324,11 @@ export class _CfgProductInternal {
342
324
  promises.push(thisAdditionalProducts[i]._internal.tryMatchSelection(otherAdditionalProducts[i]._internal, descriptionMatch, productLoaderForGroupedLoad));
343
325
  }
344
326
  }
345
- if ((yield Promise.all(promises)).some((b) => b)) {
327
+ if ((await Promise.all(promises)).some((b) => b)) {
346
328
  change = true;
347
329
  }
348
330
  return change;
349
- });
331
+ };
350
332
  /** Only features in selected options and selected additional products. */
351
333
  this._getDescendantFeaturesWithCode = (code) => this.additionalProducts.reduce((agg, additionalProduct) => {
352
334
  if (additionalProduct.selected) {
@@ -359,12 +341,12 @@ export class _CfgProductInternal {
359
341
  * product in isolation. The validation result is applied on the configuration. Then additional
360
342
  * products are synced (unloaded, loaded etc.) Finally the changes bubble up the tree.
361
343
  */
362
- this._revalidate = (bubbleMode, productLoader, committed) => __awaiter(this, void 0, void 0, function* () {
344
+ this._revalidate = async (bubbleMode, productLoader, committed) => {
363
345
  const { _configuration: configuration } = this;
364
346
  const token = this.loadingObservable.startChildLoading();
365
347
  this._revalidateInProgressToken = token;
366
348
  try {
367
- const response = yield productLoader.postValidate(correctDefaultsOnCatalogueParams(this.prodParams), {
349
+ const response = await productLoader.postValidate(correctDefaultsOnCatalogueParams(this.prodParams), {
368
350
  selOptions: configuration._internal.getApiSelection(),
369
351
  knownFeatureCodes: configuration.rawFeatures.map((f) => f.code),
370
352
  });
@@ -395,12 +377,12 @@ export class _CfgProductInternal {
395
377
  if (rootFeatureRefs !== undefined) {
396
378
  configuration._internal.populateFeatures(rootFeatureRefs);
397
379
  }
398
- yield configuration._internal.setApiSelection(productData.partsData.selOptions || [], productData.partsData.constrOptions, false);
399
- yield this._syncAndLoadAdditionalProducts(productLoader, undefined);
380
+ await configuration._internal.setApiSelection(productData.partsData.selOptions || [], productData.partsData.constrOptions, false);
381
+ await this._syncAndLoadAdditionalProducts(productLoader, undefined);
400
382
  if (this._destroyed) {
401
383
  return false;
402
384
  }
403
- yield this._notifyAllOfChange(bubbleMode, committed);
385
+ await this._notifyAllOfChange(bubbleMode, committed);
404
386
  return true;
405
387
  }
406
388
  catch (e) {
@@ -409,12 +391,12 @@ export class _CfgProductInternal {
409
391
  finally {
410
392
  this.loadingObservable.stopChildLoading(token);
411
393
  }
412
- });
394
+ };
413
395
  /**
414
396
  * Based on this configuration find what additional products should be shown and not, unload
415
397
  * (i.e. destroy) those that should no longer be shown, load the new ones.
416
398
  */
417
- this._syncAndLoadAdditionalProducts = (productLoaderForGroupedLoad, initialProductConfiguration) => __awaiter(this, void 0, void 0, function* () {
399
+ this._syncAndLoadAdditionalProducts = async (productLoaderForGroupedLoad, initialProductConfiguration) => {
418
400
  const { _productLoaderRaw: productLoaderRaw, rawProductData: productData, configuration, additionalProducts: currentAdditionalProducts, } = this;
419
401
  const additionalProductRefs = [
420
402
  ...(productData.additionalProductRefs || []),
@@ -455,20 +437,23 @@ export class _CfgProductInternal {
455
437
  if (additionalProductRefs.length !== 0) {
456
438
  change = true;
457
439
  }
458
- const newAdditionalProducts = yield Promise.all(additionalProductRefs.map((p) => (() => __awaiter(this, void 0, void 0, function* () {
459
- var _d;
440
+ const newAdditionalProducts = await Promise.all(additionalProductRefs.map((p) => (async () => {
460
441
  const additionalProductRef = p.prodRef;
461
442
  const refKey = additionalProductRef.refKey;
462
- const additionalProductInitialProductConfiguration = (_d = initialProductConfiguration === null || initialProductConfiguration === void 0 ? void 0 : initialProductConfiguration.additionalProducts) === null || _d === void 0 ? void 0 : _d.find((aP) => refKey === aP.refKey);
443
+ const additionalProductInitialProductConfiguration = initialProductConfiguration?.additionalProducts?.find((aP) => refKey === aP.refKey);
463
444
  if (initialProductConfiguration !== undefined &&
464
445
  additionalProductInitialProductConfiguration === undefined) {
465
446
  console.warn(`Did not find initial product configuration for additional product with refKey ${refKey}`);
466
447
  }
467
448
  return {
468
449
  originalIndex: p.originalIndex,
469
- product: CfgProduct._makeNewRefFrom(yield _CfgProductInternal.make(productLoaderRaw, productLoaderForGroupedLoad, Object.assign(Object.assign({}, additionalProductRef.catId), { lang: this.prodParams.lang, partNumber: additionalProductRef.partNumber }), this.settings, additionalProductRef.optional === true, this.loadingObservable, this, this.root, additionalProductRef, additionalProductInitialProductConfiguration)),
450
+ product: CfgProduct._makeNewRefFrom(await _CfgProductInternal.make(productLoaderRaw, productLoaderForGroupedLoad, {
451
+ ...additionalProductRef.catId,
452
+ lang: this.prodParams.lang,
453
+ partNumber: additionalProductRef.partNumber,
454
+ }, this.settings, additionalProductRef.optional === true, this.loadingObservable, this, this.root, additionalProductRef, additionalProductInitialProductConfiguration)),
470
455
  };
471
- }))()));
456
+ })()));
472
457
  if (this._destroyed) {
473
458
  return change;
474
459
  }
@@ -480,13 +465,16 @@ export class _CfgProductInternal {
480
465
  finally {
481
466
  this.loadingObservable.stopChildLoading(token);
482
467
  }
483
- });
468
+ };
484
469
  this._setRawProductData = (productData) => {
485
470
  this._rawProductData = productData;
486
471
  this._clearStretchMeasurements();
487
472
  };
488
- this.root = root !== null && root !== void 0 ? root : this;
489
- this.key = makeProductKey(Object.assign(Object.assign({}, prodParams), { partNumber: (_b = _additionalProductRef === null || _additionalProductRef === void 0 ? void 0 : _additionalProductRef.refKey) !== null && _b !== void 0 ? _b : prodParams.partNumber }));
473
+ this.root = root ?? this;
474
+ this.key = makeProductKey({
475
+ ...prodParams,
476
+ partNumber: _additionalProductRef?.refKey ?? prodParams.partNumber,
477
+ });
490
478
  this._selected = optional ? selected : undefined;
491
479
  this.isAdditionalProduct = _additionalProductRef !== undefined;
492
480
  if (notes !== undefined) {
@@ -503,19 +491,16 @@ export class _CfgProductInternal {
503
491
  * Providing the parent and root of what you clone as arguments is unwise as it will
504
492
  * make changes you do on the clone be propagated up to the original non-clone root product.
505
493
  */
506
- clone(parent, root) {
507
- return __awaiter(this, void 0, void 0, function* () {
508
- const product = yield new Promise((initSuccess, initFail) => {
509
- var _b;
510
- const p = new _CfgProductInternal(() => {
511
- initSuccess(p);
512
- }, initFail, this._productLoaderRaw, this.prodParams, this.settings, this.optional, this.selected, this._configuration.rootFeatureRefs, this._configuration.rawFeatures, this._notes.values(), this.uuid, this._rawUnit, this._rawProductData, this.configuration._internal.getApiSelection(), this.configuration._internal.getApiConstrained(), new AggregatedLoadingObservable(), parent, root, this._additionalProductRef, (_b = this._syncGroupHandler) === null || _b === void 0 ? void 0 : _b.clone());
513
- });
514
- for (const additionalProduct of this.additionalProducts) {
515
- product.additionalProducts.push(CfgProduct._makeNewRefFrom(yield additionalProduct._internal.clone(product, root || product)));
516
- }
517
- return product;
494
+ async clone(parent, root) {
495
+ const product = await new Promise((initSuccess, initFail) => {
496
+ const p = new _CfgProductInternal(() => {
497
+ initSuccess(p);
498
+ }, initFail, this._productLoaderRaw, this.prodParams, this.settings, this.optional, this.selected, this._configuration.rootFeatureRefs, this._configuration.rawFeatures, this._notes.values(), this.uuid, this._rawUnit, this._rawProductData, this.configuration._internal.getApiSelection(), this.configuration._internal.getApiConstrained(), new AggregatedLoadingObservable(), parent, root, this._additionalProductRef, this._syncGroupHandler?.clone());
518
499
  });
500
+ for (const additionalProduct of this.additionalProducts) {
501
+ product.additionalProducts.push(CfgProduct._makeNewRefFrom(await additionalProduct._internal.clone(product, root || product)));
502
+ }
503
+ return product;
519
504
  }
520
505
  /**
521
506
  * Internal use. Used when this product is an additional product, and
@@ -556,20 +541,17 @@ export class _CfgProductInternal {
556
541
  }
557
542
  }
558
543
  get notes() {
559
- var _b;
560
- return this.getNotes((_b = this.rawProductData.noteRefs) !== null && _b !== void 0 ? _b : []);
544
+ return this.getNotes(this.rawProductData.noteRefs ?? []);
561
545
  }
562
546
  get miscFiles() {
563
- var _b;
564
- return (_b = this._rawProductData.miscFiles) !== null && _b !== void 0 ? _b : [];
547
+ return this._rawProductData.miscFiles ?? [];
565
548
  }
566
549
  get hasRootFeaturesChanged() {
567
550
  return (this._configuration._internal.hasRootFeaturesChanged ||
568
551
  this.additionalProducts.some((p) => p._internal.hasRootFeaturesChanged));
569
552
  }
570
553
  get description() {
571
- var _b, _c;
572
- return (_c = (_b = this._additionalProductRef) === null || _b === void 0 ? void 0 : _b.refDescription) !== null && _c !== void 0 ? _c : this._rawProductData.description;
554
+ return this._additionalProductRef?.refDescription ?? this._rawProductData.description;
573
555
  }
574
556
  get rootNodeSources() {
575
557
  return this._rawProductData.models;
@@ -587,25 +569,21 @@ export class _CfgProductInternal {
587
569
  return this._rawProductData.partsData.prices;
588
570
  }
589
571
  get measureDefinitions() {
590
- var _b;
591
572
  if (this._measureDefinitions === undefined) {
592
- this._measureDefinitions = ((_b = this._rawProductData.measurements) !== null && _b !== void 0 ? _b : [])
573
+ this._measureDefinitions = (this._rawProductData.measurements ?? [])
593
574
  .map((m) => CfgMeasureDefinition.make(m))
594
575
  .filter((m) => m !== undefined);
595
576
  }
596
577
  return this._measureDefinitions;
597
578
  }
598
579
  get refKey() {
599
- var _b;
600
- return (_b = this._additionalProductRef) === null || _b === void 0 ? void 0 : _b.refKey;
580
+ return this._additionalProductRef?.refKey;
601
581
  }
602
582
  get transform() {
603
- var _b;
604
- return (_b = this._additionalProductRef) === null || _b === void 0 ? void 0 : _b.transform;
583
+ return this._additionalProductRef?.transform;
605
584
  }
606
585
  get anchor() {
607
- var _b;
608
- return (_b = this._additionalProductRef) === null || _b === void 0 ? void 0 : _b.anchor;
586
+ return this._additionalProductRef?.anchor;
609
587
  }
610
588
  /** @throws an error if the actual unit sent by the server was not a LengthUnit */
611
589
  get unit() {
@@ -641,34 +619,32 @@ export class _CfgProductInternal {
641
619
  get optional() {
642
620
  return this._selected !== undefined;
643
621
  }
644
- setSelected(selected, bubbleMode, interactive) {
645
- return __awaiter(this, void 0, void 0, function* () {
646
- if (!this.optional) {
647
- console.warn("This product is not optional. Nothing will happen");
648
- return false;
649
- }
650
- if (this._selected === selected) {
651
- return false;
652
- }
653
- // Vitally important that this happens before the call to reset,
654
- // so that the reset won't cause infinite loops
655
- this._selected = selected;
656
- if (interactive) {
657
- if (selected) {
658
- const syncGroupHandler = this.syncGroupHandler;
659
- if (syncGroupHandler !== undefined) {
660
- yield syncGroupHandler.init(this.root, wrapWithCache(this._productLoaderRaw));
661
- }
662
- }
663
- else {
664
- yield this.reset();
665
- // In case a passed initial configuration has made it reset to selected
666
- this._selected = selected;
622
+ async setSelected(selected, bubbleMode, interactive) {
623
+ if (!this.optional) {
624
+ console.warn("This product is not optional. Nothing will happen");
625
+ return false;
626
+ }
627
+ if (this._selected === selected) {
628
+ return false;
629
+ }
630
+ // Vitally important that this happens before the call to reset,
631
+ // so that the reset won't cause infinite loops
632
+ this._selected = selected;
633
+ if (interactive) {
634
+ if (selected) {
635
+ const syncGroupHandler = this.syncGroupHandler;
636
+ if (syncGroupHandler !== undefined) {
637
+ await syncGroupHandler.init(this.root, wrapWithCache(this._productLoaderRaw));
667
638
  }
668
639
  }
669
- yield this._notifyAllOfChange(bubbleMode, true);
670
- return true;
671
- });
640
+ else {
641
+ await this.reset();
642
+ // In case a passed initial configuration has made it reset to selected
643
+ this._selected = selected;
644
+ }
645
+ }
646
+ await this._notifyAllOfChange(bubbleMode, true);
647
+ return true;
672
648
  }
673
649
  get configuration() {
674
650
  return this._configuration;
@@ -711,8 +687,7 @@ export class _CfgProductInternal {
711
687
  return this.root._syncGroupHandler;
712
688
  }
713
689
  get syncGroupsVerboseLogging() {
714
- var _b, _c;
715
- return (_c = (_b = this.syncGroupHandler) === null || _b === void 0 ? void 0 : _b.verboseLogging) !== null && _c !== void 0 ? _c : false;
690
+ return this.syncGroupHandler?.verboseLogging ?? false;
716
691
  }
717
692
  /**
718
693
  * Set to true to get verbose sync state changes logged to the console.
@@ -726,8 +701,8 @@ export class _CfgProductInternal {
726
701
  }
727
702
  }
728
703
  _a = _CfgProductInternal;
729
- _CfgProductInternal.make = (productLoaderRaw, productLoaderForGroupedLoad, // Used when instantiating the current product
730
- prodParams, settings, optional, loadingObservable, parent, root, additionalProductRef, initialProductConfiguration) => __awaiter(void 0, void 0, void 0, function* () {
704
+ _CfgProductInternal.make = async (productLoaderRaw, productLoaderForGroupedLoad, // Used when instantiating the current product
705
+ prodParams, settings, optional, loadingObservable, parent, root, additionalProductRef, initialProductConfiguration) => {
731
706
  // Wrap with cache will make getProduct for this function call use the same server call
732
707
  // for the same product with the same params. Not retained for future calls, only used
733
708
  // at this initial load.
@@ -756,39 +731,38 @@ prodParams, settings, optional, loadingObservable, parent, root, additionalProdu
756
731
  initialProductConfigurationV1 = initialProductConfiguration;
757
732
  }
758
733
  }
759
- const productResponse = yield (initialProductConfigurationV1
734
+ const productResponse = await (initialProductConfigurationV1
760
735
  ? productLoaderForGroupedLoad.postValidate(defaultCorrectedProdParams, {
761
736
  knownFeatureCodes: [],
762
737
  selOptions: initialProductConfigurationV1.selOptions,
763
738
  })
764
739
  : productLoaderForGroupedLoad.getProduct(defaultCorrectedProdParams));
765
740
  const { productData, rootFeatureRefs, features: rawFeatures, notes, uuid, unit, } = productResponse;
766
- const initiallySelected = !optional || (initialProductConfigurationV1 === null || initialProductConfigurationV1 === void 0 ? void 0 : initialProductConfigurationV1.selected) === true;
767
- const product = yield new Promise((initSuccess, initFail) => {
768
- var _b;
741
+ const initiallySelected = !optional || initialProductConfigurationV1?.selected === true;
742
+ const product = await new Promise((initSuccess, initFail) => {
769
743
  const p = new _CfgProductInternal(() => {
770
744
  // We absolutely do not want anyone to assign to this._configuration. So we want that field private.
771
745
  // But we can not set the api selection synchronously. And the product configuration needs "this". So we use this callback.
772
746
  // Feel free to find a nicer more readable solution :)
773
747
  initSuccess(p);
774
- }, initFail, productLoaderRaw, prodParams, settings, optional, initiallySelected, rootFeatureRefs !== null && rootFeatureRefs !== void 0 ? rootFeatureRefs : [], rawFeatures, notes === null || notes === void 0 ? void 0 : notes.values(), uuid, unit, productData, (_b = productData.partsData.selOptions) !== null && _b !== void 0 ? _b : [], productData.partsData.constrOptions, loadingObservable, parent, root, additionalProductRef, syncGroupHandler);
748
+ }, initFail, productLoaderRaw, prodParams, settings, optional, initiallySelected, rootFeatureRefs ?? [], rawFeatures, notes?.values(), uuid, unit, productData, productData.partsData.selOptions ?? [], productData.partsData.constrOptions, loadingObservable, parent, root, additionalProductRef, syncGroupHandler);
775
749
  });
776
- yield product._syncAndLoadAdditionalProducts(productLoaderForGroupedLoad, initialProductConfigurationV1);
777
- product._initialClone = yield product.clone();
750
+ await product._syncAndLoadAdditionalProducts(productLoaderForGroupedLoad, initialProductConfigurationV1);
751
+ product._initialClone = await product.clone();
778
752
  if (syncGroupHandler !== undefined && !initialProductConfiguration) {
779
753
  // As syncGroupHandler is only set for root product we know that we will init with root.
780
754
  // If we have an initialProductConfiguration we do not run init for the syncGroups.
781
755
  // The idea with an initial configuration is that the product should look as it did when
782
756
  // the configuration was saved. Not running init does that. Also, the DtoProductConf
783
757
  // object can contain a sync state which is then used to populate the sync state.
784
- yield syncGroupHandler.init(product, productLoaderForGroupedLoad);
758
+ await syncGroupHandler.init(product, productLoaderForGroupedLoad);
785
759
  }
786
760
  return product;
787
761
  }
788
762
  catch (e) {
789
763
  throw augmentErrorMessage(e, `Load product request (${prodParams.partNumber}) failure`);
790
764
  }
791
- });
765
+ };
792
766
  export class CfgProduct {
793
767
  constructor(_internal) {
794
768
  this._internal = _internal;
@@ -799,13 +773,13 @@ export class CfgProduct {
799
773
  */
800
774
  this.destroy = () => this._internal.destroy();
801
775
  /** Makes a clone of this. It is disconnected from the original. */
802
- this.clone = () => __awaiter(this, void 0, void 0, function* () { return CfgProduct._makeNewRefFrom(yield this._internal.clone()); });
776
+ this.clone = async () => CfgProduct._makeNewRefFrom(await this._internal.clone());
803
777
  /**
804
778
  * Only applicable when this product is optional.
805
779
  * Setting this does not cause a validation call as toggling an optional additional product is
806
780
  * assumed to always be legal.
807
781
  */
808
- this.setSelected = (v) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.setSelected(v, CfgProductBubbleMode.ToRootAndBubbleSelected, true); });
782
+ this.setSelected = async (v) => await this._internal.setSelected(v, CfgProductBubbleMode.ToRootAndBubbleSelected, true);
809
783
  /**
810
784
  * Experimental. Additional products lacks descriptions or keys that are suitably for structure
811
785
  * compare, so we use strict-order when trying to match the additional products. This makes
@@ -819,8 +793,8 @@ export class CfgProduct {
819
793
  * This method does not propagate its selections.
820
794
  * This method will cause validation calls if something change.
821
795
  */
822
- this.tryMatchSelection = (other, descriptionMatch = false // Match on case insensitive description, not code
823
- ) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.tryMatchSelection(other._internal, descriptionMatch); });
796
+ this.tryMatchSelection = async (other, descriptionMatch = false // Match on case insensitive description, not code
797
+ ) => await this._internal.tryMatchSelection(other._internal, descriptionMatch);
824
798
  /**
825
799
  * Gets what selections has been made on the product, recursively including product
826
800
  * configuration, optional products and additional products. Used when a full view of all
@@ -836,7 +810,7 @@ export class CfgProduct {
836
810
  * the right models are loaded.
837
811
  * @deprecated setDtoConf uses a newer format.
838
812
  */
839
- this.setApiSelection = (configuration, doValidate = true) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.setApiSelection(configuration, doValidate); });
813
+ this.setApiSelection = async (configuration, doValidate = true) => await this._internal.setApiSelection(configuration, doValidate);
840
814
  /**
841
815
  * A newer alternative version of getApiSelection. This returns the configuration (selections)
842
816
  * on the product, recursively including product configuration, optional products and additional
@@ -858,7 +832,7 @@ export class CfgProduct {
858
832
  * @param doValidate Makes a server side validation call. These are necessary to ensure that
859
833
  * the right models are loaded.
860
834
  */
861
- this.setDtoConf = (configuration, doValidate = true) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.setDtoConf(configuration, doValidate); });
835
+ this.setDtoConf = async (configuration, doValidate = true) => await this._internal.setDtoConf(configuration, doValidate);
862
836
  this.listenForChange = (l) => this._internal.changeObservable.listen(l);
863
837
  this.stopListenForChange = (l) => this._internal.changeObservable.stopListen(l);
864
838
  this.stopAllListenForChange = () => this._internal.changeObservable.stopAllListen();
@@ -866,10 +840,8 @@ export class CfgProduct {
866
840
  this.stopListenForLoading = (l) => this._internal.loadingObservable.stopListen(l);
867
841
  this.stopAllListenForLoading = () => this._internal.loadingObservable.stopAllListen();
868
842
  }
869
- static make(productLoader, prodParams, settings, initialProductConfiguration) {
870
- return __awaiter(this, void 0, void 0, function* () {
871
- return this._makeNewRefFrom(yield _CfgProductInternal.make(productLoader, undefined, prodParams, completeSettings(settings), false, new AggregatedLoadingObservable(), undefined, undefined, undefined, initialProductConfiguration));
872
- });
843
+ static async make(productLoader, prodParams, settings, initialProductConfiguration) {
844
+ return this._makeNewRefFrom(await _CfgProductInternal.make(productLoader, undefined, prodParams, completeSettings(settings), false, new AggregatedLoadingObservable(), undefined, undefined, undefined, initialProductConfiguration));
873
845
  }
874
846
  /**
875
847
  * Makes an object wrapping the passed object. This is not a clone method, it is a method to