From 755e44bf4c218e8792db26f14b0538e7e80efe22 Mon Sep 17 00:00:00 2001 From: Randell Dawson Date: Tue, 6 Nov 2018 23:04:43 -0800 Subject: [PATCH] add: adding all files --- .gitignore | 4 + addLabels.js | 21 + constants.js | 9 + failuresToFind.json | 14 + fileFunctions.js | 16 + findFailures.js | 75 ++++ getOpenPrs.js | 45 +++ getStatuses.js | 11 + labelOpenPrs.js | 70 ++++ octokitConfig.js | 17 + openPrStats.js | 44 +++ package-lock.json | 927 ++++++++++++++++++++++++++++++++++++++++++++ paginate.js | 14 + prOpenClose.js | 14 + prProcessingLog.js | 48 +++ validLabels.js | 10 + 16 files changed, 1339 insertions(+) create mode 100644 .gitignore create mode 100644 addLabels.js create mode 100644 constants.js create mode 100644 failuresToFind.json create mode 100644 fileFunctions.js create mode 100644 findFailures.js create mode 100644 getOpenPrs.js create mode 100644 getStatuses.js create mode 100644 labelOpenPrs.js create mode 100644 octokitConfig.js create mode 100644 openPrStats.js create mode 100644 package-lock.json create mode 100644 paginate.js create mode 100644 prOpenClose.js create mode 100644 prProcessingLog.js create mode 100644 validLabels.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..c9833ca59d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# dotenv environment variables file +.env +node_modules/ +data/ diff --git a/addLabels.js b/addLabels.js new file mode 100644 index 0000000000..6889799d24 --- /dev/null +++ b/addLabels.js @@ -0,0 +1,21 @@ +require('dotenv').config(); +const { owner, repo } = require('./constants'); +const { octokitConfig, octokitAuth } = require('./octokitConfig'); +const octokit = require('@octokit/rest')(octokitConfig); + +octokit.authenticate(octokitAuth); + +const addLabels = (number, labels, log) => { + octokit.issues.addLabels({ owner, repo, number, labels }) + .then(() => { + log.update(number, true); + console.log(`PR #${number} added ${JSON.stringify(labels)}\n`); + }) + .catch((err) => { + console.log(`PR #${number} had an error when trying to label with ${JSON.stringify(labels)}\n`); + console.log(err) + log.finish() + }) +}; + +exports.addLabels = addLabels; diff --git a/constants.js b/constants.js new file mode 100644 index 0000000000..ea94130e19 --- /dev/null +++ b/constants.js @@ -0,0 +1,9 @@ +const owner = 'freeCodeCamp'; +const repo = 'freeCodeCamp'; +const fccBaseUrl = `https://github.com/${owner}/${repo}/`; +const prBaseUrl = `${fccBaseUrl}pull/`; + +exports.owner = owner; +exports.repo = repo; +exports.fccBaseUrl = fccBaseUrl; +exports.prBaseUrl = prBaseUrl; diff --git a/failuresToFind.json b/failuresToFind.json new file mode 100644 index 0000000000..504e057a13 --- /dev/null +++ b/failuresToFind.json @@ -0,0 +1,14 @@ +[ + { + "error": "missing script: test-ci", + "regex": "/missing script: test-ci/i" + }, + { + "error": "lerna ERR! npm ci exited 1 in '@freecodecamp/api-server", + "regex": "lerna ERR! npm ci exited 1 in '@freecodecamp\/api-server'" + } + { + "error": "localStorage is not available for opaque origins", + "regex": "/localStorage is not available for opaque origins/i" + } +] diff --git a/fileFunctions.js b/fileFunctions.js new file mode 100644 index 0000000000..38b026d0b3 --- /dev/null +++ b/fileFunctions.js @@ -0,0 +1,16 @@ +const fs = require('fs'); + +const saveToFile = (fileName, data) => { + fs.writeFile(fileName, data, err => { + if (err) { return console.log(err) } + }); +} + +const openJSONFile = fileName => { + const data = JSON.parse(fs.readFileSync(fileName, 'utf8')); + console.log('Opened JSON file') + return data; +}; + +exports.saveToFile = saveToFile; +exports.openJSONFile = openJSONFile; diff --git a/findFailures.js b/findFailures.js new file mode 100644 index 0000000000..4fe5df6ed7 --- /dev/null +++ b/findFailures.js @@ -0,0 +1,75 @@ +require('dotenv').config(); +const { owner, repo, fccBaseUrl, prBaseUrl } = require('./constants'); +const fs = require('fs'); +const { octokitConfig, octokitAuth } = require('./octokitConfig'); +const octokit = require('@octokit/rest')(octokitConfig); +const { paginate } = require('./paginate'); +const { saveToFile, writeToFile } = './fileFunctions'; +const fetch = require('node-fetch'); +const { getStatuses } = require('./getStatuses'); + +octokit.authenticate(octokitAuth); + +const findFailures = async (errorsToFind, maxPrs) => { + const methodProps = { + owner, repo, + state: 'open', base: 'master', sort: 'created', + direction: 'asc', page: 1, per_page: 100 + }; + if (maxPRs) { + maxPages = Math.ceil(maxPrs / 100); // limits + } + + const allOpenPRs = await paginate(octokit.pullRequests.getAll, methodProps, octokit, maxPages); + + const failedPRs = allOpenPRs.reduce(async (prevPromise, { number: pr, head: { sha: ref }) => { + const failed = await prevPromise; + const statuses = await getStatuses(octokit.repos.getStatuses, {owner, repo, ref}); + if (statuses.length) { + const { state, target_url } = statuses[0]; // first element contain most recent status + const hasProblem = state === 'failure' || state === 'error'; + if (hasProblem) { + let buildNum = Number(target_url.match(/\/builds\/(\d+)\?/i)[1]); + buildNum++; // full build log file is 1 # higher than buildNum (same as job number) + const travisLogUrl = `https://api.travis-ci.org/v3/job/${buildNum}/log.txt`; + errorsToFind.forEach(async ({ errorDesc, errorRegex }) => { + const response = await fetch(travisLogUrl) + const logText = await response.text(); + if (errorRegex.test(logText)) { + failed.push({ + errorDesc, + pr, + buildLog: buildNum + }) + } + }); + } + } + return failed; + }, Promise.resolve([])); + + return failedPRs; +}; + +/* Main Program */ +const [ n, f, inputFile, outputFile, maxPRs ] = process.argv; +const inputFileMsg = 'Please specify an input file containing errors to find.\n'; +const outputFileMsg = 'Please specify an output file to save the results of the search.\n'; +const maxPRMsg = 'Please specify an integer from 1-4500 (inclusive) for the max # of PR to search.'; +let errors = ''; +if (!inputFile) { errors += inputFileMsg } +if (!outputFile) { errors += outputFileMsg } +if (!maxPRs || parseInt(maxPRs) < 1 || parseInt(maxPRs) > 4500) { + errors += maxPRMsg; +} + +if (errors) { return console.log(errors) } + +fs.readFile(inputFile, 'utf8', (err, errorsToFind) => { + if (err) { throw err } + findFailures(errorsToFind, maxPRs) + .then((failedPRs) => { + saveToFile(outputFile, JSON.stringify(failedPRs)); + console.log(`# PRs matching specified error: ${failedPRs.length}`); + }) +}); diff --git a/getOpenPrs.js b/getOpenPrs.js new file mode 100644 index 0000000000..a4c6e21675 --- /dev/null +++ b/getOpenPrs.js @@ -0,0 +1,45 @@ +require('dotenv').config(); +const { owner, repo } = require('./constants'); +const fs = require('fs'); +const { saveToFile } = require('./fileFunctions'); +const { octokitConfig, octokitAuth } = require('./octokitConfig'); +const octokit = require('@octokit/rest')(octokitConfig); +const { paginate } = require('./paginate'); +const { getOpenPrRange } = require('./openPrStats'); + +octokit.authenticate(octokitAuth); + +(async () => { + let [ n, f, startingPR ] = process.argv; + + let [ firstPR, lastPR ] = await getOpenPrRange().then(data => data); + if (startingPR) { + startingPR = parseInt(startingPR); + if (startingPR < firstPR) { + throw `Starting PR # can not be less than first open PR # (${firstPR})`; + } + firstPR = startingPR + } + + const methodProps = { + owner, repo, state: 'open', + base: 'master', sort: 'created', + direction: 'asc', page: 1, per_page: 100 + }; + + console.log(`Retrieving PRs (starting at #${firstPR}) ...`); + const openPRs = await paginate(octokit.pullRequests.getAll, methodProps, octokit); + if (startingPR) { + openPRs = openPRs.filter(pr => pr.number >= startingPR); + } + + return { firstPR, lastPR, openPRs } +})() +.then(data => { + console.log(`# of PRs Retrieved: ${data.openPRs.length}`); + console.log(`PR Range: ${data.firstPR} - ${data.lastPR}`); + saveToFile('data/open-prs.json', JSON.stringify(data)); +}) +.catch(err => { + console.log(err); +}) diff --git a/getStatuses.js b/getStatuses.js new file mode 100644 index 0000000000..1b7e918ead --- /dev/null +++ b/getStatuses.js @@ -0,0 +1,11 @@ +require('dotenv').config(); +const { owner, repo } = require('./constants'); +const { octokitConfig, octokitAuth } = require('./octokitConfig'); +const octokit = require('@octokit/rest')(octokitConfig); + +octokit.authenticate(octokitAuth); + +exports.getStatuses = async function getStatuses (method, methodProps) { + const { data } = await method(methodProps); + return data +} diff --git a/labelOpenPrs.js b/labelOpenPrs.js new file mode 100644 index 0000000000..ec020693b7 --- /dev/null +++ b/labelOpenPrs.js @@ -0,0 +1,70 @@ +require('dotenv').config(); +const { owner, repo, fccBaseUrl, prBaseUrl } = require('./constants'); +const fs = require('fs'); +const { saveToFile, openJSONFile } = require('./fileFunctions'); +const { octokitConfig, octokitAuth } = require('./octokitConfig'); +const octokit = require('@octokit/rest')(octokitConfig); +const { validLabels } = require('./validLabels'); +const { addLabels } = require('./addLabels'); + +octokit.authenticate(octokitAuth); + +const labelsAdder = (number, existingLabels, labelsToAdd, log) => { + const newLabels = Object.keys(labelsToAdd).filter(label => !existingLabels.includes(label)); + if (newLabels.length) { + addLabels(number, newLabels, log); + } + else { + log.update(number, false); + } +}; + +const { PrProcessingLog } = require('./prProcessingLog'); +const log = new PrProcessingLog(); + +(async () => { + let [ n, f, fileName ] = process.argv; + const openPRs = openJSONFile(fileName); + log.start(); + const { openPRs: prs } = openPRs; + + console.log('Starting labeling process ...'); + const maxCount = 50; + let count = 0 + let interval = setInterval(async () => { + const { number, labels } = prs[count]; + if (count < maxCount ) { + const { data: prFiles } = await octokit.pullRequests.getFiles({ owner, repo, number }); + log.add(number) + const existingLabels = labels.map(({ name }) => name); + /* holds potential labels to add based on file path */ + const labelsToAdd = {}; + prFiles.forEach(({ filename }) => { + /* remove '/challenges' from filename so variable second (below) will be the language */ + const filenameReplacement = filename.replace(/^curriculum\/challenges\//, 'curriculum\/'); + const regex = /^(docs|curriculum|guide)(?:\/)(arabic|chinese|portuguese|russian|spanish)?\/?/ + const [ _, first, second ] = filenameReplacement.match(regex) || []; // need an array to pass to labelsAdder + if (first && validLabels[first]) { labelsToAdd[validLabels[first]] = 1 } + if (second && validLabels[second]) { labelsToAdd[validLabels[second]] = 1 } + }) + labelsAdder(number, existingLabels, labelsToAdd, log); + } + else { + clearInterval(interval); + interval = null; + log.export(); + } + if (count % 25 === 0) { + log.export(); + } + count++; + }, 1500); +})() +.then(() => { + log.finish(); + console.log('Successfully completed labeling'); +}) +.catch(err => { + log.finish(); + console.log(err) +}) diff --git a/octokitConfig.js b/octokitConfig.js new file mode 100644 index 0000000000..ce5b47c219 --- /dev/null +++ b/octokitConfig.js @@ -0,0 +1,17 @@ +exports.octokitConfig = { + timeout: 0, // 0 means no request timeout + headers: { + accept: 'application/vnd.github.v3+json', + 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version + }, + // custom GitHub Enterprise URL + baseUrl: 'https://api.github.com', + // Node only: advanced request options can be passed as http(s) agent + agent: undefined +} + +exports.octokitAuth = { + type: 'basic', + username: process.env.myUN, + password: process.env.myPW +} diff --git a/openPrStats.js b/openPrStats.js new file mode 100644 index 0000000000..4b5b917256 --- /dev/null +++ b/openPrStats.js @@ -0,0 +1,44 @@ +require('dotenv').config(); +const { owner, repo } = require('./constants'); +const { octokitConfig, octokitAuth } = require('./octokitConfig'); +const octokit = require('@octokit/rest')(octokitConfig); + +octokit.authenticate(octokitAuth); + +const getOpenPrCount = async () => { + const { data } = await octokit.search.issues({ + q: 'repo:freeCodeCamp/freeCodeCamp+is:open+type:pr+base:master', + sort: 'created', order: 'asc', page: 1, per_page: 1 + }); + return data.length; +}; + +const getFirstPr = async () => { + const state = `open`; + const base = 'master'; + const sort = 'created'; + const page = 1; + const per_page = 1; + let methodProps = {owner, repo, state, base, sort, direction: 'asc', page, per_page}; + let response = await octokit.pullRequests.getAll(methodProps); + return response.data[0].number; +}; + +const getOpenPrRange = async () => { + const state = `open`; + const base = 'master'; + const sort = 'created'; + const page = 1; + const per_page = 1; + let methodProps = {owner, repo, state, base, sort, direction: 'asc', page, per_page}; + let response = await octokit.pullRequests.getAll(methodProps); + const firstPR = response.data[0].number; + methodProps = {owner, repo, state, base, sort, direction: 'desc', page, per_page}; + response = await octokit.pullRequests.getAll(methodProps); + const lastPR = response.data[0].number; + return [firstPR, lastPR]; +}; + +exports.getOpenPrCount = getOpenPrCount; +exports.getFirstPr = getFirstPr; +exports.getOpenPrRange = getOpenPrRange; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..22c2285448 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,927 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@octokit/rest": { + "version": "15.15.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.15.1.tgz", + "integrity": "sha512-TnuzjE880qbknEFAVqEr3VeOcE0yXo0kJEW+EK8TASpzMbykKCydei6WUmDSV3bq7aI+llkMrBYes1kIjpU7fA==", + "requires": { + "before-after-hook": "^1.1.0", + "btoa-lite": "^1.0.0", + "debug": "^3.1.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.0", + "lodash": "^4.17.4", + "node-fetch": "^2.1.1", + "universal-user-agent": "^2.0.0", + "url-template": "^2.0.8" + } + }, + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.18.0", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "before-after-hook": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.2.0.tgz", + "integrity": "sha512-wI3QtdLppHNkmM1VgRVLCrlWCKk/YexlPicYbXPs4eYdd1InrUCTFsx5bX1iUQzzMsoRXXPpM1r+p7JEJJydag==" + }, + "bluebird": { + "version": "2.11.0", + "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "bottleneckp": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/bottleneckp/-/bottleneckp-1.1.3.tgz", + "integrity": "sha1-oD6pBgCVGusJzACW7QnmVYLZY9k=" + }, + "bson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + }, + "btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "charset-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/charset-parser/-/charset-parser-0.2.0.tgz", + "integrity": "sha1-IwkBCI9fbLFlmotaqtJXLbenW2s=" + }, + "cheerio": { + "version": "0.22.0", + "resolved": "http://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "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=" + }, + "crawler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/crawler/-/crawler-1.2.0.tgz", + "integrity": "sha512-94q3NfQi9dsPFBcizfwNEhMOAVRgjpTRZcf/BbNh571X6OWXgArCJ2oKPr3MSAi5vNSu06UDrXN/grfVmf5cFw==", + "requires": { + "bottleneckp": "~1.1.3", + "charset-parser": "^0.2.0", + "cheerio": "^0.22.0", + "iconv-lite": "^0.4.8", + "lodash": "^4.17.10", + "request": "~2.87.0", + "seenreq": "^0.1.7", + "type-is": "^1.6.14" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz", + "integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "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" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + } + } + }, + "domelementtype": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.2.1.tgz", + "integrity": "sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dotenv": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.1.0.tgz", + "integrity": "sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw==" + }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "es6-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "flexbuffer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flexbuffer/-/flexbuffer-0.0.6.tgz", + "integrity": "sha1-A5/fI/iCPkQMOPMnfm/vEXQhWzA=" + }, + "follow-redirects": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz", + "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "htmlparser2": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz", + "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==", + "requires": { + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.0.6" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.0", + "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" + } + } + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ioredis": { + "version": "1.15.1", + "resolved": "http://registry.npmjs.org/ioredis/-/ioredis-1.15.1.tgz", + "integrity": "sha1-UlJVzM1Ve904oO00ZhmfWesLnRw=", + "requires": { + "bluebird": "^2.9.34", + "debug": "^2.2.0", + "double-ended-queue": "^2.1.0-0", + "flexbuffer": "0.0.6", + "lodash": "^3.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "js-crawler": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/js-crawler/-/js-crawler-0.3.21.tgz", + "integrity": "sha512-T/UgXlaikrSLEaKfpLUqJuO2DJZ4wF9i5oZxG6os96hGk/Wr/8PIBFKQmOAIWKx4MIjt1sxrFwDnHVvfbAqAjw==", + "requires": { + "request": "~2.87.0", + "underscore": "~1.8.3" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "macos-release": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-1.1.0.tgz", + "integrity": "sha512-mmLbumEYMi5nXReB9js3WGsB8UE6cDBWyIO62Z4DNx6GbRhDxHNjA1MlzSpJ2S2KM1wyiPRA0d19uHWYYvMHjA==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "requires": { + "mime-db": "~1.37.0" + } + }, + "mongodb": { + "version": "2.2.36", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz", + "integrity": "sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.20", + "readable-stream": "2.2.7" + }, + "dependencies": { + "es6-promise": { + "version": "3.2.1", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "mongodb-core": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz", + "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node-fetch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" + }, + "node-url-utils": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-url-utils/-/node-url-utils-0.4.0.tgz", + "integrity": "sha1-4qEOfdqq4FEiNGTMewPSHulcrxU=" + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "os-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-2.0.1.tgz", + "integrity": "sha1-uaOGNhwXrjohc27wWZQFyajF3F4=", + "requires": { + "macos-release": "^1.0.0", + "win-release": "^1.0.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "readable-stream": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz", + "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + } + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "seenreq": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/seenreq/-/seenreq-0.1.14.tgz", + "integrity": "sha1-+/GZO9mjFUnWDIW+PWIsMrZOuKA=", + "requires": { + "ioredis": "^1.8.0", + "mongodb": "^2.2.23", + "node-url-utils": "^0.4.0", + "utils-merge": "^1.0.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "sshpk": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "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" + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "universal-user-agent": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.0.1.tgz", + "integrity": "sha512-vz+heWVydO0iyYAa65VHD7WZkYzhl7BeNVy4i54p4TF8OMiLSXdbuQe4hm+fmWAsL+rVibaQHXfhvkw3c1Ws2w==", + "requires": { + "os-name": "^2.0.1" + } + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "win-release": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", + "integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=", + "requires": { + "semver": "^5.0.1" + } + } + } +} diff --git a/paginate.js b/paginate.js new file mode 100644 index 0000000000..7acc0555f0 --- /dev/null +++ b/paginate.js @@ -0,0 +1,14 @@ +exports.paginate = async function paginate (method, methodProps, octokit, maxPages = 10000) { + let response = await method(methodProps); + let { data } = response; + let pageNum = 1; + while (octokit.hasNextPage(response) && pageNum < maxPages) { + response = await octokit.getNextPage(response); + data = data.concat(response.data); + if (pageNum % 5 === 0) { + console.log(`page #${pageNum}`); + } + pageNum++; + } + return data; +} diff --git a/prOpenClose.js b/prOpenClose.js new file mode 100644 index 0000000000..a2cb37da7d --- /dev/null +++ b/prOpenClose.js @@ -0,0 +1,14 @@ +const prOpenClose = async () => { + const result = await octokit.pullRequests.update({ owner, repo , number, state: 'closed', base }) + .then(() => { + return octokit.pullRequests.update({ owner, repo , number, state: 'open', base }) + }) + .then(() => { + log.update(true) + }) + .catch(() => { + log.update(false) + }) +}; + +exports.changePrState = changePrState; diff --git a/prProcessingLog.js b/prProcessingLog.js new file mode 100644 index 0000000000..5819d90b1b --- /dev/null +++ b/prProcessingLog.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const { saveToFile } = require('./fileFunctions'); + +class PrProcessingLog { + constructor() { + this._start = null, + this._lastUpdate = null, + this._lastPRlogged = null, + this._finish = null, + this._prs = {} + this._logfile = 'data/open-prs-processed.json' + } + + import() { + return JSON.parse(fs.readFileSync(this._logfile, 'utf8')); + } + + export() { + let sortedPRs = Object.keys(this._prs) + .sort((a, b) => a - b) + .map(num => ({ [num]: this._prs[num] })); + const log = { + start: this._start, + finish: this._finish, + prs: sortedPRs + }; + saveToFile(this._logfile, JSON.stringify(log)) + } + + add(prNum) { + this._prs[prNum] = null; + } + + update(prNum, status) { + this._prs[prNum] = status; + } + + start() { + this._start = new Date(); + } + + finish() { + this._finish = new Date(); + this.export(); + } +}; + +exports.PrProcessingLog = PrProcessingLog; diff --git a/validLabels.js b/validLabels.js new file mode 100644 index 0000000000..508e8e41ae --- /dev/null +++ b/validLabels.js @@ -0,0 +1,10 @@ +exports.validLabels = { + arabic: 'language: Arabic', + chinese: 'language: Chinese', + portuguese: 'language: Portuguese', + russian: 'language: Russian', + spanish: 'language: Spanish', + curriculum: 'scope: curriculum', + docs: 'scope: documentation', + guide: 'scope: guide' +};