@wordpress/i18n 5.26.0 → 6.0.1-next.46f643fa0.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +28 -27
  3. package/build/create-i18n.js +56 -201
  4. package/build/create-i18n.js.map +1 -1
  5. package/build/default-i18n.js +41 -34
  6. package/build/default-i18n.js.map +1 -1
  7. package/build/index.js.map +1 -1
  8. package/build/sprintf.js +10 -22
  9. package/build/sprintf.js.map +1 -1
  10. package/build/types.js +6 -0
  11. package/build/types.js.map +1 -0
  12. package/build-module/create-i18n.js +56 -201
  13. package/build-module/create-i18n.js.map +1 -1
  14. package/build-module/default-i18n.js +41 -35
  15. package/build-module/default-i18n.js.map +1 -1
  16. package/build-module/index.js.map +1 -1
  17. package/build-module/sprintf.js +10 -22
  18. package/build-module/sprintf.js.map +1 -1
  19. package/build-module/types.js +2 -0
  20. package/build-module/types.js.map +1 -0
  21. package/build-types/create-i18n.d.ts +11 -115
  22. package/build-types/create-i18n.d.ts.map +1 -1
  23. package/build-types/default-i18n.d.ts +55 -47
  24. package/build-types/default-i18n.d.ts.map +1 -1
  25. package/build-types/index.d.ts +4 -3
  26. package/build-types/index.d.ts.map +1 -1
  27. package/build-types/sprintf.d.ts +4 -10
  28. package/build-types/sprintf.d.ts.map +1 -1
  29. package/build-types/types.d.ts +114 -0
  30. package/build-types/types.d.ts.map +1 -0
  31. package/package.json +4 -4
  32. package/src/create-i18n.ts +405 -0
  33. package/src/{default-i18n.js → default-i18n.ts} +47 -35
  34. package/src/index.ts +16 -0
  35. package/src/sprintf.ts +37 -0
  36. package/src/test/{create-i18n.js → create-i18n.ts} +63 -30
  37. package/src/test/{sprintf.js → sprintf.ts} +5 -10
  38. package/src/test/{subscribe-i18n.js → subscribe-i18n.ts} +3 -3
  39. package/src/types.ts +167 -0
  40. package/tsconfig.tsbuildinfo +1 -1
  41. package/src/create-i18n.js +0 -506
  42. package/src/sprintf.js +0 -36
  43. /package/src/test/{default-i18n.js → default-i18n.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/i18n",
3
- "version": "5.26.0",
3
+ "version": "6.0.1-next.46f643fa0.0",
4
4
  "description": "WordPress internationalization (i18n) library.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -32,14 +32,14 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@babel/runtime": "7.25.7",
35
- "@wordpress/hooks": "^4.26.0",
35
+ "@tannin/sprintf": "^1.3.1",
36
+ "@wordpress/hooks": "^4.27.1-next.46f643fa0.0",
36
37
  "gettext-parser": "^1.3.1",
37
38
  "memize": "^2.1.0",
38
- "sprintf-js": "^1.1.1",
39
39
  "tannin": "^1.2.0"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"
43
43
  },
44
- "gitHead": "35e26942820d8237771af0c58e45b4303f0497f1"
44
+ "gitHead": "17e600e091675c5e3d809adfea23ac456bbeae19"
45
45
  }
