@daliusd/deepl-cli 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 +21 -0
- package/README.md +147 -0
- package/dist/args.d.ts +14 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +99 -0
- package/dist/args.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +101 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +55 -0
- package/dist/config.js.map +1 -0
- package/dist/translate.d.ts +16 -0
- package/dist/translate.d.ts.map +1 -0
- package/dist/translate.js +26 -0
- package/dist/translate.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 daliusd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# @daliusd/deepl-cli
|
|
2
|
+
|
|
3
|
+
CLI tool for translating text using the [DeepL API](https://www.deepl.com/docs-api). Pipe-friendly, configurable, supports context and formality options.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @daliusd/deepl-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Node.js >= 18.
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
Create a config file at `~/.config/deepl-cli/config.json`:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
mkdir -p ~/.config/deepl-cli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Using a static API key
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"api_key": "your-deepl-api-key"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Using a command to retrieve the API key
|
|
30
|
+
|
|
31
|
+
This is useful with password managers like [pass](https://www.passwordstore.org/), 1Password CLI, etc.
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"api_key_command": "pass show deepl-api-key"
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If both `api_key` and `api_key_command` are present, `api_key_command` takes precedence.
|
|
40
|
+
|
|
41
|
+
You can get a DeepL API key by creating a [DeepL API account](https://www.deepl.com/pro#developer) (free tier: 500,000 characters/month).
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
deepl-cli [options] [text]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Options
|
|
50
|
+
|
|
51
|
+
| Option | Short | Description |
|
|
52
|
+
|--------|-------|-------------|
|
|
53
|
+
| `--target <lang>` | `-t` | Target language code (required, e.g. `de`, `en-US`, `fr`) |
|
|
54
|
+
| `--source <lang>` | `-s` | Source language code (default: auto-detect) |
|
|
55
|
+
| `--context <text>` | `-c` | Additional context to influence translation (not translated, not billed) |
|
|
56
|
+
| `--formality <level>` | `-f` | Formality: `less`, `more`, `default`, `prefer_less`, `prefer_more` |
|
|
57
|
+
| `--verbose` | `-v` | Show metadata (detected source language, billed characters) |
|
|
58
|
+
| `--help` | `-h` | Show help |
|
|
59
|
+
| `--version` | | Show version |
|
|
60
|
+
|
|
61
|
+
### Examples
|
|
62
|
+
|
|
63
|
+
Translate text to German:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
deepl-cli -t de "Hello, world!"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Translate with context (context influences translation but is not translated or billed):
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
deepl-cli -t de -c "This is a greeting in a formal business email" "Hello"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Pipe text via stdin:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
echo "Hello, world!" | deepl-cli -t de
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use formal language:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
deepl-cli -t de -f more "How are you?"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Show translation metadata:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
deepl-cli -t de -v "Hello, world!"
|
|
91
|
+
# stdout: Hallo, Welt!
|
|
92
|
+
# stderr: Detected source language: en
|
|
93
|
+
# stderr: Billed characters: 13
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Specify source language explicitly:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
deepl-cli -t de -s en "Hello"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Piping
|
|
103
|
+
|
|
104
|
+
The translated text is printed to stdout with no extra formatting, making it easy to use in pipelines:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
echo "Hello" | deepl-cli -t de | pbcopy
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
When `--verbose` is used, metadata is written to stderr so stdout remains clean for piping.
|
|
111
|
+
|
|
112
|
+
## Language codes
|
|
113
|
+
|
|
114
|
+
Language codes are case-insensitive and follow ISO 639-1, with some target languages including regional variants:
|
|
115
|
+
|
|
116
|
+
- Source: `en`, `de`, `fr`, `ja`, `es`, etc. (or omit for auto-detection)
|
|
117
|
+
- Target: `en-US`, `en-GB`, `pt-BR`, `pt-PT`, `de`, `fr`, etc.
|
|
118
|
+
|
|
119
|
+
See the [DeepL API documentation](https://www.deepl.com/docs-api/translating-text/) for the full list of supported languages.
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git clone https://github.com/daliusd/deepl-cli.git
|
|
125
|
+
cd deepl-cli
|
|
126
|
+
npm install
|
|
127
|
+
npm run build
|
|
128
|
+
npm test
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Scripts
|
|
132
|
+
|
|
133
|
+
| Command | Description |
|
|
134
|
+
|---------|-------------|
|
|
135
|
+
| `npm run build` | Compile TypeScript to `dist/` |
|
|
136
|
+
| `npm test` | Run unit tests (`node:test`) |
|
|
137
|
+
|
|
138
|
+
### Publishing
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm run build
|
|
142
|
+
npm publish --access public
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
[MIT](LICENSE)
|
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Formality } from 'deepl-node';
|
|
2
|
+
export declare const HELP_TEXT = "Usage: deepl-cli [options] [text]\n\nTranslate text using the DeepL API.\n\nArguments:\n text Text to translate (or pipe via stdin)\n\nOptions:\n -t, --target <lang> Target language code (required, e.g. \"de\", \"en-US\")\n -s, --source <lang> Source language code (default: auto-detect)\n -c, --context <text> Additional context for translation (not translated, not billed)\n -f, --formality <level> Formality: less, more, default, prefer_less, prefer_more\n -v, --verbose Show metadata (detected source lang, billed characters)\n -h, --help Show this help\n --version Show version\n\nExamples:\n deepl-cli -t de \"Hello, world!\"\n deepl-cli -t de -c \"Email greeting\" \"Hello\"\n echo \"Hello\" | deepl-cli -t de\n deepl-cli -t de -f more \"How are you?\"";
|
|
3
|
+
export interface ParsedArgs {
|
|
4
|
+
target: string;
|
|
5
|
+
source: string | null;
|
|
6
|
+
context: string | undefined;
|
|
7
|
+
formality: Formality | undefined;
|
|
8
|
+
verbose: boolean;
|
|
9
|
+
help: boolean;
|
|
10
|
+
version: boolean;
|
|
11
|
+
text: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export declare function parseCliArgs(args: string[]): ParsedArgs;
|
|
14
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAU5C,eAAO,MAAM,SAAS,21BAoBmB,CAAC;AAE1C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAkFvD"}
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
const VALID_FORMALITY_VALUES = [
|
|
3
|
+
'less',
|
|
4
|
+
'more',
|
|
5
|
+
'default',
|
|
6
|
+
'prefer_less',
|
|
7
|
+
'prefer_more',
|
|
8
|
+
];
|
|
9
|
+
export const HELP_TEXT = `Usage: deepl-cli [options] [text]
|
|
10
|
+
|
|
11
|
+
Translate text using the DeepL API.
|
|
12
|
+
|
|
13
|
+
Arguments:
|
|
14
|
+
text Text to translate (or pipe via stdin)
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
-t, --target <lang> Target language code (required, e.g. "de", "en-US")
|
|
18
|
+
-s, --source <lang> Source language code (default: auto-detect)
|
|
19
|
+
-c, --context <text> Additional context for translation (not translated, not billed)
|
|
20
|
+
-f, --formality <level> Formality: less, more, default, prefer_less, prefer_more
|
|
21
|
+
-v, --verbose Show metadata (detected source lang, billed characters)
|
|
22
|
+
-h, --help Show this help
|
|
23
|
+
--version Show version
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
deepl-cli -t de "Hello, world!"
|
|
27
|
+
deepl-cli -t de -c "Email greeting" "Hello"
|
|
28
|
+
echo "Hello" | deepl-cli -t de
|
|
29
|
+
deepl-cli -t de -f more "How are you?"`;
|
|
30
|
+
export function parseCliArgs(args) {
|
|
31
|
+
// Show help when called with no arguments
|
|
32
|
+
if (args.length === 0) {
|
|
33
|
+
return {
|
|
34
|
+
target: '',
|
|
35
|
+
source: null,
|
|
36
|
+
context: undefined,
|
|
37
|
+
formality: undefined,
|
|
38
|
+
verbose: false,
|
|
39
|
+
help: true,
|
|
40
|
+
version: false,
|
|
41
|
+
text: undefined,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const { values, positionals } = parseArgs({
|
|
45
|
+
args,
|
|
46
|
+
options: {
|
|
47
|
+
target: { type: 'string', short: 't' },
|
|
48
|
+
source: { type: 'string', short: 's' },
|
|
49
|
+
context: { type: 'string', short: 'c' },
|
|
50
|
+
formality: { type: 'string', short: 'f' },
|
|
51
|
+
verbose: { type: 'boolean', short: 'v', default: false },
|
|
52
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
53
|
+
version: { type: 'boolean', default: false },
|
|
54
|
+
},
|
|
55
|
+
allowPositionals: true,
|
|
56
|
+
});
|
|
57
|
+
if (values.help) {
|
|
58
|
+
return {
|
|
59
|
+
target: '',
|
|
60
|
+
source: null,
|
|
61
|
+
context: undefined,
|
|
62
|
+
formality: undefined,
|
|
63
|
+
verbose: false,
|
|
64
|
+
help: true,
|
|
65
|
+
version: false,
|
|
66
|
+
text: undefined,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (values.version) {
|
|
70
|
+
return {
|
|
71
|
+
target: '',
|
|
72
|
+
source: null,
|
|
73
|
+
context: undefined,
|
|
74
|
+
formality: undefined,
|
|
75
|
+
verbose: false,
|
|
76
|
+
help: false,
|
|
77
|
+
version: true,
|
|
78
|
+
text: undefined,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (!values.target) {
|
|
82
|
+
throw new Error('Missing required option: --target (-t)\nUse --help for usage information.');
|
|
83
|
+
}
|
|
84
|
+
if (values.formality &&
|
|
85
|
+
!VALID_FORMALITY_VALUES.includes(values.formality)) {
|
|
86
|
+
throw new Error(`Invalid formality value: "${values.formality}"\nValid values: ${VALID_FORMALITY_VALUES.join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
target: values.target,
|
|
90
|
+
source: values.source || null,
|
|
91
|
+
context: values.context,
|
|
92
|
+
formality: values.formality,
|
|
93
|
+
verbose: values.verbose ?? false,
|
|
94
|
+
help: false,
|
|
95
|
+
version: false,
|
|
96
|
+
text: positionals.length > 0 ? positionals.join(' ') : undefined,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createReadStream } from 'node:fs';
|
|
3
|
+
import { loadConfig, resolveApiKey } from './config.js';
|
|
4
|
+
import { createClient, translate } from './translate.js';
|
|
5
|
+
import { parseCliArgs, HELP_TEXT } from './args.js';
|
|
6
|
+
function readStdin() {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
let data = '';
|
|
9
|
+
const stream = createReadStream('/dev/stdin', { encoding: 'utf-8' });
|
|
10
|
+
const timeout = setTimeout(() => {
|
|
11
|
+
stream.destroy();
|
|
12
|
+
reject(new Error('No input provided. Pass text as an argument or pipe via stdin.'));
|
|
13
|
+
}, 100);
|
|
14
|
+
stream.on('data', (chunk) => {
|
|
15
|
+
clearTimeout(timeout);
|
|
16
|
+
data += chunk;
|
|
17
|
+
});
|
|
18
|
+
stream.on('end', () => {
|
|
19
|
+
clearTimeout(timeout);
|
|
20
|
+
resolve(data.trim());
|
|
21
|
+
});
|
|
22
|
+
stream.on('error', (err) => {
|
|
23
|
+
clearTimeout(timeout);
|
|
24
|
+
reject(err);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function getVersion() {
|
|
29
|
+
return '0.1.0';
|
|
30
|
+
}
|
|
31
|
+
async function main() {
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = parseCliArgs(process.argv.slice(2));
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
if (parsed.help) {
|
|
41
|
+
process.stdout.write(HELP_TEXT + '\n');
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
if (parsed.version) {
|
|
45
|
+
process.stdout.write(getVersion() + '\n');
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
// Get text from argument or stdin
|
|
49
|
+
let text = parsed.text;
|
|
50
|
+
if (!text) {
|
|
51
|
+
if (process.stdin.isTTY) {
|
|
52
|
+
process.stderr.write('Error: No text provided. Pass text as an argument or pipe via stdin.\n' +
|
|
53
|
+
'Use --help for usage information.\n');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
text = await readStdin();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
process.stderr.write('Error: No text provided. Pass text as an argument or pipe via stdin.\n' +
|
|
61
|
+
'Use --help for usage information.\n');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!text) {
|
|
66
|
+
process.stderr.write('Error: Empty text provided.\nUse --help for usage information.\n');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
// Load config and resolve API key
|
|
70
|
+
let apiKey;
|
|
71
|
+
try {
|
|
72
|
+
const config = loadConfig();
|
|
73
|
+
apiKey = resolveApiKey(config);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
// Translate
|
|
80
|
+
try {
|
|
81
|
+
const client = createClient(apiKey);
|
|
82
|
+
const result = await translate(client, {
|
|
83
|
+
text,
|
|
84
|
+
sourceLang: parsed.source,
|
|
85
|
+
targetLang: parsed.target,
|
|
86
|
+
context: parsed.context,
|
|
87
|
+
formality: parsed.formality,
|
|
88
|
+
});
|
|
89
|
+
process.stdout.write(result.text + '\n');
|
|
90
|
+
if (parsed.verbose) {
|
|
91
|
+
process.stderr.write(`Detected source language: ${result.detectedSourceLang}\n`);
|
|
92
|
+
process.stderr.write(`Billed characters: ${result.billedCharacters}\n`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
main();
|
|
101
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAKD,wBAAgB,UAAU,CAAC,UAAU,GAAE,MAA4B,GAAG,MAAM,CAoC3E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBpD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
const DEFAULT_CONFIG_DIR = join(homedir(), '.config', 'deepl-cli');
|
|
6
|
+
const DEFAULT_CONFIG_PATH = join(DEFAULT_CONFIG_DIR, 'config.json');
|
|
7
|
+
export function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
|
|
8
|
+
if (!existsSync(configPath)) {
|
|
9
|
+
throw new Error(`Config file not found: ${configPath}\n` +
|
|
10
|
+
`Create it with:\n` +
|
|
11
|
+
` mkdir -p ~/.config/deepl-cli\n` +
|
|
12
|
+
` echo '{"api_key": "your-deepl-api-key"}' > ~/.config/deepl-cli/config.json\n` +
|
|
13
|
+
`\n` +
|
|
14
|
+
`Or use api_key_command to retrieve the key from a password manager:\n` +
|
|
15
|
+
` echo '{"api_key_command": "pass show deepl-api-key"}' > ~/.config/deepl-cli/config.json`);
|
|
16
|
+
}
|
|
17
|
+
let raw;
|
|
18
|
+
try {
|
|
19
|
+
raw = readFileSync(configPath, 'utf-8');
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
throw new Error(`Failed to read config file: ${configPath}: ${err}`);
|
|
23
|
+
}
|
|
24
|
+
let config;
|
|
25
|
+
try {
|
|
26
|
+
config = JSON.parse(raw);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error(`Invalid JSON in config file: ${configPath}`);
|
|
30
|
+
}
|
|
31
|
+
if (!config.api_key && !config.api_key_command) {
|
|
32
|
+
throw new Error(`Config must contain "api_key" or "api_key_command".\n` +
|
|
33
|
+
` api_key: your DeepL API key as a string\n` +
|
|
34
|
+
` api_key_command: a shell command that outputs your API key (e.g. "pass show deepl-api-key")`);
|
|
35
|
+
}
|
|
36
|
+
return config;
|
|
37
|
+
}
|
|
38
|
+
export function resolveApiKey(config) {
|
|
39
|
+
if (config.api_key_command) {
|
|
40
|
+
try {
|
|
41
|
+
return execSync(config.api_key_command, {
|
|
42
|
+
encoding: 'utf-8',
|
|
43
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
44
|
+
}).trim();
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
throw new Error(`Failed to execute api_key_command: ${config.api_key_command}\n${err}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (config.api_key) {
|
|
51
|
+
return config.api_key;
|
|
52
|
+
}
|
|
53
|
+
throw new Error('No API key available. Set "api_key" or "api_key_command" in config.');
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAOlC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACnE,MAAM,mBAAmB,GAAG,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AAEpE,MAAM,UAAU,UAAU,CAAC,aAAqB,mBAAmB;IACjE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,0BAA0B,UAAU,IAAI;YACtC,mBAAmB;YACnB,kCAAkC;YAClC,gFAAgF;YAChF,IAAI;YACJ,uEAAuE;YACvE,2FAA2F,CAC9F,CAAC;IACJ,CAAC;IAED,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,KAAK,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,uDAAuD;YACrD,6CAA6C;YAC7C,+FAA+F,CAClG,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE;gBACtC,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,sCAAsC,MAAM,CAAC,eAAe,KAAK,GAAG,EAAE,CACvE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as deepl from 'deepl-node';
|
|
2
|
+
export interface TranslateOptions {
|
|
3
|
+
text: string;
|
|
4
|
+
sourceLang: deepl.SourceLanguageCode | null;
|
|
5
|
+
targetLang: deepl.TargetLanguageCode;
|
|
6
|
+
context?: string;
|
|
7
|
+
formality?: deepl.Formality;
|
|
8
|
+
}
|
|
9
|
+
export interface TranslateResult {
|
|
10
|
+
text: string;
|
|
11
|
+
detectedSourceLang: string;
|
|
12
|
+
billedCharacters: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function createClient(apiKey: string): deepl.DeepLClient;
|
|
15
|
+
export declare function translate(client: deepl.DeepLClient, options: TranslateOptions): Promise<TranslateResult>;
|
|
16
|
+
//# sourceMappingURL=translate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AAEpC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAC5C,UAAU,EAAE,KAAK,CAAC,kBAAkB,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,CAO9D;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,KAAK,CAAC,WAAW,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAyB1B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as deepl from 'deepl-node';
|
|
2
|
+
export function createClient(apiKey) {
|
|
3
|
+
return new deepl.DeepLClient(apiKey, {
|
|
4
|
+
appInfo: {
|
|
5
|
+
appName: 'deepl-cli',
|
|
6
|
+
appVersion: '0.1.0',
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function translate(client, options) {
|
|
11
|
+
const translateOptions = {};
|
|
12
|
+
if (options.context) {
|
|
13
|
+
translateOptions.context = options.context;
|
|
14
|
+
}
|
|
15
|
+
if (options.formality) {
|
|
16
|
+
translateOptions.formality = options.formality;
|
|
17
|
+
}
|
|
18
|
+
const result = await client.translateText(options.text, options.sourceLang, options.targetLang, translateOptions);
|
|
19
|
+
const single = Array.isArray(result) ? result[0] : result;
|
|
20
|
+
return {
|
|
21
|
+
text: single.text,
|
|
22
|
+
detectedSourceLang: single.detectedSourceLang,
|
|
23
|
+
billedCharacters: single.billedCharacters,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=translate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AAgBpC,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE;QACnC,OAAO,EAAE;YACP,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,OAAO;SACpB;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAyB,EACzB,OAAyB;IAEzB,MAAM,gBAAgB,GAA+B,EAAE,CAAC;IAExD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,gBAAgB,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC7C,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,gBAAgB,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CACvC,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,UAAU,EAClB,gBAAgB,CACjB,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE1D,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@daliusd/deepl-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool for translating text using the DeepL API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"deepl-cli": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"test": "node --import tsx --test tests/*.test.ts"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"deepl",
|
|
21
|
+
"translate",
|
|
22
|
+
"translation",
|
|
23
|
+
"cli"
|
|
24
|
+
],
|
|
25
|
+
"author": "daliusd",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"deepl-node": "^1.15.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"tsx": "^4.19.0",
|
|
35
|
+
"typescript": "^5.7.0",
|
|
36
|
+
"@types/node": "^22.0.0"
|
|
37
|
+
}
|
|
38
|
+
}
|