├── .dockerignore ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .gitlab-ci.yml ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── bootstrap.js ├── docker-compose.yml ├── package-lock.json ├── package.json ├── src ├── config.ts ├── index.ts └── modules │ └── square │ ├── index.test.ts │ └── index.ts ├── tsconfig.json └── tslint.json /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | Dockerfile 4 | README 5 | LICENSE -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # don't ever lint node_modules 2 | node_modules 3 | # don't lint build output (make sure it's set to your correct build folder name) 4 | dist 5 | # don't lint nyc coverage output 6 | coverage 7 | build -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | plugins: [ 5 | '@typescript-eslint', 6 | ], 7 | extends: [ 8 | 'eslint:recommended', 9 | 'plugin:@typescript-eslint/eslint-recommended', 10 | 'plugin:@typescript-eslint/recommended', 11 | ], 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | .DS_Store 3 | typings/ 4 | .idea/ 5 | .vscode 6 | build/ 7 | node_modules/ 8 | coverage/ -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | DOCKER_DRIVE: overlay2 3 | 4 | image: node:10-alpine 5 | 6 | services: 7 | - docker:dind 8 | 9 | stages: 10 | - dependencies 11 | - test 12 | - build 13 | - scanning 14 | - cleanup 15 | 16 | cache: 17 | key: "$CI_BUILD_REF_SLUG" 18 | paths: 19 | - node_modules/ 20 | 21 | install_dependencies: 22 | stage: dependencies 23 | before_script: 24 | - node -v 25 | - npm -v 26 | script: 27 | - npm install 28 | after_script: 29 | - ./node_modules/.bin/tsc -v 30 | 31 | check_code_quality: 32 | stage: test 33 | script: 34 | - npm run lint 35 | 36 | check_code_formatting: 37 | stage: test 38 | script: 39 | - npm run prettier:check 40 | 41 | run_tests: 42 | stage: test 43 | coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/' 44 | artifacts: 45 | paths: 46 | - coverage/ 47 | script: 48 | - npm test 49 | 50 | compile_source: 51 | stage: build 52 | artifacts: 53 | paths: 54 | - build/ 55 | script: 56 | - npm run build 57 | 58 | build_image: 59 | stage: build 60 | image: docker:latest 61 | before_script: 62 | - docker info 63 | - apk update && apk add --update make git 64 | script: 65 | - make image 66 | # - docker push to a registery 67 | after_script: 68 | - make clean-image 69 | 70 | container_scanning: 71 | stage: scanning 72 | image: docker:latest 73 | variables: 74 | DOCKER_DRIVE: overlay2 75 | allow_failure: true 76 | services: 77 | - docker:dind 78 | before_script: 79 | - apk update && apk add --update --no-cache git make bash wget ca-certificates 80 | script: 81 | - docker run -d --name db arminc/clair-db:latest 82 | - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:v2.0.1 83 | - apk add -U wget ca-certificates 84 | - wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 85 | - mv clair-scanner_linux_amd64 clair-scanner 86 | - chmod +x clair-scanner 87 | - touch clair-whitelist.yml 88 | - while( ! wget -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; done 89 | - retries=0 90 | - echo "Waiting for clair daemon to start" 91 | - while( ! wget -T 10 -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; echo -n "." ; if [ $retries -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; retries=$(($retries+1)) ; done 92 | - ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-container-scanning-report.json -l clair.log -w clair-whitelist.yml tsnodestarter:${CI_COMMIT_SHA:0:6} || true 93 | 94 | image_cleanup: 95 | stage: cleanup 96 | image: docker:latest 97 | script: 98 | - docker rmi -f tsnodestarter:${CI_COMMIT_SHA:0:6} 99 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-alpine as base 2 | 3 | LABEL maintainer Loc Nguyen 4 | 5 | RUN apk update \ 6 | && apk add --no-cache \ 7 | bash 8 | 9 | ARG HOST_UID=${HOST_UID:-4000} 10 | ARG HOST_USER=${HOST_USER:-nodummy} 11 | ARG PROJECT_NAME=${PROJECT_NAME} 12 | 13 | RUN [ "${HOST_USER}" == "root" ] || \ 14 | (adduser -h /home/${HOST_USER} -D -u ${HOST_UID} ${HOST_USER} \ 15 | && chown -R "${HOST_UID}:${HOST_UID}" /home/${HOST_USER}) 16 | 17 | USER ${HOST_USER} 18 | 19 | WORKDIR /home/${HOST_USER} 20 | 21 | # Make a directory for our app and copy package.json there 22 | RUN mkdir -p /home/${HOST_USER}/${PROJECT_NAME} 23 | WORKDIR /home/${HOST_USER}/${PROJECT_NAME} 24 | COPY package*.json ./ 25 | COPY bootstrap.js . 26 | COPY tsconfig.json . 27 | 28 | # Build intermediate image with dependencies 29 | FROM base AS dependencies 30 | 31 | RUN npm set progress=false && npm config set depth 0 32 | RUN npm install --only=production 33 | RUN cp -R node_modules prod_node_modules 34 | RUN npm install 35 | 36 | 37 | # Build the TypeScript application 38 | FROM dependencies AS build 39 | COPY . . 40 | RUN npm run build --production 41 | 42 | 43 | # Create a release image w/o devDependencies 44 | FROM base AS release 45 | 46 | ARG HOST_USER=${HOST_USER:-nodummy} 47 | ARG PROJECT_NAME=${PROJECT_NAME} 48 | 49 | USER ${HOST_USER} 50 | 51 | COPY --from=dependencies /home/${HOST_USER}/${PROJECT_NAME}/prod_node_modules ./node_modules 52 | COPY --from=build /home/${HOST_USER}/${PROJECT_NAME}/build ./build 53 | EXPOSE 8080 54 | CMD ["node", "-r", "./bootstrap.js", "build"] 55 | 56 | 57 | # Create a development image with devDependencies 58 | FROM node:10-alpine as dev 59 | 60 | ARG HOST_UID=${HOST_UID:-4000} 61 | ARG HOST_USER=${HOST_USER:-nodummy} 62 | ARG PROJECT_NAME=${PROJECT_NAME} 63 | 64 | RUN [ "${HOST_USER}" == "root" ] || \ 65 | (adduser -h /home/${HOST_USER} -D -u ${HOST_UID} ${HOST_USER} \ 66 | && chown -R "${HOST_UID}:${HOST_UID}" /home/${HOST_USER}) 67 | 68 | USER ${HOST_USER} 69 | 70 | COPY --from=build /home/${HOST_USER}/${PROJECT_NAME} /home/${HOST_USER}/${PROJECT_NAME} 71 | WORKDIR /home/${HOST_USER}/${PROJECT_NAME} 72 | CMD ["npm", "run", "dev"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Loc Nguyen 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------- 2 | # This Makefile was borrowed from https://github.com/LINKIT-Group/dockerbuild 3 | # Read the blog post here: https://itnext.io/docker-makefile-x-ops-sharing-infra-as-code-parts-ea6fa0d22946 4 | # -------------------------------------------------------------------- 5 | 6 | # If you see pwd_unknown showing up, this is why. Re-calibrate your system. 7 | PWD ?= pwd_unknown 8 | 9 | # PROJECT_NAME defaults to name of the current directory. 10 | # should not to be changed if you follow GitOps operating procedures. 11 | PROJECT_NAME = $(notdir $(PWD)) 12 | 13 | # Note. If you change this, you also need to update docker-compose.yml. 14 | # only useful in a setting with multiple services/ makefiles. 15 | SERVICE_TARGET := tsapp 16 | 17 | # if vars not set specifially: try default to environment, else fixed value. 18 | # strip to ensure spaces are removed in future editorial mistakes. 19 | # tested to work consistently on popular Linux flavors and Mac. 20 | ifeq ($(user),) 21 | # USER retrieved from env, UID from shell. 22 | HOST_USER ?= $(strip $(if $(USER),$(USER),nodummy)) 23 | HOST_UID ?= $(strip $(if $(shell id -u),$(shell id -u),4000)) 24 | else 25 | # allow override by adding user= and/ or uid= (lowercase!). 26 | # uid= defaults to 0 if user= set (i.e. root). 27 | HOST_USER = $(user) 28 | HOST_UID = $(strip $(if $(uid),$(uid),0)) 29 | endif 30 | 31 | THIS_FILE := $(lastword $(MAKEFILE_LIST)) 32 | CMD_ARGUMENTS ?= $(cmd) 33 | 34 | GIT_SHA := $(shell git rev-parse --short=6 HEAD) 35 | 36 | # export such that its passed to shell functions for Docker to pick up. 37 | export PROJECT_NAME 38 | export HOST_USER 39 | export HOST_UID 40 | 41 | # all our targets are phony (no files to check). 42 | .PHONY: shell help build rebuild up down login test clean prune 43 | 44 | # suppress makes own output 45 | #.SILENT: 46 | 47 | # shell is the first target. So instead of: make shell cmd="whoami", we can type: make cmd="whoami". 48 | # more examples: make shell cmd="whoami && env", make shell cmd="echo hello container space". 49 | # leave the double quotes to prevent commands overflowing in makefile (things like && would break) 50 | # special chars: '',"",|,&&,||,*,^,[], should all work. Except "$" and "`", if someone knows how, please let me know!). 51 | # escaping (\) does work on most chars, except double quotes (if someone knows how, please let me know) 52 | # i.e. works on most cases. For everything else perhaps more useful to upload a script and execute that. 53 | shell: 54 | ifeq ($(CMD_ARGUMENTS),) 55 | # no command is given, default to shell 56 | docker-compose -p $(PROJECT_NAME)_$(HOST_UID) run --rm $(SERVICE_TARGET) sh 57 | else 58 | # run the command 59 | docker-compose -p $(PROJECT_NAME)_$(HOST_UID) run --rm $(SERVICE_TARGET) sh -c "$(CMD_ARGUMENTS)" 60 | endif 61 | 62 | # Regular Makefile part for buildpypi itself 63 | help: 64 | @echo '' 65 | @echo 'Usage: make [TARGET] [EXTRA_ARGUMENTS]' 66 | @echo 'Targets:' 67 | @echo ' build build docker --image-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 68 | @echo ' rebuild rebuild docker --image-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 69 | @echo ' test test docker --container-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 70 | @echo ' up run as service --container-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 71 | @echo ' down bring down docker --container-- for current user :$(HOST_USER)(uid=$(HOST_UID))' 72 | @echo ' login run as service and login --container-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 73 | @echo ' clean remove docker --image-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 74 | @echo ' prune shortcut for docker system prune -af. Cleanup inactive containers and cache.' 75 | @echo ' shell run docker --container-- for current user: $(HOST_USER)(uid=$(HOST_UID))' 76 | @echo '' 77 | @echo 'Extra arguments:' 78 | @echo 'cmd=: make cmd="whoami"' 79 | @echo '# user= and uid= allows to override current user. Might require additional privileges.' 80 | @echo 'user=: make shell user=root (no need to set uid=0)' 81 | @echo 'uid=: make shell user=dummy uid=4000 (defaults to 0 if user= set)' 82 | 83 | rebuild: 84 | # force a rebuild by passing --no-cache 85 | docker-compose build --no-cache $(SERVICE_TARGET) 86 | 87 | up: 88 | # bring up the app and the database 89 | docker-compose -p $(PROJECT_NAME)_$(HOST_UID) up $(SERVICE_TARGET) tsappdb 90 | 91 | down: 92 | docker-compose down 93 | 94 | login: up 95 | # run as a service and attach to it 96 | docker exec -it $(PROJECT_NAME)_$(HOST_UID) sh 97 | 98 | build: 99 | # only build the container. Note, docker does this also if you apply other targets. 100 | docker-compose build $(SERVICE_TARGET) 101 | 102 | clean: 103 | # remove created images 104 | @docker-compose -p $(PROJECT_NAME)_$(HOST_UID) down --remove-orphans --rmi all 2>/dev/null \ 105 | && echo 'Image(s) for "$(PROJECT_NAME):$(HOST_USER)" removed.' \ 106 | || echo 'Image(s) for "$(PROJECT_NAME):$(HOST_USER)" already removed.' 107 | 108 | prune: 109 | # clean all that is not actively used 110 | docker system prune -af 111 | 112 | test: 113 | # here it is useful to add your own customised tests 114 | docker-compose -p $(PROJECT_NAME)_$(HOST_UID) run --rm $(SERVICE_TARGET) sh -c '\ 115 | echo "I am `whoami`. My uid is `id -u`." && echo "Docker runs!"' \ 116 | && echo success 117 | 118 | image: 119 | docker build --no-cache --target release -t $(PROJECT_NAME):latest . 120 | docker tag $(PROJECT_NAME):latest $(PROJECT_NAME):$(GIT_SHA) 121 | 122 | clean-image: 123 | docker rmi $(PROJECT_NAME):latest 124 | docker rmi $(PROJECT_NAME):$(GIT_SHA) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # typescript-node-starter 2 | 3 | | GitLab CI | 4 | | - | 5 | | [![pipeline status](https://gitlab.com/lochnguyen/typescript-node-starter/badges/master/pipeline.svg)](https://gitlab.com/lochnguyen/typescript-node-starter/commits/master) | 6 | 7 | Barebones starter kit for server apps with TypeScript 8 | 9 | ## Quick Start 10 | 11 | Install Node dependencies 12 | 13 | ```shell 14 | $ npm install 15 | ``` 16 | 17 | Run the test suite 18 | 19 | ```shell 20 | $ npm t 21 | ``` 22 | 23 | Run the code for development and watch for changes 24 | 25 | ```shell 26 | $ npm run dev 27 | ``` 28 | 29 | Compile the code for release 30 | 31 | ```shell 32 | $ npm run build 33 | ``` 34 | 35 | Run the compiled code 36 | 37 | ```shell 38 | $ node -r ./bootstrap.js build 39 | ``` 40 | 41 | ## Docker 42 | 43 | If you want to develop in a Docker container, this project along with PostgreSQL can be brought up with 44 | 45 | ```shell 46 | make up 47 | ``` 48 | 49 | And when you are done working 50 | 51 | ```shell 52 | make down 53 | ``` 54 | 55 | See the **docker-compose.yml** file for details on this set up. 56 | 57 | ### Production Image 58 | 59 | ```shell 60 | docker build --target release -t tsnodestarter:$(git rev-parse --short=7 HEAD) . 61 | ``` -------------------------------------------------------------------------------- /bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is needed for running the code compiled into the outDir configured 3 | * in tsconfig.json. Without it Node looks for files in the src/ folder. 4 | * 5 | * https://github.com/Microsoft/TypeScript/issues/10866#issuecomment-246929461 6 | */ 7 | 8 | const path = require('path'); 9 | const tsConfigPaths = require('tsconfig-paths'); 10 | const tsConfig = require('./tsconfig.json'); 11 | 12 | const baseUrl = path.join(__dirname, 'build'); 13 | 14 | tsConfigPaths.register({ 15 | baseUrl, 16 | paths: tsConfig.compilerOptions.paths 17 | }); -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | tsapp: 4 | # Makefile fills PROJECT_NAME to current directory name. 5 | # add UID to allow multiple users run this in parallel 6 | container_name: ${PROJECT_NAME}_${HOST_UID:-4000} 7 | hostname: ${PROJECT_NAME} 8 | build: 9 | context: . 10 | dockerfile: Dockerfile 11 | target: dev 12 | args: 13 | - HOST_UID=${HOST_UID:-4000} 14 | - HOST_USER=${HOST_USER:-nodummy} 15 | - PROJECT_NAME=${PROJECT_NAME} 16 | environment: 17 | - NODE_ENV=development 18 | - PORT=8080 19 | - LOG_LEVEL=debug 20 | - DATABASE_URL=postgres://dbuser:dbpass@tsappdb:5432/starterdb 21 | - UID=${HOST_UID:-4000} 22 | # Run with user priviliges by default. 23 | user: ${HOST_USER:-nodummy} 24 | image: ${PROJECT_NAME}:${HOST_USER:-nodummy} 25 | ports: 26 | - 8080:8080 27 | volumes: 28 | - ${PWD:-.}:/home/${HOST_USER}/${PROJECT_NAME} 29 | # Make sure to not mount the host node_modules 30 | - /home/${HOST_USER}/${PROJECT_NAME}/node_modules 31 | tsappdb: 32 | image: postgres:9.6-alpine 33 | container_name: tsappdb 34 | ports: 35 | - 5432:5432 36 | environment: 37 | - POSTGRES_PASSWORD=secret 38 | - POSTGRES_USER=postgres 39 | - POSTGRES_DB=starterdb -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-node-starter", 3 | "version": "1.2.0", 4 | "description": "", 5 | "main": "build/index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "clean": "rimraf build", 9 | "dev": "NODE_ENV=development nodemon --exec ./node_modules/.bin/ts-node -r tsconfig-paths/register -- ./src/index.ts", 10 | "lint": "./node_modules/.bin/eslint src --ext .js,.jsx,.ts,.tsx", 11 | "precommit-msg": "echo 'Pre-commit checks...' && exit 0", 12 | "prettier": "prettier \"./src/**/*.ts\"", 13 | "prettier:check": "npm run prettier -- --list-different", 14 | "prettier:write": "npm run prettier -- --write", 15 | "test": "cross-env NODE_ENV=test jest --coverage", 16 | "test:watch": "npm run test -- --watch" 17 | }, 18 | "precommit": [ 19 | "precommit-msg", 20 | "prettier:check", 21 | "lint" 22 | ], 23 | "prettier": { 24 | "parser": "typescript", 25 | "tabWidth": 4, 26 | "printWidth": 120, 27 | "singleQuote": true, 28 | "semi": true 29 | }, 30 | "author": "Loc Nguyen, lochnguyen@gmail.com", 31 | "license": "MIT", 32 | "devDependencies": { 33 | "@types/jest": "^24.9.0", 34 | "@types/node": "^13.1.8", 35 | "@typescript-eslint/eslint-plugin": "^2.17.0", 36 | "@typescript-eslint/eslint-plugin-tslint": "^2.17.0", 37 | "@typescript-eslint/parser": "^2.17.0", 38 | "cross-env": "^5.2.0", 39 | "eslint": "^6.8.0", 40 | "jest": "^24.9.0", 41 | "nodemon": "^2.0.2", 42 | "pre-commit": "^1.2.2", 43 | "prettier": "^1.19.1", 44 | "rimraf": "^2.6.2", 45 | "ts-jest": "^24.3.0", 46 | "ts-node": "^8.6.2", 47 | "typescript": "^3.7.5" 48 | }, 49 | "repository": "https://locnguyen@github.com/locnguyen/typescript-node-starter", 50 | "dependencies": { 51 | "dotenv": "^6.2.0", 52 | "tsconfig-paths": "^3.7.0" 53 | }, 54 | "jest": { 55 | "transform": { 56 | "^.+\\.tsx?$": "ts-jest" 57 | }, 58 | "testRegex": "(src)/.*\\.test\\.(jsx?|tsx?)$", 59 | "moduleDirectories": [ 60 | "node_modules" 61 | ], 62 | "moduleFileExtensions": [ 63 | "ts", 64 | "tsx", 65 | "js", 66 | "jsx", 67 | "json", 68 | "node" 69 | ], 70 | "moduleNameMapper": { 71 | "~/([^\\.]*)$": "/src/$1" 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | 3 | const options = { 4 | silent: !['development', 'test'].includes(process.env.NODE_ENV) 5 | }; 6 | 7 | dotenv.config(options); 8 | 9 | const config = { 10 | LOG_LEVEL: process.env.LOG_LEVEL || 'debug', 11 | NODE_ENV: process.env.NODE_ENV || 'development', 12 | PORT: process.env.PORT || '8080' 13 | }; 14 | 15 | export { config }; 16 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { square } from '~/modules/square'; 2 | 3 | console.log(`4^2 = ${square(4)}`); 4 | -------------------------------------------------------------------------------- /src/modules/square/index.test.ts: -------------------------------------------------------------------------------- 1 | import { square } from '~/modules/square'; 2 | 3 | describe('A squaring function', () => { 4 | it('should square the argument and return the result', () => { 5 | const result = square(8); 6 | expect(result).toBe(64); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/modules/square/index.ts: -------------------------------------------------------------------------------- 1 | export const square = (x: number): number => x * x; 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./src", 4 | "paths": { 5 | "~/*": ["./*"] 6 | }, 7 | "module": "commonjs", 8 | "moduleResolution": "node", 9 | "target": "es6", 10 | "sourceMap": true, 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": true, 13 | "noEmitHelpers": true, 14 | "noEmitOnError": true, 15 | "lib": ["es2017"], 16 | "outDir": "build" 17 | }, 18 | "compileOnSave": true, 19 | "include": [ 20 | "src/**/*" 21 | ], 22 | "exclude": [ 23 | "node_modules", 24 | "src/**/*.test.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": ["./node_modules/tslint-microsoft-contrib"], 3 | "rules": { 4 | "react-a11y-aria-unsupported-elements": true, 5 | "react-a11y-event-has-role": true, 6 | "react-a11y-image-button-has-alt": true, 7 | "react-a11y-img-has-alt": true, 8 | "react-a11y-props": true, 9 | "react-a11y-role-has-required-aria-props": true, 10 | "react-a11y-role": true, 11 | "react-a11y-role-supports-aria-props": true, 12 | "react-a11y-tabindex-no-positive": true, 13 | "react-a11y-proptypes": true, 14 | "align": [false], 15 | "arrow-parens": false, 16 | "ban": false, 17 | "chai-prefer-contains-to-index-of": true, 18 | "chai-vague-errors": true, 19 | "class-name": true, 20 | "comment-format": [false], 21 | "curly": true, 22 | "eofline": false, 23 | "export-name": false, 24 | "forin": true, 25 | "function-name": true, 26 | "import-name": true, 27 | "indent": [ 28 | true, 29 | "spaces" 30 | ], 31 | "interface-name": [false], 32 | "jquery-deferred-must-complete": true, 33 | "jsdoc-format": false, 34 | "label-position": true, 35 | "linebreak-style": [ 36 | true, 37 | "LF" 38 | ], 39 | "max-file-line-count": [false], 40 | "max-func-body-length": [ 41 | true, 42 | 100, 43 | { 44 | "ignore-parameters-to-function-regex": "describe" 45 | } 46 | ], 47 | "max-line-length": [ 48 | true, 49 | 140 50 | ], 51 | "member-access": true, 52 | "member-ordering": [false], 53 | "missing-jsdoc": false, 54 | "missing-optional-annotation": true, 55 | "mocha-avoid-only": true, 56 | "mocha-no-side-effect-code": true, 57 | "mocha-unneeded-done": true, 58 | "new-parens": true, 59 | "no-angle-bracket-type-assertion": false, 60 | "no-any": false, 61 | "no-arg": true, 62 | "no-backbone-get-set-outside-model": false, 63 | "no-banned-terms": true, 64 | "no-bitwise": true, 65 | "no-conditional-assignment": true, 66 | "no-consecutive-blank-lines": [true], 67 | "no-console": [ 68 | false, 69 | "debug", 70 | "info", 71 | "log", 72 | "time", 73 | "timeEnd", 74 | "trace" 75 | ], 76 | "no-constant-condition": true, 77 | "no-construct": true, 78 | "no-control-regex": true, 79 | "no-cookies": true, 80 | "no-debugger": true, 81 | "no-default-export": true, 82 | "no-delete-expression": true, 83 | "no-disable-auto-sanitization": true, 84 | "no-document-domain": true, 85 | "no-document-write": true, 86 | "no-duplicate-switch-case": true, 87 | "no-duplicate-parameter-names": true, 88 | "no-duplicate-variable": true, 89 | "no-empty": true, 90 | "no-empty-interface": true, 91 | "no-empty-line-after-opening-brace": false, 92 | "no-eval": true, 93 | "no-exec-script": true, 94 | "no-for-in": true, 95 | "no-for-in-array": false, 96 | "no-function-constructor-with-string-args": true, 97 | "no-function-expression": true, 98 | "no-http-string": [ 99 | true, 100 | "http://www.example.com/?.*", 101 | "http://www.examples.com/?.*" 102 | ], 103 | "no-increment-decrement": true, 104 | "no-inferrable-types": [false], 105 | "no-inner-html": true, 106 | "no-internal-module": false, 107 | "no-invalid-regexp": true, 108 | "no-invalid-this": true, 109 | "no-jquery-raw-elements": true, 110 | "no-mergeable-namespace": false, 111 | "no-missing-visibility-modifiers": false, 112 | "no-multiline-string": true, 113 | "no-multiple-var-decl": true, 114 | "no-namespace": false, 115 | "no-null-keyword": false, 116 | "no-octal-literal": true, 117 | "no-reference": true, 118 | "no-regex-spaces": true, 119 | "no-require-imports": true, 120 | "no-reserved-keywords": true, 121 | "no-shadowed-variable": false, 122 | "no-single-line-block-comment": true, 123 | "no-sparse-arrays": true, 124 | "no-stateless-class": false, 125 | "no-string-based-set-immediate": true, 126 | "no-string-based-set-interval": true, 127 | "no-string-based-set-timeout": true, 128 | "no-string-literal": true, 129 | "no-suspicious-comment": false, 130 | "no-switch-case-fall-through": true, 131 | "no-trailing-whitespace": true, 132 | "no-typeof-undefined": true, 133 | "no-unnecessary-bind": true, 134 | "no-unnecessary-field-initialization": true, 135 | "no-unnecessary-local-variable": true, 136 | "no-unnecessary-override": true, 137 | "no-unnecessary-semicolons": true, 138 | "no-unsupported-browser-code": false, 139 | "no-unsafe-finally": true, 140 | "no-unused-expression": true, 141 | "no-unused-imports": false, 142 | "no-use-before-declare": true, 143 | "no-var-keyword": true, 144 | "no-var-requires": true, 145 | "no-this-assignment": true, 146 | "no-with-statement": true, 147 | "object-literal-sort-keys": false, 148 | "object-literal-key-quotes": [ 149 | false, 150 | "as-needed" 151 | ], 152 | "one-line": [ 153 | true, 154 | "check-open-brace", 155 | "check-catch", 156 | "check-else", 157 | "check-whitespace" 158 | ], 159 | "one-variable-per-declaration": [true], 160 | "only-arrow-functions": [false], 161 | "ordered-imports": [false], 162 | "prefer-array-literal": true, 163 | "prefer-const": true, 164 | "prefer-type-cast": true, 165 | "promise-must-complete": true, 166 | "quotemark": [ 167 | true, 168 | "single" 169 | ], 170 | "radix": false, 171 | "react-a11y-titles": true, 172 | "react-iframe-missing-sandbox": true, 173 | "react-no-dangerous-html": true, 174 | "react-this-binding-issue": true, 175 | "react-tsx-curly-spacing": true, 176 | "react-unused-props-and-state": true, 177 | "restrict-plus-operands": false, 178 | "semicolon": [true, "ignore-bound-class-methods"], 179 | "switch-default": false, 180 | "trailing-comma": [ 181 | true, 182 | { 183 | "singleline": "never", 184 | "multiline": "never" 185 | } 186 | ], 187 | "triple-equals": [ 188 | true, 189 | "allow-null-check" 190 | ], 191 | "typedef": [ 192 | true, 193 | "parameter", 194 | "property-declaration", 195 | "member-variable-declaration" 196 | ], 197 | "typedef-whitespace": [false], 198 | "underscore-consistent-invocation": true, 199 | "use-isnan": true, 200 | "use-named-parameter": true, 201 | "typeof-compare": true, 202 | "variable-name": true, 203 | "whitespace": [ 204 | true, 205 | "check-branch", 206 | "check-decl", 207 | "check-operator", 208 | "check-separator", 209 | "check-type" 210 | ], 211 | "react-a11y-lang": true, 212 | "react-a11y-meta": true, 213 | "react-a11y-anchors": true, 214 | "react-anchor-blank-noopener": true, 215 | "insecure-random": true, 216 | "possible-timing-attack": true, 217 | "non-literal-require": true, 218 | "adjacent-overload-signatures": false, 219 | "array-type": [false], 220 | "completed-docs": [false], 221 | "cyclomatic-complexity": [false], 222 | "file-header": [false], 223 | "max-classes-per-file": [false], 224 | "no-parameter-properties": false, 225 | "object-literal-shorthand": false, 226 | "prefer-for-of": false 227 | } 228 | } 229 | --------------------------------------------------------------------------------