@@ -0,0 +1,405 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { TanninLocaleDomain } from 'tannin';
5
+ import Tannin from 'tannin';
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import type {
10
+ getFilterDomain,
11
+ I18n,
12
+ LocaleData,
13
+ SubscribeCallback,
14
+ TranslatableText,
15
+ UnsubscribeCallback,
16
+ } from './types';
17
+ /**
18
+ * WordPress dependencies
19
+ */
20
+ import type { Hooks } from '@wordpress/hooks';
21
+ /**
22
+ * Default locale data to use for Tannin domain when not otherwise provided.
23
+ * Assumes an English plural forms expression.
24
+ */
25
+ const DEFAULT_LOCALE_DATA: LocaleData = {
26
+ '': {
27
+ plural_forms( n: number ) {
28
+ return n === 1 ? 0 : 1;
29
+ },
30
+ },
31
+ };
32
+
33
+ /*
34
+ * Regular expression that matches i18n hooks like `i18n.gettext`, `i18n.ngettext`,
35
+ * `i18n.gettext_domain` or `i18n.ngettext_with_context` or `i18n.has_translation`.
36
+ */
37
+ const I18N_HOOK_REGEXP = /^i18n\.(n?gettext|has_translation)(_|$)/;
38
+
39
+ /**
40
+ * Create an i18n instance
41
+ *
42
+ * @param [initialData] Locale data configuration.
43
+ * @param [initialDomain] Domain for which configuration applies.
44
+ * @param [hooks] Hooks implementation.
45
+ *
46
+ * @return I18n instance.
47
+ */
48
+ export const createI18n = < TextDomain extends string >(
49
+ initialData?: LocaleData< TextDomain >,
50
+ initialDomain?: TextDomain,
51
+ hooks?: Hooks
52
+ ): I18n< TextDomain > => {
53
+ /**
54
+ * The underlying instance of Tannin to which exported functions interface.
55
+ */
56
+ const tannin = new Tannin( {} );
57
+
58
+ const listeners = new Set< () => void >();
59
+
60
+ const notifyListeners = () => {
61
+ listeners.forEach( ( listener ) => listener() );
62
+ };
63
+
64
+ /**
65
+ * Subscribe to changes of locale data.
66
+ *
67
+ * @param callback Subscription callback.
68
+ * @return Unsubscribe callback.
69
+ */
70
+ const subscribe = ( callback: SubscribeCallback ): UnsubscribeCallback => {
71
+ listeners.add( callback );
72
+ return () => listeners.delete( callback );
73
+ };
74
+
75
+ const getLocaleData: I18n< TextDomain >[ 'getLocaleData' ] = (
76
+ domain = 'default' as TextDomain
77
+ ) => tannin.data[ domain ] as LocaleData< TextDomain >;
78
+
79
+ /**
80
+ * @param [data]
81
+ * @param [domain]
82
+ */
83
+ const doSetLocaleData = (
84
+ data?: LocaleData,
85
+ domain: TextDomain = 'default' as TextDomain
86
+ ) => {
87
+ tannin.data[ domain ] = {
88
+ ...tannin.data[ domain ],
89
+ ...data,
90
+ } as TanninLocaleDomain;
91
+
92
+ // Populate default domain configuration (supported locale date which omits
93
+ // a plural forms expression).
94
+ tannin.data[ domain ][ '' ] = {
95
+ ...DEFAULT_LOCALE_DATA[ '' ],
96
+ ...tannin.data[ domain ]?.[ '' ],
97
+ };
98
+
99
+ // Clean up cached plural forms functions cache as it might be updated.
100
+ delete tannin.pluralForms[ domain ];
101
+ };
102
+
103
+ const setLocaleData: I18n< TextDomain >[ 'setLocaleData' ] = (
104
+ data,
105
+ domain
106
+ ) => {
107
+ doSetLocaleData( data, domain );
108
+ notifyListeners();
109
+ };
110
+
111
+ const addLocaleData: I18n< TextDomain >[ 'addLocaleData' ] = (
112
+ data,
113
+ domain = 'default' as TextDomain
114
+ ) => {
115
+ tannin.data[ domain ] = {
116
+ ...tannin.data[ domain ],
117
+ ...data,
118
+ // Populate default domain configuration (supported locale date which omits
119
+ // a plural forms expression).
120
+ '': {
121
+ ...DEFAULT_LOCALE_DATA[ '' ],
122
+ ...tannin.data[ domain ]?.[ '' ],
123
+ ...data?.[ '' ],
124
+ },
125
+ } as TanninLocaleDomain;
126
+
127
+ // Clean up cached plural forms functions cache as it might be updated.
128
+ delete tannin.pluralForms[ domain ];
129
+
130
+ notifyListeners();
131
+ };
132
+
133
+ const resetLocaleData: I18n< TextDomain >[ 'resetLocaleData' ] = (
134
+ data,
135
+ domain
136
+ ) => {
137
+ // Reset all current Tannin locale data.
138
+ tannin.data = {};
139
+
140
+ // Reset cached plural forms functions cache.
141
+ tannin.pluralForms = {};
142
+
143
+ setLocaleData( data, domain );
144
+ };
145
+
146
+ /**
147
+ * Wrapper for Tannin's `dcnpgettext`. Populates default locale data if not
148
+ * otherwise previously assigned.
149
+ *
150
+ * @param domain Domain to retrieve the translated text.
151
+ * @param context Context information for the translators.
152
+ * @param single Text to translate if non-plural. Used as
153
+ * fallback return value on a caught error.
154
+ * @param [plural] The text to be used if the number is
155
+ * plural.
156
+ * @param [number] The number to compare against to use
157
+ * either the singular or plural form.
158
+ *
159
+ * @return The translated string.
160
+ */
161
+ const dcnpgettext = (
162
+ domain = 'default' as TextDomain,
163
+ context: string | void,
164
+ single: string,
165
+ plural?: string,
166
+ number?: number
167
+ ): string => {
168
+ if ( ! tannin.data[ domain ] ) {
169
+ // Use `doSetLocaleData` to set silently, without notifying listeners.
170
+ doSetLocaleData( undefined, domain );
171
+ }
172
+
173
+ return tannin.dcnpgettext( domain, context, single, plural, number );
174
+ };
175
+
176
+ const getFilterDomain: getFilterDomain = ( domain ) => domain || 'default';
177
+
178
+ const __: I18n< TextDomain >[ '__' ] = ( text, domain ) => {
179
+ let translation = dcnpgettext( domain, undefined, text );
180
+ if ( ! hooks ) {
181
+ return translation as TranslatableText< typeof text >;
182
+ }
183
+
184
+ /**
185
+ * Filters text with its translation.
186
+ *
187
+ * @param translation Translated text.
188
+ * @param text Text to translate.
189
+ * @param domain Text domain. Unique identifier for retrieving translated strings.
190
+ */
191
+ translation = hooks.applyFilters(
192
+ 'i18n.gettext',
193
+ translation,
194
+ text,
195
+ domain
196
+ ) as TranslatableText< typeof text >;
197
+
198
+ return hooks.applyFilters(
199
+ 'i18n.gettext_' + getFilterDomain( domain ),
200
+ translation,
201
+ text,
202
+ domain
203
+ ) as TranslatableText< typeof text >;
204
+ };
205
+
206
+ const _x: I18n< TextDomain >[ '_x' ] = ( text, context, domain ) => {
207
+ let translation = dcnpgettext( domain, context, text );
208
+ if ( ! hooks ) {
209
+ return translation as TranslatableText< typeof text >;
210
+ }
211
+
212
+ /**
213
+ * Filters text with its translation based on context information.
214
+ *
215
+ * @param translation Translated text.
216
+ * @param text Text to translate.
217
+ * @param context Context information for the translators.
218
+ * @param domain Text domain. Unique identifier for retrieving translated strings.
219
+ */
220
+ translation = hooks.applyFilters(
221
+ 'i18n.gettext_with_context',
222
+ translation,
223
+ text,
224
+ context,
225
+ domain
226
+ ) as TranslatableText< typeof text >;
227
+
228
+ return hooks.applyFilters(
229
+ 'i18n.gettext_with_context_' + getFilterDomain( domain ),
230
+ translation,
231
+ text,
232
+ context,
233
+ domain
234
+ ) as TranslatableText< typeof text >;
235
+ };
236
+
237
+ const _n: I18n< TextDomain >[ '_n' ] = (
238
+ single,
239
+ plural,
240
+ number,
241
+ domain
242
+ ) => {
243
+ let translation = dcnpgettext(
244
+ domain,
245
+ undefined,
246
+ single,
247
+ plural,
248
+ number
249
+ );
250
+ if ( ! hooks ) {
251
+ return translation as TranslatableText<
252
+ typeof single | typeof plural
253
+ >;
254
+ }
255
+
256
+ /**
257
+ * Filters the singular or plural form of a string.
258
+ *
259
+ * @param translation Translated text.
260
+ * @param single The text to be used if the number is singular.
261
+ * @param plural The text to be used if the number is plural.
262
+ * @param number The number to compare against to use either the singular or plural form.
263
+ * @param domain Text domain. Unique identifier for retrieving translated strings.
264
+ */
265
+ translation = hooks.applyFilters(
266
+ 'i18n.ngettext',
267
+ translation,
268
+ single,
269
+ plural,
270
+ number,
271
+ domain
272
+ ) as TranslatableText< typeof single | typeof plural >;
273
+
274
+ return hooks.applyFilters(
275
+ 'i18n.ngettext_' + getFilterDomain( domain ),
276
+ translation,
277
+ single,
278
+ plural,
279
+ number,
280
+ domain
281
+ ) as TranslatableText< typeof single | typeof plural >;
282
+ };
283
+
284
+ const _nx: I18n< TextDomain >[ '_nx' ] = (
285
+ single,
286
+ plural,
287
+ number,
288
+ context,
289
+ domain
290
+ ) => {
291
+ let translation = dcnpgettext(
292
+ domain,
293
+ context,
294
+ single,
295
+ plural,
296
+ number
297
+ );
298
+ if ( ! hooks ) {
299
+ return translation as TranslatableText<
300
+ typeof single | typeof plural
301
+ >;
302
+ }
303
+
304
+ /**
305
+ * Filters the singular or plural form of a string with gettext context.
306
+ *
307
+ * @param translation Translated text.
308
+ * @param single The text to be used if the number is singular.
309
+ * @param plural The text to be used if the number is plural.
310
+ * @param number The number to compare against to use either the singular or plural form.
311
+ * @param context Context information for the translators.
312
+ * @param domain Text domain. Unique identifier for retrieving translated strings.
313
+ */
314
+ translation = hooks.applyFilters(
315
+ 'i18n.ngettext_with_context',
316
+ translation,
317
+ single,
318
+ plural,
319
+ number,
320
+ context,
321
+ domain
322
+ ) as TranslatableText< typeof single | typeof plural >;
323
+
324
+ return hooks.applyFilters(
325
+ 'i18n.ngettext_with_context_' + getFilterDomain( domain ),
326
+ translation,
327
+ single,
328
+ plural,
329
+ number,
330
+ context,
331
+ domain
332
+ ) as TranslatableText< typeof single | typeof plural >;
333
+ };
334
+
335
+ const isRTL: I18n< TextDomain >[ 'isRTL' ] = () => {
336
+ return 'rtl' === _x( 'ltr', 'text direction' );
337
+ };
338
+
339
+ const hasTranslation: I18n< TextDomain >[ 'hasTranslation' ] = (
340
+ single,
341
+ context,
342
+ domain
343
+ ) => {
344
+ const key = context ? context + '\u0004' + single : single;
345
+ let result = !! tannin.data?.[ domain ?? 'default' ]?.[ key ];
346
+ if ( hooks ) {
347
+ /**
348
+ * Filters the presence of a translation in the locale data.
349
+ *
350
+ * @param hasTranslation Whether the translation is present or not..
351
+ * @param single The singular form of the translated text (used as key in locale data)
352
+ * @param context Context information for the translators.
353
+ * @param domain Text domain. Unique identifier for retrieving translated strings.
354
+ */
355
+ result = hooks.applyFilters(
356
+ 'i18n.has_translation',
357
+ result,
358
+ single,
359
+ context,
360
+ domain
361
+ ) as boolean;
362
+
363
+ result = hooks.applyFilters(
364
+ 'i18n.has_translation_' + getFilterDomain( domain ),
365
+ result,
366
+ single,
367
+ context,
368
+ domain
369
+ ) as boolean;
370
+ }
371
+ return result;
372
+ };
373
+
374
+ if ( initialData ) {
375
+ setLocaleData( initialData, initialDomain );
376
+ }
377
+
378
+ if ( hooks ) {
379
+ /**
380
+ * @param hookName
381
+ */
382
+ const onHookAddedOrRemoved = ( hookName: string ) => {
383
+ if ( I18N_HOOK_REGEXP.test( hookName ) ) {
384
+ notifyListeners();
385
+ }
386
+ };
387
+
388
+ hooks.addAction( 'hookAdded', 'core/i18n', onHookAddedOrRemoved );
389
+ hooks.addAction( 'hookRemoved', 'core/i18n', onHookAddedOrRemoved );
390
+ }
391
+
392
+ return {
393
+ getLocaleData,
394
+ setLocaleData,
395
+ addLocaleData,
396
+ resetLocaleData,
397
+ subscribe,
398
+ __,
399
+ _x,
400
+ _n,
401
+ _nx,
402
+ isRTL,
403
+ hasTranslation,
404
+ };
405
+ };
@@ -7,6 +7,12 @@ import { createI18n } from './create-i18n';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { defaultHooks } from '@wordpress/hooks';
10
+ import {
11
+ LocaleData,
12
+ SubscribeCallback,
13
+ TranslatableText,
14
+ UnsubscribeCallback,
15
+ } from './types';
10
16
 
