@scopeact/autoi18n 1.1.1 → 1.2.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/dist/chunk-36HQJSGI.cjs +40 -0
- package/dist/chunk-36HQJSGI.cjs.map +1 -0
- package/dist/chunk-NYRK5OWZ.js +40 -0
- package/dist/chunk-NYRK5OWZ.js.map +1 -0
- package/dist/chunk-RLNUAAKC.js +296 -0
- package/dist/chunk-RLNUAAKC.js.map +1 -0
- package/dist/chunk-TJT6ONON.cjs +41 -0
- package/dist/chunk-TJT6ONON.cjs.map +1 -0
- package/dist/chunk-TWTG4RTI.cjs +296 -0
- package/dist/chunk-TWTG4RTI.cjs.map +1 -0
- package/dist/chunk-VBBY4GSW.js +41 -0
- package/dist/chunk-VBBY4GSW.js.map +1 -0
- package/dist/cli.cjs +18 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.cjs +10 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +17 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.js +10 -0
- package/dist/client.js.map +1 -0
- package/dist/core/index.cjs +9 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +4 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.cjs +21 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +20 -18
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +9 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +10 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +9 -0
- package/dist/server.js.map +1 -0
- package/package.json +79 -26
- package/schema.json +51 -0
- package/README.md +0 -256
- package/dist/index.d.ts.map +0 -1
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/core/scanner.ts
|
|
2
|
+
var _ora = require('ora'); var _ora2 = _interopRequireDefault(_ora);
|
|
3
|
+
var _tsmorph = require('ts-morph');
|
|
4
|
+
|
|
5
|
+
// src/core/config.ts
|
|
6
|
+
var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
|
|
7
|
+
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
8
|
+
|
|
9
|
+
var configPath = _path2.default.join(process.cwd(), "auto-i18n.config.json");
|
|
10
|
+
function readConfig(key) {
|
|
11
|
+
if (!_fs2.default.existsSync(configPath)) {
|
|
12
|
+
createConfig();
|
|
13
|
+
}
|
|
14
|
+
const config = JSON.parse(_fs2.default.readFileSync(configPath, "utf-8"));
|
|
15
|
+
return config[key];
|
|
16
|
+
}
|
|
17
|
+
function createConfig() {
|
|
18
|
+
const spinner = _ora2.default.call(void 0, "Criando arquivos de configura\xE7\xE3o...").start();
|
|
19
|
+
const defaultConfig = {
|
|
20
|
+
$schema: `https://unpkg.com/@scopeact/autoi18n@latest/schema.json`,
|
|
21
|
+
sourceLang: "pt",
|
|
22
|
+
targetLangs: ["en", "es"],
|
|
23
|
+
autoInject: false,
|
|
24
|
+
i18nLibrary: "react-i18next",
|
|
25
|
+
provider: "openai",
|
|
26
|
+
localesDir: "./locales",
|
|
27
|
+
model: "gpt-3.5-turbo",
|
|
28
|
+
files: ["src/**/*.tsx", "app/**/*.tsx"]
|
|
29
|
+
};
|
|
30
|
+
_fs2.default.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
|
|
31
|
+
spinner.succeed();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/core/utils.ts
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
function createExtractionPrompt(itens, contexto) {
|
|
38
|
+
return `
|
|
39
|
+
Voc\xEA \xE9 um especialista em i18n. Recebi uma lista de textos de uma interface React.
|
|
40
|
+
Sua tarefa \xE9 gerar chaves (keys) sem\xE2nticas e curtas em ingl\xEAs (snake_case) para cada item.
|
|
41
|
+
|
|
42
|
+
REGRAS:
|
|
43
|
+
1. Retorne APENAS um array de objetos JSON.
|
|
44
|
+
2. Cada objeto deve ter: "id" (o mesmo enviado) e "key" (a chave sugerida).
|
|
45
|
+
3. As chaves devem ser curtas (max 4 palavras).
|
|
46
|
+
4. Textos longos devem ter chaves que resumam o sentido.
|
|
47
|
+
|
|
48
|
+
EXEMPLO DE ENTRADA:
|
|
49
|
+
[ { "id": 1, "text": "Salvar altera\xE7\xF5es" } ]
|
|
50
|
+
|
|
51
|
+
EXEMPLO DE SA\xCDDA:
|
|
52
|
+
[ { "id": 1, "key": "button_save_changes" } ]
|
|
53
|
+
|
|
54
|
+
ITENS PARA PROCESSAR:
|
|
55
|
+
${JSON.stringify(itens, null, 2)}
|
|
56
|
+
|
|
57
|
+
${contexto ? `Contexto do projeto: ${contexto}` : ""}
|
|
58
|
+
`.trim();
|
|
59
|
+
}
|
|
60
|
+
function createTranslationPrompt(delta, from, to, contexto) {
|
|
61
|
+
return `
|
|
62
|
+
Voc\xEA \xE9 um tradutor s\xEAnior de software especializado em localiza\xE7\xE3o (i18n).
|
|
63
|
+
Sua tarefa \xE9 traduzir os VALORES das novas chaves de interface que foram adicionadas ao projeto.
|
|
64
|
+
|
|
65
|
+
IDIOMAS: De "${from}" para "${to}".
|
|
66
|
+
|
|
67
|
+
REGRAS CR\xCDTICAS:
|
|
68
|
+
1. MANUTEN\xC7\xC3O DE CHAVES: Mantenha as chaves (keys) EXATAMENTE como est\xE3o. N\xE3o as traduza nem as altere.
|
|
69
|
+
2. TRADU\xC7\xC3O DE VALORES: Traduza apenas os valores para o idioma de destino.
|
|
70
|
+
3. VARI\xC1VEIS E PLACEHOLDERS: Preserve placeholders como {{name}}, {0}, %s ou qualquer texto entre chaves. Eles N\xC3O devem ser traduzidos.
|
|
71
|
+
4. TOM DE VOZ: Use um tom profissional e conciso, adequado para interfaces de usu\xE1rio (bot\xF5es, labels, mensagens de erro).
|
|
72
|
+
5. FORMATO: Retorne APENAS o objeto JSON puro, sem explica\xE7\xF5es ou blocos de c\xF3digo markdown.
|
|
73
|
+
|
|
74
|
+
${contexto ? `CONTEXTO DO PROJETO: ${contexto}` : ""}
|
|
75
|
+
|
|
76
|
+
DADOS PARA TRADUZIR:
|
|
77
|
+
${JSON.stringify(delta, null, 2)}
|
|
78
|
+
`.trim();
|
|
79
|
+
}
|
|
80
|
+
function cleanJsonResponse(text) {
|
|
81
|
+
return text.replace(/```json|```/g, "").trim();
|
|
82
|
+
}
|
|
83
|
+
function lerJson(caminho) {
|
|
84
|
+
if (!_fs2.default.existsSync(caminho)) {
|
|
85
|
+
_fs2.default.mkdirSync(_path2.default.dirname(caminho), { recursive: true });
|
|
86
|
+
_fs2.default.writeFileSync(caminho, "{}");
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
return JSON.parse(_fs2.default.readFileSync(caminho, "utf-8"));
|
|
90
|
+
}
|
|
91
|
+
function salvarJson(caminho, json) {
|
|
92
|
+
if (!_fs2.default.existsSync(caminho)) {
|
|
93
|
+
_fs2.default.mkdirSync(_path2.default.dirname(caminho), { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
_fs2.default.writeFileSync(caminho, JSON.stringify(json, null, 2));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/core/ai.ts
|
|
99
|
+
var _dotenv = require('dotenv'); var _dotenv2 = _interopRequireDefault(_dotenv);
|
|
100
|
+
var _openai = require('openai');
|
|
101
|
+
var _generativeai = require('@google/generative-ai');
|
|
102
|
+
_dotenv2.default.config();
|
|
103
|
+
async function askLLM(prompt, mode = "text") {
|
|
104
|
+
const provider = readConfig("provider") || "openai";
|
|
105
|
+
const model = readConfig("model");
|
|
106
|
+
checkEnv(provider);
|
|
107
|
+
switch (provider) {
|
|
108
|
+
case "openai":
|
|
109
|
+
return askOpenAI(prompt, model || "gpt-4o", mode);
|
|
110
|
+
case "google":
|
|
111
|
+
return askGemini(prompt, model || "gemini-2.5-flash", mode);
|
|
112
|
+
case "deepseek":
|
|
113
|
+
return askDeepSeek(prompt, model || "deepseek-chat", mode);
|
|
114
|
+
case "openrouter":
|
|
115
|
+
return askOpenRouter(prompt, model || "google/gemini-2.0-flash-001", mode);
|
|
116
|
+
case "ollama":
|
|
117
|
+
return askOllama(prompt, model || "llama3", mode);
|
|
118
|
+
default:
|
|
119
|
+
throw new Error(`Provedor de IA desconhecido: ${provider}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function checkEnv(provider) {
|
|
123
|
+
if (!process.env[`${provider.toUpperCase()}_API_KEY`]) {
|
|
124
|
+
throw new Error(`${provider.toUpperCase()}_API_KEY n\xE3o foi definido`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function askOpenAI(prompt, model, mode) {
|
|
128
|
+
const openai = new (0, _openai.OpenAI)({ apiKey: process.env.OPENAI_API_KEY });
|
|
129
|
+
const response = await openai.chat.completions.create({
|
|
130
|
+
response_format: mode === "json" ? { type: "json_object" } : { type: "text" },
|
|
131
|
+
messages: [{ role: "user", content: prompt }],
|
|
132
|
+
model
|
|
133
|
+
});
|
|
134
|
+
return _optionalChain([response, 'optionalAccess', _ => _.choices, 'optionalAccess', _2 => _2[0], 'optionalAccess', _3 => _3.message, 'optionalAccess', _4 => _4.content]) || "";
|
|
135
|
+
}
|
|
136
|
+
async function askGemini(prompt, model, mode) {
|
|
137
|
+
const genAI = new (0, _generativeai.GoogleGenerativeAI)(process.env.GOOGLE_API_KEY || "");
|
|
138
|
+
const gemini = genAI.getGenerativeModel({ model, generationConfig: { responseMimeType: mode === "json" ? "application/json" : "text/plain" } });
|
|
139
|
+
const result = await gemini.generateContent(prompt);
|
|
140
|
+
return result.response.text();
|
|
141
|
+
}
|
|
142
|
+
async function askDeepSeek(prompt, model, mode) {
|
|
143
|
+
const client = new (0, _openai.OpenAI)({
|
|
144
|
+
apiKey: process.env.DEEPSEEK_API_KEY,
|
|
145
|
+
baseURL: "https://api.deepseek.com"
|
|
146
|
+
});
|
|
147
|
+
const response = await client.chat.completions.create({
|
|
148
|
+
response_format: mode === "json" ? { type: "json_object" } : { type: "text" },
|
|
149
|
+
messages: [{ role: "user", content: prompt }],
|
|
150
|
+
model
|
|
151
|
+
});
|
|
152
|
+
return _optionalChain([response, 'optionalAccess', _5 => _5.choices, 'optionalAccess', _6 => _6[0], 'optionalAccess', _7 => _7.message, 'optionalAccess', _8 => _8.content]) || "";
|
|
153
|
+
}
|
|
154
|
+
async function askOpenRouter(prompt, model, mode) {
|
|
155
|
+
const client = new (0, _openai.OpenAI)({
|
|
156
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
157
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
158
|
+
defaultHeaders: {
|
|
159
|
+
"HTTP-Referer": "https://github.com/felipevetter/auto-i18n"
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
const response = await client.chat.completions.create({
|
|
163
|
+
response_format: mode === "json" ? { type: "json_object" } : { type: "text" },
|
|
164
|
+
messages: [{ role: "user", content: prompt }],
|
|
165
|
+
model
|
|
166
|
+
});
|
|
167
|
+
return _optionalChain([response, 'optionalAccess', _9 => _9.choices, 'optionalAccess', _10 => _10[0], 'optionalAccess', _11 => _11.message, 'optionalAccess', _12 => _12.content]) || "";
|
|
168
|
+
}
|
|
169
|
+
async function askOllama(prompt, model, mode) {
|
|
170
|
+
const response = await fetch("http://localhost:11434/api/generate", {
|
|
171
|
+
method: "POST",
|
|
172
|
+
body: JSON.stringify({
|
|
173
|
+
model,
|
|
174
|
+
prompt,
|
|
175
|
+
format: mode === "json" ? "json" : "text",
|
|
176
|
+
stream: false
|
|
177
|
+
})
|
|
178
|
+
});
|
|
179
|
+
const data = await response.json();
|
|
180
|
+
return data.response;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/core/scanner.ts
|
|
184
|
+
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
185
|
+
|
|
186
|
+
// src/core/dependecies.ts
|
|
187
|
+
|
|
188
|
+
function ensureI18nImport(sourceFile) {
|
|
189
|
+
const importDeclaration = sourceFile.getImportDeclaration("react-i18next");
|
|
190
|
+
if (!importDeclaration) {
|
|
191
|
+
sourceFile.addImportDeclaration({
|
|
192
|
+
moduleSpecifier: "react-i18next",
|
|
193
|
+
namedImports: ["useTranslation"]
|
|
194
|
+
});
|
|
195
|
+
} else {
|
|
196
|
+
const namedImports = importDeclaration.getNamedImports().map((i) => i.getName());
|
|
197
|
+
if (!namedImports.includes("useTranslation")) {
|
|
198
|
+
importDeclaration.addNamedImport("useTranslation");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/core/scanner.ts
|
|
204
|
+
async function scanFilesAndRun() {
|
|
205
|
+
const sourceLang = readConfig("sourceLang") || "pt";
|
|
206
|
+
const targetLangs = readConfig("targetLangs") || ["en"];
|
|
207
|
+
const localesDir = readConfig("localesDir") || "./locales";
|
|
208
|
+
const pendentes = [];
|
|
209
|
+
const stringsUnicas = /* @__PURE__ */ new Set();
|
|
210
|
+
const novasChavesParaSalvar = {};
|
|
211
|
+
const mapaTextoParaChave = {};
|
|
212
|
+
const project = new (0, _tsmorph.Project)({
|
|
213
|
+
skipAddingFilesFromTsConfig: true
|
|
214
|
+
});
|
|
215
|
+
const spinner = _ora2.default.call(void 0, "\u{1F4C2} Carregando e analisando arquivos...").start();
|
|
216
|
+
project.addSourceFilesAtPaths(readConfig("files"));
|
|
217
|
+
const arquivos = project.getSourceFiles();
|
|
218
|
+
for (const arquivo of arquivos) {
|
|
219
|
+
const shouldInject = readConfig("autoInject") || false;
|
|
220
|
+
if (shouldInject) {
|
|
221
|
+
ensureI18nImport(arquivo);
|
|
222
|
+
}
|
|
223
|
+
arquivo.forEachDescendant((node) => {
|
|
224
|
+
if (node.getKind() === _tsmorph.SyntaxKind.JsxText) {
|
|
225
|
+
const textoOriginal = node.getText();
|
|
226
|
+
if (textoOriginal.trim().length > 0) {
|
|
227
|
+
pendentes.push({ node, text: textoOriginal.trim() });
|
|
228
|
+
stringsUnicas.add(textoOriginal.trim());
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
const fileCount = arquivos.length;
|
|
234
|
+
const strCount = stringsUnicas.size;
|
|
235
|
+
const sFiles = fileCount === 1 ? "" : "s";
|
|
236
|
+
const sStr = strCount === 1 ? "" : "s";
|
|
237
|
+
spinner.succeed(`Encontrado(s) ${_chalk2.default.cyan(strCount)} texto${sStr} \xFAnico${sStr} em ${_chalk2.default.cyan(fileCount)} arquivo${sFiles}.`);
|
|
238
|
+
const spinnerLLM = _ora2.default.call(void 0, `\u{1F9E0} Gerando chaves inteligentes para ${strCount} textos...`).start();
|
|
239
|
+
const listaParaIA = Array.from(stringsUnicas).map((text, index) => ({
|
|
240
|
+
id: index,
|
|
241
|
+
text
|
|
242
|
+
}));
|
|
243
|
+
const respostaIA = JSON.parse(cleanJsonResponse(await askLLM(createExtractionPrompt(listaParaIA), "json")));
|
|
244
|
+
respostaIA.forEach((item) => {
|
|
245
|
+
const originalText = _optionalChain([listaParaIA, 'access', _13 => _13.find, 'call', _14 => _14((l) => l.id === item.id), 'optionalAccess', _15 => _15.text]);
|
|
246
|
+
if (originalText) mapaTextoParaChave[originalText] = item.key;
|
|
247
|
+
});
|
|
248
|
+
pendentes.forEach(({ node, text }) => {
|
|
249
|
+
const key = mapaTextoParaChave[text];
|
|
250
|
+
if (key) {
|
|
251
|
+
node.replaceWithText(`{t('${key}')}`);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
project.saveSync();
|
|
255
|
+
spinnerLLM.succeed(_chalk2.default.green("C\xF3digo atualizado com as novas chaves i18n!"));
|
|
256
|
+
const spinnerSave = _ora2.default.call(void 0, "\u{1F4BE} Gerando arquivos de tradu\xE7\xE3o...").start();
|
|
257
|
+
for (const [textoOriginal, chaveGerada] of Object.entries(mapaTextoParaChave)) {
|
|
258
|
+
novasChavesParaSalvar[chaveGerada] = textoOriginal;
|
|
259
|
+
}
|
|
260
|
+
const pathPt = `${localesDir}/${sourceLang}.json`;
|
|
261
|
+
const jsonPtAtual = lerJson(pathPt);
|
|
262
|
+
const jsonPtFinal = { ...jsonPtAtual, ...novasChavesParaSalvar };
|
|
263
|
+
salvarJson(pathPt, jsonPtFinal);
|
|
264
|
+
for (const idioma of targetLangs) {
|
|
265
|
+
const pathIdioma = `${localesDir}/${idioma}.json`;
|
|
266
|
+
const jsonIdiomaAtual = lerJson(pathIdioma);
|
|
267
|
+
const deltaParaTraduzir = {};
|
|
268
|
+
for (const [key, value] of Object.entries(novasChavesParaSalvar)) {
|
|
269
|
+
if (!jsonIdiomaAtual[key]) {
|
|
270
|
+
deltaParaTraduzir[key] = value;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (Object.keys(deltaParaTraduzir).length > 0) {
|
|
274
|
+
const prompt = createTranslationPrompt(deltaParaTraduzir, sourceLang, idioma);
|
|
275
|
+
const respostaIA2 = cleanJsonResponse(await askLLM(prompt, "json"));
|
|
276
|
+
const traducoesEn = JSON.parse(respostaIA2);
|
|
277
|
+
const jsonIdiomaFinal = { ...jsonIdiomaAtual, ...traducoesEn };
|
|
278
|
+
salvarJson(pathIdioma, jsonIdiomaFinal);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
spinnerSave.succeed("Tradu\xE7\xE3o conclu\xEDda e chaves salvas com sucesso!");
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/core/index.ts
|
|
285
|
+
var run = () => {
|
|
286
|
+
scanFilesAndRun();
|
|
287
|
+
};
|
|
288
|
+
var init = () => {
|
|
289
|
+
createConfig();
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
exports.run = run; exports.init = init;
|
|
296
|
+
//# sourceMappingURL=chunk-TWTG4RTI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/chunk-TWTG4RTI.cjs","../src/core/scanner.ts","../src/core/config.ts","../src/core/utils.ts","../src/core/ai.ts","../src/core/dependecies.ts","../src/core/index.ts"],"names":["respostaIA"],"mappings":"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","file":"/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/chunk-TWTG4RTI.cjs","sourcesContent":[null,"import ora from \"ora\";\nimport { Node, Project, SyntaxKind } from \"ts-morph\";\nimport { readConfig } from \"./config.js\";\nimport { cleanJsonResponse, createExtractionPrompt, createTranslationPrompt, lerJson, salvarJson, type ExtractionItem } from \"./utils.js\";\nimport { askLLM } from \"./ai.js\";\nimport chalk from \"chalk\";\nimport { ensureI18nImport } from \"./dependecies.js\";\n\ninterface JsonTranslation {\n [key: string]: string;\n}\n\nexport async function scanFilesAndRun() {\n const sourceLang = readConfig('sourceLang') || 'pt';\n const targetLangs = readConfig('targetLangs') || ['en'];\n const localesDir = readConfig('localesDir') || './locales';\n\n const pendentes: { node: Node, text: string }[] = [];\n const stringsUnicas = new Set<string>();\n const novasChavesParaSalvar: Record<string, string> = {};\n const mapaTextoParaChave: Record<string, string> = {};\n\n const project = new Project({\n skipAddingFilesFromTsConfig: true,\n });\n\n const spinner = ora(\"📂 Carregando e analisando arquivos...\").start();\n project.addSourceFilesAtPaths(readConfig(\"files\"));\n\n const arquivos = project.getSourceFiles();\n\n for (const arquivo of arquivos) {\n const shouldInject = readConfig(\"autoInject\") || false;\n if(shouldInject) {\n ensureI18nImport(arquivo);\n }\n arquivo.forEachDescendant((node) => {\n if (node.getKind() === SyntaxKind.JsxText) {\n const textoOriginal = node.getText();\n if (textoOriginal.trim().length > 0) {\n pendentes.push({ node, text: textoOriginal.trim() });\n stringsUnicas.add(textoOriginal.trim());\n }\n }\n });\n }\n\n //pluralização elegante\n const fileCount = arquivos.length;\n const strCount = stringsUnicas.size;\n const sFiles = fileCount === 1 ? '' : 's';\n const sStr = strCount === 1 ? '' : 's';\n spinner.succeed(`Encontrado(s) ${chalk.cyan(strCount)} texto${sStr} único${sStr} em ${chalk.cyan(fileCount)} arquivo${sFiles}.`);\n const spinnerLLM = ora(`🧠 Gerando chaves inteligentes para ${strCount} textos...`).start();\n const listaParaIA = Array.from(stringsUnicas).map((text, index) => ({\n id: index,\n text\n })) as ExtractionItem[];\n\n const respostaIA = JSON.parse(cleanJsonResponse(await askLLM(createExtractionPrompt(listaParaIA), 'json')));\n\n respostaIA.forEach((item: any) => {\n const originalText = listaParaIA.find(l => l.id === item.id)?.text;\n if (originalText) mapaTextoParaChave[originalText] = item.key;\n });\n\n pendentes.forEach(({ node, text }) => {\n const key = mapaTextoParaChave[text];\n if (key) {\n node.replaceWithText(`{t('${key}')}`);\n }\n });\n project.saveSync();\n spinnerLLM.succeed(chalk.green(\"Código atualizado com as novas chaves i18n!\"));\n\n const spinnerSave = ora(\"💾 Gerando arquivos de tradução...\").start();\n\n for (const [textoOriginal, chaveGerada] of Object.entries(mapaTextoParaChave)) {\n novasChavesParaSalvar[chaveGerada] = textoOriginal;\n }\n\n const pathPt = `${localesDir}/${sourceLang}.json`;\n const jsonPtAtual = lerJson(pathPt);\n const jsonPtFinal = { ...jsonPtAtual, ...novasChavesParaSalvar };\n\n salvarJson(pathPt, jsonPtFinal);\n\n // Salvar em outros idiomas\n for (const idioma of targetLangs) {\n const pathIdioma = `${localesDir}/${idioma}.json`;\n const jsonIdiomaAtual = lerJson(pathIdioma) as JsonTranslation;\n\n const deltaParaTraduzir: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(novasChavesParaSalvar)) {\n if (!jsonIdiomaAtual[key]) {\n deltaParaTraduzir[key] = value;\n }\n }\n\n if (Object.keys(deltaParaTraduzir).length > 0) {\n const prompt = createTranslationPrompt(deltaParaTraduzir, sourceLang, idioma);\n\n const respostaIA = cleanJsonResponse(await askLLM(prompt, 'json'));\n const traducoesEn = JSON.parse(respostaIA);\n\n const jsonIdiomaFinal = { ...jsonIdiomaAtual, ...traducoesEn };\n salvarJson(pathIdioma, jsonIdiomaFinal);\n }\n }\n\n spinnerSave.succeed('Tradução concluída e chaves salvas com sucesso!');\n}","import fs from \"fs\";\nimport path from \"path\";\nimport ora from \"ora\";\n\nconst configPath = path.join(process.cwd(), \"auto-i18n.config.json\");\n\nexport function readConfig(key: string) {\n if (!fs.existsSync(configPath)) {\n createConfig();\n }\n const config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n return config[key];\n}\n\nexport function createConfig() {\n const spinner = ora('Criando arquivos de configuração...').start();\n const defaultConfig = {\n $schema: `https://unpkg.com/@scopeact/autoi18n@latest/schema.json`,\n sourceLang: \"pt\",\n targetLangs: [\"en\", \"es\"],\n autoInject: false,\n i18nLibrary: \"react-i18next\",\n provider: \"openai\",\n localesDir: \"./locales\",\n model: \"gpt-3.5-turbo\",\n files: [\"src/**/*.tsx\", \"app/**/*.tsx\"]\n };\n\n fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));\n spinner.succeed();\n}","import fs from 'fs';\nimport path from 'path';\n\nexport interface ExtractionItem {\n id: number;\n text: string;\n}\n\nexport function createExtractionPrompt(itens: ExtractionItem[], contexto?: string): string {\n return `\nVocê é um especialista em i18n. Recebi uma lista de textos de uma interface React.\nSua tarefa é gerar chaves (keys) semânticas e curtas em inglês (snake_case) para cada item.\n\nREGRAS:\n1. Retorne APENAS um array de objetos JSON.\n2. Cada objeto deve ter: \"id\" (o mesmo enviado) e \"key\" (a chave sugerida).\n3. As chaves devem ser curtas (max 4 palavras). \n4. Textos longos devem ter chaves que resumam o sentido.\n\nEXEMPLO DE ENTRADA:\n[ { \"id\": 1, \"text\": \"Salvar alterações\" } ]\n\nEXEMPLO DE SAÍDA:\n[ { \"id\": 1, \"key\": \"button_save_changes\" } ]\n\nITENS PARA PROCESSAR:\n${JSON.stringify(itens, null, 2)}\n\n${contexto ? `Contexto do projeto: ${contexto}` : ''}\n`.trim();\n}\n\nexport function createTranslationPrompt(\n delta: object, \n from: string, \n to: string, \n contexto?: string\n): string {\n return `\nVocê é um tradutor sênior de software especializado em localização (i18n).\nSua tarefa é traduzir os VALORES das novas chaves de interface que foram adicionadas ao projeto.\n\nIDIOMAS: De \"${from}\" para \"${to}\".\n\nREGRAS CRÍTICAS:\n1. MANUTENÇÃO DE CHAVES: Mantenha as chaves (keys) EXATAMENTE como estão. Não as traduza nem as altere.\n2. TRADUÇÃO DE VALORES: Traduza apenas os valores para o idioma de destino.\n3. VARIÁVEIS E PLACEHOLDERS: Preserve placeholders como {{name}}, {0}, %s ou qualquer texto entre chaves. Eles NÃO devem ser traduzidos.\n4. TOM DE VOZ: Use um tom profissional e conciso, adequado para interfaces de usuário (botões, labels, mensagens de erro).\n5. FORMATO: Retorne APENAS o objeto JSON puro, sem explicações ou blocos de código markdown.\n\n${contexto ? `CONTEXTO DO PROJETO: ${contexto}` : ''}\n\nDADOS PARA TRADUZIR:\n${JSON.stringify(delta, null, 2)}\n`.trim();\n}\n\nexport function cleanJsonResponse(text: string): string {\n return text.replace(/```json|```/g, '').trim();\n}\n\nexport function lerJson(caminho: string): object {\n if (!fs.existsSync(caminho)) {\n fs.mkdirSync(path.dirname(caminho), { recursive: true });\n fs.writeFileSync(caminho, '{}');\n return {};\n }\n \n return JSON.parse(fs.readFileSync(caminho, 'utf-8'));\n}\n\nexport function salvarJson(caminho: string, json: object): void {\n if(!fs.existsSync(caminho)) {\n fs.mkdirSync(path.dirname(caminho), { recursive: true });\n }\n fs.writeFileSync(caminho, JSON.stringify(json, null, 2));\n}","import dotenv from 'dotenv';\ndotenv.config();\nimport { OpenAI } from 'openai';\nimport { GoogleGenerativeAI } from '@google/generative-ai';\nimport { readConfig } from \"./config.js\";\n\nexport type AIProvider = 'openai' | 'google' | 'deepseek' | 'openrouter' | 'ollama';\n\nexport async function askLLM(prompt: string, mode = 'text'): Promise<string> {\n const provider = readConfig('provider') || 'openai' as AIProvider;\n const model = readConfig('model');\n checkEnv(provider);\n switch (provider) {\n case 'openai':\n return askOpenAI(prompt, model || 'gpt-4o', mode);\n case 'google':\n return askGemini(prompt, model || 'gemini-2.5-flash', mode);\n case 'deepseek':\n return askDeepSeek(prompt, model || 'deepseek-chat', mode);\n case 'openrouter':\n return askOpenRouter(prompt, model || 'google/gemini-2.0-flash-001', mode);\n case 'ollama':\n return askOllama(prompt, model || 'llama3', mode);\n default:\n throw new Error(`Provedor de IA desconhecido: ${provider}`);\n }\n}\n\nexport function checkEnv(provider: string) {\n if (!process.env[`${provider.toUpperCase()}_API_KEY`]) {\n throw new Error(`${provider.toUpperCase()}_API_KEY não foi definido`);\n }\n}\n\nasync function askOpenAI(prompt: string, model: string, mode: string) {\n const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });\n const response = await openai.chat.completions.create({\n response_format: mode === 'json' ? { type: 'json_object' } : { type: 'text' },\n messages: [{ role: 'user', content: prompt }],\n model,\n });\n return response?.choices?.[0]?.message?.content || '';\n}\n\nasync function askGemini(prompt: string, model: string, mode: string) {\n const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY || '');\n const gemini = genAI.getGenerativeModel({ model, generationConfig: { responseMimeType: mode === 'json' ? 'application/json' : 'text/plain' } });\n const result = await gemini.generateContent(prompt);\n return result.response.text();\n}\n\nasync function askDeepSeek(prompt: string, model: string, mode: string) {\n const client = new OpenAI({\n apiKey: process.env.DEEPSEEK_API_KEY,\n baseURL: 'https://api.deepseek.com'\n });\n const response = await client.chat.completions.create({\n response_format: mode === 'json' ? { type: 'json_object' } : { type: 'text' },\n messages: [{ role: 'user', content: prompt }],\n model,\n });\n return response?.choices?.[0]?.message?.content || '';\n}\n\nasync function askOpenRouter(prompt: string, model: string, mode: string) {\n const client = new OpenAI({\n apiKey: process.env.OPENROUTER_API_KEY,\n baseURL: 'https://openrouter.ai/api/v1',\n defaultHeaders: {\n \"HTTP-Referer\": \"https://github.com/felipevetter/auto-i18n\",\n }\n });\n const response = await client.chat.completions.create({\n response_format: mode === 'json' ? { type: 'json_object' } : { type: 'text' },\n messages: [{ role: 'user', content: prompt }],\n model,\n });\n return response?.choices?.[0]?.message?.content || '';\n}\n\nasync function askOllama(prompt: string, model: string, mode: string) {\n const response = await fetch('http://localhost:11434/api/generate', {\n method: 'POST',\n body: JSON.stringify({\n model,\n prompt,\n format: mode === 'json' ? 'json' : 'text',\n stream: false,\n }),\n });\n const data = await response.json() as { response: string };\n return data.response;\n}","import { SourceFile } from \"ts-morph\";\n\nexport function ensureI18nImport(sourceFile: SourceFile) {\n const importDeclaration = sourceFile.getImportDeclaration(\"react-i18next\");\n \n if (!importDeclaration) {\n sourceFile.addImportDeclaration({\n moduleSpecifier: \"react-i18next\",\n namedImports: [\"useTranslation\"]\n });\n } else {\n const namedImports = importDeclaration.getNamedImports().map(i => i.getName());\n if (!namedImports.includes(\"useTranslation\")) {\n importDeclaration.addNamedImport(\"useTranslation\");\n }\n }\n}","import { scanFilesAndRun } from \"./scanner.js\";\nimport { createConfig } from \"./config.js\";\n\nexport const run = () => {\n scanFilesAndRun();\n};\n\nexport const init = () => {\n createConfig();\n}"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/runtime/server.ts
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { cookies, headers } from "next/headers";
|
|
5
|
+
async function detectLocale(sourceLang) {
|
|
6
|
+
const cookieStore = await cookies();
|
|
7
|
+
const localeCookie = cookieStore.get("NEXT_LOCALE")?.value;
|
|
8
|
+
if (localeCookie) return localeCookie;
|
|
9
|
+
const headersList = await headers();
|
|
10
|
+
const acceptLanguage = headersList.get("accept-language");
|
|
11
|
+
if (acceptLanguage) {
|
|
12
|
+
return acceptLanguage.split(",")[0].split("-")[0];
|
|
13
|
+
}
|
|
14
|
+
return sourceLang;
|
|
15
|
+
}
|
|
16
|
+
async function getI18nConfig(defaultLang = "en") {
|
|
17
|
+
const locale = await detectLocale(defaultLang);
|
|
18
|
+
const localesDir = path.join(process.cwd(), "./locales");
|
|
19
|
+
const filePath = path.join(localesDir, `${locale}.json`);
|
|
20
|
+
let messages = {};
|
|
21
|
+
try {
|
|
22
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
23
|
+
messages = JSON.parse(content);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.warn(`[auto-i18n] Arquivo de tradu\xE7\xE3o n\xE3o encontrado para: ${locale}`);
|
|
26
|
+
}
|
|
27
|
+
return { locale, messages };
|
|
28
|
+
}
|
|
29
|
+
async function getI18n() {
|
|
30
|
+
const { messages, locale } = await getI18nConfig();
|
|
31
|
+
const t = (key) => {
|
|
32
|
+
return messages[key] || key;
|
|
33
|
+
};
|
|
34
|
+
return { t, locale };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
getI18nConfig,
|
|
39
|
+
getI18n
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=chunk-VBBY4GSW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/server.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\n// @ts-ignore\nimport { cookies, headers } from 'next/headers';\n\nasync function detectLocale(sourceLang: string) {\n const cookieStore = await cookies();\n const localeCookie = cookieStore.get('NEXT_LOCALE')?.value;\n if (localeCookie) return localeCookie;\n\n const headersList = await headers();\n const acceptLanguage = headersList.get('accept-language');\n if (acceptLanguage) {\n return acceptLanguage.split(',')[0].split('-')[0];\n }\n\n return sourceLang;\n}\n\nexport async function getI18nConfig(defaultLang: string = \"en\") {\n const locale = await detectLocale(defaultLang);\n\n const localesDir = path.join(process.cwd(), \"./locales\");\n const filePath = path.join(localesDir, `${locale}.json`);\n\n let messages: Record<string, string> = {};\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n messages = JSON.parse(content);\n } catch (err) {\n console.warn(`[auto-i18n] Arquivo de tradução não encontrado para: ${locale}`);\n }\n\n return { locale, messages };\n}\n\n/*\n * Retorna um objeto com a função de tradução e o locale atual.\n * @param defaultLang: { defaultLocale: string }\n * @returns { t: (key: string) => string, locale: string }\n*/\nexport async function getI18n() {\n const { messages, locale } = await getI18nConfig();\n\n const t = (key: string) => {\n return messages[key] || key;\n };\n\n return { t, locale };\n}"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAGjB,SAAS,SAAS,eAAe;AAEjC,eAAe,aAAa,YAAoB;AAC5C,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,eAAe,YAAY,IAAI,aAAa,GAAG;AACrD,MAAI,aAAc,QAAO;AAEzB,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,iBAAiB,YAAY,IAAI,iBAAiB;AACxD,MAAI,gBAAgB;AAChB,WAAO,eAAe,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,EACpD;AAEA,SAAO;AACX;AAEA,eAAsB,cAAc,cAAsB,MAAM;AAC5D,QAAM,SAAS,MAAM,aAAa,WAAW;AAE7C,QAAM,aAAa,KAAK,KAAK,QAAQ,IAAI,GAAG,WAAW;AACvD,QAAM,WAAW,KAAK,KAAK,YAAY,GAAG,MAAM,OAAO;AAEvD,MAAI,WAAmC,CAAC;AACxC,MAAI;AACA,UAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,eAAW,KAAK,MAAM,OAAO;AAAA,EACjC,SAAS,KAAK;AACV,YAAQ,KAAK,iEAAwD,MAAM,EAAE;AAAA,EACjF;AAEA,SAAO,EAAE,QAAQ,SAAS;AAC9B;AAOA,eAAsB,UAAU;AAC5B,QAAM,EAAE,UAAU,OAAO,IAAI,MAAM,cAAc;AAEjD,QAAM,IAAI,CAAC,QAAgB;AACvB,WAAO,SAAS,GAAG,KAAK;AAAA,EAC5B;AAEA,SAAO,EAAE,GAAG,OAAO;AACvB;","names":[]}
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunkTWTG4RTIcjs = require('./chunk-TWTG4RTI.cjs');
|
|
6
|
+
|
|
7
|
+
// src/cli/index.ts
|
|
8
|
+
var _commander = require('commander');
|
|
9
|
+
var program = new (0, _commander.Command)();
|
|
10
|
+
program.name("@scopeact/autoi18n").description("CLI para gera\xE7\xE3o de arquivos e tradu\xE7\xE3o autom\xE1tica de arquivos tsx");
|
|
11
|
+
program.command("run").action(() => {
|
|
12
|
+
_chunkTWTG4RTIcjs.run.call(void 0, );
|
|
13
|
+
});
|
|
14
|
+
program.command("init").action(() => {
|
|
15
|
+
_chunkTWTG4RTIcjs.init.call(void 0, );
|
|
16
|
+
});
|
|
17
|
+
program.parse();
|
|
18
|
+
//# sourceMappingURL=cli.cjs.map
|
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/cli.cjs","../src/cli/index.ts"],"names":[],"mappings":"AAAA;AACA;AACE;AACA;AACF,wDAA6B;AAC7B;AACA;ACHA,sCAAwB;AACxB,IAAM,QAAA,EAAU,IAAI,uBAAA,CAAQ,CAAA;AAE5B,OAAA,CACG,IAAA,CAAK,oBAAoB,CAAA,CACzB,WAAA,CAAY,mFAAoE,CAAA;AAEnF,OAAA,CACG,OAAA,CAAQ,KAAK,CAAA,CACb,MAAA,CAAO,CAAA,EAAA,GAAM;AACZ,EAAA,mCAAA,CAAI;AACN,CAAC,CAAA;AAEH,OAAA,CACG,OAAA,CAAQ,MAAM,CAAA,CACd,MAAA,CAAO,CAAA,EAAA,GAAM;AACZ,EAAA,oCAAA,CAAK;AACP,CAAC,CAAA;AAEH,OAAA,CAAQ,KAAA,CAAM,CAAA","file":"/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/cli.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\nimport { run, init } from '../core/index.js';\nimport { Command } from 'commander';\nconst program = new Command();\n\nprogram\n .name('@scopeact/autoi18n')\n .description('CLI para geração de arquivos e tradução automática de arquivos tsx');\n\nprogram\n .command('run')\n .action(() => {\n run();\n });\n\nprogram\n .command('init')\n .action(() => {\n init();\n });\n\nprogram.parse();"]}
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
init,
|
|
4
|
+
run
|
|
5
|
+
} from "./chunk-RLNUAAKC.js";
|
|
6
|
+
|
|
7
|
+
// src/cli/index.ts
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
var program = new Command();
|
|
10
|
+
program.name("@scopeact/autoi18n").description("CLI para gera\xE7\xE3o de arquivos e tradu\xE7\xE3o autom\xE1tica de arquivos tsx");
|
|
11
|
+
program.command("run").action(() => {
|
|
12
|
+
run();
|
|
13
|
+
});
|
|
14
|
+
program.command("init").action(() => {
|
|
15
|
+
init();
|
|
16
|
+
});
|
|
17
|
+
program.parse();
|
|
18
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { run, init } from '../core/index.js';\nimport { Command } from 'commander';\nconst program = new Command();\n\nprogram\n .name('@scopeact/autoi18n')\n .description('CLI para geração de arquivos e tradução automática de arquivos tsx');\n\nprogram\n .command('run')\n .action(() => {\n run();\n });\n\nprogram\n .command('init')\n .action(() => {\n init();\n });\n\nprogram.parse();"],"mappings":";;;;;;;AAGA,SAAS,eAAe;AACxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,oBAAoB,EACzB,YAAY,mFAAoE;AAEnF,QACG,QAAQ,KAAK,EACb,OAAO,MAAM;AACZ,MAAI;AACN,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,OAAO,MAAM;AACZ,OAAK;AACP,CAAC;AAEH,QAAQ,MAAM;","names":[]}
|
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk36HQJSGIcjs = require('./chunk-36HQJSGI.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.I18nProvider = _chunk36HQJSGIcjs.I18nProvider; exports.useI18n = _chunk36HQJSGIcjs.useI18n;
|
|
10
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/client.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,mGAAC","file":"/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/client.cjs"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type I18nContextType = {
|
|
5
|
+
locale: string;
|
|
6
|
+
messages: Record<string, string>;
|
|
7
|
+
t: (key: string) => string;
|
|
8
|
+
setLocale: (newLocale: string) => void;
|
|
9
|
+
};
|
|
10
|
+
declare function I18nProvider({ children, locale: initialLocale, messages: initialMessages }: {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
locale: string;
|
|
13
|
+
messages: Record<string, string>;
|
|
14
|
+
}): react_jsx_runtime.JSX.Element;
|
|
15
|
+
declare function useI18n(): I18nContextType;
|
|
16
|
+
|
|
17
|
+
export { I18nProvider, useI18n };
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type I18nContextType = {
|
|
5
|
+
locale: string;
|
|
6
|
+
messages: Record<string, string>;
|
|
7
|
+
t: (key: string) => string;
|
|
8
|
+
setLocale: (newLocale: string) => void;
|
|
9
|
+
};
|
|
10
|
+
declare function I18nProvider({ children, locale: initialLocale, messages: initialMessages }: {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
locale: string;
|
|
13
|
+
messages: Record<string, string>;
|
|
14
|
+
}): react_jsx_runtime.JSX.Element;
|
|
15
|
+
declare function useI18n(): I18nContextType;
|
|
16
|
+
|
|
17
|
+
export { I18nProvider, useI18n };
|
package/dist/client.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/core/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACF,2EAAC","file":"/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/core/index.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkTWTG4RTIcjs = require('./chunk-TWTG4RTI.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkTJT6ONONcjs = require('./chunk-TJT6ONON.cjs');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
var _chunk36HQJSGIcjs = require('./chunk-36HQJSGI.cjs');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
exports.I18nProvider = _chunk36HQJSGIcjs.I18nProvider; exports.getI18n = _chunkTJT6ONONcjs.getI18n; exports.getI18nConfig = _chunkTJT6ONONcjs.getI18nConfig; exports.init = _chunkTWTG4RTIcjs.init; exports.run = _chunkTWTG4RTIcjs.run; exports.useI18n = _chunk36HQJSGIcjs.useI18n;
|
|
21
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,qRAAC","file":"/home/runner/work/auto-i18n/auto-i18n/packages/autoi18n/dist/index.cjs"}
|
package/dist/index.d.cts
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export {};
|
|
3
|
-
|
|
1
|
+
export { init, run } from './core/index.js';
|
|
2
|
+
export { getI18n, getI18nConfig } from './server.js';
|
|
3
|
+
export { I18nProvider, useI18n } from './client.js';
|
|
4
|
+
import 'react/jsx-runtime';
|
|
5
|
+
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
import {
|
|
2
|
+
init,
|
|
3
|
+
run
|
|
4
|
+
} from "./chunk-RLNUAAKC.js";
|
|
5
|
+
import {
|
|
6
|
+
getI18n,
|
|
7
|
+
getI18nConfig
|
|
8
|
+
} from "./chunk-VBBY4GSW.js";
|
|
9
|
+
import {
|
|
10
|
+
I18nProvider,
|
|
11
|
+
useI18n
|
|
12
|
+
} from "./chunk-NYRK5OWZ.js";
|
|
13
|
+
export {
|
|
14
|
+
I18nProvider,
|
|
15
|
+
getI18n,
|
|
16
|
+
getI18nConfig,
|
|
17
|
+
init,
|
|
18
|
+
run,
|
|
19
|
+
useI18n
|
|
20
|
+
};
|
|
19
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkTJT6ONONcjs = require('./chunk-TJT6ONON.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
exports.getI18n = _chunkTJT6ONONcjs.getI18n; exports.getI18nConfig = _chunkTJT6ONONcjs.getI18nConfig;
|
|
9
|
+
//# sourceMappingURL=server.cjs.map
|