gpt-po 1.0.11 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -20,11 +20,11 @@ Set `OPENAI_API_KEY` before using this tool.
20
20
  ## Usage Scenarios
21
21
 
22
22
  - `gpt-po sync --po <file> --pot <file>` Update the po file based on the pot file, while preserving the original translations.
23
- - `gpt-po --po <file>` Translate specified po files to a designated target language. By default, the target language is Simplified Chinese.
24
- - `gpt-po --po <file> --lang <lang>` Translate specified po files to a designated target language.
23
+ - `gpt-po --po <file>` Translate specified po files to a designated target language.
24
+ - `gpt-po --po <file> --lang <lang>` Translate specified po files to a designated target language (overriding language specified in po file).
25
25
  - `gpt-po --dir .` Translate all po files in current directory to a designated target language.
26
26
  - `gpt-po userdict` Modify or view user dictionaries
27
- - `gpt-po userdict --explore` Explore user dictionaries, if you want add new dictionaries or modify existing dictionaries. dictionaries can be named as `dictionary-<lang>.json`, for example, `dictionary-simplified-chinese.json` is the dictionary for Simplified Chinese.
27
+ - `gpt-po userdict --explore` Explore user dictionaries, if you want add new dictionaries or modify existing dictionaries. dictionaries can be named as `dictionary-<lang>.json`, for example, `dictionary-zh.json` is the dictionary for Simplified Chinese.
28
28
  - `gpt-po systemprompt` Modify or view system prompts, if you are not sure how to use it, you can leave it alone
29
29
  - `gpt-po systemprompt --reset` Reset system prompts
30
30
 
@@ -54,14 +54,15 @@ translate po file (default command)
54
54
  Options:
55
55
  -k, --key <key> openai api key (env: OPENAI_API_KEY)
56
56
  --host <host> openai api host (env: OPENAI_API_HOST)
57
- --model <model> openai model (choices: "gpt-4", "gpt-4-0314", "gpt-4-32k", "gpt-4-32k-0314", "gpt-3.5-turbo", "gpt-3.5-turbo-0301",
58
- default: "gpt-3.5-turbo")
57
+ --model <model> openai model (choices: "gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-4-0314", "gpt-4-32k", "gpt-4-32k-0314", "gpt-3.5-turbo", "gpt-3.5-turbo-0301",
58
+ default: "gpt-4o")
59
59
  --po <file> po file path
60
60
  --dir <dir> po file directory
61
61
  -src, --source <lang> source language (default: "english")
62
62
  --verbose show verbose log
63
- -l, --lang <lang> target language (default: "simplified chinese")
63
+ -l, --lang <lang> target language (ISO 639-1 code)
64
64
  -o, --output <file> output file path, overwirte po file by default
65
+ --context context file path (provides additional context to the bot)
65
66
  -h, --help display help for command
