diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..2c3d6b04 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +lib/ot +public/vendor +public/build diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..b826a37b --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,21 @@ +module.exports = { + "root": true, + "extends": "standard", + "env": { + "node": true + }, + "rules": { + // at some point all of these should return to their default "error" state + // but right now, this is not a good choice, because too many places are + // wrong. + "import/first": ["warn"], + "indent": ["warn"], + "no-multiple-empty-lines": ["warn"], + "no-multi-spaces": ["warn"], + "object-curly-spacing": ["warn"], + "one-var": ["warn"], + "quotes": ["warn"], + "semi": ["warn"], + "space-infix-ops": ["warn"] + } +}; diff --git a/README.md b/README.md index 938ba71d..6adb93d5 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ CodiMD === -[![Standard - JavaScript Style Guide][standardjs-image]][standardjs-url] - [![#CodiMD on matrix.org][matrix.org-image]][matrix.org-url] [![build status][travis-image]][travis-url] [![version][github-version-badge]][github-release-page] @@ -373,7 +371,5 @@ See more at [http://operational-transformation.github.io/](http://operational-tr [travis-url]: https://travis-ci.org/hackmdio/codimd [github-version-badge]: https://img.shields.io/github/release/hackmdio/codimd.svg [github-release-page]: https://github.com/hackmdio/codimd/releases -[standardjs-image]: https://cdn.rawgit.com/feross/standard/master/badge.svg -[standardjs-url]: https://github.com/feross/standard [poeditor-image]: https://img.shields.io/badge/POEditor-translate-blue.svg [poeditor-url]: https://poeditor.com/join/project/1OpGjF2Jir diff --git a/lib/models/index.js b/lib/models/index.js index 0a44ca87..ef70475e 100644 --- a/lib/models/index.js +++ b/lib/models/index.js @@ -25,6 +25,7 @@ if (config.dbURL) { // https://github.com/sequelize/sequelize/issues/6485 function stripNullByte (value) { value = '' + value + // eslint-disable-next-line no-control-regex return value ? value.replace(/\u0000/g, '') : value } sequelize.stripNullByte = stripNullByte diff --git a/lib/models/user.js b/lib/models/user.js index 1bd8c745..2ebf6d06 100644 --- a/lib/models/user.js +++ b/lib/models/user.js @@ -50,7 +50,7 @@ module.exports = function (sequelize, DataTypes) { }, { instanceMethods: { verifyPassword: function (attempt) { - if (scrypt.verifyKdfSync(new Buffer(this.password, 'hex'), attempt)) { + if (scrypt.verifyKdfSync(Buffer.from(this.password, 'hex'), attempt)) { return this } else { return false diff --git a/lib/realtime.js b/lib/realtime.js index 8541bafa..d04ffdc2 100644 --- a/lib/realtime.js +++ b/lib/realtime.js @@ -242,6 +242,7 @@ function getStatus (callback) { } }) models.User.count().then(function (regcount) { + // eslint-disable-next-line standard/no-callback-literal return callback ? callback({ onlineNotes: Object.keys(notes).length, onlineUsers: Object.keys(users).length, @@ -283,7 +284,7 @@ function extractNoteIdFromSocket (socket) { if (!referer) { return false } - var hostUrl = url.parse(referer) + var hostUrl = url.URL.parse(referer) var noteId = config.urlPath ? hostUrl.pathname.slice(config.urlPath.length + 1, hostUrl.pathname.length).split('/')[1] : hostUrl.pathname.split('/')[1] return noteId } else { diff --git a/lib/web/imageRouter/filesystem.js b/lib/web/imageRouter/filesystem.js index 8c432b0c..a2f8700d 100644 --- a/lib/web/imageRouter/filesystem.js +++ b/lib/web/imageRouter/filesystem.js @@ -16,5 +16,5 @@ exports.uploadImage = function (imagePath, callback) { return } - callback(null, url.resolve(config.serverURL + '/uploads/', path.basename(imagePath))) + callback(null, url.URL.resolve(config.serverURL + '/uploads/', path.basename(imagePath))) } diff --git a/package.json b/package.json index cd875ac6..bba1e36f 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "main": "app.js", "license": "AGPL-3.0", "scripts": { - "test": "npm run-script standard && npm run-script jsonlint", + "test": "npm run-script eslint && npm run-script jsonlint", + "eslint": "node_modules/.bin/eslint lib public app.js", "jsonlint": "find . -not -path './node_modules/*' -type f -name '*.json' -o -type f -name '*.json.example' | while read json; do echo $json ; jq . $json; done", - "standard": "node ./node_modules/standard/bin/cmd.js", + "standard": "echo 'standard is no longer being used, use `npm run eslint` instead!' && exit 1", "dev": "webpack --config webpack.dev.js --progress --colors --watch", "build": "webpack --config webpack.prod.js --progress --colors --bail", "postinstall": "bin/heroku", @@ -169,6 +170,12 @@ "css-loader": "^1.0.0", "doctoc": "^1.3.0", "ejs-loader": "^0.3.1", + "eslint": "^5.9.0", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-node": "^8.0.0", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-standard": "^4.0.0", "exports-loader": "^0.7.0", "expose-loader": "^0.7.5", "file-loader": "^2.0.0", @@ -180,7 +187,6 @@ "mini-css-extract-plugin": "^0.4.1", "optimize-css-assets-webpack-plugin": "^5.0.0", "script-loader": "^0.7.2", - "standard": "^9.0.1", "string-loader": "^0.0.1", "style-loader": "^0.21.0", "uglifyjs-webpack-plugin": "^1.2.7", @@ -190,34 +196,6 @@ "webpack-merge": "^4.1.4", "webpack-parallel-uglify-plugin": "^1.1.0" }, - "standard": { - "globals": [ - "$", - "CodeMirror", - "Cookies", - "moment", - "editor", - "ui", - "Spinner", - "modeType", - "Idle", - "serverurl", - "key", - "gapi", - "Dropbox", - "FilePicker", - "ot", - "MediaUploader", - "hex2rgb", - "num_loaded", - "Visibility", - "inlineAttachment" - ], - "ignore": [ - "lib/ot", - "public/vendor" - ] - }, "optionalDependencies": { "bufferutil": "^4.0.0", "utf-8-validate": "^5.0.1" diff --git a/public/.eslintrc.js b/public/.eslintrc.js new file mode 100644 index 00000000..dc37b3cb --- /dev/null +++ b/public/.eslintrc.js @@ -0,0 +1,28 @@ +// this config file is used in concert with the root .eslintrc.js in the root dir. +module.exports = { + "env": { + "browser": true + }, + "globals": { + "$": false, + "CodeMirror": false, + "Cookies": false, + "moment": false, + "editor": false, + "ui": false, + "Spinner": false, + "modeType": false, + "Idle": false, + "serverurl": false, + "key": false, + "gapi": false, + "Dropbox": false, + "FilePicker": false, + "ot": false, + "MediaUploader": false, + "hex2rgb": false, + "num_loaded": false, + "Visibility": false, + "inlineAttachment": false + } +}; diff --git a/public/js/history.js b/public/js/history.js index b4c26b42..6007bef4 100644 --- a/public/js/history.js +++ b/public/js/history.js @@ -218,6 +218,7 @@ export function getStorageHistory (callback) { if (typeof data === 'string') { data = JSON.parse(data) } callback(data) } + // eslint-disable-next-line standard/no-callback-literal callback([]) } diff --git a/public/js/index.js b/public/js/index.js index 98c3b6d2..0c575961 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -2511,7 +2511,9 @@ function buildCursor (user) { // editor actions function removeNullByte (cm, change) { var str = change.text.join('\n') + // eslint-disable-next-line no-control-regex if (/\u0000/g.test(str) && change.update) { + // eslint-disable-next-line no-control-regex change.update(change.from, change.to, str.replace(/\u0000/g, '').split('\n')) } } @@ -3046,7 +3048,7 @@ function checkInCode () { function checkAbove (method) { var cursor = editor.getCursor() var text = [] - for (var i = 0; i < cursor.line; i++) { // contain current line + for (var i = 0; i < cursor.line; i++) { // contain current line text.push(editor.getLine(i)) } text = text.join('\n') + '\n' + editor.getLine(cursor.line).slice(0, cursor.ch) diff --git a/public/js/lib/editor/index.js b/public/js/lib/editor/index.js index 0537e927..f05d01b8 100644 --- a/public/js/lib/editor/index.js +++ b/public/js/lib/editor/index.js @@ -492,7 +492,7 @@ export default class Editor { clearInterval(spellcheckTimer) } }, - 100, + 100 ) } } @@ -514,7 +514,7 @@ export default class Editor { } setOverrideBrowserKeymap () { var overrideBrowserKeymap = $( - '.ui-preferences-override-browser-keymap label > input[type="checkbox"]', + '.ui-preferences-override-browser-keymap label > input[type="checkbox"]' ) if (overrideBrowserKeymap.is(':checked')) { Cookies.set('preferences-override-browser-keymap', true, { @@ -529,10 +529,10 @@ export default class Editor { setPreferences () { var overrideBrowserKeymap = $( - '.ui-preferences-override-browser-keymap label > input[type="checkbox"]', + '.ui-preferences-override-browser-keymap label > input[type="checkbox"]' ) var cookieOverrideBrowserKeymap = Cookies.get( - 'preferences-override-browser-keymap', + 'preferences-override-browser-keymap' ) if (cookieOverrideBrowserKeymap && cookieOverrideBrowserKeymap === 'true') { overrideBrowserKeymap.prop('checked', true) diff --git a/public/js/lib/editor/ui-elements.js b/public/js/lib/editor/ui-elements.js index ca06d30c..29a37782 100644 --- a/public/js/lib/editor/ui-elements.js +++ b/public/js/lib/editor/ui-elements.js @@ -67,7 +67,7 @@ export const getUIElements = () => ({ codemirrorScroll: $('.ui-edit-area .CodeMirror .CodeMirror-scroll'), codemirrorSizer: $('.ui-edit-area .CodeMirror .CodeMirror-sizer'), codemirrorSizerInner: $( - '.ui-edit-area .CodeMirror .CodeMirror-sizer > div', + '.ui-edit-area .CodeMirror .CodeMirror-sizer > div' ), markdown: $('.ui-view-area .markdown-body'), resize: {