@itwin/core-quantity 3.1.0-dev.8 → 3.2.0-dev.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 (34) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/lib/cjs/Exception.d.ts.map +1 -1
  3. package/lib/cjs/Exception.js +1 -0
  4. package/lib/cjs/Exception.js.map +1 -1
  5. package/lib/cjs/Formatter/Format.d.ts +37 -41
  6. package/lib/cjs/Formatter/Format.d.ts.map +1 -1
  7. package/lib/cjs/Formatter/Format.js +117 -341
  8. package/lib/cjs/Formatter/Format.js.map +1 -1
  9. package/lib/cjs/Formatter/FormatEnums.d.ts +46 -1
  10. package/lib/cjs/Formatter/FormatEnums.d.ts.map +1 -1
  11. package/lib/cjs/Formatter/FormatEnums.js +219 -2
  12. package/lib/cjs/Formatter/FormatEnums.js.map +1 -1
  13. package/lib/cjs/Formatter/FormatterSpec.js +1 -1
  14. package/lib/cjs/Formatter/FormatterSpec.js.map +1 -1
  15. package/lib/cjs/Interfaces.d.ts +9 -1
  16. package/lib/cjs/Interfaces.d.ts.map +1 -1
  17. package/lib/cjs/Interfaces.js.map +1 -1
  18. package/lib/esm/Exception.d.ts.map +1 -1
  19. package/lib/esm/Exception.js +2 -1
  20. package/lib/esm/Exception.js.map +1 -1
  21. package/lib/esm/Formatter/Format.d.ts +37 -41
  22. package/lib/esm/Formatter/Format.d.ts.map +1 -1
  23. package/lib/esm/Formatter/Format.js +116 -341
  24. package/lib/esm/Formatter/Format.js.map +1 -1
  25. package/lib/esm/Formatter/FormatEnums.d.ts +46 -1
  26. package/lib/esm/Formatter/FormatEnums.d.ts.map +1 -1
  27. package/lib/esm/Formatter/FormatEnums.js +205 -1
  28. package/lib/esm/Formatter/FormatEnums.js.map +1 -1
  29. package/lib/esm/Formatter/FormatterSpec.js +1 -1
  30. package/lib/esm/Formatter/FormatterSpec.js.map +1 -1
  31. package/lib/esm/Interfaces.d.ts +9 -1
  32. package/lib/esm/Interfaces.d.ts.map +1 -1
  33. package/lib/esm/Interfaces.js.map +1 -1
  34. package/package.json +5 -5
@@ -7,20 +7,17 @@
7
7
  * @module Quantity
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.Format = void 0;
10
+ exports.Format = exports.BaseFormat = void 0;
11
11
  const Constants_1 = require("../Constants");
12
12
  const Exception_1 = require("../Exception");
13
13
  const FormatEnums_1 = require("./FormatEnums");
14
14
  const Interfaces_1 = require("./Interfaces");
15
15
  // cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses
16
16
  // cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative
17
- /** A class used to define the specifications for formatting quantity values. This class is typically loaded by reading [[FormatProps]].
17
+ /** A base Format class with shared properties and functionality between quantity and ecschema-metadata Format classes
18
18
  * @beta
19
19
  */
