@dialexjs/cli 0.6.0 → 0.7.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/api.d.mts +82 -1
- package/dist/api.d.mts.map +1 -1
- package/dist/api.mjs +2 -2
- package/dist/index.mjs +3 -14
- package/dist/index.mjs.map +1 -1
- package/dist/{project-DquSNdz8.mjs → project-Dz0FbydQ.mjs} +189 -71
- package/dist/project-Dz0FbydQ.mjs.map +1 -0
- package/package.json +3 -2
- package/dist/project-DquSNdz8.mjs.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import fg from "fast-glob";
|
|
4
3
|
import pc from "picocolors";
|
|
5
4
|
import { pathToFileURL } from "node:url";
|
|
6
5
|
import { generateCode, parseExpression, parseModule, writeFile } from "magicast";
|
|
6
|
+
import fg from "fast-glob";
|
|
7
|
+
import ignore from "ignore";
|
|
7
8
|
import { argumentSignature, findPlurals, getArguments, isIcuStructured, parseMessage } from "dialexjs/icu";
|
|
8
9
|
import { createHash } from "node:crypto";
|
|
9
10
|
import { DEFAULT_CONFIG } from "dialexjs";
|
|
@@ -272,6 +273,100 @@ function getLeafSource(df, locale, path) {
|
|
|
272
273
|
return generateCode(prop.type === "ObjectMethod" ? prop : prop.value).code;
|
|
273
274
|
}
|
|
274
275
|
//#endregion
|
|
276
|
+
//#region src/utils/files.ts
|
|
277
|
+
/** Folders that never hold project dictionaries or sources, in every scanner. */
|
|
278
|
+
const BUILTIN_IGNORE = [
|
|
279
|
+
"**/node_modules/**",
|
|
280
|
+
"**/dist/**",
|
|
281
|
+
"**/.next/**",
|
|
282
|
+
"**/dialex.locales/**"
|
|
283
|
+
];
|
|
284
|
+
/** What the source scan skips on top: other tools' output, declarations, generated and config files. */
|
|
285
|
+
const SOURCE_BUILTIN_IGNORE = [
|
|
286
|
+
...BUILTIN_IGNORE,
|
|
287
|
+
"**/.nuxt/**",
|
|
288
|
+
"**/.output/**",
|
|
289
|
+
"**/.svelte-kit/**",
|
|
290
|
+
"**/.astro/**",
|
|
291
|
+
"**/.turbo/**",
|
|
292
|
+
"**/coverage/**",
|
|
293
|
+
"**/graphify-out/**",
|
|
294
|
+
"**/*.d.ts",
|
|
295
|
+
"**/dialex.generated.*",
|
|
296
|
+
"**/dialex.config.*",
|
|
297
|
+
"**/i18n.config.*"
|
|
298
|
+
];
|
|
299
|
+
/** The nearest directory at or above `root` that contains `.git`, or `root` itself. */
|
|
300
|
+
function repositoryRoot(root) {
|
|
301
|
+
for (let dir = root;; dir = path.dirname(dir)) {
|
|
302
|
+
if (fs.existsSync(path.join(dir, ".git"))) return dir;
|
|
303
|
+
if (path.dirname(dir) === dir) return root;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function readScope(dir) {
|
|
307
|
+
try {
|
|
308
|
+
const text = fs.readFileSync(path.join(dir, ".gitignore"), "utf-8");
|
|
309
|
+
return {
|
|
310
|
+
dir,
|
|
311
|
+
matcher: ignore().add(text)
|
|
312
|
+
};
|
|
313
|
+
} catch {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* A function that says whether an absolute path is ignored by Git. It reads the `.gitignore`
|
|
319
|
+
* files of the project folder, of every folder above it up to the repository root (monorepo
|
|
320
|
+
* packages inherit the root's rules), and of nested folders.
|
|
321
|
+
*/
|
|
322
|
+
function createGitignoreFilter(root) {
|
|
323
|
+
const base = path.resolve(root);
|
|
324
|
+
const top = repositoryRoot(base);
|
|
325
|
+
const scopes = [];
|
|
326
|
+
for (let dir = base;; dir = path.dirname(dir)) {
|
|
327
|
+
const scope = readScope(dir);
|
|
328
|
+
if (scope) scopes.push(scope);
|
|
329
|
+
if (dir === top || path.dirname(dir) === dir) break;
|
|
330
|
+
}
|
|
331
|
+
const nested = fg.sync("**/.gitignore", {
|
|
332
|
+
cwd: base,
|
|
333
|
+
absolute: true,
|
|
334
|
+
dot: true,
|
|
335
|
+
ignore: ["**/node_modules/**", "**/.git/**"]
|
|
336
|
+
});
|
|
337
|
+
for (const file of nested) {
|
|
338
|
+
const dir = path.dirname(file);
|
|
339
|
+
if (dir === base) continue;
|
|
340
|
+
const scope = readScope(dir);
|
|
341
|
+
if (scope) scopes.push(scope);
|
|
342
|
+
}
|
|
343
|
+
if (scopes.length === 0) return () => false;
|
|
344
|
+
return (absolutePath) => {
|
|
345
|
+
for (const { dir, matcher } of scopes) {
|
|
346
|
+
const relative = path.relative(dir, absolutePath);
|
|
347
|
+
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) continue;
|
|
348
|
+
if (matcher.ignores(relative.split(path.sep).join("/"))) return true;
|
|
349
|
+
}
|
|
350
|
+
return false;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
/** Finds files under `root`, skipping build output, configured excludes and Git-ignored paths. */
|
|
354
|
+
function scanFiles(root, patterns, options = {}) {
|
|
355
|
+
const builtin = options.kind === "source" ? SOURCE_BUILTIN_IGNORE : BUILTIN_IGNORE;
|
|
356
|
+
const files = fg.sync(patterns, {
|
|
357
|
+
cwd: root,
|
|
358
|
+
absolute: true,
|
|
359
|
+
ignore: [
|
|
360
|
+
...builtin,
|
|
361
|
+
...options.exclude ?? [],
|
|
362
|
+
...options.ignore ?? []
|
|
363
|
+
]
|
|
364
|
+
});
|
|
365
|
+
if (options.gitignore === false) return files;
|
|
366
|
+
const ignored = options.gitignoreFilter ?? createGitignoreFilter(root);
|
|
367
|
+
return files.filter((file) => !ignored(file));
|
|
368
|
+
}
|
|
369
|
+
//#endregion
|
|
275
370
|
//#region src/utils/icu-check.ts
|
|
276
371
|
/** CLDR order. `resolvedOptions().pluralCategories` order differs between Node versions. */
|
|
277
372
|
const CATEGORY_ORDER = [
|
|
@@ -423,26 +518,18 @@ function lockFor(root, sourceLocale) {
|
|
|
423
518
|
}
|
|
424
519
|
//#endregion
|
|
425
520
|
//#region src/analysis.ts
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
521
|
+
function createAnalysisCache() {
|
|
522
|
+
return {
|
|
523
|
+
dictionaries: /* @__PURE__ */ new Map(),
|
|
524
|
+
sources: /* @__PURE__ */ new Map(),
|
|
525
|
+
gitignore: /* @__PURE__ */ new Map()
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
/** Forget the cached `.gitignore` rules, for example after a `.gitignore` file changed. */
|
|
529
|
+
function clearGitignore(cache) {
|
|
530
|
+
cache.gitignore.clear();
|
|
531
|
+
}
|
|
432
532
|
const DEFAULT_SOURCE_GLOB = "**/*.{ts,tsx,js,jsx,mjs,cjs,vue,svelte,astro,mdx}";
|
|
433
|
-
const SOURCE_IGNORE = [
|
|
434
|
-
...DICTIONARY_IGNORE$1,
|
|
435
|
-
"**/.nuxt/**",
|
|
436
|
-
"**/.output/**",
|
|
437
|
-
"**/.svelte-kit/**",
|
|
438
|
-
"**/.astro/**",
|
|
439
|
-
"**/coverage/**",
|
|
440
|
-
"**/graphify-out/**",
|
|
441
|
-
"**/*.d.ts",
|
|
442
|
-
"**/dialex.generated.*",
|
|
443
|
-
"**/dialex.config.*",
|
|
444
|
-
"**/i18n.config.*"
|
|
445
|
-
];
|
|
446
533
|
/** `getDictionary("x")`, `useDictionary("x")`, `@DialexDictionary("x")` */
|
|
447
534
|
const DICTIONARY_CALL = /\b(?:getDictionary|useDictionary|DialexDictionary)\(\s*(["'`])([^"'`$\n]+)\1/dg;
|
|
448
535
|
/** `t("dictionary.path.to.key")` */
|
|
@@ -577,22 +664,61 @@ async function loadDictionaryData(file, runtime) {
|
|
|
577
664
|
message: "This dictionary uses spreads, computed keys, imported values, or a computed name, so it cannot be analyzed statically."
|
|
578
665
|
};
|
|
579
666
|
}
|
|
667
|
+
function stampOf(file) {
|
|
668
|
+
try {
|
|
669
|
+
const stat = fs.statSync(file);
|
|
670
|
+
return `${stat.mtimeMs}:${stat.size}`;
|
|
671
|
+
} catch {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
async function cachedDictionary(file, runtime, cache) {
|
|
676
|
+
const stamp = cache ? stampOf(file) : void 0;
|
|
677
|
+
const hit = stamp ? cache.dictionaries.get(file) : void 0;
|
|
678
|
+
if (hit && hit.stamp === stamp) return hit.loaded;
|
|
679
|
+
const loaded = await loadDictionaryData(file, runtime);
|
|
680
|
+
if (cache && stamp) cache.dictionaries.set(file, {
|
|
681
|
+
stamp,
|
|
682
|
+
loaded
|
|
683
|
+
});
|
|
684
|
+
return loaded;
|
|
685
|
+
}
|
|
686
|
+
function scanSource(text) {
|
|
687
|
+
const starts = lineStarts(text);
|
|
688
|
+
const rangeOf = (start, end) => ({
|
|
689
|
+
start: positionAt(starts, start),
|
|
690
|
+
end: positionAt(starts, end)
|
|
691
|
+
});
|
|
692
|
+
return {
|
|
693
|
+
tokens: [...new Set(text.match(/[\w$-]+/g) ?? [])],
|
|
694
|
+
refs: scanReferences(text).map((ref) => ({
|
|
695
|
+
ref,
|
|
696
|
+
range: rangeOf(ref.start, ref.end)
|
|
697
|
+
}))
|
|
698
|
+
};
|
|
699
|
+
}
|
|
580
700
|
async function analyzeProject(options) {
|
|
581
701
|
const { root, config } = options;
|
|
582
702
|
const include = config.include || "**/*.content.ts";
|
|
583
703
|
const configuredLocales = config.locales || [];
|
|
584
704
|
const defaultLocale = config.defaultLocale || "en";
|
|
585
705
|
const extraIgnore = options.ignore ?? [];
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
706
|
+
const cache = options.runtime ? void 0 : options.cache;
|
|
707
|
+
let gitignore = cache?.gitignore.get(root);
|
|
708
|
+
if (cache && !gitignore) {
|
|
709
|
+
gitignore = createGitignoreFilter(root);
|
|
710
|
+
cache.gitignore.set(root, gitignore);
|
|
711
|
+
}
|
|
712
|
+
const files = scanFiles(root, include, {
|
|
713
|
+
exclude: config.exclude,
|
|
714
|
+
ignore: extraIgnore,
|
|
715
|
+
gitignoreFilter: gitignore
|
|
590
716
|
});
|
|
591
717
|
const issues = [];
|
|
592
718
|
const dictionaries = [];
|
|
593
719
|
const lock = options.lock === false ? void 0 : readLock(root);
|
|
594
720
|
for (const file of files) {
|
|
595
|
-
const loaded = await
|
|
721
|
+
const loaded = await cachedDictionary(file, options.runtime === true, cache);
|
|
596
722
|
if (!loaded.ok) {
|
|
597
723
|
for (const message of loaded.message.split("\n")) issues.push({
|
|
598
724
|
file,
|
|
@@ -699,34 +825,39 @@ async function analyzeProject(options) {
|
|
|
699
825
|
const known = new Map(dictionaries.map((d) => [d.name, d]));
|
|
700
826
|
const dictionaryFiles = new Set(files);
|
|
701
827
|
const sourceGlobs = options.src ?? ["**/*.{ts,tsx,js,jsx,mjs,cjs,vue,svelte,astro,mdx}"];
|
|
702
|
-
const sourceFiles = sourceGlobs.length === 0 ? [] :
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
ignore:
|
|
828
|
+
const sourceFiles = sourceGlobs.length === 0 ? [] : scanFiles(root, sourceGlobs, {
|
|
829
|
+
kind: "source",
|
|
830
|
+
exclude: config.exclude,
|
|
831
|
+
ignore: extraIgnore,
|
|
832
|
+
gitignoreFilter: gitignore
|
|
706
833
|
}).filter((f) => !dictionaryFiles.has(f));
|
|
707
834
|
if (sourceFiles.length > 0) {
|
|
708
835
|
const tokens = /* @__PURE__ */ new Set();
|
|
709
836
|
for (const file of sourceFiles) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
837
|
+
const stamp = cache ? stampOf(file) : void 0;
|
|
838
|
+
let scan = stamp ? cache.sources.get(file) : void 0;
|
|
839
|
+
if (!scan || scan.stamp !== stamp) {
|
|
840
|
+
let text;
|
|
841
|
+
try {
|
|
842
|
+
text = fs.readFileSync(file, "utf-8");
|
|
843
|
+
} catch {
|
|
844
|
+
continue;
|
|
845
|
+
}
|
|
846
|
+
scan = {
|
|
847
|
+
stamp: stamp ?? "",
|
|
848
|
+
scan: scanSource(text)
|
|
849
|
+
};
|
|
850
|
+
if (cache && stamp) cache.sources.set(file, scan);
|
|
715
851
|
}
|
|
716
|
-
for (const token of
|
|
717
|
-
const
|
|
718
|
-
const rangeOf = (start, end) => ({
|
|
719
|
-
start: positionAt(starts, start),
|
|
720
|
-
end: positionAt(starts, end)
|
|
721
|
-
});
|
|
722
|
-
for (const ref of scanReferences(text)) {
|
|
852
|
+
for (const token of scan.scan.tokens) tokens.add(token);
|
|
853
|
+
for (const { ref, range } of scan.scan.refs) {
|
|
723
854
|
if (ref.kind === "dictionary") {
|
|
724
855
|
if (!known.has(ref.value)) issues.push({
|
|
725
856
|
file,
|
|
726
857
|
level: "error",
|
|
727
858
|
code: "unknown-dictionary",
|
|
728
859
|
message: `Unknown dictionary "${ref.value}"`,
|
|
729
|
-
range
|
|
860
|
+
range,
|
|
730
861
|
dictionary: ref.value
|
|
731
862
|
});
|
|
732
863
|
continue;
|
|
@@ -740,7 +871,7 @@ async function analyzeProject(options) {
|
|
|
740
871
|
level: "error",
|
|
741
872
|
code: "unknown-path",
|
|
742
873
|
message: `Unknown translation path "${ref.value}"`,
|
|
743
|
-
range
|
|
874
|
+
range,
|
|
744
875
|
dictionary: name,
|
|
745
876
|
path: rest
|
|
746
877
|
});
|
|
@@ -774,6 +905,10 @@ async function analyzeProject(options) {
|
|
|
774
905
|
}
|
|
775
906
|
}
|
|
776
907
|
}
|
|
908
|
+
if (cache) {
|
|
909
|
+
const live = /* @__PURE__ */ new Set([...files, ...sourceFiles]);
|
|
910
|
+
for (const map of [cache.dictionaries, cache.sources]) for (const key of map.keys()) if (key.startsWith(root) && !live.has(key)) map.delete(key);
|
|
911
|
+
}
|
|
777
912
|
return {
|
|
778
913
|
issues,
|
|
779
914
|
dictionaries,
|
|
@@ -1132,6 +1267,7 @@ const DEFAULT_STATIC_CONFIG = {
|
|
|
1132
1267
|
defaultLocale: "en",
|
|
1133
1268
|
locales: [],
|
|
1134
1269
|
include: "**/*.content.ts",
|
|
1270
|
+
exclude: [],
|
|
1135
1271
|
fallbacks: {},
|
|
1136
1272
|
prefixDefault: true,
|
|
1137
1273
|
lazy: false
|
|
@@ -1179,6 +1315,7 @@ function apply(object, config, notes) {
|
|
|
1179
1315
|
accept("defaultLocale", (v) => typeof v === "string" && v !== "", "a string literal");
|
|
1180
1316
|
accept("locales", isStringArray, "an array of string literals");
|
|
1181
1317
|
accept("include", (v) => typeof v === "string" || isStringArray(v), "a string or array of strings");
|
|
1318
|
+
accept("exclude", isStringArray, "an array of string literals");
|
|
1182
1319
|
accept("fallbacks", (v) => typeof v === "object" && v !== null && Object.values(v).every((list) => isStringArray(list)), "an object of string arrays");
|
|
1183
1320
|
accept("prefixDefault", (v) => typeof v === "boolean", "true or false");
|
|
1184
1321
|
accept("lazy", (v) => typeof v === "boolean" || v === "locale", "true, false or \"locale\"");
|
|
@@ -1210,6 +1347,7 @@ function parseStaticConfig(text, file = "dialex.config.ts") {
|
|
|
1210
1347
|
"defaultLocale",
|
|
1211
1348
|
"locales",
|
|
1212
1349
|
"include",
|
|
1350
|
+
"exclude",
|
|
1213
1351
|
"fallbacks",
|
|
1214
1352
|
"prefixDefault",
|
|
1215
1353
|
"lazy"
|
|
@@ -1308,12 +1446,6 @@ function relativeImportExtension(root) {
|
|
|
1308
1446
|
}
|
|
1309
1447
|
//#endregion
|
|
1310
1448
|
//#region src/commands/generate.ts
|
|
1311
|
-
const DICTIONARY_IGNORE = [
|
|
1312
|
-
"**/node_modules/**",
|
|
1313
|
-
"**/dist/**",
|
|
1314
|
-
"**/.next/**",
|
|
1315
|
-
"**/dialex.locales/**"
|
|
1316
|
-
];
|
|
1317
1449
|
/** The folder, next to `dialex.generated.ts`, that holds the per-locale modules. */
|
|
1318
1450
|
const LOCALES_DIR = "dialex.locales";
|
|
1319
1451
|
const safeName = (text) => text.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
@@ -1328,12 +1460,7 @@ function renderGenerated(root, options = {}) {
|
|
|
1328
1460
|
const inlineConfig = options.config ? { configFile: options.config } : {};
|
|
1329
1461
|
const staticRead = readStaticConfig(root, options.config);
|
|
1330
1462
|
const config = options.static ? staticRead.config : resolveDialexConfig(root, inlineConfig);
|
|
1331
|
-
const
|
|
1332
|
-
const found = fg.sync(include, {
|
|
1333
|
-
cwd: root,
|
|
1334
|
-
absolute: true,
|
|
1335
|
-
ignore: DICTIONARY_IGNORE
|
|
1336
|
-
}).sort();
|
|
1463
|
+
const found = scanFiles(root, config.include || DEFAULT_CONFIG.include, { exclude: config.exclude }).sort();
|
|
1337
1464
|
const srcDir = fs.existsSync(path.join(root, "src")) ? path.join(root, "src") : root;
|
|
1338
1465
|
const outputPath = options.output ? path.resolve(root, options.output) : path.join(srcDir, "dialex.generated.ts");
|
|
1339
1466
|
const outputDir = path.dirname(outputPath);
|
|
@@ -1507,7 +1634,7 @@ const CONFIG_FILE = /(^|[\\/])(dialex|i18n)\.config\.[cm]?[jt]s(on)?$/;
|
|
|
1507
1634
|
* understands globs, so this watches the project directory and decides for itself which events
|
|
1508
1635
|
* matter, using the same `include` glob as `generate`.
|
|
1509
1636
|
*/
|
|
1510
|
-
function startGenerateWatcher(root, options, regenerate, delay = 100) {
|
|
1637
|
+
function startGenerateWatcher(root, options, regenerate, delay = 100, log = (message) => logger.info(message)) {
|
|
1511
1638
|
const dictionaryFiles = () => new Set(renderGenerated(root, options).files);
|
|
1512
1639
|
let known = dictionaryFiles();
|
|
1513
1640
|
let outputs = /* @__PURE__ */ new Set();
|
|
@@ -1523,9 +1650,10 @@ function startGenerateWatcher(root, options, regenerate, delay = 100) {
|
|
|
1523
1650
|
} catch {}
|
|
1524
1651
|
}, delay);
|
|
1525
1652
|
};
|
|
1653
|
+
const gitIgnored = createGitignoreFilter(root);
|
|
1526
1654
|
const watcher = chokidar.watch(root, {
|
|
1527
1655
|
ignoreInitial: true,
|
|
1528
|
-
ignored: (file) => WATCH_IGNORED.test(file)
|
|
1656
|
+
ignored: (file) => WATCH_IGNORED.test(file) || gitIgnored(path.resolve(root, file))
|
|
1529
1657
|
});
|
|
1530
1658
|
watcher.on("all", (event, filePath) => {
|
|
1531
1659
|
const file = path.resolve(root, filePath);
|
|
@@ -1542,7 +1670,7 @@ function startGenerateWatcher(root, options, regenerate, delay = 100) {
|
|
|
1542
1670
|
}
|
|
1543
1671
|
if (!(now.size !== known.size || [...now].some((f) => !known.has(f))) && !isConfig) return;
|
|
1544
1672
|
} else return;
|
|
1545
|
-
|
|
1673
|
+
log(`[${event}] ${path.relative(root, file)} changed, regenerating...`);
|
|
1546
1674
|
trigger();
|
|
1547
1675
|
});
|
|
1548
1676
|
return watcher;
|
|
@@ -1550,17 +1678,7 @@ function startGenerateWatcher(root, options, regenerate, delay = 100) {
|
|
|
1550
1678
|
//#endregion
|
|
1551
1679
|
//#region src/utils/project.ts
|
|
1552
1680
|
async function loadDictionaries(root, config) {
|
|
1553
|
-
const
|
|
1554
|
-
const files = fg.sync(include, {
|
|
1555
|
-
cwd: root,
|
|
1556
|
-
absolute: true,
|
|
1557
|
-
ignore: [
|
|
1558
|
-
"**/node_modules/**",
|
|
1559
|
-
"**/dist/**",
|
|
1560
|
-
"**/.next/**",
|
|
1561
|
-
"**/dialex.locales/**"
|
|
1562
|
-
]
|
|
1563
|
-
});
|
|
1681
|
+
const files = scanFiles(root, config.include || "**/*.content.ts", { exclude: config.exclude });
|
|
1564
1682
|
const dictionaries = [];
|
|
1565
1683
|
const unsupported = [];
|
|
1566
1684
|
for (const file of files) {
|
|
@@ -1611,6 +1729,6 @@ async function loadStaticProject(root, configFile) {
|
|
|
1611
1729
|
/** `home` + `["nav", "about"]` -> `home.nav.about` */
|
|
1612
1730
|
const toKey = (dictionary, keyPath) => [dictionary, ...keyPath].join(".");
|
|
1613
1731
|
//#endregion
|
|
1614
|
-
export {
|
|
1732
|
+
export { scanFiles as A, locationOf as B, lockPath as C, BUILTIN_IGNORE as D, writeLock as E, getString as F, renderDictionaryFile as H, hasPath as I, listLeaves as L, copyLeaf as M, dictionaryLocation as N, SOURCE_BUILTIN_IGNORE as O, getLeafSource as P, listLocales as R, lockFor as S, record as T, saveDictionaryFile as U, parseDictionaryText as V, setString as W, relativeFile as _, renderGenerated as a, hashSource as b, DEFAULT_STATIC_CONFIG as c, resolveDialexConfig as d, logger as f, createAnalysisCache as g, clearGitignore as h, generateDictionaries as i, TODO_PREFIX as j, createGitignoreFilter as k, parseStaticConfig as l, analyzeProject as m, loadStaticProject as n, runGenerate as o, DEFAULT_SOURCE_GLOB as p, toKey as r, startGenerateWatcher as s, loadProject as t, readStaticConfig as u, scanReferences as v, readLock as w, isStale as x, LOCK_FILE as y, loadDictionaryFile as z };
|
|
1615
1733
|
|
|
1616
|
-
//# sourceMappingURL=project-
|
|
1734
|
+
//# sourceMappingURL=project-Dz0FbydQ.mjs.map
|