reactioncommerce/redoc

View on GitHub
packages/redoc-core/server/methods/getRepoToc.js

Summary

Maintainability
C
1 day
Test Coverage

Function getRepoToc has a Cognitive Complexity of 42 (exceeds 5 allowed). Consider refactoring.
Open

function getRepoToc(repo, fetchBranch, path) {
  this.unblock();
  check(repo, String);
  check(fetchBranch,  Match.Optional(String, null));
  check(path,  Match.Optional(String, null));
Severity: Minor
Found in packages/redoc-core/server/methods/getRepoToc.js - About 6 hrs to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Function getRepoToc has 68 lines of code (exceeds 25 allowed). Consider refactoring.
Open

function getRepoToc(repo, fetchBranch, path) {
  this.unblock();
  check(repo, String);
  check(fetchBranch,  Match.Optional(String, null));
  check(path,  Match.Optional(String, null));
Severity: Major
Found in packages/redoc-core/server/methods/getRepoToc.js - About 2 hrs to fix

    Unexpected console statement.
    Open

        console.log(`redoc/getRepoTOC: Failed to load repo data for ${repo}`);

    disallow the use of console (no-console)

    In JavaScript that is designed to be executed in the browser, it's considered a best practice to avoid using methods on console. Such messages are considered to be for debugging purposes and therefore not suitable to ship to the client. In general, calls using console should be stripped before being pushed to production.

    console.log("Made it here.");
    console.error("That shouldn't have happened.");

    Rule Details

    This rule disallows calls to methods of the console object.

    Examples of incorrect code for this rule:

    /*eslint no-console: "error"*/
    
    console.log("Log a debug level message.");
    console.warn("Log a warn level message.");
    console.error("Log an error level message.");

    Examples of correct code for this rule:

    /*eslint no-console: "error"*/
    
    // custom console
    Console.log("Hello world!");

    Options

    This rule has an object option for exceptions:

    • "allow" has an array of strings which are allowed methods of the console object

    Examples of additional correct code for this rule with a sample { "allow": ["warn", "error"] } option:

    /*eslint no-console: ["error", { allow: ["warn", "error"] }] */
    
    console.warn("Log a warn level message.");
    console.error("Log an error level message.");

    When Not To Use It

    If you're using Node.js, however, console is used to output information to the user and so is not strictly used for debugging purposes. If you are developing for Node.js then you most likely do not want this rule enabled.

    Related Rules

    Unexpected assignment within an 'if' statement.
    Open

            if (matches = tocItem.name.match(/^(\d+)/)) {

    disallow assignment operators in conditional statements (no-cond-assign)

    In conditional statements, it is very easy to mistype a comparison operator (such as ==) as an assignment operator (such as =). For example:

    // Check the user's job title
    if (user.jobTitle = "manager") {
        // user.jobTitle is now incorrect
    }

    There are valid reasons to use assignment operators in conditional statements. However, it can be difficult to tell whether a specific assignment was intentional.

    Rule Details

    This rule disallows ambiguous assignment operators in test conditions of if, for, while, and do...while statements.

    Options

    This rule has a string option:

    • "except-parens" (default) allows assignments in test conditions only if they are enclosed in parentheses (for example, to allow reassigning a variable in the test of a while or do...while loop)
    • "always" disallows all assignments in test conditions

    except-parens

    Examples of incorrect code for this rule with the default "except-parens" option:

    /*eslint no-cond-assign: "error"*/
    
    // Unintentional assignment
    var x;
    if (x = 0) {
        var b = 1;
    }
    
    // Practical example that is similar to an error
    function setHeight(someNode) {
        "use strict";
        do {
            someNode.height = "100px";
        } while (someNode = someNode.parentNode);
    }

    Examples of correct code for this rule with the default "except-parens" option:

    /*eslint no-cond-assign: "error"*/
    
    // Assignment replaced by comparison
    var x;
    if (x === 0) {
        var b = 1;
    }
    
    // Practical example that wraps the assignment in parentheses
    function setHeight(someNode) {
        "use strict";
        do {
            someNode.height = "100px";
        } while ((someNode = someNode.parentNode));
    }
    
    // Practical example that wraps the assignment and tests for 'null'
    function setHeight(someNode) {
        "use strict";
        do {
            someNode.height = "100px";
        } while ((someNode = someNode.parentNode) !== null);
    }

    always

    Examples of incorrect code for this rule with the "always" option:

    /*eslint no-cond-assign: ["error", "always"]*/
    
    // Unintentional assignment
    var x;
    if (x = 0) {
        var b = 1;
    }
    
    // Practical example that is similar to an error
    function setHeight(someNode) {
        "use strict";
        do {
            someNode.height = "100px";
        } while (someNode = someNode.parentNode);
    }
    
    // Practical example that wraps the assignment in parentheses
    function setHeight(someNode) {
        "use strict";
        do {
            someNode.height = "100px";
        } while ((someNode = someNode.parentNode));
    }
    
    // Practical example that wraps the assignment and tests for 'null'
    function setHeight(someNode) {
        "use strict";
        do {
            someNode.height = "100px";
        } while ((someNode = someNode.parentNode) !== null);
    }

    Examples of correct code for this rule with the "always" option:

    /*eslint no-cond-assign: ["error", "always"]*/
    
    // Assignment replaced by comparison
    var x;
    if (x === 0) {
        var b = 1;
    }

    Related Rules

    Expected to return a value at the end of function 'getRepoToc'.
    Open

    function getRepoToc(repo, fetchBranch, path) {

    require return statements to either always or never specify values (consistent-return)

    Unlike statically-typed languages which enforce that a function returns a specified type of value, JavaScript allows different code paths in a function to return different types of values.

    A confusing aspect of JavaScript is that a function returns undefined if any of the following are true:

    • it does not execute a return statement before it exits
    • it executes return which does not specify a value explicitly
    • it executes return undefined
    • it executes return void followed by an expression (for example, a function call)
    • it executes return followed by any other expression which evaluates to undefined

    If any code paths in a function return a value explicitly but some code path do not return a value explicitly, it might be a typing mistake, especially in a large function. In the following example:

    • a code path through the function returns a Boolean value true
    • another code path does not return a value explicitly, therefore returns undefined implicitly
    function doSomething(condition) {
        if (condition) {
            return true;
        } else {
            return;
        }
    }

    Rule Details

    This rule requires return statements to either always or never specify values. This rule ignores function definitions where the name begins with an uppercase letter, because constructors (when invoked with the new operator) return the instantiated object implicitly if they do not return another object explicitly.

    Examples of incorrect code for this rule:

    /*eslint consistent-return: "error"*/
    
    function doSomething(condition) {
        if (condition) {
            return true;
        } else {
            return;
        }
    }
    
    function doSomething(condition) {
        if (condition) {
            return true;
        }
    }

    Examples of correct code for this rule:

    /*eslint consistent-return: "error"*/
    
    function doSomething(condition) {
        if (condition) {
            return true;
        } else {
            return false;
        }
    }
    
    function Foo() {
        if (!(this instanceof Foo)) {
            return new Foo();
        }
    
        this.a = 0;
    }

    Options

    This rule has an object option:

    • "treatUndefinedAsUnspecified": false (default) always either specify values or return undefined implicitly only.
    • "treatUndefinedAsUnspecified": true always either specify values or return undefined explicitly or implicitly.

    treatUndefinedAsUnspecified

    Examples of incorrect code for this rule with the default { "treatUndefinedAsUnspecified": false } option:

    /*eslint consistent-return: ["error", { "treatUndefinedAsUnspecified": false }]*/
    
    function foo(callback) {
        if (callback) {
            return void callback();
        }
        // no return statement
    }
    
    function bar(condition) {
        if (condition) {
            return undefined;
        }
        // no return statement
    }

    Examples of incorrect code for this rule with the { "treatUndefinedAsUnspecified": true } option:

    /*eslint consistent-return: ["error", { "treatUndefinedAsUnspecified": true }]*/
    
    function foo(callback) {
        if (callback) {
            return void callback();
        }
        return true;
    }
    
    function bar(condition) {
        if (condition) {
            return undefined;
        }
        return true;
    }

    Examples of correct code for this rule with the { "treatUndefinedAsUnspecified": true } option:

    /*eslint consistent-return: ["error", { "treatUndefinedAsUnspecified": true }]*/
    
    function foo(callback) {
        if (callback) {
            return void callback();
        }
        // no return statement
    }
    
    function bar(condition) {
        if (condition) {
            return undefined;
        }
        // no return statement
    }

    When Not To Use It

    If you want to allow functions to have different return behavior depending on code branching, then it is safe to disable this rule. Source: http://eslint.org/docs/rules/

    The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.
    Open

          for (const sortIndex in contentData.data) {

    Require Guarding for-in (guard-for-in)

    Looping over objects with a for in loop will include properties that are inherited through the prototype chain. This behavior can lead to unexpected items in your for loop.

    for (key in foo) {
        doSomething(key);
    }

    Note that simply checking foo.hasOwnProperty(key) is likely to cause an error in some cases; see [no-prototype-builtins](no-prototype-builtins.md).

    Rule Details

    This rule is aimed at preventing unexpected behavior that could arise from using a for in loop without filtering the results in the loop. As such, it will warn when for in loops do not filter their results with an if statement.

    Examples of incorrect code for this rule:

    /*eslint guard-for-in: "error"*/
    
    for (key in foo) {
        doSomething(key);
    }

    Examples of correct code for this rule:

    /*eslint guard-for-in: "error"*/
    
    for (key in foo) {
        if (Object.prototype.hasOwnProperty.call(foo, key)) {
            doSomething(key);
        }
        if ({}.hasOwnProperty.call(foo, key)) {
            doSomething(key);
        }
    }

    Related Rules

    • [no-prototype-builtins](no-prototype-builtins.md)

    Further Reading

    Missing radix parameter.
    Open

              sort = parseInt(sortIndex);

    Require Radix Parameter (radix)

    When using the parseInt() function it is common to omit the second argument, the radix, and let the function try to determine from the first argument what type of number it is. By default, parseInt() will autodetect decimal and hexadecimal (via 0x prefix). Prior to ECMAScript 5, parseInt() also autodetected octal literals, which caused problems because many developers assumed a leading 0 would be ignored.

    This confusion led to the suggestion that you always use the radix parameter to parseInt() to eliminate unintended consequences. So instead of doing this:

    var num = parseInt("071");      // 57

    Do this:

    var num = parseInt("071", 10);  // 71

    ECMAScript 5 changed the behavior of parseInt() so that it no longer autodetects octal literals and instead treats them as decimal literals. However, the differences between hexadecimal and decimal interpretation of the first parameter causes many developers to continue using the radix parameter to ensure the string is interpreted in the intended way.

    On the other hand, if the code is targeting only ES5-compliant environments passing the radix 10 may be redundant. In such a case you might want to disallow using such a radix.

    Rule Details

    This rule is aimed at preventing the unintended conversion of a string to a number of a different base than intended or at preventing the redundant 10 radix if targeting modern environments only.

    Options

    There are two options for this rule:

    • "always" enforces providing a radix (default)
    • "as-needed" disallows providing the 10 radix

    always

    Examples of incorrect code for the default "always" option:

    /*eslint radix: "error"*/
    
    var num = parseInt("071");
    
    var num = parseInt(someValue);
    
    var num = parseInt("071", "abc");
    
    var num = parseInt();

    Examples of correct code for the default "always" option:

    /*eslint radix: "error"*/
    
    var num = parseInt("071", 10);
    
    var num = parseInt("071", 8);
    
    var num = parseFloat(someValue);

    as-needed

    Examples of incorrect code for the "as-needed" option:

    /*eslint radix: ["error", "as-needed"]*/
    
    var num = parseInt("071", 10);
    
    var num = parseInt("071", "abc");
    
    var num = parseInt();

    Examples of correct code for the "as-needed" option:

    /*eslint radix: ["error", "as-needed"]*/
    
    var num = parseInt("071");
    
    var num = parseInt("071", 8);
    
    var num = parseFloat(someValue);

    When Not To Use It

    If you don't want to enforce either presence or omission of the 10 radix value you can turn this rule off.

    Further Reading

    Split 'let' declarations into multiple statements.
    Open

            let matches, sort;

    enforce variables to be declared either together or separately in functions (one-var)

    Variables can be declared at any point in JavaScript code using var, let, or const. There are many styles and preferences related to the declaration of variables, and one of those is deciding on how many variable declarations should be allowed in a single function.

    There are two schools of thought in this regard:

    1. There should be just one variable declaration for all variables in the function. That declaration typically appears at the top of the function.
    2. You should use one variable declaration for each variable you want to define.

    For instance:

    // one variable declaration per function
    function foo() {
        var bar, baz;
    }
    
    // multiple variable declarations per function
    function foo() {
        var bar;
        var baz;
    }

    The single-declaration school of thought is based in pre-ECMAScript 6 behaviors, where there was no such thing as block scope, only function scope. Since all var statements are hoisted to the top of the function anyway, some believe that declaring all variables in a single declaration at the top of the function removes confusion around scoping rules.

    Rule Details

    This rule enforces variables to be declared either together or separately per function ( for var) or block (for let and const) scope.

    Options

    This rule has one option, which can be a string option or an object option.

    String option:

    • "always" (default) requires one variable declaration per scope
    • "never" requires multiple variable declarations per scope

    Object option:

    • "var": "always" requires one var declaration per function
    • "var": "never" requires multiple var declarations per function
    • "let": "always" requires one let declaration per block
    • "let": "never" requires multiple let declarations per block
    • "const": "always" requires one const declaration per block
    • "const": "never" requires multiple const declarations per block

    Alternate object option:

    • "initialized": "always" requires one variable declaration for initialized variables per scope
    • "initialized": "never" requires multiple variable declarations for initialized variables per scope
    • "uninitialized": "always" requires one variable declaration for uninitialized variables per scope
    • "uninitialized": "never" requires multiple variable declarations for uninitialized variables per scope

    always

    Examples of incorrect code for this rule with the default "always" option:

    /*eslint one-var: ["error", "always"]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar;
        var baz;
        let qux;
        let norf;
    }
    
    function foo(){
        const bar = false;
        const baz = true;
        let qux;
        let norf;
    }
    
    function foo() {
        var bar;
    
        if (baz) {
            var qux = true;
        }
    }

    Examples of correct code for this rule with the default "always" option:

    /*eslint one-var: ["error", "always"]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar,
            baz;
        let qux,
            norf;
    }
    
    function foo(){
        const bar = true,
            baz = false;
        let qux,
            norf;
    }
    
    function foo() {
        var bar,
            qux;
    
        if (baz) {
            qux = true;
        }
    }
    
    function foo(){
        let bar;
    
        if (baz) {
            let qux;
        }
    }

    never

    Examples of incorrect code for this rule with the "never" option:

    /*eslint one-var: ["error", "never"]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar,
            baz;
        const bar = true,
            baz = false;
    }
    
    function foo() {
        var bar,
            qux;
    
        if (baz) {
            qux = true;
        }
    }
    
    function foo(){
        let bar = true,
            baz = false;
    }

    Examples of correct code for this rule with the "never" option:

    /*eslint one-var: ["error", "never"]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar;
        var baz;
    }
    
    function foo() {
        var bar;
    
        if (baz) {
            var qux = true;
        }
    }
    
    function foo() {
        let bar;
    
        if (baz) {
            let qux = true;
        }
    }

    var, let, and const

    Examples of incorrect code for this rule with the { var: "always", let: "never", const: "never" } option:

    /*eslint one-var: ["error", { var: "always", let: "never", const: "never" }]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar;
        var baz;
        let qux,
            norf;
    }
    
    function foo() {
        const bar = 1,
              baz = 2;
        let qux,
            norf;
    }

    Examples of correct code for this rule with the { var: "always", let: "never", const: "never" } option:

    /*eslint one-var: ["error", { var: "always", let: "never", const: "never" }]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar,
            baz;
        let qux;
        let norf;
    }
    
    function foo() {
        const bar = 1;
        const baz = 2;
        let qux;
        let norf;
    }

    Examples of incorrect code for this rule with the { var: "never" } option:

    /*eslint one-var: ["error", { var: "never" }]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar,
            baz;
    }

    Examples of correct code for this rule with the { var: "never" } option:

    /*eslint one-var: ["error", { var: "never" }]*/
    /*eslint-env es6*/
    
    function foo() {
        var bar,
            baz;
        const bar = 1; // `const` and `let` declarations are ignored if they are not specified
        const baz = 2;
        let qux;
        let norf;
    }

    initialized and uninitialized

    Examples of incorrect code for this rule with the { "initialized": "always", "uninitialized": "never" } option:

    /*eslint one-var: ["error", { "initialized": "always", "uninitialized": "never" }]*/
    /*eslint-env es6*/
    
    function foo() {
        var a, b, c;
        var foo = true;
        var bar = false;
    }

    Examples of correct code for this rule with the { "initialized": "always", "uninitialized": "never" } option:

    /*eslint one-var: ["error", { "initialized": "always", "uninitialized": "never" }]*/
    
    function foo() {
        var a;
        var b;
        var c;
        var foo = true,
            bar = false;
    }
    
    for (let z of foo) {
        doSomething(z);
    }
    
    let z;
    for (z of foo) {
        doSomething(z);
    }

    Examples of incorrect code for this rule with the { "initialized": "never" } option:

    /*eslint one-var: ["error", { "initialized": "never" }]*/
    /*eslint-env es6*/
    
    function foo() {
        var foo = true,
            bar = false;
    }

    Examples of correct code for this rule with the { "initialized": "never" } option:

    /*eslint one-var: ["error", { initialized: "never" }]*/
    
    function foo() {
        var foo = true;
        var bar = false;
        var a, b, c; // Uninitialized variables are ignored
    }

    Compatibility

    There are no issues that match your filters.

    Category
    Status