20
- class Format {
21
- /** Constructor
22
- * @param name The name of a format specification. TODO: make optional or remove
23
- */
20
+ class BaseFormat {
24
21
  constructor(name) {
25
22
  this._name = "";
26
23
  this._roundFactor = 0.0;
@@ -31,280 +28,140 @@ class Format {
31
28
  this._thousandSeparator = Constants_1.QuantityConstants.LocaleSpecificThousandSeparator;
32
29
  this._uomSeparator = " "; // optional; default is " "; defined separator between magnitude and the unit
33
30
  this._stationSeparator = "+"; // optional; default is "+"
34
- this._formatTraits = 0x0;
31
+ this._formatTraits = FormatEnums_1.FormatTraits.Uninitialized;
35
32
  this._spacer = " "; // optional; default is " "
36
33
  this._includeZero = true; // optional; default is true
37
34
  this._name = name;
38
35
  }
39
36
  get name() { return this._name; }
40
37
  get roundFactor() { return this._roundFactor; }
38
+ set roundFactor(roundFactor) { this._roundFactor = roundFactor; }
41
39
  get type() { return this._type; }
40
+ set type(formatType) { this._type = formatType; }
42
41
  get precision() { return this._precision; }
42
+ set precision(precision) { this._precision = precision; }
43
43
  get minWidth() { return this._minWidth; }
44
+ set minWidth(minWidth) { this._minWidth = minWidth; }
44
45
  get scientificType() { return this._scientificType; }
46
+ set scientificType(scientificType) { this._scientificType = scientificType; }
45
47
  get showSignOption() { return this._showSignOption; }
48
+ set showSignOption(showSignOption) { this._showSignOption = showSignOption; }
46
49
  get decimalSeparator() { return this._decimalSeparator; }
50
+ set decimalSeparator(decimalSeparator) { this._decimalSeparator = decimalSeparator; }
47
51
  get thousandSeparator() { return this._thousandSeparator; }
52
+ set thousandSeparator(thousandSeparator) { this._thousandSeparator = thousandSeparator; }
48
53
  get uomSeparator() { return this._uomSeparator; }
54
+ set uomSeparator(uomSeparator) { this._uomSeparator = uomSeparator; }
49
55
  get stationSeparator() { return this._stationSeparator; }
56
+ set stationSeparator(stationSeparator) { this._stationSeparator = stationSeparator; }
50
57
  get stationOffsetSize() { return this._stationOffsetSize; }
58
+ set stationOffsetSize(stationOffsetSize) { stationOffsetSize = this._stationOffsetSize = stationOffsetSize; }
51
59
  get formatTraits() { return this._formatTraits; }
60
+ set formatTraits(formatTraits) { this._formatTraits = formatTraits; }
52
61
  get spacer() { return this._spacer; }
62
+ set spacer(spacer) { this._spacer = spacer !== null && spacer !== void 0 ? spacer : this._spacer; }
53
63
  get includeZero() { return this._includeZero; }
54
- get units() { return this._units; }
55
- get hasUnits() { return this._units !== undefined && this._units.length > 0; }
56
- get customProps() { return this._customProps; }
57
- // parse and toString methods
58
- static scientificTypeToString(scientificType) {
59
- if (scientificType === FormatEnums_1.ScientificType.Normalized)
60
- return "Normalized";
61
- else
62
- return "ZeroNormalized";
64
+ set includeZero(includeZero) { this._includeZero = includeZero !== null && includeZero !== void 0 ? includeZero : this._includeZero; }
65
+ /** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid FormatType. Throws exception if not valid. */
66
+ parseFormatTraits(formatTraitsFromJson) {
67
+ const formatTraits = (Array.isArray(formatTraitsFromJson)) ? formatTraitsFromJson : formatTraitsFromJson.split(/,|;|\|/);
68
+ formatTraits.forEach((formatTraitsString) => {
69
+ const formatTrait = (0, FormatEnums_1.parseFormatTrait)(formatTraitsString, this.name);
70
+ this._formatTraits = this.formatTraits | formatTrait;
71
+ });
63
72
  }
64
- /** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid ScientificType. Throws exception if not valid. */
65
- static parseScientificType(scientificType, formatName) {
66
- switch (scientificType.toLowerCase()) {
67
- case "normalized":
68
- return FormatEnums_1.ScientificType.Normalized;
69
- case "zeronormalized":
70
- return FormatEnums_1.ScientificType.ZeroNormalized;
71
- default:
72
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'SCIENTIFIC_TYPE' attribute.`);
73
- }
73
+ /** This method returns true if the formatTrait is set in this Format object. */
74
+ hasFormatTraitSet(formatTrait) {
75
+ return (this._formatTraits & formatTrait) === formatTrait;
74
76
  }
75
- /** Method used when generating a JSON object that represents this Format. */
76
- static showSignOptionToString(showSign) {
77
- switch (showSign) {
78
- case FormatEnums_1.ShowSignOption.NegativeParentheses:
79
- return "NegativeParentheses";
80
- case FormatEnums_1.ShowSignOption.NoSign:
81
- return "NoSign";
82
- case FormatEnums_1.ShowSignOption.OnlyNegative:
83
- return "OnlyNegative";
84
- case FormatEnums_1.ShowSignOption.SignAlways:
85
- return "SignAlways";
77
+ loadFormatProperties(formatProps) {
78
+ this._type = (0, FormatEnums_1.parseFormatType)(formatProps.type, this.name);
79
+ if (formatProps.precision !== undefined) {
80
+ if (!Number.isInteger(formatProps.precision)) // mut be an integer
81
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'precision' attribute. It should be an integer.`);
82
+ this._precision = (0, FormatEnums_1.parsePrecision)(formatProps.precision, this._type, this.name);
86
83
  }
87
- }
88
- /** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid ShowSignOption. Throws exception if not valid. */
89
- static parseShowSignOption(showSignOption, formatName) {
90
- switch (showSignOption.toLowerCase()) {
91
- case "nosign":
92
- return FormatEnums_1.ShowSignOption.NoSign;
93
- case "onlynegative":
94
- return FormatEnums_1.ShowSignOption.OnlyNegative;
95
- case "signalways":
96
- return FormatEnums_1.ShowSignOption.SignAlways;
97
- case "negativeparentheses":
98
- return FormatEnums_1.ShowSignOption.NegativeParentheses;
99
- default:
100
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'showSignOption' attribute.`);
84
+ if (this.type === FormatEnums_1.FormatType.Scientific) {
85
+ if (undefined === formatProps.scientificType) // if format type is scientific and scientific type is undefined, throw
86
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} is 'Scientific' type therefore the attribute 'scientificType' is required.`);
87
+ this._scientificType = (0, FormatEnums_1.parseScientificType)(formatProps.scientificType, this.name);
101
88
  }
102
- }
103
- static isFormatTraitSetInProps(formatProps, trait) {
104
- if (!formatProps.formatTraits)
105
- return false;
106
- const formatTraits = Array.isArray(formatProps.formatTraits) ? formatProps.formatTraits : formatProps.formatTraits.split(/,|;|\|/);
107
- const traitStr = Format.getTraitString(trait);
108
- return formatTraits.find((traitEntry) => traitStr === traitEntry) ? true : false;
109
- }
110
- /** Get string used in FormatProps */
111
- static getTraitString(trait) {
112
- switch (trait) {
113
- case FormatEnums_1.FormatTraits.TrailZeroes:
114
- return "trailZeroes";
115
- case FormatEnums_1.FormatTraits.KeepSingleZero:
116
- return "keepSingleZero";
117
- case FormatEnums_1.FormatTraits.ZeroEmpty:
118
- return "zeroEmpty";
119
- case FormatEnums_1.FormatTraits.KeepDecimalPoint:
120
- return "keepDecimalPoint";
121
- case FormatEnums_1.FormatTraits.ApplyRounding:
122
- return "applyRounding";
123
- case FormatEnums_1.FormatTraits.FractionDash:
124
- return "fractionDash";
125
- case FormatEnums_1.FormatTraits.ShowUnitLabel:
126
- return "showUnitLabel";
127
- case FormatEnums_1.FormatTraits.PrependUnitLabel:
128
- return "prependUnitLabel";
129
- case FormatEnums_1.FormatTraits.Use1000Separator:
130
- return "use1000Separator";
131
- case FormatEnums_1.FormatTraits.ExponentOnlyNegative:
132
- default:
133
- return "exponentOnlyNegative";
89
+ if (undefined !== formatProps.roundFactor) { // optional; default is 0.0
90
+ if (typeof (formatProps.roundFactor) !== "number")
91
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'roundFactor' attribute. It should be of type 'number'.`);
92
+ if (formatProps.roundFactor !== this.roundFactor) // if roundFactor isn't default value of 0.0, reassign roundFactor variable
93
+ this._roundFactor = formatProps.roundFactor;
134
94
  }
135
- }
136
- /** Method used when generating a JSON object that represents this Format. */
137
- static formatTraitsToArray(currentFormatTrait) {
138
- const formatTraitsArr = Array();
139
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.TrailZeroes) === FormatEnums_1.FormatTraits.TrailZeroes)
140
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.TrailZeroes));
141
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.KeepSingleZero) === FormatEnums_1.FormatTraits.KeepSingleZero)
142
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.KeepSingleZero));
143
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.ZeroEmpty) === FormatEnums_1.FormatTraits.ZeroEmpty)
144
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.ZeroEmpty));
145
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.KeepDecimalPoint) === FormatEnums_1.FormatTraits.KeepDecimalPoint)
146
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.KeepDecimalPoint));
147
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.ApplyRounding) === FormatEnums_1.FormatTraits.ApplyRounding)
148
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.ApplyRounding));
149
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.FractionDash) === FormatEnums_1.FormatTraits.FractionDash)
150
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.FractionDash));
151
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.ShowUnitLabel) === FormatEnums_1.FormatTraits.ShowUnitLabel)
152
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.ShowUnitLabel));
153
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.PrependUnitLabel) === FormatEnums_1.FormatTraits.PrependUnitLabel)
154
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.PrependUnitLabel));
155
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.Use1000Separator) === FormatEnums_1.FormatTraits.Use1000Separator)
156
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.Use1000Separator));
157
- // NOTE: the formatter does not current use trait ExponentOnlyNegative
158
- if ((currentFormatTrait & FormatEnums_1.FormatTraits.ExponentOnlyNegative) === FormatEnums_1.FormatTraits.ExponentOnlyNegative)
159
- formatTraitsArr.push(Format.getTraitString(FormatEnums_1.FormatTraits.ExponentOnlyNegative));
160
- return formatTraitsArr;
161
- }
162
- /** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid FormatTrait. Throws exception if not valid. */
163
- static parseFormatTrait(stringToCheck, currentFormatTrait) {
164
- switch (stringToCheck.toLowerCase()) {
165
- case "trailzeroes":
166
- return currentFormatTrait | FormatEnums_1.FormatTraits.TrailZeroes;
167
- case "keepsinglezero":
168
- return currentFormatTrait | FormatEnums_1.FormatTraits.KeepSingleZero; // keep single when format type is Decimal
169
- case "zeroempty":
170
- return currentFormatTrait | FormatEnums_1.FormatTraits.ZeroEmpty;
171
- case "keepdecimalpoint":
172
- return currentFormatTrait | FormatEnums_1.FormatTraits.KeepDecimalPoint; // add decimal point when no fractional part and format type is Decimal
173
- case "applyrounding":
174
- return currentFormatTrait | FormatEnums_1.FormatTraits.ApplyRounding;
175
- case "fractiondash":
176
- return currentFormatTrait | FormatEnums_1.FormatTraits.FractionDash;
177
- case "showunitlabel":
178
- return currentFormatTrait | FormatEnums_1.FormatTraits.ShowUnitLabel;
179
- case "prependunitlabel":
180
- return currentFormatTrait | FormatEnums_1.FormatTraits.PrependUnitLabel;
181
- case "use1000separator":
182
- return currentFormatTrait | FormatEnums_1.FormatTraits.Use1000Separator;
183
- case "exponentonlynegative":
184
- return currentFormatTrait | FormatEnums_1.FormatTraits.ExponentOnlyNegative;
185
- default:
186
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `Format has an invalid 'formatTraits' option.`);
95
+ if (undefined !== formatProps.minWidth) { // optional
96
+ if (!Number.isInteger(formatProps.minWidth) || formatProps.minWidth < 0) // must be a positive int
97
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'minWidth' attribute. It should be a positive integer.`);
98
+ this._minWidth = formatProps.minWidth;
187
99
  }
188
- }
189
- /** Get FormatTrait from entry in FormatProps */
190
- static parseFormatTraits(formatTraitsFromJson) {
191
- if (!formatTraitsFromJson)
192
- return undefined;
193
- const formatTraits = Array.isArray(formatTraitsFromJson) ? formatTraitsFromJson : formatTraitsFromJson.split(/,|;|\|/);
194
- let traits = 0;
195
- for (const traitStr of formatTraits) {
196
- traits = Format.parseFormatTrait(traitStr, traits);
100
+ if (FormatEnums_1.FormatType.Station === this.type) {
101
+ if (undefined === formatProps.stationOffsetSize)
102
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} is 'Station' type therefore the attribute 'stationOffsetSize' is required.`);
103
+ if (!Number.isInteger(formatProps.stationOffsetSize) || formatProps.stationOffsetSize < 0) // must be a positive int > 0
104
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be a positive integer.`);
105
+ this._stationOffsetSize = formatProps.stationOffsetSize;
197
106
  }
198
- if (0 === traits)
199
- return undefined;
200
- return traits;
201
- }
202
- /** Method used when generating a JSON object that represents this Format. */
203
- static formatTypeToString(type) {
204
- switch (type) {
205
- case FormatEnums_1.FormatType.Decimal:
206
- return "Decimal";
207
- case FormatEnums_1.FormatType.Scientific:
208
- return "Scientific";
209
- case FormatEnums_1.FormatType.Station:
210
- return "Station";
211
- case FormatEnums_1.FormatType.Fractional:
212
- return "Fractional";
107
+ if (undefined !== formatProps.showSignOption) { // optional; default is "onlyNegative"
108
+ this._showSignOption = (0, FormatEnums_1.parseShowSignOption)(formatProps.showSignOption, this.name);
213
109
  }
214
- }
215
- /** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid FormatType. Throws exception if not valid. */
216
- static parseFormatType(jsonObjType, formatName) {
217
- switch (jsonObjType.toLowerCase()) {
218
- case "decimal":
219
- return FormatEnums_1.FormatType.Decimal;
220
- case "scientific":
221
- return FormatEnums_1.FormatType.Scientific;
222
- case "station":
223
- return FormatEnums_1.FormatType.Station;
224
- case "fractional":
225
- return FormatEnums_1.FormatType.Fractional;
226
- default:
227
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'type' attribute.`);
110
+ if (undefined !== formatProps.formatTraits && formatProps.formatTraits.length !== 0) { // FormatTraits is optional
111
+ if (!Array.isArray(formatProps.formatTraits) && typeof (formatProps.formatTraits) !== "string") // must be either an array of strings or a string
112
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'formatTraits' attribute. It should be of type 'string' or 'string[]'.`);
113
+ this.parseFormatTraits(formatProps.formatTraits); // check that all of the options for formatTraits are valid. If now, throw
228
114
  }
229
- }
230
- /** This method validates the input value, that is typically extracted for persisted JSON data, is a valid DecimalPrecision. Throws exception if not valid. */
231
- static parseDecimalPrecision(jsonObjPrecision) {
232
- switch (jsonObjPrecision) {
233
- case 0:
234
- return FormatEnums_1.DecimalPrecision.Zero;
235
- case 1:
236
- return FormatEnums_1.DecimalPrecision.One;
237
- case 2:
238
- return FormatEnums_1.DecimalPrecision.Two;
239
- case 3:
240
- return FormatEnums_1.DecimalPrecision.Three;
241
- case 4:
242
- return FormatEnums_1.DecimalPrecision.Four;
243
- case 5:
244
- return FormatEnums_1.DecimalPrecision.Five;
245
- case 6:
246
- return FormatEnums_1.DecimalPrecision.Six;
247
- case 7:
248
- return FormatEnums_1.DecimalPrecision.Seven;
249
- case 8:
250
- return FormatEnums_1.DecimalPrecision.Eight;
251
- case 9:
252
- return FormatEnums_1.DecimalPrecision.Nine;
253
- case 10:
254
- return FormatEnums_1.DecimalPrecision.Ten;
255
- case 11:
256
- return FormatEnums_1.DecimalPrecision.Eleven;
257
- case 12:
258
- return FormatEnums_1.DecimalPrecision.Twelve;
259
- default:
260
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The 'precision' attribute must be an integer in the range 0-12.`);
115
+ if (undefined !== formatProps.decimalSeparator) { // optional
116
+ if (typeof (formatProps.decimalSeparator) !== "string") // not a string or not a one character string
117
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be of type 'string'.`);
118
+ if (formatProps.decimalSeparator.length > 1)
119
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be an empty or one character string.`);
120
+ this._decimalSeparator = formatProps.decimalSeparator;
261
121
  }
262
- }
263
- /** This method validates the input value, that is typically extracted for persisted JSON data, is a valid FractionalPrecision. Throws exception if not valid. */
264
- static parseFractionalPrecision(jsonObjPrecision, formatName) {
265
- switch (jsonObjPrecision) {
266
- case 1:
267
- return FormatEnums_1.FractionalPrecision.One;
268
- case 2:
269
- return FormatEnums_1.FractionalPrecision.Two;
270
- case 4:
271
- return FormatEnums_1.FractionalPrecision.Four;
272
- case 8:
273
- return FormatEnums_1.FractionalPrecision.Eight;
274
- case 16:
275
- return FormatEnums_1.FractionalPrecision.Sixteen;
276
- case 32:
277
- return FormatEnums_1.FractionalPrecision.ThirtyTwo;
278
- case 64:
279
- return FormatEnums_1.FractionalPrecision.SixtyFour;
280
- case 128:
281
- return FormatEnums_1.FractionalPrecision.OneHundredTwentyEight;
282
- case 256:
283
- return FormatEnums_1.FractionalPrecision.TwoHundredFiftySix;
284
- default:
285
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'precision' attribute.`);
122
+ if (undefined !== formatProps.thousandSeparator) { // optional
123
+ if (typeof (formatProps.thousandSeparator) !== "string")
124
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be of type 'string'.`);
125
+ if (formatProps.thousandSeparator.length > 1)
126
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be an empty or one character string.`);
127
+ this._thousandSeparator = formatProps.thousandSeparator;
286
128
  }
