@tstdl/base 0.85.4 → 0.85.6
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 +1 -1
- package/text/dynamic-text.model.d.ts +7 -2
- package/text/dynamic-text.model.js +25 -0
- package/text/localization.service.d.ts +11 -12
- package/text/localization.service.js +48 -47
- package/types.d.ts +3 -0
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,11 @@ 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
|
-
|
|
69
|
-
|
|
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[]>;
|
|
69
|
+
readonly activeLanguage$: Observable<Language | null>;
|
|
70
|
+
readonly availableLanguages$: Observable<Language[]>;
|
|
74
71
|
constructor(logger: Logger);
|
|
75
72
|
registerLocalization(...localizations: Localization[]): void;
|
|
76
73
|
hasLanguage(languageCode: string): boolean;
|
|
@@ -79,8 +76,10 @@ export declare class LocalizationService {
|
|
|
79
76
|
setLocalization(localization: Localization): void;
|
|
80
77
|
tryGetItem<Parameters>(keyOrData: LocalizationKey<Parameters> | LocalizationData<Parameters>): LocalizeItem | undefined;
|
|
81
78
|
hasKey<Parameters>(key: LocalizationKey<Parameters> | LocalizationData<Parameters>): boolean;
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
localizeOnce<Parameters = void>(keyOrData: LocalizationKey<Parameters> | LocalizationData<Parameters>): string;
|
|
80
|
+
localizeEnumOnce<T extends Enumeration>(enumeration: T, value?: EnumerationValue<T>, parameters?: unknown): string;
|
|
81
|
+
localize<Parameters>(data: LocalizationData<Parameters>): Signal<string>;
|
|
82
|
+
localizeEnum<T extends Enumeration>(enumeration: T, value?: EnumerationValue<T>, parameters?: unknown): Signal<string>;
|
|
84
83
|
localize$<Parameters>(data: LocalizationData<Parameters>): Observable<string>;
|
|
85
84
|
localizeEnum$<T extends Enumeration>(enumeration: T, value?: EnumerationValue<T>, parameters?: unknown): Observable<string>;
|
|
86
85
|
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,113 @@ 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
|
-
|
|
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();
|
|
100
|
+
activeLanguage$ = (0, import_api.toObservable)(this.activeLanguage);
|
|
101
|
+
availableLanguages$ = (0, import_api.toObservable)(this.availableLanguages);
|
|
104
102
|
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();
|
|
103
|
+
this.#logger = logger;
|
|
111
104
|
}
|
|
112
105
|
registerLocalization(...localizations) {
|
|
113
106
|
for (const localization of localizations) {
|
|
114
107
|
const mappedLocalization = buildMappedLocalization(localization);
|
|
115
|
-
if (this
|
|
116
|
-
const existing = this
|
|
108
|
+
if (this.#localizations.has(localization.language.code)) {
|
|
109
|
+
const existing = this.#localizations.get(localization.language.code);
|
|
117
110
|
const merged = mergeMappedLocalization(existing, mappedLocalization);
|
|
118
|
-
this
|
|
111
|
+
this.#localizations.set(localization.language.code, merged);
|
|
119
112
|
} else {
|
|
120
|
-
this
|
|
113
|
+
this.#localizations.set(localization.language.code, mappedLocalization);
|
|
121
114
|
}
|
|
122
115
|
if ((0, import_type_guards.isUndefined)(this.activeLanguage)) {
|
|
123
116
|
this.setLocalization(localization);
|
|
124
117
|
}
|
|
125
|
-
const availableLanguages = [...this
|
|
126
|
-
this.
|
|
118
|
+
const availableLanguages = [...this.#localizations].map(([, loc]) => loc.language);
|
|
119
|
+
this.#availableLanguages.set(availableLanguages);
|
|
127
120
|
}
|
|
128
121
|
}
|
|
129
122
|
hasLanguage(languageCode) {
|
|
130
|
-
return this
|
|
123
|
+
return this.#localizations.has(languageCode);
|
|
131
124
|
}
|
|
132
125
|
getLanguage(languageCode) {
|
|
133
|
-
return (0, import_type_guards.assertDefinedPass)(this
|
|
126
|
+
return (0, import_type_guards.assertDefinedPass)(this.#localizations.get(languageCode), "language not available").language;
|
|
134
127
|
}
|
|
135
128
|
setLanguage(languageOrCode) {
|
|
136
|
-
const language = (0, import_type_guards.isString)(languageOrCode) ? this
|
|
137
|
-
if ((0, import_type_guards.isUndefined)(language) || !this
|
|
129
|
+
const language = (0, import_type_guards.isString)(languageOrCode) ? this.#localizations.get(languageOrCode)?.language : languageOrCode;
|
|
130
|
+
if ((0, import_type_guards.isUndefined)(language) || !this.#localizations.has(language.code)) {
|
|
138
131
|
throw new Error("Language not registered.");
|
|
139
132
|
}
|
|
140
|
-
this.
|
|
133
|
+
this.#activeLanguage.set(language);
|
|
141
134
|
}
|
|
142
135
|
setLocalization(localization) {
|
|
143
136
|
this.setLanguage(localization.language);
|
|
144
137
|
}
|
|
145
138
|
tryGetItem(keyOrData) {
|
|
146
|
-
|
|
139
|
+
const activeLanguageCode = this.#activeLanguage()?.code;
|
|
140
|
+
if ((0, import_type_guards.isUndefined)(activeLanguageCode)) {
|
|
147
141
|
return void 0;
|
|
148
142
|
}
|
|
149
143
|
if (isEnumLocalizationKey(keyOrData)) {
|
|
150
|
-
const enumEntry = this
|
|
144
|
+
const enumEntry = this.#localizations.get(activeLanguageCode)?.enums.get(keyOrData.enum);
|
|
151
145
|
return (0, import_type_guards.isDefined)(keyOrData.value) ? enumEntry?.values[keyOrData.value] : enumEntry?.name;
|
|
152
146
|
}
|
|
153
147
|
const actualKey = getStringKey(keyOrData);
|
|
154
|
-
return this
|
|
148
|
+
return this.#localizations.get(activeLanguageCode)?.keys.get(actualKey);
|
|
155
149
|
}
|
|
156
150
|
hasKey(key) {
|
|
157
151
|
const item = this.tryGetItem(key);
|
|
158
152
|
return (0, import_type_guards.isDefined)(item);
|
|
159
153
|
}
|
|
160
154
|
// eslint-disable-next-line max-statements
|
|
161
|
-
|
|
155
|
+
localizeOnce(keyOrData) {
|
|
162
156
|
if (isEnumLocalizationKey(keyOrData)) {
|
|
163
|
-
return this.
|
|
157
|
+
return this.localizeEnumOnce(keyOrData.enum, keyOrData.value, keyOrData.parameters);
|
|
164
158
|
}
|
|
165
159
|
const key = getStringKey(keyOrData);
|
|
166
160
|
const parameters = (0, import_type_guards.isString)(keyOrData) || isProxyLocalizationKey(keyOrData) ? {} : keyOrData.parameters;
|
|
167
|
-
const
|
|
161
|
+
const activeLanguageCode = this.#activeLanguage()?.code;
|
|
162
|
+
const templateOrFunction = (0, import_type_guards.isDefined)(activeLanguageCode) ? this.#localizations.get(activeLanguageCode)?.keys.get(key) : void 0;
|
|
168
163
|
if ((0, import_type_guards.isUndefined)(templateOrFunction)) {
|
|
169
164
|
if (!warnedMissingKeys.has(key)) {
|
|
170
|
-
this
|
|
165
|
+
this.#logger.warn(`Localization for ${key} not available.`);
|
|
171
166
|
warnedMissingKeys.add(key);
|
|
172
167
|
}
|
|
173
168
|
}
|
|
174
169
|
return this.localizeItem(key, templateOrFunction, parameters);
|
|
175
170
|
}
|
|
176
|
-
|
|
171
|
+
localizeEnumOnce(enumeration, value, parameters) {
|
|
177
172
|
if ((0, import_type_guards.isUndefined)(value)) {
|
|
178
|
-
const name = this
|
|
173
|
+
const name = this.#activeLocalization()?.enums.get(enumeration)?.name;
|
|
179
174
|
return this.localizeItem("ENUM", name, parameters);
|
|
180
175
|
}
|
|
181
176
|
const key = (0, import_type_guards.isArray)(enumeration) ? value : (0, import_enum.enumValueName)(enumeration, value);
|
|
182
|
-
const item = this
|
|
177
|
+
const item = this.#activeLocalization()?.enums.get(enumeration)?.values[value];
|
|
183
178
|
if ((0, import_type_guards.isUndefined)(item)) {
|
|
184
179
|
return autoEnumerationLocalization(enumeration)[2][value];
|
|
185
180
|
}
|
|
186
181
|
return this.localizeItem(key, item, parameters);
|
|
187
182
|
}
|
|
183
|
+
localize(data) {
|
|
184
|
+
return (0, import_computed_with_dependencies.computedWithDependencies)(() => this.localizeOnce(data), [this.#activeLanguage]);
|
|
185
|
+
}
|
|
186
|
+
localizeEnum(enumeration, value, parameters) {
|
|
187
|
+
return (0, import_computed_with_dependencies.computedWithDependencies)(() => this.localizeEnumOnce(enumeration, value, parameters), [this.#activeLanguage]);
|
|
188
|
+
}
|
|
188
189
|
localize$(data) {
|
|
189
|
-
return
|
|
190
|
+
return (0, import_api.toObservable)(this.localize(data));
|
|
190
191
|
}
|
|
191
192
|
localizeEnum$(enumeration, value, parameters) {
|
|
192
|
-
return
|
|
193
|
+
return (0, import_api.toObservable)(this.localizeEnum(enumeration, value, parameters));
|
|
193
194
|
}
|
|
194
195
|
localizeItem(key, templateOrFunction, parameters) {
|
|
195
196
|
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 {};
|