11
17
  const i18n = createI18n( undefined, undefined, defaultHooks );
12
18
 
@@ -20,19 +26,13 @@ export default i18n;
20
26
  * https://github.com/WordPress/gutenberg/pull/20318#issuecomment-590837722
21
27
  */
22
28
 
23
- /**
24
- * @typedef {import('./create-i18n').LocaleData} LocaleData
25
- * @typedef {import('./create-i18n').SubscribeCallback} SubscribeCallback
26
- * @typedef {import('./create-i18n').UnsubscribeCallback} UnsubscribeCallback
27
- */
28
-
29
29
  /**
30
30
  * Returns locale data by domain in a Jed-formatted JSON object shape.
31
31
  *
32
32
  * @see http://messageformat.github.io/Jed/
33
33
  *
34
- * @param {string} [domain] Domain for which to get the data.
35
- * @return {LocaleData} Locale data.
34
+ * @param { string | undefined } [domain] Domain for which to get the data.
35
+ * @return { LocaleData } Locale data.
36
36
  */
37
37
  export const getLocaleData = i18n.getLocaleData.bind( i18n );
38
38
 
@@ -42,8 +42,8 @@ export const getLocaleData = i18n.getLocaleData.bind( i18n );
42
42
  *
43
43
  * @see http://messageformat.github.io/Jed/