287
- }
288
- /** This method validates the input value, that is typically extracted for persisted JSON data, is a valid DecimalPrecision or FractionalPrecision. Throws exception if not valid. */
289
- static parsePrecision(precision, formatName, type) {
290
- switch (type) { // type must be decimal, fractional, scientific, or station
291
- case FormatEnums_1.FormatType.Decimal:
292
- case FormatEnums_1.FormatType.Scientific:
293
- case FormatEnums_1.FormatType.Station:
294
- return Format.parseDecimalPrecision(precision);
295
- case FormatEnums_1.FormatType.Fractional:
296
- return Format.parseFractionalPrecision(precision, formatName);
129
+ if (undefined !== formatProps.uomSeparator) { // optional; default is " "
130
+ if (typeof (formatProps.uomSeparator) !== "string")
131
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be of type 'string'.`);
132
+ if (formatProps.uomSeparator.length < 0 || formatProps.uomSeparator.length > 1)
133
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be an empty or one character string.`);
134
+ this._uomSeparator = formatProps.uomSeparator;
135
+ }
136
+ if (undefined !== formatProps.stationSeparator) { // optional; default is "+"
137
+ if (typeof (formatProps.stationSeparator) !== "string")
138
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be of type 'string'.`);
139
+ if (formatProps.stationSeparator.length > 1)
140
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be an empty or one character string.`);
141
+ this._stationSeparator = formatProps.stationSeparator;
297
142
  }
