Skip to content

Commit 0313955

Browse files
authored
Multilingual translation support (#5)
* fix: Error handling when API KEY is empty * feat: Multi-language support * docs: update README.md
1 parent 8dea892 commit 0313955

22 files changed

+112
-114
lines changed

README.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44
[![VS Code extension installs](https://img.shields.io/visual-studio-marketplace/i/nimod7890.commit-translator)](https://marketplace.visualstudio.com/items?itemName=nimod7890.commit-translator)
55
[![VS Code extension rating](https://img.shields.io/visual-studio-marketplace/r/nimod7890.commit-translator)](https://marketplace.visualstudio.com/items?itemName=nimod7890.commit-translator)
66

7-
Welcome to Commit Message Translator for Visual Studio Code! This extension leverages the power of the DeepL Translate API to seamlessly translate your commit messages from Korean to English. Ideal for international teams and open-source projects where English is the primary language of communication.
8-
97
## Preview
108

119
![preview](assets/images/preview.gif)
1210

1311
## Key Features
1412

15-
- **Korean to English Translation**: Automatically translate your commit messages from Korean to English.
13+
- **MultiLanguage Translation**: Translate your commit messages.(default: EN)
1614
- **Easy to Use**: A simple and intuitive interface integrated right into VSCode.
1715
- **DeepL API Integration**: Powered by the reliable and accurate DeepL Translate API.
1816

@@ -24,7 +22,7 @@ Welcome to Commit Message Translator for Visual Studio Code! This extension leve
2422
## Usage
2523

2624
1. **Write Your Commit Message**: Simply write your commit message in Korean as you normally would.
27-
2. **Translate**: Click the 'Translate' button in the GitHub extension menu.
25+
2. **Translate**: Click the commit-translator icon button in the source control menu.
2826
3. **Enter API Key**: If you haven't already set up a DeepL API key, you will be prompted to enter it. This is required for the translation service.
2927
1. Go to the [DeepL Page](https://www.deepl.com/pro#developer).
3028
4. **Commit**: Your commit message will be translated to English. Review and commit as usual.

package-lock.json

+4-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "commit-translator",
33
"displayName": "Commit Message Translator",
44
"description": "VSCode extension which translates commit message ",
5-
"version": "1.0.0",
5+
"version": "1.1.0",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/nimod7890/commit-translator"
@@ -62,7 +62,12 @@
6262
"commit-translator.deepl.apiKey": {
6363
"type": "string",
6464
"default": "",
65-
"description": "Needed for translating commit message."
65+
"description": "deepl auth key for translating commit message."
66+
},
67+
"commit-translator.deepl.targetLanguage": {
68+
"type": "string",
69+
"default": "EN",
70+
"description": "Enter the language code for your target translation language. \nex) 'KO' for Korean.\nmore: https://www.deepl.com/docs-api/translate-text"
6671
}
6772
}
6873
}

src/api/postDeeplApi.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ type TranslatedDataResponse = {
1212
export const postDeeplApi = async ({
1313
text,
1414
apiKey,
15+
targetLanguage,
1516
}: {
1617
text: string;
1718
apiKey: string;
19+
targetLanguage: string;
1820
}): Promise<TranslatedDataResponse> => {
1921
const { data } = await client.post(
2022
`/v2/translate`,
21-
{ text: [text], target_lang: "EN" },
23+
{ text: [text], target_lang: targetLanguage },
2224
{ headers: { Authorization: `DeepL-Auth-Key ${apiKey}` } }
2325
);
2426
return data;

src/commands/setApiKey.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as vscode from "vscode";
2-
import { setConfigurationValue } from "../utils/setConfiguration";
3-
import validateString from "../utils/validateString";
2+
import isStringValid from "../utils/isStringValid";
3+
import { setConfigurationValue } from "../utils/configuration/setConfiguration";
44
import { ApiKey } from "../constants/api";
55

66
export async function setApiKeyCommand() {
77
const apiKey = await vscode.window.showInputBox({
88
title: "Please enter your API Key",
99
});
1010

11-
if (!validateString(apiKey)) {
11+
if (!isStringValid(apiKey)) {
1212
vscode.window.showErrorMessage("api key should be string type");
1313
return;
1414
}

src/commands/translateCommit.ts

+22-32
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,46 @@
1-
import { isEmpty } from "lodash";
21
import * as vscode from "vscode";
32
import { setApiKeyCommand } from ".";
4-
import { GitExtension } from "../types/vscode";
5-
6-
import { getDeepLApiKey } from "../utils/getDeepLApiKey";
7-
import { getTranslatedCommitMessage } from "../utils/getTranslatedCommitMessage";
8-
import {
9-
activateGitExtension,
10-
getSingleRepository,
11-
isGitExtensionValidate,
12-
} from "../utils/gitExtension";
13-
import validateString from "../utils/validateString";
3+
import { isGitExtensionValid, activateGitExtension, getSingleRepository } from "../utils/git";
4+
import getTranslatedCommitMessage from "../utils/getTranslatedCommitMessage";
5+
import getDeepLApiKey from "../utils/getDeepLApiKey";
6+
import isStringValid from "../utils/isStringValid";
7+
import { isEmpty } from "lodash";
8+
import getGitExtension from "../utils/git/getGitExtension";
149

1510
export async function translateCommitCommand() {
16-
/** 1. (success) check if git extension is valid */
17-
const gitExtension =
18-
vscode.extensions.getExtension<GitExtension>("vscode.git");
19-
if (!isGitExtensionValidate(gitExtension)) {
11+
/** 1. check if git extension is valid & activate git extension*/
12+
const gitExtension = getGitExtension();
13+
if (!isGitExtensionValid(gitExtension)) {
2014
return;
2115
}
2216
await activateGitExtension(gitExtension);
2317

24-
/** 2. (success ?) check if apiKey is valid */
25-
let apikey: string | undefined = getDeepLApiKey();
26-
if (!validateString(apikey)) {
27-
apikey = await setApiKeyCommand();
28-
// vscode.window.showInformationMessage(apikey as string);
29-
// await vscode.commands.executeCommand(Commands.SetApiKey);
18+
/** 2. check if apiKey exists*/
19+
let apiKey = getDeepLApiKey();
20+
if (!isStringValid(apiKey)) {
21+
apiKey = await setApiKeyCommand();
3022
}
3123

32-
// if (!isValidateApiKey()) {
33-
// vscode.window.showInformationMessage("api key is invalid");
34-
// return;
35-
// vscode.window.showInformationMessage(apikey as string);
36-
// await vscode.commands.executeCommand(Commands.SetApiKey);
37-
// }
24+
if (!isStringValid(apiKey)) {
25+
return;
26+
}
3827

39-
/** 3. (success) get repository from git */
28+
/** 3. get repository from git */
4029
const repository = getSingleRepository(gitExtension);
4130

42-
/** 4. (success) get commit from repository */
31+
/** 4. get commit from repository */
4332
const commit = repository.inputBox.value;
4433
if (isEmpty(commit)) {
4534
vscode.window.showErrorMessage("Commit message is empty");
4635
return;
4736
}
48-
/** 5. (success) translate commit message with Deepl api */
37+
38+
/** 5. translate commit message with Deepl api */
4939
const translatedMessage = await getTranslatedCommitMessage({
50-
apikey: apikey as string,
5140
commit,
41+
apiKey,
5242
});
5343

54-
/** 6. (success) log translated commit */
44+
/** 6. log translated commit */
5545
repository.inputBox.value = translatedMessage;
5646
}

src/types/configuration.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { z } from "zod";
33
export const configurationSchema = z.object({
44
deepl: z.object({
55
apiKey: z.string().optional(),
6+
targetLanguage: z.string().optional(),
67
}),
78
});
89

src/utils/apiKey.ts

-14
This file was deleted.

src/utils/getConfiguration.ts src/utils/configuration/getConfiguration.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as vscode from "vscode";
2-
import { WorkspaceKey } from "../constants/workspace";
2+
import { WorkspaceKey } from "../../constants/workspace";
33

44
export function getConfiguration() {
55
return vscode.workspace.getConfiguration(WorkspaceKey);
File renamed without changes.

src/utils/getDeepLApiKey.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import * as vscode from "vscode";
2-
3-
export function getDeepLApiKey() {
4-
const apiKey = vscode.workspace
5-
.getConfiguration("commit-translator.deepl")
6-
.get<string>("apiKey");
1+
import { ApiKey } from "../constants/api";
2+
import { getConfiguration } from "./configuration/getConfiguration";
73

4+
export default function getDeepLApiKey(): string | undefined {
5+
const apiKey = getConfiguration().get<string | undefined>(ApiKey);
86
return apiKey;
97
}

src/utils/getParsedConfiguration.ts

-6
This file was deleted.

src/utils/getTranslatedCommitMessage.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
1-
import { postDeeplApi } from "../api/postDeeplApi";
21
import * as vscode from "vscode";
2+
import { postDeeplApi } from "../api/postDeeplApi";
3+
import { getConfiguration } from "./configuration/getConfiguration";
4+
35
type getTranslatedCommitMessageProps = {
46
commit: string;
5-
apikey: string;
7+
apiKey: string;
68
};
79

8-
export async function getTranslatedCommitMessage({
10+
export default async function getTranslatedCommitMessage({
911
commit,
10-
apikey,
12+
apiKey,
1113
}: getTranslatedCommitMessageProps): Promise<string> {
1214
try {
13-
const response = await postDeeplApi({ text: commit, apiKey: apikey });
15+
const targetLanguage =
16+
getConfiguration().get<string | undefined>("deepl.targetLanguage") ?? "EN";
17+
18+
const response = await postDeeplApi({
19+
text: commit.trim(),
20+
apiKey: apiKey,
21+
targetLanguage: targetLanguage.trim(),
22+
});
1423
return response.translations[0].text;
1524
} catch (error) {
1625
if (error instanceof Error) {

src/utils/git/activateGitExtension.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as vscode from "vscode";
2+
import { GitExtension } from "../../types/vscode";
3+
4+
export async function activateGitExtension(gitExtension: vscode.Extension<GitExtension>) {
5+
if (!gitExtension.isActive) {
6+
await gitExtension.activate();
7+
}
8+
if (!gitExtension.isActive) {
9+
throw new Error("Git extension is not active");
10+
}
11+
}

src/utils/git/getGitExtension.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as vscode from "vscode";
2+
import { GitExtension } from "../../types/vscode";
3+
4+
export default function getGitExtension() {
5+
return vscode.extensions.getExtension<GitExtension>("vscode.git");
6+
}

src/utils/git/getSingleRepository.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as vscode from "vscode";
2+
import { isEmpty } from "lodash";
3+
import { GitExtension, Repository } from "../../types/vscode";
4+
5+
export function getSingleRepository(gitExtension: vscode.Extension<GitExtension>): Repository {
6+
const repositories = gitExtension.exports.getAPI(1).repositories;
7+
8+
if (isEmpty(repositories)) {
9+
throw new Error("No repositories found");
10+
}
11+
return repositories[0];
12+
}

src/utils/git/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from "./activateGitExtension";
2+
export * from "./getSingleRepository";
3+
export * from "./isGitExtensionValid";
4+
export * from "./getGitExtension";

src/utils/git/isGitExtensionValid.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as vscode from "vscode";
2+
import { GitExtension } from "../../types/vscode";
3+
4+
export function isGitExtensionValid(
5+
gitExtension: vscode.Extension<GitExtension> | undefined
6+
): gitExtension is vscode.Extension<GitExtension> {
7+
if (!gitExtension) {
8+
vscode.window.showErrorMessage("Git extension is not installed.");
9+
return false;
10+
}
11+
return true;
12+
}

src/utils/gitExtension.ts

-31
This file was deleted.

src/utils/isStringValid.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { isEmpty } from "lodash";
2+
3+
export default function isStringValid(text: string | null | undefined): text is string {
4+
return Boolean(text) && !isEmpty(text);
5+
}

src/utils/validateString.ts

-5
This file was deleted.

yarn.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz"
195195
integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==
196196

197-
"@types/vscode@^1.84.0":
197+
"@types/vscode@^1.83.1":
198198
version "1.84.2"
199199
resolved "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.2.tgz"
200200
integrity sha512-LCe1FvCDMJKkPdLVGYhP0HRJ1PDop2gRVm/zFHiOKwYLBRS7vEV3uOOUId4HMV+L1IxqyS+IZXMmlSMRbZGIAw==

0 commit comments

Comments
 (0)