@itwin/core-quantity 5.14.0-dev.21 → 5.14.0-dev.23
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.
- package/lib/cjs/BasicUnitsProvider.d.ts +10 -7
- package/lib/cjs/BasicUnitsProvider.d.ts.map +1 -1
- package/lib/cjs/BasicUnitsProvider.js +22 -33
- package/lib/cjs/BasicUnitsProvider.js.map +1 -1
- package/lib/cjs/Formatter/Format.d.ts +3 -1
- package/lib/cjs/Formatter/Format.d.ts.map +1 -1
- package/lib/cjs/Formatter/Format.js +77 -38
- package/lib/cjs/Formatter/Format.js.map +1 -1
- package/lib/cjs/Formatter/FormatterSpec.d.ts +6 -2
- package/lib/cjs/Formatter/FormatterSpec.d.ts.map +1 -1
- package/lib/cjs/Formatter/FormatterSpec.js +42 -20
- package/lib/cjs/Formatter/FormatterSpec.js.map +1 -1
- package/lib/cjs/Formatter/Interfaces.d.ts +27 -2
- package/lib/cjs/Formatter/Interfaces.d.ts.map +1 -1
- package/lib/cjs/Formatter/Interfaces.js.map +1 -1
- package/lib/cjs/Interfaces.d.ts +14 -0
- package/lib/cjs/Interfaces.d.ts.map +1 -1
- package/lib/cjs/Interfaces.js.map +1 -1
- package/lib/cjs/Parser.js +2 -2
- package/lib/cjs/Parser.js.map +1 -1
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.d.ts +4 -0
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.d.ts.map +1 -1
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.js +7 -0
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.js.map +1 -1
- package/lib/esm/BasicUnitsProvider.d.ts +10 -7
- package/lib/esm/BasicUnitsProvider.d.ts.map +1 -1
- package/lib/esm/BasicUnitsProvider.js +21 -12
- package/lib/esm/BasicUnitsProvider.js.map +1 -1
- package/lib/esm/Formatter/Format.d.ts +3 -1
- package/lib/esm/Formatter/Format.d.ts.map +1 -1
- package/lib/esm/Formatter/Format.js +77 -38
- package/lib/esm/Formatter/Format.js.map +1 -1
- package/lib/esm/Formatter/FormatterSpec.d.ts +6 -2
- package/lib/esm/Formatter/FormatterSpec.d.ts.map +1 -1
- package/lib/esm/Formatter/FormatterSpec.js +42 -20
- package/lib/esm/Formatter/FormatterSpec.js.map +1 -1
- package/lib/esm/Formatter/Interfaces.d.ts +27 -2
- package/lib/esm/Formatter/Interfaces.d.ts.map +1 -1
- package/lib/esm/Formatter/Interfaces.js.map +1 -1
- package/lib/esm/Interfaces.d.ts +14 -0
- package/lib/esm/Interfaces.d.ts.map +1 -1
- package/lib/esm/Interfaces.js.map +1 -1
- package/lib/esm/Parser.js +2 -2
- package/lib/esm/Parser.js.map +1 -1
- package/lib/esm/internal/BasicUnitsResolvedStateCache.d.ts +4 -0
- package/lib/esm/internal/BasicUnitsResolvedStateCache.d.ts.map +1 -1
- package/lib/esm/internal/BasicUnitsResolvedStateCache.js +6 -0
- package/lib/esm/internal/BasicUnitsResolvedStateCache.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @packageDocumentation
|
|
2
2
|
* @module Quantity
|
|
3
3
|
*/
|
|
4
|
-
import { UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from "../Interfaces";
|
|
4
|
+
import { SyncUnitsProvider, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from "../Interfaces";
|
|
5
5
|
import { Format } from "./Format";
|
|
6
6
|
/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.
|
|
7
7
|
* Once created the FormatterSpec will be able to format quantity values with synchronous calls.
|
|
@@ -31,9 +31,10 @@ export declare class FormatterSpec {
|
|
|
31
31
|
get azimuthBaseConversion(): UnitConversionProps | undefined;
|
|
32
32
|
get revolutionConversion(): UnitConversionProps | undefined;
|
|
33
33
|
/** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */
|
|
34
|
-
private static
|
|
34
|
+
private static buildRatioUnitConversions;
|
|
35
35
|
/** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */
|
|
36
36
|
static getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]>;
|
|
37
|
+
private static buildUnitConversions;
|
|
37
38
|
/** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will
|
|
38
39
|
* be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make
|
|
39
40
|
* async calls to lookup unit definitions.
|
|
@@ -45,6 +46,9 @@ export declare class FormatterSpec {
|
|
|
45
46
|
* @see BaseFormat.revolutionUnit
|
|
46
47
|
*/
|
|
47
48
|
static create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec>;
|
|
49
|
+
/** Create a `FormatterSpec` using a synchronous unit provider. */
|
|
50
|
+
static createSync(name: string, format: Format, unitsProvider: SyncUnitsProvider, inputUnit?: UnitProps): FormatterSpec;
|
|
51
|
+
private static buildFormatterSpec;
|
|
48
52
|
/** Format a quantity value. */
|
|
49
53
|
applyFormatting(magnitude: number): string;
|
|
50
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatterSpec.d.ts","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"FormatterSpec.d.ts","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC;;;GAGG;AACH,qBAAa,aAAa;IACxB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAM;IAClD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,gBAAgB,EAAE,SAAS,CAAC;IACtC,SAAS,CAAC,sBAAsB,CAAC,EAAE,mBAAmB,CAAC;IACvD,SAAS,CAAC,qBAAqB,CAAC,EAAE,mBAAmB,CAAC;IAEtD;;;;;;;OAOG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,kBAAkB,EAAE,EAAE,eAAe,CAAC,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,mBAAmB,EAAE,oBAAoB,CAAC,EAAE,mBAAmB;IAmBlM,IAAW,IAAI,IAAI,MAAM,CAAuB;IAChD,uHAAuH;IACvH,IAAW,eAAe,IAAI,kBAAkB,EAAE,CAA8B;IAChF,IAAW,MAAM,IAAI,MAAM,CAAyB;IACpD,IAAW,eAAe,IAAI,SAAS,CAAkC;IACzE,IAAW,qBAAqB,IAAI,mBAAmB,GAAG,SAAS,CAAwC;IAC3G,IAAW,oBAAoB,IAAI,mBAAmB,GAAG,SAAS,CAAuC;IAEzG,8FAA8F;IAC9F,OAAO,CAAC,MAAM,CAAE,yBAAyB;IAkDzC,mHAAmH;WAC/F,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAI1I,OAAO,CAAC,MAAM,CAAE,oBAAoB;IA2CpC;;;;;;;;;OASG;WACiB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC;IAIrI,kEAAkE;WACpD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,aAAa;IAI9H,OAAO,CAAC,MAAM,CAAE,kBAAkB;IAsBlC,+BAA+B;IACxB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAGlD"}
|
|
@@ -56,15 +56,12 @@ export class FormatterSpec {
|
|
|
56
56
|
get azimuthBaseConversion() { return this._azimuthBaseConversion; }
|
|
57
57
|
get revolutionConversion() { return this._revolutionConversion; }
|
|
58
58
|
/** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */
|
|
59
|
-
static
|
|
59
|
+
static *buildRatioUnitConversions(units, persistenceUnit) {
|
|
60
60
|
const conversions = [];
|
|
61
61
|
const [numeratorUnit, numeratorLabel] = units[0];
|
|
62
62
|
const [denominatorUnit, denominatorLabel] = units[1];
|
|
63
63
|
// Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)
|
|
64
|
-
const denominatorToNumerator =
|
|
65
|
-
if (denominatorToNumerator.error) {
|
|
66
|
-
Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from "${denominatorUnit.name}" to "${numeratorUnit.name}" could not be resolved.`);
|
|
67
|
-
}
|
|
64
|
+
const denominatorToNumerator = yield* requestConversion(denominatorUnit, numeratorUnit);
|
|
68
65
|
const displayRatioScale = denominatorToNumerator.factor;
|
|
69
66
|
// Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.
|
|
70
67
|
// Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)
|
|
@@ -80,7 +77,7 @@ export class FormatterSpec {
|
|
|
80
77
|
name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,
|
|
81
78
|
label: "",
|
|
82
79
|
system: numeratorUnit.system,
|
|
83
|
-
conversion:
|
|
80
|
+
conversion: createRatioConversionProps(ratioScaleFactor, denominatorToNumerator),
|
|
84
81
|
};
|
|
85
82
|
conversions.push(ratioConversionSpec);
|
|
86
83
|
// Numerator unit for label lookup
|
|
@@ -103,6 +100,9 @@ export class FormatterSpec {
|
|
|
103
100
|
}
|
|
104
101
|
/** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */
|
|
105
102
|
static async getUnitConversions(format, unitsProvider, inputUnit) {
|
|
103
|
+
return runAsync(FormatterSpec.buildUnitConversions(format, inputUnit), unitsProvider);
|
|
104
|
+
}
|
|
105
|
+
static *buildUnitConversions(format, inputUnit) {
|
|
106
106
|
const conversions = [];
|
|
107
107
|
let persistenceUnit = inputUnit;
|
|
108
108
|
if (!persistenceUnit) {
|
|
@@ -116,17 +116,14 @@ export class FormatterSpec {
|
|
|
116
116
|
}
|
|
117
117
|
// Handle 2-unit composite for ratio formats (scale factors)
|
|
118
118
|
if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {
|
|
119
|
-
return FormatterSpec.
|
|
119
|
+
return yield* FormatterSpec.buildRatioUnitConversions(format.units, persistenceUnit);
|
|
120
120
|
}
|
|
121
121
|
if (format.units) {
|
|
122
122
|
let convertFromUnit = inputUnit;
|
|
123
123
|
for (const unit of format.units) {
|
|
124
124
|
let unitConversion;
|
|
125
125
|
if (convertFromUnit) {
|
|
126
|
-
unitConversion =
|
|
127
|
-
if (unitConversion.error) {
|
|
128
|
-
Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from "${convertFromUnit.name}" to "${unit[0].name}" could not be resolved.`);
|
|
129
|
-
}
|
|
126
|
+
unitConversion = yield* requestConversion(convertFromUnit, unit[0]);
|
|
130
127
|
}
|
|
131
128
|
else {
|
|
132
129
|
unitConversion = { factor: 1.0, offset: 0.0 };
|
|
@@ -157,14 +154,18 @@ export class FormatterSpec {
|
|
|
157
154
|
* @see BaseFormat.revolutionUnit
|
|
158
155
|
*/
|
|
159
156
|
static async create(name, format, unitsProvider, inputUnit) {
|
|
160
|
-
|
|
157
|
+
return runAsync(FormatterSpec.buildFormatterSpec(name, format, inputUnit), unitsProvider);
|
|
158
|
+
}
|
|
159
|
+
/** Create a `FormatterSpec` using a synchronous unit provider. */
|
|
160
|
+
static createSync(name, format, unitsProvider, inputUnit) {
|
|
161
|
+
return runSync(FormatterSpec.buildFormatterSpec(name, format, inputUnit), unitsProvider);
|
|
162
|
+
}
|
|
163
|
+
static *buildFormatterSpec(name, format, inputUnit) {
|
|
164
|
+
const conversions = yield* FormatterSpec.buildUnitConversions(format, inputUnit);
|
|
161
165
|
let azimuthBaseConversion;
|
|
162
166
|
if (format.azimuthBaseUnit !== undefined) {
|
|
163
167
|
if (inputUnit !== undefined) {
|
|
164
|
-
azimuthBaseConversion =
|
|
165
|
-
if (azimuthBaseConversion.error) {
|
|
166
|
-
Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from "${format.azimuthBaseUnit.name}" to "${inputUnit.name}" could not be resolved.`);
|
|
167
|
-
}
|
|
168
|
+
azimuthBaseConversion = yield* requestConversion(format.azimuthBaseUnit, inputUnit);
|
|
168
169
|
}
|
|
169
170
|
else {
|
|
170
171
|
azimuthBaseConversion = { factor: 1.0, offset: 0.0 };
|
|
@@ -173,10 +174,7 @@ export class FormatterSpec {
|
|
|
173
174
|
let revolutionConversion;
|
|
174
175
|
if (format.revolutionUnit !== undefined) {
|
|
175
176
|
if (inputUnit !== undefined) {
|
|
176
|
-
revolutionConversion =
|
|
177
|
-
if (revolutionConversion.error) {
|
|
178
|
-
Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from "${format.revolutionUnit.name}" to "${inputUnit.name}" could not be resolved.`);
|
|
179
|
-
}
|
|
177
|
+
revolutionConversion = yield* requestConversion(format.revolutionUnit, inputUnit);
|
|
180
178
|
}
|
|
181
179
|
else {
|
|
182
180
|
revolutionConversion = { factor: 1.0, offset: 0.0 };
|
|
@@ -189,4 +187,28 @@ export class FormatterSpec {
|
|
|
189
187
|
return Formatter.formatQuantity(magnitude, this);
|
|
190
188
|
}
|
|
191
189
|
}
|
|
190
|
+
function* requestConversion(fromUnit, toUnit) {
|
|
191
|
+
const conversion = yield [fromUnit, toUnit];
|
|
192
|
+
if (conversion.error) {
|
|
193
|
+
Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from "${fromUnit.name}" to "${toUnit.name}" could not be resolved.`);
|
|
194
|
+
}
|
|
195
|
+
return conversion;
|
|
196
|
+
}
|
|
197
|
+
async function runAsync(builder, unitsProvider) {
|
|
198
|
+
let step = builder.next();
|
|
199
|
+
while (!step.done)
|
|
200
|
+
step = builder.next(await unitsProvider.getConversion(...step.value));
|
|
201
|
+
return step.value;
|
|
202
|
+
}
|
|
203
|
+
function runSync(builder, unitsProvider) {
|
|
204
|
+
let step = builder.next();
|
|
205
|
+
while (!step.done)
|
|
206
|
+
step = builder.next(unitsProvider.getConversionSync(...step.value));
|
|
207
|
+
return step.value;
|
|
208
|
+
}
|
|
209
|
+
function createRatioConversionProps(ratioScaleFactor, sourceConversion) {
|
|
210
|
+
return sourceConversion.error
|
|
211
|
+
? { factor: ratioScaleFactor, offset: 0.0, error: true }
|
|
212
|
+
: { factor: ratioScaleFactor, offset: 0.0 };
|
|
213
|
+
}
|
|
192
214
|
//# sourceMappingURL=FormatterSpec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatterSpec.js","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"../Interfaces\";\r\nimport { QuantityLoggerCategory } from \"../QuantityLoggerCategory\";\r\nimport { Format } from \"./Format\";\r\nimport { FormatType } from \"./FormatEnums\";\r\nimport { Formatter } from \"./Formatter\";\r\n\r\n// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses\r\n// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative\r\n\r\n/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * Once created the FormatterSpec will be able to format quantity values with synchronous calls.\r\n * @beta\r\n */\r\nexport class FormatterSpec {\r\n protected _name: string;\r\n protected _conversions: UnitConversionSpec[] = []; // max four entries\r\n protected _format: Format;\r\n protected _persistenceUnit: UnitProps;\r\n protected _azimuthBaseConversion?: UnitConversionProps; // converts azimuth base unit to persistence unit\r\n protected _revolutionConversion?: UnitConversionProps; // converts revolution unit to persistence unit\r\n\r\n /** Constructor\r\n * @param name The name of a format specification.\r\n * @param format Defines the output format for the quantity value.\r\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * @param persistenceUnit The unit the magnitude value is input.\r\n * @param azimuthBaseConversion The conversion used to interpret azimuth base values.\r\n * @param revolutionConversion The conversion used to determine a revolution value (used for bearing and azimuth).\r\n */\r\n constructor(name: string, format: Format, conversions?: UnitConversionSpec[], persistenceUnit?: UnitProps, azimuthBaseConversion?: UnitConversionProps, revolutionConversion?: UnitConversionProps) {\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n this._name = name;\r\n this._format = format;\r\n this._persistenceUnit = persistenceUnit;\r\n if (conversions)\r\n this._conversions = conversions;\r\n this._azimuthBaseConversion = azimuthBaseConversion;\r\n this._revolutionConversion = revolutionConversion;\r\n }\r\n\r\n public get name(): string { return this._name; }\r\n /** Returns an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\r\n public get format(): Format { return this._format; }\r\n public get persistenceUnit(): UnitProps { return this._persistenceUnit; }\r\n public get azimuthBaseConversion(): UnitConversionProps | undefined { return this._azimuthBaseConversion; }\r\n public get revolutionConversion(): UnitConversionProps | undefined { return this._revolutionConversion; }\r\n\r\n /** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */\r\n private static async getRatioUnitConversions(units: ReadonlyArray<[UnitProps, string | undefined]>, unitsProvider: UnitsProvider, persistenceUnit: UnitProps): Promise<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n\r\n const [numeratorUnit, numeratorLabel] = units[0];\r\n const [denominatorUnit, denominatorLabel] = units[1];\r\n\r\n // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)\r\n const denominatorToNumerator = await unitsProvider.getConversion(denominatorUnit, numeratorUnit);\r\n if (denominatorToNumerator.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${denominatorUnit.name}\" to \"${numeratorUnit.name}\" could not be resolved.`);\r\n }\r\n const displayRatioScale = denominatorToNumerator.factor;\r\n\r\n // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.\r\n // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)\r\n const persistenceName = persistenceUnit.name.toUpperCase();\r\n const numName = numeratorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\r\n const denName = denominatorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\r\n // Split by word boundaries (underscores, dots) and check for exact token matches\r\n const persistenceTokens = persistenceName.split(/[._]/);\r\n const isPersistenceMatchingRatio = persistenceTokens.includes(numName) && persistenceTokens.includes(denName);\r\n const ratioScaleFactor = isPersistenceMatchingRatio ? 1.0 : displayRatioScale;\r\n\r\n // First conversion spec: effective ratio unit conversion\r\n const ratioConversionSpec: UnitConversionSpec = {\r\n name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,\r\n label: \"\",\r\n system: numeratorUnit.system,\r\n conversion: { factor: ratioScaleFactor, offset: 0.0 },\r\n };\r\n conversions.push(ratioConversionSpec);\r\n\r\n // Numerator unit for label lookup\r\n const numeratorSpec: UnitConversionSpec = {\r\n name: numeratorUnit.name,\r\n label: numeratorLabel?.length ? numeratorLabel : numeratorUnit.label,\r\n system: numeratorUnit.system,\r\n conversion: { factor: 1.0, offset: 0.0 },\r\n };\r\n conversions.push(numeratorSpec);\r\n\r\n // Denominator unit for label lookup\r\n const denominatorSpec: UnitConversionSpec = {\r\n name: denominatorUnit.name,\r\n label: denominatorLabel?.length ? denominatorLabel : denominatorUnit.label,\r\n system: denominatorUnit.system,\r\n conversion: { factor: 1.0, offset: 0.0 },\r\n };\r\n conversions.push(denominatorSpec);\r\n\r\n return conversions;\r\n }\r\n\r\n /** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public static async getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n let persistenceUnit = inputUnit;\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n // Handle 2-unit composite for ratio formats (scale factors)\r\n if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {\r\n return FormatterSpec.getRatioUnitConversions(format.units, unitsProvider, persistenceUnit);\r\n }\r\n\r\n if (format.units) {\r\n let convertFromUnit = inputUnit;\r\n for (const unit of format.units) {\r\n let unitConversion: UnitConversionProps;\r\n if (convertFromUnit) {\r\n unitConversion = await unitsProvider.getConversion(convertFromUnit, unit[0]);\r\n if (unitConversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${convertFromUnit.name}\" to \"${unit[0].name}\" could not be resolved.`);\r\n }\r\n } else {\r\n unitConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n const unitLabel = (unit[1] && unit[1].length > 0) ? unit[1] : unit[0].label;\r\n const spec = ({ name: unit[0].name, label: unitLabel, conversion: unitConversion, system: unit[0].system }) as UnitConversionSpec;\r\n\r\n conversions.push(spec);\r\n convertFromUnit = unit[0];\r\n }\r\n } else {\r\n // if format is only numeric and a input unit is defined set spec to use the input unit as the format unit\r\n if (inputUnit) {\r\n const spec: UnitConversionSpec = { name: inputUnit.name, label: inputUnit.label, system: inputUnit.system, conversion: { factor: 1.0, offset: 0.0 } };\r\n conversions.push(spec);\r\n }\r\n }\r\n\r\n return conversions;\r\n }\r\n\r\n /** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will\r\n * be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make\r\n * async calls to lookup unit definitions.\r\n * @param name The name of a format specification.\r\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\r\n * @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit.\r\n * @note For Bearing/Azimuth formats, `inputUnit`'s phenomenon must match `format.azimuthBaseUnit`/`format.revolutionUnit`.\r\n * @see BaseFormat.azimuthBaseUnit\r\n * @see BaseFormat.revolutionUnit\r\n */\r\n public static async create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec> {\r\n const conversions: UnitConversionSpec[] = await FormatterSpec.getUnitConversions(format, unitsProvider, inputUnit);\r\n let azimuthBaseConversion: UnitConversionProps | undefined;\r\n if (format.azimuthBaseUnit !== undefined) {\r\n if (inputUnit !== undefined) {\r\n azimuthBaseConversion = await unitsProvider.getConversion(format.azimuthBaseUnit, inputUnit);\r\n if (azimuthBaseConversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${format.azimuthBaseUnit.name}\" to \"${inputUnit.name}\" could not be resolved.`);\r\n }\r\n } else {\r\n azimuthBaseConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n }\r\n let revolutionConversion: UnitConversionProps | undefined;\r\n if (format.revolutionUnit !== undefined) {\r\n if (inputUnit !== undefined) {\r\n revolutionConversion = await unitsProvider.getConversion(format.revolutionUnit, inputUnit);\r\n if (revolutionConversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${format.revolutionUnit.name}\" to \"${inputUnit.name}\" could not be resolved.`);\r\n }\r\n } else {\r\n revolutionConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n }\r\n\r\n return new FormatterSpec(name, format, conversions, inputUnit, azimuthBaseConversion, revolutionConversion);\r\n }\r\n\r\n /** Format a quantity value. */\r\n public applyFormatting(magnitude: number): string {\r\n return Formatter.formatQuantity(magnitude, this);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"FormatterSpec.js","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { SyncUnitsProvider, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"../Interfaces\";\r\nimport { QuantityLoggerCategory } from \"../QuantityLoggerCategory\";\r\nimport { Format } from \"./Format\";\r\nimport { FormatType } from \"./FormatEnums\";\r\nimport { Formatter } from \"./Formatter\";\r\n\r\n// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses\r\n// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative\r\n\r\n/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * Once created the FormatterSpec will be able to format quantity values with synchronous calls.\r\n * @beta\r\n */\r\nexport class FormatterSpec {\r\n protected _name: string;\r\n protected _conversions: UnitConversionSpec[] = []; // max four entries\r\n protected _format: Format;\r\n protected _persistenceUnit: UnitProps;\r\n protected _azimuthBaseConversion?: UnitConversionProps; // converts azimuth base unit to persistence unit\r\n protected _revolutionConversion?: UnitConversionProps; // converts revolution unit to persistence unit\r\n\r\n /** Constructor\r\n * @param name The name of a format specification.\r\n * @param format Defines the output format for the quantity value.\r\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * @param persistenceUnit The unit the magnitude value is input.\r\n * @param azimuthBaseConversion The conversion used to interpret azimuth base values.\r\n * @param revolutionConversion The conversion used to determine a revolution value (used for bearing and azimuth).\r\n */\r\n constructor(name: string, format: Format, conversions?: UnitConversionSpec[], persistenceUnit?: UnitProps, azimuthBaseConversion?: UnitConversionProps, revolutionConversion?: UnitConversionProps) {\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n this._name = name;\r\n this._format = format;\r\n this._persistenceUnit = persistenceUnit;\r\n if (conversions)\r\n this._conversions = conversions;\r\n this._azimuthBaseConversion = azimuthBaseConversion;\r\n this._revolutionConversion = revolutionConversion;\r\n }\r\n\r\n public get name(): string { return this._name; }\r\n /** Returns an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\r\n public get format(): Format { return this._format; }\r\n public get persistenceUnit(): UnitProps { return this._persistenceUnit; }\r\n public get azimuthBaseConversion(): UnitConversionProps | undefined { return this._azimuthBaseConversion; }\r\n public get revolutionConversion(): UnitConversionProps | undefined { return this._revolutionConversion; }\r\n\r\n /** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */\r\n private static *buildRatioUnitConversions(units: ReadonlyArray<[UnitProps, string | undefined]>, persistenceUnit: UnitProps): ConversionBuilder<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n\r\n const [numeratorUnit, numeratorLabel] = units[0];\r\n const [denominatorUnit, denominatorLabel] = units[1];\r\n\r\n // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)\r\n const denominatorToNumerator = yield* requestConversion(denominatorUnit, numeratorUnit);\r\n const displayRatioScale = denominatorToNumerator.factor;\r\n\r\n // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.\r\n // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)\r\n const persistenceName = persistenceUnit.name.toUpperCase();\r\n const numName = numeratorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\r\n const denName = denominatorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\r\n // Split by word boundaries (underscores, dots) and check for exact token matches\r\n const persistenceTokens = persistenceName.split(/[._]/);\r\n const isPersistenceMatchingRatio = persistenceTokens.includes(numName) && persistenceTokens.includes(denName);\r\n const ratioScaleFactor = isPersistenceMatchingRatio ? 1.0 : displayRatioScale;\r\n\r\n // First conversion spec: effective ratio unit conversion\r\n const ratioConversionSpec: UnitConversionSpec = {\r\n name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,\r\n label: \"\",\r\n system: numeratorUnit.system,\r\n conversion: createRatioConversionProps(ratioScaleFactor, denominatorToNumerator),\r\n };\r\n conversions.push(ratioConversionSpec);\r\n\r\n // Numerator unit for label lookup\r\n const numeratorSpec: UnitConversionSpec = {\r\n name: numeratorUnit.name,\r\n label: numeratorLabel?.length ? numeratorLabel : numeratorUnit.label,\r\n system: numeratorUnit.system,\r\n conversion: { factor: 1.0, offset: 0.0 },\r\n };\r\n conversions.push(numeratorSpec);\r\n\r\n // Denominator unit for label lookup\r\n const denominatorSpec: UnitConversionSpec = {\r\n name: denominatorUnit.name,\r\n label: denominatorLabel?.length ? denominatorLabel : denominatorUnit.label,\r\n system: denominatorUnit.system,\r\n conversion: { factor: 1.0, offset: 0.0 },\r\n };\r\n conversions.push(denominatorSpec);\r\n\r\n return conversions;\r\n }\r\n\r\n /** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public static async getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]> {\r\n return runAsync(FormatterSpec.buildUnitConversions(format, inputUnit), unitsProvider);\r\n }\r\n\r\n private static *buildUnitConversions(format: Format, inputUnit?: UnitProps): ConversionBuilder<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n let persistenceUnit = inputUnit;\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n // Handle 2-unit composite for ratio formats (scale factors)\r\n if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {\r\n return yield* FormatterSpec.buildRatioUnitConversions(format.units, persistenceUnit);\r\n }\r\n\r\n if (format.units) {\r\n let convertFromUnit = inputUnit;\r\n for (const unit of format.units) {\r\n let unitConversion: UnitConversionProps;\r\n if (convertFromUnit) {\r\n unitConversion = yield* requestConversion(convertFromUnit, unit[0]);\r\n } else {\r\n unitConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n const unitLabel = (unit[1] && unit[1].length > 0) ? unit[1] : unit[0].label;\r\n const spec = ({ name: unit[0].name, label: unitLabel, conversion: unitConversion, system: unit[0].system }) as UnitConversionSpec;\r\n\r\n conversions.push(spec);\r\n convertFromUnit = unit[0];\r\n }\r\n } else {\r\n // if format is only numeric and a input unit is defined set spec to use the input unit as the format unit\r\n if (inputUnit) {\r\n const spec: UnitConversionSpec = { name: inputUnit.name, label: inputUnit.label, system: inputUnit.system, conversion: { factor: 1.0, offset: 0.0 } };\r\n conversions.push(spec);\r\n }\r\n }\r\n\r\n return conversions;\r\n }\r\n\r\n /** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will\r\n * be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make\r\n * async calls to lookup unit definitions.\r\n * @param name The name of a format specification.\r\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\r\n * @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit.\r\n * @note For Bearing/Azimuth formats, `inputUnit`'s phenomenon must match `format.azimuthBaseUnit`/`format.revolutionUnit`.\r\n * @see BaseFormat.azimuthBaseUnit\r\n * @see BaseFormat.revolutionUnit\r\n */\r\n public static async create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec> {\r\n return runAsync(FormatterSpec.buildFormatterSpec(name, format, inputUnit), unitsProvider);\r\n }\r\n\r\n /** Create a `FormatterSpec` using a synchronous unit provider. */\r\n public static createSync(name: string, format: Format, unitsProvider: SyncUnitsProvider, inputUnit?: UnitProps): FormatterSpec {\r\n return runSync(FormatterSpec.buildFormatterSpec(name, format, inputUnit), unitsProvider);\r\n }\r\n\r\n private static *buildFormatterSpec(name: string, format: Format, inputUnit?: UnitProps): ConversionBuilder<FormatterSpec> {\r\n const conversions: UnitConversionSpec[] = yield* FormatterSpec.buildUnitConversions(format, inputUnit);\r\n let azimuthBaseConversion: UnitConversionProps | undefined;\r\n if (format.azimuthBaseUnit !== undefined) {\r\n if (inputUnit !== undefined) {\r\n azimuthBaseConversion = yield* requestConversion(format.azimuthBaseUnit, inputUnit);\r\n } else {\r\n azimuthBaseConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n }\r\n let revolutionConversion: UnitConversionProps | undefined;\r\n if (format.revolutionUnit !== undefined) {\r\n if (inputUnit !== undefined) {\r\n revolutionConversion = yield* requestConversion(format.revolutionUnit, inputUnit);\r\n } else {\r\n revolutionConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n }\r\n\r\n return new FormatterSpec(name, format, conversions, inputUnit, azimuthBaseConversion, revolutionConversion);\r\n }\r\n\r\n /** Format a quantity value. */\r\n public applyFormatting(magnitude: number): string {\r\n return Formatter.formatQuantity(magnitude, this);\r\n }\r\n}\r\n\r\n/** Builds a value while yielding each unit conversion it needs, so the async and sync factories share one implementation. */\r\ntype ConversionBuilder<T> = Generator<[fromUnit: UnitProps, toUnit: UnitProps], T, UnitConversionProps>;\r\n\r\nfunction* requestConversion(fromUnit: UnitProps, toUnit: UnitProps): ConversionBuilder<UnitConversionProps> {\r\n const conversion = yield [fromUnit, toUnit];\r\n if (conversion.error) {\r\n Logger.logWarning(QuantityLoggerCategory.Formatting, `Unit conversion from \"${fromUnit.name}\" to \"${toUnit.name}\" could not be resolved.`);\r\n }\r\n return conversion;\r\n}\r\n\r\nasync function runAsync<T>(builder: ConversionBuilder<T>, unitsProvider: UnitsProvider): Promise<T> {\r\n let step = builder.next();\r\n while (!step.done)\r\n step = builder.next(await unitsProvider.getConversion(...step.value));\r\n return step.value;\r\n}\r\n\r\nfunction runSync<T>(builder: ConversionBuilder<T>, unitsProvider: SyncUnitsProvider): T {\r\n let step = builder.next();\r\n while (!step.done)\r\n step = builder.next(unitsProvider.getConversionSync(...step.value));\r\n return step.value;\r\n}\r\n\r\nfunction createRatioConversionProps(ratioScaleFactor: number, sourceConversion: UnitConversionProps): UnitConversionProps {\r\n return sourceConversion.error\r\n ? { factor: ratioScaleFactor, offset: 0.0, error: true }\r\n : { factor: ratioScaleFactor, offset: 0.0 };\r\n}\r\n"]}
|
|
@@ -65,7 +65,10 @@ export interface FormatProps {
|
|
|
65
65
|
readonly scientificType?: string;
|
|
66
66
|
/** Required when type is Ratio. See [[RatioType]]*/
|
|
67
67
|
readonly ratioType?: string;
|
|
68
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* The separator string used for ratio formatting. Defaults to ":".
|
|
70
|
+
* @note The separator may contain one non-space character, optionally surrounded by spaces.
|
|
71
|
+
*/
|
|
69
72
|
readonly ratioSeparator?: string;
|
|
70
73
|
/** The format type for the numbers within a ratio. Defaults to "Decimal". */
|
|
71
74
|
readonly ratioFormatType?: string;
|
|
@@ -168,20 +171,42 @@ export interface FormatsChangedArgs {
|
|
|
168
171
|
*/
|
|
169
172
|
impliedUnitSystem?: UnitSystemKey;
|
|
170
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Context passed through a chain of providers while resolving one format request.
|
|
176
|
+
* A provider that delegates the current request must forward this context unchanged; omit it only when starting an independent request.
|
|
177
|
+
* @beta
|
|
178
|
+
*/
|
|
179
|
+
export interface FormatsProviderContext {
|
|
180
|
+
/** Providers already visited while resolving the current format request. */
|
|
181
|
+
readonly providerChain: ReadonlySet<FormatsProvider>;
|
|
182
|
+
}
|
|
171
183
|
/** This interface is implemented by a class that would provide formats for use in formatting quantities.
|
|
172
184
|
* @beta
|
|
173
185
|
*/
|
|
174
186
|
export interface FormatsProvider {
|
|
175
187
|
/**
|
|
176
188
|
* @param name The full name of the Format or KindOfQuantity.
|
|
189
|
+
* @param context Optional context to forward when delegating the current lookup through another provider.
|
|
177
190
|
*/
|
|
178
|
-
getFormat(name: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined>;
|
|
191
|
+
getFormat(name: string, system?: UnitSystemKey, context?: FormatsProviderContext): Promise<FormatDefinition | undefined>;
|
|
179
192
|
/**
|
|
180
193
|
* Fired when formats are added, removed, or changed.
|
|
181
194
|
* If all formats are changed, a single string "all" is emitted. Else, an array of changed format names is emitted.
|
|
182
195
|
*/
|
|
183
196
|
onFormatsChanged: BeEvent<(args: FormatsChangedArgs) => void>;
|
|
184
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Optional capability for providers that can resolve format definitions from local data without awaiting.
|
|
200
|
+
* @note Implementations should use already-loaded local data and avoid schema loading or asynchronous I/O from this method.
|
|
201
|
+
* @beta
|
|
202
|
+
*/
|
|
203
|
+
export interface SyncFormatsProvider {
|
|
204
|
+
/**
|
|
205
|
+
* Return a locally available format definition, or `undefined` when unavailable.
|
|
206
|
+
* @param context Optional context to forward when delegating the current lookup through another provider.
|
|
207
|
+
*/
|
|
208
|
+
getFormatSync(name: string, system?: UnitSystemKey, context?: FormatsProviderContext): FormatDefinition | undefined;
|
|
209
|
+
}
|
|
185
210
|
/** This interface is implemented by a class that would provide and allow creating formats for use in formatting quantities.
|
|
186
211
|
* @beta
|
|
187
212
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yGAAyG;IACzG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,wBAAwB;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,oEAAoE;IACpE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,sHAAsH;IACtH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;sGACkG;IAClG,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,6GAA6G;IAC7G,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,mHAAmH;IACnH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B,+GAA+G;IAC/G,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,qFAAqF;IACrF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC,gFAAgF;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE1C,8FAA8F;IAC9F,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC,+FAA+F;IAC/F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC,mGAAmG;IACnG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC,oDAAoD;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAgIH;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAiB,EAA6B,EAAE;IAClF,OAAQ,IAA0B,CAAC,MAAM,KAAK,SAAS,CAAC;AAC1D,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { BeEvent, BeUnorderedUiEvent } from \"@itwin/core-bentley\";\r\nimport { UnitProps, UnitSystemKey } from \"../Interfaces\";\r\nimport { DecimalPrecision, FormatTraits, FormatType, FractionalPrecision } from \"./FormatEnums\";\r\nimport type { FormatterSpec } from \"./FormatterSpec\";\r\nimport type { ParserSpec } from \"../ParserSpec\";\r\n\r\n/** Defines a unit specification with a name and optional label override.\r\n * Used in composite formats and ratio unit specifications.\r\n * @beta\r\n */\r\nexport interface FormatUnitSpec {\r\n /** The name of the unit (e.g., \"Units.FT\", \"Units.IN\") */\r\n readonly name: string;\r\n /** Optional custom label that overrides the unit's default label (e.g., '\"' for inches, \"'\" for feet) */\r\n readonly label?: string;\r\n}\r\n\r\n/** A resolved [[FormatUnitSpec]] with the unit name replaced with the resolved UnitProps.\r\n * @beta\r\n */\r\nexport interface ResolvedFormatUnitSpec {\r\n /** The resolved unit */\r\n readonly unit: UnitProps;\r\n /** Optional custom label that overrides the unit's default label */\r\n readonly label?: string;\r\n}\r\n\r\n/** Defines the units that make up a composite format and their display properties.\r\n * A composite format allows displaying a single quantity value across multiple units,\r\n * such as displaying length as \"5 feet 6 inches\" or angle as \"45° 30' 15\"\".\r\n * @beta\r\n */\r\nexport interface FormatCompositeProps {\r\n /** Separator character between unit values when formatting composite strings. Must be empty or a single character. */\r\n readonly spacer?: string;\r\n /** Whether to include unit segments with zero magnitude in the formatted output. */\r\n readonly includeZero?: boolean;\r\n /** Array of units this format is comprised of. Each unit specifies the unit name and\r\n * an optional custom label that will override the unit's default label when displaying values. */\r\n readonly units: FormatUnitSpec[];\r\n}\r\n\r\n/** This interface defines the persistence format for describing the formatting of quantity values.\r\n * @beta\r\n */\r\nexport interface FormatProps {\r\n /** The format type. See [[FormatType]] */\r\n readonly type: string;\r\n\r\n /** The precision for the format. Must be an integer. See [[DecimalPrecision]] and [[FractionalPrecision]] */\r\n readonly precision?: number;\r\n\r\n /** Value is rounded to a multiple of this factor if nonzero and the `applyRounding` trait is set, defaults to 0 */\r\n readonly roundFactor?: number;\r\n\r\n /** Minimum width of the formatted output including digits and separators. Must be a positive integer (≥ 0). */\r\n readonly minWidth?: number;\r\n\r\n /** How and when positive and negative signs are displayed. See [[ShowSignOption]] */\r\n readonly showSignOption?: string;\r\n\r\n /** Array of format traits controlling display behavior. See [[FormatTraits]] */\r\n readonly formatTraits?: string | string[];\r\n\r\n /** Character separating integer from fractional part. Must be empty or a single character. */\r\n readonly decimalSeparator?: string;\r\n\r\n /** Character separating thousands in the integer part. Must be empty or a single character. */\r\n readonly thousandSeparator?: string;\r\n\r\n /** Character separating the magnitude from the unit label. Must be empty or a single character. */\r\n readonly uomSeparator?: string;\r\n\r\n /** Required when type is Scientific. See [[ScientificType]] */\r\n readonly scientificType?: string;\r\n\r\n /** Required when type is Ratio. See [[RatioType]]*/\r\n readonly ratioType?: string;\r\n /** The separator character for ratio formatting. Defaults to ':' if not specified. */\r\n readonly ratioSeparator?: string;\r\n /** The format type for the numbers within a ratio. Defaults to \"Decimal\". */\r\n readonly ratioFormatType?: string;\r\n\r\n /** Required when type is Station. Number of decimal places for calculating station offset magnitude. Must be a positive integer > 0. */\r\n readonly stationOffsetSize?: number;\r\n\r\n /** Character separating station and offset portions of a Station formatted value. Must be empty or a single character. */\r\n readonly stationSeparator?: string;\r\n\r\n /** Optional base factor for station formatting. A positive integer, defaults to 1. */\r\n readonly stationBaseFactor?: number;\r\n\r\n /** The base value for azimuth, specified from east counter-clockwise. */\r\n readonly azimuthBase?: number;\r\n\r\n /** The name of the unit for the azimuth base value. Required if azimuthBase is set.\r\n * @note Must share the same phenomenon as the persistence unit the Format/FormatterSpec/ParserSpec is used with (e.g. a `Units.HORIZONTAL_DIRECTION`\r\n * unit for a `Units.HORIZONTAL_DIRECTION` persistence unit, or a `Units.ANGLE` unit for a `Units.ANGLE` persistence unit) - the units provider\r\n * cannot convert between different phenomena, so a mismatch will fail to resolve.\r\n */\r\n readonly azimuthBaseUnit?: string;\r\n\r\n /** If set to true, azimuth values are returned counter-clockwise from the base. */\r\n readonly azimuthCounterClockwise?: boolean;\r\n\r\n /** The name of the unit that represents a revolution/perigon. Required for bearing or azimuth types.\r\n * @note Must share the same phenomenon as the persistence unit the Format/FormatterSpec/ParserSpec is used with (e.g. `Units.HORIZONTAL_DIR_REVOLUTION`\r\n * for a `Units.HORIZONTAL_DIRECTION` persistence unit, or `Units.REVOLUTION` for a `Units.ANGLE` persistence unit) - the units provider cannot\r\n * convert between different phenomena, so a mismatch will fail to resolve.\r\n */\r\n readonly revolutionUnit?: string;\r\n\r\n /** Enables calculating mathematic operations during parsing; only addition and subtraction are supported. */\r\n readonly allowMathematicOperations?: boolean;\r\n\r\n /** Composite format specification for multi-unit display. */\r\n readonly composite?: FormatCompositeProps;\r\n}\r\n\r\n/** This interface is used when supporting Custom Formatters that need more than the standard set of properties.\r\n * @beta\r\n */\r\nexport interface CustomFormatProps extends FormatProps {\r\n readonly custom: any;\r\n}\r\n\r\n/** CustomFormatProps type guard.\r\n * @beta\r\n */\r\nexport const isCustomFormatProps = (item: FormatProps): item is CustomFormatProps => {\r\n return (item as CustomFormatProps).custom !== undefined;\r\n};\r\n\r\n/** A [[FormatCompositeProps]] with unit names replaced with JSON representations of those units.\r\n * @beta\r\n */\r\nexport type ResolvedFormatCompositeProps = Omit<FormatCompositeProps, \"units\"> & {\r\n readonly units: ResolvedFormatUnitSpec[];\r\n};\r\n\r\n/** A [[FormatProps]] with all the references to units replaced with JSON representations of those units.\r\n * @beta\r\n */\r\nexport type ResolvedFormatProps = Omit<FormatDefinition, \"azimuthBaseUnit\" | \"revolutionUnit\" | \"composite\"> & {\r\n readonly azimuthBaseUnit?: UnitProps;\r\n readonly revolutionUnit?: UnitProps;\r\n readonly composite?: ResolvedFormatCompositeProps;\r\n readonly custom?: any;\r\n};\r\n\r\n/** CloneFormat defines unit and label specification if primary unit is to be set during clone.\r\n * @beta\r\n */\r\nexport interface CloneUnit {\r\n unit?: UnitProps;\r\n label?: string;\r\n}\r\n\r\n/** CloneOptions that define modifications that can be made during the cloning of a Format.\r\n * @beta\r\n */\r\nexport interface CloneOptions {\r\n /** allows composite formats to be converted to only show primary unit */\r\n showOnlyPrimaryUnit?: boolean;\r\n /** allow format traits to be set */\r\n traits?: FormatTraits;\r\n /** allows new FormatType to be specified */\r\n type?: FormatType;\r\n /** allows precision to be set, this will throw if value is not valid for FormatType */\r\n precision?: DecimalPrecision | FractionalPrecision;\r\n /** allows primary unit and label to be specified */\r\n primaryUnit?: CloneUnit;\r\n}\r\n\r\n/** An extension of FormatProps to help identify formats.\r\n * @beta\r\n */\r\nexport interface FormatDefinition extends FormatProps {\r\n readonly name?: string;\r\n readonly label?: string;\r\n readonly description?: string;\r\n}\r\n\r\n/** Argument for [[FormatsProvider.onFormatsChanged]]\r\n * @beta\r\n */\r\nexport interface FormatsChangedArgs {\r\n /**\r\n * If `all` - all formats within the `FormatsProvider` have changed.\r\n * If array, the array items list the names of formats that were changed or removed.\r\n */\r\n formatsChanged: \"all\" | string[];\r\n /** If set, indicates that the format set implies a particular unit system. The consumer\r\n * (e.g., QuantityFormatter) will synchronize the active unit system to match.\r\n * If `undefined`, the format change does not imply a unit system switch — the active\r\n * unit system remains unchanged.\r\n * @beta\r\n */\r\n impliedUnitSystem?: UnitSystemKey;\r\n}\r\n\r\n/** This interface is implemented by a class that would provide formats for use in formatting quantities.\r\n * @beta\r\n */\r\nexport interface FormatsProvider {\r\n /**\r\n * @param name The full name of the Format or KindOfQuantity.\r\n */\r\n getFormat(name: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined>;\r\n\r\n /**\r\n * Fired when formats are added, removed, or changed.\r\n * If all formats are changed, a single string \"all\" is emitted. Else, an array of changed format names is emitted.\r\n */\r\n onFormatsChanged: BeEvent<(args: FormatsChangedArgs) => void>;\r\n}\r\n\r\n/** This interface is implemented by a class that would provide and allow creating formats for use in formatting quantities.\r\n * @beta\r\n */\r\nexport interface MutableFormatsProvider extends FormatsProvider {\r\n /**\r\n * Adds a new format or updates an existing format associated with the specified name.\r\n */\r\n addFormat(name: string, format: FormatDefinition): Promise<void>;\r\n /**\r\n * Removes the format associated with the specified name.\r\n * @param name The name of the format to remove.\r\n */\r\n removeFormat(name: string): Promise<void>;\r\n}\r\n\r\n/** Entries returned when looking up specs from the format registry.\r\n * @beta\r\n */\r\nexport interface FormattingSpecEntry {\r\n formatterSpec: FormatterSpec;\r\n parserSpec: ParserSpec;\r\n}\r\n\r\n/** Arguments for looking up a formatting spec entry.\r\n * @beta\r\n */\r\nexport interface FormattingSpecArgs {\r\n /** The KoQ name to look up. */\r\n name: string;\r\n /** The persistence unit name (e.g., `\"Units.M\"`). */\r\n persistenceUnitName: string;\r\n /** Optional unit system override. When omitted, the active system is used. */\r\n system?: UnitSystemKey;\r\n}\r\n\r\n/** Arguments for registering a formatting spec entry.\r\n * @beta\r\n */\r\nexport interface AddFormattingSpecArgs extends FormattingSpecArgs {\r\n /** Format properties to use. When omitted, the provider resolves them from the KoQ schema. */\r\n formatProps?: FormatProps;\r\n}\r\n\r\n/** Minimal contract required by [[FormatSpecHandle]] to look up current specs and expose formatting readiness.\r\n * Implemented by [[QuantityFormatter]] in `@itwin/core-frontend`.\r\n * @beta\r\n */\r\nexport interface FormattingSpecProvider {\r\n /** Look up a formatting spec entry by KoQ name and persistence unit. */\r\n getSpecsByNameAndUnit(args: FormattingSpecArgs): FormattingSpecEntry | undefined;\r\n /** Format a numeric value using the given formatter spec. */\r\n formatQuantity(magnitude: number, formatSpec: FormatterSpec): string;\r\n /** Event raised after the provider has finished reloading its caches.\r\n * Uses Set-backed event for safe concurrent add/remove during emit.\r\n */\r\n readonly onFormattingReady: BeUnorderedUiEvent<void>;\r\n}\r\n\r\n"]}
|
|
1
|
+
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAmIH;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAiB,EAA6B,EAAE;IAClF,OAAQ,IAA0B,CAAC,MAAM,KAAK,SAAS,CAAC;AAC1D,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { BeEvent, BeUnorderedUiEvent } from \"@itwin/core-bentley\";\r\nimport { UnitProps, UnitSystemKey } from \"../Interfaces\";\r\nimport { DecimalPrecision, FormatTraits, FormatType, FractionalPrecision } from \"./FormatEnums\";\r\nimport type { FormatterSpec } from \"./FormatterSpec\";\r\nimport type { ParserSpec } from \"../ParserSpec\";\r\n\r\n/** Defines a unit specification with a name and optional label override.\r\n * Used in composite formats and ratio unit specifications.\r\n * @beta\r\n */\r\nexport interface FormatUnitSpec {\r\n /** The name of the unit (e.g., \"Units.FT\", \"Units.IN\") */\r\n readonly name: string;\r\n /** Optional custom label that overrides the unit's default label (e.g., '\"' for inches, \"'\" for feet) */\r\n readonly label?: string;\r\n}\r\n\r\n/** A resolved [[FormatUnitSpec]] with the unit name replaced with the resolved UnitProps.\r\n * @beta\r\n */\r\nexport interface ResolvedFormatUnitSpec {\r\n /** The resolved unit */\r\n readonly unit: UnitProps;\r\n /** Optional custom label that overrides the unit's default label */\r\n readonly label?: string;\r\n}\r\n\r\n/** Defines the units that make up a composite format and their display properties.\r\n * A composite format allows displaying a single quantity value across multiple units,\r\n * such as displaying length as \"5 feet 6 inches\" or angle as \"45° 30' 15\"\".\r\n * @beta\r\n */\r\nexport interface FormatCompositeProps {\r\n /** Separator character between unit values when formatting composite strings. Must be empty or a single character. */\r\n readonly spacer?: string;\r\n /** Whether to include unit segments with zero magnitude in the formatted output. */\r\n readonly includeZero?: boolean;\r\n /** Array of units this format is comprised of. Each unit specifies the unit name and\r\n * an optional custom label that will override the unit's default label when displaying values. */\r\n readonly units: FormatUnitSpec[];\r\n}\r\n\r\n/** This interface defines the persistence format for describing the formatting of quantity values.\r\n * @beta\r\n */\r\nexport interface FormatProps {\r\n /** The format type. See [[FormatType]] */\r\n readonly type: string;\r\n\r\n /** The precision for the format. Must be an integer. See [[DecimalPrecision]] and [[FractionalPrecision]] */\r\n readonly precision?: number;\r\n\r\n /** Value is rounded to a multiple of this factor if nonzero and the `applyRounding` trait is set, defaults to 0 */\r\n readonly roundFactor?: number;\r\n\r\n /** Minimum width of the formatted output including digits and separators. Must be a positive integer (≥ 0). */\r\n readonly minWidth?: number;\r\n\r\n /** How and when positive and negative signs are displayed. See [[ShowSignOption]] */\r\n readonly showSignOption?: string;\r\n\r\n /** Array of format traits controlling display behavior. See [[FormatTraits]] */\r\n readonly formatTraits?: string | string[];\r\n\r\n /** Character separating integer from fractional part. Must be empty or a single character. */\r\n readonly decimalSeparator?: string;\r\n\r\n /** Character separating thousands in the integer part. Must be empty or a single character. */\r\n readonly thousandSeparator?: string;\r\n\r\n /** Character separating the magnitude from the unit label. Must be empty or a single character. */\r\n readonly uomSeparator?: string;\r\n\r\n /** Required when type is Scientific. See [[ScientificType]] */\r\n readonly scientificType?: string;\r\n\r\n /** Required when type is Ratio. See [[RatioType]]*/\r\n readonly ratioType?: string;\r\n/**\r\n * The separator string used for ratio formatting. Defaults to \":\".\r\n * @note The separator may contain one non-space character, optionally surrounded by spaces.\r\n */\r\n readonly ratioSeparator?: string;\r\n /** The format type for the numbers within a ratio. Defaults to \"Decimal\". */\r\n readonly ratioFormatType?: string;\r\n\r\n /** Required when type is Station. Number of decimal places for calculating station offset magnitude. Must be a positive integer > 0. */\r\n readonly stationOffsetSize?: number;\r\n\r\n /** Character separating station and offset portions of a Station formatted value. Must be empty or a single character. */\r\n readonly stationSeparator?: string;\r\n\r\n /** Optional base factor for station formatting. A positive integer, defaults to 1. */\r\n readonly stationBaseFactor?: number;\r\n\r\n /** The base value for azimuth, specified from east counter-clockwise. */\r\n readonly azimuthBase?: number;\r\n\r\n /** The name of the unit for the azimuth base value. Required if azimuthBase is set.\r\n * @note Must share the same phenomenon as the persistence unit the Format/FormatterSpec/ParserSpec is used with (e.g. a `Units.HORIZONTAL_DIRECTION`\r\n * unit for a `Units.HORIZONTAL_DIRECTION` persistence unit, or a `Units.ANGLE` unit for a `Units.ANGLE` persistence unit) - the units provider\r\n * cannot convert between different phenomena, so a mismatch will fail to resolve.\r\n */\r\n readonly azimuthBaseUnit?: string;\r\n\r\n /** If set to true, azimuth values are returned counter-clockwise from the base. */\r\n readonly azimuthCounterClockwise?: boolean;\r\n\r\n /** The name of the unit that represents a revolution/perigon. Required for bearing or azimuth types.\r\n * @note Must share the same phenomenon as the persistence unit the Format/FormatterSpec/ParserSpec is used with (e.g. `Units.HORIZONTAL_DIR_REVOLUTION`\r\n * for a `Units.HORIZONTAL_DIRECTION` persistence unit, or `Units.REVOLUTION` for a `Units.ANGLE` persistence unit) - the units provider cannot\r\n * convert between different phenomena, so a mismatch will fail to resolve.\r\n */\r\n readonly revolutionUnit?: string;\r\n\r\n /** Enables calculating mathematic operations during parsing; only addition and subtraction are supported. */\r\n readonly allowMathematicOperations?: boolean;\r\n\r\n /** Composite format specification for multi-unit display. */\r\n readonly composite?: FormatCompositeProps;\r\n}\r\n\r\n/** This interface is used when supporting Custom Formatters that need more than the standard set of properties.\r\n * @beta\r\n */\r\nexport interface CustomFormatProps extends FormatProps {\r\n readonly custom: any;\r\n}\r\n\r\n/** CustomFormatProps type guard.\r\n * @beta\r\n */\r\nexport const isCustomFormatProps = (item: FormatProps): item is CustomFormatProps => {\r\n return (item as CustomFormatProps).custom !== undefined;\r\n};\r\n\r\n/** A [[FormatCompositeProps]] with unit names replaced with JSON representations of those units.\r\n * @beta\r\n */\r\nexport type ResolvedFormatCompositeProps = Omit<FormatCompositeProps, \"units\"> & {\r\n readonly units: ResolvedFormatUnitSpec[];\r\n};\r\n\r\n/** A [[FormatProps]] with all the references to units replaced with JSON representations of those units.\r\n * @beta\r\n */\r\nexport type ResolvedFormatProps = Omit<FormatDefinition, \"azimuthBaseUnit\" | \"revolutionUnit\" | \"composite\"> & {\r\n readonly azimuthBaseUnit?: UnitProps;\r\n readonly revolutionUnit?: UnitProps;\r\n readonly composite?: ResolvedFormatCompositeProps;\r\n readonly custom?: any;\r\n};\r\n\r\n/** CloneFormat defines unit and label specification if primary unit is to be set during clone.\r\n * @beta\r\n */\r\nexport interface CloneUnit {\r\n unit?: UnitProps;\r\n label?: string;\r\n}\r\n\r\n/** CloneOptions that define modifications that can be made during the cloning of a Format.\r\n * @beta\r\n */\r\nexport interface CloneOptions {\r\n /** allows composite formats to be converted to only show primary unit */\r\n showOnlyPrimaryUnit?: boolean;\r\n /** allow format traits to be set */\r\n traits?: FormatTraits;\r\n /** allows new FormatType to be specified */\r\n type?: FormatType;\r\n /** allows precision to be set, this will throw if value is not valid for FormatType */\r\n precision?: DecimalPrecision | FractionalPrecision;\r\n /** allows primary unit and label to be specified */\r\n primaryUnit?: CloneUnit;\r\n}\r\n\r\n/** An extension of FormatProps to help identify formats.\r\n * @beta\r\n */\r\nexport interface FormatDefinition extends FormatProps {\r\n readonly name?: string;\r\n readonly label?: string;\r\n readonly description?: string;\r\n}\r\n\r\n/** Argument for [[FormatsProvider.onFormatsChanged]]\r\n * @beta\r\n */\r\nexport interface FormatsChangedArgs {\r\n /**\r\n * If `all` - all formats within the `FormatsProvider` have changed.\r\n * If array, the array items list the names of formats that were changed or removed.\r\n */\r\n formatsChanged: \"all\" | string[];\r\n /** If set, indicates that the format set implies a particular unit system. The consumer\r\n * (e.g., QuantityFormatter) will synchronize the active unit system to match.\r\n * If `undefined`, the format change does not imply a unit system switch — the active\r\n * unit system remains unchanged.\r\n * @beta\r\n */\r\n impliedUnitSystem?: UnitSystemKey;\r\n}\r\n\r\n/**\r\n * Context passed through a chain of providers while resolving one format request.\r\n * A provider that delegates the current request must forward this context unchanged; omit it only when starting an independent request.\r\n * @beta\r\n */\r\nexport interface FormatsProviderContext {\r\n /** Providers already visited while resolving the current format request. */\r\n readonly providerChain: ReadonlySet<FormatsProvider>;\r\n}\r\n\r\n/** This interface is implemented by a class that would provide formats for use in formatting quantities.\r\n * @beta\r\n */\r\nexport interface FormatsProvider {\r\n /**\r\n * @param name The full name of the Format or KindOfQuantity.\r\n * @param context Optional context to forward when delegating the current lookup through another provider.\r\n */\r\n getFormat(name: string, system?: UnitSystemKey, context?: FormatsProviderContext): Promise<FormatDefinition | undefined>;\r\n\r\n /**\r\n * Fired when formats are added, removed, or changed.\r\n * If all formats are changed, a single string \"all\" is emitted. Else, an array of changed format names is emitted.\r\n */\r\n onFormatsChanged: BeEvent<(args: FormatsChangedArgs) => void>;\r\n}\r\n\r\n/**\r\n * Optional capability for providers that can resolve format definitions from local data without awaiting.\r\n * @note Implementations should use already-loaded local data and avoid schema loading or asynchronous I/O from this method.\r\n * @beta\r\n */\r\nexport interface SyncFormatsProvider {\r\n /**\r\n * Return a locally available format definition, or `undefined` when unavailable.\r\n * @param context Optional context to forward when delegating the current lookup through another provider.\r\n */\r\n getFormatSync(name: string, system?: UnitSystemKey, context?: FormatsProviderContext): FormatDefinition | undefined;\r\n}\r\n\r\n/** This interface is implemented by a class that would provide and allow creating formats for use in formatting quantities.\r\n * @beta\r\n */\r\nexport interface MutableFormatsProvider extends FormatsProvider {\r\n /**\r\n * Adds a new format or updates an existing format associated with the specified name.\r\n */\r\n addFormat(name: string, format: FormatDefinition): Promise<void>;\r\n /**\r\n * Removes the format associated with the specified name.\r\n * @param name The name of the format to remove.\r\n */\r\n removeFormat(name: string): Promise<void>;\r\n}\r\n\r\n/** Entries returned when looking up specs from the format registry.\r\n * @beta\r\n */\r\nexport interface FormattingSpecEntry {\r\n formatterSpec: FormatterSpec;\r\n parserSpec: ParserSpec;\r\n}\r\n\r\n/** Arguments for looking up a formatting spec entry.\r\n * @beta\r\n */\r\nexport interface FormattingSpecArgs {\r\n /** The KoQ name to look up. */\r\n name: string;\r\n /** The persistence unit name (e.g., `\"Units.M\"`). */\r\n persistenceUnitName: string;\r\n /** Optional unit system override. When omitted, the active system is used. */\r\n system?: UnitSystemKey;\r\n}\r\n\r\n/** Arguments for registering a formatting spec entry.\r\n * @beta\r\n */\r\nexport interface AddFormattingSpecArgs extends FormattingSpecArgs {\r\n /** Format properties to use. When omitted, the provider resolves them from the KoQ schema. */\r\n formatProps?: FormatProps;\r\n}\r\n\r\n/** Minimal contract required by [[FormatSpecHandle]] to look up current specs and expose formatting readiness.\r\n * Implemented by [[QuantityFormatter]] in `@itwin/core-frontend`.\r\n * @beta\r\n */\r\nexport interface FormattingSpecProvider {\r\n /** Look up a formatting spec entry by KoQ name and persistence unit. */\r\n getSpecsByNameAndUnit(args: FormattingSpecArgs): FormattingSpecEntry | undefined;\r\n /** Format a numeric value using the given formatter spec. */\r\n formatQuantity(magnitude: number, formatSpec: FormatterSpec): string;\r\n /** Event raised after the provider has finished reloading its caches.\r\n * Uses Set-backed event for safe concurrent add/remove during emit.\r\n */\r\n readonly onFormattingReady: BeUnorderedUiEvent<void>;\r\n}\r\n\r\n"]}
|
package/lib/esm/Interfaces.d.ts
CHANGED
|
@@ -106,6 +106,20 @@ export interface UnitsProvider {
|
|
|
106
106
|
*/
|
|
107
107
|
getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Optional capability for providers that can resolve units and conversions from local data without awaiting.
|
|
111
|
+
* @note Implementations should use already-loaded local data and avoid schema loading or asynchronous I/O from these methods.
|
|
112
|
+
* @beta
|
|
113
|
+
*/
|
|
114
|
+
export interface SyncUnitsProvider {
|
|
115
|
+
/** Find a unit by fully qualified name using local data. */
|
|
116
|
+
findUnitByNameSync(unitName: string): UnitProps;
|
|
117
|
+
/**
|
|
118
|
+
* Compute conversion factors using local data.
|
|
119
|
+
* @note On failure, implementations should return `{ factor: 1.0, offset: 0.0, error: true }`.
|
|
120
|
+
*/
|
|
121
|
+
getConversionSync(fromUnit: UnitProps, toUnit: UnitProps): UnitConversionProps;
|
|
122
|
+
}
|
|
109
123
|
/**
|
|
110
124
|
* Identifies a user-facing unit system preference group.
|
|
111
125
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../src/Interfaces.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sBAAsB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;CACnE;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wHAAwH;IACxH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uGAAuG;IACvG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,EAAE,mBAAmB,CAAC;IAChC,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,oBAAY,oBAAoB;IAC9B,mGAAmG;IACnG,mBAAmB,wBAAwB;IAC3C,gGAAgG;IAChG,oBAAoB,yBAAyB;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/G,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3D,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD;;;;;;OAMG;IACH,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACrF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../src/Interfaces.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sBAAsB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;CACnE;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wHAAwH;IACxH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uGAAuG;IACvG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,EAAE,mBAAmB,CAAC;IAChC,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,oBAAY,oBAAoB;IAC9B,mGAAmG;IACnG,mBAAmB,wBAAwB;IAC3C,gGAAgG;IAChG,oBAAoB,yBAAyB;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/G,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3D,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD;;;;;;OAMG;IACH,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACrF;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,mBAAmB,CAAC;CAChF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../src/Interfaces.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAmDH;;GAEG;AACH,MAAM,CAAN,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,mGAAmG;IACnG,mEAA2C,CAAA;IAC3C,gGAAgG;IAChG,qEAA6C,CAAA;AAC/C,CAAC,EALW,oBAAoB,KAApB,oBAAoB,QAK/B","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\n/** This interface allows a provider to be specified that will define an array of alternate labels for a specific unit.\r\n * @beta\r\n */\r\nexport interface AlternateUnitLabelsProvider {\r\n getAlternateUnitLabels: (unit: UnitProps) => string[] | undefined;\r\n}\r\n\r\n/** This interface provides basic information about a Unit that is return from a UnitProvider. This info\r\n * uniquely identifies a unit by its name.\r\n * @beta\r\n */\r\nexport interface UnitProps {\r\n /** Unique name for unit. */\r\n readonly name: string;\r\n /** Default label for unit. */\r\n readonly label: string;\r\n /** Unique name of unit phenomenon. Example phenomenon names include 'Units.LENGTH', 'Units.AREA', and 'Units.VOLUME' */\r\n readonly phenomenon: string;\r\n /** This is set to true if the Unit is known by the UnitsProvider. */\r\n readonly isValid: boolean;\r\n /** Unique system name. Example \"Units.USCUSTOM\",\" Units.METRIC\", \"Units.USSURVEY\", \"Units.IMPERIAL\" */\r\n readonly system: string;\r\n}\r\n\r\n/** This interface defines the required properties of a Quantity.\r\n * @beta\r\n */\r\nexport interface QuantityProps {\r\n readonly magnitude: number;\r\n readonly unit: UnitProps;\r\n readonly isValid: boolean;\r\n}\r\n\r\n/** Interface that defines how to convert between a specific unit an another in synchronous formatting or parsing processing.\r\n * @beta\r\n */\r\nexport interface UnitConversionSpec {\r\n /** Unit name that was used to locate the unit by the Unit Provider */\r\n name: string;\r\n /** The default label that is used to display unit */\r\n label: string;\r\n /** Unit system name, used to when finding preferred parse unit */\r\n system: string;\r\n /** the information necessary to convert the unit to a specific display unit */\r\n conversion: UnitConversionProps;\r\n /** Labels that may be used to represent the unit in a string that is to be parsed. */\r\n parseLabels?: string[];\r\n}\r\n\r\n/** Indicates the way in which unit values are inverted during conversion\r\n * @beta\r\n */\r\nexport enum UnitConversionInvert {\r\n /** Invert value before applying the other conversion steps (the from-unit is the inverted unit) */\r\n InvertPreConversion = \"InvertPreConversion\",\r\n /** Invert value after applying the other conversion steps (the to-unit is the inverted unit) */\r\n InvertPostConversion = \"InvertPostConversion\"\r\n}\r\n\r\n/** This interface defines the properties required to convert a quantity value from one unit to another such as from meters to feet\r\n * or from Celsius to Fahrenheit.\r\n * @beta\r\n */\r\nexport interface UnitConversionProps {\r\n /** The factor to multiply the input value by to convert to the output value. */\r\n factor: number;\r\n /** The offset to add to the input value to convert to the output value. */\r\n offset: number;\r\n /** If set, inverts the unit value (1/x) before or after conversion. */\r\n inversion?: UnitConversionInvert;\r\n /**\r\n * If `true`, the conversion could not be resolved (e.g. unknown unit, incompatible phenomena).\r\n * When `error` is `true`, `factor` MUST be `1.0` and `offset` MUST be `0.0` (identity).\r\n * Callers must check this flag before applying the conversion — applying an identity conversion\r\n * silently produces wrong output.\r\n */\r\n error?: boolean;\r\n}\r\n\r\n/** Interface that defines potential parse units that may be found in user's string input of a quantity value.\r\n * @beta\r\n */\r\nexport interface PotentialParseUnit {\r\n unitName: string;\r\n altLabels?: string[];\r\n}\r\n\r\n/**\r\n * This interface defines extra properties to be associated with Units from Units Schema by name\r\n * @alpha\r\n */\r\nexport interface UnitExtraData {\r\n readonly name: string;\r\n readonly altDisplayLabels: string[];\r\n}\r\n\r\n/** This interface is implemented by the class that is responsible for locating units by name or label and providing conversion values between units.\r\n * The methods to be implemented are async allowing the UnitsProvider to query the backend when necessary to look up unit definition and conversion rules.\r\n * @beta\r\n */\r\nexport interface UnitsProvider {\r\n findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps>;\r\n getUnitsByFamily(phenomenon: string): Promise<UnitProps[]>;\r\n findUnitByName(unitName: string): Promise<UnitProps>;\r\n /**\r\n * Compute the conversion factors from `fromUnit` to `toUnit`.\r\n * On failure (unknown unit, incompatible phenomena), implementations MUST return\r\n * `{ factor: 1.0, offset: 0.0, error: true }`. Throwing is also permitted;\r\n * composite providers treat a throw as equivalent to `error: true`.\r\n * Callers MUST check `result.error` before applying the conversion.\r\n */\r\n getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;\r\n}\r\n\r\n/**\r\n * Identifies a user-facing unit system preference group.\r\n *\r\n * A `UnitSystemKey` does **not** map one-to-one to an EC `UnitSystem` element. Instead, each key\r\n * represents a *preference group* that matches against one or more EC `UnitSystem` names in\r\n * priority order when resolving formats from a `KindOfQuantity`:\r\n *\r\n * | Key | EC UnitSystems matched (highest priority first) |\r\n * | -------------- | ------------------------------------------------------- |\r\n * | `\"metric\"` | SI / METRIC, INTERNATIONAL, FINANCE |\r\n * | `\"imperial\"` | IMPERIAL, USCUSTOM, INTERNATIONAL, FINANCE |\r\n * | `\"usCustomary\"`| USCUSTOM, INTERNATIONAL, FINANCE |\r\n * | `\"usSurvey\"` | USSURVEY, USCUSTOM, INTERNATIONAL, FINANCE |\r\n *\r\n * EC `UnitSystem` elements not listed above (e.g. CGS, MARITIME, INDUSTRIAL) are not covered by\r\n * any preference group and will only appear if a `KindOfQuantity` explicitly references them.\r\n *\r\n * @see [SchemaFormatsProvider]($ecschema-metadata) for how preference groups resolve formats.\r\n * @beta\r\n */\r\nexport type UnitSystemKey = \"metric\" | \"imperial\" | \"usCustomary\" | \"usSurvey\";\r\n"]}
|
|
1
|
+
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../src/Interfaces.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAmDH;;GAEG;AACH,MAAM,CAAN,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,mGAAmG;IACnG,mEAA2C,CAAA;IAC3C,gGAAgG;IAChG,qEAA6C,CAAA;AAC/C,CAAC,EALW,oBAAoB,KAApB,oBAAoB,QAK/B","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\n/** This interface allows a provider to be specified that will define an array of alternate labels for a specific unit.\r\n * @beta\r\n */\r\nexport interface AlternateUnitLabelsProvider {\r\n getAlternateUnitLabels: (unit: UnitProps) => string[] | undefined;\r\n}\r\n\r\n/** This interface provides basic information about a Unit that is return from a UnitProvider. This info\r\n * uniquely identifies a unit by its name.\r\n * @beta\r\n */\r\nexport interface UnitProps {\r\n /** Unique name for unit. */\r\n readonly name: string;\r\n /** Default label for unit. */\r\n readonly label: string;\r\n /** Unique name of unit phenomenon. Example phenomenon names include 'Units.LENGTH', 'Units.AREA', and 'Units.VOLUME' */\r\n readonly phenomenon: string;\r\n /** This is set to true if the Unit is known by the UnitsProvider. */\r\n readonly isValid: boolean;\r\n /** Unique system name. Example \"Units.USCUSTOM\",\" Units.METRIC\", \"Units.USSURVEY\", \"Units.IMPERIAL\" */\r\n readonly system: string;\r\n}\r\n\r\n/** This interface defines the required properties of a Quantity.\r\n * @beta\r\n */\r\nexport interface QuantityProps {\r\n readonly magnitude: number;\r\n readonly unit: UnitProps;\r\n readonly isValid: boolean;\r\n}\r\n\r\n/** Interface that defines how to convert between a specific unit an another in synchronous formatting or parsing processing.\r\n * @beta\r\n */\r\nexport interface UnitConversionSpec {\r\n /** Unit name that was used to locate the unit by the Unit Provider */\r\n name: string;\r\n /** The default label that is used to display unit */\r\n label: string;\r\n /** Unit system name, used to when finding preferred parse unit */\r\n system: string;\r\n /** the information necessary to convert the unit to a specific display unit */\r\n conversion: UnitConversionProps;\r\n /** Labels that may be used to represent the unit in a string that is to be parsed. */\r\n parseLabels?: string[];\r\n}\r\n\r\n/** Indicates the way in which unit values are inverted during conversion\r\n * @beta\r\n */\r\nexport enum UnitConversionInvert {\r\n /** Invert value before applying the other conversion steps (the from-unit is the inverted unit) */\r\n InvertPreConversion = \"InvertPreConversion\",\r\n /** Invert value after applying the other conversion steps (the to-unit is the inverted unit) */\r\n InvertPostConversion = \"InvertPostConversion\"\r\n}\r\n\r\n/** This interface defines the properties required to convert a quantity value from one unit to another such as from meters to feet\r\n * or from Celsius to Fahrenheit.\r\n * @beta\r\n */\r\nexport interface UnitConversionProps {\r\n /** The factor to multiply the input value by to convert to the output value. */\r\n factor: number;\r\n /** The offset to add to the input value to convert to the output value. */\r\n offset: number;\r\n /** If set, inverts the unit value (1/x) before or after conversion. */\r\n inversion?: UnitConversionInvert;\r\n /**\r\n * If `true`, the conversion could not be resolved (e.g. unknown unit, incompatible phenomena).\r\n * When `error` is `true`, `factor` MUST be `1.0` and `offset` MUST be `0.0` (identity).\r\n * Callers must check this flag before applying the conversion — applying an identity conversion\r\n * silently produces wrong output.\r\n */\r\n error?: boolean;\r\n}\r\n\r\n/** Interface that defines potential parse units that may be found in user's string input of a quantity value.\r\n * @beta\r\n */\r\nexport interface PotentialParseUnit {\r\n unitName: string;\r\n altLabels?: string[];\r\n}\r\n\r\n/**\r\n * This interface defines extra properties to be associated with Units from Units Schema by name\r\n * @alpha\r\n */\r\nexport interface UnitExtraData {\r\n readonly name: string;\r\n readonly altDisplayLabels: string[];\r\n}\r\n\r\n/** This interface is implemented by the class that is responsible for locating units by name or label and providing conversion values between units.\r\n * The methods to be implemented are async allowing the UnitsProvider to query the backend when necessary to look up unit definition and conversion rules.\r\n * @beta\r\n */\r\nexport interface UnitsProvider {\r\n findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps>;\r\n getUnitsByFamily(phenomenon: string): Promise<UnitProps[]>;\r\n findUnitByName(unitName: string): Promise<UnitProps>;\r\n /**\r\n * Compute the conversion factors from `fromUnit` to `toUnit`.\r\n * On failure (unknown unit, incompatible phenomena), implementations MUST return\r\n * `{ factor: 1.0, offset: 0.0, error: true }`. Throwing is also permitted;\r\n * composite providers treat a throw as equivalent to `error: true`.\r\n * Callers MUST check `result.error` before applying the conversion.\r\n */\r\n getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;\r\n}\r\n\r\n/**\r\n * Optional capability for providers that can resolve units and conversions from local data without awaiting.\r\n * @note Implementations should use already-loaded local data and avoid schema loading or asynchronous I/O from these methods.\r\n * @beta\r\n */\r\nexport interface SyncUnitsProvider {\r\n /** Find a unit by fully qualified name using local data. */\r\n findUnitByNameSync(unitName: string): UnitProps;\r\n /**\r\n * Compute conversion factors using local data.\r\n * @note On failure, implementations should return `{ factor: 1.0, offset: 0.0, error: true }`.\r\n */\r\n getConversionSync(fromUnit: UnitProps, toUnit: UnitProps): UnitConversionProps;\r\n}\r\n\r\n/**\r\n * Identifies a user-facing unit system preference group.\r\n *\r\n * A `UnitSystemKey` does **not** map one-to-one to an EC `UnitSystem` element. Instead, each key\r\n * represents a *preference group* that matches against one or more EC `UnitSystem` names in\r\n * priority order when resolving formats from a `KindOfQuantity`:\r\n *\r\n * | Key | EC UnitSystems matched (highest priority first) |\r\n * | -------------- | ------------------------------------------------------- |\r\n * | `\"metric\"` | SI / METRIC, INTERNATIONAL, FINANCE |\r\n * | `\"imperial\"` | IMPERIAL, USCUSTOM, INTERNATIONAL, FINANCE |\r\n * | `\"usCustomary\"`| USCUSTOM, INTERNATIONAL, FINANCE |\r\n * | `\"usSurvey\"` | USSURVEY, USCUSTOM, INTERNATIONAL, FINANCE |\r\n *\r\n * EC `UnitSystem` elements not listed above (e.g. CGS, MARITIME, INDUSTRIAL) are not covered by\r\n * any preference group and will only appear if a `KindOfQuantity` explicitly references them.\r\n *\r\n * @see [SchemaFormatsProvider]($ecschema-metadata) for how preference groups resolve formats.\r\n * @beta\r\n */\r\nexport type UnitSystemKey = \"metric\" | \"imperial\" | \"usCustomary\" | \"usSurvey\";\r\n"]}
|
package/lib/esm/Parser.js
CHANGED
|
@@ -851,8 +851,8 @@ export class Parser {
|
|
|
851
851
|
static parseRatioFormat(inString, spec) {
|
|
852
852
|
if (!inString)
|
|
853
853
|
return { ok: false, error: ParseError.NoValueOrUnitFoundInString };
|
|
854
|
-
const separator = spec.format.ratioSeparator
|
|
855
|
-
const parts = inString.split(separator);
|
|
854
|
+
const separator = spec.format.ratioSeparator?.split(" ").join("") || ":";
|
|
855
|
+
const parts = inString.split(separator).map((p) => p.trim());
|
|
856
856
|
if (parts.length > 2)
|
|
857
857
|
return { ok: false, error: ParseError.UnableToConvertParseTokensToQuantity };
|
|
858
858
|
// If the string doesn't contain the expected separator but contains other ratio-like separators,
|