@better-translate/cli 2.0.0 → 3.0.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/README.md +97 -0
- package/dist/ai-sdk-generator-QEGOC4LN.js +94 -0
- package/dist/ai-sdk-generator.d.ts.map +1 -1
- package/dist/bin.js +21 -7
- package/dist/{chunk-NRZIFUEW.js → chunk-RBZAR5EL.js} +155 -34
- package/dist/chunk-VYOBAIBH.js +8 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config.d.ts +1 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -5
- package/dist/confirm.d.ts +3 -0
- package/dist/confirm.d.ts.map +1 -0
- package/dist/generate.d.ts.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -6
- package/dist/types.d.ts +22 -12
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/ai-sdk-generator-WPQCTPGA.js +0 -37
- package/dist/chunk-WMIZO3GE.js +0 -19
- package/dist/provider-models.d.ts +0 -5
- package/dist/provider-models.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -2,4 +2,101 @@
|
|
|
2
2
|
|
|
3
3
|
`@better-translate/cli` extracts marked source strings into your source locale file, generates translated message files, and localizes markdown. Use it when you want Better Translate to create or update locale files for you.
|
|
4
4
|
|
|
5
|
+
Install the CLI and the provider package you want to use in your own project:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install -D @better-translate/cli @ai-sdk/openai
|
|
9
|
+
# or: npm install -D @better-translate/cli @ai-sdk/anthropic
|
|
10
|
+
# or: npm install -D @better-translate/cli @ai-sdk/moonshotai
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then configure the CLI with a real AI SDK language model. The flow is the same for any provider package:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { openai } from "@ai-sdk/openai";
|
|
17
|
+
import { defineConfig } from "@better-translate/cli/config";
|
|
18
|
+
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
sourceLocale: "en",
|
|
21
|
+
locales: ["es", "fr"],
|
|
22
|
+
model: openai("gpt-5"),
|
|
23
|
+
messages: {
|
|
24
|
+
entry: "./src/messages/en.json",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
31
|
+
import { defineConfig } from "@better-translate/cli/config";
|
|
32
|
+
|
|
33
|
+
export default defineConfig({
|
|
34
|
+
sourceLocale: "en",
|
|
35
|
+
locales: ["es", "fr"],
|
|
36
|
+
model: anthropic("claude-sonnet-4-5"),
|
|
37
|
+
messages: {
|
|
38
|
+
entry: "./src/messages/en.json",
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { moonshotai } from "@ai-sdk/moonshotai";
|
|
45
|
+
import { defineConfig } from "@better-translate/cli/config";
|
|
46
|
+
|
|
47
|
+
export default defineConfig({
|
|
48
|
+
sourceLocale: "en",
|
|
49
|
+
locales: ["es", "fr"],
|
|
50
|
+
model: moonshotai("kimi-k2-0905-preview"),
|
|
51
|
+
messages: {
|
|
52
|
+
entry: "./src/messages/en.json",
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If you need provider-specific settings, create the model in your app first and pass it through. Credentials and provider configuration stay entirely in the provider package setup:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
61
|
+
import { defineConfig } from "@better-translate/cli/config";
|
|
62
|
+
|
|
63
|
+
const model = createOpenAI({
|
|
64
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
65
|
+
baseURL: process.env.OPENAI_BASE_URL,
|
|
66
|
+
})("gpt-5");
|
|
67
|
+
|
|
68
|
+
export default defineConfig({
|
|
69
|
+
sourceLocale: "en",
|
|
70
|
+
locales: ["es", "fr"],
|
|
71
|
+
model,
|
|
72
|
+
messages: {
|
|
73
|
+
entry: "./src/messages/en.json",
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
5
78
|
Full docs: [better-translate-placeholder.com/en/docs/cli](https://better-translate-placeholder.com/en/docs/cli)
|
|
79
|
+
|
|
80
|
+
## Commands
|
|
81
|
+
|
|
82
|
+
Extract new source keys:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
npx bt extract
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Generate translated locale files:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
npx bt generate
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
When markdown generation is enabled and `bt generate` would create or overwrite translated `.md` or `.mdx` files, the CLI asks for confirmation before it makes changes.
|
|
95
|
+
|
|
96
|
+
Use `--yes` or `-y` to skip that confirmation, especially in CI or other non-interactive environments:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
npx bt generate --yes
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
In non-interactive environments, markdown generation requires `--yes` when translated markdown files would be written.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/ai-sdk-generator.ts
|
|
2
|
+
function validateGeneratedValue(value, request) {
|
|
3
|
+
if (!request.validate) {
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
return request.validate(value);
|
|
7
|
+
}
|
|
8
|
+
function createOutputValidator(request) {
|
|
9
|
+
return {
|
|
10
|
+
validate(value) {
|
|
11
|
+
try {
|
|
12
|
+
return {
|
|
13
|
+
success: true,
|
|
14
|
+
value: validateGeneratedValue(value, request)
|
|
15
|
+
};
|
|
16
|
+
} catch (error) {
|
|
17
|
+
return {
|
|
18
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
19
|
+
success: false
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function isSchemaTooLargeError(error) {
|
|
26
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
27
|
+
const normalizedMessage = message.toLowerCase();
|
|
28
|
+
return normalizedMessage.includes("compiled grammar is too large") || normalizedMessage.includes("reduce the number of strict tools") || normalizedMessage.includes("tool schemas exceed") || normalizedMessage.includes("tool schema size") || normalizedMessage.includes("exceeds maximum schema size") || normalizedMessage.includes("too many tools");
|
|
29
|
+
}
|
|
30
|
+
function extractJsonPayload(text) {
|
|
31
|
+
const trimmed = text.trim();
|
|
32
|
+
const fencedMatch = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);
|
|
33
|
+
if (fencedMatch?.[1]) {
|
|
34
|
+
return fencedMatch[1].trim();
|
|
35
|
+
}
|
|
36
|
+
const firstBrace = trimmed.indexOf("{");
|
|
37
|
+
const lastBrace = trimmed.lastIndexOf("}");
|
|
38
|
+
if (firstBrace >= 0 && lastBrace > firstBrace) {
|
|
39
|
+
return trimmed.slice(firstBrace, lastBrace + 1);
|
|
40
|
+
}
|
|
41
|
+
return trimmed;
|
|
42
|
+
}
|
|
43
|
+
function parseJsonText(text, request) {
|
|
44
|
+
if (!request.validate) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`Fallback JSON parsing failed for "${request.sourcePath}": no validator provided`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const payload = extractJsonPayload(text);
|
|
50
|
+
try {
|
|
51
|
+
return validateGeneratedValue(JSON.parse(payload), request);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Fallback JSON parsing failed for "${request.sourcePath}": ${reason}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function generateWithAiSdk(model, request) {
|
|
60
|
+
const { Output, generateText, jsonSchema } = await import("ai");
|
|
61
|
+
const baseInput = {
|
|
62
|
+
model,
|
|
63
|
+
prompt: request.prompt,
|
|
64
|
+
system: request.system,
|
|
65
|
+
temperature: 0
|
|
66
|
+
};
|
|
67
|
+
try {
|
|
68
|
+
const result = await generateText({
|
|
69
|
+
...baseInput,
|
|
70
|
+
experimental_output: Output.object({
|
|
71
|
+
schema: jsonSchema(request.schema, createOutputValidator(request))
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
return result.experimental_output;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (!isSchemaTooLargeError(error)) {
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const fallbackResult = await generateText({
|
|
81
|
+
...baseInput,
|
|
82
|
+
prompt: [
|
|
83
|
+
request.prompt,
|
|
84
|
+
"",
|
|
85
|
+
"Return only a valid JSON object that matches the required shape exactly.",
|
|
86
|
+
"Do not wrap the JSON in markdown fences."
|
|
87
|
+
].join("\n"),
|
|
88
|
+
system: `${request.system} Return only valid JSON.`
|
|
89
|
+
});
|
|
90
|
+
return parseJsonText(fallbackResult.text, request);
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
generateWithAiSdk
|
|
94
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-sdk-generator.d.ts","sourceRoot":"","sources":["../src/ai-sdk-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ai-sdk-generator.d.ts","sourceRoot":"","sources":["../src/ai-sdk-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAiG9D,wBAAsB,iBAAiB,CAAC,OAAO,EAC7C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC5C,OAAO,CAAC,OAAO,CAAC,CAoClB"}
|
package/dist/bin.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
extractProject,
|
|
4
4
|
generateProject
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RBZAR5EL.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
8
8
|
import pc2 from "picocolors";
|
|
@@ -70,7 +70,7 @@ ${pc.magenta("\u25C6")} locale: ${pc.bold(localeMatch[1])}`);
|
|
|
70
70
|
spinner.stopAndPersist({ symbol: "\u25CC", text: pc.dim(message) });
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
-
if (message.startsWith("Using AI Gateway model:") || message.startsWith("Using
|
|
73
|
+
if (message.startsWith("Using AI Gateway model:") || message.startsWith("Using configured provider model:") || message.startsWith("Source locale:") || message.startsWith("Target locales:")) {
|
|
74
74
|
spinner.stop();
|
|
75
75
|
console.log(pc.dim(message));
|
|
76
76
|
return;
|
|
@@ -137,19 +137,24 @@ function usage() {
|
|
|
137
137
|
return [
|
|
138
138
|
"Usage:",
|
|
139
139
|
" bt extract [--config ./better-translate.config.ts] [--dry-run] [--max-length 40]",
|
|
140
|
-
" bt generate [--config ./better-translate.config.ts] [--dry-run]"
|
|
140
|
+
" bt generate [--config ./better-translate.config.ts] [--dry-run] [--yes|-y]"
|
|
141
141
|
].join("\n");
|
|
142
142
|
}
|
|
143
143
|
function parseCommonArgs(argv) {
|
|
144
144
|
let configPath;
|
|
145
145
|
let dryRun = false;
|
|
146
146
|
let maxLength;
|
|
147
|
+
let yes = false;
|
|
147
148
|
for (let index = 0; index < argv.length; index += 1) {
|
|
148
149
|
const arg = argv[index];
|
|
149
150
|
if (arg === "--dry-run") {
|
|
150
151
|
dryRun = true;
|
|
151
152
|
continue;
|
|
152
153
|
}
|
|
154
|
+
if (arg === "--yes" || arg === "-y") {
|
|
155
|
+
yes = true;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
153
158
|
if (arg === "--config" || arg === "-c") {
|
|
154
159
|
const value = argv[index + 1];
|
|
155
160
|
if (!value) {
|
|
@@ -180,12 +185,15 @@ function parseCommonArgs(argv) {
|
|
|
180
185
|
return {
|
|
181
186
|
configPath,
|
|
182
187
|
dryRun,
|
|
183
|
-
maxLength
|
|
188
|
+
maxLength,
|
|
189
|
+
yes
|
|
184
190
|
};
|
|
185
191
|
}
|
|
186
192
|
async function runCli(argv = process.argv.slice(2), options = {}) {
|
|
187
193
|
const stderr = options.stderr ?? console.error;
|
|
188
194
|
const stdout = options.stdout ?? console.log;
|
|
195
|
+
const extractProjectImpl = options.extractProjectImpl ?? extractProject;
|
|
196
|
+
const generateProjectImpl = options.generateProjectImpl ?? generateProject;
|
|
189
197
|
const [command, ...args] = argv;
|
|
190
198
|
if (!command || command === "--help" || command === "-h") {
|
|
191
199
|
stdout(usage());
|
|
@@ -200,12 +208,17 @@ ${usage()}`);
|
|
|
200
208
|
const parsed = parseCommonArgs(args);
|
|
201
209
|
if (command === "generate" && parsed.maxLength !== void 0) {
|
|
202
210
|
stderr(`--max-length is not valid for "generate".
|
|
211
|
+
${usage()}`);
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
if (command === "extract" && parsed.yes) {
|
|
215
|
+
stderr(`--yes is not valid for "extract".
|
|
203
216
|
${usage()}`);
|
|
204
217
|
return 1;
|
|
205
218
|
}
|
|
206
219
|
console.log(pc2.bold("\n better-translate\n"));
|
|
207
220
|
if (command === "extract") {
|
|
208
|
-
await
|
|
221
|
+
await extractProjectImpl({
|
|
209
222
|
configPath: parsed.configPath,
|
|
210
223
|
cwd: options.cwd,
|
|
211
224
|
dryRun: parsed.dryRun,
|
|
@@ -213,11 +226,12 @@ ${usage()}`);
|
|
|
213
226
|
maxLength: parsed.maxLength
|
|
214
227
|
});
|
|
215
228
|
} else {
|
|
216
|
-
await
|
|
229
|
+
await generateProjectImpl({
|
|
217
230
|
configPath: parsed.configPath,
|
|
218
231
|
cwd: options.cwd,
|
|
219
232
|
dryRun: parsed.dryRun,
|
|
220
|
-
logger: createSpinnerLogger()
|
|
233
|
+
logger: createSpinnerLogger(),
|
|
234
|
+
yes: parsed.yes
|
|
221
235
|
});
|
|
222
236
|
}
|
|
223
237
|
return 0;
|
|
@@ -179,33 +179,32 @@ function toJavaScriptIdentifier(value) {
|
|
|
179
179
|
|
|
180
180
|
// src/config-loader.ts
|
|
181
181
|
var DEFAULT_CONFIG_FILE = "better-translate.config.ts";
|
|
182
|
-
function
|
|
182
|
+
function resolveCliLanguageModel(model) {
|
|
183
183
|
assert(
|
|
184
184
|
isRecord(model),
|
|
185
|
-
|
|
185
|
+
"Config requires model to be a non-empty string or an AI SDK language model instance."
|
|
186
186
|
);
|
|
187
187
|
assert(
|
|
188
|
-
model.
|
|
189
|
-
|
|
188
|
+
model.specificationVersion === "v3",
|
|
189
|
+
"Config requires model to be a non-empty string or an AI SDK language model instance."
|
|
190
190
|
);
|
|
191
191
|
assert(
|
|
192
|
-
model.provider === "
|
|
193
|
-
|
|
192
|
+
typeof model.provider === "string" && model.provider.trim().length > 0,
|
|
193
|
+
"AI SDK language model instances require a non-empty provider string."
|
|
194
194
|
);
|
|
195
195
|
assert(
|
|
196
196
|
typeof model.modelId === "string" && model.modelId.trim().length > 0,
|
|
197
|
-
|
|
197
|
+
"AI SDK language model instances require a non-empty modelId string."
|
|
198
198
|
);
|
|
199
199
|
assert(
|
|
200
|
-
typeof model.
|
|
201
|
-
|
|
200
|
+
typeof model.doGenerate === "function",
|
|
201
|
+
"AI SDK language model instances must provide a doGenerate function."
|
|
202
202
|
);
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
};
|
|
203
|
+
assert(
|
|
204
|
+
typeof model.doStream === "function",
|
|
205
|
+
"AI SDK language model instances must provide a doStream function."
|
|
206
|
+
);
|
|
207
|
+
return model;
|
|
209
208
|
}
|
|
210
209
|
function resolveConfig(rawConfig, configDirectory) {
|
|
211
210
|
assert(
|
|
@@ -271,7 +270,7 @@ function resolveConfig(rawConfig, configDirectory) {
|
|
|
271
270
|
if (typeof model === "string") {
|
|
272
271
|
assert(
|
|
273
272
|
model.trim().length > 0,
|
|
274
|
-
'Config requires a non-empty model string, for example "
|
|
273
|
+
'Config requires a non-empty model string, for example "provider/model-id".'
|
|
275
274
|
);
|
|
276
275
|
assert(
|
|
277
276
|
isRecord(gateway),
|
|
@@ -291,9 +290,9 @@ function resolveConfig(rawConfig, configDirectory) {
|
|
|
291
290
|
}
|
|
292
291
|
assert(
|
|
293
292
|
gateway === void 0,
|
|
294
|
-
"Config must not include gateway when model is
|
|
293
|
+
"Config must not include gateway when model is an AI SDK language model instance."
|
|
295
294
|
);
|
|
296
|
-
const resolvedModel =
|
|
295
|
+
const resolvedModel = resolveCliLanguageModel(model);
|
|
297
296
|
return {
|
|
298
297
|
...resolvedBase,
|
|
299
298
|
model: resolvedModel
|
|
@@ -932,12 +931,85 @@ async function extractProject(options = {}) {
|
|
|
932
931
|
}
|
|
933
932
|
|
|
934
933
|
// src/generate.ts
|
|
935
|
-
import { mkdir, writeFile as writeFile3 } from "fs/promises";
|
|
936
|
-
import
|
|
934
|
+
import { access, mkdir, writeFile as writeFile3 } from "fs/promises";
|
|
935
|
+
import path8 from "path";
|
|
936
|
+
|
|
937
|
+
// src/confirm.ts
|
|
938
|
+
import path6 from "path";
|
|
939
|
+
import readline from "readline";
|
|
940
|
+
var MAX_PREVIEW_WRITES = 5;
|
|
941
|
+
function pluralize(count, singular, plural) {
|
|
942
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
943
|
+
}
|
|
944
|
+
function formatSummary(request) {
|
|
945
|
+
const parts = [];
|
|
946
|
+
if (request.createCount > 0) {
|
|
947
|
+
parts.push(`create ${pluralize(request.createCount, "new file", "new files")}`);
|
|
948
|
+
}
|
|
949
|
+
if (request.overwriteCount > 0) {
|
|
950
|
+
parts.push(
|
|
951
|
+
`overwrite ${pluralize(request.overwriteCount, "existing file", "existing files")}`
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
if (parts.length === 0) {
|
|
955
|
+
return "write translated markdown files";
|
|
956
|
+
}
|
|
957
|
+
if (parts.length === 1) {
|
|
958
|
+
return parts[0] ?? "write translated markdown files";
|
|
959
|
+
}
|
|
960
|
+
return `${parts[0]} and ${parts[1]}`;
|
|
961
|
+
}
|
|
962
|
+
function formatTargetPath(targetPath, projectCwd) {
|
|
963
|
+
const relativePath = path6.relative(projectCwd, targetPath);
|
|
964
|
+
if (relativePath.length > 0 && !relativePath.startsWith("..") && !path6.isAbsolute(relativePath)) {
|
|
965
|
+
return relativePath;
|
|
966
|
+
}
|
|
967
|
+
return targetPath;
|
|
968
|
+
}
|
|
969
|
+
async function confirmMarkdownWrites(request) {
|
|
970
|
+
if (request.writes.length === 0) {
|
|
971
|
+
return true;
|
|
972
|
+
}
|
|
973
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
974
|
+
throw new Error(
|
|
975
|
+
"Markdown translation would create or overwrite translated .md/.mdx files in a non-interactive environment. Re-run with --yes to continue."
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
const locales = Array.from(new Set(request.writes.map((write) => write.locale))).sort().join(", ");
|
|
979
|
+
const projectCwd = request.projectCwd ?? process.cwd();
|
|
980
|
+
const previewWrites = request.writes.slice(0, MAX_PREVIEW_WRITES);
|
|
981
|
+
const remainingCount = request.writes.length - previewWrites.length;
|
|
982
|
+
const preview = previewWrites.map(
|
|
983
|
+
(write) => ` - ${write.action}: ${formatTargetPath(write.targetPath, projectCwd)}`
|
|
984
|
+
).join("\n");
|
|
985
|
+
const prompt = [
|
|
986
|
+
"",
|
|
987
|
+
`This run will ${formatSummary(request)} as translated markdown files (.md/.mdx).`,
|
|
988
|
+
`Target locales: ${locales}`,
|
|
989
|
+
"Planned markdown writes:",
|
|
990
|
+
preview,
|
|
991
|
+
remainingCount > 0 ? ` - ...and ${remainingCount} more planned write${remainingCount === 1 ? "" : "s"}` : "",
|
|
992
|
+
"",
|
|
993
|
+
"Continue? [y/N] "
|
|
994
|
+
].filter(Boolean).join("\n");
|
|
995
|
+
const rl = readline.createInterface({
|
|
996
|
+
input: process.stdin,
|
|
997
|
+
output: process.stdout
|
|
998
|
+
});
|
|
999
|
+
try {
|
|
1000
|
+
const answer = await new Promise((resolve) => {
|
|
1001
|
+
rl.question(prompt, resolve);
|
|
1002
|
+
});
|
|
1003
|
+
const normalized = answer.trim().toLowerCase();
|
|
1004
|
+
return normalized === "y" || normalized === "yes";
|
|
1005
|
+
} finally {
|
|
1006
|
+
rl.close();
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
937
1009
|
|
|
938
1010
|
// src/markdown.ts
|
|
939
1011
|
import { readdir as readdir2, readFile as readFile4 } from "fs/promises";
|
|
940
|
-
import
|
|
1012
|
+
import path7 from "path";
|
|
941
1013
|
import matter from "gray-matter";
|
|
942
1014
|
async function walkDirectory(directory) {
|
|
943
1015
|
const entries = await readdir2(directory, {
|
|
@@ -945,7 +1017,7 @@ async function walkDirectory(directory) {
|
|
|
945
1017
|
});
|
|
946
1018
|
const files = await Promise.all(
|
|
947
1019
|
entries.map(async (entry) => {
|
|
948
|
-
const entryPath =
|
|
1020
|
+
const entryPath = path7.join(directory, entry.name);
|
|
949
1021
|
if (entry.isDirectory()) {
|
|
950
1022
|
return walkDirectory(entryPath);
|
|
951
1023
|
}
|
|
@@ -1035,7 +1107,7 @@ async function loadMarkdownDocument(rootDir, sourcePath) {
|
|
|
1035
1107
|
const parsed = matter(sourceText);
|
|
1036
1108
|
const frontmatter = isRecord(parsed.data) ? parsed.data : {};
|
|
1037
1109
|
const frontmatterStrings = extractFrontmatterStrings(frontmatter);
|
|
1038
|
-
const relativePath =
|
|
1110
|
+
const relativePath = path7.relative(rootDir, sourcePath).split(path7.sep).join("/");
|
|
1039
1111
|
return {
|
|
1040
1112
|
body: parsed.content,
|
|
1041
1113
|
frontmatter,
|
|
@@ -1047,15 +1119,15 @@ async function loadMarkdownDocument(rootDir, sourcePath) {
|
|
|
1047
1119
|
};
|
|
1048
1120
|
}
|
|
1049
1121
|
function deriveTargetMarkdownRoot(rootDir, sourceLocale, targetLocale) {
|
|
1050
|
-
const basename =
|
|
1122
|
+
const basename = path7.basename(rootDir);
|
|
1051
1123
|
assert(
|
|
1052
1124
|
basename === sourceLocale,
|
|
1053
1125
|
`markdown.rootDir must end with the source locale "${sourceLocale}" so the CLI can mirror sibling locale folders.`
|
|
1054
1126
|
);
|
|
1055
|
-
return
|
|
1127
|
+
return path7.join(path7.dirname(rootDir), targetLocale);
|
|
1056
1128
|
}
|
|
1057
1129
|
function deriveTargetMarkdownPath(rootDir, sourceLocale, targetLocale, relativePath) {
|
|
1058
|
-
return
|
|
1130
|
+
return path7.join(
|
|
1059
1131
|
deriveTargetMarkdownRoot(rootDir, sourceLocale, targetLocale),
|
|
1060
1132
|
relativePath
|
|
1061
1133
|
);
|
|
@@ -1151,6 +1223,46 @@ function createConsoleLogger() {
|
|
|
1151
1223
|
function describeError(error) {
|
|
1152
1224
|
return error instanceof Error ? error.message : String(error);
|
|
1153
1225
|
}
|
|
1226
|
+
async function pathExists(filePath) {
|
|
1227
|
+
try {
|
|
1228
|
+
await access(filePath);
|
|
1229
|
+
return true;
|
|
1230
|
+
} catch (error) {
|
|
1231
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
throw error;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
function toMarkdownRelativePath(rootDir, sourcePath) {
|
|
1238
|
+
return path8.relative(rootDir, sourcePath).split(path8.sep).join("/");
|
|
1239
|
+
}
|
|
1240
|
+
async function createMarkdownWriteConfirmationRequest(options) {
|
|
1241
|
+
const writes = await Promise.all(
|
|
1242
|
+
options.locales.flatMap(
|
|
1243
|
+
(locale) => options.sourcePaths.map(async (sourcePath) => {
|
|
1244
|
+
const targetPath = deriveTargetMarkdownPath(
|
|
1245
|
+
options.markdownRootDir,
|
|
1246
|
+
options.sourceLocale,
|
|
1247
|
+
locale,
|
|
1248
|
+
toMarkdownRelativePath(options.markdownRootDir, sourcePath)
|
|
1249
|
+
);
|
|
1250
|
+
return {
|
|
1251
|
+
action: await pathExists(targetPath) ? "overwrite" : "create",
|
|
1252
|
+
locale,
|
|
1253
|
+
sourcePath,
|
|
1254
|
+
targetPath
|
|
1255
|
+
};
|
|
1256
|
+
})
|
|
1257
|
+
)
|
|
1258
|
+
);
|
|
1259
|
+
return {
|
|
1260
|
+
createCount: writes.filter((write) => write.action === "create").length,
|
|
1261
|
+
overwriteCount: writes.filter((write) => write.action === "overwrite").length,
|
|
1262
|
+
projectCwd: options.projectCwd,
|
|
1263
|
+
writes
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1154
1266
|
async function persistWrite(write, options) {
|
|
1155
1267
|
if (options.dryRun) {
|
|
1156
1268
|
options.logger.info(
|
|
@@ -1158,7 +1270,7 @@ async function persistWrite(write, options) {
|
|
|
1158
1270
|
);
|
|
1159
1271
|
return;
|
|
1160
1272
|
}
|
|
1161
|
-
await mkdir(
|
|
1273
|
+
await mkdir(path8.dirname(write.targetPath), {
|
|
1162
1274
|
recursive: true
|
|
1163
1275
|
});
|
|
1164
1276
|
await writeFile3(write.targetPath, write.content, "utf8");
|
|
@@ -1174,7 +1286,7 @@ function prepareGatewayEnvironment(apiKey) {
|
|
|
1174
1286
|
process.env.AI_GATEWAY_API_KEY = apiKey;
|
|
1175
1287
|
}
|
|
1176
1288
|
async function createDefaultGenerator(model) {
|
|
1177
|
-
const { generateWithAiSdk } = await import("./ai-sdk-generator-
|
|
1289
|
+
const { generateWithAiSdk } = await import("./ai-sdk-generator-QEGOC4LN.js");
|
|
1178
1290
|
return async (request) => generateWithAiSdk(model, request);
|
|
1179
1291
|
}
|
|
1180
1292
|
async function resolveRuntimeModel(config) {
|
|
@@ -1185,13 +1297,9 @@ async function resolveRuntimeModel(config) {
|
|
|
1185
1297
|
model: config.model
|
|
1186
1298
|
};
|
|
1187
1299
|
}
|
|
1188
|
-
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
1189
|
-
const provider = createOpenAI({
|
|
1190
|
-
apiKey: config.model.apiKey
|
|
1191
|
-
});
|
|
1192
1300
|
return {
|
|
1193
|
-
description: `Using
|
|
1194
|
-
model:
|
|
1301
|
+
description: `Using configured provider model: ${config.model.provider}/${config.model.modelId}`,
|
|
1302
|
+
model: config.model
|
|
1195
1303
|
};
|
|
1196
1304
|
}
|
|
1197
1305
|
function validateMarkdownTranslation(frontmatterStrings, value) {
|
|
@@ -1248,6 +1356,19 @@ async function generateProject(options = {}) {
|
|
|
1248
1356
|
} else {
|
|
1249
1357
|
logger.info("Markdown generation disabled.");
|
|
1250
1358
|
}
|
|
1359
|
+
if (config.markdown && markdownSources.length > 0 && !options.dryRun && !options.yes) {
|
|
1360
|
+
const confirmationRequest = await createMarkdownWriteConfirmationRequest({
|
|
1361
|
+
locales: config.locales,
|
|
1362
|
+
markdownRootDir: config.markdown.rootDir,
|
|
1363
|
+
projectCwd: cwd,
|
|
1364
|
+
sourceLocale: config.sourceLocale,
|
|
1365
|
+
sourcePaths: markdownSources
|
|
1366
|
+
});
|
|
1367
|
+
const confirmed = await (options.confirmMarkdownWrites ?? confirmMarkdownWrites)(confirmationRequest);
|
|
1368
|
+
if (!confirmed) {
|
|
1369
|
+
throw new Error("Markdown translation cancelled. No files were written.");
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1251
1372
|
for (const locale of config.locales) {
|
|
1252
1373
|
logger.info(`Starting locale "${locale}"...`);
|
|
1253
1374
|
const messagePrompt = createMessagesPrompt({
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { extractProject } from "./extract.js";
|
|
2
|
+
import { generateProject } from "./generate.js";
|
|
1
3
|
export declare function runCli(argv?: string[], options?: {
|
|
2
4
|
cwd?: string;
|
|
5
|
+
extractProjectImpl?: typeof extractProject;
|
|
6
|
+
generateProjectImpl?: typeof generateProject;
|
|
3
7
|
stderr?: (message: string) => void;
|
|
4
8
|
stdout?: (message: string) => void;
|
|
5
9
|
}): Promise<number>;
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAgFhD,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,OAAO,cAAc,CAAC;IAC3C,mBAAmB,CAAC,EAAE,OAAO,eAAe,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,GACL,OAAO,CAAC,MAAM,CAAC,CA2DjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,8BAA8B,EAE/B,MAAM,YAAY,CAAC;AAsJpB,wBAAsB,aAAa,CACjC,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACT,GACL,OAAO,CAAC,8BAA8B,CAAC,CAyBzC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { defineConfig } from "./define-config.js";
|
|
2
|
-
export {
|
|
3
|
-
export type { BetterTranslateCliConfig, MarkdownExtension, OpenAIProviderModelSpec, } from "./types.js";
|
|
2
|
+
export type { BetterTranslateCliConfig, BetterTranslateCliDirectModelConfig, CliLanguageModel, MarkdownExtension, } from "./types.js";
|
|
4
3
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,YAAY,EACV,wBAAwB,EACxB,mCAAmC,EACnC,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../src/confirm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAC;AA8CnE,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,OAAO,CAAC,CAqDlB"}
|
package/dist/generate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAGV,sBAAsB,EACtB,qBAAqB,EAKtB,MAAM,YAAY,CAAC;AAqKpB,wBAAsB,eAAe,CACnC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAoMhC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,5 @@ export { loadCliConfig } from "./config-loader.js";
|
|
|
2
2
|
export { defineConfig } from "./define-config.js";
|
|
3
3
|
export { extractProject } from "./extract.js";
|
|
4
4
|
export { generateProject } from "./generate.js";
|
|
5
|
-
export {
|
|
6
|
-
export type { BetterTranslateCliConfig, BetterTranslateCliGatewayConfig, BetterTranslateCliOpenAIConfig, CliLogger, ExtractProjectOptions, ExtractProjectResult, CliWriteOperation, GenerateProjectOptions, GenerateProjectResult, LoadedBetterTranslateCliConfig, MarkdownExtension, OpenAIProviderModelSpec, ResolvedBetterTranslateCliConfig, ResolvedBetterTranslateCliGatewayConfig, ResolvedBetterTranslateCliOpenAIConfig, StructuredGenerationRequest, StructuredGenerator, } from "./types.js";
|
|
5
|
+
export type { BetterTranslateCliConfig, BetterTranslateCliDirectModelConfig, BetterTranslateCliGatewayConfig, CliLanguageModel, CliLogger, ExtractProjectOptions, ExtractProjectResult, CliWriteOperation, GenerateProjectOptions, GenerateProjectResult, LoadedBetterTranslateCliConfig, MarkdownWriteConfirmationEntry, MarkdownWriteConfirmationRequest, MarkdownExtension, ResolvedBetterTranslateCliConfig, ResolvedBetterTranslateCliDirectModelConfig, ResolvedBetterTranslateCliGatewayConfig, StructuredGenerationRequest, StructuredGenerator, } from "./types.js";
|
|
7
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,YAAY,EACV,wBAAwB,EACxB,mCAAmC,EACnC,+BAA+B,EAC/B,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,EAC9B,8BAA8B,EAC9B,gCAAgC,EAChC,iBAAiB,EACjB,gCAAgC,EAChC,2CAA2C,EAC3C,uCAAuC,EACvC,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,15 +2,13 @@ import {
|
|
|
2
2
|
extractProject,
|
|
3
3
|
generateProject,
|
|
4
4
|
loadCliConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RBZAR5EL.js";
|
|
6
6
|
import {
|
|
7
|
-
defineConfig
|
|
8
|
-
|
|
9
|
-
} from "./chunk-WMIZO3GE.js";
|
|
7
|
+
defineConfig
|
|
8
|
+
} from "./chunk-VYOBAIBH.js";
|
|
10
9
|
export {
|
|
11
10
|
defineConfig,
|
|
12
11
|
extractProject,
|
|
13
12
|
generateProject,
|
|
14
|
-
loadCliConfig
|
|
15
|
-
openai
|
|
13
|
+
loadCliConfig
|
|
16
14
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { LanguageModelV3 } from "@ai-sdk/provider";
|
|
1
2
|
export type MarkdownExtension = ".md" | ".mdx";
|
|
3
|
+
export type CliLanguageModel = LanguageModelV3;
|
|
2
4
|
interface BetterTranslateCliConfigBase {
|
|
3
5
|
locales: string[];
|
|
4
6
|
markdown?: {
|
|
@@ -10,23 +12,17 @@ interface BetterTranslateCliConfigBase {
|
|
|
10
12
|
};
|
|
11
13
|
sourceLocale: string;
|
|
12
14
|
}
|
|
13
|
-
export interface OpenAIProviderModelSpec {
|
|
14
|
-
apiKey: string;
|
|
15
|
-
kind: "provider-model";
|
|
16
|
-
modelId: string;
|
|
17
|
-
provider: "openai";
|
|
18
|
-
}
|
|
19
15
|
export interface BetterTranslateCliGatewayConfig extends BetterTranslateCliConfigBase {
|
|
20
16
|
gateway: {
|
|
21
17
|
apiKey: string;
|
|
22
18
|
};
|
|
23
19
|
model: string;
|
|
24
20
|
}
|
|
25
|
-
export interface
|
|
21
|
+
export interface BetterTranslateCliDirectModelConfig extends BetterTranslateCliConfigBase {
|
|
26
22
|
gateway?: never;
|
|
27
|
-
model:
|
|
23
|
+
model: CliLanguageModel;
|
|
28
24
|
}
|
|
29
|
-
export type BetterTranslateCliConfig = BetterTranslateCliGatewayConfig |
|
|
25
|
+
export type BetterTranslateCliConfig = BetterTranslateCliGatewayConfig | BetterTranslateCliDirectModelConfig;
|
|
30
26
|
interface ResolvedBetterTranslateCliConfigBase {
|
|
31
27
|
locales: readonly string[];
|
|
32
28
|
markdown?: {
|
|
@@ -44,10 +40,10 @@ export interface ResolvedBetterTranslateCliGatewayConfig extends ResolvedBetterT
|
|
|
44
40
|
};
|
|
45
41
|
model: string;
|
|
46
42
|
}
|
|
47
|
-
export interface
|
|
48
|
-
model:
|
|
43
|
+
export interface ResolvedBetterTranslateCliDirectModelConfig extends ResolvedBetterTranslateCliConfigBase {
|
|
44
|
+
model: CliLanguageModel;
|
|
49
45
|
}
|
|
50
|
-
export type ResolvedBetterTranslateCliConfig = ResolvedBetterTranslateCliGatewayConfig |
|
|
46
|
+
export type ResolvedBetterTranslateCliConfig = ResolvedBetterTranslateCliGatewayConfig | ResolvedBetterTranslateCliDirectModelConfig;
|
|
51
47
|
export interface LoadedBetterTranslateCliConfig {
|
|
52
48
|
config: ResolvedBetterTranslateCliConfig;
|
|
53
49
|
directory: string;
|
|
@@ -60,6 +56,18 @@ export interface CliWriteOperation {
|
|
|
60
56
|
sourcePath: string;
|
|
61
57
|
targetPath: string;
|
|
62
58
|
}
|
|
59
|
+
export interface MarkdownWriteConfirmationEntry {
|
|
60
|
+
action: "create" | "overwrite";
|
|
61
|
+
locale: string;
|
|
62
|
+
sourcePath: string;
|
|
63
|
+
targetPath: string;
|
|
64
|
+
}
|
|
65
|
+
export interface MarkdownWriteConfirmationRequest {
|
|
66
|
+
createCount: number;
|
|
67
|
+
overwriteCount: number;
|
|
68
|
+
projectCwd?: string;
|
|
69
|
+
writes: readonly MarkdownWriteConfirmationEntry[];
|
|
70
|
+
}
|
|
63
71
|
export interface CliLogger {
|
|
64
72
|
error(message: string): void;
|
|
65
73
|
info(message: string): void;
|
|
@@ -76,10 +84,12 @@ export interface StructuredGenerationRequest<TOutput> {
|
|
|
76
84
|
export type StructuredGenerator = <TOutput>(request: StructuredGenerationRequest<TOutput>) => Promise<TOutput>;
|
|
77
85
|
export interface GenerateProjectOptions {
|
|
78
86
|
configPath?: string;
|
|
87
|
+
confirmMarkdownWrites?: (request: MarkdownWriteConfirmationRequest) => Promise<boolean>;
|
|
79
88
|
cwd?: string;
|
|
80
89
|
dryRun?: boolean;
|
|
81
90
|
generator?: StructuredGenerator;
|
|
82
91
|
logger?: CliLogger;
|
|
92
|
+
yes?: boolean;
|
|
83
93
|
}
|
|
84
94
|
export interface GenerateProjectResult {
|
|
85
95
|
dryRun: boolean;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,CAAC;AAE/C,UAAU,4BAA4B;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE;QACT,UAAU,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;QAC1C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-translate/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "AI-powered translation generation CLI for Better Translate.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"url": "https://github.com/jralvarenga/better-translate/issues"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@ai-sdk/
|
|
48
|
+
"@ai-sdk/provider": "^3.0.8",
|
|
49
|
+
"@better-translate/core": "^2.1.0",
|
|
49
50
|
"ai": "^6.0.116",
|
|
50
|
-
"@better-translate/core": "^2.0.0",
|
|
51
51
|
"dotenv": "^17.2.3",
|
|
52
52
|
"gray-matter": "^4.0.3",
|
|
53
53
|
"ora": "^8.2.0",
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// src/ai-sdk-generator.ts
|
|
2
|
-
async function generateWithAiSdk(model, request) {
|
|
3
|
-
const { Output, generateText, jsonSchema } = await import("ai");
|
|
4
|
-
const result = await generateText({
|
|
5
|
-
experimental_output: Output.object({
|
|
6
|
-
schema: jsonSchema(request.schema, {
|
|
7
|
-
validate(value) {
|
|
8
|
-
if (!request.validate) {
|
|
9
|
-
return {
|
|
10
|
-
success: true,
|
|
11
|
-
value
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
try {
|
|
15
|
-
return {
|
|
16
|
-
success: true,
|
|
17
|
-
value: request.validate(value)
|
|
18
|
-
};
|
|
19
|
-
} catch (error) {
|
|
20
|
-
return {
|
|
21
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
22
|
-
success: false
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
}),
|
|
28
|
-
model,
|
|
29
|
-
prompt: request.prompt,
|
|
30
|
-
system: request.system,
|
|
31
|
-
temperature: 0
|
|
32
|
-
});
|
|
33
|
-
return result.experimental_output;
|
|
34
|
-
}
|
|
35
|
-
export {
|
|
36
|
-
generateWithAiSdk
|
|
37
|
-
};
|
package/dist/chunk-WMIZO3GE.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// src/define-config.ts
|
|
2
|
-
function defineConfig(config) {
|
|
3
|
-
return config;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// src/provider-models.ts
|
|
7
|
-
function openai(modelId, options) {
|
|
8
|
-
return {
|
|
9
|
-
apiKey: options.apiKey,
|
|
10
|
-
kind: "provider-model",
|
|
11
|
-
modelId,
|
|
12
|
-
provider: "openai"
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
defineConfig,
|
|
18
|
-
openai
|
|
19
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-models.d.ts","sourceRoot":"","sources":["../src/provider-models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,wBAAgB,MAAM,CACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;CAChB,GACA,uBAAuB,CAOzB"}
|