diff --git a/.eslintrc-frontend.yml b/.eslintrc-frontend.yml deleted file mode 100644 index da884feae6..0000000000 --- a/.eslintrc-frontend.yml +++ /dev/null @@ -1,36 +0,0 @@ -env: - browser: true - -plugins: - - import - - react-hooks - -parser: '@typescript-eslint/parser' - -parserOptions: - sourceType: 'module' - -extends: - - 'standard-jsx' - - 'standard-react' - - './.eslintrc.yml' - - 'plugin:@typescript-eslint/recommended' - - 'prettier/@typescript-eslint' - -settings: - react: - version: '16.8' - -rules: - no-console: 'error' - - import/extensions: ['error', 'never', { 'json': 'always', 'yml': 'always' }] - react/jsx-sort-props: 'error' - react-hooks/rules-of-hooks: 'error' - react-hooks/exhaustive-deps: 'error' - - '@typescript-eslint/no-unused-vars': ['error', { 'args': 'none' }] - - # Argh. - '@typescript-eslint/explicit-function-return-type': 'off' - '@typescript-eslint/no-object-literal-type-assertion': 'off' diff --git a/.eslintrc.yml b/.eslintrc.yml index 0a28589d78..aefc96002c 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,22 +1,65 @@ extends: - - standard - - prettier + - standard-jsx + - standard-react - plugin:jsdoc/recommended - -env: - node: true - mocha: true + - plugin:@typescript-eslint/recommended + - prettier/@typescript-eslint + - prettier/standard parserOptions: # Override eslint-config-standard, which incorrectly sets this to "module", # though that setting is only for ES6 modules, not CommonJS modules. sourceType: 'script' +settings: + react: + version: '16.8' + +plugins: + - chai-friendly + - jsdoc + - mocha + - no-extension-in-require + - sort-class-members + - import + - react-hooks + - promise + overrides: + # For simplicity's sake, when possible prefer to add rules to the top-level + # list of rules, even if they only apply to certain files. That way the + # rules listed here are only ones which conflict. + - files: - - gatsby-browser.js + - '**/*.js' + - '!frontend/**/*.js' + env: + node: true + rules: + no-console: 'off' + '@typescript-eslint/no-var-requires': off + + - files: + - '**/*.@(ts|tsx)' parserOptions: sourceType: 'module' + parser: '@typescript-eslint/parser' + rules: + # Argh. + '@typescript-eslint/explicit-function-return-type': 'off' + '@typescript-eslint/no-object-literal-type-assertion': 'off' + + - files: + - gatsby-browser.js + - 'frontend/**/*.@(js|ts|tsx)' + parserOptions: + sourceType: 'module' + env: + browser: true + rules: + import/extensions: + ['error', 'never', { 'json': 'always', 'yml': 'always' }] + - files: - 'core/base-service/**/*.js' - 'services/**/*.js' @@ -44,25 +87,29 @@ overrides: }, ] -plugins: - - chai-friendly - - jsdoc - - mocha - - no-extension-in-require - - sort-class-members + - files: + - '**/*.spec.@(js|ts|tsx)' + - '**/*.integration.js' + env: + mocha: true + rules: + mocha/no-exclusive-tests: 'error' + mocha/no-mocha-arrows: 'error' + mocha/prefer-arrow-callback: 'error' rules: # Disable some rules from eslint:recommended. - no-console: 'off' no-empty: ['error', { 'allowEmptyCatch': true }] + # Allow unused parameters. In callbacks, removing them seems to obscure # what the functions are doing. - no-unused-vars: ['error', { 'args': 'none' }] + '@typescript-eslint/no-unused-vars': ['error', { 'args': 'none' }] + no-unused-vars: off + + '@typescript-eslint/no-var-requires': error # These should be disabled by eslint-config-prettier, but are not. spaced-comment: 'off' - standard/object-curly-even-spacing: 'off' - one-var: 'off' # Shields additions. no-var: 'error' @@ -77,14 +124,17 @@ rules: new-cap: ['error', { 'capIsNew': true }] import/order: ['error', { 'newlines-between': 'never' }] - # Mocha-related. - mocha/no-exclusive-tests: 'error' - mocha/no-mocha-arrows: 'error' - mocha/prefer-arrow-callback: 'error' - # Chai friendly. no-unused-expressions: 'off' chai-friendly/no-unused-expressions: 'error' # Disable some rules from jsdoc/recommended. - jsdoc/require-jsdoc: 0 + jsdoc/require-jsdoc: off + + # Disable some from TypeScript. + '@typescript-eslint/camelcase': off + + react/jsx-sort-props: 'error' + react-hooks/rules-of-hooks: 'error' + react-hooks/exhaustive-deps: 'error' + jsx-quotes: ['error', 'prefer-double'] diff --git a/core/base-service/lru-cache.js b/core/base-service/lru-cache.js index 7a4788dd97..3aacf7277d 100644 --- a/core/base-service/lru-cache.js +++ b/core/base-service/lru-cache.js @@ -7,6 +7,23 @@ const typeEnum = { heap: 1, } +// In bytes. +let heapSize +function computeHeapSize() { + return (heapSize = process.memoryUsage().heapTotal) +} + +let heapSizeTimeout +function getHeapSize() { + if (heapSizeTimeout == null) { + // Compute the heap size every 60 seconds. + heapSizeTimeout = setInterval(computeHeapSize, 60 * 1000) + return computeHeapSize() + } else { + return heapSize + } +} + function CacheSlot(key, value) { this.key = key this.value = value @@ -116,20 +133,4 @@ Cache.prototype = { }, } -// In bytes. -let heapSize -let heapSizeTimeout -function getHeapSize() { - if (heapSizeTimeout == null) { - // Compute the heap size every 60 seconds. - heapSizeTimeout = setInterval(computeHeapSize, 60 * 1000) - return computeHeapSize() - } else { - return heapSize - } -} -function computeHeapSize() { - return (heapSize = process.memoryUsage().heapTotal) -} - module.exports = Cache diff --git a/core/server/secret-is-valid.js b/core/server/secret-is-valid.js index 49cdc27dcd..d0846a061a 100644 --- a/core/server/secret-is-valid.js +++ b/core/server/secret-is-valid.js @@ -2,13 +2,6 @@ const serverSecrets = require('../../lib/server-secrets') -function secretIsValid(secret = '') { - return ( - serverSecrets.shields_secret && - constEq(secret, serverSecrets.shields_secret) - ) -} - function constEq(a, b) { if (a.length !== b.length) { return false @@ -20,4 +13,9 @@ function constEq(a, b) { return zero === 0 } -module.exports = secretIsValid +module.exports = function secretIsValid(secret = '') { + return ( + serverSecrets.shields_secret && + constEq(secret, serverSecrets.shields_secret) + ) +} diff --git a/frontend/.eslintrc.yml b/frontend/.eslintrc.yml deleted file mode 100644 index e3f319d833..0000000000 --- a/frontend/.eslintrc.yml +++ /dev/null @@ -1 +0,0 @@ -extends: '../.eslintrc-frontend.yml' diff --git a/services/color-formatters.js b/services/color-formatters.js index 479cf7447f..ce9fa6e78b 100644 --- a/services/color-formatters.js +++ b/services/color-formatters.js @@ -22,14 +22,6 @@ function version(version) { } } -function downloadCount(downloads) { - return floorCount(downloads, 10, 100, 1000) -} - -function coveragePercentage(percentage) { - return floorCount(percentage, 80, 90, 100) -} - function floorCount(value, yellow, yellowgreen, green) { if (value <= 0) { return 'red' @@ -44,6 +36,14 @@ function floorCount(value, yellow, yellowgreen, green) { } } +function downloadCount(downloads) { + return floorCount(downloads, 10, 100, 1000) +} + +function coveragePercentage(percentage) { + return floorCount(percentage, 80, 90, 100) +} + function letterScore(score) { if (score === 'A') { return 'brightgreen' diff --git a/services/jsdelivr/jsdelivr-hits-github.service.js b/services/jsdelivr/jsdelivr-hits-github.service.js index fcffb66419..881f99f034 100644 --- a/services/jsdelivr/jsdelivr-hits-github.service.js +++ b/services/jsdelivr/jsdelivr-hits-github.service.js @@ -2,7 +2,7 @@ const { schema, periodMap, BaseJsDelivrService } = require('./jsdelivr-base') -module.exports = class jsDelivrHitsGitHub extends BaseJsDelivrService { +module.exports = class JsDelivrHitsGitHub extends BaseJsDelivrService { static get route() { return { base: 'jsdelivr/gh', diff --git a/services/jsdelivr/jsdelivr-hits-npm.service.js b/services/jsdelivr/jsdelivr-hits-npm.service.js index 96a5787fde..87af8aca11 100644 --- a/services/jsdelivr/jsdelivr-hits-npm.service.js +++ b/services/jsdelivr/jsdelivr-hits-npm.service.js @@ -2,7 +2,7 @@ const { schema, periodMap, BaseJsDelivrService } = require('./jsdelivr-base') -module.exports = class jsDelivrHitsNPM extends BaseJsDelivrService { +module.exports = class JsDelivrHitsNPM extends BaseJsDelivrService { static get route() { return { base: 'jsdelivr/npm', diff --git a/services/version.js b/services/version.js index b1d61191dc..e13623f3fb 100644 --- a/services/version.js +++ b/services/version.js @@ -11,6 +11,61 @@ const semver = require('semver') const { addv } = require('./text-formatters') const { version: versionColor } = require('./color-formatters') +function listCompare(a, b) { + const alen = a.length, + blen = b.length + for (let i = 0; i < alen; i++) { + if (a[i] < b[i]) { + return -1 + } else if (a[i] > b[i]) { + return 1 + } + } + return alen - blen +} + +// Take string versions. +// -1 if v1 < v2, 1 if v1 > v2, 0 otherwise. +function compareDottedVersion(v1, v2) { + const parts1 = /([0-9.]+)(.*)$/.exec(v1) + const parts2 = /([0-9.]+)(.*)$/.exec(v2) + if (parts1 != null && parts2 != null) { + const numbers1 = parts1[1] + const numbers2 = parts2[1] + const distinguisher1 = parts1[2] + const distinguisher2 = parts2[2] + const numlist1 = numbers1.split('.').map(e => +e) + const numlist2 = numbers2.split('.').map(e => +e) + const cmp = listCompare(numlist1, numlist2) + if (cmp !== 0) { + return cmp + } else { + return distinguisher1 < distinguisher2 + ? -1 + : distinguisher1 > distinguisher2 + ? 1 + : 0 + } + } + return v1 < v2 ? -1 : v1 > v2 ? 1 : 0 +} + +// Take a list of string versions. +// Return the latest, or undefined, if there are none. +function latestDottedVersion(versions) { + const len = versions.length + if (len === 0) { + return + } + let version = versions[0] + for (let i = 1; i < len; i++) { + if (compareDottedVersion(version, versions[i]) < 0) { + version = versions[i] + } + } + return version +} + // Given a list of versions (as strings), return the latest version. // Return undefined if no version could be found. function latest(versions, { pre = false } = {}) { @@ -45,63 +100,6 @@ function latest(versions, { pre = false } = {}) { return version } -function listCompare(a, b) { - const alen = a.length, - blen = b.length - for (let i = 0; i < alen; i++) { - if (a[i] < b[i]) { - return -1 - } else if (a[i] > b[i]) { - return 1 - } - } - return alen - blen -} - -// === Private helper functions === - -// Take a list of string versions. -// Return the latest, or undefined, if there are none. -function latestDottedVersion(versions) { - const len = versions.length - if (len === 0) { - return - } - let version = versions[0] - for (let i = 1; i < len; i++) { - if (compareDottedVersion(version, versions[i]) < 0) { - version = versions[i] - } - } - return version -} - -// Take string versions. -// -1 if v1 < v2, 1 if v1 > v2, 0 otherwise. -function compareDottedVersion(v1, v2) { - const parts1 = /([0-9.]+)(.*)$/.exec(v1) - const parts2 = /([0-9.]+)(.*)$/.exec(v2) - if (parts1 != null && parts2 != null) { - const numbers1 = parts1[1] - const numbers2 = parts2[1] - const distinguisher1 = parts1[2] - const distinguisher2 = parts2[2] - const numlist1 = numbers1.split('.').map(e => +e) - const numlist2 = numbers2.split('.').map(e => +e) - const cmp = listCompare(numlist1, numlist2) - if (cmp !== 0) { - return cmp - } else { - return distinguisher1 < distinguisher2 - ? -1 - : distinguisher1 > distinguisher2 - ? 1 - : 0 - } - } - return v1 < v2 ? -1 : v1 > v2 ? 1 : 0 -} - // Slice the specified number of dotted parts from the given semver version. // e.g. slice('2.4.7', 'minor') -> '2.4' function slice(v, releaseType) {