66
67
  ```
67
68
 
package/README_zh-CN.md CHANGED
@@ -15,69 +15,71 @@ npm install gpt-po
15
15
 
16
16
  使用此工具前先设置 `OPENAI_API_KEY`,Windows中使用 `set OPENAI_API_KEY=<key>`, Linux中 `export OPENAI_API_KEY=<key>`
17
17
 
18
- **建议使用付费的OpenAI API以提高翻译速度,免费的OpenAI API速度较慢(一分钟3条),且有使用限制。**
18
+ **建议使用付费的OpenAI API以提高翻译速度,免费的OpenAI API速度较慢(一分钟3条一天200条),且有使用限制。**
19
+
20
+ *国内用户要设置`HTTPS_PROXY`环境变量上梯子才能用*
19
21
 
20
22
  ## 常见用法
21
23
 
22
- - `gpt-po sync --po <file> --pot <file>` 根据pot文件更新po文件,保留原有翻译
23
- - `gpt-po --po <file>` 翻译指定的po文件到指定的目标语言,默认目标语言是简体中文
24
- - `gpt-po --po <file> --lang <lang>` Translate specified po files to a designated target language.
25
- - `gpt-po --dir .` 翻译当前目录下的所有po文件到指定的目标语言,默认目标语言是简体中文
26
- - `gpt-po userdict` 修改或查看用户字典
27
- - `gpt-po userdict --explore` 用于浏览字典目录, 如果你想要增加或修改现有的字典。字典可以按`dictionary-<lang>.json`格式命令, 例如, `dictionary-simplified-chinese.json` 是针对简体中文的字典.
28
- - `gpt-po systemprompt` 修改或查看系统提示词,如果你不确定如何使用,可以不用修改
29
- - `gpt-po systemprompt --reset` 重置系统提示词
24
+ - `gpt-po sync --po <file> --pot <file>` 根据 pot 文件更新 po 文件,同时保留原有翻译。
25
+ - `gpt-po --po <file>` 将指定的 po 文件翻译成目标语言。
26
+ - `gpt-po --po <file> --lang <lang>` 将指定的 po 文件翻译成目标语言(覆盖 po 文件中指定的语言)。
27
+ - `gpt-po --dir .` 将当前目录下的所有 po 文件翻译成目标语言。
28
+ - `gpt-po userdict` 修改或查看用户词典。
29
+ - `gpt-po userdict --explore` 浏览用户词典,如果您想添加新词典或修改现有词典,词典可以命名为 `dictionary-<lang>.json`,例如 `dictionary-zh.json` 是简体中文词典。
30
+ - `gpt-po systemprompt` 修改或查看系统提示,如果您不确定如何使用它,可以忽略。
31
+ - `gpt-po systemprompt --reset` 重置系统提示。
30
32
 
31
33
  ```
32
- Usage: gpt-po [options] [command]
34
+ 用法: gpt-po [options] [command]
33
35
 
34
- command tool for translate po files by gpt
36
+ 通过 gpt 翻译 po 文件的命令工具
35
37
 
36
- Options:
37
- -V, --version output the version number
38
- -h, --help display help for command
38
+ 选项:
39
+ -V, --version 输出版本号
40
+ -h, --help 显示命令帮助
39
41
 
40
- Commands:
41
- translate [options] translate po file (default command)
42
- sync [options] update po from pot file
43
- systemprompt [options] open/edit system prompt
44
- userdict [options] open/edit user dictionary
45
- remove [options] remove po entries by options
46
- help [command] display help for command
42
+ 命令:
43
+ translate [options] 翻译 po 文件(默认命令)
44
+ sync [options] 根据 pot 文件更新 po 文件
45
+ systemprompt [options] 打开/编辑系统提示
46
+ userdict [options] 打开/编辑用户词典
47
+ remove [options] 通过选项删除 po 条目
48
+ help [command] 显示命令帮助
47
49
  ```
48
50
 
49
51
  ```
50
- Usage: gpt-po [options]
51
-
52
- translate po file (default command)
53
-
54
- Options:
55
- -k, --key <key> openai api key (env: OPENAI_API_KEY)
56
- --host <host> openai api host (env: OPENAI_API_HOST)
57
- --model <model> openai model (choices: "gpt-4", "gpt-4-0314", "gpt-4-32k", "gpt-4-32k-0314", "gpt-3.5-turbo", "gpt-3.5-turbo-0301",
58
- default: "gpt-3.5-turbo")
59
- --po <file> po file path
60
- --dir <dir> po file directory
61
- -src, --source <lang> source language (default: "english")
62
- --verbose show verbose log
63
- -l, --lang <lang> target language (default: "simplified chinese")
64
- -o, --output <file> output file path, overwirte po file by default
65
- -h, --help display help for command
52
+ 用法: gpt-po [options]
53
+
54
+ 翻译 po 文件(默认命令)
55
+
56
+ 选项:
57
+ -k, --key <key> openai api key (环境变量: OPENAI_API_KEY)
58
+ --host <host> openai api host (环境变量: OPENAI_API_HOST)
59
+ --model <model> openai 模型 (选项: "gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-4-0314", "gpt-4-32k", "gpt-4-32k-0314", "gpt-3.5-turbo", "gpt-3.5-turbo-0301", 默认: "gpt-4o")
60
+ --po <file> po 文件路径
61
+ --dir <dir> po 文件目录
62
+ -src, --source <lang> 源语言 (默认: "english")
63
+ --verbose 显示详细日志
64
+ -l, --lang <lang> 目标语言 (ISO 639-1 代码)
65
+ -o, --output <file> 输出文件路径,默认覆盖 po 文件
66
+ --context 上下文文件路径(为机器人提供额外的上下文)
67
+ -h, --help 显示命令帮助
66
68
  ```
67
69
 
68
70
  ```
