@dws-std/i18n 1.0.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 +2 -2
- package/dist/exception/define-exception-catalog.d.ts +2 -2
- package/dist/exception/localized-http-exception.d.ts +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -12
- package/dist/message/define-message-catalog.d.ts +3 -3
- package/dist/message/type/{resolved-message.d.ts → localized-message.d.ts} +2 -2
- package/dist/resolve-message.d.ts +3 -3
- package/package.json +54 -54
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ const unauthorized = entry({
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
// This will produce a plain
|
|
59
|
+
// This will produce a plain LocalizedMessage when used in a message catalog
|
|
60
60
|
const welcome = entry<{ name: string }>({
|
|
61
61
|
translations: {
|
|
62
62
|
en: 'Welcome, {{name}}!',
|
|
@@ -124,7 +124,7 @@ const msg = DNS_MESSAGES.recordCreated();
|
|
|
124
124
|
|
|
125
125
|
### Resolving to a specific locale
|
|
126
126
|
|
|
127
|
-
`resolveMessage` takes a `LocalizedHttpException` or a `
|
|
127
|
+
`resolveMessage` takes a `LocalizedHttpException` or a `LocalizedMessage` and returns the interpolated string for the locale you want.
|
|
128
128
|
|
|
129
129
|
```ts
|
|
130
130
|
import { resolveMessage } from '@dws-std/i18n';
|
|
@@ -9,7 +9,7 @@ export type ExceptionCatalog<TDefs extends Record<string, ExceptionEntry<any>>>
|
|
|
9
9
|
* @template TDefs - Shape of the exception definitions map.
|
|
10
10
|
*/
|
|
11
11
|
export interface DefineExceptionCatalogOptions<TDefs extends Record<string, ExceptionEntry<any>>> {
|
|
12
|
-
/** Prefix prepended to every error
|
|
12
|
+
/** Prefix prepended to every error key (e.g. `'dns'` → `'dns.invalidRecordType'`). */
|
|
13
13
|
readonly namespace: string;
|
|
14
14
|
/** Locale used to build the default `message` when no locale is specified. */
|
|
15
15
|
readonly defaultLocale: keyof TDefs[keyof TDefs]['translations'];
|
|
@@ -21,7 +21,7 @@ export interface DefineExceptionCatalogOptions<TDefs extends Record<string, Exce
|
|
|
21
21
|
*
|
|
22
22
|
* Each key in `definitions` becomes a factory function that creates
|
|
23
23
|
* a {@link LocalizedHttpException} pre-filled with the right translations,
|
|
24
|
-
* HTTP status, and error
|
|
24
|
+
* HTTP status, and error key (`namespace.key`).
|
|
25
25
|
*
|
|
26
26
|
* @param options - Namespace, default locale, and exception definitions.
|
|
27
27
|
*
|
|
@@ -16,8 +16,8 @@ export interface LocalizedHttpExceptionOptions<TCause = unknown> extends HttpExc
|
|
|
16
16
|
/**
|
|
17
17
|
* HTTP exception that carries translated messages.
|
|
18
18
|
*
|
|
19
|
-
* The `message` property
|
|
20
|
-
* Use {@link resolveMessage} to get
|
|
19
|
+
* The `message` property contains the raw template for the default locale.
|
|
20
|
+
* Use {@link resolveMessage} to get the interpolated string for any locale.
|
|
21
21
|
*
|
|
22
22
|
* @template TCause - Type of the underlying cause.
|
|
23
23
|
*/
|
|
@@ -31,8 +31,8 @@ export declare class LocalizedHttpException<const TCause = unknown> extends Http
|
|
|
31
31
|
/**
|
|
32
32
|
* Creates a new localized HTTP exception.
|
|
33
33
|
*
|
|
34
|
-
* @param
|
|
34
|
+
* @param key - Application-specific error key (e.g. `'dns.invalidRecordType'`).
|
|
35
35
|
* @param init - Translations, params, status, and cause.
|
|
36
36
|
*/
|
|
37
|
-
constructor(
|
|
37
|
+
constructor(key: string, init: LocalizedHttpExceptionOptions<TCause>);
|
|
38
38
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ export { entry } from './entry';
|
|
|
2
2
|
export { defineExceptionCatalog } from './exception/define-exception-catalog';
|
|
3
3
|
export type { DefineExceptionCatalogOptions, ExceptionCatalog } from './exception/define-exception-catalog';
|
|
4
4
|
export { LocalizedHttpException } from './exception/localized-http-exception';
|
|
5
|
-
export type { LocalizedHttpExceptionOptions
|
|
5
|
+
export type { LocalizedHttpExceptionOptions } from './exception/localized-http-exception';
|
|
6
6
|
export type { ExceptionEntry } from './exception/type/exception-entry';
|
|
7
7
|
export { defineMessageCatalog } from './message/define-message-catalog';
|
|
8
8
|
export type { DefineMessageCatalogOptions, MessageCatalog } from './message/define-message-catalog';
|
|
9
|
+
export type { LocalizedMessage } from './message/type/localized-message';
|
|
9
10
|
export type { MessageEntry } from './message/type/message-entry';
|
|
10
|
-
export type { ResolvedMessage } from './message/type/resolved-message';
|
|
11
11
|
export { resolveMessage } from './resolve-message';
|
|
12
12
|
export type { Translations } from './type/translations';
|
package/dist/index.js
CHANGED
|
@@ -6,24 +6,15 @@ function entry(definition) {
|
|
|
6
6
|
// src/exception/localized-http-exception.ts
|
|
7
7
|
import { HttpException } from "@dws-std/error";
|
|
8
8
|
|
|
9
|
-
// src/resolve-message.ts
|
|
10
|
-
var _interpolate = (template, params) => template.replace(/\{\{(\w+)\}\}/g, (_, key) => params[key] ?? `{{${key}}}`);
|
|
11
|
-
var resolveMessage = (target, locale) => target.params ? _interpolate(target.translations[locale ?? target.defaultLocale] ?? "", target.params) : target.translations[locale ?? target.defaultLocale] ?? "";
|
|
12
|
-
|
|
13
|
-
// src/exception/localized-http-exception.ts
|
|
14
9
|
class LocalizedHttpException extends HttpException {
|
|
15
10
|
translations;
|
|
16
11
|
params;
|
|
17
12
|
defaultLocale;
|
|
18
|
-
constructor(
|
|
19
|
-
super(
|
|
20
|
-
translations: init.translations,
|
|
21
|
-
params: init.params,
|
|
22
|
-
defaultLocale: init.defaultLocale
|
|
23
|
-
}), {
|
|
13
|
+
constructor(key, init) {
|
|
14
|
+
super(init.translations[init.defaultLocale] ?? "", {
|
|
24
15
|
cause: init.cause,
|
|
25
16
|
status: init.status,
|
|
26
|
-
|
|
17
|
+
key
|
|
27
18
|
});
|
|
28
19
|
this.translations = init.translations;
|
|
29
20
|
this.params = init.params;
|
|
@@ -59,6 +50,9 @@ var defineMessageCatalog = (options) => {
|
|
|
59
50
|
}
|
|
60
51
|
return catalog;
|
|
61
52
|
};
|
|
53
|
+
// src/resolve-message.ts
|
|
54
|
+
var _interpolate = (template, params) => template.replace(/\{\{(\w+)\}\}/g, (_, key) => params[key] ?? `{{${key}}}`);
|
|
55
|
+
var resolveMessage = (target, locale) => target.params ? _interpolate(target.translations[locale ?? target.defaultLocale] ?? "", target.params) : target.translations[locale ?? target.defaultLocale] ?? "";
|
|
62
56
|
export {
|
|
63
57
|
resolveMessage,
|
|
64
58
|
entry,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MessageEntry } from './type/message-entry';
|
|
2
|
-
import type {
|
|
2
|
+
import type { LocalizedMessage } from './type/localized-message';
|
|
3
3
|
export type MessageCatalog<TDefs extends Record<string, MessageEntry<any>>> = {
|
|
4
|
-
readonly [K in keyof TDefs]: TDefs[K] extends MessageEntry<infer P> ? [P] extends [Record<string, never>] ? () =>
|
|
4
|
+
readonly [K in keyof TDefs]: TDefs[K] extends MessageEntry<infer P> ? [P] extends [Record<string, never>] ? () => LocalizedMessage : (params: P) => LocalizedMessage : never;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
7
|
* Configuration for {@link defineMessageCatalog}.
|
|
@@ -18,7 +18,7 @@ export interface DefineMessageCatalogOptions<TDefs extends Record<string, Messag
|
|
|
18
18
|
* Builds a typed message catalog from a set of {@link MessageEntry} definitions.
|
|
19
19
|
*
|
|
20
20
|
* Each key in `definitions` becomes a factory function that creates
|
|
21
|
-
* a {@link
|
|
21
|
+
* a {@link LocalizedMessage} pre-filled with the right translations and default locale.
|
|
22
22
|
*
|
|
23
23
|
* @param options - Default locale and message definitions.
|
|
24
24
|
*
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Translations } from '../../type/translations';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Localized message carrying translations and interpolation parameters.
|
|
4
4
|
*
|
|
5
5
|
* Returned by the factory functions generated by `defineMessageCatalog`.
|
|
6
6
|
* Pass it to {@link resolveMessage} to get the final string for a given locale.
|
|
7
7
|
*/
|
|
8
|
-
export interface
|
|
8
|
+
export interface LocalizedMessage {
|
|
9
9
|
/** All available translations keyed by locale. */
|
|
10
10
|
readonly translations: Translations;
|
|
11
11
|
/** Parameter values to interpolate into `{{placeholder}}` tokens. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LocalizedHttpException } from './exception/localized-http-exception';
|
|
2
|
-
import type {
|
|
2
|
+
import type { LocalizedMessage } from './message/type/localized-message';
|
|
3
3
|
/**
|
|
4
|
-
* Turns a {@link
|
|
4
|
+
* Turns a {@link LocalizedMessage} or {@link LocalizedHttpException} into
|
|
5
5
|
* a plain string for the requested locale.
|
|
6
6
|
*
|
|
7
7
|
* `{{placeholder}}` tokens are replaced with matching values from `target.params`.
|
|
@@ -13,4 +13,4 @@ import type { ResolvedMessage } from './message/type/resolved-message';
|
|
|
13
13
|
*
|
|
14
14
|
* @returns Translated string with placeholders interpolated.
|
|
15
15
|
*/
|
|
16
|
-
export declare const resolveMessage: (target: LocalizedHttpException |
|
|
16
|
+
export declare const resolveMessage: (target: LocalizedHttpException | LocalizedMessage, locale?: string) => string;
|
package/package.json
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
2
|
+
"name": "@dws-std/i18n",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Type-safe i18n for TypeScript — define localized exception and message catalogs with compile-time validated parameters.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"bun",
|
|
7
|
+
"dws",
|
|
8
|
+
"exception",
|
|
9
|
+
"http-error",
|
|
10
|
+
"i18n",
|
|
11
|
+
"internationalization",
|
|
12
|
+
"l10n",
|
|
13
|
+
"localization",
|
|
14
|
+
"translation"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "Dominus Web Services (DWS)",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/Dominus-Web-Service/std",
|
|
21
|
+
"directory": "packages/i18n"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"type": "module",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "bun builder.ts",
|
|
35
|
+
"docs": "bunx typedoc --tsconfig tsconfig.build.json",
|
|
36
|
+
"fmt:check": "oxfmt --check",
|
|
37
|
+
"fmt": "oxfmt",
|
|
38
|
+
"lint:fix": "oxlint --type-aware --type-check --fix ./src",
|
|
39
|
+
"lint:github": "oxlint --type-aware --type-check --format=github ./src",
|
|
40
|
+
"lint": "oxlint --type-aware --type-check ./src",
|
|
41
|
+
"test": "bun test --pass-with-no-tests --coverage"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@dws-std/error": "^2.1.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/bun": "^1.3.11",
|
|
48
|
+
"oxfmt": "0.41.0",
|
|
49
|
+
"oxlint": "1.56.0",
|
|
50
|
+
"oxlint-tsgolint": "0.17.1",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@dws-std/error": "^2.1.0"
|
|
55
|
+
}
|
|
56
56
|
}
|