From 668bd74690b7d110334b1e3d93188fe48c7c8e48 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Thu, 23 Jun 2016 20:05:30 -0700 Subject: [PATCH] Fix(lint): Add import eslint and fix import errors --- .eslintrc | 26 +++- client/rechallenge/transformers.js | 2 + client/sagas/frame-saga.js | 2 + client/sagas/hard-go-to-saga.js | 3 +- client/sagas/window-saga.js | 3 +- common/app/redux/actions.js | 1 + common/app/redux/entities-reducer.js | 6 +- common/app/redux/fetch-user-saga.js | 4 +- common/app/redux/index.js | 8 +- .../challenges/components/project/Forms.jsx | 3 +- .../challenges/redux/fetch-challenges-saga.js | 12 +- common/app/routes/challenges/redux/index.js | 8 +- .../challenges/redux/next-challenge-saga.js | 4 +- common/models/User-Identity.js | 2 +- package.json | 1 + server/boot/randomAPIs.js | 12 +- server/boot/user.js | 8 +- server/debug-entry.js | 1 + server/middlewares/cookie-parser.js | 4 +- server/middlewares/jade-helpers.js | 2 + server/middlewares/sessions.js | 7 +- server/passport-providers.js | 3 +- server/production-start.js | 1 + server/server.js | 1 + server/utils/commit.js | 2 +- server/utils/constants.js | 2 +- server/utils/index.js | 119 +++--------------- 27 files changed, 103 insertions(+), 144 deletions(-) diff --git a/.eslintrc b/.eslintrc index c943753581f..e435aa4148d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,8 +13,19 @@ }, "parser": "babel-eslint", "plugins": [ - "react" + "react", + "import" ], + "settings": { + "import/ignore": [ + "node_modules", + "\\.json$" + ], + "import/extensions": [ + ".js", + ".jsx" + ] + }, "globals": { "Promise": true, "window": true, @@ -223,9 +234,9 @@ "no-bitwise": 2, "no-plusplus": 0, + "jsx-quotes": [2, "prefer-single"], "react/display-name": 2, "react/jsx-boolean-value": [2, "always"], - "jsx-quotes": [2, "prefer-single"], "react/jsx-no-undef": 2, "react/jsx-sort-props": [2, { "ignoreCase": true }], "react/jsx-uses-react": 2, @@ -237,6 +248,15 @@ "react/react-in-jsx-scope": 2, "react/self-closing-comp": 2, "react/wrap-multilines": 2, - "react/jsx-closing-bracket-location": [ 2, { "selfClosing": "line-aligned", "nonEmpty": "props-aligned" } ] + "react/jsx-closing-bracket-location": [ 2, { "selfClosing": "line-aligned", "nonEmpty": "props-aligned" } ], + + "import/no-unresolved": 2, + "import/named": 2, + "import/namespace": 2, + "import/default": 2, + "import/export": 2, + "import/imports-first": 2, + "import/no-duplicates": 2, + "import/newline-after-import": 2 } } diff --git a/client/rechallenge/transformers.js b/client/rechallenge/transformers.js index 932d4c1eb36..e7993c5f6dd 100644 --- a/client/rechallenge/transformers.js +++ b/client/rechallenge/transformers.js @@ -1,5 +1,7 @@ import { Observable } from 'rx'; +/* eslint-disable import/no-unresolved */ import loopProtect from 'loop-protect'; +/* eslint-enable import/no-unresolved */ import { updateContents } from '../../common/utils/polyvinyl'; diff --git a/client/sagas/frame-saga.js b/client/sagas/frame-saga.js index e35d28b15b0..c9acf2f0ae0 100644 --- a/client/sagas/frame-saga.js +++ b/client/sagas/frame-saga.js @@ -1,5 +1,7 @@ import Rx, { Observable, Subject } from 'rx'; +/* eslint-disable import/no-unresolved */ import loopProtect from 'loop-protect'; +/* eslint-enable import/no-unresolved */ import types from '../../common/app/routes/challenges/redux/types'; import { updateOutput, diff --git a/client/sagas/hard-go-to-saga.js b/client/sagas/hard-go-to-saga.js index b3c9a8a3a72..1d967a265d0 100644 --- a/client/sagas/hard-go-to-saga.js +++ b/client/sagas/hard-go-to-saga.js @@ -1,5 +1,6 @@ -import { hardGoTo } from '../../common/app/redux/types'; +import types from '../../common/app/redux/types'; +const { hardGoTo } = types; export default function hardGoToSaga(action$, getState, { history }) { return action$ .filter(({ type }) => type === hardGoTo) diff --git a/client/sagas/window-saga.js b/client/sagas/window-saga.js index add0d4102c8..0e3302186d5 100644 --- a/client/sagas/window-saga.js +++ b/client/sagas/window-saga.js @@ -1,7 +1,8 @@ import { Observable } from 'rx'; -import { initWindowHeight } from '../../common/app/redux/types'; +import types from '../../common/app/redux/types'; import { updateWindowHeight } from '../../common/app/redux/actions'; +const { initWindowHeight } = types; function getWindowSize(document, window) { const body = document.getElementsByTagName('body')[0]; return window.innerHeight || diff --git a/common/app/redux/actions.js b/common/app/redux/actions.js index 734f568f995..4be119253c1 100644 --- a/common/app/redux/actions.js +++ b/common/app/redux/actions.js @@ -32,6 +32,7 @@ export const addUser = createAction( entities => ({ entities }) ); export const updateThisUser = createAction(types.updateThisUser); +export const showSignIn = createAction(types.showSignIn); // updateUserPoints(username: String, points: Number) => Action export const updateUserPoints = createAction( diff --git a/common/app/redux/entities-reducer.js b/common/app/redux/entities-reducer.js index 8bb0a508a09..979fb7ca980 100644 --- a/common/app/redux/entities-reducer.js +++ b/common/app/redux/entities-reducer.js @@ -1,8 +1,6 @@ -import { - updateUserPoints, - updateCompletedChallenges -} from './types'; +import types from './types'; +const { updateUserPoints, updateCompletedChallenges } = types; const initialState = { superBlock: {}, block: {}, diff --git a/common/app/redux/fetch-user-saga.js b/common/app/redux/fetch-user-saga.js index 3bcaf28f431..ba2f6cbc4ee 100644 --- a/common/app/redux/fetch-user-saga.js +++ b/common/app/redux/fetch-user-saga.js @@ -1,5 +1,5 @@ import { Observable } from 'rx'; -import { fetchUser } from './types'; +import types from './types'; import { addUser, updateThisUser, @@ -8,6 +8,8 @@ import { showSignIn } from './actions'; +const { fetchUser } = types; + export default function getUserSaga(action$, getState, { services }) { return action$ .filter(action => action.type === fetchUser) diff --git a/common/app/redux/index.js b/common/app/redux/index.js index d0e8381658d..90d8e67847d 100644 --- a/common/app/redux/index.js +++ b/common/app/redux/index.js @@ -1,6 +1,6 @@ -export { default as reducer } from './reducer'; -export { default as actions } from './actions'; -export { default as types } from './types'; - import fetchUserSaga from './fetch-user-saga'; + +export { default as reducer } from './reducer'; +export * as actions from './actions'; +export { default as types } from './types'; export const sagas = [ fetchUserSaga ]; diff --git a/common/app/routes/challenges/components/project/Forms.jsx b/common/app/routes/challenges/components/project/Forms.jsx index 3e0bde0b49b..84edbc6eea3 100644 --- a/common/app/routes/challenges/components/project/Forms.jsx +++ b/common/app/routes/challenges/components/project/Forms.jsx @@ -1,5 +1,5 @@ import React, { PropTypes } from 'react'; -import { resetForm, reduxForm } from 'redux-form'; +import { reduxForm } from 'redux-form'; import { Button, FormGroup, @@ -25,7 +25,6 @@ const propTypes = { }; const bindableActions = { - resetForm, submitChallenge, showProjectSubmit }; diff --git a/common/app/routes/challenges/redux/fetch-challenges-saga.js b/common/app/routes/challenges/redux/fetch-challenges-saga.js index 51e8c899114..30ae7506100 100644 --- a/common/app/routes/challenges/redux/fetch-challenges-saga.js +++ b/common/app/routes/challenges/redux/fetch-challenges-saga.js @@ -1,10 +1,6 @@ import { Observable } from 'rx'; import { challengeSelector } from './selectors'; -import { - fetchChallenge, - fetchChallenges, - replaceChallenge -} from './types'; +import types from './types'; import { fetchChallengeCompleted, fetchChallengesCompleted, @@ -13,9 +9,11 @@ import { } from './actions'; import { delayedRedirect, - createErrorObserable + createErrorObservable } from '../../../redux/actions'; +const { fetchChallenge, fetchChallenges, replaceChallenge } = types; + function createNameIdMap(entities) { const { challenge } = entities; return { @@ -77,6 +75,6 @@ export default function fetchChallengesSaga(action$, getState, { services }) { initMap(entities, result), ); }) - .catch(createErrorObserable); + .catch(createErrorObservable); }); } diff --git a/common/app/routes/challenges/redux/index.js b/common/app/routes/challenges/redux/index.js index 5d0fc7cc672..ffb98e4e478 100644 --- a/common/app/routes/challenges/redux/index.js +++ b/common/app/routes/challenges/redux/index.js @@ -1,12 +1,12 @@ -export actions from './actions'; -export reducer from './reducer'; -export types from './types'; - import fetchChallengesSaga from './fetch-challenges-saga'; import completionSaga from './completion-saga'; import nextChallengeSaga from './next-challenge-saga'; import answerSaga from './answer-saga'; +export * as actions from './actions'; +export reducer from './reducer'; +export types from './types'; + export projectNormalizer from './project-normalizer'; export const sagas = [ diff --git a/common/app/routes/challenges/redux/next-challenge-saga.js b/common/app/routes/challenges/redux/next-challenge-saga.js index bb2daacd9be..d8008aaa9d6 100644 --- a/common/app/routes/challenges/redux/next-challenge-saga.js +++ b/common/app/routes/challenges/redux/next-challenge-saga.js @@ -1,6 +1,6 @@ import { Observable } from 'rx'; import { push } from 'react-router-redux'; -import { moveToNextChallenge } from './types'; +import types from './types'; import { resetUi, updateCurrentChallenge } from './actions'; import { createErrorObservable, makeToast } from '../../../redux/actions'; import { @@ -10,6 +10,8 @@ import { } from '../utils'; import { randomVerb } from '../../../utils/get-words'; +const { moveToNextChallenge } = types; + export default function nextChallengeSaga(actions$, getState) { return actions$ .filter(({ type }) => type === moveToNextChallenge) diff --git a/common/models/User-Identity.js b/common/models/User-Identity.js index 5293dfbc482..962fe0dc16e 100644 --- a/common/models/User-Identity.js +++ b/common/models/User-Identity.js @@ -7,8 +7,8 @@ import { getUsernameFromProvider, getSocialProvider } from '../../server/utils/auth'; +import { defaultProfileImage } from '../utils/constantStrings.json'; -const { defaultProfileImage } = require('../utils/constantStrings.json'); const githubRegex = (/github/i); const debug = debugFactory('fcc:models:userIdent'); diff --git a/package.json b/package.json index 3b44b07a152..25728f9d706 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,7 @@ "chunk-manifest-webpack-plugin": "0.1.0", "del": "^2.2.0", "eslint": "^3.1.0", + "eslint-plugin-import": "^1.9.2", "eslint-plugin-react": "^5.1.1", "gulp": "^3.9.0", "gulp-babel": "^6.1.1", diff --git a/server/boot/randomAPIs.js b/server/boot/randomAPIs.js index 1423ca9d5c2..3f516a2fb99 100644 --- a/server/boot/randomAPIs.js +++ b/server/boot/randomAPIs.js @@ -1,7 +1,9 @@ import request from 'request'; import constantStrings from '../utils/constantStrings.json'; import testimonials from '../resources/testimonials.json'; -import secrets from '../../config/secrets'; + +const githubClient = process.env.GITHUB_ID; +const githubSecret = process.env.GITHUB_SECRET; module.exports = function(app) { const router = app.loopback.Router(); @@ -258,9 +260,9 @@ module.exports = function(app) { [ 'https://api.github.com/repos/freecodecamp/', 'freecodecamp/pulls?client_id=', - secrets.github.clientID, + githubClient, '&client_secret=', - secrets.github.clientSecret + githubSecret ].join(''), githubHeaders, function(err, status1, pulls) { @@ -273,9 +275,9 @@ module.exports = function(app) { [ 'https://api.github.com/repos/freecodecamp/', 'freecodecamp/issues?client_id=', - secrets.github.clientID, + githubClient, '&client_secret=', - secrets.github.clientSecret + githubSecret ].join(''), githubHeaders, function(err, status2, issues) { diff --git a/server/boot/user.js b/server/boot/user.js index 18c13119a14..19c7d8cc765 100644 --- a/server/boot/user.js +++ b/server/boot/user.js @@ -12,7 +12,11 @@ import { import certTypes from '../utils/certTypes.json'; -import { ifNoUser401, ifNoUserRedirectTo } from '../utils/middleware'; +import { + ifNoUser401, + ifNoUserRedirectTo, + flashIfNotVerified +} from '../utils/middleware'; import { observeQuery } from '../utils/rx'; import { prepUniqueDays, @@ -20,8 +24,6 @@ import { calcLongestStreak } from '../utils/user-stats'; -import { flashIfNotVerified } from '../utils/middleware'; - const debug = debugFactory('fcc:boot:user'); const sendNonUserToMap = ifNoUserRedirectTo('/map'); const certIds = { diff --git a/server/debug-entry.js b/server/debug-entry.js index fba89b55124..f0e969a841c 100644 --- a/server/debug-entry.js +++ b/server/debug-entry.js @@ -2,4 +2,5 @@ // or mocha. require('babel-register'); var app = require('./server'); + app.start(); diff --git a/server/middlewares/cookie-parser.js b/server/middlewares/cookie-parser.js index a991b5dc7e4..4bcb0cde79c 100644 --- a/server/middlewares/cookie-parser.js +++ b/server/middlewares/cookie-parser.js @@ -1,4 +1,4 @@ import cookieParser from 'cookie-parser'; -import secrets from '../../config/secrets'; -export default cookieParser.bind(cookieParser, secrets.cookieSecret); +const cookieSecret = process.env.COOKIE_SECRET; +export default cookieParser.bind(cookieParser, cookieSecret); diff --git a/server/middlewares/jade-helpers.js b/server/middlewares/jade-helpers.js index d1331a35fad..f7672ef9c6a 100644 --- a/server/middlewares/jade-helpers.js +++ b/server/middlewares/jade-helpers.js @@ -1,5 +1,7 @@ import manifest from '../rev-manifest'; +/* eslint-disable import/default */ import config from '../../webpack.config'; +/* eslint-enable import/default */ let chunkManifest; try { diff --git a/server/middlewares/sessions.js b/server/middlewares/sessions.js index afd8516720f..313f06d6085 100644 --- a/server/middlewares/sessions.js +++ b/server/middlewares/sessions.js @@ -1,8 +1,9 @@ import session from 'express-session'; import MongoStoreFactory from 'connect-mongo'; -import secrets from '../../config/secrets'; const MongoStore = MongoStoreFactory(session); +const sessionSecret = process.env.SESSION_SECRET; +const url = process.env.MONGODB || process.env.MONGOHQ_URL; export default function sessionsMiddleware() { return session({ @@ -10,7 +11,7 @@ export default function sessionsMiddleware() { cookie: { maxAge: 900 * 24 * 60 * 60 * 1000 }, resave: true, saveUninitialized: true, - secret: secrets.sessionSecret, - store: new MongoStore({ url: secrets.db }) + secret: sessionSecret, + store: new MongoStore({ url }) }); } diff --git a/server/passport-providers.js b/server/passport-providers.js index 6103a56eaa0..f5d1a28ddad 100644 --- a/server/passport-providers.js +++ b/server/passport-providers.js @@ -1,7 +1,8 @@ var successRedirect = '/'; var failureRedirect = '/signin'; var linkFailureRedirect = '/account'; -module.exports = { + +export default { local: { provider: 'local', module: 'passport-local', diff --git a/server/production-start.js b/server/production-start.js index 1de0abcc293..9c6d393b973 100644 --- a/server/production-start.js +++ b/server/production-start.js @@ -5,6 +5,7 @@ var startTime = Date.now(); var timeoutHandler; // this is where server starts booting up var app = require('./server'); + console.log('waiting for db to connect'); diff --git a/server/server.js b/server/server.js index 33ea75461a3..56afcfabb54 100755 --- a/server/server.js +++ b/server/server.js @@ -1,5 +1,6 @@ require('dotenv').load(); var pmx = require('pmx'); + pmx.init(); var _ = require('lodash'), diff --git a/server/utils/commit.js b/server/utils/commit.js index 0a9474c40ab..a7f5d2ba7be 100644 --- a/server/utils/commit.js +++ b/server/utils/commit.js @@ -1,8 +1,8 @@ import dedent from 'dedent'; import debugFactory from 'debug'; import { Observable } from 'rx'; - import commitGoals from './commit-goals.json'; + const debug = debugFactory('fcc:utils/commit'); export { commitGoals }; diff --git a/server/utils/constants.js b/server/utils/constants.js index 49055b3477c..37c1f6fc5f3 100644 --- a/server/utils/constants.js +++ b/server/utils/constants.js @@ -1,4 +1,4 @@ -exports.blacklistedUsernames = [ +export const blacklistedUsernames = [ 'bonfire', 'account', 'user', diff --git a/server/utils/index.js b/server/utils/index.js index 8f3a80c66de..4b107169087 100644 --- a/server/utils/index.js +++ b/server/utils/index.js @@ -1,101 +1,22 @@ -var cheerio = require('cheerio'), - request = require('request'), - MDNlinks = require('../../seed/bonfireMDNlinks'), - resources = require('./resources.json'); +export function dasherize(name) { + return ('' + name) + .toLowerCase() + .replace(/\s/g, '-') + .replace(/[^a-z0-9\-\.]/gi, '') + .replace(/\:/g, ''); +} -/** - * Cached values - */ +export function nameify(str) { + return ('' + str) + .replace(/[^a-zA-Z0-9\s]/g, '') + .replace(/\:/g, ''); +} -module.exports = { - dasherize: function dasherize(name) { - return ('' + name) - .toLowerCase() - .replace(/\s/g, '-') - .replace(/[^a-z0-9\-\.]/gi, '') - .replace(/\:/g, ''); - }, - - nameify: function nameify(str) { - return ('' + str) - .replace(/[^a-zA-Z0-9\s]/g, '') - .replace(/\:/g, ''); - }, - - unDasherize: function unDasherize(name) { - return ('' + name) - // replace dash with space - .replace(/\-/g, ' ') - // strip nonalphanumarics chars except whitespace - .replace(/[^a-zA-Z\d\s]/g, '') - .trim(); - }, - - randomPhrase: function() { - return resources.phrases[ - Math.floor(Math.random() * resources.phrases.length) - ]; - }, - - randomVerb: function() { - return resources.verbs[ - Math.floor(Math.random() * resources.verbs.length) - ]; - }, - - randomCompliment: function() { - return resources.compliments[ - Math.floor(Math.random() * resources.compliments.length) - ]; - }, - - whichEnvironment: function() { - return process.env.NODE_ENV; - }, - - getURLTitle: function(url, callback) { - var result = { - title: '', - image: '', - url: '', - description: '' - }; - request(url, function(err, response, body) { - if (err || response.statusCode !== 200) { - return callback(new Error('failed')); - } - var $ = cheerio.load(body); - var metaDescription = $("meta[name='description']"); - var metaImage = $("meta[property='og:image']"); - var urlImage = metaImage.attr('content') ? - metaImage.attr('content') : - ''; - - var metaTitle = $('title'); - var description = metaDescription.attr('content') ? - metaDescription.attr('content') : - ''; - - result.title = metaTitle.text().length < 90 ? - metaTitle.text() : - metaTitle.text().slice(0, 87) + '...'; - - result.image = urlImage; - result.description = description; - return callback(null, result); - }); - }, - - getMDNLinks: function(links) { - if (!links) { - return []; - } - // takes in an array of links, which are strings - - // for each key value, push the corresponding link - // from the MDNlinks object into a new array - return links.map(function(value) { - return MDNlinks[value]; - }); - } -}; +export function unDasherize(name) { + return ('' + name) + // replace dash with space + .replace(/\-/g, ' ') + // strip nonalphanumarics chars except whitespace + .replace(/[^a-zA-Z\d\s]/g, '') + .trim(); +}