298
143
  }
299
- verifyFormatTraitsOptions(formatTraitsFromJson) {
300
- const formatTraits = (Array.isArray(formatTraitsFromJson)) ? formatTraitsFromJson : formatTraitsFromJson.split(/,|;|\|/);
301
- formatTraits.forEach((formatTraitsString) => {
302
- this._formatTraits = Format.parseFormatTrait(formatTraitsString, this.formatTraits);
303
- });
144
+ }
145
+ exports.BaseFormat = BaseFormat;
146
+ /** A class used to define the specifications for formatting quantity values. This class is typically loaded by reading [[FormatProps]].
147
+ * @beta
148
+ */
149
+ class Format extends BaseFormat {
150
+ /** Constructor
151
+ * @param name The name of a format specification. TODO: make optional or remove
152
+ */
153
+ constructor(name) {
154
+ super(name);
304
155
  }
305
- /** This method returns true if the formatTrait is set in this Format object. */
306
- hasFormatTraitSet(formatTrait) {
307
- return (this._formatTraits & formatTrait) === formatTrait;
156
+ get units() { return this._units; }
157
+ get hasUnits() { return this._units !== undefined && this._units.length > 0; }
158
+ get customProps() { return this._customProps; }
159
+ static isFormatTraitSetInProps(formatProps, trait) {
160
+ if (!formatProps.formatTraits)
161
+ return false;
162
+ const formatTraits = Array.isArray(formatProps.formatTraits) ? formatProps.formatTraits : formatProps.formatTraits.split(/,|;|\|/);
163
+ const traitStr = (0, FormatEnums_1.getTraitString)(trait);
164
+ return formatTraits.find((traitEntry) => traitStr === traitEntry) ? true : false;
308
165
  }
309
166
  async createUnit(unitsProvider, name, label) {
310
167
  if (name === undefined || typeof (name) !== "string" || (label !== undefined && typeof (label) !== "string")) // throws if name is undefined or name isn't a string or if label is defined and isn't a string
@@ -353,7 +210,7 @@ class Format {
353
210
  newFormat._type = options.type;
354
211
  if (undefined !== (options === null || options === void 0 ? void 0 : options.precision)) {
355
212
  // ensure specified precision is valid
356
- const precision = Format.parsePrecision(options === null || options === void 0 ? void 0 : options.precision, "clone", newFormat._type);
213
+ const precision = (0, FormatEnums_1.parsePrecision)(options === null || options === void 0 ? void 0 : options.precision, newFormat._type, newFormat.name);
357
214
  newFormat._precision = precision;
358
215
  }
359
216
  if (undefined !== (options === null || options === void 0 ? void 0 : options.primaryUnit)) {
@@ -369,94 +226,13 @@ class Format {
369
226
  }
370
227
  return newFormat;
371
228
  }
372
- loadFormatProperties(jsonObj) {
373
- if ((0, Interfaces_1.isCustomFormatProps)(jsonObj))
374
- this._customProps = jsonObj.custom;
375
- if (undefined === jsonObj.type) // type is required
376
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} does not have the required 'type' attribute.`);
377
- if (typeof (jsonObj.type) !== "string")
378
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'type' attribute. It should be of type 'string'.`);
379
- this._type = Format.parseFormatType(jsonObj.type, this.name);
380
- if (undefined === jsonObj.precision) // precision is required
381
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} does not have the required 'precision' attribute.`);
382
- else if (typeof (jsonObj.precision) !== "number") // must be a number
383
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'precision' attribute. It should be of type 'number'.`);
384
- else if (!Number.isInteger(jsonObj.precision)) // must be an integer
385
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'precision' attribute. It should be an integer.`);
386
- this._precision = Format.parsePrecision(jsonObj.precision, this.name, this._type);
387
- if (this.type === FormatEnums_1.FormatType.Scientific) {
388
- if (undefined === jsonObj.scientificType) // if format type is scientific and scientific type is undefined, throw
389
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has type 'Scientific' therefore attribute 'scientificType' is required.`);
390
- if (typeof (jsonObj.scientificType) !== "string")
391
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'scientificType' attribute. It should be of type 'string'.`);
392
- this._scientificType = Format.parseScientificType(jsonObj.scientificType.toLowerCase(), this.name);
393
- }
394
- if (this.type === FormatEnums_1.FormatType.Station) {
395
- if (undefined === jsonObj.stationOffsetSize)
396
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has type 'Station' therefore attribute 'stationOffsetSize' is required.`);
397
- if (typeof (jsonObj.stationOffsetSize) !== "number")
398
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be of type 'number'.`);
399
- if (!Number.isInteger(jsonObj.stationOffsetSize) || jsonObj.stationOffsetSize <= 0) // must be a positive int > 0
400
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be a positive integer.`);
401
- this._stationOffsetSize = jsonObj.stationOffsetSize;
402
- }
403
- if (undefined !== jsonObj.roundFactor) { // optional; default is 0.0
404
- if (typeof (jsonObj.roundFactor) !== "number")
405
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'roundFactor' attribute. It should be of type 'number'.`);
406
- if (jsonObj.roundFactor !== this.roundFactor) // if roundFactor isn't default value of 0.0, reassign roundFactor variable
407
- this._roundFactor = jsonObj.roundFactor;
408
- }
409
- if (undefined !== jsonObj.minWidth) { // optional
410
- if (typeof (jsonObj.minWidth) !== "number")
411
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'minWidth' attribute. It should be of type 'number'.`);
412
- if (!Number.isInteger(jsonObj.minWidth) || jsonObj.minWidth < 0) // must be a positive int
413
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'minWidth' attribute. It should be a positive integer.`);
414
- this._minWidth = jsonObj.minWidth;
415
- }
416
- if (undefined !== jsonObj.showSignOption) { // optional; default is "onlyNegative"
417
- if (typeof (jsonObj.showSignOption) !== "string")
418
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'showSignOption' attribute. It should be of type 'string'.`);
419
- this._showSignOption = Format.parseShowSignOption(jsonObj.showSignOption, this.name);
420
- }
421
- if (undefined !== jsonObj.formatTraits && jsonObj.formatTraits.length !== 0) { // FormatTraits is optional
422
- if (!Array.isArray(jsonObj.formatTraits) && typeof (jsonObj.formatTraits) !== "string") // must be either an array of strings or a string
423
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'formatTraits' attribute. It should be of type 'string' or 'string[]'.`);
424
- this.verifyFormatTraitsOptions(jsonObj.formatTraits); // check that all of the options for formatTraits are valid. If now, throw
425
- }
426
- if (undefined !== jsonObj.decimalSeparator) { // optional
427
- if (typeof (jsonObj.decimalSeparator) !== "string") // not a string or not a one character string
428
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be of type 'string'.`);
429
- if (jsonObj.decimalSeparator.length !== 1)
430
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It must be a one character string.`);
431
- this._decimalSeparator = jsonObj.decimalSeparator;
432
- }
433
- if (undefined !== jsonObj.thousandSeparator) { // optional
434
- if (typeof (jsonObj.thousandSeparator) !== "string")
435
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be of type 'string'.`);
436
- if (jsonObj.thousandSeparator.length !== 1)
437
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It must be a one character string.`);
438
- this._thousandSeparator = jsonObj.thousandSeparator;
439
- }
440
- if (undefined !== jsonObj.uomSeparator) { // optional; default is " "
441
- if (typeof (jsonObj.uomSeparator) !== "string")
442
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be of type 'string'.`);
443
- if (jsonObj.uomSeparator.length < 0 || jsonObj.uomSeparator.length > 1)
444
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It must be empty or a string with a single character.`);
445
- this._uomSeparator = jsonObj.uomSeparator;
446
- }
447
- if (undefined !== jsonObj.stationSeparator) { // optional; default is "+"
448
- if (typeof (jsonObj.stationSeparator) !== "string")
449
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be of type 'string'.`);
450
- if (jsonObj.stationSeparator.length !== 1)
451
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It must be a one character string.`);
452
- this._stationSeparator = jsonObj.stationSeparator;
453
- }
454
- }
455
229
  /**
456
230
  * Populates this Format with the values from the provided.
457
231
  */
458
232
  async fromJSON(unitsProvider, jsonObj) {
459
233
  this.loadFormatProperties(jsonObj);
234
+ if ((0, Interfaces_1.isCustomFormatProps)(jsonObj))
235
+ this._customProps = jsonObj.custom;
460
236
  if (undefined !== jsonObj.composite) { // optional
461
237
  this._units = new Array();
462
238
  if (jsonObj.composite.includeZero !== undefined) {
@@ -467,8 +243,8 @@ class Format {
467
243
  if (jsonObj.composite.spacer !== undefined) { // spacer must be a string IF it is defined
468
244
  if (typeof (jsonObj.composite.spacer) !== "string")
469
245
  throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be of type 'string'.`);
