@twin.org/core 0.0.3-next.4 → 0.0.3-next.41

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 (144) hide show
  1. package/README.md +1 -9
  2. package/dist/es/encoding/base32.js +1 -1
  3. package/dist/es/encoding/base32.js.map +1 -1
  4. package/dist/es/encoding/base64.js +1 -1
  5. package/dist/es/encoding/base64.js.map +1 -1
  6. package/dist/es/errors/alreadyExistsError.js +1 -1
  7. package/dist/es/errors/alreadyExistsError.js.map +1 -1
  8. package/dist/es/errors/baseError.js +1 -1
  9. package/dist/es/errors/baseError.js.map +1 -1
  10. package/dist/es/errors/conflictError.js +1 -1
  11. package/dist/es/errors/conflictError.js.map +1 -1
  12. package/dist/es/errors/generalError.js +1 -1
  13. package/dist/es/errors/generalError.js.map +1 -1
  14. package/dist/es/errors/guardError.js +1 -1
  15. package/dist/es/errors/guardError.js.map +1 -1
  16. package/dist/es/errors/notFoundError.js +1 -1
  17. package/dist/es/errors/notFoundError.js.map +1 -1
  18. package/dist/es/errors/notSupportedError.js +1 -1
  19. package/dist/es/errors/notSupportedError.js.map +1 -1
  20. package/dist/es/errors/unauthorizedError.js +2 -2
  21. package/dist/es/errors/unauthorizedError.js.map +1 -1
  22. package/dist/es/errors/unprocessableError.js +1 -1
  23. package/dist/es/errors/unprocessableError.js.map +1 -1
  24. package/dist/es/factories/factory.js +41 -0
  25. package/dist/es/factories/factory.js.map +1 -1
  26. package/dist/es/helpers/arrayHelper.js +2 -0
  27. package/dist/es/helpers/arrayHelper.js.map +1 -1
  28. package/dist/es/helpers/jsonHelper.js.map +1 -1
  29. package/dist/es/helpers/objectHelper.js +12 -36
  30. package/dist/es/helpers/objectHelper.js.map +1 -1
  31. package/dist/es/helpers/randomHelper.js +50 -2
  32. package/dist/es/helpers/randomHelper.js.map +1 -1
  33. package/dist/es/helpers/stringHelper.js +11 -0
  34. package/dist/es/helpers/stringHelper.js.map +1 -1
  35. package/dist/es/index.js +4 -1
  36. package/dist/es/index.js.map +1 -1
  37. package/dist/es/models/IComponent.js +0 -2
  38. package/dist/es/models/IComponent.js.map +1 -1
  39. package/dist/es/models/IError.js.map +1 -1
  40. package/dist/es/models/IHealth.js +2 -0
  41. package/dist/es/models/IHealth.js.map +1 -0
  42. package/dist/es/models/healthStatus.js +21 -0
  43. package/dist/es/models/healthStatus.js.map +1 -0
  44. package/dist/es/types/objectOrArray.js.map +1 -0
  45. package/dist/es/types/singleOccurrenceArray.js +2 -0
  46. package/dist/es/types/singleOccurrenceArray.js.map +1 -0
  47. package/dist/es/types/urn.js +1 -2
  48. package/dist/es/types/urn.js.map +1 -1
  49. package/dist/es/utils/asyncCache.js +102 -75
  50. package/dist/es/utils/asyncCache.js.map +1 -1
  51. package/dist/es/utils/guards.js +16 -0
  52. package/dist/es/utils/guards.js.map +1 -1
  53. package/dist/es/utils/i18n.js.map +1 -1
  54. package/dist/es/utils/is.js +16 -0
  55. package/dist/es/utils/is.js.map +1 -1
  56. package/dist/types/encoding/base32.d.ts +1 -1
  57. package/dist/types/errors/alreadyExistsError.d.ts +1 -1
  58. package/dist/types/errors/baseError.d.ts +1 -1
  59. package/dist/types/errors/conflictError.d.ts +1 -1
  60. package/dist/types/errors/generalError.d.ts +1 -1
  61. package/dist/types/errors/guardError.d.ts +1 -1
  62. package/dist/types/errors/notFoundError.d.ts +1 -1
  63. package/dist/types/errors/notSupportedError.d.ts +1 -1
  64. package/dist/types/errors/unauthorizedError.d.ts +2 -2
  65. package/dist/types/errors/unprocessableError.d.ts +1 -1
  66. package/dist/types/factories/factory.d.ts +23 -1
  67. package/dist/types/helpers/arrayHelper.d.ts +1 -8
  68. package/dist/types/helpers/objectHelper.d.ts +18 -14
  69. package/dist/types/helpers/randomHelper.d.ts +16 -0
  70. package/dist/types/helpers/stringHelper.d.ts +6 -0
  71. package/dist/types/index.d.ts +4 -1
  72. package/dist/types/models/IComponent.d.ts +12 -0
  73. package/dist/types/models/IError.d.ts +1 -1
  74. package/dist/types/models/IHealth.d.ts +32 -0
  75. package/dist/types/models/healthStatus.d.ts +21 -0
  76. package/dist/types/types/singleOccurrenceArray.d.ts +9 -0
  77. package/dist/types/utils/asyncCache.d.ts +7 -0
  78. package/dist/types/utils/guards.d.ts +10 -1
  79. package/dist/types/utils/is.d.ts +7 -0
  80. package/docs/changelog.md +887 -184
  81. package/docs/examples.md +308 -1
  82. package/docs/reference/classes/AlreadyExistsError.md +36 -36
  83. package/docs/reference/classes/ArrayHelper.md +10 -44
  84. package/docs/reference/classes/AsyncCache.md +8 -8
  85. package/docs/reference/classes/Base32.md +4 -4
  86. package/docs/reference/classes/Base58.md +3 -3
  87. package/docs/reference/classes/Base64.md +4 -4
  88. package/docs/reference/classes/Base64Url.md +3 -3
  89. package/docs/reference/classes/BaseError.md +35 -35
  90. package/docs/reference/classes/BitString.md +6 -6
  91. package/docs/reference/classes/Coerce.md +11 -11
  92. package/docs/reference/classes/Compression.md +3 -3
  93. package/docs/reference/classes/ConflictError.md +36 -36
  94. package/docs/reference/classes/Converter.md +18 -18
  95. package/docs/reference/classes/EnvHelper.md +1 -1
  96. package/docs/reference/classes/ErrorHelper.md +3 -3
  97. package/docs/reference/classes/Factory.md +112 -18
  98. package/docs/reference/classes/FilenameHelper.md +1 -1
  99. package/docs/reference/classes/GeneralError.md +36 -36
  100. package/docs/reference/classes/GuardError.md +36 -36
  101. package/docs/reference/classes/Guards.md +72 -30
  102. package/docs/reference/classes/HexHelper.md +6 -6
  103. package/docs/reference/classes/I18n.md +14 -14
  104. package/docs/reference/classes/Is.md +67 -39
  105. package/docs/reference/classes/JsonHelper.md +10 -10
  106. package/docs/reference/classes/NotFoundError.md +36 -36
  107. package/docs/reference/classes/NotImplementedError.md +35 -35
  108. package/docs/reference/classes/NotSupportedError.md +36 -36
  109. package/docs/reference/classes/NumberHelper.md +2 -2
  110. package/docs/reference/classes/ObjectHelper.md +135 -73
  111. package/docs/reference/classes/RandomHelper.md +53 -1
  112. package/docs/reference/classes/SharedStore.md +3 -3
  113. package/docs/reference/classes/StringHelper.md +45 -23
  114. package/docs/reference/classes/Uint8ArrayHelper.md +1 -1
  115. package/docs/reference/classes/UnauthorizedError.md +37 -37
  116. package/docs/reference/classes/UnprocessableError.md +36 -36
  117. package/docs/reference/classes/Url.md +8 -8
  118. package/docs/reference/classes/Urn.md +24 -24
  119. package/docs/reference/classes/Validation.md +25 -25
  120. package/docs/reference/classes/ValidationError.md +35 -35
  121. package/docs/reference/index.md +5 -0
  122. package/docs/reference/interfaces/IComponent.md +40 -4
  123. package/docs/reference/interfaces/IError.md +11 -11
  124. package/docs/reference/interfaces/IHealth.md +55 -0
  125. package/docs/reference/interfaces/II18nShared.md +4 -4
  126. package/docs/reference/interfaces/IKeyValue.md +2 -2
  127. package/docs/reference/interfaces/ILabelledValue.md +2 -2
  128. package/docs/reference/interfaces/ILocale.md +2 -2
  129. package/docs/reference/interfaces/ILocaleDictionary.md +1 -1
  130. package/docs/reference/interfaces/ILocalesIndex.md +1 -1
  131. package/docs/reference/interfaces/IPatchOperation.md +6 -6
  132. package/docs/reference/interfaces/IUrlParts.md +9 -9
  133. package/docs/reference/interfaces/IValidationFailure.md +4 -4
  134. package/docs/reference/type-aliases/HealthStatus.md +5 -0
  135. package/docs/reference/type-aliases/SingleOccurrenceArray.md +15 -0
  136. package/docs/reference/type-aliases/SingleOccurrenceArrayDepthHelper.md +19 -0
  137. package/docs/reference/variables/CoerceType.md +10 -10
  138. package/docs/reference/variables/CompressionType.md +2 -2
  139. package/docs/reference/variables/HealthStatus.md +25 -0
  140. package/locales/en.json +5 -2
  141. package/package.json +6 -6
  142. package/dist/es/models/objectOrArray.js.map +0 -1
  143. /package/dist/es/{models → types}/objectOrArray.js +0 -0
  144. /package/dist/types/{models → types}/objectOrArray.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"urn.js","sourceRoot":"","sources":["../../../src/types/urn.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { GuardError } from \"../errors/guardError.js\";\nimport { RandomHelper } from \"../helpers/randomHelper.js\";\nimport type { IValidationFailure } from \"../models/IValidationFailure.js\";\nimport { Converter } from \"../utils/converter.js\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Class to help with urns.\n */\nexport class Urn {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Urn>();\n\n\t/**\n\t * The specific part of the namespace.\n\t * @internal\n\t */\n\tprivate readonly _urnParts: string[];\n\n\t/**\n\t * Create a new instance of Urn.\n\t * @param namespaceIdentifier The identifier for the namespace.\n\t * @param namespaceSpecific The specific part of the namespace.\n\t */\n\tconstructor(namespaceIdentifier: string, namespaceSpecific: string | string[]) {\n\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceIdentifier), namespaceIdentifier);\n\n\t\t// Strip leading and trailing colons\n\t\tthis._urnParts = [this.stripColons(namespaceIdentifier)];\n\n\t\tif (Is.array(namespaceSpecific)) {\n\t\t\tGuards.arrayValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...namespaceSpecific);\n\t\t} else {\n\t\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...this.stripColons(namespaceSpecific).split(\":\"));\n\t\t}\n\t}\n\n\t/**\n\t * Generate a random identifier with 32 byte id.\n\t * @param namespace The prefix for the urn.\n\t * @returns A new Id in URN format.\n\t */\n\tpublic static generateRandom(namespace: string): Urn {\n\t\treturn new Urn(namespace, Converter.bytesToHex(RandomHelper.generate(32)));\n\t}\n\n\t/**\n\t * Does the provided urn match the namespace.\n\t * @param urn The urn to check.\n\t * @param namespace The namespace to match.\n\t * @returns True if the namespace matches.\n\t */\n\tpublic static hasNamespace(urn: string, namespace: string): boolean {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\turn = urn.slice(4);\n\t\t}\n\n\t\tif (urn.length === namespace.length) {\n\t\t\treturn urn === namespace;\n\t\t}\n\n\t\treturn urn.startsWith(`${namespace}:`);\n\t}\n\n\t/**\n\t * Try and parse a string into the urn parts.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn or undefined if the value is not a urn.\n\t */\n\tpublic static tryParseExact(urn: unknown): Urn | undefined {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\tif (parts.length < 2) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!/[\\da-z][\\da-z-]{0,31}/.test(parts[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\tif (!/[\\d!#$%'()*+,./:;=?@_a-z-]+/.test(parts[i])) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Construct a urn from a string that has already been validated.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn.\n\t */\n\tpublic static fromValidString(urn: string): Urn {\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Add a urn: prefix if there isn't one already.\n\t * @param urn The urn string to add a prefix to.\n\t * @returns The urn with a prefix.\n\t */\n\tpublic static addPrefix(urn: unknown): string | undefined {\n\t\tif (Is.stringValue(urn)) {\n\t\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\t\treturn urn;\n\t\t\t}\n\t\t\treturn `urn:${urn}`;\n\t\t}\n\t}\n\n\t/**\n\t * Parse a string into the urn parts.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The urn to parse.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static guard(source: string, property: string, value: unknown): asserts value is string {\n\t\tGuards.stringValue(source, property, value);\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (!result) {\n\t\t\tthrow new GuardError(source, \"guard.urn\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Validate a string as a Urn.\n\t * @param property Throw an exception if the urn property is invalid.\n\t * @param value The urn to parse.\n\t * @param failures The list of failures to add to.\n\t * @param fieldNameResource The optional human readable name for the field as an i18 resource.\n\t * @returns The formatted urn.\n\t */\n\tpublic static validate(\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tfailures: IValidationFailure[],\n\t\tfieldNameResource?: string\n\t): value is string {\n\t\tif (!Is.stringValue(value)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beNotEmpty\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (Is.undefined(result)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beUrn\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get the parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The parts.\n\t */\n\tpublic parts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.slice(startIndex);\n\t}\n\n\t/**\n\t * Get the namespace identifier.\n\t * @returns The namespace identifier.\n\t */\n\tpublic namespaceIdentifier(): string {\n\t\treturn this._urnParts[0];\n\t}\n\n\t/**\n\t * Get the namespace method, the first component after the identifier.\n\t * @returns The namespace method.\n\t */\n\tpublic namespaceMethod(): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts[1] : \"\";\n\t}\n\n\t/**\n\t * Get the namespace specific parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific parts.\n\t */\n\tpublic namespaceSpecificParts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1) : [];\n\t}\n\n\t/**\n\t * Get the namespace specific.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific.\n\t */\n\tpublic namespaceSpecific(startIndex: number = 0): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1).join(\":\") : \"\";\n\t}\n\n\t/**\n\t * Convert the parts in to a full string.\n\t * @param omitPrefix Omit the urn: prefix from the string.\n\t * @returns The formatted urn.\n\t */\n\tpublic toString(omitPrefix: boolean = true): string {\n\t\treturn omitPrefix ? this._urnParts.join(\":\") : `urn:${this._urnParts.join(\":\")}`;\n\t}\n\n\t/**\n\t * Strip the leading and trailing colons from a string.\n\t * @param val The value to strip.\n\t * @returns The stripped string.\n\t * @internal\n\t */\n\tprivate stripColons(val: string): string {\n\t\treturn val.replace(/^:?(.*?):?$/, \"$1\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"urn.js","sourceRoot":"","sources":["../../../src/types/urn.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { GuardError } from \"../errors/guardError.js\";\nimport { RandomHelper } from \"../helpers/randomHelper.js\";\nimport type { IValidationFailure } from \"../models/IValidationFailure.js\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Class to help with urns.\n */\nexport class Urn {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Urn>();\n\n\t/**\n\t * The specific part of the namespace.\n\t * @internal\n\t */\n\tprivate readonly _urnParts: string[];\n\n\t/**\n\t * Create a new instance of Urn.\n\t * @param namespaceIdentifier The identifier for the namespace.\n\t * @param namespaceSpecific The specific part of the namespace.\n\t */\n\tconstructor(namespaceIdentifier: string, namespaceSpecific: string | string[]) {\n\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceIdentifier), namespaceIdentifier);\n\n\t\t// Strip leading and trailing colons\n\t\tthis._urnParts = [this.stripColons(namespaceIdentifier)];\n\n\t\tif (Is.array(namespaceSpecific)) {\n\t\t\tGuards.arrayValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...namespaceSpecific);\n\t\t} else {\n\t\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...this.stripColons(namespaceSpecific).split(\":\"));\n\t\t}\n\t}\n\n\t/**\n\t * Generate a random identifier with 32 byte id.\n\t * @param namespace The prefix for the urn.\n\t * @returns A new Id in URN format.\n\t */\n\tpublic static generateRandom(namespace: string): Urn {\n\t\treturn new Urn(namespace, RandomHelper.generateUuidV7(\"compact\"));\n\t}\n\n\t/**\n\t * Does the provided urn match the namespace.\n\t * @param urn The urn to check.\n\t * @param namespace The namespace to match.\n\t * @returns True if the namespace matches.\n\t */\n\tpublic static hasNamespace(urn: string, namespace: string): boolean {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\turn = urn.slice(4);\n\t\t}\n\n\t\tif (urn.length === namespace.length) {\n\t\t\treturn urn === namespace;\n\t\t}\n\n\t\treturn urn.startsWith(`${namespace}:`);\n\t}\n\n\t/**\n\t * Try and parse a string into the urn parts.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn or undefined if the value is not a urn.\n\t */\n\tpublic static tryParseExact(urn: unknown): Urn | undefined {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\tif (parts.length < 2) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!/[\\da-z][\\da-z-]{0,31}/.test(parts[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\tif (!/[\\d!#$%'()*+,./:;=?@_a-z-]+/.test(parts[i])) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Construct a urn from a string that has already been validated.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn.\n\t */\n\tpublic static fromValidString(urn: string): Urn {\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Add a urn: prefix if there isn't one already.\n\t * @param urn The urn string to add a prefix to.\n\t * @returns The urn with a prefix.\n\t */\n\tpublic static addPrefix(urn: unknown): string | undefined {\n\t\tif (Is.stringValue(urn)) {\n\t\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\t\treturn urn;\n\t\t\t}\n\t\t\treturn `urn:${urn}`;\n\t\t}\n\t}\n\n\t/**\n\t * Parse a string into the urn parts.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The urn to parse.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static guard(source: string, property: string, value: unknown): asserts value is string {\n\t\tGuards.stringValue(source, property, value);\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (!result) {\n\t\t\tthrow new GuardError(source, \"guard.urn\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Validate a string as a Urn.\n\t * @param property Throw an exception if the urn property is invalid.\n\t * @param value The urn to parse.\n\t * @param failures The list of failures to add to.\n\t * @param fieldNameResource The optional human readable name for the field as an i18 resource.\n\t * @returns The formatted urn.\n\t */\n\tpublic static validate(\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tfailures: IValidationFailure[],\n\t\tfieldNameResource?: string\n\t): value is string {\n\t\tif (!Is.stringValue(value)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beNotEmpty\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (Is.undefined(result)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beUrn\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get the parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The parts.\n\t */\n\tpublic parts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.slice(startIndex);\n\t}\n\n\t/**\n\t * Get the namespace identifier.\n\t * @returns The namespace identifier.\n\t */\n\tpublic namespaceIdentifier(): string {\n\t\treturn this._urnParts[0];\n\t}\n\n\t/**\n\t * Get the namespace method, the first component after the identifier.\n\t * @returns The namespace method.\n\t */\n\tpublic namespaceMethod(): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts[1] : \"\";\n\t}\n\n\t/**\n\t * Get the namespace specific parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific parts.\n\t */\n\tpublic namespaceSpecificParts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1) : [];\n\t}\n\n\t/**\n\t * Get the namespace specific.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific.\n\t */\n\tpublic namespaceSpecific(startIndex: number = 0): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1).join(\":\") : \"\";\n\t}\n\n\t/**\n\t * Convert the parts in to a full string.\n\t * @param omitPrefix Omit the urn: prefix from the string.\n\t * @returns The formatted urn.\n\t */\n\tpublic toString(omitPrefix: boolean = true): string {\n\t\treturn omitPrefix ? this._urnParts.join(\":\") : `urn:${this._urnParts.join(\":\")}`;\n\t}\n\n\t/**\n\t * Strip the leading and trailing colons from a string.\n\t * @param val The value to strip.\n\t * @returns The stripped string.\n\t * @internal\n\t */\n\tprivate stripColons(val: string): string {\n\t\treturn val.replace(/^:?(.*?):?$/, \"$1\");\n\t}\n}\n"]}
