@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
  const CONFIGURA_ATTRIBUTE = "C0nf1gura";
11
2
  const CONFIGURA_SHEBANG = "arug1fn0C";
12
3
  // Support function. Did not manage to check both attribute and value in one step
@@ -90,7 +81,7 @@ export class CfgIOManager {
90
81
  return a;
91
82
  }, new Set());
92
83
  const promises = [];
93
- (() => __awaiter(this, void 0, void 0, function* () {
84
+ (async () => {
94
85
  for (const messageKey of allMessageKeys) {
95
86
  if (!CfgIOManager.hasIOContainerMessageKey(data, messageKey)) {
96
87
  continue;
@@ -104,7 +95,7 @@ export class CfgIOManager {
104
95
  promises.push(item.l(message));
105
96
  }
106
97
  }
107
- }))();
98
+ })();
108
99
  Promise.all(promises)
109
100
  .then(() => {
110
101
  this._receiveInProgress = false;
@@ -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 { convertDtoProductConfToV1 } from "../utilitiesConfiguration.js";
12
3
  export const isCfgProdConfMessage = (data) => typeof data === "object" && data !== null && "version" in data && "conf" in data;
@@ -31,8 +22,7 @@ export class CfgIOProdConfConnector {
31
22
  this._includeInSend = _includeInSend;
32
23
  this._stopListenToMessage = undefined;
33
24
  this._stopListenToProdConf = undefined;
34
- this.setProduct = (product) => __awaiter(this, void 0, void 0, function* () {
35
- var _b, _c;
25
+ this.setProduct = async (product) => {
36
26
  const currentProduct = this._product;
37
27
  const newProduct = product;
38
28
  this._product = newProduct;
@@ -43,14 +33,14 @@ export class CfgIOProdConfConnector {
43
33
  return;
44
34
  }
45
35
  if (currentProduct !== undefined) {
46
- (_b = this._stopListenToMessage) === null || _b === void 0 ? void 0 : _b.call(this);
47
- (_c = this._stopListenToProdConf) === null || _c === void 0 ? void 0 : _c.call(this);
36
+ this._stopListenToMessage?.();
37
+ this._stopListenToProdConf?.();
48
38
  }
49
39
  if (newProduct === undefined) {
50
40
  return;
51
41
  }
52
42
  this._send(this.makeSendData(newProduct.getDtoConf(this._includeInSend), true));
53
- this._stopListenToMessage = CfgIOProdConfConnector.listenForMessage((messages) => __awaiter(this, void 0, void 0, function* () {
43
+ this._stopListenToMessage = CfgIOProdConfConnector.listenForMessage(async (messages) => {
54
44
  const subMessages = messages.subMessages;
55
45
  if (subMessages.length === 0) {
56
46
  console.warn(`${STAGE_PROD_CONF_MESSAGE_KEY} message without any submessages. Unexpected.`);
@@ -58,24 +48,23 @@ export class CfgIOProdConfConnector {
58
48
  }
59
49
  const highestVersionMessage = getHighestVersionProdConfMessage(subMessages);
60
50
  if (isCfgProdConfMessageV1(highestVersionMessage)) {
61
- yield newProduct.setApiSelection(highestVersionMessage.conf);
51
+ await newProduct.setApiSelection(highestVersionMessage.conf);
62
52
  return;
63
53
  }
64
54
  if (isCfgProdConfMessageV2(highestVersionMessage)) {
65
- yield newProduct.setDtoConf(highestVersionMessage.conf);
55
+ await newProduct.setDtoConf(highestVersionMessage.conf);
66
56
  return;
67
57
  }
68
58
  throw new Error("Unknown message version");
69
- }), this._ioManager);
70
- this._stopListenToProdConf = CfgIOProdConfConnector.listenForProdConf(newProduct, (conf) => __awaiter(this, void 0, void 0, function* () { return this._send(this.makeSendData(conf, false)); }), this._includeInSend);
71
- });
59
+ }, this._ioManager);
60
+ this._stopListenToProdConf = CfgIOProdConfConnector.listenForProdConf(newProduct, async (conf) => this._send(this.makeSendData(conf, false)), this._includeInSend);
61
+ };
72
62
  this._send = (data) => this._ioManager.send(STAGE_PROD_CONF_MESSAGE_KEY, data);
73
63
  _ioManager.addWarningSupplier(this);
74
64
  }
75
65
  destroy() {
76
- var _b, _c;
77
- (_b = this._stopListenToMessage) === null || _b === void 0 ? void 0 : _b.call(this);
78
- (_c = this._stopListenToProdConf) === null || _c === void 0 ? void 0 : _c.call(this);
66
+ this._stopListenToMessage?.();
67
+ this._stopListenToProdConf?.();
79
68
  this._ioManager.removeWarningSupplier(this);
80
69
  }
81
70
  getWarnings() {
@@ -127,10 +116,10 @@ CfgIOProdConfConnector.makeMessage = (conf, initial, sendVersions) => {
127
116
  }
128
117
  return { subMessages: result, initial };
129
118
  };
130
- CfgIOProdConfConnector.makeMessageListener = (callback) => (message) => __awaiter(void 0, void 0, void 0, function* () {
119
+ CfgIOProdConfConnector.makeMessageListener = (callback) => async (message) => {
131
120
  const prodConfMessage = message;
132
- yield callback(prodConfMessage);
133
- });
121
+ await callback(prodConfMessage);
122
+ };
134
123
  CfgIOProdConfConnector.makeProdConfListener = (callback, includeInSend) => (n) => {
135
124
  if (!n.committed) {
136
125
  return;
@@ -52,7 +52,7 @@ export class CfgObservableStateManager extends CfgIOManager {
52
52
  try {
53
53
  asJson = JSON.parse(data);
54
54
  }
55
- catch (_a) {
55
+ catch {
56
56
  throw new Error("Not JSON data");
57
57
  }
58
58
  if (!CfgIOManager.isIOContainer(asJson)) {
@@ -44,6 +44,7 @@ export declare class _CfgFeatureInternal {
44
44
  private _options;
45
45
  private readonly _selectedOptions;
46
46
  private readonly _constrainedOptions;
47
+ private readonly _unresolvableOptions;
47
48
  private _mtrlApplications;
48
49
  readonly hasUpcharge: boolean;
49
50
  readonly changeObservable: Observable<FeatureChangeNotification>;
@@ -126,6 +127,10 @@ export declare class _CfgFeatureInternal {
126
127
  selectOption: (optionInternal: _CfgOptionInternal, on: boolean, bubbleMode: ProductConfigurationBubbleMode) => Promise<boolean>;
127
128
  isSelected: (option: _CfgOptionInternal) => boolean;
128
129
  isDisabled: (option: _CfgOptionInternal) => boolean;
130
+ /**
131
+ * An option is unresolvable when it is constrained from any possible value.
132
+ */
133
+ isUnresolvable: (option: _CfgOptionInternal) => boolean;
129
134
  keyMatch: (other: _CfgFeatureInternal, descriptionMatch?: boolean) => boolean;
130
135
  /** Only in selected options */
131
136
  _getFeaturesWithCode: (code: string) => _CfgFeatureInternal[];
@@ -1,13 +1,4 @@
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
- import { assertDefined, compareArrays, convertLength, count, Observable, someMatch, toLengthUnit, } from "@configura/web-utilities";
1
+ import { Observable, assertDefined, compareArrays, convertLength, count, someMatch, toLengthUnit, } from "@configura/web-utilities";
11
2
  import { CfgProduct } from "../CfgProduct.js";
12
3
  import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
13
4
  import { CfgMtrlApplicationSource } from "../material/CfgMtrlApplicationSource.js";
@@ -73,8 +64,9 @@ export class _CfgFeatureInternal {
73
64
  this.rootProduct = rootProduct;
74
65
  this._selectedOptions = [];
75
66
  this._constrainedOptions = [];
67
+ this._unresolvableOptions = [];
76
68
  this.changeObservable = new Observable();
77
- this.setNumericValue = (val) => __awaiter(this, void 0, void 0, function* () {
69
+ this.setNumericValue = async (val) => {
78
70
  if (this.selectionType !== SelectionType.SelectOne) {
79
71
  throw new Error("Only SelectOne Features can have numeric values");
80
72
  }
@@ -82,9 +74,9 @@ export class _CfgFeatureInternal {
82
74
  if (option === undefined) {
83
75
  throw new Error("No Option allows the value you tried to set");
84
76
  }
85
- return yield option.setNumericValue(val, true);
86
- });
87
- this._notifyAllOfChange = (bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
77
+ return await option.setNumericValue(val, true);
78
+ };
79
+ this._notifyAllOfChange = async (bubbleMode, committed) => {
88
80
  if (bubbleMode === ProductConfigurationBubbleMode.Stop) {
89
81
  return;
90
82
  }
@@ -92,17 +84,17 @@ export class _CfgFeatureInternal {
92
84
  this.changeObservable.notifyAll({ freshRef, committed });
93
85
  const parent = this.parent;
94
86
  if (parent !== undefined) {
95
- yield parent._childHasChanged(freshRef, bubbleMode === ProductConfigurationBubbleMode.OneLevel
87
+ await parent._childHasChanged(freshRef, bubbleMode === ProductConfigurationBubbleMode.OneLevel
96
88
  ? ProductConfigurationBubbleMode.Stop
97
89
  : bubbleMode, committed);
98
90
  }
99
- });
91
+ };
100
92
  /**
101
93
  * Called by child to tell its parent that it has changed.
102
94
  * @throws Will throw if options have not yet been generated. This should be impossible
103
95
  * as nonexisting children can not call their parent.
104
96
  */
105
- this._childHasChanged = (childOption, bubbleMode, committed) => __awaiter(this, void 0, void 0, function* () {
97
+ this._childHasChanged = async (childOption, bubbleMode, committed) => {
106
98
  const options = this._options;
107
99
  if (options === undefined) {
108
100
  throw Error("Child says it changed, but no children has actually been generated");
@@ -113,8 +105,8 @@ export class _CfgFeatureInternal {
113
105
  if (i !== -1) {
114
106
  selectedOptions[i] = freshRef;
115
107
  }
116
- yield this._notifyAllOfChange(bubbleMode, committed);
117
- });
108
+ await this._notifyAllOfChange(bubbleMode, committed);
109
+ };
118
110
  // Keep in sync with stripExtendedDataFromDtoFeatureConf
119
111
  this.getDtoConf = (includeExtendedData) => {
120
112
  const result = {
@@ -136,8 +128,7 @@ export class _CfgFeatureInternal {
136
128
  // way around. For that reason the get-method above uses the new format, and the set-method
137
129
  // below the old format. As these functions are meant to only be used internally this should't
138
130
  // cause too much confusion.
139
- this.setApiSelection = (apiOptionSelectionMap, apiOptionConstraintMap) => __awaiter(this, void 0, void 0, function* () {
140
- var _a, _b;
131
+ this.setApiSelection = async (apiOptionSelectionMap, apiOptionConstraintMap) => {
141
132
  const selectionType = this.selectionType;
142
133
  const isGroup = selectionType === SelectionType.Group;
143
134
  const isSelectOne = selectionType === SelectionType.SelectOne;
@@ -152,15 +143,21 @@ export class _CfgFeatureInternal {
152
143
  options = this.options; // This will generate all children
153
144
  }
154
145
  let change = false;
155
- const constraintMap = apiOptionConstraintMap !== null && apiOptionConstraintMap !== void 0 ? apiOptionConstraintMap : {};
156
- // The first value that belongs to this features options is used as the key to look up constrained options
157
- const featureConstrainedOptions = (_b = (_a = options.map((o) => constraintMap[o.code]).find((o) => !!o)) === null || _a === void 0 ? void 0 : _a.constrOptions) !== null && _b !== void 0 ? _b : [];
146
+ const constraintMap = apiOptionConstraintMap ?? {};
147
+ const { constrOptions = [], constrBooleans = [] } = Object.values(constraintMap).find(({ feature }) => feature === this.code) ?? {};
148
+ const optionalConstrainedOptions = constrBooleans.map(({ code }) => code);
149
+ const unresolvedConstrainedOptions = constrBooleans
150
+ .filter(({ value }) => value === undefined)
151
+ .map(({ code }) => code);
152
+ const featureConstrainedOptions = constrOptions.concat(optionalConstrainedOptions);
158
153
  for (let i = 0; i < options.length; i++) {
159
154
  const option = options[i];
160
155
  const apiOptionSelection = apiOptionSelectionMap[option.code];
161
156
  const isConstrained = featureConstrainedOptions.indexOf(option.code) >= 0;
157
+ const isUnresolvable = unresolvedConstrainedOptions.indexOf(option.code) >= 0;
162
158
  const selectedIndex = this._selectedOptions.findIndex(getOptionFilter(option._internal));
163
159
  const constrainedIndex = this._constrainedOptions.findIndex(getOptionFilter(option._internal));
160
+ const unresolvedIndex = this._unresolvableOptions.findIndex(getOptionFilter(option._internal));
164
161
  const isOn = isGroup || apiOptionSelection;
165
162
  if (isConstrained) {
166
163
  if (constrainedIndex === -1) {
@@ -175,6 +172,19 @@ export class _CfgFeatureInternal {
175
172
  change = true;
176
173
  }
177
174
  }
175
+ if (isUnresolvable) {
176
+ if (unresolvedIndex === -1) {
177
+ doFreshRefOptionAtIndex(options, i, committed, (freshRef) => this._unresolvableOptions.push(freshRef));
178
+ change = true;
179
+ }
180
+ }
181
+ else {
182
+ if (unresolvedIndex !== -1) {
183
+ this._unresolvableOptions.splice(unresolvedIndex, 1);
184
+ doFreshRefOptionAtIndex(options, i, committed);
185
+ change = true;
186
+ }
187
+ }
178
188
  if (isOn) {
179
189
  if (isSelectOne) {
180
190
  if (this.isUseNumericValue) {
@@ -183,7 +193,7 @@ export class _CfgFeatureInternal {
183
193
  throw new Error("No numeric value for numeric feature");
184
194
  }
185
195
  const { value, unit } = numericValue;
186
- if (yield option.setNumericValue(unit === undefined
196
+ if (await option.setNumericValue(unit === undefined
187
197
  ? value
188
198
  : convertLength(value, toLengthUnit(unit), this.unit), false)) {
189
199
  change = true;
@@ -209,14 +219,14 @@ export class _CfgFeatureInternal {
209
219
  change = true;
210
220
  }
211
221
  }
212
- if (yield option._internal.setApiSelection(apiOptionSelection, constraintMap[option.code])) {
222
+ if (await option._internal.setApiSelection(apiOptionSelection, constraintMap[option.code])) {
213
223
  change = true;
214
224
  }
215
225
  }
216
226
  if (this.ancestorsSelected) {
217
227
  const selectionCount = this._selectedOptions.length;
218
228
  if (isSelectOne && selectionCount !== 1) {
219
- const wrongCountWarning = `A select-one Feature (i.e. neither optional nor multiple) should have exactly one Option selected. Feature key: "${this.key}". Actual: ${selectionCount}`;
229
+ const wrongCountWarning = `A select-one Feature (i.e. neither optional nor multiple) should have exactly one Option selected. Feature code: "${this.code}". Actual: ${selectionCount}`;
220
230
  if (this.rootProduct.settings.strictSelectOneSelectionCount) {
221
231
  throw new Error(wrongCountWarning);
222
232
  }
@@ -230,7 +240,7 @@ export class _CfgFeatureInternal {
230
240
  this._freshRefAllOptions(committed);
231
241
  }
232
242
  if (selectionType === SelectionType.SelectOne) {
233
- yield this.pushStretch();
243
+ await this.pushStretch();
234
244
  }
235
245
  // setApiSelection works its way top down and handles notifications on
236
246
  // each level by looking at change returned from its children. That way
@@ -238,10 +248,10 @@ export class _CfgFeatureInternal {
238
248
  // if multiple descendants are affected by the setApiSelection. Therefore
239
249
  // we use OneLevel to make this feature notify and the parent update its
240
250
  // reference.
241
- yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, committed);
251
+ await this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, committed);
242
252
  }
243
253
  return change;
244
- });
254
+ };
245
255
  this.addForApiConstrained = (next) => {
246
256
  const constrOptions = this._constrainedOptions;
247
257
  for (const so of this._selectedOptions) {
@@ -249,16 +259,16 @@ export class _CfgFeatureInternal {
249
259
  }
250
260
  };
251
261
  /** Pushes to refresh stretch. Does not cause validation. */
252
- this.pushStretch = () => __awaiter(this, void 0, void 0, function* () {
262
+ this.pushStretch = async () => {
253
263
  if (this.selectionType !== SelectionType.SelectOne) {
254
264
  throw new Error("Can only push stretch for SelectOne");
255
265
  }
256
266
  const value = this.numericValue;
257
- return (yield Promise.all((this.measureParamCodes || []).map((measureParamCode) => this.parentConfiguration.setStretchReferenceLength(measureParamCode, value, this.unit)))).some((change) => change);
258
- });
267
+ return (await Promise.all((this.measureParamCodes || []).map((measureParamCode) => this.parentConfiguration.setStretchReferenceLength(measureParamCode, value, this.unit)))).some((change) => change);
268
+ };
259
269
  this.structureCompare = (other, strictOrder = true, descriptionMatch = false) => this.keyMatch(other, descriptionMatch) &&
260
270
  compareArrays(this.options, other.options, (l, r) => l._internal.structureCompare(r._internal, strictOrder, descriptionMatch), strictOrder);
261
- this.tryMatchSelection = (other, descriptionMatch = false) => __awaiter(this, void 0, void 0, function* () {
271
+ this.tryMatchSelection = async (other, descriptionMatch = false) => {
262
272
  const { selectionType, isUseNumericValue } = this;
263
273
  if (selectionType !== other.selectionType) {
264
274
  // Will not try if the selection type is different
@@ -276,7 +286,7 @@ export class _CfgFeatureInternal {
276
286
  throw new Error("Numeric feature without numeric value, this should never happen");
277
287
  }
278
288
  else {
279
- if (yield this.setNumericValue(otherNumericValue)) {
289
+ if (await this.setNumericValue(otherNumericValue)) {
280
290
  change = true;
281
291
  }
282
292
  }
@@ -284,7 +294,7 @@ export class _CfgFeatureInternal {
284
294
  else {
285
295
  const thisOptions = this.options;
286
296
  const otherOptions = other.options;
287
- change = (yield Promise.all(otherOptions.map((otherO) => (() => __awaiter(this, void 0, void 0, function* () {
297
+ change = (await Promise.all(otherOptions.map((otherO) => (async () => {
288
298
  const otherOSelected = otherO.selected;
289
299
  if (selectionType === SelectionType.SelectOne && !otherOSelected) {
290
300
  return false;
@@ -310,14 +320,14 @@ export class _CfgFeatureInternal {
310
320
  // so we do not need to bubble the notification.
311
321
  // Instead we use the change variable to know
312
322
  // when to notify for this feature.
313
- change = yield toTryChangeOption._internal.parent.selectOption(toTryChangeOption._internal, otherOSelected, ProductConfigurationBubbleMode.Stop);
323
+ change = await toTryChangeOption._internal.parent.selectOption(toTryChangeOption._internal, otherOSelected, ProductConfigurationBubbleMode.Stop);
314
324
  }
315
325
  if (otherOSelected &&
316
- (yield toTryChangeOption._internal.tryMatchSelection(otherO, descriptionMatch))) {
326
+ (await toTryChangeOption._internal.tryMatchSelection(otherO, descriptionMatch))) {
317
327
  change = true;
318
328
  }
319
329
  return change;
320
- }))()))).some((b) => b);
330
+ })()))).some((b) => b);
321
331
  }
322
332
  if (change) {
323
333
  // tryMatchSelection works its way top down and handles notifications on
@@ -326,23 +336,23 @@ export class _CfgFeatureInternal {
326
336
  // if multiple descendants are affected by the tryMatchSelection. Therefore
327
337
  // we use OneLevel to make this feature notify and the parent update its
328
338
  // reference.
329
- yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, true);
339
+ await this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, true);
330
340
  }
331
341
  return change;
332
- });
342
+ };
333
343
  /**
334
344
  * Normally this is used through methods on CfgFeature and CfgOption. Use this internal version
335
345
  * if you need to control the bubbleMode.
336
346
  *
337
347
  * Using a validate bubbleMode will cause validation calls to the server.
338
348
  */
339
- this.selectOption = (optionInternal, on, bubbleMode) => __awaiter(this, void 0, void 0, function* () {
349
+ this.selectOption = async (optionInternal, on, bubbleMode) => {
340
350
  if (bubbleMode ===
341
351
  ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups) {
342
352
  const product = this.rootProduct;
343
353
  const syncGroupHandler = product.syncGroupHandler;
344
354
  assertDefined(syncGroupHandler, `Sync group handler is required for bubble mode ${ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups}`);
345
- return yield syncGroupHandler.selectOption(product, optionInternal, on, wrapWithCache(product._productLoaderRaw));
355
+ return await syncGroupHandler.selectOption(product, optionInternal, on, wrapWithCache(product._productLoaderRaw));
346
356
  }
347
357
  if (!on) {
348
358
  if (this.selectionType === SelectionType.Group) {
@@ -378,7 +388,7 @@ export class _CfgFeatureInternal {
378
388
  doFreshRefOption(options, optionInternal, committed, (freshRef) => selectedOptions.push(freshRef));
379
389
  }
380
390
  if (this.selectionType === SelectionType.SelectOne) {
381
- yield this.pushStretch();
391
+ await this.pushStretch();
382
392
  }
383
393
  }
384
394
  else {
@@ -409,12 +419,16 @@ export class _CfgFeatureInternal {
409
419
  nextLevelBubbleMode = ProductConfigurationBubbleMode.ToRoot;
410
420
  }
411
421
  }
412
- yield this._notifyAllOfChange(nextLevelBubbleMode, committed);
422
+ await this._notifyAllOfChange(nextLevelBubbleMode, committed);
413
423
  return isActualChange;
414
- });
424
+ };
415
425
  this.isSelected = (option) => this.selectionType === SelectionType.Group ||
416
426
  this._selectedOptions.some(getOptionFilter(option));
417
427
  this.isDisabled = (option) => this._constrainedOptions.some(getOptionFilter(option));
428
+ /**
429
+ * An option is unresolvable when it is constrained from any possible value.
430
+ */
431
+ this.isUnresolvable = (option) => this._unresolvableOptions.some(getOptionFilter(option));
418
432
  this.keyMatch = (other, descriptionMatch = false) => descriptionMatch
419
433
  ? this.description.toLowerCase() === other.description.toLowerCase()
420
434
  : this.code === other.code;
@@ -448,8 +462,7 @@ export class _CfgFeatureInternal {
448
462
  this._key = k;
449
463
  }
450
464
  get notes() {
451
- var _a;
452
- return this.parentProduct.getNotes((_a = this.rawFeature.noteRefs) !== null && _a !== void 0 ? _a : []);
465
+ return this.parentProduct.getNotes(this.rawFeature.noteRefs ?? []);
453
466
  }
454
467
  get isUseNumericValue() {
455
468
  return this.rawFeature.numericOrder;
@@ -502,8 +515,7 @@ export class _CfgFeatureInternal {
502
515
  * of this Feature. Hence only the code property is used.
503
516
  */
504
517
  get measureParamCodes() {
505
- var _a;
506
- return (_a = this.rawFeature.measureParams) === null || _a === void 0 ? void 0 : _a.map((measureParam) => measureParam.code);
518
+ return this.rawFeature.measureParams?.map((measureParam) => measureParam.code);
507
519
  }
508
520
  get unit() {
509
521
  const unit = this.rawFeature.unit;
@@ -597,15 +609,13 @@ export class CfgFeature {
597
609
  * This will find the first option allowing the value, set the value on it and select it.
598
610
  * This is an implicit option-select.
599
611
  */
600
- this.setNumericValue = (val) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.setNumericValue(val); });
612
+ this.setNumericValue = async (val) => await this._internal.setNumericValue(val);
601
613
  /**
602
614
  * Selects the passed Option.
603
615
  * Only Options belonging to Features that are "select many" can be deselected.
604
616
  * Calling this will cause a validation call to the server.
605
617
  */
606
- this.selectOption = (option, on) => __awaiter(this, void 0, void 0, function* () {
607
- return yield this._internal.selectOption(option._internal, on, ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups);
608
- });
618
+ this.selectOption = async (option, on) => await this._internal.selectOption(option._internal, on, ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups);
609
619
  this.isSelected = (option) => this._internal.isSelected(option._internal);
610
620
  this.listenForChange = (l) => this._internal.changeObservable.listen(l);
611
621
  this.stopListenForChange = (l) => this._internal.changeObservable.stopListen(l);
@@ -84,6 +84,10 @@ export declare class _CfgOptionInternal {
84
84
  get description(): string;
85
85
  get selected(): boolean;
86
86
  get disabled(): boolean;
87
+ /**
88
+ * An option is unresolvable when it is constrained from any possible value.
89
+ */
90
+ get unresolvable(): boolean;
87
91
  get selectedChangeInProgress(): boolean;
88
92
  get ancestorsSelected(): boolean;
89
93
  get mtrlApplications(): CfgMtrlApplication[];
@@ -91,6 +95,24 @@ export declare class _CfgOptionInternal {
91
95
  private _calculateUpcharge;
92
96
  get upcharge(): number;
93
97
  get priceChangeAtSelectChange(): number;
98
+ /**
99
+ * Get the child features that are contained within this option.
100
+ *
101
+ * Safe to call outside of the sync process, but may not contain any
102
+ * children until the sync process is complete.
103
+ */
104
+ getFeaturesOutsideSync(): CfgFeature[];
105
+ /**
106
+ * Get the child features that are contained within this option.
107
+ *
108
+ * ONLY ACCESS THIS PROPERTY UNDER THESE CONDITIONS:
109
+ * 1. The product is undergoing the sync group sync process.
110
+ * 2. AND you are operating on the new "target" product.
111
+ *
112
+ * Explanation: This method will generate all children if they have not been
113
+ * generated yet, which breaks sync group syncing, due to the presence of
114
+ * these children being used to determine if the sync should happen at all.
115
+ */
94
116
  get features(): CfgFeature[];
95
117
  /** Called by child to tell its parent that it has changed. */
96
118
  _childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
@@ -135,6 +157,10 @@ export declare class CfgOption {
135
157
  get description(): string;
136
158
  get selected(): boolean;
137
159
  get disabled(): boolean;
160
+ /**
161
+ * An option is unresolvable when it is constrained from any possible value.
162
+ */
163
+ get unresolvable(): boolean;
138
164
  /**
139
165
  * Selection state is in progress to be changed. This can be used in GUI
140
166
  * to display the state as transitioning, or as already changed.
@@ -154,6 +180,24 @@ export declare class CfgOption {
154
180
  get thumbnail(): string | undefined;
155
181
  get upcharge(): number;
156
182
  get priceChangeAtSelectChange(): number;
183
+ /**
184
+ * Get the child features that are contained within this option.
185
+ *
186
+ * Safe to call outside of the sync process, but may not contain any
187
+ * children until the sync process is complete.
188
+ */
189
+ getFeaturesOutsideSync(): CfgFeature[];
190
+ /**
191
+ * Get the child features that are contained within this option.
192
+ *
193
+ * ONLY ACCESS THIS PROPERTY UNDER THESE CONDITIONS:
194
+ * 1. The product is undergoing the sync group sync process.
195
+ * 2. AND you are operating on the new "target" product.
196
+ *
197
+ * Explanation: This method will generate all children if they have not been
198
+ * generated yet, which breaks sync group syncing, due to the presence of
199
+ * these children being used to determine if the sync should happen at all.
200
+ */
157
201
  get features(): CfgFeature[];
158
202
  listenForChange: (l: SingleArgCallback<OptionChangeNotification>) => void;
159
203
  stopListenForChange: (l: SingleArgCallback<OptionChangeNotification>) => void;