@babelize/engine 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/dist/BabelizeEngine.d.ts +12 -0
- package/dist/BabelizeEngine.js +47 -0
- package/dist/analysis/analyze.d.ts +106 -0
- package/dist/analysis/analyze.js +323 -0
- package/dist/config/env.d.ts +9 -0
- package/dist/config/env.js +16 -0
- package/dist/config.d.ts +74 -0
- package/dist/config.js +47 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +126 -0
- package/dist/injection/InjectionStrategy.d.ts +62 -0
- package/dist/injection/InjectionStrategy.js +2 -0
- package/dist/injection/StrategyFactory.d.ts +4 -0
- package/dist/injection/StrategyFactory.js +29 -0
- package/dist/injection/django/django-template-injector.d.ts +29 -0
- package/dist/injection/django/django-template-injector.js +216 -0
- package/dist/injection/html/html-injector.d.ts +11 -0
- package/dist/injection/html/html-injector.js +173 -0
- package/dist/injection/strategies/NextIntlStrategy.d.ts +25 -0
- package/dist/injection/strategies/NextIntlStrategy.js +141 -0
- package/dist/injection/strategies/ReactI18nextStrategy.d.ts +19 -0
- package/dist/injection/strategies/ReactI18nextStrategy.js +116 -0
- package/dist/injection/strategies/VanillaStrategy.d.ts +11 -0
- package/dist/injection/strategies/VanillaStrategy.js +73 -0
- package/dist/injection/strategies/VueI18nStrategy.d.ts +11 -0
- package/dist/injection/strategies/VueI18nStrategy.js +84 -0
- package/dist/local/formatter.d.ts +26 -0
- package/dist/local/formatter.js +105 -0
- package/dist/local/git.d.ts +23 -0
- package/dist/local/git.js +136 -0
- package/dist/local/hosted-provider.d.ts +68 -0
- package/dist/local/hosted-provider.js +215 -0
- package/dist/local/index.d.ts +23 -0
- package/dist/local/index.js +75 -0
- package/dist/local/provider.d.ts +56 -0
- package/dist/local/provider.js +119 -0
- package/dist/local/pseudo-provider.d.ts +18 -0
- package/dist/local/pseudo-provider.js +207 -0
- package/dist/local/report.d.ts +177 -0
- package/dist/local/report.js +186 -0
- package/dist/local/translate-core.d.ts +215 -0
- package/dist/local/translate-core.js +461 -0
- package/dist/local/translate-messages.d.ts +49 -0
- package/dist/local/translate-messages.js +91 -0
- package/dist/local/workspace-copy.d.ts +91 -0
- package/dist/local/workspace-copy.js +355 -0
- package/dist/modules/extractor/extract.d.ts +20 -0
- package/dist/modules/extractor/extract.js +701 -0
- package/dist/modules/extractor/index.d.ts +2 -0
- package/dist/modules/extractor/index.js +63 -0
- package/dist/modules/finalization/django-finalize.d.ts +13 -0
- package/dist/modules/finalization/django-finalize.js +275 -0
- package/dist/modules/finalization/finalize.d.ts +36 -0
- package/dist/modules/finalization/finalize.js +717 -0
- package/dist/modules/finalization/index.d.ts +1 -0
- package/dist/modules/finalization/index.js +5 -0
- package/dist/modules/finalization/nextjs-finalize.d.ts +37 -0
- package/dist/modules/finalization/nextjs-finalize.js +329 -0
- package/dist/modules/finalization/static-runtime.d.ts +9 -0
- package/dist/modules/finalization/static-runtime.js +261 -0
- package/dist/modules/format-injection/index.d.ts +19 -0
- package/dist/modules/format-injection/index.js +272 -0
- package/dist/modules/format-injection/inject-formats.d.ts +31 -0
- package/dist/modules/format-injection/inject-formats.js +208 -0
- package/dist/modules/glossary/glossary.d.ts +9 -0
- package/dist/modules/glossary/glossary.js +27 -0
- package/dist/modules/glossary/index.d.ts +3 -0
- package/dist/modules/glossary/index.js +8 -0
- package/dist/modules/glossary/masker.d.ts +23 -0
- package/dist/modules/glossary/masker.js +56 -0
- package/dist/modules/glossary/types.d.ts +22 -0
- package/dist/modules/glossary/types.js +2 -0
- package/dist/modules/injection/index.d.ts +1 -0
- package/dist/modules/injection/index.js +6 -0
- package/dist/modules/injection/inject.d.ts +29 -0
- package/dist/modules/injection/inject.js +1066 -0
- package/dist/modules/keygen/index.d.ts +1 -0
- package/dist/modules/keygen/index.js +11 -0
- package/dist/modules/keygen/keygen.d.ts +4 -0
- package/dist/modules/keygen/keygen.js +116 -0
- package/dist/modules/keygen/locale-data.d.ts +7 -0
- package/dist/modules/keygen/locale-data.js +73 -0
- package/dist/modules/keygen/public.d.ts +2 -0
- package/dist/modules/keygen/public.js +12 -0
- package/dist/modules/locale-builder/index.d.ts +1 -0
- package/dist/modules/locale-builder/index.js +7 -0
- package/dist/modules/locale-builder/locales.d.ts +13 -0
- package/dist/modules/locale-builder/locales.js +107 -0
- package/dist/modules/locale-builder/po.d.ts +33 -0
- package/dist/modules/locale-builder/po.js +131 -0
- package/dist/modules/lockfile/hasher.d.ts +7 -0
- package/dist/modules/lockfile/hasher.js +13 -0
- package/dist/modules/lockfile/index.d.ts +3 -0
- package/dist/modules/lockfile/index.js +21 -0
- package/dist/modules/lockfile/lockfile-manager.d.ts +90 -0
- package/dist/modules/lockfile/lockfile-manager.js +482 -0
- package/dist/modules/lockfile/schema.d.ts +154 -0
- package/dist/modules/lockfile/schema.js +45 -0
- package/dist/modules/parser/index.d.ts +2 -0
- package/dist/modules/parser/index.js +9 -0
- package/dist/modules/summary/index.d.ts +1 -0
- package/dist/modules/summary/index.js +7 -0
- package/dist/modules/summary/summary.d.ts +9 -0
- package/dist/modules/summary/summary.js +195 -0
- package/dist/modules/sync-detector/index.d.ts +2 -0
- package/dist/modules/sync-detector/index.js +7 -0
- package/dist/modules/sync-detector/reporter.d.ts +3 -0
- package/dist/modules/sync-detector/reporter.js +16 -0
- package/dist/modules/sync-detector/sync-detector.d.ts +39 -0
- package/dist/modules/sync-detector/sync-detector.js +374 -0
- package/dist/modules/translator/batch-optimizer.d.ts +12 -0
- package/dist/modules/translator/batch-optimizer.js +30 -0
- package/dist/modules/translator/client/byok.provider.d.ts +64 -0
- package/dist/modules/translator/client/byok.provider.js +319 -0
- package/dist/modules/translator/client/direct-translator.client.d.ts +12 -0
- package/dist/modules/translator/client/direct-translator.client.js +71 -0
- package/dist/modules/translator/client/gemini.provider.d.ts +1 -0
- package/dist/modules/translator/client/gemini.provider.js +110 -0
- package/dist/modules/translator/client/groq.provider.d.ts +1 -0
- package/dist/modules/translator/client/groq.provider.js +111 -0
- package/dist/modules/translator/client/request.types.d.ts +1 -0
- package/dist/modules/translator/client/request.types.js +2 -0
- package/dist/modules/translator/client/retry.d.ts +29 -0
- package/dist/modules/translator/client/retry.js +94 -0
- package/dist/modules/translator/client/test-utils/mock.client.d.ts +31 -0
- package/dist/modules/translator/client/test-utils/mock.client.js +59 -0
- package/dist/modules/translator/client/translator.interface.d.ts +1 -0
- package/dist/modules/translator/client/translator.interface.js +2 -0
- package/dist/modules/translator/language-codes/errors.d.ts +10 -0
- package/dist/modules/translator/language-codes/errors.js +18 -0
- package/dist/modules/translator/language-codes/flores-map.d.ts +1 -0
- package/dist/modules/translator/language-codes/flores-map.js +107 -0
- package/dist/modules/translator/language-codes/index.d.ts +11 -0
- package/dist/modules/translator/language-codes/index.js +24 -0
- package/dist/modules/translator/language-codes/language-mapper.d.ts +25 -0
- package/dist/modules/translator/language-codes/language-mapper.js +132 -0
- package/dist/modules/translator/language-codes/rtl-languages.d.ts +2 -0
- package/dist/modules/translator/language-codes/rtl-languages.js +9 -0
- package/dist/modules/translator/memory/memory-matcher.d.ts +8 -0
- package/dist/modules/translator/memory/memory-matcher.js +218 -0
- package/dist/modules/translator/memory/types.d.ts +22 -0
- package/dist/modules/translator/memory/types.js +2 -0
- package/dist/modules/translator/translate.d.ts +38 -0
- package/dist/modules/translator/translate.js +932 -0
- package/dist/modules/translator/translator.d.ts +5 -0
- package/dist/modules/translator/translator.js +46 -0
- package/dist/modules/vue/migrate.d.ts +13 -0
- package/dist/modules/vue/migrate.js +40 -0
- package/dist/modules/vue/script-inject.d.ts +16 -0
- package/dist/modules/vue/script-inject.js +115 -0
- package/dist/modules/vue/sfc.d.ts +11 -0
- package/dist/modules/vue/sfc.js +51 -0
- package/dist/modules/vue/template-rewrite.d.ts +25 -0
- package/dist/modules/vue/template-rewrite.js +76 -0
- package/dist/modules/vue/template-scan.d.ts +29 -0
- package/dist/modules/vue/template-scan.js +264 -0
- package/dist/modules/workspace/index.d.ts +1 -0
- package/dist/modules/workspace/index.js +5 -0
- package/dist/modules/workspace/validate.d.ts +13 -0
- package/dist/modules/workspace/validate.js +298 -0
- package/dist/orchestrator.d.ts +8 -0
- package/dist/orchestrator.js +616 -0
- package/dist/providers/default-translation-provider.d.ts +20 -0
- package/dist/providers/default-translation-provider.js +30 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.js +21 -0
- package/dist/providers/types.d.ts +145 -0
- package/dist/providers/types.js +2 -0
- package/dist/qa/check-project.d.ts +49 -0
- package/dist/qa/check-project.js +150 -0
- package/dist/qa/locale-files.d.ts +44 -0
- package/dist/qa/locale-files.js +159 -0
- package/dist/qa/locale-qa.d.ts +61 -0
- package/dist/qa/locale-qa.js +325 -0
- package/dist/qa/review.d.ts +43 -0
- package/dist/qa/review.js +175 -0
- package/dist/runtime/config.d.ts +8 -0
- package/dist/runtime/config.js +36 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/types.d.ts +363 -0
- package/dist/runtime/types.js +38 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.js +12 -0
- package/dist/utils/ast-helpers.d.ts +57 -0
- package/dist/utils/ast-helpers.js +608 -0
- package/dist/utils/cache-keys.d.ts +8 -0
- package/dist/utils/cache-keys.js +18 -0
- package/dist/utils/circuit-breaker.d.ts +43 -0
- package/dist/utils/circuit-breaker.js +119 -0
- package/dist/utils/concurrent-map.d.ts +4 -0
- package/dist/utils/concurrent-map.js +21 -0
- package/dist/utils/detect-format.d.ts +5 -0
- package/dist/utils/detect-format.js +125 -0
- package/dist/utils/dtl-mask.d.ts +25 -0
- package/dist/utils/dtl-mask.js +58 -0
- package/dist/utils/extraction-options.d.ts +23 -0
- package/dist/utils/extraction-options.js +23 -0
- package/dist/utils/file-utils.d.ts +33 -0
- package/dist/utils/file-utils.js +262 -0
- package/dist/utils/glossary-match.d.ts +9 -0
- package/dist/utils/glossary-match.js +25 -0
- package/dist/utils/html-extractor.d.ts +8 -0
- package/dist/utils/html-extractor.js +317 -0
- package/dist/utils/i18next-icu.d.ts +38 -0
- package/dist/utils/i18next-icu.js +159 -0
- package/dist/utils/icu-message.d.ts +65 -0
- package/dist/utils/icu-message.js +346 -0
- package/dist/utils/icu-spans.d.ts +10 -0
- package/dist/utils/icu-spans.js +126 -0
- package/dist/utils/jsx-message.d.ts +93 -0
- package/dist/utils/jsx-message.js +621 -0
- package/dist/utils/key-usage.d.ts +35 -0
- package/dist/utils/key-usage.js +247 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.js +33 -0
- package/dist/utils/metadata.d.ts +80 -0
- package/dist/utils/metadata.js +255 -0
- package/dist/utils/module-constants.d.ts +30 -0
- package/dist/utils/module-constants.js +265 -0
- package/dist/utils/not-injected.d.ts +6 -0
- package/dist/utils/not-injected.js +36 -0
- package/dist/utils/placeholder-protection.d.ts +57 -0
- package/dist/utils/placeholder-protection.js +136 -0
- package/dist/utils/pseudo-markers.d.ts +9 -0
- package/dist/utils/pseudo-markers.js +16 -0
- package/dist/utils/py-extractor.d.ts +14 -0
- package/dist/utils/py-extractor.js +285 -0
- package/dist/utils/string-utils.d.ts +52 -0
- package/dist/utils/string-utils.js +270 -0
- package/dist/utils/translation-quality.d.ts +34 -0
- package/dist/utils/translation-quality.js +156 -0
- package/dist/utils/translation-sanitizer.d.ts +10 -0
- package/dist/utils/translation-sanitizer.js +57 -0
- package/dist/utils/translator-caller.d.ts +32 -0
- package/dist/utils/translator-caller.js +217 -0
- package/dist/utils/translator-load-balancer.d.ts +73 -0
- package/dist/utils/translator-load-balancer.js +293 -0
- package/dist/utils/ui-copy.d.ts +32 -0
- package/dist/utils/ui-copy.js +126 -0
- package/dist/utils/workspace.d.ts +14 -0
- package/dist/utils/workspace.js +89 -0
- package/package.json +64 -4
- package/schemas/translate-report.schema.json +297 -0
- package/README.md +0 -3
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.frameworkSupport = frameworkSupport;
|
|
40
|
+
exports.analyzeProject = analyzeProject;
|
|
41
|
+
exports.analyzeWorkspace = analyzeWorkspace;
|
|
42
|
+
/**
|
|
43
|
+
* Localization readiness of a local project, from the same pipeline phases
|
|
44
|
+
* `babelize translate` runs — validate, extract, keygen, inject and finalize,
|
|
45
|
+
* all in dry-run mode on a temp copy — but with no translation, no network
|
|
46
|
+
* and no writes to the project.
|
|
47
|
+
*/
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const types_1 = require("@babelize/types");
|
|
50
|
+
const workspace_1 = require("../modules/workspace");
|
|
51
|
+
const extract_1 = require("../modules/extractor/extract");
|
|
52
|
+
const keygen_1 = require("../modules/keygen");
|
|
53
|
+
const locale_builder_1 = require("../modules/locale-builder");
|
|
54
|
+
const injection_1 = require("../modules/injection");
|
|
55
|
+
const finalization_1 = require("../modules/finalization");
|
|
56
|
+
const finalize_1 = require("../modules/finalization/finalize");
|
|
57
|
+
const file_utils_1 = require("../utils/file-utils");
|
|
58
|
+
const not_injected_1 = require("../utils/not-injected");
|
|
59
|
+
const key_usage_1 = require("../utils/key-usage");
|
|
60
|
+
const extraction_options_1 = require("../utils/extraction-options");
|
|
61
|
+
const check_project_1 = require("../qa/check-project");
|
|
62
|
+
const workspace_copy_1 = require("../local/workspace-copy");
|
|
63
|
+
const translate_core_1 = require("../local/translate-core");
|
|
64
|
+
const static_runtime_1 = require("../modules/finalization/static-runtime");
|
|
65
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
66
|
+
const fs_1 = require("fs");
|
|
67
|
+
/** How well `babelize translate` handles a detected framework. */
|
|
68
|
+
function frameworkSupport(framework) {
|
|
69
|
+
if (translate_core_1.SUPPORTED_LOCAL_FRAMEWORKS.includes(framework))
|
|
70
|
+
return 'supported';
|
|
71
|
+
if (translate_core_1.BETA_LOCAL_FRAMEWORKS.includes(framework))
|
|
72
|
+
return 'beta';
|
|
73
|
+
return 'unsupported';
|
|
74
|
+
}
|
|
75
|
+
const ADVISORY_WARNINGS = new Set(['hardcoded-currency', 'hardcoded-date', 'hardcoded-plural', 'complex-expression', 'dynamic-string', 'ambiguous-format']);
|
|
76
|
+
function lineOf(extractionId) {
|
|
77
|
+
const n = Number(extractionId.split(':')[1]);
|
|
78
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
79
|
+
}
|
|
80
|
+
function toPosix(p) {
|
|
81
|
+
return p.split(path.sep).join('/');
|
|
82
|
+
}
|
|
83
|
+
/** Analyze `projectDir` on a temp copy; the project itself is only read. */
|
|
84
|
+
async function analyzeProject(projectDir, options = {}) {
|
|
85
|
+
const dir = path.resolve(projectDir);
|
|
86
|
+
// Same copy translate makes (gitignored files skipped in a repo), so the
|
|
87
|
+
// report matches what a run would see.
|
|
88
|
+
const temp = await (0, workspace_copy_1.createTempCopy)(dir, { files: (await (0, workspace_copy_1.listGitFiles)(dir)) ?? undefined, tmpRoot: options.tmpRoot });
|
|
89
|
+
try {
|
|
90
|
+
return await analyzeWorkspace(temp.dir, options);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
await temp.cleanup();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Analyze a workspace in place. Pipeline phases run in dry-run mode, but
|
|
98
|
+
* framework detection creates `.babelize/`: call it on a disposable copy
|
|
99
|
+
* (see {@link analyzeProject}).
|
|
100
|
+
*/
|
|
101
|
+
async function analyzeWorkspace(workspacePath, options = {}) {
|
|
102
|
+
const startedAt = Date.now();
|
|
103
|
+
const config = await (0, check_project_1.readProjectLocaleConfig)(workspacePath);
|
|
104
|
+
const sourceLocale = options.sourceLocale ?? config.sourceLocale ?? 'en';
|
|
105
|
+
const targetLocales = (options.targetLocales ?? config.targetLocales ?? []).filter((l) => l !== sourceLocale);
|
|
106
|
+
const empty = (framework, error) => ({
|
|
107
|
+
framework,
|
|
108
|
+
support: 'unsupported',
|
|
109
|
+
error,
|
|
110
|
+
sourceLocale,
|
|
111
|
+
setup: { library: 'none', missingDependencies: [], wiredUp: false, pendingChanges: [], notes: [] },
|
|
112
|
+
files: { scanned: 0, withStrings: 0, skipped: [] },
|
|
113
|
+
strings: [],
|
|
114
|
+
groupedSentences: [],
|
|
115
|
+
fragmentedSentences: [],
|
|
116
|
+
notInjectable: [],
|
|
117
|
+
warnings: [],
|
|
118
|
+
locales: [],
|
|
119
|
+
unusedKeys: [],
|
|
120
|
+
dynamicKeyFiles: [],
|
|
121
|
+
nextSteps: [error],
|
|
122
|
+
durationMs: Date.now() - startedAt,
|
|
123
|
+
});
|
|
124
|
+
(0, file_utils_1.clearFindFilesCache)();
|
|
125
|
+
let workspace;
|
|
126
|
+
try {
|
|
127
|
+
({ workspace } = await (0, workspace_1.validateWorkspace)({
|
|
128
|
+
workspacePath,
|
|
129
|
+
inputType: 'zip',
|
|
130
|
+
sourceLocale,
|
|
131
|
+
targetLocales,
|
|
132
|
+
confidenceThreshold: 80,
|
|
133
|
+
dryRun: true,
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return empty('unknown', err.message);
|
|
138
|
+
}
|
|
139
|
+
const framework = workspace.framework;
|
|
140
|
+
const support = frameworkSupport(framework);
|
|
141
|
+
if (support === 'unsupported') {
|
|
142
|
+
return empty(framework, `Detected ${framework}, which local translation does not support. Supported: React and Next.js (Vue and static HTML in beta).`);
|
|
143
|
+
}
|
|
144
|
+
const phases = (types_1.FRAMEWORK_CONFIGS[framework] ?? types_1.FRAMEWORK_CONFIGS.unknown).phases;
|
|
145
|
+
// Same ICU decision as a local translate run (whose translator is an LLM).
|
|
146
|
+
const icuOptions = await (0, extraction_options_1.resolveIcuOptions)(workspace, true);
|
|
147
|
+
const { extraction } = await (0, extract_1.extractStrings)(workspace, undefined, icuOptions);
|
|
148
|
+
const existing = workspace.localeFormat === 'json' ? ((await (0, locale_builder_1.readLocaleFile)(workspace, sourceLocale)) ?? {}) : {};
|
|
149
|
+
const { keyGeneration } = (0, keygen_1.generateKeys)(extraction.strings, existing);
|
|
150
|
+
let injection = { modifiedFiles: [], skippedFiles: [], totalInjections: 0 };
|
|
151
|
+
if (phases.includes('inject')) {
|
|
152
|
+
const positions = new Map();
|
|
153
|
+
for (const str of extraction.strings)
|
|
154
|
+
if (str.offsets)
|
|
155
|
+
positions.set(str.id, new Set(str.offsets));
|
|
156
|
+
injection = await (0, injection_1.injectTranslations)(workspace, (0, keygen_1.createKeyMapping)(keyGeneration.keys), 80, true, positions);
|
|
157
|
+
}
|
|
158
|
+
const lineByKey = new Map(keyGeneration.keys.map((k) => [`${k.extractionId.split(':')[0]}\u0000${k.key}`, lineOf(k.extractionId)]));
|
|
159
|
+
const notInjectable = phases.includes('inject')
|
|
160
|
+
? [...(0, not_injected_1.findNotInjected)(keyGeneration, injection), ...(extraction.notInjected ?? [])].map((n) => ({
|
|
161
|
+
file: n.file,
|
|
162
|
+
line: lineByKey.get(`${n.file}\u0000${n.key}`),
|
|
163
|
+
text: n.text,
|
|
164
|
+
reason: n.reason,
|
|
165
|
+
}))
|
|
166
|
+
: [];
|
|
167
|
+
// What translate's finalize phase would still change to wire i18n up.
|
|
168
|
+
const runtime = (0, finalize_1.i18nRuntimeFor)(framework, workspace.packageJson);
|
|
169
|
+
const pendingChanges = [];
|
|
170
|
+
const notes = [];
|
|
171
|
+
if (framework === 'static') {
|
|
172
|
+
// finalize always rewrites its own i18n.js, so it can't tell "set up"
|
|
173
|
+
// from "not set up": look at the real state instead.
|
|
174
|
+
const wiring = await staticWiring(workspacePath);
|
|
175
|
+
if (wiring.runtime === 'missing')
|
|
176
|
+
pendingChanges.push('create the i18n.js runtime');
|
|
177
|
+
if (wiring.runtime === 'user')
|
|
178
|
+
notes.push('i18n.js exists but was not generated by Babelize; translate leaves it untouched.');
|
|
179
|
+
if (wiring.pagesWithoutScript.length) {
|
|
180
|
+
pendingChanges.push(`add <script src="i18n.js"> to ${wiring.pagesWithoutScript.length} HTML page(s)`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else if (phases.includes('finalize')) {
|
|
184
|
+
try {
|
|
185
|
+
const { finalization } = await (0, finalization_1.finalizeProject)(workspace, true, { targetLocales, sourceLocale, installDependencies: false });
|
|
186
|
+
if (finalization.configFileCreated)
|
|
187
|
+
pendingChanges.push(`create or update the ${runtime.library} config`);
|
|
188
|
+
if (finalization.entryPointModified)
|
|
189
|
+
pendingChanges.push('wire the i18n provider into the app entry point / root layout');
|
|
190
|
+
notes.push(...(finalization.warnings ?? []).filter((w) => !/missing dependencies/i.test(w) && !/^Created i18n\.js/.test(w)));
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
notes.push(`Could not check the i18n wiring: ${err.message}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (!icuOptions.sentences) {
|
|
197
|
+
notes.push('react-i18next without i18next-icu: sentences with variables or inline tags stay split into fragments. Add i18next-icu to translate them as whole messages.');
|
|
198
|
+
}
|
|
199
|
+
if (runtime.missing.length)
|
|
200
|
+
pendingChanges.unshift(`add ${runtime.missing.join(', ')} to package.json`);
|
|
201
|
+
const asString = (s) => ({ file: s.file, line: s.line, text: s.text, context: s.context });
|
|
202
|
+
const strings = extraction.strings.map(asString);
|
|
203
|
+
const groupedSentences = extraction.strings.filter((s) => s.icuMessage).map(asString);
|
|
204
|
+
const fragments = new Map();
|
|
205
|
+
for (const s of extraction.strings) {
|
|
206
|
+
if (!s.siblingGroupId || s.icuMessage)
|
|
207
|
+
continue;
|
|
208
|
+
const id = `${s.file}\u0000${s.siblingGroupId}`;
|
|
209
|
+
fragments.set(id, [...(fragments.get(id) ?? []), s]);
|
|
210
|
+
}
|
|
211
|
+
const fragmentedSentences = [...fragments.values()]
|
|
212
|
+
.filter((group) => group.length >= 2)
|
|
213
|
+
.map((group) => ({
|
|
214
|
+
file: group[0].file,
|
|
215
|
+
line: Math.min(...group.map((g) => g.line)),
|
|
216
|
+
sentence: (group[0].parentContext ?? group.map((g) => g.text).join(' … ')).replace(/\{#\d+\}/g, '<…>'),
|
|
217
|
+
pieces: group.length,
|
|
218
|
+
}));
|
|
219
|
+
const sourceKeys = {};
|
|
220
|
+
for (const [k, v] of Object.entries((0, keygen_1.flattenLocaleData)(existing))) {
|
|
221
|
+
if (k !== '_meta' && !k.startsWith('_meta.'))
|
|
222
|
+
sourceKeys[k] = v;
|
|
223
|
+
}
|
|
224
|
+
const usage = await (0, key_usage_1.reportKeyUsage)(workspace, sourceKeys, new Set(keyGeneration.keys.map((k) => k.key)));
|
|
225
|
+
const check = await (0, check_project_1.checkProjectLocales)(workspacePath, { sourceLocale, locales: targetLocales.length ? targetLocales : undefined });
|
|
226
|
+
const locales = check.sets.map((set) => ({
|
|
227
|
+
dir: set.dir,
|
|
228
|
+
sourceKeys: set.sourceKeys,
|
|
229
|
+
locales: set.locales.map((l) => ({
|
|
230
|
+
locale: l.locale,
|
|
231
|
+
total: l.total,
|
|
232
|
+
translated: l.translated,
|
|
233
|
+
missing: l.counts.missing_key ?? 0,
|
|
234
|
+
errors: l.errors,
|
|
235
|
+
warnings: l.warnings,
|
|
236
|
+
})),
|
|
237
|
+
missingLocales: set.missingLocales,
|
|
238
|
+
}));
|
|
239
|
+
const skipped = [...extraction.skippedFiles, ...injection.skippedFiles].map((f) => ({
|
|
240
|
+
file: toPosix(f.file),
|
|
241
|
+
reason: f.details ? `${f.reason}: ${f.details.split('\n')[0]}` : f.reason,
|
|
242
|
+
}));
|
|
243
|
+
const warnings = (extraction.warnings ?? [])
|
|
244
|
+
.filter((w) => ADVISORY_WARNINGS.has(w.type))
|
|
245
|
+
.map((w) => ({ type: w.type, file: w.file, line: w.line, message: w.message }));
|
|
246
|
+
const analysis = {
|
|
247
|
+
framework,
|
|
248
|
+
support,
|
|
249
|
+
sourceLocale,
|
|
250
|
+
setup: {
|
|
251
|
+
library: runtime.library,
|
|
252
|
+
missingDependencies: runtime.missing,
|
|
253
|
+
wiredUp: pendingChanges.length === 0,
|
|
254
|
+
pendingChanges,
|
|
255
|
+
notes,
|
|
256
|
+
},
|
|
257
|
+
files: {
|
|
258
|
+
scanned: extraction.filesAnalyzed.length,
|
|
259
|
+
withStrings: new Set(extraction.strings.map((s) => s.file)).size,
|
|
260
|
+
skipped,
|
|
261
|
+
},
|
|
262
|
+
strings,
|
|
263
|
+
groupedSentences,
|
|
264
|
+
fragmentedSentences,
|
|
265
|
+
notInjectable,
|
|
266
|
+
warnings,
|
|
267
|
+
locales,
|
|
268
|
+
unusedKeys: usage.unused,
|
|
269
|
+
dynamicKeyFiles: usage.dynamicFiles,
|
|
270
|
+
nextSteps: [],
|
|
271
|
+
durationMs: 0,
|
|
272
|
+
};
|
|
273
|
+
analysis.nextSteps = recommendNextSteps(analysis, targetLocales);
|
|
274
|
+
analysis.durationMs = Date.now() - startedAt;
|
|
275
|
+
return analysis;
|
|
276
|
+
}
|
|
277
|
+
/** Static sites: is the Babelize i18n.js runtime there, and does every page load it? */
|
|
278
|
+
async function staticWiring(root) {
|
|
279
|
+
const runtimeSrc = await fs_1.promises.readFile(path.join(root, 'i18n.js'), 'utf8').catch(() => '');
|
|
280
|
+
const runtime = (0, static_runtime_1.checkRuntimeNeedsRegeneration)(runtimeSrc);
|
|
281
|
+
const pages = await (0, fast_glob_1.default)(['**/*.html', '**/*.htm'], {
|
|
282
|
+
cwd: root,
|
|
283
|
+
ignore: ['**/node_modules/**', '**/.git/**', '**/dist/**', '**/build/**', '**/.babelize/**'],
|
|
284
|
+
onlyFiles: true,
|
|
285
|
+
deep: 8,
|
|
286
|
+
});
|
|
287
|
+
const pagesWithoutScript = [];
|
|
288
|
+
for (const page of pages.sort()) {
|
|
289
|
+
const html = await fs_1.promises.readFile(path.join(root, page), 'utf8').catch(() => '');
|
|
290
|
+
if (!/<script[^>]+src=["'][^"']*i18n\.js["']/i.test(html))
|
|
291
|
+
pagesWithoutScript.push(page);
|
|
292
|
+
}
|
|
293
|
+
return { runtime, pagesWithoutScript };
|
|
294
|
+
}
|
|
295
|
+
function recommendNextSteps(a, targetLocales) {
|
|
296
|
+
const steps = [];
|
|
297
|
+
const to = targetLocales.length ? targetLocales.join(', ') : 'your target locales (e.g. de, ja)';
|
|
298
|
+
const localeGaps = a.locales.flatMap((s) => s.locales).filter((l) => l.missing > 0);
|
|
299
|
+
const requestedMissing = a.locales.flatMap((s) => s.missingLocales);
|
|
300
|
+
if (a.support === 'beta')
|
|
301
|
+
steps.push(`${a.framework} support is in beta: review the changes carefully.`);
|
|
302
|
+
if (a.strings.length > 0) {
|
|
303
|
+
steps.push(`Translate: extract ${a.strings.length} hardcoded string(s), wire them to ${a.setup.library} and translate into ${to}.`);
|
|
304
|
+
}
|
|
305
|
+
else if (localeGaps.length > 0 || requestedMissing.length > 0) {
|
|
306
|
+
steps.push(`Translate: fill ${localeGaps.reduce((n, l) => n + l.missing, 0)} missing translation(s)${requestedMissing.length ? ` and add ${[...new Set(requestedMissing)].join(', ')}` : ''}.`);
|
|
307
|
+
}
|
|
308
|
+
else if (a.locales.length === 0) {
|
|
309
|
+
steps.push('No hardcoded strings or locale files found: nothing to localize yet.');
|
|
310
|
+
}
|
|
311
|
+
if (a.notInjectable.length > 0) {
|
|
312
|
+
steps.push(`${a.notInjectable.length} string(s) can't be wired automatically: move them into a component or call t() by hand after translating.`);
|
|
313
|
+
}
|
|
314
|
+
if (a.setup.missingDependencies.length > 0) {
|
|
315
|
+
steps.push(`After translating, install ${a.setup.missingDependencies.join(', ')} with your package manager.`);
|
|
316
|
+
}
|
|
317
|
+
if (a.locales.some((s) => s.locales.some((l) => l.errors > 0))) {
|
|
318
|
+
steps.push('Existing locale files have errors (placeholders, ICU, plural forms): run the check.');
|
|
319
|
+
}
|
|
320
|
+
if (steps.length === 0)
|
|
321
|
+
steps.push('Looks localized. Re-run the check after editing strings or locale files.');
|
|
322
|
+
return steps;
|
|
323
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment the engine reads directly. Read lazily so a host that loads
|
|
3
|
+
* dotenv after importing the engine still sees its values, and so importing
|
|
4
|
+
* the engine never requires any variable to be set.
|
|
5
|
+
*/
|
|
6
|
+
export declare const config: {
|
|
7
|
+
readonly GEMINI_API_KEY: string | undefined;
|
|
8
|
+
readonly GROQ_API_KEY: string | undefined;
|
|
9
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Environment the engine reads directly. Read lazily so a host that loads
|
|
6
|
+
* dotenv after importing the engine still sees its values, and so importing
|
|
7
|
+
* the engine never requires any variable to be set.
|
|
8
|
+
*/
|
|
9
|
+
exports.config = {
|
|
10
|
+
get GEMINI_API_KEY() {
|
|
11
|
+
return process.env.GEMINI_API_KEY;
|
|
12
|
+
},
|
|
13
|
+
get GROQ_API_KEY() {
|
|
14
|
+
return process.env.GROQ_API_KEY;
|
|
15
|
+
},
|
|
16
|
+
};
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { BabelizeConfig } from './types';
|
|
3
|
+
declare const configSchema: z.ZodObject<{
|
|
4
|
+
workspacePath: z.ZodString;
|
|
5
|
+
sourceLocale: z.ZodDefault<z.ZodString>;
|
|
6
|
+
targetLocales: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
framework: z.ZodOptional<z.ZodEnum<["react", "nextjs", "vue", "static", "unknown", "django"]>>;
|
|
8
|
+
dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
9
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
10
|
+
sourceDir: z.ZodOptional<z.ZodString>;
|
|
11
|
+
localesDir: z.ZodOptional<z.ZodString>;
|
|
12
|
+
glossary: z.ZodOptional<z.ZodObject<{
|
|
13
|
+
neverTranslate: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
14
|
+
alwaysTranslateAs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
15
|
+
term: z.ZodString;
|
|
16
|
+
translations: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
term: string;
|
|
19
|
+
translations: Record<string, string>;
|
|
20
|
+
}, {
|
|
21
|
+
term: string;
|
|
22
|
+
translations: Record<string, string>;
|
|
23
|
+
}>, "many">>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
neverTranslate: string[];
|
|
26
|
+
alwaysTranslateAs: {
|
|
27
|
+
term: string;
|
|
28
|
+
translations: Record<string, string>;
|
|
29
|
+
}[];
|
|
30
|
+
}, {
|
|
31
|
+
neverTranslate?: string[] | undefined;
|
|
32
|
+
alwaysTranslateAs?: {
|
|
33
|
+
term: string;
|
|
34
|
+
translations: Record<string, string>;
|
|
35
|
+
}[] | undefined;
|
|
36
|
+
}>>;
|
|
37
|
+
lockfilePath: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
workspacePath: string;
|
|
40
|
+
sourceLocale: string;
|
|
41
|
+
targetLocales: string[];
|
|
42
|
+
dryRun: boolean;
|
|
43
|
+
framework?: "react" | "nextjs" | "vue" | "static" | "unknown" | "django" | undefined;
|
|
44
|
+
projectId?: string | undefined;
|
|
45
|
+
sourceDir?: string | undefined;
|
|
46
|
+
localesDir?: string | undefined;
|
|
47
|
+
glossary?: {
|
|
48
|
+
neverTranslate: string[];
|
|
49
|
+
alwaysTranslateAs: {
|
|
50
|
+
term: string;
|
|
51
|
+
translations: Record<string, string>;
|
|
52
|
+
}[];
|
|
53
|
+
} | undefined;
|
|
54
|
+
lockfilePath?: string | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
workspacePath: string;
|
|
57
|
+
sourceLocale?: string | undefined;
|
|
58
|
+
targetLocales?: string[] | undefined;
|
|
59
|
+
framework?: "react" | "nextjs" | "vue" | "static" | "unknown" | "django" | undefined;
|
|
60
|
+
dryRun?: boolean | undefined;
|
|
61
|
+
projectId?: string | undefined;
|
|
62
|
+
sourceDir?: string | undefined;
|
|
63
|
+
localesDir?: string | undefined;
|
|
64
|
+
glossary?: {
|
|
65
|
+
neverTranslate?: string[] | undefined;
|
|
66
|
+
alwaysTranslateAs?: {
|
|
67
|
+
term: string;
|
|
68
|
+
translations: Record<string, string>;
|
|
69
|
+
}[] | undefined;
|
|
70
|
+
} | undefined;
|
|
71
|
+
lockfilePath?: string | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
export declare function loadBabelizeConfig(input: unknown): BabelizeConfig;
|
|
74
|
+
export { configSchema as babelizeConfigSchema };
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.babelizeConfigSchema = void 0;
|
|
4
|
+
exports.loadBabelizeConfig = loadBabelizeConfig;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const types_1 = require("@babelize/types");
|
|
7
|
+
const isoCode = zod_1.z
|
|
8
|
+
.string()
|
|
9
|
+
.trim()
|
|
10
|
+
.toLowerCase()
|
|
11
|
+
.regex(/^[a-z]{2}$/, 'Expected ISO 639-1 (e.g. "en")');
|
|
12
|
+
const configSchema = zod_1.z.object({
|
|
13
|
+
workspacePath: zod_1.z.string().min(1),
|
|
14
|
+
sourceLocale: isoCode.default('en'),
|
|
15
|
+
targetLocales: zod_1.z.array(isoCode).default([]),
|
|
16
|
+
framework: zod_1.z.enum(types_1.FRAMEWORKS).optional(),
|
|
17
|
+
dryRun: zod_1.z.boolean().optional().default(false),
|
|
18
|
+
projectId: zod_1.z.string().optional(),
|
|
19
|
+
sourceDir: zod_1.z.string().optional(),
|
|
20
|
+
localesDir: zod_1.z.string().optional(),
|
|
21
|
+
glossary: zod_1.z
|
|
22
|
+
.object({
|
|
23
|
+
neverTranslate: zod_1.z.array(zod_1.z.string().min(1)).default([]),
|
|
24
|
+
alwaysTranslateAs: zod_1.z.array(zod_1.z.object({
|
|
25
|
+
term: zod_1.z.string().min(1),
|
|
26
|
+
translations: zod_1.z.record(zod_1.z.string(), zod_1.z.string()),
|
|
27
|
+
})).default([]),
|
|
28
|
+
})
|
|
29
|
+
.optional(),
|
|
30
|
+
lockfilePath: zod_1.z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
exports.babelizeConfigSchema = configSchema;
|
|
33
|
+
function loadBabelizeConfig(input) {
|
|
34
|
+
const parsed = configSchema.parse(input);
|
|
35
|
+
if (parsed.targetLocales.includes(parsed.sourceLocale)) {
|
|
36
|
+
console.warn(`[babelize] sourceLocale "${parsed.sourceLocale}" was also listed in targetLocales. ` +
|
|
37
|
+
`It has been removed from the target list — the source locale is always generated ` +
|
|
38
|
+
`separately by handleBaseLocale.`);
|
|
39
|
+
}
|
|
40
|
+
// Normalize/defensive defaults beyond Zod
|
|
41
|
+
const targetLocales = Array.from(new Set(parsed.targetLocales)).filter((l) => l !== parsed.sourceLocale);
|
|
42
|
+
return {
|
|
43
|
+
...parsed,
|
|
44
|
+
targetLocales,
|
|
45
|
+
glossary: parsed.glossary ?? { neverTranslate: [], alwaysTranslateAs: [] },
|
|
46
|
+
};
|
|
47
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Babelize Engine v2 — public API.
|
|
3
|
+
*
|
|
4
|
+
* This folder is introduced alongside the existing v1 engine (phases/*) using a
|
|
5
|
+
* strangler-fig approach. Nothing outside v2 should import internal modules
|
|
6
|
+
* directly — only this file re-exports the public surface.
|
|
7
|
+
*/
|
|
8
|
+
export { BabelizeEngine } from './BabelizeEngine';
|
|
9
|
+
export type { BabelizeConfig, BabelizeEngineDependencies, BabelRunResult, ExtractedString, TranslationResult, TranslationUnit, } from './types';
|
|
10
|
+
export { loadBabelizeConfig } from './config';
|
|
11
|
+
export { runEngineV2, validateEngineConfigV2 } from './runtime';
|
|
12
|
+
export type { EngineConfigV2, EngineResultV2 } from './runtime';
|
|
13
|
+
export type { KeyUsageReport, ProcessingStats } from './runtime/types';
|
|
14
|
+
export { scanKeyReferences } from './utils/key-usage';
|
|
15
|
+
export { validateWorkspace } from './modules/workspace';
|
|
16
|
+
export * from './providers';
|
|
17
|
+
export { runWithEngineLogger, setEngineLogger } from './utils/logger';
|
|
18
|
+
export type { EngineLogger, LogContext } from './utils/logger';
|
|
19
|
+
export * from './modules/lockfile';
|
|
20
|
+
export * from './modules/translator/language-codes';
|
|
21
|
+
export type { MemoryEntry, FuzzyMatch, MemoryLookupResult } from './modules/translator/memory/types';
|
|
22
|
+
export { matchFromMemory } from './modules/translator/memory/memory-matcher';
|
|
23
|
+
export { detectSyncIssues, formatSyncNotificationMessage } from './modules/sync-detector';
|
|
24
|
+
export type { SyncDetectionResult, SyncDetectedString, SyncMissingLocaleKey } from './modules/sync-detector';
|
|
25
|
+
export type { TranslationEntry, WorkspaceInfo } from './runtime/types';
|
|
26
|
+
export { addBabelToHistory, detectProjectInfo, getBabelizeSummary, getProjectInfo, saveCachedStrings, saveProjectConfig, } from './utils/metadata';
|
|
27
|
+
export type { BabelHistoryEntry, ExtractedStringEntry, ProjectInfo } from './utils/metadata';
|
|
28
|
+
export { parseCode } from './utils/ast-helpers';
|
|
29
|
+
export { extractPlaceholders, hasICUSyntax, hashString, protectPlaceholders, restorePlaceholders, } from './utils/string-utils';
|
|
30
|
+
export { sanitizeTranslation, validateRawTokens } from './utils/translation-sanitizer';
|
|
31
|
+
export { checkTokens, hasNothingToTranslate, protectText, restoreText, sameProtectedSpans } from './utils/placeholder-protection';
|
|
32
|
+
export type { ProtectedText, TokenCheck } from './utils/placeholder-protection';
|
|
33
|
+
export { compareIcuMessages, isIcuMessage, parseIcu, requiredPluralCategories } from './utils/icu-message';
|
|
34
|
+
export type { IcuIssue, IcuNode } from './utils/icu-message';
|
|
35
|
+
export { callTranslator, checkTranslatorHealth, warmupTranslator } from './utils/translator-caller';
|
|
36
|
+
export { translatorLoadBalancer } from './utils/translator-load-balancer';
|
|
37
|
+
export type { TranslatorEndpoint } from './utils/translator-load-balancer';
|
|
38
|
+
export { validateTranslationQuality, validateBatchQuality } from './utils/translation-quality';
|
|
39
|
+
export type { QualityIssue, QualityResult } from './utils/translation-quality';
|
|
40
|
+
export { CircuitBreaker, CircuitState, getCircuitBreaker } from './utils/circuit-breaker';
|
|
41
|
+
export type { CircuitBreakerOptions } from './utils/circuit-breaker';
|
|
42
|
+
export { localeExtension } from './utils/file-utils';
|
|
43
|
+
export { analyzeProject, analyzeWorkspace, frameworkSupport, } from './analysis/analyze';
|
|
44
|
+
export type { AnalyzeOptions, AnalyzedString, FrameworkSupport, ProjectAnalysis } from './analysis/analyze';
|
|
45
|
+
export { checkLocalePair, flattenLocaleMessages, tallyLocaleIssues } from './qa/locale-qa';
|
|
46
|
+
export type { LocaleGlossary, LocaleIssue, LocaleIssueCode, LocaleIssueSeverity, LocalePairOptions, LocalePairReport, } from './qa/locale-qa';
|
|
47
|
+
export { DEFAULT_LOCALE_IGNORE_DIRS, findLocaleFileSets, groupLocaleFiles, isIgnoredLocalePath, isLocaleCode, loadLocale } from './qa/locale-files';
|
|
48
|
+
export type { FindLocaleOptions, LoadedLocale, LocaleFileSet, ProjectFileReader } from './qa/locale-files';
|
|
49
|
+
export { reviewLocaleChanges, ReviewError } from './qa/review';
|
|
50
|
+
export type { LocaleChangeReview, LocaleSetChangeReview, ReviewOptions } from './qa/review';
|
|
51
|
+
export { checkProjectLocales, localeIssueFile, readProjectLocaleConfig } from './qa/check-project';
|
|
52
|
+
export type { CheckProjectOptions, LocaleSetReport, ProjectLocaleCheck, ProjectLocaleConfig } from './qa/check-project';
|
|
53
|
+
export { hashText, translationCacheKey, TRANSLATION_CACHE_TTL_SECONDS } from './utils/cache-keys';
|
|
54
|
+
export * from './local';
|