i18next-cli 1.64.0 → 1.64.1
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/cjs/cli.js +1 -1
- package/dist/cjs/extractor/core/translation-manager.js +5 -2
- package/dist/cjs/extractor/parsers/call-expression-handler.js +8 -3
- package/dist/cjs/extractor/parsers/comment-parser.js +7 -3
- package/dist/cjs/extractor/parsers/jsx-handler.js +5 -1
- package/dist/cjs/status.js +123 -21
- package/dist/esm/cli.js +1 -1
- package/dist/esm/extractor/core/translation-manager.js +5 -2
- package/dist/esm/extractor/parsers/call-expression-handler.js +8 -3
- package/dist/esm/extractor/parsers/comment-parser.js +7 -3
- package/dist/esm/extractor/parsers/jsx-handler.js +5 -1
- package/dist/esm/status.js +123 -21
- package/package.json +1 -1
- package/types/extractor/core/translation-manager.d.ts.map +1 -1
- package/types/extractor/parsers/call-expression-handler.d.ts.map +1 -1
- package/types/extractor/parsers/comment-parser.d.ts.map +1 -1
- package/types/extractor/parsers/jsx-handler.d.ts.map +1 -1
- package/types/status.d.ts.map +1 -1
package/dist/cjs/cli.js
CHANGED
|
@@ -37,7 +37,7 @@ const program = new commander.Command();
|
|
|
37
37
|
program
|
|
38
38
|
.name('i18next-cli')
|
|
39
39
|
.description('A unified, high-performance i18next CLI.')
|
|
40
|
-
.version('1.64.
|
|
40
|
+
.version('1.64.1'); // This string is replaced with the actual version at build time by rollup
|
|
41
41
|
// new: global config override option
|
|
42
42
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
43
43
|
program
|
|
@@ -394,8 +394,11 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
394
394
|
if (shouldFilterKey(key)) {
|
|
395
395
|
return false;
|
|
396
396
|
}
|
|
397
|
-
if (!hasCount) {
|
|
398
|
-
// Non-plural keys are always included
|
|
397
|
+
if (!hasCount || config.extract.disablePlurals) {
|
|
398
|
+
// Non-plural keys are always included. Under `disablePlurals`, count keys
|
|
399
|
+
// are emitted as plain keys (no plural expansion) but still carry
|
|
400
|
+
// `hasCount` so `status` can recognise them — they must bypass the
|
|
401
|
+
// plural-form filtering below and always be included, exactly as before.
|
|
399
402
|
return true;
|
|
400
403
|
}
|
|
401
404
|
// For plural keys, check if this specific plural form is needed for the target language
|
|
@@ -337,12 +337,17 @@ class CallExpressionHandler {
|
|
|
337
337
|
// Check if plurals are disabled FIRST, before any plural optimization paths
|
|
338
338
|
if (this.config.extract.disablePlurals) {
|
|
339
339
|
// When plurals are disabled, treat count as a regular option (for interpolation only)
|
|
340
|
-
// Still handle context normally
|
|
340
|
+
// Still handle context normally. We keep `hasCount`/`isOrdinal` on the
|
|
341
|
+
// emitted key so `status` knows it is count-driven and can accept the
|
|
342
|
+
// file's plural variants (or the bare key) instead of demanding the
|
|
343
|
+
// literal base key. File generation ignores these flags under
|
|
344
|
+
// disablePlurals (see translation-manager), so output is unchanged.
|
|
345
|
+
const countMeta = hasCount ? { hasCount: true, isOrdinal: isOrdinalByKey } : {};
|
|
341
346
|
if (keysWithContext.length > 0) {
|
|
342
|
-
keysWithContext.forEach(this.pluginContext.addKey);
|
|
347
|
+
keysWithContext.forEach(k => this.pluginContext.addKey({ ...k, ...countMeta }));
|
|
343
348
|
}
|
|
344
349
|
else {
|
|
345
|
-
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase });
|
|
350
|
+
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase, ...countMeta });
|
|
346
351
|
}
|
|
347
352
|
continue; // This key is fully handled
|
|
348
353
|
}
|
|
@@ -124,14 +124,18 @@ function extractKeysFromComments(code, pluginContext, config, scopeResolver) {
|
|
|
124
124
|
ns = config.extract.defaultNS;
|
|
125
125
|
// 5. Handle context and count combinations based on disablePlurals setting
|
|
126
126
|
if (config.extract.disablePlurals) {
|
|
127
|
-
// When plurals are disabled, ignore count for key generation
|
|
127
|
+
// When plurals are disabled, ignore count for key generation. We still
|
|
128
|
+
// tag the key with `hasCount` (when a count was present) so `status` can
|
|
129
|
+
// recognise it as count-driven; file generation ignores the flag under
|
|
130
|
+
// disablePlurals (see translation-manager).
|
|
131
|
+
const countMeta = count ? { hasCount: true, isOrdinal } : {};
|
|
128
132
|
if (context) {
|
|
129
133
|
// Only generate context variants (no base key when context is static)
|
|
130
|
-
pluginContext.addKey({ key: `${key}_${context}`, ns, defaultValue: defaultValue ?? key });
|
|
134
|
+
pluginContext.addKey({ key: `${key}_${context}`, ns, defaultValue: defaultValue ?? key, ...countMeta });
|
|
131
135
|
}
|
|
132
136
|
else {
|
|
133
137
|
// Simple key (ignore count)
|
|
134
|
-
pluginContext.addKey({ key, ns, defaultValue: defaultValue ?? key });
|
|
138
|
+
pluginContext.addKey({ key, ns, defaultValue: defaultValue ?? key, ...countMeta });
|
|
135
139
|
}
|
|
136
140
|
}
|
|
137
141
|
else {
|
|
@@ -369,12 +369,16 @@ class JSXHandler {
|
|
|
369
369
|
else if (hasCount) {
|
|
370
370
|
// Check if plurals are disabled
|
|
371
371
|
if (this.config.extract.disablePlurals) {
|
|
372
|
-
// When plurals are disabled, just add the base keys (no plural forms)
|
|
372
|
+
// When plurals are disabled, just add the base keys (no plural forms).
|
|
373
|
+
// We keep `hasCount` so `status` recognises the key as count-driven and
|
|
374
|
+
// accepts the file's plural variants (or bare key); file generation
|
|
375
|
+
// ignores it under disablePlurals (see translation-manager).
|
|
373
376
|
extractedKeys.forEach(extractedKey => {
|
|
374
377
|
this.pluginContext.addKey({
|
|
375
378
|
key: extractedKey.key,
|
|
376
379
|
ns: extractedKey.ns,
|
|
377
380
|
defaultValue: extractedKey.defaultValue,
|
|
381
|
+
hasCount: true,
|
|
378
382
|
locations: extractedKey.locations
|
|
379
383
|
});
|
|
380
384
|
});
|
package/dist/cjs/status.js
CHANGED
|
@@ -26,6 +26,53 @@ function classifyValue(value) {
|
|
|
26
26
|
return 'empty';
|
|
27
27
|
return 'translated';
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Representative counts used to decide which CLDR plural categories a locale can
|
|
31
|
+
* actually reach in normal usage: small integers (the common case), a handful
|
|
32
|
+
* of larger integers, and common decimals (so categories that only fire for
|
|
33
|
+
* fractional display values — e.g. Polish/Russian `other` — stay required).
|
|
34
|
+
*
|
|
35
|
+
* Any category NOT produced by these counts is treated as "optional". The prime
|
|
36
|
+
* example is French `many`, which `Intl.PluralRules` only selects for values
|
|
37
|
+
* ≥ 1,000,000 — the i18next runtime can technically request it, but real apps
|
|
38
|
+
* almost never hit those values (and the runtime falls back to the base key
|
|
39
|
+
* when the variant is missing), so a missing `_many` should be a soft note
|
|
40
|
+
* rather than a hard "missing key" failure.
|
|
41
|
+
*/
|
|
42
|
+
const REPRESENTATIVE_COUNTS = (() => {
|
|
43
|
+
const counts = [];
|
|
44
|
+
for (let n = 0; n <= 20; n++)
|
|
45
|
+
counts.push(n);
|
|
46
|
+
counts.push(100, 101, 1000, 1001, 10000);
|
|
47
|
+
counts.push(0.5, 1.1, 1.5, 2.5, 3.5);
|
|
48
|
+
return counts;
|
|
49
|
+
})();
|
|
50
|
+
const optionalCategoriesCache = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Returns the CLDR plural categories for a locale that are NOT reachable by any
|
|
53
|
+
* representative count (see {@link REPRESENTATIVE_COUNTS}). These are reported
|
|
54
|
+
* by `status` as optional: a missing variant is a soft note instead of a hard
|
|
55
|
+
* absence, mirroring how the i18next runtime resolves such forms.
|
|
56
|
+
*/
|
|
57
|
+
function getOptionalPluralCategories(locale, isOrdinal) {
|
|
58
|
+
const type = isOrdinal ? 'ordinal' : 'cardinal';
|
|
59
|
+
const cacheKey = `${locale}|${type}`;
|
|
60
|
+
const cached = optionalCategoriesCache.get(cacheKey);
|
|
61
|
+
if (cached)
|
|
62
|
+
return cached;
|
|
63
|
+
let optional;
|
|
64
|
+
try {
|
|
65
|
+
const rules = pluralRules.safePluralRules(locale, { type });
|
|
66
|
+
const all = rules.resolvedOptions().pluralCategories;
|
|
67
|
+
const reachable = new Set(REPRESENTATIVE_COUNTS.map(n => rules.select(n)));
|
|
68
|
+
optional = new Set(all.filter(c => !reachable.has(c)));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
optional = new Set();
|
|
72
|
+
}
|
|
73
|
+
optionalCategoriesCache.set(cacheKey, optional);
|
|
74
|
+
return optional;
|
|
75
|
+
}
|
|
29
76
|
/**
|
|
30
77
|
* Runs a health check on the project's i18next translations and displays a status report.
|
|
31
78
|
*
|
|
@@ -222,6 +269,7 @@ async function generateStatusReport(config) {
|
|
|
222
269
|
let totalTranslatedForLocale = 0;
|
|
223
270
|
let totalEmptyForLocale = 0;
|
|
224
271
|
let totalAbsentForLocale = 0;
|
|
272
|
+
let totalOptionalForLocale = 0;
|
|
225
273
|
let totalKeysForLocale = 0;
|
|
226
274
|
const namespaces = new Map();
|
|
227
275
|
const mergedTranslations = mergeNamespaces
|
|
@@ -250,6 +298,7 @@ async function generateStatusReport(config) {
|
|
|
250
298
|
let translatedInNs = 0;
|
|
251
299
|
let emptyInNs = 0;
|
|
252
300
|
let absentInNs = 0;
|
|
301
|
+
let optionalInNs = 0;
|
|
253
302
|
let totalInNs = 0;
|
|
254
303
|
const keyDetails = [];
|
|
255
304
|
// Get the plural categories for THIS specific locale
|
|
@@ -314,37 +363,85 @@ async function generateStatusReport(config) {
|
|
|
314
363
|
// Only count this key if it's a plural form used by this locale
|
|
315
364
|
if (localePluralCategories.includes(category) && !processedKeys.has(baseKey)) {
|
|
316
365
|
processedKeys.add(baseKey);
|
|
317
|
-
totalInNs++;
|
|
318
366
|
const state = resolveAndClassify(baseKey);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
367
|
+
const optionalCategories = getOptionalPluralCategories(locale, isOrdinalVariant);
|
|
368
|
+
// An optional category (e.g. French `_many`) is a soft note whenever
|
|
369
|
+
// it isn't translated — whether absent or an empty placeholder that
|
|
370
|
+
// `extract` wrote. It is never a hard failure. See #270 and
|
|
371
|
+
// getOptionalPluralCategories.
|
|
372
|
+
if (state !== 'translated' && optionalCategories.has(category)) {
|
|
373
|
+
optionalInNs++;
|
|
374
|
+
keyDetails.push({ key: baseKey, state: 'optional' });
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
totalInNs++;
|
|
378
|
+
if (state === 'translated')
|
|
379
|
+
translatedInNs++;
|
|
380
|
+
else if (state === 'empty')
|
|
381
|
+
emptyInNs++;
|
|
382
|
+
else
|
|
383
|
+
absentInNs++;
|
|
384
|
+
keyDetails.push({ key: baseKey, state });
|
|
385
|
+
}
|
|
326
386
|
}
|
|
327
387
|
}
|
|
328
388
|
else {
|
|
329
|
-
// This is a base plural key without expanded variants
|
|
330
|
-
//
|
|
389
|
+
// This is a base plural key without expanded variants. Mirror the
|
|
390
|
+
// i18next runtime, where t(key, { count }) resolves `key + suffix`
|
|
391
|
+
// and falls back to the bare `key`. A family is therefore satisfied
|
|
392
|
+
// either by its plural variants OR by a bare key (the convention
|
|
393
|
+
// used when `disablePlurals` is enabled and no variants are written).
|
|
331
394
|
const localePluralCategories = getLocalePluralCategories(locale, isOrdinal || false);
|
|
332
|
-
|
|
333
|
-
|
|
395
|
+
const optionalCategories = getOptionalPluralCategories(locale, isOrdinal || false);
|
|
396
|
+
const variants = localePluralCategories.map(category => ({
|
|
397
|
+
category,
|
|
398
|
+
pluralKey: isOrdinal
|
|
334
399
|
? `${baseKey}${pluralSeparator}ordinal${pluralSeparator}${category}`
|
|
335
|
-
: `${baseKey}${pluralSeparator}${category}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
400
|
+
: `${baseKey}${pluralSeparator}${category}`,
|
|
401
|
+
}));
|
|
402
|
+
const anyVariantPresent = variants.some(({ pluralKey }) => resolveAndClassify(pluralKey) !== 'absent');
|
|
403
|
+
const bareState = resolveAndClassify(baseKey);
|
|
404
|
+
if (!anyVariantPresent && bareState !== 'absent' && !processedKeys.has(baseKey)) {
|
|
405
|
+
// Convention (a): only the bare key exists (typical under
|
|
406
|
+
// disablePlurals, or single-"other" languages). The runtime
|
|
407
|
+
// resolves count via the bare key, so it satisfies the family on
|
|
408
|
+
// its own — don't demand plural variants that were never written.
|
|
409
|
+
processedKeys.add(baseKey);
|
|
339
410
|
totalInNs++;
|
|
340
|
-
|
|
341
|
-
if (state === 'translated')
|
|
411
|
+
if (bareState === 'translated')
|
|
342
412
|
translatedInNs++;
|
|
343
|
-
else if (
|
|
413
|
+
else if (bareState === 'empty')
|
|
344
414
|
emptyInNs++;
|
|
345
415
|
else
|
|
346
416
|
absentInNs++;
|
|
347
|
-
keyDetails.push({ key:
|
|
417
|
+
keyDetails.push({ key: baseKey, state: bareState });
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
// Convention (b): plural variants exist (or the family is missing
|
|
421
|
+
// entirely). Evaluate each CLDR category — a missing variant is a
|
|
422
|
+
// hard absence only when the category is required for this locale;
|
|
423
|
+
// optional categories (e.g. French `_many`) downgrade to a soft note.
|
|
424
|
+
for (const { category, pluralKey } of variants) {
|
|
425
|
+
if (processedKeys.has(pluralKey))
|
|
426
|
+
continue;
|
|
427
|
+
processedKeys.add(pluralKey);
|
|
428
|
+
const state = resolveAndClassify(pluralKey);
|
|
429
|
+
// An optional category (e.g. French `_many`) is a soft note
|
|
430
|
+
// whenever it isn't translated — never a hard failure. See #270.
|
|
431
|
+
if (state !== 'translated' && optionalCategories.has(category)) {
|
|
432
|
+
optionalInNs++;
|
|
433
|
+
keyDetails.push({ key: pluralKey, state: 'optional' });
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
totalInNs++;
|
|
437
|
+
if (state === 'translated')
|
|
438
|
+
translatedInNs++;
|
|
439
|
+
else if (state === 'empty')
|
|
440
|
+
emptyInNs++;
|
|
441
|
+
else
|
|
442
|
+
absentInNs++;
|
|
443
|
+
keyDetails.push({ key: pluralKey, state });
|
|
444
|
+
}
|
|
348
445
|
}
|
|
349
446
|
}
|
|
350
447
|
}
|
|
@@ -380,10 +477,11 @@ async function generateStatusReport(config) {
|
|
|
380
477
|
absentInNs++;
|
|
381
478
|
keyDetails.push({ key: variantKey, state });
|
|
382
479
|
}
|
|
383
|
-
namespaces.set(ns, { totalKeys: totalInNs, translatedKeys: translatedInNs, emptyKeys: emptyInNs, absentKeys: absentInNs, keyDetails });
|
|
480
|
+
namespaces.set(ns, { totalKeys: totalInNs, translatedKeys: translatedInNs, emptyKeys: emptyInNs, absentKeys: absentInNs, optionalKeys: optionalInNs, keyDetails });
|
|
384
481
|
totalTranslatedForLocale += translatedInNs;
|
|
385
482
|
totalEmptyForLocale += emptyInNs;
|
|
386
483
|
totalAbsentForLocale += absentInNs;
|
|
484
|
+
totalOptionalForLocale += optionalInNs;
|
|
387
485
|
totalKeysForLocale += totalInNs;
|
|
388
486
|
}
|
|
389
487
|
const localeStatus = {
|
|
@@ -391,6 +489,7 @@ async function generateStatusReport(config) {
|
|
|
391
489
|
totalTranslated: totalTranslatedForLocale,
|
|
392
490
|
totalEmpty: totalEmptyForLocale,
|
|
393
491
|
totalAbsent: totalAbsentForLocale,
|
|
492
|
+
totalOptional: totalOptionalForLocale,
|
|
394
493
|
namespaces,
|
|
395
494
|
};
|
|
396
495
|
if (isPrimary) {
|
|
@@ -482,6 +581,9 @@ async function displayDetailedLocaleReport(report, config, locale, namespaceFilt
|
|
|
482
581
|
else if (state === 'empty') {
|
|
483
582
|
console.log(` ${node_util.styleText('yellow', '~')} ${key} ${node_util.styleText('yellow', '(untranslated)')}`);
|
|
484
583
|
}
|
|
584
|
+
else if (state === 'optional') {
|
|
585
|
+
console.log(` ${node_util.styleText('gray', '○')} ${key} ${node_util.styleText('gray', '(optional plural form)')}`);
|
|
586
|
+
}
|
|
485
587
|
else {
|
|
486
588
|
console.log(` ${node_util.styleText('red', '✗')} ${key} ${node_util.styleText('red', '(absent)')}`);
|
|
487
589
|
}
|
package/dist/esm/cli.js
CHANGED
|
@@ -31,7 +31,7 @@ const program = new Command();
|
|
|
31
31
|
program
|
|
32
32
|
.name('i18next-cli')
|
|
33
33
|
.description('A unified, high-performance i18next CLI.')
|
|
34
|
-
.version('1.64.
|
|
34
|
+
.version('1.64.1'); // This string is replaced with the actual version at build time by rollup
|
|
35
35
|
// new: global config override option
|
|
36
36
|
program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
|
|
37
37
|
program
|
|
@@ -392,8 +392,11 @@ function buildNewTranslationsForNs(nsKeys, existingTranslations, config, locale,
|
|
|
392
392
|
if (shouldFilterKey(key)) {
|
|
393
393
|
return false;
|
|
394
394
|
}
|
|
395
|
-
if (!hasCount) {
|
|
396
|
-
// Non-plural keys are always included
|
|
395
|
+
if (!hasCount || config.extract.disablePlurals) {
|
|
396
|
+
// Non-plural keys are always included. Under `disablePlurals`, count keys
|
|
397
|
+
// are emitted as plain keys (no plural expansion) but still carry
|
|
398
|
+
// `hasCount` so `status` can recognise them — they must bypass the
|
|
399
|
+
// plural-form filtering below and always be included, exactly as before.
|
|
397
400
|
return true;
|
|
398
401
|
}
|
|
399
402
|
// For plural keys, check if this specific plural form is needed for the target language
|
|
@@ -335,12 +335,17 @@ class CallExpressionHandler {
|
|
|
335
335
|
// Check if plurals are disabled FIRST, before any plural optimization paths
|
|
336
336
|
if (this.config.extract.disablePlurals) {
|
|
337
337
|
// When plurals are disabled, treat count as a regular option (for interpolation only)
|
|
338
|
-
// Still handle context normally
|
|
338
|
+
// Still handle context normally. We keep `hasCount`/`isOrdinal` on the
|
|
339
|
+
// emitted key so `status` knows it is count-driven and can accept the
|
|
340
|
+
// file's plural variants (or the bare key) instead of demanding the
|
|
341
|
+
// literal base key. File generation ignores these flags under
|
|
342
|
+
// disablePlurals (see translation-manager), so output is unchanged.
|
|
343
|
+
const countMeta = hasCount ? { hasCount: true, isOrdinal: isOrdinalByKey } : {};
|
|
339
344
|
if (keysWithContext.length > 0) {
|
|
340
|
-
keysWithContext.forEach(this.pluginContext.addKey);
|
|
345
|
+
keysWithContext.forEach(k => this.pluginContext.addKey({ ...k, ...countMeta }));
|
|
341
346
|
}
|
|
342
347
|
else {
|
|
343
|
-
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase });
|
|
348
|
+
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase, ...countMeta });
|
|
344
349
|
}
|
|
345
350
|
continue; // This key is fully handled
|
|
346
351
|
}
|
|
@@ -122,14 +122,18 @@ function extractKeysFromComments(code, pluginContext, config, scopeResolver) {
|
|
|
122
122
|
ns = config.extract.defaultNS;
|
|
123
123
|
// 5. Handle context and count combinations based on disablePlurals setting
|
|
124
124
|
if (config.extract.disablePlurals) {
|
|
125
|
-
// When plurals are disabled, ignore count for key generation
|
|
125
|
+
// When plurals are disabled, ignore count for key generation. We still
|
|
126
|
+
// tag the key with `hasCount` (when a count was present) so `status` can
|
|
127
|
+
// recognise it as count-driven; file generation ignores the flag under
|
|
128
|
+
// disablePlurals (see translation-manager).
|
|
129
|
+
const countMeta = count ? { hasCount: true, isOrdinal } : {};
|
|
126
130
|
if (context) {
|
|
127
131
|
// Only generate context variants (no base key when context is static)
|
|
128
|
-
pluginContext.addKey({ key: `${key}_${context}`, ns, defaultValue: defaultValue ?? key });
|
|
132
|
+
pluginContext.addKey({ key: `${key}_${context}`, ns, defaultValue: defaultValue ?? key, ...countMeta });
|
|
129
133
|
}
|
|
130
134
|
else {
|
|
131
135
|
// Simple key (ignore count)
|
|
132
|
-
pluginContext.addKey({ key, ns, defaultValue: defaultValue ?? key });
|
|
136
|
+
pluginContext.addKey({ key, ns, defaultValue: defaultValue ?? key, ...countMeta });
|
|
133
137
|
}
|
|
134
138
|
}
|
|
135
139
|
else {
|
|
@@ -367,12 +367,16 @@ class JSXHandler {
|
|
|
367
367
|
else if (hasCount) {
|
|
368
368
|
// Check if plurals are disabled
|
|
369
369
|
if (this.config.extract.disablePlurals) {
|
|
370
|
-
// When plurals are disabled, just add the base keys (no plural forms)
|
|
370
|
+
// When plurals are disabled, just add the base keys (no plural forms).
|
|
371
|
+
// We keep `hasCount` so `status` recognises the key as count-driven and
|
|
372
|
+
// accepts the file's plural variants (or bare key); file generation
|
|
373
|
+
// ignores it under disablePlurals (see translation-manager).
|
|
371
374
|
extractedKeys.forEach(extractedKey => {
|
|
372
375
|
this.pluginContext.addKey({
|
|
373
376
|
key: extractedKey.key,
|
|
374
377
|
ns: extractedKey.ns,
|
|
375
378
|
defaultValue: extractedKey.defaultValue,
|
|
379
|
+
hasCount: true,
|
|
376
380
|
locations: extractedKey.locations
|
|
377
381
|
});
|
|
378
382
|
});
|
package/dist/esm/status.js
CHANGED
|
@@ -20,6 +20,53 @@ function classifyValue(value) {
|
|
|
20
20
|
return 'empty';
|
|
21
21
|
return 'translated';
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Representative counts used to decide which CLDR plural categories a locale can
|
|
25
|
+
* actually reach in normal usage: small integers (the common case), a handful
|
|
26
|
+
* of larger integers, and common decimals (so categories that only fire for
|
|
27
|
+
* fractional display values — e.g. Polish/Russian `other` — stay required).
|
|
28
|
+
*
|
|
29
|
+
* Any category NOT produced by these counts is treated as "optional". The prime
|
|
30
|
+
* example is French `many`, which `Intl.PluralRules` only selects for values
|
|
31
|
+
* ≥ 1,000,000 — the i18next runtime can technically request it, but real apps
|
|
32
|
+
* almost never hit those values (and the runtime falls back to the base key
|
|
33
|
+
* when the variant is missing), so a missing `_many` should be a soft note
|
|
34
|
+
* rather than a hard "missing key" failure.
|
|
35
|
+
*/
|
|
36
|
+
const REPRESENTATIVE_COUNTS = (() => {
|
|
37
|
+
const counts = [];
|
|
38
|
+
for (let n = 0; n <= 20; n++)
|
|
39
|
+
counts.push(n);
|
|
40
|
+
counts.push(100, 101, 1000, 1001, 10000);
|
|
41
|
+
counts.push(0.5, 1.1, 1.5, 2.5, 3.5);
|
|
42
|
+
return counts;
|
|
43
|
+
})();
|
|
44
|
+
const optionalCategoriesCache = new Map();
|
|
45
|
+
/**
|
|
46
|
+
* Returns the CLDR plural categories for a locale that are NOT reachable by any
|
|
47
|
+
* representative count (see {@link REPRESENTATIVE_COUNTS}). These are reported
|
|
48
|
+
* by `status` as optional: a missing variant is a soft note instead of a hard
|
|
49
|
+
* absence, mirroring how the i18next runtime resolves such forms.
|
|
50
|
+
*/
|
|
51
|
+
function getOptionalPluralCategories(locale, isOrdinal) {
|
|
52
|
+
const type = isOrdinal ? 'ordinal' : 'cardinal';
|
|
53
|
+
const cacheKey = `${locale}|${type}`;
|
|
54
|
+
const cached = optionalCategoriesCache.get(cacheKey);
|
|
55
|
+
if (cached)
|
|
56
|
+
return cached;
|
|
57
|
+
let optional;
|
|
58
|
+
try {
|
|
59
|
+
const rules = safePluralRules(locale, { type });
|
|
60
|
+
const all = rules.resolvedOptions().pluralCategories;
|
|
61
|
+
const reachable = new Set(REPRESENTATIVE_COUNTS.map(n => rules.select(n)));
|
|
62
|
+
optional = new Set(all.filter(c => !reachable.has(c)));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
optional = new Set();
|
|
66
|
+
}
|
|
67
|
+
optionalCategoriesCache.set(cacheKey, optional);
|
|
68
|
+
return optional;
|
|
69
|
+
}
|
|
23
70
|
/**
|
|
24
71
|
* Runs a health check on the project's i18next translations and displays a status report.
|
|
25
72
|
*
|
|
@@ -216,6 +263,7 @@ async function generateStatusReport(config) {
|
|
|
216
263
|
let totalTranslatedForLocale = 0;
|
|
217
264
|
let totalEmptyForLocale = 0;
|
|
218
265
|
let totalAbsentForLocale = 0;
|
|
266
|
+
let totalOptionalForLocale = 0;
|
|
219
267
|
let totalKeysForLocale = 0;
|
|
220
268
|
const namespaces = new Map();
|
|
221
269
|
const mergedTranslations = mergeNamespaces
|
|
@@ -244,6 +292,7 @@ async function generateStatusReport(config) {
|
|
|
244
292
|
let translatedInNs = 0;
|
|
245
293
|
let emptyInNs = 0;
|
|
246
294
|
let absentInNs = 0;
|
|
295
|
+
let optionalInNs = 0;
|
|
247
296
|
let totalInNs = 0;
|
|
248
297
|
const keyDetails = [];
|
|
249
298
|
// Get the plural categories for THIS specific locale
|
|
@@ -308,37 +357,85 @@ async function generateStatusReport(config) {
|
|
|
308
357
|
// Only count this key if it's a plural form used by this locale
|
|
309
358
|
if (localePluralCategories.includes(category) && !processedKeys.has(baseKey)) {
|
|
310
359
|
processedKeys.add(baseKey);
|
|
311
|
-
totalInNs++;
|
|
312
360
|
const state = resolveAndClassify(baseKey);
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
361
|
+
const optionalCategories = getOptionalPluralCategories(locale, isOrdinalVariant);
|
|
362
|
+
// An optional category (e.g. French `_many`) is a soft note whenever
|
|
363
|
+
// it isn't translated — whether absent or an empty placeholder that
|
|
364
|
+
// `extract` wrote. It is never a hard failure. See #270 and
|
|
365
|
+
// getOptionalPluralCategories.
|
|
366
|
+
if (state !== 'translated' && optionalCategories.has(category)) {
|
|
367
|
+
optionalInNs++;
|
|
368
|
+
keyDetails.push({ key: baseKey, state: 'optional' });
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
totalInNs++;
|
|
372
|
+
if (state === 'translated')
|
|
373
|
+
translatedInNs++;
|
|
374
|
+
else if (state === 'empty')
|
|
375
|
+
emptyInNs++;
|
|
376
|
+
else
|
|
377
|
+
absentInNs++;
|
|
378
|
+
keyDetails.push({ key: baseKey, state });
|
|
379
|
+
}
|
|
320
380
|
}
|
|
321
381
|
}
|
|
322
382
|
else {
|
|
323
|
-
// This is a base plural key without expanded variants
|
|
324
|
-
//
|
|
383
|
+
// This is a base plural key without expanded variants. Mirror the
|
|
384
|
+
// i18next runtime, where t(key, { count }) resolves `key + suffix`
|
|
385
|
+
// and falls back to the bare `key`. A family is therefore satisfied
|
|
386
|
+
// either by its plural variants OR by a bare key (the convention
|
|
387
|
+
// used when `disablePlurals` is enabled and no variants are written).
|
|
325
388
|
const localePluralCategories = getLocalePluralCategories(locale, isOrdinal || false);
|
|
326
|
-
|
|
327
|
-
|
|
389
|
+
const optionalCategories = getOptionalPluralCategories(locale, isOrdinal || false);
|
|
390
|
+
const variants = localePluralCategories.map(category => ({
|
|
391
|
+
category,
|
|
392
|
+
pluralKey: isOrdinal
|
|
328
393
|
? `${baseKey}${pluralSeparator}ordinal${pluralSeparator}${category}`
|
|
329
|
-
: `${baseKey}${pluralSeparator}${category}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
394
|
+
: `${baseKey}${pluralSeparator}${category}`,
|
|
395
|
+
}));
|
|
396
|
+
const anyVariantPresent = variants.some(({ pluralKey }) => resolveAndClassify(pluralKey) !== 'absent');
|
|
397
|
+
const bareState = resolveAndClassify(baseKey);
|
|
398
|
+
if (!anyVariantPresent && bareState !== 'absent' && !processedKeys.has(baseKey)) {
|
|
399
|
+
// Convention (a): only the bare key exists (typical under
|
|
400
|
+
// disablePlurals, or single-"other" languages). The runtime
|
|
401
|
+
// resolves count via the bare key, so it satisfies the family on
|
|
402
|
+
// its own — don't demand plural variants that were never written.
|
|
403
|
+
processedKeys.add(baseKey);
|
|
333
404
|
totalInNs++;
|
|
334
|
-
|
|
335
|
-
if (state === 'translated')
|
|
405
|
+
if (bareState === 'translated')
|
|
336
406
|
translatedInNs++;
|
|
337
|
-
else if (
|
|
407
|
+
else if (bareState === 'empty')
|
|
338
408
|
emptyInNs++;
|
|
339
409
|
else
|
|
340
410
|
absentInNs++;
|
|
341
|
-
keyDetails.push({ key:
|
|
411
|
+
keyDetails.push({ key: baseKey, state: bareState });
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
// Convention (b): plural variants exist (or the family is missing
|
|
415
|
+
// entirely). Evaluate each CLDR category — a missing variant is a
|
|
416
|
+
// hard absence only when the category is required for this locale;
|
|
417
|
+
// optional categories (e.g. French `_many`) downgrade to a soft note.
|
|
418
|
+
for (const { category, pluralKey } of variants) {
|
|
419
|
+
if (processedKeys.has(pluralKey))
|
|
420
|
+
continue;
|
|
421
|
+
processedKeys.add(pluralKey);
|
|
422
|
+
const state = resolveAndClassify(pluralKey);
|
|
423
|
+
// An optional category (e.g. French `_many`) is a soft note
|
|
424
|
+
// whenever it isn't translated — never a hard failure. See #270.
|
|
425
|
+
if (state !== 'translated' && optionalCategories.has(category)) {
|
|
426
|
+
optionalInNs++;
|
|
427
|
+
keyDetails.push({ key: pluralKey, state: 'optional' });
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
totalInNs++;
|
|
431
|
+
if (state === 'translated')
|
|
432
|
+
translatedInNs++;
|
|
433
|
+
else if (state === 'empty')
|
|
434
|
+
emptyInNs++;
|
|
435
|
+
else
|
|
436
|
+
absentInNs++;
|
|
437
|
+
keyDetails.push({ key: pluralKey, state });
|
|
438
|
+
}
|
|
342
439
|
}
|
|
343
440
|
}
|
|
344
441
|
}
|
|
@@ -374,10 +471,11 @@ async function generateStatusReport(config) {
|
|
|
374
471
|
absentInNs++;
|
|
375
472
|
keyDetails.push({ key: variantKey, state });
|
|
376
473
|
}
|
|
377
|
-
namespaces.set(ns, { totalKeys: totalInNs, translatedKeys: translatedInNs, emptyKeys: emptyInNs, absentKeys: absentInNs, keyDetails });
|
|
474
|
+
namespaces.set(ns, { totalKeys: totalInNs, translatedKeys: translatedInNs, emptyKeys: emptyInNs, absentKeys: absentInNs, optionalKeys: optionalInNs, keyDetails });
|
|
378
475
|
totalTranslatedForLocale += translatedInNs;
|
|
379
476
|
totalEmptyForLocale += emptyInNs;
|
|
380
477
|
totalAbsentForLocale += absentInNs;
|
|
478
|
+
totalOptionalForLocale += optionalInNs;
|
|
381
479
|
totalKeysForLocale += totalInNs;
|
|
382
480
|
}
|
|
383
481
|
const localeStatus = {
|
|
@@ -385,6 +483,7 @@ async function generateStatusReport(config) {
|
|
|
385
483
|
totalTranslated: totalTranslatedForLocale,
|
|
386
484
|
totalEmpty: totalEmptyForLocale,
|
|
387
485
|
totalAbsent: totalAbsentForLocale,
|
|
486
|
+
totalOptional: totalOptionalForLocale,
|
|
388
487
|
namespaces,
|
|
389
488
|
};
|
|
390
489
|
if (isPrimary) {
|
|
@@ -476,6 +575,9 @@ async function displayDetailedLocaleReport(report, config, locale, namespaceFilt
|
|
|
476
575
|
else if (state === 'empty') {
|
|
477
576
|
console.log(` ${styleText('yellow', '~')} ${key} ${styleText('yellow', '(untranslated)')}`);
|
|
478
577
|
}
|
|
578
|
+
else if (state === 'optional') {
|
|
579
|
+
console.log(` ${styleText('gray', '○')} ${key} ${styleText('gray', '(optional plural form)')}`);
|
|
580
|
+
}
|
|
479
581
|
else {
|
|
480
582
|
console.log(` ${styleText('red', '✗')} ${key} ${styleText('red', '(absent)')}`);
|
|
481
583
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AA0jC9F;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,oBAAoB,EAC5B,EACE,uBAA+B,EAC/B,OAAe,EACf,oBAA4B,EAC5B,MAA4B,EAC7B,GAAE;IACD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAA;CACX,GACL,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiK9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-expression-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/call-expression-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAgB,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1G,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAc7D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,kBAAkB,CAAoB;IACvC,UAAU,cAAoB;IACrC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAAsC;gBAG7D,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM,EAC5B,iBAAiB,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAA2B;IAW3E;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,CAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"call-expression-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/call-expression-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAgB,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1G,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAc7D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,kBAAkB,CAAoB;IACvC,UAAU,cAAoB;IACrC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAAsC;gBAG7D,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM,EAC5B,iBAAiB,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAA2B;IAW3E;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,CAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI;IA8ZxG;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,wBAAwB;IAyEhC;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IAsDpC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,sBAAsB;IA2B9B;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;;;;;;;OAQG;IACH,OAAO,CAAC,iCAAiC;IAwFzC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IAyMxB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/comment-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAOzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC1F,IAAI,
|
|
1
|
+
{"version":3,"file":"comment-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/comment-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAOzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC1F,IAAI,CAyJN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAqC,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAgB,MAAM,gBAAgB,CAAA;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAS7D,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;gBAGlC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM;IAS9B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iCAAiC;IAgCzC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;;OAQG;IACH,gBAAgB,CAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"jsx-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAqC,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAgB,MAAM,gBAAgB,CAAA;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAS7D,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAc;gBAGlC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,MAAM,MAAM,EAC5B,cAAc,EAAE,MAAM,MAAM;IAS9B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iCAAiC;IAgCzC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;;OAQG;IACH,gBAAgB,CAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IA+UjI;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,0BAA0B;IAkIlC;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;CAevB"}
|
package/types/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,YAAY,CAAA;AAOpE;;GAEG;AACH,UAAU,aAAa;IACrB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,YAAY,CAAA;AAOpE;;GAEG;AACH,UAAU,aAAa;IACrB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAyHD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAE,aAAkB,iBA4BzF"}
|