470
- if (jsonObj.composite.spacer.length < 0 || jsonObj.composite.spacer.length > 1)
471
- throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be empty or a string with a single character.`);
246
+ if (jsonObj.composite.spacer.length > 1)
247
+ throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidJson, `The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It should be an empty or one character string.`);
472
248
  this._spacer = jsonObj.composite.spacer;
473
249
  }
474
250
  if (jsonObj.composite.units !== undefined) { // if composite is defined, it must be an array with 1-4 units
@@ -518,32 +294,32 @@ class Format {
518
294
  }
519
295
  if (this.customProps)
520
296
  return {
521
- type: Format.formatTypeToString(this.type),
297
+ type: (0, FormatEnums_1.formatTypeToString)(this.type),
522
298
  precision: this.precision,
523
299
  roundFactor: this.roundFactor,
524
300
  minWidth: this.minWidth,
525
- showSignOption: Format.showSignOptionToString(this.showSignOption),
526
- formatTraits: Format.formatTraitsToArray(this.formatTraits),
301
+ showSignOption: (0, FormatEnums_1.showSignOptionToString)(this.showSignOption),
302
+ formatTraits: (0, FormatEnums_1.formatTraitsToArray)(this.formatTraits),
527
303
  decimalSeparator: this.decimalSeparator,
528
304
  thousandSeparator: this.thousandSeparator,
529
305
  uomSeparator: this.uomSeparator,
530
- scientificType: this.scientificType ? Format.scientificTypeToString(this.scientificType) : undefined,
306
+ scientificType: this.scientificType ? (0, FormatEnums_1.scientificTypeToString)(this.scientificType) : undefined,
531
307
  stationOffsetSize: this.stationOffsetSize,
532
308
  stationSeparator: this.stationSeparator,
533
309
  composite,
534
310
  custom: this.customProps,
535
311
  };
536
312
  return {
537
- type: Format.formatTypeToString(this.type),
313
+ type: (0, FormatEnums_1.formatTypeToString)(this.type),
538
314
  precision: this.precision,
539
315
  roundFactor: this.roundFactor,
540
316
  minWidth: this.minWidth,
541
- showSignOption: Format.showSignOptionToString(this.showSignOption),
542
- formatTraits: Format.formatTraitsToArray(this.formatTraits),
317
+ showSignOption: (0, FormatEnums_1.showSignOptionToString)(this.showSignOption),
318
+ formatTraits: (0, FormatEnums_1.formatTraitsToArray)(this.formatTraits),
543
319
  decimalSeparator: this.decimalSeparator,
544
320
  thousandSeparator: this.thousandSeparator,
545
321
  uomSeparator: this.uomSeparator,
546
- scientificType: this.scientificType ? Format.scientificTypeToString(this.scientificType) : undefined,
322
+ scientificType: this.scientificType ? (0, FormatEnums_1.scientificTypeToString)(this.scientificType) : undefined,
547
323
  stationOffsetSize: this.stationOffsetSize,
548
324
  stationSeparator: this.stationSeparator,
549
325
  composite,