@itwin/core-quantity 5.12.0-dev.8 → 5.12.0

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 (48) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/lib/cjs/Formatter/Format.d.ts +8 -0
  3. package/lib/cjs/Formatter/Format.d.ts.map +1 -1
  4. package/lib/cjs/Formatter/Format.js +8 -0
  5. package/lib/cjs/Formatter/Format.js.map +1 -1
  6. package/lib/cjs/Formatter/Formatter.d.ts +7 -0
  7. package/lib/cjs/Formatter/Formatter.d.ts.map +1 -1
  8. package/lib/cjs/Formatter/Formatter.js +13 -1
  9. package/lib/cjs/Formatter/Formatter.js.map +1 -1
  10. package/lib/cjs/Formatter/FormatterSpec.d.ts +3 -0
  11. package/lib/cjs/Formatter/FormatterSpec.d.ts.map +1 -1
  12. package/lib/cjs/Formatter/FormatterSpec.js +3 -0
  13. package/lib/cjs/Formatter/FormatterSpec.js.map +1 -1
  14. package/lib/cjs/Formatter/Interfaces.d.ts +10 -2
  15. package/lib/cjs/Formatter/Interfaces.d.ts.map +1 -1
  16. package/lib/cjs/Formatter/Interfaces.js.map +1 -1
  17. package/lib/cjs/Parser.d.ts +6 -1
  18. package/lib/cjs/Parser.d.ts.map +1 -1
  19. package/lib/cjs/Parser.js +20 -3
  20. package/lib/cjs/Parser.js.map +1 -1
  21. package/lib/cjs/ParserSpec.d.ts +3 -0
  22. package/lib/cjs/ParserSpec.d.ts.map +1 -1
  23. package/lib/cjs/ParserSpec.js +3 -0
  24. package/lib/cjs/ParserSpec.js.map +1 -1
  25. package/lib/esm/Formatter/Format.d.ts +8 -0
  26. package/lib/esm/Formatter/Format.d.ts.map +1 -1
  27. package/lib/esm/Formatter/Format.js +8 -0
  28. package/lib/esm/Formatter/Format.js.map +1 -1
  29. package/lib/esm/Formatter/Formatter.d.ts +7 -0
  30. package/lib/esm/Formatter/Formatter.d.ts.map +1 -1
  31. package/lib/esm/Formatter/Formatter.js +13 -1
  32. package/lib/esm/Formatter/Formatter.js.map +1 -1
  33. package/lib/esm/Formatter/FormatterSpec.d.ts +3 -0
  34. package/lib/esm/Formatter/FormatterSpec.d.ts.map +1 -1
  35. package/lib/esm/Formatter/FormatterSpec.js +3 -0
  36. package/lib/esm/Formatter/FormatterSpec.js.map +1 -1
  37. package/lib/esm/Formatter/Interfaces.d.ts +10 -2
  38. package/lib/esm/Formatter/Interfaces.d.ts.map +1 -1
  39. package/lib/esm/Formatter/Interfaces.js.map +1 -1
  40. package/lib/esm/Parser.d.ts +6 -1
  41. package/lib/esm/Parser.d.ts.map +1 -1
  42. package/lib/esm/Parser.js +20 -3
  43. package/lib/esm/Parser.js.map +1 -1
  44. package/lib/esm/ParserSpec.d.ts +3 -0
  45. package/lib/esm/ParserSpec.d.ts.map +1 -1
  46. package/lib/esm/ParserSpec.js +3 -0
  47. package/lib/esm/ParserSpec.js.map +1 -1
  48. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"ParserSpec.js","sourceRoot":"","sources":["../../src/ParserSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { Logger } from \"@itwin/core-bentley\";\nimport { Format } from \"./Formatter/Format\";\nimport { FormatType } from \"./Formatter/FormatEnums\";\nimport { AlternateUnitLabelsProvider, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"./Interfaces\";\nimport { Parser, QuantityParseResult } from \"./Parser\";\nimport { QuantityLoggerCategory } from \"./QuantityLoggerCategory\";\n\n/** A ParserSpec holds information needed to parse a string into a quantity synchronously.\n * @beta\n */\nexport class ParserSpec {\n private _outUnit: UnitProps;\n private _conversions: UnitConversionSpec[] = []; // max four entries\n private _format: Format;\n protected _azimuthBaseConversion?: UnitConversionProps; // converts azimuth base unit to persistence unit\n protected _revolutionConversion?: UnitConversionProps; // converts revolution unit to persistence unit\n\n /** Constructor\n * @param outUnit The name of a format specification.\n * @param format Defines the output format for the quantity value.\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format..\n */\n constructor(outUnit: UnitProps, format: Format, conversions: UnitConversionSpec[]) {\n this._outUnit = outUnit;\n this._format = format;\n this._conversions = conversions;\n }\n\n /** Returns an array of UnitConversionSpecs for each unit label that may be used in the input string. */\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\n public get format(): Format { return this._format; }\n public get outUnit(): UnitProps { return this._outUnit; }\n public get azimuthBaseConversion(): UnitConversionProps | undefined { return this._azimuthBaseConversion; }\n public get revolutionConversion(): UnitConversionProps | undefined { return this._revolutionConversion; }\n\n /** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */\n private static async getRatioUnitConversions(units: ReadonlyArray<[UnitProps, string | undefined]>, unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\n const conversions: UnitConversionSpec[] = [];\n\n const [numeratorUnit, numeratorLabel] = units[0];\n const [denominatorUnit, denominatorLabel] = units[1];\n\n // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)\n const denominatorToNumerator = await unitsProvider.getConversion(denominatorUnit, numeratorUnit);\n if (denominatorToNumerator.error) {\n Logger.logWarning(QuantityLoggerCategory.Parsing, `Unit conversion from \"${denominatorUnit.name}\" to \"${numeratorUnit.name}\" could not be resolved.`);\n }\n const displayRatioScale = denominatorToNumerator.factor;\n\n // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.\n // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)\n const persistenceName = outUnit.name.toUpperCase();\n const numName = numeratorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\n const denName = denominatorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\n // Split by word boundaries (underscores, dots) and check for exact token matches\n const persistenceTokens = persistenceName.split(/[._]/);\n const isPersistenceMatchingRatio = persistenceTokens.includes(numName) && persistenceTokens.includes(denName);\n const ratioScaleFactor = isPersistenceMatchingRatio ? 1.0 : displayRatioScale;\n\n // First conversion spec: effective ratio unit conversion\n const ratioConversionSpec: UnitConversionSpec = {\n name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,\n label: \"\",\n system: numeratorUnit.system,\n conversion: { factor: ratioScaleFactor, offset: 0.0 },\n };\n conversions.push(ratioConversionSpec);\n\n // Numerator unit for label lookup\n const numeratorSpec: UnitConversionSpec = {\n name: numeratorUnit.name,\n label: numeratorLabel?.length ? numeratorLabel : numeratorUnit.label,\n system: numeratorUnit.system,\n conversion: { factor: 1.0, offset: 0.0 },\n parseLabels: altUnitLabelsProvider?.getAlternateUnitLabels(numeratorUnit),\n };\n conversions.push(numeratorSpec);\n\n // Denominator unit for label lookup\n const denominatorSpec: UnitConversionSpec = {\n name: denominatorUnit.name,\n label: denominatorLabel?.length ? denominatorLabel : denominatorUnit.label,\n system: denominatorUnit.system,\n conversion: { factor: 1.0, offset: 0.0 },\n parseLabels: altUnitLabelsProvider?.getAlternateUnitLabels(denominatorUnit),\n };\n conversions.push(denominatorSpec);\n\n return conversions;\n }\n\n /** Static async method to create a ParserSpec given the format and unit of the quantity that will be passed to the Parser. The input unit will\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\n * async calls to lookup unit definitions.\n * @param format The format specification.\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\n * @param outUnit The unit a value will be formatted to. This unit is often referred to as persistence unit.\n */\n public static async create(format: Format, unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<ParserSpec> {\n let conversions: UnitConversionSpec[];\n\n // For ratio formats with 2 composite units, use private helper method\n if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {\n conversions = await ParserSpec.getRatioUnitConversions(format.units, unitsProvider, outUnit, altUnitLabelsProvider);\n } else {\n conversions = await Parser.createUnitConversionSpecsForUnit(unitsProvider, outUnit, altUnitLabelsProvider);\n }\n\n const spec = new ParserSpec(outUnit, format, conversions);\n if (format.azimuthBaseUnit !== undefined) {\n if (outUnit !== undefined) {\n const azimuthResult = await unitsProvider.getConversion(format.azimuthBaseUnit, outUnit);\n if (azimuthResult.error) {\n Logger.logWarning(QuantityLoggerCategory.Parsing, `Unit conversion from \"${format.azimuthBaseUnit.name}\" to \"${outUnit.name}\" could not be resolved.`);\n }\n spec._azimuthBaseConversion = azimuthResult;\n } else {\n spec._azimuthBaseConversion = { factor: 1.0, offset: 0.0 };\n }\n }\n if (format.revolutionUnit !== undefined) {\n if (outUnit !== undefined) {\n const revolutionResult = await unitsProvider.getConversion(format.revolutionUnit, outUnit);\n if (revolutionResult.error) {\n Logger.logWarning(QuantityLoggerCategory.Parsing, `Unit conversion from \"${format.revolutionUnit.name}\" to \"${outUnit.name}\" could not be resolved.`);\n }\n spec._revolutionConversion = revolutionResult;\n } else {\n spec._revolutionConversion = { factor: 1.0, offset: 0.0 };\n }\n }\n return spec;\n }\n\n /** Do the parsing. Done this way to allow Custom Parser Specs to parse custom formatted strings into their quantities. */\n public parseToQuantityValue(inString: string): QuantityParseResult {\n return Parser.parseQuantityString(inString, this);\n }\n}\n\n"]}
