@parallelworks/i18n 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,10 +67,13 @@ root.render(
67
67
  ```sh
68
68
  parallelworks-i18n check --dir src/i18n/locales # in CI
69
69
  parallelworks-i18n add new-messages.json --dir src/i18n/locales
70
+ parallelworks-i18n unused --dir src/i18n/locales --src src --keep apiErrors
70
71
  ```
71
72
 
72
73
  `check` fails when a locale is missing a key or has one the default doesn't, when a message isn't valid ICU, when a translation uses different arguments or rich-text tags than the default, or when a split layout's `index.ts` is stale. `add` merges messages without changing an existing one, and is safe to run from several processes at once. Its file is one locale's tree, or trees keyed by locale.
73
74
 
75
+ `unused` fails when a message in the default locale is never referenced. It reads the source with a parser, not a search: a key is used when a `useTranslations('ns')` or `getTranslations('ns')` translator, or a parameter typed `TFunction<'ns'>`, calls it (`t('key')`, `t.rich`, `t.markup`, `t.has`); when it sits under a subtree read whole, by `t.raw('key')`, a template key such as `` t(`states.${s}`) ``, a fully dynamic `t(key)` or `useMessages().ns`; or when its full dotted path appears as a string literal. A translator passed to a helper untyped matches by key suffix. It would rather miss an unused key than report a used one. `--keep` names namespaces read by key outside the source.
76
+
74
77
  `@parallelworks/i18n/node` exports the same functions and the catalog reader for an app's own scripts.
75
78
 
76
79
  ## Dates and numbers
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { readFileSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { add, check, writeIndex } from './check.js';
5
+ import { unused } from './unused.js';
5
6
  const usage = `usage: parallelworks-i18n <command> [--dir <locales>] [--default <locale>]
6
7
 
7
8
  check every locale has the default locale's keys, valid ICU messages
@@ -9,14 +10,19 @@ const usage = `usage: parallelworks-i18n <command> [--dir <locales>] [--default
9
10
  index rewrite the default locale's index.ts (one-file-per-namespace layout)
10
11
  add <file> merge messages from a JSON file without changing existing ones;
11
12
  the file is one locale's tree, or trees keyed by locale
13
+ unused list the default locale's keys that no source file references
12
14
 
13
15
  --dir locales directory (default: src/i18n/locales)
14
- --default default locale (default: en)`;
16
+ --default default locale (default: en)
17
+ --src for unused: a source directory to scan, repeatable (default: src)
18
+ --keep for unused: a namespace read by key elsewhere, such as error codes
19
+ from a server, repeatable`;
15
20
  const args = process.argv.slice(2);
16
21
  const flag = (name, fallback) => {
17
22
  const i = args.indexOf(`--${name}`);
18
23
  return i >= 0 && args[i + 1] ? (args[i + 1] ?? fallback) : fallback;
19
24
  };
25
+ const flags = (name) => args.flatMap((a, i) => (a === `--${name}` && args[i + 1] ? [args[i + 1] ?? ''] : []));
20
26
  const dir = path.resolve(flag('dir', 'src/i18n/locales'));
21
27
  const defaultLocale = flag('default', 'en');
22
28
  const [command, file] = args.filter((a, i) => !a.startsWith('--') && !args[i - 1]?.startsWith('--'));
@@ -35,6 +41,24 @@ else if (command === 'index') {
35
41
  else if (command === 'add' && file) {
36
42
  add(dir, defaultLocale, JSON.parse(readFileSync(file, 'utf8')));
37
43
  }
44
+ else if (command === 'unused') {
45
+ const src = flags('src');
46
+ const keys = unused({
47
+ dir,
48
+ defaultLocale,
49
+ src: src.length > 0 ? src : ['src'],
50
+ keep: flags('keep'),
51
+ });
52
+ for (const key of keys)
53
+ console.error(key);
54
+ if (keys.length > 0) {
55
+ console.error(`${keys.length} unused key(s) in ${defaultLocale}: use them, or remove them from every locale`);
56
+ process.exitCode = 1;
57
+ }
58
+ else {
59
+ console.log('i18n: every message is used');
60
+ }
61
+ }
38
62
  else {
39
63
  console.error(usage);
40
64
  process.exitCode = 2;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,KAAK,GAAG;;;;;;;;;0CAS4B,CAAA;AAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAClC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAE;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACnC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;AACrE,CAAC,CAAA;AACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAA;AACzD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;AAC3C,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AAEpG,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;IAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACtD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;;QACxC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,IAAI,GAAG,iBAAiB,CAAC,CAAA;AAClG,CAAC;KAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IAC/B,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;AAChC,CAAC;KAAM,IAAI,OAAO,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC;IACrC,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AACjE,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACpB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/node.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { type CatalogMap, COMMON, flatten, isSplit, listLocales, localeFiles, type Messages, readLocale, selectCatalog, } from './catalogs.js';
2
2
  export { add, argumentsOf, check, indexSource, writeIndex } from './check.js';
3
+ export { collectUsage, emptyUsage, findUnused, type UnusedOptions, type Usage, unused, } from './unused.js';
3
4
  //# sourceMappingURL=node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,MAAM,EACN,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EACX,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,MAAM,EACN,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EACX,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,MAAM,GACP,MAAM,aAAa,CAAA"}
package/dist/node.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { COMMON, flatten, isSplit, listLocales, localeFiles, readLocale, selectCatalog, } from './catalogs.js';
2
2
  export { add, argumentsOf, check, indexSource, writeIndex } from './check.js';
3
+ export { collectUsage, emptyUsage, findUnused, unused, } from './unused.js';
3
4
  //# sourceMappingURL=node.js.map
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EAEX,UAAU,EACV,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EAEX,UAAU,EACV,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EAGV,MAAM,GACP,MAAM,aAAa,CAAA"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Where messages are referenced. A key is used when it is in usedKeys, under a
3
+ * usedPrefixes subtree, written out in full as a string literal, or matched by
4
+ * an unscoped key from a translator whose namespace can't be resolved.
5
+ */
6
+ export interface Usage {
7
+ usedKeys: Set<string>;
8
+ usedPrefixes: Set<string>;
9
+ literals: Set<string>;
10
+ unscopedKeys: Set<string>;
11
+ unscopedPrefixes: Set<string>;
12
+ }
13
+ export declare function emptyUsage(): Usage;
14
+ /** What one source file references. */
15
+ export declare function collectUsage(source: string, fileName: string): Usage;
16
+ /**
17
+ * The keys nothing references. It would rather miss an unused key than report
18
+ * a used one, since a false report invites deleting a message that ships.
19
+ */
20
+ export declare function findUnused(keys: Iterable<string>, usage: Usage, keep?: readonly string[]): string[];
21
+ export interface UnusedOptions {
22
+ /** The locales directory. */
23
+ dir: string;
24
+ defaultLocale: string;
25
+ /** Source directories to scan. */
26
+ src: readonly string[];
27
+ /** Namespaces read by key outside the source, such as error codes from a server. */
28
+ keep?: readonly string[];
29
+ }
30
+ /** The default locale's keys that no source file references. */
31
+ export declare function unused({ dir, defaultLocale, src, keep }: UnusedOptions): string[];
32
+ //# sourceMappingURL=unused.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused.d.ts","sourceRoot":"","sources":["../src/unused.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC9B;AAID,wBAAgB,UAAU,IAAI,KAAK,CAQlC;AA4ED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAgJpE;AAkBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtB,KAAK,EAAE,KAAK,EACZ,IAAI,GAAE,SAAS,MAAM,EAAO,GAC3B,MAAM,EAAE,CAQV;AAeD,MAAM,WAAW,aAAa;IAC5B,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,MAAM,CAAA;IACrB,kCAAkC;IAClC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAA;IACtB,oFAAoF;IACpF,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED,gEAAgE;AAChE,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,IAAS,EAAE,EAAE,aAAa,GAAG,MAAM,EAAE,CAiBtF"}
package/dist/unused.js ADDED
@@ -0,0 +1,292 @@
1
+ import { readdirSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parse } from '@babel/parser';
4
+ import { flatten, readLocale } from './catalogs.js';
5
+ const FIELDS = ['usedKeys', 'usedPrefixes', 'literals', 'unscopedKeys', 'unscopedPrefixes'];
6
+ export function emptyUsage() {
7
+ return {
8
+ usedKeys: new Set(),
9
+ usedPrefixes: new Set(),
10
+ literals: new Set(),
11
+ unscopedKeys: new Set(),
12
+ unscopedPrefixes: new Set(),
13
+ };
14
+ }
15
+ const FACTORIES = new Set(['useTranslations', 'getTranslations']);
16
+ // Members of a translator that take a key: t.rich('key'), t.raw('key').
17
+ const METHODS = new Set(['rich', 'markup', 'raw', 'has']);
18
+ const MESSAGES_HOOK = 'useMessages';
19
+ // A translator passed to a helper untyped (`t`, `tNav`) has no namespace here.
20
+ const TRANSLATOR_NAME = /^t([A-Z]|$)/;
21
+ const SKIP_DIRS = new Set(['node_modules', 'dist', 'coverage']);
22
+ const SOURCE = /\.(?:[cm]?tsx?|[cm]?jsx?)$/;
23
+ function isNode(value) {
24
+ return (typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string');
25
+ }
26
+ function child(node, key) {
27
+ const value = node[key];
28
+ return isNode(value) ? value : undefined;
29
+ }
30
+ function children(node, key) {
31
+ const value = node[key];
32
+ return Array.isArray(value) ? value.filter(isNode) : [];
33
+ }
34
+ function name(node) {
35
+ return node?.type === 'Identifier' && typeof node['name'] === 'string' ? node['name'] : undefined;
36
+ }
37
+ /** A plain string: 'x', "x" or `x` with no substitutions. */
38
+ function text(node) {
39
+ if (node?.type === 'StringLiteral' && typeof node['value'] === 'string')
40
+ return node['value'];
41
+ if (node?.type === 'TemplateLiteral' && children(node, 'expressions').length === 0)
42
+ return templateHead(node);
43
+ return undefined;
44
+ }
45
+ function templateHead(node) {
46
+ const value = children(node, 'quasis')[0]?.['value'];
47
+ return typeof value === 'object' &&
48
+ value !== null &&
49
+ 'cooked' in value &&
50
+ typeof value.cooked === 'string'
51
+ ? value.cooked
52
+ : '';
53
+ }
54
+ const isCall = (node) => node?.type === 'CallExpression' || node?.type === 'OptionalCallExpression';
55
+ const isMember = (node) => (node?.type === 'MemberExpression' || node?.type === 'OptionalMemberExpression') &&
56
+ node['computed'] !== true;
57
+ function unwrapAwait(node) {
58
+ return node?.type === 'AwaitExpression' ? child(node, 'argument') : node;
59
+ }
60
+ function* walk(node) {
61
+ yield node;
62
+ for (const [key, value] of Object.entries(node)) {
63
+ if (key === 'loc' || key === 'extra' || key.endsWith('Comments'))
64
+ continue;
65
+ if (Array.isArray(value)) {
66
+ for (const item of value)
67
+ if (isNode(item))
68
+ yield* walk(item);
69
+ }
70
+ else if (isNode(value)) {
71
+ yield* walk(value);
72
+ }
73
+ }
74
+ }
75
+ const join = (namespace, relative) => !namespace ? relative : !relative ? namespace : `${namespace}.${relative}`;
76
+ /** What one source file references. */
77
+ export function collectUsage(source, fileName) {
78
+ const plugins = /\.[cm]?ts$/.test(fileName)
79
+ ? ['typescript']
80
+ : ['typescript', 'jsx'];
81
+ const ast = parse(source, { sourceType: 'module', plugins, errorRecovery: true });
82
+ if (!isNode(ast))
83
+ return emptyUsage();
84
+ const nodes = [...walk(ast)];
85
+ // Translator name -> namespaces it may carry; '' is the root scope, null a
86
+ // dynamic one. A name bound differently in different functions gets both.
87
+ const bindings = new Map();
88
+ const bind = (id, namespace) => {
89
+ const set = bindings.get(id) ?? new Set();
90
+ set.add(namespace);
91
+ bindings.set(id, set);
92
+ };
93
+ const messagesNames = new Set();
94
+ const isFactory = (node) => isCall(node) && FACTORIES.has(name(child(node, 'callee')) ?? '');
95
+ const isMessages = (node) => isCall(node) && name(child(node, 'callee')) === MESSAGES_HOOK;
96
+ const factoryNamespace = (call) => {
97
+ const arg = children(call, 'arguments')[0];
98
+ return arg ? (text(arg) ?? null) : '';
99
+ };
100
+ // The namespace of `t: TFunction<'ns'>`; TFunction alone is the root scope.
101
+ const annotatedNamespace = (id) => {
102
+ const annotation = child(id, 'typeAnnotation');
103
+ const ref = annotation && child(annotation, 'typeAnnotation');
104
+ if (ref?.type !== 'TSTypeReference' || name(child(ref, 'typeName')) !== 'TFunction')
105
+ return undefined;
106
+ const args = child(ref, 'typeParameters') ?? child(ref, 'typeArguments');
107
+ const first = args ? children(args, 'params')[0] : undefined;
108
+ if (!first)
109
+ return '';
110
+ return first.type === 'TSLiteralType' ? (text(child(first, 'literal')) ?? null) : null;
111
+ };
112
+ for (const node of nodes) {
113
+ if (node.type === 'VariableDeclarator') {
114
+ const id = name(child(node, 'id'));
115
+ const init = unwrapAwait(child(node, 'init'));
116
+ if (id && isFactory(init))
117
+ bind(id, factoryNamespace(init));
118
+ if (id && isMessages(init))
119
+ messagesNames.add(id);
120
+ }
121
+ if (node.type === 'Identifier' && typeof node['name'] === 'string') {
122
+ const namespace = annotatedNamespace(node);
123
+ if (namespace !== undefined)
124
+ bind(node['name'], namespace);
125
+ }
126
+ }
127
+ const usage = emptyUsage();
128
+ // An empty prefix would cover every key, so it is never recorded.
129
+ const addPrefix = (prefix) => {
130
+ if (prefix)
131
+ usage.usedPrefixes.add(prefix);
132
+ };
133
+ const record = (namespace, arg, subtree) => {
134
+ const ns = namespace ?? '';
135
+ if (!arg)
136
+ return;
137
+ const literal = text(arg);
138
+ if (literal !== undefined) {
139
+ const key = join(ns, literal);
140
+ usage.usedKeys.add(key);
141
+ if (subtree)
142
+ addPrefix(key);
143
+ }
144
+ else if (arg.type === 'TemplateLiteral') {
145
+ const head = templateHead(arg);
146
+ addPrefix(join(ns, head.slice(0, Math.max(head.lastIndexOf('.'), 0))));
147
+ }
148
+ else {
149
+ addPrefix(ns);
150
+ }
151
+ };
152
+ const recordUnscoped = (arg) => {
153
+ const literal = text(arg);
154
+ if (literal !== undefined)
155
+ usage.unscopedKeys.add(literal);
156
+ else if (arg?.type === 'TemplateLiteral') {
157
+ const head = templateHead(arg);
158
+ const dot = head.lastIndexOf('.');
159
+ if (dot > 0)
160
+ usage.unscopedPrefixes.add(head.slice(0, dot));
161
+ }
162
+ };
163
+ const resolve = (callee) => {
164
+ const id = name(callee);
165
+ if (id && bindings.has(id))
166
+ return { namespaces: bindings.get(id) ?? new Set() };
167
+ if (isFactory(callee))
168
+ return { namespaces: new Set([factoryNamespace(callee)]) };
169
+ if (isMember(callee)) {
170
+ const method = name(child(callee, 'property'));
171
+ if (!method || !METHODS.has(method))
172
+ return undefined;
173
+ const object = child(callee, 'object');
174
+ const objectId = name(object);
175
+ if (objectId && bindings.has(objectId))
176
+ return { namespaces: bindings.get(objectId) ?? new Set(), method };
177
+ if (isFactory(object))
178
+ return { namespaces: new Set([factoryNamespace(object)]), method };
179
+ }
180
+ return undefined;
181
+ };
182
+ const unscopedTranslator = (callee) => {
183
+ const id = name(callee);
184
+ if (id)
185
+ return TRANSLATOR_NAME.test(id);
186
+ return (isMember(callee) &&
187
+ TRANSLATOR_NAME.test(name(child(callee, 'object')) ?? '') &&
188
+ METHODS.has(name(child(callee, 'property')) ?? ''));
189
+ };
190
+ for (const node of nodes) {
191
+ const literal = node.type === 'StringLiteral' ? text(node) : undefined;
192
+ if (literal !== undefined)
193
+ usage.literals.add(literal);
194
+ // const { clusterForm } = useMessages()
195
+ if (node.type === 'VariableDeclarator' && isMessages(child(node, 'init'))) {
196
+ const pattern = child(node, 'id');
197
+ if (pattern?.type === 'ObjectPattern') {
198
+ for (const property of children(pattern, 'properties')) {
199
+ const key = name(child(property, 'key'));
200
+ if (key)
201
+ addPrefix(key);
202
+ }
203
+ }
204
+ }
205
+ // useMessages().clusterForm, messages.clusterForm
206
+ if (isMember(node)) {
207
+ const object = child(node, 'object');
208
+ if (isMessages(object) || messagesNames.has(name(object) ?? ''))
209
+ addPrefix(name(child(node, 'property')) ?? '');
210
+ }
211
+ if (isCall(node)) {
212
+ const callee = child(node, 'callee');
213
+ const arg = children(node, 'arguments')[0];
214
+ const resolved = resolve(callee);
215
+ if (resolved) {
216
+ for (const namespace of resolved.namespaces)
217
+ record(namespace, arg, resolved.method === 'raw');
218
+ }
219
+ else if (unscopedTranslator(callee)) {
220
+ recordUnscoped(arg);
221
+ }
222
+ }
223
+ }
224
+ return usage;
225
+ }
226
+ const covered = (key, prefixes) => {
227
+ for (const p of prefixes)
228
+ if (key === p || key.startsWith(`${p}.`))
229
+ return true;
230
+ return false;
231
+ };
232
+ // An unscoped key matches any dotted suffix of a message key, since where its
233
+ // namespace ends is unknown: 'browserDefault' covers 'languageSettings.browserDefault'.
234
+ function coveredUnscoped(key, usage) {
235
+ const parts = key.split('.');
236
+ for (let i = 0; i < parts.length; i++) {
237
+ const suffix = parts.slice(i).join('.');
238
+ if (usage.unscopedKeys.has(suffix) || covered(suffix, usage.unscopedPrefixes))
239
+ return true;
240
+ }
241
+ return false;
242
+ }
243
+ /**
244
+ * The keys nothing references. It would rather miss an unused key than report
245
+ * a used one, since a false report invites deleting a message that ships.
246
+ */
247
+ export function findUnused(keys, usage, keep = []) {
248
+ const unusedKeys = [];
249
+ for (const key of keys) {
250
+ if (usage.usedKeys.has(key) || covered(key, keep) || covered(key, usage.usedPrefixes))
251
+ continue;
252
+ if (usage.literals.has(key) || coveredUnscoped(key, usage))
253
+ continue;
254
+ unusedKeys.push(key);
255
+ }
256
+ return unusedKeys.sort();
257
+ }
258
+ function sourceFiles(dir, skip, out) {
259
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
260
+ const full = path.join(dir, entry.name);
261
+ if (entry.isDirectory()) {
262
+ if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith('.') && full !== skip)
263
+ sourceFiles(full, skip, out);
264
+ }
265
+ else if (entry.isFile() && SOURCE.test(entry.name) && !/\.d\.[cm]?ts$/.test(entry.name)) {
266
+ out.push(full);
267
+ }
268
+ }
269
+ return out;
270
+ }
271
+ /** The default locale's keys that no source file references. */
272
+ export function unused({ dir, defaultLocale, src, keep = [] }) {
273
+ const usage = emptyUsage();
274
+ const locales = path.resolve(dir);
275
+ for (const root of src) {
276
+ for (const file of sourceFiles(path.resolve(root), locales, [])) {
277
+ let found;
278
+ try {
279
+ found = collectUsage(readFileSync(file, 'utf8'), file);
280
+ }
281
+ catch (error) {
282
+ throw new Error(`${file}: ${error instanceof Error ? error.message : String(error)}`);
283
+ }
284
+ for (const field of FIELDS) {
285
+ for (const value of found[field])
286
+ usage[field].add(value);
287
+ }
288
+ }
289
+ }
290
+ return findUnused(flatten(readLocale(dir, defaultLocale)).keys(), usage, keep);
291
+ }
292
+ //# sourceMappingURL=unused.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused.js","sourceRoot":"","sources":["../src/unused.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAqB,KAAK,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAenD,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,CAAU,CAAA;AAEpG,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,YAAY,EAAE,IAAI,GAAG,EAAE;QACvB,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,YAAY,EAAE,IAAI,GAAG,EAAE;QACvB,gBAAgB,EAAE,IAAI,GAAG,EAAE;KAC5B,CAAA;AACH,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAA;AACjE,wEAAwE;AACxE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;AACzD,MAAM,aAAa,GAAG,aAAa,CAAA;AACnC,+EAA+E;AAC/E,MAAM,eAAe,GAAG,aAAa,CAAA;AACrC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;AAC/D,MAAM,MAAM,GAAG,4BAA4B,CAAA;AAI3C,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CACjG,CAAA;AACH,CAAC;AAED,SAAS,KAAK,CAAC,IAAU,EAAE,GAAW;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1C,CAAC;AAED,SAAS,QAAQ,CAAC,IAAU,EAAE,GAAW;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;IACvB,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACzD,CAAC;AAED,SAAS,IAAI,CAAC,IAAsB;IAClC,OAAO,IAAI,EAAE,IAAI,KAAK,YAAY,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACnG,CAAC;AAED,6DAA6D;AAC7D,SAAS,IAAI,CAAC,IAAsB;IAClC,IAAI,IAAI,EAAE,IAAI,KAAK,eAAe,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,CAAA;IAC7F,IAAI,IAAI,EAAE,IAAI,KAAK,iBAAiB,IAAI,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC;QAChF,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;IAC3B,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,IAAU;IAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAA;IACpD,OAAO,OAAO,KAAK,KAAK,QAAQ;QAC9B,KAAK,KAAK,IAAI;QACd,QAAQ,IAAI,KAAK;QACjB,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChC,CAAC,CAAC,KAAK,CAAC,MAAM;QACd,CAAC,CAAC,EAAE,CAAA;AACR,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,IAAsB,EAAgB,EAAE,CACtD,IAAI,EAAE,IAAI,KAAK,gBAAgB,IAAI,IAAI,EAAE,IAAI,KAAK,wBAAwB,CAAA;AAC5E,MAAM,QAAQ,GAAG,CAAC,IAAsB,EAAgB,EAAE,CACxD,CAAC,IAAI,EAAE,IAAI,KAAK,kBAAkB,IAAI,IAAI,EAAE,IAAI,KAAK,0BAA0B,CAAC;IAChF,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAA;AAE3B,SAAS,WAAW,CAAC,IAAsB;IACzC,OAAO,IAAI,EAAE,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC1E,CAAC;AAED,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAU;IACvB,MAAM,IAAI,CAAA;IACV,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,SAAQ;QAC1E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,MAAM,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/D,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAE,QAAgB,EAAE,EAAE,CACnD,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAA;AAE5E,uCAAuC;AACvC,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,QAAgB;IAC3D,MAAM,OAAO,GAAmB,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;QACzD,CAAC,CAAC,CAAC,YAAY,CAAC;QAChB,CAAC,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;IACzB,MAAM,GAAG,GAAY,KAAK,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1F,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,EAAE,CAAA;IACrC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAE5B,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAA;IACtD,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,SAAwB,EAAE,EAAE;QACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE,CAAA;QACzC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAClB,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IACvB,CAAC,CAAA;IACD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAA;IAEvC,MAAM,SAAS,GAAG,CAAC,IAAsB,EAAgB,EAAE,CACzD,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAClE,MAAM,UAAU,GAAG,CAAC,IAAsB,EAAgB,EAAE,CAC1D,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,aAAa,CAAA;IAC/D,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAiB,EAAE;QACrD,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;QAC1C,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACvC,CAAC,CAAA;IACD,4EAA4E;IAC5E,MAAM,kBAAkB,GAAG,CAAC,EAAQ,EAA6B,EAAE;QACjE,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAA;QAC9C,MAAM,GAAG,GAAG,UAAU,IAAI,KAAK,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAA;QAC7D,IAAI,GAAG,EAAE,IAAI,KAAK,iBAAiB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,KAAK,WAAW;YACjF,OAAO,SAAS,CAAA;QAClB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,gBAAgB,CAAC,IAAI,KAAK,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC5D,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAA;QACrB,OAAO,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxF,CAAC,CAAA;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACvC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;YAClC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;YAC7C,IAAI,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAA;YAC3D,IAAI,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC;gBAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACnD,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;YAC1C,IAAI,SAAS,KAAK,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,EAAE,CAAA;IAC1B,kEAAkE;IAClE,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,EAAE;QACnC,IAAI,MAAM;YAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,CAAC,SAAwB,EAAE,GAAqB,EAAE,OAAgB,EAAE,EAAE;QACnF,MAAM,EAAE,GAAG,SAAS,IAAI,EAAE,CAAA;QAC1B,IAAI,CAAC,GAAG;YAAE,OAAM;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;QACzB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;YAC7B,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvB,IAAI,OAAO;gBAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QAC7B,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;YAC9B,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxE,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,EAAE,CAAC,CAAA;QACf,CAAC;IACH,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,CAAC,GAAqB,EAAE,EAAE;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;QACzB,IAAI,OAAO,KAAK,SAAS;YAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;aACrD,IAAI,GAAG,EAAE,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACjC,IAAI,GAAG,GAAG,CAAC;gBAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,CACd,MAAwB,EACyC,EAAE;QACnE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;QACvB,IAAI,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE,EAAE,CAAA;QAChF,IAAI,SAAS,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QACjF,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;YAC9C,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO,SAAS,CAAA;YACrD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;YAC7B,IAAI,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;gBACpC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,CAAA;YACpE,IAAI,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO,EAAE,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAA;QAC3F,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,CAAC,MAAwB,EAAW,EAAE;QAC/D,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;QACvB,IAAI,EAAE;YAAE,OAAO,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACvC,OAAO,CACL,QAAQ,CAAC,MAAM,CAAC;YAChB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,CACnD,CAAA;IACH,CAAC,CAAA;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACtE,IAAI,OAAO,KAAK,SAAS;YAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAEtD,wCAAwC;QACxC,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACjC,IAAI,OAAO,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;gBACtC,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;oBACvD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;oBACxC,IAAI,GAAG;wBAAE,SAAS,CAAC,GAAG,CAAC,CAAA;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QACD,kDAAkD;QAClD,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YACpC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC7D,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QAClD,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;YAChC,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU;oBACzC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,CAAA;YACrD,CAAC;iBAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtC,cAAc,CAAC,GAAG,CAAC,CAAA;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,QAA0B,EAAE,EAAE;IAC1D,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;IAC/E,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,8EAA8E;AAC9E,wFAAwF;AACxF,SAAS,eAAe,CAAC,GAAW,EAAE,KAAY;IAChD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC;YAAE,OAAO,IAAI,CAAA;IAC5F,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,IAAsB,EACtB,KAAY,EACZ,IAAI,GAAsB,EAAE;IAE5B,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC;YAAE,SAAQ;QAC/F,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC;YAAE,SAAQ;QACpE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,EAAE,CAAA;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,IAAY,EAAE,GAAa;IAC3D,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI;gBAC5E,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;QAChC,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1F,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAYD,gEAAgE;AAChE,MAAM,UAAU,MAAM,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,EAAiB;IAC1E,MAAM,KAAK,GAAG,UAAU,EAAE,CAAA;IAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACjC,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;YAChE,IAAI,KAAY,CAAA;YAChB,IAAI,CAAC;gBACH,KAAK,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAA;YACxD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACvF,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;oBAAE,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parallelworks/i18n",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Localization for React apps on use-intl: locale negotiation, a provider, lazily loaded catalogs and catalog checks",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -43,6 +43,7 @@
43
43
  "client.d.ts"
44
44
  ],
45
45
  "dependencies": {
46
+ "@babel/parser": "^7.29.9",
46
47
  "@formatjs/icu-messageformat-parser": "^3.5.20"
47
48
  },
48
49
  "peerDependencies": {