├── .gitignore ├── .prettierrc ├── .releaserc ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── __mocks__ │ ├── chalk.ts │ └── jsonfile.ts ├── bin │ └── order.bin.ts ├── file-access.spec.ts ├── file-access.ts ├── waiter.spec.ts └── waiter.ts ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | dist/** 64 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true, 6 | "arrowParens": "avoid" 7 | } -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "pkgRoot": "dist", 3 | "plugins": [ 4 | "@semantic-release/commit-analyzer", 5 | "@semantic-release/release-notes-generator", 6 | "@semantic-release/changelog", 7 | "@semantic-release/npm", 8 | ["@semantic-release/exec", { 9 | "prepareCmd": "VERSION=${nextRelease.version} npm run bump-version" 10 | }], 11 | ["@semantic-release/git", { 12 | "assets": ["package.json", "CHANGELOG.md"], 13 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 14 | }], 15 | "@semantic-release/github" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: required 3 | language: node_js 4 | node_js: 5 | - "14" 6 | 7 | os: 8 | - linux 9 | 10 | jobs: 11 | include: 12 | - stage: install 13 | script: npm install 14 | skip_cleanup: true 15 | - stage: test 16 | script: npm run report:coverage 17 | skip_cleanup: true 18 | - stage: Build & publish 19 | script: 20 | - npm run build 21 | - npx semantic-release 22 | if: branch = master 23 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [2.0.0](https://github.com/kreuzerk/node-command-line-starter/compare/v1.0.0...v2.0.0) (2019-09-04) 2 | 3 | 4 | ### Features 5 | 6 | * **typescript:** adjust docs ([5664b92](https://github.com/kreuzerk/node-command-line-starter/commit/5664b92)) 7 | 8 | 9 | ### BREAKING CHANGES 10 | 11 | * **typescript:** Project is now updated to Typescript 12 | 13 | # 1.0.0 (2019-02-23) 14 | 15 | 16 | ### Features 17 | 18 | * **order:** display order in boxes ([05f2cd2](https://github.com/kreuzerk/node-command-line-starter/commit/05f2cd2)) 19 | * **order:** write order to file ([e971858](https://github.com/kreuzerk/node-command-line-starter/commit/e971858)) 20 | * **starter:** initial commit - add starter files ([2cbf0b3](https://github.com/kreuzerk/node-command-line-starter/commit/2cbf0b3)) 21 | * **starter:** log food to console ([916154b](https://github.com/kreuzerk/node-command-line-starter/commit/916154b)) 22 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Contributor Covenant Code of Conduct 2 | Our Pledge 3 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 4 | 5 | Our Standards 6 | Examples of behavior that contributes to creating a positive environment include: 7 | 8 | Using welcoming and inclusive language 9 | Being respectful of differing viewpoints and experiences 10 | Gracefully accepting constructive criticism 11 | Focusing on what is best for the community 12 | Showing empathy towards other community members 13 | Examples of unacceptable behavior by participants include: 14 | 15 | The use of sexualized language or imagery and unwelcome sexual attention or advances 16 | Trolling, insulting/derogatory comments, and personal or political attacks 17 | Public or private harassment 18 | Publishing others' private information, such as a physical or electronic address, without explicit permission 19 | Other conduct which could reasonably be considered inappropriate in a professional setting 20 | Our Responsibilities 21 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 24 | 25 | Scope 26 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 27 | 28 | Enforcement 29 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at kevin.kreuzer90@icloud.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 30 | 31 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 32 | 33 | Attribution 34 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-command-line-starter 2 | Progammers are lazy. As soon as we have to do the same task over and over again we start on automizing it. 3 | Automization is often done in the form of a command line utility. 4 | 5 | [![node-command-line-starter image](https://i.ibb.co/VjzD8bF/nodecommandlinestarter-project-setup-5c7a49.jpg)](https://imgbb.com/) 6 | 7 | This starter provides you with all the necessary setup to quickly create your node-command-line utility. Focus on your util and don't loose time with 8 | the project setup. 9 | 10 | The starter provides you with a setup to perform fully automated releases with Travis. Publish new versions quickly and automated to your npm repositiory. If this is 11 | new to you, you may want to read my blog-post about [The way to fully automated releases in open source projects](https://medium.com/@kevinkreuzer/the-way-to-fully-automated-releases-in-open-source-projects-44c015f38fd6) 12 | 13 | ## What's included? 14 | 15 | ### Language 16 | This starter allows you to write your command line util in TypeScript. 💪 17 | 18 | ### Testing 19 | - [Jest](https://jestjs.io/) - JavaScript Testing Framework 20 | - Jest configurations to mock third party libaries 21 | - Sample tests 22 | 23 | ### Command line utils 24 | - [Commander](https://github.com/tj/commander.js) - Complete solution for node.js command-line interfaces. 25 | - [Chalk](https://github.com/chalk/chalk) - Terminal string styling 26 | - [Boxen](https://github.com/sindresorhus/boxen#readme) - Create boxes in terminal 27 | 28 | ### Dev utilities 29 | - [Prettier](https://prettier.io/) - Code formater 30 | - [Commitizen](https://github.com/commitizen/cz-cli) Util that helps to create conventional commit messages 31 | - [Commitlint](https://github.com/conventional-changelog/commitlint) Lint your commit messages to ensure you use conventional commits 32 | - [Husky](https://github.com/typicode/husky) and [Lint-staged](https://github.com/okonet/lint-staged) to run prettier on each commit on staged files. Husky is also used to run commitlint on a commit. 33 | 34 | ### Build tools 35 | - [Codecov](https://codecov.io/) - Integration to upload your coverage report to codecov 36 | - [Travis](https://travis-ci.org/) - Sample travis file with all the necessary build steps 37 | - [SemanticRelease](https://github.com/semantic-release/semantic-release) - All the setup to use semantic release. Publish your command line utility to npm by using conventional commits 38 | 39 | ## Folder structure 40 | 41 | |__ **__mocks__** Folder that contains the mocks for third party libraries 42 | 43 | |__ **bin** contains your file with the commander instructions - this is the entry to your command line tool 44 | 45 | |__ **src** contains your implementation and the logic - is called by the file in your bin folder 46 | 47 | ## Getting started 48 | 49 | ### Development 50 | 1. Fork this repo 51 | 2. Adjust the URLs and names in package.json 52 | 3. Adjust the files in bin, src and __mocks__ 53 | 4. Adjust the bin command in package.json 54 | 55 | ### Setup CI (Travis) 56 | 1. Go to https://travis-ci.org/ and sign up with your Github account. Accept the Authorizaiton of GitHub. Activate Travis for your repository. 57 | 2. The starter allready contains a .travis.yml file that will be interpreted up by travis. 58 | 59 | ### Setup npm account 60 | Sign up on https://www.npmjs.com/. 61 | 62 | ### Setup using semantic-release-cli 63 | ``` 64 | npm install -g semantic-release-cli 65 | 66 | cd your-module 67 | semantic-release-cli setup 68 | ``` 69 | Enter the required informations. The CLI will do the setup and add the necessary tokens to your Travie repository settings. 70 | 71 | ### Visualize coverage 72 | To visualize coverage just sign up on https://codecov.io/. 73 | Go to Settings and copy the token. Add this token as CODECOV_TOKEN to your travis repository settings. 74 | 75 | ### Merge your feature branch into master 76 | Use conventional commit messages for your commits. A merge on master 77 | will then analyze the commits, automatically bump the version, create 78 | the release assets and then publish the package. 79 | 80 | ## Play around with the example 81 | If you are curious about how this example is used, just try it out. Open up a terminal 82 | and run: 83 | ``` 84 | npx node-command-line-starter pizza beer 85 | ``` 86 | which will output the following: 87 | ``` _ 88 | _ _ ___ _ _ _ __ ___ _ __ __| | ___ _ __ 89 | | | | |/ _ \| | | | '__| / _ \| '__/ _` |/ _ \ '__| 90 | | |_| | (_) | |_| | | | (_) | | | (_| | __/ | 91 | \__, |\___/ \__,_|_| \___/|_| \__,_|\___|_| 92 | |___/ 93 | 94 | ╭─────────────────────────────────────────────╮ 95 | │ │ 96 | │ You ordered the following food: pizza │ 97 | │ You ordered the following drink: beer │ 98 | │ │ 99 | ╰─────────────────────────────────────────────╯ 100 | ``` 101 | additionally the starter example also allows you to use a -w option followed 102 | by a filename. In case you do so, your order is written to the file you specified. 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/src'], 3 | transform: { 4 | '^.+\\.tsx?$': 'ts-jest', 5 | }, 6 | testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$', 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-command-line-starter", 3 | "version": "2.0.0", 4 | "description": "Starter to create node-command-line utilities", 5 | "main": "index.js", 6 | "husky": { 7 | "hooks": { 8 | "pre-commit": "lint-staged", 9 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 10 | } 11 | }, 12 | "lint-staged": { 13 | "{src,__mocks__,bin}/**/*.ts": [ 14 | "prettier --write", 15 | "git add" 16 | ] 17 | }, 18 | "commitlint": { 19 | "extends": [ 20 | "@commitlint/config-conventional" 21 | ] 22 | }, 23 | "config": { 24 | "commitizen": { 25 | "path": "@commitlint/prompt" 26 | } 27 | }, 28 | "scripts": { 29 | "build": "tsc", 30 | "commit": "git-cz", 31 | "format:check": "prettier --list-different '{src,__mocks__,bin}/**/*.ts'", 32 | "format:write": "prettier --write '{src,__mocks__,bin}/**/*.ts'", 33 | "start:help": "ts-node ./src/bin/order.bin.ts -h", 34 | "start:example": "ts-node ./src/bin/order.bin.ts pizza beer", 35 | "test": "jest", 36 | "bump-version": "rjp package.json version $VERSION", 37 | "test:coverage": "jest --coverage", 38 | "report:coverage": "npm run test:coverage && codecov", 39 | "semantic-release": "semantic-release" 40 | }, 41 | "bin": { 42 | "node-command-line-starter": "./src/bin/order.bin.js", 43 | "restaurant": "./src/bin/order.bin.js" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "https://github.com/kreuzerk/node-command-line-starter.git" 48 | }, 49 | "keywords": [ 50 | "CLI", 51 | "Replace", 52 | "JSON", 53 | "Buildtool", 54 | "Starter" 55 | ], 56 | "author": "Kevin Kreuzer", 57 | "license": "MIT", 58 | "bugs": { 59 | "url": "https://github.com/kreuzerk/node-command-line-starter/issues" 60 | }, 61 | "homepage": "https://github.com/kreuzerk/node-command-line-starter#readme", 62 | "dependencies": { 63 | "boxen": "^5.1.2", 64 | "commander": "^8.2.0", 65 | "jsonfile": "^6.1.0" 66 | }, 67 | "devDependencies": { 68 | "@commitlint/cli": "^13.1.0", 69 | "@commitlint/config-conventional": "^13.1.0", 70 | "@commitlint/prompt": "^13.1.0", 71 | "@semantic-release/changelog": "^5.0.1", 72 | "@semantic-release/exec": "^5.0.0", 73 | "@semantic-release/git": "^9.0.1", 74 | "@types/jest": "^27.0.1", 75 | "@types/node": "^16.9.4", 76 | "codecov": "^3.1.0", 77 | "commitizen": "^4.2.4", 78 | "husky": "^7.0.2", 79 | "jest": "^27.2.0", 80 | "lint-staged": "^11.1.2", 81 | "prettier": "^2.4.1", 82 | "replace-json-property": "^1.4.1", 83 | "semantic-release": "^18.0.0", 84 | "ts-jest": "^27.0.5", 85 | "ts-node": "^10.2.1", 86 | "typescript": "^4.4.3" 87 | } 88 | } -------------------------------------------------------------------------------- /src/__mocks__/chalk.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const chalk = jest.genMockFromModule('chalk'); 3 | 4 | chalk.red = jest.fn(); 5 | chalk.green = jest.fn(); 6 | chalk.blue = { 7 | bold: jest.fn() 8 | }; 9 | 10 | module.exports = chalk; 11 | -------------------------------------------------------------------------------- /src/__mocks__/jsonfile.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const jsonfile = jest.genMockFromModule('jsonfile'); 3 | 4 | let error; 5 | 6 | const setup = createError => (error = createError); 7 | 8 | const writeFile = jest.fn((fileName, order, cb) => { 9 | error ? cb('Something went wrong') : cb(); 10 | }); 11 | jsonfile.setup = setup; 12 | jsonfile.writeFile = writeFile; 13 | 14 | module.exports = jsonfile; 15 | -------------------------------------------------------------------------------- /src/bin/order.bin.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Command } from 'commander'; 3 | import * as packgeJSON from '../../package.json'; 4 | import { writeFile } from '../file-access'; 5 | import { placeOrder } from '../waiter'; 6 | 7 | const program = new Command(); 8 | 9 | program 10 | .version(packgeJSON.version) 11 | .arguments(' ') 12 | .option( 13 | '-w --write ', 14 | 'Specifies the path of the file the order will be written to' 15 | ) 16 | .action(function(food, drink, options) { 17 | const fileName = options.write; 18 | placeOrder(food, drink); 19 | if (fileName) { 20 | writeFile(fileName, { food, drink }); 21 | } 22 | }) 23 | .parse(process.argv); 24 | -------------------------------------------------------------------------------- /src/file-access.spec.ts: -------------------------------------------------------------------------------- 1 | import jsonfile from 'jsonfile'; 2 | import chalk from 'chalk'; 3 | 4 | const sut = require('./file-access'); 5 | 6 | describe('file access', () => { 7 | beforeAll(() => (console.log = jest.fn())); 8 | 9 | test('should log an error message if something went wrong', () => { 10 | const throwError = true; 11 | jsonfile.setup(throwError); 12 | 13 | sut.writeFile('../test', {}); 14 | expect(chalk.red).toHaveBeenCalled(); 15 | }); 16 | 17 | test('should log a success message if everything went well', () => { 18 | jsonfile.setup(false); 19 | 20 | sut.writeFile('../test', {}); 21 | expect(chalk.green).toHaveBeenCalledWith( 22 | 'Order successfully written to file' 23 | ); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/file-access.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import jsonfile from 'jsonfile'; 3 | 4 | export function writeFile(fileName, order) { 5 | jsonfile.writeFile(fileName, order, function(err) { 6 | err 7 | ? console.log((chalk as any).red(err)) 8 | : console.log( 9 | (chalk as any).green('Order successfully written to file') 10 | ); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /src/waiter.spec.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import sut = require('./waiter'); 3 | 4 | describe('Waiter', () => { 5 | beforeAll(() => (console.log = jest.fn())); 6 | 7 | test('should print the food on the order', () => { 8 | const food = 'Pizza'; 9 | const drink = 'Coke'; 10 | sut.placeOrder(food, drink); 11 | 12 | expect(chalk.green).toHaveBeenCalledWith( 13 | 'You ordered the following food: ' 14 | ); 15 | expect(chalk.blue.bold).toHaveBeenCalledWith(food); 16 | }); 17 | 18 | test('should print the drink to the order', () => { 19 | const food = 'Pizza'; 20 | const drink = 'Coke'; 21 | sut.placeOrder(food, drink); 22 | 23 | expect(chalk.green).toHaveBeenCalledWith( 24 | 'You ordered the following drink: ' 25 | ); 26 | expect(chalk.blue.bold).toHaveBeenCalledWith(drink); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/waiter.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import boxen from 'boxen'; 3 | 4 | const orderTitle = 5 | '\n' + 6 | ' _ \n' + 7 | ' _ _ ___ _ _ _ __ ___ _ __ __| | ___ _ __ \n' + 8 | " | | | |/ _ \\| | | | '__| / _ \\| '__/ _` |/ _ \\ '__|\n" + 9 | ' | |_| | (_) | |_| | | | (_) | | | (_| | __/ | \n' + 10 | ' \\__, |\\___/ \\__,_|_| \\___/|_| \\__,_|\\___|_| \n' + 11 | ' |___/ \n'; 12 | 13 | export function placeOrder(food, drink) { 14 | const foodOrder = `${(chalk as any).green( 15 | 'You ordered the following food: ' 16 | )} ${(chalk as any).blue.bold(food)} \n`; 17 | const drinkOrder = `${(chalk as any).green( 18 | 'You ordered the following drink: ' 19 | )} ${(chalk as any).blue.bold(drink)}`; 20 | 21 | const order = `${orderTitle} ${boxen(foodOrder + drinkOrder, { 22 | padding: 1, 23 | margin: 1, 24 | borderStyle: 'round' 25 | })}`; 26 | 27 | console.log(order); 28 | } 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "target": "es6", 6 | "moduleResolution": "node", 7 | "declaration": true, 8 | "sourceMap": true, 9 | "outDir": "dist", 10 | "resolveJsonModule": true, 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["node_modules", "**/*.spec.ts"], 14 | "lib": [ 15 | "es2015" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jest", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": {}, 8 | "rulesDirectory": [] 9 | } --------------------------------------------------------------------------------