Coder Social home page Coder Social logo

nodelinter's Introduction

Nodelinter

Static code analyzer for n8n node files
by Iván Ovejero


Nodelinter is a static code analyzer for n8n node files, with ~70 linting rules for:

  • default values based on param type,
  • casing for display names and descriptions,
  • alphabetization for params and options,
  • required and optional key-value pairs,
  • expected values for specific params,
  • etc.

See full lintings list.

Operation

Run via npx:

npx nodelinter --target=/Users/john/n8n/packages/nodes-base/nodes/Stripe/Stripe.node.ts

Or run locally:

git clone https://github.com/n8n-io/nodelinter
cd nodelinter; npm i
npm run lint -- --target=/Users/john/n8n/packages/nodes-base/nodes/Stripe/Stripe.node.ts

Options

Option Effect
--target Path of the file or directory to lint
--config Path of the custom config to use
--print Whether to print output to lintOutput.json
--patterns Lintable file patterns
--errors-only Enable error logs only
--warnings-only Enable warning logs only
--infos-only Enable info logs only

Examples:

# lint a single file
--target=./packages/nodes-base/nodes/Stripe/Stripe.node.ts

# lint all files in a dir
--target=./packages/nodes-base/nodes/Stripe

# use a custom config
--config=/Users/john/Documents/myConfig.json

# print logs to lintOutput.json
--print

# lint files ending with these patterns
--target=./src/input/MyNode --patterns:.node.ts,Description.ts

# lint files ending with this pattern
--target=./src/input/MyNode --patterns:.node.ts

# lint only rules with error classification
--target=./src/input/MyNode --errors-only

Custom config

You can override the Nodelinter default config with a custom config.

To do so, create a JSON file containing any keys to overwrite:

{
  "target": "/Users/john/n8n/packages/nodes-base/nodes/Notion/Notion.node.ts",
  "patterns": [".node.ts"],
  "sortMethod": "lineNumber",
  "lintings": {
    "PARAM_DESCRIPTION_MISSING_WHERE_OPTIONAL": {
      "enabled": false
    },
    "NAME_WITH_NO_CAMELCASE": {
      "enabled": false
    }
  }
}

And use the --config option:

npx nodelinter --config=/Users/john/Documents/myConfig.json

For convenience, when running locally, if you place a custom config file named nodelinter.config.json anywhere inside the nodelinter dir, the custom config file will be auto-detected.

Lint exceptions

Add // nodelinter-ignore-next-line LINTING_NAME to except the next line from one or more specific lintings:

// nodelinter-ignore-next-line PARAM_DESCRIPTION_WITH_EXCESS_WHITESPACE
description: 'Time zone used in the response.    The default is the time zone of the calendar.',

// nodelinter-ignore-next-line PARAM_DESCRIPTION_WITH_EXCESS_WHITESPACE PARAM_DESCRIPTION_UNTRIMMED
description: 'Time zone used in the response.    The default is the time zone of the calendar.   ',

Or add // nodelinter-ignore-next-line to except the next line from all lintings:

// nodelinter-ignore-next-line
description: 'Time zone used in the response.    The default is the time zone of the calendar.',

Author

© 2021 Iván Ovejero

License

Distributed under the MIT License.

nodelinter's People

Contributors

ivov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nodelinter's Issues

Simplify --print option

  • Turn from string/boolean to boolean, removing unused output filename setting.
  • Add to defaultConfig.ts.
  • Remove workaround in unknown option detection.
  • Adjust docs.

Lint non-OAuth2 credentials test methods

  • Ensure every non-OAuth2 credentials object refers to a test method using the testedBy key.
  • Ensure every non-OAuth2 credentials object reference is to a test method defined in methods.credentialsTest.

Lint filenames and dirnames

Check filenames and dirnames against [Node].description.name, assumed to be correct. Including icon filename.

Error: Cannot find module './subvalidators'

Running npx nodelinter at project root of n8n-io/n8n clone throws:

$ npx nodelinter --option
internal/modules/cjs/loader.js:888
  throw err;
  ^

Error: Cannot find module './subvalidators'
Require stack:
- /home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/services/Validator.js
- /home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/services/index.js
- /home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/scripts/lintAll.js
- /home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/index.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:885:15)
    at Function.Module._load (internal/modules/cjs/loader.js:730:27)
    at Module.require (internal/modules/cjs/loader.js:957:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/services/Validator.js:61:34)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Module.require (internal/modules/cjs/loader.js:957:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/services/Validator.js',
    '/home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/services/index.js',
    '/home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/scripts/lintAll.js',
    '/home/user/.npm/_npx/3480a7d4487c2a23/node_modules/nodelinter/dist/index.js'
  ]
}

Additional info:

  • $ git describe --tags --always --first-parent --dirty=+dirty
    [email protected]
    
  • Reproducible: always

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'getText' of undefined

We're able to crash node.js via nodelinter when a nodes load-option-method is a shorthand (compare: Shorthand property names (ES2015)).

https://github.com/seatable/n8n/blob/seatable-node-release%40r1.0.0-beta-3/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts#L89-L92

> tmp/seatable-node-release@r1.0.0-beta-3-04478f5a19cfb6d33d2a1b72a070361e.log
+ in: ./packages/nodes-base/nodes/SeaTable
+ npx --no-install [email protected] --errors-only --target .
No --config option specified, attempting to autodetect...

(node:3406074) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'getText' of undefined
    at + in: ./node_modules/nodelinter/dist/services/Collector.js:55:62
    at visitNodes (+ in: ./node_modules/nodelinter/node_modules/typescript/lib/typescript.js:29004:30)
    at Object.forEachChild (+ in: ./node_modules/nodelinter/node_modules/typescript/lib/typescript.js:29180:24)
    at NodeObject.forEachChild (+ in: ./node_modules/nodelinter/node_modules/typescript/lib/typescript.js:152730:23)
    at Function.Collector.collectLoadOptionsMethods (+ in: ./node_modules/nodelinter/dist/services/Collector.js:53:37)
    at Function.Collector.run (+ in: ./node_modules/nodelinter/dist/services/Collector.js:32:19)
    at collectorVisitor (+ in: ./node_modules/nodelinter/dist/services/Traverser.js:18:43)
    at visitNode (+ in: ./node_modules/nodelinter/node_modules/typescript/lib/typescript.js:83594:23)
    at Object.visitEachChild (+ in: ./node_modules/nodelinter/node_modules/typescript/lib/typescript.js:84210:63)
    at collectorVisitor (+ in: ./node_modules/nodelinter/dist/services/Traverser.js:19:49)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3406074) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:3406074) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

(Remark: + in: . is added when shortening the path in build output)

These load methods are all async. n8n has no problem with the property.

Related PR: n8n-io/n8n#1976

Handle unknown flags

  • Show help message when passing in unknown flags.
  • Show help message when passing in --option.
  • Update docs to emphasize --option is a stand-in.

Based on #4

Lint inputs and outputs

  • Check that trigger nodes have no input but at least 1 output.
  • Check that regular nodes have at least 1 input and 1 output.

Lint for standard strings in multiOptions

For multiOptions params with loadOptionsMethod

  • Display name must end with: Name/ID
  • Description must be or end with: Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>

Lint for standard strings in options

For options params with loadOptionsMethod

  • Display name must end with: Name/ID
  • Description must be or end with: Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/nodes/expressions.html#expressions">expression</a>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.