@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.
Files changed (246) hide show
  1. package/LICENSE +202 -0
  2. package/dist/BabelizeEngine.d.ts +12 -0
  3. package/dist/BabelizeEngine.js +47 -0
  4. package/dist/analysis/analyze.d.ts +106 -0
  5. package/dist/analysis/analyze.js +323 -0
  6. package/dist/config/env.d.ts +9 -0
  7. package/dist/config/env.js +16 -0
  8. package/dist/config.d.ts +74 -0
  9. package/dist/config.js +47 -0
  10. package/dist/index.d.ts +54 -0
  11. package/dist/index.js +126 -0
  12. package/dist/injection/InjectionStrategy.d.ts +62 -0
  13. package/dist/injection/InjectionStrategy.js +2 -0
  14. package/dist/injection/StrategyFactory.d.ts +4 -0
  15. package/dist/injection/StrategyFactory.js +29 -0
  16. package/dist/injection/django/django-template-injector.d.ts +29 -0
  17. package/dist/injection/django/django-template-injector.js +216 -0
  18. package/dist/injection/html/html-injector.d.ts +11 -0
  19. package/dist/injection/html/html-injector.js +173 -0
  20. package/dist/injection/strategies/NextIntlStrategy.d.ts +25 -0
  21. package/dist/injection/strategies/NextIntlStrategy.js +141 -0
  22. package/dist/injection/strategies/ReactI18nextStrategy.d.ts +19 -0
  23. package/dist/injection/strategies/ReactI18nextStrategy.js +116 -0
  24. package/dist/injection/strategies/VanillaStrategy.d.ts +11 -0
  25. package/dist/injection/strategies/VanillaStrategy.js +73 -0
  26. package/dist/injection/strategies/VueI18nStrategy.d.ts +11 -0
  27. package/dist/injection/strategies/VueI18nStrategy.js +84 -0
  28. package/dist/local/formatter.d.ts +26 -0
  29. package/dist/local/formatter.js +105 -0
  30. package/dist/local/git.d.ts +23 -0
  31. package/dist/local/git.js +136 -0
  32. package/dist/local/hosted-provider.d.ts +68 -0
  33. package/dist/local/hosted-provider.js +215 -0
  34. package/dist/local/index.d.ts +23 -0
  35. package/dist/local/index.js +75 -0
  36. package/dist/local/provider.d.ts +56 -0
  37. package/dist/local/provider.js +119 -0
  38. package/dist/local/pseudo-provider.d.ts +18 -0
  39. package/dist/local/pseudo-provider.js +207 -0
  40. package/dist/local/report.d.ts +177 -0
  41. package/dist/local/report.js +186 -0
  42. package/dist/local/translate-core.d.ts +215 -0
  43. package/dist/local/translate-core.js +461 -0
  44. package/dist/local/translate-messages.d.ts +49 -0
  45. package/dist/local/translate-messages.js +91 -0
  46. package/dist/local/workspace-copy.d.ts +91 -0
  47. package/dist/local/workspace-copy.js +355 -0
  48. package/dist/modules/extractor/extract.d.ts +20 -0
  49. package/dist/modules/extractor/extract.js +701 -0
  50. package/dist/modules/extractor/index.d.ts +2 -0
  51. package/dist/modules/extractor/index.js +63 -0
  52. package/dist/modules/finalization/django-finalize.d.ts +13 -0
  53. package/dist/modules/finalization/django-finalize.js +275 -0
  54. package/dist/modules/finalization/finalize.d.ts +36 -0
  55. package/dist/modules/finalization/finalize.js +717 -0
  56. package/dist/modules/finalization/index.d.ts +1 -0
  57. package/dist/modules/finalization/index.js +5 -0
  58. package/dist/modules/finalization/nextjs-finalize.d.ts +37 -0
  59. package/dist/modules/finalization/nextjs-finalize.js +329 -0
  60. package/dist/modules/finalization/static-runtime.d.ts +9 -0
  61. package/dist/modules/finalization/static-runtime.js +261 -0
  62. package/dist/modules/format-injection/index.d.ts +19 -0
  63. package/dist/modules/format-injection/index.js +272 -0
  64. package/dist/modules/format-injection/inject-formats.d.ts +31 -0
  65. package/dist/modules/format-injection/inject-formats.js +208 -0
  66. package/dist/modules/glossary/glossary.d.ts +9 -0
  67. package/dist/modules/glossary/glossary.js +27 -0
  68. package/dist/modules/glossary/index.d.ts +3 -0
  69. package/dist/modules/glossary/index.js +8 -0
  70. package/dist/modules/glossary/masker.d.ts +23 -0
  71. package/dist/modules/glossary/masker.js +56 -0
  72. package/dist/modules/glossary/types.d.ts +22 -0
  73. package/dist/modules/glossary/types.js +2 -0
  74. package/dist/modules/injection/index.d.ts +1 -0
  75. package/dist/modules/injection/index.js +6 -0
  76. package/dist/modules/injection/inject.d.ts +29 -0
  77. package/dist/modules/injection/inject.js +1066 -0
  78. package/dist/modules/keygen/index.d.ts +1 -0
  79. package/dist/modules/keygen/index.js +11 -0
  80. package/dist/modules/keygen/keygen.d.ts +4 -0
  81. package/dist/modules/keygen/keygen.js +116 -0
  82. package/dist/modules/keygen/locale-data.d.ts +7 -0
  83. package/dist/modules/keygen/locale-data.js +73 -0
  84. package/dist/modules/keygen/public.d.ts +2 -0
  85. package/dist/modules/keygen/public.js +12 -0
  86. package/dist/modules/locale-builder/index.d.ts +1 -0
  87. package/dist/modules/locale-builder/index.js +7 -0
  88. package/dist/modules/locale-builder/locales.d.ts +13 -0
  89. package/dist/modules/locale-builder/locales.js +107 -0
  90. package/dist/modules/locale-builder/po.d.ts +33 -0
  91. package/dist/modules/locale-builder/po.js +131 -0
  92. package/dist/modules/lockfile/hasher.d.ts +7 -0
  93. package/dist/modules/lockfile/hasher.js +13 -0
  94. package/dist/modules/lockfile/index.d.ts +3 -0
  95. package/dist/modules/lockfile/index.js +21 -0
  96. package/dist/modules/lockfile/lockfile-manager.d.ts +90 -0
  97. package/dist/modules/lockfile/lockfile-manager.js +482 -0
  98. package/dist/modules/lockfile/schema.d.ts +154 -0
  99. package/dist/modules/lockfile/schema.js +45 -0
  100. package/dist/modules/parser/index.d.ts +2 -0
  101. package/dist/modules/parser/index.js +9 -0
  102. package/dist/modules/summary/index.d.ts +1 -0
  103. package/dist/modules/summary/index.js +7 -0
  104. package/dist/modules/summary/summary.d.ts +9 -0
  105. package/dist/modules/summary/summary.js +195 -0
  106. package/dist/modules/sync-detector/index.d.ts +2 -0
  107. package/dist/modules/sync-detector/index.js +7 -0
  108. package/dist/modules/sync-detector/reporter.d.ts +3 -0
  109. package/dist/modules/sync-detector/reporter.js +16 -0
  110. package/dist/modules/sync-detector/sync-detector.d.ts +39 -0
  111. package/dist/modules/sync-detector/sync-detector.js +374 -0
  112. package/dist/modules/translator/batch-optimizer.d.ts +12 -0
  113. package/dist/modules/translator/batch-optimizer.js +30 -0
  114. package/dist/modules/translator/client/byok.provider.d.ts +64 -0
  115. package/dist/modules/translator/client/byok.provider.js +319 -0
  116. package/dist/modules/translator/client/direct-translator.client.d.ts +12 -0
  117. package/dist/modules/translator/client/direct-translator.client.js +71 -0
  118. package/dist/modules/translator/client/gemini.provider.d.ts +1 -0
  119. package/dist/modules/translator/client/gemini.provider.js +110 -0
  120. package/dist/modules/translator/client/groq.provider.d.ts +1 -0
  121. package/dist/modules/translator/client/groq.provider.js +111 -0
  122. package/dist/modules/translator/client/request.types.d.ts +1 -0
  123. package/dist/modules/translator/client/request.types.js +2 -0
  124. package/dist/modules/translator/client/retry.d.ts +29 -0
  125. package/dist/modules/translator/client/retry.js +94 -0
  126. package/dist/modules/translator/client/test-utils/mock.client.d.ts +31 -0
  127. package/dist/modules/translator/client/test-utils/mock.client.js +59 -0
  128. package/dist/modules/translator/client/translator.interface.d.ts +1 -0
  129. package/dist/modules/translator/client/translator.interface.js +2 -0
  130. package/dist/modules/translator/language-codes/errors.d.ts +10 -0
  131. package/dist/modules/translator/language-codes/errors.js +18 -0
  132. package/dist/modules/translator/language-codes/flores-map.d.ts +1 -0
  133. package/dist/modules/translator/language-codes/flores-map.js +107 -0
  134. package/dist/modules/translator/language-codes/index.d.ts +11 -0
  135. package/dist/modules/translator/language-codes/index.js +24 -0
  136. package/dist/modules/translator/language-codes/language-mapper.d.ts +25 -0
  137. package/dist/modules/translator/language-codes/language-mapper.js +132 -0
  138. package/dist/modules/translator/language-codes/rtl-languages.d.ts +2 -0
  139. package/dist/modules/translator/language-codes/rtl-languages.js +9 -0
  140. package/dist/modules/translator/memory/memory-matcher.d.ts +8 -0
  141. package/dist/modules/translator/memory/memory-matcher.js +218 -0
  142. package/dist/modules/translator/memory/types.d.ts +22 -0
  143. package/dist/modules/translator/memory/types.js +2 -0
  144. package/dist/modules/translator/translate.d.ts +38 -0
  145. package/dist/modules/translator/translate.js +932 -0
  146. package/dist/modules/translator/translator.d.ts +5 -0
  147. package/dist/modules/translator/translator.js +46 -0
  148. package/dist/modules/vue/migrate.d.ts +13 -0
  149. package/dist/modules/vue/migrate.js +40 -0
  150. package/dist/modules/vue/script-inject.d.ts +16 -0
  151. package/dist/modules/vue/script-inject.js +115 -0
  152. package/dist/modules/vue/sfc.d.ts +11 -0
  153. package/dist/modules/vue/sfc.js +51 -0
  154. package/dist/modules/vue/template-rewrite.d.ts +25 -0
  155. package/dist/modules/vue/template-rewrite.js +76 -0
  156. package/dist/modules/vue/template-scan.d.ts +29 -0
  157. package/dist/modules/vue/template-scan.js +264 -0
  158. package/dist/modules/workspace/index.d.ts +1 -0
  159. package/dist/modules/workspace/index.js +5 -0
  160. package/dist/modules/workspace/validate.d.ts +13 -0
  161. package/dist/modules/workspace/validate.js +298 -0
  162. package/dist/orchestrator.d.ts +8 -0
  163. package/dist/orchestrator.js +616 -0
  164. package/dist/providers/default-translation-provider.d.ts +20 -0
  165. package/dist/providers/default-translation-provider.js +30 -0
  166. package/dist/providers/index.d.ts +2 -0
  167. package/dist/providers/index.js +21 -0
  168. package/dist/providers/types.d.ts +145 -0
  169. package/dist/providers/types.js +2 -0
  170. package/dist/qa/check-project.d.ts +49 -0
  171. package/dist/qa/check-project.js +150 -0
  172. package/dist/qa/locale-files.d.ts +44 -0
  173. package/dist/qa/locale-files.js +159 -0
  174. package/dist/qa/locale-qa.d.ts +61 -0
  175. package/dist/qa/locale-qa.js +325 -0
  176. package/dist/qa/review.d.ts +43 -0
  177. package/dist/qa/review.js +175 -0
  178. package/dist/runtime/config.d.ts +8 -0
  179. package/dist/runtime/config.js +36 -0
  180. package/dist/runtime/index.d.ts +3 -0
  181. package/dist/runtime/index.js +8 -0
  182. package/dist/runtime/types.d.ts +363 -0
  183. package/dist/runtime/types.js +38 -0
  184. package/dist/types.d.ts +134 -0
  185. package/dist/types.js +12 -0
  186. package/dist/utils/ast-helpers.d.ts +57 -0
  187. package/dist/utils/ast-helpers.js +608 -0
  188. package/dist/utils/cache-keys.d.ts +8 -0
  189. package/dist/utils/cache-keys.js +18 -0
  190. package/dist/utils/circuit-breaker.d.ts +43 -0
  191. package/dist/utils/circuit-breaker.js +119 -0
  192. package/dist/utils/concurrent-map.d.ts +4 -0
  193. package/dist/utils/concurrent-map.js +21 -0
  194. package/dist/utils/detect-format.d.ts +5 -0
  195. package/dist/utils/detect-format.js +125 -0
  196. package/dist/utils/dtl-mask.d.ts +25 -0
  197. package/dist/utils/dtl-mask.js +58 -0
  198. package/dist/utils/extraction-options.d.ts +23 -0
  199. package/dist/utils/extraction-options.js +23 -0
  200. package/dist/utils/file-utils.d.ts +33 -0
  201. package/dist/utils/file-utils.js +262 -0
  202. package/dist/utils/glossary-match.d.ts +9 -0
  203. package/dist/utils/glossary-match.js +25 -0
  204. package/dist/utils/html-extractor.d.ts +8 -0
  205. package/dist/utils/html-extractor.js +317 -0
  206. package/dist/utils/i18next-icu.d.ts +38 -0
  207. package/dist/utils/i18next-icu.js +159 -0
  208. package/dist/utils/icu-message.d.ts +65 -0
  209. package/dist/utils/icu-message.js +346 -0
  210. package/dist/utils/icu-spans.d.ts +10 -0
  211. package/dist/utils/icu-spans.js +126 -0
  212. package/dist/utils/jsx-message.d.ts +93 -0
  213. package/dist/utils/jsx-message.js +621 -0
  214. package/dist/utils/key-usage.d.ts +35 -0
  215. package/dist/utils/key-usage.js +247 -0
  216. package/dist/utils/logger.d.ts +24 -0
  217. package/dist/utils/logger.js +33 -0
  218. package/dist/utils/metadata.d.ts +80 -0
  219. package/dist/utils/metadata.js +255 -0
  220. package/dist/utils/module-constants.d.ts +30 -0
  221. package/dist/utils/module-constants.js +265 -0
  222. package/dist/utils/not-injected.d.ts +6 -0
  223. package/dist/utils/not-injected.js +36 -0
  224. package/dist/utils/placeholder-protection.d.ts +57 -0
  225. package/dist/utils/placeholder-protection.js +136 -0
  226. package/dist/utils/pseudo-markers.d.ts +9 -0
  227. package/dist/utils/pseudo-markers.js +16 -0
  228. package/dist/utils/py-extractor.d.ts +14 -0
  229. package/dist/utils/py-extractor.js +285 -0
  230. package/dist/utils/string-utils.d.ts +52 -0
  231. package/dist/utils/string-utils.js +270 -0
  232. package/dist/utils/translation-quality.d.ts +34 -0
  233. package/dist/utils/translation-quality.js +156 -0
  234. package/dist/utils/translation-sanitizer.d.ts +10 -0
  235. package/dist/utils/translation-sanitizer.js +57 -0
  236. package/dist/utils/translator-caller.d.ts +32 -0
  237. package/dist/utils/translator-caller.js +217 -0
  238. package/dist/utils/translator-load-balancer.d.ts +73 -0
  239. package/dist/utils/translator-load-balancer.js +293 -0
  240. package/dist/utils/ui-copy.d.ts +32 -0
  241. package/dist/utils/ui-copy.js +126 -0
  242. package/dist/utils/workspace.d.ts +14 -0
  243. package/dist/utils/workspace.js +89 -0
  244. package/package.json +64 -4
  245. package/schemas/translate-report.schema.json +297 -0
  246. package/README.md +0 -3
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.matchFromMemory = matchFromMemory;
4
+ const FUZZY_THRESHOLD = 0.9;
5
+ const MAX_FUZZY_MATCHES = 3;
6
+ const Q = 3;
7
+ /**
8
+ * Fuzzy results are suggestions only (never auto-applied) and only the top
9
+ * MAX_FUZZY_MATCHES are kept, so Levenshtein is run on at most this many
10
+ * candidates — those sharing the most q-grams with the query. Without a cap,
11
+ * a memory full of near-identical templated strings makes every entry a
12
+ * candidate.
13
+ */
14
+ const MAX_FUZZY_CANDIDATES = 50;
15
+ /** Largest edit distance that still scores ≥ FUZZY_THRESHOLD (float-safe). */
16
+ function maxDistanceFor(maxLength) {
17
+ return Math.floor(maxLength - FUZZY_THRESHOLD * maxLength + 1e-9);
18
+ }
19
+ /** Multiset of the string's q-grams: gram → occurrences. */
20
+ function qgrams(text) {
21
+ const grams = new Map();
22
+ for (let i = 0; i + Q <= text.length; i++) {
23
+ const g = text.slice(i, i + Q);
24
+ grams.set(g, (grams.get(g) ?? 0) + 1);
25
+ }
26
+ return grams;
27
+ }
28
+ /**
29
+ * Levenshtein distance, or `maxDistance + 1` as soon as it is known to exceed
30
+ * `maxDistance`. Only cells within `maxDistance` of the diagonal can lead to
31
+ * an answer under the bound, so each row computes that band only, and the
32
+ * loop exits once a whole band row is over the bound.
33
+ */
34
+ function boundedLevenshtein(s1, s2, maxDistance) {
35
+ const m = s1.length;
36
+ const n = s2.length;
37
+ const over = maxDistance + 1;
38
+ if (Math.abs(m - n) > maxDistance)
39
+ return over;
40
+ let prev = new Array(n + 1).fill(over);
41
+ let curr = new Array(n + 1).fill(over);
42
+ for (let j = 0; j <= Math.min(n, maxDistance); j++)
43
+ prev[j] = j;
44
+ for (let i = 1; i <= m; i++) {
45
+ const from = Math.max(1, i - maxDistance);
46
+ const to = Math.min(n, i + maxDistance);
47
+ curr.fill(over);
48
+ curr[0] = i <= maxDistance ? i : over;
49
+ let rowMin = curr[0];
50
+ for (let j = from; j <= to; j++) {
51
+ const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
52
+ curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost, over);
53
+ if (curr[j] < rowMin)
54
+ rowMin = curr[j];
55
+ }
56
+ if (rowMin > maxDistance)
57
+ return over;
58
+ [prev, curr] = [curr, prev];
59
+ }
60
+ return Math.min(prev[n], over);
61
+ }
62
+ /**
63
+ * Indexes are built once per (memory array, target locale) and reused for
64
+ * every key in the run. The caller fetches one array per locale and matches
65
+ * every uncached key against it, so rebuilding (or re-hashing every entry)
66
+ * per key was O(keys × entries).
67
+ */
68
+ const indexCache = new WeakMap();
69
+ function getIndex(entries, targetLocale) {
70
+ let byLocale = indexCache.get(entries);
71
+ if (!byLocale) {
72
+ byLocale = new Map();
73
+ indexCache.set(entries, byLocale);
74
+ }
75
+ let index = byLocale.get(targetLocale);
76
+ if (!index) {
77
+ const forLocale = entries.filter((e) => e.targetLocale === targetLocale);
78
+ const exact = new Map();
79
+ for (const e of forLocale) {
80
+ // Prefer a human-approved entry if the same text appears twice.
81
+ const existing = exact.get(e.sourceText);
82
+ if (!existing || (!existing.approvedAt && e.approvedAt))
83
+ exact.set(e.sourceText, e);
84
+ }
85
+ const lists = new Map();
86
+ forLocale.forEach((e, idx) => {
87
+ for (const [g, n] of qgrams(e.sourceText)) {
88
+ let list = lists.get(g);
89
+ if (!list)
90
+ lists.set(g, (list = []));
91
+ list.push(idx, n);
92
+ }
93
+ });
94
+ const postings = new Map();
95
+ for (const [g, list] of lists) {
96
+ const idx = new Int32Array(list.length / 2);
97
+ const count = new Uint16Array(list.length / 2);
98
+ for (let p = 0; p < idx.length; p++) {
99
+ idx[p] = list[2 * p];
100
+ count[p] = Math.min(list[2 * p + 1], 0xffff);
101
+ }
102
+ postings.set(g, { idx, count });
103
+ }
104
+ index = { exact, entries: forLocale, postings, shared: new Int32Array(forLocale.length) };
105
+ byLocale.set(targetLocale, index);
106
+ }
107
+ return index;
108
+ }
109
+ /**
110
+ * Match from memory with exact and fuzzy matching.
111
+ * Exact matches are a map lookup; fuzzy matches (≥90% similar) are only
112
+ * computed when there is no exact match, and only against candidates whose
113
+ * length could possibly reach the threshold.
114
+ */
115
+ function matchFromMemory(entries, sourceText, targetLocale) {
116
+ if (!entries.length)
117
+ return { hit: false };
118
+ const index = getIndex(entries, targetLocale);
119
+ const exactMatch = index.exact.get(sourceText);
120
+ if (exactMatch) {
121
+ return {
122
+ hit: true,
123
+ translatedText: exactMatch.translatedText,
124
+ confidence: 1,
125
+ fromMemory: true
126
+ };
127
+ }
128
+ const fuzzyMatches = [];
129
+ const consider = (i) => {
130
+ const e = index.entries[i];
131
+ const maxLength = Math.max(sourceText.length, e.sourceText.length);
132
+ if (maxLength === 0)
133
+ return;
134
+ const maxDistance = maxDistanceFor(maxLength);
135
+ if (Math.abs(sourceText.length - e.sourceText.length) > maxDistance)
136
+ return;
137
+ const distance = boundedLevenshtein(sourceText, e.sourceText, maxDistance);
138
+ if (distance > maxDistance)
139
+ return;
140
+ fuzzyMatches.push({
141
+ translatedText: e.translatedText,
142
+ sourceText: e.sourceText,
143
+ similarity: (maxLength - distance) / maxLength,
144
+ });
145
+ };
146
+ if (sourceText.length <= Q + 1) {
147
+ // Too short for the q-gram filter to prune safely; short strings are cheap.
148
+ for (let i = 0; i < index.entries.length; i++)
149
+ consider(i);
150
+ }
151
+ else {
152
+ // q-gram lemma: strings within edit distance d share at least
153
+ // max(len) - Q + 1 - Q·d q-grams. Count shared grams via the inverted
154
+ // index and only run Levenshtein on entries that clear that bar.
155
+ const { shared } = index;
156
+ const touched = [];
157
+ for (const [g, qn] of qgrams(sourceText)) {
158
+ const posting = index.postings.get(g);
159
+ if (!posting)
160
+ continue;
161
+ const { idx: ids, count: counts } = posting;
162
+ for (let p = 0; p < ids.length; p++) {
163
+ const idx = ids[p];
164
+ if (shared[idx] === 0)
165
+ touched.push(idx);
166
+ shared[idx] += counts[p] < qn ? counts[p] : qn;
167
+ }
168
+ }
169
+ const candidates = [];
170
+ const candidateCounts = [];
171
+ let maxCount = 0;
172
+ for (const idx of touched) {
173
+ const count = shared[idx];
174
+ shared[idx] = 0;
175
+ const maxLength = Math.max(sourceText.length, index.entries[idx].sourceText.length);
176
+ if (count >= maxLength - Q + 1 - Q * maxDistanceFor(maxLength)) {
177
+ candidates.push(idx);
178
+ candidateCounts.push(count);
179
+ if (count > maxCount)
180
+ maxCount = count;
181
+ }
182
+ }
183
+ if (candidates.length <= MAX_FUZZY_CANDIDATES) {
184
+ for (const idx of candidates)
185
+ consider(idx);
186
+ }
187
+ else {
188
+ // Top-K by shared count in O(n): counts are small integers, so bucket them.
189
+ const buckets = new Int32Array(maxCount + 1);
190
+ for (const c of candidateCounts)
191
+ buckets[c]++;
192
+ let cutoff = maxCount;
193
+ for (let taken = 0; cutoff > 0 && taken + buckets[cutoff] < MAX_FUZZY_CANDIDATES; cutoff--)
194
+ taken += buckets[cutoff];
195
+ let budget = MAX_FUZZY_CANDIDATES;
196
+ for (let i = 0; i < candidates.length && budget > 0; i++) {
197
+ if (candidateCounts[i] > cutoff) {
198
+ consider(candidates[i]);
199
+ budget--;
200
+ }
201
+ }
202
+ for (let i = 0; i < candidates.length && budget > 0; i++) {
203
+ if (candidateCounts[i] === cutoff) {
204
+ consider(candidates[i]);
205
+ budget--;
206
+ }
207
+ }
208
+ }
209
+ }
210
+ if (fuzzyMatches.length > 0) {
211
+ fuzzyMatches.sort((a, b) => b.similarity - a.similarity);
212
+ return {
213
+ hit: false, // Don't auto-apply fuzzy matches
214
+ fuzzyMatches: fuzzyMatches.slice(0, MAX_FUZZY_MATCHES),
215
+ };
216
+ }
217
+ return { hit: false };
218
+ }
@@ -0,0 +1,22 @@
1
+ export interface MemoryEntry {
2
+ sourceText: string;
3
+ sourceLocale: string;
4
+ targetLocale: string;
5
+ translatedText: string;
6
+ projectId?: string;
7
+ projectName?: string;
8
+ approvedAt?: string;
9
+ isoKey?: string;
10
+ }
11
+ export interface FuzzyMatch {
12
+ translatedText: string;
13
+ similarity: number;
14
+ sourceText: string;
15
+ }
16
+ export interface MemoryLookupResult {
17
+ hit: boolean;
18
+ translatedText?: string;
19
+ confidence?: number;
20
+ fromMemory?: boolean;
21
+ fuzzyMatches?: FuzzyMatch[];
22
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,38 @@
1
+ import type { LocaleFile, WorkspaceInfo } from '../../runtime/types';
2
+ import type { ByokProvider } from '@babelize/types';
3
+ import type { EngineProviders, TranslationFailure, TranslationCache } from '../../providers/types';
4
+ /** QA note on keys the backup (NLLB) translator produced. */
5
+ export declare const FALLBACK_QA_WARNING = "translated with the backup translator; will be retried with the AI translator next run";
6
+ export interface TranslateOptions {
7
+ /**
8
+ * The project's runtime formats ICU (next-intl, react-i18next + i18next-icu)
9
+ * and the translator is an LLM: a translation may turn a count placeholder
10
+ * into an ICU plural. Otherwise a plain source must stay plain.
11
+ */
12
+ targetPlurals?: boolean;
13
+ }
14
+ export declare function translateLocales(workspace: WorkspaceInfo, sourceLocale: LocaleFile, targetLocales: string[], forceTranslation?: boolean, dryRun?: boolean, projectId?: string, onProgress?: (message: string) => void, keysToTranslateByLocale?: Record<string, string[]>, cacheProvider?: TranslationCache, byokConfig?: {
15
+ provider: ByokProvider;
16
+ apiKey: string;
17
+ model?: string;
18
+ }, contextMap?: Record<string, string>, extractionContextMap?: Record<string, string>, providers?: EngineProviders, options?: TranslateOptions): Promise<{
19
+ translation: {
20
+ locales: LocaleFile[];
21
+ errors: {
22
+ locale: string;
23
+ error: string;
24
+ }[];
25
+ failures: TranslationFailure[];
26
+ };
27
+ stats: {
28
+ tmHits: number;
29
+ };
30
+ metadata: Record<string, Record<string, any>>;
31
+ }>;
32
+ /**
33
+ * Backfill TM from translations that were reused without calling the
34
+ * translator (lockfile hits). Existing TM rows are left untouched.
35
+ * Locales are ISO codes here; identity translations (source === target) are
36
+ * skipped since they mean a previous run had no working translator.
37
+ */
38
+ export declare function backfillTranslationMemory(projectId: string, sourceLocale: string, flatSource: Record<string, string>, translationsByLocale: Record<string, Record<string, string>>, excludeKeys?: Set<string>, providers?: EngineProviders): Promise<Record<string, string[]>>;