44
44
  *
45
- * @param {LocaleData} [data] Locale data configuration.
46
- * @param {string} [domain] Domain for which configuration applies.
45
+ * @param {LocaleData } [data] Locale data configuration.
46
+ * @param {string | undefined} [domain] Domain for which configuration applies.
47
47
  */
48
48
  export const setLocaleData = i18n.setLocaleData.bind( i18n );
49
49
 
@@ -53,8 +53,8 @@ export const setLocaleData = i18n.setLocaleData.bind( i18n );
53
53
  *
54
54
  * @see http://messageformat.github.io/Jed/
55
55
  *
56
- * @param {LocaleData} [data] Locale data configuration.
57
- * @param {string} [domain] Domain for which configuration applies.
56
+ * @param {LocaleData} [data] Locale data configuration.
57
+ * @param {string | undefined} [domain] Domain for which configuration applies.
58
58
  */
59
59
  export const resetLocaleData = i18n.resetLocaleData.bind( i18n );
60
60
 
@@ -71,10 +71,12 @@ export const subscribe = i18n.subscribe.bind( i18n );
71
71
  *
72
72
  * @see https://developer.wordpress.org/reference/functions/__/
73
73
  *
74
- * @param {string} text Text to translate.
75
- * @param {string} [domain] Domain to retrieve the translated text.
74
+ * @template {string} Text
75
+ *
76
+ * @param {Text} text Text to translate.
77
+ * @param {string | undefined} domain Domain to retrieve the translated text.
76
78
  *
