@itwin/ecschema-metadata 5.14.0-dev.9 → 5.14.2

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 (50) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/lib/cjs/ECName.d.ts +4 -0
  3. package/lib/cjs/ECName.d.ts.map +1 -1
  4. package/lib/cjs/ECName.js +9 -1
  5. package/lib/cjs/ECName.js.map +1 -1
  6. package/lib/cjs/Formatting/FormatSetFormatsProvider.d.ts +13 -5
  7. package/lib/cjs/Formatting/FormatSetFormatsProvider.d.ts.map +1 -1
  8. package/lib/cjs/Formatting/FormatSetFormatsProvider.js +65 -22
  9. package/lib/cjs/Formatting/FormatSetFormatsProvider.js.map +1 -1
  10. package/lib/cjs/Formatting/SchemaFormatsProvider.d.ts +15 -6
  11. package/lib/cjs/Formatting/SchemaFormatsProvider.d.ts.map +1 -1
  12. package/lib/cjs/Formatting/SchemaFormatsProvider.js +163 -44
  13. package/lib/cjs/Formatting/SchemaFormatsProvider.js.map +1 -1
  14. package/lib/cjs/SchemaView/SchemaManifest.d.ts +11 -14
  15. package/lib/cjs/SchemaView/SchemaManifest.d.ts.map +1 -1
  16. package/lib/cjs/SchemaView/SchemaManifest.js +8 -11
  17. package/lib/cjs/SchemaView/SchemaManifest.js.map +1 -1
  18. package/lib/cjs/SchemaView/SchemaView.d.ts +14 -5
  19. package/lib/cjs/SchemaView/SchemaView.d.ts.map +1 -1
  20. package/lib/cjs/SchemaView/SchemaView.js +22 -12
  21. package/lib/cjs/SchemaView/SchemaView.js.map +1 -1
  22. package/lib/cjs/SchemaView/SchemaViewManager.d.ts +22 -17
  23. package/lib/cjs/SchemaView/SchemaViewManager.d.ts.map +1 -1
  24. package/lib/cjs/SchemaView/SchemaViewManager.js +11 -11
  25. package/lib/cjs/SchemaView/SchemaViewManager.js.map +1 -1
  26. package/lib/esm/ECName.d.ts +4 -0
  27. package/lib/esm/ECName.d.ts.map +1 -1
  28. package/lib/esm/ECName.js +9 -1
  29. package/lib/esm/ECName.js.map +1 -1
  30. package/lib/esm/Formatting/FormatSetFormatsProvider.d.ts +13 -5
  31. package/lib/esm/Formatting/FormatSetFormatsProvider.d.ts.map +1 -1
  32. package/lib/esm/Formatting/FormatSetFormatsProvider.js +65 -22
  33. package/lib/esm/Formatting/FormatSetFormatsProvider.js.map +1 -1
  34. package/lib/esm/Formatting/SchemaFormatsProvider.d.ts +15 -6
  35. package/lib/esm/Formatting/SchemaFormatsProvider.d.ts.map +1 -1
  36. package/lib/esm/Formatting/SchemaFormatsProvider.js +163 -44
  37. package/lib/esm/Formatting/SchemaFormatsProvider.js.map +1 -1
  38. package/lib/esm/SchemaView/SchemaManifest.d.ts +11 -14
  39. package/lib/esm/SchemaView/SchemaManifest.d.ts.map +1 -1
  40. package/lib/esm/SchemaView/SchemaManifest.js +8 -11
  41. package/lib/esm/SchemaView/SchemaManifest.js.map +1 -1
  42. package/lib/esm/SchemaView/SchemaView.d.ts +14 -5
  43. package/lib/esm/SchemaView/SchemaView.d.ts.map +1 -1
  44. package/lib/esm/SchemaView/SchemaView.js +22 -12
  45. package/lib/esm/SchemaView/SchemaView.js.map +1 -1
  46. package/lib/esm/SchemaView/SchemaViewManager.d.ts +22 -17
  47. package/lib/esm/SchemaView/SchemaViewManager.d.ts.map +1 -1
  48. package/lib/esm/SchemaView/SchemaViewManager.js +11 -11
  49. package/lib/esm/SchemaView/SchemaViewManager.js.map +1 -1
  50. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,6 +1,59 @@
1
1
  # Change Log - @itwin/ecschema-metadata
2
2
 
3
- This log was last generated on Thu, 03 Sep 2026 18:51:17 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 06 Oct 2026 19:48:29 GMT and should not be manually modified.
4
+
5
+ ## 5.14.2
6
+ Tue, 06 Oct 2026 19:48:29 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 5.14.1
11
+ Tue, 06 Oct 2026 14:00:55 GMT
12
+
13
+ _Version update only_
14
+
15
+ ## 5.14.0
16
+ Fri, 02 Oct 2026 14:55:04 GMT
17
+
18
+ ### Updates
19
+
20
+ - Expose SchemaView incremental-loading APIs as beta and decode ECName escapes in fallback display labels
21
+ - Add synchronous format lookup to schema and format-set providers.
22
+
23
+ ## 5.13.7
24
+ Thu, 01 Oct 2026 15:15:30 GMT
25
+
26
+ _Version update only_
27
+
28
+ ## 5.13.6
29
+ Fri, 25 Sep 2026 22:27:22 GMT
30
+
31
+ _Version update only_
32
+
33
+ ## 5.13.5
34
+ Tue, 22 Sep 2026 22:38:08 GMT
35
+
36
+ _Version update only_
37
+
38
+ ## 5.13.4
39
+ Fri, 18 Sep 2026 15:11:19 GMT
40
+
41
+ _Version update only_
42
+
43
+ ## 5.13.3
44
+ Tue, 15 Sep 2026 20:25:28 GMT
45
+
46
+ _Version update only_
47
+
48
+ ## 5.13.2
49
+ Mon, 14 Sep 2026 20:22:20 GMT
50
+
51
+ _Version update only_
52
+
53
+ ## 5.13.1
54
+ Tue, 08 Sep 2026 18:43:29 GMT
55
+
56
+ _Version update only_
4
57
 
