Initial commit

This commit is contained in:
Garrone Joseph 2021-02-20 11:51:44 +01:00
commit 997a62d821
25 changed files with 13806 additions and 0 deletions

4
.eslintignore Normal file
View File

@ -0,0 +1,4 @@
/node_modules/
/dist/
/.eslintrc.js
/CHANGELOG.md

16
.eslintrc.js Normal file
View File

@ -0,0 +1,16 @@
module.exports = {
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint",
],
"rules": {
"no-extra-boolean-cast": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
},
};

89
.github/workflows/ci.yaml vendored Normal file
View File

@ -0,0 +1,89 @@
name: ci
on:
push:
branches:
- develop
pull_request:
branches:
- develop
jobs:
test_lint:
runs-on: ubuntu-latest
if: ${{ !github.event.created }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- run: npm ci
- name: Making sure 'npm run lint' and 'npm run format' does not changes anything.
run: |
npm run lint:check
npm run format:check
test_node:
runs-on: ${{ matrix.os }}
needs: test_lint
strategy:
matrix:
node: [ '14', '13', '12', '11', '10', '8' ]
os: [ windows-latest, ubuntu-latest ]
name: Test with Node v${{ matrix.node }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm run build
- run: npm run test
trigger_publish:
name: Trigger publish.yaml workflow if package.json version updated ( and secrets.PAT is set ).
runs-on: ubuntu-latest
env:
PAT: ${{secrets.PAT}}
if: github.event_name == 'push' && github.event.head_commit.author.name != 'ts_ci'
needs: test_node
steps:
- name: Get version on latest
id: v_latest
uses: garronej/github_actions_toolkit@v1.9
with:
action_name: get_package_json_version
owner: ${{github.repository_owner}}
repo: ${{github.event.repository.name}}
branch: latest
compare_to_version: '0.0.0'
- name: Get version on develop
id: v_develop
uses: garronej/github_actions_toolkit@v1.9
with:
action_name: get_package_json_version
owner: ${{github.repository_owner}}
repo: ${{github.event.repository.name}}
branch: ${{ github.sha }}
compare_to_version: ${{steps.v_latest.outputs.version || '0.0.0'}}
- name: 'Trigger the ''publish'' workflow'
if: ${{ !!env.PAT && steps.v_develop.outputs.compare_result == '1' }}
uses: garronej/github_actions_toolkit@v1.9
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
with:
action_name: dispatch_event
owner: ${{github.repository_owner}}
repo: ${{github.event.repository.name}}
event_type: publish
client_payload_json: |
${{
format(
'{{"from_version":"{0}","to_version":"{1}","repo":"{2}"}}',
steps.v_latest.outputs.version,
steps.v_develop.outputs.version,
github.event.repository.name
)
}}

106
.github/workflows/publish.yaml vendored Normal file
View File

@ -0,0 +1,106 @@
on:
repository_dispatch:
types: publish
jobs:
update_changelog_and_sync_package_lock_version:
name: Update CHANGELOG.md and make sure package.json and package-lock.json versions matches.
runs-on: ubuntu-latest
steps:
- name: Synchronize package.json and package-lock.json version if needed.
uses: garronej/github_actions_toolkit@v1.9
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
with:
action_name: sync_package_and_package_lock_version
owner: ${{github.repository_owner}}
repo: ${{github.event.client_payload.repo}}
branch: develop
commit_author_email: ts_ci@github.com
- name: Update CHANGELOG.md
if: ${{ !!github.event.client_payload.from_version }}
uses: garronej/github_actions_toolkit@v1.9
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
with:
action_name: update_changelog
owner: ${{github.repository_owner}}
repo: ${{github.event.client_payload.repo}}
branch_behind: latest
branch_ahead: develop
commit_author_email: ts_ci@github.com
exclude_commit_from_author_names_json: '["ts_ci"]'
publish:
runs-on: ubuntu-latest
needs: update_changelog_and_sync_package_lock_version
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
ref: develop
- name: Remove .github directory, useless on 'latest' branch
run: rm -r .github
- name: Remove branch 'latest'
continue-on-error: true
run: |
git branch -d latest || true
git push origin :latest
- name: Create the new 'latest' branch
run: |
git branch latest
git checkout latest
- uses: actions/setup-node@v1
- run: npm ci
- run: npm run enable_short_import_path
env:
DRY_RUN: "0"
- name: (DEBUG) Show how the files have been moved to enable short import
run: ls -lR
- name: Publishing on NPM
run: |
if [ "$(npm show . version)" = "$VERSION" ]; then
echo "This version is already published"
exit 0
fi
if [ "$NPM_TOKEN" = "" ]; then
echo "Can't publish on NPM, You must first create a secret called NPM_TOKEN that contains your NPM auth token. https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets"
false
fi
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > .npmrc
npm publish
rm .npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
VERSION: ${{ github.event.client_payload.to_version }}
- name: Commit changes
run: |
git config --local user.email "ts_ci@github.com"
git config --local user.name "ts_ci"
git add -A
git commit -am "Enabling shorter import paths [automatic]"
- run: git push origin latest
- name: Release body
id: id_rb
run: |
if [ "$FROM_VERSION" = "" ]; then
echo "::set-output name=body::🚀"
else
echo "::set-output name=body::📋 [CHANGELOG](https://github.com/$OWNER/$REPO/blob/$REF/CHANGELOG.md)"
fi
env:
FROM_VERSION: ${{ github.event.client_payload.from_version }}
OWNER: ${{github.repository_owner}}
REPO: ${{github.event.client_payload.repo}}
REF: v${{github.event.client_payload.to_version}}
- name: Create Release
uses: garronej/create-release@master
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
with:
tag_name: v${{ github.event.client_payload.to_version }}
release_name: Release v${{ github.event.client_payload.to_version }}
branch: latest
draft: false
prerelease: false
body: ${{ steps.id_rb.outputs.body }}

View File

@ -0,0 +1,65 @@
name: template_initialization
on:
create:
branches:
- develop
jobs:
template_initialization:
runs-on: ubuntu-latest
steps:
- name: Checking availability for module name ${{github.event.repository.name}} on NPM.
id: id1
uses: garronej/github_actions_toolkit@v1.9
with:
action_name: is_well_formed_and_available_module_name
module_name: ${{github.event.repository.name}}
- name: Checks results
run: |
if [ "$IS_VALID_NODE_MODULE_NAME" = "false" ]; then
echo $MODULE_NAME" is not a valid node module name"
false
fi
if [ "$IS_AVAILABLE_ON_NPM" = "false" ]; then
echo "WARNING: There is already a NPM module named "$MODULE_NAME", if you are not the owner consider picking another name"
fi
true
env:
MODULE_NAME: ${{github.event.repository.name}}
IS_VALID_NODE_MODULE_NAME: ${{steps.id1.outputs.is_valid_node_module_name}}
IS_AVAILABLE_ON_NPM: ${{steps.id1.outputs.is_available_on_npm}}
- uses: actions/checkout@v2
- run: mv README.template.md README.md
- run: mv LICENSE.template LICENSE
- name : String replace
id: id2
uses: garronej/github_actions_toolkit@v1.9
with:
action_name: string_replace
input_string: ${{github.event.repository.name}}
search_value: '-'
replace_value: '_'
- name: Replace tokens in README.MD and package.json
uses: cschleiden/replace-tokens@v1
with:
files: '["README.md","package.json","LICENSE","package-lock.json"]'
env:
REPO_NAME: ${{ github.event.repository.name }}
USER_OR_ORG: ${{ github.repository_owner }}
DESC: ${{ github.event.repository.description }}
REPO_NAME_NO_DASHES: ${{ steps.id2.outputs.replace_result }}
- name: Remove this workflow, it only needs to be run once.
run: rm .github/workflows/template_initialization.yaml
- name: Commit files
run: |
git config --local user.email "ts_ci@github.com"
git config --local user.name "ts_ci"
git commit -am "Replacing the template's placeholders"
- name: Push changes
uses: ad-m/github-push-action@v0.5.0
with:
github_token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
branch: develop

43
.gitignore vendored Normal file
View File

@ -0,0 +1,43 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
.vscode
.DS_Store
/dist

5
.prettierignore Normal file
View File

@ -0,0 +1,5 @@
/node_modules/
/dist/
/.eslintrc.js
/docs/
/CHANGELOG.md

11
.prettierrc.json Normal file
View File

@ -0,0 +1,11 @@
{
"printWidth": 80,
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": false,
"quoteProps": "preserve",
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "avoid"
}

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Joseph Garrone
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

21
LICENSE.template Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 GitHub user u/#{USER_OR_ORG}#
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

406
README.md Normal file
View File

@ -0,0 +1,406 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/6702424/82094662-cd17c200-96fd-11ea-8645-808344bad951.png">
</p>
<p align="center">
<i> A template to assist you in creating and publishing TypeScript modules on NPM </i>
<br>
<br>
</p>
---
# Presentation
This template automates the boring and tedious tasks of:
- Filling up the ``package.json``
- Setting up Typescript.
- Writing a [README.md](https://github.com/garronej/ts_ci/blob/master/README.template.md) with decent presentation and instructions on how to install/import your module.
- Testing on multiple Node version running on Ubuntu and Windows before publishing.
- Maintaining a CHANGELOG.
- Publishing on NPM and creating corresponding GitHub releases.
Besides, good stuff that comes with using this template:
- No dist files are tracked on the ``master`` branch.
- Shorter specific file import path.
``import {...} from "my_module/theFile"`` instead of the usual
``import {...} from "my_module/dist/theFile"``
- CDN distribution for importing from an ``.html`` file with a ``<script>`` tag.
- A branch ``latest`` always in sync with the latest release.
- When your users hit *"Go to Definition"* they get redirected to the actual ``.ts`` source file instead of the ``.d.ts``.
( Feature disabled by default, refer to [instructions](#enabling-go-to-definition-to-redirect-to-the-source-ts-file) on how to enable it ).
- ESlint and Prettier are automatically run against files staged for commit. ( You can [disable](#disable-linting-and-formatting) this feature. )
If you want your module to support Deno as well checkout [denoify_ci](https://github.com/garronej/denoify_ci).
# Table of content
- [Presentation](#presentation)
- [Table of content](#table-of-content)
- [How to use](#how-to-use)
- [Fork it ( click use the template )](#fork-it--click-use-the-template-)
- [Enable automatic publishing](#enable-automatic-publishing)
- [Few things you need to be aware of before getting started](#few-things-you-need-to-be-aware-of-before-getting-started)
- [Customization:](#customization)
- [Changing the directories structure](#changing-the-directories-structure)
- [Enabling "Go to Definition" to redirect to the source ``.ts`` file](#enabling-go-to-definition-to-redirect-to-the-source-ts-file)
- [Swipe the image in the ``README.md``](#swipe-the-image-in-the-readmemd)
- [Disable linting and formatting](#disable-linting-and-formatting)
- [Disable Prettier](#disable-prettier)
- [Disable Eslint and Prettier altogether](#disable-eslint-and-prettier-altogether)
- [Disable CDN build](#disable-cdn-build)
- [Completely disable](#completely-disable)
- [Only disable ES Module build ( ``dist/zz_esm/*`` )](#only-disable-es-module-build--distzz_esm-)
- [Remove unwanted dev dependencies](#remove-unwanted-dev-dependencies)
- [Customizing the Badges](#customizing-the-badges)
- [Accessing files outside the ``dist/`` directory](#accessing-files-outside-the-dist-directory)
- [The automatically updated ``CHANGELOG.md``](#the-automatically-updated-changelogmd)
- [Video demo](#video-demo)
- [Examples of auto-generated readme](#examples-of-auto-generated-readme)
- [Creating a documentation website for your project](#creating-a-documentation-website-for-your-project)
- [Creating a landing page for your project](#creating-a-landing-page-for-your-project)
# How to use
## Fork it ( click use the template )
- Click on ![image](https://user-images.githubusercontent.com/6702424/98155461-92395e80-1ed6-11eb-93b2-98c64453043f.png)
- The repo name you will choose will be used as a module name for NPM so:
- Be sure it makes for a valid NPM module name.
- Check if there is not already a NPM module named like that.
- The description you provide will be the one used on NPM and in ``package.json`` ( you can change it later )
Once you've done that a GitHub action workflow will set up the ``README.md`` and the ``package.json``
for you, wait a couple of minutes for it to complete ( a bot will push ). You can follow the job advancement in the "Action" tab.
(**warning** please read [this](#few-things-you-need-to-be-aware-of-before-getting-started))
Each time you will push changes ``npm test`` will be run on remote docker containers against multiple node versions if everything passes you will get a green ``ci`` badges in your readme.
## Enable automatic publishing
Once you are ready to make your package available on NPM you
will need to provide two tokens so that the workflow can publish on your behalf:
Go to repository ``Settings`` tab, then ``Secrets`` you will need to add two new secrets:
- ``NPM_TOKEN``, you NPM authorization token.
- ``PAT``, GitHub **P**ersonal **A**ccess **T**oken with the **repo** authorization. [link](https://github.com/settings/tokens)
To trigger publishing edit the ``package.json`` ``version`` field ( ``0.0.0``-> ``0.0.1`` for example) then push changes... that's all !
The publishing will actually be performed only if ``npm test`` passes.
# Few things you need to be aware of before getting started
- You probably want to "Use this template" ( the green button ) instead of forking the repo.
- The files to include in the NPM bundle are cherry-picked using the ``package.json`` ``files`` field.
If you don't want to bother and includes everything just remove the ``files`` field from the ``package.json``.
- If you are going to programmatically load files outside of the ``dis/`` directory ( like the ``package.json`` or files inside ``res/`` ) be mindful that the paths might not be the one you expect. [Details](#accessing-files-outside-the-dist-directory).
- The template does not support ``.npmignore`` ( it use the safer ``package.json`` ``files`` instead ).
- The template does not support ``.npmrc``.
# Customization:
## Changing the directories structure
<details>
<summary>Click to expand</summary>
All your source files must remain inside the ``src`` dir, you can change how things are organized inside the source directory
but don't forget to update your ``package.json`` ``main``, ``type`` and ``files`` fields and ``tsconfig.esm.json`` ``include`` field when appropriate.
</details>
## Enabling "Go to Definition" to redirect to the source ``.ts`` file
<details>
<summary>Click to expand</summary>
There is no denying that it is more convenient when clicking "Go To Definition" to get redirected to
a file ``.ts`` file rather than to a ``.d.ts``.
To enable this feature simply point to the ``package.json``'s ``types`` filed to the ``main``'s source
file instead the type definition file ``.d.ts``.
For example you would replace:
```json
{
"main": "dist/index.js",
"types": "dist/index.d.ts",
}
```
by:
```json
{
"main": "dist/index.js",
"types": "src/index.ts",
}
```
Enabling this feature comes at a cost though. Be aware that if you use [optional chaining](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining) or [nullish coalescing](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing) for example, your module will only be importable
in projects using typescript 3.7 or newer ( version that introduces theses features ).
It is important to keep your project compatible with older TS version because
- You don't want to force your users to update the typescript version they use in their project,
updating typescript might break some other things in their code.
- In certain environments updating TypeScript is not an option. Take [Stackblitz](https://stackblitz.com)
for example.
</details>
## Swipe the image in the ``README.md``
<details>
<summary>Click to expand</summary>
A good way to host your repo image is to open an issue named ASSET in your project, close it, create a comment, drag and drop the picture you want to use and that's it. You have a link that you can replace in the ``README.md``.
While you are at it submit this image as *social preview* in your repos github page's settings so that when you share on
Twitter or Reddit you don't get your GitHub profile picture to show up.
</details>
## Disable linting and formatting
### Disable Prettier
<details>
<summary>Click to expand</summary>
[Prettier](https://prettier.io) is opinionated, it is OK to want to break free from it.
Remove these ``package.json``'s ``scripts``:
- ``_format``
- ``format``
- ``format:check``
Remove these ``package.json``'s ``devDependencies``:
- ``prettier``
- ``eslint-config-prettier``
In the ``package.json``'s ``lint-staged`` field remove ``"*.{`s,json,md}": [ "prettier --write" ]``
From ``.eslintrc.js``, remove the line: ``"prettier/@typescript-eslint",``.
Delete these files:
- ``.prettierignore``
- ``.prettierrc.json``
In ``.github/workflows/ci.yaml`` remove the line ``npm run format:check`` from the ``test_lint`` job.
</details>
### Disable Eslint and Prettier altogether
<details>
<summary>Click to expand</summary>
Remove these ``package.json``'s ``scripts``:
- ``_format``
- ``format``
- ``format:check``
- ``lint:check``
- ``lint``
Remove these ``package.j`on``'s ``devDependencies``:
- ``prettier``
- ``eslint-config-prettier``
- ``eslint``
- ``@typescript-eslint/parser``
- ``@typescript-eslint/eslint-plugin``
- ``husky``
Remove the ``lint-staged`` and ``husky`` fields from the ``package.json``.
Delete these files:
- ``.prettierignore``
- ``.prettierrc.json``
- ``.eslintignore``
- ``.eslintrc.js``
In ``.github/workflows/ci.yaml`` remove the ``test_lint`` job and the line ``needs: test_lint``.
</details>
## Disable CDN build
### Completely disable
<details>
<summary>Click to expand</summary>
If your project does not target the browser or if you are not interested in offering CDN distribution:
- Remove all ``cdn:*`` npm scripts and ``npm run cdn`` from the `build` script ( in ``package.json`` ).
- Remove ``./tsconfig.esm.json``
- Remove ``simplifyify`` and ``terser`` from dev dependencies.
</details>
### Only disable ES Module build ( ``dist/zz_esm/*`` )
<details>
<summary>Click to expand</summary>
If ``npm run build`` fail because ``tsc -p tsconfig.esm.json`` gives errors you may want to remove the ESM
build but keep the ``bundle.js`` and ``bundle.min.js``. To do that:
In ``package.json`` replace theses ``scripts``:
```json
{
"cdn:bundle:.js": "simplifyify dist/index.js -s #{REPO_NAME}# -o dist/bundle.js --debug --bundle",
"cdn:bundle:.min.js": "terser dist/bundle.js -cmo dist/bundle.min.js",
"cdn:bundle": "npm run cdn:bundle:.js && npm run cdn:bundle:.min.js",
"cdn:esm": "tsc -p tsconfig.esm.json",
"cdn": "npm run cdn:bundle && npm run cdn:esm",
}
```
By theses ones:
```json
{
"cdn:.js": "simplifyify dist/index.js -s #{REPO_NAME}# -o dist/bundle.js --debug --bundle",
"cdn:.min.js": "terser dist/bundle.js -cmo dist/bundle.min.js",
"cdn": "npm run cdn:.js && npm run cdn:.min.js",
}
```
Remove ``tsconfig.esm.json``. ( file at the root of the project )
Edit the ``README.md`` to remove instructions about how to
import as ES module.
</details>
## Remove unwanted dev dependencies
<details>
<summary>Click to expand</summary>
Dev dependencies that are not required by the template ( you can safely remove them if you don't use them ):
- ``evt``
- ``@types/node``
Must keep:
- ``typescript``
- ``denoify`` ( for the script that moves dist files to the root before publishing )
- ``simplifyify`` ( for CDN build )
- ``terser`` ( for CDN build )
</details>
## Customizing the Badges
<details>
<summary>Click to expand</summary>
You can use [shields.io](https://shields.io) to create badges on metrics you would like to showcase.
</details>
# Accessing files outside the ``dist/`` directory
<details>
<summary>Click to expand</summary>
The drawback of having short import path is that the dir structure
is not exactly the same in production ( in the npm bundle ) and in development.
The files and directories in ``dist/`` will be moved to the root of the project.
As a result this won't work in production:
``src/index.ts``
```typescript
import * as fs from "fs";
import * as path from "path";
const str = fs.readFileSync(
path.join(__dirname,"..", "package.json")
).toString("utf8");
```
Because ``/dist/index.js`` will be moved to ``/index.js``
You'll have to do:
``src/index.ts``
```typescript
import * as fs from "fs";
import * as path from "path";
import { getProjectRoot } from "./tools/getProjectRoot";
const str = fs.readFileSync(
path.join(getProjectRoot(),"package.json")
).toString("utf8");
```
</details>
# The automatically updated ``CHANGELOG.md``
Starting from the second release, a ``CHANGELOG.md`` will be created at the root of the repo.
*Example:*
![image](https://user-images.githubusercontent.com/6702424/82747884-c47a5800-9d9d-11ea-8f3b-22df03352e54.png)
The ``CHANGELOG.md`` is built from the commits messages since last release.
Are NOT included in the ``CHANGELOG.md``:
- The commit messages that includes the word "changelog" ( non-case sensitive ).
- The commit messages that start with "Merge branch ".
- The commit messages that with "GitBook: "
*The GitHub release will point to a freezed version of the ``CHANGELOG.md``*:
![image](https://user-images.githubusercontent.com/6702424/82748469-6439e500-9da2-11ea-8552-ea9b7322dfa7.png)
# Video demo
[![Watch the video](https://user-images.githubusercontent.com/6702424/82117367-c32ea700-976f-11ea-93f9-ec056aebc528.png)](https://youtu.be/Q5t-yP2PvPA)
# Examples of auto-generated readme
![npmjs com](https://user-images.githubusercontent.com/6702424/82402717-70017080-9a5d-11ea-8137-0bfa9a139655.jpg)
# Creating a documentation website for your project
I recommend [GitBook](https://www.gitbook.com), It enables you to write your documentation in markdown from their
website and get the markdown files synchronized with your repo.
They will provide you with a nice website for which you can customize the domain name.
All this is covered by their free tier.
Example:
- [repo](https://github.com/garronej/evt)
- [GitBook documentation website](https://docs.evt.land)
I advise you to have a special directory at the root of your project where the markdown documentation files
are stored. It is configured by placing a ``.gitbook.yaml`` file at the root of the repo containing, for example:
``root: ./docs/``
Do not hesitate to request free access to premium features. Open source projects are eligible!
PS: I am not affiliated with GitBook in any way.
# Creating a landing page for your project
Beside the documentation website, you might want to have a catchy landing page to share on social networks.
You can use [GitHub pages](https://pages.github.com) to host it.
If you like the landing page of EVT, [evt.land](http://evt.land), you can fork the [repo](https://github.com/garronej/evt.land) and adapt it for your module.
To produce high quality GIF from screen recording that remain relatively small checkout the wonderful [Gifski](https://gif.ski) from [Sindre Sorhus](https://github.com/sindresorhus).
Once your page is ready you'll just have to go to settings and enable Pages yo put it online.
![image](https://user-images.githubusercontent.com/6702424/82155402-0aeb2680-9875-11ea-9159-f6167ee2928e.png)
And update your DNS:
![image](https://user-images.githubusercontent.com/6702424/82155473-7e8d3380-9875-11ea-9bba-115cbb3ef162.png)
I personally use [Hurricane Electric](https://dns.he.net) free DNS servers because they support a lot of record types.
However, if your DNS provider does not support ``ALIAS``, you can use ``A`` records and manually enter the IP of GitHub servers.
I let you consult the [GitHub Pages Documentation](https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site#configuring-an-apex-domain).

66
README.template.md Normal file
View File

@ -0,0 +1,66 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/6702424/80216211-00ef5280-863e-11ea-81de-59f3a3d4b8e4.png">
</p>
<p align="center">
<i>#{DESC}#</i>
<br>
<br>
<img src="https://github.com/garronej/#{REPO_NAME}#/workflows/ci/badge.svg?branch=develop">
<img src="https://img.shields.io/bundlephobia/minzip/#{REPO_NAME}#">
<img src="https://img.shields.io/npm/dw/#{REPO_NAME}#">
<img src="https://img.shields.io/npm/l/#{REPO_NAME}#">
</p>
<p align="center">
<a href="https://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#">Home</a>
-
<a href="https://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#">Documentation</a>
</p>
# Install / Import
```bash
$ npm install --save #{REPO_NAME}#
```
```typescript
import { myFunction, myObject } from "#{REPO_NAME}#";
```
Specific imports:
```typescript
import { myFunction } from "#{REPO_NAME}#/myFunction";
import { myObject } from "#{REPO_NAME}#/myObject";
```
## Import from HTML, with CDN
Import it via a bundle that creates a global ( wider browser support ):
```html
<script src="//unpkg.com/#{REPO_NAME}#/bundle.min.js"></script>
<script>
const { myFunction, myObject } = #{REPO_NAME_NO_DASHES}#;
</script>
```
Or import it as an ES module:
```html
<script type="module">
import {
myFunction,
myObject,
} from "//unpkg.com/#{REPO_NAME}#/zz_esm/index.js";
</script>
```
_You can specify the version you wish to import:_ [unpkg.com](https://unpkg.com)
## Contribute
```bash
npm install
npm run build
npm test
```

12759
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

65
package.json Executable file
View File

@ -0,0 +1,65 @@
{
"name": "#{REPO_NAME}#",
"version": "0.0.0",
"description": "#{DESC}#",
"repository": {
"type": "git",
"url": "git://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#.git"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "node dist/test/",
"cdn:bundle:.js": "simplifyify dist/index.js -s #{REPO_NAME_NO_DASHES}# -o dist/bundle.js --debug --bundle",
"cdn:bundle:.min.js": "terser dist/bundle.js -cmo dist/bundle.min.js",
"cdn:bundle": "npm run cdn:bundle:.js && npm run cdn:bundle:.min.js",
"cdn:esm": "tsc -p tsconfig.esm.json",
"cdn": "npm run cdn:bundle && npm run cdn:esm",
"build": "tsc && npm run cdn",
"enable_short_import_path": "npm run build && denoify_enable_short_npm_import_path",
"lint:check": "eslint . --ext .ts,.tsx",
"lint": "npm run lint:check -- --fix",
"_format": "prettier '**/*.{ts,tsx,json,md}'",
"format": "npm run _format -- --write",
"format:check": "npm run _format -- --list-different"
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix"
],
"*.{ts,tsx,json,md}": [
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged -v"
}
},
"author": "u/#{USER_OR_ORG}#",
"license": "MIT",
"files": [
"src/",
"!src/test/",
"dist/",
"!dist/test/",
"!dist/tsconfig.tsbuildinfo"
],
"keywords": [],
"homepage": "https://github.com/#{USER_OR_ORG}#/#{REPO_NAME}#",
"devDependencies": {
"typescript": "^4.1.5",
"@types/node": "^10.0.0",
"denoify": "^0.5.10",
"evt": "^1.8.11",
"simplifyify": "^8.0.3",
"terser": "^5.3.8",
"husky": "^4.3.0",
"prettier": "^2.0.5",
"eslint": "^7.7.0",
"@typescript-eslint/parser": "^4.5.0",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"eslint-config-prettier": "^6.14.0",
"lint-staged": "^10.4.2"
}
}

2
src/index.ts Normal file
View File

@ -0,0 +1,2 @@
export { myFunction } from "./myFunction";
export { myObject } from "./myObject";

3
src/myFunction.ts Normal file
View File

@ -0,0 +1,3 @@
export function myFunction() {
return Promise.resolve(["a", "b", "c"]);
}

3
src/myObject.ts Normal file
View File

@ -0,0 +1,3 @@
import { toUpperCase } from "./tools/toUpperCase";
export const myObject = { "p": toUpperCase("foo") };

View File

@ -0,0 +1,5 @@
import { getProjectRoot } from "../tools/getProjectRoot";
console.log(
`Project root path: ${getProjectRoot()} does it seems right ? If yes then PASS`,
);

41
src/test/index.ts Normal file
View File

@ -0,0 +1,41 @@
//This will not run on deno, we need a separate test runner for Deno (./mod.ts).
import * as child_process from "child_process";
import * as path from "path";
import { Deferred } from "evt/tools/Deferred";
const names = ["myFunction", "myObject", "getProjectRoot"];
(async () => {
if (!!process.env.FORK) {
process.once("unhandledRejection", error => {
throw error;
});
require(process.env.FORK);
return;
}
for (const name of names) {
console.log(`Running: ${name}`);
const dExitCode = new Deferred<number>();
child_process
.fork(__filename, undefined, {
"env": { "FORK": path.join(__dirname, name) },
})
.on("message", console.log)
.once("exit", code => dExitCode.resolve(code ?? 1));
const exitCode = await dExitCode.pr;
if (exitCode !== 0) {
console.log(`${name} exited with error code: ${exitCode}`);
process.exit(exitCode);
}
console.log("\n");
}
})();

16
src/test/myFunction.ts Normal file
View File

@ -0,0 +1,16 @@
import { myFunction } from "..";
import { getPromiseAssertionApi } from "evt/tools/testing";
const { mustResolve } = getPromiseAssertionApi({
"takeIntoAccountArraysOrdering": true,
});
(async () => {
await mustResolve({
"promise": myFunction(),
"expectedData": ["a", "b", "c"],
"delay": 0,
});
console.log("PASS");
})();

7
src/test/myObject.ts Normal file
View File

@ -0,0 +1,7 @@
import { assert } from "evt/tools/typeSafety";
import * as inDepth from "evt/tools/inDepth";
import { myObject } from "..";
assert(inDepth.same(myObject, { "p": "FOO" }));
console.log("PASS");

View File

@ -0,0 +1,19 @@
import * as fs from "fs";
import * as path from "path";
function getProjectRootRec(dirPath: string): string {
if (fs.existsSync(path.join(dirPath, "package.json"))) {
return dirPath;
}
return getProjectRootRec(path.join(dirPath, ".."));
}
let result: string | undefined = undefined;
export function getProjectRoot(): string {
if (result !== undefined) {
return result;
}
return (result = getProjectRootRec(__dirname));
}

3
src/tools/toUpperCase.ts Normal file
View File

@ -0,0 +1,3 @@
export function toUpperCase(str: string): string {
return str.toUpperCase();
}

8
tsconfig.esm.json Normal file
View File

@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"include": ["src/index.ts"],
"compilerOptions": {
"module": "es2015",
"outDir": "dist/zz_esm/"
}
}

22
tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "CommonJS",
"target": "es5",
"lib": ["es2015", "DOM"],
"esModuleInterop": true,
"declaration": true,
"outDir": "./dist",
"sourceMap": true,
"newLine": "LF",
"noUnusedLocals": true,
"noUnusedParameters": true,
"incremental": true,
"strict": true,
"downlevelIteration": true,
"jsx": "react-jsx",
"noFallthroughCasesInSwitch": true
},
"include": [
"src"
]
}