@babelize/engine 0.0.0-stage → 0.1.2

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 (270) 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/detection/stack.d.ts +42 -0
  11. package/dist/detection/stack.js +277 -0
  12. package/dist/django/catalog.d.ts +92 -0
  13. package/dist/django/catalog.js +677 -0
  14. package/dist/django/extract.d.ts +20 -0
  15. package/dist/django/extract.js +79 -0
  16. package/dist/django/inject-file.d.ts +6 -0
  17. package/dist/django/inject-file.js +52 -0
  18. package/dist/django/inject.d.ts +11 -0
  19. package/dist/django/inject.js +205 -0
  20. package/dist/django/keys.d.ts +21 -0
  21. package/dist/django/keys.js +63 -0
  22. package/dist/django/locale-names.d.ts +13 -0
  23. package/dist/django/locale-names.js +60 -0
  24. package/dist/django/mo-file.d.ts +6 -0
  25. package/dist/django/mo-file.js +60 -0
  26. package/dist/django/plural-forms.d.ts +34 -0
  27. package/dist/django/plural-forms.js +216 -0
  28. package/dist/django/po-file.d.ts +38 -0
  29. package/dist/django/po-file.js +273 -0
  30. package/dist/django/python-extract.d.ts +34 -0
  31. package/dist/django/python-extract.js +619 -0
  32. package/dist/django/python-lexer.d.ts +65 -0
  33. package/dist/django/python-lexer.js +398 -0
  34. package/dist/django/template-extract.d.ts +32 -0
  35. package/dist/django/template-extract.js +680 -0
  36. package/dist/django/types.d.ts +49 -0
  37. package/dist/django/types.js +15 -0
  38. package/dist/index.d.ts +59 -0
  39. package/dist/index.js +140 -0
  40. package/dist/injection/InjectionStrategy.d.ts +62 -0
  41. package/dist/injection/InjectionStrategy.js +2 -0
  42. package/dist/injection/StrategyFactory.d.ts +4 -0
  43. package/dist/injection/StrategyFactory.js +29 -0
  44. package/dist/injection/html/html-injector.d.ts +11 -0
  45. package/dist/injection/html/html-injector.js +173 -0
  46. package/dist/injection/strategies/NextIntlStrategy.d.ts +25 -0
  47. package/dist/injection/strategies/NextIntlStrategy.js +141 -0
  48. package/dist/injection/strategies/ReactI18nextStrategy.d.ts +19 -0
  49. package/dist/injection/strategies/ReactI18nextStrategy.js +116 -0
  50. package/dist/injection/strategies/VanillaStrategy.d.ts +11 -0
  51. package/dist/injection/strategies/VanillaStrategy.js +73 -0
  52. package/dist/injection/strategies/VueI18nStrategy.d.ts +11 -0
  53. package/dist/injection/strategies/VueI18nStrategy.js +84 -0
  54. package/dist/local/formatter.d.ts +26 -0
  55. package/dist/local/formatter.js +105 -0
  56. package/dist/local/git.d.ts +23 -0
  57. package/dist/local/git.js +136 -0
  58. package/dist/local/hosted-provider.d.ts +68 -0
  59. package/dist/local/hosted-provider.js +215 -0
  60. package/dist/local/index.d.ts +23 -0
  61. package/dist/local/index.js +75 -0
  62. package/dist/local/provider.d.ts +56 -0
  63. package/dist/local/provider.js +119 -0
  64. package/dist/local/pseudo-provider.d.ts +18 -0
  65. package/dist/local/pseudo-provider.js +208 -0
  66. package/dist/local/report.d.ts +177 -0
  67. package/dist/local/report.js +186 -0
  68. package/dist/local/translate-core.d.ts +218 -0
  69. package/dist/local/translate-core.js +499 -0
  70. package/dist/local/translate-messages.d.ts +49 -0
  71. package/dist/local/translate-messages.js +89 -0
  72. package/dist/local/workspace-copy.d.ts +91 -0
  73. package/dist/local/workspace-copy.js +355 -0
  74. package/dist/modules/extractor/extract.d.ts +20 -0
  75. package/dist/modules/extractor/extract.js +709 -0
  76. package/dist/modules/extractor/index.d.ts +2 -0
  77. package/dist/modules/extractor/index.js +63 -0
  78. package/dist/modules/finalization/django-finalize.d.ts +28 -0
  79. package/dist/modules/finalization/django-finalize.js +412 -0
  80. package/dist/modules/finalization/finalize.d.ts +38 -0
  81. package/dist/modules/finalization/finalize.js +745 -0
  82. package/dist/modules/finalization/index.d.ts +1 -0
  83. package/dist/modules/finalization/index.js +5 -0
  84. package/dist/modules/finalization/nextjs-finalize.d.ts +40 -0
  85. package/dist/modules/finalization/nextjs-finalize.js +328 -0
  86. package/dist/modules/finalization/static-runtime.d.ts +9 -0
  87. package/dist/modules/finalization/static-runtime.js +261 -0
  88. package/dist/modules/finalization/writes.d.ts +29 -0
  89. package/dist/modules/finalization/writes.js +78 -0
  90. package/dist/modules/format-injection/index.d.ts +19 -0
  91. package/dist/modules/format-injection/index.js +273 -0
  92. package/dist/modules/format-injection/inject-formats.d.ts +31 -0
  93. package/dist/modules/format-injection/inject-formats.js +208 -0
  94. package/dist/modules/glossary/index.d.ts +2 -0
  95. package/dist/modules/glossary/index.js +16 -0
  96. package/dist/modules/glossary/rules.d.ts +81 -0
  97. package/dist/modules/glossary/rules.js +244 -0
  98. package/dist/modules/glossary/types.d.ts +22 -0
  99. package/dist/modules/glossary/types.js +2 -0
  100. package/dist/modules/injection/index.d.ts +1 -0
  101. package/dist/modules/injection/index.js +6 -0
  102. package/dist/modules/injection/inject.d.ts +29 -0
  103. package/dist/modules/injection/inject.js +1050 -0
  104. package/dist/modules/keygen/index.d.ts +1 -0
  105. package/dist/modules/keygen/index.js +11 -0
  106. package/dist/modules/keygen/keygen.d.ts +4 -0
  107. package/dist/modules/keygen/keygen.js +123 -0
  108. package/dist/modules/keygen/locale-data.d.ts +7 -0
  109. package/dist/modules/keygen/locale-data.js +73 -0
  110. package/dist/modules/keygen/public.d.ts +2 -0
  111. package/dist/modules/keygen/public.js +12 -0
  112. package/dist/modules/locale-builder/index.d.ts +1 -0
  113. package/dist/modules/locale-builder/index.js +7 -0
  114. package/dist/modules/locale-builder/locales.d.ts +13 -0
  115. package/dist/modules/locale-builder/locales.js +130 -0
  116. package/dist/modules/lockfile/hasher.d.ts +7 -0
  117. package/dist/modules/lockfile/hasher.js +13 -0
  118. package/dist/modules/lockfile/index.d.ts +3 -0
  119. package/dist/modules/lockfile/index.js +22 -0
  120. package/dist/modules/lockfile/lockfile-manager.d.ts +99 -0
  121. package/dist/modules/lockfile/lockfile-manager.js +497 -0
  122. package/dist/modules/lockfile/schema.d.ts +196 -0
  123. package/dist/modules/lockfile/schema.js +56 -0
  124. package/dist/modules/parser/index.d.ts +2 -0
  125. package/dist/modules/parser/index.js +9 -0
  126. package/dist/modules/summary/index.d.ts +1 -0
  127. package/dist/modules/summary/index.js +7 -0
  128. package/dist/modules/summary/summary.d.ts +9 -0
  129. package/dist/modules/summary/summary.js +195 -0
  130. package/dist/modules/sync-detector/index.d.ts +2 -0
  131. package/dist/modules/sync-detector/index.js +7 -0
  132. package/dist/modules/sync-detector/reporter.d.ts +3 -0
  133. package/dist/modules/sync-detector/reporter.js +16 -0
  134. package/dist/modules/sync-detector/sync-detector.d.ts +39 -0
  135. package/dist/modules/sync-detector/sync-detector.js +374 -0
  136. package/dist/modules/translator/batch-optimizer.d.ts +12 -0
  137. package/dist/modules/translator/batch-optimizer.js +30 -0
  138. package/dist/modules/translator/client/byok.provider.d.ts +64 -0
  139. package/dist/modules/translator/client/byok.provider.js +319 -0
  140. package/dist/modules/translator/client/direct-translator.client.d.ts +12 -0
  141. package/dist/modules/translator/client/direct-translator.client.js +71 -0
  142. package/dist/modules/translator/client/gemini.provider.d.ts +1 -0
  143. package/dist/modules/translator/client/gemini.provider.js +110 -0
  144. package/dist/modules/translator/client/groq.provider.d.ts +1 -0
  145. package/dist/modules/translator/client/groq.provider.js +111 -0
  146. package/dist/modules/translator/client/request.types.d.ts +1 -0
  147. package/dist/modules/translator/client/request.types.js +2 -0
  148. package/dist/modules/translator/client/retry.d.ts +29 -0
  149. package/dist/modules/translator/client/retry.js +94 -0
  150. package/dist/modules/translator/client/test-utils/mock.client.d.ts +31 -0
  151. package/dist/modules/translator/client/test-utils/mock.client.js +59 -0
  152. package/dist/modules/translator/client/translator.interface.d.ts +1 -0
  153. package/dist/modules/translator/client/translator.interface.js +2 -0
  154. package/dist/modules/translator/icu-branches.d.ts +138 -0
  155. package/dist/modules/translator/icu-branches.js +393 -0
  156. package/dist/modules/translator/language-codes/errors.d.ts +10 -0
  157. package/dist/modules/translator/language-codes/errors.js +18 -0
  158. package/dist/modules/translator/language-codes/flores-map.d.ts +1 -0
  159. package/dist/modules/translator/language-codes/flores-map.js +107 -0
  160. package/dist/modules/translator/language-codes/index.d.ts +11 -0
  161. package/dist/modules/translator/language-codes/index.js +24 -0
  162. package/dist/modules/translator/language-codes/language-mapper.d.ts +25 -0
  163. package/dist/modules/translator/language-codes/language-mapper.js +132 -0
  164. package/dist/modules/translator/language-codes/rtl-languages.d.ts +2 -0
  165. package/dist/modules/translator/language-codes/rtl-languages.js +9 -0
  166. package/dist/modules/translator/memory/memory-matcher.d.ts +8 -0
  167. package/dist/modules/translator/memory/memory-matcher.js +218 -0
  168. package/dist/modules/translator/memory/types.d.ts +22 -0
  169. package/dist/modules/translator/memory/types.js +2 -0
  170. package/dist/modules/translator/translate.d.ts +74 -0
  171. package/dist/modules/translator/translate.js +1047 -0
  172. package/dist/modules/vue/migrate.d.ts +13 -0
  173. package/dist/modules/vue/migrate.js +40 -0
  174. package/dist/modules/vue/script-inject.d.ts +16 -0
  175. package/dist/modules/vue/script-inject.js +115 -0
  176. package/dist/modules/vue/sfc.d.ts +11 -0
  177. package/dist/modules/vue/sfc.js +51 -0
  178. package/dist/modules/vue/template-rewrite.d.ts +25 -0
  179. package/dist/modules/vue/template-rewrite.js +76 -0
  180. package/dist/modules/vue/template-scan.d.ts +29 -0
  181. package/dist/modules/vue/template-scan.js +264 -0
  182. package/dist/modules/workspace/index.d.ts +1 -0
  183. package/dist/modules/workspace/index.js +5 -0
  184. package/dist/modules/workspace/validate.d.ts +13 -0
  185. package/dist/modules/workspace/validate.js +333 -0
  186. package/dist/orchestrator.d.ts +13 -0
  187. package/dist/orchestrator.js +727 -0
  188. package/dist/providers/default-translation-provider.d.ts +20 -0
  189. package/dist/providers/default-translation-provider.js +30 -0
  190. package/dist/providers/index.d.ts +2 -0
  191. package/dist/providers/index.js +21 -0
  192. package/dist/providers/types.d.ts +153 -0
  193. package/dist/providers/types.js +2 -0
  194. package/dist/qa/check-project.d.ts +50 -0
  195. package/dist/qa/check-project.js +193 -0
  196. package/dist/qa/gettext-files.d.ts +15 -0
  197. package/dist/qa/gettext-files.js +115 -0
  198. package/dist/qa/locale-files.d.ts +44 -0
  199. package/dist/qa/locale-files.js +159 -0
  200. package/dist/qa/locale-qa.d.ts +61 -0
  201. package/dist/qa/locale-qa.js +342 -0
  202. package/dist/qa/review.d.ts +43 -0
  203. package/dist/qa/review.js +175 -0
  204. package/dist/runtime/config.d.ts +8 -0
  205. package/dist/runtime/config.js +37 -0
  206. package/dist/runtime/index.d.ts +3 -0
  207. package/dist/runtime/index.js +8 -0
  208. package/dist/runtime/types.d.ts +427 -0
  209. package/dist/runtime/types.js +38 -0
  210. package/dist/types.d.ts +134 -0
  211. package/dist/types.js +12 -0
  212. package/dist/utils/ast-helpers.d.ts +57 -0
  213. package/dist/utils/ast-helpers.js +608 -0
  214. package/dist/utils/cache-keys.d.ts +8 -0
  215. package/dist/utils/cache-keys.js +18 -0
  216. package/dist/utils/circuit-breaker.d.ts +43 -0
  217. package/dist/utils/circuit-breaker.js +119 -0
  218. package/dist/utils/concurrent-map.d.ts +4 -0
  219. package/dist/utils/concurrent-map.js +21 -0
  220. package/dist/utils/detect-format.d.ts +5 -0
  221. package/dist/utils/detect-format.js +125 -0
  222. package/dist/utils/extraction-options.d.ts +29 -0
  223. package/dist/utils/extraction-options.js +33 -0
  224. package/dist/utils/file-utils.d.ts +33 -0
  225. package/dist/utils/file-utils.js +267 -0
  226. package/dist/utils/glossary-match.d.ts +9 -0
  227. package/dist/utils/glossary-match.js +25 -0
  228. package/dist/utils/html-extractor.d.ts +8 -0
  229. package/dist/utils/html-extractor.js +317 -0
  230. package/dist/utils/i18next-icu.d.ts +38 -0
  231. package/dist/utils/i18next-icu.js +159 -0
  232. package/dist/utils/icu-message.d.ts +65 -0
  233. package/dist/utils/icu-message.js +346 -0
  234. package/dist/utils/icu-spans.d.ts +10 -0
  235. package/dist/utils/icu-spans.js +126 -0
  236. package/dist/utils/jsx-message.d.ts +93 -0
  237. package/dist/utils/jsx-message.js +628 -0
  238. package/dist/utils/key-usage.d.ts +35 -0
  239. package/dist/utils/key-usage.js +247 -0
  240. package/dist/utils/logger.d.ts +24 -0
  241. package/dist/utils/logger.js +33 -0
  242. package/dist/utils/metadata.d.ts +82 -0
  243. package/dist/utils/metadata.js +261 -0
  244. package/dist/utils/module-constants.d.ts +30 -0
  245. package/dist/utils/module-constants.js +265 -0
  246. package/dist/utils/not-injected.d.ts +6 -0
  247. package/dist/utils/not-injected.js +38 -0
  248. package/dist/utils/placeholder-protection.d.ts +74 -0
  249. package/dist/utils/placeholder-protection.js +181 -0
  250. package/dist/utils/pseudo-markers.d.ts +9 -0
  251. package/dist/utils/pseudo-markers.js +16 -0
  252. package/dist/utils/string-utils.d.ts +52 -0
  253. package/dist/utils/string-utils.js +270 -0
  254. package/dist/utils/translation-quality.d.ts +34 -0
  255. package/dist/utils/translation-quality.js +156 -0
  256. package/dist/utils/translation-sanitizer.d.ts +11 -0
  257. package/dist/utils/translation-sanitizer.js +71 -0
  258. package/dist/utils/translator-caller.d.ts +32 -0
  259. package/dist/utils/translator-caller.js +217 -0
  260. package/dist/utils/translator-load-balancer.d.ts +73 -0
  261. package/dist/utils/translator-load-balancer.js +297 -0
  262. package/dist/utils/ui-copy.d.ts +32 -0
  263. package/dist/utils/ui-copy.js +126 -0
  264. package/dist/utils/untranslated.d.ts +15 -0
  265. package/dist/utils/untranslated.js +34 -0
  266. package/dist/utils/workspace.d.ts +14 -0
  267. package/dist/utils/workspace.js +89 -0
  268. package/package.json +64 -4
  269. package/schemas/translate-report.schema.json +297 -0
  270. package/README.md +0 -3
