@tstdl/base 0.85.4 → 0.85.5
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/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { PickBy, ReplaceKey } from '../types.js';
|
|
2
1
|
import type { Observable } from 'rxjs';
|
|
2
|
+
import type { Signal } from '../signals/api.js';
|
|
3
|
+
import type { PickBy, ReactiveValue, ReplaceKey } from '../types.js';
|
|
3
4
|
import type { LocalizableText } from './localizable-text.model.js';
|
|
4
5
|
import { LocalizationService } from './localization.service.js';
|
|
5
|
-
export type DynamicText =
|
|
6
|
+
export type DynamicText = ReactiveValue<LocalizableText>;
|
|
7
|
+
export declare function resolveDynamicText(text: DynamicText, localizationService?: LocalizationService): Signal<string>;
|
|
6
8
|
export declare function resolveDynamicText$(text: DynamicText, localizationService?: LocalizationService): Observable<string>;
|
|
9
|
+
export declare function resolveDynamicTexts(texts: DynamicText[], localizationService?: LocalizationService): Signal<string[]>;
|
|
7
10
|
export declare function resolveDynamicTexts$(texts: DynamicText[], localizationService?: LocalizationService): Observable<string[]>;
|
|
11
|
+
export declare function resolveNestedDynamicText<T, K extends keyof PickBy<T, DynamicText>>(item: T, key: K, localizationService?: LocalizationService): Signal<ReplaceKey<T, K, string>>;
|
|
8
12
|
export declare function resolveNestedDynamicText$<T, K extends keyof PickBy<T, DynamicText>>(item: T, key: K, localizationService?: LocalizationService): Observable<ReplaceKey<T, K, string>>;
|
|
13
|
+
export declare function resolveNestedDynamicTexts<T, K extends keyof PickBy<T, DynamicText>>(items: T[], key: K, localizationService?: LocalizationService): Signal<ReplaceKey<T, K, string>[]>;
|
|
9
14
|
export declare function resolveNestedDynamicTexts$<T, K extends keyof PickBy<T, DynamicText>>(items: T[], key: K, localizationService?: LocalizationService): Observable<ReplaceKey<T, K, string>[]>;
|
|
@@ -18,34 +18,59 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var dynamic_text_model_exports = {};
|
|
20
20
|
__export(dynamic_text_model_exports, {
|
|
21
|
+
resolveDynamicText: () => resolveDynamicText,
|
|
21
22
|
resolveDynamicText$: () => resolveDynamicText$,
|
|
23
|
+
resolveDynamicTexts: () => resolveDynamicTexts,
|
|
22
24
|
resolveDynamicTexts$: () => resolveDynamicTexts$,
|
|
25
|
+
resolveNestedDynamicText: () => resolveNestedDynamicText,
|
|
23
26
|
resolveNestedDynamicText$: () => resolveNestedDynamicText$,
|
|
27
|
+
resolveNestedDynamicTexts: () => resolveNestedDynamicTexts,
|
|
24
28
|
resolveNestedDynamicTexts$: () => resolveNestedDynamicTexts$
|
|
25
29
|
});
|
|
26
30
|
module.exports = __toCommonJS(dynamic_text_model_exports);
|
|
27
31
|
var import_container = require("../container/index.js");
|
|
32
|
+
var import_api = require("../signals/api.js");
|
|
33
|
+
var import_to_observable = require("../signals/implementation/to-observable.js");
|
|
34
|
+
var import_to_signal = require("../signals/implementation/to-signal.js");
|
|
28
35
|
var import_type_guards = require("../utils/type-guards.js");
|
|
29
36
|
var import_rxjs = require("rxjs");
|
|
30
37
|
var import_localization_service = require("./localization.service.js");
|
|
38
|
+
const missingLocalizationKeyText = "[MISSING LOCALIZATION KEY]";
|
|
39
|
+
function resolveDynamicText(text, localizationService) {
|
|
40
|
+
return (0, import_to_signal.toSignal)(resolveDynamicText$(text, localizationService), { initialValue: missingLocalizationKeyText });
|
|
41
|
+
}
|
|
31
42
|
function resolveDynamicText$(text, localizationService) {
|
|
32
43
|
const resolvedLocalizationService = localizationService ?? import_container.container.resolve(import_localization_service.LocalizationService);
|
|
33
44
|
if ((0, import_rxjs.isObservable)(text)) {
|
|
34
45
|
return text.pipe((0, import_rxjs.switchMap)((inner) => resolveDynamicText$(inner, localizationService)));
|
|
35
46
|
}
|
|
47
|
+
if ((0, import_api.isSignal)(text)) {
|
|
48
|
+
const text$ = (0, import_to_observable.toObservable)(text);
|
|
49
|
+
return resolveDynamicText$(text$, resolvedLocalizationService);
|
|
50
|
+
}
|
|
36
51
|
if ((0, import_type_guards.isString)(text)) {
|
|
37
52
|
return (0, import_rxjs.of)(text);
|
|
38
53
|
}
|
|
39
54
|
return resolvedLocalizationService.localize$(text);
|
|
40
55
|
}
|
|
56
|
+
function resolveDynamicTexts(texts, localizationService) {
|
|
57
|
+
const initialValue = texts.map(() => missingLocalizationKeyText);
|
|
58
|
+
return (0, import_to_signal.toSignal)(resolveDynamicTexts$(texts, localizationService), { initialValue });
|
|
59
|
+
}
|
|
41
60
|
function resolveDynamicTexts$(texts, localizationService) {
|
|
42
61
|
const resolvedLocalizationService = localizationService ?? import_container.container.resolve(import_localization_service.LocalizationService);
|
|
43
62
|
const resolvedTextObservables = texts.map((text) => resolveDynamicText$(text, resolvedLocalizationService));
|
|
44
63
|
return (0, import_rxjs.combineLatest)(resolvedTextObservables);
|
|
45
64
|
}
|
|
65
|
+
function resolveNestedDynamicText(item, key, localizationService) {
|
|
66
|
+
return (0, import_to_signal.toSignal)(resolveNestedDynamicText$(item, key, localizationService), { requireSync: true });
|
|
67
|
+
}
|
|
46
68
|
function resolveNestedDynamicText$(item, key, localizationService) {
|
|
47
69
|
return resolveDynamicText$(item[key], localizationService).pipe((0, import_rxjs.map)((resolvedText) => ({ ...item, [key]: resolvedText })));
|
|
48
70
|
}
|
|
71
|
+
function resolveNestedDynamicTexts(items, key, localizationService) {
|
|
72
|
+
return (0, import_to_signal.toSignal)(resolveNestedDynamicTexts$(items, key, localizationService), { requireSync: true });
|
|
73
|
+
}
|
|
49
74
|
function resolveNestedDynamicTexts$(items, key, localizationService) {
|
|
50
75
|
const resolvedLocalizationService = localizationService ?? import_container.container.resolve(import_localization_service.LocalizationService);
|
|
51
76
|
const resolvedTextObservables = items.map((item) => resolveNestedDynamicText$(item, key, resolvedLocalizationService));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { Observable } from 'rxjs';
|
|
1
2
|
import { Logger } from '../logger/index.js';
|
|
3
|
+
import type { Signal } from '../signals/api.js';
|
|
2
4
|
import type { Enumeration, EnumerationValue } from '../types.js';
|
|
3
5
|
import type { PropertyName } from '../utils/object/property-name.js';
|
|
4
|
-
import type { Observable } from 'rxjs';
|
|
5
6
|
export type Language = {
|
|
6
7
|
code: string;
|
|
7
8
|
name: string;
|
|
@@ -62,15 +63,9 @@ export declare function localizationData<T>(data: LocalizationData<T>): Localiza
|
|
|
62
63
|
export declare function getLocalizationKeys<T extends Localization>(_localization?: T): ProxyLocalizationKeys<T['keys']>;
|
|
63
64
|
export declare const autoEnumerationLocalization: typeof _autoEnumerationLocalization;
|
|
64
65
|
export declare class LocalizationService {
|
|
65
|
-
private
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
private readonly availableLanguagesSubject;
|
|
69
|
-
private get activeLocalization();
|
|
70
|
-
get availableLanguages(): readonly Language[];
|
|
71
|
-
get activeLanguage(): Language | undefined;
|
|
72
|
-
readonly activeLanguage$: Observable<Language | undefined>;
|
|
73
|
-
readonly availableLanguages$: Observable<readonly Language[]>;
|
|
66
|
+
#private;
|
|
67
|
+
readonly activeLanguage: Signal<Language | null>;
|
|
68
|
+
readonly availableLanguages: Signal<Language[]>;
|
|
74
69
|
constructor(logger: Logger);
|
|
75
70
|
registerLocalization(...localizations: Localization[]): void;
|
|
76
71
|
hasLanguage(languageCode: string): boolean;
|
|
@@ -79,8 +74,10 @@ export declare class LocalizationService {
|
|
|
79
74
|
setLocalization(localization: Localization): void;
|
|
80
75
|
tryGetItem<Parameters>(keyOrData: LocalizationKey<Parameters> | LocalizationData<Parameters>): LocalizeItem | undefined;
|
|
81
76
|
hasKey<Parameters>(key: LocalizationKey<Parameters> | LocalizationData<Parameters>): boolean;
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
localizeOnce<Parameters = void>(keyOrData: LocalizationKey<Parameters> | LocalizationData<Parameters>): string;
|
|
78
|
+
localizeEnumOnce<T extends Enumeration>(enumeration: T, value?: EnumerationValue<T>, parameters?: unknown): string;
|
|
79
|
+
localize<Parameters>(data: LocalizationData<Parameters>): Signal<string>;
|
|
80
|
+
localizeEnum<T extends Enumeration>(enumeration: T, value?: EnumerationValue<T>, parameters?: unknown): Signal<string>;
|
|
84
81
|
localize$<Parameters>(data: LocalizationData<Parameters>): Observable<string>;
|
|
85
82
|
localizeEnum$<T extends Enumeration>(enumeration: T, value?: EnumerationValue<T>, parameters?: unknown): Observable<string>;
|
|
86
83
|
private localizeItem;
|
|
@@ -33,12 +33,13 @@ module.exports = __toCommonJS(localization_service_exports);
|
|
|
33
33
|
var import_container = require("../container/index.js");
|
|
34
34
|
var import_details_error = require("../error/details.error.js");
|
|
35
35
|
var import_logger = require("../logger/index.js");
|
|
36
|
+
var import_api = require("../signals/api.js");
|
|
37
|
+
var import_computed_with_dependencies = require("../signals/computed-with-dependencies.js");
|
|
36
38
|
var import_enum = require("../utils/enum.js");
|
|
37
39
|
var import_memoize = require("../utils/function/memoize.js");
|
|
38
40
|
var import_object = require("../utils/object/object.js");
|
|
39
41
|
var import_property_name = require("../utils/object/property-name.js");
|
|
40
42
|
var import_type_guards = require("../utils/type-guards.js");
|
|
41
|
-
var import_rxjs = require("rxjs");
|
|
42
43
|
var __decorate = function(decorators, target, key, desc) {
|
|
43
44
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
44
45
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
@@ -83,113 +84,111 @@ const autoEnumerationLocalization = (0, import_memoize.memoize)(_autoEnumeration
|
|
|
83
84
|
const parametersPattern = /(?:\{\{\s*(?<parameter>\w+)\s*\}\})/ug;
|
|
84
85
|
const warnedMissingKeys = /* @__PURE__ */ new Set();
|
|
85
86
|
let LocalizationService = class LocalizationService2 {
|
|
86
|
-
logger;
|
|
87
|
-
localizations;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
#logger;
|
|
88
|
+
#localizations = /* @__PURE__ */ new Map();
|
|
89
|
+
#activeLanguage = (0, import_api.signal)(null);
|
|
90
|
+
#availableLanguages = (0, import_api.signal)([]);
|
|
91
|
+
#activeLocalization = (0, import_api.computed)(() => {
|
|
92
|
+
const language = this.activeLanguage();
|
|
93
|
+
if ((0, import_type_guards.isNull)(language)) {
|
|
94
|
+
return null;
|
|
93
95
|
}
|
|
94
|
-
return this
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
get activeLanguage() {
|
|
100
|
-
return this.activeLanguageSubject.value;
|
|
101
|
-
}
|
|
102
|
-
activeLanguage$;
|
|
103
|
-
availableLanguages$;
|
|
96
|
+
return this.#localizations.get(language.code);
|
|
97
|
+
});
|
|
98
|
+
activeLanguage = this.#activeLanguage.asReadonly();
|
|
99
|
+
availableLanguages = this.#availableLanguages.asReadonly();
|
|
104
100
|
constructor(logger) {
|
|
105
|
-
this
|
|
106
|
-
this.localizations = /* @__PURE__ */ new Map();
|
|
107
|
-
this.activeLanguageSubject = new import_rxjs.BehaviorSubject(void 0);
|
|
108
|
-
this.availableLanguagesSubject = new import_rxjs.BehaviorSubject([]);
|
|
109
|
-
this.activeLanguage$ = this.activeLanguageSubject.asObservable();
|
|
110
|
-
this.availableLanguages$ = this.availableLanguagesSubject.asObservable();
|
|
101
|
+
this.#logger = logger;
|
|
111
102
|
}
|
|
112
103
|
registerLocalization(...localizations) {
|
|
113
104
|
for (const localization of localizations) {
|
|
114
105
|
const mappedLocalization = buildMappedLocalization(localization);
|
|
115
|
-
if (this
|
|
116
|
-
const existing = this
|
|
106
|
+
if (this.#localizations.has(localization.language.code)) {
|
|
107
|
+
const existing = this.#localizations.get(localization.language.code);
|
|
117
108
|
const merged = mergeMappedLocalization(existing, mappedLocalization);
|
|
118
|
-
this
|
|
109
|
+
this.#localizations.set(localization.language.code, merged);
|
|
119
110
|
} else {
|
|
120
|
-
this
|
|
111
|
+
this.#localizations.set(localization.language.code, mappedLocalization);
|
|
121
112
|
}
|
|
122
113
|
if ((0, import_type_guards.isUndefined)(this.activeLanguage)) {
|
|
123
114
|
this.setLocalization(localization);
|
|
124
115
|
}
|
|
125
|
-
const availableLanguages = [...this
|
|
126
|
-
this.
|
|
116
|
+
const availableLanguages = [...this.#localizations].map(([, loc]) => loc.language);
|
|
117
|
+
this.#availableLanguages.set(availableLanguages);
|
|
127
118
|
}
|
|
128
119
|
}
|
|
129
120
|
hasLanguage(languageCode) {
|
|
130
|
-
return this
|
|
121
|
+
return this.#localizations.has(languageCode);
|
|
131
122
|
}
|
|
132
123
|
getLanguage(languageCode) {
|
|
133
|
-
return (0, import_type_guards.assertDefinedPass)(this
|
|
124
|
+
return (0, import_type_guards.assertDefinedPass)(this.#localizations.get(languageCode), "language not available").language;
|
|
134
125
|
}
|
|
135
126
|
setLanguage(languageOrCode) {
|
|
136
|
-
const language = (0, import_type_guards.isString)(languageOrCode) ? this
|
|
137
|
-
if ((0, import_type_guards.isUndefined)(language) || !this
|
|
127
|
+
const language = (0, import_type_guards.isString)(languageOrCode) ? this.#localizations.get(languageOrCode)?.language : languageOrCode;
|
|
128
|
+
if ((0, import_type_guards.isUndefined)(language) || !this.#localizations.has(language.code)) {
|
|
138
129
|
throw new Error("Language not registered.");
|
|
139
130
|
}
|
|
140
|
-
this.
|
|
131
|
+
this.#activeLanguage.set(language);
|
|
141
132
|
}
|
|
142
133
|
setLocalization(localization) {
|
|
143
134
|
this.setLanguage(localization.language);
|
|
144
135
|
}
|
|
145
136
|
tryGetItem(keyOrData) {
|
|
146
|
-
|
|
137
|
+
const activeLanguageCode = this.#activeLanguage()?.code;
|
|
138
|
+
if ((0, import_type_guards.isUndefined)(activeLanguageCode)) {
|
|
147
139
|
return void 0;
|
|
148
140
|
}
|
|
149
141
|
if (isEnumLocalizationKey(keyOrData)) {
|
|
150
|
-
const enumEntry = this
|
|
142
|
+
const enumEntry = this.#localizations.get(activeLanguageCode)?.enums.get(keyOrData.enum);
|
|
151
143
|
return (0, import_type_guards.isDefined)(keyOrData.value) ? enumEntry?.values[keyOrData.value] : enumEntry?.name;
|
|
152
144
|
}
|
|
153
145
|
const actualKey = getStringKey(keyOrData);
|
|
154
|
-
return this
|
|
146
|
+
return this.#localizations.get(activeLanguageCode)?.keys.get(actualKey);
|
|
155
147
|
}
|
|
156
148
|
hasKey(key) {
|
|
157
149
|
const item = this.tryGetItem(key);
|
|
158
150
|
return (0, import_type_guards.isDefined)(item);
|
|
159
151
|
}
|
|
160
152
|
// eslint-disable-next-line max-statements
|
|
161
|
-
|
|
153
|
+
localizeOnce(keyOrData) {
|
|
162
154
|
if (isEnumLocalizationKey(keyOrData)) {
|
|
163
|
-
return this.
|
|
155
|
+
return this.localizeEnumOnce(keyOrData.enum, keyOrData.value, keyOrData.parameters);
|
|
164
156
|
}
|
|
165
157
|
const key = getStringKey(keyOrData);
|
|
166
158
|
const parameters = (0, import_type_guards.isString)(keyOrData) || isProxyLocalizationKey(keyOrData) ? {} : keyOrData.parameters;
|
|
167
|
-
const
|
|
159
|
+
const activeLanguageCode = this.#activeLanguage()?.code;
|
|
160
|
+
const templateOrFunction = (0, import_type_guards.isDefined)(activeLanguageCode) ? this.#localizations.get(activeLanguageCode)?.keys.get(key) : void 0;
|
|
168
161
|
if ((0, import_type_guards.isUndefined)(templateOrFunction)) {
|
|
169
162
|
if (!warnedMissingKeys.has(key)) {
|
|
170
|
-
this
|
|
163
|
+
this.#logger.warn(`Localization for ${key} not available.`);
|
|
171
164
|
warnedMissingKeys.add(key);
|
|
172
165
|
}
|
|
173
166
|
}
|
|
174
167
|
return this.localizeItem(key, templateOrFunction, parameters);
|
|
175
168
|
}
|
|
176
|
-
|
|
169
|
+
localizeEnumOnce(enumeration, value, parameters) {
|
|
177
170
|
if ((0, import_type_guards.isUndefined)(value)) {
|
|
178
|
-
const name = this
|
|
171
|
+
const name = this.#activeLocalization()?.enums.get(enumeration)?.name;
|
|
179
172
|
return this.localizeItem("ENUM", name, parameters);
|
|
180
173
|
}
|
|
181
174
|
const key = (0, import_type_guards.isArray)(enumeration) ? value : (0, import_enum.enumValueName)(enumeration, value);
|
|
182
|
-
const item = this
|
|
175
|
+
const item = this.#activeLocalization()?.enums.get(enumeration)?.values[value];
|
|
183
176
|
if ((0, import_type_guards.isUndefined)(item)) {
|
|
184
177
|
return autoEnumerationLocalization(enumeration)[2][value];
|
|
185
178
|
}
|
|
186
179
|
return this.localizeItem(key, item, parameters);
|
|
187
180
|
}
|
|
181
|
+
localize(data) {
|
|
182
|
+
return (0, import_computed_with_dependencies.computedWithDependencies)(() => this.localizeOnce(data), [this.#activeLanguage]);
|
|
183
|
+
}
|
|
184
|
+
localizeEnum(enumeration, value, parameters) {
|
|
185
|
+
return (0, import_computed_with_dependencies.computedWithDependencies)(() => this.localizeEnumOnce(enumeration, value, parameters), [this.#activeLanguage]);
|
|
186
|
+
}
|
|
188
187
|
localize$(data) {
|
|
189
|
-
return
|
|
188
|
+
return (0, import_api.toObservable)(this.localize(data));
|
|
190
189
|
}
|
|
191
190
|
localizeEnum$(enumeration, value, parameters) {
|
|
192
|
-
return
|
|
191
|
+
return (0, import_api.toObservable)(this.localizeEnum(enumeration, value, parameters));
|
|
193
192
|
}
|
|
194
193
|
localizeItem(key, templateOrFunction, parameters) {
|
|
195
194
|
if ((0, import_type_guards.isUndefined)(templateOrFunction)) {
|
package/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { Observable } from 'rxjs';
|
|
1
2
|
import type { Except, UnionToIntersection } from 'type-fest';
|
|
3
|
+
import type { Signal } from './signals/api.js';
|
|
2
4
|
export type ObjectLiteral = {};
|
|
3
5
|
export type PrimitiveTypeMap = {
|
|
4
6
|
'string': string;
|
|
@@ -189,4 +191,5 @@ export type TypeFromPath<T extends Record, Path extends Paths<T> | string> = {
|
|
|
189
191
|
[K in Path]: K extends keyof T ? T[K] : K extends `${infer P}.${infer S}` ? T[P] extends Record ? TypeFromPath<T[P], S> : never : never;
|
|
190
192
|
}[Path];
|
|
191
193
|
export type ConstructorParameterDecorator = (target: Object, propertyKey: undefined, parameterIndex: number) => void;
|
|
194
|
+
export type ReactiveValue<T> = T | Signal<T> | Observable<T>;
|
|
192
195
|
export {};
|