@reforgium/internal 1.3.0 → 2.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.
- package/LICENSE +21 -0
- package/README.md +88 -3
- package/fesm2022/reforgium-internal.mjs +486 -19
- package/package.json +11 -12
- package/types/reforgium-internal.d.ts +242 -229
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rtommievich
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -5,8 +5,28 @@
|
|
|
5
5
|
|
|
6
6
|
Shared infrastructure package for Reforgium Angular libraries.
|
|
7
7
|
|
|
8
|
+
`internal` is being tightened into a foundation layer. The target boundary is documented in
|
|
9
|
+
[INTERNAL_V2.md](./INTERNAL_V2.md).
|
|
10
|
+
|
|
11
|
+
The first classification pass is documented in
|
|
12
|
+
[INTERNAL_V2_AUDIT.md](./INTERNAL_V2_AUDIT.md).
|
|
13
|
+
|
|
14
|
+
The file-by-file pass is documented in
|
|
15
|
+
[INTERNAL_V2_FILE_AUDIT.md](./INTERNAL_V2_FILE_AUDIT.md).
|
|
16
|
+
|
|
17
|
+
Short version:
|
|
18
|
+
|
|
19
|
+
- foundation primitives belong here
|
|
20
|
+
- feature semantics do not
|
|
21
|
+
- legacy compatibility for `angular-common-kit` does not
|
|
22
|
+
|
|
23
|
+
`@reforgium/internal` is infrastructure for Reforgium packages and is not intended as a user-facing product package.
|
|
24
|
+
|
|
8
25
|
## Install
|
|
9
26
|
|
|
27
|
+
`internal` is primarily consumed transitively by other `@reforgium/*` packages.
|
|
28
|
+
Direct installation is possible for workspace and low-level internal use, but it is not the recommended first entrypoint for app code.
|
|
29
|
+
|
|
10
30
|
```bash
|
|
11
31
|
npm i @reforgium/internal
|
|
12
32
|
```
|
|
@@ -16,6 +36,8 @@ npm i @reforgium/internal
|
|
|
16
36
|
`@reforgium/internal` exports:
|
|
17
37
|
|
|
18
38
|
- `models`
|
|
39
|
+
- `codecs`
|
|
40
|
+
- `storage`
|
|
19
41
|
- `tokens`
|
|
20
42
|
- `utils`
|
|
21
43
|
|
|
@@ -23,11 +45,40 @@ npm i @reforgium/internal
|
|
|
23
45
|
|
|
24
46
|
Main model groups:
|
|
25
47
|
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
48
|
+
- `query.models.ts`: `SortToken`, `SortDirection`, `SortRule`, `SortInput`, `QueryArrayMode`, `QueryFieldModes`, `QueryParams`, `Query`
|
|
49
|
+
- `transport.models.ts`: `RestMethods`, `PageableRequest`, `PageableResponse<T>`, `ErrorResponse`
|
|
28
50
|
- `elements.ts`: `Direction`, `ElementRect`, `ElementSize`, `ElementPosition`, `ElementEdges`
|
|
29
51
|
- `util.ts`: `AnyType`, `AnyDict`, `LiteralOf`, `ValueOf`, `Nullable`, `Nullish`, `NullableProps`, `OptionalExcept`, `RequiredExcept`, `Mutable`, JSON helper types
|
|
30
52
|
|
|
53
|
+
Compatibility-only model surface:
|
|
54
|
+
|
|
55
|
+
- `components.ts`: `Appearance`, `SelectOption`, `SelectIconOption`
|
|
56
|
+
- `api.ts`: deprecated mixed facade kept for compatibility; prefer explicit query and transport types
|
|
57
|
+
|
|
58
|
+
### Codecs
|
|
59
|
+
|
|
60
|
+
Main codec exports:
|
|
61
|
+
|
|
62
|
+
- `Serializer`
|
|
63
|
+
- `SerializerFieldError`
|
|
64
|
+
- `SerializerConfig`
|
|
65
|
+
- `FieldConfig`
|
|
66
|
+
- `SerializedType`
|
|
67
|
+
|
|
68
|
+
These are shared bidirectional transform primitives used by `statum` and `regula`.
|
|
69
|
+
|
|
70
|
+
### Storage
|
|
71
|
+
|
|
72
|
+
Main storage exports:
|
|
73
|
+
|
|
74
|
+
- `StorageInterface`
|
|
75
|
+
- `StorageStrategy`, `StorageStrategyOptions`
|
|
76
|
+
- `MemoryStorage`
|
|
77
|
+
- `LocalStorage`
|
|
78
|
+
- `SessionStorage`
|
|
79
|
+
- `LruCache`
|
|
80
|
+
- `storageStrategy(...)`
|
|
81
|
+
|
|
31
82
|
### Tokens
|
|
32
83
|
|
|
33
84
|
Language tokens:
|
|
@@ -44,7 +95,8 @@ Theme/device/validation tokens:
|
|
|
44
95
|
|
|
45
96
|
- `SELECTED_THEME`, `CHANGE_THEME`, `Themes`
|
|
46
97
|
- `CURRENT_DEVICE`, `Devices`
|
|
47
|
-
- `VALIDATION_MESSAGES`, `ValidationMessages`, `ValidationErrorData
|
|
98
|
+
- `VALIDATION_MESSAGES`, `ValidationMessages`, `ValidationErrorData`:
|
|
99
|
+
compatibility-only legacy validation token surface
|
|
48
100
|
|
|
49
101
|
Example:
|
|
50
102
|
|
|
@@ -134,6 +186,39 @@ makeQuery({ ids: [1, 2, 3], q: 'ok' }, 'multi');
|
|
|
134
186
|
// ids=1&ids=2&ids=3&q=ok
|
|
135
187
|
```
|
|
136
188
|
|
|
189
|
+
`storage` example:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { LruCache, storageStrategy } from '@reforgium/internal';
|
|
193
|
+
|
|
194
|
+
const pages = new LruCache<number, string[]>(5);
|
|
195
|
+
pages.set(1, ['a', 'b']);
|
|
196
|
+
|
|
197
|
+
const persisted = storageStrategy<string, { updatedAt: number }>('persist');
|
|
198
|
+
persisted.set('users', { updatedAt: Date.now() });
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
`codecs` example:
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { Serializer } from '@reforgium/internal';
|
|
205
|
+
|
|
206
|
+
const serializer = new Serializer<{
|
|
207
|
+
search: string;
|
|
208
|
+
createdAt: Date;
|
|
209
|
+
}>({
|
|
210
|
+
mapFields: {
|
|
211
|
+
createdAt: { type: 'date' },
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
serializer.serialize({
|
|
216
|
+
search: ' regula ',
|
|
217
|
+
createdAt: new Date('2026-04-04'),
|
|
218
|
+
});
|
|
219
|
+
// { search: 'regula', createdAt: '2026-04-04' }
|
|
220
|
+
```
|
|
221
|
+
|
|
137
222
|
## License
|
|
138
223
|
|
|
139
224
|
MIT
|
|
@@ -1,5 +1,179 @@
|
|
|
1
1
|
import { InjectionToken, makeEnvironmentProviders, signal, effect, untracked } from '@angular/core';
|
|
2
2
|
|
|
3
|
+
class LocalStorage {
|
|
4
|
+
prefix;
|
|
5
|
+
constructor(prefix = 're') {
|
|
6
|
+
this.prefix = prefix;
|
|
7
|
+
}
|
|
8
|
+
get length() {
|
|
9
|
+
return Object.keys(localStorage).filter((key) => key.startsWith(this.safePrefix())).length;
|
|
10
|
+
}
|
|
11
|
+
get(key) {
|
|
12
|
+
const storageKey = this.getSafePrefix(key);
|
|
13
|
+
const raw = localStorage.getItem(storageKey);
|
|
14
|
+
if (raw == null) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(raw);
|
|
19
|
+
return parsed ?? null;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
localStorage.removeItem(storageKey);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
set(key, value) {
|
|
27
|
+
localStorage.setItem(this.getSafePrefix(key), JSON.stringify(value));
|
|
28
|
+
}
|
|
29
|
+
remove(key) {
|
|
30
|
+
localStorage.removeItem(this.getSafePrefix(key));
|
|
31
|
+
}
|
|
32
|
+
clear() {
|
|
33
|
+
const keys = Object.keys(localStorage).filter((key) => key.startsWith(this.safePrefix()));
|
|
34
|
+
keys.forEach((key) => localStorage.removeItem(key));
|
|
35
|
+
}
|
|
36
|
+
getSafePrefix(key) {
|
|
37
|
+
return this.prefix ? `${this.prefix}:${key}` : String(key);
|
|
38
|
+
}
|
|
39
|
+
safePrefix() {
|
|
40
|
+
return this.prefix ? `${this.prefix}:` : '';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
class LruCache {
|
|
45
|
+
map = new Map();
|
|
46
|
+
_limit = 100;
|
|
47
|
+
constructor(limit = 100) {
|
|
48
|
+
this.limit = limit;
|
|
49
|
+
}
|
|
50
|
+
get limit() {
|
|
51
|
+
return this._limit;
|
|
52
|
+
}
|
|
53
|
+
get length() {
|
|
54
|
+
return this.map.size;
|
|
55
|
+
}
|
|
56
|
+
set limit(value) {
|
|
57
|
+
this._limit = Math.max(1, Math.floor(value || 0));
|
|
58
|
+
}
|
|
59
|
+
get(key) {
|
|
60
|
+
if (!this.map.has(key)) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const val = this.map.get(key);
|
|
64
|
+
this.map.delete(key);
|
|
65
|
+
this.map.set(key, val);
|
|
66
|
+
return val;
|
|
67
|
+
}
|
|
68
|
+
set(key, value) {
|
|
69
|
+
if (this.map.has(key)) {
|
|
70
|
+
this.map.delete(key);
|
|
71
|
+
}
|
|
72
|
+
else if (this.map.size >= this.limit) {
|
|
73
|
+
const oldest = this.map.keys().next().value;
|
|
74
|
+
oldest !== undefined && this.map.delete(oldest);
|
|
75
|
+
}
|
|
76
|
+
this.map.set(key, value);
|
|
77
|
+
}
|
|
78
|
+
remove(key) {
|
|
79
|
+
return this.map.delete(key);
|
|
80
|
+
}
|
|
81
|
+
clear() {
|
|
82
|
+
this.map.clear();
|
|
83
|
+
}
|
|
84
|
+
has(key) {
|
|
85
|
+
return this.map.has(key);
|
|
86
|
+
}
|
|
87
|
+
keys() {
|
|
88
|
+
return Array.from(this.map.keys());
|
|
89
|
+
}
|
|
90
|
+
values() {
|
|
91
|
+
return Array.from(this.map.values());
|
|
92
|
+
}
|
|
93
|
+
entries() {
|
|
94
|
+
return Array.from(this.map.entries());
|
|
95
|
+
}
|
|
96
|
+
toArray() {
|
|
97
|
+
return Array.from(this.map.values());
|
|
98
|
+
}
|
|
99
|
+
fromArray(entries) {
|
|
100
|
+
this.map.clear();
|
|
101
|
+
for (const [k, v] of entries) {
|
|
102
|
+
this.set(k, v);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
class MemoryStorage {
|
|
108
|
+
cache = new Map();
|
|
109
|
+
get length() {
|
|
110
|
+
return this.cache.size;
|
|
111
|
+
}
|
|
112
|
+
get(key) {
|
|
113
|
+
return this.cache.get(key) ?? null;
|
|
114
|
+
}
|
|
115
|
+
set(key, value) {
|
|
116
|
+
this.cache.set(key, value);
|
|
117
|
+
}
|
|
118
|
+
remove(key) {
|
|
119
|
+
this.cache.delete(key);
|
|
120
|
+
}
|
|
121
|
+
clear() {
|
|
122
|
+
this.cache.clear();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
class SessionStorage {
|
|
127
|
+
prefix;
|
|
128
|
+
constructor(prefix = 're') {
|
|
129
|
+
this.prefix = prefix;
|
|
130
|
+
}
|
|
131
|
+
get length() {
|
|
132
|
+
return Object.keys(sessionStorage).filter((key) => key.startsWith(this.safePrefix())).length;
|
|
133
|
+
}
|
|
134
|
+
get(key) {
|
|
135
|
+
const storageKey = this.getSafePrefix(key);
|
|
136
|
+
const raw = sessionStorage.getItem(storageKey);
|
|
137
|
+
if (raw == null) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const parsed = JSON.parse(raw);
|
|
142
|
+
return parsed ?? null;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
sessionStorage.removeItem(storageKey);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
set(key, value) {
|
|
150
|
+
sessionStorage.setItem(this.getSafePrefix(key), JSON.stringify(value));
|
|
151
|
+
}
|
|
152
|
+
remove(key) {
|
|
153
|
+
sessionStorage.removeItem(this.getSafePrefix(key));
|
|
154
|
+
}
|
|
155
|
+
clear() {
|
|
156
|
+
const keys = Object.keys(sessionStorage).filter((key) => key.startsWith(this.safePrefix()));
|
|
157
|
+
keys.forEach((key) => sessionStorage.removeItem(key));
|
|
158
|
+
}
|
|
159
|
+
getSafePrefix(key) {
|
|
160
|
+
return this.prefix ? `${this.prefix}:${key}` : String(key);
|
|
161
|
+
}
|
|
162
|
+
safePrefix() {
|
|
163
|
+
return this.prefix ? `${this.prefix}:` : '';
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const storageStrategy = (strategy, options = {}) => {
|
|
168
|
+
const fabrics = {
|
|
169
|
+
memory: () => new MemoryStorage(),
|
|
170
|
+
session: () => new SessionStorage(),
|
|
171
|
+
persist: () => new LocalStorage(),
|
|
172
|
+
lru: () => new LruCache(options.lruLimit ?? 100),
|
|
173
|
+
};
|
|
174
|
+
return fabrics[strategy]();
|
|
175
|
+
};
|
|
176
|
+
|
|
3
177
|
/**
|
|
4
178
|
* Built-in languages always available in the registry.
|
|
5
179
|
*/
|
|
@@ -73,27 +247,18 @@ const CHANGE_THEME = new InjectionToken('RE_CHANGE_THEME');
|
|
|
73
247
|
const CURRENT_DEVICE = new InjectionToken('RE_CURRENT_DEVICE');
|
|
74
248
|
|
|
75
249
|
/**
|
|
76
|
-
*
|
|
77
|
-
* Can be overridden in feature modules to provide custom validation messages.
|
|
78
|
-
* Defaults to an empty object when not provided.
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* // In a feature module:
|
|
82
|
-
* providers: [
|
|
83
|
-
* {
|
|
84
|
-
* provide: VALIDATION_MESSAGES,
|
|
85
|
-
* useValue: {
|
|
86
|
-
* required: () => 'This field is required',
|
|
87
|
-
* minlength: (error) => `Min length: ${error.requiredLength}`
|
|
88
|
-
* }
|
|
89
|
-
* }
|
|
90
|
-
* ]
|
|
250
|
+
* Legacy validation messages token.
|
|
91
251
|
*/
|
|
92
252
|
const VALIDATION_MESSAGES = new InjectionToken('RE_VALIDATION_MESSAGES', {
|
|
93
253
|
providedIn: 'root',
|
|
94
254
|
factory: () => ({}),
|
|
95
255
|
});
|
|
96
256
|
|
|
257
|
+
/**
|
|
258
|
+
* @deprecated Legacy validation token surface is being isolated from the `internal v2`
|
|
259
|
+
* foundation boundary. Do not add new consumers here.
|
|
260
|
+
*/
|
|
261
|
+
|
|
97
262
|
/**
|
|
98
263
|
* Browser-only helper that downloads a file from a Blob object and prompts the user to save it.
|
|
99
264
|
*
|
|
@@ -207,7 +372,7 @@ function base64ToBlob(base64, mimeType = '') {
|
|
|
207
372
|
* ```
|
|
208
373
|
*/
|
|
209
374
|
const debounceSignal = (src, ms = 150, opts) => {
|
|
210
|
-
const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : []));
|
|
375
|
+
const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : /* istanbul ignore next */ []));
|
|
211
376
|
let timeoutRef;
|
|
212
377
|
effect((onCleanup) => {
|
|
213
378
|
const v = src();
|
|
@@ -246,7 +411,7 @@ const debounceSignal = (src, ms = 150, opts) => {
|
|
|
246
411
|
* ```
|
|
247
412
|
*/
|
|
248
413
|
const throttleSignal = (src, ms = 100, opts) => {
|
|
249
|
-
const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : []));
|
|
414
|
+
const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : /* istanbul ignore next */ []));
|
|
250
415
|
let last = 0;
|
|
251
416
|
let queued;
|
|
252
417
|
let timeoutRef;
|
|
@@ -305,6 +470,9 @@ const pad = (n) => n.toString().padStart(2, '0');
|
|
|
305
470
|
* @returns {string} Formatted date string. Returns an empty string if the input date is invalid.
|
|
306
471
|
*/
|
|
307
472
|
const formatDate = (date, format = 'yyyy-MM-dd') => {
|
|
473
|
+
if (!date) {
|
|
474
|
+
return '';
|
|
475
|
+
}
|
|
308
476
|
if (isNaN(date['getTime']?.())) {
|
|
309
477
|
return '';
|
|
310
478
|
}
|
|
@@ -565,7 +733,7 @@ const concatArray = (value, mode, key) => {
|
|
|
565
733
|
* if the input is invalid.
|
|
566
734
|
*/
|
|
567
735
|
function formatToSpacedNumber(num) {
|
|
568
|
-
const stringed = String(num).
|
|
736
|
+
const stringed = String(num).replace(/ /g, '');
|
|
569
737
|
if (num === null || num === undefined || Number.isNaN(+stringed)) {
|
|
570
738
|
return '';
|
|
571
739
|
}
|
|
@@ -1111,9 +1279,308 @@ const generateId = (limit = 15, radix = 36) => Math.random()
|
|
|
1111
1279
|
.toString(radix)
|
|
1112
1280
|
.substring(2, limit + 2);
|
|
1113
1281
|
|
|
1282
|
+
const serializeString = (config, value) => config.mapString.format?.(value) ?? (config.mapString.trim ? value.trim() : value);
|
|
1283
|
+
const serializeNumber = (config, value) => config.mapNumber.format?.(value) ?? Number(value);
|
|
1284
|
+
const serializeBoolean = (config, value) => config.mapBoolean.format?.(value) ?? (value ? (config.mapBoolean.true ?? true) : (config.mapBoolean.false ?? false));
|
|
1285
|
+
const serializeDate = (config, value) => config.mapDate.format?.(value) ?? formatDate(value, config.mapDate.dateFormat);
|
|
1286
|
+
|
|
1287
|
+
const getTypedField = (field) => {
|
|
1288
|
+
return field && 'type' in field ? field : undefined;
|
|
1289
|
+
};
|
|
1290
|
+
class SerializerFieldError extends Error {
|
|
1291
|
+
field;
|
|
1292
|
+
stage;
|
|
1293
|
+
originalError;
|
|
1294
|
+
constructor(field, stage, originalError) {
|
|
1295
|
+
const originalMessage = originalError instanceof Error ? originalError.message : String(originalError);
|
|
1296
|
+
super(`Serializer ${stage} error for field "${field}": ${originalMessage}`);
|
|
1297
|
+
this.field = field;
|
|
1298
|
+
this.stage = stage;
|
|
1299
|
+
this.originalError = originalError;
|
|
1300
|
+
this.name = 'SerializerFieldError';
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
class Serializer {
|
|
1304
|
+
config;
|
|
1305
|
+
constructor(config = {}) {
|
|
1306
|
+
this.config = this.mergeConfig({
|
|
1307
|
+
mapString: { trim: true },
|
|
1308
|
+
mapNumber: { fromString: false },
|
|
1309
|
+
mapBoolean: {},
|
|
1310
|
+
mapArray: { concatType: 'comma' },
|
|
1311
|
+
mapObject: { deep: true },
|
|
1312
|
+
mapDate: { dateFormat: 'yyyy-MM-dd' },
|
|
1313
|
+
mapPeriod: {
|
|
1314
|
+
dateFormat: 'yyyy-MM-dd',
|
|
1315
|
+
transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' },
|
|
1316
|
+
},
|
|
1317
|
+
mapNullable: { remove: true, includeEmptyString: false },
|
|
1318
|
+
}, config);
|
|
1319
|
+
}
|
|
1320
|
+
serialize(obj, _seen = new WeakSet()) {
|
|
1321
|
+
const result = {};
|
|
1322
|
+
if (obj != null && typeof obj === 'object') {
|
|
1323
|
+
_seen.add(obj);
|
|
1324
|
+
}
|
|
1325
|
+
for (const [key, value] of Object.entries(obj ?? {})) {
|
|
1326
|
+
const fields = this.config.mapFields?.[key];
|
|
1327
|
+
const typedField = getTypedField(fields);
|
|
1328
|
+
if (fields && 'format' in fields) {
|
|
1329
|
+
try {
|
|
1330
|
+
result[key] = fields.format(value, obj);
|
|
1331
|
+
}
|
|
1332
|
+
catch (error) {
|
|
1333
|
+
throw new SerializerFieldError(key, 'format', error);
|
|
1334
|
+
}
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
if (typedField?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {
|
|
1338
|
+
if (this.config.mapNullable.remove) {
|
|
1339
|
+
continue;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
if (typedField?.type === 'period' || isDatePeriod(value)) {
|
|
1343
|
+
const transform = this.config.mapPeriod.transformMode;
|
|
1344
|
+
const [from, to] = value;
|
|
1345
|
+
if (transform?.mode === 'split') {
|
|
1346
|
+
result[`${key}${transform.dateFromKeyPostfix}`] = formatDate(from, this.config.mapPeriod.dateFormat);
|
|
1347
|
+
result[`${key}${transform.dateToKeyPostfix}`] = formatDate(to, this.config.mapPeriod.dateFormat);
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
result[key] = this.serializeElement(value, key, _seen);
|
|
1352
|
+
}
|
|
1353
|
+
if (obj != null && typeof obj === 'object') {
|
|
1354
|
+
_seen.delete(obj);
|
|
1355
|
+
}
|
|
1356
|
+
return result;
|
|
1357
|
+
}
|
|
1358
|
+
deserialize = (val) => {
|
|
1359
|
+
const data = typeof val === 'string' ? this.parseInputString(val) : val;
|
|
1360
|
+
const result = {};
|
|
1361
|
+
for (const [key, value] of Object.entries(data ?? {})) {
|
|
1362
|
+
const field = this.config.mapFields?.[key];
|
|
1363
|
+
const typedField = getTypedField(field);
|
|
1364
|
+
if (field && 'parse' in field) {
|
|
1365
|
+
try {
|
|
1366
|
+
result[key] = field.parse(value, data);
|
|
1367
|
+
}
|
|
1368
|
+
catch (error) {
|
|
1369
|
+
throw new SerializerFieldError(key, 'parse', error);
|
|
1370
|
+
}
|
|
1371
|
+
continue;
|
|
1372
|
+
}
|
|
1373
|
+
if (typedField?.type === 'nullable' ||
|
|
1374
|
+
(typedField?.type !== 'array' && isNullable(value, this.config.mapNullable?.includeEmptyString))) {
|
|
1375
|
+
if (this.config.mapNullable.remove) {
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
const periodTransform = this.config.mapPeriod.transformMode;
|
|
1380
|
+
if (periodTransform.mode === 'split') {
|
|
1381
|
+
const isFrom = (key || '').endsWith(periodTransform.dateFromKeyPostfix);
|
|
1382
|
+
const isTo = (key || '').endsWith(periodTransform.dateToKeyPostfix);
|
|
1383
|
+
const keyJoint = (key || '')
|
|
1384
|
+
.replace(periodTransform.dateFromKeyPostfix, '')
|
|
1385
|
+
.replace(periodTransform.dateToKeyPostfix, '');
|
|
1386
|
+
const jointField = this.config.mapFields?.[keyJoint];
|
|
1387
|
+
const fieldType = jointField && 'type' in jointField ? jointField.type : undefined;
|
|
1388
|
+
if (fieldType === 'period' && (isFrom || isTo)) {
|
|
1389
|
+
result[keyJoint] ??= [null, null];
|
|
1390
|
+
if (isFrom) {
|
|
1391
|
+
result[keyJoint][0] = parseToDate(value, this.config.mapPeriod.dateFormat);
|
|
1392
|
+
}
|
|
1393
|
+
else if (isTo) {
|
|
1394
|
+
result[keyJoint][1] = parseToDate(value, this.config.mapPeriod.dateFormat);
|
|
1395
|
+
}
|
|
1396
|
+
continue;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
result[key] = this.deserializeElement(value, key);
|
|
1400
|
+
}
|
|
1401
|
+
return result;
|
|
1402
|
+
};
|
|
1403
|
+
deserializeQuery = (query) => {
|
|
1404
|
+
return this.deserialize(this.parseQuery(query));
|
|
1405
|
+
};
|
|
1406
|
+
deserializeJson = (json) => {
|
|
1407
|
+
return this.deserialize(this.parseJsonObject(json));
|
|
1408
|
+
};
|
|
1409
|
+
toQuery = (val) => {
|
|
1410
|
+
return buildQueryParams(this.serialize(val), this.config.mapArray.concatType, this.resolveArrayFieldModes());
|
|
1411
|
+
};
|
|
1412
|
+
withConfig(config) {
|
|
1413
|
+
return new Serializer(this.mergeConfig(this.config, config));
|
|
1414
|
+
}
|
|
1415
|
+
serializeElement(value, key, _seen = new WeakSet()) {
|
|
1416
|
+
const fields = this.config.mapFields?.[key || ''];
|
|
1417
|
+
const typedField = getTypedField(fields);
|
|
1418
|
+
if (fields && 'format' in fields) {
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
if (typedField?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {
|
|
1422
|
+
const nullableVal = value ?? null;
|
|
1423
|
+
return this.config.mapNullable.format?.(nullableVal) || this.config.mapNullable.replaceWith || nullableVal;
|
|
1424
|
+
}
|
|
1425
|
+
if (typedField?.type === 'string') {
|
|
1426
|
+
return serializeString(this.config, value);
|
|
1427
|
+
}
|
|
1428
|
+
if (typedField?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {
|
|
1429
|
+
return serializeNumber(this.config, value);
|
|
1430
|
+
}
|
|
1431
|
+
if (typeof value === 'string') {
|
|
1432
|
+
return serializeString(this.config, value);
|
|
1433
|
+
}
|
|
1434
|
+
if (typedField?.type === 'boolean' || typeof value === 'boolean') {
|
|
1435
|
+
return serializeBoolean(this.config, value);
|
|
1436
|
+
}
|
|
1437
|
+
if (typedField?.type === 'date' || value instanceof Date) {
|
|
1438
|
+
return serializeDate(this.config, value);
|
|
1439
|
+
}
|
|
1440
|
+
if (typedField?.type === 'period' || isDatePeriod(value)) {
|
|
1441
|
+
const mapPeriod = this.config.mapPeriod;
|
|
1442
|
+
if (mapPeriod.format) {
|
|
1443
|
+
return mapPeriod.format(value);
|
|
1444
|
+
}
|
|
1445
|
+
const [from, to] = value;
|
|
1446
|
+
const transform = mapPeriod.transformMode;
|
|
1447
|
+
if (transform.mode === 'join') {
|
|
1448
|
+
const period = [
|
|
1449
|
+
formatDate(from, this.config.mapPeriod.dateFormat),
|
|
1450
|
+
formatDate(to, this.config.mapPeriod.dateFormat),
|
|
1451
|
+
];
|
|
1452
|
+
return period.join(transform.concat);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
if (typedField?.type === 'array' || Array.isArray(value)) {
|
|
1456
|
+
return value.map((it) => this.serializeElement(it, undefined, _seen));
|
|
1457
|
+
}
|
|
1458
|
+
if (typedField?.type === 'object' || isObject(value)) {
|
|
1459
|
+
if (this.config.mapObject.deep && !this.config.mapObject.format && value != null && _seen.has(value)) {
|
|
1460
|
+
return undefined;
|
|
1461
|
+
}
|
|
1462
|
+
return (this.config.mapObject.format?.(value) ??
|
|
1463
|
+
(this.config.mapObject.deep ? this.serialize(value, _seen) : JSON.stringify(value)));
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
deserializeElement(value, key) {
|
|
1467
|
+
const field = this.config.mapFields?.[key || ''];
|
|
1468
|
+
const typedField = getTypedField(field);
|
|
1469
|
+
if (field && 'format' in field) {
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
if (typedField?.type === 'array' || Array.isArray(value)) {
|
|
1473
|
+
const array = Array.isArray(value) ? value : [value];
|
|
1474
|
+
if (this.config.mapArray.removeNullable) {
|
|
1475
|
+
if (!isNullable(value, this.config.mapNullable?.includeEmptyString)) {
|
|
1476
|
+
return array.map((it) => this.deserializeElement(it));
|
|
1477
|
+
}
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
return !value ? [] : array.map((it) => this.deserializeElement(it));
|
|
1481
|
+
}
|
|
1482
|
+
if (typedField?.type === 'object') {
|
|
1483
|
+
try {
|
|
1484
|
+
if (this.config.mapObject.deep) {
|
|
1485
|
+
return isObject(value) ? this.deserialize(value) : value;
|
|
1486
|
+
}
|
|
1487
|
+
return typeof value === 'string' ? JSON.parse(value) : value;
|
|
1488
|
+
}
|
|
1489
|
+
catch {
|
|
1490
|
+
return value;
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
if (typedField?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {
|
|
1494
|
+
return this.config.mapNullable.parse?.(value) || value;
|
|
1495
|
+
}
|
|
1496
|
+
if (typedField?.type === 'boolean' ||
|
|
1497
|
+
typeof value === 'boolean' ||
|
|
1498
|
+
value === this.config.mapBoolean.true ||
|
|
1499
|
+
value === this.config.mapBoolean.false) {
|
|
1500
|
+
return this.config.mapBoolean.parse?.(value) ?? (value === this.config.mapBoolean.true || value === true);
|
|
1501
|
+
}
|
|
1502
|
+
const maybeDate = parseToDate(value, this.config.mapDate.dateFormat);
|
|
1503
|
+
if (typedField?.type === 'date' || maybeDate) {
|
|
1504
|
+
return this.config.mapDate.parse?.(value) || maybeDate;
|
|
1505
|
+
}
|
|
1506
|
+
const periodTransform = this.config.mapPeriod.transformMode;
|
|
1507
|
+
if (periodTransform.mode === 'join') {
|
|
1508
|
+
const maybePeriod = parseToDatePeriod(value, this.config.mapPeriod.dateFormat);
|
|
1509
|
+
if (typedField?.type === 'period' || (maybePeriod || []).some(Boolean)) {
|
|
1510
|
+
return this.config.mapPeriod.parse?.(value) || maybePeriod;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
if (typedField?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {
|
|
1514
|
+
return this.config.mapNumber.parse?.(value) || Number(String(value).trim());
|
|
1515
|
+
}
|
|
1516
|
+
if (typedField?.type === 'string' || typeof value === 'string') {
|
|
1517
|
+
const parsed = this.config.mapString.parse?.(value);
|
|
1518
|
+
if (parsed !== undefined) {
|
|
1519
|
+
return parsed;
|
|
1520
|
+
}
|
|
1521
|
+
return this.config.mapString.trim ? String(value).trim() : value;
|
|
1522
|
+
}
|
|
1523
|
+
return value;
|
|
1524
|
+
}
|
|
1525
|
+
parseQuery(val) {
|
|
1526
|
+
return parseQueryParamsByMode(val, undefined, this.resolveArrayFieldModes());
|
|
1527
|
+
}
|
|
1528
|
+
parseJsonObject(val) {
|
|
1529
|
+
try {
|
|
1530
|
+
const parsed = JSON.parse(val);
|
|
1531
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
1532
|
+
return parsed;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
catch (error) {
|
|
1536
|
+
throw new Error(`Invalid JSON input: ${error instanceof Error ? error.message : String(error)}`);
|
|
1537
|
+
}
|
|
1538
|
+
throw new Error('Invalid JSON input: expected a JSON object');
|
|
1539
|
+
}
|
|
1540
|
+
parseInputString(val) {
|
|
1541
|
+
try {
|
|
1542
|
+
return this.parseJsonObject(val);
|
|
1543
|
+
}
|
|
1544
|
+
catch {
|
|
1545
|
+
return this.parseQuery(val);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
mergeConfig(base, override) {
|
|
1549
|
+
return {
|
|
1550
|
+
...base,
|
|
1551
|
+
...override,
|
|
1552
|
+
mapString: { ...base.mapString, ...override.mapString },
|
|
1553
|
+
mapNumber: { ...base.mapNumber, ...override.mapNumber },
|
|
1554
|
+
mapBoolean: { ...base.mapBoolean, ...override.mapBoolean },
|
|
1555
|
+
mapDate: { ...base.mapDate, ...override.mapDate },
|
|
1556
|
+
mapPeriod: {
|
|
1557
|
+
...base.mapPeriod,
|
|
1558
|
+
...override.mapPeriod,
|
|
1559
|
+
transformMode: {
|
|
1560
|
+
...base.mapPeriod.transformMode,
|
|
1561
|
+
...override.mapPeriod?.transformMode,
|
|
1562
|
+
},
|
|
1563
|
+
},
|
|
1564
|
+
mapNullable: { ...base.mapNullable, ...override.mapNullable },
|
|
1565
|
+
mapArray: { ...base.mapArray, ...override.mapArray },
|
|
1566
|
+
mapObject: { ...base.mapObject, ...override.mapObject },
|
|
1567
|
+
mapFields: { ...(base.mapFields || {}), ...(override.mapFields || {}) },
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
resolveArrayFieldModes() {
|
|
1571
|
+
const result = {};
|
|
1572
|
+
Object.entries(this.config.mapFields || {}).forEach(([key, field]) => {
|
|
1573
|
+
if ('type' in field && field.type === 'array') {
|
|
1574
|
+
result[key] = field.concatType ?? this.config.mapArray.concatType;
|
|
1575
|
+
}
|
|
1576
|
+
});
|
|
1577
|
+
return result;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1114
1581
|
/**
|
|
1115
1582
|
* Generated bundle index. Do not edit.
|
|
1116
1583
|
*/
|
|
1117
1584
|
|
|
1118
|
-
export { BUILTIN_LANGS, CHANGE_LANG, CHANGE_THEME, CURRENT_DEVICE, REGISTER_LANG, SELECTED_LANG, SELECTED_THEME, TRANSLATION, VALIDATION_MESSAGES, appendQueryParams, appendQueryParamsByMode, base64ToBlob, buildQueryParams, compareRoutes, concatArray, copyText, debounceSignal, deepEqual, downloadByBlob, downloadByUrl, fillUrlWithParams, formatDate, formatToLocaledDate, formatToSpacedNumber, generateId, getAvailableHeight, getChainedValue, getCorrectedPosition, isDatePeriod, isNullable, isNumber, isObject, makeQuery, materializeRoutePath, mergeQueryParams, normalizeSortInput, normalizeUrl, parseQueryArray, parseQueryParams, parseQueryParamsByMode, parseSortToken, parseToDate, parseToDatePeriod, provideLangs, reformatDateToISO, sortInputToTokens, sortRuleToToken, throttleSignal, toDate, toSortToken, truncate };
|
|
1585
|
+
export { BUILTIN_LANGS, CHANGE_LANG, CHANGE_THEME, CURRENT_DEVICE, LocalStorage, LruCache, MemoryStorage, REGISTER_LANG, SELECTED_LANG, SELECTED_THEME, Serializer, SerializerFieldError, SessionStorage, TRANSLATION, VALIDATION_MESSAGES, appendQueryParams, appendQueryParamsByMode, base64ToBlob, buildQueryParams, compareRoutes, concatArray, copyText, debounceSignal, deepEqual, downloadByBlob, downloadByUrl, fillUrlWithParams, formatDate, formatToLocaledDate, formatToSpacedNumber, generateId, getAvailableHeight, getChainedValue, getCorrectedPosition, isDatePeriod, isNullable, isNumber, isObject, makeQuery, materializeRoutePath, mergeQueryParams, normalizeSortInput, normalizeUrl, parseQueryArray, parseQueryParams, parseQueryParamsByMode, parseSortToken, parseToDate, parseToDatePeriod, provideLangs, reformatDateToISO, sortInputToTokens, sortRuleToToken, storageStrategy, throttleSignal, toDate, toSortToken, truncate };
|
|
1119
1586
|
//# sourceMappingURL=reforgium-internal.mjs.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "2.0.2",
|
|
3
3
|
"name": "@reforgium/internal",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Hidden Reforgium foundation package for shared primitives, tokens, and infrastructure.",
|
|
5
5
|
"author": "rtommievich",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -21,12 +21,11 @@
|
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"reforgium",
|
|
24
|
-
"common",
|
|
25
24
|
"internal",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
25
|
+
"foundation",
|
|
26
|
+
"infrastructure"
|
|
28
27
|
],
|
|
29
|
-
"types": "
|
|
28
|
+
"types": "./src/public-api.ts",
|
|
30
29
|
"typings": "types/reforgium-internal.d.ts",
|
|
31
30
|
"module": "fesm2022/reforgium-internal.mjs",
|
|
32
31
|
"files": [
|
|
@@ -37,12 +36,6 @@
|
|
|
37
36
|
"CHANGELOG.md",
|
|
38
37
|
"LICENSE*"
|
|
39
38
|
],
|
|
40
|
-
"dependencies": {
|
|
41
|
-
"tslib": "^2.8.1"
|
|
42
|
-
},
|
|
43
|
-
"peerDependencies": {
|
|
44
|
-
"@angular/core": ">=19.0.0"
|
|
45
|
-
},
|
|
46
39
|
"exports": {
|
|
47
40
|
"./package.json": {
|
|
48
41
|
"default": "./package.json"
|
|
@@ -51,5 +44,11 @@
|
|
|
51
44
|
"types": "./types/reforgium-internal.d.ts",
|
|
52
45
|
"default": "./fesm2022/reforgium-internal.mjs"
|
|
53
46
|
}
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"tslib": "^2.8.1"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@angular/core": ">=19.0.0"
|
|
54
53
|
}
|
|
55
54
|
}
|
|
@@ -1,64 +1,29 @@
|
|
|
1
1
|
import { EnvironmentProviders, InjectionToken, Signal, Injector } from '@angular/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Used for buttons, icons, notifications, etc.
|
|
4
|
+
* Legacy UI-facing appearance semantics.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Possible values:
|
|
10
|
-
* - `primary` - main accent color
|
|
11
|
-
* - `success` - successful action completion
|
|
12
|
-
* - `warning` - warning
|
|
13
|
-
* - `error` - error
|
|
14
|
-
* - `info` - informational message
|
|
15
|
-
* - `light` - light theme
|
|
16
|
-
* - `gray` - gray/neutral color
|
|
17
|
-
* - `inherit` - inherit color from parent
|
|
6
|
+
* This model remains only for compatibility with legacy consumers.
|
|
7
|
+
* It is not part of the desired `internal v2` foundation boundary.
|
|
18
8
|
*/
|
|
19
9
|
type Appearance = 'primary' | 'success' | 'warning' | 'error' | 'info' | 'light' | 'gray' | 'inherit';
|
|
20
10
|
/**
|
|
21
|
-
*
|
|
22
|
-
* Universal for selecting, lists, autocompletes, and radio groups.
|
|
23
|
-
*
|
|
24
|
-
* @template ValueType - Type of the option value (string or number). Default is `string | number`.
|
|
25
|
-
*
|
|
26
|
-
* @property {string} label - Displayed label of the option for the user
|
|
27
|
-
* @property {ValueType} value - Value of the option used programmatically
|
|
11
|
+
* Legacy option model for UI selects.
|
|
28
12
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* const option: SelectOption<string> = { label: 'Option 1', value: 'option1' };
|
|
32
|
-
* const numericOption: SelectOption<number> = { label: 'First', value: 1 };
|
|
33
|
-
* ```
|
|
13
|
+
* This model remains only for compatibility with legacy consumers.
|
|
14
|
+
* It is not part of the desired `internal v2` foundation boundary.
|
|
34
15
|
*/
|
|
35
16
|
type SelectOption<ValueType extends string | number = string | number> = {
|
|
36
|
-
/** Displayed label */
|
|
37
17
|
label: string;
|
|
38
|
-
/** Value (string or number) */
|
|
39
18
|
value: ValueType;
|
|
40
19
|
};
|
|
41
20
|
/**
|
|
42
|
-
*
|
|
43
|
-
* Extends the base model {@link SelectOption} by adding an icon field.
|
|
21
|
+
* Legacy icon option model for UI selects.
|
|
44
22
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* @property {string} label - Displayed label of the option (inherited from SelectOption)
|
|
48
|
-
* @property {ValueType} value - Value of the option (inherited from SelectOption)
|
|
49
|
-
* @property {string} icon - Name of the icon to display next to the option (read-only)
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```typescript
|
|
53
|
-
* const iconOption: SelectIconOption<string> = {
|
|
54
|
-
* label: 'Settings',
|
|
55
|
-
* value: 'settings',
|
|
56
|
-
* icon: 'settings-icon'
|
|
57
|
-
* };
|
|
58
|
-
* ```
|
|
23
|
+
* This model remains only for compatibility with legacy consumers.
|
|
24
|
+
* It is not part of the desired `internal v2` foundation boundary.
|
|
59
25
|
*/
|
|
60
26
|
type SelectIconOption<ValueType extends string | number = string | number> = SelectOption<ValueType> & {
|
|
61
|
-
/** Icon name */
|
|
62
27
|
readonly icon: string;
|
|
63
28
|
};
|
|
64
29
|
|
|
@@ -124,6 +89,75 @@ type ElementEdges = {
|
|
|
124
89
|
*/
|
|
125
90
|
type ElementRect = Readonly<Partial<ElementPosition> & ElementSize & ElementEdges>;
|
|
126
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Single sort token in format "field,direction".
|
|
94
|
+
* Used to specify sorting criteria for a single field.
|
|
95
|
+
*
|
|
96
|
+
* @template F - Field name type, defaults to string
|
|
97
|
+
*/
|
|
98
|
+
type SortToken<F extends string = string> = `${F},${'asc' | 'desc'}`;
|
|
99
|
+
type SortDirection = 'asc' | 'desc';
|
|
100
|
+
type SortRule<F extends string = string> = {
|
|
101
|
+
sort: F;
|
|
102
|
+
order: SortDirection;
|
|
103
|
+
};
|
|
104
|
+
type SortInput<F extends string = string> = SortRule<F> | ReadonlyArray<SortRule<F>> | null | undefined;
|
|
105
|
+
type QueryArrayMode = 'comma' | 'json' | 'multi';
|
|
106
|
+
type QueryFieldModes = Partial<Record<string, QueryArrayMode>>;
|
|
107
|
+
/**
|
|
108
|
+
* Common query parameters interface for API-like requests.
|
|
109
|
+
*
|
|
110
|
+
* Kept as a generic query contract rather than a transport implementation detail.
|
|
111
|
+
*/
|
|
112
|
+
interface QueryParams<Filters = unknown> {
|
|
113
|
+
page?: number;
|
|
114
|
+
size?: number;
|
|
115
|
+
sort?: SortToken | ReadonlyArray<SortToken>;
|
|
116
|
+
filters?: Partial<Filters>;
|
|
117
|
+
}
|
|
118
|
+
type QueryScalar = string | number | boolean;
|
|
119
|
+
type Query = Record<string, QueryScalar | ReadonlyArray<QueryScalar>>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Supported REST API HTTP methods.
|
|
123
|
+
*
|
|
124
|
+
* This is transport-facing and remains in `internal` only while no clearer transport
|
|
125
|
+
* contract layer exists.
|
|
126
|
+
*/
|
|
127
|
+
type RestMethods = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
128
|
+
/**
|
|
129
|
+
* Pagination request with optional multi-field sorting.
|
|
130
|
+
*
|
|
131
|
+
* This remains transport/data-domain flavored and should not define the long-term
|
|
132
|
+
* `internal v2` foundation boundary by itself.
|
|
133
|
+
*/
|
|
134
|
+
type PageableRequest = {
|
|
135
|
+
page: number;
|
|
136
|
+
size?: number;
|
|
137
|
+
sort?: string | ReadonlyArray<string>;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Paginated response structure.
|
|
141
|
+
*/
|
|
142
|
+
type PageableResponse<T> = {
|
|
143
|
+
pageable?: {
|
|
144
|
+
offset?: number;
|
|
145
|
+
pageNumber: number;
|
|
146
|
+
pageSize: number;
|
|
147
|
+
};
|
|
148
|
+
totalElements: number;
|
|
149
|
+
content: T[];
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Business-level error response structure.
|
|
153
|
+
*/
|
|
154
|
+
type ErrorResponse = {
|
|
155
|
+
errorCode: number | string;
|
|
156
|
+
message: string;
|
|
157
|
+
fields?: Record<string, string>;
|
|
158
|
+
details?: unknown;
|
|
159
|
+
};
|
|
160
|
+
|
|
127
161
|
/**
|
|
128
162
|
* Universal type "anything".
|
|
129
163
|
* Prefer to use `unknown` to avoid `any` leaks.
|
|
@@ -216,161 +250,72 @@ type JsonObject = {
|
|
|
216
250
|
[k: string]: JsonValue;
|
|
217
251
|
};
|
|
218
252
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
* Used to specify sorting criteria for a single field.
|
|
227
|
-
*
|
|
228
|
-
* @template F - Field name type, defaults to string
|
|
229
|
-
* @example
|
|
230
|
-
* ```typescript
|
|
231
|
-
* const sort: SortToken = "name,asc";
|
|
232
|
-
* const sort2: SortToken<"id" | "createdAt"> = "id,desc";
|
|
233
|
-
* ```
|
|
234
|
-
*/
|
|
235
|
-
type SortToken<F extends string = string> = `${F},${'asc' | 'desc'}`;
|
|
236
|
-
type SortDirection = 'asc' | 'desc';
|
|
237
|
-
type SortRule<F extends string = string> = {
|
|
238
|
-
sort: F;
|
|
239
|
-
order: SortDirection;
|
|
253
|
+
type StorageInterface<Key, Type = AnyType> = {
|
|
254
|
+
prefix?: string;
|
|
255
|
+
get(key: Key): Type | null;
|
|
256
|
+
set(key: Key, value: Type): void;
|
|
257
|
+
remove(key: Key): void | boolean;
|
|
258
|
+
clear(): void;
|
|
259
|
+
get length(): number;
|
|
240
260
|
};
|
|
241
|
-
type
|
|
242
|
-
type
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Pagination request with optional multi-field sorting.
|
|
246
|
-
* Used to request paginated data from API endpoints.
|
|
247
|
-
*/
|
|
248
|
-
type PageableRequest = {
|
|
249
|
-
/**
|
|
250
|
-
* Page number (0-based indexing).
|
|
251
|
-
* The first page is 0, the second page is 1, etc.
|
|
252
|
-
*/
|
|
253
|
-
page: number;
|
|
254
|
-
/**
|
|
255
|
-
* Optional page size limit.
|
|
256
|
-
* Specifies the maximum number of items to return per page.
|
|
257
|
-
*/
|
|
258
|
-
size?: number;
|
|
259
|
-
/**
|
|
260
|
-
* Optional sorting criteria.
|
|
261
|
-
* Can be a single sort token or an array of sort tokens for multi-field sorting.
|
|
262
|
-
* Format: "field,direction" where direction is "asc" or "desc".
|
|
263
|
-
* @example ["name,asc", "createdAt,desc"]
|
|
264
|
-
*/
|
|
265
|
-
sort?: SortToken | ReadonlyArray<SortToken>;
|
|
261
|
+
type StorageStrategy = 'memory' | 'lru' | 'session' | 'persist';
|
|
262
|
+
type StorageStrategyOptions = {
|
|
263
|
+
lruLimit?: number;
|
|
266
264
|
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
* Array of items for the current page.
|
|
298
|
-
*/
|
|
299
|
-
content: T[];
|
|
300
|
-
};
|
|
301
|
-
/**
|
|
302
|
-
* Business-level error response structure.
|
|
303
|
-
* Used to communicate structured error information from API endpoints.
|
|
304
|
-
*/
|
|
305
|
-
type ErrorResponse = {
|
|
306
|
-
/**
|
|
307
|
-
* Error code identifier.
|
|
308
|
-
* Can be a numeric code or string constant for error categorization.
|
|
309
|
-
*/
|
|
310
|
-
errorCode: number | string;
|
|
311
|
-
/**
|
|
312
|
-
* Human-readable error message.
|
|
313
|
-
* Provides a description of the error for display or logging.
|
|
314
|
-
*/
|
|
315
|
-
message: string;
|
|
316
|
-
/**
|
|
317
|
-
* Optional field-level validation errors map.
|
|
318
|
-
* Maps form/DTO field names to their respective error messages.
|
|
319
|
-
* Supports multiple errors per field when concatenated in the string value.
|
|
320
|
-
*/
|
|
321
|
-
fields?: Record<string, string>;
|
|
322
|
-
/**
|
|
323
|
-
* Optional arbitrary error details.
|
|
324
|
-
* Can contain additional context such as error code enums, hints, or debugging information.
|
|
325
|
-
*/
|
|
326
|
-
details?: unknown;
|
|
327
|
-
};
|
|
328
|
-
/**
|
|
329
|
-
* Common query parameters interface for API requests.
|
|
330
|
-
* Combines pagination, sorting, and filtering capabilities.
|
|
331
|
-
*
|
|
332
|
-
* @template Filters - Type of the domain model used for filtering, defaults to unknown
|
|
333
|
-
*/
|
|
334
|
-
interface QueryParams<Filters = unknown> {
|
|
335
|
-
/**
|
|
336
|
-
* Optional page number for pagination (0-based indexing).
|
|
337
|
-
*/
|
|
338
|
-
page?: number;
|
|
339
|
-
/**
|
|
340
|
-
* Optional page size limit.
|
|
341
|
-
*/
|
|
342
|
-
size?: number;
|
|
343
|
-
/**
|
|
344
|
-
* Optional sorting criteria.
|
|
345
|
-
* Can be a single sort token or an array of sort tokens for multi-field sorting.
|
|
346
|
-
*/
|
|
347
|
-
sort?: SortToken | ReadonlyArray<SortToken>;
|
|
348
|
-
/**
|
|
349
|
-
* Optional filters as a partial subset of the domain model.
|
|
350
|
-
* Allows filtering by any combination of model properties.
|
|
351
|
-
*/
|
|
352
|
-
filters?: Partial<Filters>;
|
|
265
|
+
|
|
266
|
+
declare class LocalStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {
|
|
267
|
+
prefix: string;
|
|
268
|
+
constructor(prefix?: string);
|
|
269
|
+
get length(): number;
|
|
270
|
+
get(key: Key): Type | null;
|
|
271
|
+
set(key: Key, value: Type): void;
|
|
272
|
+
remove(key: Key): void;
|
|
273
|
+
clear(): void;
|
|
274
|
+
private getSafePrefix;
|
|
275
|
+
private safePrefix;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
declare class LruCache<KeyT, ValueT> implements StorageInterface<KeyT, ValueT> {
|
|
279
|
+
private map;
|
|
280
|
+
private _limit;
|
|
281
|
+
constructor(limit?: number);
|
|
282
|
+
get limit(): number;
|
|
283
|
+
get length(): number;
|
|
284
|
+
set limit(value: number);
|
|
285
|
+
get(key: KeyT): NonNullable<ValueT> | null;
|
|
286
|
+
set(key: KeyT, value: ValueT): void;
|
|
287
|
+
remove(key: KeyT): boolean;
|
|
288
|
+
clear(): void;
|
|
289
|
+
has(key: KeyT): boolean;
|
|
290
|
+
keys(): KeyT[];
|
|
291
|
+
values(): ValueT[];
|
|
292
|
+
entries(): [KeyT, ValueT][];
|
|
293
|
+
toArray(): ValueT[];
|
|
294
|
+
fromArray(entries: [KeyT, ValueT][]): void;
|
|
353
295
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
296
|
+
|
|
297
|
+
declare class MemoryStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {
|
|
298
|
+
private cache;
|
|
299
|
+
get length(): number;
|
|
300
|
+
get(key: Key): Type | null;
|
|
301
|
+
set(key: Key, value: Type): void;
|
|
302
|
+
remove(key: Key): void;
|
|
303
|
+
clear(): void;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
declare class SessionStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {
|
|
307
|
+
prefix: string;
|
|
308
|
+
constructor(prefix?: string);
|
|
309
|
+
get length(): number;
|
|
310
|
+
get(key: Key): Type | null;
|
|
311
|
+
set(key: Key, value: Type): void;
|
|
312
|
+
remove(key: Key): void;
|
|
313
|
+
clear(): void;
|
|
314
|
+
private getSafePrefix;
|
|
315
|
+
private safePrefix;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
declare const storageStrategy: <Key = string, Type extends AnyType = AnyDict>(strategy: StorageStrategy, options?: StorageStrategyOptions) => StorageInterface<Key, Type>;
|
|
374
319
|
|
|
375
320
|
/**
|
|
376
321
|
* Built-in language codes.
|
|
@@ -467,7 +412,7 @@ declare const TRANSLATION: InjectionToken<TranslationProvider>;
|
|
|
467
412
|
* `'light'` — light theme
|
|
468
413
|
* `'dark'` — dark theme
|
|
469
414
|
*/
|
|
470
|
-
type Themes = 'light' | 'dark';
|
|
415
|
+
type Themes = 'light' | 'dark' | (string & {});
|
|
471
416
|
/**
|
|
472
417
|
* Provider for changing the application theme.
|
|
473
418
|
*
|
|
@@ -522,12 +467,11 @@ type Devices = 'mobile' | 'tablet' | 'desktop-s' | 'desktop';
|
|
|
522
467
|
declare const CURRENT_DEVICE: InjectionToken<Signal<Devices>>;
|
|
523
468
|
|
|
524
469
|
/**
|
|
525
|
-
*
|
|
526
|
-
* Contains common properties like requiredLength and actualLength
|
|
527
|
-
* and allows additional string properties through index signature.
|
|
470
|
+
* Legacy validation token surface kept only for compatibility with legacy consumers.
|
|
528
471
|
*
|
|
529
|
-
*
|
|
530
|
-
*
|
|
472
|
+
* This token set is form/UI-facing and does not belong to the desired `internal v2`
|
|
473
|
+
* foundation boundary. Keep usage isolated and migrate consumers away from the top-level
|
|
474
|
+
* `@reforgium/internal` surface over time.
|
|
531
475
|
*/
|
|
532
476
|
type ValidationErrorData = {
|
|
533
477
|
requiredLength: string;
|
|
@@ -535,32 +479,11 @@ type ValidationErrorData = {
|
|
|
535
479
|
[key: string]: string;
|
|
536
480
|
};
|
|
537
481
|
/**
|
|
538
|
-
*
|
|
539
|
-
* Each key represents an error name, and the value is a function
|
|
540
|
-
* that takes validation error data and returns a formatted error message.
|
|
541
|
-
*
|
|
542
|
-
* @example
|
|
543
|
-
* const messages: ValidationMessages = {
|
|
544
|
-
* minlength: (error) => `Minimum length is ${error.requiredLength}`
|
|
545
|
-
* };
|
|
482
|
+
* Legacy validation message map.
|
|
546
483
|
*/
|
|
547
484
|
type ValidationMessages = Record<string, (error: ValidationErrorData) => string>;
|
|
548
485
|
/**
|
|
549
|
-
*
|
|
550
|
-
* Can be overridden in feature modules to provide custom validation messages.
|
|
551
|
-
* Defaults to an empty object when not provided.
|
|
552
|
-
*
|
|
553
|
-
* @example
|
|
554
|
-
* // In a feature module:
|
|
555
|
-
* providers: [
|
|
556
|
-
* {
|
|
557
|
-
* provide: VALIDATION_MESSAGES,
|
|
558
|
-
* useValue: {
|
|
559
|
-
* required: () => 'This field is required',
|
|
560
|
-
* minlength: (error) => `Min length: ${error.requiredLength}`
|
|
561
|
-
* }
|
|
562
|
-
* }
|
|
563
|
-
* ]
|
|
486
|
+
* Legacy validation messages token.
|
|
564
487
|
*/
|
|
565
488
|
declare const VALIDATION_MESSAGES: InjectionToken<ValidationMessages>;
|
|
566
489
|
|
|
@@ -668,7 +591,7 @@ declare const throttleSignal: <T>(src: Signal<T>, ms?: number, opts?: {
|
|
|
668
591
|
*
|
|
669
592
|
* @returns {string} Formatted date string. Returns an empty string if the input date is invalid.
|
|
670
593
|
*/
|
|
671
|
-
declare const formatDate: (date
|
|
594
|
+
declare const formatDate: (date?: Date | null, format?: string) => string;
|
|
672
595
|
/**
|
|
673
596
|
* Formats the given date into a `day month year` string using the `ru-RU` locale.
|
|
674
597
|
* The month is abbreviated and normalized without a trailing dot.
|
|
@@ -729,7 +652,7 @@ declare const toDate: (v: unknown) => Date;
|
|
|
729
652
|
* reformatDateToISO("24.11.2025", "dd.MM.yyyy")
|
|
730
653
|
* → "2025-11-24T00:00:00.000Z"
|
|
731
654
|
*/
|
|
732
|
-
declare function reformatDateToISO(dateStr
|
|
655
|
+
declare function reformatDateToISO(dateStr?: string | null, mask?: string | null): string | null;
|
|
733
656
|
|
|
734
657
|
/**
|
|
735
658
|
* Determines if the given value is null/undefined.
|
|
@@ -1005,6 +928,96 @@ declare function deepEqual(a: AnyType, b: AnyType, seen?: Map<any, any>): boolea
|
|
|
1005
928
|
*/
|
|
1006
929
|
declare const generateId: (limit?: number, radix?: number) => string;
|
|
1007
930
|
|
|
1008
|
-
|
|
1009
|
-
|
|
931
|
+
type Types = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'period' | 'nullable';
|
|
932
|
+
type FieldConcatType = 'comma' | 'multi' | 'json';
|
|
933
|
+
type SerializedPrimitives = string | number | boolean | null;
|
|
934
|
+
type SerializedTypeType = SerializedPrimitives | SerializedPrimitives[];
|
|
935
|
+
type DatePeriod = [Date | null, Date | null];
|
|
936
|
+
type ParseFormatConfig<TypeFrom, TypeTo = SerializedTypeType> = {
|
|
937
|
+
parse?: (val: TypeTo) => TypeFrom;
|
|
938
|
+
format?: (val: TypeFrom) => TypeTo;
|
|
939
|
+
};
|
|
940
|
+
type FormatConfig<TypeFrom, TypeTo = SerializedTypeType> = {
|
|
941
|
+
format?: (val: TypeFrom) => TypeTo;
|
|
942
|
+
};
|
|
943
|
+
type FieldConfig = ({
|
|
944
|
+
type: Types;
|
|
945
|
+
concatType?: FieldConcatType;
|
|
946
|
+
} | FieldsTypeConfig<DataType, AnyType>) & {
|
|
947
|
+
concatType?: FieldConcatType;
|
|
948
|
+
};
|
|
949
|
+
type FieldsTypeConfig<EntityType extends DataType, TypeFrom, TypeTo = SerializedTypeType> = {
|
|
950
|
+
parse: (val: TypeTo, data: SerializedType) => TypeFrom;
|
|
951
|
+
format: (val: TypeFrom, data: EntityType) => TypeTo;
|
|
952
|
+
};
|
|
953
|
+
type PeriodSplitMode = {
|
|
954
|
+
mode: 'split';
|
|
955
|
+
dateFromKeyPostfix: string;
|
|
956
|
+
dateToKeyPostfix: string;
|
|
957
|
+
};
|
|
958
|
+
type PeriodJoinMode = {
|
|
959
|
+
mode: 'join';
|
|
960
|
+
concat: string;
|
|
961
|
+
};
|
|
962
|
+
type SerializerConfig = {
|
|
963
|
+
mapString: {
|
|
964
|
+
trim?: boolean;
|
|
965
|
+
} & ParseFormatConfig<string>;
|
|
966
|
+
mapNumber: {
|
|
967
|
+
fromString?: boolean;
|
|
968
|
+
} & ParseFormatConfig<number>;
|
|
969
|
+
mapBoolean: {
|
|
970
|
+
true?: string;
|
|
971
|
+
false?: string;
|
|
972
|
+
} & ParseFormatConfig<boolean>;
|
|
973
|
+
mapDate: {
|
|
974
|
+
dateFormat?: string;
|
|
975
|
+
} & ParseFormatConfig<Date>;
|
|
976
|
+
mapPeriod: {
|
|
977
|
+
transformMode?: PeriodSplitMode | PeriodJoinMode;
|
|
978
|
+
dateFormat?: string;
|
|
979
|
+
} & ParseFormatConfig<DatePeriod>;
|
|
980
|
+
mapNullable: {
|
|
981
|
+
remove?: boolean;
|
|
982
|
+
replaceWith?: string;
|
|
983
|
+
includeEmptyString?: boolean;
|
|
984
|
+
} & ParseFormatConfig<null | undefined>;
|
|
985
|
+
mapArray: {
|
|
986
|
+
concatType: FieldConcatType;
|
|
987
|
+
removeNullable?: boolean;
|
|
988
|
+
} & FormatConfig<AnyType[]>;
|
|
989
|
+
mapObject: {
|
|
990
|
+
deep: boolean;
|
|
991
|
+
} & FormatConfig<DataType>;
|
|
992
|
+
mapFields?: Record<string, FieldConfig>;
|
|
993
|
+
};
|
|
994
|
+
type SerializedType = Record<string, SerializedTypeType>;
|
|
995
|
+
type DataType = AnyDict;
|
|
996
|
+
|
|
997
|
+
declare class SerializerFieldError extends Error {
|
|
998
|
+
readonly field: string;
|
|
999
|
+
readonly stage: 'parse' | 'format';
|
|
1000
|
+
readonly originalError: unknown;
|
|
1001
|
+
constructor(field: string, stage: 'parse' | 'format', originalError: unknown);
|
|
1002
|
+
}
|
|
1003
|
+
declare class Serializer<EntityType extends DataType> {
|
|
1004
|
+
readonly config: SerializerConfig;
|
|
1005
|
+
constructor(config?: Partial<SerializerConfig>);
|
|
1006
|
+
serialize(obj: EntityType, _seen?: WeakSet<object>): SerializedType;
|
|
1007
|
+
deserialize: (val: string | AnyDict) => EntityType;
|
|
1008
|
+
deserializeQuery: (query: string) => EntityType;
|
|
1009
|
+
deserializeJson: (json: string) => EntityType;
|
|
1010
|
+
toQuery: (val: EntityType) => string;
|
|
1011
|
+
withConfig(config: Partial<SerializerConfig>): Serializer<EntityType>;
|
|
1012
|
+
private serializeElement;
|
|
1013
|
+
private deserializeElement;
|
|
1014
|
+
private parseQuery;
|
|
1015
|
+
private parseJsonObject;
|
|
1016
|
+
private parseInputString;
|
|
1017
|
+
private mergeConfig;
|
|
1018
|
+
private resolveArrayFieldModes;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
export { BUILTIN_LANGS, CHANGE_LANG, CHANGE_THEME, CURRENT_DEVICE, LocalStorage, LruCache, MemoryStorage, REGISTER_LANG, SELECTED_LANG, SELECTED_THEME, Serializer, SerializerFieldError, SessionStorage, TRANSLATION, VALIDATION_MESSAGES, appendQueryParams, appendQueryParamsByMode, base64ToBlob, buildQueryParams, compareRoutes, concatArray, copyText, debounceSignal, deepEqual, downloadByBlob, downloadByUrl, fillUrlWithParams, formatDate, formatToLocaledDate, formatToSpacedNumber, generateId, getAvailableHeight, getChainedValue, getCorrectedPosition, isDatePeriod, isNullable, isNumber, isObject, makeQuery, materializeRoutePath, mergeQueryParams, normalizeSortInput, normalizeUrl, parseQueryArray, parseQueryParams, parseQueryParamsByMode, parseSortToken, parseToDate, parseToDatePeriod, provideLangs, reformatDateToISO, sortInputToTokens, sortRuleToToken, storageStrategy, throttleSignal, toDate, toSortToken, truncate };
|
|
1022
|
+
export type { AnyDict, AnyType, Appearance, DataType, Devices, Direction, ElementEdges, ElementPosition, ElementRect, ElementSize, ErrorResponse, FieldConcatType, FieldConfig, FormatConfig, JsonObject, JsonPrimitive, JsonValue, Langs, LiteralOf, Mutable, Nullable, NullableProps, Nullish, OptionalExcept, PageableRequest, PageableResponse, ParseFormatConfig, Query, QueryArrayMode, QueryFieldModes, QueryParams, QueryScalar, RequiredExcept, RestMethods, SelectIconOption, SelectOption, SerializedType, SerializerConfig, SortDirection, SortInput, SortRule, SortToken, StorageInterface, StorageStrategy, StorageStrategyOptions, Themes, Types, ValidationErrorData, ValidationMessages, ValueOf };
|
|
1010
1023
|
//# sourceMappingURL=reforgium-internal.d.ts.map
|