@twin.org/core 0.0.2-next.9 → 0.0.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 (225) hide show
  1. package/README.md +1 -9
  2. package/dist/es/encoding/base32.js +75 -0
  3. package/dist/es/encoding/base32.js.map +1 -0
  4. package/dist/es/encoding/base58.js +124 -0
  5. package/dist/es/encoding/base58.js.map +1 -0
  6. package/dist/es/encoding/base64.js +231 -0
  7. package/dist/es/encoding/base64.js.map +1 -0
  8. package/dist/es/encoding/base64Url.js +42 -0
  9. package/dist/es/encoding/base64Url.js.map +1 -0
  10. package/dist/es/errors/alreadyExistsError.js +22 -0
  11. package/dist/es/errors/alreadyExistsError.js.map +1 -0
  12. package/dist/es/errors/baseError.js +257 -0
  13. package/dist/es/errors/baseError.js.map +1 -0
  14. package/dist/es/errors/conflictError.js +23 -0
  15. package/dist/es/errors/conflictError.js.map +1 -0
  16. package/dist/es/errors/generalError.js +21 -0
  17. package/dist/es/errors/generalError.js.map +1 -0
  18. package/dist/es/errors/guardError.js +27 -0
  19. package/dist/es/errors/guardError.js.map +1 -0
  20. package/dist/es/errors/notFoundError.js +22 -0
  21. package/dist/es/errors/notFoundError.js.map +1 -0
  22. package/dist/es/errors/notImplementedError.js +24 -0
  23. package/dist/es/errors/notImplementedError.js.map +1 -0
  24. package/dist/es/errors/notSupportedError.js +21 -0
  25. package/dist/es/errors/notSupportedError.js.map +1 -0
  26. package/dist/es/errors/unauthorizedError.js +21 -0
  27. package/dist/es/errors/unauthorizedError.js.map +1 -0
  28. package/dist/es/errors/unprocessableError.js +21 -0
  29. package/dist/es/errors/unprocessableError.js.map +1 -0
  30. package/dist/es/errors/validationError.js +23 -0
  31. package/dist/es/errors/validationError.js.map +1 -0
  32. package/dist/es/factories/componentFactory.js +9 -0
  33. package/dist/es/factories/componentFactory.js.map +1 -0
  34. package/dist/es/factories/factory.js +297 -0
  35. package/dist/es/factories/factory.js.map +1 -0
  36. package/dist/es/helpers/arrayHelper.js +46 -0
  37. package/dist/es/helpers/arrayHelper.js.map +1 -0
  38. package/dist/es/helpers/envHelper.js +39 -0
  39. package/dist/es/helpers/envHelper.js.map +1 -0
  40. package/dist/es/helpers/errorHelper.js +100 -0
  41. package/dist/es/helpers/errorHelper.js.map +1 -0
  42. package/dist/es/helpers/filenameHelper.js +32 -0
  43. package/dist/es/helpers/filenameHelper.js.map +1 -0
  44. package/dist/es/helpers/hexHelper.js +45 -0
  45. package/dist/es/helpers/hexHelper.js.map +1 -0
  46. package/dist/es/helpers/jsonHelper.js +163 -0
  47. package/dist/es/helpers/jsonHelper.js.map +1 -0
  48. package/dist/es/helpers/numberHelper.js +30 -0
  49. package/dist/es/helpers/numberHelper.js.map +1 -0
  50. package/dist/es/helpers/objectHelper.js +309 -0
  51. package/dist/es/helpers/objectHelper.js.map +1 -0
  52. package/dist/es/helpers/randomHelper.js +66 -0
  53. package/dist/es/helpers/randomHelper.js.map +1 -0
  54. package/dist/es/helpers/stringHelper.js +252 -0
  55. package/dist/es/helpers/stringHelper.js.map +1 -0
  56. package/dist/es/helpers/uint8ArrayHelper.js +26 -0
  57. package/dist/es/helpers/uint8ArrayHelper.js.map +1 -0
  58. package/dist/es/index.js +60 -0
  59. package/dist/es/index.js.map +1 -0
  60. package/dist/es/models/IComponent.js +2 -0
  61. package/dist/es/models/IComponent.js.map +1 -0
  62. package/dist/es/models/IError.js +4 -0
  63. package/dist/es/models/IError.js.map +1 -0
  64. package/dist/es/models/IHealth.js +2 -0
  65. package/dist/es/models/IHealth.js.map +1 -0
  66. package/dist/es/models/II18nShared.js +2 -0
  67. package/dist/es/models/II18nShared.js.map +1 -0
  68. package/dist/es/models/IKeyValue.js +2 -0
  69. package/dist/es/models/IKeyValue.js.map +1 -0
  70. package/dist/es/models/ILabelledValue.js +2 -0
  71. package/dist/es/models/ILabelledValue.js.map +1 -0
  72. package/dist/es/models/ILocale.js +2 -0
  73. package/dist/es/models/ILocale.js.map +1 -0
  74. package/dist/es/models/ILocaleDictionary.js +4 -0
  75. package/dist/es/models/ILocaleDictionary.js.map +1 -0
  76. package/dist/es/models/ILocalesIndex.js +2 -0
  77. package/dist/es/models/ILocalesIndex.js.map +1 -0
  78. package/dist/es/models/IPatchOperation.js +4 -0
  79. package/dist/es/models/IPatchOperation.js.map +1 -0
  80. package/dist/es/models/IUrlParts.js +4 -0
  81. package/dist/es/models/IUrlParts.js.map +1 -0
  82. package/dist/es/models/IValidationFailure.js +2 -0
  83. package/dist/es/models/IValidationFailure.js.map +1 -0
  84. package/dist/es/models/coerceType.js +49 -0
  85. package/dist/es/models/coerceType.js.map +1 -0
  86. package/dist/es/models/compressionType.js +17 -0
  87. package/dist/es/models/compressionType.js.map +1 -0
  88. package/dist/es/models/healthStatus.js +21 -0
  89. package/dist/es/models/healthStatus.js.map +1 -0
  90. package/dist/es/types/bitString.js +98 -0
  91. package/dist/es/types/bitString.js.map +1 -0
  92. package/dist/es/types/objectOrArray.js +2 -0
  93. package/dist/es/types/objectOrArray.js.map +1 -0
  94. package/dist/es/types/singleOccurrenceArray.js +2 -0
  95. package/dist/es/types/singleOccurrenceArray.js.map +1 -0
  96. package/dist/es/types/url.js +144 -0
  97. package/dist/es/types/url.js.map +1 -0
  98. package/dist/es/types/urn.js +211 -0
  99. package/dist/es/types/urn.js.map +1 -0
  100. package/dist/es/utils/asyncCache.js +206 -0
  101. package/dist/es/utils/asyncCache.js.map +1 -0
  102. package/dist/es/utils/coerce.js +269 -0
  103. package/dist/es/utils/coerce.js.map +1 -0
  104. package/dist/es/utils/compression.js +49 -0
  105. package/dist/es/utils/compression.js.map +1 -0
  106. package/dist/es/utils/converter.js +256 -0
  107. package/dist/es/utils/converter.js.map +1 -0
  108. package/dist/es/utils/guards.js +385 -0
  109. package/dist/es/utils/guards.js.map +1 -0
  110. package/dist/es/utils/i18n.js +243 -0
  111. package/dist/es/utils/i18n.js.map +1 -0
  112. package/dist/es/utils/is.js +367 -0
  113. package/dist/es/utils/is.js.map +1 -0
  114. package/dist/es/utils/sharedStore.js +48 -0
  115. package/dist/es/utils/sharedStore.js.map +1 -0
  116. package/dist/es/utils/validation.js +774 -0
  117. package/dist/es/utils/validation.js.map +1 -0
  118. package/dist/types/encoding/base32.d.ts +5 -1
  119. package/dist/types/encoding/base58.d.ts +4 -0
  120. package/dist/types/encoding/base64.d.ts +4 -0
  121. package/dist/types/encoding/base64Url.d.ts +4 -0
  122. package/dist/types/errors/alreadyExistsError.d.ts +6 -3
  123. package/dist/types/errors/baseError.d.ts +2 -2
  124. package/dist/types/errors/conflictError.d.ts +6 -3
  125. package/dist/types/errors/generalError.d.ts +2 -2
  126. package/dist/types/errors/guardError.d.ts +2 -2
  127. package/dist/types/errors/notFoundError.d.ts +6 -3
  128. package/dist/types/errors/notImplementedError.d.ts +6 -2
  129. package/dist/types/errors/notSupportedError.d.ts +6 -3
  130. package/dist/types/errors/unauthorizedError.d.ts +7 -4
  131. package/dist/types/errors/unprocessableError.d.ts +2 -2
  132. package/dist/types/errors/validationError.d.ts +2 -2
  133. package/dist/types/factories/componentFactory.d.ts +2 -2
  134. package/dist/types/factories/factory.d.ts +27 -1
  135. package/dist/types/helpers/arrayHelper.d.ts +1 -8
  136. package/dist/types/helpers/errorHelper.d.ts +1 -1
  137. package/dist/types/helpers/jsonHelper.d.ts +5 -1
  138. package/dist/types/helpers/numberHelper.d.ts +17 -0
  139. package/dist/types/helpers/objectHelper.d.ts +24 -6
  140. package/dist/types/helpers/randomHelper.d.ts +16 -0
  141. package/dist/types/helpers/stringHelper.d.ts +12 -6
  142. package/dist/types/index.d.ts +57 -53
  143. package/dist/types/models/IComponent.d.ts +18 -7
  144. package/dist/types/models/IError.d.ts +1 -1
  145. package/dist/types/models/IHealth.d.ts +32 -0
  146. package/dist/types/models/ILocalesIndex.d.ts +1 -1
  147. package/dist/types/models/IValidationFailure.d.ts +0 -4
  148. package/dist/types/models/healthStatus.d.ts +21 -0
  149. package/dist/types/types/bitString.d.ts +4 -0
  150. package/dist/types/types/singleOccurrenceArray.d.ts +9 -0
  151. package/dist/types/types/url.d.ts +8 -3
  152. package/dist/types/types/urn.d.ts +7 -2
  153. package/dist/types/utils/asyncCache.d.ts +7 -0
  154. package/dist/types/utils/coerce.d.ts +1 -1
  155. package/dist/types/utils/compression.d.ts +5 -1
  156. package/dist/types/utils/guards.d.ts +11 -3
  157. package/dist/types/utils/i18n.d.ts +16 -1
  158. package/dist/types/utils/is.d.ts +8 -1
  159. package/dist/types/utils/validation.d.ts +1 -1
  160. package/docs/changelog.md +1224 -131
  161. package/docs/examples.md +308 -1
  162. package/docs/reference/classes/AlreadyExistsError.md +43 -39
  163. package/docs/reference/classes/ArrayHelper.md +10 -44
  164. package/docs/reference/classes/AsyncCache.md +12 -12
  165. package/docs/reference/classes/Base32.md +11 -3
  166. package/docs/reference/classes/Base58.md +10 -2
  167. package/docs/reference/classes/Base64.md +11 -3
  168. package/docs/reference/classes/Base64Url.md +10 -2
  169. package/docs/reference/classes/BaseError.md +37 -37
  170. package/docs/reference/classes/BitString.md +13 -5
  171. package/docs/reference/classes/Coerce.md +31 -31
  172. package/docs/reference/classes/Compression.md +10 -2
  173. package/docs/reference/classes/ConflictError.md +43 -39
  174. package/docs/reference/classes/Converter.md +18 -18
  175. package/docs/reference/classes/EnvHelper.md +1 -1
  176. package/docs/reference/classes/ErrorHelper.md +5 -5
  177. package/docs/reference/classes/Factory.md +122 -20
  178. package/docs/reference/classes/FilenameHelper.md +1 -1
  179. package/docs/reference/classes/GeneralError.md +38 -38
  180. package/docs/reference/classes/GuardError.md +38 -38
  181. package/docs/reference/classes/Guards.md +80 -34
  182. package/docs/reference/classes/HexHelper.md +6 -6
  183. package/docs/reference/classes/I18n.md +66 -14
  184. package/docs/reference/classes/Is.md +77 -43
  185. package/docs/reference/classes/JsonHelper.md +17 -9
  186. package/docs/reference/classes/NotFoundError.md +43 -39
  187. package/docs/reference/classes/NotImplementedError.md +48 -38
  188. package/docs/reference/classes/NotSupportedError.md +43 -39
  189. package/docs/reference/classes/NumberHelper.md +55 -0
  190. package/docs/reference/classes/ObjectHelper.md +163 -51
  191. package/docs/reference/classes/RandomHelper.md +53 -1
  192. package/docs/reference/classes/SharedStore.md +5 -5
  193. package/docs/reference/classes/StringHelper.md +52 -30
  194. package/docs/reference/classes/Uint8ArrayHelper.md +1 -1
  195. package/docs/reference/classes/UnauthorizedError.md +44 -40
  196. package/docs/reference/classes/UnprocessableError.md +38 -38
  197. package/docs/reference/classes/Url.md +24 -10
  198. package/docs/reference/classes/Urn.md +42 -28
  199. package/docs/reference/classes/Validation.md +27 -27
  200. package/docs/reference/classes/ValidationError.md +37 -37
  201. package/docs/reference/index.md +6 -0
  202. package/docs/reference/interfaces/IComponent.md +57 -27
  203. package/docs/reference/interfaces/IError.md +11 -11
  204. package/docs/reference/interfaces/IHealth.md +55 -0
  205. package/docs/reference/interfaces/II18nShared.md +4 -4
  206. package/docs/reference/interfaces/IKeyValue.md +2 -2
  207. package/docs/reference/interfaces/ILabelledValue.md +2 -2
  208. package/docs/reference/interfaces/ILocale.md +2 -2
  209. package/docs/reference/interfaces/ILocaleDictionary.md +1 -1
  210. package/docs/reference/interfaces/ILocalesIndex.md +1 -1
  211. package/docs/reference/interfaces/IPatchOperation.md +6 -6
  212. package/docs/reference/interfaces/IUrlParts.md +9 -9
  213. package/docs/reference/interfaces/IValidationFailure.md +4 -12
  214. package/docs/reference/type-aliases/HealthStatus.md +5 -0
  215. package/docs/reference/type-aliases/SingleOccurrenceArray.md +15 -0
  216. package/docs/reference/type-aliases/SingleOccurrenceArrayDepthHelper.md +19 -0
  217. package/docs/reference/variables/CoerceType.md +10 -10
  218. package/docs/reference/variables/CompressionType.md +2 -2
  219. package/docs/reference/variables/HealthStatus.md +25 -0
  220. package/locales/.validate-ignore +1 -0
  221. package/locales/en.json +9 -7
  222. package/package.json +24 -12
  223. package/dist/cjs/index.cjs +0 -5175
  224. package/dist/esm/index.mjs +0 -5133
  225. /package/dist/types/{models → types}/objectOrArray.d.ts +0 -0
