From a08a2b4bdeab756a5b8e4f842a7ce85bb544a0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harun=20KELE=C5=9EO=C4=9ELU?= Date: Sun, 1 Oct 2023 18:16:22 +0300 Subject: [PATCH 1/4] feat: removed openai package dependency - BREAKING CHANGE: removed apiKey field from baseConfig - httpClient used instead of openai package - removed LIBConfig interface --- package-lock.json | 103 ++---------- package.json | 5 +- src/config/index.ts | 52 +++--- src/constants/index.ts | 254 ++++++++++++++++------------- src/index.ts | 8 +- src/modules/ci/bitbucket-ci.bot.ts | 14 +- src/modules/ci/git.bot.ts | 16 +- src/modules/ci/github-ci.bot.ts | 12 +- src/modules/localize/localize.ts | 19 ++- src/utils/http-client.ts | 16 +- tsconfig.json | 2 +- 11 files changed, 228 insertions(+), 273 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf5fe4c..6b53a73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,11 @@ "version": "2.1.1", "license": "MIT", "dependencies": { - "openai": "^3.3.0", "winston": "^3.9.0" }, + "bin": { + "localize": "node dist/index.js" + }, "devDependencies": { "@commitlint/cli": "^17.6.5", "@commitlint/config-conventional": "^17.6.5", @@ -21,6 +23,7 @@ "@semantic-release/npm": "^10.0.4", "@types/node": "^20.3.1", "husky": "^8.0.0", + "reflect-metadata": "^0.1.13", "semantic-release": "^21.0.5" } }, @@ -1453,19 +1456,6 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", @@ -1649,17 +1639,6 @@ "text-hex": "1.0.x" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -1935,14 +1914,6 @@ "node": ">=4.0.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", @@ -2291,38 +2262,6 @@ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -3234,25 +3173,6 @@ "node": ">=10.0.0" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -6533,15 +6453,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/openai": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-3.3.0.tgz", - "integrity": "sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==", - "dependencies": { - "axios": "^0.26.0", - "form-data": "^4.0.0" - } - }, "node_modules/p-each-series": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", @@ -7192,6 +7103,12 @@ "esprima": "~4.0.0" } }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "dev": true + }, "node_modules/registry-auth-token": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", diff --git a/package.json b/package.json index a5fec27..de7ae5a 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "release": "semantic-release", "start": "node dist/index.js" }, + "bin": { + "localize": "node dist/index.js" + }, "repository": { "type": "git", "url": "https://github.com/celsus-ai/localize.git" @@ -26,7 +29,6 @@ }, "homepage": "https://github.com/celsus-ai/localize#readme", "dependencies": { - "openai": "^3.3.0", "winston": "^3.9.0" }, "devDependencies": { @@ -38,6 +40,7 @@ "@semantic-release/npm": "^10.0.4", "@types/node": "^20.3.1", "husky": "^8.0.0", + "reflect-metadata": "^0.1.13", "semantic-release": "^21.0.5" }, "release": { diff --git a/src/config/index.ts b/src/config/index.ts index f5a32b6..3127601 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,41 +1,53 @@ import { Parser } from '../utils'; -import { BitbucketAPI, ConfigConstants, GithubAPI, LanguageCodes, Platform, SortBy } from "../constants"; +import { BitbucketAPI, ConfigConstants, GithubAPI, LanguageCodes, OpenAIAPI, OpenAIModels, Platform, SortBy } from "../constants"; + +export interface IAPIConfig { + baseUrl: string; + token: string; +}; + +export interface ICIConfig extends IAPIConfig { + platform: Platform | undefined; + owner: string; + repo: string; +}; + +export interface IAIConfig extends IAPIConfig { + model: OpenAIModels | string, + organization?: string, +}; export interface IBaseConfig { baseLanguage: LanguageCodes; localesDir: string; targetLanguages: LanguageCodes[]; - apiKey: string; email: string; - sortBy: SortBy -} -export interface ICIConfig { - platform: Platform | undefined, - owner: string, - repo: string, - apiBaseUrl: string, - apiToken: string -} - -export interface ILibConfig extends ICIConfig, IBaseConfig {} + sortBy: SortBy; + ai: IAIConfig; + ci?: ICIConfig; +}; export const baseConfig: IBaseConfig = { baseLanguage: LanguageCodes.English, localesDir: ConfigConstants.localesDir, targetLanguages: [LanguageCodes.English, LanguageCodes.Turkish], - apiKey: ConfigConstants.openAIKey, email: ConfigConstants.email, - sortBy: SortBy.asceding + sortBy: SortBy.asceding, + ai: { + baseUrl: OpenAIAPI.baseUrl, + token: OpenAIAPI.token, + model: OpenAIAPI.model + }, }; -export function loadConfig(configPath: string, packageJsonPath: string): ILibConfig { +export function loadConfig(configPath: string, packageJsonPath: string): IBaseConfig { const configuration = require(configPath); const pkg = require(packageJsonPath); if(!pkg.repository?.url) { - throw new Error(`[Localize AI][Config] repository information not found in ${packageJsonPath}`); + throw new Error(`[Localize AI][loadConfig] repository information not found in ${packageJsonPath}`); } const { platform, owner, repo } = Parser.parseRepositoryUrl(pkg.repository.url); @@ -43,10 +55,10 @@ export function loadConfig(configPath: string, packageJsonPath: string): ILibCon platform, owner, repo, - apiBaseUrl: (platform === Platform.github) ? GithubAPI.baseUrl || '' : (platform === Platform.bitbucket) ? BitbucketAPI.baseUrl || '' : '', - apiToken: (platform === Platform.github) ? GithubAPI.token || '' : (platform === Platform.bitbucket) ? BitbucketAPI.token || '' : '' + baseUrl: (platform === Platform.github) ? GithubAPI.baseUrl || '' : (platform === Platform.bitbucket) ? BitbucketAPI.baseUrl || '' : '', + token: (platform === Platform.github) ? GithubAPI.token || '' : (platform === Platform.bitbucket) ? BitbucketAPI.token || '' : '' }; - return { ...baseConfig, ...ciConfig, ...configuration }; + return { ...baseConfig, ci: { ...ciConfig }, ...configuration }; }; diff --git a/src/constants/index.ts b/src/constants/index.ts index 8d8bf10..f46aadf 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,119 +1,118 @@ export enum LanguageCodes { - "Afrikaans" = "af", - "Albanian" = "sq", - "Amharic" = "am", - "Arabic" = "ar", - "Armenian" = "hy", - "Azerbaijani" = "az", - "Basque" = "eu", - "Belarusian" = "be", - "Bengali" = "bn", - "Bosnian" = "bs", - "Bulgarian" = "bg", - "Catalan" = "ca", - "Cebuano" = "ceb", - "Chichewa" = "ny", - "Chinese (Simplified)" = "zh-cn", - "Chinese (Traditional)" = "zh-tw", - "Corsican" = "co", - "Croatian" = "hr", - "Czech" = "cs", - "Danish" = "da", - "Dutch" = "nl", - "English" = "en", - "Esperanto" = "eo", - "Estonian" = "et", - "Filipino" = "tl", - "Finnish" = "fi", - "French" = "fr", - "Frisian" = "fy", - "Galician" = "gl", - "Georgian" = "ka", - "German" = "de", - "Greek" = "el", - "Gujarati" = "gu", - "Haitian Creole" = "ht", - "Hausa" = "ha", - "Hawaiian" = "haw", - "Hebrew" = "iw", - "Hindi" = "hi", - "Hmong" = "hmn", - "Hungarian" = "hu", - "Icelandic" = "is", - "Igbo" = "ig", - "Indonesian" = "id", - "Irish" = "ga", - "Italian" = "it", - "Japanese" = "ja", - "Javanese" = "jv", - "Kannada" = "kn", - "Kazakh" = "kk", - "Khmer" = "km", - "Kinyarwanda" = "rw", - "Korean" = "ko", - "Kurdish (Kurmanji)" = "ku", - "Kyrgyz" = "ky", - "Lao" = "lo", - "Latin" = "la", - "Latvian" = "lv", - "Lithuanian" = "lt", - "Luxembourgish" = "lb", - "Macedonian" = "mk", - "Malagasy" = "mg", - "Malay" = "ms", - "Malayalam" = "ml", - "Maltese" = "mt", - "Maori" = "mi", - "Marathi" = "mr", - "Mongolian" = "mn", - "Myanmar (Burmese)" = "my", - "Nepali" = "ne", - "Norwegian" = "no", - "Odia (Oriya)" = "or", - "Pashto" = "ps", - "Persian" = "fa", - "Polish" = "pl", - "Portuguese" = "pt", - "Punjabi" = "pa", - "Romanian" = "ro", - "Russian" = "ru", - "Samoan" = "sm", - "Scots Gaelic" = "gd", - "Serbian" = "sr", - "Sesotho" = "st", - "Shona" = "sn", - "Sindhi" = "sd", - "Sinhala" = "si", - "Slovak" = "sk", - "Slovenian" = "sl", - "Somali" = "so", - "Spanish" = "es", - "Sundanese" = "su", - "Swahili" = "sw", - "Swedish" = "sv", - "Tajik" = "tg", - "Tamil" = "ta", - "Tatar" = "tt", - "Telugu" = "te", - "Thai" = "th", - "Turkish" = "tr", - "Turkmen" = "tk", - "Ukrainian" = "uk", - "Urdu" = "ur", - "Uyghur" = "ug", - "Uzbek" = "uz", - "Vietnamese" = "vi", - "Welsh" = "cy", - "Xhosa" = "xh", - "Yiddish" = "yi", - "Yoruba" = "yo", - "Zulu" = "zu" + 'Afrikaans' = 'af', + 'Albanian' = 'sq', + 'Amharic' = 'am', + 'Arabic' = 'ar', + 'Armenian' = 'hy', + 'Azerbaijani' = 'az', + 'Basque' = 'eu', + 'Belarusian' = 'be', + 'Bengali' = 'bn', + 'Bosnian' = 'bs', + 'Bulgarian' = 'bg', + 'Catalan' = 'ca', + 'Cebuano' = 'ceb', + 'Chichewa' = 'ny', + 'Chinese (Simplified)' = 'zh-cn', + 'Chinese (Traditional)' = 'zh-tw', + 'Corsican' = 'co', + 'Croatian' = 'hr', + 'Czech' = 'cs', + 'Danish' = 'da', + 'Dutch' = 'nl', + 'English' = 'en', + 'Esperanto' = 'eo', + 'Estonian' = 'et', + 'Filipino' = 'tl', + 'Finnish' = 'fi', + 'French' = 'fr', + 'Frisian' = 'fy', + 'Galician' = 'gl', + 'Georgian' = 'ka', + 'German' = 'de', + 'Greek' = 'el', + 'Gujarati' = 'gu', + 'Haitian Creole' = 'ht', + 'Hausa' = 'ha', + 'Hawaiian' = 'haw', + 'Hebrew' = 'iw', + 'Hindi' = 'hi', + 'Hmong' = 'hmn', + 'Hungarian' = 'hu', + 'Icelandic' = 'is', + 'Igbo' = 'ig', + 'Indonesian' = 'id', + 'Irish' = 'ga', + 'Italian' = 'it', + 'Japanese' = 'ja', + 'Javanese' = 'jv', + 'Kannada' = 'kn', + 'Kazakh' = 'kk', + 'Khmer' = 'km', + 'Kinyarwanda' = 'rw', + 'Korean' = 'ko', + 'Kurdish (Kurmanji)' = 'ku', + 'Kyrgyz' = 'ky', + 'Lao' = 'lo', + 'Latin' = 'la', + 'Latvian' = 'lv', + 'Lithuanian' = 'lt', + 'Luxembourgish' = 'lb', + 'Macedonian' = 'mk', + 'Malagasy' = 'mg', + 'Malay' = 'ms', + 'Malayalam' = 'ml', + 'Maltese' = 'mt', + 'Maori' = 'mi', + 'Marathi' = 'mr', + 'Mongolian' = 'mn', + 'Myanmar (Burmese)' = 'my', + 'Nepali' = 'ne', + 'Norwegian' = 'no', + 'Odia (Oriya)' = 'or', + 'Pashto' = 'ps', + 'Persian' = 'fa', + 'Polish' = 'pl', + 'Portuguese' = 'pt', + 'Punjabi' = 'pa', + 'Romanian' = 'ro', + 'Russian' = 'ru', + 'Samoan' = 'sm', + 'Scots Gaelic' = 'gd', + 'Serbian' = 'sr', + 'Sesotho' = 'st', + 'Shona' = 'sn', + 'Sindhi' = 'sd', + 'Sinhala' = 'si', + 'Slovak' = 'sk', + 'Slovenian' = 'sl', + 'Somali' = 'so', + 'Spanish' = 'es', + 'Sundanese' = 'su', + 'Swahili' = 'sw', + 'Swedish' = 'sv', + 'Tajik' = 'tg', + 'Tamil' = 'ta', + 'Tatar' = 'tt', + 'Telugu' = 'te', + 'Thai' = 'th', + 'Turkish' = 'tr', + 'Turkmen' = 'tk', + 'Ukrainian' = 'uk', + 'Urdu' = 'ur', + 'Uyghur' = 'ug', + 'Uzbek' = 'uz', + 'Vietnamese' = 'vi', + 'Welsh' = 'cy', + 'Xhosa' = 'xh', + 'Yiddish' = 'yi', + 'Yoruba' = 'yo', + 'Zulu' = 'zu' }; - export enum Platform { - github = "github", - bitbucket = "bitbucket" + github = 'github', + bitbucket = 'bitbucket' }; export const RegexPatterns = { @@ -122,8 +121,8 @@ export const RegexPatterns = { }; export const Commit = { - title: "\"chore: [Localize AI] Translation Update\"", - description: "\"[Localize AI] Translations completed\"" + title: '\'chore: [Localize AI] Translation Update\'', + description: '\'[Localize AI] Translations completed\'' }; export const GithubAPI = { @@ -141,9 +140,32 @@ export const ConfigConstants = { packageJsonPath: './package.json', localesDir: './locales', projectDir: './', - openAIKey: process.env.OPENAI_API_KEY || 'your-api-key', email: 'localize@celsus-ai.com', - username:"celsus-ai/localize" + username:'celsus-ai/localize' +} + +export enum OpenAIModels { + 'gpt-4' = 'gpt-4', + 'gpt-4-0613' = 'gpt-4-0613', + 'gpt-4-32k' = 'gpt-4-32k', + 'gpt-4-32k-0613' = 'gpt-4-32k-0613', + 'gpt-4-0314' = 'gpt-4-0314', + 'gpt-4-32k-0314' = 'gpt-4-32k-0314', + 'gpt-3.5-turbo' = 'gpt-3.5-turbo', + 'gpt-3.5-turbo-16k' = 'gpt-3.5-turbo-16k', + 'gpt-3.5-turbo-instruct' = 'gpt-3.5-turbo-instruct', + 'gpt-3.5-turbo-0613' = 'gpt-3.5-turbo-0613', + 'gpt-3.5-turbo-16k-0613' = 'gpt-3.5-turbo-16k-0613', + 'gpt-3.5-turbo-0301' = 'gpt-3.5-turbo-0301', + 'text-davinci-003' = 'text-davinci-003', + 'text-davinci-002' = '', + 'code-davinci-002' = 'code-davinci-002' +} + +export const OpenAIAPI = { + baseUrl: 'https://api.openai.com/v1/', + token: process.env.OPENAI_API_KEY || 'your-api-key', + model: process.env.OPENAI_MODEL || OpenAIModels['gpt-3.5-turbo'], } export enum SortBy { diff --git a/src/index.ts b/src/index.ts index 287867b..1548132 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import { LocalizationAI } from "./modules/localize/localize"; import {GitBot, BitbucketCIBot, GithubCIBot } from "./modules/ci"; -import { ILibConfig, loadConfig } from "./config"; +import { IBaseConfig, loadConfig } from "./config"; import { logger } from './utils' import { Platform, ConfigConstants } from "./constants"; import path from 'path'; @@ -9,14 +9,14 @@ const isCIEnvironment = process.env.CI; const baseBranch = process.env.GITHUB_REF || process.env.BITBUCKET_BRANCH || ''; const translationBranch = `localize-ai-${new Date().getTime()}`; -function ciCreator(config: ILibConfig ): GitBot { - switch(config.platform){ +function ciCreator(config: IBaseConfig ): GitBot { + switch(config.ci?.platform){ case Platform.github: return new GithubCIBot(config); case Platform.bitbucket: return new BitbucketCIBot(config); default: - throw new Error(`[Localize AI][ciCreator] unsupported ci environment: ${config.platform}`); + throw new Error(`[Localize AI][ciCreator] unsupported ci environment: ${config.ci?.platform}`); } } diff --git a/src/modules/ci/bitbucket-ci.bot.ts b/src/modules/ci/bitbucket-ci.bot.ts index 2d3164e..278d99f 100644 --- a/src/modules/ci/bitbucket-ci.bot.ts +++ b/src/modules/ci/bitbucket-ci.bot.ts @@ -1,22 +1,20 @@ -import { ILibConfig } from "../../config"; +import { IBaseConfig } from "../../config"; import { Commit } from "../../constants"; -import { logger, HttpClient } from '../../utils/'; +import { logger } from '../../utils/'; import { GitBot } from './git.bot'; export class BitbucketCIBot extends GitBot { - private httpClient: HttpClient; - constructor(config: ILibConfig){ + constructor(config: IBaseConfig){ super(config); - this.httpClient = new HttpClient(config.apiBaseUrl, config.apiToken); } public async createPullRequest(baseBranch: string, translationBranch: string,): Promise { - const { owner, repo } = this.config; + const { ci } = this.config; logger.debug('[Localize AI][BitbucketCIBot] pull request creating...', { baseBranch, translationBranch }); - const endpoint = `${owner}/${repo}/pullrequests/`; + const endpoint = `${ci?.owner}/${ci?.repo}/pullrequests/`; const payload = { title: Commit.title, description: Commit.description, @@ -26,7 +24,7 @@ export class BitbucketCIBot extends GitBot { name: translationBranch }, repository:{ - full_name:`${owner}/${repo}` + full_name:`${ci?.owner}/${ci?.repo}` } }, destination: { diff --git a/src/modules/ci/git.bot.ts b/src/modules/ci/git.bot.ts index 72059f8..4ff4cad 100644 --- a/src/modules/ci/git.bot.ts +++ b/src/modules/ci/git.bot.ts @@ -1,12 +1,16 @@ -import { ILibConfig } from "../../config"; +import { IBaseConfig } from "../../config"; import { execSync } from 'child_process'; -import { logger } from '../../utils'; +import { HttpClient, logger } from '../../utils'; import { Commit, ConfigConstants } from "../../constants"; - export abstract class GitBot { - protected config: ILibConfig; - constructor(config: ILibConfig){ + protected config: IBaseConfig; + protected httpClient: HttpClient; + constructor(config: IBaseConfig) { this.config = config; + this.httpClient = new HttpClient({ + baseUrl: config.ci?.baseUrl || '', + token: config.ci?.token || '' + }); } public hasTranslationChanges(): boolean { @@ -21,7 +25,7 @@ export abstract class GitBot { execSync(`git checkout -b ${translationBranch}`); } - public stagedChanges(): void{ + public stagedChanges(): void { const { localesDir } = this.config; logger.debug('[Localize AI][GitBot] changes staging...'); execSync(`git add ${localesDir}/*.json`); diff --git a/src/modules/ci/github-ci.bot.ts b/src/modules/ci/github-ci.bot.ts index 68a21ba..683a224 100644 --- a/src/modules/ci/github-ci.bot.ts +++ b/src/modules/ci/github-ci.bot.ts @@ -1,21 +1,19 @@ -import { ILibConfig } from "../../config"; +import { IBaseConfig } from "../../config"; import { Commit } from "../../constants"; -import {logger, HttpClient, Parser} from '../../utils'; +import { logger } from '../../utils'; import { GitBot } from './git.bot'; export class GithubCIBot extends GitBot { - private httpClient : HttpClient; - constructor(config: ILibConfig){ + constructor(config: IBaseConfig){ super(config); - this.httpClient = new HttpClient(config.apiBaseUrl, config.apiToken); } public async createPullRequest(baseBranch: string, translationBranch: string): Promise { - const { owner, repo } = this.config; + const { ci } = this.config; logger.debug('[Localize AI][GithubCIBot] pull request creating...', { baseBranch, translationBranch }); - const endpoint = `${owner}/${repo}/pulls`; + const endpoint = `${ci?.owner}/${ci?.repo}/pulls`; const payload = { title: Commit.title, body: Commit.description, diff --git a/src/modules/localize/localize.ts b/src/modules/localize/localize.ts index da2a740..43f90e2 100644 --- a/src/modules/localize/localize.ts +++ b/src/modules/localize/localize.ts @@ -1,6 +1,5 @@ import * as fs from 'fs'; -import { OpenAIApi, Configuration, CreateChatCompletionRequest } from 'openai'; -import { logger, Sorter } from '../../utils'; +import { HttpClient, logger, Sorter } from '../../utils'; import { LanguageCodes } from '../../constants'; import { IBaseConfig } from '../../config'; @@ -10,19 +9,23 @@ export interface Translation { export class LocalizationAI { private config: IBaseConfig; - private openAIClient: OpenAIApi; + private httpClient: HttpClient; constructor(config: IBaseConfig) { this.config = config; - this.openAIClient = new OpenAIApi(new Configuration({ apiKey: config.apiKey })); + this.httpClient = new HttpClient({ + baseUrl: config.ai?.baseUrl || '', + token: config.ai?.token || '' + }); } private async openAITranslator(baseLanguage: LanguageCodes, targetLanguage: LanguageCodes, sourceText: string): Promise { logger.debug('[Localize AI][openAITranslator] being translated...', { baseLanguage, targetLanguage, sourceText }); - const createChatCompletionRequest: CreateChatCompletionRequest = { - model: "gpt-3.5-turbo", + const endpoint = 'chat/completions' + const createChatCompletionRequest = { + model: this.config.ai.model, messages: [ { role: "user", @@ -31,8 +34,8 @@ export class LocalizationAI { ] } - const translation: any = await this.openAIClient.createChatCompletion(createChatCompletionRequest); - return translation.data.choices[0].message.content; + const translation: any = await this.httpClient.post(endpoint ,createChatCompletionRequest) + return translation.choices[0].message.content; } public async translate(): Promise { diff --git a/src/utils/http-client.ts b/src/utils/http-client.ts index 0f66521..7871e8f 100644 --- a/src/utils/http-client.ts +++ b/src/utils/http-client.ts @@ -1,18 +1,16 @@ import axios from 'axios'; import { logger } from '../utils'; +import { IAPIConfig } from '../config'; export class HttpClient { - private baseUrl: string; - private token: string; - - constructor(baseUrl: string, token: string) { - this.baseUrl = baseUrl; - this.token = token; + private readonly api: IAPIConfig + constructor(apiConfig: IAPIConfig) { + this.api = apiConfig; } private getHeaders(): { [key: string]: string } { return { - 'Authorization': `Bearer ${this.token}`, + 'Authorization': `Bearer ${this.api.token}`, 'Content-Type': 'application/json' }; } @@ -21,10 +19,10 @@ export class HttpClient { const headers = this.getHeaders(); try{ - const response = await axios.post(`${this.baseUrl}${endpoint}`, payload, { headers }); + const response = await axios.post(`${this.api.baseUrl}${endpoint}`, payload, { headers }); return response.data; } catch(err) { - logger.error('[Localize AI][HttpClient] Error creating pull request:', { err }); + logger.error('[Localize AI][HttpClient] Something went wrong', { err }); throw err; } } diff --git a/tsconfig.json b/tsconfig.json index dea6d63..6586358 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,7 @@ "target": "ES2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ From 96b52dbf8bb24859d0ef662e1c26120bf02d81ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harun=20KELE=C5=9EO=C4=9ELU?= Date: Sun, 1 Oct 2023 18:24:04 +0300 Subject: [PATCH 2/4] fix: added axios package --- package-lock.json | 100 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 101 insertions(+) diff --git a/package-lock.json b/package-lock.json index 6b53a73..d221c67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@semantic-release/github": "^9.0.3", "@semantic-release/npm": "^10.0.4", "@types/node": "^20.3.1", + "axios": "^1.5.1", "husky": "^8.0.0", "reflect-metadata": "^0.1.13", "semantic-release": "^21.0.5" @@ -1456,6 +1457,23 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/axios": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", @@ -1639,6 +1657,18 @@ "text-hex": "1.0.x" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -1914,6 +1944,15 @@ "node": ">=4.0.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", @@ -2262,6 +2301,40 @@ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -3173,6 +3246,27 @@ "node": ">=10.0.0" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -6762,6 +6856,12 @@ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "dev": true }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", diff --git a/package.json b/package.json index de7ae5a..952f4de 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@semantic-release/github": "^9.0.3", "@semantic-release/npm": "^10.0.4", "@types/node": "^20.3.1", + "axios": "^1.5.1", "husky": "^8.0.0", "reflect-metadata": "^0.1.13", "semantic-release": "^21.0.5" From a3ce7c5064ab7fe55a350ed49d550570068c99b8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 1 Oct 2023 15:25:07 +0000 Subject: [PATCH 3/4] chore(release): 2.2.0-alpha.1 [skip ci] # [2.2.0-alpha.1](https://github.com/celsus-ai/localize/compare/v2.1.1...v2.2.0-alpha.1) (2023-10-01) ### Bug Fixes * added axios package ([96b52db](https://github.com/celsus-ai/localize/commit/96b52dbf8bb24859d0ef662e1c26120bf02d81ab)) * added axios package ([#29](https://github.com/celsus-ai/localize/issues/29)) ([fa05567](https://github.com/celsus-ai/localize/commit/fa0556788c34545bafb9b3e998f20af21ea397f9)) ### Features * removed openai package dependency ([a08a2b4](https://github.com/celsus-ai/localize/commit/a08a2b4bdeab756a5b8e4f842a7ce85bb544a0e0)) * removed openai package dependency ([#28](https://github.com/celsus-ai/localize/issues/28)) ([2a7f2ff](https://github.com/celsus-ai/localize/commit/2a7f2ff8d021bfec9faf00a0bed4f63a63d3eb42)) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d221c67..15ee534 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@celsus-ai/localize", - "version": "2.1.1", + "version": "2.2.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@celsus-ai/localize", - "version": "2.1.1", + "version": "2.2.0-alpha.1", "license": "MIT", "dependencies": { "winston": "^3.9.0" diff --git a/package.json b/package.json index 952f4de..23702e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@celsus-ai/localize", - "version": "2.1.1", + "version": "2.2.0-alpha.1", "description": "The LocalizeAI is an npm package that enables easy localization of your applications using OpenAI. It provides seamless integration with OpenAI's language models, allowing you to localize and adapt your applications to different languages and regions effortlessly", "main": "dist/index.js", "private": false, From 090aa4034120cb87484ce538106e830826c83561 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 1 Oct 2023 15:30:55 +0000 Subject: [PATCH 4/4] chore(release): 2.2.0-beta.1 [skip ci] # [2.2.0-beta.1](https://github.com/celsus-ai/localize/compare/v2.1.1...v2.2.0-beta.1) (2023-10-01) ### Bug Fixes * added axios package ([96b52db](https://github.com/celsus-ai/localize/commit/96b52dbf8bb24859d0ef662e1c26120bf02d81ab)) * added axios package ([#29](https://github.com/celsus-ai/localize/issues/29)) ([fa05567](https://github.com/celsus-ai/localize/commit/fa0556788c34545bafb9b3e998f20af21ea397f9)) ### Features * removed openai package dependency ([a08a2b4](https://github.com/celsus-ai/localize/commit/a08a2b4bdeab756a5b8e4f842a7ce85bb544a0e0)) * removed openai package dependency ([#28](https://github.com/celsus-ai/localize/issues/28)) ([2a7f2ff](https://github.com/celsus-ai/localize/commit/2a7f2ff8d021bfec9faf00a0bed4f63a63d3eb42)) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15ee534..6feb4de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@celsus-ai/localize", - "version": "2.2.0-alpha.1", + "version": "2.2.0-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@celsus-ai/localize", - "version": "2.2.0-alpha.1", + "version": "2.2.0-beta.1", "license": "MIT", "dependencies": { "winston": "^3.9.0" diff --git a/package.json b/package.json index 23702e1..e189082 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@celsus-ai/localize", - "version": "2.2.0-alpha.1", + "version": "2.2.0-beta.1", "description": "The LocalizeAI is an npm package that enables easy localization of your applications using OpenAI. It provides seamless integration with OpenAI's language models, allowing you to localize and adapt your applications to different languages and regions effortlessly", "main": "dist/index.js", "private": false,