77
- * @return {string} Translated text.
79
+ * @return {TranslatableText<Text>} Translated text.
78
80
  */
79
81
  export const __ = i18n.__.bind( i18n );
80
82
 
@@ -83,11 +85,13 @@ export const __ = i18n.__.bind( i18n );
83
85
  *
84
86
  * @see https://developer.wordpress.org/reference/functions/_x/
85
87
  *
86
- * @param {string} text Text to translate.
87
- * @param {string} context Context information for the translators.
88
- * @param {string} [domain] Domain to retrieve the translated text.
88
+ * @template {string} Text
89
89
  *
90
- * @return {string} Translated context string without pipe.
90
+ * @param {Text} text Text to translate.
91
+ * @param {string} context Context information for the translators.
92
+ * @param {string | undefined} domain Domain to retrieve the translated text.
93
+ *
94
+ * @return {TranslatableText<Text>} Translated context string without pipe.
91
95
  */
92
96
  export const _x = i18n._x.bind( i18n );
93
97
 
@@ -97,13 +101,16 @@ export const _x = i18n._x.bind( i18n );
97
101
  *
98
102
  * @see https://developer.wordpress.org/reference/functions/_n/
99
103
  *
100
- * @param {string} single The text to be used if the number is singular.
101
- * @param {string} plural The text to be used if the number is plural.
102
- * @param {number} number The number to compare against to use either the
103
- * singular or plural form.
104
- * @param {string} [domain] Domain to retrieve the translated text.
104
+ * @template {string} Single
105
+ * @template {string} Plural
106
+ *
107
+ * @param {Single} single The text to be used if the number is singular.
108
+ * @param {Plural} plural The text to be used if the number is plural.
109
+ * @param {number} number The number to compare against to use either the
110
+ * singular or plural form.
111
+ * @param {string | undefined} domain Domain to retrieve the translated text.
105
112
  *