@@ -0,0 +1,126 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DATA_KEYS = exports.UI_COPY_KEYS = void 0;
37
+ exports.isMultiWordCopy = isMultiWordCopy;
38
+ exports.looksLikeCopy = looksLikeCopy;
39
+ exports.isUiCopyForName = isUiCopyForName;
40
+ exports.isUiCopyLiteral = isUiCopyLiteral;
41
+ const t = __importStar(require("@babel/types"));
42
+ /**
43
+ * UI copy vs program data in object / array / variable initializers.
44
+ *
45
+ * `const user = { name: "Ada" }` is data: translating it rewrites a user's
46
+ * name (`{ name: t("page.ada") }`). `[{ label: "Home", href: "/" }]` holds UI
47
+ * copy under `label` and data under `href`. A string in an initializer is
48
+ * only extracted when its key says it's copy, or (without a telling key) when
49
+ * it looks like copy: a sentence, a Title Case phrase or a capitalized word.
50
+ * Both lists match the key's last camelCase word (`buttonLabel` → label,
51
+ * `firstName` → name) or the whole key, case-insensitively, and can be
52
+ * extended by callers.
53
+ */
54
+ exports.UI_COPY_KEYS = new Set([
55
+ 'label', 'title', 'description', 'placeholder', 'text', 'message', 'heading', 'subheading', 'headline', 'subtitle',
56
+ 'tooltip', 'cta', 'alt', 'arialabel', 'caption', 'hint', 'help', 'helptext', 'summary', 'body', 'question',
57
+ 'answer', 'notice', 'error', 'success', 'warning', 'confirm', 'prompt', 'greeting', 'tagline', 'blurb', 'excerpt',
58
+ ]);
59
+ exports.DATA_KEYS = new Set([
60
+ 'name', 'id', 'key', 'email', 'username', 'slug', 'url', 'href', 'src', 'path', 'type', 'value', 'code', 'locale',
61
+ 'lang', 'language', 'classname', 'class', 'variant', 'color', 'colour', 'icon', 'date', 'currency', 'size', 'status',
62
+ 'role', 'method', 'format', 'mode', 'theme', 'target', 'rel', 'route', 'to', 'link', 'ref', 'uuid', 'token',
63
+ 'phone', 'address', 'image', 'avatar', 'file', 'filename', 'extension', 'mime', 'kind', 'timezone', 'country',
64
+ 'handle', 'domain', 'host', 'endpoint', 'version', 'sku', 'hash', 'secret', 'password', 'field', 'event', 'action',
65
+ 'user', 'author', 'owner', 'customer', 'company', 'brand', 'city', 'state', 'zip', 'region',
66
+ ]);
67
+ function words(name) {
68
+ return name.split(/(?=[A-Z])|[-_\s]/).filter(Boolean).map((w) => w.toLowerCase());
69
+ }
70
+ /** Two or more words with letters: reads like copy, not an identifier. */
71
+ function isMultiWordCopy(text) {
72
+ return text.trim().split(/\s+/).filter((w) => /\p{L}/u.test(w)).length >= 2;
73
+ }
74
+ /**
75
+ * Copy without a key to say so: a sentence or Title Case phrase, or a single
76
+ * capitalized word ("Overview", "Settings"). Data looks different: lowercase
77
+ * tokens ("active"), kebab/snake/camelCase, ALLCAPS, or anything with digits,
78
+ * underscores, slashes or dots in a single token.
79
+ */
80
+ function looksLikeCopy(text) {
81
+ const trimmed = text.trim();
82
+ if (isMultiWordCopy(trimmed))
83
+ return true;
84
+ return /^\p{Lu}\p{Ll}+[!?.:…]?$/u.test(trimmed);
85
+ }
86
+ /** Whether a string stored under `name` (a key or a variable) is UI copy. */
87
+ function isUiCopyForName(name, text) {
88
+ if (name) {
89
+ const parts = words(name);
90
+ const last = parts[parts.length - 1] ?? '';
91
+ const full = name.toLowerCase().replace(/[-_]/g, '');
92
+ if (exports.UI_COPY_KEYS.has(last) || exports.UI_COPY_KEYS.has(full))
93
+ return true;
94
+ if (exports.DATA_KEYS.has(last) || exports.DATA_KEYS.has(full))
95
+ return false;
96
+ }
97
+ return looksLikeCopy(text);
98
+ }
99
+ function keyName(key) {
100
+ if (t.isIdentifier(key))
101
+ return key.name;
102
+ if (t.isStringLiteral(key))
103
+ return key.value;
104
+ return null;
105
+ }
106
+ /**
107
+ * For a string literal in an object property value, array element or
108
+ * variable/assignment initializer: is it UI copy? Other positions (JSX,
109
+ * returns, conditionals, …) aren't initializers and are left as they are.
110
+ */
111
+ function isUiCopyLiteral(node, parent, text) {
112
+ if (!parent)
113
+ return true;
114
+ if (t.isObjectProperty(parent) && parent.value === node)
115
+ return isUiCopyForName(parent.computed ? null : keyName(parent.key), text);
116
+ if (t.isVariableDeclarator(parent) && parent.init === node)
117
+ return isUiCopyForName(t.isIdentifier(parent.id) ? parent.id.name : null, text);
118
+ if (t.isAssignmentExpression(parent) && parent.right === node) {
119
+ const left = parent.left;
120
+ const name = t.isIdentifier(left) ? left.name : t.isMemberExpression(left) && !left.computed && t.isIdentifier(left.property) ? left.property.name : null;
121
+ return isUiCopyForName(name, text);
122
+ }
123
+ if (t.isArrayExpression(parent))
124
+ return looksLikeCopy(text);
125
+ return true;
126
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Detects source text that came back from translation unchanged.
3
+ *
4
+ * Into a Latin-script language an unchanged short string can be a real
5
+ * translation ("Hotel", "Email"). Into a non-Latin-script language, English
6
+ * letters returned verbatim were not translated. Such values must be rejected
7
+ * when the translator returns them AND when a cache or TM lookup does: once
8
+ * stored, a bad value would otherwise be replayed on every run and never retried.
9
+ */
10
+ /** Is the locale written in Latin script (where an unchanged word can be a real translation)? */
11
+ export declare function isLatinScript(locale: string): boolean;
12
+ /** Letters left once placeholders, tags and entities are removed. */
13
+ export declare function hasWords(text: string | undefined): boolean;
14
+ /** `translated` is the untouched source, into a language where that cannot be a translation. */
15
+ export declare function isUntranslatedInto(source: string, translated: string, targetLocale: string): boolean;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * Detects source text that came back from translation unchanged.
4
+ *
5
+ * Into a Latin-script language an unchanged short string can be a real
6
+ * translation ("Hotel", "Email"). Into a non-Latin-script language, English
7
+ * letters returned verbatim were not translated. Such values must be rejected
8
+ * when the translator returns them AND when a cache or TM lookup does: once
9
+ * stored, a bad value would otherwise be replayed on every run and never retried.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isLatinScript = isLatinScript;
13
+ exports.hasWords = hasWords;
14
+ exports.isUntranslatedInto = isUntranslatedInto;
15
+ /** Is the locale written in Latin script (where an unchanged word can be a real translation)? */
16
+ function isLatinScript(locale) {
17
+ try {
18
+ return new Intl.Locale(locale).maximize().script === 'Latn';
19
+ }
20
+ catch {
21
+ return true;
22
+ }
23
+ }
24
+ /** Letters left once placeholders, tags and entities are removed. */
25
+ function hasWords(text) {
26
+ if (!text)
27
+ return false;
28
+ const stripped = text.replace(/%\(\w+\)[-#0 +]*\d*(?:\.\d+)?[a-zA-Z]|%[sdif%]|\{[^{}]*\}|<[^>]*>|&[#\w]+;|\[\s*#\s*VAR_\d+\s*#\s*\]/gi, ' ');
29
+ return /\p{L}{2,}/u.test(stripped);
30
+ }
31
+ /** `translated` is the untouched source, into a language where that cannot be a translation. */
32
+ function isUntranslatedInto(source, translated, targetLocale) {
33
+ return !isLatinScript(targetLocale) && translated.trim() === source.trim() && hasWords(source);
34
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Remove stale locale files from the workspace that are NOT in the target locale list.
3
+ *
4
+ * When a project is re-run with changed languages, old locale files from previous
5
+ * runs persist because `git reset --hard` only resets tracked files and generated
6
+ * locale files are untracked. This function cleans them up.
7
+ *
8
+ * @param workspacePath - Path to the workspace directory
9
+ * @param targetLocales - Current list of target locale codes (e.g., ['fr', 'de'])
10
+ * @param sourceLocale - Source locale code (e.g., 'en') — always preserved
11
+ * @param localeFormat - Output format ('json' | 'po' | 'arb')
12
+ * @param publicDir - Public directory relative to workspace (e.g., 'public')
13
+ */
14
+ export declare function removeStaleLocales(workspacePath: string, targetLocales: string[], sourceLocale: string, localeFormat?: string, publicDir?: string): Promise<void>;
@@ -0,0 +1,89 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.removeStaleLocales = removeStaleLocales;
37
+ const fs = __importStar(require("fs-extra"));
38
+ const path = __importStar(require("path"));
39
+ const file_utils_1 = require("./file-utils");
40
+ const logger_1 = require("./logger");
41
+ /**
42
+ * Remove stale locale files from the workspace that are NOT in the target locale list.
43
+ *
44
+ * When a project is re-run with changed languages, old locale files from previous
45
+ * runs persist because `git reset --hard` only resets tracked files and generated
46
+ * locale files are untracked. This function cleans them up.
47
+ *
48
+ * @param workspacePath - Path to the workspace directory
49
+ * @param targetLocales - Current list of target locale codes (e.g., ['fr', 'de'])
50
+ * @param sourceLocale - Source locale code (e.g., 'en') — always preserved
51
+ * @param localeFormat - Output format ('json' | 'po' | 'arb')
52
+ * @param publicDir - Public directory relative to workspace (e.g., 'public')
53
+ */
54
+ async function removeStaleLocales(workspacePath, targetLocales, sourceLocale, localeFormat = 'json', publicDir = 'public') {
55
+ // Django uses locale/<lang>/LC_MESSAGES/ — skip stale locale removal for PO format
56
+ if (localeFormat === 'po')
57
+ return;
58
+ const localesDir = path.join(workspacePath, publicDir, 'locales');
59
+ if (!(await fs.pathExists(localesDir))) {
60
+ return;
61
+ }
62
+ const ext = (0, file_utils_1.localeExtension)(localeFormat);
63
+ const allowedLocales = new Set([sourceLocale, ...targetLocales]);
64
+ try {
65
+ const entries = await fs.readdir(localesDir);
66
+ let removedCount = 0;
67
+ for (const entry of entries) {
68
+ if (!entry.endsWith(ext))
69
+ continue;
70
+ const localeCode = entry.replace(ext, '');
71
+ if (!allowedLocales.has(localeCode)) {
72
+ const filePath = path.join(localesDir, entry);
73
+ await fs.remove(filePath);
74
+ removedCount++;
75
+ logger_1.engineLogger.debug('Removed stale locale file', { file: entry, localeCode });
76
+ }
77
+ }
78
+ if (removedCount > 0) {
79
+ logger_1.engineLogger.info('Cleaned up stale locale files', {
80
+ removedCount,
81
+ keptLocales: [...allowedLocales],
82
+ workspacePath,
83
+ });
84
+ }
85
+ }
86
+ catch (err) {
87
+ logger_1.engineLogger.warn('Failed to clean up stale locale files', { error: err, workspacePath });
88
+ }
89
+ }
package/package.json CHANGED
@@ -1,6 +1,66 @@
1
1
  {
2
2
  "name": "@babelize/engine",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.2",
4
+ "description": "Babelize translation pipeline (extract, keygen, translate, inject). Infrastructure is injected through provider/store interfaces.",
5
+ "keywords": [
6
+ "babelize",
7
+ "i18n",
8
+ "localization",
9
+ "translation",
10
+ "ast"
11
+ ],
12
+ "license": "Apache-2.0",
13
+ "homepage": "https://babelize.co",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/babelize/babelize-dashboard.git"
17
+ },
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist",
22
+ "schemas"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "scripts": {
28
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
29
+ "typecheck": "tsc --noEmit",
30
+ "lint": "eslint src",
31
+ "test": "jest",
32
+ "prepublishOnly": "npm run build && npm test && npm run typecheck"
33
+ },
34
+ "dependencies": {
35
+ "@babel/generator": "^7.28.5",
36
+ "@babel/parser": "^7.28.5",
37
+ "@babel/traverse": "^7.28.5",
38
+ "@babel/types": "^7.29.8",
39
+ "@babelize/types": "^0.1.2",
40
+ "@vue/compiler-dom": "^3.5",
41
+ "@vue/compiler-sfc": "^3.5",
42
+ "diff": "^8.0.4",
43
+ "fast-glob": "^3.3.3",
44
+ "fs-extra": "^11.3.3",
45
+ "gettext-parser": "^9.1.1",
46
+ "magic-string": "^0.30",
47
+ "node-html-parser": "^8.0.4",
48
+ "zod": "^3.22.4"
49
+ },
50
+ "devDependencies": {
51
+ "@eslint/js": "^9.39.2",
52
+ "@jest/globals": "^30.3.0",
53
+ "@types/babel__generator": "^7.27.0",
54
+ "@types/babel__traverse": "^7.28.0",
55
+ "@types/fs-extra": "^11.0.4",
56
+ "@types/jest": "^30.0.0",
57
+ "@types/node": "^25.0.3",
58
+ "ajv": "^8.17.1",
59
+ "eslint": "^9.39.2",
60
+ "intl-messageformat": "^10.7.16",
61
+ "jest": "^30.2.0",
62
+ "ts-jest": "^29.4.6",
63
+ "typescript": "^5.9.3",
64
+ "typescript-eslint": "^8.53.1"
65
+ }
66
+ }
@@ -0,0 +1,297 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://babelize.co/schemas/translate-report.v1.json",
4
+ "title": "Babelize translate report",
5
+ "description": "What `babelize translate --json` prints and `.babelize/local/report.json` contains (TranslateReport in @babelize/engine). Every per-key list is complete.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "$schema", "schemaVersion", "ok", "startedAt", "finishedAt", "durationMs", "framework", "frameworkStatus",
10
+ "provider", "sourceLocale", "targetLocales", "keptLocales", "droppedLocales", "dryRun", "applied",
11
+ "filesChanged", "diffSummary", "stats", "summary", "locales", "failures", "qaWarnings", "missing",
12
+ "unchanged", "notInjected", "unusedKeys", "dynamicKeyFiles", "keys", "warnings", "notes", "engineLog",
13
+ "lockfile", "lockfileIgnored"
14
+ ],
15
+ "properties": {
16
+ "$schema": { "type": "string" },
17
+ "schemaVersion": { "const": 1 },
18
+ "ok": { "type": "boolean", "description": "False when any key failed (the run is partial; the CLI exits 6)." },
19
+ "startedAt": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$" },
20
+ "finishedAt": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$" },
21
+ "durationMs": { "type": "number", "minimum": 0 },
22
+ "framework": { "type": "string" },
23
+ "frameworkStatus": { "enum": ["supported", "beta"] },
24
+ "provider": {
25
+ "oneOf": [
26
+ { "type": "null" },
27
+ {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "required": ["provider", "name"],
31
+ "properties": {
32
+ "provider": { "type": "string" },
33
+ "name": { "type": "string" },
34
+ "model": { "type": "string" }
35
+ }
36
+ }
37
+ ]
38
+ },
39
+ "sourceLocale": { "type": "string" },
40
+ "targetLocales": { "$ref": "#/$defs/strings" },
41
+ "keptLocales": { "$ref": "#/$defs/strings" },
42
+ "droppedLocales": { "$ref": "#/$defs/strings" },
43
+ "dryRun": { "type": "boolean" },
44
+ "applied": { "type": "boolean" },
45
+ "filesChanged": {
46
+ "type": "object",
47
+ "additionalProperties": false,
48
+ "required": ["added", "modified", "deleted"],
49
+ "properties": {
50
+ "added": { "$ref": "#/$defs/strings" },
51
+ "modified": { "$ref": "#/$defs/strings" },
52
+ "deleted": { "$ref": "#/$defs/strings" }
53
+ }
54
+ },
55
+ "diffSummary": {
56
+ "type": "array",
57
+ "items": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "required": ["file", "kind", "added", "removed"],
61
+ "properties": {
62
+ "file": { "type": "string" },
63
+ "kind": { "enum": ["added", "modified", "deleted"] },
64
+ "added": { "$ref": "#/$defs/count" },
65
+ "removed": { "$ref": "#/$defs/count" }
66
+ }
67
+ }
68
+ },
69
+ "diff": { "type": "string", "description": "Unified diff; dry runs only." },
70
+ "stats": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["filesScanned", "stringsExtracted", "keysExtracted", "injectionsApplied", "keysFromLockfile", "keysSentToTranslator"],
74
+ "properties": {
75
+ "filesScanned": { "$ref": "#/$defs/count" },
76
+ "stringsExtracted": { "$ref": "#/$defs/count" },
77
+ "keysExtracted": { "$ref": "#/$defs/count" },
78
+ "injectionsApplied": { "$ref": "#/$defs/count" },
79
+ "keysFromLockfile": { "$ref": "#/$defs/count" },
80
+ "keysSentToTranslator": { "$ref": "#/$defs/count" },
81
+ "translatedThisRun": { "$ref": "#/$defs/count" }
82
+ }
83
+ },
84
+ "summary": {
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "required": ["sourceKeys", "translations", "newTranslations", "reused", "failed", "qaWarnings", "missing", "unchanged", "notInjected"],
88
+ "properties": {
89
+ "sourceKeys": { "$ref": "#/$defs/count" },
90
+ "translations": { "$ref": "#/$defs/count" },
91
+ "newTranslations": { "$ref": "#/$defs/count" },
92
+ "reused": { "$ref": "#/$defs/count" },
93
+ "failed": { "$ref": "#/$defs/count" },
94
+ "qaWarnings": { "$ref": "#/$defs/count" },
95
+ "missing": { "$ref": "#/$defs/count" },
96
+ "unchanged": { "$ref": "#/$defs/count" },
97
+ "notInjected": { "$ref": "#/$defs/count" }
98
+ }
99
+ },
100
+ "locales": {
101
+ "type": "array",
102
+ "items": {
103
+ "type": "object",
104
+ "additionalProperties": false,
105
+ "required": ["locale", "status", "total", "translated", "missing", "failed", "qaWarnings", "sameAsSource"],
106
+ "properties": {
107
+ "locale": { "type": "string" },
108
+ "status": { "enum": ["ok", "warning", "failed"] },
109
+ "total": { "$ref": "#/$defs/count" },
110
+ "translated": { "$ref": "#/$defs/count" },
111
+ "missing": { "$ref": "#/$defs/count" },
112
+ "failed": { "$ref": "#/$defs/count" },
113
+ "qaWarnings": { "$ref": "#/$defs/count" },
114
+ "sameAsSource": { "$ref": "#/$defs/count" }
115
+ }
116
+ }
117
+ },
118
+ "failures": {
119
+ "$ref": "#/$defs/list",
120
+ "type": "object",
121
+ "properties": {
122
+ "items": {
123
+ "type": "array",
124
+ "items": {
125
+ "type": "object",
126
+ "additionalProperties": false,
127
+ "required": ["locale", "key", "source", "reason", "retryable"],
128
+ "properties": {
129
+ "locale": { "type": "string" },
130
+ "key": { "type": "string" },
131
+ "source": { "type": "string" },
132
+ "reason": { "$ref": "#/$defs/failureReason" },
133
+ "retryable": { "type": "boolean" },
134
+ "message": { "type": "string" }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ },
140
+ "qaWarnings": {
141
+ "$ref": "#/$defs/list",
142
+ "type": "object",
143
+ "properties": {
144
+ "items": {
145
+ "type": "array",
146
+ "items": {
147
+ "type": "object",
148
+ "additionalProperties": false,
149
+ "required": ["locale", "key", "warnings"],
150
+ "properties": {
151
+ "locale": { "type": "string" },
152
+ "key": { "type": "string" },
153
+ "warnings": { "$ref": "#/$defs/strings" }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ },
159
+ "missing": {
160
+ "$ref": "#/$defs/list",
161
+ "type": "object",
162
+ "properties": {
163
+ "items": {
164
+ "type": "array",
165
+ "items": {
166
+ "type": "object",
167
+ "additionalProperties": false,
168
+ "required": ["locale", "key"],
169
+ "properties": { "locale": { "type": "string" }, "key": { "type": "string" } }
170
+ }
171
+ }
172
+ }
173
+ },
174
+ "unchanged": {
175
+ "$ref": "#/$defs/list",
176
+ "type": "object",
177
+ "properties": {
178
+ "items": {
179
+ "type": "array",
180
+ "items": {
181
+ "type": "object",
182
+ "additionalProperties": false,
183
+ "required": ["locale", "key", "value"],
184
+ "properties": { "locale": { "type": "string" }, "key": { "type": "string" }, "value": { "type": "string" } }
185
+ }
186
+ }
187
+ }
188
+ },
189
+ "notInjected": {
190
+ "$ref": "#/$defs/list",
191
+ "type": "object",
192
+ "properties": {
193
+ "items": {
194
+ "type": "array",
195
+ "items": {
196
+ "type": "object",
197
+ "additionalProperties": false,
198
+ "required": ["file", "key", "text", "reason"],
199
+ "properties": {
200
+ "file": { "type": "string" },
201
+ "key": { "type": "string" },
202
+ "text": { "type": "string" },
203
+ "reason": { "type": "string" }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ },
209
+ "unusedKeys": {
210
+ "$ref": "#/$defs/list",
211
+ "type": "object",
212
+ "properties": { "items": { "$ref": "#/$defs/strings" } }
213
+ },
214
+ "dynamicKeyFiles": { "$ref": "#/$defs/strings" },
215
+ "keys": {
216
+ "type": "array",
217
+ "items": {
218
+ "type": "object",
219
+ "additionalProperties": false,
220
+ "required": ["key", "source", "locales"],
221
+ "properties": {
222
+ "key": { "type": "string" },
223
+ "source": { "type": "string" },
224
+ "locales": {
225
+ "type": "object",
226
+ "additionalProperties": {
227
+ "type": "object",
228
+ "additionalProperties": false,
229
+ "required": ["status"],
230
+ "properties": {
231
+ "status": { "enum": ["translated", "warning", "unchanged", "failed", "missing"] },
232
+ "value": { "type": "string" },
233
+ "reason": { "$ref": "#/$defs/failureReason" },
234
+ "message": { "type": "string" },
235
+ "retryable": { "type": "boolean" },
236
+ "warnings": { "$ref": "#/$defs/strings" }
237
+ }
238
+ }
239
+ }
240
+ }
241
+ }
242
+ },
243
+ "warnings": {
244
+ "type": "array",
245
+ "items": {
246
+ "type": "object",
247
+ "additionalProperties": false,
248
+ "required": ["type", "file", "message"],
249
+ "properties": {
250
+ "type": { "type": "string" },
251
+ "file": { "type": "string" },
252
+ "line": { "type": "number" },
253
+ "message": { "type": "string" }
254
+ }
255
+ }
256
+ },
257
+ "notes": { "$ref": "#/$defs/strings" },
258
+ "engineLog": {
259
+ "type": "array",
260
+ "items": {
261
+ "type": "object",
262
+ "additionalProperties": false,
263
+ "required": ["level", "message"],
264
+ "properties": { "level": { "enum": ["warn", "error"] }, "message": { "type": "string" } }
265
+ }
266
+ },
267
+ "formatter": {
268
+ "type": "object",
269
+ "additionalProperties": false,
270
+ "required": ["tool", "files", "ok"],
271
+ "properties": {
272
+ "tool": { "enum": ["prettier", "biome"] },
273
+ "files": { "$ref": "#/$defs/strings" },
274
+ "ok": { "type": "boolean" },
275
+ "message": { "type": "string" }
276
+ }
277
+ },
278
+ "lockfile": { "type": "string" },
279
+ "lockfileIgnored": { "type": "boolean" }
280
+ },
281
+ "$defs": {
282
+ "count": { "type": "integer", "minimum": 0 },
283
+ "strings": { "type": "array", "items": { "type": "string" } },
284
+ "list": {
285
+ "type": "object",
286
+ "additionalProperties": false,
287
+ "required": ["total", "items"],
288
+ "properties": { "total": { "type": "integer", "minimum": 0 }, "items": { "type": "array" } }
289
+ },
290
+ "failureReason": {
291
+ "enum": [
292
+ "missing_from_response", "empty_value", "placeholder_lost", "untranslated", "icu_invalid",
293
+ "markup_mismatch", "unsupported_by_provider", "provider_error"
294
+ ]
295
+ }
296
+ }
297
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.