@configura/web-api 3.0.0-alpha.1 → 3.0.0-alpha.3

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 (31) 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.d.ts +22 -3
  5. package/dist/CfgProduct.js +172 -162
  6. package/dist/io/CfgIOManager.js +2 -11
  7. package/dist/io/CfgIOProdConfConnector.js +14 -25
  8. package/dist/io/CfgObservableStateManager.js +1 -1
  9. package/dist/productConfiguration/CfgFeature.d.ts +5 -0
  10. package/dist/productConfiguration/CfgFeature.js +68 -53
  11. package/dist/productConfiguration/CfgOption.d.ts +8 -0
  12. package/dist/productConfiguration/CfgOption.js +68 -73
  13. package/dist/productConfiguration/CfgProductConfiguration.js +22 -34
  14. package/dist/productConfiguration/productParamsGenerator.js +43 -57
  15. package/dist/productLoader.js +2 -13
  16. package/dist/syncGroups/SyncGroupsHandler.js +60 -83
  17. package/dist/syncGroups/SyncGroupsPathHelper.js +5 -5
  18. package/dist/syncGroups/SyncGroupsState.js +4 -5
  19. package/dist/syncGroups/SyncGroupsTransaction.d.ts +19 -1
  20. package/dist/syncGroups/SyncGroupsTransaction.js +352 -303
  21. package/dist/tasks/TaskHandler.js +53 -64
  22. package/dist/tests/testData/dummyProductForTest.js +4 -1
  23. package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +18 -21
  24. package/dist/tests/testData/testDataCachedGetProduct.js +20 -20
  25. package/dist/tests/testData/testDataCachedPostValidate.js +6 -15
  26. package/dist/tests/testData/testDataProductAggregatedPrice.js +21 -21
  27. package/dist/tests/testData/testDataUpcharge.js +31 -22
  28. package/dist/utilitiesCatalogueData.js +21 -9
  29. package/dist/utilitiesCataloguePermission.js +5 -2
  30. package/dist/utilitiesConfiguration.js +21 -23
  31. 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 { Observable, assertDefined, compareArrays, convertLength, count, someMatch, toLengthUnit, } from "@configura/web-utilities";
1
+ import { assertDefined, compareArrays, convertLength, count, Observable, 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,12 +193,17 @@ 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;
190
200
  }
191
201
  }
202
+ // Triggers `pushStretch` when it is a stretch feature
203
+ // Fixes https://configura.atlassian.net/browse/WEB-16599
204
+ if (this.measureParamCodes?.length) {
205
+ change = true;
206
+ }
192
207
  }
193
208
  if (selectedIndex === -1) {
194
209
  if (isAllOptionsAffectedByAnySelection) {
@@ -209,7 +224,7 @@ export class _CfgFeatureInternal {
209
224
  change = true;
210
225
  }
211
226
  }
212
- if (yield option._internal.setApiSelection(apiOptionSelection, constraintMap[option.code])) {
227
+ if (await option._internal.setApiSelection(apiOptionSelection, constraintMap[option.code])) {
213
228
  change = true;
214
229
  }
215
230
  }
@@ -230,7 +245,7 @@ export class _CfgFeatureInternal {
230
245
  this._freshRefAllOptions(committed);
231
246
  }
232
247
  if (selectionType === SelectionType.SelectOne) {
233
- yield this.pushStretch();
248
+ await this.pushStretch();
234
249
  }
235
250
  // setApiSelection works its way top down and handles notifications on
236
251
  // each level by looking at change returned from its children. That way
@@ -238,10 +253,10 @@ export class _CfgFeatureInternal {
238
253
  // if multiple descendants are affected by the setApiSelection. Therefore
239
254
  // we use OneLevel to make this feature notify and the parent update its
240
255
  // reference.
241
- yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, committed);
256
+ await this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, committed);
242
257
  }
243
258
  return change;
