From 26367a17c783b5771763cbc40ff6dead4a0536e3 Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Mon, 13 Feb 2023 23:53:38 -0800 Subject: [PATCH] chore: remove crowdin scripts (#49374) --- .github/labeler.yml | 1 - package-lock.json | 388 ------------------ package.json | 1 - .../actions/convert-chinese/action.yml | 5 - .../crowdin/actions/convert-chinese/index.js | 41 -- .../hide-non-translated-strings/action.yml | 5 - .../hide-non-translated-strings/index.js | 62 --- .../actions/hide-specific-string/action.yml | 12 - .../actions/hide-specific-string/index.js | 34 -- tools/crowdin/actions/pr-creator/action.yml | 37 -- tools/crowdin/actions/pr-creator/index.js | 101 ----- .../actions/remove-deleted-files/action.yml | 5 - .../actions/remove-deleted-files/index.js | 55 --- .../actions/unhide-specific-string/action.yml | 12 - .../actions/unhide-specific-string/index.js | 33 -- .../delete-all-translations-for-a-language.js | 30 -- .../mark-translated-strings-as-done.js | 54 --- tools/crowdin/package.json | 35 -- tools/crowdin/sample.env | 4 - tools/crowdin/utils/auth-header.js | 7 - tools/crowdin/utils/delay.js | 5 - tools/crowdin/utils/dirs.js | 86 ---- tools/crowdin/utils/files.js | 122 ------ tools/crowdin/utils/get-languages.js | 17 - tools/crowdin/utils/make-request.js | 34 -- tools/crowdin/utils/strings.js | 239 ----------- 26 files changed, 1425 deletions(-) delete mode 100644 tools/crowdin/actions/convert-chinese/action.yml delete mode 100644 tools/crowdin/actions/convert-chinese/index.js delete mode 100644 tools/crowdin/actions/hide-non-translated-strings/action.yml delete mode 100644 tools/crowdin/actions/hide-non-translated-strings/index.js delete mode 100644 tools/crowdin/actions/hide-specific-string/action.yml delete mode 100644 tools/crowdin/actions/hide-specific-string/index.js delete mode 100644 tools/crowdin/actions/pr-creator/action.yml delete mode 100644 tools/crowdin/actions/pr-creator/index.js delete mode 100644 tools/crowdin/actions/remove-deleted-files/action.yml delete mode 100644 tools/crowdin/actions/remove-deleted-files/index.js delete mode 100644 tools/crowdin/actions/unhide-specific-string/action.yml delete mode 100644 tools/crowdin/actions/unhide-specific-string/index.js delete mode 100644 tools/crowdin/one-off-scripts/delete-all-translations-for-a-language.js delete mode 100644 tools/crowdin/one-off-scripts/mark-translated-strings-as-done.js delete mode 100644 tools/crowdin/package.json delete mode 100644 tools/crowdin/sample.env delete mode 100644 tools/crowdin/utils/auth-header.js delete mode 100644 tools/crowdin/utils/delay.js delete mode 100644 tools/crowdin/utils/dirs.js delete mode 100644 tools/crowdin/utils/files.js delete mode 100644 tools/crowdin/utils/get-languages.js delete mode 100644 tools/crowdin/utils/make-request.js delete mode 100644 tools/crowdin/utils/strings.js diff --git a/.github/labeler.yml b/.github/labeler.yml index cae5f5099b4..1581cb23b3d 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -23,4 +23,3 @@ - client/i18n/**/* - config/crowdin/**/* - config/i18n/**/* - - tools/crowdin/**/* diff --git a/package-lock.json b/package-lock.json index dddecc03938..342aa194961 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,6 @@ "tools/challenge-editor/client", "tools/challenge-helper-scripts", "tools/challenge-parser", - "tools/crowdin", "tools/scripts/build", "tools/scripts/seed", "tools/ui-components" @@ -702,38 +701,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@actions/core": { - "version": "1.10.0", - "license": "MIT", - "dependencies": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" - } - }, - "node_modules/@actions/core/node_modules/uuid": { - "version": "8.3.2", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@actions/github": { - "version": "5.1.1", - "license": "MIT", - "dependencies": { - "@actions/http-client": "^2.0.1", - "@octokit/core": "^3.6.0", - "@octokit/plugin-paginate-rest": "^2.17.0", - "@octokit/plugin-rest-endpoint-methods": "^5.13.0" - } - }, - "node_modules/@actions/http-client": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "tunnel": "^0.0.6" - } - }, "node_modules/@adobe/css-tools": { "version": "4.0.1", "license": "MIT" @@ -3272,10 +3239,6 @@ "resolved": "client", "link": true }, - "node_modules/@freecodecamp/crowdin": { - "resolved": "tools/crowdin", - "link": true - }, "node_modules/@freecodecamp/curriculum": { "resolved": "curriculum", "link": true @@ -4946,111 +4909,6 @@ "node": ">=10" } }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "license": "MIT", - "dependencies": { - "@octokit/types": "^6.0.3" - } - }, - "node_modules/@octokit/core": { - "version": "3.6.0", - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "license": "MIT", - "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/endpoint/node_modules/is-plain-object": { - "version": "5.0.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", - "license": "MIT", - "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "11.2.0", - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.17.0", - "license": "MIT", - "dependencies": { - "@octokit/types": "^6.34.0" - }, - "peerDependencies": { - "@octokit/core": ">=2" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.13.0", - "license": "MIT", - "dependencies": { - "@octokit/types": "^6.34.0", - "deprecation": "^2.3.1" - }, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/request": { - "version": "5.6.3", - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", - "license": "MIT", - "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/request/node_modules/is-plain-object": { - "version": "5.0.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@octokit/types": { - "version": "6.34.0", - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^11.2.0" - } - }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.4.3", "license": "MIT", @@ -17982,10 +17840,6 @@ "version": "2.4.3", "license": "MIT" }, - "node_modules/before-after-hook": { - "version": "2.2.2", - "license": "Apache-2.0" - }, "node_modules/better-opn": { "version": "2.1.1", "license": "MIT", @@ -22030,10 +21884,6 @@ "node": ">= 0.6" } }, - "node_modules/deprecation": { - "version": "2.3.1", - "license": "ISC" - }, "node_modules/deps-sort": { "version": "2.0.1", "license": "MIT", @@ -38651,13 +38501,6 @@ "node": ">=0.10.0" } }, - "node_modules/node-opencc": { - "version": "2.0.1", - "license": "MIT", - "engines": { - "node": ">= 7.6.0" - } - }, "node_modules/node-releases": { "version": "2.0.6", "license": "MIT" @@ -40516,14 +40359,6 @@ "which": "bin/which" } }, - "node_modules/path": { - "version": "0.12.7", - "license": "MIT", - "dependencies": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, "node_modules/path-browserify": { "version": "1.0.1", "license": "MIT" @@ -40581,17 +40416,6 @@ "node": ">=8" } }, - "node_modules/path/node_modules/inherits": { - "version": "2.0.3", - "license": "ISC" - }, - "node_modules/path/node_modules/util": { - "version": "0.10.4", - "license": "MIT", - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/pathval": { "version": "1.1.1", "license": "MIT", @@ -50289,13 +50113,6 @@ "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", "dev": true }, - "node_modules/tunnel": { - "version": "0.0.6", - "license": "MIT", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, "node_modules/tunnel-agent": { "version": "0.6.0", "license": "Apache-2.0", @@ -50841,10 +50658,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "license": "ISC" - }, "node_modules/universalify": { "version": "2.0.0", "license": "MIT", @@ -54282,38 +54095,6 @@ "unist-util-stringify-position": "^1.1.1" } }, - "tools/crowdin": { - "name": "@freecodecamp/crowdin", - "version": "0.0.1", - "license": "BSD-3-Clause", - "dependencies": { - "@actions/core": "1.10.0", - "@actions/github": "5.1.1", - "dotenv": "16.0.3", - "fs-extra": "10.0.0", - "gray-matter": "4.0.3", - "node-fetch": "2.6.9", - "node-opencc": "2.0.1", - "path": "0.12.7", - "readdirp": "3.6.0" - }, - "engines": { - "node": ">=16", - "npm": ">=8" - } - }, - "tools/crowdin/node_modules/fs-extra": { - "version": "10.0.0", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, "tools/scripts/build": { "name": "@freecodecamp/scripts-build", "version": "0.0.1", @@ -54447,33 +54228,6 @@ } }, "dependencies": { - "@actions/core": { - "version": "1.10.0", - "requires": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" - }, - "dependencies": { - "uuid": { - "version": "8.3.2" - } - } - }, - "@actions/github": { - "version": "5.1.1", - "requires": { - "@actions/http-client": "^2.0.1", - "@octokit/core": "^3.6.0", - "@octokit/plugin-paginate-rest": "^2.17.0", - "@octokit/plugin-rest-endpoint-methods": "^5.13.0" - } - }, - "@actions/http-client": { - "version": "2.0.1", - "requires": { - "tunnel": "^0.0.6" - } - }, "@adobe/css-tools": { "version": "4.0.1" }, @@ -56515,30 +56269,6 @@ } } }, - "@freecodecamp/crowdin": { - "version": "file:tools/crowdin", - "requires": { - "@actions/core": "1.10.0", - "@actions/github": "5.1.1", - "dotenv": "16.0.3", - "fs-extra": "10.0.0", - "gray-matter": "4.0.3", - "node-fetch": "2.6.9", - "node-opencc": "2.0.1", - "path": "0.12.7", - "readdirp": "3.6.0" - }, - "dependencies": { - "fs-extra": { - "version": "10.0.0", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, "@freecodecamp/curriculum": { "version": "file:curriculum", "requires": { @@ -57801,91 +57531,6 @@ } } }, - "@octokit/auth-token": { - "version": "2.5.0", - "requires": { - "@octokit/types": "^6.0.3" - } - }, - "@octokit/core": { - "version": "3.6.0", - "requires": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "6.0.12", - "requires": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0" - } - } - }, - "@octokit/graphql": { - "version": "4.8.0", - "requires": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "11.2.0" - }, - "@octokit/plugin-paginate-rest": { - "version": "2.17.0", - "requires": { - "@octokit/types": "^6.34.0" - } - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "5.13.0", - "requires": { - "@octokit/types": "^6.34.0", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "5.6.3", - "requires": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0" - } - } - }, - "@octokit/request-error": { - "version": "2.1.0", - "requires": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/types": { - "version": "6.34.0", - "requires": { - "@octokit/openapi-types": "^11.2.0" - } - }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.4.3", "requires": { @@ -67305,9 +66950,6 @@ "bcryptjs": { "version": "2.4.3" }, - "before-after-hook": { - "version": "2.2.2" - }, "better-opn": { "version": "2.1.1", "requires": { @@ -70066,9 +69708,6 @@ "depd": { "version": "1.1.2" }, - "deprecation": { - "version": "2.3.1" - }, "deps-sort": { "version": "2.0.1", "requires": { @@ -81047,9 +80686,6 @@ "node-object-hash": { "version": "2.3.10" }, - "node-opencc": { - "version": "2.0.1" - }, "node-releases": { "version": "2.0.6" }, @@ -82247,24 +81883,6 @@ } } }, - "path": { - "version": "0.12.7", - "requires": { - "process": "^0.11.1", - "util": "^0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3" - }, - "util": { - "version": "0.10.4", - "requires": { - "inherits": "2.0.3" - } - } - } - }, "path-browserify": { "version": "1.0.1" }, @@ -88378,9 +87996,6 @@ "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", "dev": true }, - "tunnel": { - "version": "0.0.6" - }, "tunnel-agent": { "version": "0.6.0", "requires": { @@ -88719,9 +88334,6 @@ "unist-util-is": "^4.0.0" } }, - "universal-user-agent": { - "version": "6.0.0" - }, "universalify": { "version": "2.0.0" }, diff --git a/package.json b/package.json index a92224abef4..24a8b37021b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "tools/challenge-editor/client", "tools/challenge-helper-scripts", "tools/challenge-parser", - "tools/crowdin", "tools/scripts/build", "tools/scripts/seed", "tools/ui-components" diff --git a/tools/crowdin/actions/convert-chinese/action.yml b/tools/crowdin/actions/convert-chinese/action.yml deleted file mode 100644 index 58cba1de57b..00000000000 --- a/tools/crowdin/actions/convert-chinese/action.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: 'Translate Simplified Chinese to Traditional' -description: 'Converts Simplified Chinese characters to Traditional Chinese Characters' -runs: - using: 'node12' - main: './index.js' diff --git a/tools/crowdin/actions/convert-chinese/index.js b/tools/crowdin/actions/convert-chinese/index.js deleted file mode 100644 index 97040135075..00000000000 --- a/tools/crowdin/actions/convert-chinese/index.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable import/no-unresolved */ -const path = require('path'); -const fs = require('fs-extra'); -const opencc = require('node-opencc'); - -const getFiles = async (directory, fileList = []) => { - const files = await fs.readdir(directory); - for (const file of files) { - const fileStat = await fs.stat(path.join(directory, file)); - if (fileStat.isDirectory()) { - fileList = await getFiles(path.join(directory, file), fileList); - } else { - fileList.push(path.join(directory, file)); - } - } - return fileList; -}; - -(async () => { - console.info('Getting file list...'); - const fileList = []; - const curriculum = await getFiles( - path.join(__dirname, '/../../../../curriculum/challenges/chinese') - ); - fileList.push(...curriculum); - - const client = await getFiles( - path.join(__dirname, '/../../../../client/i18n/locales/chinese') - ); - fileList.push(...client); - - for (const file of fileList) { - console.info(`Translating ${file}`); - const fileText = await fs.readFile(file, 'utf-8'); - const translatedText = await opencc.simplifiedToTraditional(fileText); - await fs.outputFile( - file.replace('chinese', 'chinese-traditional'), - translatedText - ); - } -})(); diff --git a/tools/crowdin/actions/hide-non-translated-strings/action.yml b/tools/crowdin/actions/hide-non-translated-strings/action.yml deleted file mode 100644 index c736f451059..00000000000 --- a/tools/crowdin/actions/hide-non-translated-strings/action.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: 'Hide Non-Translated Strings' -description: "Updates each file's non-translatable string to Hidden" -runs: - using: 'node12' - main: './index.js' diff --git a/tools/crowdin/actions/hide-non-translated-strings/index.js b/tools/crowdin/actions/hide-non-translated-strings/index.js deleted file mode 100644 index 9f41e3d0680..00000000000 --- a/tools/crowdin/actions/hide-non-translated-strings/index.js +++ /dev/null @@ -1,62 +0,0 @@ -require('dotenv').config({ path: `${__dirname}/../../.env` }); -const fs = require('fs'); -const path = require('path'); -const matter = require('gray-matter'); -const { getFiles } = require('../../utils/files'); -const { getStrings, updateFileString } = require('../../utils/strings'); - -const createChallengeTitleLookup = ( - lookup, - { fileId, path: crowdinFilePath } -) => { - const challengeFilePath = path.join( - __dirname, - '/../../../../', - crowdinFilePath - ); - try { - const challengeContent = fs.readFileSync(challengeFilePath); - const { - data: { title: challengeTitle } - } = matter(challengeContent); - return { - ...lookup, - [fileId]: { - crowdinFilePath, - challengeTitle - } - }; - } catch (err) { - console.log(err.name); - console.log(err.message); - } - return lookup; -}; - -const hideNonTranslatedStrings = async projectId => { - console.log('hide non-translated strings...'); - const crowdinFiles = await getFiles(projectId); - if (crowdinFiles && crowdinFiles.length) { - const challengeTitleLookup = crowdinFiles.reduce( - createChallengeTitleLookup, - {} - ); - const crowdinStrings = await getStrings({ projectId }); - if (crowdinStrings && crowdinStrings.length) { - for (let string of crowdinStrings) { - const { crowdinFilePath, challengeTitle } = - challengeTitleLookup[string.data.fileId]; - await updateFileString({ - projectId, - string, - challengeTitle, - crowdinFilePath - }); - } - } - } - console.log('complete'); -}; - -const projectId = process.env.CROWDIN_PROJECT_ID; -hideNonTranslatedStrings(projectId); diff --git a/tools/crowdin/actions/hide-specific-string/action.yml b/tools/crowdin/actions/hide-specific-string/action.yml deleted file mode 100644 index f22ebbd945a..00000000000 --- a/tools/crowdin/actions/hide-specific-string/action.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: 'Hide Specific String' -description: 'Updates a specific string to be hidden' -runs: - using: 'node12' - main: './index.js' -inputs: - filename: - description: 'name of file with specific string to hide' - required: true - string-content: - description: 'text content of string to hide' - required: true diff --git a/tools/crowdin/actions/hide-specific-string/index.js b/tools/crowdin/actions/hide-specific-string/index.js deleted file mode 100644 index a3faed2015a..00000000000 --- a/tools/crowdin/actions/hide-specific-string/index.js +++ /dev/null @@ -1,34 +0,0 @@ -require('dotenv').config({ path: `${__dirname}/../../.env` }); -const core = require('@actions/core'); -const { getFiles } = require('../../utils/files'); -const { getStrings, changeHiddenStatus } = require('../../utils/strings'); -// eslint-disable-next-line import/no-unresolved - -const filename = core.getInput('filename'); -const stringContent = core.getInput('string-content'); - -const hideString = async (projectId, fileName, string) => { - const fileResponse = await getFiles(projectId); - const targetFile = fileResponse.find(el => el.path.endsWith(filename)); - if (!targetFile) { - core.setFailed(`${fileName} was not found.`); - return; - } - - const stringResponse = await getStrings({ - projectId, - fileId: targetFile.fileId - }); - - const targetString = stringResponse.find(el => el.data.text === string); - if (!targetString) { - core.setFailed(`${string} was not found.`); - return; - } - - await changeHiddenStatus(projectId, targetString.data.id, true); - console.log('string hidden!'); -}; - -const projectId = process.env.CROWDIN_PROJECT_ID; -hideString(projectId, filename, stringContent); diff --git a/tools/crowdin/actions/pr-creator/action.yml b/tools/crowdin/actions/pr-creator/action.yml deleted file mode 100644 index 57bfb7fa2c2..00000000000 --- a/tools/crowdin/actions/pr-creator/action.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: 'Create Crowdin PRs' -description: 'Creates a PR by camperbot for Crowdin translation downloads' -runs: - using: 'node12' - main: './index.js' -inputs: - github-token: - description: 'PAT with write access to create PRs' - required: true - branch: - description: 'Branch name to which commits are made' - required: true - owner-repo: - description: 'owner and repo name specified as ownerName/repoName' - required: true - base: - description: 'base branch name' - default: 'main' - required: true - title: - description: 'PR title' - required: true - body: - description: 'PR body text' - required: true - labels: - description: 'PR labels' - required: false - reviewers: - description: 'Requested PR reviewers' - required: false - team_reviewers: - # Note that this should be a slug, not a full tag - # So a requested review from @freeCodeCamp/dev-team - # Should be passed only as 'dev-team' - description: 'Requested organization team PR reviewers' - required: false diff --git a/tools/crowdin/actions/pr-creator/index.js b/tools/crowdin/actions/pr-creator/index.js deleted file mode 100644 index f81a6504a64..00000000000 --- a/tools/crowdin/actions/pr-creator/index.js +++ /dev/null @@ -1,101 +0,0 @@ -/* eslint-disable import/no-unresolved */ -/* eslint-disable camelcase */ -const core = require('@actions/core'); -const githubRoot = require('@actions/github'); - -(async () => { - try { - const token = core.getInput('github-token'); - const branch = core.getInput('branch'); - const [owner, repo] = core.getInput('owner-repo').split('/'); - if (!owner || !repo) { - core.setFailed('Must specify a valid ownerName/repoName'); - } - const base = core.getInput('base'); - const title = core.getInput('title'); - const body = core.getInput('body'); - const labelsStr = core.getInput('labels'); - const labels = labelsStr.trim().split(/,\s+/); - const reviewersStr = core.getInput('reviewers'); - const reviewers = reviewersStr.trim().split(/,\s+/); - const teamStr = core.getInput('team_reviewers'); - const team_reviewers = teamStr.trim().split(/,\s+/); - - const github = githubRoot.getOctokit(token); - - const branchExists = await github.rest.repos - .getBranch({ - owner, - repo, - branch - }) - .catch(() => { - console.info('Branch does not exist. Likely no changes in download?'); - }); - if (!branchExists || branchExists.status !== 200) { - return; - } - const pullRequestExists = await github.rest.pulls.list({ - owner, - repo, - head: `${owner}:${branch}` - }); - if (pullRequestExists.data.length) { - console.info( - 'It looks like a pull request already exists for this branch.' - ); - return; - } - const PR = await github.rest.pulls - .create({ - owner, - repo, - head: branch, - base, - title, - body - }) - .catch(err => { - console.info( - 'Unpredicted error occurred when trying to create the PR.' - ); - console.error(err); - }); - if (!PR || PR.status !== 201) { - return; - } - const prNumber = PR.data.number; - console.log( - `https://github.com/freeCodeCamp/freeCodeCamp/pull/${prNumber} created` - ); - if (labels && labels.length) { - await github.rest.issues.addLabels({ - owner, - repo, - issue_number: prNumber, - labels - }); - console.log(`Labels ${labels} added to PR`); - } - if (reviewers && reviewers.length) { - await github.rest.pulls.requestReviewers({ - owner, - repo, - pull_number: prNumber, - reviewers - }); - console.log(`Requested Reviewers ${reviewers} added to PR`); - } - if (team_reviewers && team_reviewers.length) { - await github.rest.pulls.requestReviewers({ - owner, - repo, - pull_number: prNumber, - team_reviewers - }); - console.log(`Requested Team Reviewers ${team_reviewers} added to PR`); - } - } catch (error) { - core.setFailed(error.message); - } -})(); diff --git a/tools/crowdin/actions/remove-deleted-files/action.yml b/tools/crowdin/actions/remove-deleted-files/action.yml deleted file mode 100644 index fade21c6270..00000000000 --- a/tools/crowdin/actions/remove-deleted-files/action.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: 'Remove Deleted English Files From Crowdin' -description: 'Deletes files from Crowdin that are no longer in the English curriculum folder' -runs: - using: 'node12' - main: './index.js' diff --git a/tools/crowdin/actions/remove-deleted-files/index.js b/tools/crowdin/actions/remove-deleted-files/index.js deleted file mode 100644 index 8dbe0acbeb2..00000000000 --- a/tools/crowdin/actions/remove-deleted-files/index.js +++ /dev/null @@ -1,55 +0,0 @@ -require('dotenv').config({ path: `${__dirname}/../../.env` }); -// const core = require('@actions/core'); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); - -const { getFiles, deleteFile } = require('../../utils/files'); - -const getOutputFromCommand = async command => { - try { - const { stdout } = await exec(command); - return stdout; - } catch (err) { - console.log('Error'); - console.log('command'); - console.log(command + '\n'); - console.log(err.message); - return null; - } -}; - -const removeDeletedFiles = async projectId => { - console.log('start deleting source files no longer in English curriculum...'); - const crowdinFiles = await getFiles(projectId); - - if (crowdinFiles && crowdinFiles.length) { - const challengeCommand = 'find curriculum/challenges/english -name \\*.*'; - const listOfEnglishFiles = await getOutputFromCommand(challengeCommand); - const dictionaryCommand = - 'find curriculum/dictionaries/english -name \\*.*'; - const listOfDictFiles = await getOutputFromCommand(dictionaryCommand); - let curriculumFilesArr = listOfEnglishFiles.split('\n'); - curriculumFilesArr = curriculumFilesArr.concat(listOfDictFiles.split('\n')); - if (curriculumFilesArr.length) { - const curriculumLookup = curriculumFilesArr.reduce((obj, filename) => { - return { ...obj, [filename]: 1 }; - }, {}); - for (let { fileId, path: crowdinFilePath } of crowdinFiles) { - if ( - !Object.prototype.hasOwnProperty.call( - curriculumLookup, - crowdinFilePath - ) - ) { - await deleteFile(projectId, fileId, crowdinFilePath); - } - } - } - } else { - console.log(`WARNING! No Crowdin files found for projectId ${projectId}`); - } - console.log('deleting source non-existent source files complete'); -}; - -const projectId = process.env.CROWDIN_PROJECT_ID; -removeDeletedFiles(projectId); diff --git a/tools/crowdin/actions/unhide-specific-string/action.yml b/tools/crowdin/actions/unhide-specific-string/action.yml deleted file mode 100644 index 7f36098838e..00000000000 --- a/tools/crowdin/actions/unhide-specific-string/action.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: 'Unhide Specific String' -description: 'Updates a specific string to be not hidden' -runs: - using: 'node12' - main: './index.js' -inputs: - filename: - description: 'name of file with specific string to hide' - required: true - string-content: - description: 'text content of string to unhide' - required: true diff --git a/tools/crowdin/actions/unhide-specific-string/index.js b/tools/crowdin/actions/unhide-specific-string/index.js deleted file mode 100644 index 1c87883a053..00000000000 --- a/tools/crowdin/actions/unhide-specific-string/index.js +++ /dev/null @@ -1,33 +0,0 @@ -require('dotenv').config({ path: `${__dirname}/../../.env` }); -const core = require('@actions/core'); -const { getFiles } = require('../../utils/files'); -const { getStrings, changeHiddenStatus } = require('../../utils/strings'); - -const filename = core.getInput('filename'); -const stringContent = core.getInput('string-content'); - -const hideString = async (projectId, fileName, string) => { - const fileResponse = await getFiles(projectId); - const targetFile = fileResponse.find(el => el.path.endsWith(filename)); - if (!targetFile) { - core.setFailed(`${fileName} was not found.`); - return; - } - - const stringResponse = await getStrings({ - projectId, - fileId: targetFile.fileId - }); - - const targetString = stringResponse.find(el => el.data.text === string); - if (!targetString) { - core.setFailed(`${string} was not found.`); - return; - } - - await changeHiddenStatus(projectId, targetString.data.id, false); - console.log('string unhidden!'); -}; - -const projectId = process.env.CROWDIN_PROJECT_ID; -hideString(projectId, filename, stringContent); diff --git a/tools/crowdin/one-off-scripts/delete-all-translations-for-a-language.js b/tools/crowdin/one-off-scripts/delete-all-translations-for-a-language.js deleted file mode 100644 index b316904dfcd..00000000000 --- a/tools/crowdin/one-off-scripts/delete-all-translations-for-a-language.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -This one-off script can be used to delete all existing translations for a specified language on Crowdin. - -Specifying a projectId and lanaguageId in the .env file allows the script to accomplish this task. -*/ - -require('dotenv').config({ path: `${__dirname}/../.env` }); - -const { - getLanguageTranslations, - deleteLanguageTranslations -} = require('../utils/strings'); - -const projectId = process.env.CROWDIN_PROJECT_ID; -const languageId = process.env.CROWDIN_LANGUAGE_ID; - -(async (projectId, languageId) => { - console.log('starting script...'); - const translations = await getLanguageTranslations({ - projectId, - languageId - }); - if (translations && translations.length) { - for (let translation of translations) { - const { stringId } = translation.data; - await deleteLanguageTranslations(projectId, languageId, stringId); - } - } - console.log('complete'); -})(projectId, languageId); diff --git a/tools/crowdin/one-off-scripts/mark-translated-strings-as-done.js b/tools/crowdin/one-off-scripts/mark-translated-strings-as-done.js deleted file mode 100644 index a643e451973..00000000000 --- a/tools/crowdin/one-off-scripts/mark-translated-strings-as-done.js +++ /dev/null @@ -1,54 +0,0 @@ -/* -This one-off script can be used to make any string in a Crowdin project to be marked as "Done" in case a workflow -change inadvertently causes strings, which already have translations (and even an approved translation), to be -reverted to "To Do". - -Specifying a projectId in the .env file allows the script to find any string with at least one translation, -adds a new temporary translation to it, and then delete the newly added translation. It is the addition of a -new translation that switches the status back to "Done" in the Crowdsourcing view on Crowdin. - -*/ - -require('dotenv').config({ path: `${__dirname}/../.env` }); - -const getLanguages = require('../utils/get-languages'); - -const { - addTranslation, - deleteTranslation, - getLanguageTranslations -} = require('../utils/strings'); - -const markTranslatedStringsAsDone = async projectId => { - console.log('starting script...'); - const languageIds = await getLanguages(projectId); - for (let languageId of languageIds) { - const translations = await getLanguageTranslations({ - projectId, - languageId - }); - if (translations && translations.length) { - console.log( - `${languageId} has ${translations.length} strings with at least one translation` - ); - for (let translation of translations) { - const { stringId } = translation.data; - const newTranslation = await addTranslation( - projectId, - stringId, - languageId, - 'this is a camperbot test translation' - ); - if (newTranslation && newTranslation.id); - console.log( - `added new translation (translationId: ${newTranslation.id}) for stringId: ${stringId}` - ); - await deleteTranslation(projectId, newTranslation.id); - } - } - } - console.log('complete'); -}; - -const projectId = process.env.CROWDIN_PROJECT_ID; -markTranslatedStringsAsDone(projectId); diff --git a/tools/crowdin/package.json b/tools/crowdin/package.json deleted file mode 100644 index d2581fc490e..00000000000 --- a/tools/crowdin/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@freecodecamp/crowdin", - "version": "0.0.1", - "description": "The freeCodeCamp.org open-source codebase and curriculum", - "license": "BSD-3-Clause", - "private": true, - "engines": { - "node": ">=16", - "npm": ">=8" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/freeCodeCamp/freeCodeCamp.git" - }, - "bugs": { - "url": "https://github.com/freeCodeCamp/freeCodeCamp/issues" - }, - "homepage": "https://github.com/freeCodeCamp/freeCodeCamp#readme", - "author": "freeCodeCamp ", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "@actions/core": "1.10.0", - "@actions/github": "5.1.1", - "dotenv": "16.0.3", - "fs-extra": "10.0.0", - "gray-matter": "4.0.3", - "node-fetch": "2.6.9", - "node-opencc": "2.0.1", - "path": "0.12.7", - "readdirp": "3.6.0" - } -} diff --git a/tools/crowdin/sample.env b/tools/crowdin/sample.env deleted file mode 100644 index 19149dbfe7b..00000000000 --- a/tools/crowdin/sample.env +++ /dev/null @@ -1,4 +0,0 @@ -CROWDIN_PROJECT_ID= -CROWDIN_PERSONAL_TOKEN= -CROWDIN_API_URL='https://freecodecamp.crowdin.com/api/v2/' -CROWDIN_LANGUAGE_ID= \ No newline at end of file diff --git a/tools/crowdin/utils/auth-header.js b/tools/crowdin/utils/auth-header.js deleted file mode 100644 index 2e216f8f0d9..00000000000 --- a/tools/crowdin/utils/auth-header.js +++ /dev/null @@ -1,7 +0,0 @@ -require('dotenv').config(); - -const authHeader = { - Authorization: `Bearer ${process.env.CROWDIN_PERSONAL_TOKEN}` -}; - -module.exports = authHeader; diff --git a/tools/crowdin/utils/delay.js b/tools/crowdin/utils/delay.js deleted file mode 100644 index a311e0cdfcf..00000000000 --- a/tools/crowdin/utils/delay.js +++ /dev/null @@ -1,5 +0,0 @@ -const delay = (time = 2000) => { - return new Promise(resolve => setTimeout(() => resolve(true), time)); -}; - -module.exports = delay; diff --git a/tools/crowdin/utils/dirs.js b/tools/crowdin/utils/dirs.js deleted file mode 100644 index e7138555e19..00000000000 --- a/tools/crowdin/utils/dirs.js +++ /dev/null @@ -1,86 +0,0 @@ -const authHeader = require('./auth-header'); -const delay = require('./delay'); -const makeRequest = require('./make-request'); - -const getDirs = async projectId => { - let headers = { ...authHeader }; - let done = false; - let offset = 0; - let files = []; - while (!done) { - const endPoint = `projects/${projectId}/directories?limit=500&offset=${offset}`; - await delay(1000); - const response = await makeRequest({ - method: 'get', - endPoint, - headers - }); - if (response.data) { - if (response.data.length) { - files = [...files, ...response.data]; - offset += 500; - } else { - done = true; - return files; - } - } else { - const { error } = response; - console.log(error.errorcode); - console.log(error.messsage); - } - } - return null; -}; - -const addDir = async (projectId, dirName, parentDirId) => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}/directories`; - let body = { - name: dirName - }; - if (parentDirId) { - body = { ...body, directoryId: parentDirId }; - } - - const response = await makeRequest({ - method: 'post', - endPoint, - headers, - body - }); - return response; -}; - -const createDirs = async (crowdinDirs, dirPath) => { - // superParent is the top level directory on crowdin - const superParent = crowdinDirs.find(dir => !dir.data.directoryId); - let lastParentId = superParent.data.id; - - const splitDirPath = dirPath.split('/'); - splitDirPath.shift(); - - // we are assuming that the first directory in 'newFile' is the same as the superParent - // maybe throw a check in here to verify that's true - const findCurrDir = (directory, crowdinDirs) => { - return crowdinDirs.find(({ data: { name, directoryId } }) => { - return name === directory && directoryId === lastParentId; - }); - }; - - for (let directory of splitDirPath) { - const currentDirectory = findCurrDir(directory, crowdinDirs); - if (!currentDirectory) { - const response = await addDir(10, directory, lastParentId); - lastParentId = response.data.id; - } else { - lastParentId = currentDirectory.data.id; - } - } - return lastParentId; -}; - -module.exports = { - addDir, - getDirs, - createDirs -}; diff --git a/tools/crowdin/utils/files.js b/tools/crowdin/utils/files.js deleted file mode 100644 index 740fd0771c9..00000000000 --- a/tools/crowdin/utils/files.js +++ /dev/null @@ -1,122 +0,0 @@ -const authHeader = require('./auth-header'); -const makeRequest = require('./make-request'); - -const addFile = async (projectId, filename, fileContent, directoryId) => { - let headers = { ...authHeader }; - headers['Crowdin-API-FileName'] = filename; - const endPoint = `storages`; - const contentType = 'application/text'; - const body = fileContent; - const storageResponse = await makeRequest({ - method: 'post', - contentType, - endPoint, - headers, - body - }); - if (storageResponse.data) { - const fileBody = { - storageId: storageResponse.data.id, - name: filename, - directoryId - }; - const fileResponse = await makeRequest({ - method: 'post', - endPoint: `projects/${projectId}/files`, - headers, - body: fileBody - }); - if (fileResponse.data) { - return fileResponse.data; - } else { - console.log('error'); - console.dir(fileResponse, { depth: null, colors: true }); - } - } - return null; -}; - -const updateFile = async (projectId, fileId, fileContent) => { - let headers = { ...authHeader }; - const endPoint = `storages`; - const contentType = 'application/text'; - const body = fileContent; - const storageResponse = await makeRequest({ - method: 'post', - contentType, - endPoint, - headers, - body - }); - if (storageResponse.data) { - const fileBody = { - storageId: storageResponse.data.id - }; - const fileResponse = await makeRequest({ - method: 'put', - endPoint: `projects/${projectId}/files${fileId}`, - headers, - body: fileBody - }); - if (fileResponse.data) { - return fileResponse.data; - } else { - console.log('error'); - console.dir(fileResponse, { depth: null, colors: true }); - } - } - return null; -}; - -const deleteFile = async (projectId, fileId, filePath) => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}/files/${fileId}`; - await makeRequest({ - method: 'delete', - endPoint, - headers - }); - console.log(`Deleted ${filePath} from Crowdin project`); - return null; -}; - -const getFiles = async projectId => { - let headers = { ...authHeader }; - let done = false; - let offset = 0; - let files = []; - while (!done) { - const endPoint = `projects/${projectId}/files?limit=500&offset=${offset}`; - const response = await makeRequest({ - method: 'get', - endPoint, - headers - }); - if (response.data) { - if (response.data.length) { - files = [...files, ...response.data]; - offset += 500; - } else { - done = true; - files = files.map(({ data: { directoryId, id: fileId, path } }) => { - // remove leading forwardslash - path = path.slice(1); - return { directoryId, fileId, path }; - }); - return files; - } - } else { - const { error } = response; - console.log(error.errorcode); - console.log(error.messsage); - } - } - return null; -}; - -module.exports = { - addFile, - updateFile, - deleteFile, - getFiles -}; diff --git a/tools/crowdin/utils/get-languages.js b/tools/crowdin/utils/get-languages.js deleted file mode 100644 index cdf4901a0a6..00000000000 --- a/tools/crowdin/utils/get-languages.js +++ /dev/null @@ -1,17 +0,0 @@ -const authHeader = require('./auth-header'); -const makeRequest = require('./make-request'); - -const getLanguages = async projectId => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}?limit=500`; - const response = await makeRequest({ method: 'get', endPoint, headers }); - if (response.data && response.data.targetLanguageIds.length) { - return response.data.targetLanguageIds; - } else { - const { error, errors } = response; - console.error(error ? error : errors); - return null; - } -}; - -module.exports = getLanguages; diff --git a/tools/crowdin/utils/make-request.js b/tools/crowdin/utils/make-request.js deleted file mode 100644 index 37e0af14369..00000000000 --- a/tools/crowdin/utils/make-request.js +++ /dev/null @@ -1,34 +0,0 @@ -require('dotenv').config(); -const fetch = require('node-fetch'); - -const makeRequest = async ({ - method, - endPoint, - contentType = 'application/json', - accept = 'application/json', - headers, - body -}) => { - headers = { ...headers, 'Content-Type': contentType, Accept: accept }; - const apiUrl = process.env.CROWDIN_API_URL + endPoint; - - if (contentType === 'application/x-www-form-urlencoded') { - body = Object.entries(body) - .reduce((formDataArr, [key, value]) => { - return formDataArr.concat(`${key}=${value}`); - }, []) - .join('&'); - } else if (contentType === 'application/json') { - body = JSON.stringify(body); - } - - const response = await fetch(apiUrl, { headers, method, body }); - if (method !== 'delete') { - const data = await response.json(); - return data; - } else { - return null; - } -}; - -module.exports = makeRequest; diff --git a/tools/crowdin/utils/strings.js b/tools/crowdin/utils/strings.js deleted file mode 100644 index 4403f657fb7..00000000000 --- a/tools/crowdin/utils/strings.js +++ /dev/null @@ -1,239 +0,0 @@ -const authHeader = require('./auth-header'); -const makeRequest = require('./make-request'); - -const isReservedHeading = (context, str) => { - const reservedHeadings = [ - 'after-user-code', - 'answers', - 'before-user-code', - 'description', - 'fcc-editable-region', - 'hints', - 'instructions', - 'question', - 'assignments', - 'seed', - 'seed-contents', - 'solutions', - 'text', - 'video-solution' - ]; - const captureGroupStr = `(${reservedHeadings.join('|')})`; - const regex = new RegExp(`--${captureGroupStr}--`); - 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 = async ({ projectId, fileId }) => { - let headers = { ...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 = await makeRequest({ method: 'get', endPoint, headers }); - if (response.data) { - if (response.data.length) { - strings = [...strings, ...response.data]; - offset += 500; - } else { - done = true; - return strings; - } - } else { - const { error, errors } = response; - console.error(error ? error : errors); - } - } - return null; -}; - -const updateString = async ({ projectId, stringId, propsToUpdate }) => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}/strings/${stringId}`; - const body = propsToUpdate.map(({ path, value }) => ({ - op: 'replace', - path, - value - })); - await makeRequest({ - method: 'patch', - endPoint, - headers, - body - }); -}; - -const changeHiddenStatus = async (projectId, stringId, newStatus) => { - await updateString({ - projectId, - stringId, - propsToUpdate: [{ path: '/isHidden', value: newStatus }] - }); -}; - -const updateFileStrings = async ({ projectId, fileId, challengeTitle }) => { - const fileStrings = await getStrings({ - projectId, - fileId - }); - - for (let { - data: { id: stringId, text, isHidden, context } - } of fileStrings) { - const hideString = shouldHide(text, context, challengeTitle); - if (!isHidden && hideString) { - changeHiddenStatus(projectId, stringId, true); - } else if (isHidden && !hideString) { - changeHiddenStatus(projectId, stringId, false); - } - } -}; - -const updateFileString = async ({ - projectId, - string, - challengeTitle, - crowdinFilePath -}) => { - const { - data: { id: stringId, text, isHidden, context } - } = string; - const hideString = shouldHide(text, context, challengeTitle, crowdinFilePath); - if (!isHidden && hideString) { - await changeHiddenStatus(projectId, stringId, true); - console.log( - `${challengeTitle} - stringId: ${stringId} - changed isHidden to true` - ); - } else if (isHidden && !hideString) { - await changeHiddenStatus(projectId, stringId, false); - console.log( - `${challengeTitle} - stringId: ${stringId} - changed isHidden to false` - ); - } -}; - -const getStringTranslations = async ({ projectId, stringId, languageId }) => { - let headers = { ...authHeader }; - let done = false; - let offset = 0; - let translations = []; - while (!done) { - let endPoint = `projects/${projectId}/translations?stringId=${stringId}&languageId=${languageId}&limit=500&offset=${offset}`; - const response = await makeRequest({ method: 'get', endPoint, headers }); - if (response.data) { - if (response.data.length) { - translations = [...translations, ...response.data]; - offset += 500; - } else { - done = true; - return translations; - } - } else { - const { error, errors } = response; - console.error( - error ? JSON.stringify(error, null, 2) : JSON.stringify(errors, null, 2) - ); - } - } - return null; -}; - -const deleteTranslation = async (projectId, translationId) => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}/translations/${translationId}`; - await makeRequest({ - method: 'delete', - endPoint, - headers - }); - console.log(`Deleted translationId ${translationId} from Crowdin project`); - return null; -}; - -const addTranslation = async (projectId, stringId, languageId, text) => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}/translations`; - const body = { - stringId, - languageId, - text - }; - const response = await makeRequest({ - method: 'post', - endPoint, - headers, - body - }); - if (response.data) { - return response.data; - } - return null; -}; - -const getLanguageTranslations = async ({ projectId, languageId }) => { - let headers = { ...authHeader }; - let done = false; - let offset = 0; - let translations = []; - while (!done) { - let endPoint = `projects/${projectId}/languages/${languageId}/translations?limit=500&offset=${offset}`; - const response = await makeRequest({ method: 'get', endPoint, headers }); - if (response.data) { - if (response.data.length) { - translations = [...translations, ...response.data]; - offset += 500; - } else { - done = true; - return translations; - } - } else { - const { error, errors } = response; - console.error( - error ? JSON.stringify(error, null, 2) : JSON.stringify(errors, null, 2) - ); - } - } - return null; -}; - -const deleteLanguageTranslations = async (projectId, languageId, stringId) => { - let headers = { ...authHeader }; - const endPoint = `projects/${projectId}/translations?languageId=${languageId}&stringId=${stringId}`; - console.log(`deleting ${stringId}...`); - await makeRequest({ - method: 'delete', - endPoint, - headers - }); - return null; -}; - -module.exports = { - getStrings, - updateString, - updateFileStrings, - updateFileString, - getStringTranslations, - addTranslation, - deleteTranslation, - getLanguageTranslations, - deleteLanguageTranslations, - changeHiddenStatus -};