package/docs/examples.md CHANGED
@@ -1 +1,308 @@
1
- # @twin.org/core - Examples
1
+ # Core Examples
2
+
3
+ Use these snippets to validate input, transform data and handle errors consistently in shared runtime code.
4
+
5
+ ## Is
6
+
7
+ ```typescript
8
+ import { Is } from '@twin.org/core';
9
+
10
+ console.log(Is.string('alpha')); // true
11
+ console.log(Is.number(42)); // true
12
+ console.log(Is.array(['a', 'b'])); // true
13
+ console.log(Is.objectValue({ id: 'u-1' })); // true
14
+ console.log(Is.boolean(false)); // true
15
+ console.log(Is.json('{"ok":true}')); // true
16
+ console.log(Is.email('dev@example.org')); // true
17
+ console.log(Is.dateTimeString('2026-03-09T11:32:00Z')); // true
18
+ console.log(Is.stringHex('aabbccdd')); // true
19
+ console.log(Is.uuidV7('019531ce-6f7d-7c08-a6f3-f6f7cf9f41b0')); // true
20
+ ```
21
+
22
+ ## Guards
23
+
24
+ ```typescript
25
+ import { Guards } from '@twin.org/core';
26
+ import { nameof } from '@twin.org/nameof';
27
+
28
+ const name = 'Ari';
29
+ const profile = {
30
+ age: 31,
31
+ active: true
32
+ };
33
+ const createdAt = new Date('2026-03-09T10:00:00.000Z');
34
+
35
+ Guards.stringValue(this.CLASS_NAME, nameof(name), name);
36
+ Guards.objectValue(this.CLASS_NAME, nameof(profile), profile);
37
+ Guards.integer(this.CLASS_NAME, nameof(profile.age), profile.age);
38
+ Guards.boolean(this.CLASS_NAME, nameof(profile.active), profile.active);
39
+ Guards.date(this.CLASS_NAME, nameof(createdAt), createdAt);
40
+
41
+ console.log(name.toUpperCase()); // ARI
42
+ console.log(profile.age + 1); // 32
43
+
44
+ const amount = 'ten';
45
+
46
+ try {
47
+ Guards.number(this.CLASS_NAME, nameof(amount), amount);
48
+ } catch (error) {
49
+ if (error instanceof GuardError) {
50
+ console.log(error.message); // guard.number
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## Validation
56
+
57
+ ```typescript
58
+ import type { IValidationFailure } from '@twin.org/core';
59
+ import { Validation } from '@twin.org/core';
60
+
61
+ const failures: IValidationFailure[] = [];
62
+
63
+ Validation.stringValue('customer.name', 'Ari', failures, undefined, {
64
+ minLength: 2,
65
+ maxLength: 30
66
+ });
67
+ Validation.integer('customer.age', 31, failures, undefined, {
68
+ minValue: 18,
69
+ maxValue: 120
70
+ });
71
+ Validation.email('customer.email', 'customer@example.org', failures);
72
+
73
+ console.log(failures.length); // 0
74
+ ```
75
+
76
+ ## ObjectHelper
77
+
78
+ ```typescript
79
+ import { ObjectHelper } from '@twin.org/core';
80
+
81
+ const source = {
82
+ id: 'u-01',
83
+ profile: {
84
+ givenName: 'Ari'
85
+ },
86
+ tags: ['admin']
87
+ };
88
+
89
+ ObjectHelper.propertyGet(source, 'profile.givenName'); // 'Ari'
90
+ ObjectHelper.pick(source, ['id', 'tags']); // { id: 'u-01', tags: ['admin'] }
91
+ ObjectHelper.clone(source).id; // 'u-01'
92
+ ```
93
+
94
+ ## Converter
95
+
96
+ ```typescript
97
+ import { Converter } from '@twin.org/core';
98
+
99
+ const bytes = Converter.utf8ToBytes('twin');
100
+ Converter.bytesToHex(bytes); // '7477696e'
101
+ Converter.bytesToBase64Url(bytes); // 'dHdpbg'
102
+ ```
103
+
104
+ ## Coerce
105
+
106
+ ```typescript
107
+ import { Coerce } from '@twin.org/core';
108
+
109
+ Coerce.integer('19'); // 19
110
+ Coerce.boolean('true'); // true
111
+ Coerce.dateTime('2026-03-09T11:32:00Z')?.toISOString(); // '2026-03-09T11:32:00.000Z'
112
+ ```
113
+
114
+ ## StringHelper
115
+
116
+ ```typescript
117
+ import { StringHelper } from '@twin.org/core';
118
+
119
+ StringHelper.kebabCase('OrderCreatedEvent'); // 'order-created-event'
120
+ StringHelper.camelCase('order-created-event'); // 'orderCreatedEvent'
121
+ StringHelper.words('PaymentReferenceId'); // ['Payment', 'Reference', 'Id']
122
+ ```
123
+
124
+ ## Error Classes
125
+
126
+ ```typescript
127
+ import {
128
+ AlreadyExistsError,
129
+ BaseError,
130
+ ConflictError,
131
+ GeneralError,
132
+ GuardError,
133
+ NotFoundError,
134
+ NotImplementedError,
135
+ NotSupportedError,
136
+ UnauthorizedError,
137
+ UnprocessableError,
138
+ ValidationError
139
+ } from '@twin.org/core';
140
+
141
+ const base = new BaseError(this.CLASS_NAME, 'baseUnexpectedFailure', { module: 'orders' });
142
+ new AlreadyExistsError(this.CLASS_NAME, 'alreadyExistsOrder', { orderId: 'o-1' });
143
+ new ConflictError(this.CLASS_NAME, 'conflictVersionMismatch', { expected: 3, actual: 2 });
144
+ new GeneralError(this.CLASS_NAME, 'generalUnexpectedFailure', { retryable: false });
145
+ new GuardError(this.CLASS_NAME, 'guardValidationFailed', { field: 'name' });
146
+ new NotFoundError(this.CLASS_NAME, 'notFoundOrder', { orderId: 'o-1' });
147
+ new NotImplementedError(this.CLASS_NAME, 'notImplementedFeature', {
148
+ feature: 'export'
149
+ });
150
+ new NotSupportedError(this.CLASS_NAME, 'notSupportedFormat', { format: 'xml' });
151
+ new UnauthorizedError(this.CLASS_NAME, 'unauthorizedInvalidToken', {
152
+ scope: 'orders:write'
153
+ });
154
+ new UnprocessableError(this.CLASS_NAME, 'unprocessableInvalidContent', { field: 'email' });
155
+ new ValidationError(this.CLASS_NAME, 'validationInputFailed', { failures: 2 });
156
+ base.toJsonObject().name; // 'BaseError'
157
+ ```
158
+
159
+ ## Factory
160
+
161
+ ```typescript
162
+ import { Factory } from '@twin.org/core';
163
+
164
+ interface IHasher {
165
+ hash(value: string): string;
166
+ }
167
+
168
+ class SimpleHasher implements IHasher {
169
+ public hash(value: string): string {
170
+ return `${value}-hash`;
171
+ }
172
+ }
173
+
174
+ const factory = new Factory<IHasher>('hashers');
175
+ factory.register('simple', () => new SimpleHasher());
176
+
177
+ factory.create('simple').hash('abc'); // 'abc-hash'
178
+ ```
179
+
180
+ ## Encoding and Compression
181
+
182
+ ```typescript
183
+ import { Base32, Base58, Base64, Base64Url, Compression, HexHelper } from '@twin.org/core';
184
+
185
+ const bytes = new Uint8Array([1, 2, 3, 4]);
186
+
187
+ Base32.encode(bytes);
188
+ Base58.encode(bytes);
189
+ Base64.encode(bytes);
190
+ Base64Url.encode(bytes);
191
+ Compression.compress(bytes, 'gzip');
192
+ HexHelper.addPrefix('aabbcc'); // '0xaabbcc'
193
+ ```
194
+
195
+ ## AsyncCache and SharedStore
196
+
197
+ ```typescript
198
+ import { AsyncCache, SharedStore } from '@twin.org/core';
199
+
200
+ const cache = new AsyncCache<string, number>({ expirySeconds: 30 });
201
+ await cache.exec('invoice-1', async () => 4200); // 4200
202
+
203
+ SharedStore.set('region', 'eu-west-1');
204
+ SharedStore.get<string>('region'); // 'eu-west-1'
205
+ ```
206
+
207
+ ## RandomHelper and NumberHelper
208
+
209
+ ```typescript
210
+ import { NumberHelper, RandomHelper } from '@twin.org/core';
211
+
212
+ NumberHelper.clamp(150, 0, 100); // 100
213
+ RandomHelper.generate(16).length; // 16
214
+ RandomHelper.generateUuidV7(); // 'xxxxxxxx-xxxx-7xxx-xxxx-xxxxxxxxxxxx'
215
+ ```
216
+
217
+ ## Url, Urn and BitString
218
+
219
+ ```typescript
220
+ import { BitString, Url, Urn } from '@twin.org/core';
221
+
222
+ const url = Url.fromParts({
223
+ scheme: 'https',
224
+ host: 'example.org',
225
+ pathname: '/products'
226
+ });
227
+
228
+ url.toString(); // 'https://example.org/products'
229
+ Urn.fromValidString('urn:example:widget:123').namespaceMethod(); // 'example'
230
+
231
+ const bits = BitString.fromBits([1, 0, 1, 1]);
232
+ bits.getLength(); // 4
233
+ ```
234
+
235
+ ## JsonHelper
236
+
237
+ ```typescript
238
+ import { JsonHelper } from '@twin.org/core';
239
+
240
+ const left = { id: 'u-1', active: true };
241
+ const right = { id: 'u-1', active: false };
242
+
243
+ const patch = JsonHelper.diff(left, right);
244
+ JsonHelper.patch(left, patch); // { id: 'u-1', active: false }
245
+ ```
246
+
247
+ ## ErrorHelper
248
+
249
+ ```typescript
250
+ import { BaseError, ErrorHelper } from '@twin.org/core';
251
+
252
+ const error = new BaseError(this.CLASS_NAME, 'saveFailed', { entityId: 'u-1' });
253
+ const messages = ErrorHelper.formatErrors(error);
254
+
255
+ messages[0]; // 'saveFailed'
256
+ ```
257
+
258
+ ## Type Utilities
259
+
260
+ ```typescript
261
+ import type { ObjectOrArray, SingleOccurrenceArray } from '@twin.org/core';
262
+
263
+ type IdOrIds = ObjectOrArray<string>;
264
+
265
+ const singleId: IdOrIds = 'id-1';
266
+ const manyIds: IdOrIds = ['id-1', 'id-2'];
267
+
268
+ const withOneNumber: SingleOccurrenceArray<string, number> = ['alpha', 7, 'beta'];
269
+ const numberOnly: SingleOccurrenceArray<string, number> = [7];
270
+
271
+ interface IFoo {
272
+ foo: boolean;
273
+ }
274
+
275
+ interface IBar {
276
+ bar: string;
277
+ }
278
+
279
+ const mixedObjects: SingleOccurrenceArray<IFoo, IBar> = [
280
+ { foo: true },
281
+ { bar: 'marker' },
282
+ { foo: false }
283
+ ];
284
+ ```
285
+
286
+ ## Array, Uint8Array, Filename and Env Helpers
287
+
288
+ ```typescript
289
+ import { ArrayHelper, EnvHelper, FilenameHelper, Uint8ArrayHelper } from '@twin.org/core';
290
+
291
+ ArrayHelper.matches([1, 2, 3], [1, 2, 3]); // true
292
+ Uint8ArrayHelper.concat(new Uint8Array([1, 2]), new Uint8Array([3, 4]));
293
+ FilenameHelper.safeFilename('Q1 Report: Europe/West.csv'); // 'Q1-Report-Europe-West.csv'
294
+ EnvHelper.envToJson('API_KEY=abc\nLOG_LEVEL=debug'); // { API_KEY: 'abc', LOG_LEVEL: 'debug' }
295
+ ```
296
+
297
+ ## I18n
298
+
299
+ ```typescript
300
+ import { I18n } from '@twin.org/core';
301
+
302
+ I18n.setLocale('en');
303
+ I18n.addDictionary('en', {
304
+ greeting: 'Hello {name}'
305
+ });
306
+
307
+ I18n.formatMessage('greeting', { name: 'Ari' }); // 'Hello Ari'
308
+ ```
@@ -10,7 +10,7 @@ Class to handle errors which are triggered by data already existing.
10
10
 
11
11
  ### Constructor
12
12
 
13
- > **new AlreadyExistsError**(`source`, `message`, `existingId?`, `cause?`): `AlreadyExistsError`
13
+ > **new AlreadyExistsError**(`source`, `message`, `existingId?`, `properties?`, `cause?`): `AlreadyExistsError`
14
14
 
15
15
  Create a new instance of AlreadyExistsError.
16
16
 
@@ -26,7 +26,7 @@ The source of the error.
26
26
 
27
27
  `string`
28
28
 
29
- The message as a code.
29
+ The message as an i18n key.
30
30
 
31
31
  ##### existingId?
32
32
 
@@ -34,6 +34,10 @@ The message as a code.
34
34
 
35
35
  The id for the item.
36
36
 
37
+ ##### properties?
38
+
39
+ Any additional information for the error.
40
+
37
41
  ##### cause?
38
42
 
39
43
  `unknown`
@@ -50,7 +54,7 @@ The cause of the error if we have wrapped another error.
50
54
 
51
55
  ## Properties
52
56
 
53
- ### CLASS\_NAME
57
+ ### CLASS\_NAME {#class_name}
54
58
 
55
59
  > `readonly` `static` **CLASS\_NAME**: `string`
56
60
 
@@ -58,9 +62,9 @@ Runtime name for the class.
58
62
 
59
63
  ***
60
64
 
61
- ### source?
65
+ ### source? {#source}
62
66
 
63
- > `optional` **source**: `string`
67
+ > `optional` **source?**: `string`
64
68
 
65
69
  The source of the error.
66
70
 
@@ -70,9 +74,9 @@ The source of the error.
70
74
 
71
75
  ***
72
76
 
73
- ### properties?
77
+ ### properties? {#properties}
74
78
 
75
- > `optional` **properties**: `object`
79
+ > `optional` **properties?**: `object`
76
80
 
77
81
  Any additional information for the error.
78
82
 
@@ -86,9 +90,9 @@ Any additional information for the error.
86
90
 
87
91
  ***
88
92
 
89
- ### cause?
93
+ ### cause? {#cause}
90
94
 
91
- > `optional` **cause**: [`IError`](../interfaces/IError.md)
95
+ > `optional` **cause?**: [`IError`](../interfaces/IError.md)
92
96
 
93
97
  The cause of the error.
94
98
 
@@ -98,7 +102,7 @@ The cause of the error.
98
102
 
99
103
  ## Methods
100
104
 
101
- ### fromError()
105
+ ### fromError() {#fromerror}
102
106
 
103
107
  > `static` **fromError**(`err`): [`BaseError`](BaseError.md)
104
108
 
@@ -124,7 +128,7 @@ The new instance.
124
128
 
125
129
  ***
126
130
 
127
- ### flatten()
131
+ ### flatten() {#flatten}
128
132
 
129
133
  > `static` **flatten**(`err`): [`IError`](../interfaces/IError.md)[]
130
134
 
@@ -150,9 +154,9 @@ The list of all internal errors.
150
154
 
151
155
  ***
152
156
 
153
- ### expand()
157
+ ### expand() {#expand}
154
158
 
155
- > `static` **expand**(`errors`): `undefined` \| [`IError`](../interfaces/IError.md)
159
+ > `static` **expand**(`errors`): [`IError`](../interfaces/IError.md) \| `undefined`
156
160
 
157
161
  Expand an error tree.
158
162
 
@@ -160,13 +164,13 @@ Expand an error tree.
160
164
 
161
165
  ##### errors
162
166
 
163
- The list of errors to expand.
167
+ [`IError`](../interfaces/IError.md)[] \| `undefined`
164
168
 
165
- `undefined` | [`IError`](../interfaces/IError.md)[]
169
+ The list of errors to expand.
166
170
 
167
171
  #### Returns
168
172
 
169
- `undefined` \| [`IError`](../interfaces/IError.md)
173
+ [`IError`](../interfaces/IError.md) \| `undefined`
170
174
 
171
175
  The first level error.
172
176
 
@@ -176,7 +180,7 @@ The first level error.
176
180
 
177
181
  ***
178
182
 
179
- ### isErrorName()
183
+ ### isErrorName() {#iserrorname}
180
184
 
181
185
  > `static` **isErrorName**(`error`, `name`): `error is BaseError`
182
186
 
@@ -192,9 +196,9 @@ The error to test.
192
196
 
193
197
  ##### name
194
198
 
195
- The name to check for.
199
+ `string` \| `RegExp`
196
200
 
197
- `string` | `RegExp`
201
+ The name to check for.
198
202
 
199
203
  #### Returns
200
204
 
@@ -208,7 +212,7 @@ True if the error has the name.
208
212
 
209
213
  ***
210
214
 
211
- ### isErrorMessage()
215
+ ### isErrorMessage() {#iserrormessage}
212
216
 
213
217
  > `static` **isErrorMessage**(`error`, `message`): `error is BaseError`
214
218
 
@@ -224,9 +228,9 @@ The error to test.
224
228
 
225
229
  ##### message
226
230
 
227
- The message to check for.
231
+ `string` \| `RegExp`
228
232
 
229
- `string` | `RegExp`
233
+ The message to check for.
230
234
 
231
235
  #### Returns
232
236
 
@@ -240,7 +244,7 @@ True if the error has the name.
240
244
 
241
245
  ***
242
246
 
243
- ### isErrorCode()
247
+ ### isErrorCode() {#iserrorcode}
244
248
 
245
249
  > `static` **isErrorCode**(`error`, `code`): `boolean`
246
250
 
@@ -256,9 +260,9 @@ The error to test.
256
260
 
257
261
  ##### code
258
262
 
259
- The code to check for.
263
+ `string` \| `RegExp`
260
264
 
261
- `string` | `RegExp`
265
+ The code to check for.
262
266
 
263
267
  #### Returns
264
268
 
@@ -272,7 +276,7 @@ True if the error has the code.
272
276
 
273
277
  ***
274
278
 
275
- ### someErrorName()
279
+ ### someErrorName() {#someerrorname}
276
280
 
277
281
  > `static` **someErrorName**(`error`, `name`): `error is BaseError`
278
282
 
@@ -288,9 +292,9 @@ The error to test.
288
292
 
289
293
  ##### name
290
294
 
291
- The name to check for.
295
+ `string` \| `RegExp`
292
296
 
293
- `string` | `RegExp`
297
+ The name to check for.
294
298
 
295
299
  #### Returns
296
300
 
@@ -304,7 +308,7 @@ True if the error has the name.
304
308
 
305
309
  ***
306
310
 
307
- ### someErrorMessage()
311
+ ### someErrorMessage() {#someerrormessage}
308
312
 
309
313
  > `static` **someErrorMessage**(`error`, `message`): `error is BaseError`
310
314
 
@@ -320,9 +324,9 @@ The error to test.
320
324
 
321
325
  ##### message
322
326
 
323
- The message to check for.
327
+ `string` \| `RegExp`
324
328
 
325
- `string` | `RegExp`
329
+ The message to check for.
326
330
 
327
331
  #### Returns
328
332
 
@@ -336,7 +340,7 @@ True if the error has the name.
336
340
 
337
341
  ***
338
342
 
339
- ### someErrorClass()
343
+ ### someErrorClass() {#someerrorclass}
340
344
 
341
345
  > `static` **someErrorClass**(`error`, `cls`): `error is BaseError`
342
346
 
@@ -368,7 +372,7 @@ True if the error has the specific class.
368
372
 
369
373
  ***
370
374
 
371
- ### someErrorCode()
375
+ ### someErrorCode() {#someerrorcode}
372
376
 
373
377
  > `static` **someErrorCode**(`error`, `code`): `error is BaseError`
374
378
 
@@ -384,9 +388,9 @@ The error to test.
384
388
 
385
389
  ##### code
386
390
 
387
- The code to check for.
391
+ `string` \| `RegExp`
388
392
 
389
- `string` | `RegExp`
393
+ The code to check for.
390
394
 
391
395
  #### Returns
392
396
 
@@ -400,7 +404,7 @@ True if the error has the name.
400
404
 
401
405
  ***
402
406
 
403
- ### isEmpty()
407
+ ### isEmpty() {#isempty}
404
408
 
405
409
  > `static` **isEmpty**(`err`): `boolean`
406
410
 
@@ -426,7 +430,7 @@ True if the error is empty.
426
430
 
427
431
  ***
428
432
 
429
- ### isAggregateError()
433
+ ### isAggregateError() {#isaggregateerror}
430
434
 
431
435
  > `static` **isAggregateError**(`err`): `err is AggregateError`
432
436
 
@@ -452,7 +456,7 @@ True if the error is an aggregate error.
452
456
 
453
457
  ***
454
458
 
455
- ### fromAggregate()
459
+ ### fromAggregate() {#fromaggregate}
456
460
 
457
461
  > `static` **fromAggregate**(`err`, `includeStackTrace?`): [`IError`](../interfaces/IError.md)[]
458
462
 
@@ -484,7 +488,7 @@ The array of errors.
484
488
 
485
489
  ***
486
490
 
487
- ### toJsonObject()
491
+ ### toJsonObject() {#tojsonobject}
488
492
 
489
493
  > **toJsonObject**(`includeStackTrace?`): [`IError`](../interfaces/IError.md)
490
494
 
@@ -14,7 +14,7 @@ Class to help with arrays.
14
14
 
15
15
  ## Methods
16
16
 
17
- ### matches()
17
+ ### matches() {#matches}
18
18
 
19
19
  > `static` **matches**(`arr1`, `arr2`): `boolean`
20
20
 
@@ -42,62 +42,28 @@ True if both arrays are empty of have the same values.
42
42
 
43
43
  ***
44
44
 
45
- ### fromObjectOrArray()
45
+ ### fromObjectOrArray() {#fromobjectorarray}
46
46
 
47
- Convert an object or array to an array.
48
-
49
- #### Param
50
-
51
- The object or array to convert.
52
-
53
- #### Call Signature
54
-
55
- > `static` **fromObjectOrArray**\<`T`\>(`value`): `undefined`
47
+ > `static` **fromObjectOrArray**\<`T`\>(`value`): `T` *extends* `undefined` ? `undefined` : `T`[]
56
48
 
57
49
  Convert an object or array to an array.
58
50
 
59
- ##### Type Parameters
51
+ #### Type Parameters
60
52
 
61
- ###### T
53
+ ##### T
62
54
 
63
55
  `T` = `unknown`
64
56
 
65
- ##### Parameters
66
-
67
- ###### value
68
-
69
- `undefined`
70
-
71
- The object or array to convert.
72
-
73
- ##### Returns
74
-
75
- `undefined`
76
-
77
- The array.
78
-
79
- #### Call Signature
80
-
81
- > `static` **fromObjectOrArray**\<`T`\>(`value`): `T`[]
82
-
83
- Convert an object or array to an array.
84
-
85
- ##### Type Parameters
86
-
87
- ###### T
88
-
89
- `T` = `unknown`
90
-
91
- ##### Parameters
57
+ #### Parameters
92
58
 
93
- ###### value
59
+ ##### value
94
60
 
95
- [`ObjectOrArray`](../type-aliases/ObjectOrArray.md)\<`T`\>
61
+ `T` \| `T`[] \| `undefined`
96
62
 
97
63
  The object or array to convert.
98
64
 
99
- ##### Returns
65
+ #### Returns
100
66
 
101
- `T`[]
67
+ `T` *extends* `undefined` ? `undefined` : `T`[]
102
68
 
103
69
  The array.