106
- * @return {string} The translated singular or plural form.
113
+ * @return {TranslatableText<Single | Plural>} The translated singular or plural form.
107
114
  */
108
115
  export const _n = i18n._n.bind( i18n );
109
116
 
@@ -113,14 +120,18 @@ export const _n = i18n._n.bind( i18n );
113
120
  *
114
121
  * @see https://developer.wordpress.org/reference/functions/_nx/
115
122
  *
116
- * @param {string} single The text to be used if the number is singular.
117
- * @param {string} plural The text to be used if the number is plural.
118
- * @param {number} number The number to compare against to use either the
119
- * singular or plural form.
120
- * @param {string} context Context information for the translators.
121
- * @param {string} [domain] Domain to retrieve the translated text.
123
+ * @template {string} Single
124
+ * @template {string} Plural
125
+ * @param {Single} single The text to be used if the number is singular.
122
126
  *
123
- * @return {string} The translated singular or plural form.
127
+ * @param {Single} single The text to be used if the number is singular.
128
+ * @param {Plural} plural The text to be used if the number is plural.
129
+ * @param {number} number The number to compare against to use either the
130
+ * singular or plural form.
131
+ * @param {string} context Context information for the translators.
132
+ * @param {string | undefined} [domain] Domain to retrieve the translated text.
133
+ *
134
+ * @return {TranslatableText<Single | Plural>} The translated singular or plural form.
124
135
  */
125
136
  export const _nx = i18n._nx.bind( i18n );
126
137
 
@@ -139,9 +150,10 @@ export const isRTL = i18n.isRTL.bind( i18n );
139
150
  /**
140
151
  * Check if there is a translation for a given string (in singular form).
141
152
  *
142
- * @param {string} single Singular form of the string to look up.
143
- * @param {string} [context] Context information for the translators.
144
- * @param {string} [domain] Domain to retrieve the translated text.
153
+ * @param {string} single Singular form of the string to look up.
154
+ * @param {string} context Context information for the translators.
155
+ * @param {string} domain Domain to retrieve the translated text.
156
+ *
145
157
  * @return {boolean} Whether the translation exists or not.
146
158
  */
147
159
  export const hasTranslation = i18n.hasTranslation.bind( i18n );
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ export { sprintf } from './sprintf';
2
+ export * from './create-i18n';
3
+ export type * from './types';
4
+ export {
5
+ default as defaultI18n,
6
+ setLocaleData,
7
+ resetLocaleData,
8
+ getLocaleData,
9
+ subscribe,
10
+ __,
11
+ _x,
12
+ _n,
13
+ _nx,
14
+ isRTL,
15
+ hasTranslation,
16
+ } from './default-i18n';
package/src/sprintf.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ // Disable reason: `eslint-plugin-import` doesn't support `exports` (https://github.com/import-js/eslint-plugin-import/issues/1810)
5
+ // eslint-disable-next-line import/no-unresolved
6
+ import _sprintf from '@tannin/sprintf';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import type { DistributeSprintfArgs, TranslatableText } from './types';
12
+
13
+ export function sprintf< T extends string >(
14
+ format: T | TranslatableText< T >,
15
+ ...args: DistributeSprintfArgs< T >
16
+ ): string;
17
+ export function sprintf< T extends string >(
18
+ format: T | TranslatableText< T >,
19
+ args: DistributeSprintfArgs< T >
20
+ ): string;
21
+
22
+ /**
23
+ * Returns a formatted string.
24
+ *
25
+ * @param format The format of the string to generate.
26
+ * @param args Arguments to apply to the format.
27
+ *
28
+ * @see https://www.npmjs.com/package/@tannin/sprintf
29
+ *
30
+ * @return The formatted string.
31
+ */
32
+ export function sprintf< T extends string >(
33
+ format: T | TranslatableText< T >,
34
+ ...args: DistributeSprintfArgs< T >
35
+ ): string {
36
+ return _sprintf( format as T, ...( args as DistributeSprintfArgs< T > ) );
37
+ }