@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.
- 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/detection/stack.d.ts +42 -0
- package/dist/detection/stack.js +277 -0
- package/dist/django/catalog.d.ts +92 -0
- package/dist/django/catalog.js +677 -0
- package/dist/django/extract.d.ts +20 -0
- package/dist/django/extract.js +79 -0
- package/dist/django/inject-file.d.ts +6 -0
- package/dist/django/inject-file.js +52 -0
- package/dist/django/inject.d.ts +11 -0
- package/dist/django/inject.js +205 -0
- package/dist/django/keys.d.ts +21 -0
- package/dist/django/keys.js +63 -0
- package/dist/django/locale-names.d.ts +13 -0
- package/dist/django/locale-names.js +60 -0
- package/dist/django/mo-file.d.ts +6 -0
- package/dist/django/mo-file.js +60 -0
- package/dist/django/plural-forms.d.ts +34 -0
- package/dist/django/plural-forms.js +216 -0
- package/dist/django/po-file.d.ts +38 -0
- package/dist/django/po-file.js +273 -0
- package/dist/django/python-extract.d.ts +34 -0
- package/dist/django/python-extract.js +619 -0
- package/dist/django/python-lexer.d.ts +65 -0
- package/dist/django/python-lexer.js +398 -0
- package/dist/django/template-extract.d.ts +32 -0
- package/dist/django/template-extract.js +680 -0
- package/dist/django/types.d.ts +49 -0
- package/dist/django/types.js +15 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +140 -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/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 +208 -0
- package/dist/local/report.d.ts +177 -0
- package/dist/local/report.js +186 -0
- package/dist/local/translate-core.d.ts +218 -0
- package/dist/local/translate-core.js +499 -0
- package/dist/local/translate-messages.d.ts +49 -0
- package/dist/local/translate-messages.js +89 -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 +709 -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 +28 -0
- package/dist/modules/finalization/django-finalize.js +412 -0
- package/dist/modules/finalization/finalize.d.ts +38 -0
- package/dist/modules/finalization/finalize.js +745 -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 +40 -0
- package/dist/modules/finalization/nextjs-finalize.js +328 -0
- package/dist/modules/finalization/static-runtime.d.ts +9 -0
- package/dist/modules/finalization/static-runtime.js +261 -0
- package/dist/modules/finalization/writes.d.ts +29 -0
- package/dist/modules/finalization/writes.js +78 -0
- package/dist/modules/format-injection/index.d.ts +19 -0
- package/dist/modules/format-injection/index.js +273 -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/index.d.ts +2 -0
- package/dist/modules/glossary/index.js +16 -0
- package/dist/modules/glossary/rules.d.ts +81 -0
- package/dist/modules/glossary/rules.js +244 -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 +1050 -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 +123 -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 +130 -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 +22 -0
- package/dist/modules/lockfile/lockfile-manager.d.ts +99 -0
- package/dist/modules/lockfile/lockfile-manager.js +497 -0
- package/dist/modules/lockfile/schema.d.ts +196 -0
- package/dist/modules/lockfile/schema.js +56 -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/icu-branches.d.ts +138 -0
- package/dist/modules/translator/icu-branches.js +393 -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 +74 -0
- package/dist/modules/translator/translate.js +1047 -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 +333 -0
- package/dist/orchestrator.d.ts +13 -0
- package/dist/orchestrator.js +727 -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 +153 -0
- package/dist/providers/types.js +2 -0
- package/dist/qa/check-project.d.ts +50 -0
- package/dist/qa/check-project.js +193 -0
- package/dist/qa/gettext-files.d.ts +15 -0
- package/dist/qa/gettext-files.js +115 -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 +342 -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 +37 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/types.d.ts +427 -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/extraction-options.d.ts +29 -0
- package/dist/utils/extraction-options.js +33 -0
- package/dist/utils/file-utils.d.ts +33 -0
- package/dist/utils/file-utils.js +267 -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 +628 -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 +82 -0
- package/dist/utils/metadata.js +261 -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 +38 -0
- package/dist/utils/placeholder-protection.d.ts +74 -0
- package/dist/utils/placeholder-protection.js +181 -0
- package/dist/utils/pseudo-markers.d.ts +9 -0
- package/dist/utils/pseudo-markers.js +16 -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 +11 -0
- package/dist/utils/translation-sanitizer.js +71 -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 +297 -0
- package/dist/utils/ui-copy.d.ts +32 -0
- package/dist/utils/ui-copy.js +126 -0
- package/dist/utils/untranslated.d.ts +15 -0
- package/dist/utils/untranslated.js +34 -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,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* What a repository is built with — framework and package manager — from its
|
|
4
|
+
* file list and a few small files. Works on a local directory and on a
|
|
5
|
+
* remote listing (the GitHub tree API), so the dashboard can refuse an
|
|
6
|
+
* unsupported repository before a project is created instead of letting the
|
|
7
|
+
* first run fail.
|
|
8
|
+
*
|
|
9
|
+
* Supported signals always win over unsupported ones (a Laravel app whose UI
|
|
10
|
+
* is React is a React project for Babelize). An unsupported stack is only
|
|
11
|
+
* reported when nothing Babelize can translate was found.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
47
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.FRAMEWORK_DISPLAY_NAMES = void 0;
|
|
51
|
+
exports.mentionsPythonPackage = mentionsPythonPackage;
|
|
52
|
+
exports.detectPackageManagers = detectPackageManagers;
|
|
53
|
+
exports.detectStack = detectStack;
|
|
54
|
+
exports.localRepoFiles = localRepoFiles;
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
58
|
+
exports.FRAMEWORK_DISPLAY_NAMES = {
|
|
59
|
+
react: 'React', nextjs: 'Next.js', vue: 'Vue', static: 'HTML/CSS/JS', django: 'Django', unknown: 'Unknown',
|
|
60
|
+
};
|
|
61
|
+
const IGNORED_DIR = /(?:^|\/)(?:node_modules|\.git|venv|\.venv|env|site-packages|vendor|dist|build|\.next|__pycache__)\//;
|
|
62
|
+
function depth(p) {
|
|
63
|
+
return p.split('/').length - 1;
|
|
64
|
+
}
|
|
65
|
+
/** Does a Python dependency file list Django itself (not just django-* add-ons)? */
|
|
66
|
+
function mentionsPythonPackage(content, pkg) {
|
|
67
|
+
const name = pkg.replace(/[-_]/g, '[-_]');
|
|
68
|
+
// requirements.txt lines, pyproject/Pipfile/setup.py entries: django>=4, "Django (>=4)", django = "*"
|
|
69
|
+
const re = new RegExp(`(?:^|["'\\s,\\[(])${name}\\s*(?:\\[[^\\]]*\\])?\\s*(?:[<>=~!;"',)\\]]|\\(|$)`, 'im');
|
|
70
|
+
return re.test(content);
|
|
71
|
+
}
|
|
72
|
+
function jsFramework(pkg) {
|
|
73
|
+
if (!pkg)
|
|
74
|
+
return { id: 'unknown' };
|
|
75
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
76
|
+
if (deps['next'])
|
|
77
|
+
return { id: 'nextjs' };
|
|
78
|
+
if (deps['nuxt'] || deps['vue'])
|
|
79
|
+
return { id: 'vue' };
|
|
80
|
+
if (deps['react'] || deps['gatsby'] || deps['@remix-run/react'] || deps['astro'] || deps['react-dom'] || deps['react-scripts'])
|
|
81
|
+
return { id: 'react' };
|
|
82
|
+
if (deps['@angular/core'])
|
|
83
|
+
return { id: 'angular' };
|
|
84
|
+
if (deps['svelte'] || deps['@sveltejs/kit'])
|
|
85
|
+
return { id: 'svelte' };
|
|
86
|
+
if (deps['solid-js'])
|
|
87
|
+
return { id: 'solid' };
|
|
88
|
+
if (deps['ember-source'] || deps['ember-cli'])
|
|
89
|
+
return { id: 'ember' };
|
|
90
|
+
return { id: 'unknown' };
|
|
91
|
+
}
|
|
92
|
+
const UNSUPPORTED_NAMES = {
|
|
93
|
+
angular: 'Angular', svelte: 'Svelte', solid: 'SolidJS', ember: 'Ember', laravel: 'Laravel', symfony: 'Symfony',
|
|
94
|
+
wordpress: 'WordPress', php: 'PHP', rails: 'Ruby on Rails', jekyll: 'Jekyll', ruby: 'Ruby', flutter: 'Flutter',
|
|
95
|
+
dart: 'Dart', flask: 'Flask', fastapi: 'FastAPI', python: 'Python', go: 'Go', rust: 'Rust', android: 'Android',
|
|
96
|
+
java: 'Java', kotlin: 'Kotlin', dotnet: '.NET', ios: 'iOS (Swift)', elixir: 'Elixir/Phoenix', hugo: 'Hugo',
|
|
97
|
+
};
|
|
98
|
+
async function readJson(files, p) {
|
|
99
|
+
const raw = await files.read(p);
|
|
100
|
+
if (!raw)
|
|
101
|
+
return null;
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(raw);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function detectPackageManagers(paths, pyproject, preferPython) {
|
|
110
|
+
const js = [];
|
|
111
|
+
if (paths.has('bun.lockb') || paths.has('bun.lock'))
|
|
112
|
+
js.push('bun');
|
|
113
|
+
if (paths.has('pnpm-lock.yaml'))
|
|
114
|
+
js.push('pnpm');
|
|
115
|
+
if (paths.has('yarn.lock'))
|
|
116
|
+
js.push('yarn');
|
|
117
|
+
if (paths.has('package-lock.json'))
|
|
118
|
+
js.push('npm');
|
|
119
|
+
if (js.length === 0 && paths.has('package.json'))
|
|
120
|
+
js.push('npm');
|
|
121
|
+
const py = [];
|
|
122
|
+
if (paths.has('uv.lock'))
|
|
123
|
+
py.push('uv');
|
|
124
|
+
if (paths.has('poetry.lock') || (pyproject && /^\s*\[tool\.poetry\]/m.test(pyproject)))
|
|
125
|
+
py.push('poetry');
|
|
126
|
+
if (paths.has('Pipfile') || paths.has('Pipfile.lock'))
|
|
127
|
+
py.push('pipenv');
|
|
128
|
+
if (paths.has('pdm.lock'))
|
|
129
|
+
py.push('pdm');
|
|
130
|
+
const hasRequirements = [...paths].some((p) => /^requirements[^/]*\.txt$/.test(p) || /^requirements\/[^/]+\.txt$/.test(p));
|
|
131
|
+
if (hasRequirements || ((paths.has('pyproject.toml') || paths.has('setup.py') || paths.has('setup.cfg')) && py.length === 0))
|
|
132
|
+
py.push('pip');
|
|
133
|
+
return preferPython ? [...py, ...js] : [...js, ...py];
|
|
134
|
+
}
|
|
135
|
+
async function detectStack(files) {
|
|
136
|
+
const paths = files.paths.filter((p) => !IGNORED_DIR.test(`${p}`));
|
|
137
|
+
const set = new Set(paths);
|
|
138
|
+
const has = (p) => set.has(p);
|
|
139
|
+
const pyproject = has('pyproject.toml') ? await files.read('pyproject.toml') : null;
|
|
140
|
+
const result = (framework, preferPython = false) => ({
|
|
141
|
+
framework,
|
|
142
|
+
name: exports.FRAMEWORK_DISPLAY_NAMES[framework],
|
|
143
|
+
supported: framework !== 'unknown',
|
|
144
|
+
packageManagers: detectPackageManagers(set, pyproject, preferPython),
|
|
145
|
+
});
|
|
146
|
+
const unsupported = (id, preferPython = false) => {
|
|
147
|
+
const name = UNSUPPORTED_NAMES[id] ?? id;
|
|
148
|
+
return {
|
|
149
|
+
framework: 'unknown',
|
|
150
|
+
name,
|
|
151
|
+
supported: false,
|
|
152
|
+
unsupported: { id, name },
|
|
153
|
+
packageManagers: detectPackageManagers(set, pyproject, preferPython),
|
|
154
|
+
message: `${name} isn't supported yet. Babelize supports React, Next.js, Vue, Django and plain HTML/CSS/JS projects.`,
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
// 1. Django at the root.
|
|
158
|
+
if (has('manage.py'))
|
|
159
|
+
return result('django', true);
|
|
160
|
+
// 2. A JS framework at the root.
|
|
161
|
+
const rootPkg = has('package.json') ? await readJson(files, 'package.json') : null;
|
|
162
|
+
const rootJs = jsFramework(rootPkg);
|
|
163
|
+
if (rootJs.id === 'nextjs' || rootJs.id === 'vue' || rootJs.id === 'react')
|
|
164
|
+
return result(rootJs.id);
|
|
165
|
+
// 3. Django deeper in the tree, or declared as a dependency.
|
|
166
|
+
const pyDepFiles = ['requirements.txt', 'requirements/base.txt', 'requirements/prod.txt', 'requirements/production.txt', 'Pipfile', 'setup.py', 'setup.cfg']
|
|
167
|
+
.filter(has);
|
|
168
|
+
const pyDeps = [pyproject ?? '', ...(await Promise.all(pyDepFiles.map((p) => files.read(p)))).map((c) => c ?? '')].join('\n');
|
|
169
|
+
const managePy = paths.filter((p) => p.endsWith('/manage.py') && depth(p) <= 3).sort((a, b) => depth(a) - depth(b));
|
|
170
|
+
if (managePy.length > 0 || mentionsPythonPackage(pyDeps, 'django'))
|
|
171
|
+
return result('django', true);
|
|
172
|
+
// 4. A JS framework in a workspace package or first-level subdirectory.
|
|
173
|
+
const subPkgs = paths.filter((p) => p.endsWith('/package.json') && depth(p) <= 2).slice(0, 25);
|
|
174
|
+
for (const p of subPkgs) {
|
|
175
|
+
const sub = jsFramework(await readJson(files, p));
|
|
176
|
+
if (sub.id === 'nextjs' || sub.id === 'vue' || sub.id === 'react')
|
|
177
|
+
return result(sub.id);
|
|
178
|
+
}
|
|
179
|
+
// 5. Unsupported stacks with a clear signal.
|
|
180
|
+
if (rootJs.id !== 'unknown')
|
|
181
|
+
return unsupported(rootJs.id);
|
|
182
|
+
for (const p of subPkgs) {
|
|
183
|
+
const sub = jsFramework(await readJson(files, p));
|
|
184
|
+
if (sub.id !== 'unknown')
|
|
185
|
+
return unsupported(sub.id);
|
|
186
|
+
}
|
|
187
|
+
if (has('artisan'))
|
|
188
|
+
return unsupported('laravel');
|
|
189
|
+
if (has('composer.json')) {
|
|
190
|
+
const composer = (await files.read('composer.json')) ?? '';
|
|
191
|
+
if (/laravel\/framework/.test(composer))
|
|
192
|
+
return unsupported('laravel');
|
|
193
|
+
if (/symfony\/(?:framework-bundle|symfony)/.test(composer))
|
|
194
|
+
return unsupported('symfony');
|
|
195
|
+
}
|
|
196
|
+
if (has('wp-config.php') || has('wp-config-sample.php') || paths.some((p) => p.startsWith('wp-content/')))
|
|
197
|
+
return unsupported('wordpress');
|
|
198
|
+
if (has('Gemfile')) {
|
|
199
|
+
const gemfile = (await files.read('Gemfile')) ?? '';
|
|
200
|
+
if (/gem\s+['"]rails['"]/.test(gemfile) || has('config/routes.rb'))
|
|
201
|
+
return unsupported('rails');
|
|
202
|
+
if (/gem\s+['"]jekyll['"]/.test(gemfile))
|
|
203
|
+
return unsupported('jekyll');
|
|
204
|
+
}
|
|
205
|
+
if (has('pubspec.yaml')) {
|
|
206
|
+
const pubspec = (await files.read('pubspec.yaml')) ?? '';
|
|
207
|
+
return unsupported(/^\s*flutter\s*:/m.test(pubspec) ? 'flutter' : 'dart');
|
|
208
|
+
}
|
|
209
|
+
if (mentionsPythonPackage(pyDeps, 'flask'))
|
|
210
|
+
return unsupported('flask', true);
|
|
211
|
+
if (mentionsPythonPackage(pyDeps, 'fastapi'))
|
|
212
|
+
return unsupported('fastapi', true);
|
|
213
|
+
if (paths.some((p) => /(?:^|\/)AndroidManifest\.xml$/.test(p)))
|
|
214
|
+
return unsupported('android');
|
|
215
|
+
if (has('Package.swift') || paths.some((p) => /\.xcodeproj\//.test(p)))
|
|
216
|
+
return unsupported('ios');
|
|
217
|
+
if (has('hugo.toml') || (has('config.toml') && paths.some((p) => p.startsWith('layouts/'))))
|
|
218
|
+
return unsupported('hugo');
|
|
219
|
+
// 6. Plain HTML — unless every page is a server template.
|
|
220
|
+
const html = paths.filter((p) => /\.html?$/i.test(p) && depth(p) <= 6);
|
|
221
|
+
if (html.length > 0) {
|
|
222
|
+
const sample = await Promise.all(html.slice(0, 10).map((p) => files.read(p)));
|
|
223
|
+
if (!sample.some((c) => c && /\{%|<\?php|<%=/.test(c)))
|
|
224
|
+
return result('static');
|
|
225
|
+
}
|
|
226
|
+
// 7. Other languages (a static site served by them would have matched above).
|
|
227
|
+
if (has('Gemfile'))
|
|
228
|
+
return unsupported('ruby');
|
|
229
|
+
if (has('mix.exs'))
|
|
230
|
+
return unsupported('elixir');
|
|
231
|
+
if (has('go.mod'))
|
|
232
|
+
return unsupported('go');
|
|
233
|
+
if (has('Cargo.toml'))
|
|
234
|
+
return unsupported('rust');
|
|
235
|
+
if (paths.some((p) => /\.(?:csproj|sln|fsproj)$/.test(p)))
|
|
236
|
+
return unsupported('dotnet');
|
|
237
|
+
if (has('pom.xml') || has('build.gradle') || has('build.gradle.kts'))
|
|
238
|
+
return unsupported(has('build.gradle.kts') ? 'kotlin' : 'java');
|
|
239
|
+
if (has('composer.json') || paths.some((p) => p.endsWith('.php')))
|
|
240
|
+
return unsupported('php');
|
|
241
|
+
if (pyDeps.trim() || paths.some((p) => p.endsWith('.py')))
|
|
242
|
+
return unsupported('python', true);
|
|
243
|
+
return {
|
|
244
|
+
framework: 'unknown',
|
|
245
|
+
name: 'Unknown',
|
|
246
|
+
supported: false,
|
|
247
|
+
packageManagers: detectPackageManagers(set, pyproject, false),
|
|
248
|
+
message: files.truncated
|
|
249
|
+
? "This repository is too large to inspect before creating the project."
|
|
250
|
+
: 'No React, Next.js, Vue, Django or HTML files were found in this repository.',
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/** RepoFiles for a local directory. */
|
|
254
|
+
async function localRepoFiles(dir) {
|
|
255
|
+
const paths = await (0, fast_glob_1.default)('**/*', {
|
|
256
|
+
cwd: dir,
|
|
257
|
+
onlyFiles: true,
|
|
258
|
+
dot: true,
|
|
259
|
+
deep: 7,
|
|
260
|
+
ignore: ['**/node_modules/**', '**/.git/**', '**/venv/**', '**/.venv/**', '**/site-packages/**', '**/__pycache__/**'],
|
|
261
|
+
});
|
|
262
|
+
return {
|
|
263
|
+
paths,
|
|
264
|
+
read: async (rel) => {
|
|
265
|
+
try {
|
|
266
|
+
const full = path.join(dir, rel);
|
|
267
|
+
const stat = await fs.promises.stat(full);
|
|
268
|
+
if (stat.size > 512 * 1024)
|
|
269
|
+
return null;
|
|
270
|
+
return await fs.promises.readFile(full, 'utf8');
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The gettext catalogue of a Django run: which messages the code uses, the
|
|
3
|
+
* existing translations in the project's .po files, and the merged .po (and,
|
|
4
|
+
* when the project commits them, .mo) files the run writes.
|
|
5
|
+
*
|
|
6
|
+
* Existing translations are the project's: a complete, non-fuzzy msgstr is
|
|
7
|
+
* never overwritten and never re-translated (it seeds the lockfile instead).
|
|
8
|
+
* Fuzzy entries are left for review. Only missing or empty entries are
|
|
9
|
+
* filled. Untouched entries are written back byte-for-byte.
|
|
10
|
+
*/
|
|
11
|
+
import type { ExtractedString, GeneratedKey, GettextInfo, InjectionResult, LocaleFile, TranslationResult, WorkspaceInfo } from '../runtime/types';
|
|
12
|
+
import type { LockfileData } from '../modules/lockfile/schema';
|
|
13
|
+
export interface CatalogEntry {
|
|
14
|
+
message: GettextInfo;
|
|
15
|
+
references: string[];
|
|
16
|
+
/** Engine keys by form. */
|
|
17
|
+
keys: {
|
|
18
|
+
single?: string;
|
|
19
|
+
icu?: string;
|
|
20
|
+
singular?: string;
|
|
21
|
+
plural?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface GettextWriteResult {
|
|
25
|
+
locales: LocaleFile[];
|
|
26
|
+
notes: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Why a translated form would fail `msgfmt --check-format` (and break
|
|
30
|
+
* `compilemessages`), or null if it's fine.
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatProblem(source: string, translated: string, flags: string[], allowDroppingCount: boolean, union?: string): string | null;
|
|
33
|
+
export declare class GettextCatalog {
|
|
34
|
+
private readonly workspace;
|
|
35
|
+
readonly entries: CatalogEntry[];
|
|
36
|
+
private readonly byKey;
|
|
37
|
+
private readonly states;
|
|
38
|
+
private constructor();
|
|
39
|
+
/** Build the run's catalogue and read the existing .po file of every target locale. */
|
|
40
|
+
static create(workspace: WorkspaceInfo, strings: ExtractedString[], keys: GeneratedKey[], targetLocales: string[]): Promise<GettextCatalog>;
|
|
41
|
+
/** The Django project's name: the package of its settings module (from manage.py). */
|
|
42
|
+
private projectName;
|
|
43
|
+
private loadLocale;
|
|
44
|
+
private existingEntry;
|
|
45
|
+
/**
|
|
46
|
+
* Translations already in the .po files, by engine key: they count as done
|
|
47
|
+
* (seeded into the lockfile) so they are neither re-translated nor billed.
|
|
48
|
+
*/
|
|
49
|
+
existingTranslations(locale: string): Record<string, string>;
|
|
50
|
+
/**
|
|
51
|
+
* For each ICU-plural key: the placeholder that shows the count in its
|
|
52
|
+
* branches (`%(count)d`, or a lone `%d`). A plain-text translator gets a
|
|
53
|
+
* number of each plural category in its place, so every gettext form is
|
|
54
|
+
* inflected for its own numbers.
|
|
55
|
+
*/
|
|
56
|
+
pluralValuePlaceholders(): Record<string, string>;
|
|
57
|
+
/** Put existing .po translations into the lockfile (they win over its cached values). */
|
|
58
|
+
seedLockfile(lockfile: LockfileData, flatKeys: Record<string, string>): LockfileData;
|
|
59
|
+
/**
|
|
60
|
+
* msgstr forms for an entry from the run's translations, or a reason it
|
|
61
|
+
* can't have them yet (null when simply untranslated).
|
|
62
|
+
*/
|
|
63
|
+
formsFor(entry: CatalogEntry, locale: string, values: Record<string, string>): {
|
|
64
|
+
forms: string[];
|
|
65
|
+
} | {
|
|
66
|
+
problem: string;
|
|
67
|
+
key: string;
|
|
68
|
+
} | null;
|
|
69
|
+
/**
|
|
70
|
+
* Check every fresh translation can go into a .po file that compiles:
|
|
71
|
+
* placeholders must match the source (msgfmt --check-format), plurals must
|
|
72
|
+
* map onto the language's forms. Bad values are removed and reported as
|
|
73
|
+
* failures (and retried next run) — never shipped, never replaced by the
|
|
74
|
+
* source text.
|
|
75
|
+
*/
|
|
76
|
+
validate(translation: TranslationResult, sourceValues: Record<string, string>): void;
|
|
77
|
+
/** Point references at where strings are after injection (lines move when imports/tags are added). */
|
|
78
|
+
refreshReferences(injection: InjectionResult): void;
|
|
79
|
+
/**
|
|
80
|
+
* Merge the run's translations into each target locale's .po file.
|
|
81
|
+
* Returns LocaleFiles carrying the exact content (and .mo when the project
|
|
82
|
+
* commits compiled catalogues); writes them unless `dryRun`.
|
|
83
|
+
*/
|
|
84
|
+
write(targetLocales: string[], valuesByLocale: Record<string, Record<string, string>>, options: {
|
|
85
|
+
dryRun: boolean;
|
|
86
|
+
pseudo: boolean;
|
|
87
|
+
now?: Date;
|
|
88
|
+
projectName?: string;
|
|
89
|
+
}): Promise<GettextWriteResult>;
|
|
90
|
+
}
|
|
91
|
+
/** PO date format: 2026-10-10 14:03+0000 */
|
|
92
|
+
export declare function formatPoDate(d: Date): string;
|