69
- Usage: gpt-po remove [options]
70
-
71
- remove po entries by options
72
-
73
- Options:
74
- --po <file> po file path
75
- --fuzzy remove fuzzy entries
76
- -obs, --obsolete remove obsolete entries
77
- -ut, --untranslated remove untranslated entries
78
- -t, --translated remove translated entries
79
- -tnf, --translated-not-fuzzy remove translated not fuzzy entries
80
- -ft, --fuzzy-translated remove fuzzy translated entries
81
- -rc, --reference-contains <text> remove entries whose reference contains text, text can be a regular expression like /text/ig
82
- -h, --help display help for command
71
+ 用法: gpt-po remove [options]
72
+
73
+ 通过选项删除 po 条目
74
+
75
+ 选项:
76
+ --po <file> po 文件路径
77
+ --fuzzy 删除模糊条目
78
+ -obs, --obsolete 删除过时条目
79
+ -ut, --untranslated 删除未翻译条目
80
+ -t, --translated 删除已翻译条目
81
+ -tnf, --translated-not-fuzzy 删除已翻译但不是模糊的条目
82
+ -ft, --fuzzy-translated 删除模糊翻译条目
83
+ -rc, --reference-contains <text> 删除引用包含文本的条目,文本可以是正则表达式,例如 /text/ig
84
+ -h, --help 显示命令帮助
83
85
  ```
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpt-po",
3
- "version": "1.0.11",
3
+ "version": "1.1.0",
4
4
  "description": "command tool for translate po files by gpt",
5
5
  "main": "lib/src/index.js",
6
6
  "bin": {
package/lib/src/index.js CHANGED
@@ -24,8 +24,10 @@ program
24
24
  .addOption(new commander_1.Option("-k, --key <key>", "openai api key").env("OPENAI_API_KEY"))
25
25
  .addOption(new commander_1.Option("--host <host>", "openai api host").env("OPENAI_API_HOST"))
26
26
  .addOption(new commander_1.Option("--model <model>", "openai model")
27
- .default("gpt-3.5-turbo")
27
+ .default("gpt-4o")
28
28
  .choices([
29
+ "gpt-4o",
30
+ "gpt-4-turbo",
29
31
  "gpt-4",
30
32
  "gpt-4-0314",
31
33
  "gpt-4-32k",
@@ -35,12 +37,13 @@ program
35
37
  ]))
36
38
  .addOption(new commander_1.Option("--po <file>", "po file path").conflicts("dir"))
37
39
  .addOption(new commander_1.Option("--dir <dir>", "po file directory").conflicts("po"))
38
- .option("-src, --source <lang>", "source language", "English")
39
- .option("-l, --lang <lang>", "target language", "Simplified Chinese")
40
+ .option("-src, --source <lang>", "source language (ISO 639-1)", "en")
41
+ .option("-l, --lang <lang>", "target language (ISO 639-1)")
40
42
  .option("--verbose", "print verbose log")
43
+ .option("--context <file>", "text file that provides the bot additional context")
41
44
  .addOption(new commander_1.Option("-o, --output <file>", "output file path, overwirte po file by default").conflicts("dir"))
42
45
  .action((args) => __awaiter(void 0, void 0, void 0, function* () {
43
- const { key, host, model, po, dir, source, lang, verbose, output, checkRegx } = args;
46
+ const { key, host, model, po, dir, source, lang, verbose, output, context } = args;
44
47
  if (host) {
45
48
  process.env.OPENAI_API_HOST = host;
46
49
  }
@@ -54,10 +57,10 @@ program
54
57
  }
55
58
  (0, translate_1.init)();
56
59
  if (po) {
57
- yield (0, translate_1.translatePo)(model, po, source, lang, verbose, output);
60
+ yield (0, translate_1.translatePo)(model, po, source, lang, verbose, output, context);
58
61
  }
59
62
  else if (dir) {
60
- yield (0, translate_1.translatePoDir)(model, dir, source, lang, verbose);
63
+ yield (0, translate_1.translatePoDir)(model, dir, source, lang, verbose, context);
61
64
  }
62
65
  else {
63
66
  console.error("po file or directory is required");
@@ -1 +1,20 @@
1
- You are a translation expert, translate the text in a colloquial, professional and elegant manner without sounding like a machine translation. Remember to only translate the text and not interpret it further.
1
+ You are a language translation expert.
2
+ You will be translating text from one language to another.
3
+ Languages shall be indetified to you via their ISO 639-1 two-letter code.
4
+ The text is in the gettext format, which uses placeholders like %s, %d, etc. These placeholders must remain unchanged in the translated text.
5
+ Untranslatable portions should retain their original formatting.
6
+ For example, you may encounter placeholders such as "%s" - these must be retained in the correct position.
7
+ Do not add a period (.) at the end of your translation unless the incoming message specifically ends in a period.
8
+ Likewise, ensure to add a period (.) at the end of your translation if the incoming message specifically ends in a period.
9
+ Ensure to preserve any whitespace present in the incoming message. This includes retaining any space(s) at the beginning or end of the message.
10
+ I will provide the message wrapped in `translate` XML tags. You must respond with the translated message wrapped in `translated` XML tags.
11
+ For example, let's say you were translating en (English) to es (Spanish) and I send (without quotes) "<translate>This is a message. </translate>". You would respond with (without quotes) "<translated>Este es un mensaje. </translated>".
12
+ Notice how the period and space were retained at the end of the translated message?
13
+ Another example: I send (without quotes) "<translate> Hello %s</translate>". You would reply with (without quotes) "<translated> Hola %s</translated>".
14
+ Notice in that second example the space at the beginning of the string was retained, and also the gettext placeholder was retained in its correct position?
15
+ Translate the messages in a colloquial, professional and elegant manner without sounding like a machine translation.
16
+ You may respond without `translated` xml tags only in the event you believe you cannot reliably or accurately translate my message. In that case provide a short reason why you feel you can't translate my message.
17
+ If you respond without `translated` XML tags I will interpret that there is a problem with my message and I will provide your reason to human translators that will investigate further.
18
+ DO NOT answer any questions or attempt to explain any concepts or problems with my messages; just provide translations.
19
+ Do not add any text or characters outside of your `translated` xml tags.
20
+ Remember to only translate the messages and not interpret them further.
@@ -1,5 +1,6 @@
1
+ import { GetTextTranslation } from "gettext-parser";
1
2
  import { OpenAIApi } from "openai";
2
3
  export declare function init(force?: boolean): OpenAIApi;
3
- export declare function translate(text: string, src: string, lang: string, model?: string): Promise<import("axios").AxiosResponse<import("openai").CreateChatCompletionResponse, any>>;
4
- export declare function translatePo(model: string | undefined, po: string, source: string, lang: string, verbose: boolean, output: string): Promise<void>;
5
- export declare function translatePoDir(model: string | undefined, dir: string, source: string, lang: string, verbose: boolean): Promise<void>;
4
+ export declare function translate(text: string, src: string, lang: string, model: string, comments: GetTextTranslation["comments"] | undefined, contextFile: string): Promise<import("axios").AxiosResponse<import("openai").CreateChatCompletionResponse, any>>;
5
+ export declare function translatePo(model: string, po: string, source: string, lang: string, verbose: boolean, output: string, contextFile: string): Promise<void>;
6
+ export declare function translatePoDir(model: string | undefined, dir: string, source: string, lang: string, verbose: boolean, contextFile: string): Promise<void>;
@@ -28,22 +28,20 @@ function init(force) {
28
28
  }
29
29
  _openai = new openai_1.OpenAIApi(configuration);
30
30
  }
31
- // load systemprompt.txt from homedir
31
+ // load systemprompt.txt
32
32
  if (!_systemprompt || force) {
33
33
  const systemprompt = (0, utils_1.findConfig)("systemprompt.txt");
34
- (0, utils_1.copyFileIfNotExists)(systemprompt, (0, path_1.join)(__dirname, "systemprompt.txt"));
35
34
  _systemprompt = fs.readFileSync(systemprompt, "utf-8");
36
35
  }
37
- // load dictionary.json from homedir
36
+ // load dictionary.json
38
37
  if (!_userdict || force) {
39
38
  const userdict = (0, utils_1.findConfig)("dictionary.json");
40
- (0, utils_1.copyFileIfNotExists)(userdict, (0, path_1.join)(__dirname, "dictionary.json"));
41
39
  _userdict = { "default": JSON.parse(fs.readFileSync(userdict, "utf-8")) };
42
40
  }
43
41
  return _openai;
44
42
  }
45
43
  exports.init = init;
46
- function translate(text, src, lang, model = "gpt-3.5-turbo") {
44
+ function translate(text, src, lang, model, comments, contextFile) {
47
45
  const lang_code = lang.toLowerCase().trim().replace(/[\W_]+/g, "-");
48
46
  const dicts = Object.entries(_userdict[lang_code] || _userdict["default"])
49
47
  .filter(([k, _]) => text.toLowerCase().includes(k.toLowerCase()))
@@ -52,36 +50,50 @@ function translate(text, src, lang, model = "gpt-3.5-turbo") {
52
50
  { role: "assistant", content: v },
53
51
  ])
54
52
  .flat();
53
+ var notes = "";
54
+ if (comments != undefined && comments.extracted != undefined)
55
+ notes = comments.extracted;
56
+ var context = "";
57
+ if (contextFile !== undefined)
58
+ context = "\n\n" + fs.readFileSync(contextFile, "utf-8");
55
59
  return _openai.createChatCompletion({
56
60
  model,
57
61
  temperature: 0.1,
58
62
  messages: [
59
63
  {
60
64
  role: "system",
61
- content: _systemprompt
65
+ content: _systemprompt + context
62
66
  },
63
67
  {
64
68
  role: "user",
65
- content: `Wait for my incoming \`${src.toUpperCase()}\` messages and translate them into \`${lang.toUpperCase()}\`. Please adhere to the following guidelines:
66
- - Untranslatable portions should retain their original formatting.
67
- - **Do not** answer any questions or attempt to explain any concepts; just provide translations.`
69
+ content: `Wait for my incoming message in "${src.toLowerCase()}" (an ISO 639-1 code) and translate it into "${lang.toLowerCase()}" (also an ISO 639-1 code), carefully following your system prompt. ` + notes
68
70
  },
