@twin.org/core 0.0.2-next.9 → 0.0.3-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/es/encoding/base32.js +75 -0
  2. package/dist/es/encoding/base32.js.map +1 -0
  3. package/dist/es/encoding/base58.js +124 -0
  4. package/dist/es/encoding/base58.js.map +1 -0
  5. package/dist/es/encoding/base64.js +231 -0
  6. package/dist/es/encoding/base64.js.map +1 -0
  7. package/dist/es/encoding/base64Url.js +42 -0
  8. package/dist/es/encoding/base64Url.js.map +1 -0
  9. package/dist/es/errors/alreadyExistsError.js +22 -0
  10. package/dist/es/errors/alreadyExistsError.js.map +1 -0
  11. package/dist/es/errors/baseError.js +257 -0
  12. package/dist/es/errors/baseError.js.map +1 -0
  13. package/dist/es/errors/conflictError.js +23 -0
  14. package/dist/es/errors/conflictError.js.map +1 -0
  15. package/dist/es/errors/generalError.js +21 -0
  16. package/dist/es/errors/generalError.js.map +1 -0
  17. package/dist/es/errors/guardError.js +27 -0
  18. package/dist/es/errors/guardError.js.map +1 -0
  19. package/dist/es/errors/notFoundError.js +22 -0
  20. package/dist/es/errors/notFoundError.js.map +1 -0
  21. package/dist/es/errors/notImplementedError.js +24 -0
  22. package/dist/es/errors/notImplementedError.js.map +1 -0
  23. package/dist/es/errors/notSupportedError.js +21 -0
  24. package/dist/es/errors/notSupportedError.js.map +1 -0
  25. package/dist/es/errors/unauthorizedError.js +21 -0
  26. package/dist/es/errors/unauthorizedError.js.map +1 -0
  27. package/dist/es/errors/unprocessableError.js +21 -0
  28. package/dist/es/errors/unprocessableError.js.map +1 -0
  29. package/dist/es/errors/validationError.js +23 -0
  30. package/dist/es/errors/validationError.js.map +1 -0
  31. package/dist/es/factories/componentFactory.js +9 -0
  32. package/dist/es/factories/componentFactory.js.map +1 -0
  33. package/dist/es/factories/factory.js +256 -0
  34. package/dist/es/factories/factory.js.map +1 -0
  35. package/dist/es/helpers/arrayHelper.js +44 -0
  36. package/dist/es/helpers/arrayHelper.js.map +1 -0
  37. package/dist/es/helpers/envHelper.js +39 -0
  38. package/dist/es/helpers/envHelper.js.map +1 -0
  39. package/dist/es/helpers/errorHelper.js +100 -0
  40. package/dist/es/helpers/errorHelper.js.map +1 -0
  41. package/dist/es/helpers/filenameHelper.js +32 -0
  42. package/dist/es/helpers/filenameHelper.js.map +1 -0
  43. package/dist/es/helpers/hexHelper.js +45 -0
  44. package/dist/es/helpers/hexHelper.js.map +1 -0
  45. package/dist/es/helpers/jsonHelper.js +163 -0
  46. package/dist/es/helpers/jsonHelper.js.map +1 -0
  47. package/dist/es/helpers/numberHelper.js +30 -0
  48. package/dist/es/helpers/numberHelper.js.map +1 -0
  49. package/dist/es/helpers/objectHelper.js +333 -0
  50. package/dist/es/helpers/objectHelper.js.map +1 -0
  51. package/dist/es/helpers/randomHelper.js +18 -0
  52. package/dist/es/helpers/randomHelper.js.map +1 -0
  53. package/dist/es/helpers/stringHelper.js +241 -0
  54. package/dist/es/helpers/stringHelper.js.map +1 -0
  55. package/dist/es/helpers/uint8ArrayHelper.js +26 -0
  56. package/dist/es/helpers/uint8ArrayHelper.js.map +1 -0
  57. package/dist/es/index.js +57 -0
  58. package/dist/es/index.js.map +1 -0
  59. package/dist/es/models/IComponent.js +4 -0
  60. package/dist/es/models/IComponent.js.map +1 -0
  61. package/dist/es/models/IError.js +4 -0
  62. package/dist/es/models/IError.js.map +1 -0
  63. package/dist/es/models/II18nShared.js +2 -0
  64. package/dist/es/models/II18nShared.js.map +1 -0
  65. package/dist/es/models/IKeyValue.js +2 -0
  66. package/dist/es/models/IKeyValue.js.map +1 -0
  67. package/dist/es/models/ILabelledValue.js +2 -0
  68. package/dist/es/models/ILabelledValue.js.map +1 -0
  69. package/dist/es/models/ILocale.js +2 -0
  70. package/dist/es/models/ILocale.js.map +1 -0
  71. package/dist/es/models/ILocaleDictionary.js +4 -0
  72. package/dist/es/models/ILocaleDictionary.js.map +1 -0
  73. package/dist/es/models/ILocalesIndex.js +2 -0
  74. package/dist/es/models/ILocalesIndex.js.map +1 -0
  75. package/dist/es/models/IPatchOperation.js +4 -0
  76. package/dist/es/models/IPatchOperation.js.map +1 -0
  77. package/dist/es/models/IUrlParts.js +4 -0
  78. package/dist/es/models/IUrlParts.js.map +1 -0
  79. package/dist/es/models/IValidationFailure.js +2 -0
  80. package/dist/es/models/IValidationFailure.js.map +1 -0
  81. package/dist/es/models/coerceType.js +49 -0
  82. package/dist/es/models/coerceType.js.map +1 -0
  83. package/dist/es/models/compressionType.js +17 -0
  84. package/dist/es/models/compressionType.js.map +1 -0
  85. package/dist/es/models/objectOrArray.js +2 -0
  86. package/dist/es/models/objectOrArray.js.map +1 -0
  87. package/dist/es/types/bitString.js +98 -0
  88. package/dist/es/types/bitString.js.map +1 -0
  89. package/dist/es/types/url.js +144 -0
  90. package/dist/es/types/url.js.map +1 -0
  91. package/dist/es/types/urn.js +212 -0
  92. package/dist/es/types/urn.js.map +1 -0
  93. package/dist/es/utils/asyncCache.js +179 -0
  94. package/dist/es/utils/asyncCache.js.map +1 -0
  95. package/dist/es/utils/coerce.js +269 -0
  96. package/dist/es/utils/coerce.js.map +1 -0
  97. package/dist/es/utils/compression.js +49 -0
  98. package/dist/es/utils/compression.js.map +1 -0
  99. package/dist/es/utils/converter.js +256 -0
  100. package/dist/es/utils/converter.js.map +1 -0
  101. package/dist/es/utils/guards.js +369 -0
  102. package/dist/es/utils/guards.js.map +1 -0
  103. package/dist/es/utils/i18n.js +243 -0
  104. package/dist/es/utils/i18n.js.map +1 -0
  105. package/dist/es/utils/is.js +351 -0
  106. package/dist/es/utils/is.js.map +1 -0
  107. package/dist/es/utils/sharedStore.js +48 -0
  108. package/dist/es/utils/sharedStore.js.map +1 -0
  109. package/dist/es/utils/validation.js +774 -0
  110. package/dist/es/utils/validation.js.map +1 -0
  111. package/dist/types/encoding/base32.d.ts +4 -0
  112. package/dist/types/encoding/base58.d.ts +4 -0
  113. package/dist/types/encoding/base64.d.ts +4 -0
  114. package/dist/types/encoding/base64Url.d.ts +4 -0
  115. package/dist/types/errors/alreadyExistsError.d.ts +5 -2
  116. package/dist/types/errors/baseError.d.ts +1 -1
  117. package/dist/types/errors/conflictError.d.ts +5 -2
  118. package/dist/types/errors/generalError.d.ts +1 -1
  119. package/dist/types/errors/guardError.d.ts +1 -1
  120. package/dist/types/errors/notFoundError.d.ts +5 -2
  121. package/dist/types/errors/notImplementedError.d.ts +6 -2
  122. package/dist/types/errors/notSupportedError.d.ts +5 -2
  123. package/dist/types/errors/unauthorizedError.d.ts +5 -2
  124. package/dist/types/errors/unprocessableError.d.ts +1 -1
  125. package/dist/types/errors/validationError.d.ts +2 -2
  126. package/dist/types/factories/componentFactory.d.ts +2 -2
  127. package/dist/types/factories/factory.d.ts +4 -0
  128. package/dist/types/helpers/arrayHelper.d.ts +1 -1
  129. package/dist/types/helpers/errorHelper.d.ts +1 -1
  130. package/dist/types/helpers/jsonHelper.d.ts +5 -1
  131. package/dist/types/helpers/numberHelper.d.ts +17 -0
  132. package/dist/types/helpers/objectHelper.d.ts +14 -0
  133. package/dist/types/helpers/stringHelper.d.ts +6 -6
  134. package/dist/types/index.d.ts +54 -53
  135. package/dist/types/models/IComponent.d.ts +6 -7
  136. package/dist/types/models/ILocalesIndex.d.ts +1 -1
  137. package/dist/types/models/IValidationFailure.d.ts +0 -4
  138. package/dist/types/types/bitString.d.ts +4 -0
  139. package/dist/types/types/url.d.ts +8 -3
  140. package/dist/types/types/urn.d.ts +7 -2
  141. package/dist/types/utils/coerce.d.ts +1 -1
  142. package/dist/types/utils/compression.d.ts +5 -1
  143. package/dist/types/utils/guards.d.ts +2 -3
  144. package/dist/types/utils/i18n.d.ts +16 -1
  145. package/dist/types/utils/is.d.ts +1 -1
  146. package/dist/types/utils/validation.d.ts +1 -1
  147. package/docs/changelog.md +283 -0
  148. package/docs/reference/classes/AlreadyExistsError.md +8 -4
  149. package/docs/reference/classes/AsyncCache.md +5 -5
  150. package/docs/reference/classes/Base32.md +8 -0
  151. package/docs/reference/classes/Base58.md +8 -0
  152. package/docs/reference/classes/Base64.md +8 -0
  153. package/docs/reference/classes/Base64Url.md +8 -0
  154. package/docs/reference/classes/BaseError.md +3 -3
  155. package/docs/reference/classes/BitString.md +8 -0
  156. package/docs/reference/classes/Coerce.md +20 -20
  157. package/docs/reference/classes/Compression.md +8 -0
  158. package/docs/reference/classes/ConflictError.md +8 -4
  159. package/docs/reference/classes/ErrorHelper.md +2 -2
  160. package/docs/reference/classes/Factory.md +11 -3
  161. package/docs/reference/classes/GeneralError.md +3 -3
  162. package/docs/reference/classes/GuardError.md +3 -3
  163. package/docs/reference/classes/Guards.md +8 -4
  164. package/docs/reference/classes/I18n.md +54 -2
  165. package/docs/reference/classes/Is.md +10 -4
  166. package/docs/reference/classes/JsonHelper.md +8 -0
  167. package/docs/reference/classes/NotFoundError.md +8 -4
  168. package/docs/reference/classes/NotImplementedError.md +14 -4
  169. package/docs/reference/classes/NotSupportedError.md +8 -4
  170. package/docs/reference/classes/NumberHelper.md +55 -0
  171. package/docs/reference/classes/ObjectHelper.md +58 -8
  172. package/docs/reference/classes/SharedStore.md +2 -2
  173. package/docs/reference/classes/StringHelper.md +8 -8
  174. package/docs/reference/classes/UnauthorizedError.md +8 -4
  175. package/docs/reference/classes/UnprocessableError.md +3 -3
  176. package/docs/reference/classes/Url.md +17 -3
  177. package/docs/reference/classes/Urn.md +19 -5
  178. package/docs/reference/classes/Validation.md +2 -2
  179. package/docs/reference/classes/ValidationError.md +3 -3
  180. package/docs/reference/index.md +1 -0
  181. package/docs/reference/interfaces/IComponent.md +19 -25
  182. package/docs/reference/interfaces/IValidationFailure.md +0 -8
  183. package/locales/.validate-ignore +1 -0
  184. package/locales/en.json +4 -5
  185. package/package.json +22 -10
  186. package/dist/cjs/index.cjs +0 -5175
  187. package/dist/esm/index.mjs +0 -5133
