@configura/web-api 1.3.0-alpha.1 → 1.3.0-alpha.5

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 (32) hide show
  1. package/dist/CatalogueAPI.d.ts +56 -2
  2. package/dist/CatalogueAPI.js +1 -1
  3. package/dist/CfgMeasure.d.ts +33 -0
  4. package/dist/CfgMeasure.js +30 -0
  5. package/dist/CfgProduct.d.ts +106 -5
  6. package/dist/CfgProduct.js +117 -71
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +1 -0
  9. package/dist/material/CfgMaterialMapping.js +11 -6
  10. package/dist/material/CfgMtrlApplication.js +4 -4
  11. package/dist/productConfiguration/CfgFeature.d.ts +30 -4
  12. package/dist/productConfiguration/CfgFeature.js +162 -52
  13. package/dist/productConfiguration/CfgOption.d.ts +21 -5
  14. package/dist/productConfiguration/CfgOption.js +125 -24
  15. package/dist/productConfiguration/CfgProductConfiguration.d.ts +74 -4
  16. package/dist/productConfiguration/CfgProductConfiguration.js +158 -49
  17. package/dist/productConfiguration/utilitiesProductConfiguration.d.ts +9 -1
  18. package/dist/productConfiguration/utilitiesProductConfiguration.js +32 -13
  19. package/dist/productLoader.d.ts +22 -0
  20. package/dist/productLoader.js +22 -14
  21. package/dist/tests/testData/dummyProductForTest.js +1 -0
  22. package/dist/tests/testData/testDataAdditionalProductInAdditionalProductInProductForTest.js +13 -0
  23. package/dist/tests/testData/testDataCachedGetProduct.js +6 -0
  24. package/dist/tests/testData/testDataCachedPostValidate.js +6 -0
  25. package/dist/tests/testData/testDataNoAdditionalProductNoPropagateForTest.js +2 -0
  26. package/dist/tests/testData/testDataProductAggregatedPrice.js +6 -1
  27. package/dist/tests/testData/testDataUpcharge.js +4 -0
  28. package/dist/utilitiesCatalogueData.d.ts +5 -1
  29. package/dist/utilitiesCatalogueData.js +9 -1
  30. package/dist/utilitiesNumericValues.d.ts +25 -0
  31. package/dist/utilitiesNumericValues.js +109 -0
  32. package/package.json +3 -3
@@ -12,10 +12,12 @@ import { Collector } from "./collectorForTest";
12
12
  import { dummyCatId } from "./dummyProductForTest";
