@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,25 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { InjectionStrategy, InjectionContext, MessageRendering } from '../InjectionStrategy';
|
|
3
|
+
import { type JsxMessage } from '../../utils/jsx-message';
|
|
4
|
+
export declare class NextIntlStrategy implements InjectionStrategy {
|
|
5
|
+
id: string;
|
|
6
|
+
hasImport(ast: t.File): boolean;
|
|
7
|
+
createImport(context: InjectionContext): t.ImportDeclaration;
|
|
8
|
+
hasHook(componentPath: any): boolean;
|
|
9
|
+
createHook(context: InjectionContext): t.Statement[];
|
|
10
|
+
getTranslationFunctionName(): string;
|
|
11
|
+
/**
|
|
12
|
+
* `{t("key", { user })}`, or with inline elements
|
|
13
|
+
* `{t.rich("key", { user, link: (chunks) => <Link href="/x">{chunks}</Link> })}`
|
|
14
|
+
* for the message "Hi {user}, read the <link>terms</link>". Works with both
|
|
15
|
+
* useTranslations() and await getTranslations().
|
|
16
|
+
*/
|
|
17
|
+
createMessage(key: string, message: JsxMessage): MessageRendering;
|
|
18
|
+
/**
|
|
19
|
+
* Never. An async component can't be rendered by a Client Component, and
|
|
20
|
+
* shared UI components often are. `useTranslations()` works in Server
|
|
21
|
+
* Components and client/shared ones as long as they aren't async, so only
|
|
22
|
+
* components that are already async get `await getTranslations()`.
|
|
23
|
+
*/
|
|
24
|
+
requiresAsyncComponent(_context?: InjectionContext): boolean;
|
|
25
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
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.NextIntlStrategy = void 0;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
const jsx_message_1 = require("../../utils/jsx-message");
|
|
39
|
+
/** `await getTranslations()` only for components that are already async (and not in a 'use client' file). */
|
|
40
|
+
function usesServerApi(context) {
|
|
41
|
+
return !!context && !context.hasUseClient && context.isAsyncComponent === true;
|
|
42
|
+
}
|
|
43
|
+
class NextIntlStrategy {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.id = 'next-intl';
|
|
46
|
+
}
|
|
47
|
+
hasImport(ast) {
|
|
48
|
+
let found = false;
|
|
49
|
+
for (const node of ast.program.body) {
|
|
50
|
+
if (t.isImportDeclaration(node) && (node.source.value === 'next-intl' || node.source.value === 'next-intl/server')) {
|
|
51
|
+
const hasSpecifier = node.specifiers.some(spec => t.isImportSpecifier(spec) &&
|
|
52
|
+
t.isIdentifier(spec.imported) &&
|
|
53
|
+
(spec.imported.name === 'useTranslations' || spec.imported.name === 'getTranslations'));
|
|
54
|
+
if (hasSpecifier) {
|
|
55
|
+
found = true;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return found;
|
|
61
|
+
}
|
|
62
|
+
createImport(context) {
|
|
63
|
+
const server = usesServerApi(context);
|
|
64
|
+
const importName = server ? 'getTranslations' : 'useTranslations';
|
|
65
|
+
const importSource = server ? 'next-intl/server' : 'next-intl';
|
|
66
|
+
return t.importDeclaration([t.importSpecifier(t.identifier(importName), t.identifier(importName))], t.stringLiteral(importSource));
|
|
67
|
+
}
|
|
68
|
+
hasHook(componentPath) {
|
|
69
|
+
let found = false;
|
|
70
|
+
componentPath.traverse({
|
|
71
|
+
VariableDeclarator(path) {
|
|
72
|
+
if (path.node.init &&
|
|
73
|
+
((t.isCallExpression(path.node.init) &&
|
|
74
|
+
t.isIdentifier(path.node.init.callee) &&
|
|
75
|
+
path.node.init.callee.name === 'useTranslations') ||
|
|
76
|
+
(t.isAwaitExpression(path.node.init) &&
|
|
77
|
+
t.isCallExpression(path.node.init.argument) &&
|
|
78
|
+
t.isIdentifier(path.node.init.argument.callee) &&
|
|
79
|
+
path.node.init.argument.callee.name === 'getTranslations'))) {
|
|
80
|
+
found = true;
|
|
81
|
+
path.stop();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return found;
|
|
86
|
+
}
|
|
87
|
+
createHook(context) {
|
|
88
|
+
if (!usesServerApi(context)) {
|
|
89
|
+
// const t = useTranslations();
|
|
90
|
+
return [
|
|
91
|
+
t.variableDeclaration('const', [
|
|
92
|
+
t.variableDeclarator(t.identifier('t'), t.callExpression(t.identifier('useTranslations'), []))
|
|
93
|
+
])
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// const t = await getTranslations();
|
|
98
|
+
return [
|
|
99
|
+
t.variableDeclaration('const', [
|
|
100
|
+
t.variableDeclarator(t.identifier('t'), t.awaitExpression(t.callExpression(t.identifier('getTranslations'), [])))
|
|
101
|
+
])
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
getTranslationFunctionName() {
|
|
106
|
+
return 't';
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* `{t("key", { user })}`, or with inline elements
|
|
110
|
+
* `{t.rich("key", { user, link: (chunks) => <Link href="/x">{chunks}</Link> })}`
|
|
111
|
+
* for the message "Hi {user}, read the <link>terms</link>". Works with both
|
|
112
|
+
* useTranslations() and await getTranslations().
|
|
113
|
+
*/
|
|
114
|
+
createMessage(key, message) {
|
|
115
|
+
if (!(0, jsx_message_1.hasTags)(message))
|
|
116
|
+
return { node: t.jsxExpressionContainer((0, jsx_message_1.createMessageTCall)(key, message)) };
|
|
117
|
+
const values = (0, jsx_message_1.placeholderValues)(message);
|
|
118
|
+
const props = [];
|
|
119
|
+
for (const entry of message.entries) {
|
|
120
|
+
if (entry.kind === 'placeholder')
|
|
121
|
+
props.push(values.shift());
|
|
122
|
+
else
|
|
123
|
+
props.push((0, jsx_message_1.richTagValue)(entry));
|
|
124
|
+
}
|
|
125
|
+
const call = t.callExpression(t.memberExpression(t.identifier('t'), t.identifier('rich')), [
|
|
126
|
+
t.stringLiteral(key),
|
|
127
|
+
t.objectExpression(props),
|
|
128
|
+
]);
|
|
129
|
+
return { node: t.jsxExpressionContainer(call) };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Never. An async component can't be rendered by a Client Component, and
|
|
133
|
+
* shared UI components often are. `useTranslations()` works in Server
|
|
134
|
+
* Components and client/shared ones as long as they aren't async, so only
|
|
135
|
+
* components that are already async get `await getTranslations()`.
|
|
136
|
+
*/
|
|
137
|
+
requiresAsyncComponent(_context) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.NextIntlStrategy = NextIntlStrategy;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { InjectionStrategy, InjectionContext, MessageOptions, MessageRendering } from '../InjectionStrategy';
|
|
3
|
+
import { type JsxMessage } from '../../utils/jsx-message';
|
|
4
|
+
export declare class ReactI18nextStrategy implements InjectionStrategy {
|
|
5
|
+
id: string;
|
|
6
|
+
hasImport(ast: t.File): boolean;
|
|
7
|
+
createImport(): t.ImportDeclaration;
|
|
8
|
+
hasHook(componentPath: any): boolean;
|
|
9
|
+
createHook(_context: InjectionContext): t.Statement[];
|
|
10
|
+
getTranslationFunctionName(): string;
|
|
11
|
+
requiresAsyncComponent(_context: InjectionContext): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* `{t("key", { user })}`, or with inline elements
|
|
14
|
+
* `<Trans i18nKey="key" t={t} values={{ user }} components={{ link: <Link href="/x" /> }} />`
|
|
15
|
+
* for the message "Hi {user}, read the <link>terms</link>" (named Trans
|
|
16
|
+
* components; placeholders are ICU arguments, rendered by i18next-icu).
|
|
17
|
+
*/
|
|
18
|
+
createMessage(key: string, message: JsxMessage, options?: MessageOptions): MessageRendering;
|
|
19
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
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.ReactI18nextStrategy = void 0;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
const jsx_message_1 = require("../../utils/jsx-message");
|
|
39
|
+
class ReactI18nextStrategy {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.id = 'react-i18next';
|
|
42
|
+
}
|
|
43
|
+
hasImport(ast) {
|
|
44
|
+
let found = false;
|
|
45
|
+
// We cannot use traverse easily here without passing it or doing manual loop.
|
|
46
|
+
// It's better to implement this using a basic AST scan. Let's rely on standard search
|
|
47
|
+
for (const node of ast.program.body) {
|
|
48
|
+
if (t.isImportDeclaration(node) && node.source.value === 'react-i18next') {
|
|
49
|
+
const hasSpecifier = node.specifiers.some(spec => t.isImportSpecifier(spec) &&
|
|
50
|
+
t.isIdentifier(spec.imported) &&
|
|
51
|
+
spec.imported.name === 'useTranslation');
|
|
52
|
+
if (hasSpecifier) {
|
|
53
|
+
found = true;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return found;
|
|
59
|
+
}
|
|
60
|
+
createImport() {
|
|
61
|
+
return t.importDeclaration([t.importSpecifier(t.identifier('useTranslation'), t.identifier('useTranslation'))], t.stringLiteral('react-i18next'));
|
|
62
|
+
}
|
|
63
|
+
hasHook(componentPath) {
|
|
64
|
+
let found = false;
|
|
65
|
+
componentPath.traverse({
|
|
66
|
+
VariableDeclarator(path) {
|
|
67
|
+
if (path.node.init &&
|
|
68
|
+
t.isCallExpression(path.node.init) &&
|
|
69
|
+
t.isIdentifier(path.node.init.callee) &&
|
|
70
|
+
path.node.init.callee.name === 'useTranslation') {
|
|
71
|
+
found = true;
|
|
72
|
+
path.stop();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return found;
|
|
77
|
+
}
|
|
78
|
+
createHook(_context) {
|
|
79
|
+
return [
|
|
80
|
+
t.variableDeclaration('const', [
|
|
81
|
+
t.variableDeclarator(t.objectPattern([
|
|
82
|
+
t.objectProperty(t.identifier('t'), t.identifier('t'), false, true)
|
|
83
|
+
]), t.callExpression(t.identifier('useTranslation'), []))
|
|
84
|
+
])
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
getTranslationFunctionName() {
|
|
88
|
+
return 't';
|
|
89
|
+
}
|
|
90
|
+
requiresAsyncComponent(_context) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* `{t("key", { user })}`, or with inline elements
|
|
95
|
+
* `<Trans i18nKey="key" t={t} values={{ user }} components={{ link: <Link href="/x" /> }} />`
|
|
96
|
+
* for the message "Hi {user}, read the <link>terms</link>" (named Trans
|
|
97
|
+
* components; placeholders are ICU arguments, rendered by i18next-icu).
|
|
98
|
+
*/
|
|
99
|
+
createMessage(key, message, options = {}) {
|
|
100
|
+
const transName = options.transName ?? 'Trans';
|
|
101
|
+
if (!(0, jsx_message_1.hasTags)(message))
|
|
102
|
+
return { node: t.jsxExpressionContainer((0, jsx_message_1.createMessageTCall)(key, message)) };
|
|
103
|
+
const values = (0, jsx_message_1.placeholderValues)(message);
|
|
104
|
+
const components = message.entries.flatMap((e) => (e.kind === 'tag' ? [(0, jsx_message_1.transComponent)(e)] : []));
|
|
105
|
+
const attrs = [
|
|
106
|
+
t.jsxAttribute(t.jsxIdentifier('i18nKey'), t.stringLiteral(key)),
|
|
107
|
+
t.jsxAttribute(t.jsxIdentifier('t'), t.jsxExpressionContainer(t.identifier('t'))),
|
|
108
|
+
];
|
|
109
|
+
if (values.length > 0)
|
|
110
|
+
attrs.push(t.jsxAttribute(t.jsxIdentifier('values'), t.jsxExpressionContainer(t.objectExpression(values))));
|
|
111
|
+
attrs.push(t.jsxAttribute(t.jsxIdentifier('components'), t.jsxExpressionContainer(t.objectExpression(components))));
|
|
112
|
+
const node = t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(transName), attrs, true), null, [], true);
|
|
113
|
+
return { node, imports: [{ source: 'react-i18next', name: 'Trans', local: transName }] };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.ReactI18nextStrategy = ReactI18nextStrategy;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { InjectionStrategy, InjectionContext } from '../InjectionStrategy';
|
|
3
|
+
export declare class VanillaStrategy implements InjectionStrategy {
|
|
4
|
+
id: string;
|
|
5
|
+
hasImport(ast: t.File): boolean;
|
|
6
|
+
createImport(): t.ImportDeclaration;
|
|
7
|
+
hasHook(_componentPath: any): boolean;
|
|
8
|
+
createHook(_context: InjectionContext): t.Statement[];
|
|
9
|
+
getTranslationFunctionName(): string;
|
|
10
|
+
requiresAsyncComponent(_context: InjectionContext): boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
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.VanillaStrategy = void 0;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
class VanillaStrategy {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.id = 'vanilla';
|
|
41
|
+
}
|
|
42
|
+
hasImport(ast) {
|
|
43
|
+
let found = false;
|
|
44
|
+
for (const node of ast.program.body) {
|
|
45
|
+
if (t.isImportDeclaration(node) && node.source.value === '@/i18n') {
|
|
46
|
+
const hasSpecifier = node.specifiers.some(spec => t.isImportSpecifier(spec) &&
|
|
47
|
+
t.isIdentifier(spec.imported) &&
|
|
48
|
+
spec.imported.name === 't');
|
|
49
|
+
if (hasSpecifier) {
|
|
50
|
+
found = true;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return found;
|
|
56
|
+
}
|
|
57
|
+
createImport() {
|
|
58
|
+
return t.importDeclaration([t.importSpecifier(t.identifier('t'), t.identifier('t'))], t.stringLiteral('@/i18n'));
|
|
59
|
+
}
|
|
60
|
+
hasHook(_componentPath) {
|
|
61
|
+
return true; // No hook needed for vanilla JS
|
|
62
|
+
}
|
|
63
|
+
createHook(_context) {
|
|
64
|
+
return []; // No hook needed
|
|
65
|
+
}
|
|
66
|
+
getTranslationFunctionName() {
|
|
67
|
+
return 't';
|
|
68
|
+
}
|
|
69
|
+
requiresAsyncComponent(_context) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.VanillaStrategy = VanillaStrategy;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { InjectionStrategy, InjectionContext } from '../InjectionStrategy';
|
|
3
|
+
export declare class VueI18nStrategy implements InjectionStrategy {
|
|
4
|
+
id: string;
|
|
5
|
+
hasImport(ast: t.File): boolean;
|
|
6
|
+
createImport(): t.ImportDeclaration;
|
|
7
|
+
hasHook(componentPath: any): boolean;
|
|
8
|
+
createHook(_context: InjectionContext): t.Statement[];
|
|
9
|
+
getTranslationFunctionName(): string;
|
|
10
|
+
requiresAsyncComponent(_context: InjectionContext): boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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.VueI18nStrategy = void 0;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
class VueI18nStrategy {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.id = 'vue-i18n';
|
|
41
|
+
}
|
|
42
|
+
hasImport(ast) {
|
|
43
|
+
for (const node of ast.program.body) {
|
|
44
|
+
if (t.isImportDeclaration(node) && node.source.value === 'vue-i18n') {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
createImport() {
|
|
51
|
+
return t.importDeclaration([t.importSpecifier(t.identifier('useI18n'), t.identifier('useI18n'))], t.stringLiteral('vue-i18n'));
|
|
52
|
+
}
|
|
53
|
+
hasHook(componentPath) {
|
|
54
|
+
let found = false;
|
|
55
|
+
componentPath.traverse({
|
|
56
|
+
VariableDeclarator(path) {
|
|
57
|
+
if (path.node.init &&
|
|
58
|
+
t.isCallExpression(path.node.init) &&
|
|
59
|
+
t.isIdentifier(path.node.init.callee) &&
|
|
60
|
+
path.node.init.callee.name === 'useI18n') {
|
|
61
|
+
found = true;
|
|
62
|
+
path.stop();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return found;
|
|
67
|
+
}
|
|
68
|
+
createHook(_context) {
|
|
69
|
+
return [
|
|
70
|
+
t.variableDeclaration('const', [
|
|
71
|
+
t.variableDeclarator(t.objectPattern([
|
|
72
|
+
t.objectProperty(t.identifier('t'), t.identifier('t'), false, true)
|
|
73
|
+
]), t.callExpression(t.identifier('useI18n'), []))
|
|
74
|
+
])
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
getTranslationFunctionName() {
|
|
78
|
+
return 't';
|
|
79
|
+
}
|
|
80
|
+
requiresAsyncComponent(_context) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.VueI18nStrategy = VueI18nStrategy;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type FormatterName = 'prettier' | 'biome';
|
|
2
|
+
export interface FormatResult {
|
|
3
|
+
tool: FormatterName;
|
|
4
|
+
/** Files handed to the formatter (relative to the project root). */
|
|
5
|
+
files: string[];
|
|
6
|
+
ok: boolean;
|
|
7
|
+
/** Why formatting was skipped or failed. */
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const FORMATTERS: Array<{
|
|
11
|
+
name: FormatterName;
|
|
12
|
+
packages: string[];
|
|
13
|
+
args: (files: string[]) => string[];
|
|
14
|
+
}>;
|
|
15
|
+
/** The formatter the project declares in package.json (prettier first), or null. */
|
|
16
|
+
export declare function detectFormatter(projectRoot: string): Promise<(typeof FORMATTERS)[number] | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Run the project's own prettier/biome on the files the engine changed, in
|
|
19
|
+
* the temp copy, using the binary from the project's node_modules (with the
|
|
20
|
+
* project's config, which was copied). Best effort: any problem is returned
|
|
21
|
+
* as a message and the run carries on with unformatted output.
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatChangedFiles(projectDir: string, workDir: string, changedFiles: string[], opts?: {
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
}): Promise<FormatResult | null>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
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.detectFormatter = detectFormatter;
|
|
37
|
+
exports.formatChangedFiles = formatChangedFiles;
|
|
38
|
+
const node_child_process_1 = require("node:child_process");
|
|
39
|
+
const promises_1 = require("node:fs/promises");
|
|
40
|
+
const path = __importStar(require("node:path"));
|
|
41
|
+
const node_util_1 = require("node:util");
|
|
42
|
+
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
43
|
+
/** Files a JS formatter should touch; locale JSON and package.json are left as the engine wrote them. */
|
|
44
|
+
const FORMATTABLE = /\.(?:[cm]?[jt]sx?|vue)$/;
|
|
45
|
+
const FORMATTERS = [
|
|
46
|
+
{ name: 'prettier', packages: ['prettier'], args: (files) => ['--write', ...files] },
|
|
47
|
+
{ name: 'biome', packages: ['@biomejs/biome'], args: (files) => ['format', '--write', ...files] },
|
|
48
|
+
];
|
|
49
|
+
/** The formatter the project declares in package.json (prettier first), or null. */
|
|
50
|
+
async function detectFormatter(projectRoot) {
|
|
51
|
+
try {
|
|
52
|
+
const pkg = JSON.parse(await (0, promises_1.readFile)(path.join(projectRoot, 'package.json'), 'utf8'));
|
|
53
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
54
|
+
return FORMATTERS.find((f) => f.packages.some((p) => deps[p])) ?? null;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run the project's own prettier/biome on the files the engine changed, in
|
|
62
|
+
* the temp copy, using the binary from the project's node_modules (with the
|
|
63
|
+
* project's config, which was copied). Best effort: any problem is returned
|
|
64
|
+
* as a message and the run carries on with unformatted output.
|
|
65
|
+
*/
|
|
66
|
+
async function formatChangedFiles(projectDir, workDir, changedFiles, opts = {}) {
|
|
67
|
+
const formatter = await detectFormatter(workDir);
|
|
68
|
+
if (!formatter)
|
|
69
|
+
return null;
|
|
70
|
+
const files = changedFiles.filter((f) => FORMATTABLE.test(f));
|
|
71
|
+
if (files.length === 0)
|
|
72
|
+
return null;
|
|
73
|
+
const bin = path.join(projectDir, 'node_modules', '.bin', formatter.name);
|
|
74
|
+
if (!(await (0, promises_1.lstat)(bin).catch(() => null))) {
|
|
75
|
+
return {
|
|
76
|
+
tool: formatter.name,
|
|
77
|
+
files,
|
|
78
|
+
ok: false,
|
|
79
|
+
message: `${formatter.name} is in package.json but not installed, so changed files were not formatted. Run your package manager install, then ${formatter.name} on them.`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// Let the formatter resolve its plugins/config packages from the project.
|
|
83
|
+
const link = path.join(workDir, 'node_modules');
|
|
84
|
+
const linked = !(await (0, promises_1.lstat)(link).catch(() => null));
|
|
85
|
+
if (linked)
|
|
86
|
+
await (0, promises_1.symlink)(path.join(projectDir, 'node_modules'), link, 'dir').catch(() => { });
|
|
87
|
+
try {
|
|
88
|
+
await execFileAsync(bin, formatter.args(files), {
|
|
89
|
+
cwd: workDir,
|
|
90
|
+
timeout: opts.timeoutMs ?? 60000,
|
|
91
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
92
|
+
env: { ...process.env, NO_COLOR: '1' },
|
|
93
|
+
});
|
|
94
|
+
return { tool: formatter.name, files, ok: true };
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
const e = err;
|
|
98
|
+
const detail = (e.stderr || e.message || String(err)).trim().split('\n')[0];
|
|
99
|
+
return { tool: formatter.name, files, ok: false, message: `${formatter.name} failed (${detail}); files were left unformatted.` };
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
if (linked)
|
|
103
|
+
await (0, promises_1.unlink)(link).catch(() => { });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `file` is a Babelize translate report: JSON whose first field is
|
|
3
|
+
* `"$schema": "https://babelize.co/schemas/translate-report.v…"`, wherever it
|
|
4
|
+
* was written (`--report <path>`). Identified by content, not by name.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isBabelizeReportFile(file: string): Promise<boolean>;
|
|
7
|
+
/** Whether `rel` (relative to `dir`) is git-ignored. */
|
|
8
|
+
export declare function isGitIgnored(dir: string, rel: string): Promise<boolean>;
|
|
9
|
+
export declare class GitError extends Error {
|
|
10
|
+
readonly code: 'not_a_repo' | 'git_missing' | 'dirty';
|
|
11
|
+
readonly dirtyFiles: string[];
|
|
12
|
+
constructor(message: string, code: 'not_a_repo' | 'git_missing' | 'dirty', dirtyFiles?: string[]);
|
|
13
|
+
}
|
|
14
|
+
/** Throws GitError('not_a_repo' | 'git_missing') unless `dir` is inside a git work tree. */
|
|
15
|
+
export declare function assertGitRepo(dir: string): Promise<void>;
|
|
16
|
+
/** Uncommitted changes under `dir` (tracked edits and untracked files), as porcelain lines. */
|
|
17
|
+
export declare function getUncommittedChanges(dir: string): Promise<string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Refuse to run on a dirty tree unless `force`: the result has to be reviewable
|
|
20
|
+
* as its own `git diff`, and a failed review has to be undoable with
|
|
21
|
+
* `git checkout . && git clean -fd` without losing the user's work.
|
|
22
|
+
*/
|
|
23
|
+
export declare function assertCleanTree(dir: string, force: boolean): Promise<string[]>;
|