├── .nvmrc ├── .node-version ├── src ├── index.ts └── __tests__ │ └── greet.test.ts ├── commitlint.config.js ├── .prettierignore ├── nodemon.json ├── .prettierrc ├── renovate.json ├── .sonarcloud.properties ├── jest.config.js ├── .editorconfig ├── .github └── workflows │ ├── test.yml │ └── publish.yml ├── .eslintrc ├── LICENSE ├── tsconfig.json ├── .gitignore ├── package.json └── README.md /.nvmrc: -------------------------------------------------------------------------------- 1 | 12.16.1 2 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 12.13.0 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export const greet = (name: string) => `Hello ${name}` 2 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { extends: ["@commitlint/config-conventional"] }; 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | /dist 4 | /coverage 5 | /tmp 6 | 7 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src", "types", "@types"], 3 | "ext": "ts", 4 | "exec": "yarn watch && npm link" 5 | } 6 | -------------------------------------------------------------------------------- /src/__tests__/greet.test.ts: -------------------------------------------------------------------------------- 1 | import { greet } from '..' 2 | 3 | test('My Greeter', () => { 4 | expect(greet('Carl')).toBe('Hello Carl') 5 | }) 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "singleQuote": true, 4 | "semi": false, 5 | "trailingComma": "all", 6 | "printWidth": 120 7 | } 8 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "semanticCommits": true, 3 | "packageRules": [ 4 | { 5 | "depTypeList": ["devDependencies"], 6 | "automerge": true 7 | } 8 | ], 9 | "ignoreDeps": [], 10 | "extends": ["config:base"] 11 | } 12 | -------------------------------------------------------------------------------- /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | # Path to sources 2 | #sonar.sources=. 3 | #sonar.exclusions= 4 | #sonar.inclusions= 5 | 6 | # Path to tests 7 | #sonar.tests= 8 | #sonar.test.exclusions= 9 | #sonar.test.inclusions= 10 | 11 | # Source encoding 12 | #sonar.sourceEncoding=UTF-8 13 | 14 | # Exclusions for copy-paste detection 15 | #sonar.cpd.exclusions= 16 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | collectCoverage: true, 5 | collectCoverageFrom: ["src/**/*.ts", "src/**/*.js"], 6 | coverageThreshold: { 7 | global: { 8 | branches: 100, 9 | functions: 100, 10 | lines: 100, 11 | statements: 100, 12 | }, 13 | }, 14 | testEnvironment: "node", 15 | preset: "ts-jest", 16 | }; 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.txt] 16 | trim_trailing_whitespace = false 17 | 18 | [*.json] 19 | insert_final_newline = false 20 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package Lint And Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - "*" 7 | - "!master" 8 | pull_request: 9 | branches: 10 | - "*" 11 | 12 | jobs: 13 | lint-and-test: 14 | name: Test on node 12 and ubuntu-latest 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v1 19 | with: 20 | fetch-depth: 1 21 | - uses: actions/setup-node@v1 22 | with: 23 | node-version: 12 24 | - run: yarn 25 | - run: yarn lint 26 | - run: yarn build 27 | - run: yarn test 28 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { "es6": true, "node": true }, 3 | "extends": [ 4 | "eslint:recommended", 5 | "prettier", 6 | "plugin:@typescript-eslint/eslint-recommended", 7 | "plugin:@typescript-eslint/recommended", 8 | "prettier/@typescript-eslint", 9 | "plugin:prettier/recommended" 10 | ], 11 | "parser": "@typescript-eslint/parser", 12 | "parserOptions": { 13 | "ecmaVersion": 2018, 14 | "sourceType": "module" 15 | // "project": "./tsconfig.json" 16 | }, 17 | "plugins": ["@typescript-eslint", "prettier"], 18 | "rules": { 19 | "prettier/prettier": ["error"], 20 | "@typescript-eslint/no-explicit-any": 0, 21 | "@typescript-eslint/explicit-function-return-type": 0 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 beeman 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 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "lib": ["es5", "es6", "es2015", "es2016", "es2017", "es2018", "esnext"], 6 | "declaration": true, 7 | "sourceMap": true, 8 | "outDir": "./dist", 9 | "removeComments": true, 10 | "strict": true, 11 | "noImplicitAny": true, 12 | "strictNullChecks": true, 13 | "strictFunctionTypes": true, 14 | "strictPropertyInitialization": true, 15 | "noImplicitThis": true, 16 | "alwaysStrict": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noImplicitReturns": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "moduleResolution": "node", 22 | "rootDirs": ["./", "./src"], 23 | "typeRoots": ["./types", "./@types", "node_modules/@types"], 24 | "types": ["node", "jest"], 25 | "esModuleInterop": true, 26 | "preserveConstEnums": true, 27 | "suppressImplicitAnyIndexErrors": true, 28 | "forceConsistentCasingInFileNames": true, 29 | "incremental": true 30 | }, 31 | "include": ["src"], 32 | "exclude": ["node_modules", "**/__tests__/*", "coverage"] 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # next.js build output 63 | .next 64 | 65 | # npm build output 66 | /dist 67 | 68 | .sonarlint/ 69 | 70 | .idea/ 71 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package Lint, Test and Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | 8 | jobs: 9 | lint-and-test: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | with: 14 | fetch-depth: 1 15 | - uses: actions/setup-node@v1 16 | with: 17 | node-version: 12 18 | - run: yarn 19 | - run: yarn lint 20 | - run: yarn test 21 | 22 | build-and-publish-gpr: 23 | needs: lint-and-test 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v1 27 | with: 28 | fetch-depth: 1 29 | - uses: actions/setup-node@v1 30 | with: 31 | node-version: 12 32 | registry-url: https://npm.pkg.github.com/ 33 | - run: yarn 34 | - run: yarn build 35 | - run: yarn semantic-release 36 | env: 37 | NPM_TOKEN: ${{secrets.NPM_TOKEN}} 38 | GH_TOKEN: ${{secrets.GH_TOKEN}} 39 | CI: true 40 | 41 | build-and-publish-npm: 42 | needs: build-and-publish-gpr 43 | runs-on: ubuntu-latest 44 | steps: 45 | - uses: actions/checkout@v1 46 | with: 47 | fetch-depth: 1 48 | - uses: actions/setup-node@v1 49 | with: 50 | node-version: 12 51 | registry-url: https://registry.npmjs.org/ 52 | - run: yarn 53 | - run: yarn build 54 | - run: yarn semantic-release 55 | env: 56 | NPM_TOKEN: ${{secrets.NPM_TOKEN}} 57 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 58 | GH_TOKEN: ${{secrets.GH_TOKEN}} 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template-typescript-package", 3 | "version": "0.0.0-development", 4 | "description": "A boilerplate repo for publishing typescript packages to npm", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "lint": "eslint './src/**/*.{js,ts,tsx}'", 9 | "test": "jest", 10 | "test:watch": "jest --watchAll", 11 | "build": "tsc", 12 | "watch": "tsc -w", 13 | "start": "npm link && nodemon", 14 | "semantic-release": "semantic-release" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/beeman/template-typescript-package.git" 19 | }, 20 | "keywords": [ 21 | "TypeScript", 22 | "Package", 23 | "Starter" 24 | ], 25 | "author": { 26 | "name": "Bram Borggreve", 27 | "email": "borggreve@gmail.com" 28 | }, 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/beeman/template-typescript-package/issues" 32 | }, 33 | "homepage": "https://github.com/beeman/template-typescript-package#readme", 34 | "husky": { 35 | "hooks": { 36 | "pre-commit": "yarn lint && npm test", 37 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", 38 | "pre-push": "yarn lint && npm test" 39 | } 40 | }, 41 | "devDependencies": { 42 | "@commitlint/cli": "11.0.0", 43 | "@commitlint/config-conventional": "11.0.0", 44 | "@types/jest": "26.0.15", 45 | "@types/node": "12.12.20", 46 | "@typescript-eslint/eslint-plugin": "4.8.2", 47 | "@typescript-eslint/parser": "4.8.2", 48 | "eslint": "7.14.0", 49 | "eslint-config-prettier": "6.15.0", 50 | "eslint-plugin-prettier": "3.1.4", 51 | "husky": "4.3.0", 52 | "jest": "26.6.3", 53 | "nodemon": "2.0.6", 54 | "prettier": "2.2.0", 55 | "semantic-release": "17.3.0", 56 | "ts-jest": "26.4.4", 57 | "typescript": "4.1.2" 58 | }, 59 | "files": [ 60 | "dist/**/*" 61 | ], 62 | "dependencies": {} 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # template-typescript-package 2 | 3 | ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/beeman/template-typescript-package.svg) 4 | ![GitHub repo size](https://img.shields.io/github/repo-size/beeman/template-typescript-package.svg) 5 | ![npm](https://img.shields.io/npm/dw/template-typescript-package.svg) 6 | ![npm](https://img.shields.io/npm/dm/template-typescript-package.svg) 7 | ![npm](https://img.shields.io/npm/dy/template-typescript-package.svg) 8 | ![npm](https://img.shields.io/npm/dt/template-typescript-package.svg) 9 | ![NPM](https://img.shields.io/npm/l/template-typescript-package.svg) 10 | ![npm](https://img.shields.io/npm/v/template-typescript-package.svg) 11 | ![GitHub last commit](https://img.shields.io/github/last-commit/beeman/template-typescript-package.svg) 12 | ![npm collaborators](https://img.shields.io/npm/collaborators/template-typescript-package.svg) 13 | 14 | A boilerplate repo for publishing typescript packages to npm 15 | 16 | ## Usage 17 | 18 | Some notes on how to use this repo. Some day I'll hopefully automate the biggest part of this. 19 | 20 | ### Clone the repo or [generate](https://github.com/beeman/template-typescript-package/generate) your repo: 21 | 22 | ```shell script 23 | npx degit https://github.com/beeman/template-typescript-package my-new-package 24 | ``` 25 | 26 | ### Initialize the new project 27 | 28 | 29 | ```shell script 30 | cd my-new-package 31 | yarn # to install the deps 32 | git init # to initialize a new Git repo 33 | # Manually create a remote repo and follow the instructions OR: 34 | hub create # Use this amazing tool called 'hub': https://github.com/github/hub 35 | ``` 36 | 37 | #### Update meta data: 38 | 39 | Update the following fields in `package.json`: 40 | 41 | - name 42 | - description 43 | - repository 44 | - keywords 45 | - author 46 | - license 47 | - bugs 48 | - homepage 49 | 50 | Make sure to don't change the `version` property, versioning this package is handled by `semantic-release`! 51 | 52 | #### Update README 53 | 54 | Basically you want to search/replace the repo and package name to match your repo/package name and add any new info. 55 | 56 | ### Getting the GitHub and NPM tokens 57 | 58 | #### GitHub 59 | 60 | - Log in to GitHub. 61 | - Navigate to [https://github.com/settings/tokens](https://github.com/settings/tokens). 62 | - Click `Generate new token`. 63 | - Fill in the `note` field so you remember what the token is for. 64 | - Select the `write:packages` scope. This will also enable the `repo` and `read:packages` scopes. 65 | - Click `Generate token`. 66 | - Copy the code and store it to use in the next step. 67 | 68 | #### NPM 69 | 70 | - Log in to NPM. 71 | - Click the Tokens link from the top-right menu. 72 | - Click Create New Token 73 | - Select `Read and Publish` then click `Create Token`. 74 | - Copy the code and store it to use in the next step. 75 | 76 | ### Setting the GitHub and NPM tokens 77 | 78 | - Open your new repo on GitHub. 79 | - Navigate to `Settings` then `Secrets`. 80 | - Click `Add a new secret`. 81 | - Add the `GH_TOKEN` secret with the GitHub token. 82 | - Click `Add a new secret` again. 83 | - Add the `NPM_TOKEN` secret with the NPM token. 84 | 85 | Your repo is now set up to publish packages to NPM and the GitHub Package Registry. 86 | 87 | ### Write your code 88 | 89 | Write your amazing new code and make sure to update the tests! 90 | 91 | You can run `yarn lint` and `yarn test` to check if your project will pass CI. 92 | 93 | ### Publish it 94 | 95 | With a `git push` you will create a new version and publish it to `npm`. 96 | 97 | ```shell script 98 | git commit -m "feat: initial commit" 99 | git push origin master 100 | ``` 101 | 102 | ## Credits 103 | 104 | Based on [npm-typescript-package-boilerplate](https://github.com/93v/npm-typescript-package-boilerplate) with a few changes. 105 | 106 | ## MIT License 107 | --------------------------------------------------------------------------------