├── .gitignore ├── example ├── example.ts └── example.js ├── types └── index.d.ts ├── LICENSE ├── package.json ├── .github └── workflows │ └── node.js.yml ├── lib └── exec-sh.js ├── README.md ├── test └── exec-sh.js └── .jshintrc /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | artifacts/ 3 | .nyc_output 4 | -------------------------------------------------------------------------------- /example/example.ts: -------------------------------------------------------------------------------- 1 | import execSh from '../' 2 | 3 | (async () => { 4 | console.log(await execSh.promise('pwd')) 5 | console.log(await execSh.promise('pwd', true)) 6 | execSh('pwd') 7 | execSh('pwd', true) 8 | execSh('pwd', {}, () => {}) 9 | execSh('pwd', true, ( error: Error | null, stdout: string, stderr: string) => { 10 | console.log({ error, stdout, stderr }) 11 | }) 12 | })() 13 | -------------------------------------------------------------------------------- /example/example.js: -------------------------------------------------------------------------------- 1 | const execSh = require('../') 2 | 3 | // run interactive bash shell 4 | execSh('echo ola && bash', { cwd: '/home' }, function (err) { 5 | if (err) { 6 | console.log('Exit code: ', err.code) 7 | return 8 | } 9 | 10 | // collect streams output 11 | execSh(['bash -c id', 'echo olaola >&2'], true, 12 | function (err, stdout, stderr) { 13 | console.log('error: ', err) 14 | console.log('stdout: ', stdout) 15 | console.log('stderr: ', stderr) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { ChildProcess } from 'child_process'; 2 | 3 | declare function execSh( 4 | command: string | string[], 5 | options?: object | true, 6 | callback?: ( 7 | error: Error | null, 8 | stdout: string, 9 | stderr: string 10 | ) => void 11 | ): ChildProcess; 12 | 13 | declare namespace execSh { 14 | function promise( 15 | command: string | string[], 16 | options?: object | true 17 | ): Promise<{ stdout: string, stderr: string }>; 18 | } 19 | 20 | export default execSh; 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Aleksandr Tsertkov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exec-sh", 3 | "version": "0.4.0", 4 | "description": "Execute shell command forwarding all stdio.", 5 | "main": "lib/exec-sh.js", 6 | "types": "types/index.d.ts", 7 | "scripts": { 8 | "test": "npm run lint && npm run test-ts && npm run cover-test", 9 | "test-ts": "tsc --noEmit example/example.ts", 10 | "cover-test": "nyc --reporter=lcov --report-dir=artifacts/coverage mocha", 11 | "lint": "standard --verbose **/*.js", 12 | "dev": "mocha --reporter spec --watch", 13 | "jsdoc": "jsdoc --private --destination artifacts/jsdoc lib/" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git@github.com:tsertkov/exec-sh.git" 18 | }, 19 | "keywords": [ 20 | "exec", 21 | "spawn", 22 | "terminal", 23 | "console", 24 | "shell", 25 | "command", 26 | "child_process" 27 | ], 28 | "author": "Aleksandr Tsertkov ", 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/tsertkov/exec-sh/issues" 32 | }, 33 | "devDependencies": { 34 | "@types/node": "^20.3.3", 35 | "jsdoc": "^4.0.2", 36 | "jshint": "^2.13.6", 37 | "mocha": "^10.2.0", 38 | "nyc": "^15.1.0", 39 | "sinon": "^15.2.0", 40 | "standard": "^17.1.0", 41 | "typescript": "^5.1.6" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build-on-linux: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: [14.x, 16.x, 18.x, 20.x] 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | cache: 'npm' 22 | - run: npm ci 23 | - run: npm test 24 | 25 | build-on-windows: 26 | runs-on: windows-latest 27 | strategy: 28 | matrix: 29 | node-version: [14.x, 16.x, 18.x, 20.x] 30 | steps: 31 | - uses: actions/checkout@v4 32 | - name: Use Node.js ${{ matrix.node-version }} 33 | uses: actions/setup-node@v4 34 | with: 35 | node-version: ${{ matrix.node-version }} 36 | cache: 'npm' 37 | - run: npm ci 38 | - run: npm test 39 | 40 | publish-assets: 41 | needs: [ build-on-linux, build-on-windows ] 42 | runs-on: ubuntu-latest 43 | steps: 44 | - uses: actions/checkout@v4 45 | - uses: actions/setup-node@v4 46 | with: 47 | node-version: 18.x 48 | cache: 'npm' 49 | - run: npm ci 50 | - run: npm run jsdoc 51 | - run: npm run cover-test 52 | - name: Upload jsdoc artifacts 53 | uses: actions/upload-artifact@v3 54 | with: 55 | name: jsdoc 56 | path: artifacts/jsdoc 57 | - name: Upload coverage artifacts 58 | uses: actions/upload-artifact@v3 59 | with: 60 | name: coverage 61 | path: artifacts/coverage 62 | -------------------------------------------------------------------------------- /lib/exec-sh.js: -------------------------------------------------------------------------------- 1 | const cp = require('child_process') 2 | 3 | const defSpawnOptions = { stdio: 'inherit' } 4 | 5 | /** 6 | * @summary Get shell program meta for current platform 7 | * @private 8 | * @returns {Object} 9 | */ 10 | function getShell () { 11 | if (process.platform === 'win32') { 12 | return { cmd: 'cmd', arg: '/C' } 13 | } else { 14 | return { cmd: 'sh', arg: '-c' } 15 | } 16 | } 17 | 18 | /** 19 | * Callback is called with the output when the process terminates. Output is 20 | * available when true is passed as options argument or stdio: null set 21 | * within given options. 22 | * 23 | * @summary Execute shell command forwarding all stdio 24 | * @param {String|Array} command 25 | * @param {Object|TRUE} [options] spawn() options or TRUE to set stdio: null 26 | * @param {Function} [callback] 27 | * @returns {ChildProcess} 28 | */ 29 | function execSh (command, options, callback) { 30 | if (Array.isArray(command)) { 31 | command = command.join(';') 32 | } 33 | 34 | if (options === true) { 35 | options = { stdio: null } 36 | } 37 | 38 | if (typeof options === 'function') { 39 | callback = options 40 | options = defSpawnOptions 41 | } else { 42 | options = options || {} 43 | options = Object.assign({}, defSpawnOptions, options) 44 | callback = callback || function () {} 45 | } 46 | 47 | let child 48 | let stdout = '' 49 | let stderr = '' 50 | const shell = getShell() 51 | 52 | try { 53 | child = cp.spawn(shell.cmd, [shell.arg, command], options) 54 | } catch (e) { 55 | callback(e, stdout, stderr) 56 | return 57 | } 58 | 59 | if (child.stdout) { 60 | child.stdout.on('data', function (data) { 61 | stdout += data 62 | }) 63 | } 64 | 65 | if (child.stderr) { 66 | child.stderr.on('data', function (data) { 67 | stderr += data 68 | }) 69 | } 70 | 71 | child.on('close', function (code) { 72 | if (code) { 73 | const e = new Error('Shell command exit with non zero code: ' + code) 74 | e.code = code 75 | callback(e, stdout, stderr) 76 | } else { 77 | callback(null, stdout, stderr) 78 | } 79 | }) 80 | 81 | return child 82 | } 83 | 84 | execSh.promise = function (command, options) { 85 | return new Promise(function (resolve, reject) { 86 | execSh(command, options, function (err, stdout, stderr) { 87 | if (err) { 88 | err.stdout = stdout 89 | err.stderr = stderr 90 | return reject(err) 91 | } 92 | 93 | resolve({ 94 | stderr, 95 | stdout 96 | }) 97 | }) 98 | }) 99 | } 100 | 101 | module.exports = execSh 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # exec-sh 2 | 3 | [![NPM](https://nodei.co/npm/exec-sh.png)](https://nodei.co/npm/exec-sh/) 4 | [![NPM Downloads](https://img.shields.io/npm/dm/exec-sh.svg)](https://www.npmjs.com/package/exec-sh) 5 | 6 | > Execute shell command forwarding all stdio streams. 7 | 8 | ## Features 9 | 10 | exec-sh is a wrapper for [`child_process.spawn`](http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) with some improvements: 11 | 12 | - Cross platform command execution: 13 | - Windows: `cmd /C COMMAND` 14 | - others: `sh -c COMMAND` 15 | - Forwards all stdio streams to current terminal (by default): 16 | - `execSh("bash")` 17 | - `execsh("echo -n Say: && read i && echo Said:$i")` 18 | - stdout and stderr are passed to callback when available 19 | - `execSh("pwd", console.log)` 20 | 21 | ## Showcase 22 | ```javascript 23 | // JavaScript 24 | 25 | execSh("echo hello exec-sh && bash", { cwd: "/home" }, function(err){ 26 | if (err) { 27 | console.log("Exit code: ", err.code); 28 | } 29 | }); 30 | ``` 31 | 32 | ```sh 33 | # Terminal output: interactive bash session 34 | 35 | hello exec-sh 36 | bash-3.2$ pwd 37 | /home 38 | bash-3.2$ exit 99 39 | exit 40 | Exit code: 99 41 | ``` 42 | 43 | ## Usage 44 | 45 | ```javascript 46 | const execSh = require("../"); 47 | 48 | // run interactive bash shell 49 | execSh("echo lorem && bash", { cwd: "/home" }, (err) => { 50 | if (err) { 51 | console.log("Exit code: ", err.code); 52 | return; 53 | } 54 | 55 | // collect streams output 56 | const child = execSh(["bash -c id", "echo lorem >&2"], true, 57 | (err, stdout, stderr) => { 58 | console.log("error: ", err); 59 | console.log("stdout: ", stdout); 60 | console.log("stderr: ", stderr); 61 | }); 62 | }); 63 | ``` 64 | 65 | ## Promise Interface 66 | 67 | ```javascript 68 | const execShPromise = require("exec-sh").promise; 69 | 70 | // run interactive bash shell 71 | const run = async () => { 72 | let out; 73 | 74 | try { 75 | out = await execShPromise('pwd', true); 76 | } catch (e) { 77 | console.log('Error: ', e); 78 | console.log('Stderr: ', e.stderr); 79 | console.log('Stdout: ', e.stdout); 80 | 81 | return e; 82 | } 83 | 84 | console.log('out: ', out.stdout, out.stderr); 85 | } 86 | 87 | run(); 88 | ``` 89 | 90 | ## Public API 91 | 92 | ### `execSh(command, [options], [callback])` 93 | 94 | Execute shell command forwarding all stdio. 95 | 96 | **Parameters:** 97 | 98 | - `command {String|Array}` - The command to run, or array of commands 99 | - `[options] {Object|TRUE}` - Options object passed directly to [`child_process.spawn`](http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options), when `TRUE` then `{ stdio: null }` used 100 | - `[callback] {Function}` - `callback(err, stdout, stderr)` 101 | - `err {Error|NULL}` - Error object. Has `code` property containing last command exit code when available 102 | - `stdout {String|NULL}` - aggregated stdout or `NULL` if not available 103 | - `stderr {String|NULL}` - aggregated stderr or `NULL` if not available 104 | 105 | **Return Values:** 106 | 107 | Returns [ChildProcess](http://nodejs.org/api/child_process.html#child_process_class_childprocess) object. 108 | 109 | ## Scripts 110 | 111 | - `npm test` - run tests 112 | - `npm run jsdoc` - build jsdoc 113 | - `npm run dev` - run tests continuously 114 | 115 | ## License 116 | 117 | The MIT License (MIT) 118 | -------------------------------------------------------------------------------- /test/exec-sh.js: -------------------------------------------------------------------------------- 1 | /* global describe, it, beforeEach, afterEach */ 2 | const execSh = require('..') 3 | const assert = require('assert') 4 | const sinon = require('sinon') 5 | const cp = require('child_process') 6 | 7 | describe('exec-sh', function () { 8 | describe('module.exports', function () { 9 | it('should export a single function', function () { 10 | assert.strictEqual(typeof execSh, 'function') 11 | }) 12 | 13 | it('should export promise interface', function () { 14 | assert.strictEqual(typeof execSh.promise, 'function') 15 | }) 16 | }) 17 | 18 | describe('#execSh() arguments', function () { 19 | let spawn, exitCode, stream 20 | 21 | stream = { 22 | on: function (e, c) { 23 | if (e === 'data') { 24 | // execute callback two times to check if stream 25 | // aggregation works correctly 26 | c('1') 27 | c('2') 28 | } 29 | } 30 | } 31 | 32 | beforeEach(function () { 33 | exitCode = 0 34 | spawn = sinon.stub(cp, 'spawn') 35 | spawn.returns({ 36 | spawn_return: true, 37 | on: function (e, c) { 38 | if (e === 'close') { 39 | c(exitCode) 40 | } 41 | }, 42 | stdout: stream, 43 | stderr: stream 44 | }) 45 | }) 46 | 47 | afterEach(function () { 48 | cp.spawn.restore() 49 | }) 50 | 51 | it('should pass command to spawn function', function () { 52 | execSh('command') 53 | sinon.assert.calledOnce(spawn) 54 | assert.strictEqual('command', spawn.getCall(0).args[1][1]) 55 | }) 56 | 57 | it('should accept array of commands to run', function () { 58 | execSh(['command1', 'command2']) 59 | sinon.assert.calledOnce(spawn) 60 | assert.strictEqual('command1;command2', spawn.getCall(0).args[1][1]) 61 | }) 62 | 63 | it('should accept true as options argument', function () { 64 | execSh('command', true) 65 | sinon.assert.calledOnce(spawn) 66 | assert.strictEqual(spawn.getCall(0).args[2].stdio, null) 67 | }) 68 | 69 | it('should merge defaults with options', function () { 70 | const options = { key: 'value' } 71 | const expectedOptions = { 72 | key: 'value', 73 | stdio: 'inherit' 74 | } 75 | execSh('command', options) 76 | assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions) 77 | }) 78 | 79 | it('should allow overriding default options', function () { 80 | const options = { foo: 'bar', stdio: null } 81 | const expectedOptions = { 82 | foo: 'bar', 83 | stdio: null 84 | } 85 | execSh('command', options) 86 | assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions) 87 | }) 88 | 89 | it('should allow passing nested environment options', function () { 90 | const options = { 91 | env: { 92 | key1: 'value 1', 93 | key2: 'value 2' 94 | } 95 | } 96 | const expectedOptions = { 97 | env: { 98 | key1: 'value 1', 99 | key2: 'value 2' 100 | }, 101 | stdio: 'inherit' 102 | } 103 | execSh('command', options) 104 | assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions) 105 | }) 106 | 107 | it("should accept optional 'callback' parameter", function () { 108 | const callback = sinon.spy() 109 | execSh('command', callback) 110 | execSh('command', { key: 'value' }, callback) 111 | sinon.assert.callCount(callback, 2) 112 | }) 113 | 114 | it("should use 'cmd /C' command prefix on windows", function () { 115 | const platform = process.platform 116 | Object.defineProperty(process, 'platform', { value: 'win32' }) 117 | execSh('command') 118 | Object.defineProperty(process, 'platform', { value: platform }) 119 | 120 | sinon.assert.calledOnce(spawn) 121 | assert.strictEqual(spawn.getCall(0).args[0], 'cmd') 122 | }) 123 | 124 | it("should use 'sh -c' command prefix on *nix", function () { 125 | const platform = process.platform 126 | Object.defineProperty(process, 'platform', { value: 'linux' }) 127 | execSh('command') 128 | Object.defineProperty(process, 'platform', { value: platform }) 129 | 130 | sinon.assert.calledOnce(spawn) 131 | assert.strictEqual(spawn.getCall(0).args[1][0], '-c') 132 | assert.strictEqual(spawn.getCall(0).args[0], 'sh') 133 | }) 134 | 135 | it('should return spawn() result', function () { 136 | assert(execSh('command').spawn_return) 137 | }) 138 | 139 | it('should aggregate stdoout and stderr', function (done) { 140 | execSh('command', function (_err, stdout, stderr) { 141 | assert.strictEqual(stdout, '12') 142 | assert.strictEqual(stderr, '12') 143 | done() 144 | }) 145 | }) 146 | 147 | it('should catch exceptions thrown by spawn', function (done) { 148 | spawn.throws() 149 | execSh('command', function (err, stdout, stderr) { 150 | assert(err instanceof Error) 151 | done() 152 | }) 153 | }) 154 | 155 | it('should return empty stdout and stderr when spawn throws', function (done) { 156 | spawn.throws() 157 | stream = null 158 | execSh('command', function (_err, stdout, stderr) { 159 | assert.strictEqual(stderr, '') 160 | assert.strictEqual(stdout, '') 161 | done() 162 | }) 163 | }) 164 | 165 | it('should run callback with error when shell exit with non-zero code', function (done) { 166 | exitCode = 1 167 | execSh('command', function (err) { 168 | assert(err instanceof Error) 169 | assert.strictEqual(exitCode, err.code) 170 | done() 171 | }) 172 | }) 173 | 174 | it('promise interface: should return promise', function () { 175 | assert(execSh.promise('command') instanceof Promise) 176 | }) 177 | 178 | it('promise interface: should resolve with stderr and stdout', function (done) { 179 | execSh.promise('command').then(function (data) { 180 | assert.ok('stdout' in data) 181 | assert.ok('stderr' in data) 182 | done() 183 | }) 184 | }) 185 | 186 | it('promise interface: should reject promise when exceptions thrown by spawn', function (done) { 187 | spawn.throws() 188 | execSh.promise('command').catch(function (err) { 189 | assert(err instanceof Error) 190 | done() 191 | }) 192 | }) 193 | }) 194 | }) 195 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // -------------------------------------------------------------------- 3 | // JSHint Configuration, Strict Edition 4 | // -------------------------------------------------------------------- 5 | // 6 | // This is a options template for [JSHint][1], using [JSHint example][2] 7 | // and [Ory Band's example][3] as basis and setting config values to 8 | // be most strict: 9 | // 10 | // * set all enforcing options to true 11 | // * set all relaxing options to false 12 | // * set all environment options to false, except the browser value 13 | // * set all JSLint legacy options to false 14 | // 15 | // [1]: http://www.jshint.com/ 16 | // [2]: https://github.com/jshint/node-jshint/blob/master/example/config.json 17 | // [3]: https://github.com/oryband/dotfiles/blob/master/jshintrc 18 | // 19 | // @author http://michael.haschke.biz/ 20 | // @license http://unlicense.org/ 21 | 22 | // == Enforcing Options =============================================== 23 | // 24 | // These options tell JSHint to be more strict towards your code. Use 25 | // them if you want to allow only a safe subset of JavaScript, very 26 | // useful when your codebase is shared with a big number of developers 27 | // with different skill levels. 28 | 29 | "bitwise" : true, // Prohibit bitwise operators (&, |, ^, etc.). 30 | "curly" : true, // Require {} for every new block or scope. 31 | "eqeqeq" : true, // Require triple equals i.e. `===`. 32 | "forin" : true, // Tolerate `for in` loops without `hasOwnPrototype`. 33 | "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` 34 | "latedef" : true, // Prohibit variable use before definition. 35 | "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. 36 | "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. 37 | "noempty" : true, // Prohibit use of empty blocks. 38 | "nonew" : true, // Prohibit use of constructors for side-effects. 39 | "plusplus" : true, // Prohibit use of `++` & `--`. 40 | "regexp" : true, // Prohibit `.` and `[^...]` in regular expressions. 41 | "undef" : true, // Require all non-global variables be declared before they are used. 42 | "strict" : false, // Require `use strict` pragma in every file. 43 | "trailing" : true, // Prohibit trailing whitespaces. 44 | 45 | // == Relaxing Options ================================================ 46 | // 47 | // These options allow you to suppress certain types of warnings. Use 48 | // them only if you are absolutely positive that you know what you are 49 | // doing. 50 | 51 | "asi" : false, // Tolerate Automatic Semicolon Insertion (no semicolons). 52 | "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. 53 | "debug" : false, // Allow debugger statements e.g. browser breakpoints. 54 | "eqnull" : false, // Tolerate use of `== null`. 55 | "es5" : false, // Allow EcmaScript 5 syntax. 56 | "esnext" : false, // Allow ES.next specific features such as `const` and `let`. 57 | "evil" : false, // Tolerate use of `eval`. 58 | "expr" : false, // Tolerate `ExpressionStatement` as Programs. 59 | "funcscope" : false, // Tolerate declarations of variables inside of control structures while accessing them later from the outside. 60 | "globalstrict" : false, // Allow global "use strict" (also enables 'strict'). 61 | "iterator" : false, // Allow usage of __iterator__ property. 62 | "lastsemic" : false, // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block. 63 | "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. 64 | "laxcomma" : false, // Suppress warnings about comma-first coding style. 65 | "loopfunc" : false, // Allow functions to be defined within loops. 66 | "multistr" : false, // Tolerate multi-line strings. 67 | "onecase" : false, // Tolerate switches with just one case. 68 | "proto" : false, // Tolerate __proto__ property. This property is deprecated. 69 | "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`. 70 | "scripturl" : false, // Tolerate script-targeted URLs. 71 | "smarttabs" : false, // Tolerate mixed tabs and spaces when the latter are used for alignmnent only. 72 | "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. 73 | "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. 74 | "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. 75 | "validthis" : false, // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function. 76 | 77 | // == Environments ==================================================== 78 | // 79 | // These options pre-define global variables that are exposed by 80 | // popular JavaScript libraries and runtime environments—such as 81 | // browser or node.js. 82 | 83 | "browser" : false, // Standard browser globals e.g. `window`, `document`. 84 | "couch" : false, // Enable globals exposed by CouchDB. 85 | "devel" : false, // Allow development statements e.g. `console.log();`. 86 | "dojo" : false, // Enable globals exposed by Dojo Toolkit. 87 | "jquery" : false, // Enable globals exposed by jQuery JavaScript library. 88 | "mootools" : false, // Enable globals exposed by MooTools JavaScript framework. 89 | "node" : true, // Enable globals available when code is running inside of the NodeJS runtime environment. 90 | "nonstandard" : false, // Define non-standard but widely adopted globals such as escape and unescape. 91 | "prototypejs" : false, // Enable globals exposed by Prototype JavaScript framework. 92 | "rhino" : false, // Enable globals available when your code is running inside of the Rhino runtime environment. 93 | "wsh" : false, // Enable globals available when your code is running as a script for the Windows Script Host. 94 | 95 | // == JSLint Legacy =================================================== 96 | // 97 | // These options are legacy from JSLint. Aside from bug fixes they will 98 | // not be improved in any way and might be removed at any point. 99 | 100 | "nomen" : false, // Prohibit use of initial or trailing underbars in names. 101 | "onevar" : false, // Allow only one `var` statement per function. 102 | "passfail" : false, // Stop on first error. 103 | "white" : false, // Check against strict whitespace and indentation rules. 104 | 105 | // == Undocumented Options ============================================ 106 | // 107 | // While I've found these options in [example1][2] and [example2][3] 108 | // they are not described in the [JSHint Options documentation][4]. 109 | // 110 | // [4]: http://www.jshint.com/options/ 111 | 112 | "maxerr" : 100, // Maximum errors before stopping. 113 | "predef" : [ // Extra globals. 114 | //"exampleVar", 115 | //"anotherCoolGlobal", 116 | //"iLoveDouglas" 117 | ], 118 | "indent" : 2, // Specify indentation spacing 119 | "maxlen" : 100 // The maximum number of characters in a line. 120 | } --------------------------------------------------------------------------------