@@ -15,85 +15,96 @@ export class AsyncCache {
15
15
  * @returns The response.
16
16
  */
17
17
  static exec(key, ttlMs, requestMethod, cacheFailures) {
18
- const cacheEnabled = Is.integer(ttlMs) && ttlMs >= 0;
19
- if (cacheEnabled) {
20
- AsyncCache.cleanupExpired();
21
- const cache = AsyncCache.getSharedCache();
22
- // Do we have a cache entry for the key
23
- if (cache[key]) {
24
- if (!Is.empty(cache[key].result)) {
25
- // If the cache has already resulted in a value, resolve it
26
- return Promise.resolve(cache[key].result);
27
- }
28
- else if (!Is.empty(cache[key].error)) {
29
- // If the cache has already resulted in an error, reject it
30
- return Promise.reject(cache[key].error);
31
- }
32
- // Otherwise create a promise to return and store the resolver
33
- // and rejector in the cache entry, so that we can call then
34
- // when the request is done
35
- let storedResolve;
36
- let storedReject;
37
- const wait = new Promise((resolve, reject) => {
38
- storedResolve = resolve;
39
- storedReject = reject;
18
+ const cacheEnabled = Is.integer(ttlMs) && ttlMs > 0;
19
+ if (!cacheEnabled) {
20
+ // No caching, just execute the request method
21
+ return requestMethod();
22
+ }
23
+ AsyncCache.cleanupExpired();
24
+ const cache = AsyncCache.getSharedCache();
25
+ const cachedEntry = cache[key];
26
+ // Do we have a cache entry for the key
27
+ if (cachedEntry) {
28
+ if (!Is.empty(cachedEntry.result)) {
29
+ // If the cache has already resulted in a value, resolve it
30
+ return Promise.resolve(cachedEntry.result);
31
+ }
32
+ else if (!Is.empty(cachedEntry.error)) {
33
+ // If the cache has already resulted in an error, reject it
34
+ return Promise.reject(cachedEntry.error);
35
+ }
36
+ // Otherwise create a promise to return and store the resolver
37
+ // and rejector in the cache entry, so that we can call then
38
+ // when the request is done
39
+ let storedResolve;
40
+ let storedReject;
41
+ const wait = new Promise((resolve, reject) => {
42
+ storedResolve = resolve;
43
+ storedReject = reject;
44
+ });
45
+ if (!Is.empty(storedResolve) && !Is.empty(storedReject)) {
46
+ cachedEntry.promiseQueue.push({
47
+ requestMethod,
48
+ resolve: storedResolve,
49
+ reject: storedReject
40
50
  });
41
- if (!Is.empty(storedResolve) && !Is.empty(storedReject)) {
42
- cache[key].promiseQueue.push({
43
- requestMethod,
44
- resolve: storedResolve,
45
- reject: storedReject
46
- });
47
- }
48
- return wait;
49
51
  }
50
- // If we don't have a cache entry, create a new one
51
- cache[key] = {
52
- promiseQueue: [],
53
- expires: ttlMs === 0 ? 0 : Date.now() + ttlMs
54
- };
55
- // Return a promise that wraps the original request method
56
- // so that we can store any results or errors in the cache
57
- return new Promise((resolve, reject) => {
58
- // Call the request method and store the result
59
- requestMethod()
60
- // eslint-disable-next-line promise/prefer-await-to-then
61
- .then(res => {
62
- // If the request was successful, store the result
63
- cache[key].result = res;
64
- // and resolve both this promise and all the waiters
65
- resolve(res);
66
- for (const wait of cache[key].promiseQueue) {
67
- wait.resolve(res);
52
+ return wait;
53
+ }
54
+ // If we don't have a cache entry, create a new one
55
+ const cacheEntry = {
56
+ inProgress: true,
57
+ promiseQueue: [],
58
+ expires: Date.now() + ttlMs
59
+ };
60
+ cache[key] = cacheEntry;
61
+ // Return a promise that wraps the original request method
62
+ // so that we can store any results or errors in the cache
63
+ return new Promise((resolve, reject) => {
64
+ // Call the request method and store the result
65
+ requestMethod()
66
+ // eslint-disable-next-line promise/prefer-await-to-then
67
+ .then(res => {
68
+ // If the request was successful, store the result
69
+ cacheEntry.inProgress = false;
70
+ cacheEntry.result = res;
71
+ // and resolve both this promise and all the waiters
72
+ resolve(res);
73
+ for (const wait of cacheEntry.promiseQueue) {
74
+ wait.resolve(res);
75
+ }
76
+ cacheEntry.promiseQueue = [];
77
+ return res;
78
+ })
79
+ // eslint-disable-next-line promise/prefer-await-to-then
80
+ .catch((err) => {
81
+ // Reject the promise
82
+ reject(err);
83
+ cacheEntry.inProgress = false;
84
+ // Handle the waiters based on the cacheFailures flag
85
+ if (cacheFailures ?? false) {
86
+ // If we are caching failures, store the error and reject the waiters
87
+ cacheEntry.error = err;
88
+ for (const wait of cacheEntry.promiseQueue) {
89
+ wait.reject(err);
68
90
  }
69
- return res;
70
- })
71
- // eslint-disable-next-line promise/prefer-await-to-then
72
- .catch((err) => {
73
- // Reject the promise
74
- reject(err);
75
- // Handle the waiters based on the cacheFailures flag
76
- if (cacheFailures ?? false) {
77
- // If we are caching failures, store the error and reject the waiters
78
- cache[key].error = err;
79
- for (const wait of cache[key].promiseQueue) {
80
- wait.reject(err);
81
- }
82
- // Clear the waiters so we don't call them again
83
- cache[key].promiseQueue = [];
91
+ // Clear the waiters so we don't call them again
92
+ cacheEntry.promiseQueue = [];
93
+ }
94
+ else {
95
+ // If not caching failures for any queued requests we
96
+ // have no value to either resolve or reject, so we
97
+ // just resolve with the original request method
98
+ for (const wait of cacheEntry.promiseQueue) {
99
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
100
+ AsyncCache.resolveWaiter(wait.requestMethod, wait.resolve, wait.reject);
84
101
  }
85
- else {
86
- // If not caching failures for any queued requests we
87
- // have no value to either resolve or reject, so we
88
- // just resolve with the original request method
89
- for (const wait of cache[key].promiseQueue) {
90
- wait.resolve(wait.requestMethod());
91
- }
102
+ if (cache[key] === cacheEntry) {
92
103
  delete cache[key];
93
104
  }
94
- });
105
+ }
95
106
  });
96
- }
107
+ });
97
108
  }
98
109
  /**
99
110
  * Get an entry from the cache.
@@ -102,11 +113,11 @@ export class AsyncCache {
102
113
  */
103
114
  static async get(key) {
104
115
  const cache = AsyncCache.getSharedCache();
105
- if (!Is.empty(cache[key].result)) {
116
+ if (!Is.empty(cache[key]?.result)) {
106
117
  // If the cache has already resulted in a value, resolve it
107
118
  return cache[key].result;
108
119
  }
109
- else if (!Is.empty(cache[key].error)) {
120
+ if (!Is.empty(cache[key]?.error)) {
110
121
  // If the cache has already resulted in an error, reject it
111
122
  throw cache[key].error;
112
123
  }
@@ -157,7 +168,9 @@ export class AsyncCache {
157
168
  static cleanupExpired() {
158
169
  const cache = AsyncCache.getSharedCache();
159
170
  for (const entry in cache) {
160
- if (cache[entry].expires > 0 && cache[entry].expires < Date.now()) {
171
+ if (cache[entry].expires > 0 &&
172
+ cache[entry].expires < Date.now() &&
173
+ cache[entry].inProgress !== true) {
161
174
  delete cache[entry];
162
175
  }
163
176
  }
@@ -175,5 +188,19 @@ export class AsyncCache {
175
188
  }
176
189
  return sharedCache;
177
190
  }
191
+ /**
192
+ * Resolve a waiter by re-running its request method safely.
193
+ * @param requestMethod The method to execute.
194
+ * @param resolve The resolver for the waiter.
195
+ * @param reject The rejector for the waiter.
196
+ */
197
+ static async resolveWaiter(requestMethod, resolve, reject) {
198
+ try {
199
+ resolve(await requestMethod());
200
+ }
201
+ catch (waitErr) {
202
+ reject(waitErr);
203
+ }
204
+ }
178
205
  }
179
206
  //# sourceMappingURL=asyncCache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"asyncCache.js","sourceRoot":"","sources":["../../../src/utils/asyncCache.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"./is.js\";\nimport { SharedStore } from \"./sharedStore.js\";\n\n/**\n * Cache the results from asynchronous requests.\n */\nexport class AsyncCache {\n\t/**\n\t * Execute an async request and cache the result.\n\t * @param key The key for the entry in the cache.\n\t * @param ttlMs The TTL of the entry in the cache.\n\t * @param requestMethod The method to call if not cached.\n\t * @param cacheFailures Cache failure results, defaults to false.\n\t * @returns The response.\n\t */\n\tpublic static exec<T = unknown>(\n\t\tkey: string,\n\t\tttlMs: number | undefined,\n\t\trequestMethod: () => Promise<T>,\n\t\tcacheFailures?: boolean\n\t): Promise<T> | undefined {\n\t\tconst cacheEnabled = Is.integer(ttlMs) && ttlMs >= 0;\n\t\tif (cacheEnabled) {\n\t\t\tAsyncCache.cleanupExpired();\n\n\t\t\tconst cache = AsyncCache.getSharedCache<T>();\n\n\t\t\t// Do we have a cache entry for the key\n\t\t\tif (cache[key]) {\n\t\t\t\tif (!Is.empty(cache[key].result)) {\n\t\t\t\t\t// If the cache has already resulted in a value, resolve it\n\t\t\t\t\treturn Promise.resolve(cache[key].result);\n\t\t\t\t} else if (!Is.empty(cache[key].error)) {\n\t\t\t\t\t// If the cache has already resulted in an error, reject it\n\t\t\t\t\treturn Promise.reject(cache[key].error);\n\t\t\t\t}\n\n\t\t\t\t// Otherwise create a promise to return and store the resolver\n\t\t\t\t// and rejector in the cache entry, so that we can call then\n\t\t\t\t// when the request is done\n\n\t\t\t\tlet storedResolve: ((value: T | PromiseLike<T>) => void) | undefined;\n\t\t\t\tlet storedReject: ((reason?: unknown) => void) | undefined;\n\t\t\t\tconst wait = new Promise<T>((resolve, reject) => {\n\t\t\t\t\tstoredResolve = resolve;\n\t\t\t\t\tstoredReject = reject;\n\t\t\t\t});\n\t\t\t\tif (!Is.empty(storedResolve) && !Is.empty(storedReject)) {\n\t\t\t\t\tcache[key].promiseQueue.push({\n\t\t\t\t\t\trequestMethod,\n\t\t\t\t\t\tresolve: storedResolve,\n\t\t\t\t\t\treject: storedReject\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn wait;\n\t\t\t}\n\n\t\t\t// If we don't have a cache entry, create a new one\n\t\t\tcache[key] = {\n\t\t\t\tpromiseQueue: [],\n\t\t\t\texpires: ttlMs === 0 ? 0 : Date.now() + ttlMs\n\t\t\t};\n\n\t\t\t// Return a promise that wraps the original request method\n\t\t\t// so that we can store any results or errors in the cache\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t// Call the request method and store the result\n\t\t\t\trequestMethod()\n\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\t\t\t\t.then(res => {\n\t\t\t\t\t\t// If the request was successful, store the result\n\t\t\t\t\t\tcache[key].result = res;\n\n\t\t\t\t\t\t// and resolve both this promise and all the waiters\n\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t\tfor (const wait of cache[key].promiseQueue) {\n\t\t\t\t\t\t\twait.resolve(res);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t})\n\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\t\t\t\t.catch((err: Error) => {\n\t\t\t\t\t\t// Reject the promise\n\t\t\t\t\t\treject(err);\n\n\t\t\t\t\t\t// Handle the waiters based on the cacheFailures flag\n\t\t\t\t\t\tif (cacheFailures ?? false) {\n\t\t\t\t\t\t\t// If we are caching failures, store the error and reject the waiters\n\t\t\t\t\t\t\tcache[key].error = err;\n\t\t\t\t\t\t\tfor (const wait of cache[key].promiseQueue) {\n\t\t\t\t\t\t\t\twait.reject(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Clear the waiters so we don't call them again\n\t\t\t\t\t\t\tcache[key].promiseQueue = [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// If not caching failures for any queued requests we\n\t\t\t\t\t\t\t// have no value to either resolve or reject, so we\n\t\t\t\t\t\t\t// just resolve with the original request method\n\t\t\t\t\t\t\tfor (const wait of cache[key].promiseQueue) {\n\t\t\t\t\t\t\t\twait.resolve(wait.requestMethod());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete cache[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get an entry from the cache.\n\t * @param key The key to get from the cache.\n\t * @returns The item from the cache if it exists.\n\t */\n\tpublic static async get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst cache = AsyncCache.getSharedCache<T>();\n\t\tif (!Is.empty(cache[key].result)) {\n\t\t\t// If the cache has already resulted in a value, resolve it\n\t\t\treturn cache[key].result;\n\t\t} else if (!Is.empty(cache[key].error)) {\n\t\t\t// If the cache has already resulted in an error, reject it\n\t\t\tthrow cache[key].error;\n\t\t}\n\t}\n\n\t/**\n\t * Set an entry into the cache.\n\t * @param key The key to set in the cache.\n\t * @param value The value to set in the cache.\n\t * @param ttlMs The TTL of the entry in the cache in ms, defaults to 1s.\n\t * @returns Nothing.\n\t */\n\tpublic static async set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void> {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tcache[key] = {\n\t\t\tresult: value,\n\t\t\tpromiseQueue: [],\n\t\t\texpires: Date.now() + (ttlMs ?? 1000)\n\t\t};\n\t}\n\n\t/**\n\t * Remove an entry from the cache.\n\t * @param key The key to remove from the cache.\n\t */\n\tpublic static remove(key: string): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tdelete cache[key];\n\t}\n\n\t/**\n\t * Clear the cache.\n\t * @param prefix Optional prefix to clear only entries with that prefix.\n\t */\n\tpublic static clearCache(prefix?: string): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tif (Is.stringValue(prefix)) {\n\t\t\tfor (const entry in cache) {\n\t\t\t\tif (entry.startsWith(prefix)) {\n\t\t\t\t\tdelete cache[entry];\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tSharedStore.set(\"asyncCache\", {});\n\t\t}\n\t}\n\n\t/**\n\t * Perform a cleanup of the expired entries in the cache.\n\t */\n\tpublic static cleanupExpired(): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tfor (const entry in cache) {\n\t\t\tif (cache[entry].expires > 0 && cache[entry].expires < Date.now()) {\n\t\t\t\tdelete cache[entry];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared cache.\n\t * @returns The shared cache.\n\t * @internal\n\t */\n\tprivate static getSharedCache<T = unknown>(): {\n\t\t[url: string]: {\n\t\t\tresult?: T;\n\t\t\terror?: Error;\n\t\t\tpromiseQueue: {\n\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t}[];\n\t\t\texpires: number;\n\t\t};\n\t} {\n\t\tlet sharedCache = SharedStore.get<{\n\t\t\t[url: string]: {\n\t\t\t\tresult?: T;\n\t\t\t\terror?: Error;\n\t\t\t\tpromiseQueue: {\n\t\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t\t}[];\n\t\t\t\texpires: number;\n\t\t\t};\n\t\t}>(\"asyncCache\");\n\n\t\tif (Is.undefined(sharedCache)) {\n\t\t\tsharedCache = {};\n\t\t\tSharedStore.set(\"asyncCache\", sharedCache);\n\t\t}\n\n\t\treturn sharedCache;\n\t}\n}\n"]}
1
+ {"version":3,"file":"asyncCache.js","sourceRoot":"","sources":["../../../src/utils/asyncCache.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"./is.js\";\nimport { SharedStore } from \"./sharedStore.js\";\n\n/**\n * Cache the results from asynchronous requests.\n */\nexport class AsyncCache {\n\t/**\n\t * Execute an async request and cache the result.\n\t * @param key The key for the entry in the cache.\n\t * @param ttlMs The TTL of the entry in the cache.\n\t * @param requestMethod The method to call if not cached.\n\t * @param cacheFailures Cache failure results, defaults to false.\n\t * @returns The response.\n\t */\n\tpublic static exec<T = unknown>(\n\t\tkey: string,\n\t\tttlMs: number | undefined,\n\t\trequestMethod: () => Promise<T>,\n\t\tcacheFailures?: boolean\n\t): Promise<T> | undefined {\n\t\tconst cacheEnabled = Is.integer(ttlMs) && ttlMs > 0;\n\t\tif (!cacheEnabled) {\n\t\t\t// No caching, just execute the request method\n\t\t\treturn requestMethod();\n\t\t}\n\n\t\tAsyncCache.cleanupExpired();\n\n\t\tconst cache = AsyncCache.getSharedCache<T>();\n\t\tconst cachedEntry = cache[key];\n\n\t\t// Do we have a cache entry for the key\n\t\tif (cachedEntry) {\n\t\t\tif (!Is.empty(cachedEntry.result)) {\n\t\t\t\t// If the cache has already resulted in a value, resolve it\n\t\t\t\treturn Promise.resolve(cachedEntry.result);\n\t\t\t} else if (!Is.empty(cachedEntry.error)) {\n\t\t\t\t// If the cache has already resulted in an error, reject it\n\t\t\t\treturn Promise.reject(cachedEntry.error);\n\t\t\t}\n\n\t\t\t// Otherwise create a promise to return and store the resolver\n\t\t\t// and rejector in the cache entry, so that we can call then\n\t\t\t// when the request is done\n\n\t\t\tlet storedResolve: ((value: T | PromiseLike<T>) => void) | undefined;\n\t\t\tlet storedReject: ((reason?: unknown) => void) | undefined;\n\t\t\tconst wait = new Promise<T>((resolve, reject) => {\n\t\t\t\tstoredResolve = resolve;\n\t\t\t\tstoredReject = reject;\n\t\t\t});\n\t\t\tif (!Is.empty(storedResolve) && !Is.empty(storedReject)) {\n\t\t\t\tcachedEntry.promiseQueue.push({\n\t\t\t\t\trequestMethod,\n\t\t\t\t\tresolve: storedResolve,\n\t\t\t\t\treject: storedReject\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn wait;\n\t\t}\n\n\t\t// If we don't have a cache entry, create a new one\n\t\tconst cacheEntry: {\n\t\t\tresult?: T;\n\t\t\terror?: unknown;\n\t\t\tinProgress?: boolean;\n\t\t\tpromiseQueue: {\n\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t}[];\n\t\t\texpires: number;\n\t\t} = {\n\t\t\tinProgress: true,\n\t\t\tpromiseQueue: [],\n\t\t\texpires: Date.now() + ttlMs\n\t\t};\n\t\tcache[key] = cacheEntry;\n\n\t\t// Return a promise that wraps the original request method\n\t\t// so that we can store any results or errors in the cache\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Call the request method and store the result\n\t\t\trequestMethod()\n\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\t\t\t.then(res => {\n\t\t\t\t\t// If the request was successful, store the result\n\t\t\t\t\tcacheEntry.inProgress = false;\n\t\t\t\t\tcacheEntry.result = res;\n\n\t\t\t\t\t// and resolve both this promise and all the waiters\n\t\t\t\t\tresolve(res);\n\t\t\t\t\tfor (const wait of cacheEntry.promiseQueue) {\n\t\t\t\t\t\twait.resolve(res);\n\t\t\t\t\t}\n\t\t\t\t\tcacheEntry.promiseQueue = [];\n\t\t\t\t\treturn res;\n\t\t\t\t})\n\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\t// Reject the promise\n\t\t\t\t\treject(err);\n\t\t\t\t\tcacheEntry.inProgress = false;\n\n\t\t\t\t\t// Handle the waiters based on the cacheFailures flag\n\t\t\t\t\tif (cacheFailures ?? false) {\n\t\t\t\t\t\t// If we are caching failures, store the error and reject the waiters\n\t\t\t\t\t\tcacheEntry.error = err;\n\t\t\t\t\t\tfor (const wait of cacheEntry.promiseQueue) {\n\t\t\t\t\t\t\twait.reject(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Clear the waiters so we don't call them again\n\t\t\t\t\t\tcacheEntry.promiseQueue = [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If not caching failures for any queued requests we\n\t\t\t\t\t\t// have no value to either resolve or reject, so we\n\t\t\t\t\t\t// just resolve with the original request method\n\t\t\t\t\t\tfor (const wait of cacheEntry.promiseQueue) {\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\t\t\t\tAsyncCache.resolveWaiter(wait.requestMethod, wait.resolve, wait.reject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (cache[key] === cacheEntry) {\n\t\t\t\t\t\t\tdelete cache[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Get an entry from the cache.\n\t * @param key The key to get from the cache.\n\t * @returns The item from the cache if it exists.\n\t */\n\tpublic static async get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst cache = AsyncCache.getSharedCache<T>();\n\t\tif (!Is.empty(cache[key]?.result)) {\n\t\t\t// If the cache has already resulted in a value, resolve it\n\t\t\treturn cache[key].result;\n\t\t}\n\n\t\tif (!Is.empty(cache[key]?.error)) {\n\t\t\t// If the cache has already resulted in an error, reject it\n\t\t\tthrow cache[key].error as Error;\n\t\t}\n\t}\n\n\t/**\n\t * Set an entry into the cache.\n\t * @param key The key to set in the cache.\n\t * @param value The value to set in the cache.\n\t * @param ttlMs The TTL of the entry in the cache in ms, defaults to 1s.\n\t * @returns Nothing.\n\t */\n\tpublic static async set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void> {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tcache[key] = {\n\t\t\tresult: value,\n\t\t\tpromiseQueue: [],\n\t\t\texpires: Date.now() + (ttlMs ?? 1000)\n\t\t};\n\t}\n\n\t/**\n\t * Remove an entry from the cache.\n\t * @param key The key to remove from the cache.\n\t */\n\tpublic static remove(key: string): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tdelete cache[key];\n\t}\n\n\t/**\n\t * Clear the cache.\n\t * @param prefix Optional prefix to clear only entries with that prefix.\n\t */\n\tpublic static clearCache(prefix?: string): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tif (Is.stringValue(prefix)) {\n\t\t\tfor (const entry in cache) {\n\t\t\t\tif (entry.startsWith(prefix)) {\n\t\t\t\t\tdelete cache[entry];\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tSharedStore.set(\"asyncCache\", {});\n\t\t}\n\t}\n\n\t/**\n\t * Perform a cleanup of the expired entries in the cache.\n\t */\n\tpublic static cleanupExpired(): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tfor (const entry in cache) {\n\t\t\tif (\n\t\t\t\tcache[entry].expires > 0 &&\n\t\t\t\tcache[entry].expires < Date.now() &&\n\t\t\t\tcache[entry].inProgress !== true\n\t\t\t) {\n\t\t\t\tdelete cache[entry];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared cache.\n\t * @returns The shared cache.\n\t * @internal\n\t */\n\tprivate static getSharedCache<T = unknown>(): {\n\t\t[url: string]: {\n\t\t\tresult?: T;\n\t\t\terror?: unknown;\n\t\t\tinProgress?: boolean;\n\t\t\tpromiseQueue: {\n\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t}[];\n\t\t\texpires: number;\n\t\t};\n\t} {\n\t\tlet sharedCache = SharedStore.get<{\n\t\t\t[url: string]: {\n\t\t\t\tresult?: T;\n\t\t\t\terror?: unknown;\n\t\t\t\tinProgress?: boolean;\n\t\t\t\tpromiseQueue: {\n\t\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t\t}[];\n\t\t\t\texpires: number;\n\t\t\t};\n\t\t}>(\"asyncCache\");\n\n\t\tif (Is.undefined(sharedCache)) {\n\t\t\tsharedCache = {};\n\t\t\tSharedStore.set(\"asyncCache\", sharedCache);\n\t\t}\n\n\t\treturn sharedCache;\n\t}\n\n\t/**\n\t * Resolve a waiter by re-running its request method safely.\n\t * @param requestMethod The method to execute.\n\t * @param resolve The resolver for the waiter.\n\t * @param reject The rejector for the waiter.\n\t */\n\tprivate static async resolveWaiter<T>(\n\t\trequestMethod: () => Promise<T>,\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: unknown) => void\n\t): Promise<void> {\n\t\ttry {\n\t\t\tresolve(await requestMethod());\n\t\t} catch (waitErr) {\n\t\t\treject(waitErr);\n\t\t}\n\t}\n}\n"]}
@@ -365,5 +365,21 @@ export class Guards {
365
365
  throw new GuardError(source, "guard.email", property, value);
366
366
  }
367
367
  }
368
+ /**
369
+ * Is the property a string containing uuidV7.
370
+ * @param source The source of the error.
371
+ * @param property The name of the property.
372
+ * @param value The value to test.
373
+ * @param format The format of the uuidV7, either standard or compact.
374
+ * @throws GuardError If the value does not match the assertion.
375
+ */
376
+ static uuidV7(source, property, value, format) {
377
+ if (!Is.uuidV7(value, format)) {
378
+ if (format === "compact") {
379
+ throw new GuardError(source, "guard.uuidV7Compact", property, value);
380
+ }
381
+ throw new GuardError(source, "guard.uuidV7", property, value);
382
+ }
383
+ }
368
384
  }
369
385
  //# sourceMappingURL=guards.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/utils/guards.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGpD;;GAEG;AACH,MAAM,OAAO,MAAM;IAClB;;;;;;OAMG;IACI,MAAM,CAAC,OAAO,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACrE,IAAI,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACpE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,WAAW,CACxB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,IAAI,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QAClE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,YAAY,CACzB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,eAAe,CAC5B,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,uBAAuB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,YAAY,CACzB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrE,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,SAAS,CACtB,MAAc,EACd,QAAgB,EAChB,KAAc,EACd,cAAuB,KAAK;QAE5B,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,eAAe,CAC5B,MAAc,EACd,QAAgB,EAChB,KAAc,EACd,MAAc,EACd,cAAuB,KAAK;QAE5B,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QACvD,IAAI,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACpD,MAAM,IAAI,UAAU,CACnB,MAAM,EACN,uBAAuB,EACvB,QAAQ,EACR,KAAK,CAAC,MAAM,EACZ,MAAM,CAAC,QAAQ,EAAE,CACjB,CAAC;QACH,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACpE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,OAAO,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACrE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACpE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,OAAO,CACpB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,IAAI,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QAClE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,qBAAqB,CAClC,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,6BAA6B,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9E,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,gBAAgB,CAC7B,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,wBAAwB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CACnB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,uBAAuB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,MAAM,CAAI,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,WAAW,CACxB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,uBAAuB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,MAAM,CAAI,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,KAAK,CAAI,MAAc,EAAE,QAAgB,EAAE,KAAc;QACtE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAI,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,UAAU,CACvB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,UAAU,CACvB,MAAc,EACd,QAAgB,EAChB,KAAQ,EACR,OAAY;QAEZ,IAAI,CAAC,EAAE,CAAC,KAAK,CAAI,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvF,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,eAAe,CAC5B,MAAc,EACd,QAAgB,EAChB,KAAc,EACd,WAA6B;QAE7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAI,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAEpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAI,gBAAgB,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACzE,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAI,UAAU,CACnB,MAAM,EACN,uBAAuB,EACvB,QAAQ,EACR,KAAK,EACL,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3B,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,aAAa,CAC1B,MAAc,EACd,QAAgB,EAChB,KAAc,EACd,SAA2B;QAE3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAI,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,cAAc,GAAG,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAEhE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAI,cAAc,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;QACvE,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACnF,MAAM,IAAI,UAAU,CACnB,MAAM,EACN,qBAAqB,EACrB,QAAQ,EACR,KAAK,EACL,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CACzB,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,UAAU,CACvB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACH,8DAA8D;IACvD,MAAM,CAAC,QAAQ,CACrB,MAAc,EACd,QAAgB,EAChB,KAAc;QAEd,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAI,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,KAAK,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACnE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"./is.js\";\nimport { GuardError } from \"../errors/guardError.js\";\nimport { ArrayHelper } from \"../helpers/arrayHelper.js\";\nimport { HexHelper } from \"../helpers/hexHelper.js\";\nimport type { ObjectOrArray } from \"../models/objectOrArray.js\";\n\n/**\n * Class to handle guard operations for parameters.\n */\nexport class Guards {\n\t/**\n\t * Is the property defined.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static defined(source: string, property: string, value: unknown): asserts value {\n\t\tif (Is.undefined(value)) {\n\t\t\tthrow new GuardError(source, \"guard.undefined\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static string(source: string, property: string, value: unknown): asserts value is string {\n\t\tif (!Is.string(value)) {\n\t\t\tthrow new GuardError(source, \"guard.string\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string with a value.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringValue(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.string(value)) {\n\t\t\tthrow new GuardError(source, \"guard.string\", property, value);\n\t\t}\n\t\tif (value.length === 0) {\n\t\t\tthrow new GuardError(source, \"guard.stringEmpty\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a JSON value.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static json(source: string, property: string, value: unknown): asserts value is string {\n\t\tif (!Is.json(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringJson\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a base64 string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringBase64(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.stringBase64(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringBase64\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a base64 url string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringBase64Url(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.stringBase64Url(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringBase64Url\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a base58 string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringBase58(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.stringBase58(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringBase58\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string with a hex value.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param allowPrefix Allow the hex to have the 0x prefix.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringHex(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tallowPrefix: boolean = false\n\t): asserts value is string {\n\t\tGuards.stringValue(source, property, value);\n\t\tif (!HexHelper.isHex(value, allowPrefix)) {\n\t\t\tthrow new GuardError(source, \"guard.stringHex\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string with a hex value with fixed length.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param length The length of the string to match.\n\t * @param allowPrefix Allow the hex to have the 0x prefix.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringHexLength(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tlength: number,\n\t\tallowPrefix: boolean = false\n\t): asserts value is string {\n\t\tGuards.stringHex(source, property, value, allowPrefix);\n\t\tif (HexHelper.stripPrefix(value).length !== length) {\n\t\t\tthrow new GuardError(\n\t\t\t\tsource,\n\t\t\t\t\"guard.stringHexLength\",\n\t\t\t\tproperty,\n\t\t\t\tvalue.length,\n\t\t\t\tlength.toString()\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a number.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static number(source: string, property: string, value: unknown): asserts value is number {\n\t\tif (!Is.number(value)) {\n\t\t\tthrow new GuardError(source, \"guard.number\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property an integer.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static integer(source: string, property: string, value: unknown): asserts value is number {\n\t\tif (!Is.integer(value)) {\n\t\t\tthrow new GuardError(source, \"guard.integer\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a bigint.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static bigint(source: string, property: string, value: unknown): asserts value is bigint {\n\t\tif (!Is.bigint(value)) {\n\t\t\tthrow new GuardError(source, \"guard.bigint\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a boolean.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static boolean(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is boolean {\n\t\tif (!Is.boolean(value)) {\n\t\t\tthrow new GuardError(source, \"guard.boolean\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a date.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static date(source: string, property: string, value: unknown): asserts value is Date {\n\t\tif (!Is.date(value)) {\n\t\t\tthrow new GuardError(source, \"guard.date\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a timestamp in milliseconds.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static timestampMilliseconds(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is number {\n\t\tif (!Is.timestampMilliseconds(value)) {\n\t\t\tthrow new GuardError(source, \"guard.timestampMilliseconds\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a timestamp in seconds.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static timestampSeconds(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is number {\n\t\tif (!Is.timestampSeconds(value)) {\n\t\t\tthrow new GuardError(source, \"guard.timestampSeconds\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property an object.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static object<T = { [id: string]: unknown }>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T {\n\t\tif (Is.undefined(value)) {\n\t\t\tthrow new GuardError(source, \"guard.objectUndefined\", property, value);\n\t\t}\n\t\tif (!Is.object<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.object\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property is an object with at least one property.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static objectValue<T = { [id: string]: unknown }>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T {\n\t\tif (Is.undefined(value)) {\n\t\t\tthrow new GuardError(source, \"guard.objectUndefined\", property, value);\n\t\t}\n\t\tif (!Is.object<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.object\", property, value);\n\t\t}\n\t\tif (Object.keys(value || {}).length === 0) {\n\t\t\tthrow new GuardError(source, \"guard.objectValue\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property is an array.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static array<T>(source: string, property: string, value: unknown): asserts value is T[] {\n\t\tif (!Is.array<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property is an array with at least one item.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayValue<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T[] {\n\t\tif (!Is.array(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\t\tif (value.length === 0) {\n\t\t\tthrow new GuardError(source, \"guard.arrayValue\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property one of a list of items.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param options The options the value must be one of.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayOneOf<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: T,\n\t\toptions: T[]\n\t): asserts value is T {\n\t\tif (!Is.array<T>(options)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\t\tif (!options.includes(value)) {\n\t\t\tthrow new GuardError(source, \"guard.arrayOneOf\", property, value, options.join(\", \"));\n\t\t}\n\t}\n\n\t/**\n\t * Does the array start with the specified data.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param startValues The values that must start the array.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayStartsWith<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tstartValues: ObjectOrArray<T>\n\t): asserts value is T[] {\n\t\tif (!Is.arrayValue<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\n\t\tconst startValuesArray = ArrayHelper.fromObjectOrArray(startValues);\n\n\t\tif (!Is.arrayValue<T>(startValuesArray)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, startValuesArray);\n\t\t}\n\n\t\tfor (let i = 0; i < startValuesArray.length; i++) {\n\t\t\tif (value[i] !== startValuesArray[i]) {\n\t\t\t\tthrow new GuardError(\n\t\t\t\t\tsource,\n\t\t\t\t\t\"guard.arrayStartsWith\",\n\t\t\t\t\tproperty,\n\t\t\t\t\tvalue,\n\t\t\t\t\tstartValuesArray.join(\", \")\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Does the array end with the specified data.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param endValues The values that must end the array.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayEndsWith<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tendValues: ObjectOrArray<T>\n\t): asserts value is T[] {\n\t\tif (!Is.arrayValue<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\n\t\tconst endValuesArray = ArrayHelper.fromObjectOrArray(endValues);\n\n\t\tif (!Is.arrayValue<T>(endValuesArray)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, endValuesArray);\n\t\t}\n\n\t\tfor (let i = 0; i < endValuesArray.length; i++) {\n\t\t\tif (value[value.length - i - 1] !== endValuesArray[endValuesArray.length - i - 1]) {\n\t\t\t\tthrow new GuardError(\n\t\t\t\t\tsource,\n\t\t\t\t\t\"guard.arrayEndsWith\",\n\t\t\t\t\tproperty,\n\t\t\t\t\tvalue,\n\t\t\t\t\tendValuesArray.join(\", \")\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a Uint8Array.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static uint8Array(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is Uint8Array {\n\t\tif (!Is.uint8Array(value)) {\n\t\t\tthrow new GuardError(source, \"guard.uint8Array\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a function.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static function<T extends (...args: any[]) => any = (...args: any[]) => any>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T {\n\t\tif (!Is.function<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.function\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string formatted as an email address.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static email(source: string, property: string, value: unknown): asserts value is string {\n\t\tif (!Is.email(value)) {\n\t\t\tthrow new GuardError(source, \"guard.email\", property, value);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/utils/guards.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"./is.js\";\nimport { GuardError } from \"../errors/guardError.js\";\nimport { ArrayHelper } from \"../helpers/arrayHelper.js\";\nimport { HexHelper } from \"../helpers/hexHelper.js\";\nimport type { ObjectOrArray } from \"../types/objectOrArray.js\";\n\n/**\n * Class to handle guard operations for parameters.\n */\nexport class Guards {\n\t/**\n\t * Is the property defined.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static defined(source: string, property: string, value: unknown): asserts value {\n\t\tif (Is.undefined(value)) {\n\t\t\tthrow new GuardError(source, \"guard.undefined\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static string(source: string, property: string, value: unknown): asserts value is string {\n\t\tif (!Is.string(value)) {\n\t\t\tthrow new GuardError(source, \"guard.string\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string with a value.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringValue(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.string(value)) {\n\t\t\tthrow new GuardError(source, \"guard.string\", property, value);\n\t\t}\n\t\tif (value.length === 0) {\n\t\t\tthrow new GuardError(source, \"guard.stringEmpty\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a JSON value.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static json(source: string, property: string, value: unknown): asserts value is string {\n\t\tif (!Is.json(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringJson\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a base64 string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringBase64(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.stringBase64(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringBase64\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a base64 url string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringBase64Url(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.stringBase64Url(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringBase64Url\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a base58 string.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringBase58(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is string {\n\t\tif (!Is.stringBase58(value)) {\n\t\t\tthrow new GuardError(source, \"guard.stringBase58\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string with a hex value.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param allowPrefix Allow the hex to have the 0x prefix.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringHex(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tallowPrefix: boolean = false\n\t): asserts value is string {\n\t\tGuards.stringValue(source, property, value);\n\t\tif (!HexHelper.isHex(value, allowPrefix)) {\n\t\t\tthrow new GuardError(source, \"guard.stringHex\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string with a hex value with fixed length.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param length The length of the string to match.\n\t * @param allowPrefix Allow the hex to have the 0x prefix.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static stringHexLength(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tlength: number,\n\t\tallowPrefix: boolean = false\n\t): asserts value is string {\n\t\tGuards.stringHex(source, property, value, allowPrefix);\n\t\tif (HexHelper.stripPrefix(value).length !== length) {\n\t\t\tthrow new GuardError(\n\t\t\t\tsource,\n\t\t\t\t\"guard.stringHexLength\",\n\t\t\t\tproperty,\n\t\t\t\tvalue.length,\n\t\t\t\tlength.toString()\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a number.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static number(source: string, property: string, value: unknown): asserts value is number {\n\t\tif (!Is.number(value)) {\n\t\t\tthrow new GuardError(source, \"guard.number\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property an integer.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static integer(source: string, property: string, value: unknown): asserts value is number {\n\t\tif (!Is.integer(value)) {\n\t\t\tthrow new GuardError(source, \"guard.integer\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a bigint.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static bigint(source: string, property: string, value: unknown): asserts value is bigint {\n\t\tif (!Is.bigint(value)) {\n\t\t\tthrow new GuardError(source, \"guard.bigint\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a boolean.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static boolean(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is boolean {\n\t\tif (!Is.boolean(value)) {\n\t\t\tthrow new GuardError(source, \"guard.boolean\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a date.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static date(source: string, property: string, value: unknown): asserts value is Date {\n\t\tif (!Is.date(value)) {\n\t\t\tthrow new GuardError(source, \"guard.date\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a timestamp in milliseconds.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static timestampMilliseconds(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is number {\n\t\tif (!Is.timestampMilliseconds(value)) {\n\t\t\tthrow new GuardError(source, \"guard.timestampMilliseconds\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a timestamp in seconds.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static timestampSeconds(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is number {\n\t\tif (!Is.timestampSeconds(value)) {\n\t\t\tthrow new GuardError(source, \"guard.timestampSeconds\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property an object.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static object<T = { [id: string]: unknown }>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T {\n\t\tif (Is.undefined(value)) {\n\t\t\tthrow new GuardError(source, \"guard.objectUndefined\", property, value);\n\t\t}\n\t\tif (!Is.object<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.object\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property is an object with at least one property.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static objectValue<T = { [id: string]: unknown }>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T {\n\t\tif (Is.undefined(value)) {\n\t\t\tthrow new GuardError(source, \"guard.objectUndefined\", property, value);\n\t\t}\n\t\tif (!Is.object<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.object\", property, value);\n\t\t}\n\t\tif (Object.keys(value || {}).length === 0) {\n\t\t\tthrow new GuardError(source, \"guard.objectValue\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property is an array.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static array<T>(source: string, property: string, value: unknown): asserts value is T[] {\n\t\tif (!Is.array<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property is an array with at least one item.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayValue<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T[] {\n\t\tif (!Is.array(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\t\tif (value.length === 0) {\n\t\t\tthrow new GuardError(source, \"guard.arrayValue\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property one of a list of items.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param options The options the value must be one of.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayOneOf<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: T,\n\t\toptions: T[]\n\t): asserts value is T {\n\t\tif (!Is.array<T>(options)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\t\tif (!options.includes(value)) {\n\t\t\tthrow new GuardError(source, \"guard.arrayOneOf\", property, value, options.join(\", \"));\n\t\t}\n\t}\n\n\t/**\n\t * Does the array start with the specified data.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param startValues The values that must start the array.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayStartsWith<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tstartValues: ObjectOrArray<T>\n\t): asserts value is T[] {\n\t\tif (!Is.arrayValue<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\n\t\tconst startValuesArray = ArrayHelper.fromObjectOrArray(startValues);\n\n\t\tif (!Is.arrayValue<T>(startValuesArray)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, startValuesArray);\n\t\t}\n\n\t\tfor (let i = 0; i < startValuesArray.length; i++) {\n\t\t\tif (value[i] !== startValuesArray[i]) {\n\t\t\t\tthrow new GuardError(\n\t\t\t\t\tsource,\n\t\t\t\t\t\"guard.arrayStartsWith\",\n\t\t\t\t\tproperty,\n\t\t\t\t\tvalue,\n\t\t\t\t\tstartValuesArray.join(\", \")\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Does the array end with the specified data.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param endValues The values that must end the array.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static arrayEndsWith<T>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tendValues: ObjectOrArray<T>\n\t): asserts value is T[] {\n\t\tif (!Is.arrayValue<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, value);\n\t\t}\n\n\t\tconst endValuesArray = ArrayHelper.fromObjectOrArray(endValues);\n\n\t\tif (!Is.arrayValue<T>(endValuesArray)) {\n\t\t\tthrow new GuardError(source, \"guard.array\", property, endValuesArray);\n\t\t}\n\n\t\tfor (let i = 0; i < endValuesArray.length; i++) {\n\t\t\tif (value[value.length - i - 1] !== endValuesArray[endValuesArray.length - i - 1]) {\n\t\t\t\tthrow new GuardError(\n\t\t\t\t\tsource,\n\t\t\t\t\t\"guard.arrayEndsWith\",\n\t\t\t\t\tproperty,\n\t\t\t\t\tvalue,\n\t\t\t\t\tendValuesArray.join(\", \")\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a Uint8Array.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static uint8Array(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is Uint8Array {\n\t\tif (!Is.uint8Array(value)) {\n\t\t\tthrow new GuardError(source, \"guard.uint8Array\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a function.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static function<T extends (...args: any[]) => any = (...args: any[]) => any>(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown\n\t): asserts value is T {\n\t\tif (!Is.function<T>(value)) {\n\t\t\tthrow new GuardError(source, \"guard.function\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string formatted as an email address.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static email(source: string, property: string, value: unknown): asserts value is string {\n\t\tif (!Is.email(value)) {\n\t\t\tthrow new GuardError(source, \"guard.email\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Is the property a string containing uuidV7.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The value to test.\n\t * @param format The format of the uuidV7, either standard or compact.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static uuidV7(\n\t\tsource: string,\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tformat?: \"standard\" | \"compact\"\n\t): asserts value is string {\n\t\tif (!Is.uuidV7(value, format)) {\n\t\t\tif (format === \"compact\") {\n\t\t\t\tthrow new GuardError(source, \"guard.uuidV7Compact\", property, value);\n\t\t\t}\n\t\t\tthrow new GuardError(source, \"guard.uuidV7\", property, value);\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../../src/utils/i18n.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { IntlMessageFormat } from \"intl-messageformat\";\nimport { Is } from \"./is.js\";\nimport { SharedStore } from \"./sharedStore.js\";\nimport type { II18nShared } from \"../models/II18nShared.js\";\nimport type { ILocaleDictionary } from \"../models/ILocaleDictionary.js\";\n\n/**\n * Class to perform internationalization.\n */\nexport class I18n {\n\t/**\n\t * The default translation.\n\t */\n\tpublic static DEFAULT_LOCALE: string = \"en\";\n\n\t/**\n\t * Set the locale.\n\t * @param locale The new locale.\n\t */\n\tpublic static setLocale(locale: string): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\ti18nShared.currentLocale = locale;\n\n\t\tfor (const callback in i18nShared.localeChangedHandlers) {\n\t\t\ti18nShared.localeChangedHandlers[callback](i18nShared.currentLocale);\n\t\t}\n\t}\n\n\t/**\n\t * Get the locale.\n\t * @returns The current locale.\n\t */\n\tpublic static getLocale(): string {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn i18nShared.currentLocale;\n\t}\n\n\t/**\n\t * Add a locale dictionary.\n\t * @param locale The locale.\n\t * @param dictionary The dictionary to add.\n\t */\n\tpublic static addDictionary(locale: string, dictionary: ILocaleDictionary): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\tconst mergedKeys: { [key: string]: string } = {};\n\t\tI18n.flattenTranslationKeys(dictionary, \"\", mergedKeys);\n\t\ti18nShared.localeDictionaries[locale] = mergedKeys;\n\n\t\tfor (const callback in i18nShared.dictionaryChangedHandlers) {\n\t\t\ti18nShared.dictionaryChangedHandlers[callback](i18nShared.currentLocale);\n\t\t}\n\t}\n\n\t/**\n\t * Get a locale dictionary.\n\t * @param locale The locale.\n\t * @returns The dictionary of undefined if it does not exist.\n\t */\n\tpublic static getDictionary(locale: string): { [key: string]: string } | undefined {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn i18nShared.localeDictionaries[locale];\n\t}\n\n\t/**\n\t * Get all the locale dictionaries.\n\t * @returns The dictionaries.\n\t */\n\tpublic static getAllDictionaries(): {\n\t\t[locale: string]: { [key: string]: string };\n\t} {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn i18nShared.localeDictionaries;\n\t}\n\n\t/**\n\t * Add a locale changed handler.\n\t * @param id The id of the handler.\n\t * @param handler The handler to add.\n\t */\n\tpublic static addLocaleHandler(id: string, handler: (locale: string) => void): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\ti18nShared.localeChangedHandlers[id] = handler;\n\t}\n\n\t/**\n\t * Remove a locale changed handler.\n\t * @param id The id of the handler.\n\t */\n\tpublic static removeLocaleHandler(id: string): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\tdelete i18nShared.localeChangedHandlers[id];\n\t}\n\n\t/**\n\t * Add a dictionary changed handler.\n\t * @param id The id of the handler.\n\t * @param handler The handler to add.\n\t */\n\tpublic static addDictionaryHandler(id: string, handler: (locale: string) => void): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\ti18nShared.dictionaryChangedHandlers[id] = handler;\n\t}\n\n\t/**\n\t * Remove a dictionary changed handler.\n\t * @param id The id of the handler.\n\t */\n\tpublic static removeDictionaryHandler(id: string): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\tdelete i18nShared.dictionaryChangedHandlers[id];\n\t}\n\n\t/**\n\t * Format a message.\n\t * @param key The key of the message to format.\n\t * @param values The values to substitute into the message.\n\t * @param overrideLocale Override the locale.\n\t * @returns The formatted string.\n\t */\n\tpublic static formatMessage(\n\t\tkey: string,\n\t\tvalues?: { [key: string]: unknown },\n\t\toverrideLocale?: string\n\t): string {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\tlet cl = overrideLocale ?? i18nShared.currentLocale;\n\t\tif (cl.startsWith(\"debug-\")) {\n\t\t\tcl = I18n.DEFAULT_LOCALE;\n\t\t}\n\n\t\tif (!i18nShared.localeDictionaries[cl]) {\n\t\t\treturn `!!Missing ${cl}`;\n\t\t}\n\t\tif (!i18nShared.localeDictionaries[cl][key]) {\n\t\t\treturn `!!Missing ${cl}.${key}`;\n\t\t}\n\n\t\tif (i18nShared.currentLocale === \"debug-k\") {\n\t\t\treturn key;\n\t\t}\n\n\t\ttry {\n\t\t\tlet ret = new IntlMessageFormat(i18nShared.localeDictionaries[cl][key], cl).format(\n\t\t\t\tvalues\n\t\t\t) as string;\n\n\t\t\tif (i18nShared.currentLocale === \"debug-x\") {\n\t\t\t\tret = ret.replace(/[a-z]/g, \"x\").replace(/[A-Z]/g, \"x\").replace(/\\d/g, \"n\");\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t} catch {\n\t\t\t// if there is an error the assumption is that one of the properties\n\t\t\t// is undefined, which the formatting library does not like\n\t\t\t// in this case we get all the property names and ensure they are defined\n\t\t\tconst propertyNames = I18n.getPropertyNames(i18nShared.localeDictionaries[cl][key]);\n\t\t\tconst safeValues: { [key: string]: unknown } = values ?? {};\n\n\t\t\tfor (const propertyName of propertyNames) {\n\t\t\t\tsafeValues[propertyName] ??= \"\";\n\t\t\t}\n\n\t\t\t// Format again with the safe values, if it still fails we let the error\n\t\t\t// propagate up as there is nothing more we can do\n\t\t\treturn new IntlMessageFormat(i18nShared.localeDictionaries[cl][key], cl).format(\n\t\t\t\tsafeValues\n\t\t\t) as string;\n\t\t}\n\t}\n\n\t/**\n\t * Check if the dictionaries have a message for the given key.\n\t * @param key The key to check for existence.\n\t * @returns True if the key exists.\n\t */\n\tpublic static hasMessage(key: string): boolean {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn Is.string(i18nShared.localeDictionaries[i18nShared.currentLocale]?.[key]);\n\t}\n\n\t/**\n\t * Flatten the translation property paths for faster lookup.\n\t * @param translation The translation to merge.\n\t * @param propertyPath The current root path.\n\t * @param mergedKeys The merged keys dictionary to populate.\n\t */\n\tpublic static flattenTranslationKeys(\n\t\ttranslation: ILocaleDictionary,\n\t\tpropertyPath: string,\n\t\tmergedKeys: { [key: string]: string }\n\t): void {\n\t\tfor (const key in translation) {\n\t\t\tconst val = translation[key];\n\t\t\tconst mergedPath = propertyPath.length > 0 ? `${propertyPath}.${key}` : key;\n\t\t\tif (Is.string(val)) {\n\t\t\t\tmergedKeys[mergedPath] = val;\n\t\t\t} else if (Is.object<ILocaleDictionary>(val)) {\n\t\t\t\tI18n.flattenTranslationKeys(val, mergedPath, mergedKeys);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get a list of the property names from the message.\n\t * @param message The message to extract the property names from.\n\t * @returns The list of property names.\n\t */\n\tpublic static getPropertyNames(message: string): string[] {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\ttry {\n\t\t\tconst ast = new IntlMessageFormat(message, i18nShared.currentLocale).getAst();\n\t\t\tconst properties = new Set<string>();\n\n\t\t\tI18n.extractPropertiesFromAst(ast, properties);\n\n\t\t\treturn Array.from(properties);\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Recursively extract property names from the AST.\n\t * @param node The AST node to process.\n\t * @param properties The set to collect property names.\n\t * @internal\n\t */\n\tprivate static extractPropertiesFromAst(node: unknown, properties: Set<string>): void {\n\t\tif (Is.array(node)) {\n\t\t\tfor (const item of node) {\n\t\t\t\tI18n.extractPropertiesFromAst(item, properties);\n\t\t\t}\n\t\t} else if (Is.object(node)) {\n\t\t\tconst obj = node as { [key: string]: unknown };\n\n\t\t\t// Check for elements that have property names\n\t\t\t// Type 1 = ArgumentElement (simple placeholder like {name})\n\t\t\t// Type 2 = NumberElement ({count, number})\n\t\t\t// Type 3 = DateElement ({date, date, short})\n\t\t\t// Type 4 = TimeElement ({time, time, medium})\n\t\t\t// Type 5 = SelectElement ({gender, select, ...})\n\t\t\t// Type 6 = PluralElement ({count, plural, ...})\n\t\t\tif (\n\t\t\t\t(obj.type === 1 ||\n\t\t\t\t\tobj.type === 2 ||\n\t\t\t\t\tobj.type === 3 ||\n\t\t\t\t\tobj.type === 4 ||\n\t\t\t\t\tobj.type === 5 ||\n\t\t\t\t\tobj.type === 6) &&\n\t\t\t\tIs.string(obj.value)\n\t\t\t) {\n\t\t\t\tproperties.add(obj.value);\n\t\t\t}\n\n\t\t\t// Recursively process all object properties\n\t\t\tfor (const key in obj) {\n\t\t\t\tconst value = obj[key];\n\t\t\t\tif (Is.object(value) || Is.array(value)) {\n\t\t\t\t\tI18n.extractPropertiesFromAst(value, properties);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the I18n shared data.\n\t * @returns The I18n shared data.\n\t * @internal\n\t */\n\tprivate static getI18nShared(): II18nShared {\n\t\tlet i18nShared = SharedStore.get<II18nShared>(\"i18n\");\n\n\t\tif (Is.undefined(i18nShared)) {\n\t\t\ti18nShared = {\n\t\t\t\tlocaleDictionaries: {},\n\t\t\t\tcurrentLocale: I18n.DEFAULT_LOCALE,\n\t\t\t\tlocaleChangedHandlers: {},\n\t\t\t\tdictionaryChangedHandlers: {}\n\t\t\t};\n\t\t\tSharedStore.set<II18nShared>(\"i18n\", i18nShared);\n\t\t}\n\n\t\treturn i18nShared;\n\t}\n}\n"]}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../../src/utils/i18n.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C;;GAEG;AACH,MAAM,OAAO,IAAI;IAChB;;OAEG;IACI,MAAM,CAAC,cAAc,GAAW,IAAI,CAAC;IAE5C;;;OAGG;IACI,MAAM,CAAC,SAAS,CAAC,MAAc;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAExC,UAAU,CAAC,aAAa,GAAG,MAAM,CAAC;QAElC,KAAK,MAAM,QAAQ,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YACzD,UAAU,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,SAAS;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,aAAa,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,aAAa,CAAC,MAAc,EAAE,UAA6B;QACxE,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAExC,MAAM,UAAU,GAA8B,EAAE,CAAC;QACjD,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QACxD,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;QAEnD,KAAK,MAAM,QAAQ,IAAI,UAAU,CAAC,yBAAyB,EAAE,CAAC;YAC7D,UAAU,CAAC,yBAAyB,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAC1E,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,aAAa,CAAC,MAAc;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,kBAAkB;QAG/B,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,kBAAkB,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,gBAAgB,CAAC,EAAU,EAAE,OAAiC;QAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;IAChD,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,mBAAmB,CAAC,EAAU;QAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,oBAAoB,CAAC,EAAU,EAAE,OAAiC;QAC/E,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,UAAU,CAAC,yBAAyB,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;IACpD,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,uBAAuB,CAAC,EAAU;QAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,aAAa,CAC1B,GAAW,EACX,MAAmC,EACnC,cAAuB;QAEvB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAExC,IAAI,EAAE,GAAG,cAAc,IAAI,UAAU,CAAC,aAAa,CAAC;QACpD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;YACxC,OAAO,aAAa,EAAE,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,OAAO,aAAa,EAAE,IAAI,GAAG,EAAE,CAAC;QACjC,CAAC;QAED,IAAI,UAAU,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YAC5C,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,GAAG,GAAG,IAAI,iBAAiB,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CACjF,MAAM,CACI,CAAC;YAEZ,IAAI,UAAU,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;gBAC5C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC7E,CAAC;YAED,OAAO,GAAG,CAAC;QACZ,CAAC;QAAC,MAAM,CAAC;YACR,oEAAoE;YACpE,2DAA2D;YAC3D,yEAAyE;YACzE,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACpF,MAAM,UAAU,GAA+B,MAAM,IAAI,EAAE,CAAC;YAE5D,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBAC1C,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACjC,CAAC;YAED,wEAAwE;YACxE,kDAAkD;YAClD,OAAO,IAAI,iBAAiB,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAC9E,UAAU,CACA,CAAC;QACb,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,UAAU,CAAC,GAAW;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClF,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,sBAAsB,CACnC,WAA8B,EAC9B,YAAoB,EACpB,UAAqC;QAErC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAC5E,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpB,UAAU,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC;YAC9B,CAAC;iBAAM,IAAI,EAAE,CAAC,MAAM,CAAoB,GAAG,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;YAC1D,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,gBAAgB,CAAC,OAAe;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAExC,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,CAAC;YAC9E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;YAErC,IAAI,CAAC,wBAAwB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAE/C,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,wBAAwB,CAAC,IAAa,EAAE,UAAuB;QAC7E,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACzB,IAAI,CAAC,wBAAwB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACjD,CAAC;QACF,CAAC;aAAM,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC;YAEjB,8CAA8C;YAC9C,4DAA4D;YAC5D,2CAA2C;YAC3C,6CAA6C;YAC7C,8CAA8C;YAC9C,iDAAiD;YACjD,gDAAgD;YAChD,IACC,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;gBACd,GAAG,CAAC,IAAI,KAAK,CAAC;gBACd,GAAG,CAAC,IAAI,KAAK,CAAC;gBACd,GAAG,CAAC,IAAI,KAAK,CAAC;gBACd,GAAG,CAAC,IAAI,KAAK,CAAC;gBACd,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC;gBAChB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EACnB,CAAC;gBACF,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;YAED,4CAA4C;YAC5C,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;gBACvB,IAAI,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzC,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBAClD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,aAAa;QAC3B,IAAI,UAAU,GAAG,WAAW,CAAC,GAAG,CAAc,MAAM,CAAC,CAAC;QAEtD,IAAI,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,UAAU,GAAG;gBACZ,kBAAkB,EAAE,EAAE;gBACtB,aAAa,EAAE,IAAI,CAAC,cAAc;gBAClC,qBAAqB,EAAE,EAAE;gBACzB,yBAAyB,EAAE,EAAE;aAC7B,CAAC;YACF,WAAW,CAAC,GAAG,CAAc,MAAM,EAAE,UAAU,CAAC,CAAC;QAClD,CAAC;QAED,OAAO,UAAU,CAAC;IACnB,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { IntlMessageFormat } from \"intl-messageformat\";\nimport { Is } from \"./is.js\";\nimport { SharedStore } from \"./sharedStore.js\";\nimport type { II18nShared } from \"../models/II18nShared.js\";\nimport type { ILocaleDictionary } from \"../models/ILocaleDictionary.js\";\n\n/**\n * Class to perform internationalization.\n */\nexport class I18n {\n\t/**\n\t * The default translation.\n\t */\n\tpublic static DEFAULT_LOCALE: string = \"en\";\n\n\t/**\n\t * Set the locale.\n\t * @param locale The new locale.\n\t */\n\tpublic static setLocale(locale: string): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\ti18nShared.currentLocale = locale;\n\n\t\tfor (const callback in i18nShared.localeChangedHandlers) {\n\t\t\ti18nShared.localeChangedHandlers[callback](i18nShared.currentLocale);\n\t\t}\n\t}\n\n\t/**\n\t * Get the locale.\n\t * @returns The current locale.\n\t */\n\tpublic static getLocale(): string {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn i18nShared.currentLocale;\n\t}\n\n\t/**\n\t * Add a locale dictionary.\n\t * @param locale The locale.\n\t * @param dictionary The dictionary to add.\n\t */\n\tpublic static addDictionary(locale: string, dictionary: ILocaleDictionary): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\tconst mergedKeys: { [key: string]: string } = {};\n\t\tI18n.flattenTranslationKeys(dictionary, \"\", mergedKeys);\n\t\ti18nShared.localeDictionaries[locale] = mergedKeys;\n\n\t\tfor (const callback in i18nShared.dictionaryChangedHandlers) {\n\t\t\ti18nShared.dictionaryChangedHandlers[callback](i18nShared.currentLocale);\n\t\t}\n\t}\n\n\t/**\n\t * Get a locale dictionary.\n\t * @param locale The locale.\n\t * @returns The dictionary of undefined if it does not exist.\n\t */\n\tpublic static getDictionary(locale: string): { [key: string]: string } | undefined {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn i18nShared.localeDictionaries[locale];\n\t}\n\n\t/**\n\t * Get all the locale dictionaries.\n\t * @returns The dictionaries.\n\t */\n\tpublic static getAllDictionaries(): {\n\t\t[locale: string]: { [key: string]: string };\n\t} {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn i18nShared.localeDictionaries;\n\t}\n\n\t/**\n\t * Add a locale changed handler.\n\t * @param id The id of the handler.\n\t * @param handler The handler to add.\n\t */\n\tpublic static addLocaleHandler(id: string, handler: (locale: string) => void): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\ti18nShared.localeChangedHandlers[id] = handler;\n\t}\n\n\t/**\n\t * Remove a locale changed handler.\n\t * @param id The id of the handler.\n\t */\n\tpublic static removeLocaleHandler(id: string): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\tdelete i18nShared.localeChangedHandlers[id];\n\t}\n\n\t/**\n\t * Add a dictionary changed handler.\n\t * @param id The id of the handler.\n\t * @param handler The handler to add.\n\t */\n\tpublic static addDictionaryHandler(id: string, handler: (locale: string) => void): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\ti18nShared.dictionaryChangedHandlers[id] = handler;\n\t}\n\n\t/**\n\t * Remove a dictionary changed handler.\n\t * @param id The id of the handler.\n\t */\n\tpublic static removeDictionaryHandler(id: string): void {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\tdelete i18nShared.dictionaryChangedHandlers[id];\n\t}\n\n\t/**\n\t * Format a message.\n\t * @param key The key of the message to format.\n\t * @param values The values to substitute into the message.\n\t * @param overrideLocale Override the locale.\n\t * @returns The formatted string.\n\t */\n\tpublic static formatMessage(\n\t\tkey: string,\n\t\tvalues?: { [key: string]: unknown },\n\t\toverrideLocale?: string\n\t): string {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\tlet cl = overrideLocale ?? i18nShared.currentLocale;\n\t\tif (cl.startsWith(\"debug-\")) {\n\t\t\tcl = I18n.DEFAULT_LOCALE;\n\t\t}\n\n\t\tif (!i18nShared.localeDictionaries[cl]) {\n\t\t\treturn `!!Missing ${cl}`;\n\t\t}\n\t\tif (!i18nShared.localeDictionaries[cl][key]) {\n\t\t\treturn `!!Missing ${cl}.${key}`;\n\t\t}\n\n\t\tif (i18nShared.currentLocale === \"debug-k\") {\n\t\t\treturn key;\n\t\t}\n\n\t\ttry {\n\t\t\tlet ret = new IntlMessageFormat(i18nShared.localeDictionaries[cl][key], cl).format(\n\t\t\t\tvalues\n\t\t\t) as string;\n\n\t\t\tif (i18nShared.currentLocale === \"debug-x\") {\n\t\t\t\tret = ret.replace(/[a-z]/g, \"x\").replace(/[A-Z]/g, \"x\").replace(/\\d/g, \"n\");\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t} catch {\n\t\t\t// if there is an error the assumption is that one of the properties\n\t\t\t// is undefined, which the formatting library does not like\n\t\t\t// in this case we get all the property names and ensure they are defined\n\t\t\tconst propertyNames = I18n.getPropertyNames(i18nShared.localeDictionaries[cl][key]);\n\t\t\tconst safeValues: { [key: string]: unknown } = values ?? {};\n\n\t\t\tfor (const propertyName of propertyNames) {\n\t\t\t\tsafeValues[propertyName] ??= \"\";\n\t\t\t}\n\n\t\t\t// Format again with the safe values, if it still fails we let the error\n\t\t\t// propagate up as there is nothing more we can do\n\t\t\treturn new IntlMessageFormat(i18nShared.localeDictionaries[cl][key], cl).format(\n\t\t\t\tsafeValues\n\t\t\t) as string;\n\t\t}\n\t}\n\n\t/**\n\t * Check if the dictionaries have a message for the given key.\n\t * @param key The key to check for existence.\n\t * @returns True if the key exists.\n\t */\n\tpublic static hasMessage(key: string): boolean {\n\t\tconst i18nShared = I18n.getI18nShared();\n\t\treturn Is.string(i18nShared.localeDictionaries[i18nShared.currentLocale]?.[key]);\n\t}\n\n\t/**\n\t * Flatten the translation property paths for faster lookup.\n\t * @param translation The translation to merge.\n\t * @param propertyPath The current root path.\n\t * @param mergedKeys The merged keys dictionary to populate.\n\t */\n\tpublic static flattenTranslationKeys(\n\t\ttranslation: ILocaleDictionary,\n\t\tpropertyPath: string,\n\t\tmergedKeys: { [key: string]: string }\n\t): void {\n\t\tfor (const key in translation) {\n\t\t\tconst val = translation[key];\n\t\t\tconst mergedPath = propertyPath.length > 0 ? `${propertyPath}.${key}` : key;\n\t\t\tif (Is.string(val)) {\n\t\t\t\tmergedKeys[mergedPath] = val;\n\t\t\t} else if (Is.object<ILocaleDictionary>(val)) {\n\t\t\t\tI18n.flattenTranslationKeys(val, mergedPath, mergedKeys);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get a list of the property names from the message.\n\t * @param message The message to extract the property names from.\n\t * @returns The list of property names.\n\t */\n\tpublic static getPropertyNames(message: string): string[] {\n\t\tconst i18nShared = I18n.getI18nShared();\n\n\t\ttry {\n\t\t\tconst ast = new IntlMessageFormat(message, i18nShared.currentLocale).getAst();\n\t\t\tconst properties = new Set<string>();\n\n\t\t\tI18n.extractPropertiesFromAst(ast, properties);\n\n\t\t\treturn Array.from(properties);\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\t/**\n\t * Recursively extract property names from the AST.\n\t * @param node The AST node to process.\n\t * @param properties The set to collect property names.\n\t * @internal\n\t */\n\tprivate static extractPropertiesFromAst(node: unknown, properties: Set<string>): void {\n\t\tif (Is.array(node)) {\n\t\t\tfor (const item of node) {\n\t\t\t\tI18n.extractPropertiesFromAst(item, properties);\n\t\t\t}\n\t\t} else if (Is.object(node)) {\n\t\t\tconst obj = node;\n\n\t\t\t// Check for elements that have property names\n\t\t\t// Type 1 = ArgumentElement (simple placeholder like {name})\n\t\t\t// Type 2 = NumberElement ({count, number})\n\t\t\t// Type 3 = DateElement ({date, date, short})\n\t\t\t// Type 4 = TimeElement ({time, time, medium})\n\t\t\t// Type 5 = SelectElement ({gender, select, ...})\n\t\t\t// Type 6 = PluralElement ({count, plural, ...})\n\t\t\tif (\n\t\t\t\t(obj.type === 1 ||\n\t\t\t\t\tobj.type === 2 ||\n\t\t\t\t\tobj.type === 3 ||\n\t\t\t\t\tobj.type === 4 ||\n\t\t\t\t\tobj.type === 5 ||\n\t\t\t\t\tobj.type === 6) &&\n\t\t\t\tIs.string(obj.value)\n\t\t\t) {\n\t\t\t\tproperties.add(obj.value);\n\t\t\t}\n\n\t\t\t// Recursively process all object properties\n\t\t\tfor (const key in obj) {\n\t\t\t\tconst value = obj[key];\n\t\t\t\tif (Is.object(value) || Is.array(value)) {\n\t\t\t\t\tI18n.extractPropertiesFromAst(value, properties);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the I18n shared data.\n\t * @returns The I18n shared data.\n\t * @internal\n\t */\n\tprivate static getI18nShared(): II18nShared {\n\t\tlet i18nShared = SharedStore.get<II18nShared>(\"i18n\");\n\n\t\tif (Is.undefined(i18nShared)) {\n\t\t\ti18nShared = {\n\t\t\t\tlocaleDictionaries: {},\n\t\t\t\tcurrentLocale: I18n.DEFAULT_LOCALE,\n\t\t\t\tlocaleChangedHandlers: {},\n\t\t\t\tdictionaryChangedHandlers: {}\n\t\t\t};\n\t\t\tSharedStore.set<II18nShared>(\"i18n\", i18nShared);\n\t\t}\n\n\t\treturn i18nShared;\n\t}\n}\n"]}
@@ -347,5 +347,21 @@ export class Is {
347
347
  const str = Function.prototype.toString.call(obj);
348
348
  return /^class\s/.test(str);
349
349
  }
350
+ /**
351
+ * Is the value a uuidV7 string.
352
+ * @param value The value to test.
353
+ * @param format The format of the UUIDv7 string.
354
+ * @returns True if the value is a uuidV7 string.
355
+ */
356
+ static uuidV7(value, format) {
357
+ if (format === "compact") {
358
+ // 32 hex chars, where:
359
+ // - char 13 (0-based index 12) is the version (7)
360
+ // - char 17 (0-based index 16) is the variant (8, 9, a, b)
361
+ return Is.stringValue(value) && /^[\da-f]{12}7[\da-f]{3}[89ab][\da-f]{15}$/i.test(value);
362
+ }
363
+ return (Is.stringValue(value) &&
364
+ /^[\da-f]{8}-[\da-f]{4}-7[\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}$/i.test(value));
365
+ }
350
366
  }
351
367
  //# sourceMappingURL=is.js.map