5
58
  ## 5.13.0
6
59
  Thu, 03 Sep 2026 18:49:56 GMT
@@ -25,6 +25,10 @@ export declare class ECName {
25
25
  * @throws ECSchemaError if `input` is an empty string.
26
26
  */
27
27
  static encode(input: string): ECName;
28
+ /** Decode EC name escape sequences without requiring a valid EC identifier.
29
+ * @internal
30
+ */
31
+ static decode(name: string): string;
28
32
  /** Decode this ECName, replacing encoded special characters with the characters they encode. */
29
33
  decode(): string;
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ECName.d.ts","sourceRoot":"","sources":["../../src/ECName.ts"],"names":[],"mappings":"AAIA;;GAEG;AAmBH;;;;;;;;;GASG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAS;IAEtB;;OAEG;gBACS,IAAI,EAAE,MAAM;IAOxB,sEAAsE;WACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI7C,uCAAuC;IACvC,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;WACW,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAiC3C,gGAAgG;IACzF,MAAM,IAAI,MAAM;CAGxB"}
1
+ {"version":3,"file":"ECName.d.ts","sourceRoot":"","sources":["../../src/ECName.ts"],"names":[],"mappings":"AAIA;;GAEG;AAmBH;;;;;;;;;GASG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAS;IAEtB;;OAEG;gBACS,IAAI,EAAE,MAAM;IAOxB,sEAAsE;WACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI7C,uCAAuC;IACvC,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;WACW,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAiC3C;;OAEG;WACW,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAO1C,gGAAgG;IACzF,MAAM,IAAI,MAAM;CAGxB"}
package/lib/cjs/ECName.js CHANGED
@@ -78,9 +78,17 @@ class ECName {
78
78
  }
79
79
  return new ECName(output);
80
80
  }
