@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,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Circuit Breaker Pattern
|
|
4
|
+
*
|
|
5
|
+
* Prevents cascading failures by stopping requests to failing services
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.CircuitBreaker = exports.CircuitState = void 0;
|
|
9
|
+
exports.getCircuitBreaker = getCircuitBreaker;
|
|
10
|
+
var CircuitState;
|
|
11
|
+
(function (CircuitState) {
|
|
12
|
+
CircuitState["CLOSED"] = "closed";
|
|
13
|
+
CircuitState["OPEN"] = "open";
|
|
14
|
+
CircuitState["HALF_OPEN"] = "half-open";
|
|
15
|
+
})(CircuitState || (exports.CircuitState = CircuitState = {}));
|
|
16
|
+
class CircuitBreaker {
|
|
17
|
+
constructor(name, options = {
|
|
18
|
+
failureThreshold: 5,
|
|
19
|
+
resetTimeout: 60000, // 1 minute
|
|
20
|
+
halfOpenMaxCalls: 3,
|
|
21
|
+
}) {
|
|
22
|
+
this.name = name;
|
|
23
|
+
this.options = options;
|
|
24
|
+
this.state = CircuitState.CLOSED;
|
|
25
|
+
this.failureCount = 0;
|
|
26
|
+
this.lastFailureTime = 0;
|
|
27
|
+
this.halfOpenCalls = 0;
|
|
28
|
+
this.successCount = 0;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Execute a function with circuit breaker protection
|
|
32
|
+
*/
|
|
33
|
+
async execute(fn) {
|
|
34
|
+
if (this.state === CircuitState.OPEN) {
|
|
35
|
+
if (Date.now() - this.lastFailureTime > this.options.resetTimeout) {
|
|
36
|
+
this.state = CircuitState.HALF_OPEN;
|
|
37
|
+
this.halfOpenCalls = 0;
|
|
38
|
+
this.successCount = 0;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
throw new Error(`Circuit breaker ${this.name} is OPEN`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (this.state === CircuitState.HALF_OPEN) {
|
|
45
|
+
if (this.halfOpenCalls >= this.options.halfOpenMaxCalls) {
|
|
46
|
+
// Too many calls in half-open, open the circuit
|
|
47
|
+
this.state = CircuitState.OPEN;
|
|
48
|
+
this.lastFailureTime = Date.now();
|
|
49
|
+
throw new Error(`Circuit breaker ${this.name} is OPEN`);
|
|
50
|
+
}
|
|
51
|
+
this.halfOpenCalls++;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const result = await fn();
|
|
55
|
+
this.onSuccess();
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
this.onFailure();
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
onSuccess() {
|
|
64
|
+
this.failureCount = 0;
|
|
65
|
+
if (this.state === CircuitState.HALF_OPEN) {
|
|
66
|
+
this.successCount++;
|
|
67
|
+
if (this.successCount >= this.options.halfOpenMaxCalls) {
|
|
68
|
+
// Service recovered
|
|
69
|
+
this.state = CircuitState.CLOSED;
|
|
70
|
+
this.halfOpenCalls = 0;
|
|
71
|
+
this.successCount = 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
onFailure() {
|
|
76
|
+
this.failureCount++;
|
|
77
|
+
this.lastFailureTime = Date.now();
|
|
78
|
+
if (this.state === CircuitState.HALF_OPEN) {
|
|
79
|
+
// Failed in half-open, open the circuit
|
|
80
|
+
this.state = CircuitState.OPEN;
|
|
81
|
+
this.halfOpenCalls = 0;
|
|
82
|
+
this.successCount = 0;
|
|
83
|
+
}
|
|
84
|
+
else if (this.failureCount >= this.options.failureThreshold) {
|
|
85
|
+
// Too many failures, open the circuit
|
|
86
|
+
this.state = CircuitState.OPEN;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
getState() {
|
|
90
|
+
return this.state;
|
|
91
|
+
}
|
|
92
|
+
getStats() {
|
|
93
|
+
return {
|
|
94
|
+
name: this.name,
|
|
95
|
+
state: this.state,
|
|
96
|
+
failureCount: this.failureCount,
|
|
97
|
+
lastFailureTime: this.lastFailureTime,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
reset() {
|
|
101
|
+
this.state = CircuitState.CLOSED;
|
|
102
|
+
this.failureCount = 0;
|
|
103
|
+
this.lastFailureTime = 0;
|
|
104
|
+
this.halfOpenCalls = 0;
|
|
105
|
+
this.successCount = 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.CircuitBreaker = CircuitBreaker;
|
|
109
|
+
// Global circuit breakers
|
|
110
|
+
const circuitBreakers = new Map();
|
|
111
|
+
/**
|
|
112
|
+
* Get or create a circuit breaker
|
|
113
|
+
*/
|
|
114
|
+
function getCircuitBreaker(name, options) {
|
|
115
|
+
if (!circuitBreakers.has(name)) {
|
|
116
|
+
circuitBreakers.set(name, new CircuitBreaker(name, options));
|
|
117
|
+
}
|
|
118
|
+
return circuitBreakers.get(name);
|
|
119
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.concurrentMap = concurrentMap;
|
|
4
|
+
async function concurrentMap(items, fn, concurrency) {
|
|
5
|
+
const results = new Array(items.length);
|
|
6
|
+
const errors = [];
|
|
7
|
+
let nextIndex = 0;
|
|
8
|
+
const worker = async () => {
|
|
9
|
+
while (nextIndex < items.length) {
|
|
10
|
+
const i = nextIndex++;
|
|
11
|
+
try {
|
|
12
|
+
results[i] = await fn(items[i], i);
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
errors.push(err instanceof Error ? err : new Error(String(err)));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
20
|
+
return { results, errors };
|
|
21
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DetectedFormat } from '../runtime/types';
|
|
2
|
+
export declare function extractCurrency(raw: string): DetectedFormat | null;
|
|
3
|
+
export declare function extractDate(raw: string): DetectedFormat | null;
|
|
4
|
+
export declare function extractNumber(raw: string): DetectedFormat | null;
|
|
5
|
+
export declare function detectFormat(text: string): DetectedFormat | null;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractCurrency = extractCurrency;
|
|
4
|
+
exports.extractDate = extractDate;
|
|
5
|
+
exports.extractNumber = extractNumber;
|
|
6
|
+
exports.detectFormat = detectFormat;
|
|
7
|
+
// ─────────────────────────────────────────────────────────────
|
|
8
|
+
// Currency Detection
|
|
9
|
+
// ─────────────────────────────────────────────────────────────
|
|
10
|
+
const CURRENCY_CODES = ['USD', 'EUR', 'GBP', 'JPY', 'CNY', 'INR', 'KRW', 'RUB', 'TRY', 'VND', 'UAH', 'NGN', 'PHP', 'GHS', 'ARS', 'BRL', 'MXN', 'CAD', 'AUD', 'CHF', 'SEK', 'NOK', 'DKK', 'NZD', 'SGD', 'HKD', 'TWD', 'THB', 'MYR', 'IDR'];
|
|
11
|
+
const CURRENCY_PATTERNS = [
|
|
12
|
+
/^[€$£¥₹₩₽₺\u20B9\u20A8]?\s?\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?\s?[€$£¥₹₩₽₺A-Z]*$/,
|
|
13
|
+
/^[A-Z]{3}\s?\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?$/,
|
|
14
|
+
/^\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{2})?\s?[€$£¥€]$/,
|
|
15
|
+
];
|
|
16
|
+
function extractCurrency(raw) {
|
|
17
|
+
const trimmed = raw.trim();
|
|
18
|
+
if (!CURRENCY_PATTERNS.some((p) => p.test(trimmed)))
|
|
19
|
+
return null;
|
|
20
|
+
const match = trimmed.match(/[\d,.\s]+(?:\.[0-9]{2})?/);
|
|
21
|
+
if (!match)
|
|
22
|
+
return null;
|
|
23
|
+
const numericPart = match[0].replace(/[^\d,.]/g, '').trim();
|
|
24
|
+
if (!numericPart)
|
|
25
|
+
return null;
|
|
26
|
+
const symbolMatch = trimmed.match(/[€$£¥₹₩₽₺\u20B9\u20A8]/);
|
|
27
|
+
const codeMatch = trimmed.match(/\b([A-Z]{3})\b/);
|
|
28
|
+
let detectedCurrency;
|
|
29
|
+
if (symbolMatch) {
|
|
30
|
+
const symbolToCode = {
|
|
31
|
+
'$': 'USD', '€': 'EUR', '£': 'GBP', '¥': 'JPY',
|
|
32
|
+
'₹': 'INR', '₩': 'KRW', '₽': 'RUB', '₺': 'TRY',
|
|
33
|
+
'₫': 'VND', '₴': 'UAH', '₦': 'NGN', '₱': 'PHP',
|
|
34
|
+
'₵': 'GHS', '₿': 'BTC',
|
|
35
|
+
};
|
|
36
|
+
detectedCurrency = symbolToCode[symbolMatch[0]] || symbolMatch[0];
|
|
37
|
+
}
|
|
38
|
+
else if (codeMatch && CURRENCY_CODES.includes(codeMatch[1])) {
|
|
39
|
+
detectedCurrency = codeMatch[1];
|
|
40
|
+
}
|
|
41
|
+
const rawNumber = numericPart.replace(/,/g, '');
|
|
42
|
+
const parsed = parseFloat(rawNumber);
|
|
43
|
+
if (isNaN(parsed))
|
|
44
|
+
return null;
|
|
45
|
+
return {
|
|
46
|
+
class: 'currency',
|
|
47
|
+
rawValue: numericPart,
|
|
48
|
+
originalString: trimmed,
|
|
49
|
+
confidence: 0.85,
|
|
50
|
+
detectedCurrency,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// ─────────────────────────────────────────────────────────────
|
|
54
|
+
// Date Detection
|
|
55
|
+
// ─────────────────────────────────────────────────────────────
|
|
56
|
+
const DATE_PATTERNS = [
|
|
57
|
+
{ regex: /^(0[1-9]|1[012])[-/](0[1-9]|[12]\d|3[01])[-/](\d{4})$/, options: { month: '2-digit', day: '2-digit', year: 'numeric' }, source: 'MM/DD/YYYY' },
|
|
58
|
+
{ regex: /^(0[1-9]|[12]\d|3[01])[-/](0[1-9]|1[012])[-/](\d{4})$/, options: { day: '2-digit', month: '2-digit', year: 'numeric' }, source: 'DD/MM/YYYY' },
|
|
59
|
+
{ regex: /^(\d{4})[-/](0[1-9]|1[012])[-/](0[1-9]|[12]\d|3[01])$/, options: { year: 'numeric', month: '2-digit', day: '2-digit' }, source: 'YYYY-MM-DD' },
|
|
60
|
+
{ regex: /^(0[1-9]|[12]\d|3[01])\.(0[1-9]|1[012])\.(\d{4})$/, options: { day: '2-digit', month: '2-digit', year: 'numeric' }, source: 'DD.MM.YYYY' },
|
|
61
|
+
{ regex: /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*\s+(0[1-9]|[12]\d|3[01]),\s+(\d{4})$/, options: { month: 'short', day: '2-digit', year: 'numeric' }, source: 'MMM DD, YYYY' },
|
|
62
|
+
{ regex: /^(0[1-9]|[12]\d|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*\s+(\d{4})$/, options: { day: '2-digit', month: 'short', year: 'numeric' }, source: 'DD MMM YYYY' },
|
|
63
|
+
];
|
|
64
|
+
function extractDate(raw) {
|
|
65
|
+
const trimmed = raw.trim();
|
|
66
|
+
for (const { regex, options, source } of DATE_PATTERNS) {
|
|
67
|
+
const match = trimmed.match(regex);
|
|
68
|
+
if (match) {
|
|
69
|
+
return {
|
|
70
|
+
class: 'date',
|
|
71
|
+
rawValue: trimmed,
|
|
72
|
+
originalString: trimmed,
|
|
73
|
+
confidence: 0.9,
|
|
74
|
+
dateOptions: options,
|
|
75
|
+
dateSource: source,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// ─────────────────────────────────────────────────────────────
|
|
82
|
+
// Number Detection
|
|
83
|
+
// ─────────────────────────────────────────────────────────────
|
|
84
|
+
const NUMBER_PATTERNS = [
|
|
85
|
+
/^-?\d{1,3}(?:,\d{3})+(?:\.\d+)?$/,
|
|
86
|
+
/^-?\d{1,3}(?:\.\d{3})+(?:,\d+)?$/,
|
|
87
|
+
/^-?\d+(?:\.\d+)?$/,
|
|
88
|
+
];
|
|
89
|
+
function extractNumber(raw) {
|
|
90
|
+
const trimmed = raw.trim();
|
|
91
|
+
if (!NUMBER_PATTERNS.some((p) => p.test(trimmed)))
|
|
92
|
+
return null;
|
|
93
|
+
const hasDotDecimal = /\.\d+$/.test(trimmed);
|
|
94
|
+
const hasCommaDecimal = /,\d+$/.test(trimmed);
|
|
95
|
+
const numberOptions = {};
|
|
96
|
+
if (hasDotDecimal || hasCommaDecimal) {
|
|
97
|
+
numberOptions.minimumFractionDigits = 0;
|
|
98
|
+
numberOptions.maximumFractionDigits = 10;
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
class: 'number',
|
|
102
|
+
rawValue: trimmed,
|
|
103
|
+
originalString: trimmed,
|
|
104
|
+
confidence: 0.75,
|
|
105
|
+
numberOptions: Object.keys(numberOptions).length > 0 ? numberOptions : undefined,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// ─────────────────────────────────────────────────────────────
|
|
109
|
+
// Dispatch
|
|
110
|
+
// ─────────────────────────────────────────────────────────────
|
|
111
|
+
function detectFormat(text) {
|
|
112
|
+
if (!text || text.length < 2)
|
|
113
|
+
return null;
|
|
114
|
+
const trimmed = text.trim();
|
|
115
|
+
const dateResult = extractDate(trimmed);
|
|
116
|
+
if (dateResult)
|
|
117
|
+
return dateResult;
|
|
118
|
+
const currencyResult = extractCurrency(trimmed);
|
|
119
|
+
if (currencyResult)
|
|
120
|
+
return currencyResult;
|
|
121
|
+
const numberResult = extractNumber(trimmed);
|
|
122
|
+
if (numberResult)
|
|
123
|
+
return numberResult;
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask Django Template Language tags with private-use sentinels
|
|
3
|
+
* so node-html-parser treats them as opaque text.
|
|
4
|
+
*
|
|
5
|
+
* Handles: {% %}, {{ }}, {# #}
|
|
6
|
+
*
|
|
7
|
+
* After masking, the HTML can be safely parsed by node-html-parser
|
|
8
|
+
* and run through the standard HTML injection pipeline.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Mask DTL template tags in content.
|
|
12
|
+
* Returns the masked string and a restore function to undo masking.
|
|
13
|
+
*/
|
|
14
|
+
export declare function maskTemplateTags(content: string): {
|
|
15
|
+
masked: string;
|
|
16
|
+
restore: (masked: string) => string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Check if content contains any Django template tags.
|
|
20
|
+
*/
|
|
21
|
+
export declare function hasTemplateTags(content: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Extract all DTL template tags from content for inspection.
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractTemplateTags(content: string): string[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mask Django Template Language tags with private-use sentinels
|
|
4
|
+
* so node-html-parser treats them as opaque text.
|
|
5
|
+
*
|
|
6
|
+
* Handles: {% %}, {{ }}, {# #}
|
|
7
|
+
*
|
|
8
|
+
* After masking, the HTML can be safely parsed by node-html-parser
|
|
9
|
+
* and run through the standard HTML injection pipeline.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.maskTemplateTags = maskTemplateTags;
|
|
13
|
+
exports.hasTemplateTags = hasTemplateTags;
|
|
14
|
+
exports.extractTemplateTags = extractTemplateTags;
|
|
15
|
+
// Unicode Private Use Area block tag characters used as sentinels
|
|
16
|
+
const BLOCK_START = '\uE000';
|
|
17
|
+
const BLOCK_END = '\uE001';
|
|
18
|
+
/**
|
|
19
|
+
* Mask DTL template tags in content.
|
|
20
|
+
* Returns the masked string and a restore function to undo masking.
|
|
21
|
+
*/
|
|
22
|
+
function maskTemplateTags(content) {
|
|
23
|
+
const replacements = [];
|
|
24
|
+
let counter = 0;
|
|
25
|
+
// Unified pattern for {% %}, {{ }}, {# #}
|
|
26
|
+
// Match opening braces with space-or-tag or closing braces with space-or-tag
|
|
27
|
+
const tagPattern = /(\{%.*?%\}|\{\{.*?\}\}|\{#.*?#\})/gs;
|
|
28
|
+
const masked = content.replace(tagPattern, (match) => {
|
|
29
|
+
const sentinel = `${BLOCK_START}${counter}${BLOCK_END}`;
|
|
30
|
+
replacements.push({ sentinel, original: match });
|
|
31
|
+
counter++;
|
|
32
|
+
return sentinel;
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
masked,
|
|
36
|
+
restore: (maskedContent) => {
|
|
37
|
+
let restored = maskedContent;
|
|
38
|
+
for (const { sentinel, original } of replacements) {
|
|
39
|
+
// Escape sentinel for safe use in regex replacement
|
|
40
|
+
restored = restored.split(sentinel).join(original);
|
|
41
|
+
}
|
|
42
|
+
return restored;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if content contains any Django template tags.
|
|
48
|
+
*/
|
|
49
|
+
function hasTemplateTags(content) {
|
|
50
|
+
return /\{%.*?%\}|\{\{.*?\}\}|\{#.*?#\}/s.test(content);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract all DTL template tags from content for inspection.
|
|
54
|
+
*/
|
|
55
|
+
function extractTemplateTags(content) {
|
|
56
|
+
const tagPattern = /\{%.*?%\}|\{\{.*?\}\}|\{#.*?#\}/gs;
|
|
57
|
+
return content.match(tagPattern) || [];
|
|
58
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WorkspaceInfo } from '../runtime/types';
|
|
2
|
+
/**
|
|
3
|
+
* How a run treats ICU, resolved once from the project and the translator
|
|
4
|
+
* and shared by extraction, translation and the sync detector, so they agree.
|
|
5
|
+
*/
|
|
6
|
+
export interface ResolvedIcuOptions {
|
|
7
|
+
/** Group JSX sentences into one message (needs ICU placeholders at runtime for react-i18next). */
|
|
8
|
+
sentences: boolean;
|
|
9
|
+
/** Generate ICU plurals in source sentences ("{count, plural, …}"): ICU runtime + LLM translator. */
|
|
10
|
+
plurals: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The project's runtime formats ICU messages: next-intl, or react-i18next
|
|
13
|
+
* with i18next-icu. Not vue-i18n, the vanilla runtime or static HTML.
|
|
14
|
+
*/
|
|
15
|
+
icuRuntime: boolean;
|
|
16
|
+
/** A translation may add an ICU plural over a count (`{files} files`): ICU runtime + LLM translator. */
|
|
17
|
+
targetPlurals: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @param llm the run's translator is an LLM (BYOK or an injected provider);
|
|
21
|
+
* the NLLB service can't translate ICU plural messages.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveIcuOptions(workspace: WorkspaceInfo, llm: boolean): Promise<ResolvedIcuOptions>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveIcuOptions = resolveIcuOptions;
|
|
4
|
+
const StrategyFactory_1 = require("../injection/StrategyFactory");
|
|
5
|
+
const i18next_icu_1 = require("./i18next-icu");
|
|
6
|
+
/**
|
|
7
|
+
* @param llm the run's translator is an LLM (BYOK or an injected provider);
|
|
8
|
+
* the NLLB service can't translate ICU plural messages.
|
|
9
|
+
*/
|
|
10
|
+
async function resolveIcuOptions(workspace, llm) {
|
|
11
|
+
const deps = { ...workspace.packageJson?.dependencies, ...workspace.packageJson?.devDependencies };
|
|
12
|
+
const strategy = ['react', 'nextjs'].includes(workspace.framework) ? StrategyFactory_1.StrategyFactory.getStrategy(workspace.framework, deps).id : 'other';
|
|
13
|
+
let icuRuntime = false;
|
|
14
|
+
let sentences = true;
|
|
15
|
+
if (strategy === 'next-intl') {
|
|
16
|
+
icuRuntime = true;
|
|
17
|
+
}
|
|
18
|
+
else if (strategy === 'react-i18next') {
|
|
19
|
+
icuRuntime = (await (0, i18next_icu_1.detectI18nextIcu)(workspace)).available;
|
|
20
|
+
sentences = icuRuntime;
|
|
21
|
+
}
|
|
22
|
+
return { sentences, plurals: icuRuntime && llm, icuRuntime, targetPlurals: icuRuntime && llm };
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare function clearFindFilesCache(): void;
|
|
2
|
+
export declare function readFile(filePath: string): Promise<string>;
|
|
3
|
+
export declare function writeFile(filePath: string, content: string, allowedBaseDir?: string): Promise<void>;
|
|
4
|
+
export declare function pathExists(filePath: string): Promise<boolean>;
|
|
5
|
+
export declare function isDirectory(filePath: string): Promise<boolean>;
|
|
6
|
+
export declare function findFiles(dir: string, extensions: string[], excludePatterns?: string[]): Promise<string[]>;
|
|
7
|
+
export declare function getRelativePath(workspacePath: string, filePath: string): string;
|
|
8
|
+
export declare function readJsonFile<T = any>(filePath: string): Promise<T | null>;
|
|
9
|
+
export declare function writeJsonFile(filePath: string, data: any, sortKeys?: boolean): Promise<void>;
|
|
10
|
+
export declare function localeExtension(format: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Compute the locale directory and file path for a given target locale.
|
|
13
|
+
* Django uses `locale/<lang>/LC_MESSAGES/django.po`,
|
|
14
|
+
* other frameworks use `<publicDir>/locales/<lang>.json`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function localeFilePath(workspacePath: string, publicDir: string, localeFormat: string, targetLocale: string): {
|
|
17
|
+
dir: string;
|
|
18
|
+
file: string;
|
|
19
|
+
relativeFile: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
22
|
+
export declare function copyFile(src: string, dest: string): Promise<void>;
|
|
23
|
+
export declare function deleteFile(filePath: string): Promise<void>;
|
|
24
|
+
export declare function readDir(dirPath: string): Promise<string[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Process items with bounded concurrency.
|
|
27
|
+
* Unlike Promise.all, this limits the number of concurrent operations.
|
|
28
|
+
* Errors are collected and returned alongside results.
|
|
29
|
+
*/
|
|
30
|
+
export declare function concurrentMap<T, R>(items: T[], fn: (item: T, index: number) => Promise<R>, concurrency: number): Promise<{
|
|
31
|
+
results: R[];
|
|
32
|
+
errors: Error[];
|
|
33
|
+
}>;
|