diff --git a/package-lock.json b/package-lock.json index 251cf8d085..2e095eb43d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3398,6 +3398,12 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=", + "dev": true + }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", @@ -7227,6 +7233,12 @@ "dev": true, "optional": true }, + "nanoid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.0.tgz", + "integrity": "sha512-SG2qscLE3iM4C0CNzGrsAojJHSVHMS1J8NnvJ31P1lH8P0hGHOiafmniNJz6w6q7vuoDlV7RdySlJgtqkFEVtQ==", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -8875,6 +8887,15 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, + "shortid": { + "version": "2.2.14", + "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.14.tgz", + "integrity": "sha512-4UnZgr9gDdA1kaKj/38IiudfC3KHKhDc1zi/HSxd9FQDR0VLwH3/y79tZJLsVYPsJgIjeHjqIWaWVRJUj9qZOQ==", + "dev": true, + "requires": { + "nanoid": "^2.0.0" + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -8908,6 +8929,12 @@ "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", "dev": true }, + "slugg": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/slugg/-/slugg-1.2.1.tgz", + "integrity": "sha1-51KvIkGvPycURjxd4iXOpHYIdAo=", + "dev": true + }, "smart-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", diff --git a/package.json b/package.json index 04d585e0d9..419ee70d5c 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "develop": "npm-run-all -s ensure-env start-develop", "ensure-env": "cross-env DEBUG=fcc:* node ./tools/scripts/ensure-env.js", "lint": "echo 'Warning: TODO - Define Linting with fixing.'", - "seed": "cross-env DEBUG=fcc:* node ./tools/scripts/seed/seedChallenges", + "seed": "npm-run-all -p seed:*", + "seed:challenges": "cross-env DEBUG=fcc:* node ./tools/scripts/seed/seedChallenges", + "seed:news":"cross-env DEBUG=fcc:* node ./tools/scripts/seed/seedNewsArticles", "start-develop": "node ./tools/scripts/start-develop.js", "pretest": "npm-run-all -s test:lint", "test": "npm-run-all -p test:*", @@ -25,12 +27,15 @@ "debug": "^4.0.1", "dotenv": "^6.0.0", "eslint-config-freecodecamp": "^1.1.1", + "faker": "^4.1.0", "gray-matter": "^4.0.1", "jest": "^23.6.0", "lerna": "^3.4.0", "lodash": "^4.17.11", "npm-run-all": "^4.1.3", "readdirp-walk": "^1.6.0", + "slugg": "^1.2.1", + "shortid": "^2.2.14", "tree-kill": "^1.2.0" } } diff --git a/tools/scripts/seed/seedNewsArticles.js b/tools/scripts/seed/seedNewsArticles.js new file mode 100644 index 0000000000..5e4c386d75 --- /dev/null +++ b/tools/scripts/seed/seedNewsArticles.js @@ -0,0 +1,118 @@ +const path = require('path'); +require('dotenv').config({ path: path.resolve(__dirname, '../../../.env') }); +const MongoClient = require('mongodb').MongoClient; +const faker = require('faker'); +const shortId = require('shortid'); +const slugg = require('slugg'); +const { homeLocation } = require('../../../config/env.json'); +const debug = require('debug'); + +const log = debug('fcc:tools:seedNewsArticles'); + +const { MONGOHQ_URL } = process.env; + +function handleError(err, client) { + if (err) { + console.error('Oh noes!!'); + console.error(err); + try { + client.close(); + } catch (e) { + // no-op + } finally { + /* eslint-disable-next-line no-process-exit */ + process.exit(1); + } + } +} + +MongoClient.connect( + MONGOHQ_URL, + { useNewUrlParser: true }, + async function(err, client) { + handleError(err, client); + + log('Connected successfully to mongo'); + const db = client.db('freecodecamp'); + const articleCollection = db.collection('article'); + + const articles = stubArticles(200); + + await articleCollection + .deleteMany({}) + .catch(err => handleError(err, client)); + return articleCollection + .insertMany(articles) + .then(({ insertedCount }) => { + log('inserted %d new articles', insertedCount); + client.close(); + }) + .catch(err => handleError(err, client)); + } +); + +function stubArticles(numberOfArticles = 1) { + return new Array(numberOfArticles).fill('').map(() => generateArticle()); +} + +const sixMonths = 15780000000; + +function generateArticle() { + const now = Date.now(); + const id = shortId.generate(); + const title = faker.lorem.sentence(); + const paragraphs = faker.random.number(10) || 1; + const arrayToLoopOver = new Array(paragraphs).fill(''); + const fakeDate = faker.date.between(new Date(now - sixMonths), new Date(now)); + const fakeDateMs = new Date(fakeDate).getTime(); + return { + shortId: id, + slugPart: slugg(title), + title, + author: { + name: faker.name.findName(), + avatar: faker.internet.avatar(), + twitter: 'https://twitter.com/camperbot', + bio: faker.lorem.sentence(), + username: faker.internet.userName() + }, + featureImage: { + src: faker.image.image(2000, 1300), + alt: faker.lorem.sentence(), + caption: paragraphs >= 5 ? faker.lorem.sentence() : '' + }, + meta: { + readTime: paragraphs, + refLink: `${homeLocation}/n/${id}` + }, + draft: 'this needs to be fixed', + renderableContent: arrayToLoopOver.map( + () => `
${faker.lorem.paragraph()}
` + ), + published: true, + featured: true, + underReview: false, + viewCount: faker.random.number(90000), + firstPublishedDate: fakeDate, + createdDate: fakeDate, + lastEditedDate: fakeDate, + history: [ + { + event: 'created', + timestamp: fakeDateMs + }, + { + event: 'edited', + timestamp: fakeDateMs + }, + { + event: 'publish', + timestamp: fakeDateMs + }, + { + event: 'featured', + timestamp: fakeDateMs + } + ] + }; +}