81
+ /** Decode EC name escape sequences without requiring a valid EC identifier.
82
+ * @internal
83
+ */
84
+ static decode(name) {
85
+ if (!name.includes("__x"))
86
+ return name;
87
+ return name.replace(ecNameReplacerRegex, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
88
+ }
81
89
  /** Decode this ECName, replacing encoded special characters with the characters they encode. */
82
90
  decode() {
83
- return this.name.replace(ecNameReplacerRegex, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
91
+ return ECName.decode(this.name);
84
92
  }
85
93
  }
86
94
  exports.ECName = ECName;
@@ -1 +1 @@
1
- {"version":3,"file":"ECName.js","sourceRoot":"","sources":["../../src/ECName.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 Metadata\r\n */\r\n\r\nimport { assert } from \"@itwin/core-bentley\";\r\nimport { ECSchemaError, ECSchemaStatus } from \"./Exception\";\r\n\r\nconst validECNameRegex = /^[a-zA-Z_]\\w*$/i;\r\nconst ecNameReplacerRegex = /__x([0-9a-fA-F]{4})__/g;\r\nconst leadingDigits = [\"0000\", \"000\", \"00\", \"0\", \"\"];\r\n\r\nfunction isDigit(character: string): boolean {\r\n assert(1 === character.length);\r\n return character >= \"0\" && character <= \"9\";\r\n}\r\n\r\nfunction isValidAlphaNumericCharacter(c: string): boolean {\r\n assert(1 === c.length);\r\n return (((c >= \"0\" && c <= \"9\") || (c >= \"A\" && c <= \"Z\") || (c >= \"a\" && c <= \"z\") || c === \"_\"));\r\n}\r\n\r\n/** The name of an item in a [[Schema]], encoded to meet restrictions on the characters usable in such names.\r\n * An ECName meets the following criteria:\r\n * - Contains at least one character.\r\n * - Does not begin with a digit.\r\n * - Consists entirely of characters in the ASCII ranges A-Z, a-z, and 0-9; and the underscore (\"_\") character.\r\n *\r\n * All characters not meeting the above criteria are encoded as \"__x####__\" where \"####\" is the UTF-16 character code.\r\n * Such names are often automatically generated from the item's display label, which is unrestricted in the characters it may contain.\r\n * @public\r\n */\r\nexport class ECName {\r\n private _name: string;\r\n\r\n /** Construct a new ECName from a valid EC name.\r\n * throws ECSchemaError if `name` does not meet the criteria for a valid EC name.\r\n */\r\n constructor(name: string) {\r\n if (!ECName.validate(name))\r\n throw new ECSchemaError(ECSchemaStatus.InvalidECName);\r\n\r\n this._name = name;\r\n }\r\n\r\n /** Returns true if a string meets the criteria of a valid EC name. */\r\n public static validate(name: string): boolean {\r\n return validECNameRegex.test(name);\r\n }\r\n\r\n /** The underlying name as a string. */\r\n public get name(): string {\r\n return this._name;\r\n }\r\n\r\n /** Create an ECName from an arbitrary string, encoding any special characters as \"__x####__\" where \"####\" is the UTF-16 character code.\r\n * @throws ECSchemaError if `input` is an empty string.\r\n */\r\n public static encode(input: string): ECName {\r\n if (0 === input.length)\r\n throw new ECSchemaError(ECSchemaStatus.InvalidECName);\r\n\r\n if (ECName.validate(input)) {\r\n // It's already a valid EC name.\r\n return new ECName(input);\r\n }\r\n\r\n let output = \"\";\r\n\r\n function appendEncodedCharacter(index: number): void {\r\n const hex = input.charCodeAt(index).toString(16).toUpperCase();\r\n assert(hex.length > 0 && hex.length < 5);\r\n output += `__x${leadingDigits[hex.length]}${hex}__`;\r\n }\r\n\r\n // First character cannot be a digit.\r\n const firstCharIsDigit = isDigit(input[0]);\r\n if (firstCharIsDigit)\r\n appendEncodedCharacter(0);\r\n\r\n for (let i = firstCharIsDigit ? 1 : 0; i < input.length; i++) {\r\n const char = input[i];\r\n if (!isValidAlphaNumericCharacter(char))\r\n appendEncodedCharacter(i);\r\n else\r\n output += char;\r\n }\r\n\r\n return new ECName(output);\r\n }\r\n\r\n /** Decode this ECName, replacing encoded special characters with the characters they encode. */\r\n public decode(): string {\r\n return this.name.replace(ecNameReplacerRegex, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ECName.js","sourceRoot":"","sources":["../../src/ECName.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 Metadata\r\n */\r\n\r\nimport { assert } from \"@itwin/core-bentley\";\r\nimport { ECSchemaError, ECSchemaStatus } from \"./Exception\";\r\n\r\nconst validECNameRegex = /^[a-zA-Z_]\\w*$/i;\r\nconst ecNameReplacerRegex = /__x([0-9a-fA-F]{4})__/g;\r\nconst leadingDigits = [\"0000\", \"000\", \"00\", \"0\", \"\"];\r\n\r\nfunction isDigit(character: string): boolean {\r\n assert(1 === character.length);\r\n return character >= \"0\" && character <= \"9\";\r\n}\r\n\r\nfunction isValidAlphaNumericCharacter(c: string): boolean {\r\n assert(1 === c.length);\r\n return (((c >= \"0\" && c <= \"9\") || (c >= \"A\" && c <= \"Z\") || (c >= \"a\" && c <= \"z\") || c === \"_\"));\r\n}\r\n\r\n/** The name of an item in a [[Schema]], encoded to meet restrictions on the characters usable in such names.\r\n * An ECName meets the following criteria:\r\n * - Contains at least one character.\r\n * - Does not begin with a digit.\r\n * - Consists entirely of characters in the ASCII ranges A-Z, a-z, and 0-9; and the underscore (\"_\") character.\r\n *\r\n * All characters not meeting the above criteria are encoded as \"__x####__\" where \"####\" is the UTF-16 character code.\r\n * Such names are often automatically generated from the item's display label, which is unrestricted in the characters it may contain.\r\n * @public\r\n */\r\nexport class ECName {\r\n private _name: string;\r\n\r\n /** Construct a new ECName from a valid EC name.\r\n * throws ECSchemaError if `name` does not meet the criteria for a valid EC name.\r\n */\r\n constructor(name: string) {\r\n if (!ECName.validate(name))\r\n throw new ECSchemaError(ECSchemaStatus.InvalidECName);\r\n\r\n this._name = name;\r\n }\r\n\r\n /** Returns true if a string meets the criteria of a valid EC name. */\r\n public static validate(name: string): boolean {\r\n return validECNameRegex.test(name);\r\n }\r\n\r\n /** The underlying name as a string. */\r\n public get name(): string {\r\n return this._name;\r\n }\r\n\r\n /** Create an ECName from an arbitrary string, encoding any special characters as \"__x####__\" where \"####\" is the UTF-16 character code.\r\n * @throws ECSchemaError if `input` is an empty string.\r\n */\r\n public static encode(input: string): ECName {\r\n if (0 === input.length)\r\n throw new ECSchemaError(ECSchemaStatus.InvalidECName);\r\n\r\n if (ECName.validate(input)) {\r\n // It's already a valid EC name.\r\n return new ECName(input);\r\n }\r\n\r\n let output = \"\";\r\n\r\n function appendEncodedCharacter(index: number): void {\r\n const hex = input.charCodeAt(index).toString(16).toUpperCase();\r\n assert(hex.length > 0 && hex.length < 5);\r\n output += `__x${leadingDigits[hex.length]}${hex}__`;\r\n }\r\n\r\n // First character cannot be a digit.\r\n const firstCharIsDigit = isDigit(input[0]);\r\n if (firstCharIsDigit)\r\n appendEncodedCharacter(0);\r\n\r\n for (let i = firstCharIsDigit ? 1 : 0; i < input.length; i++) {\r\n const char = input[i];\r\n if (!isValidAlphaNumericCharacter(char))\r\n appendEncodedCharacter(i);\r\n else\r\n output += char;\r\n }\r\n\r\n return new ECName(output);\r\n }\r\n\r\n /** Decode EC name escape sequences without requiring a valid EC identifier.\r\n * @internal\r\n */\r\n public static decode(name: string): string {\r\n if (!name.includes(\"__x\"))\r\n return name;\r\n\r\n return name.replace(ecNameReplacerRegex, (_match, hex: string) => String.fromCharCode(Number.parseInt(hex, 16)));\r\n }\r\n\r\n /** Decode this ECName, replacing encoded special characters with the characters they encode. */\r\n public decode(): string {\r\n return ECName.decode(this.name);\r\n }\r\n}\r\n"]}
@@ -1,12 +1,12 @@
1
1
  import { BeEvent } from "@itwin/core-bentley";
2
- import { FormatDefinition, FormatsChangedArgs, FormatsProvider, MutableFormatsProvider, UnitSystemKey } from "@itwin/core-quantity";
2
+ import { FormatDefinition, FormatsChangedArgs, FormatsProvider, FormatsProviderContext, MutableFormatsProvider, SyncFormatsProvider, UnitSystemKey } from "@itwin/core-quantity";
3
3
  import { FormatSet } from "../Deserialization/JsonProps";
4
4
  /**
5
5
  * A mutable format provider that manages format definitions within a format set.
6
6
  * When formats are added or removed, the underlying format set is automatically updated.
7
7
  * @beta
8
8
  */
9
- export declare class FormatSetFormatsProvider implements MutableFormatsProvider {
9
+ export declare class FormatSetFormatsProvider implements MutableFormatsProvider, SyncFormatsProvider {
10
10
  onFormatsChanged: BeEvent<(args: FormatsChangedArgs) => void>;
11
11
  private _formatSet;
12
12
  private _fallbackProvider?;
@@ -26,17 +26,25 @@ export declare class FormatSetFormatsProvider implements MutableFormatsProvider
26
26
  */
27
27
  clearFallbackProvider(): void;
28
28
  /**
29
- * Retrieves a format definition by its name from the format set. If not found, it checks the fallback provider to find the format, else returns undefined.
30
- * If the format is a string reference to another format, it resolves the reference and returns the FormatDefinition.
29
+ * Retrieves a format definition from the format set, resolving string references and consulting the fallback provider when needed.
31
30
  */
32
- getFormat(input: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined>;
31
+ getFormat(input: string, system?: UnitSystemKey, context?: FormatsProviderContext): Promise<FormatDefinition | undefined>;
32
+ private getFormatFromFallback;
33
+ /**
34
+ * Retrieves a format definition from the format set without awaiting a provider. String references are resolved
35
+ * locally; a fallback is used only when it implements `SyncFormatsProvider`.
36
+ */
37
+ getFormatSync(input: string, system?: UnitSystemKey, context?: FormatsProviderContext): FormatDefinition | undefined;
38
+ private getFormatSyncFromFallback;
33
39
  /**
34
40
  * Resolves a string reference to its FormatDefinition, following chains of references.
35
41
  * @param reference The string reference to resolve
36
42
  * @param visited Set of visited references to detect circular references
37
43
  * @param system Optional unit system override
44
+ * @param context Lookup context to forward to the fallback provider
38
45
  */
39
46
  private resolveReference;
47
+ private resolveReferenceSync;
40
48
  /**
41
49
  * Removes a format definition or string reference from the format set.
42
50
  * @param name The name of the format to remove
@@ -1 +1 @@
1
- {"version":3,"file":"FormatSetFormatsProvider.d.ts","sourceRoot":"","sources":["../../../src/Formatting/FormatSetFormatsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpI,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD;;;;GAIG;AACH,qBAAa,wBAAyB,YAAW,sBAAsB;IAC9D,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC,CAAqD;IAEzH,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAkB;IAC5C,OAAO,CAAC,WAAW,CAAsB;gBAEtB,KAAK,EAAE;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,gBAAgB,CAAC,EAAE,eAAe,CAAA;KAAC;IAapF;;;;OAIG;IACU,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtF;;OAEG;IACI,qBAAqB,IAAI,IAAI;IAIpC;;;OAGG;IACU,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAmBpG;;;;;OAKG;YACW,gBAAgB;IAwB9B;;;OAGG;IACU,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;CAiBpC"}
1
+ {"version":3,"file":"FormatSetFormatsProvider.d.ts","sourceRoot":"","sources":["../../../src/Formatting/FormatSetFormatsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACjL,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD;;;;GAIG;AACH,qBAAa,wBAAyB,YAAW,sBAAsB,EAAE,mBAAmB;IACnF,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC,CAAqD;IAEzH,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAkB;IAC5C,OAAO,CAAC,WAAW,CAAsB;gBAEtB,KAAK,EAAE;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,gBAAgB,CAAC,EAAE,eAAe,CAAA;KAAC;IAapF;;;;OAIG;IACU,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtF;;OAEG;IACI,qBAAqB,IAAI,IAAI;IAIpC;;OAEG;IACU,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;YAiBxH,qBAAqB;IAOnC;;;OAGG;IACI,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,gBAAgB,GAAG,SAAS;IAiB3H,OAAO,CAAC,yBAAyB;IAKjC;;;;;;OAMG;YACW,gBAAgB;IAkB9B,OAAO,CAAC,oBAAoB;IAiB5B;;;OAGG;IACU,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;CAiBpC"}
@@ -50,48 +50,79 @@ class FormatSetFormatsProvider {
50
50
  this._fallbackProvider = undefined;
51
51
  }
52
52
  /**
53
- * Retrieves a format definition by its name from the format set. If not found, it checks the fallback provider to find the format, else returns undefined.
54
- * If the format is a string reference to another format, it resolves the reference and returns the FormatDefinition.
53
+ * Retrieves a format definition from the format set, resolving string references and consulting the fallback provider when needed.
55
54
  */
56
- async getFormat(input, system) {
57
- // Normalizes any schemaItem names coming from node addon 'schemaName:schemaItemName' -> 'schemaName.schemaItemName'
58
- const [schemaName, itemName] = SchemaItem_1.SchemaItem.parseFullName(input);
59
- const name = (schemaName === "") ? itemName : `${schemaName}.${itemName}`;
55
+ async getFormat(input, system, context) {
56
+ const lookupContext = extendProviderContext(context, this);
57
+ if (!lookupContext)
58
+ return undefined;
59
+ const name = normalizeFormatName(input);
60
60
  const format = this._formatSet.formats[name];
61
61
  if (format !== undefined) {
62
- // If format is a string reference, resolve it
63
- if (typeof format === "string") {
64
- return this.resolveReference(format, undefined, system);
65
- }
62
+ if (typeof format === "string")
63
+ return this.resolveReference(format, new Set(), system, lookupContext);
66
64
  return format;
67
65
  }
68
- if (this._fallbackProvider)
69
- return this._fallbackProvider.getFormat(name, system);
70
- return undefined;
66
+ return this.getFormatFromFallback(name, system, lookupContext);
67
+ }
68
+ async getFormatFromFallback(name, system, context) {
69
+ const fallbackProvider = this._fallbackProvider;
70
+ if (!fallbackProvider)
71
+ return undefined;
72
+ return fallbackProvider.getFormat(name, system, context);
73
+ }
74
+ /**
75
+ * Retrieves a format definition from the format set without awaiting a provider. String references are resolved
76
+ * locally; a fallback is used only when it implements `SyncFormatsProvider`.
77
+ */
78
+ getFormatSync(input, system, context) {
79
+ const lookupContext = extendProviderContext(context, this);
80
+ if (!lookupContext)
81
+ return undefined;
82
+ const name = normalizeFormatName(input);
83
+ const format = this._formatSet.formats[name];
84
+ if (format !== undefined) {
85
+ if (typeof format === "string")
86
+ return this.resolveReferenceSync(format, new Set(), system, lookupContext);
87
+ return format;
88
+ }
89
+ return this.getFormatSyncFromFallback(name, system, lookupContext);
90
+ }
91
+ getFormatSyncFromFallback(name, system, context) {
92
+ const fallbackProvider = this._fallbackProvider;
93
+ return typeof fallbackProvider?.getFormatSync === "function" ? fallbackProvider.getFormatSync(name, system, context) : undefined;
71
94
  }
72
95
  /**
73
96
  * Resolves a string reference to its FormatDefinition, following chains of references.
74
97
  * @param reference The string reference to resolve
75
98
  * @param visited Set of visited references to detect circular references
76
99
  * @param system Optional unit system override
100
+ * @param context Lookup context to forward to the fallback provider
77
101
  */
78
- async resolveReference(reference, visited = new Set(), system) {
102
+ async resolveReference(reference, visited, system, context) {
79
103
  // Prevent infinite loops from circular references
80
104
  if (visited.has(reference)) {
81
105
  return undefined;
82
106
  }
83
107
  visited.add(reference);
84
108
  const format = this._formatSet.formats[reference];
85
- if (format === undefined) {
86
- if (this._fallbackProvider) {
87
- return this._fallbackProvider.getFormat(reference, system);
88
- }
109
+ if (format === undefined)
110
+ return this.getFormatFromFallback(reference, system, context);
111
+ if (typeof format === "string")
112
+ return this.resolveReference(format, visited, system, context);
113
+ return format;
114
+ }
115
+ resolveReferenceSync(reference, visited, system, context) {
116
+ // Prevent infinite loops from circular references
117
+ if (visited.has(reference)) {
89
118
  return undefined;
90
119
  }
91
- // If we found another string reference, resolve it recursively
92
- if (typeof format === "string") {
93
- return this.resolveReference(format, visited, system);
94
- }
120
+ visited.add(reference);
121
+ const format = this._formatSet.formats[reference];
122
+ if (format === undefined)
123
+ return this.getFormatSyncFromFallback(reference, system, context);
124
+ if (typeof format === "string")
125
+ return this.resolveReferenceSync(format, visited, system, context);
95
126
  return format;
96
127
  }
97
128
  /**
@@ -128,4 +159,16 @@ class FormatSetFormatsProvider {
128
159
  }
129
160
  }
130
161
  exports.FormatSetFormatsProvider = FormatSetFormatsProvider;
162
+ function extendProviderContext(context, provider) {
163
+ const providerChain = new Set(context?.providerChain);
164
+ if (providerChain.has(provider))
165
+ return undefined;
166
+ providerChain.add(provider);
167
+ return { providerChain };
168
+ }
169
+ function normalizeFormatName(input) {
170
+ // Convert node-addon names from `schemaName:schemaItemName` to the dot-separated key used by FormatSet.
171
+ const [schemaName, itemName] = SchemaItem_1.SchemaItem.parseFullName(input);
172
+ return schemaName === "" ? itemName : `${schemaName}.${itemName}`;
173
+ }
131
174
  //# sourceMappingURL=FormatSetFormatsProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormatSetFormatsProvider.js","sourceRoot":"","sources":["../../../src/Formatting/FormatSetFormatsProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { BeEvent } from \"@itwin/core-bentley\";\r\nimport { FormatDefinition, FormatsChangedArgs, FormatsProvider, MutableFormatsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { FormatSet } from \"../Deserialization/JsonProps\";\r\nimport { SchemaItem } from \"../Metadata/SchemaItem\";\r\n\r\n/**\r\n * A mutable format provider that manages format definitions within a format set.\r\n * When formats are added or removed, the underlying format set is automatically updated.\r\n * @beta\r\n */\r\nexport class FormatSetFormatsProvider implements MutableFormatsProvider {\r\n public onFormatsChanged: BeEvent<(args: FormatsChangedArgs) => void> = new BeEvent<(args: FormatsChangedArgs) => void>();\r\n\r\n private _formatSet: FormatSet;\r\n private _fallbackProvider?: FormatsProvider;\r\n private _references: Map<string, string>; // Maps format name to the reference it points to\r\n\r\n public constructor(props: {formatSet: FormatSet, fallbackProvider?: FormatsProvider}) {\r\n this._formatSet = props.formatSet;\r\n this._fallbackProvider = props.fallbackProvider;\r\n this._references = new Map<string, string>();\r\n\r\n // Build up the map of string references\r\n for (const [name, format] of Object.entries(this._formatSet.formats)) {\r\n if (typeof format === \"string\") {\r\n this._references.set(name, format);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Adds or updates the format definition returned for a kind of quantity. Takes either a format definition or a kind of quantity full name that will be used to lookup the format that will be used.\r\n * @param name A kind of quantity full name used as a key to lookup this format\r\n * @param format The format definition or the name of a kind of quantity\r\n */\r\n public async addFormat(name: string, format: FormatDefinition | string): Promise<void> {\r\n this._formatSet.formats[name] = format;\r\n\r\n // Update the references map\r\n if (typeof format === \"string\") {\r\n this._references.set(name, format);\r\n } else {\r\n this._references.delete(name);\r\n }\r\n\r\n // Collect all formats that reference this format (directly or indirectly)\r\n const affectedFormats = this.getFormatsReferencingTarget(name);\r\n affectedFormats.add(name); // Include the format itself\r\n\r\n this.onFormatsChanged.raiseEvent({ formatsChanged: Array.from(affectedFormats) });\r\n }\r\n\r\n /**\r\n * Clears the fallback provider, if one is set.\r\n */\r\n public clearFallbackProvider(): void {\r\n this._fallbackProvider = undefined;\r\n }\r\n\r\n /**\r\n * Retrieves a format definition by its name from the format set. If not found, it checks the fallback provider to find the format, else returns undefined.\r\n * If the format is a string reference to another format, it resolves the reference and returns the FormatDefinition.\r\n */\r\n public async getFormat(input: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined> {\r\n // Normalizes any schemaItem names coming from node addon 'schemaName:schemaItemName' -> 'schemaName.schemaItemName'\r\n const [schemaName, itemName] = SchemaItem.parseFullName(input);\r\n\r\n const name = (schemaName === \"\") ? itemName : `${schemaName}.${itemName}`;\r\n const format = this._formatSet.formats[name];\r\n\r\n if (format !== undefined) {\r\n // If format is a string reference, resolve it\r\n if (typeof format === \"string\") {\r\n return this.resolveReference(format, undefined, system);\r\n }\r\n return format;\r\n }\r\n\r\n if (this._fallbackProvider) return this._fallbackProvider.getFormat(name, system);\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Resolves a string reference to its FormatDefinition, following chains of references.\r\n * @param reference The string reference to resolve\r\n * @param visited Set of visited references to detect circular references\r\n * @param system Optional unit system override\r\n */\r\n private async resolveReference(reference: string, visited: Set<string> = new Set(), system?: UnitSystemKey): Promise<FormatDefinition | undefined> {\r\n // Prevent infinite loops from circular references\r\n if (visited.has(reference)) {\r\n return undefined;\r\n }\r\n visited.add(reference);\r\n\r\n const format = this._formatSet.formats[reference];\r\n\r\n if (format === undefined) {\r\n if (this._fallbackProvider) {\r\n return this._fallbackProvider.getFormat(reference, system);\r\n }\r\n return undefined;\r\n }\r\n\r\n // If we found another string reference, resolve it recursively\r\n if (typeof format === \"string\") {\r\n return this.resolveReference(format, visited, system);\r\n }\r\n\r\n return format;\r\n }\r\n\r\n /**\r\n * Removes a format definition or string reference from the format set.\r\n * @param name The name of the format to remove\r\n */\r\n public async removeFormat(name: string): Promise<void> {\r\n // Collect all formats that reference this format (directly or indirectly)\r\n const affectedFormats = this.getFormatsReferencingTarget(name);\r\n affectedFormats.add(name); // Include the format itself\r\n\r\n delete this._formatSet.formats[name];\r\n this._references.delete(name);\r\n\r\n this.onFormatsChanged.raiseEvent({ formatsChanged: Array.from(affectedFormats) });\r\n }\r\n\r\n /**\r\n * Gets all format names that reference the target format (directly or indirectly).\r\n * @param target The format name to find references to\r\n * @returns Set of format names that reference the target\r\n */\r\n private getFormatsReferencingTarget(target: string): Set<string> {\r\n const referencingFormats = new Set<string>();\r\n\r\n // Find all formats that directly reference the target\r\n for (const [formatName, reference] of this._references.entries()) {\r\n if (reference === target) {\r\n referencingFormats.add(formatName);\r\n // Recursively find formats that reference this format\r\n const indirectReferences = this.getFormatsReferencingTarget(formatName);\r\n for (const indirectRef of indirectReferences) {\r\n referencingFormats.add(indirectRef);\r\n }\r\n }\r\n }\r\n\r\n return referencingFormats;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"FormatSetFormatsProvider.js","sourceRoot":"","sources":["../../../src/Formatting/FormatSetFormatsProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { BeEvent } from \"@itwin/core-bentley\";\r\nimport { FormatDefinition, FormatsChangedArgs, FormatsProvider, FormatsProviderContext, MutableFormatsProvider, SyncFormatsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { FormatSet } from \"../Deserialization/JsonProps\";\r\nimport { SchemaItem } from \"../Metadata/SchemaItem\";\r\n\r\n/**\r\n * A mutable format provider that manages format definitions within a format set.\r\n * When formats are added or removed, the underlying format set is automatically updated.\r\n * @beta\r\n */\r\nexport class FormatSetFormatsProvider implements MutableFormatsProvider, SyncFormatsProvider {\r\n public onFormatsChanged: BeEvent<(args: FormatsChangedArgs) => void> = new BeEvent<(args: FormatsChangedArgs) => void>();\r\n\r\n private _formatSet: FormatSet;\r\n private _fallbackProvider?: FormatsProvider;\r\n private _references: Map<string, string>; // Maps format name to the reference it points to\r\n\r\n public constructor(props: {formatSet: FormatSet, fallbackProvider?: FormatsProvider}) {\r\n this._formatSet = props.formatSet;\r\n this._fallbackProvider = props.fallbackProvider;\r\n this._references = new Map<string, string>();\r\n\r\n // Build up the map of string references\r\n for (const [name, format] of Object.entries(this._formatSet.formats)) {\r\n if (typeof format === \"string\") {\r\n this._references.set(name, format);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Adds or updates the format definition returned for a kind of quantity. Takes either a format definition or a kind of quantity full name that will be used to lookup the format that will be used.\r\n * @param name A kind of quantity full name used as a key to lookup this format\r\n * @param format The format definition or the name of a kind of quantity\r\n */\r\n public async addFormat(name: string, format: FormatDefinition | string): Promise<void> {\r\n this._formatSet.formats[name] = format;\r\n\r\n // Update the references map\r\n if (typeof format === \"string\") {\r\n this._references.set(name, format);\r\n } else {\r\n this._references.delete(name);\r\n }\r\n\r\n // Collect all formats that reference this format (directly or indirectly)\r\n const affectedFormats = this.getFormatsReferencingTarget(name);\r\n affectedFormats.add(name); // Include the format itself\r\n\r\n this.onFormatsChanged.raiseEvent({ formatsChanged: Array.from(affectedFormats) });\r\n }\r\n\r\n /**\r\n * Clears the fallback provider, if one is set.\r\n */\r\n public clearFallbackProvider(): void {\r\n this._fallbackProvider = undefined;\r\n }\r\n\r\n /**\r\n * Retrieves a format definition from the format set, resolving string references and consulting the fallback provider when needed.\r\n */\r\n public async getFormat(input: string, system?: UnitSystemKey, context?: FormatsProviderContext): Promise<FormatDefinition | undefined> {\r\n const lookupContext = extendProviderContext(context, this);\r\n if (!lookupContext)\r\n return undefined;\r\n\r\n const name = normalizeFormatName(input);\r\n const format = this._formatSet.formats[name];\r\n\r\n if (format !== undefined) {\r\n if (typeof format === \"string\")\r\n return this.resolveReference(format, new Set(), system, lookupContext);\r\n return format;\r\n }\r\n\r\n return this.getFormatFromFallback(name, system, lookupContext);\r\n }\r\n\r\n private async getFormatFromFallback(name: string, system: UnitSystemKey | undefined, context: FormatsProviderContext): Promise<FormatDefinition | undefined> {\r\n const fallbackProvider = this._fallbackProvider;\r\n if (!fallbackProvider)\r\n return undefined;\r\n return fallbackProvider.getFormat(name, system, context);\r\n }\r\n\r\n /**\r\n * Retrieves a format definition from the format set without awaiting a provider. String references are resolved\r\n * locally; a fallback is used only when it implements `SyncFormatsProvider`.\r\n */\r\n public getFormatSync(input: string, system?: UnitSystemKey, context?: FormatsProviderContext): FormatDefinition | undefined {\r\n const lookupContext = extendProviderContext(context, this);\r\n if (!lookupContext)\r\n return undefined;\r\n\r\n const name = normalizeFormatName(input);\r\n const format = this._formatSet.formats[name];\r\n\r\n if (format !== undefined) {\r\n if (typeof format === \"string\")\r\n return this.resolveReferenceSync(format, new Set(), system, lookupContext);\r\n return format;\r\n }\r\n\r\n return this.getFormatSyncFromFallback(name, system, lookupContext);\r\n }\r\n\r\n private getFormatSyncFromFallback(name: string, system: UnitSystemKey | undefined, context: FormatsProviderContext): FormatDefinition | undefined {\r\n const fallbackProvider: (FormatsProvider & Partial<SyncFormatsProvider>) | undefined = this._fallbackProvider;\r\n return typeof fallbackProvider?.getFormatSync === \"function\" ? fallbackProvider.getFormatSync(name, system, context) : undefined;\r\n }\r\n\r\n /**\r\n * Resolves a string reference to its FormatDefinition, following chains of references.\r\n * @param reference The string reference to resolve\r\n * @param visited Set of visited references to detect circular references\r\n * @param system Optional unit system override\r\n * @param context Lookup context to forward to the fallback provider\r\n */\r\n private async resolveReference(reference: string, visited: Set<string>, system: UnitSystemKey | undefined, context: FormatsProviderContext): Promise<FormatDefinition | undefined> {\r\n // Prevent infinite loops from circular references\r\n if (visited.has(reference)) {\r\n return undefined;\r\n }\r\n visited.add(reference);\r\n\r\n const format = this._formatSet.formats[reference];\r\n\r\n if (format === undefined)\r\n return this.getFormatFromFallback(reference, system, context);\r\n\r\n if (typeof format === \"string\")\r\n return this.resolveReference(format, visited, system, context);\r\n\r\n return format;\r\n }\r\n\r\n private resolveReferenceSync(reference: string, visited: Set<string>, system: UnitSystemKey | undefined, context: FormatsProviderContext): FormatDefinition | undefined {\r\n // Prevent infinite loops from circular references\r\n if (visited.has(reference)) {\r\n return undefined;\r\n }\r\n visited.add(reference);\r\n\r\n const format = this._formatSet.formats[reference];\r\n if (format === undefined)\r\n return this.getFormatSyncFromFallback(reference, system, context);\r\n\r\n if (typeof format === \"string\")\r\n return this.resolveReferenceSync(format, visited, system, context);\r\n\r\n return format;\r\n }\r\n\r\n /**\r\n * Removes a format definition or string reference from the format set.\r\n * @param name The name of the format to remove\r\n */\r\n public async removeFormat(name: string): Promise<void> {\r\n // Collect all formats that reference this format (directly or indirectly)\r\n const affectedFormats = this.getFormatsReferencingTarget(name);\r\n affectedFormats.add(name); // Include the format itself\r\n\r\n delete this._formatSet.formats[name];\r\n this._references.delete(name);\r\n\r\n this.onFormatsChanged.raiseEvent({ formatsChanged: Array.from(affectedFormats) });\r\n }\r\n\r\n /**\r\n * Gets all format names that reference the target format (directly or indirectly).\r\n * @param target The format name to find references to\r\n * @returns Set of format names that reference the target\r\n */\r\n private getFormatsReferencingTarget(target: string): Set<string> {\r\n const referencingFormats = new Set<string>();\r\n\r\n // Find all formats that directly reference the target\r\n for (const [formatName, reference] of this._references.entries()) {\r\n if (reference === target) {\r\n referencingFormats.add(formatName);\r\n // Recursively find formats that reference this format\r\n const indirectReferences = this.getFormatsReferencingTarget(formatName);\r\n for (const indirectRef of indirectReferences) {\r\n referencingFormats.add(indirectRef);\r\n }\r\n }\r\n }\r\n\r\n return referencingFormats;\r\n }\r\n}\r\n\r\nfunction extendProviderContext(context: FormatsProviderContext | undefined, provider: FormatsProvider): FormatsProviderContext | undefined {\r\n const providerChain = new Set(context?.providerChain);\r\n if (providerChain.has(provider))\r\n return undefined;\r\n\r\n providerChain.add(provider);\r\n return { providerChain };\r\n}\r\n\r\nfunction normalizeFormatName(input: string): string {\r\n // Convert node-addon names from `schemaName:schemaItemName` to the dot-separated key used by FormatSet.\r\n const [schemaName, itemName] = SchemaItem.parseFullName(input);\r\n return schemaName === \"\" ? itemName : `${schemaName}.${itemName}`;\r\n}\r\n"]}
@@ -3,12 +3,12 @@
3
3
  */
4
4
  import { ISchemaLocater, SchemaContext } from "../Context";
5
5
  import { BeEvent } from "@itwin/core-bentley";
6
- import { FormatDefinition, FormatsChangedArgs, FormatsProvider, UnitSystemKey } from "@itwin/core-quantity";
6
+ import { FormatDefinition, FormatsChangedArgs, FormatsProvider, SyncFormatsProvider, UnitSystemKey } from "@itwin/core-quantity";
7
7
  /**
8
8
  * Provides default formats and kind of quantities from a given SchemaContext or SchemaLocater.
9
9
  * @beta
10
10
  */
11
- export declare class SchemaFormatsProvider implements FormatsProvider {
11
+ export declare class SchemaFormatsProvider implements FormatsProvider, SyncFormatsProvider {
12
12
  private _context;
13
13
  private _unitSystem?;
14
14
  private _formatsRetrieved;
@@ -29,13 +29,22 @@ export declare class SchemaFormatsProvider implements FormatsProvider {
29
29
  /** When using a presentation unit from a KindOfQuantity, the label and description should come from the KindOfQuantity */
30
30
  private convertToFormatDefinition;
31
31
  private getKindOfQuantityFormatFromSchema;
32
+ private getKindOfQuantityFormatProps;
32
33
  /**
33
- * Retrieves a Format from a SchemaContext. If the format is part of a KindOfQuantity, the first presentation format in the KindOfQuantity that matches the current unit system will be retrieved.
34
- * If no presentation format matches the current unit system, the persistence unit format will be retrieved if it matches the current unit system.
35
- * Else, the default presentation format will be retrieved.
34
+ * Retrieves a format definition from the schema context.
35
+ *
36
+ * For a KindOfQuantity with a unit system, matching presentation formats are checked first, followed by the persistence unit and then the default presentation format. Without a unit system, the default presentation format is used.
36
37
  * @param name The full name of the Format or KindOfQuantity.
37
- * @returns
38
+ * @param system Optional unit system used to select a KindOfQuantity format.
38
39
  */
39
40
  getFormat(name: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined>;
41
+ /**
42
+ * Retrieves a format definition using only schema metadata already loaded in the context.
43
+ * It follows the same selection order as `getFormat` but never asks a locater to load a schema. Returns `undefined` when required metadata is not cached.
44
+ * Unlike `getFormat`, which logs lookup errors and returns `undefined`, this method treats only a schema that is still loading as a cache miss and rethrows other errors.
45
+ */
46
+ getFormatSync(name: string, system?: UnitSystemKey): FormatDefinition | undefined;
47
+ private getKindOfQuantityFormatFromSchemaSync;
48
+ private getKindOfQuantityFormatPropsSync;
40
49
  }
41
50
  //# sourceMappingURL=SchemaFormatsProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaFormatsProvider.d.ts","sourceRoot":"","sources":["../../../src/Formatting/SchemaFormatsProvider.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAK3D,OAAO,EAAE,OAAO,EAAU,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,gBAAgB,EAAe,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAMzH;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,iBAAiB,CAA0B;IAC5C,gBAAgB,iBAAsB,kBAAkB,KAAK,IAAI,EAAI;IAC5E;;;;;;;OAOG;gBACS,gBAAgB,EAAE,cAAc,EAAE,UAAU,CAAC,EAAE,aAAa;IAUxE,IAAW,OAAO,kBAA4B;IAC9C,IAAW,UAAU,IAEa,aAAa,GAAG,SAAS,CAFP;IAEpD,IAAW,UAAU,CAAC,UAAU,EAAE,aAAa,GAAG,SAAS,EAG1D;IAED,OAAO,CAAC,KAAK;IAMb,0HAA0H;IAC1H,OAAO,CAAC,yBAAyB;YAenB,iCAAiC;IA0D/C;;;;;;OAMG;IACU,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;CA8BpG"}
1
+ {"version":3,"file":"SchemaFormatsProvider.d.ts","sourceRoot":"","sources":["../../../src/Formatting/SchemaFormatsProvider.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAQ3D,OAAO,EAAE,OAAO,EAAU,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAe,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAO9I;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,eAAe,EAAE,mBAAmB;IAChF,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,iBAAiB,CAA0B;IAC5C,gBAAgB,iBAAsB,kBAAkB,KAAK,IAAI,EAAI;IAC5E;;;;;;;OAOG;gBACS,gBAAgB,EAAE,cAAc,EAAE,UAAU,CAAC,EAAE,aAAa;IAUxE,IAAW,OAAO,kBAA4B;IAC9C,IAAW,UAAU,IAEa,aAAa,GAAG,SAAS,CAFP;IAEpD,IAAW,UAAU,CAAC,UAAU,EAAE,aAAa,GAAG,SAAS,EAG1D;IAED,OAAO,CAAC,KAAK;IAMb,0HAA0H;IAC1H,OAAO,CAAC,yBAAyB;YAenB,iCAAiC;YAoBjC,4BAA4B;IA0B1C;;;;;;OAMG;IACU,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IA+BnG;;;;OAIG;IACI,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,gBAAgB,GAAG,SAAS;IAgBxF,OAAO,CAAC,qCAAqC;IAc7C,OAAO,CAAC,gCAAgC;CAkCzC"}