@streamscloud/kit 0.60.0 → 0.61.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { resolvePluralForm } from './resolve-plural-form';
|
package/dist/core/i18n/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { resolvePluralForm } from './resolve-plural-form';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ResolvePluralFormOptions = {
|
|
2
|
+
count: number;
|
|
3
|
+
candidates: [string, ...string[]];
|
|
4
|
+
locale: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Picks the plural form matching `count` for `locale`.
|
|
8
|
+
*
|
|
9
|
+
* @param count - The number to pluralize
|
|
10
|
+
* @param candidates - One string per plural category `locale` distinguishes, in canonical CLDR order
|
|
11
|
+
* (zero, one, two, few, many, other) filtered to that locale's categories — e.g. 2 entries for 'en'
|
|
12
|
+
* (one, other), 4 for 'ru' (one, few, many, other). The caller (or its translation catalog) owns
|
|
13
|
+
* supplying the right length and order for the given locale. In dev, a length mismatch against
|
|
14
|
+
* `locale`'s actual category count throws instead of silently resolving the wrong form.
|
|
15
|
+
* @param locale - BCP 47 locale used to resolve the matching category via `Intl.PluralRules`.
|
|
16
|
+
* Invalid locale tags silently fall back to the runtime default — validate the locale upstream.
|
|
17
|
+
* @returns The matching candidate with # replaced by count
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* resolvePluralForm({ count: 1, candidates: ['# item', '# items'], locale: 'en' }) // "1 item"
|
|
21
|
+
* resolvePluralForm({ count: 5, candidates: ['# item', '# items'], locale: 'en' }) // "5 items"
|
|
22
|
+
*/
|
|
23
|
+
export declare const resolvePluralForm: ({ count, candidates, locale }: ResolvePluralFormOptions) => string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Picks the plural form matching `count` for `locale`.
|
|
3
|
+
*
|
|
4
|
+
* @param count - The number to pluralize
|
|
5
|
+
* @param candidates - One string per plural category `locale` distinguishes, in canonical CLDR order
|
|
6
|
+
* (zero, one, two, few, many, other) filtered to that locale's categories — e.g. 2 entries for 'en'
|
|
7
|
+
* (one, other), 4 for 'ru' (one, few, many, other). The caller (or its translation catalog) owns
|
|
8
|
+
* supplying the right length and order for the given locale. In dev, a length mismatch against
|
|
9
|
+
* `locale`'s actual category count throws instead of silently resolving the wrong form.
|
|
10
|
+
* @param locale - BCP 47 locale used to resolve the matching category via `Intl.PluralRules`.
|
|
11
|
+
* Invalid locale tags silently fall back to the runtime default — validate the locale upstream.
|
|
12
|
+
* @returns The matching candidate with # replaced by count
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* resolvePluralForm({ count: 1, candidates: ['# item', '# items'], locale: 'en' }) // "1 item"
|
|
16
|
+
* resolvePluralForm({ count: 5, candidates: ['# item', '# items'], locale: 'en' }) // "5 items"
|
|
17
|
+
*/
|
|
18
|
+
export const resolvePluralForm = ({ count, candidates, locale }) => {
|
|
19
|
+
const { index, categoriesLength } = indexerFor(locale);
|
|
20
|
+
if (import.meta.env?.DEV && candidates.length !== categoriesLength) {
|
|
21
|
+
throw new Error(`resolvePluralForm(): locale "${locale}" needs ${categoriesLength} candidate(s), got ${JSON.stringify(candidates)}.`);
|
|
22
|
+
}
|
|
23
|
+
const template = candidates[index(count)] ?? candidates[candidates.length - 1];
|
|
24
|
+
return template.replace(/#/g, String(count));
|
|
25
|
+
};
|
|
26
|
+
const PLURAL_CATEGORY_ORDER = ['zero', 'one', 'two', 'few', 'many', 'other'];
|
|
27
|
+
const indexers = new Map();
|
|
28
|
+
const indexerFor = (locale) => {
|
|
29
|
+
const cached = indexers.get(locale);
|
|
30
|
+
if (cached) {
|
|
31
|
+
return cached;
|
|
32
|
+
}
|
|
33
|
+
const rules = new Intl.PluralRules(locale);
|
|
34
|
+
const categories = rules
|
|
35
|
+
.resolvedOptions()
|
|
36
|
+
.pluralCategories.slice()
|
|
37
|
+
.sort((a, b) => PLURAL_CATEGORY_ORDER.indexOf(a) - PLURAL_CATEGORY_ORDER.indexOf(b));
|
|
38
|
+
const indexer = { index: (count) => categories.indexOf(rules.select(count)), categoriesLength: categories.length };
|
|
39
|
+
indexers.set(locale, indexer);
|
|
40
|
+
return indexer;
|
|
41
|
+
};
|
package/package.json
CHANGED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plural function for wuchale i18n.
|
|
3
|
-
* Wuchale extracts the candidates array and compiles locale-specific plural rules.
|
|
4
|
-
*
|
|
5
|
-
* @param count - The number to pluralize
|
|
6
|
-
* @param candidates - Array of plural forms, e.g., ['One item', '# items']
|
|
7
|
-
* @param rule - Optional plural rule function (injected by wuchale at compile time)
|
|
8
|
-
* @returns The appropriate plural form with # replaced by count
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* plural(1, ['# item', '# items']) // "1 item"
|
|
12
|
-
* plural(5, ['# item', '# items']) // "5 items"
|
|
13
|
-
*/
|
|
14
|
-
export declare const plural: (count: number, candidates: string[], rule?: (n: number) => number) => string;
|
package/dist/core/i18n/plural.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plural function for wuchale i18n.
|
|
3
|
-
* Wuchale extracts the candidates array and compiles locale-specific plural rules.
|
|
4
|
-
*
|
|
5
|
-
* @param count - The number to pluralize
|
|
6
|
-
* @param candidates - Array of plural forms, e.g., ['One item', '# items']
|
|
7
|
-
* @param rule - Optional plural rule function (injected by wuchale at compile time)
|
|
8
|
-
* @returns The appropriate plural form with # replaced by count
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* plural(1, ['# item', '# items']) // "1 item"
|
|
12
|
-
* plural(5, ['# item', '# items']) // "5 items"
|
|
13
|
-
*/
|
|
14
|
-
export const plural = (count, candidates, rule = (n) => (n === 1 ? 0 : 1)) => {
|
|
15
|
-
const index = rule(count);
|
|
16
|
-
const template = candidates[index] ?? candidates[candidates.length - 1];
|
|
17
|
-
return template.replace(/#/g, String(count));
|
|
18
|
-
};
|