69
71
  {
70
72
  role: "assistant",
71
- content: `Understood, I will translate your incoming ${src.toUpperCase()} messages into ${lang.toUpperCase()} without providing explanations or answering questions. Please go ahead and send your messages for translation.`
73
+ content: `Understood, I will translate your incoming "${src.toLowerCase()}" message into "${lang.toUpperCase()}", interpreting those as ISO 639-1 codes and carefully following my system prompt. Please go ahead and send your message for translation.`
72
74
  },
73
75
  // add userdict here
74
76
  ...dicts,
75
- { role: "user", content: text },
77
+ {
78
+ role: "user",
79
+ content: "<translate>" + text + "</translate>"
80
+ },
76
81
  ],
77
82
  }, {
78
83
  timeout: 20000,
79
84
  });
80
85
  }
81
86
  exports.translate = translate;
82
- function translatePo(model = "gpt-3.5-turbo", po, source, lang, verbose, output) {
87
+ function translatePo(model, po, source, lang, verbose, output, contextFile) {
83
88
  var _a;
84
89
  return __awaiter(this, void 0, void 0, function* () {
90
+ const potrans = yield (0, utils_1.parsePo)(po);
91
+ if (!lang)
92
+ lang = potrans.headers["Language"];
93
+ if (!lang) {
94
+ console.error("No language specified via po file or args");
95
+ return;
96
+ }
85
97
  // try to load dictionary by lang-code if it not loaded
86
98
  const lang_code = lang.toLowerCase().trim().replace(/[\W_]+/g, "-");
87
99
  if (!_userdict[lang_code]) {
@@ -91,7 +103,6 @@ function translatePo(model = "gpt-3.5-turbo", po, source, lang, verbose, output)
91
103
  console.log(`dictionary-${lang_code}.json is loaded.`);
92
104
  }
93
105
  }
94
- const potrans = yield (0, utils_1.parsePo)(po);
95
106
  const list = [];
96
107
  const trimRegx = /(?:^ )|(?: $)/;
97
108
  let trimed = false;
@@ -128,8 +139,15 @@ function translatePo(model = "gpt-3.5-turbo", po, source, lang, verbose, output)
128
139
  }
129
140
  const trans = list[i];
130
141
  try {
131
- const res = yield translate(trans.msgid, source, lang, model);
132
- trans.msgstr[0] = ((_a = res.data.choices[0].message) === null || _a === void 0 ? void 0 : _a.content) || trans.msgstr[0];
142
+ const res = yield translate(trans.msgid, source, lang, model, trans.comments, contextFile);
143
+ var translated = ((_a = res.data.choices[0].message) === null || _a === void 0 ? void 0 : _a.content) || trans.msgstr[0];
144
+ if (!translated.startsWith('<translated>') && !translated.endsWith('</translated>')) {
145
+ // We got an error response
146
+ console.log("Error: Unable to translate string [" + trans.msgid + "]. Bot says [" + translated + "]");
147
+ continue;
148
+ }
149
+ // We got a valid translation response
150
+ trans.msgstr[0] = translated.replace('<translated>', '').replace('</translated>', '');
133
151
  modified = true;
134
152
  if (verbose) {
135
153
  console.log(trans.msgid);
@@ -162,14 +180,14 @@ function translatePo(model = "gpt-3.5-turbo", po, source, lang, verbose, output)
162
180
  });
163
181
  }
164
182
  exports.translatePo = translatePo;
165
- function translatePoDir(model = "gpt-3.5-turbo", dir, source, lang, verbose) {
183
+ function translatePoDir(model = "gpt-3.5-turbo", dir, source, lang, verbose, contextFile) {
166
184
  return __awaiter(this, void 0, void 0, function* () {
167
185
  const files = fs.readdirSync(dir);
168
186
  for (const file of files) {
169
187
  if (file.endsWith(".po")) {
170
188
  const po = (0, path_1.join)(dir, file);
171
189
  console.log(`translating ${po}`);
172
- yield translatePo(model, po, source, lang, verbose, po);
190
+ yield translatePo(model, po, source, lang, verbose, po, contextFile);
173
191
  }
174
192
  }
175
193
  });
package/lib/src/utils.js CHANGED
@@ -101,7 +101,7 @@ function findConfig(fileName) {
101
101
  const gitDir = gitRootDir() || currentDir;
102
102
  const homeDir = (0, os_1.homedir)();
103
103
  const filePaths = [
104
- path.join(currentDir, ".gpt-po", fileName),
104
+ path.join(currentDir, "src", fileName),
105
105
  path.join(gitDir, ".gpt-po", fileName),
106
106
  path.join(homeDir, ".config", ".gpt-po", fileName)
107
107
  ];
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "gpt-po",
3
- "version": "1.0.11",
4
- "description": "command tool for translate po files by gpt",
5
- "main": "lib/src/index.js",
6
- "bin": {
7
- "gpt-po": "lib/src/index.js"
8
- },
9
- "scripts": {
10
- "start": "node lib/src/index.js",
11
- "test": "echo \"Error: no test specified\" && exit 1",
12
- "prebuild": "rimraf ./lib",
13
- "build": "tsc",
14
- "postbuild": "ncp ./src/ ./lib/src/ \"--filter=^(?!.*\\.ts$).*$\"",
15
- "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
16
- "lint": "tslint -p tsconfig.json"
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/ryanhex53/gpt-po.git"
21
- },
22
- "author": "Ryan",
23
- "license": "MIT",
24
- "bugs": {
25
- "url": "https://github.com/ryanhex53/gpt-po/issues"
26
- },
27
- "homepage": "https://github.com/ryanhex53/gpt-po#readme",
28
- "keywords": [
29
- "gettext",
30
- "po",
31
- "pot",
32
- "chatgpt",
33
- "openai"
34
- ],
35
- "devDependencies": {
36
- "@types/gettext-parser": "^4.0.2",
37
- "@types/jest": "^29.5.1",
38
- "jest": "^29.5.0",
39
- "ncp": "^2.0.0",
40
- "prettier": "^3.0.3",
41
- "rimraf": "^5.0.0",
42
- "ts-jest": "^29.1.0",
43
- "tslint": "^6.1.3",
44
- "tslint-config-prettier": "^1.18.0",
45
- "typescript": "^5.0.4"
46
- },
47
- "dependencies": {
48
- "commander": "^10.0.1",
49
- "gettext-parser": "^6.0.0",
50
- "openai": "^3.2.1"
51
- },
52
- "engines": {
53
- "node": ">=12.0.0"
54
- }
55
- }
1
+ {
2
+ "name": "gpt-po",
3
+ "version": "1.1.0",
4
+ "description": "command tool for translate po files by gpt",
5
+ "main": "lib/src/index.js",
6
+ "bin": {
7
+ "gpt-po": "lib/src/index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node lib/src/index.js",
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "prebuild": "rimraf ./lib",
13
+ "build": "tsc",
14
+ "postbuild": "ncp ./src/ ./lib/src/ \"--filter=^(?!.*\\.ts$).*$\"",
15
+ "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
16
+ "lint": "tslint -p tsconfig.json"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/ryanhex53/gpt-po.git"
21
+ },
22
+ "author": "Ryan",
23
+ "license": "MIT",
24
+ "bugs": {
25
+ "url": "https://github.com/ryanhex53/gpt-po/issues"
26
+ },
27
+ "homepage": "https://github.com/ryanhex53/gpt-po#readme",
28
+ "keywords": [
29
+ "gettext",
30
+ "po",
31
+ "pot",
32
+ "chatgpt",
33
+ "openai"
34
+ ],
35
+ "devDependencies": {
36
+ "@types/gettext-parser": "^4.0.2",
37
+ "@types/jest": "^29.5.1",
38
+ "jest": "^29.5.0",
39
+ "ncp": "^2.0.0",
40
+ "prettier": "^3.0.3",
41
+ "rimraf": "^5.0.0",
42
+ "ts-jest": "^29.1.0",
43
+ "tslint": "^6.1.3",
44
+ "tslint-config-prettier": "^1.18.0",
45
+ "typescript": "^5.0.4"
46
+ },
47
+ "dependencies": {
48
+ "commander": "^10.0.1",
49
+ "gettext-parser": "^6.0.0",
50
+ "openai": "^3.2.1"
51
+ },
52
+ "engines": {
53
+ "node": ">=12.0.0"
54
+ }
55
+ }