@reforgium/internal 1.1.0 → 1.2.0

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/README.md CHANGED
@@ -1,260 +1,82 @@
1
- # @reforgium/internal
2
-
3
- [![npm version](https://badge.fury.io/js/%40reforgium%2Finternal.svg)](https://www.npmjs.com/package/@reforgium/internal)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
-
6
- **Core infrastructure package for Angular (20+) applications.**
7
-
8
- `@reforgium/internal` is a foundational layer that sits *under* feature libraries and applications.
9
- It provides shared models, typed DI tokens, and low-level utilities designed for reuse, consistency, and long-term maintainability.
10
-
11
- This package is **not** a UI kit and **not** a framework replacement.
12
- It is a **stable internal contract** for building scalable Angular systems.
13
-
14
- ---
15
-
16
- ## Why
17
-
18
- - Centralize shared domain primitives
19
- - Prevent cross-package circular dependencies
20
- - Keep feature/UI layers clean
21
- - Enable aggressive tree-shaking and dead-code elimination
22
- - Provide a reusable internal base across multiple libraries and apps
23
-
24
- ---
25
-
26
- ## What’s inside
27
-
28
- - **Models** — shared domain models, interfaces, and value objects
29
- - **Tokens** — typed DI tokens for configuration and infrastructure contracts
30
- - **Utilities** — framework-agnostic helpers and low-level utilities (including Signal-friendly helpers)
31
-
32
- > It’s the bedrock, not the building.
33
-
34
- ---
35
-
36
- ## Install
37
-
38
- ```bash
39
- npm i @reforgium/internal
40
- ```
41
-
42
- ---
43
-
44
- # Public API
45
-
46
- ## Models
47
-
48
- ### Component models (`components.ts`)
49
-
50
- #### `Appearance`
51
- Preset UI appearance tokens.
52
-
53
- ```ts
54
- import type { Appearance } from '@reforgium/internal';
55
-
56
- const appearance: Appearance = 'primary';
57
- ```
58
-
59
- #### `SelectOption`
60
- Basic select option shape: `{ label: string; value: string | number }`.
61
-
62
- ```ts
63
- import type { SelectOption } from '@reforgium/internal';
64
-
65
- const options: SelectOption[] = [
66
- { label: 'Admin', value: 'admin' },
67
- { label: 'User', value: 'user' },
68
- ];
69
- ```
70
-
71
- #### `SelectIconOption extends SelectOption`
72
- Select option with an icon: `icon: string`.
73
-
74
- ```ts
75
- import type { SelectIconOption } from '@reforgium/internal';
76
-
77
- const langOptions: SelectIconOption[] = [
78
- { value: 'en', label: 'English', icon: 'flag-en' },
79
- { value: 'ru', label: 'Рус', icon: 'flag-ru' },
80
- ];
81
- ```
82
-
83
- ### Utility types (`util.ts`)
84
-
85
- #### `AnyType`
86
- Compatibility type (similar to `any`) used in low-level helpers.
87
-
88
- #### `AnyDict`
89
- Compatibility dict type (similar to `Record<string, any>`) used across infra/helpers.
90
-
91
- #### `LiteralOf<T>`
92
- Returns a union of literal keys of an object type.
93
-
94
- ```ts
95
- import type { LiteralOf } from '@reforgium/internal';
96
-
97
- type StatusMap = { new: 1; done: 2 };
98
- type StatusCode = LiteralOf<StatusMap>; // 'new' | 'done'
99
- ```
100
-
101
- #### `ValueOf<T>`
102
- Returns a union of values of an object type.
103
-
104
- ```ts
105
- import type { ValueOf } from '@reforgium/internal';
106
-
107
- type StatusMap = { new: 1; done: 2 };
108
- type StatusCode = ValueOf<StatusMap>; // 1 | 2
109
- ```
110
-
111
- #### `Nullable<T>`
112
- Returns a nullable copy of an object type.
113
-
114
- ```ts
115
- import type { Nullable } from '@reforgium/internal';
116
-
117
- type StatusMap = { new: number; done: number };
118
- type StatusCode = Nullable<StatusMap>; // { new: number | null; done: number | null }
119
- ```
120
-
121
- ### API & pagination models (`api.ts`)
122
-
123
- - `RestMethods` — `'GET' | 'POST' | 'PUT' | 'DELETE'`
124
- - `PageableRequest` — `{ page: number; size?: number; sort?: string }`
125
- - `PageableResponse<T>` — `content: T[]` + paging metadata
126
- - `ErrorResponse` — `{ errorCode: number; message: string; fields: Record<string, string> }`
127
- - `QueryParams<T>` — `page?`, `size?`, `sort?`, `filters?: Partial<T>`
128
- - `Params` — route/query params dict
129
-
130
- Example (typing only):
131
-
132
- ```ts
133
- import type { PageableRequest, QueryParams } from '@reforgium/internal';
134
-
135
- const params: QueryParams<{ role: string }> = {
136
- page: 0,
137
- size: 20,
138
- filters: { role: 'admin' },
139
- };
140
-
141
- const asPageable: PageableRequest = {
142
- page: params.page ?? 0,
143
- size: params.size,
144
- sort: params.sort,
145
- };
146
- ```
147
-
148
- ---
149
-
150
- ## Tokens
151
- The localization system is built around a service that manages translations across different languages and namespaces. It supports:
152
-
153
- - Multiple languages (Russian 'ru', Kyrgyz 'kg'/'ky')
154
- - Namespace-based translation loading
155
- - Dynamic language switching with persistence
156
- - Translation caching for performance
157
- - Parameter interpolation in translations
158
- - Reactive translation updates using Angular signals
159
-
160
- ## Utilities
161
-
162
- ### Dates (`date.utils.ts`)
163
-
164
- - `formatDate(date, format = 'yyyy-MM-dd')`
165
- - `formatToLocaledDate(date)` (ru-RU localized format)
166
- - `parseToDate(value, format = 'dd.MM.yyyy')`
167
- - `parseToDatePeriod(value, format = 'dd.MM.yyyy')`
168
- - `isDatePeriod(value)`
169
-
170
- ```ts
171
- import { formatDate, parseToDatePeriod } from '@reforgium/internal';
172
-
173
- formatDate(new Date(2025, 0, 2), 'dd.MM.yyyy'); // '02.01.2025'
174
- parseToDatePeriod('01.01.2025 - 31.01.2025'); // [Date, Date]
175
- ```
176
-
177
- ### Formatting (`format.utils.ts`)
178
-
179
- - `formatToSpacedNumber(num)` — thousand separators
180
- - `truncate(text, limit)`
181
-
182
- ```ts
183
- import { formatToSpacedNumber, truncate } from '@reforgium/internal';
184
-
185
- formatToSpacedNumber(1234567); // '1 234 567'
186
- truncate('Very long text', 8); // 'Very lon…'
187
- ```
188
-
189
- ### Routes & query (`routes.utils.ts`, `types.utils.ts`)
190
- Sources: `src/common/utils/routes.utils.ts`, `src/common/utils/types.utils.ts`
191
-
192
- - `makeQuery(object, concatType: 'comma' | 'json' | 'multi')`
193
- - `materializeRoutePath(actualRoute, pureRoute)`
194
- - `compareRoutes(actualRoute, pureRoute, withSubroute = false)`
195
- - `parseQueryArray(val, mode, key?)`
196
- - `concatArray(value, mode, key?)`
197
-
198
- ```ts
199
- import { makeQuery, compareRoutes } from '@reforgium/internal';
200
-
201
- makeQuery({ a: 1, b: [1, 2] }, 'comma'); // 'a=1&b=1,2'
202
- compareRoutes('/users/42', '/users/:id'); // true
203
- ```
204
-
205
- ### Signal timers (`times.utils.ts`)
206
-
207
- - `debounceSignal(src, ms = 150, opts?)`
208
- - `throttleSignal(src, ms = 100, opts?)`
209
-
210
- ### Web helpers (`web.utils.ts`)
211
-
212
- - `downloadFile(blob, fileName?)`
213
- - `downloadUrl(url, fileName?)`
214
- - `copyText(text)`
215
- - `base64ToBlob(base64, mimeType = '')`
216
-
217
- ### DOM (`available-height.utils.ts`)
218
-
219
- - `getAvailableHeight(el, margin = 20)`
220
-
221
- ### Positioning (`positions.utils.ts`)
222
-
223
- - `getCorrectedPosition(anchor, triggerSize, boundBox, directions, offset)`
224
-
225
- ### Object access (`get-chained-value.utils.ts`)
226
-
227
- - `getChainedValue(obj, path)`
228
-
229
- ```ts
230
- import { getChainedValue } from '@reforgium/internal';
231
-
232
- getChainedValue({ a: { b: [{ c: 1 }] } }, 'a.b.0.c'); // 1
233
- ```
234
-
235
- ### Deep compare (`deep-equal.utils.ts`)
236
-
237
- - `deepEqual(a, b)` (supports Map/Set/Date/RegExp/NaN, cycle-safe)
238
-
239
- ### Type guards (`types.utils.ts`)
240
-
241
- - `isNullable(value, withEmptyString = false)`
242
- - `isNumber(value, fromString = false)`
243
- - `isObject(val)`
244
-
245
- ### Misc (`generate.utils.ts`)
246
-
247
- - `generateId(limit = 15, radix = 36)`
248
-
249
- ```ts
250
- import { generateId } from '@reforgium/internal';
251
-
252
- generateId(); // e.g. 'k3f9mz72q'
253
- generateId(10, 16); // hex-like
254
- ```
255
-
256
- ---
257
-
258
- ## License
259
-
1
+ # @reforgium/internal
2
+
3
+ [![npm version](https://badge.fury.io/js/%40reforgium%2Finternal.svg)](https://www.npmjs.com/package/@reforgium/internal)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Shared infrastructure package for Reforgium Angular libraries.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm i @reforgium/internal
12
+ ```
13
+
14
+ ## Public API
15
+
16
+ `@reforgium/internal` exports:
17
+ - `models`
18
+ - `tokens`
19
+ - `utils`
20
+
21
+ ### Models
22
+
23
+ Main model groups:
24
+ - `api.ts`: `RestMethods`, `SortToken`, `PageableRequest`, `PageableResponse<T>`, `ErrorResponse`, `QueryParams`, `Query`
25
+ - `components.ts`: `Appearance`, `SelectOption`, `SelectIconOption`
26
+ - `elements.ts`: `Direction`, `ElementRect`, `ElementSize`, `ElementPosition`, `ElementEdges`
27
+ - `util.ts`: `AnyType`, `AnyDict`, `LiteralOf`, `ValueOf`, `Nullable`, `Nullish`, `NullableProps`, `OptionalExcept`, `RequiredExcept`, `Mutable`, JSON helper types
28
+
29
+ ### Tokens
30
+
31
+ Language tokens:
32
+ - `SELECTED_LANG: InjectionToken<Signal<Langs>>`
33
+ - `CHANGE_LANG: InjectionToken<(lang: Langs) => void>`
34
+ - `TRANSLATION`
35
+ - `REGISTER_LANG` (multi-token)
36
+ - `BUILTIN_LANGS`
37
+ - `provideLangs(...langs: string[])`
38
+ - `Langs = BuiltInLangs | (string & {})`
39
+
40
+ Theme/device/validation tokens:
41
+ - `SELECTED_THEME`, `CHANGE_THEME`, `Themes`
42
+ - `CURRENT_DEVICE`, `Devices`
43
+ - `VALIDATION_MESSAGES`, `ValidationMessages`, `ValidationErrorData`
44
+
45
+ Example:
46
+
47
+ ```ts
48
+ import { provideLangs } from '@reforgium/internal';
49
+
50
+ export const appConfig = {
51
+ providers: [provideLangs('de', 'fr')],
52
+ };
53
+ ```
54
+
55
+ ### Utilities
56
+
57
+ Exported utilities:
58
+ - `web.utils.ts`: `downloadByBlob`, `downloadByUrl`, `copyText`, `base64ToBlob`
59
+ - `timers.utils.ts`: `throttleSignal`, `debounceSignal`
60
+ - `date.utils.ts`: `toDate`, `formatDate`, `formatToLocaledDate`, `parseToDate`, `parseToDatePeriod`, `isDatePeriod`, `reformatDateToISO`
61
+ - `types.utils.ts`: `isNumber`, `isNullable`, `isObject`, `parseQueryArray`, `concatArray`
62
+ - `format.utils.ts`: `formatToSpacedNumber`, `truncate`
63
+ - `positions.utils.ts`: `getCorrectedPosition`
64
+ - `available-height.utils.ts`: `getAvailableHeight`
65
+ - `get-chained-value.utils.ts`: `getChainedValue`
66
+ - `urls.utils.ts`: `normalizeUrl`, `fillUrlWithParams`, `appendQueryParams`, `parseQueryParams`
67
+ - `routes.utils.ts`: `materializeRoutePath`, `compareRoutes`, `makeQuery`
68
+ - `deep-equal.utils.ts`: `deepEqual`
69
+ - `generate.utils.ts`: `generateId`
70
+
71
+ `makeQuery(..., 'multi')` behavior:
72
+
73
+ ```ts
74
+ import { makeQuery } from '@reforgium/internal';
75
+
76
+ makeQuery({ ids: [1, 2, 3], q: 'ok' }, 'multi');
77
+ // ids=1&ids=2&ids=3&q=ok
78
+ ```
79
+
80
+ ## License
81
+
260
82
  MIT