@@ -0,0 +1,163 @@
1
+ import { applyPatch, createPatch } from "rfc6902";
2
+ import { ObjectHelper } from "./objectHelper.js";
3
+ import { GeneralError } from "../errors/generalError.js";
4
+ import { Converter } from "../utils/converter.js";
5
+ import { Is } from "../utils/is.js";
6
+ /**
7
+ * Helpers methods for JSON objects.
8
+ */
9
+ export class JsonHelper {
10
+ /**
11
+ * Runtime name for the class.
12
+ */
13
+ static CLASS_NAME = "JsonHelper";
14
+ /**
15
+ * Serializes in canonical format.
16
+ * Based on https://www.rfc-editor.org/rfc/rfc8785.
17
+ * @param object The object to be serialized.
18
+ * @returns The serialized object.
19
+ */
20
+ static canonicalize(object) {
21
+ const buffer = [];
22
+ if (object === null ||
23
+ typeof object !== "object" ||
24
+ ("toJSON" in object && Is.function(object.toJSON))) {
25
+ // Primitive data type
26
+ buffer.push(JSON.stringify(object));
27
+ }
28
+ else if (Array.isArray(object)) {
29
+ // Array maintain element order
30
+ const parts = [];
31
+ for (const element of object) {
32
+ if (element === undefined) {
33
+ parts.push("null");
34
+ }
35
+ else {
36
+ parts.push(JsonHelper.canonicalize(element));
37
+ }
38
+ }
39
+ buffer.push(`[${parts.join(",")}]`);
40
+ }
41
+ else {
42
+ // Object sort properties
43
+ const props = [];
44
+ const keys = Object.keys(object).sort();
45
+ const o = object;
46
+ for (const key of keys) {
47
+ if (o[key] !== undefined) {
48
+ props.push(`${JSON.stringify(key)}:${JsonHelper.canonicalize(o[key])}`);
49
+ }
50
+ }
51
+ buffer.push(`{${props.join(",")}}`);
52
+ }
53
+ return buffer.join("");
54
+ }
55
+ /**
56
+ * Creates a RFC 6902 diff set.
57
+ * Based on https://www.rfc-editor.org/rfc/rfc6902.
58
+ * @param object1 The first object.
59
+ * @param object2 The second object.
60
+ * @returns The list of patches.
61
+ */
62
+ static diff(object1, object2) {
63
+ const operations = createPatch(object1, object2);
64
+ return operations;
65
+ }
66
+ /**
67
+ * Applies a RFC 6902 diff set to an object.
68
+ * Based on https://www.rfc-editor.org/rfc/rfc6902.
69
+ * @param object The object to patch.
70
+ * @param patches The second object.
71
+ * @returns The updated object.
72
+ * @throws GeneralError if the patch fails.
73
+ */
74
+ static patch(object, patches) {
75
+ const clone = ObjectHelper.clone(object);
76
+ const result = applyPatch(clone, patches);
77
+ for (let i = 0; i < result.length; i++) {
78
+ if (!Is.empty(result[i])) {
79
+ throw new GeneralError(JsonHelper.CLASS_NAME, "failedPatch", { index: i }, result[i]);
80
+ }
81
+ }
82
+ return clone;
83
+ }
84
+ /**
85
+ * Stringify the JSON with support for extended data types date/bigint/uint8array.
86
+ * @param object The object to stringify.
87
+ * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
88
+ * @returns The stringified object.
89
+ */
90
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
+ static stringifyEx(object, space) {
92
+ // We want to keep the 'this' intact for the replacer
93
+ // eslint-disable-next-line @typescript-eslint/unbound-method
94
+ return JSON.stringify(object, JsonHelper.stringifyExReplacer, space);
95
+ }
96
+ /**
97
+ * Parse the JSON string with support for extended data types date/bigint/uint8array.
98
+ * @param json The object to pause.
99
+ * @returns The object.
100
+ */
101
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
+ static parseEx(json) {
103
+ // We want to keep the 'this' intact for the reviver
104
+ // eslint-disable-next-line @typescript-eslint/unbound-method
105
+ return JSON.parse(json, JsonHelper.parseExReviver);
106
+ }
107
+ /**
108
+ * Replacer function to handle extended data types.
109
+ * @param this The object.
110
+ * @param key The key.
111
+ * @param value The value.
112
+ * @returns The value.
113
+ */
114
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
+ static stringifyExReplacer(key, value) {
116
+ // The this in the replacer is the containing object
117
+ // so we need to get the actual value from there
118
+ // eslint-disable-next-line no-restricted-syntax
119
+ const rawValue = this[key];
120
+ if (Is.bigint(rawValue)) {
121
+ return {
122
+ "@ext": "bigint",
123
+ value: rawValue.toString()
124
+ };
125
+ }
126
+ else if (Is.date(rawValue)) {
127
+ return {
128
+ "@ext": "date",
129
+ value: rawValue.getTime()
130
+ };
131
+ }
132
+ else if (Is.uint8Array(rawValue)) {
133
+ return {
134
+ "@ext": "uint8array",
135
+ value: Converter.bytesToBase64(rawValue)
136
+ };
137
+ }
138
+ return value;
139
+ }
140
+ /**
141
+ * Reviver function to handle extended data types.
142
+ * @param this The object.
143
+ * @param key The key.
144
+ * @param value The value.
145
+ * @returns The value.
146
+ */
147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
+ static parseExReviver(key, value) {
149
+ if (Is.object(value)) {
150
+ if (value["@ext"] === "bigint") {
151
+ return BigInt(value.value);
152
+ }
153
+ else if (value["@ext"] === "date") {
154
+ return new Date(value.value);
155
+ }
156
+ else if (value["@ext"] === "uint8array") {
157
+ return Converter.base64ToBytes(value.value);
158
+ }
159
+ }
160
+ return value;
161
+ }
162
+ }
163
+ //# sourceMappingURL=jsonHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonHelper.js","sourceRoot":"","sources":["../../../src/helpers/jsonHelper.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 { applyPatch, createPatch, type Operation } from \"rfc6902\";\nimport { ObjectHelper } from \"./objectHelper.js\";\nimport { GeneralError } from \"../errors/generalError.js\";\nimport type { IPatchOperation } from \"../models/IPatchOperation.js\";\nimport { Converter } from \"../utils/converter.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Helpers methods for JSON objects.\n */\nexport class JsonHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<JsonHelper>();\n\n\t/**\n\t * Serializes in canonical format.\n\t * Based on https://www.rfc-editor.org/rfc/rfc8785.\n\t * @param object The object to be serialized.\n\t * @returns The serialized object.\n\t */\n\tpublic static canonicalize(object: unknown): string {\n\t\tconst buffer: string[] = [];\n\n\t\tif (\n\t\t\tobject === null ||\n\t\t\ttypeof object !== \"object\" ||\n\t\t\t(\"toJSON\" in object && Is.function(object.toJSON))\n\t\t) {\n\t\t\t// Primitive data type\n\t\t\tbuffer.push(JSON.stringify(object));\n\t\t} else if (Array.isArray(object)) {\n\t\t\t// Array maintain element order\n\t\t\tconst parts: string[] = [];\n\t\t\tfor (const element of object) {\n\t\t\t\tif (element === undefined) {\n\t\t\t\t\tparts.push(\"null\");\n\t\t\t\t} else {\n\t\t\t\t\tparts.push(JsonHelper.canonicalize(element));\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuffer.push(`[${parts.join(\",\")}]`);\n\t\t} else {\n\t\t\t// Object sort properties\n\t\t\tconst props: string[] = [];\n\t\t\tconst keys = Object.keys(object).sort();\n\t\t\tconst o = object as { [id: string]: unknown };\n\t\t\tfor (const key of keys) {\n\t\t\t\tif (o[key] !== undefined) {\n\t\t\t\t\tprops.push(`${JSON.stringify(key)}:${JsonHelper.canonicalize(o[key])}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuffer.push(`{${props.join(\",\")}}`);\n\t\t}\n\n\t\treturn buffer.join(\"\");\n\t}\n\n\t/**\n\t * Creates a RFC 6902 diff set.\n\t * Based on https://www.rfc-editor.org/rfc/rfc6902.\n\t * @param object1 The first object.\n\t * @param object2 The second object.\n\t * @returns The list of patches.\n\t */\n\tpublic static diff<T = unknown>(object1: T, object2: T): IPatchOperation[] {\n\t\tconst operations = createPatch(object1, object2);\n\t\treturn operations as IPatchOperation[];\n\t}\n\n\t/**\n\t * Applies a RFC 6902 diff set to an object.\n\t * Based on https://www.rfc-editor.org/rfc/rfc6902.\n\t * @param object The object to patch.\n\t * @param patches The second object.\n\t * @returns The updated object.\n\t * @throws GeneralError if the patch fails.\n\t */\n\tpublic static patch<T = unknown>(object: T, patches: IPatchOperation[]): T {\n\t\tconst clone = ObjectHelper.clone(object);\n\t\tconst result = applyPatch(clone, patches as Operation[]);\n\n\t\tfor (let i = 0; i < result.length; i++) {\n\t\t\tif (!Is.empty(result[i])) {\n\t\t\t\tthrow new GeneralError(JsonHelper.CLASS_NAME, \"failedPatch\", { index: i }, result[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn clone;\n\t}\n\n\t/**\n\t * Stringify the JSON with support for extended data types date/bigint/uint8array.\n\t * @param object The object to stringify.\n\t * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\n\t * @returns The stringified object.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static stringifyEx(object: any, space?: string | number): string {\n\t\t// We want to keep the 'this' intact for the replacer\n\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\t\treturn JSON.stringify(object, JsonHelper.stringifyExReplacer, space);\n\t}\n\n\t/**\n\t * Parse the JSON string with support for extended data types date/bigint/uint8array.\n\t * @param json The object to pause.\n\t * @returns The object.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static parseEx(json: string): any {\n\t\t// We want to keep the 'this' intact for the reviver\n\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\t\treturn JSON.parse(json, JsonHelper.parseExReviver);\n\t}\n\n\t/**\n\t * Replacer function to handle extended data types.\n\t * @param this The object.\n\t * @param key The key.\n\t * @param value The value.\n\t * @returns The value.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static stringifyExReplacer(this: any, key: string, value: unknown): unknown {\n\t\t// The this in the replacer is the containing object\n\t\t// so we need to get the actual value from there\n\t\t// eslint-disable-next-line no-restricted-syntax\n\t\tconst rawValue = this[key];\n\n\t\tif (Is.bigint(rawValue)) {\n\t\t\treturn {\n\t\t\t\t\"@ext\": \"bigint\",\n\t\t\t\tvalue: rawValue.toString()\n\t\t\t};\n\t\t} else if (Is.date(rawValue)) {\n\t\t\treturn {\n\t\t\t\t\"@ext\": \"date\",\n\t\t\t\tvalue: rawValue.getTime()\n\t\t\t};\n\t\t} else if (Is.uint8Array(rawValue)) {\n\t\t\treturn {\n\t\t\t\t\"@ext\": \"uint8array\",\n\t\t\t\tvalue: Converter.bytesToBase64(rawValue)\n\t\t\t};\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Reviver function to handle extended data types.\n\t * @param this The object.\n\t * @param key The key.\n\t * @param value The value.\n\t * @returns The value.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static parseExReviver(this: any, key: string, value: unknown): unknown {\n\t\tif (Is.object<{ \"@ext\": string; value: string }>(value)) {\n\t\t\tif (value[\"@ext\"] === \"bigint\") {\n\t\t\t\treturn BigInt(value.value);\n\t\t\t} else if (value[\"@ext\"] === \"date\") {\n\t\t\t\treturn new Date(value.value);\n\t\t\t} else if (value[\"@ext\"] === \"uint8array\") {\n\t\t\t\treturn Converter.base64ToBytes(value.value);\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t}\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import { Guards } from "../utils/guards.js";
2
+ import { Is } from "../utils/is.js";
3
+ /**
4
+ * Class to help with numbers.
5
+ */
6
+ export class NumberHelper {
7
+ /**
8
+ * Runtime name for the class.
9
+ */
10
+ static CLASS_NAME = "NumberHelper";
11
+ /**
12
+ * Clamps a number between a minimum and maximum value.
13
+ * @param value The value to clamp.
14
+ * @param minValue The minimum value.
15
+ * @param maxValue The maximum value.
16
+ * @returns The clamped value.
17
+ */
18
+ static clamp(value, minValue, maxValue) {
19
+ Guards.number(NumberHelper.CLASS_NAME, "value", value);
20
+ let output = value;
21
+ if (Is.number(minValue) && output < minValue) {
22
+ output = minValue;
23
+ }
24
+ if (Is.number(maxValue) && output > maxValue) {
25
+ output = maxValue;
26
+ }
27
+ return output;
28
+ }
29
+ }
30
+ //# sourceMappingURL=numberHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numberHelper.js","sourceRoot":"","sources":["../../../src/helpers/numberHelper.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEpC;;GAEG;AACH,MAAM,OAAO,YAAY;IACxB;;OAEG;IACI,MAAM,CAAU,UAAU,kBAAkC;IAEnE;;;;;;OAMG;IACI,MAAM,CAAC,KAAK,CAAC,KAAa,EAAE,QAAiB,EAAE,QAAiB;QACtE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,WAAiB,KAAK,CAAC,CAAC;QAE7D,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;YAC9C,MAAM,GAAG,QAAQ,CAAC;QACnB,CAAC;QACD,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;YAC9C,MAAM,GAAG,QAAQ,CAAC;QACnB,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Class to help with numbers.\n */\nexport class NumberHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<NumberHelper>();\n\n\t/**\n\t * Clamps a number between a minimum and maximum value.\n\t * @param value The value to clamp.\n\t * @param minValue The minimum value.\n\t * @param maxValue The maximum value.\n\t * @returns The clamped value.\n\t */\n\tpublic static clamp(value: number, minValue?: number, maxValue?: number): number {\n\t\tGuards.number(NumberHelper.CLASS_NAME, nameof(value), value);\n\n\t\tlet output = value;\n\t\tif (Is.number(minValue) && output < minValue) {\n\t\t\toutput = minValue;\n\t\t}\n\t\tif (Is.number(maxValue) && output > maxValue) {\n\t\t\toutput = maxValue;\n\t\t}\n\n\t\treturn output;\n\t}\n}\n"]}
@@ -0,0 +1,333 @@
1
+ import { JsonHelper } from "./jsonHelper.js";
2
+ import { GeneralError } from "../errors/generalError.js";
3
+ import { Converter } from "../utils/converter.js";
4
+ import { Is } from "../utils/is.js";
5
+ /**
6
+ * Class to help with objects.
7
+ */
8
+ export class ObjectHelper {
9
+ /**
10
+ * Runtime name for the class.
11
+ */
12
+ static CLASS_NAME = "ObjectHelper";
13
+ /**
14
+ * Convert an object to bytes.
15
+ * @param obj The object to convert.
16
+ * @param format Format the JSON content.
17
+ * @returns The object as bytes.
18
+ */
19
+ static toBytes(obj, format = false) {
20
+ if (Is.undefined(obj)) {
21
+ return new Uint8Array();
22
+ }
23
+ const json = format ? JSON.stringify(obj, undefined, "\t") : JSON.stringify(obj);
24
+ return Converter.utf8ToBytes(json);
25
+ }
26
+ /**
27
+ * Convert a bytes to an object.
28
+ * @param bytes The bytes to convert to an object.
29
+ * @returns The object.
30
+ * @throws GeneralError if there was an error parsing the JSON.
31
+ */
32
+ static fromBytes(bytes) {
33
+ if (Is.empty(bytes) || bytes.length === 0) {
34
+ return undefined;
35
+ }
36
+ try {
37
+ const utf8 = Converter.bytesToUtf8(bytes);
38
+ return JSON.parse(utf8);
39
+ }
40
+ catch (err) {
41
+ throw new GeneralError(ObjectHelper.CLASS_NAME, "failedBytesToJSON", undefined, err);
42
+ }
43
+ }
44
+ /**
45
+ * Make a deep clone of an object.
46
+ * @param obj The object to clone.
47
+ * @returns The objects clone.
48
+ */
49
+ static clone(obj) {
50
+ if (Is.undefined(obj)) {
51
+ return undefined;
52
+ }
53
+ return structuredClone(obj);
54
+ }
55
+ /**
56
+ * Deep merge objects.
57
+ * @param obj1 The first object to merge.
58
+ * @param obj2 The second object to merge.
59
+ * @returns The combined deep merge of the objects.
60
+ */
61
+ static merge(obj1, obj2) {
62
+ if (Is.empty(obj1)) {
63
+ return ObjectHelper.clone(obj2);
64
+ }
65
+ if (Is.empty(obj2)) {
66
+ return ObjectHelper.clone(obj1);
67
+ }
68
+ const obj1Clone = ObjectHelper.clone(obj1);
69
+ if (Is.object(obj1Clone) && Is.object(obj2)) {
70
+ const keys = Object.keys(obj2);
71
+ for (const key of keys) {
72
+ if (Is.object(obj1Clone[key]) && Is.object(obj2[key])) {
73
+ ObjectHelper.propertySet(obj1Clone, key, ObjectHelper.merge(obj1Clone[key], obj2[key]));
74
+ }
75
+ else {
76
+ ObjectHelper.propertySet(obj1Clone, key, obj2[key]);
77
+ }
78
+ }
79
+ }
80
+ return obj1Clone;
81
+ }
82
+ /**
83
+ * Does one object equal another.
84
+ * @param obj1 The first object to compare.
85
+ * @param obj2 The second object to compare.
86
+ * @param strictPropertyOrder Should the properties be in the same order, defaults to true.
87
+ * @returns True is the objects are equal.
88
+ */
89
+ static equal(obj1, obj2, strictPropertyOrder) {
90
+ if (strictPropertyOrder ?? true) {
91
+ return JSON.stringify(obj1) === JSON.stringify(obj2);
92
+ }
93
+ return JsonHelper.canonicalize(obj1) === JsonHelper.canonicalize(obj2);
94
+ }
95
+ /**
96
+ * Get the property of an unknown object.
97
+ * @param obj The object to get the property from.
98
+ * @param property The property to get, can be separated by dots for nested path.
99
+ * @returns The property.
100
+ */
101
+ static propertyGet(obj, property) {
102
+ const pathParts = property.split(".");
103
+ let pathValue = obj;
104
+ for (const pathPart of pathParts) {
105
+ // Is the path part numeric i.e. an array index.
106
+ const arrayMatch = /^(\d+)$/.exec(pathPart);
107
+ if (arrayMatch) {
108
+ const arrayIndex = Number.parseInt(arrayMatch[1], 10);
109
+ if (Is.arrayValue(pathValue) && arrayIndex < pathValue.length) {
110
+ // There is no prop name so this is a direct array index on the current object
111
+ pathValue = pathValue[arrayIndex];
112
+ }
113
+ else {
114
+ // Array index for non array object so return
115
+ return undefined;
116
+ }
117
+ }
118
+ else if (Is.object(pathValue)) {
119
+ // No array part in path so assume object sub property
120
+ pathValue = pathValue[pathPart];
121
+ }
122
+ else {
123
+ return undefined;
124
+ }
125
+ }
126
+ return pathValue;
127
+ }
128
+ /**
129
+ * Set the property of an unknown object.
130
+ * @param obj The object to set the property from.
131
+ * @param property The property to set.
132
+ * @param value The value to set.
133
+ * @throws GeneralError if the property target is not an object.
134
+ */
135
+ static propertySet(obj, property, value) {
136
+ const pathParts = property.split(".");
137
+ let pathValue = obj;
138
+ let parentObj;
139
+ for (let i = 0; i < pathParts.length; i++) {
140
+ const pathPart = pathParts[i];
141
+ // Is the path part numeric i.e. an array index.
142
+ const arrayMatch = /^(\d+)$/.exec(pathPart);
143
+ const arrayIndex = arrayMatch ? Number.parseInt(arrayMatch[1], 10) : -1;
144
+ if (i === pathParts.length - 1) {
145
+ // Last part of path so set the value
146
+ if (arrayIndex >= 0) {
147
+ if (Is.array(pathValue)) {
148
+ pathValue[arrayIndex] = value;
149
+ }
150
+ else if (Is.object(pathValue)) {
151
+ pathValue[arrayIndex] = value;
152
+ }
153
+ else {
154
+ throw new GeneralError(ObjectHelper.CLASS_NAME, "cannotSetArrayIndex", {
155
+ property,
156
+ index: arrayIndex
157
+ });
158
+ }
159
+ }
160
+ else if (Is.object(pathValue)) {
161
+ pathValue[pathPart] = value;
162
+ }
163
+ else {
164
+ throw new GeneralError(ObjectHelper.CLASS_NAME, "cannotSetProperty", { property });
165
+ }
166
+ }
167
+ else {
168
+ parentObj = pathValue;
169
+ if (Is.object(pathValue)) {
170
+ pathValue = pathValue[pathPart];
171
+ }
172
+ else if (Is.array(pathValue)) {
173
+ pathValue = pathValue[arrayIndex];
174
+ }
175
+ if (Is.empty(pathValue)) {
176
+ const nextArrayMatch = /^(\d+)$/.exec(pathParts[i + 1]);
177
+ const nextArrayIndex = nextArrayMatch ? Number.parseInt(nextArrayMatch[1], 10) : -1;
178
+ if (nextArrayIndex >= 0) {
179
+ pathValue = [];
180
+ }
181
+ else {
182
+ pathValue = {};
183
+ }
184
+ if (Is.object(parentObj)) {
185
+ parentObj[pathPart] = pathValue;
186
+ }
187
+ else if (Is.array(parentObj)) {
188
+ parentObj[arrayIndex] = pathValue;
189
+ }
190
+ }
191
+ }
192
+ }
193
+ }
194
+ /**
195
+ * Delete the property of an unknown object.
196
+ * @param obj The object to set the property from.
197
+ * @param property The property to set
198
+ */
199
+ static propertyDelete(obj, property) {
200
+ if (Is.object(obj)) {
201
+ delete obj[property];
202
+ }
203
+ }
204
+ /**
205
+ * Extract a property from the object, providing alternative names.
206
+ * @param obj The object to extract from.
207
+ * @param propertyNames The possible names for the property.
208
+ * @param removeProperties Remove the properties from the object, defaults to true.
209
+ * @returns The property if available.
210
+ */
211
+ static extractProperty(obj, propertyNames, removeProperties = true) {
212
+ let retVal;
213
+ if (Is.object(obj)) {
214
+ const names = Is.string(propertyNames) ? [propertyNames] : propertyNames;
215
+ for (const prop of names) {
216
+ retVal ??= ObjectHelper.propertyGet(obj, prop);
217
+ if (removeProperties) {
218
+ ObjectHelper.propertyDelete(obj, prop);
219
+ }
220
+ }
221
+ }
222
+ return retVal;
223
+ }
224
+ /**
225
+ * Pick a subset of properties from an object.
226
+ * @param obj The object to pick the properties from.
227
+ * @param keys The property keys to pick.
228
+ * @returns The partial object.
229
+ */
230
+ static pick(obj, keys) {
231
+ if (Is.object(obj) && Is.arrayValue(keys)) {
232
+ const result = {};
233
+ for (const key of keys) {
234
+ result[key] = obj[key];
235
+ }
236
+ return result;
237
+ }
238
+ return obj;
239
+ }
240
+ /**
241
+ * Omit a subset of properties from an object.
242
+ * @param obj The object to omit the properties from.
243
+ * @param keys The property keys to omit.
244
+ * @returns The partial object.
245
+ */
246
+ static omit(obj, keys) {
247
+ if (Is.object(obj) && Is.arrayValue(keys)) {
248
+ const result = { ...obj };
249
+ for (const key of keys) {
250
+ delete result[key];
251
+ }
252
+ return result;
253
+ }
254
+ return obj;
255
+ }
256
+ /**
257
+ * Split an object into two with the specified keys.
258
+ * @param obj The object to split.
259
+ * @param keys The property keys to split.
260
+ * @returns The two partial objects.
261
+ */
262
+ static split(obj, keys) {
263
+ if (Is.object(obj) && Is.array(keys)) {
264
+ const picked = {};
265
+ const omitted = {};
266
+ const allKeys = Object.keys(obj);
267
+ for (const key of allKeys) {
268
+ if (keys.includes(key)) {
269
+ picked[key] = obj[key];
270
+ }
271
+ else {
272
+ omitted[key] = obj[key];
273
+ }
274
+ }
275
+ return {
276
+ picked: Object.keys(picked).length > 0 ? picked : undefined,
277
+ omitted: Object.keys(omitted).length > 0 ? omitted : undefined
278
+ };
279
+ }
280
+ return { picked: obj, omitted: undefined };
281
+ }
282
+ /**
283
+ * Converter the non JSON primitives to extended types.
284
+ * @param obj The object to convert.
285
+ * @returns The object with extended properties.
286
+ */
287
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
288
+ static toExtended(obj) {
289
+ const jsonExtended = JsonHelper.stringifyEx(obj);
290
+ return JSON.parse(jsonExtended);
291
+ }
292
+ /**
293
+ * Converter the extended types to non JSON primitives.
294
+ * @param obj The object to convert.
295
+ * @returns The object with regular properties.
296
+ */
297
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
+ static fromExtended(obj) {
299
+ const jsonExtended = JsonHelper.stringifyEx(obj);
300
+ return JsonHelper.parseEx(jsonExtended);
301
+ }
302
+ /**
303
+ * Remove empty properties from an object.
304
+ * @param obj The object to remove the empty properties from.
305
+ * @param options The options for the removal.
306
+ * @param options.removeUndefined Remove undefined properties, defaults to true.
307
+ * @param options.removeNull Remove null properties, defaults to false.
308
+ * @returns The object with empty properties removed.
309
+ */
310
+ static removeEmptyProperties(obj, options) {
311
+ if (Is.object(obj)) {
312
+ const removeUndefined = options?.removeUndefined ?? true;
313
+ const removeNull = options?.removeNull ?? false;
314
+ const newObj = {};
315
+ const keys = Object.keys(obj);
316
+ for (const key of keys) {
317
+ if (!((removeUndefined && Is.undefined(obj[key])) || (removeNull && Is.null(obj[key])))) {
318
+ newObj[key] = ObjectHelper.removeEmptyProperties(obj[key], options);
319
+ }
320
+ }
321
+ return newObj;
322
+ }
323
+ else if (Is.array(obj)) {
324
+ const arr = [];
325
+ for (const element of obj) {
326
+ arr.push(ObjectHelper.removeEmptyProperties(element, options));
327
+ }
328
+ return arr;
329
+ }
330
+ return obj;
331
+ }
332
+ }
333
+ //# sourceMappingURL=objectHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objectHelper.js","sourceRoot":"","sources":["../../../src/helpers/objectHelper.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 { JsonHelper } from \"./jsonHelper.js\";\nimport { GeneralError } from \"../errors/generalError.js\";\nimport { Converter } from \"../utils/converter.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Class to help with objects.\n */\nexport class ObjectHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ObjectHelper>();\n\n\t/**\n\t * Convert an object to bytes.\n\t * @param obj The object to convert.\n\t * @param format Format the JSON content.\n\t * @returns The object as bytes.\n\t */\n\tpublic static toBytes<T>(obj: T | undefined, format: boolean = false): Uint8Array {\n\t\tif (Is.undefined(obj)) {\n\t\t\treturn new Uint8Array();\n\t\t}\n\t\tconst json = format ? JSON.stringify(obj, undefined, \"\\t\") : JSON.stringify(obj);\n\n\t\treturn Converter.utf8ToBytes(json);\n\t}\n\n\t/**\n\t * Convert a bytes to an object.\n\t * @param bytes The bytes to convert to an object.\n\t * @returns The object.\n\t * @throws GeneralError if there was an error parsing the JSON.\n\t */\n\tpublic static fromBytes<T>(bytes: Uint8Array | undefined | null): T {\n\t\tif (Is.empty(bytes) || bytes.length === 0) {\n\t\t\treturn undefined as unknown as T;\n\t\t}\n\t\ttry {\n\t\t\tconst utf8 = Converter.bytesToUtf8(bytes);\n\t\t\treturn JSON.parse(utf8) as T;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(ObjectHelper.CLASS_NAME, \"failedBytesToJSON\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Make a deep clone of an object.\n\t * @param obj The object to clone.\n\t * @returns The objects clone.\n\t */\n\tpublic static clone<T>(obj: T): T {\n\t\tif (Is.undefined(obj)) {\n\t\t\treturn undefined as T;\n\t\t}\n\t\treturn structuredClone(obj);\n\t}\n\n\t/**\n\t * Deep merge objects.\n\t * @param obj1 The first object to merge.\n\t * @param obj2 The second object to merge.\n\t * @returns The combined deep merge of the objects.\n\t */\n\tpublic static merge<T = unknown, U = unknown>(obj1: T, obj2: U): T & U {\n\t\tif (Is.empty(obj1)) {\n\t\t\treturn ObjectHelper.clone(obj2) as T & U;\n\t\t}\n\t\tif (Is.empty(obj2)) {\n\t\t\treturn ObjectHelper.clone(obj1) as T & U;\n\t\t}\n\n\t\tconst obj1Clone = ObjectHelper.clone(obj1);\n\n\t\tif (Is.object(obj1Clone) && Is.object(obj2)) {\n\t\t\tconst keys = Object.keys(obj2);\n\t\t\tfor (const key of keys) {\n\t\t\t\tif (Is.object(obj1Clone[key]) && Is.object(obj2[key])) {\n\t\t\t\t\tObjectHelper.propertySet(obj1Clone, key, ObjectHelper.merge(obj1Clone[key], obj2[key]));\n\t\t\t\t} else {\n\t\t\t\t\tObjectHelper.propertySet(obj1Clone, key, obj2[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj1Clone as T & U;\n\t}\n\n\t/**\n\t * Does one object equal another.\n\t * @param obj1 The first object to compare.\n\t * @param obj2 The second object to compare.\n\t * @param strictPropertyOrder Should the properties be in the same order, defaults to true.\n\t * @returns True is the objects are equal.\n\t */\n\tpublic static equal<T>(obj1: T, obj2: T, strictPropertyOrder?: boolean): boolean {\n\t\tif (strictPropertyOrder ?? true) {\n\t\t\treturn JSON.stringify(obj1) === JSON.stringify(obj2);\n\t\t}\n\t\treturn JsonHelper.canonicalize(obj1) === JsonHelper.canonicalize(obj2);\n\t}\n\n\t/**\n\t * Get the property of an unknown object.\n\t * @param obj The object to get the property from.\n\t * @param property The property to get, can be separated by dots for nested path.\n\t * @returns The property.\n\t */\n\tpublic static propertyGet<T = unknown>(obj: unknown, property: string): T | undefined {\n\t\tconst pathParts = property.split(\".\");\n\n\t\tlet pathValue: unknown = obj;\n\t\tfor (const pathPart of pathParts) {\n\t\t\t// Is the path part numeric i.e. an array index.\n\t\t\tconst arrayMatch = /^(\\d+)$/.exec(pathPart);\n\n\t\t\tif (arrayMatch) {\n\t\t\t\tconst arrayIndex = Number.parseInt(arrayMatch[1], 10);\n\n\t\t\t\tif (Is.arrayValue(pathValue) && arrayIndex < pathValue.length) {\n\t\t\t\t\t// There is no prop name so this is a direct array index on the current object\n\t\t\t\t\tpathValue = pathValue[arrayIndex];\n\t\t\t\t} else {\n\t\t\t\t\t// Array index for non array object so return\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t} else if (Is.object(pathValue)) {\n\t\t\t\t// No array part in path so assume object sub property\n\t\t\t\tpathValue = pathValue[pathPart];\n\t\t\t} else {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\n\t\treturn pathValue as T;\n\t}\n\n\t/**\n\t * Set the property of an unknown object.\n\t * @param obj The object to set the property from.\n\t * @param property The property to set.\n\t * @param value The value to set.\n\t * @throws GeneralError if the property target is not an object.\n\t */\n\tpublic static propertySet(obj: unknown, property: string, value: unknown): void {\n\t\tconst pathParts = property.split(\".\");\n\n\t\tlet pathValue: unknown = obj;\n\t\tlet parentObj: unknown;\n\t\tfor (let i = 0; i < pathParts.length; i++) {\n\t\t\tconst pathPart = pathParts[i];\n\n\t\t\t// Is the path part numeric i.e. an array index.\n\t\t\tconst arrayMatch = /^(\\d+)$/.exec(pathPart);\n\t\t\tconst arrayIndex = arrayMatch ? Number.parseInt(arrayMatch[1], 10) : -1;\n\n\t\t\tif (i === pathParts.length - 1) {\n\t\t\t\t// Last part of path so set the value\n\t\t\t\tif (arrayIndex >= 0) {\n\t\t\t\t\tif (Is.array(pathValue)) {\n\t\t\t\t\t\tpathValue[arrayIndex] = value;\n\t\t\t\t\t} else if (Is.object(pathValue)) {\n\t\t\t\t\t\tpathValue[arrayIndex] = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new GeneralError(ObjectHelper.CLASS_NAME, \"cannotSetArrayIndex\", {\n\t\t\t\t\t\t\tproperty,\n\t\t\t\t\t\t\tindex: arrayIndex\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (Is.object(pathValue)) {\n\t\t\t\t\tpathValue[pathPart] = value;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new GeneralError(ObjectHelper.CLASS_NAME, \"cannotSetProperty\", { property });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tparentObj = pathValue;\n\t\t\t\tif (Is.object(pathValue)) {\n\t\t\t\t\tpathValue = pathValue[pathPart];\n\t\t\t\t} else if (Is.array(pathValue)) {\n\t\t\t\t\tpathValue = pathValue[arrayIndex];\n\t\t\t\t}\n\n\t\t\t\tif (Is.empty(pathValue)) {\n\t\t\t\t\tconst nextArrayMatch = /^(\\d+)$/.exec(pathParts[i + 1]);\n\t\t\t\t\tconst nextArrayIndex = nextArrayMatch ? Number.parseInt(nextArrayMatch[1], 10) : -1;\n\n\t\t\t\t\tif (nextArrayIndex >= 0) {\n\t\t\t\t\t\tpathValue = [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpathValue = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tif (Is.object(parentObj)) {\n\t\t\t\t\t\tparentObj[pathPart] = pathValue;\n\t\t\t\t\t} else if (Is.array(parentObj)) {\n\t\t\t\t\t\tparentObj[arrayIndex] = pathValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Delete the property of an unknown object.\n\t * @param obj The object to set the property from.\n\t * @param property The property to set\n\t */\n\tpublic static propertyDelete(obj: unknown, property: string): void {\n\t\tif (Is.object(obj)) {\n\t\t\tdelete obj[property];\n\t\t}\n\t}\n\n\t/**\n\t * Extract a property from the object, providing alternative names.\n\t * @param obj The object to extract from.\n\t * @param propertyNames The possible names for the property.\n\t * @param removeProperties Remove the properties from the object, defaults to true.\n\t * @returns The property if available.\n\t */\n\tpublic static extractProperty<T>(\n\t\tobj: unknown,\n\t\tpropertyNames: string | string[],\n\t\tremoveProperties: boolean = true\n\t): T | undefined {\n\t\tlet retVal: T | undefined;\n\n\t\tif (Is.object(obj)) {\n\t\t\tconst names = Is.string(propertyNames) ? [propertyNames] : propertyNames;\n\n\t\t\tfor (const prop of names) {\n\t\t\t\tretVal ??= ObjectHelper.propertyGet<T>(obj, prop);\n\t\t\t\tif (removeProperties) {\n\t\t\t\t\tObjectHelper.propertyDelete(obj, prop);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn retVal;\n\t}\n\n\t/**\n\t * Pick a subset of properties from an object.\n\t * @param obj The object to pick the properties from.\n\t * @param keys The property keys to pick.\n\t * @returns The partial object.\n\t */\n\tpublic static pick<T>(obj: T | undefined, keys?: (keyof T)[]): Partial<T> {\n\t\tif (Is.object(obj) && Is.arrayValue(keys)) {\n\t\t\tconst result: Partial<T> = {};\n\t\t\tfor (const key of keys) {\n\t\t\t\tresult[key] = obj[key];\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn obj as Partial<T>;\n\t}\n\n\t/**\n\t * Omit a subset of properties from an object.\n\t * @param obj The object to omit the properties from.\n\t * @param keys The property keys to omit.\n\t * @returns The partial object.\n\t */\n\tpublic static omit<T>(obj: T | undefined, keys?: (keyof T)[]): Partial<T> {\n\t\tif (Is.object(obj) && Is.arrayValue(keys)) {\n\t\t\tconst result = { ...obj };\n\t\t\tfor (const key of keys) {\n\t\t\t\tdelete result[key];\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn obj as Partial<T>;\n\t}\n\n\t/**\n\t * Split an object into two with the specified keys.\n\t * @param obj The object to split.\n\t * @param keys The property keys to split.\n\t * @returns The two partial objects.\n\t */\n\tpublic static split<T>(\n\t\tobj: T | undefined,\n\t\tkeys?: (keyof T)[]\n\t): { picked: Partial<T> | undefined; omitted: Partial<T> | undefined } {\n\t\tif (Is.object(obj) && Is.array(keys)) {\n\t\t\tconst picked: Partial<T> = {};\n\t\t\tconst omitted: Partial<T> = {};\n\n\t\t\tconst allKeys = Object.keys(obj) as (keyof T)[];\n\t\t\tfor (const key of allKeys) {\n\t\t\t\tif (keys.includes(key)) {\n\t\t\t\t\tpicked[key] = obj[key];\n\t\t\t\t} else {\n\t\t\t\t\tomitted[key] = obj[key];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tpicked: Object.keys(picked).length > 0 ? picked : undefined,\n\t\t\t\tomitted: Object.keys(omitted).length > 0 ? omitted : undefined\n\t\t\t};\n\t\t}\n\n\t\treturn { picked: obj as Partial<T>, omitted: undefined };\n\t}\n\n\t/**\n\t * Converter the non JSON primitives to extended types.\n\t * @param obj The object to convert.\n\t * @returns The object with extended properties.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static toExtended(obj: any): any {\n\t\tconst jsonExtended = JsonHelper.stringifyEx(obj);\n\t\treturn JSON.parse(jsonExtended);\n\t}\n\n\t/**\n\t * Converter the extended types to non JSON primitives.\n\t * @param obj The object to convert.\n\t * @returns The object with regular properties.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static fromExtended(obj: any): any {\n\t\tconst jsonExtended = JsonHelper.stringifyEx(obj);\n\t\treturn JsonHelper.parseEx(jsonExtended);\n\t}\n\n\t/**\n\t * Remove empty properties from an object.\n\t * @param obj The object to remove the empty properties from.\n\t * @param options The options for the removal.\n\t * @param options.removeUndefined Remove undefined properties, defaults to true.\n\t * @param options.removeNull Remove null properties, defaults to false.\n\t * @returns The object with empty properties removed.\n\t */\n\tpublic static removeEmptyProperties<T = unknown>(\n\t\tobj: T,\n\t\toptions?: { removeUndefined?: boolean; removeNull?: boolean }\n\t): T {\n\t\tif (Is.object(obj)) {\n\t\t\tconst removeUndefined = options?.removeUndefined ?? true;\n\t\t\tconst removeNull = options?.removeNull ?? false;\n\t\t\tconst newObj: { [id: string]: unknown } = {};\n\t\t\tconst keys = Object.keys(obj);\n\t\t\tfor (const key of keys) {\n\t\t\t\tif (!((removeUndefined && Is.undefined(obj[key])) || (removeNull && Is.null(obj[key])))) {\n\t\t\t\t\tnewObj[key] = ObjectHelper.removeEmptyProperties(obj[key], options);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn newObj as T;\n\t\t} else if (Is.array(obj)) {\n\t\t\tconst arr = [];\n\t\t\tfor (const element of obj) {\n\t\t\t\tarr.push(ObjectHelper.removeEmptyProperties(element, options));\n\t\t\t}\n\t\t\treturn arr as T;\n\t\t}\n\t\treturn obj;\n\t}\n}\n"]}
@@ -0,0 +1,18 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ /**
4
+ * Class to help with random generation.
5
+ */
6
+ export class RandomHelper {
7
+ /**
8
+ * Generate a new random array.
9
+ * @param length The length of buffer to create.
10
+ * @returns The random array.
11
+ */
12
+ static generate(length) {
13
+ const randomBytes = new Uint8Array(length);
14
+ globalThis.crypto.getRandomValues(randomBytes);
15
+ return randomBytes;
16
+ }
17
+ }
18
+ //# sourceMappingURL=randomHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"randomHelper.js","sourceRoot":"","sources":["../../../src/helpers/randomHelper.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AAEvC;;GAEG;AACH,MAAM,OAAO,YAAY;IACxB;;;;OAIG;IACI,MAAM,CAAC,QAAQ,CAAC,MAAc;QACpC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAC3C,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAC/C,OAAO,WAAW,CAAC;IACpB,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Class to help with random generation.\n */\nexport class RandomHelper {\n\t/**\n\t * Generate a new random array.\n\t * @param length The length of buffer to create.\n\t * @returns The random array.\n\t */\n\tpublic static generate(length: number): Uint8Array {\n\t\tconst randomBytes = new Uint8Array(length);\n\t\tglobalThis.crypto.getRandomValues(randomBytes);\n\t\treturn randomBytes;\n\t}\n}\n"]}