@embedpdf/plugin-i18n 3.0.0-next.14 → 3.0.0-next.15
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/dist/contract-D2EGxESh.d.cts +140 -0
- package/dist/contract-D2EGxESh.d.ts +140 -0
- package/dist/contract-TF72RUxK.cjs +25 -0
- package/dist/contract-TF72RUxK.cjs.map +1 -0
- package/dist/contract-w0S-ipz5.js +15 -0
- package/dist/contract-w0S-ipz5.js.map +1 -0
- package/dist/contract.cjs +2 -1
- package/dist/contract.d.cts +2 -2
- package/dist/contract.d.ts +2 -2
- package/dist/contract.js +2 -2
- package/dist/index.cjs +926 -192
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -38
- package/dist/index.d.ts +26 -38
- package/dist/index.js +926 -192
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/contract-BIk4Kv-7.cjs +0 -11
- package/dist/contract-BIk4Kv-7.cjs.map +0 -1
- package/dist/contract-D08iYq9-.js +0 -7
- package/dist/contract-D08iYq9-.js.map +0 -1
- package/dist/contract-DCt9Ikqu.d.cts +0 -116
- package/dist/contract-DCt9Ikqu.d.ts +0 -116
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { DeepPartial, EventHook, OperationOptions, PluginErrorInfo, SettingsApi, Unsubscribe } from "@embedpdf/core";
|
|
2
|
+
//#region src/token.d.ts
|
|
3
|
+
declare const I18nToken: import("@embedpdf/core").CapabilityToken<I18nCapability>;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/contract.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* A tree of strings. A leaf may hold `{name}` slots. A dotted key is the same as a nested one:
|
|
8
|
+
* `{ 'review.reject': 'Reject' }` is `{ review: { reject: 'Reject' } }`.
|
|
9
|
+
*/
|
|
10
|
+
interface TranslationDictionary {
|
|
11
|
+
readonly [key: string]: string | TranslationDictionary;
|
|
12
|
+
}
|
|
13
|
+
/** How a language reads. */
|
|
14
|
+
type TextDirection = 'ltr' | 'rtl';
|
|
15
|
+
/** A language and its strings. */
|
|
16
|
+
interface Locale {
|
|
17
|
+
/** Its language tag (RFC 5646): `'en'`, `'nl'`, `'ar'`, `'zh-CN'`. */
|
|
18
|
+
readonly code: string;
|
|
19
|
+
/** Its name in itself, as a language picker shows it: `'Nederlands'`. */
|
|
20
|
+
readonly name: string;
|
|
21
|
+
/** How it reads; `'ltr'` when left out. */
|
|
22
|
+
readonly direction?: TextDirection;
|
|
23
|
+
readonly translations: TranslationDictionary;
|
|
24
|
+
}
|
|
25
|
+
/** Loads a language the first time someone switches to it. */
|
|
26
|
+
type LocaleLoader = () => Promise<Locale>;
|
|
27
|
+
/**
|
|
28
|
+
* The i18n plugin's settings. `i18nPlugin(config)` registers them over
|
|
29
|
+
* {@link I18N_DEFAULTS}, and `updateSettings()` changes them while the app runs: a new `locale`
|
|
30
|
+
* switches to it, new `locales` are registered, and `fallbackLocale` and `loaders` apply to the
|
|
31
|
+
* next lookup and the next switch.
|
|
32
|
+
*/
|
|
33
|
+
interface I18nSettings {
|
|
34
|
+
/**
|
|
35
|
+
* The language to start with; `null` starts with `fallbackLocale`. Pick it outside the plugin,
|
|
36
|
+
* which never reads the browser: `negotiateLocale(codes, navigator.languages)`. A language in
|
|
37
|
+
* `loaders` shows the fallback language until it has loaded.
|
|
38
|
+
*/
|
|
39
|
+
readonly locale: string | null;
|
|
40
|
+
/** The language to use for a string another language doesn't have. */
|
|
41
|
+
readonly fallbackLocale: string;
|
|
42
|
+
/** Languages loaded from the start. */
|
|
43
|
+
readonly locales: readonly Locale[];
|
|
44
|
+
/**
|
|
45
|
+
* Languages loaded the first time someone switches to them, by code. Until then a language
|
|
46
|
+
* picker shows the code as the name.
|
|
47
|
+
*/
|
|
48
|
+
readonly loaders: Readonly<Record<string, LocaleLoader>>;
|
|
49
|
+
}
|
|
50
|
+
/** What the i18n settings are when the app registers none. */
|
|
51
|
+
declare const I18N_DEFAULTS: I18nSettings;
|
|
52
|
+
/** What `i18nPlugin(config)` takes: any of the settings, merged over the defaults. */
|
|
53
|
+
type I18nConfig = DeepPartial<I18nSettings>;
|
|
54
|
+
interface TranslateOptions {
|
|
55
|
+
/**
|
|
56
|
+
* The values of the string's `{name}` slots. A number `count` also picks the plural: a key
|
|
57
|
+
* whose string is `{ one, other }` gives the form for the language's plural rule
|
|
58
|
+
* (`Intl.PluralRules`), and `other` when the rule's form is missing.
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* // pages: { one: '{count} page', other: '{count} pages' }
|
|
62
|
+
* t('pages', { params: { count: 1 } }) // '1 page'
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
params?: Record<string, string | number>;
|
|
66
|
+
/**
|
|
67
|
+
* Another key, read in each language that has no string for the key, before the fallback
|
|
68
|
+
* language is: a specific key in front of a general one.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* // a language's 'review:approve', else its 'commands.approve'
|
|
72
|
+
* t('review:approve', { fallbackKey: 'commands.approve' })
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
fallbackKey?: string;
|
|
76
|
+
/** What to show, with its slots filled, when no language has the key; the key itself otherwise. */
|
|
77
|
+
fallback?: string;
|
|
78
|
+
}
|
|
79
|
+
/** A language as a picker shows it: the loaded ones and the ones in `loaders`. */
|
|
80
|
+
interface LocaleInfo {
|
|
81
|
+
readonly code: string;
|
|
82
|
+
/** Its name in itself; the code until a language in `loaders` has loaded. */
|
|
83
|
+
readonly name: string;
|
|
84
|
+
readonly direction: TextDirection;
|
|
85
|
+
readonly loaded: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface LocaleChangedEvent {
|
|
88
|
+
readonly locale: string;
|
|
89
|
+
readonly previousLocale: string;
|
|
90
|
+
}
|
|
91
|
+
interface LocaleLoadFailedEvent {
|
|
92
|
+
readonly locale: string;
|
|
93
|
+
readonly error: PluginErrorInfo;
|
|
94
|
+
}
|
|
95
|
+
interface I18nCapability extends SettingsApi<I18nSettings> {
|
|
96
|
+
/**
|
|
97
|
+
* A string in the current language, with `params` filled in: the app's strings for the
|
|
98
|
+
* language, then EmbedPDF's own (for the key, then `options.fallbackKey`), then the same for
|
|
99
|
+
* the fallback language, then `options.fallback`, then the key. A key no language has warns
|
|
100
|
+
* once in the console.
|
|
101
|
+
*/
|
|
102
|
+
t(key: string, options?: TranslateOptions): string;
|
|
103
|
+
/**
|
|
104
|
+
* A `t` function that stays the same until the language or the strings change, so a memoized
|
|
105
|
+
* component holding it renders again exactly when its strings may differ.
|
|
106
|
+
*/
|
|
107
|
+
getTranslator(): (key: string, options?: TranslateOptions) => string;
|
|
108
|
+
/** Whether a key has a string in the current or the fallback language. Never warns. */
|
|
109
|
+
hasKey(key: string): boolean;
|
|
110
|
+
/** The current language's code. */
|
|
111
|
+
getLocale(): string;
|
|
112
|
+
/** How the current language reads: set it as `dir` on your viewer's root. */
|
|
113
|
+
getDirection(): TextDirection;
|
|
114
|
+
/** Every language you can switch to, loaded or not, in the order they were added. The same array until one changes. */
|
|
115
|
+
listLocales(): readonly LocaleInfo[];
|
|
116
|
+
/** The code of the language being loaded, or `null`. */
|
|
117
|
+
getLoadingLocale(): string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Switch the language, loading it first when it's in `loaders`. Resolves once it shows, and
|
|
120
|
+
* fires `onLocaleChanged`. Rejects `not-found` for a code that is neither loaded nor in
|
|
121
|
+
* `loaders`, `operation-failed` when it can't load (and fires `onLocaleLoadFailed`), and
|
|
122
|
+
* `operation-cancelled` when the signal fires or a newer call replaces it.
|
|
123
|
+
*/
|
|
124
|
+
setLocale(code: string, options?: OperationOptions): Promise<void>;
|
|
125
|
+
/** Add a whole language, and get a function that removes it again. */
|
|
126
|
+
registerLocale(locale: Locale): Unsubscribe;
|
|
127
|
+
/**
|
|
128
|
+
* Add strings to a language, loaded or not, replacing the ones with the same key; dotted keys
|
|
129
|
+
* work. A language in `loaders` gets them when it loads, on top of its own. Throws `not-found`
|
|
130
|
+
* for a code that is neither loaded nor in `loaders`.
|
|
131
|
+
*/
|
|
132
|
+
addTranslations(code: string, translations: TranslationDictionary): void;
|
|
133
|
+
/** The current language changed and shows; never while a language is still loading. */
|
|
134
|
+
readonly onLocaleChanged: EventHook<LocaleChangedEvent>;
|
|
135
|
+
/** A language in `loaders` couldn't be loaded; the current language stays. */
|
|
136
|
+
readonly onLocaleLoadFailed: EventHook<LocaleLoadFailedEvent>;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { Locale as a, LocaleLoadFailedEvent as c, TranslateOptions as d, TranslationDictionary as f, I18nSettings as i, LocaleLoader as l, I18nCapability as n, LocaleChangedEvent as o, I18nToken as p, I18nConfig as r, LocaleInfo as s, I18N_DEFAULTS as t, TextDirection as u };
|
|
140
|
+
//# sourceMappingURL=contract-D2EGxESh.d.cts.map
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { DeepPartial, EventHook, OperationOptions, PluginErrorInfo, SettingsApi, Unsubscribe } from "@embedpdf/core";
|
|
2
|
+
//#region src/token.d.ts
|
|
3
|
+
declare const I18nToken: import("@embedpdf/core").CapabilityToken<I18nCapability>;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/contract.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* A tree of strings. A leaf may hold `{name}` slots. A dotted key is the same as a nested one:
|
|
8
|
+
* `{ 'review.reject': 'Reject' }` is `{ review: { reject: 'Reject' } }`.
|
|
9
|
+
*/
|
|
10
|
+
interface TranslationDictionary {
|
|
11
|
+
readonly [key: string]: string | TranslationDictionary;
|
|
12
|
+
}
|
|
13
|
+
/** How a language reads. */
|
|
14
|
+
type TextDirection = 'ltr' | 'rtl';
|
|
15
|
+
/** A language and its strings. */
|
|
16
|
+
interface Locale {
|
|
17
|
+
/** Its language tag (RFC 5646): `'en'`, `'nl'`, `'ar'`, `'zh-CN'`. */
|
|
18
|
+
readonly code: string;
|
|
19
|
+
/** Its name in itself, as a language picker shows it: `'Nederlands'`. */
|
|
20
|
+
readonly name: string;
|
|
21
|
+
/** How it reads; `'ltr'` when left out. */
|
|
22
|
+
readonly direction?: TextDirection;
|
|
23
|
+
readonly translations: TranslationDictionary;
|
|
24
|
+
}
|
|
25
|
+
/** Loads a language the first time someone switches to it. */
|
|
26
|
+
type LocaleLoader = () => Promise<Locale>;
|
|
27
|
+
/**
|
|
28
|
+
* The i18n plugin's settings. `i18nPlugin(config)` registers them over
|
|
29
|
+
* {@link I18N_DEFAULTS}, and `updateSettings()` changes them while the app runs: a new `locale`
|
|
30
|
+
* switches to it, new `locales` are registered, and `fallbackLocale` and `loaders` apply to the
|
|
31
|
+
* next lookup and the next switch.
|
|
32
|
+
*/
|
|
33
|
+
interface I18nSettings {
|
|
34
|
+
/**
|
|
35
|
+
* The language to start with; `null` starts with `fallbackLocale`. Pick it outside the plugin,
|
|
36
|
+
* which never reads the browser: `negotiateLocale(codes, navigator.languages)`. A language in
|
|
37
|
+
* `loaders` shows the fallback language until it has loaded.
|
|
38
|
+
*/
|
|
39
|
+
readonly locale: string | null;
|
|
40
|
+
/** The language to use for a string another language doesn't have. */
|
|
41
|
+
readonly fallbackLocale: string;
|
|
42
|
+
/** Languages loaded from the start. */
|
|
43
|
+
readonly locales: readonly Locale[];
|
|
44
|
+
/**
|
|
45
|
+
* Languages loaded the first time someone switches to them, by code. Until then a language
|
|
46
|
+
* picker shows the code as the name.
|
|
47
|
+
*/
|
|
48
|
+
readonly loaders: Readonly<Record<string, LocaleLoader>>;
|
|
49
|
+
}
|
|
50
|
+
/** What the i18n settings are when the app registers none. */
|
|
51
|
+
declare const I18N_DEFAULTS: I18nSettings;
|
|
52
|
+
/** What `i18nPlugin(config)` takes: any of the settings, merged over the defaults. */
|
|
53
|
+
type I18nConfig = DeepPartial<I18nSettings>;
|
|
54
|
+
interface TranslateOptions {
|
|
55
|
+
/**
|
|
56
|
+
* The values of the string's `{name}` slots. A number `count` also picks the plural: a key
|
|
57
|
+
* whose string is `{ one, other }` gives the form for the language's plural rule
|
|
58
|
+
* (`Intl.PluralRules`), and `other` when the rule's form is missing.
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* // pages: { one: '{count} page', other: '{count} pages' }
|
|
62
|
+
* t('pages', { params: { count: 1 } }) // '1 page'
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
params?: Record<string, string | number>;
|
|
66
|
+
/**
|
|
67
|
+
* Another key, read in each language that has no string for the key, before the fallback
|
|
68
|
+
* language is: a specific key in front of a general one.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* // a language's 'review:approve', else its 'commands.approve'
|
|
72
|
+
* t('review:approve', { fallbackKey: 'commands.approve' })
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
fallbackKey?: string;
|
|
76
|
+
/** What to show, with its slots filled, when no language has the key; the key itself otherwise. */
|
|
77
|
+
fallback?: string;
|
|
78
|
+
}
|
|
79
|
+
/** A language as a picker shows it: the loaded ones and the ones in `loaders`. */
|
|
80
|
+
interface LocaleInfo {
|
|
81
|
+
readonly code: string;
|
|
82
|
+
/** Its name in itself; the code until a language in `loaders` has loaded. */
|
|
83
|
+
readonly name: string;
|
|
84
|
+
readonly direction: TextDirection;
|
|
85
|
+
readonly loaded: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface LocaleChangedEvent {
|
|
88
|
+
readonly locale: string;
|
|
89
|
+
readonly previousLocale: string;
|
|
90
|
+
}
|
|
91
|
+
interface LocaleLoadFailedEvent {
|
|
92
|
+
readonly locale: string;
|
|
93
|
+
readonly error: PluginErrorInfo;
|
|
94
|
+
}
|
|
95
|
+
interface I18nCapability extends SettingsApi<I18nSettings> {
|
|
96
|
+
/**
|
|
97
|
+
* A string in the current language, with `params` filled in: the app's strings for the
|
|
98
|
+
* language, then EmbedPDF's own (for the key, then `options.fallbackKey`), then the same for
|
|
99
|
+
* the fallback language, then `options.fallback`, then the key. A key no language has warns
|
|
100
|
+
* once in the console.
|
|
101
|
+
*/
|
|
102
|
+
t(key: string, options?: TranslateOptions): string;
|
|
103
|
+
/**
|
|
104
|
+
* A `t` function that stays the same until the language or the strings change, so a memoized
|
|
105
|
+
* component holding it renders again exactly when its strings may differ.
|
|
106
|
+
*/
|
|
107
|
+
getTranslator(): (key: string, options?: TranslateOptions) => string;
|
|
108
|
+
/** Whether a key has a string in the current or the fallback language. Never warns. */
|
|
109
|
+
hasKey(key: string): boolean;
|
|
110
|
+
/** The current language's code. */
|
|
111
|
+
getLocale(): string;
|
|
112
|
+
/** How the current language reads: set it as `dir` on your viewer's root. */
|
|
113
|
+
getDirection(): TextDirection;
|
|
114
|
+
/** Every language you can switch to, loaded or not, in the order they were added. The same array until one changes. */
|
|
115
|
+
listLocales(): readonly LocaleInfo[];
|
|
116
|
+
/** The code of the language being loaded, or `null`. */
|
|
117
|
+
getLoadingLocale(): string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Switch the language, loading it first when it's in `loaders`. Resolves once it shows, and
|
|
120
|
+
* fires `onLocaleChanged`. Rejects `not-found` for a code that is neither loaded nor in
|
|
121
|
+
* `loaders`, `operation-failed` when it can't load (and fires `onLocaleLoadFailed`), and
|
|
122
|
+
* `operation-cancelled` when the signal fires or a newer call replaces it.
|
|
123
|
+
*/
|
|
124
|
+
setLocale(code: string, options?: OperationOptions): Promise<void>;
|
|
125
|
+
/** Add a whole language, and get a function that removes it again. */
|
|
126
|
+
registerLocale(locale: Locale): Unsubscribe;
|
|
127
|
+
/**
|
|
128
|
+
* Add strings to a language, loaded or not, replacing the ones with the same key; dotted keys
|
|
129
|
+
* work. A language in `loaders` gets them when it loads, on top of its own. Throws `not-found`
|
|
130
|
+
* for a code that is neither loaded nor in `loaders`.
|
|
131
|
+
*/
|
|
132
|
+
addTranslations(code: string, translations: TranslationDictionary): void;
|
|
133
|
+
/** The current language changed and shows; never while a language is still loading. */
|
|
134
|
+
readonly onLocaleChanged: EventHook<LocaleChangedEvent>;
|
|
135
|
+
/** A language in `loaders` couldn't be loaded; the current language stays. */
|
|
136
|
+
readonly onLocaleLoadFailed: EventHook<LocaleLoadFailedEvent>;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { Locale as a, LocaleLoadFailedEvent as c, TranslateOptions as d, TranslationDictionary as f, I18nSettings as i, LocaleLoader as l, I18nCapability as n, LocaleChangedEvent as o, I18nToken as p, I18nConfig as r, LocaleInfo as s, I18N_DEFAULTS as t, TextDirection as u };
|
|
140
|
+
//# sourceMappingURL=contract-D2EGxESh.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/token.ts
|
|
2
|
+
/** The package token, created once here and re-exported by `contract.ts`. */
|
|
3
|
+
const I18nToken = (0, require("@embedpdf/core").createCapabilityToken)("i18n", { hint: `add i18nPlugin() from '@embedpdf/plugin-i18n' to your plugins list` });
|
|
4
|
+
/** What the i18n settings are when the app registers none. */
|
|
5
|
+
const I18N_DEFAULTS = {
|
|
6
|
+
locale: null,
|
|
7
|
+
fallbackLocale: "en",
|
|
8
|
+
locales: [],
|
|
9
|
+
loaders: {}
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
Object.defineProperty(exports, "I18N_DEFAULTS", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function() {
|
|
15
|
+
return I18N_DEFAULTS;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "I18nToken", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function() {
|
|
21
|
+
return I18nToken;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=contract-TF72RUxK.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-TF72RUxK.cjs","names":[],"sources":["../src/token.ts","../src/contract.ts"],"sourcesContent":["/** The package token, created once here and re-exported by `contract.ts`. */\nimport { createCapabilityToken } from '@embedpdf/core';\n\nimport type { I18nCapability } from './contract';\n\nexport const I18nToken = createCapabilityToken<I18nCapability>('i18n', {\n hint: `add i18nPlugin() from '@embedpdf/plugin-i18n' to your plugins list`,\n});\n","/**\n * @embedpdf/plugin-i18n/contract — translations and the current language.\n *\n * Languages are data: the packs live in the plugin's state, so `t()` is a pure\n * read and every reader follows the kernel's one change stream. The plugin is\n * workspace-scoped and needs no engine or document, so it translates a loading\n * screen and a password prompt too. It ships EmbedPDF's own strings (the\n * standard commands' labels) in eight languages, under the app's.\n */\nimport type {\n DeepPartial,\n EventHook,\n OperationOptions,\n PluginErrorInfo,\n SettingsApi,\n Unsubscribe,\n} from '@embedpdf/core';\n\nexport { I18nToken } from './token';\n\n/**\n * A tree of strings. A leaf may hold `{name}` slots. A dotted key is the same as a nested one:\n * `{ 'review.reject': 'Reject' }` is `{ review: { reject: 'Reject' } }`.\n */\nexport interface TranslationDictionary {\n readonly [key: string]: string | TranslationDictionary;\n}\n\n/** How a language reads. */\nexport type TextDirection = 'ltr' | 'rtl';\n\n/** A language and its strings. */\nexport interface Locale {\n /** Its language tag (RFC 5646): `'en'`, `'nl'`, `'ar'`, `'zh-CN'`. */\n readonly code: string;\n /** Its name in itself, as a language picker shows it: `'Nederlands'`. */\n readonly name: string;\n /** How it reads; `'ltr'` when left out. */\n readonly direction?: TextDirection;\n readonly translations: TranslationDictionary;\n}\n\n/** Loads a language the first time someone switches to it. */\nexport type LocaleLoader = () => Promise<Locale>;\n\n/**\n * The i18n plugin's settings. `i18nPlugin(config)` registers them over\n * {@link I18N_DEFAULTS}, and `updateSettings()` changes them while the app runs: a new `locale`\n * switches to it, new `locales` are registered, and `fallbackLocale` and `loaders` apply to the\n * next lookup and the next switch.\n */\nexport interface I18nSettings {\n /**\n * The language to start with; `null` starts with `fallbackLocale`. Pick it outside the plugin,\n * which never reads the browser: `negotiateLocale(codes, navigator.languages)`. A language in\n * `loaders` shows the fallback language until it has loaded.\n */\n readonly locale: string | null;\n /** The language to use for a string another language doesn't have. */\n readonly fallbackLocale: string;\n /** Languages loaded from the start. */\n readonly locales: readonly Locale[];\n /**\n * Languages loaded the first time someone switches to them, by code. Until then a language\n * picker shows the code as the name.\n */\n readonly loaders: Readonly<Record<string, LocaleLoader>>;\n}\n\nconst NO_LOCALES: readonly Locale[] = [];\nconst NO_LOADERS: Readonly<Record<string, LocaleLoader>> = {};\n\n/** What the i18n settings are when the app registers none. */\nexport const I18N_DEFAULTS: I18nSettings = {\n locale: null,\n fallbackLocale: 'en',\n locales: NO_LOCALES,\n loaders: NO_LOADERS,\n};\n\n/** What `i18nPlugin(config)` takes: any of the settings, merged over the defaults. */\nexport type I18nConfig = DeepPartial<I18nSettings>;\n\nexport interface TranslateOptions {\n /**\n * The values of the string's `{name}` slots. A number `count` also picks the plural: a key\n * whose string is `{ one, other }` gives the form for the language's plural rule\n * (`Intl.PluralRules`), and `other` when the rule's form is missing.\n *\n * ```ts\n * // pages: { one: '{count} page', other: '{count} pages' }\n * t('pages', { params: { count: 1 } }) // '1 page'\n * ```\n */\n params?: Record<string, string | number>;\n /**\n * Another key, read in each language that has no string for the key, before the fallback\n * language is: a specific key in front of a general one.\n *\n * ```ts\n * // a language's 'review:approve', else its 'commands.approve'\n * t('review:approve', { fallbackKey: 'commands.approve' })\n * ```\n */\n fallbackKey?: string;\n /** What to show, with its slots filled, when no language has the key; the key itself otherwise. */\n fallback?: string;\n}\n\n/** A language as a picker shows it: the loaded ones and the ones in `loaders`. */\nexport interface LocaleInfo {\n readonly code: string;\n /** Its name in itself; the code until a language in `loaders` has loaded. */\n readonly name: string;\n readonly direction: TextDirection;\n readonly loaded: boolean;\n}\n\n// ── events ──\nexport interface LocaleChangedEvent {\n readonly locale: string;\n readonly previousLocale: string;\n}\nexport interface LocaleLoadFailedEvent {\n readonly locale: string;\n readonly error: PluginErrorInfo;\n}\n\nexport interface I18nCapability extends SettingsApi<I18nSettings> {\n /**\n * A string in the current language, with `params` filled in: the app's strings for the\n * language, then EmbedPDF's own (for the key, then `options.fallbackKey`), then the same for\n * the fallback language, then `options.fallback`, then the key. A key no language has warns\n * once in the console.\n */\n t(key: string, options?: TranslateOptions): string;\n /**\n * A `t` function that stays the same until the language or the strings change, so a memoized\n * component holding it renders again exactly when its strings may differ.\n */\n getTranslator(): (key: string, options?: TranslateOptions) => string;\n /** Whether a key has a string in the current or the fallback language. Never warns. */\n hasKey(key: string): boolean;\n /** The current language's code. */\n getLocale(): string;\n /** How the current language reads: set it as `dir` on your viewer's root. */\n getDirection(): TextDirection;\n /** Every language you can switch to, loaded or not, in the order they were added. The same array until one changes. */\n listLocales(): readonly LocaleInfo[];\n /** The code of the language being loaded, or `null`. */\n getLoadingLocale(): string | null;\n /**\n * Switch the language, loading it first when it's in `loaders`. Resolves once it shows, and\n * fires `onLocaleChanged`. Rejects `not-found` for a code that is neither loaded nor in\n * `loaders`, `operation-failed` when it can't load (and fires `onLocaleLoadFailed`), and\n * `operation-cancelled` when the signal fires or a newer call replaces it.\n */\n setLocale(code: string, options?: OperationOptions): Promise<void>;\n /** Add a whole language, and get a function that removes it again. */\n registerLocale(locale: Locale): Unsubscribe;\n /**\n * Add strings to a language, loaded or not, replacing the ones with the same key; dotted keys\n * work. A language in `loaders` gets them when it loads, on top of its own. Throws `not-found`\n * for a code that is neither loaded nor in `loaders`.\n */\n addTranslations(code: string, translations: TranslationDictionary): void;\n /** The current language changed and shows; never while a language is still loading. */\n readonly onLocaleChanged: EventHook<LocaleChangedEvent>;\n /** A language in `loaders` couldn't be loaded; the current language stays. */\n readonly onLocaleLoadFailed: EventHook<LocaleLoadFailedEvent>;\n}\n"],"mappings":";;AAKA,MAAa,aAAA,2BAAA,CAAA,CAAA,sBAAA,CAAkD,QAAQ,EACrE,MAAM,qEACR,CAAC;;ACkED,MAAa,gBAA8B;CACzC,QAAQ;CACR,gBAAgB;CAChB,SAAS,CAAA;CACT,SAAS,CAAA;AACX"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createCapabilityToken } from "@embedpdf/core";
|
|
2
|
+
//#region src/token.ts
|
|
3
|
+
/** The package token, created once here and re-exported by `contract.ts`. */
|
|
4
|
+
const I18nToken = createCapabilityToken("i18n", { hint: `add i18nPlugin() from '@embedpdf/plugin-i18n' to your plugins list` });
|
|
5
|
+
/** What the i18n settings are when the app registers none. */
|
|
6
|
+
const I18N_DEFAULTS = {
|
|
7
|
+
locale: null,
|
|
8
|
+
fallbackLocale: "en",
|
|
9
|
+
locales: [],
|
|
10
|
+
loaders: {}
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { I18nToken as n, I18N_DEFAULTS as t };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=contract-w0S-ipz5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-w0S-ipz5.js","names":[],"sources":["../src/token.ts","../src/contract.ts"],"sourcesContent":["/** The package token, created once here and re-exported by `contract.ts`. */\nimport { createCapabilityToken } from '@embedpdf/core';\n\nimport type { I18nCapability } from './contract';\n\nexport const I18nToken = createCapabilityToken<I18nCapability>('i18n', {\n hint: `add i18nPlugin() from '@embedpdf/plugin-i18n' to your plugins list`,\n});\n","/**\n * @embedpdf/plugin-i18n/contract — translations and the current language.\n *\n * Languages are data: the packs live in the plugin's state, so `t()` is a pure\n * read and every reader follows the kernel's one change stream. The plugin is\n * workspace-scoped and needs no engine or document, so it translates a loading\n * screen and a password prompt too. It ships EmbedPDF's own strings (the\n * standard commands' labels) in eight languages, under the app's.\n */\nimport type {\n DeepPartial,\n EventHook,\n OperationOptions,\n PluginErrorInfo,\n SettingsApi,\n Unsubscribe,\n} from '@embedpdf/core';\n\nexport { I18nToken } from './token';\n\n/**\n * A tree of strings. A leaf may hold `{name}` slots. A dotted key is the same as a nested one:\n * `{ 'review.reject': 'Reject' }` is `{ review: { reject: 'Reject' } }`.\n */\nexport interface TranslationDictionary {\n readonly [key: string]: string | TranslationDictionary;\n}\n\n/** How a language reads. */\nexport type TextDirection = 'ltr' | 'rtl';\n\n/** A language and its strings. */\nexport interface Locale {\n /** Its language tag (RFC 5646): `'en'`, `'nl'`, `'ar'`, `'zh-CN'`. */\n readonly code: string;\n /** Its name in itself, as a language picker shows it: `'Nederlands'`. */\n readonly name: string;\n /** How it reads; `'ltr'` when left out. */\n readonly direction?: TextDirection;\n readonly translations: TranslationDictionary;\n}\n\n/** Loads a language the first time someone switches to it. */\nexport type LocaleLoader = () => Promise<Locale>;\n\n/**\n * The i18n plugin's settings. `i18nPlugin(config)` registers them over\n * {@link I18N_DEFAULTS}, and `updateSettings()` changes them while the app runs: a new `locale`\n * switches to it, new `locales` are registered, and `fallbackLocale` and `loaders` apply to the\n * next lookup and the next switch.\n */\nexport interface I18nSettings {\n /**\n * The language to start with; `null` starts with `fallbackLocale`. Pick it outside the plugin,\n * which never reads the browser: `negotiateLocale(codes, navigator.languages)`. A language in\n * `loaders` shows the fallback language until it has loaded.\n */\n readonly locale: string | null;\n /** The language to use for a string another language doesn't have. */\n readonly fallbackLocale: string;\n /** Languages loaded from the start. */\n readonly locales: readonly Locale[];\n /**\n * Languages loaded the first time someone switches to them, by code. Until then a language\n * picker shows the code as the name.\n */\n readonly loaders: Readonly<Record<string, LocaleLoader>>;\n}\n\nconst NO_LOCALES: readonly Locale[] = [];\nconst NO_LOADERS: Readonly<Record<string, LocaleLoader>> = {};\n\n/** What the i18n settings are when the app registers none. */\nexport const I18N_DEFAULTS: I18nSettings = {\n locale: null,\n fallbackLocale: 'en',\n locales: NO_LOCALES,\n loaders: NO_LOADERS,\n};\n\n/** What `i18nPlugin(config)` takes: any of the settings, merged over the defaults. */\nexport type I18nConfig = DeepPartial<I18nSettings>;\n\nexport interface TranslateOptions {\n /**\n * The values of the string's `{name}` slots. A number `count` also picks the plural: a key\n * whose string is `{ one, other }` gives the form for the language's plural rule\n * (`Intl.PluralRules`), and `other` when the rule's form is missing.\n *\n * ```ts\n * // pages: { one: '{count} page', other: '{count} pages' }\n * t('pages', { params: { count: 1 } }) // '1 page'\n * ```\n */\n params?: Record<string, string | number>;\n /**\n * Another key, read in each language that has no string for the key, before the fallback\n * language is: a specific key in front of a general one.\n *\n * ```ts\n * // a language's 'review:approve', else its 'commands.approve'\n * t('review:approve', { fallbackKey: 'commands.approve' })\n * ```\n */\n fallbackKey?: string;\n /** What to show, with its slots filled, when no language has the key; the key itself otherwise. */\n fallback?: string;\n}\n\n/** A language as a picker shows it: the loaded ones and the ones in `loaders`. */\nexport interface LocaleInfo {\n readonly code: string;\n /** Its name in itself; the code until a language in `loaders` has loaded. */\n readonly name: string;\n readonly direction: TextDirection;\n readonly loaded: boolean;\n}\n\n// ── events ──\nexport interface LocaleChangedEvent {\n readonly locale: string;\n readonly previousLocale: string;\n}\nexport interface LocaleLoadFailedEvent {\n readonly locale: string;\n readonly error: PluginErrorInfo;\n}\n\nexport interface I18nCapability extends SettingsApi<I18nSettings> {\n /**\n * A string in the current language, with `params` filled in: the app's strings for the\n * language, then EmbedPDF's own (for the key, then `options.fallbackKey`), then the same for\n * the fallback language, then `options.fallback`, then the key. A key no language has warns\n * once in the console.\n */\n t(key: string, options?: TranslateOptions): string;\n /**\n * A `t` function that stays the same until the language or the strings change, so a memoized\n * component holding it renders again exactly when its strings may differ.\n */\n getTranslator(): (key: string, options?: TranslateOptions) => string;\n /** Whether a key has a string in the current or the fallback language. Never warns. */\n hasKey(key: string): boolean;\n /** The current language's code. */\n getLocale(): string;\n /** How the current language reads: set it as `dir` on your viewer's root. */\n getDirection(): TextDirection;\n /** Every language you can switch to, loaded or not, in the order they were added. The same array until one changes. */\n listLocales(): readonly LocaleInfo[];\n /** The code of the language being loaded, or `null`. */\n getLoadingLocale(): string | null;\n /**\n * Switch the language, loading it first when it's in `loaders`. Resolves once it shows, and\n * fires `onLocaleChanged`. Rejects `not-found` for a code that is neither loaded nor in\n * `loaders`, `operation-failed` when it can't load (and fires `onLocaleLoadFailed`), and\n * `operation-cancelled` when the signal fires or a newer call replaces it.\n */\n setLocale(code: string, options?: OperationOptions): Promise<void>;\n /** Add a whole language, and get a function that removes it again. */\n registerLocale(locale: Locale): Unsubscribe;\n /**\n * Add strings to a language, loaded or not, replacing the ones with the same key; dotted keys\n * work. A language in `loaders` gets them when it loads, on top of its own. Throws `not-found`\n * for a code that is neither loaded nor in `loaders`.\n */\n addTranslations(code: string, translations: TranslationDictionary): void;\n /** The current language changed and shows; never while a language is still loading. */\n readonly onLocaleChanged: EventHook<LocaleChangedEvent>;\n /** A language in `loaders` couldn't be loaded; the current language stays. */\n readonly onLocaleLoadFailed: EventHook<LocaleLoadFailedEvent>;\n}\n"],"mappings":";;;AAKA,MAAa,YAAY,sBAAsC,QAAQ,EACrE,MAAM,qEACR,CAAC;;ACkED,MAAa,gBAA8B;CACzC,QAAQ;CACR,gBAAgB;CAChB,SAAS,CAAA;CACT,SAAS,CAAA;AACX"}
|
package/dist/contract.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_contract = require("./contract-
|
|
2
|
+
const require_contract = require("./contract-TF72RUxK.cjs");
|
|
3
|
+
exports.I18N_DEFAULTS = require_contract.I18N_DEFAULTS;
|
|
3
4
|
exports.I18nToken = require_contract.I18nToken;
|
package/dist/contract.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export {
|
|
1
|
+
import { a as Locale, c as LocaleLoadFailedEvent, d as TranslateOptions, f as TranslationDictionary, i as I18nSettings, l as LocaleLoader, n as I18nCapability, o as LocaleChangedEvent, p as I18nToken, r as I18nConfig, s as LocaleInfo, t as I18N_DEFAULTS, u as TextDirection } from "./contract-D2EGxESh.cjs";
|
|
2
|
+
export { I18N_DEFAULTS, I18nCapability, I18nConfig, I18nSettings, I18nToken, Locale, LocaleChangedEvent, LocaleInfo, LocaleLoadFailedEvent, LocaleLoader, TextDirection, TranslateOptions, TranslationDictionary };
|
package/dist/contract.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export {
|
|
1
|
+
import { a as Locale, c as LocaleLoadFailedEvent, d as TranslateOptions, f as TranslationDictionary, i as I18nSettings, l as LocaleLoader, n as I18nCapability, o as LocaleChangedEvent, p as I18nToken, r as I18nConfig, s as LocaleInfo, t as I18N_DEFAULTS, u as TextDirection } from "./contract-D2EGxESh.js";
|
|
2
|
+
export { I18N_DEFAULTS, I18nCapability, I18nConfig, I18nSettings, I18nToken, Locale, LocaleChangedEvent, LocaleInfo, LocaleLoadFailedEvent, LocaleLoader, TextDirection, TranslateOptions, TranslationDictionary };
|
package/dist/contract.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { I18nToken };
|
|
1
|
+
import { n as I18nToken, t as I18N_DEFAULTS } from "./contract-w0S-ipz5.js";
|
|
2
|
+
export { I18N_DEFAULTS, I18nToken };
|