diff --git a/README.md b/README.md index 6361fff..745f8c3 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ The action is designed to be modular, with multiple plugins to choose from for e | `hide-curriculum-strings` | This plugin runs through all of the strings in the specified project and hides them if they meet specific conditions. | none | | `hide-renpy-strings` | This plugin runs through all of the strings in the specified project and hides them if they meet specific conditions. | none | | `hide-string` | Looks for a specific string in a specific file and marks it as hidden. | `FILE_NAME`, `STRING_CONTENT` | +| `lowercase-directories` | This plugin will walk through the `FILE_PATHS` directories and make sure all directories are set to lowercase | `FILE_PATHS` | | | `pull-request` | Creates a pull request from the specified branch and targets the specified base, or main by default. | `GH_TOKEN`, `BRANCH`, `REPOSITORY`, `BASE`, `TITLE`, `BODY` | | `remove-deleted-files` | This will recursively walk through the `FILE_PATHS` directories and remove any files from Crowdin that are no longer present in the repo. Note that `FILE_PATHS` should be a stringified array, as GitHub `yaml` doesn't accept array values: `'["curriculum/challenges/english", "curriculum/dictionaries/english"]'` | `FILE_PATHS` | | `unhide-string` | Looks for a specific string in a specific file and marks it as visible. | `FILE_NAME`, `STRING_CONTENT` | diff --git a/dist/index.js b/dist/index.js index 5000977..6efa97b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -40052,115 +40052,123 @@ function wrappy (fn, cb) { /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const core_1 = __nccwpck_require__(6733); -const check_paths_1 = __nccwpck_require__(56); -const commit_changes_1 = __nccwpck_require__(1827); -const convert_chinese_1 = __nccwpck_require__(8940); -const generate_config_1 = __nccwpck_require__(8605); -const hide_curriculum_strings_1 = __nccwpck_require__(8644); -const hide_renpy_strings_1 = __nccwpck_require__(2624); -const hide_specific_string_1 = __nccwpck_require__(6261); -const pull_request_1 = __nccwpck_require__(1107); -const remove_deleted_files_1 = __nccwpck_require__(5823); -const unhide_specific_string_1 = __nccwpck_require__(4378); -const validate_environment_1 = __nccwpck_require__(1246); -(() => __awaiter(void 0, void 0, void 0, function* () { - const validEnvironment = (0, validate_environment_1.validateEnvironment)(); - if (!validEnvironment) { - (0, core_1.setFailed)("Missing Crowdin credentials."); - return; - } - const projectId = parseInt(process.env.CROWDIN_PROJECT_ID || "", 10); - if (isNaN(projectId)) { - (0, core_1.setFailed)("Invalid Crowdin project ID."); - return; - } - const plugin = process.env.PLUGIN; - if (!plugin) { - (0, core_1.setFailed)("No plugins specified."); - return; - } - switch (plugin) { - case "check-paths": - yield (0, check_paths_1.checkPaths)(); - break; - case "commit-changes": - if (!process.env.GH_BRANCH || !process.env.GH_MESSAGE) { - (0, core_1.setFailed)("Missing commit configuration data."); - break; - } - yield (0, commit_changes_1.commitChanges)(process.env.GH_USERNAME || "camperbot", process.env.GH_EMAIL || "camperbot@users.noreply.github.com", process.env.GH_BRANCH, process.env.GH_MESSAGE); - break; - case "convert-chinese": - if (!process.env.FILE_PATHS) { - (0, core_1.setFailed)("Missing file paths."); - break; - } - yield (0, convert_chinese_1.convertChinese)(JSON.parse(process.env.FILE_PATHS)); - break; - case "generate-config": - if (!process.env.PROJECT_NAME) { - (0, core_1.setFailed)("Missing project name."); - break; - } - yield (0, generate_config_1.generateConfig)(process.env.PROJECT_NAME); - break; - case "hide-curriculum-strings": - yield (0, hide_curriculum_strings_1.hideCurriculumStrings)(projectId); - break; - case "hide-renpy-strings": - yield (0, hide_renpy_strings_1.hideRenpyStrings)(projectId); - break; - case "hide-string": - if (!process.env.FILE_NAME || !process.env.STRING_CONTENT) { - (0, core_1.setFailed)("Missing file name and/or string content."); - break; - } - yield (0, hide_specific_string_1.hideSpecificString)(projectId, process.env.FILE_NAME, process.env.STRING_CONTENT); - break; - case "pull-request": - if (!process.env.GH_TOKEN || - !process.env.BRANCH || - !process.env.REPOSITORY || - !process.env.BASE || - !process.env.TITLE || - !process.env.BODY) { - (0, core_1.setFailed)("Missing pull request configuration data."); - break; - } - (yield (0, pull_request_1.createPullRequest)(process.env.GH_TOKEN, process.env.BRANCH, process.env.REPOSITORY, process.env.BASE, process.env.TITLE, process.env.BODY, process.env.LABELS, process.env.REVIEWERS, process.env.TEAM_REVIEWERS)) - ? null - : (0, core_1.setFailed)("Failed to create pull request."); - break; - case "remove-deleted-files": - if (!process.env.FILE_PATHS) { - (0, core_1.setFailed)("Missing file path."); - break; - } - yield (0, remove_deleted_files_1.removeDeletedFiles)(projectId, JSON.parse(process.env.FILE_PATHS)); - break; - case "unhide-string": - if (!process.env.FILE_NAME || !process.env.STRING_CONTENT) { - (0, core_1.setFailed)("Missing file name and/or string content."); - break; - } - yield (0, unhide_specific_string_1.unhideSpecificString)(projectId, process.env.FILE_NAME, process.env.STRING_CONTENT); - break; - default: - (0, core_1.setFailed)("Invalid plugin specified."); - } -}))(); + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core_1 = __nccwpck_require__(6733); +const check_paths_1 = __nccwpck_require__(56); +const commit_changes_1 = __nccwpck_require__(1827); +const convert_chinese_1 = __nccwpck_require__(8940); +const generate_config_1 = __nccwpck_require__(8605); +const hide_curriculum_strings_1 = __nccwpck_require__(8644); +const hide_renpy_strings_1 = __nccwpck_require__(2624); +const hide_specific_string_1 = __nccwpck_require__(6261); +const lowercase_directories_1 = __nccwpck_require__(4960); +const pull_request_1 = __nccwpck_require__(1107); +const remove_deleted_files_1 = __nccwpck_require__(5823); +const unhide_specific_string_1 = __nccwpck_require__(4378); +const validate_environment_1 = __nccwpck_require__(1246); +(() => __awaiter(void 0, void 0, void 0, function* () { + const validEnvironment = (0, validate_environment_1.validateEnvironment)(); + if (!validEnvironment) { + (0, core_1.setFailed)("Missing Crowdin credentials."); + return; + } + const projectId = parseInt(process.env.CROWDIN_PROJECT_ID || "", 10); + if (isNaN(projectId)) { + (0, core_1.setFailed)("Invalid Crowdin project ID."); + return; + } + const plugin = process.env.PLUGIN; + if (!plugin) { + (0, core_1.setFailed)("No plugins specified."); + return; + } + switch (plugin) { + case "check-paths": + yield (0, check_paths_1.checkPaths)(); + break; + case "commit-changes": + if (!process.env.GH_BRANCH || !process.env.GH_MESSAGE) { + (0, core_1.setFailed)("Missing commit configuration data."); + break; + } + yield (0, commit_changes_1.commitChanges)(process.env.GH_USERNAME || "camperbot", process.env.GH_EMAIL || "camperbot@users.noreply.github.com", process.env.GH_BRANCH, process.env.GH_MESSAGE); + break; + case "convert-chinese": + if (!process.env.FILE_PATHS) { + (0, core_1.setFailed)("Missing file paths."); + break; + } + yield (0, convert_chinese_1.convertChinese)(JSON.parse(process.env.FILE_PATHS)); + break; + case "generate-config": + if (!process.env.PROJECT_NAME) { + (0, core_1.setFailed)("Missing project name."); + break; + } + yield (0, generate_config_1.generateConfig)(process.env.PROJECT_NAME); + break; + case "hide-curriculum-strings": + yield (0, hide_curriculum_strings_1.hideCurriculumStrings)(projectId); + break; + case "hide-renpy-strings": + yield (0, hide_renpy_strings_1.hideRenpyStrings)(projectId); + break; + case "hide-string": + if (!process.env.FILE_NAME || !process.env.STRING_CONTENT) { + (0, core_1.setFailed)("Missing file name and/or string content."); + break; + } + yield (0, hide_specific_string_1.hideSpecificString)(projectId, process.env.FILE_NAME, process.env.STRING_CONTENT); + break; + case "lowercase-directories": + if (!process.env.FILE_PATHS) { + (0, core_1.setFailed)("Missing file paths."); + break; + } + (0, lowercase_directories_1.lowercaseDirectories)(JSON.parse(process.env.FILE_PATHS)); + break; + case "pull-request": + if (!process.env.GH_TOKEN || + !process.env.BRANCH || + !process.env.REPOSITORY || + !process.env.BASE || + !process.env.TITLE || + !process.env.BODY) { + (0, core_1.setFailed)("Missing pull request configuration data."); + break; + } + (yield (0, pull_request_1.createPullRequest)(process.env.GH_TOKEN, process.env.BRANCH, process.env.REPOSITORY, process.env.BASE, process.env.TITLE, process.env.BODY, process.env.LABELS, process.env.REVIEWERS, process.env.TEAM_REVIEWERS)) + ? null + : (0, core_1.setFailed)("Failed to create pull request."); + break; + case "remove-deleted-files": + if (!process.env.FILE_PATHS) { + (0, core_1.setFailed)("Missing file path."); + break; + } + yield (0, remove_deleted_files_1.removeDeletedFiles)(projectId, JSON.parse(process.env.FILE_PATHS)); + break; + case "unhide-string": + if (!process.env.FILE_NAME || !process.env.STRING_CONTENT) { + (0, core_1.setFailed)("Missing file name and/or string content."); + break; + } + yield (0, unhide_specific_string_1.unhideSpecificString)(projectId, process.env.FILE_NAME, process.env.STRING_CONTENT); + break; + default: + (0, core_1.setFailed)("Invalid plugin specified."); + } +}))(); /***/ }), @@ -40169,30 +40177,30 @@ const validate_environment_1 = __nccwpck_require__(1246); /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.checkPaths = void 0; -const child_process_1 = __nccwpck_require__(2081); -const util_1 = __nccwpck_require__(3837); -/** - * Utility to print the current directory and its contents. - */ -const checkPaths = () => __awaiter(void 0, void 0, void 0, function* () { - const currentDirectory = process.cwd(); - const awaitExec = (0, util_1.promisify)(child_process_1.exec); - const currentDirectoryContents = (yield awaitExec("ls -a")).stdout; - console.table({ currentDirectory, currentDirectoryContents }); -}); -exports.checkPaths = checkPaths; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.checkPaths = void 0; +const child_process_1 = __nccwpck_require__(2081); +const util_1 = __nccwpck_require__(3837); +/** + * Utility to print the current directory and its contents. + */ +const checkPaths = () => __awaiter(void 0, void 0, void 0, function* () { + const currentDirectory = process.cwd(); + const awaitExec = (0, util_1.promisify)(child_process_1.exec); + const currentDirectoryContents = (yield awaitExec("ls -a")).stdout; + console.table({ currentDirectory, currentDirectoryContents }); +}); +exports.checkPaths = checkPaths; /***/ }), @@ -40201,40 +40209,40 @@ exports.checkPaths = checkPaths; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.commitChanges = void 0; -const child_process_1 = __nccwpck_require__(2081); -const util_1 = __nccwpck_require__(3837); -/** - * Module to stage all current changes except the crowdin-config.yml file and - * commit them to a designated branch name. - * - * @param {string} username The GitHub username to commit from. - * @param {string} email The GitHub email to commit from. - * @param {string} branchName The name of the branch to commit to. - * @param {string} commitMessage The commit message to use. - */ -const commitChanges = (username, email, branchName, commitMessage) => __awaiter(void 0, void 0, void 0, function* () { - const asyncExec = (0, util_1.promisify)(child_process_1.exec); - yield asyncExec(`git config --global user.name ${username}`); - yield asyncExec(`git config --global user.email ${email}`); - yield asyncExec(`git checkout -b ${branchName}`); - yield asyncExec("git add ."); - yield asyncExec("git reset crowdin-config.yml"); - yield asyncExec(`git diff-index --quiet HEAD || git commit -m "${commitMessage}"`); - yield asyncExec(`git push -u origin ${branchName} -f`); -}); -exports.commitChanges = commitChanges; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.commitChanges = void 0; +const child_process_1 = __nccwpck_require__(2081); +const util_1 = __nccwpck_require__(3837); +/** + * Module to stage all current changes except the crowdin-config.yml file and + * commit them to a designated branch name. + * + * @param {string} username The GitHub username to commit from. + * @param {string} email The GitHub email to commit from. + * @param {string} branchName The name of the branch to commit to. + * @param {string} commitMessage The commit message to use. + */ +const commitChanges = (username, email, branchName, commitMessage) => __awaiter(void 0, void 0, void 0, function* () { + const asyncExec = (0, util_1.promisify)(child_process_1.exec); + yield asyncExec(`git config --global user.name ${username}`); + yield asyncExec(`git config --global user.email ${email}`); + yield asyncExec(`git checkout -b ${branchName}`); + yield asyncExec("git add ."); + yield asyncExec("git reset crowdin-config.yml"); + yield asyncExec(`git diff-index --quiet HEAD || git commit -m "${commitMessage}"`); + yield asyncExec(`git push -u origin ${branchName} -f`); +}); +exports.commitChanges = commitChanges; /***/ }), @@ -40243,62 +40251,62 @@ exports.commitChanges = commitChanges; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.convertChinese = void 0; -const promises_1 = __nccwpck_require__(3292); -const path_1 = __nccwpck_require__(1017); -const fs_extra_1 = __nccwpck_require__(1400); -const node_opencc_1 = __importDefault(__nccwpck_require__(637)); -const getFiles = (directory, fileList = []) => __awaiter(void 0, void 0, void 0, function* () { - const files = yield (0, promises_1.readdir)(directory); - for (const file of files) { - const fileStat = yield (0, promises_1.stat)((0, path_1.join)(directory, file)); - if (fileStat.isDirectory()) { - // eslint-disable-next-line no-param-reassign - fileList = yield getFiles((0, path_1.join)(directory, file), fileList); - } - else { - fileList.push((0, path_1.join)(directory, file)); - } - } - return fileList; -}); -/** - * Module to convert Simplified Chinese files to Traditional Chinese. - * - * @param {string[]} directories The directory to convert. - */ -const convertChinese = (directories) => __awaiter(void 0, void 0, void 0, function* () { - console.info("Getting file list..."); - for (const directory of directories) { - const files = yield getFiles((0, path_1.join)(process.cwd(), directory)); - for (const file of files) { - console.info(`Converting ${file}...`); - const fileText = yield (0, promises_1.readFile)(file, "utf-8"); - const translatedText = yield node_opencc_1.default.simplifiedToTraditional(fileText); - if (process.env.USE_LANG_CODE) { - yield (0, fs_extra_1.outputFile)(file.replace("zh", "zh-TW"), translatedText); - } - else { - yield (0, fs_extra_1.outputFile)(file.replace("chinese", "chinese-traditional"), translatedText); - } - } - } -}); -exports.convertChinese = convertChinese; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.convertChinese = void 0; +const promises_1 = __nccwpck_require__(3292); +const path_1 = __nccwpck_require__(1017); +const fs_extra_1 = __nccwpck_require__(1400); +const node_opencc_1 = __importDefault(__nccwpck_require__(637)); +const getFiles = (directory, fileList = []) => __awaiter(void 0, void 0, void 0, function* () { + const files = yield (0, promises_1.readdir)(directory); + for (const file of files) { + const fileStat = yield (0, promises_1.stat)((0, path_1.join)(directory, file)); + if (fileStat.isDirectory()) { + // eslint-disable-next-line no-param-reassign + fileList = yield getFiles((0, path_1.join)(directory, file), fileList); + } + else { + fileList.push((0, path_1.join)(directory, file)); + } + } + return fileList; +}); +/** + * Module to convert Simplified Chinese files to Traditional Chinese. + * + * @param {string[]} directories The directory to convert. + */ +const convertChinese = (directories) => __awaiter(void 0, void 0, void 0, function* () { + console.info("Getting file list..."); + for (const directory of directories) { + const files = yield getFiles((0, path_1.join)(process.cwd(), directory)); + for (const file of files) { + console.info(`Converting ${file}...`); + const fileText = yield (0, promises_1.readFile)(file, "utf-8"); + const translatedText = yield node_opencc_1.default.simplifiedToTraditional(fileText); + if (process.env.USE_LANG_CODE) { + yield (0, fs_extra_1.outputFile)(file.replace("zh", "zh-TW"), translatedText); + } + else { + yield (0, fs_extra_1.outputFile)(file.replace("chinese", "chinese-traditional"), translatedText); + } + } + } +}); +exports.convertChinese = convertChinese; /***/ }), @@ -40307,32 +40315,32 @@ exports.convertChinese = convertChinese; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.generateConfig = void 0; -const child_process_1 = __nccwpck_require__(2081); -const util_1 = __nccwpck_require__(3837); -/** - * Locates the correct config file for the provided project, and copies it to - * the current file system. - * - * @param {string} projectName The name of the project to load a config for. - */ -const generateConfig = (projectName) => __awaiter(void 0, void 0, void 0, function* () { - const asyncExec = (0, util_1.promisify)(child_process_1.exec); - const configPath = __nccwpck_require__.ab + "configs/" + projectName + '.yml'; - yield asyncExec(`cp ${configPath} ./crowdin-config.yml`); -}); -exports.generateConfig = generateConfig; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.generateConfig = void 0; +const child_process_1 = __nccwpck_require__(2081); +const util_1 = __nccwpck_require__(3837); +/** + * Locates the correct config file for the provided project, and copies it to + * the current file system. + * + * @param {string} projectName The name of the project to load a config for. + */ +const generateConfig = (projectName) => __awaiter(void 0, void 0, void 0, function* () { + const asyncExec = (0, util_1.promisify)(child_process_1.exec); + const configPath = __nccwpck_require__.ab + "configs/" + projectName + '.yml'; + yield asyncExec(`cp ${configPath} ./crowdin-config.yml`); +}); +exports.generateConfig = generateConfig; /***/ }), @@ -40341,71 +40349,71 @@ exports.generateConfig = generateConfig; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.hideCurriculumStrings = void 0; -const fs_1 = __nccwpck_require__(7147); -const path_1 = __nccwpck_require__(1017); -const gray_matter_1 = __importDefault(__nccwpck_require__(5594)); -const files_1 = __nccwpck_require__(1134); -const strings_1 = __nccwpck_require__(9185); -const createChallengeTitleLookup = (lookup, { fileId, path }, projectId) => { - const crowdinFilePath = - /** - * This is some hacky logic. Because we are using a single crowdin project - * for multiple repositories, the configs are set to nest the files within subdirectories - * on Crowdin. However, these subdirectories do not exist in the local repository files, so - * we need to detect if this plugin is running on that specific project. If so, remove the subdirectory - * from the path. - */ - String(projectId) === "31" ? (0, path_1.join)(...path.split("/").slice(1)) : path; - const challengeFilePath = (0, path_1.join)(process.cwd(), crowdinFilePath); - try { - const challengeContent = (0, fs_1.readFileSync)(challengeFilePath, "utf-8"); - const { data: { title: challengeTitle }, } = (0, gray_matter_1.default)(challengeContent); - return Object.assign(Object.assign({}, lookup), { [fileId]: { - crowdinFilePath, - challengeTitle, - } }); - } - catch (err) { - console.log(JSON.stringify(err, null, 2)); - return lookup; - } -}; -/** - * Module to hide the curriculum strings. - * - * @param {number} projectId The ID of the project to hide the strings for. - */ -const hideCurriculumStrings = (projectId) => __awaiter(void 0, void 0, void 0, function* () { - console.log("Hiding non-translated strings..."); - const crowdinFiles = yield files_1.CrowdinFilesHelper.getFiles(projectId); - if (crowdinFiles && crowdinFiles.length) { - const challengeTitleLookup = crowdinFiles.reduce((lookup, file) => createChallengeTitleLookup(lookup, file, projectId), {}); - const crowdinStrings = yield strings_1.CrowdinStringHelper.getStrings(projectId); - if (crowdinStrings && crowdinStrings.length) { - for (const string of crowdinStrings) { - const { crowdinFilePath, challengeTitle } = challengeTitleLookup[string.data.fileId]; - yield strings_1.CrowdinStringHelper.updateFileString(projectId, string, challengeTitle, crowdinFilePath); - } - } - } - console.log("complete"); -}); -exports.hideCurriculumStrings = hideCurriculumStrings; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.hideCurriculumStrings = void 0; +const fs_1 = __nccwpck_require__(7147); +const path_1 = __nccwpck_require__(1017); +const gray_matter_1 = __importDefault(__nccwpck_require__(5594)); +const files_1 = __nccwpck_require__(1134); +const strings_1 = __nccwpck_require__(9185); +const createChallengeTitleLookup = (lookup, { fileId, path }, projectId) => { + const crowdinFilePath = + /** + * This is some hacky logic. Because we are using a single crowdin project + * for multiple repositories, the configs are set to nest the files within subdirectories + * on Crowdin. However, these subdirectories do not exist in the local repository files, so + * we need to detect if this plugin is running on that specific project. If so, remove the subdirectory + * from the path. + */ + String(projectId) === "31" ? (0, path_1.join)(...path.split("/").slice(1)) : path; + const challengeFilePath = (0, path_1.join)(process.cwd(), crowdinFilePath); + try { + const challengeContent = (0, fs_1.readFileSync)(challengeFilePath, "utf-8"); + const { data: { title: challengeTitle }, } = (0, gray_matter_1.default)(challengeContent); + return Object.assign(Object.assign({}, lookup), { [fileId]: { + crowdinFilePath, + challengeTitle, + } }); + } + catch (err) { + console.log(JSON.stringify(err, null, 2)); + return lookup; + } +}; +/** + * Module to hide the curriculum strings. + * + * @param {number} projectId The ID of the project to hide the strings for. + */ +const hideCurriculumStrings = (projectId) => __awaiter(void 0, void 0, void 0, function* () { + console.log("Hiding non-translated strings..."); + const crowdinFiles = yield files_1.CrowdinFilesHelper.getFiles(projectId); + if (crowdinFiles && crowdinFiles.length) { + const challengeTitleLookup = crowdinFiles.reduce((lookup, file) => createChallengeTitleLookup(lookup, file, projectId), {}); + const crowdinStrings = yield strings_1.CrowdinStringHelper.getStrings(projectId); + if (crowdinStrings && crowdinStrings.length) { + for (const string of crowdinStrings) { + const { crowdinFilePath, challengeTitle } = challengeTitleLookup[string.data.fileId]; + yield strings_1.CrowdinStringHelper.updateFileString(projectId, string, challengeTitle, crowdinFilePath); + } + } + } + console.log("complete"); +}); +exports.hideCurriculumStrings = hideCurriculumStrings; /***/ }), @@ -40414,91 +40422,91 @@ exports.hideCurriculumStrings = hideCurriculumStrings; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.hideRenpyStrings = void 0; -const files_1 = __nccwpck_require__(1134); -const strings_1 = __nccwpck_require__(9185); -const labelNames = [ - "new", - "player", - "kid", - "mom", - "dad", - "mint", - "annika", - "girl", - "boy", - "college_boy", - "college_girl", - "female", - "marco", - "layla", - "cafe_manager", - "host", - "journalist", - "office_worker", - "male", - "trivia_guy", - "interviewer", - "npc", -]; -/** - * Module to hide strings for Renpy translations (such as in LearnToCodeRPG). - * Hides any string that doesn't start with `new`. - * - * @param {number} projectId The Crowdin project ID for strings to hide. - */ -const hideRenpyStrings = (projectId) => __awaiter(void 0, void 0, void 0, function* () { - const projectFiles = yield files_1.CrowdinFilesHelper.getFiles(projectId); - if (!projectFiles || !projectFiles.length) { - return; - } - for (const file of projectFiles) { - const fileStrings = yield strings_1.CrowdinStringHelper.getStrings(projectId, file.fileId); - if (!fileStrings || !fileStrings.length) { - continue; - } - let prevStringHidden = false; - for (const string of fileStrings) { - const trimText = string.data.text.trim(); - const quoteRegex = /^['"]/; - if (trimText.startsWith("translate") || - trimText.startsWith("old") || - trimText.startsWith("#") || - (prevStringHidden && - labelNames.every((label) => !trimText.startsWith(label)) && - !quoteRegex.test(trimText))) { - prevStringHidden = true; - if (string.data.isHidden) { - console.log(`string already hidden: ${string.data.text}`); - continue; - } - console.log(`hiding string: ${string.data.text}`); - yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, string.data.id, true); - } - else { - prevStringHidden = false; - if (!string.data.isHidden) { - console.log(`string already visible: ${string.data.text}`); - continue; - } - console.log(`keeping string: ${string.data.text}`); - yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, string.data.id, false); - } - } - } -}); -exports.hideRenpyStrings = hideRenpyStrings; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.hideRenpyStrings = void 0; +const files_1 = __nccwpck_require__(1134); +const strings_1 = __nccwpck_require__(9185); +const labelNames = [ + "new", + "player", + "kid", + "mom", + "dad", + "mint", + "annika", + "girl", + "boy", + "college_boy", + "college_girl", + "female", + "marco", + "layla", + "cafe_manager", + "host", + "journalist", + "office_worker", + "male", + "trivia_guy", + "interviewer", + "npc", +]; +/** + * Module to hide strings for Renpy translations (such as in LearnToCodeRPG). + * Hides any string that doesn't start with `new`. + * + * @param {number} projectId The Crowdin project ID for strings to hide. + */ +const hideRenpyStrings = (projectId) => __awaiter(void 0, void 0, void 0, function* () { + const projectFiles = yield files_1.CrowdinFilesHelper.getFiles(projectId); + if (!projectFiles || !projectFiles.length) { + return; + } + for (const file of projectFiles) { + const fileStrings = yield strings_1.CrowdinStringHelper.getStrings(projectId, file.fileId); + if (!fileStrings || !fileStrings.length) { + continue; + } + let prevStringHidden = false; + for (const string of fileStrings) { + const trimText = string.data.text.trim(); + const quoteRegex = /^['"]/; + if (trimText.startsWith("translate") || + trimText.startsWith("old") || + trimText.startsWith("#") || + (prevStringHidden && + labelNames.every((label) => !trimText.startsWith(label)) && + !quoteRegex.test(trimText))) { + prevStringHidden = true; + if (string.data.isHidden) { + console.log(`string already hidden: ${string.data.text}`); + continue; + } + console.log(`hiding string: ${string.data.text}`); + yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, string.data.id, true); + } + else { + prevStringHidden = false; + if (!string.data.isHidden) { + console.log(`string already visible: ${string.data.text}`); + continue; + } + console.log(`keeping string: ${string.data.text}`); + yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, string.data.id, false); + } + } + } +}); +exports.hideRenpyStrings = hideRenpyStrings; /***/ }), @@ -40507,49 +40515,93 @@ exports.hideRenpyStrings = hideRenpyStrings; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.hideSpecificString = void 0; +const files_1 = __nccwpck_require__(1134); +const strings_1 = __nccwpck_require__(9185); +/** + * Module to hide a specific string on Crowdin. + * + * @param {number} projectId The ID of the project to hide the string for. + * @param {string} fileName The name of the file to hide the string in. + * @param {string} string The content of the string to hide. + * @returns {Promise} True if the string was hidden, false otherwise. + */ +const hideSpecificString = (projectId, fileName, string) => __awaiter(void 0, void 0, void 0, function* () { + const fileResponse = yield files_1.CrowdinFilesHelper.getFiles(projectId); + if (!fileResponse) { + return false; + } + const targetFile = fileResponse.find((el) => el.path.endsWith(fileName)); + if (!targetFile) { + return false; + } + const stringResponse = yield strings_1.CrowdinStringHelper.getStrings(projectId, targetFile.fileId); + if (!stringResponse) { + return false; + } + const targetString = stringResponse.find((el) => el.data.text === string); + if (!targetString) { + return false; + } + yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, targetString.data.id, true); + return true; +}); +exports.hideSpecificString = hideSpecificString; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.hideSpecificString = void 0; -const files_1 = __nccwpck_require__(1134); -const strings_1 = __nccwpck_require__(9185); -/** - * Module to hide a specific string on Crowdin. - * - * @param {number} projectId The ID of the project to hide the string for. - * @param {string} fileName The name of the file to hide the string in. - * @param {string} string The content of the string to hide. - * @returns {Promise} True if the string was hidden, false otherwise. - */ -const hideSpecificString = (projectId, fileName, string) => __awaiter(void 0, void 0, void 0, function* () { - const fileResponse = yield files_1.CrowdinFilesHelper.getFiles(projectId); - if (!fileResponse) { - return false; - } - const targetFile = fileResponse.find((el) => el.path.endsWith(fileName)); - if (!targetFile) { - return false; - } - const stringResponse = yield strings_1.CrowdinStringHelper.getStrings(projectId, targetFile.fileId); - if (!stringResponse) { - return false; - } - const targetString = stringResponse.find((el) => el.data.text === string); - if (!targetString) { - return false; - } - yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, targetString.data.id, true); - return true; -}); -exports.hideSpecificString = hideSpecificString; + +/***/ }), + +/***/ 4960: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.lowercaseDirectories = void 0; +const fs_1 = __nccwpck_require__(7147); +const path_1 = __nccwpck_require__(1017); +/** + * + * @param {string[]} directories The directories that must be sorted through. + */ +const lowercaseDirectories = (directories) => __awaiter(void 0, void 0, void 0, function* () { + console.info("Getting file list..."); + for (const directory of directories) { + if (directory.toLocaleLowerCase() !== directory) { + const oldPath = (0, path_1.join)(process.cwd(), directory); + const newPath = (0, path_1.join)(process.cwd(), directory.toLocaleLowerCase()); + yield (0, fs_1.rename)(oldPath, newPath, (err) => { + if (err) { + console.error("Error making directory lowercase:", err); + } + else { + console.log(`${directory} has been made lowercase`); + } + }); + } + } +}); +exports.lowercaseDirectories = lowercaseDirectories; /***/ }), @@ -40558,127 +40610,127 @@ exports.hideSpecificString = hideSpecificString; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createPullRequest = void 0; -const child_process_1 = __nccwpck_require__(2081); -const util_1 = __nccwpck_require__(3837); -const github_1 = __nccwpck_require__(3695); -/** - * Module to create a pull request. - * - * @param {string} token The GitHub token for the account that is creating a PR. - * @param {string} branch The name of the branch to create a PR from. - * @param {string} repository The name of the repository to create a PR for - follow "owner/repo" syntax. - * @param {string} base The name of the branch to target with the PR (probably `main`). - * @param {string} title The title of the PR. - * @param {string} body The body of the PR. - * @param {string} labels A comma-separated list of labels to apply to the PR. - * @param {string} reviewers A comma-separated list of GitHub usernames to request review from. - * @param {string} teamReviewers A comma-separated list of GitHub team names to request review from. - * @returns {boolean} Whether or not the PR was created successfully. - */ -const createPullRequest = (token, branch, repository, base = "main", title, body, labels, reviewers, teamReviewers) => __awaiter(void 0, void 0, void 0, function* () { - try { - const asyncExec = (0, util_1.promisify)(child_process_1.exec); - const parsedLabels = labels ? labels.split(/,\s+/) : []; - const parsedReviewers = reviewers ? reviewers.split(/,\s+/) : []; - const parsedTeamReviewers = teamReviewers - ? teamReviewers.split(/,\s+/) - : []; - const [owner, repo] = repository.split("/"); - if (!owner || !repo) { - return false; - } - const githubClient = (0, github_1.getOctokit)(token); - const doesBranchExist = yield githubClient.rest.repos - .getBranch({ owner, repo, branch }) - .catch(() => console.info("Branch does not exist.")); - if (!doesBranchExist || doesBranchExist.status !== 200) { - return false; - } - const pullRequestExists = yield githubClient.rest.pulls.list({ - owner, - repo, - head: `${owner}:${branch}`, - }); - if (pullRequestExists.data.length) { - console.info(`It looks like pull request ${pullRequestExists.data[0].number} already exists.`); - // we want to exit successfully as this isn't a failure condition. - return true; - } - const { stdout: currentBranch } = yield asyncExec("git rev-parse HEAD"); - const { stdout: baseBranch } = yield asyncExec(`git rev-parse ${base}`); - if (currentBranch === baseBranch) { - console.info("Nothing was committed, no PR will be created."); - return true; - } - const pullRequest = yield githubClient.rest.pulls - .create({ - owner, - repo, - head: branch, - base, - title, - body, - }) - .catch((err) => { - console.info("Attempt to create the PR failed:"); - console.error(err); - }); - if (!pullRequest || pullRequest.status !== 201) { - return false; - } - const pullNumber = pullRequest.data.number; - console.log(`https://github.com/${owner}/${repo}/pull/${pullNumber} created!`); - if (parsedLabels && parsedLabels.length) { - yield githubClient.rest.issues.addLabels({ - owner, - repo, - // eslint-disable-next-line camelcase - issue_number: pullNumber, - labels: parsedLabels, - }); - console.log(`Labels ${parsedLabels.join(", ")} added to PR.`); - } - if (parsedReviewers && parsedReviewers.length) { - yield githubClient.rest.pulls.requestReviewers({ - owner, - repo, - // eslint-disable-next-line camelcase - pull_number: pullNumber, - reviewers: parsedReviewers, - }); - console.log(`Reviewers ${parsedReviewers.join(", ")} added to PR.`); - } - if (parsedTeamReviewers && parsedTeamReviewers.length) { - yield githubClient.rest.pulls.requestReviewers({ - owner, - repo, - // eslint-disable-next-line camelcase - pull_number: pullNumber, - // eslint-disable-next-line camelcase - team_reviewers: parsedTeamReviewers, - }); - console.log(`Team Reviewers ${parsedTeamReviewers.join(", ")} added to PR.`); - } - return true; - } - catch (err) { - console.error(err); - return false; - } -}); -exports.createPullRequest = createPullRequest; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.createPullRequest = void 0; +const child_process_1 = __nccwpck_require__(2081); +const util_1 = __nccwpck_require__(3837); +const github_1 = __nccwpck_require__(3695); +/** + * Module to create a pull request. + * + * @param {string} token The GitHub token for the account that is creating a PR. + * @param {string} branch The name of the branch to create a PR from. + * @param {string} repository The name of the repository to create a PR for - follow "owner/repo" syntax. + * @param {string} base The name of the branch to target with the PR (probably `main`). + * @param {string} title The title of the PR. + * @param {string} body The body of the PR. + * @param {string} labels A comma-separated list of labels to apply to the PR. + * @param {string} reviewers A comma-separated list of GitHub usernames to request review from. + * @param {string} teamReviewers A comma-separated list of GitHub team names to request review from. + * @returns {boolean} Whether or not the PR was created successfully. + */ +const createPullRequest = (token, branch, repository, base = "main", title, body, labels, reviewers, teamReviewers) => __awaiter(void 0, void 0, void 0, function* () { + try { + const asyncExec = (0, util_1.promisify)(child_process_1.exec); + const parsedLabels = labels ? labels.split(/,\s+/) : []; + const parsedReviewers = reviewers ? reviewers.split(/,\s+/) : []; + const parsedTeamReviewers = teamReviewers + ? teamReviewers.split(/,\s+/) + : []; + const [owner, repo] = repository.split("/"); + if (!owner || !repo) { + return false; + } + const githubClient = (0, github_1.getOctokit)(token); + const doesBranchExist = yield githubClient.rest.repos + .getBranch({ owner, repo, branch }) + .catch(() => console.info("Branch does not exist.")); + if (!doesBranchExist || doesBranchExist.status !== 200) { + return false; + } + const pullRequestExists = yield githubClient.rest.pulls.list({ + owner, + repo, + head: `${owner}:${branch}`, + }); + if (pullRequestExists.data.length) { + console.info(`It looks like pull request ${pullRequestExists.data[0].number} already exists.`); + // we want to exit successfully as this isn't a failure condition. + return true; + } + const { stdout: currentBranch } = yield asyncExec("git rev-parse HEAD"); + const { stdout: baseBranch } = yield asyncExec(`git rev-parse ${base}`); + if (currentBranch === baseBranch) { + console.info("Nothing was committed, no PR will be created."); + return true; + } + const pullRequest = yield githubClient.rest.pulls + .create({ + owner, + repo, + head: branch, + base, + title, + body, + }) + .catch((err) => { + console.info("Attempt to create the PR failed:"); + console.error(err); + }); + if (!pullRequest || pullRequest.status !== 201) { + return false; + } + const pullNumber = pullRequest.data.number; + console.log(`https://github.com/${owner}/${repo}/pull/${pullNumber} created!`); + if (parsedLabels && parsedLabels.length) { + yield githubClient.rest.issues.addLabels({ + owner, + repo, + // eslint-disable-next-line camelcase + issue_number: pullNumber, + labels: parsedLabels, + }); + console.log(`Labels ${parsedLabels.join(", ")} added to PR.`); + } + if (parsedReviewers && parsedReviewers.length) { + yield githubClient.rest.pulls.requestReviewers({ + owner, + repo, + // eslint-disable-next-line camelcase + pull_number: pullNumber, + reviewers: parsedReviewers, + }); + console.log(`Reviewers ${parsedReviewers.join(", ")} added to PR.`); + } + if (parsedTeamReviewers && parsedTeamReviewers.length) { + yield githubClient.rest.pulls.requestReviewers({ + owner, + repo, + // eslint-disable-next-line camelcase + pull_number: pullNumber, + // eslint-disable-next-line camelcase + team_reviewers: parsedTeamReviewers, + }); + console.log(`Team Reviewers ${parsedTeamReviewers.join(", ")} added to PR.`); + } + return true; + } + catch (err) { + console.error(err); + return false; + } +}); +exports.createPullRequest = createPullRequest; /***/ }), @@ -40687,69 +40739,69 @@ exports.createPullRequest = createPullRequest; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.removeDeletedFiles = void 0; -const child_process_1 = __nccwpck_require__(2081); -const util_1 = __nccwpck_require__(3837); -const files_1 = __nccwpck_require__(1134); -const getOutputFromShellCommand = (command) => __awaiter(void 0, void 0, void 0, function* () { - try { - const awaitExec = (0, util_1.promisify)(child_process_1.exec); - const { stdout } = yield awaitExec(command); - return stdout; - } - catch (error) { - console.log("Error"); - console.log(command); - console.log(JSON.stringify(error, null, 2)); - } -}); -/** - * Module to remove files from a Crowdin project if they are no longer present - * in the source repository. - * - * @param {number} projectId The ID of the project to remove files from. - * @param {string[]} paths The base paths for the files to check. - * @returns {boolean} True if files were successfully removed, false if no files were present on Crowdin. - */ -const removeDeletedFiles = (projectId, paths) => __awaiter(void 0, void 0, void 0, function* () { - console.log("Cleaning deleted files..."); - const crowdinFiles = yield files_1.CrowdinFilesHelper.getFiles(projectId); - if (crowdinFiles && crowdinFiles.length) { - let totalFiles = []; - for (const path of paths) { - const shellCommand = `find ${path} -name \\*.*`; - const localFiles = yield getOutputFromShellCommand(shellCommand); - const localFilesArray = localFiles === null || localFiles === void 0 ? void 0 : localFiles.split("\n"); - if (localFilesArray === null || localFilesArray === void 0 ? void 0 : localFilesArray.length) { - totalFiles = totalFiles.concat(localFilesArray); - } - } - const localFilesMap = totalFiles.reduce((map, filename) => (Object.assign(Object.assign({}, map), { [filename]: true })), {}); - for (const { fileId, path: crowdinFilePath } of crowdinFiles) { - if (!localFilesMap[crowdinFilePath]) { - yield files_1.CrowdinFilesHelper.deleteFile(projectId, fileId, crowdinFilePath); - } - } - } - else { - console.log(`WARNING! No files found for project ${projectId}`); - return false; - } - console.log("File deletion process complete."); - return true; -}); -exports.removeDeletedFiles = removeDeletedFiles; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.removeDeletedFiles = void 0; +const child_process_1 = __nccwpck_require__(2081); +const util_1 = __nccwpck_require__(3837); +const files_1 = __nccwpck_require__(1134); +const getOutputFromShellCommand = (command) => __awaiter(void 0, void 0, void 0, function* () { + try { + const awaitExec = (0, util_1.promisify)(child_process_1.exec); + const { stdout } = yield awaitExec(command); + return stdout; + } + catch (error) { + console.log("Error"); + console.log(command); + console.log(JSON.stringify(error, null, 2)); + } +}); +/** + * Module to remove files from a Crowdin project if they are no longer present + * in the source repository. + * + * @param {number} projectId The ID of the project to remove files from. + * @param {string[]} paths The base paths for the files to check. + * @returns {boolean} True if files were successfully removed, false if no files were present on Crowdin. + */ +const removeDeletedFiles = (projectId, paths) => __awaiter(void 0, void 0, void 0, function* () { + console.log("Cleaning deleted files..."); + const crowdinFiles = yield files_1.CrowdinFilesHelper.getFiles(projectId); + if (crowdinFiles && crowdinFiles.length) { + let totalFiles = []; + for (const path of paths) { + const shellCommand = `find ${path} -name \\*.*`; + const localFiles = yield getOutputFromShellCommand(shellCommand); + const localFilesArray = localFiles === null || localFiles === void 0 ? void 0 : localFiles.split("\n"); + if (localFilesArray === null || localFilesArray === void 0 ? void 0 : localFilesArray.length) { + totalFiles = totalFiles.concat(localFilesArray); + } + } + const localFilesMap = totalFiles.reduce((map, filename) => (Object.assign(Object.assign({}, map), { [filename]: true })), {}); + for (const { fileId, path: crowdinFilePath } of crowdinFiles) { + if (!localFilesMap[crowdinFilePath]) { + yield files_1.CrowdinFilesHelper.deleteFile(projectId, fileId, crowdinFilePath); + } + } + } + else { + console.log(`WARNING! No files found for project ${projectId}`); + return false; + } + console.log("File deletion process complete."); + return true; +}); +exports.removeDeletedFiles = removeDeletedFiles; /***/ }), @@ -40758,49 +40810,49 @@ exports.removeDeletedFiles = removeDeletedFiles; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.unhideSpecificString = void 0; -const files_1 = __nccwpck_require__(1134); -const strings_1 = __nccwpck_require__(9185); -/** - * Module to unhide a specific string on Crowdin. - * - * @param {number} projectId The ID of the project to hide the string for. - * @param {string} fileName The name of the file to hide the string in. - * @param {string} string The content of the string to hide. - * @returns {Promise} True if the string was unhidden, false otherwise. - */ -const unhideSpecificString = (projectId, fileName, string) => __awaiter(void 0, void 0, void 0, function* () { - const fileResponse = yield files_1.CrowdinFilesHelper.getFiles(projectId); - if (!fileResponse) { - return false; - } - const targetFile = fileResponse.find((el) => el.path.endsWith(fileName)); - if (!targetFile) { - return false; - } - const stringResponse = yield strings_1.CrowdinStringHelper.getStrings(projectId, targetFile.fileId); - if (!stringResponse) { - return false; - } - const targetString = stringResponse.find((el) => el.data.text === string); - if (!targetString) { - return false; - } - yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, targetString.data.id, false); - return true; -}); -exports.unhideSpecificString = unhideSpecificString; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.unhideSpecificString = void 0; +const files_1 = __nccwpck_require__(1134); +const strings_1 = __nccwpck_require__(9185); +/** + * Module to unhide a specific string on Crowdin. + * + * @param {number} projectId The ID of the project to hide the string for. + * @param {string} fileName The name of the file to hide the string in. + * @param {string} string The content of the string to hide. + * @returns {Promise} True if the string was unhidden, false otherwise. + */ +const unhideSpecificString = (projectId, fileName, string) => __awaiter(void 0, void 0, void 0, function* () { + const fileResponse = yield files_1.CrowdinFilesHelper.getFiles(projectId); + if (!fileResponse) { + return false; + } + const targetFile = fileResponse.find((el) => el.path.endsWith(fileName)); + if (!targetFile) { + return false; + } + const stringResponse = yield strings_1.CrowdinStringHelper.getStrings(projectId, targetFile.fileId); + if (!stringResponse) { + return false; + } + const targetString = stringResponse.find((el) => el.data.text === string); + if (!targetString) { + return false; + } + yield strings_1.CrowdinStringHelper.changeHiddenStatus(projectId, targetString.data.id, false); + return true; +}); +exports.unhideSpecificString = unhideSpecificString; /***/ }), @@ -40809,12 +40861,12 @@ exports.unhideSpecificString = unhideSpecificString; /***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.authHeader = void 0; -exports.authHeader = { - Authorization: `Bearer ${process.env.CROWDIN_PERSONAL_TOKEN}`, -}; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.authHeader = void 0; +exports.authHeader = { + Authorization: `Bearer ${process.env.CROWDIN_PERSONAL_TOKEN}`, +}; /***/ }), @@ -40823,166 +40875,166 @@ exports.authHeader = { /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.CrowdinFilesHelper = void 0; -const auth_header_1 = __nccwpck_require__(8677); -const make_request_1 = __nccwpck_require__(3961); -/** - * Module to upload a file to a project. - * - * @param {number} projectId The ID of the project to add a file to. - * @param {string} fileName The name of the file to create. - * @param {string} fileContent The content of the file to create. - * @param {number} directoryId The ID of the directory to add the file to. - * @returns {Promise} The data of the file created, or null on failure. - */ -const addFile = (projectId, fileName, fileContent, directoryId) => __awaiter(void 0, void 0, void 0, function* () { - const headers = Object.assign({ "Crowdin-API-FileName": fileName }, auth_header_1.authHeader); - const endPoint = "storages"; - const contentType = "application/text"; - const body = fileContent; - const storageResponse = yield (0, make_request_1.makeRequest)({ - method: "post", - contentType, - endPoint, - headers, - body, - }); - if (storageResponse && storageResponse.data) { - const fileBody = { - storageId: storageResponse.data.id, - name: fileName, - directoryId, - }; - const fileResponse = yield (0, make_request_1.makeRequest)({ - method: "post", - endPoint: `projects/${projectId}/files`, - headers, - body: fileBody, - contentType: "application/json", - }); - if (fileResponse && fileResponse.data) { - return fileResponse.data; - } - else { - console.log("error"); - console.dir(fileResponse, { depth: null, colors: true }); - } - } - return null; -}); -/** - * Module to update an existing file on a project. - * - * @param {number} projectId The ID of the project to update a file on. - * @param {number} fileId The ID of the file to update. - * @param {string} fileContent The content of the file to update. - * @returns {Promise} The data of the file updated, or null on failure. - */ -const updateFile = (projectId, fileId, fileContent) => __awaiter(void 0, void 0, void 0, function* () { - const headers = Object.assign({}, auth_header_1.authHeader); - const endPoint = "storages"; - const contentType = "application/text"; - const body = fileContent; - const storageResponse = yield (0, make_request_1.makeRequest)({ - method: "post", - contentType, - endPoint, - headers, - body, - }); - if (storageResponse && storageResponse.data) { - const fileBody = { - storageId: storageResponse.data.id, - }; - const fileResponse = yield (0, make_request_1.makeRequest)({ - method: "put", - endPoint: `projects/${projectId}/files/${fileId}`, - headers, - body: fileBody, - }); - if (fileResponse && fileResponse.data) { - return fileResponse.data; - } - else { - console.log("error"); - console.dir(fileResponse, { depth: null, colors: true }); - } - } - return null; -}); -/** - * Module to delete a file from a Crowdin project. - * - * @param {number} projectId The ID of the project to delete the file from. - * @param {number} fileId The ID of the file to delete. - * @param {string} filePath The path of the file to delete. - * @returns {Promise} One big ol' null. - */ -const deleteFile = (projectId, fileId, filePath) => __awaiter(void 0, void 0, void 0, function* () { - const headers = Object.assign({}, auth_header_1.authHeader); - const endPoint = `projects/${projectId}/files/${fileId}`; - yield (0, make_request_1.makeRequest)({ - method: "delete", - endPoint, - headers, - }); - console.log(`Deleted file ${filePath}`); - return null; -}); -/** - * Module to list all files on a Crowdin project. - * - * @param {number} projectId The ID of the project to list files for. - * @returns {Promise} Trimmed data of the files listed, or null on failure. - */ -const getFiles = (projectId) => __awaiter(void 0, void 0, void 0, function* () { - const headers = Object.assign({}, auth_header_1.authHeader); - let done = false; - let offset = 0; - let files = []; - while (!done) { - const endPoint = `projects/${projectId}/files?offset=${offset}&limit=500`; - const response = yield (0, make_request_1.makeRequest)({ - method: "get", - endPoint, - headers, - }); - if (response && response.data) { - if (response.data.length) { - files = [...files, ...response.data]; - offset += 500; - } - else { - done = true; - const mappedFiles = files.map(({ data: { directoryId, id: fileId, path } }) => { - return { directoryId, fileId, path: path.slice(1) }; - }); - return mappedFiles; - } - } - else { - console.log(JSON.stringify(response, null, 2)); - } - } - return null; -}); -exports.CrowdinFilesHelper = { - addFile, - updateFile, - deleteFile, - getFiles, -}; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.CrowdinFilesHelper = void 0; +const auth_header_1 = __nccwpck_require__(8677); +const make_request_1 = __nccwpck_require__(3961); +/** + * Module to upload a file to a project. + * + * @param {number} projectId The ID of the project to add a file to. + * @param {string} fileName The name of the file to create. + * @param {string} fileContent The content of the file to create. + * @param {number} directoryId The ID of the directory to add the file to. + * @returns {Promise} The data of the file created, or null on failure. + */ +const addFile = (projectId, fileName, fileContent, directoryId) => __awaiter(void 0, void 0, void 0, function* () { + const headers = Object.assign({ "Crowdin-API-FileName": fileName }, auth_header_1.authHeader); + const endPoint = "storages"; + const contentType = "application/text"; + const body = fileContent; + const storageResponse = yield (0, make_request_1.makeRequest)({ + method: "post", + contentType, + endPoint, + headers, + body, + }); + if (storageResponse && storageResponse.data) { + const fileBody = { + storageId: storageResponse.data.id, + name: fileName, + directoryId, + }; + const fileResponse = yield (0, make_request_1.makeRequest)({ + method: "post", + endPoint: `projects/${projectId}/files`, + headers, + body: fileBody, + contentType: "application/json", + }); + if (fileResponse && fileResponse.data) { + return fileResponse.data; + } + else { + console.log("error"); + console.dir(fileResponse, { depth: null, colors: true }); + } + } + return null; +}); +/** + * Module to update an existing file on a project. + * + * @param {number} projectId The ID of the project to update a file on. + * @param {number} fileId The ID of the file to update. + * @param {string} fileContent The content of the file to update. + * @returns {Promise} The data of the file updated, or null on failure. + */ +const updateFile = (projectId, fileId, fileContent) => __awaiter(void 0, void 0, void 0, function* () { + const headers = Object.assign({}, auth_header_1.authHeader); + const endPoint = "storages"; + const contentType = "application/text"; + const body = fileContent; + const storageResponse = yield (0, make_request_1.makeRequest)({ + method: "post", + contentType, + endPoint, + headers, + body, + }); + if (storageResponse && storageResponse.data) { + const fileBody = { + storageId: storageResponse.data.id, + }; + const fileResponse = yield (0, make_request_1.makeRequest)({ + method: "put", + endPoint: `projects/${projectId}/files/${fileId}`, + headers, + body: fileBody, + }); + if (fileResponse && fileResponse.data) { + return fileResponse.data; + } + else { + console.log("error"); + console.dir(fileResponse, { depth: null, colors: true }); + } + } + return null; +}); +/** + * Module to delete a file from a Crowdin project. + * + * @param {number} projectId The ID of the project to delete the file from. + * @param {number} fileId The ID of the file to delete. + * @param {string} filePath The path of the file to delete. + * @returns {Promise} One big ol' null. + */ +const deleteFile = (projectId, fileId, filePath) => __awaiter(void 0, void 0, void 0, function* () { + const headers = Object.assign({}, auth_header_1.authHeader); + const endPoint = `projects/${projectId}/files/${fileId}`; + yield (0, make_request_1.makeRequest)({ + method: "delete", + endPoint, + headers, + }); + console.log(`Deleted file ${filePath}`); + return null; +}); +/** + * Module to list all files on a Crowdin project. + * + * @param {number} projectId The ID of the project to list files for. + * @returns {Promise} Trimmed data of the files listed, or null on failure. + */ +const getFiles = (projectId) => __awaiter(void 0, void 0, void 0, function* () { + const headers = Object.assign({}, auth_header_1.authHeader); + let done = false; + let offset = 0; + let files = []; + while (!done) { + const endPoint = `projects/${projectId}/files?offset=${offset}&limit=500`; + const response = yield (0, make_request_1.makeRequest)({ + method: "get", + endPoint, + headers, + }); + if (response && response.data) { + if (response.data.length) { + files = [...files, ...response.data]; + offset += 500; + } + else { + done = true; + const mappedFiles = files.map(({ data: { directoryId, id: fileId, path } }) => { + return { directoryId, fileId, path: path.slice(1) }; + }); + return mappedFiles; + } + } + else { + console.log(JSON.stringify(response, null, 2)); + } + } + return null; +}); +exports.CrowdinFilesHelper = { + addFile, + updateFile, + deleteFile, + getFiles, +}; /***/ }), @@ -40991,57 +41043,57 @@ exports.CrowdinFilesHelper = { /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.makeRequest = void 0; -const node_fetch_1 = __importDefault(__nccwpck_require__(976)); -/** - * Utility to build and send a request to the Crowdin API. - * - * @param {requestParams} param0 Object containing all of the request parameters. - * @returns {Promise} The response from the API. - */ -const makeRequest = ({ method, endPoint, contentType = "application/json", accept = "application/json", headers, body, }) => __awaiter(void 0, void 0, void 0, function* () { - const newHeaders = Object.assign(Object.assign({}, headers), { "Content-Type": contentType, Accept: accept }); - const apiUrl = process.env.CROWDIN_API_URL + endPoint; - let newBody = ""; - if (contentType === "application/x-www-form-urlencoded") { - newBody = Object.entries(body || {}) - .reduce((formDataArr, [key, value]) => formDataArr.concat(`${key}=${value}`), []) - .join("&"); - } - else if (contentType === "application/json") { - newBody = JSON.stringify(body); - } - else { - newBody = body; - } - const response = yield (0, node_fetch_1.default)(apiUrl, { - headers: newHeaders, - method, - body: newBody, - }); - if (method !== "delete") { - const data = yield response.json(); - return data; - } - else { - return null; - } -}); -exports.makeRequest = makeRequest; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.makeRequest = void 0; +const node_fetch_1 = __importDefault(__nccwpck_require__(976)); +/** + * Utility to build and send a request to the Crowdin API. + * + * @param {requestParams} param0 Object containing all of the request parameters. + * @returns {Promise} The response from the API. + */ +const makeRequest = ({ method, endPoint, contentType = "application/json", accept = "application/json", headers, body, }) => __awaiter(void 0, void 0, void 0, function* () { + const newHeaders = Object.assign(Object.assign({}, headers), { "Content-Type": contentType, Accept: accept }); + const apiUrl = process.env.CROWDIN_API_URL + endPoint; + let newBody = ""; + if (contentType === "application/x-www-form-urlencoded") { + newBody = Object.entries(body || {}) + .reduce((formDataArr, [key, value]) => formDataArr.concat(`${key}=${value}`), []) + .join("&"); + } + else if (contentType === "application/json") { + newBody = JSON.stringify(body); + } + else { + newBody = body; + } + const response = yield (0, node_fetch_1.default)(apiUrl, { + headers: newHeaders, + method, + body: newBody, + }); + if (method !== "delete") { + const data = yield response.json(); + return data; + } + else { + return null; + } +}); +exports.makeRequest = makeRequest; /***/ }), @@ -41050,139 +41102,139 @@ exports.makeRequest = makeRequest; /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.CrowdinStringHelper = void 0; -const auth_header_1 = __nccwpck_require__(8677); -const make_request_1 = __nccwpck_require__(3961); -const isReservedHeading = (context, str) => { - const reservedHeadings = [ - "after-user-code", - "answers", - "before-user-code", - "description", - "fcc-editable-region", - "hints", - "instructions", - "question", - "seed", - "seed-contents", - "solutions", - "text", - "video-solution", - "tests", - "notes", - ]; - const captureGroupString = `(${reservedHeadings.join("|")})`; - const regex = new RegExp(`--${captureGroupString}--`); - return !!(context.match(/^Headline/) && str.match(regex)); -}; -const isCode = (str) => /^\/pre\/code|\/code$/.test(str); -const isTitle = (str) => str.endsWith("title"); -const shouldHide = (text, context, challengeTitle, crowdinFilePath) => { - if (crowdinFilePath.endsWith("yml")) { - return !isTitle(context); - } - if (isReservedHeading(context, text) || isCode(context)) { - return true; - } - return text !== challengeTitle && context.includes("id=front-matter"); -}; -const getStrings = (projectId, fileId) => __awaiter(void 0, void 0, void 0, function* () { - const headers = Object.assign({}, auth_header_1.authHeader); - let done = false; - let offset = 0; - let strings = []; - while (!done) { - let endPoint = `projects/${projectId}/strings?limit=500&offset=${offset}`; - if (fileId) { - endPoint += `&fileId=${fileId}`; - } - const response = yield (0, make_request_1.makeRequest)({ - method: "get", - endPoint, - headers, - }); - if (response && response.data) { - if (response.data.length) { - strings = [...strings, ...response.data]; - offset += 500; - } - else { - done = true; - return strings; - } - } - else { - console.log(JSON.stringify(response, null, 2)); - return null; - } - } -}); -const updateString = (projectId, stringId, propsToUpdate) => __awaiter(void 0, void 0, void 0, function* () { - const headers = Object.assign({}, auth_header_1.authHeader); - const endPoint = `projects/${projectId}/strings/${stringId}`; - const body = propsToUpdate.map(({ path, value }) => ({ - op: "replace", - path, - value, - })); - yield (0, make_request_1.makeRequest)({ - method: "patch", - endPoint, - headers, - body, - contentType: "application/json", - }); -}); -const changeHiddenStatus = (projectId, stringId, newStatus) => __awaiter(void 0, void 0, void 0, function* () { - yield updateString(projectId, stringId, [ - { path: "/isHidden", value: newStatus }, - ]); -}); -const updateFileStrings = (projectId, fileId, challengeTitle) => __awaiter(void 0, void 0, void 0, function* () { - const fileStrings = yield getStrings(projectId, fileId); - if (!fileStrings) { - return; - } - for (const { data: { id: stringId, text, isHidden, context, type }, } of fileStrings) { - const hideString = shouldHide(text, context, challengeTitle, type); - if (!isHidden && hideString) { - yield changeHiddenStatus(projectId, stringId, true); - } - else if (isHidden && !hideString) { - yield changeHiddenStatus(projectId, stringId, false); - } - } -}); -const updateFileString = (projectId, string, challengeTitle, crowdinFilePath) => __awaiter(void 0, void 0, void 0, function* () { - const { data: { id: stringId, text, isHidden, context }, } = string; - const hideString = shouldHide(text, context, challengeTitle, crowdinFilePath); - if (!isHidden && hideString) { - yield changeHiddenStatus(projectId, stringId, true); - console.log(`${challengeTitle} - stringId: ${stringId} - changed isHidden to true`); - } - else if (isHidden && !hideString) { - yield changeHiddenStatus(projectId, stringId, false); - console.log(`${challengeTitle} - stringId: ${stringId} - changed isHidden to false`); - } -}); -exports.CrowdinStringHelper = { - getStrings, - shouldHide, - changeHiddenStatus, - updateFileString, - updateFileStrings, -}; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.CrowdinStringHelper = void 0; +const auth_header_1 = __nccwpck_require__(8677); +const make_request_1 = __nccwpck_require__(3961); +const isReservedHeading = (context, str) => { + const reservedHeadings = [ + "after-user-code", + "answers", + "before-user-code", + "description", + "fcc-editable-region", + "hints", + "instructions", + "question", + "seed", + "seed-contents", + "solutions", + "text", + "video-solution", + "tests", + "notes", + ]; + const captureGroupString = `(${reservedHeadings.join("|")})`; + const regex = new RegExp(`--${captureGroupString}--`); + return !!(context.match(/^Headline/) && str.match(regex)); +}; +const isCode = (str) => /^\/pre\/code|\/code$/.test(str); +const isTitle = (str) => str.endsWith("title"); +const shouldHide = (text, context, challengeTitle, crowdinFilePath) => { + if (crowdinFilePath.endsWith("yml")) { + return !isTitle(context); + } + if (isReservedHeading(context, text) || isCode(context)) { + return true; + } + return text !== challengeTitle && context.includes("id=front-matter"); +}; +const getStrings = (projectId, fileId) => __awaiter(void 0, void 0, void 0, function* () { + const headers = Object.assign({}, auth_header_1.authHeader); + let done = false; + let offset = 0; + let strings = []; + while (!done) { + let endPoint = `projects/${projectId}/strings?limit=500&offset=${offset}`; + if (fileId) { + endPoint += `&fileId=${fileId}`; + } + const response = yield (0, make_request_1.makeRequest)({ + method: "get", + endPoint, + headers, + }); + if (response && response.data) { + if (response.data.length) { + strings = [...strings, ...response.data]; + offset += 500; + } + else { + done = true; + return strings; + } + } + else { + console.log(JSON.stringify(response, null, 2)); + return null; + } + } +}); +const updateString = (projectId, stringId, propsToUpdate) => __awaiter(void 0, void 0, void 0, function* () { + const headers = Object.assign({}, auth_header_1.authHeader); + const endPoint = `projects/${projectId}/strings/${stringId}`; + const body = propsToUpdate.map(({ path, value }) => ({ + op: "replace", + path, + value, + })); + yield (0, make_request_1.makeRequest)({ + method: "patch", + endPoint, + headers, + body, + contentType: "application/json", + }); +}); +const changeHiddenStatus = (projectId, stringId, newStatus) => __awaiter(void 0, void 0, void 0, function* () { + yield updateString(projectId, stringId, [ + { path: "/isHidden", value: newStatus }, + ]); +}); +const updateFileStrings = (projectId, fileId, challengeTitle) => __awaiter(void 0, void 0, void 0, function* () { + const fileStrings = yield getStrings(projectId, fileId); + if (!fileStrings) { + return; + } + for (const { data: { id: stringId, text, isHidden, context, type }, } of fileStrings) { + const hideString = shouldHide(text, context, challengeTitle, type); + if (!isHidden && hideString) { + yield changeHiddenStatus(projectId, stringId, true); + } + else if (isHidden && !hideString) { + yield changeHiddenStatus(projectId, stringId, false); + } + } +}); +const updateFileString = (projectId, string, challengeTitle, crowdinFilePath) => __awaiter(void 0, void 0, void 0, function* () { + const { data: { id: stringId, text, isHidden, context }, } = string; + const hideString = shouldHide(text, context, challengeTitle, crowdinFilePath); + if (!isHidden && hideString) { + yield changeHiddenStatus(projectId, stringId, true); + console.log(`${challengeTitle} - stringId: ${stringId} - changed isHidden to true`); + } + else if (isHidden && !hideString) { + yield changeHiddenStatus(projectId, stringId, false); + console.log(`${challengeTitle} - stringId: ${stringId} - changed isHidden to false`); + } +}); +exports.CrowdinStringHelper = { + getStrings, + shouldHide, + changeHiddenStatus, + updateFileString, + updateFileStrings, +}; /***/ }), @@ -41191,22 +41243,22 @@ exports.CrowdinStringHelper = { /***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.validateEnvironment = void 0; -/** - * Utility to confirm that the required environment variables are present. - * - * @returns {Promise} Whether the environment variables are valid. - */ -const validateEnvironment = () => { - if (!process.env.CROWDIN_PERSONAL_TOKEN || !process.env.CROWDIN_API_URL) { - console.error("Missing Crowdin credentials."); - return false; - } - return true; -}; -exports.validateEnvironment = validateEnvironment; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.validateEnvironment = void 0; +/** + * Utility to confirm that the required environment variables are present. + * + * @returns {Promise} Whether the environment variables are valid. + */ +const validateEnvironment = () => { + if (!process.env.CROWDIN_PERSONAL_TOKEN || !process.env.CROWDIN_API_URL) { + console.error("Missing Crowdin credentials."); + return false; + } + return true; +}; +exports.validateEnvironment = validateEnvironment; /***/ }), diff --git a/src/index.ts b/src/index.ts index 179c99c..5f0db32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ import { generateConfig } from "./plugins/generate-config"; import { hideCurriculumStrings } from "./plugins/hide-curriculum-strings"; import { hideRenpyStrings } from "./plugins/hide-renpy-strings"; import { hideSpecificString } from "./plugins/hide-specific-string"; +import { lowercaseDirectories } from "./plugins/lowercase-directories"; import { createPullRequest } from "./plugins/pull-request"; import { removeDeletedFiles } from "./plugins/remove-deleted-files"; import { unhideSpecificString } from "./plugins/unhide-specific-string"; @@ -81,6 +82,13 @@ import { validateEnvironment } from "./utils/validate-environment"; process.env.STRING_CONTENT ); break; + case "lowercase-directories": + if (!process.env.FILE_PATHS) { + setFailed("Missing file paths."); + break; + } + lowercaseDirectories(JSON.parse(process.env.FILE_PATHS)); + break; case "pull-request": if ( !process.env.GH_TOKEN || diff --git a/src/plugins/lowercase-directories.ts b/src/plugins/lowercase-directories.ts new file mode 100644 index 0000000..ac1f8c8 --- /dev/null +++ b/src/plugins/lowercase-directories.ts @@ -0,0 +1,18 @@ +import { rename } from "fs/promises"; +import { join } from "path"; + +/** + * + * @param {string[]} directories The directories that must be sorted through. + */ +export const lowercaseDirectories = async (directories: string[]) => { + console.info("Getting file list..."); + for (const directory of directories) { + if (directory.toLocaleLowerCase() !== directory) { + const oldPath = join(process.cwd(), directory); + const newPath = join(process.cwd(), directory.toLocaleLowerCase()); + console.log(`Renaming ${directory}`); + await rename(oldPath, newPath); + } + } +};