244
- });
259
+ };
245
260
  this.addForApiConstrained = (next) => {
246
261
  const constrOptions = this._constrainedOptions;
247
262
  for (const so of this._selectedOptions) {
@@ -249,16 +264,16 @@ export class _CfgFeatureInternal {
249
264
  }
250
265
  };
251
266
  /** Pushes to refresh stretch. Does not cause validation. */
252
- this.pushStretch = () => __awaiter(this, void 0, void 0, function* () {
267
+ this.pushStretch = async () => {
253
268
  if (this.selectionType !== SelectionType.SelectOne) {
254
269
  throw new Error("Can only push stretch for SelectOne");
255
270
  }
256
271
  const value = this.numericValue;
257
- return (yield Promise.all((this.measureParamCodes || []).map((measureParamCode) => this.parentConfiguration.setStretchReferenceLength(measureParamCode, value, this.unit)))).some((change) => change);
258
- });
272
+ return (await Promise.all((this.measureParamCodes || []).map((measureParamCode) => this.parentConfiguration.setStretchReferenceLength(measureParamCode, value, this.unit)))).some((change) => change);
273
+ };
259
274
  this.structureCompare = (other, strictOrder = true, descriptionMatch = false) => this.keyMatch(other, descriptionMatch) &&
260
275
  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* () {
276
+ this.tryMatchSelection = async (other, descriptionMatch = false) => {
262
277
  const { selectionType, isUseNumericValue } = this;
263
278
  if (selectionType !== other.selectionType) {
264
279
  // Will not try if the selection type is different
@@ -276,7 +291,7 @@ export class _CfgFeatureInternal {
276
291
  throw new Error("Numeric feature without numeric value, this should never happen");
277
292
  }
278
293
  else {
279
- if (yield this.setNumericValue(otherNumericValue)) {
294
+ if (await this.setNumericValue(otherNumericValue)) {
280
295
  change = true;
281
296
  }
282
297
  }
@@ -284,7 +299,7 @@ export class _CfgFeatureInternal {
284
299
  else {
285
300
  const thisOptions = this.options;
286
301
  const otherOptions = other.options;
287
- change = (yield Promise.all(otherOptions.map((otherO) => (() => __awaiter(this, void 0, void 0, function* () {
302
+ change = (await Promise.all(otherOptions.map((otherO) => (async () => {
288
303
  const otherOSelected = otherO.selected;
289
304
  if (selectionType === SelectionType.SelectOne && !otherOSelected) {
290
305
  return false;
@@ -310,14 +325,14 @@ export class _CfgFeatureInternal {
310
325
  // so we do not need to bubble the notification.
311
326
  // Instead we use the change variable to know
312
327
  // when to notify for this feature.
313
- change = yield toTryChangeOption._internal.parent.selectOption(toTryChangeOption._internal, otherOSelected, ProductConfigurationBubbleMode.Stop);
328
+ change = await toTryChangeOption._internal.parent.selectOption(toTryChangeOption._internal, otherOSelected, ProductConfigurationBubbleMode.Stop);
314
329
  }
315
330
  if (otherOSelected &&
316
- (yield toTryChangeOption._internal.tryMatchSelection(otherO, descriptionMatch))) {
331
+ (await toTryChangeOption._internal.tryMatchSelection(otherO, descriptionMatch))) {
317
332
  change = true;
318
333
  }
319
334
  return change;
320
- }))()))).some((b) => b);
335
+ })()))).some((b) => b);
321
336
  }
322
337
  if (change) {
323
338
  // tryMatchSelection works its way top down and handles notifications on
@@ -326,23 +341,23 @@ export class _CfgFeatureInternal {
326
341
  // if multiple descendants are affected by the tryMatchSelection. Therefore
327
342
  // we use OneLevel to make this feature notify and the parent update its
328
343
  // reference.
329
- yield this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, true);
344
+ await this._notifyAllOfChange(ProductConfigurationBubbleMode.OneLevel, true);
330
345
  }
331
346
  return change;
332
- });
347
+ };
333
348
  /**
334
349
  * Normally this is used through methods on CfgFeature and CfgOption. Use this internal version
335
350
  * if you need to control the bubbleMode.
336
351
  *
337
352
  * Using a validate bubbleMode will cause validation calls to the server.
338
353
  */
339
- this.selectOption = (optionInternal, on, bubbleMode) => __awaiter(this, void 0, void 0, function* () {
354
+ this.selectOption = async (optionInternal, on, bubbleMode) => {
340
355
  if (bubbleMode ===
341
356
  ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups) {
342
357
  const product = this.rootProduct;
343
358
  const syncGroupHandler = product.syncGroupHandler;
344
359
  assertDefined(syncGroupHandler, `Sync group handler is required for bubble mode ${ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups}`);
345
- return yield syncGroupHandler.selectOption(product, optionInternal, on, wrapWithCache(product._productLoaderRaw));
360
+ return await syncGroupHandler.selectOption(product, optionInternal, on, wrapWithCache(product._productLoaderRaw));
346
361
  }
347
362
  if (!on) {
348
363
  if (this.selectionType === SelectionType.Group) {
@@ -378,7 +393,7 @@ export class _CfgFeatureInternal {
378
393
  doFreshRefOption(options, optionInternal, committed, (freshRef) => selectedOptions.push(freshRef));
379
394
  }
380
395
  if (this.selectionType === SelectionType.SelectOne) {
381
- yield this.pushStretch();
396
+ await this.pushStretch();
382
397
  }
383
398
  }
384
399
  else {
@@ -409,12 +424,16 @@ export class _CfgFeatureInternal {
409
424
  nextLevelBubbleMode = ProductConfigurationBubbleMode.ToRoot;
410
425
  }
411
426
  }
412
- yield this._notifyAllOfChange(nextLevelBubbleMode, committed);
427
+ await this._notifyAllOfChange(nextLevelBubbleMode, committed);
413
428
  return isActualChange;
414
- });
429
+ };
415
430
  this.isSelected = (option) => this.selectionType === SelectionType.Group ||
416
431
  this._selectedOptions.some(getOptionFilter(option));
417
432
  this.isDisabled = (option) => this._constrainedOptions.some(getOptionFilter(option));
433
+ /**
434
+ * An option is unresolvable when it is constrained from any possible value.
435
+ */
436
+ this.isUnresolvable = (option) => this._unresolvableOptions.some(getOptionFilter(option));
418
437
  this.keyMatch = (other, descriptionMatch = false) => descriptionMatch
419
438
  ? this.description.toLowerCase() === other.description.toLowerCase()
420
439
  : this.code === other.code;
@@ -448,8 +467,7 @@ export class _CfgFeatureInternal {
448
467
  this._key = k;
449
468
  }
450
469
  get notes() {
451
- var _a;
452
- return this.parentProduct.getNotes((_a = this.rawFeature.noteRefs) !== null && _a !== void 0 ? _a : []);
470
+ return this.parentProduct.getNotes(this.rawFeature.noteRefs ?? []);
453
471
  }
454
472
  get isUseNumericValue() {
455
473
  return this.rawFeature.numericOrder;
@@ -502,8 +520,7 @@ export class _CfgFeatureInternal {
502
520
  * of this Feature. Hence only the code property is used.
503
521
  */
504
522
  get measureParamCodes() {
505
- var _a;
506
- return (_a = this.rawFeature.measureParams) === null || _a === void 0 ? void 0 : _a.map((measureParam) => measureParam.code);
523
+ return this.rawFeature.measureParams?.map((measureParam) => measureParam.code);
507
524
  }
508
525
  get unit() {
509
526
  const unit = this.rawFeature.unit;
@@ -597,15 +614,13 @@ export class CfgFeature {
597
614
  * This will find the first option allowing the value, set the value on it and select it.
598
615
  * This is an implicit option-select.
599
616
  */
600
- this.setNumericValue = (val) => __awaiter(this, void 0, void 0, function* () { return yield this._internal.setNumericValue(val); });
617
+ this.setNumericValue = async (val) => await this._internal.setNumericValue(val);
601
618
  /**
602
619
  * Selects the passed Option.
603
620
  * Only Options belonging to Features that are "select many" can be deselected.
604
621
  * Calling this will cause a validation call to the server.
605
622
  */
606
- this.selectOption = (option, on) => __awaiter(this, void 0, void 0, function* () {
607
- return yield this._internal.selectOption(option._internal, on, ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups);
608
- });
623
+ this.selectOption = async (option, on) => await this._internal.selectOption(option._internal, on, ProductConfigurationBubbleMode.ValidateAndBubbleSelectedAndApplySyncGroups);
609
624
  this.isSelected = (option) => this._internal.isSelected(option._internal);
610
625
  this.listenForChange = (l) => this._internal.changeObservable.listen(l);
611
626
  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[];
@@ -153,6 +157,10 @@ export declare class CfgOption {
153
157
  get description(): string;
154
158
  get selected(): boolean;
155
159
  get disabled(): boolean;
160
+ /**
161
+ * An option is unresolvable when it is constrained from any possible value.
162
+ */
163
+ get unresolvable(): boolean;
156
164
  /**
157
165
  * Selection state is in progress to be changed. This can be used in GUI
158
166
  * to display the state as transitioning, or as already changed.