Chore: remove old translation tools, import parser (#39273)
This commit is contained in:
committed by
GitHub
parent
bf9837c1da
commit
de3492fded
@ -1,7 +1,7 @@
|
||||
const path = require('path');
|
||||
const { findIndex } = require('lodash');
|
||||
const readDirP = require('readdirp-walk');
|
||||
const { parseMarkdown } = require('@freecodecamp/challenge-md-parser');
|
||||
const { parseMarkdown } = require('../tools/challenge-md-parser');
|
||||
const fs = require('fs');
|
||||
|
||||
const { dasherize } = require('../utils/slugs');
|
||||
|
@ -1,205 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const YAML = require('js-yaml');
|
||||
const readDirP = require('readdirp-walk');
|
||||
const { parseMarkdown } = require('@freecodecamp/challenge-md-parser');
|
||||
const { Translate } = require('@google-cloud/translate');
|
||||
|
||||
const lang = 'pt';
|
||||
const langFull = 'portuguese';
|
||||
|
||||
const outputDir = path.resolve(__dirname, `./challenges/${langFull}`);
|
||||
fs.ensureDirSync(outputDir);
|
||||
|
||||
readDirP({
|
||||
root: path.resolve(__dirname, './challenges/english')
|
||||
}).on('data', translateChallenge);
|
||||
|
||||
async function translateChallenge(file) {
|
||||
const { name, path: filePath, fullPath, stat } = file;
|
||||
if (stat.isDirectory() || name === '.DS_Store') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const blockName = getBlockNameFromPath(filePath);
|
||||
const { fileName: superBlock } = superBlockInfoFromPath(filePath);
|
||||
const outputFile = `${outputDir}/${superBlock}/${blockName}/${name.replace(
|
||||
'english',
|
||||
langFull
|
||||
)}`;
|
||||
if (fs.existsSync(outputFile)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const challenge = await parseMarkdown(fullPath);
|
||||
const { title, description, instructions, tests } = challenge;
|
||||
challenge['videoUrl'] = '';
|
||||
if (challenge['guideUrl']) {
|
||||
challenge['guideUrl'] = challenge['guideUrl'].replace('www', langFull);
|
||||
}
|
||||
const translatePromises = [
|
||||
translateText(title),
|
||||
translateText(description),
|
||||
translateText(instructions),
|
||||
...tests.map(
|
||||
test =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
const { testString, text } = test;
|
||||
const translatedText = await translateText(text).catch(reject);
|
||||
return resolve({
|
||||
text: translatedText ? translatedText.join(' ').trim() : '',
|
||||
testString
|
||||
});
|
||||
})
|
||||
)
|
||||
];
|
||||
return Promise.all(translatePromises).then(
|
||||
([title, description, instructions, ...tests]) => {
|
||||
const { files = {}, solutions = [], ...challengeMeta } = challenge;
|
||||
const md = `---
|
||||
${YAML.dump(
|
||||
Object.assign(challengeMeta, {
|
||||
localeTitle: title ? title.join(' ').trim() : ''
|
||||
}),
|
||||
{ lineWidth: 10000 }
|
||||
)}---
|
||||
|
||||
## Description
|
||||
${description}
|
||||
|
||||
## Instructions
|
||||
${instructions}
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
\`\`\`yml
|
||||
${YAML.dump({ tests }, { lineWidth: 10000 })}
|
||||
\`\`\`
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
${generateChallengeSeed(files)}
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
${
|
||||
solutions.length === 0
|
||||
? `\`\`\`js
|
||||
// solution required
|
||||
\`\`\``
|
||||
: solutions
|
||||
.map(
|
||||
solution => `
|
||||
\`\`\`js
|
||||
${solution}
|
||||
\`\`\`
|
||||
`
|
||||
)
|
||||
.join('\n')
|
||||
}
|
||||
</section>
|
||||
`;
|
||||
|
||||
console.log(outputFile);
|
||||
fs.ensureFileSync(outputFile);
|
||||
fs.writeFile(outputFile, md);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function generateChallengeSeed(files) {
|
||||
return Object.keys(files)
|
||||
.map(key => files[key])
|
||||
.map(file => {
|
||||
const { ext, contents = [], head = [], tail = [] } = file;
|
||||
return `
|
||||
<div id='${ext}-seed'>
|
||||
|
||||
\`\`\`${ext}
|
||||
${contents}
|
||||
\`\`\`
|
||||
|
||||
</div>
|
||||
${
|
||||
head.length
|
||||
? `
|
||||
### Before Test
|
||||
<div id='${ext}-setup'>
|
||||
|
||||
\`\`\`${ext}
|
||||
${head}
|
||||
\`\`\`
|
||||
|
||||
</div>`
|
||||
: ''
|
||||
}
|
||||
${
|
||||
tail.length
|
||||
? `
|
||||
### After Test
|
||||
<div id='${ext}-teardown'>
|
||||
|
||||
\`\`\`js
|
||||
console.info('after the test');
|
||||
\`\`\`
|
||||
|
||||
</div>`
|
||||
: ''
|
||||
}
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
const createTranslateText = target => text => {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
const translate = new Translate();
|
||||
|
||||
return translate
|
||||
.translate(text, target)
|
||||
.then(results => {
|
||||
let translations = results[0];
|
||||
translations = Array.isArray(translations)
|
||||
? translations
|
||||
: [translations];
|
||||
return translations;
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const translateText = createTranslateText(lang);
|
||||
|
||||
function superBlockInfoFromPath(filePath) {
|
||||
const [maybeSuper] = filePath.split('/');
|
||||
return superBlockInfo(maybeSuper);
|
||||
}
|
||||
|
||||
function superBlockInfo(fileName) {
|
||||
const [maybeOrder, ...superBlock] = fileName.split('-');
|
||||
let order = parseInt(maybeOrder, 10);
|
||||
if (isNaN(order)) {
|
||||
return {
|
||||
order: 0,
|
||||
name: fileName
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
order: order,
|
||||
name: superBlock.join('-'),
|
||||
fileName
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getBlockNameFromPath(filePath) {
|
||||
const [, block] = filePath.split('/');
|
||||
return block;
|
||||
}
|
1021
curriculum/package-lock.json
generated
1021
curriculum/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,6 @@
|
||||
"@commitlint/cli": "^8.3.5",
|
||||
"@commitlint/config-conventional": "^7.0.1",
|
||||
"@commitlint/travis-cli": "^8.3.5",
|
||||
"@freecodecamp/challenge-md-parser": "^2.0.0",
|
||||
"@semantic-release/changelog": "^2.0.2",
|
||||
"@semantic-release/git": "^5.0.0",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
@ -49,12 +48,12 @@
|
||||
"gulp": "^4.0.2",
|
||||
"joi": "^13.3.0",
|
||||
"joi-objectid": "^2.0.0",
|
||||
"jquery": "^3.4.1",
|
||||
"jquery": "^3.5.1",
|
||||
"js-yaml": "^3.12.0",
|
||||
"jsdom": "^12.2.0",
|
||||
"lint-staged": "^7.2.0",
|
||||
"live-server": "^1.2.1",
|
||||
"lodash": "^4.17.15",
|
||||
"lodash": "^4.17.19",
|
||||
"mocha": "5.2.0",
|
||||
"puppeteer": "^1.19.0",
|
||||
"readdirp-walk": "^1.7.0",
|
||||
|
@ -1,397 +0,0 @@
|
||||
const unified = require('unified');
|
||||
const markdown = require('remark-parse');
|
||||
const remark2rehype = require('remark-rehype');
|
||||
const stringify = require('remark-stringify');
|
||||
const frontmatter = require('remark-frontmatter');
|
||||
const raw = require('rehype-raw');
|
||||
const visit = require('unist-util-visit');
|
||||
const vfile = require('to-vfile');
|
||||
const path = require('path');
|
||||
const { Transform } = require('stream');
|
||||
const { Translate } = require('@google-cloud/translate');
|
||||
const YAML = require('js-yaml');
|
||||
|
||||
const solutionsToData = require('./solution-to-data');
|
||||
const challengeSeedToData = require('./challengeSeed-to-data');
|
||||
|
||||
const transformChallenge = new Transform({
|
||||
transform(chunk, encoding, callback) {
|
||||
const fileName = chunk.toString().trim();
|
||||
|
||||
rebuildChallengeFile(fileName)
|
||||
.then(file => callback(null, String(file.contents)))
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
});
|
||||
|
||||
process.stdin.pipe(transformChallenge).pipe(process.stdout);
|
||||
|
||||
const processor = unified()
|
||||
.use(markdown)
|
||||
.use(frontmatter, ['yaml'])
|
||||
.use(frontmatterToData)
|
||||
.use(testsToData)
|
||||
.use(textToData, ['description', 'instructions'])
|
||||
.use(remark2rehype, { allowDangerousHTML: true })
|
||||
.use(raw)
|
||||
.use(solutionsToData)
|
||||
.use(challengeSeedToData)
|
||||
.use(replaceWithReferenceData)
|
||||
.use(output);
|
||||
|
||||
exports.rebuildChallengeFile = rebuildChallengeFile;
|
||||
|
||||
async function rebuildChallengeFile(fileName) {
|
||||
const filePath = path.resolve(fileName);
|
||||
const lang = detectLang(filePath);
|
||||
let referenceChallenge;
|
||||
let translateText;
|
||||
if (lang !== 'english') {
|
||||
referenceChallenge = await getReferenceChallengeData(filePath);
|
||||
translateText = createTranslateText(lang);
|
||||
}
|
||||
|
||||
const file = await vfile.read(filePath);
|
||||
file.data = {
|
||||
...file.data,
|
||||
lang,
|
||||
referenceChallenge,
|
||||
translateText
|
||||
};
|
||||
return await processor.process(file);
|
||||
}
|
||||
|
||||
async function getReferenceChallengeData(filePath) {
|
||||
const parts = filePath.split(path.sep);
|
||||
parts.push(parts.pop().replace(/\.[^.]+\.md$/, '.english.md'));
|
||||
parts[parts.length - 4] = 'english';
|
||||
const filePathEnglishChallenge = parts.join(path.sep);
|
||||
try {
|
||||
const fileData = await vfile.read(filePathEnglishChallenge);
|
||||
fileData.data = { ...fileData.data, refData: true };
|
||||
return (await processor.process(fileData)).data;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function detectLang(filePath) {
|
||||
const match = /\.([^.]+)\.md$/.exec(filePath);
|
||||
if (!match) {
|
||||
throw new Error(`Incorrect file path ${filePath}`);
|
||||
}
|
||||
return match[1];
|
||||
}
|
||||
|
||||
function frontmatterToData() {
|
||||
return transformer;
|
||||
|
||||
function transformer(tree, file) {
|
||||
visit(tree, 'yaml', visitor);
|
||||
|
||||
function visitor(node) {
|
||||
const frontmatter = node.value;
|
||||
|
||||
file.data = { ...file.data, frontmatter };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testsToData() {
|
||||
return (tree, file) => {
|
||||
visit(tree, 'code', visitor);
|
||||
|
||||
function visitor(node) {
|
||||
const { lang, value } = node;
|
||||
if (lang === 'yml') {
|
||||
file.data = {
|
||||
...file.data,
|
||||
tests: value
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function textToData(sectionIds) {
|
||||
return (tree, file) => {
|
||||
let indexId = 0;
|
||||
let currentSection = sectionIds[indexId];
|
||||
let inSection = false;
|
||||
let nodes = [];
|
||||
let findSection;
|
||||
const visitor = (node, index, parent) => {
|
||||
if (!parent) {
|
||||
return visit.CONTINUE;
|
||||
}
|
||||
|
||||
if (node.type === 'heading') {
|
||||
if (inSection) {
|
||||
findSection = new RegExp(`^<section id=('|")${currentSection}\\1>`);
|
||||
file.data = {
|
||||
...file.data,
|
||||
[currentSection]: new stringify.Compiler(
|
||||
{ type: 'root', children: nodes },
|
||||
file
|
||||
)
|
||||
.compile()
|
||||
.trim()
|
||||
.replace(findSection, '')
|
||||
.replace(/<\/section>$/, '')
|
||||
.trim()
|
||||
};
|
||||
nodes = [];
|
||||
indexId++;
|
||||
if (indexId < sectionIds.length) {
|
||||
currentSection = sectionIds[indexId];
|
||||
} else {
|
||||
return visit.EXIT;
|
||||
}
|
||||
}
|
||||
inSection = true;
|
||||
} else if (inSection) {
|
||||
nodes.push(node);
|
||||
}
|
||||
|
||||
return visit.SKIP;
|
||||
};
|
||||
visit(tree, visitor);
|
||||
};
|
||||
}
|
||||
|
||||
function createTranslateText(target, source = 'english') {
|
||||
const projectId = process.env.GOOGLE_CLOUD_PROJECT_ID;
|
||||
if (!projectId) {
|
||||
return async text => text;
|
||||
}
|
||||
const languageCodes = {
|
||||
arabic: 'ar',
|
||||
chinese: 'zh',
|
||||
english: 'en',
|
||||
portuguese: 'pt',
|
||||
russian: 'ru',
|
||||
spanish: 'es'
|
||||
};
|
||||
const from = languageCodes[source];
|
||||
const to = languageCodes[target];
|
||||
return async text => {
|
||||
if (!text) {
|
||||
return text;
|
||||
}
|
||||
try {
|
||||
const translate = new Translate({ projectId });
|
||||
const result = await translate.translate(text, { from, to });
|
||||
const translations = result[0];
|
||||
return translations;
|
||||
} catch (err) {
|
||||
// console.error(err);
|
||||
return text;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function processTests(tests, referenceTests, translateText) {
|
||||
const testsObject = YAML.load(referenceTests);
|
||||
if (
|
||||
!testsObject.tests ||
|
||||
testsObject.tests.length === 0 ||
|
||||
!testsObject.tests[0].text
|
||||
) {
|
||||
return referenceTests;
|
||||
}
|
||||
const newTests = await Promise.all(
|
||||
testsObject.tests.map(async test => {
|
||||
const text = await translateText(test.text);
|
||||
return { ...test, text };
|
||||
})
|
||||
);
|
||||
const testStrings = newTests
|
||||
.map(
|
||||
({ text, testString }) =>
|
||||
` - text: ${dumpToYamlString(text)} testString: ${dumpToYamlString(
|
||||
testString
|
||||
)}`
|
||||
)
|
||||
.join('');
|
||||
return `tests:${testStrings ? '\n' + testStrings : ' []\n'}`;
|
||||
}
|
||||
|
||||
function dumpToYamlString(text) {
|
||||
let fromYaml;
|
||||
try {
|
||||
fromYaml = YAML.load(text);
|
||||
} catch {
|
||||
// console.error(`YAML load: ${text}`);
|
||||
}
|
||||
if (text === fromYaml) {
|
||||
return text + '\n';
|
||||
}
|
||||
return YAML.dump(text, { lineWidth: 10000 });
|
||||
}
|
||||
|
||||
async function processFrontmatter(fileData) {
|
||||
const { referenceChallenge, lang, translateText } = fileData;
|
||||
const challengeData = YAML.load(fileData.frontmatter);
|
||||
let data;
|
||||
if (referenceChallenge) {
|
||||
data = YAML.load(referenceChallenge.frontmatter);
|
||||
} else {
|
||||
data = challengeData;
|
||||
}
|
||||
|
||||
if (lang && lang !== 'english') {
|
||||
if (challengeData.localeTitle) {
|
||||
data.localeTitle = challengeData.localeTitle;
|
||||
} else {
|
||||
data.localeTitle = await translateText(data.title);
|
||||
}
|
||||
}
|
||||
|
||||
fileData.frontmatter = Object.entries(data)
|
||||
.map(([name, value]) => {
|
||||
if (typeof value === 'object') {
|
||||
return `${name}:
|
||||
${dumpToYamlString(value)
|
||||
.replace(/\n/, '\n ')
|
||||
.trimRight()}
|
||||
`;
|
||||
}
|
||||
return `${name}: ${dumpToYamlString(value)}`;
|
||||
})
|
||||
.join('')
|
||||
.trimRight();
|
||||
}
|
||||
|
||||
function replaceWithReferenceData() {
|
||||
return async (tree, file) => {
|
||||
if (file.data.refData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { referenceChallenge, translateText } = file.data;
|
||||
|
||||
await processFrontmatter(file.data);
|
||||
|
||||
if (referenceChallenge) {
|
||||
const { description, instructions } = file.data;
|
||||
|
||||
if (!description || description === 'undefined') {
|
||||
file.data.description = await translateText(
|
||||
referenceChallenge.description
|
||||
);
|
||||
}
|
||||
if (!instructions || instructions === 'undefined') {
|
||||
file.data.instructions = await translateText(
|
||||
referenceChallenge.instructions
|
||||
);
|
||||
}
|
||||
file.data.tests = await processTests(
|
||||
file.data.tests,
|
||||
referenceChallenge.tests,
|
||||
translateText
|
||||
);
|
||||
file.data.files = referenceChallenge.files;
|
||||
file.data.solutions = referenceChallenge.solutions;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function output() {
|
||||
this.Compiler = function(tree, file) {
|
||||
let {
|
||||
frontmatter,
|
||||
description,
|
||||
instructions,
|
||||
tests,
|
||||
files: [challengeFile = {}]
|
||||
} = file.data;
|
||||
const { ext, contents, head, tail } = challengeFile;
|
||||
let { solutions = [] } = file.data;
|
||||
solutions = solutions
|
||||
.map(s => s.trim())
|
||||
.map(s =>
|
||||
!s.includes('\n') && /^\/\//.test(s) ? '// solution required' : s
|
||||
);
|
||||
return `---
|
||||
${frontmatter}
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
${description}
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
${instructions}
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
\`\`\`yml
|
||||
${tests}
|
||||
\`\`\`
|
||||
|
||||
</section>
|
||||
|
||||
${
|
||||
ext
|
||||
? `## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='${ext}-seed'>
|
||||
|
||||
\`\`\`${ext}
|
||||
${contents}
|
||||
\`\`\`
|
||||
|
||||
</div>${
|
||||
head
|
||||
? `
|
||||
|
||||
### Before Tests
|
||||
<div id='${ext}-setup'>
|
||||
|
||||
\`\`\`${ext}
|
||||
${head}
|
||||
\`\`\`
|
||||
|
||||
</div>`
|
||||
: ''
|
||||
}${
|
||||
tail
|
||||
? `
|
||||
|
||||
### After Tests
|
||||
<div id='${ext}-teardown'>
|
||||
|
||||
\`\`\`${ext}
|
||||
${tail}
|
||||
\`\`\`
|
||||
|
||||
</div>`
|
||||
: ''
|
||||
}
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
${solutions.reduce(
|
||||
(result, solution) =>
|
||||
result +
|
||||
`<section id='solution'>
|
||||
|
||||
\`\`\`${ext}
|
||||
${solution.trim()}
|
||||
\`\`\`
|
||||
|
||||
</section>`,
|
||||
''
|
||||
)}
|
||||
`
|
||||
: ''
|
||||
}`;
|
||||
};
|
||||
}
|
456
tools/challenge-md-parser/package-lock.json
generated
456
tools/challenge-md-parser/package-lock.json
generated
@ -217,55 +217,6 @@
|
||||
"minimist": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@google-cloud/common": {
|
||||
"version": "0.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.31.1.tgz",
|
||||
"integrity": "sha512-MgaF8VmDaoyIqzZUXIbcohTb5sQn+PYlYmcpb0/E8psUpVe+kaBwLq/Z8pcFtACCr6PNT36n+a6s1kG35bAuCA==",
|
||||
"requires": {
|
||||
"@google-cloud/projectify": "^0.3.2",
|
||||
"@google-cloud/promisify": "^0.4.0",
|
||||
"@types/duplexify": "^3.5.0",
|
||||
"@types/request": "^2.47.0",
|
||||
"arrify": "^1.0.1",
|
||||
"duplexify": "^3.6.0",
|
||||
"ent": "^2.2.0",
|
||||
"extend": "^3.0.1",
|
||||
"google-auth-library": "^3.0.0",
|
||||
"pify": "^4.0.0",
|
||||
"retry-request": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@google-cloud/projectify": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz",
|
||||
"integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw=="
|
||||
},
|
||||
"@google-cloud/promisify": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz",
|
||||
"integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q=="
|
||||
},
|
||||
"@google-cloud/translate": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@google-cloud/translate/-/translate-2.1.4.tgz",
|
||||
"integrity": "sha512-m9yIGnJg0aTohb1arNGfGYyZd7tt+ncB4xqGj3Saf6fiUgfQ0jCnadDKdVVDN00Ziu5//qS1bz38eb+8wX4Cug==",
|
||||
"requires": {
|
||||
"@google-cloud/common": "^0.31.0",
|
||||
"@google-cloud/promisify": "^0.4.0",
|
||||
"arrify": "^1.0.1",
|
||||
"extend": "^3.0.1",
|
||||
"is": "^3.2.1",
|
||||
"is-html": "^1.1.0",
|
||||
"teeny-request": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"@jest/console": {
|
||||
"version": "24.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz",
|
||||
@ -475,19 +426,6 @@
|
||||
"@babel/types": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@types/caseless": {
|
||||
"version": "0.12.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
|
||||
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w=="
|
||||
},
|
||||
"@types/duplexify": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz",
|
||||
"integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
|
||||
@ -513,45 +451,12 @@
|
||||
"@types/istanbul-lib-report": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz",
|
||||
"integrity": "sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg=="
|
||||
},
|
||||
"@types/request": {
|
||||
"version": "2.48.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.2.tgz",
|
||||
"integrity": "sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA==",
|
||||
"requires": {
|
||||
"@types/caseless": "*",
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*",
|
||||
"form-data": "^2.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"form-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.0.tgz",
|
||||
"integrity": "sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/stack-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz",
|
||||
"integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg=="
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "13.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz",
|
||||
@ -573,14 +478,6 @@
|
||||
"integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
|
||||
"dev": true
|
||||
},
|
||||
"abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"requires": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "5.7.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
|
||||
@ -611,14 +508,6 @@
|
||||
"integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
|
||||
"dev": true
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
|
||||
@ -700,11 +589,6 @@
|
||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
||||
"dev": true
|
||||
},
|
||||
"arrify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
@ -741,7 +625,8 @@
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
@ -872,11 +757,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"bcp-47-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.0.tgz",
|
||||
@ -891,11 +771,6 @@
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
|
||||
"integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ=="
|
||||
},
|
||||
"bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
@ -982,11 +857,6 @@
|
||||
"node-int64": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
@ -1153,6 +1023,7 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
@ -1195,7 +1066,8 @@
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
@ -1360,7 +1232,8 @@
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"detab": {
|
||||
"version": "2.0.1",
|
||||
@ -1396,17 +1269,6 @@
|
||||
"webidl-conversions": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"duplexify": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
|
||||
"integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
|
||||
"requires": {
|
||||
"end-of-stream": "^1.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^2.0.0",
|
||||
"stream-shift": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
@ -1417,14 +1279,6 @@
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
@ -1435,15 +1289,11 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"ent": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
|
||||
"integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0="
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
@ -1483,19 +1333,6 @@
|
||||
"is-symbol": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"requires": {
|
||||
"es6-promise": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
@ -1532,11 +1369,6 @@
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||
"dev": true
|
||||
},
|
||||
"event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||
},
|
||||
"exec-sh": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
|
||||
@ -1728,11 +1560,6 @@
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-text-encoding": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz",
|
||||
"integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ=="
|
||||
},
|
||||
"fault": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz",
|
||||
@ -2396,26 +2223,6 @@
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"gaxios": {
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz",
|
||||
"integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==",
|
||||
"requires": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^2.2.1",
|
||||
"node-fetch": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"gcp-metadata": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz",
|
||||
"integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==",
|
||||
"requires": {
|
||||
"gaxios": "^1.0.2",
|
||||
"json-bigint": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"gensync": {
|
||||
"version": "1.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
|
||||
@ -2472,38 +2279,6 @@
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||
"dev": true
|
||||
},
|
||||
"google-auth-library": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz",
|
||||
"integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.0",
|
||||
"fast-text-encoding": "^1.0.0",
|
||||
"gaxios": "^1.2.1",
|
||||
"gcp-metadata": "^1.0.0",
|
||||
"gtoken": "^2.3.2",
|
||||
"https-proxy-agent": "^2.2.1",
|
||||
"jws": "^3.1.5",
|
||||
"lru-cache": "^5.0.0",
|
||||
"semver": "^5.5.0"
|
||||
}
|
||||
},
|
||||
"google-p12-pem": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz",
|
||||
"integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==",
|
||||
"requires": {
|
||||
"node-forge": "^0.8.0",
|
||||
"pify": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
@ -2516,25 +2291,6 @@
|
||||
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
|
||||
"dev": true
|
||||
},
|
||||
"gtoken": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz",
|
||||
"integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==",
|
||||
"requires": {
|
||||
"gaxios": "^1.0.4",
|
||||
"google-p12-pem": "^1.0.0",
|
||||
"jws": "^3.1.5",
|
||||
"mime": "^2.2.0",
|
||||
"pify": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
@ -2758,11 +2514,6 @@
|
||||
"integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==",
|
||||
"dev": true
|
||||
},
|
||||
"html-tags": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-1.2.0.tgz",
|
||||
"integrity": "sha1-x43mW1Zjqll5id0rerSSANfk25g="
|
||||
},
|
||||
"html-void-elements": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.3.tgz",
|
||||
@ -2779,30 +2530,6 @@
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
|
||||
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
|
||||
"requires": {
|
||||
"agent-base": "^4.3.0",
|
||||
"debug": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
@ -2852,11 +2579,6 @@
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
|
||||
"integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg=="
|
||||
},
|
||||
"is-accessor-descriptor": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
|
||||
@ -2996,14 +2718,6 @@
|
||||
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz",
|
||||
"integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A=="
|
||||
},
|
||||
"is-html": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-html/-/is-html-1.1.0.tgz",
|
||||
"integrity": "sha1-4E8cGNOUhRETlvmgJz6rUa8hhGQ=",
|
||||
"requires": {
|
||||
"html-tags": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
||||
@ -3093,7 +2807,8 @@
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
@ -3690,14 +3405,6 @@
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
|
||||
"dev": true
|
||||
},
|
||||
"json-bigint": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
|
||||
"integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=",
|
||||
"requires": {
|
||||
"bignumber.js": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
@ -3743,25 +3450,6 @@
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"jwa": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jws": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||
"requires": {
|
||||
"jwa": "^1.4.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
@ -3843,14 +3531,6 @@
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"requires": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
|
||||
@ -3969,20 +3649,17 @@
|
||||
"to-regex": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
||||
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
@ -4076,16 +3753,6 @@
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"node-forge": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz",
|
||||
"integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q=="
|
||||
},
|
||||
"node-int64": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||
@ -4258,6 +3925,7 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -4449,11 +4117,6 @@
|
||||
"react-is": "^16.8.4"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
},
|
||||
"prompts": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz",
|
||||
@ -4527,20 +4190,6 @@
|
||||
"read-pkg": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"realpath-native": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
|
||||
@ -4754,30 +4403,6 @@
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
|
||||
"dev": true
|
||||
},
|
||||
"retry-request": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz",
|
||||
"integrity": "sha512-BINDzVtLI2BDukjWmjAIRZ0oglnCAkpP2vQjM3jdLhmT62h0xnQgciPwBRDAvHqpkPT2Wo1XuUyLyn6nbGrZQQ==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"through2": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
@ -4796,7 +4421,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safe-regex": {
|
||||
"version": "1.1.0",
|
||||
@ -4839,7 +4465,8 @@
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"dev": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
@ -5164,11 +4791,6 @@
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
|
||||
"dev": true
|
||||
},
|
||||
"stream-shift": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
|
||||
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
|
||||
},
|
||||
"string-length": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
|
||||
@ -5227,14 +4849,6 @@
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"stringify-entities": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz",
|
||||
@ -5290,16 +4904,6 @@
|
||||
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
|
||||
"dev": true
|
||||
},
|
||||
"teeny-request": {
|
||||
"version": "3.11.3",
|
||||
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz",
|
||||
"integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==",
|
||||
"requires": {
|
||||
"https-proxy-agent": "^2.2.1",
|
||||
"node-fetch": "^2.2.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"test-exclude": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
|
||||
@ -5318,14 +4922,6 @@
|
||||
"integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=",
|
||||
"dev": true
|
||||
},
|
||||
"through2": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
|
||||
"integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
|
||||
"requires": {
|
||||
"readable-stream": "2 || 3"
|
||||
}
|
||||
},
|
||||
"tmpl": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
|
||||
@ -5605,11 +5201,6 @@
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"util.promisify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
|
||||
@ -5625,7 +5216,8 @@
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
@ -5769,7 +5361,8 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"write-file-atomic": {
|
||||
"version": "2.4.1",
|
||||
@ -5813,11 +5406,6 @@
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.3.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
|
||||
|
@ -16,7 +16,6 @@
|
||||
"jest": "^24.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google-cloud/translate": "^2.1.3",
|
||||
"hast-util-select": "^2.1.0",
|
||||
"hast-util-to-html": "^4.0.1",
|
||||
"js-yaml": "^3.12.0",
|
||||
|
@ -1,180 +0,0 @@
|
||||
var fs = require('fs');
|
||||
|
||||
var lang = 'es';
|
||||
var langFull = 'spanish';
|
||||
|
||||
var dir1 = fs.readdirSync('../../curriculum/challenges/english')[5];
|
||||
var dir2 = fs.readdirSync('../../curriculum/challenges/english/' + dir1)[3];
|
||||
var dir = dir1 + '/' + dir2;
|
||||
fs.readdirSync('../../curriculum/challenges/english/' + dir).forEach(file => {
|
||||
if (file.includes('.md') && dir) {
|
||||
let originalFileName =
|
||||
'../../curriculum/challenges/' +
|
||||
langFull +
|
||||
'/' +
|
||||
dir +
|
||||
'/' +
|
||||
file.slice(0, -10) +
|
||||
langFull +
|
||||
'.md';
|
||||
|
||||
fs.exists(originalFileName, function(exists) {
|
||||
if (!exists) {
|
||||
console.log(originalFileName);
|
||||
getFile(file, dir);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// TEST
|
||||
// var dir1 = fs.readdirSync('../../curriculum/challenges/english')[4];
|
||||
// var dir2 = fs.readdirSync('../../curriculum/challenges/english/' + dir1)[0];
|
||||
// var dir = dir1 + '/' + dir2;
|
||||
// getFile('exercise-tracker.english.md', dir);
|
||||
|
||||
// Load in full text, description, instructions, and title
|
||||
function getFile(file, dir) {
|
||||
let originalFileName =
|
||||
'../../curriculum/challenges/english/' + dir + '/' + file;
|
||||
let fileString = fs.readFileSync(originalFileName).toString();
|
||||
|
||||
// Add 'notranslate' class to code so Google Translate API
|
||||
// will not translate code segments.
|
||||
fileString = fileString.replace(/<code>/g, '<code class="notranslate">');
|
||||
fileString = fileString.replace(
|
||||
/<blockquote>/g,
|
||||
'<blockquote class="notranslate">'
|
||||
);
|
||||
fileString = fileString.replace(/^.*videoUrl.*$/gm, "videoUrl: ''");
|
||||
fileString = fileString.replace(
|
||||
/https:\/\/www\.freecodecamp\.org/,
|
||||
'https://' + langFull + '.freecodecamp.org'
|
||||
);
|
||||
let description = fileString.match(
|
||||
/<section id='description'>(.|\n)*?<\/section>/
|
||||
)[0];
|
||||
description = description.replace(/\r?\n/g, '<code>0</code>');
|
||||
let instructions = fileString.match(
|
||||
/<section id='instructions'>(.|\n)*?<\/section>/
|
||||
)[0];
|
||||
instructions = instructions.replace(/\r?\n/g, '<code>0</code>');
|
||||
let tests = fileString.match(/<section id='tests'>(.|\n)*?<\/section>/)[0];
|
||||
let title = fileString.split('\n')[2].split(': ')[1];
|
||||
processFile(fileString, description, instructions, tests, title, file, dir);
|
||||
}
|
||||
|
||||
// Get translations from Google Translate API and insert into file
|
||||
function processFile(
|
||||
fileString,
|
||||
description,
|
||||
instructions,
|
||||
tests,
|
||||
title,
|
||||
file,
|
||||
dir
|
||||
) {
|
||||
const translateText = (text, target) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof text === 'object' && Object.keys(text).length === 0) {
|
||||
resolve(['']);
|
||||
} else {
|
||||
// Imports the Google Cloud client library
|
||||
const { Translate } = require('@google-cloud/translate');
|
||||
|
||||
// Creates a client
|
||||
const translate = new Translate();
|
||||
|
||||
translate
|
||||
.translate(text, target)
|
||||
.then(results => {
|
||||
let translations = results[0];
|
||||
translations = Array.isArray(translations)
|
||||
? translations
|
||||
: [translations];
|
||||
resolve(translations);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(console.log('!!!!!', err));
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// FOR TESTING ONLY
|
||||
// const translateText = (text, target) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// resolve(['translated', 'translated', 'translated', 'translated']);
|
||||
// });
|
||||
// };
|
||||
|
||||
const translateTests = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let testsArray = tests.split('\n');
|
||||
let testsToTranslate = [];
|
||||
|
||||
testsArray.forEach(test => {
|
||||
if (test.includes('- text: ')) {
|
||||
testsToTranslate.push(test.slice(10));
|
||||
}
|
||||
});
|
||||
translateText(testsToTranslate, lang)
|
||||
.then(translation => {
|
||||
let transIndex = 0;
|
||||
testsArray.forEach((test, index) => {
|
||||
if (test.includes('- text')) {
|
||||
testsArray[index] = ' - text: ' + translation[transIndex];
|
||||
transIndex++;
|
||||
}
|
||||
});
|
||||
resolve(testsArray.join('\n'));
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
translateText(description, lang),
|
||||
translateText(instructions, lang),
|
||||
translateText(title, lang),
|
||||
translateTests(tests, lang)
|
||||
]).then(function(translations) {
|
||||
// Replace English with translation
|
||||
fileString = fileString.replace(
|
||||
/<section id='description'>(.|\n)*?<\/section>/,
|
||||
translations[0][0].replace(/<code>0<\/code> /g, '\n')
|
||||
);
|
||||
fileString = fileString.replace(
|
||||
/<section id='instructions'>(.|\n)*?<\/section>/,
|
||||
translations[1][0].replace(/<code>0<\/code> /g, '\n')
|
||||
);
|
||||
fileString = fileString.replace(
|
||||
title,
|
||||
title + '\nlocaleTitle: ' + translations[2]
|
||||
);
|
||||
fileString = fileString.replace(
|
||||
/<section id='tests'>(.|\n)*?<\/section>/,
|
||||
translations[3]
|
||||
);
|
||||
fileString = fileString.replace(/ class=\"notranslate\"/g, '');
|
||||
writeFile(fileString, file, dir);
|
||||
});
|
||||
}
|
||||
|
||||
function writeFile(fileString, file, dir) {
|
||||
let fullFileName =
|
||||
'../../curriculum/challenges/' +
|
||||
langFull +
|
||||
'/' +
|
||||
dir +
|
||||
'/' +
|
||||
file.slice(0, -10) +
|
||||
langFull +
|
||||
'.md';
|
||||
fs.writeFile(fullFileName, fileString, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
console.log('Saved!');
|
||||
});
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const unified = require('unified');
|
||||
const parse = require('remark-parse');
|
||||
const parse2 = require('rehype-parse');
|
||||
const rehype = require('remark-rehype');
|
||||
const stringify = require('rehype-stringify');
|
||||
const stringify2 = require('remark-stringify');
|
||||
const remark = require('rehype-remark');
|
||||
const path = require('path');
|
||||
const readDirP = require('readdirp-walk');
|
||||
const { Translate } = require('@google-cloud/translate');
|
||||
|
||||
const lang = 'es';
|
||||
const langFull = 'spanish';
|
||||
|
||||
const mdProcessor = unified()
|
||||
.use(parse)
|
||||
.use(rehype, { allowDangerousHTML: true })
|
||||
.use(stringify);
|
||||
|
||||
const htmlProcessor = unified()
|
||||
.use(parse2)
|
||||
.use(remark)
|
||||
.use(stringify2);
|
||||
|
||||
readDirP({
|
||||
root: path.resolve(__dirname, './test')
|
||||
}).on('data', translateChallenge);
|
||||
|
||||
async function translateChallenge(file) {
|
||||
const { name, fullPath, fullParentDir, stat } = file;
|
||||
if (stat.isDirectory() || name === '.DS_Store' || file.depth === 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pathIndex = fullPath.indexOf('guide') + 6;
|
||||
const outputDir =
|
||||
fullParentDir.substring(0, pathIndex) +
|
||||
`${langFull}/` +
|
||||
fullParentDir.substring(pathIndex + 5);
|
||||
const outputPath =
|
||||
fullPath.substring(0, pathIndex) +
|
||||
`${langFull}/` +
|
||||
fullPath.substring(pathIndex + 5);
|
||||
if (fs.existsSync(outputPath)) {
|
||||
return null;
|
||||
}
|
||||
fs.ensureDirSync(outputDir);
|
||||
|
||||
const fileString = fs.readFileSync(fullPath).toString();
|
||||
var i = fileString.indexOf('---', 4);
|
||||
const meta = fileString.substring(0, i + 4);
|
||||
const title = fileString.split('\n')[1].split(': ')[1];
|
||||
var article = fileString.substring(i + 4);
|
||||
|
||||
return mdToHtml(article).then(htmlArticle => {
|
||||
htmlArticle = htmlArticle.replace(/\n/g, '<br>');
|
||||
htmlArticle = htmlArticle.replace(
|
||||
/ {8}/g,
|
||||
' '
|
||||
);
|
||||
htmlArticle = htmlArticle.replace(/ {4}/g, ' ');
|
||||
htmlArticle = htmlArticle.replace(/ {2}/g, ' ');
|
||||
translate(htmlArticle, title, meta, outputPath);
|
||||
});
|
||||
}
|
||||
|
||||
function translate(htmlArticle, title, meta, outputPath) {
|
||||
Promise.all([translateText(title), translateText(htmlArticle)]).then(function(
|
||||
translations
|
||||
) {
|
||||
// Replace English with translation
|
||||
let translatedTitle = translations[0][0];
|
||||
let tempArticle = translations[1][0];
|
||||
tempArticle = tempArticle.replace(/<br>/g, '\n');
|
||||
tempArticle = tempArticle.replace(/'/g, "'");
|
||||
|
||||
// tempArticle = tempArticle.replace(/language-html">/g,'language-html">\n')
|
||||
// tempArticle = tempArticle.replace(/<pre> <code/g, '<pre><code')
|
||||
// tempArticle = tempArticle.replace(/<\/code> <\/pre/g, '</code></pre')
|
||||
tempArticle = tempArticle.replace(/ /g, ' ');
|
||||
|
||||
htmlToMd(tempArticle).then(translatedArticle => {
|
||||
const i = meta.indexOf('---', 4);
|
||||
let translatedFile =
|
||||
meta.slice(0, i) +
|
||||
`localeTitle: ${translatedTitle}\n` +
|
||||
meta.slice(i) +
|
||||
translatedArticle;
|
||||
writeFile(translatedFile, outputPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const createTranslateText = target => text => {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
const translate = new Translate();
|
||||
|
||||
return translate
|
||||
.translate(text, target)
|
||||
.then(results => {
|
||||
let translations = results[0];
|
||||
translations = Array.isArray(translations)
|
||||
? translations
|
||||
: [translations];
|
||||
return translations;
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const translateText = createTranslateText(lang);
|
||||
|
||||
function writeFile(fileString, outputPath) {
|
||||
fs.writeFile(outputPath, fileString, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
console.log('Saved:' + outputPath);
|
||||
});
|
||||
}
|
||||
|
||||
function mdToHtml(file) {
|
||||
return new Promise((resolve, reject) =>
|
||||
mdProcessor.process(file, function(err, file) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
return resolve(file.contents);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function htmlToMd(file) {
|
||||
return new Promise((resolve, reject) =>
|
||||
htmlProcessor.process(file, function(err, file) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
return resolve(file.contents);
|
||||
})
|
||||
);
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
var showdown = require('showdown');
|
||||
const path = require('path');
|
||||
const readDirP = require('readdirp-walk');
|
||||
const { Translate } = require('@google-cloud/translate');
|
||||
|
||||
var TurndownService = require('turndown');
|
||||
|
||||
var turndownService = new TurndownService({
|
||||
codeBlockStyle: 'fenced',
|
||||
headingStyle: 'atx'
|
||||
});
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
|
||||
const lang = 'pt';
|
||||
const langFull = 'portuguese';
|
||||
|
||||
readDirP({
|
||||
root: path.resolve(__dirname, './english')
|
||||
}).on('data', translateChallenge);
|
||||
|
||||
async function translateChallenge(file) {
|
||||
const { name, fullPath, fullParentDir, stat } = file;
|
||||
if (stat.isDirectory() || name === '.DS_Store' || file.depth === 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pathIndex = fullPath.indexOf('guide') + 6;
|
||||
const outputDir =
|
||||
fullParentDir.substring(0, pathIndex) +
|
||||
`${langFull}/` +
|
||||
fullParentDir.substring(pathIndex + 8);
|
||||
const outputPath =
|
||||
fullPath.substring(0, pathIndex) +
|
||||
`${langFull}/` +
|
||||
fullPath.substring(pathIndex + 8);
|
||||
if (fs.existsSync(outputPath)) {
|
||||
return null;
|
||||
}
|
||||
fs.ensureDirSync(outputDir);
|
||||
|
||||
const fileString = fs.readFileSync(fullPath).toString();
|
||||
var i = fileString.indexOf('---', 4);
|
||||
const meta = fileString.substring(0, i + 4);
|
||||
const title = fileString.split('\n')[1].split(': ')[1];
|
||||
var article = fileString.substring(i + 4);
|
||||
|
||||
var htmlArticle = converter.makeHtml(article);
|
||||
htmlArticle = htmlArticle.replace(/\n/g, '<br>');
|
||||
htmlArticle = htmlArticle.replace(
|
||||
/ {8}/g,
|
||||
' '
|
||||
);
|
||||
htmlArticle = htmlArticle.replace(/ {4}/g, ' ');
|
||||
htmlArticle = htmlArticle.replace(/ {2}/g, ' ');
|
||||
return Promise.all([translateText(title), translateText(htmlArticle)]).then(
|
||||
function(translations) {
|
||||
// Replace English with translation
|
||||
let translatedTitle = translations[0][0];
|
||||
let tempArticle = translations[1][0];
|
||||
tempArticle = tempArticle.replace(/<br>/g, '\n');
|
||||
tempArticle = tempArticle.replace(/'/g, "'");
|
||||
|
||||
tempArticle = tempArticle.replace(
|
||||
/language-html">/g,
|
||||
'language-html">\n'
|
||||
);
|
||||
tempArticle = tempArticle.replace(/<pre> <code/g, '<pre><code');
|
||||
tempArticle = tempArticle.replace(/<\/pre> <\/code/g, '</pre></code');
|
||||
tempArticle = tempArticle.replace(/ /g, ' ');
|
||||
let translatedArticle = turndownService.turndown(tempArticle);
|
||||
translatedArticle = translatedArticle.replace(/\n\n\`\`\`\n/g, '\n```\n');
|
||||
let translatedFile =
|
||||
meta.slice(0, i) +
|
||||
`localeTitle: ${translatedTitle}\n` +
|
||||
meta.slice(i) +
|
||||
translatedArticle;
|
||||
|
||||
writeFile(translatedFile, outputPath);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const createTranslateText = target => text => {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
const translate = new Translate();
|
||||
|
||||
return translate
|
||||
.translate(text, target)
|
||||
.then(results => {
|
||||
let translations = results[0];
|
||||
translations = Array.isArray(translations)
|
||||
? translations
|
||||
: [translations];
|
||||
return translations;
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const translateText = createTranslateText(lang);
|
||||
|
||||
function writeFile(fileString, outputPath) {
|
||||
fs.writeFile(outputPath, fileString, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
console.log('Saved:' + outputPath);
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user