13
13
  const A = () => ({
14
14
  uuid: "A",
15
+ unit: "m",
15
16
  features: [
16
17
  {
17
18
  code: "featureA",
18
19
  description: "",
20
+ numericOrder: false,
19
21
  options: [
20
22
  {
21
23
  code: "optionA",
@@ -39,6 +41,7 @@ const A = () => ({
39
41
  {
40
42
  code: "featureX",
41
43
  description: "",
44
+ numericOrder: false,
42
45
  options: [
43
46
  {
44
47
  code: "optionA",
@@ -57,6 +60,7 @@ const A = () => ({
57
60
  {
58
61
  code: "featureNotUsed",
59
62
  description: "",
63
+ numericOrder: false,
60
64
  options: [
61
65
  {
62
66
  code: "optionA",
@@ -71,6 +75,7 @@ const A = () => ({
71
75
  {
72
76
  code: "featureOptionCSelectedAtStart",
73
77
  description: "",
78
+ numericOrder: false,
74
79
  options: [
75
80
  {
76
81
  code: "optionA",
@@ -89,6 +94,7 @@ const A = () => ({
89
94
  {
90
95
  code: "featureSelectMany",
91
96
  description: "",
97
+ numericOrder: false,
92
98
  options: [
93
99
  {
94
100
  code: "optionA",
@@ -164,10 +170,12 @@ const A = () => ({
164
170
  });
165
171
  const B = () => ({
166
172
  uuid: "B",
173
+ unit: "m",
167
174
  features: [
168
175
  {
169
176
  code: "featureI",
170
177
  description: "",
178
+ numericOrder: false,
171
179
  options: [
172
180
  { code: "optionI0", description: "" },
173
181
  { code: "optionI1", description: "", featureRefs: [{ code: "featureII" }] },
@@ -176,6 +184,7 @@ const B = () => ({
176
184
  {
177
185
  code: "featureII",
178
186
  description: "",
187
+ numericOrder: false,
179
188
  options: [
180
189
  { code: "optionII0", description: "" },
181
190
  { code: "optionII1", description: "", featureRefs: [{ code: "featureIII" }] },
@@ -184,6 +193,7 @@ const B = () => ({
184
193
  {
185
194
  code: "featureIII",
186
195
  description: "",
196
+ numericOrder: false,
187
197
  options: [
188
198
  { code: "optionIII0", description: "" },
189
199
  { code: "optionIII1", description: "" },
@@ -219,10 +229,12 @@ const B = () => ({
219
229
  });
220
230
  const C = () => ({
221
231
  uuid: "C",
232
+ unit: "m",
222
233
  features: [
223
234
  {
224
235
  code: "featureC",
225
236
  description: "",
237
+ numericOrder: false,
226
238
  options: [
227
239
  {
228
240
  code: "optionA",
@@ -267,6 +279,7 @@ const C = () => ({
267
279
  });
268
280
  const D = () => ({
269
281
  uuid: "D",
282
+ unit: "m",
270
283
  features: [],
271
284
  productData: {
272
285
  sku: "D",
@@ -13,10 +13,12 @@ import { dummyCatId } from "./dummyProductForTest.js";
13
13
  let prodKeyArray = [];
14
14
  const A = () => ({
15
15
  uuid: "A",
16
+ unit: "m",
16
17
  features: [
17
18
  {
18
19
  code: "featureA",
19
20
  description: "",
21
+ numericOrder: false,
20
22
  options: [
21
23
  {
22
24
  code: "optionA",
@@ -70,6 +72,7 @@ const A = () => ({
70
72
  });
71
73
  const B = () => ({
72
74
  uuid: "B",
75
+ unit: "m",
73
76
  features: [],
74
77
  productData: {
75
78
  sku: "B",
@@ -87,6 +90,7 @@ const B = () => ({
87
90
  });
88
91
  const C = () => ({
89
92
  uuid: "C",
93
+ unit: "m",
90
94
  features: [],
91
95
  productData: {
92
96
  sku: "C",
@@ -103,6 +107,7 @@ const C = () => ({
103
107
  });
104
108
  const D = () => ({
105
109
  uuid: "D",
110
+ unit: "m",
106
111
  features: [],
107
112
  productData: {
108
113
  sku: "D",
@@ -119,6 +124,7 @@ const D = () => ({
119
124
  });
120
125
  const E = () => ({
121
126
  uuid: "E",
127
+ unit: "m",
122
128
  features: [],
123
129
  productData: {
124
130
  sku: "E",
@@ -11,10 +11,12 @@ import { CfgProduct } from "../../CfgProduct.js";
11
11
  import { dummyCatId } from "./dummyProductForTest.js";
12
12
  const Table = () => ({
13
13
  uuid: "Table",
14
+ unit: "m",
14
15
  features: [
15
16
  {
16
17
  code: "Leg",
17
18
  description: "",
19
+ numericOrder: false,
18
20
  options: [
19
21
  {
20
22
  code: "LegA",
@@ -67,10 +69,12 @@ const Table = () => ({
67
69
  });
68
70
  const LegA = () => ({
69
71
  uuid: "LegA",
72
+ unit: "m",
70
73
  features: [
71
74
  {
72
75
  code: "Color",
73
76
  description: "",
77
+ numericOrder: false,
74
78
  options: [
75
79
  {
76
80
  code: "Red",
@@ -115,10 +119,12 @@ const LegA = () => ({
115
119
  });
116
120
  const LegWheel = () => ({
117
121
  uuid: "LegWheel",
122
+ unit: "m",
118
123
  features: [
119
124
  {
120
125
  code: "Color",
121
126
  description: "",
127
+ numericOrder: false,
122
128
  options: [
123
129
  {
124
130
  code: "Red",
@@ -4,6 +4,7 @@ export default {
4
4
  {
5
5
  code: "SIDECHAIR-SHELL-OP",
6
6
  description: "Shell Color Options",
7
+ numericOrder: false,
7
8
  mtrlApplications: [{ areas: ["EA-SHELL-PL"] }],
8
9
  options: [
9
10
  {
@@ -1114,4 +1115,5 @@ export default {
1114
1115
  },
1115
1116
  },
1116
1117
  uuid: "436293a0-e94c-4091-a138-bc900521ff48",
1118
+ unit: "m",
1117
1119
  };
@@ -11,11 +11,12 @@ import { CfgProduct } from "../../CfgProduct";
11
11
  import { dummyCatId } from "./dummyProductForTest";
12
12
  const A = () => ({
13
13
  uuid: "A",
14
+ unit: "m",
14
15
  features: [
15
16
  {
16
17
  code: "featureA",
17
18
  description: "",
18
- options: [
19
+ numericOrder: false, options: [
19
20
  {
20
21
  code: "optionA",
21
22
  description: "",
@@ -68,6 +69,7 @@ const A = () => ({
68
69
  });
69
70
  const B = () => ({
70
71
  uuid: "B",
72
+ unit: "m",
71
73
  features: [],
72
74
  productData: {
73
75
  sku: "B",
@@ -85,6 +87,7 @@ const B = () => ({
85
87
  });
86
88
  const C = () => ({
87
89
  uuid: "C",
90
+ unit: "m",
88
91
  features: [],
89
92
  productData: {
90
93
  sku: "C",
@@ -101,6 +104,7 @@ const C = () => ({
101
104
  });
102
105
  const D = () => ({
103
106
  uuid: "D",
107
+ unit: "m",
104
108
  features: [],
105
109
  productData: {
106
110
  sku: "D",
@@ -117,6 +121,7 @@ const D = () => ({
117
121
  });
118
122
  const E = () => ({
119
123
  uuid: "E",
124
+ unit: "m",
120
125
  features: [],
121
126
  productData: {
122
127
  sku: "E",
@@ -12,10 +12,12 @@ import { Collector } from "./collectorForTest.js";
12
12
  import { dummyCatId } from "./dummyProductForTest.js";
13
13
  const Prd = () => ({
14
14
  uuid: "Prd",
15
+ unit: "m",
15
16
  features: [
16
17
  {
17
18
  code: "NoUpcharge",
18
19
  description: "",
20
+ numericOrder: false,
19
21
  options: [
20
22
  {
21
23
  code: "A",
@@ -36,6 +38,7 @@ const Prd = () => ({
36
38
  {
37
39
  code: "WithUpcharge",
38
40
  description: "",
41
+ numericOrder: false,
39
42
  options: [
40
43
  {
41
44
  code: "A",
@@ -56,6 +59,7 @@ const Prd = () => ({
56
59
  {
57
60
  code: "WithUpchargeSelectMany",
58
61
  description: "",
62
+ numericOrder: false,
59
63
  optional: true,
60
64
  options: [
61
65
  {
@@ -1,4 +1,4 @@
1
- import { CatalogueParams, Model, Prices, ProductData, ProductResponse, SelectedOption, ValidateResponse } from "./CatalogueAPI";
1
+ import { CatalogueParams, GetProductParams, Model, Prices, ProductData, ProductResponse, SelectedOption, ValidateResponse } from "./CatalogueAPI";
2
2
  export declare const makeCatalogueKey: (cat: CatalogueParams) => string;
3
3
  export declare const makeProductKey: (cat: CatalogueParams, pKey: string) => string;
4
4
  export declare const makeSelOptionsKey: (options: SelectedOption[]) => string;
@@ -9,11 +9,15 @@ export declare type CfgProductData = Omit<ProductData, "models"> & {
9
9
  export declare type CfgProductResponse = Omit<ProductResponse, "productData"> & {
10
10
  productData: CfgProductData;
11
11
  };
12
+ /** This must be kept in sync with ValidateResponse. */
12
13
  export declare type CfgValidateResponse = Omit<ValidateResponse, "productData"> & {
13
14
  productData: CfgProductData;
14
15
  };
15
16
  export declare function isModel(arg: any): arg is Model;
17
+ /** Replace empty strings with "-" for compatibility with the API. */
16
18
  export declare function correctDefaultsOnCatalogueParams(catId: CatalogueParams): CatalogueParams;
17
19
  export declare function recursivelyGetPriceCodeValue(priceCodes: string[], prices: Prices | undefined): number | undefined;
18
20
  export declare function comparePricesObjects(prices1: Prices | undefined, prices2: Prices | undefined): boolean;
21
+ export declare const decodeCatalogueParams: <T extends CatalogueParams>(params: T) => T;
22
+ export declare const decodeProductParams: <T extends GetProductParams>(params: T) => T;
19
23
  //# sourceMappingURL=utilitiesCatalogueData.d.ts.map
@@ -17,7 +17,7 @@ export const makeSelOptionsKey = (options) => options.reduce((p, option) => {
17
17
  export function isModel(arg) {
18
18
  return arg.cid !== undefined && arg.uri !== undefined;
19
19
  }
20
- /// Replace empty strings with "-" for compatibility with the API
20
+ /** Replace empty strings with "-" for compatibility with the API. */
21
21
  export function correctDefaultsOnCatalogueParams(catId) {
22
22
  // Enterprise, prdCat and vendor have to be set, so we don't try and fix those
23
23
  return {
@@ -54,3 +54,11 @@ export function comparePricesObjects(prices1, prices2) {
54
54
  }
55
55
  return shallowCompareDictionaries(prices1.values, prices2.values);
56
56
  }
57
+ export const decodeCatalogueParams = (params) => {
58
+ const decoded = Object.assign(Object.assign({}, params), { enterprise: decodeURIComponent(params.enterprise), prdCat: decodeURIComponent(params.prdCat), prdCatVersion: decodeURIComponent(params.prdCatVersion), priceList: decodeURIComponent(params.priceList), vendor: decodeURIComponent(params.vendor) });
59
+ return decoded;
60
+ };
61
+ export const decodeProductParams = (params) => {
62
+ const decoded = Object.assign(Object.assign({}, decodeCatalogueParams(params)), { partNumber: decodeURIComponent(params.partNumber) });
63
+ return decoded;
64
+ };
@@ -0,0 +1,25 @@
1
+ import { CodeRange } from "./CatalogueAPI";
2
+ export declare class NumericValuesSelection {
3
+ constructor(rawRanges: CodeRange[]);
4
+ readonly ranges: (NumericValueRangeDefinition | NumericValueDiscrete)[];
5
+ includesValue(value: number): boolean;
6
+ get first(): number;
7
+ get legend(): string;
8
+ }
9
+ export declare class NumericValueDiscrete {
10
+ readonly value: number;
11
+ constructor(value: number);
12
+ includesValue(value: number): boolean;
13
+ get first(): number;
14
+ get legend(): string;
15
+ }
16
+ export declare class NumericValueRangeDefinition {
17
+ constructor(rawRange: CodeRange);
18
+ readonly minValue: number;
19
+ readonly maxValue: number;
20
+ readonly increment: number | undefined;
21
+ includesValue(value: number): boolean;
22
+ get first(): number;
23
+ get legend(): string;
24
+ }
25
+ //# sourceMappingURL=utilitiesNumericValues.d.ts.map
@@ -0,0 +1,109 @@
1
+ /** Rounds the supplied value to 3 decimal points. */
2
+ function round(v) {
3
+ return Math.round(v * 1000) / 1000;
4
+ }
5
+ export class NumericValuesSelection {
6
+ constructor(rawRanges) {
7
+ if (rawRanges.length === 0) {
8
+ throw new Error("A numeric values selection must have at least one value");
9
+ }
10
+ this.ranges = rawRanges.map((rawRange) => {
11
+ const { minValue, maxValue } = rawRange;
12
+ if (minValue === maxValue) {
13
+ return new NumericValueDiscrete(minValue);
14
+ }
15
+ else {
16
+ return new NumericValueRangeDefinition(rawRange);
17
+ }
18
+ });
19
+ }
20
+ includesValue(value) {
21
+ return this.ranges.some((range) => range.includesValue(value));
22
+ }
23
+ get first() {
24
+ return this.ranges[0].first;
25
+ }
26
+ get legend() {
27
+ return this.ranges
28
+ .sort((l, r) => l.first - r.first)
29
+ .map((range) => range.legend)
30
+ .join(", ");
31
+ }
32
+ }
33
+ export class NumericValueDiscrete {
34
+ constructor(value) {
35
+ this.value = value;
36
+ }
37
+ includesValue(value) {
38
+ return value === this.value;
39
+ }
40
+ get first() {
41
+ return this.value;
42
+ }
43
+ get legend() {
44
+ return `${round(this.value)}`;
45
+ }
46
+ }
47
+ export class NumericValueRangeDefinition {
48
+ constructor(rawRange) {
49
+ const { minValue, maxValue, increment } = rawRange;
50
+ this.minValue = minValue;
51
+ this.maxValue = maxValue;
52
+ this.increment = increment === 0 ? undefined : increment;
53
+ }
54
+ includesValue(value) {
55
+ const { minValue: start, maxValue: end, increment: step } = this;
56
+ if (value < start || end < value) {
57
+ return false;
58
+ }
59
+ // TODO: This comparison will often fail due to the fact that all the values used are
60
+ // base-2 (binary) floating point numbers based on base-10 (decimal) input strings.
61
+ //
62
+ // Such calculations are often not 100% accurate as is visible in JS by simply
63
+ // computing "0.1 + 0.2" which should equal about "0.30000000000000004" != "0.3".
64
+ //
65
+ // The easiest workaround is to define an static accuracy, say "6 decimals" and round
66
+ // everything when comparing. One could also use a scaled version of Number.EPSILON to
67
+ // dynamically match the precision to the precision of the input numbers.
68
+ //
69
+ // Both workarounds share the same problem however; an infinite number of numbers will be
70
+ // included in the range since an "infinite" number of values will map to the same rounded
71
+ // actual number.
72
+ //
73
+ // The proper fix is probably to use a fixed point mathematics, where we either define a
74
+ // maximum of say 6 decimals or the number of decimals vary on the number of decimals given
75
+ // in the JSON for each value.
76
+ //
77
+ // This should work given that the input in CatCreator is decimal (human created string) and
78
+ // both XML and JSON uses string based decimal numbers. One question mark remains however,
79
+ // and that is how the numbers are stored in CatCreator if you use a db3-file. If it is a
80
+ // string there as well, everything is dandy. Otherwise we might get problems with rounding
81
+ // or infinite decimals during the conversions to/from the db3-file.
82
+ return step === undefined || (value - start) % step === 0;
83
+ }
84
+ get first() {
85
+ return this.minValue;
86
+ }
87
+ get legend() {
88
+ const { minValue, maxValue, increment } = this;
89
+ if (increment === undefined) {
90
+ return `[${round(minValue)} ... ${round(maxValue)}]`;
91
+ }
92
+ const steps = 1 + Math.floor((maxValue - minValue) / increment);
93
+ let legend = `[${round(minValue)}`;
94
+ if (increment !== undefined && 3 <= steps) {
95
+ legend += `, ${round(minValue + increment)}`;
96
+ }
97
+ if (5 <= steps) {
98
+ legend += " ... ";
99
+ }
100
+ else {
101
+ legend += ", ";
102
+ }
103
+ if (4 <= steps) {
104
+ legend += `${round(minValue + increment * (steps - 2))}, `;
105
+ }
106
+ legend += `${round(minValue + increment * (steps - 1))}]`;
107
+ return legend;
108
+ }
109
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configura/web-api",
3
- "version": "1.3.0-alpha.1",
3
+ "version": "1.3.0-alpha.5",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@configura/web-utilities": "^1.3.0-alpha.1"
26
+ "@configura/web-utilities": "^1.3.0-alpha.5"
27
27
  },
28
- "gitHead": "b0ef255a9f27f06a00378e09b24a40a840ba4722"
28
+ "gitHead": "7f22abef2c1047db092c871d9e9eceecbce5831e"
29
29
  }