1
+ {"version":3,"file":"ParserSpec.js","sourceRoot":"","sources":["../../src/ParserSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { Logger } from \"@itwin/core-bentley\";\nimport { Format } from \"./Formatter/Format\";\nimport { FormatType } from \"./Formatter/FormatEnums\";\nimport { AlternateUnitLabelsProvider, UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"./Interfaces\";\nimport { Parser, QuantityParseResult } from \"./Parser\";\nimport { QuantityLoggerCategory } from \"./QuantityLoggerCategory\";\n\n/** A ParserSpec holds information needed to parse a string into a quantity synchronously.\n * @beta\n */\nexport class ParserSpec {\n private _outUnit: UnitProps;\n private _conversions: UnitConversionSpec[] = []; // max four entries\n private _format: Format;\n protected _azimuthBaseConversion?: UnitConversionProps; // converts azimuth base unit to persistence unit\n protected _revolutionConversion?: UnitConversionProps; // converts revolution unit to persistence unit\n\n /** Constructor\n * @param outUnit The name of a format specification.\n * @param format Defines the output format for the quantity value.\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format..\n */\n constructor(outUnit: UnitProps, format: Format, conversions: UnitConversionSpec[]) {\n this._outUnit = outUnit;\n this._format = format;\n this._conversions = conversions;\n }\n\n /** Returns an array of UnitConversionSpecs for each unit label that may be used in the input string. */\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\n public get format(): Format { return this._format; }\n public get outUnit(): UnitProps { return this._outUnit; }\n public get azimuthBaseConversion(): UnitConversionProps | undefined { return this._azimuthBaseConversion; }\n public get revolutionConversion(): UnitConversionProps | undefined { return this._revolutionConversion; }\n\n /** Build conversion specs for ratio format with 2 composite units (numerator/denominator). */\n private static async getRatioUnitConversions(units: ReadonlyArray<[UnitProps, string | undefined]>, unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<UnitConversionSpec[]> {\n const conversions: UnitConversionSpec[] = [];\n\n const [numeratorUnit, numeratorLabel] = units[0];\n const [denominatorUnit, denominatorLabel] = units[1];\n\n // Compute ratio scale: how many numerator units per denominator unit (e.g., IN:FT = 12)\n const denominatorToNumerator = await unitsProvider.getConversion(denominatorUnit, numeratorUnit);\n if (denominatorToNumerator.error) {\n Logger.logWarning(QuantityLoggerCategory.Parsing, `Unit conversion from \"${denominatorUnit.name}\" to \"${numeratorUnit.name}\" could not be resolved.`);\n }\n const displayRatioScale = denominatorToNumerator.factor;\n\n // Avoid double-scaling: if persistence unit already encodes the display ratio, use factor 1.\n // Check by name heuristic (e.g., IN_PER_FT with ratioUnits [IN, FT] → no scaling needed)\n const persistenceName = outUnit.name.toUpperCase();\n const numName = numeratorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\n const denName = denominatorUnit.name.toUpperCase().split(\".\").pop() ?? \"\";\n // Split by word boundaries (underscores, dots) and check for exact token matches\n const persistenceTokens = persistenceName.split(/[._]/);\n const isPersistenceMatchingRatio = persistenceTokens.includes(numName) && persistenceTokens.includes(denName);\n const ratioScaleFactor = isPersistenceMatchingRatio ? 1.0 : displayRatioScale;\n\n // First conversion spec: effective ratio unit conversion\n const ratioConversionSpec: UnitConversionSpec = {\n name: `${numeratorUnit.name}_per_${denominatorUnit.name}`,\n label: \"\",\n system: numeratorUnit.system,\n conversion: { factor: ratioScaleFactor, offset: 0.0 },\n };\n conversions.push(ratioConversionSpec);\n\n // Numerator unit for label lookup\n const numeratorSpec: UnitConversionSpec = {\n name: numeratorUnit.name,\n label: numeratorLabel?.length ? numeratorLabel : numeratorUnit.label,\n system: numeratorUnit.system,\n conversion: { factor: 1.0, offset: 0.0 },\n parseLabels: altUnitLabelsProvider?.getAlternateUnitLabels(numeratorUnit),\n };\n conversions.push(numeratorSpec);\n\n // Denominator unit for label lookup\n const denominatorSpec: UnitConversionSpec = {\n name: denominatorUnit.name,\n label: denominatorLabel?.length ? denominatorLabel : denominatorUnit.label,\n system: denominatorUnit.system,\n conversion: { factor: 1.0, offset: 0.0 },\n parseLabels: altUnitLabelsProvider?.getAlternateUnitLabels(denominatorUnit),\n };\n conversions.push(denominatorSpec);\n\n return conversions;\n }\n\n /** Static async method to create a ParserSpec given the format and unit of the quantity that will be passed to the Parser. The input unit will\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\n * async calls to lookup unit definitions.\n * @param format The format specification.\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\n * @param outUnit The unit a value will be formatted to. This unit is often referred to as persistence unit.\n * @note For Bearing/Azimuth formats, `outUnit`'s phenomenon must match `format.azimuthBaseUnit`/`format.revolutionUnit`.\n * @see BaseFormat.azimuthBaseUnit\n * @see BaseFormat.revolutionUnit\n */\n public static async create(format: Format, unitsProvider: UnitsProvider, outUnit: UnitProps, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<ParserSpec> {\n let conversions: UnitConversionSpec[];\n\n // For ratio formats with 2 composite units, use private helper method\n if (format.type === FormatType.Ratio && format.units && format.units.length === 2) {\n conversions = await ParserSpec.getRatioUnitConversions(format.units, unitsProvider, outUnit, altUnitLabelsProvider);\n } else {\n conversions = await Parser.createUnitConversionSpecsForUnit(unitsProvider, outUnit, altUnitLabelsProvider);\n }\n\n const spec = new ParserSpec(outUnit, format, conversions);\n if (format.azimuthBaseUnit !== undefined) {\n if (outUnit !== undefined) {\n const azimuthResult = await unitsProvider.getConversion(format.azimuthBaseUnit, outUnit);\n if (azimuthResult.error) {\n Logger.logWarning(QuantityLoggerCategory.Parsing, `Unit conversion from \"${format.azimuthBaseUnit.name}\" to \"${outUnit.name}\" could not be resolved.`);\n }\n spec._azimuthBaseConversion = azimuthResult;\n } else {\n spec._azimuthBaseConversion = { factor: 1.0, offset: 0.0 };\n }\n }\n if (format.revolutionUnit !== undefined) {\n if (outUnit !== undefined) {\n const revolutionResult = await unitsProvider.getConversion(format.revolutionUnit, outUnit);\n if (revolutionResult.error) {\n Logger.logWarning(QuantityLoggerCategory.Parsing, `Unit conversion from \"${format.revolutionUnit.name}\" to \"${outUnit.name}\" could not be resolved.`);\n }\n spec._revolutionConversion = revolutionResult;\n } else {\n spec._revolutionConversion = { factor: 1.0, offset: 0.0 };\n }\n }\n return spec;\n }\n\n /** Do the parsing. Done this way to allow Custom Parser Specs to parse custom formatted strings into their quantities. */\n public parseToQuantityValue(inString: string): QuantityParseResult {\n return Parser.parseQuantityString(inString, this);\n }\n}\n\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/core-quantity",
3
- "version": "5.12.0-dev.8",
3
+ "version": "5.12.0",
4
4
  "description": "Quantity parsing, formatting and conversions for iModel.js",
5
5
  "main": "lib/cjs/core-quantity.js",
6
6
  "module": "lib/esm/core-quantity.js",
@@ -24,17 +24,17 @@
24
24
  "@bentley/units-schema": "^1.0.10",
25
25
  "@itwin/eslint-plugin": "^6.0.0",
26
26
  "@types/node": "~20.17.0",
27
- "@vitest/coverage-v8": "^4.1.8",
27
+ "@vitest/coverage-v8": "^4.1.10",
28
28
  "eslint": "^9.31.0",
29
29
  "rimraf": "^6.0.1",
30
30
  "tsx": "~4.22.0",
31
31
  "typescript": "~5.6.2",
32
- "vitest": "^4.1.8",
33
- "@itwin/build-tools": "5.12.0-dev.8",
34
- "@itwin/core-bentley": "5.12.0-dev.8"
32
+ "vitest": "^4.1.10",
33
+ "@itwin/build-tools": "5.12.0",
34
+ "@itwin/core-bentley": "5.12.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@itwin/core-bentley": "5.12.0-dev.8"
37
+ "@itwin/core-bentley": "5.12.0"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "npm run -s build:cjs && npm run -s build:esm && npm run -s build:typecheck",