diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 2d1771f65..d5649bd65 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -11,8 +11,8 @@ contact_links: - name: "Help! My Types Are Missing!" about: "This is likely a configuration problem. Check our README" - url: "https://github.com/TypeStrong/ts-node/blob/main/README.md#help-my-types-are-missing" + url: "https://typestrong.org/ts-node/docs/types" - name: "TSError or SyntaxError" about: "These errors come from TypeScript and node, respectively. Use StackOverflow or Discord for usage and configuration help." - url: "https://stackoverflow.com/questions/tagged/ts-node" + url: "https://typestrong.org/ts-node/docs/troubleshooting" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..84b73b369 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,52 @@ +*This guide is best-effort and will be improved as necessary.* + +## Features, bugfixes, and other code + +We use npm scripts for building, testing, and linting. Read the scripts to become familiar with our build process. The big ones are: + +``` +npm install +npm run build +npm run test +npm run lint-fix +``` + +`npm prepare` is maintained so that anyone can install `ts-node` from git, which is useful for testing experimental branches and unreleased features. + +Source lives in `src` and is compiled to `dist`. Some shim files live outside of `src` so that they can be imported at +certain paths. For example, to allow users to import `ts-node/register`, we have `register/index.js` which is a shim to +compiled code in `dist`. + +`dist-raw` is for larger chunks of code which are not compiled nor linted because they have been copy-pasted from `node`'s source code. + +We publish using `np`: https://npm.im/np + +## Documentation + +Documentation is written in markdown in `website/docs` and rendered into a website by Docusaurus. + +To edit documentation, modify the markdown files in `./website/docs` and the sidebar declaration in `./website/sidebars.js` + +Docs for the latest stable release live in a `docs` branch. The "Edit this page" links on the website link to the `docs` +branch so that the website can be improved in parallel with new feature work. + +Docs changes for unreleased features are merged to `main` in the same PR which implements the feature, adds tests, etc. +When we release a new version, we merge `main` into `docs` and `docs` into `main`, unifying the two. + +```shell +cd ./website +yarn +yarn start +# Will host live website locally +``` + +This site was used to generate the favicon from a high-res PNG export of the SVG. https://realfavicongenerator.net/ + +## Release checklist + +1. Merge `docs` into `main` +2. Rebuild the README (see instructions above, necessary because npmjs.com renders the readme) +3. Publish with `np` +4. Add changelog to the Github Release; match formatting from previous releases +5. Merge `main` into `docs` (this automatically rebuilds the website) +6. If tsconfig schema has changed, send a pull request to schemastore. [Example](https://github.com/SchemaStore/schemastore/pull/1208) diff --git a/package-lock.json b/package-lock.json index 02b9605bb..4f638c9d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -321,6 +321,16 @@ "path-exists": "^4.0.0" } }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -566,6 +576,11 @@ "@types/node": "*" } }, + "@types/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-4vlpCM5KPCL5CfGmTbpjwVKbISRYhduEJvvUWsH5EB7QInhEj94XPZ3ts/9FPiLZFqYO0xoW4ZL8z2AabTGgJA==" + }, "@types/json-schema": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", @@ -578,6 +593,14 @@ "integrity": "sha512-Zst90IcBX5wnwSu7CAS0vvJkTjTELY4ssKbHiTnGcJgi170uiS8yQDdc3v6S77bRqYQIN1App5a1Pc2lceE5/g==", "dev": true }, + "@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "requires": { + "@types/unist": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -636,6 +659,11 @@ "@types/node": "*" } }, + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + }, "@yarnpkg/fslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.4.0.tgz", @@ -1083,6 +1111,11 @@ "follow-redirects": "^1.10.0" } }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1380,6 +1413,21 @@ } } }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1557,6 +1605,11 @@ "mimic-response": "^1.0.0" } }, + "co": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" + }, "code-excerpt": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", @@ -1566,6 +1619,11 @@ "convert-to-spaces": "^1.0.1" } }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1727,6 +1785,21 @@ "time-zone": "^1.0.0" } }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -1957,6 +2030,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", @@ -1986,6 +2064,14 @@ "reusify": "^1.0.4" } }, + "fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "requires": { + "format": "^0.2.0" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -2050,6 +2136,11 @@ "signal-exit": "^3.0.2" } }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" + }, "fromentries": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz", @@ -2111,6 +2202,21 @@ "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "dev": true }, + "github-slugger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", + "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", + "requires": { + "emoji-regex": ">=6.0.0 <=6.1.1" + }, + "dependencies": { + "emoji-regex": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", + "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=" + } + } + }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -2355,6 +2461,20 @@ "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", "dev": true }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2370,6 +2490,11 @@ "binary-extensions": "^2.0.0" } }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, "is-callable": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", @@ -2400,6 +2525,11 @@ "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", "dev": true }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + }, "is-error": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", @@ -2427,6 +2557,11 @@ "is-extglob": "^2.1.1" } }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + }, "is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -2479,6 +2614,11 @@ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", "dev": true }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + }, "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -2656,20 +2796,17 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc=", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", - "dev": true + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" } } }, @@ -2812,6 +2949,16 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.iteratee": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz", + "integrity": "sha1-vkF32yiajMw8CZDx2ya1si/BVUw=" + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2905,6 +3052,68 @@ "blueimp-md5": "^2.10.0" } }, + "mdast-comment-marker": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.1.2.tgz", + "integrity": "sha512-vTFXtmbbF3rgnTh3Zl3irso4LtvwUq/jaDvT2D1JqTGAwaipcS7RpTxzi6KjoRqI9n2yuAhzLDAC8xVTF3XYVQ==" + }, + "mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "mdast-util-frontmatter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz", + "integrity": "sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==", + "requires": { + "micromark-extension-frontmatter": "^0.2.0" + } + }, + "mdast-util-heading-style": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.6.tgz", + "integrity": "sha512-8ZuuegRqS0KESgjAGW8zTx4tJ3VNIiIaGFNEzFpRSAQBavVc7AvOo9I4g3crcZBfYisHs4seYh0rAVimO6HyOw==" + }, + "mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + } + }, + "mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" + }, + "mdast-util-toc": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-5.1.0.tgz", + "integrity": "sha512-csimbRIVkiqc+PpFeKDGQ/Ck2N4f9FYH3zzBMMJzcxoKL8m+cM0n94xXm0I9eaxHnKdY9n145SGTdyJC7i273g==", + "requires": { + "@types/mdast": "^3.0.3", + "@types/unist": "^2.0.3", + "extend": "^3.0.2", + "github-slugger": "^1.2.1", + "mdast-util-to-string": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit": "^2.0.0" + } + }, "mem": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/mem/-/mem-8.0.0.tgz", @@ -2935,6 +3144,23 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "micromark-extension-frontmatter": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz", + "integrity": "sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==", + "requires": { + "fault": "^1.0.0" + } + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -3504,6 +3730,19 @@ } } }, + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -3632,6 +3871,11 @@ "irregular-plurals": "^3.2.0" } }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -3840,6 +4084,296 @@ "es6-error": "^4.0.1" } }, + "remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "requires": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + } + }, + "remark-behead": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/remark-behead/-/remark-behead-2.3.3.tgz", + "integrity": "sha512-quY6Of8Bwj4pgrG/Qce6a/sMMzFc0XxbfeYko+mPjOScIB+TKw3T0Y2GUcIEL8+xbQgAnCylkPQNt9haCEWK9w==", + "requires": { + "unist-util-find": "^1.0.1", + "unist-util-find-all-after": "^3.0.1", + "unist-util-find-all-before": "^2.0.5", + "unist-util-find-all-between": "^2.0.0", + "unist-util-visit": "^2.0.3" + } + }, + "remark-frontmatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz", + "integrity": "sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==", + "requires": { + "mdast-util-frontmatter": "^0.2.0", + "micromark-extension-frontmatter": "^0.2.0" + } + }, + "remark-lint": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-8.0.0.tgz", + "integrity": "sha512-ESI8qJQ/TIRjABDnqoFsTiZntu+FRifZ5fJ77yX63eIDijl/arvmDvT+tAf75/Nm5BFL4R2JFUtkHRGVjzYUsg==", + "requires": { + "remark-message-control": "^6.0.0" + } + }, + "remark-lint-final-newline": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.5.tgz", + "integrity": "sha512-rfLlW8+Fz2dqnaEgU4JwLA55CQF1T4mfSs/GwkkeUCGPenvEYwSkCN2KO2Gr1dy8qPoOdTFE1rSufLjmeTW5HA==", + "requires": { + "unified-lint-rule": "^1.0.0" + } + }, + "remark-lint-hard-break-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.1.tgz", + "integrity": "sha512-Qfn/BMQFamHhtbfLrL8Co/dbYJFLRL4PGVXZ5wumkUO5f9FkZC2RsV+MD9lisvGTkJK0ZEJrVVeaPbUIFM0OAw==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-list-item-bullet-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-3.0.0.tgz", + "integrity": "sha512-X2rleWP8XReC4LXKF7Qi5vYiPJkA4Grx5zxsjHofFrVRz6j0PYOCuz7vsO+ZzMunFMfom6FODnscSWz4zouDVw==", + "requires": { + "pluralize": "^8.0.0", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-list-item-indent": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.1.tgz", + "integrity": "sha512-4IKbA9GA14Q9PzKSQI6KEHU/UGO36CSQEjaDIhmb9UOhyhuzz4vWhnSIsxyI73n9nl9GGRAMNUSGzr4pQUFwTA==", + "requires": { + "pluralize": "^8.0.0", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-no-auto-link-without-protocol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.1.tgz", + "integrity": "sha512-TFcXxzucsfBb/5uMqGF1rQA+WJJqm1ZlYQXyvJEXigEZ8EAxsxZGPb/gOQARHl/y0vymAuYxMTaChavPKaBqpQ==", + "requires": { + "mdast-util-to-string": "^1.0.2", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" + } + } + }, + "remark-lint-no-blockquote-without-marker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-4.0.0.tgz", + "integrity": "sha512-Y59fMqdygRVFLk1gpx2Qhhaw5IKOR9T38Wf7pjR07bEFBGUNfcoNVIFMd1TCJfCPQxUyJzzSqfZz/KT7KdUuiQ==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + } + }, + "remark-lint-no-duplicate-definitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.1.tgz", + "integrity": "sha512-XL22benJZB01m+aOse91nsu1IMFqeWJWme9QvoJuxIcBROO1BG1VoqLOkwNcawE/M/0CkvTo5rfx0eMlcnXOIw==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-stringify-position": "^2.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-no-heading-content-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-3.0.0.tgz", + "integrity": "sha512-yULDoVSIqKylLDfW6mVUbrHlyEWUSFtVFiKc+/BA412xDIhm8HZLUnP+FsuBC0OzbIZ+bO9Txy52WtO3LGnK1A==", + "requires": { + "mdast-util-heading-style": "^1.0.2", + "pluralize": "^8.0.0", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-no-inline-padding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-3.0.0.tgz", + "integrity": "sha512-3s9uW3Yux9RFC0xV81MQX3bsYs+UY7nPnRuMxeIxgcVwxQ4E/mTJd9QjXUwBhU9kdPtJ5AalngdmOW2Tgar8Cg==", + "requires": { + "mdast-util-to-string": "^1.0.2", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" + } + } + }, + "remark-lint-no-literal-urls": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.1.tgz", + "integrity": "sha512-IDdKtWOMuKVQIlb1CnsgBoyoTcXU3LppelDFAIZePbRPySVHklTtuK57kacgU5grc7gPM04bZV96eliGrRU7Iw==", + "requires": { + "mdast-util-to-string": "^1.0.2", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" + } + } + }, + "remark-lint-no-shortcut-reference-image": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.1.tgz", + "integrity": "sha512-2jcZBdnN6ecP7u87gkOVFrvICLXIU5OsdWbo160FvS/2v3qqqwF2e/n/e7D9Jd+KTq1mR1gEVVuTqkWWuh3cig==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-no-shortcut-reference-link": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.1.tgz", + "integrity": "sha512-pTZbslG412rrwwGQkIboA8wpBvcjmGFmvugIA+UQR+GfFysKtJ5OZMPGJ98/9CYWjw9Z5m0/EktplZ5TjFjqwA==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-no-undefined-references": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-3.0.0.tgz", + "integrity": "sha512-0hzaJS9GuzSQVOeeNdJr/s66LRQOzp618xuOQPYWHcJdd+SCaRTyWbjMrTM/cCI5L1sYjgurp410NkIBQ32Vqg==", + "requires": { + "collapse-white-space": "^1.0.4", + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.1.0", + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.1.0" + } + }, + "remark-lint-no-unused-definitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.1.tgz", + "integrity": "sha512-+BMc0BOjc364SvKYLkspmxDch8OaKPbnUGgQBvK0Bmlwy42baR4C9zhwAWBxm0SBy5Z4AyM4G4jKpLXPH40Oxg==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-lint-ordered-list-marker-style": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.1.tgz", + "integrity": "sha512-Cnpw1Dn9CHn+wBjlyf4qhPciiJroFOEGmyfX008sQ8uGoPZsoBVIJx76usnHklojSONbpjEDcJCjnOvfAcWW1A==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-message-control": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", + "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "requires": { + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^3.0.0" + } + }, + "remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "requires": { + "mdast-util-from-markdown": "^0.8.0" + } + }, + "remark-preset-lint-recommended": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-5.0.0.tgz", + "integrity": "sha512-uu+Ab8JCwMMaKvvB0LOWTWtM3uAvJbKQM/oyWCEJqj7lUVNTKZS575Ro5rKM3Dx7kQjjR1iw0e99bpAYTc5xNA==", + "requires": { + "remark-lint": "^8.0.0", + "remark-lint-final-newline": "^1.0.0", + "remark-lint-hard-break-spaces": "^2.0.0", + "remark-lint-list-item-bullet-indent": "^3.0.0", + "remark-lint-list-item-indent": "^2.0.0", + "remark-lint-no-auto-link-without-protocol": "^2.0.0", + "remark-lint-no-blockquote-without-marker": "^4.0.0", + "remark-lint-no-duplicate-definitions": "^2.0.0", + "remark-lint-no-heading-content-indent": "^3.0.0", + "remark-lint-no-inline-padding": "^3.0.0", + "remark-lint-no-literal-urls": "^2.0.0", + "remark-lint-no-shortcut-reference-image": "^2.0.0", + "remark-lint-no-shortcut-reference-link": "^2.0.0", + "remark-lint-no-undefined-references": "^3.0.0", + "remark-lint-no-unused-definitions": "^2.0.0", + "remark-lint-ordered-list-marker-style": "^2.0.0" + } + }, + "remark-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "requires": { + "mdast-util-to-markdown": "^0.6.0" + } + }, + "remark-toc": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-7.2.0.tgz", + "integrity": "sha512-ppHepvpbg7j5kPFmU5rzDC4k2GTcPDvWcxXyr/7BZzO1cBSPk0stKtEJdsgAyw2WHKPGxadcHIZRjb2/sHxjkg==", + "requires": { + "@types/unist": "^2.0.3", + "mdast-util-toc": "^5.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4075,6 +4609,11 @@ } } }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4330,6 +4869,11 @@ "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -4493,6 +5037,36 @@ "dev": true, "optional": true }, + "unified": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.1.tgz", + "integrity": "sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==", + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + } + }, + "unified-lint-rule": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.6.tgz", + "integrity": "sha512-YPK15YBFwnsVorDFG/u0cVVQN5G2a3V8zv5/N6KN3TCG+ajKtaALcy7u14DCSrJI+gZeyYquFL9cioJXOGXSvg==", + "requires": { + "wrapped": "^1.0.1" + } + }, + "unified-message-control": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.3.tgz", + "integrity": "sha512-oY5z2n8ugjpNHXOmcgrw0pQeJzavHS0VjPBP21tOcm7rc2C+5Q+kW9j5+gqtf8vfW/8sabbsK5+P+9QPwwEHDA==", + "requires": { + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + } + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -4502,6 +5076,105 @@ "crypto-random-string": "^2.0.0" } }, + "unist-util-find": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unist-util-find/-/unist-util-find-1.0.2.tgz", + "integrity": "sha512-ft06UDYzqi9o9RmGP0sZWI/zvLLQiBW2/MD+rW6mDqbOWDcmknGX9orQPspfuGRYWr8eSJAmfsBcvOpfGRJseA==", + "requires": { + "lodash.iteratee": "^4.5.0", + "unist-util-visit": "^1.1.0" + }, + "dependencies": { + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "requires": { + "unist-util-is": "^3.0.0" + } + } + } + }, + "unist-util-find-all-after": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", + "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==", + "requires": { + "unist-util-is": "^4.0.0" + } + }, + "unist-util-find-all-before": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-all-before/-/unist-util-find-all-before-2.0.5.tgz", + "integrity": "sha512-lYakZyw3trON5qbsOsmtRARZTyKcQN8pkoMKLy558Nt8WhlqGAnRSD9qLrISkMKbS+0nhj8LiebgoheUtQXOZw==", + "requires": { + "unist-util-is": "^4.0.0" + } + }, + "unist-util-find-all-between": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unist-util-find-all-between/-/unist-util-find-all-between-2.1.0.tgz", + "integrity": "sha512-OCCUtDD8UHKeODw3TPXyFDxPCbpgBzbGTTaDpR68nvxkwiVcawBqMVrokfBMvUi7ij2F5q7S4s4Jq5dvkcBt+w==", + "requires": { + "unist-util-find": "^1.0.1", + "unist-util-is": "^4.0.2" + } + }, + "unist-util-generated": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", + "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==" + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" + }, + "unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==" + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "requires": { + "@types/unist": "^2.0.2" + } + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -4648,6 +5321,31 @@ "spdx-expression-parse": "^3.0.0" } }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + } + }, + "vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==" + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, "vscode-textmate": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", @@ -4769,6 +5467,15 @@ } } }, + "wrapped": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wrapped/-/wrapped-1.0.1.tgz", + "integrity": "sha1-x4PZ2Aeyc+mwHoUWgKk4yHyQckI=", + "requires": { + "co": "3.1.0", + "sliced": "^1.0.1" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4809,6 +5516,11 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha1-HodAGgnXZ8HV6rJqbkwYUYLS61A=" + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" } } } diff --git a/package.json b/package.json index e8c5494da..406d2b4be 100644 --- a/package.json +++ b/package.json @@ -159,9 +159,11 @@ "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.1", + "@types/js-yaml": "^4.0.0", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", + "js-yaml": "^4.0.0", "make-error": "^1.1.1", "source-map-support": "^0.5.17", "yn": "3.1.1" diff --git a/src/index.ts b/src/index.ts index 550940b7a..e8d44384d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,14 @@ import type { TSCommon, TSInternal } from './ts-compiler-types'; export { TSCommon }; export { createRepl, CreateReplOptions, ReplService } from './repl'; +export type { + TranspilerModule, + TranspilerFactory, + CreateTranspilerOptions, + TranspileOutput, + TranspileOptions, + Transpiler, +} from './transpilers/types'; /** * Does this version of node obey the package.json "type" field @@ -110,10 +118,6 @@ const debugFn = shouldDebug } : (_: string, fn: (arg: T) => U) => fn; -export interface TSCompilerFactory { - createTypescriptCompiler(options?: any): TSCommon; -} - /** * Export the current version. */ diff --git a/website/docs/compilers.md b/website/docs/compilers.md new file mode 100644 index 000000000..6b96a621b --- /dev/null +++ b/website/docs/compilers.md @@ -0,0 +1,22 @@ +--- +title: Third-party compilers +--- + +Some projects require a patched typescript compiler which adds additional features. For example, [`ttypescript`](https://github.com/cevek/ttypescript/tree/master/packages/ttypescript) and [`ts-patch`](https://github.com/nonara/ts-patch#readme) +add the ability to configure custom transformers. These are drop-in replacements for the vanilla `typescript` module and +implement the same API. + +For example, to use `ts-patch` and `ts-transformer-keys`, add this to your `tsconfig.json`: + +```json title="tsconfig.json" +{ + "ts-node": { + "compiler": "ts-patch" + }, + "compilerOptions": { + "plugins": [ + { "transform": "ts-transformer-keys/transformer" } + ] + } +} +``` diff --git a/website/docs/configuration.md b/website/docs/configuration.md index 85c1b20b7..ad9998328 100644 --- a/website/docs/configuration.md +++ b/website/docs/configuration.md @@ -2,96 +2,85 @@ title: Configuration --- -You can set options by passing them before the script path, via programmatic usage, via `tsconfig.json`, or via environment variables. +`ts-node` supports a variety of options which can be specified via `tsconfig.json`, as CLI flags, as environment variables, or programmatically. + +For a complete list, see [Options](./options.md). + +## CLI flags + +`ts-node` CLI flags must come *before* the entrypoint script. For example: ```shell -ts-node --compiler ntypescript --project src/tsconfig.json hello-world.ts +$ ts-node --project tsconfig-dev.json say-hello.ts Ronald +Hello, Ronald! ``` -**Note:** [`ntypescript`](https://github.com/TypeStrong/ntypescript#readme) is an example of a TypeScript-compatible `compiler`. +## Via tsconfig.json (recommended) +`ts-node` automatically finds and loads `tsconfig.json`. Most `ts-node` options can be specified in a `"ts-node"` object using their programmatic, camelCase names. We recommend this because it works even when you cannot pass CLI flags, such as `node --require ts-node/register` and when using shebangs. -## Options via tsconfig.json (recommended) +Use `--skip-project` to skip loading the `tsconfig.json`. Use `--project` to explicitly specify the path to a `tsconfig.json`. -`ts-node` loads `tsconfig.json` automatically. Use this recommended configuration as a starting point. +When searching, it is resolved using [the same search behavior as `tsc`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). By default, this search is performed relative to the entrypoint script. In `--cwd-mode` or if no entrypoint is specified -- for example when using the REPL -- the search is performed relative to `--cwd` / `process.cwd()`. + +You can use this sample configuration as a starting point: ```json title="tsconfig.json" { + // This is an alias to @tsconfig/node12: https://github.com/tsconfig/bases + "extends": "ts-node/node12/tsconfig.json", + + // Most ts-node options can be specified here using their programmatic names. "ts-node": { - // Most ts-node options can be specified here using their programmatic, camel-case names. - "transpileOnly": true, // It is faster to skip typechecking. Remove if you want ts-node to do typechecking + // It is faster to skip typechecking. + // Remove if you want ts-node to do typechecking. + "transpileOnly": true, + "files": true, + "compilerOptions": { - // typescript compilerOptions specified here will override those declared below, but *only* in ts-node + // compilerOptions specified here will override those declared below, + // but *only* in ts-node. Useful if you want ts-node and tsc to use + // different options with a single tsconfig.json. } }, - "compilerOptions": { - // Copied from @tsconfig/node10: https://github.com/tsconfig/bases/blob/master/bases/node10.json - "lib": ["es2018"], - "module": "commonjs", - "target": "es2018", - - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true + // typescript options here } } ``` -Use `--skip-project` to skip loading the `tsconfig.json`. - Our bundled [JSON schema](https://unpkg.com/browse/ts-node@latest/tsconfig.schema.json) lists all compatible options. -### Finding `tsconfig.json` +### @tsconfig/bases -It is resolved relative to `--dir` using [the same search behavior as `tsc`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). In `--script-mode`, this is the directory containing the script. Otherwise it is resolved relative to `process.cwd()`, which matches the behavior of `tsc`. +[@tsconfig/bases](https://github.com/tsconfig/bases) maintains recommended configurations for several node versions. +As a convenience, these are bundled with `ts-node`. -Use `--project` to specify the path to your `tsconfig.json`, ignoring `--dir`. - -**Tip**: You can use `ts-node` together with [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths) to load modules according to the `paths` section in `tsconfig.json`. - -## CLI Options - -`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). - -* `-h, --help` Prints the help text -* `-v, --version` Prints the version. `-vv` prints node and typescript compiler versions, too -* `-s, --script-mode` Resolve config relative to the directory of the passed script instead of the current directory. Changes default of `--dir` +```json title="tsconfig.json" +{ + "extends": "ts-node/node16/tsconfig.json", -## CLI and Programmatic Options + // Or install directly with `npm i -D @tsconfig/node16` + "extends": "@tsconfig/node16/tsconfig.json", +} +``` -_The name of the environment variable and the option's default value are denoted in parentheses._ +### Default config -* `-T, --transpile-only` Use TypeScript's faster `transpileModule` (`TS_NODE_TRANSPILE_ONLY`, default: `false`) -* `-H, --compiler-host` Use TypeScript's compiler host API (`TS_NODE_COMPILER_HOST`, default: `false`) -* `-I, --ignore [pattern]` Override the path patterns to skip compilation (`TS_NODE_IGNORE`, default: `/node_modules/`) -* `-P, --project [path]` Path to TypeScript JSON project file (`TS_NODE_PROJECT`) -* `-C, --compiler [name]` Specify a custom TypeScript compiler (`TS_NODE_COMPILER`, default: `typescript`) -* `-D, --ignore-diagnostics [code]` Ignore TypeScript warnings by diagnostic code (`TS_NODE_IGNORE_DIAGNOSTICS`) -* `-O, --compiler-options [opts]` JSON object to merge with compiler options (`TS_NODE_COMPILER_OPTIONS`) -* `--dir` Specify working directory for config resolution (`TS_NODE_CWD`, default: `process.cwd()`, or `dirname(scriptPath)` if `--script-mode`) -* `--scope` Scope compiler to files within `cwd` (`TS_NODE_SCOPE`, default: `false`) -* `--files` Load `files`, `include` and `exclude` from `tsconfig.json` on startup (`TS_NODE_FILES`, default: `false`) -* `--pretty` Use pretty diagnostic formatter (`TS_NODE_PRETTY`, default: `false`) -* `--skip-project` Skip project config resolution and loading (`TS_NODE_SKIP_PROJECT`, default: `false`) -* `--skip-ignore` Skip ignore checks (`TS_NODE_SKIP_IGNORE`, default: `false`) -* `--emit` Emit output files into `.ts-node` directory (`TS_NODE_EMIT`, default: `false`) -* `--prefer-ts-exts` Re-order file extensions so that TypeScript imports are preferred (`TS_NODE_PREFER_TS_EXTS`, default: `false`) -* `--log-error` Logs TypeScript errors to stderr instead of throwing exceptions (`TS_NODE_LOG_ERROR`, default: `false`) +If no `tsconfig.json` is loaded from disk, `ts-node` will use the newest recommended defaults from +[@tsconfig/bases](https://github.com/tsconfig/bases/) compatible with your `node` and `typescript` versions. +With the latest `node` and `typescript`, this is [`@tsconfig/node16`](https://github.com/tsconfig/bases/blob/master/bases/node16.json). -## Programmatic-only Options +Older versions of `typescript` are incompatible with `@tsconfig/node16`. In those cases we will use an older default configuration. -* `transformers` `_ts.CustomTransformers | ((p: _ts.Program) => _ts.CustomTransformers)`: An object with transformers or a factory function that accepts a program and returns a transformers object to pass to TypeScript. Factory function cannot be used with `transpileOnly` flag -* `readFile`: Custom TypeScript-compatible file reading function -* `fileExists`: Custom TypeScript-compatible file existence function +When in doubt, `ts-node --show-config` will log the configuration being used, and `ts-node -vv` will log `node` and `typescript` versions. ## `node` flags [`node` flags](https://nodejs.org/api/cli.html) must be passed directly to `node`; they cannot be passed to the `ts-node` binary nor can they be specified in `tsconfig.json` -We recommend using the `NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) environment variable to pass options to `node`. +We recommend using the [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) environment variable to pass options to `node`. ```shell NODE_OPTIONS='--trace-deprecation --abort-on-uncaught-exception' ts-node ./index.ts diff --git a/website/docs/errors.md b/website/docs/errors.md deleted file mode 100644 index 0d3b4c085..000000000 --- a/website/docs/errors.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Troubleshooting Errors ---- - -It is important to differentiate between errors from `ts-node`, errors from the TypeScript compiler, and errors from `node`. It is also important to understand when errors are caused by a type error in your code, a bug in your code, or a flaw in your configuration. - -## `TSError` - -Type errors from the compiler are thrown as a `TSError`. These are the same as errors you get from `tsc`. - -## `SyntaxError` - -Any error that is not a `TSError` is from node.js (e.g. `SyntaxError`), and cannot be fixed by TypeScript or `ts-node`. These are bugs in your code or configuration. - -### Unsupported JavaScript syntax - -Your version of `node` may not support all JavaScript syntax supported by TypeScript. The compiler must transform this syntax via "downleveling," which is controlled by -the [tsconfig `"target"` option](https://www.typescriptlang.org/tsconfig#target). Otherwise your code will compile fine, but node will throw a `SyntaxError`. - -For example, `node` 12 does not understand the `?.` optional chaining operator. If you use `"target": "esnext"`, then the following TypeScript syntax: - -```typescript -const bar: string | undefined = foo?.bar; -``` - -will compile into this JavaScript: - -```javascript -const a = foo?.bar; -``` - -When you try to run this code, node 12 will throw a `SyntaxError`. To fix this, you must switch to `"target": "es2019"` or lower so TypeScript transforms `?.` into something `node` can understand. diff --git a/website/docs/getting-started.md b/website/docs/getting-started.md deleted file mode 100644 index 91267c60f..000000000 --- a/website/docs/getting-started.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -# id: getting-started -title: Getting Started -# sidebar_label: Style Guide -slug: / ---- - -*This website is still under construction. Until it is ready, official documentation lives in our [README](https://github.com/TypeStrong/ts-node)* - -## Installation - -```sh -# Locally in your project. -npm install -D typescript -npm install -D ts-node - -# Or globally with TypeScript. -npm install -g typescript -npm install -g ts-node -``` - -**Tip:** Installing modules locally allows you to control and share the versions through `package.json`. TS Node will always resolve the compiler from `cwd` before checking relative to its own installation. - -## Usage - -### Shell - -```sh -# Execute a script as `node` + `tsc`. -ts-node script.ts - -# Starts a TypeScript REPL. -ts-node - -# Execute code with TypeScript. -ts-node -e 'console.log("Hello, world!")' - -# Execute, and print, code with TypeScript. -ts-node -p -e '"Hello, world!"' - -# Pipe scripts to execute with TypeScript. -echo 'console.log("Hello, world!")' | ts-node - -# Equivalent to ts-node --script-mode -ts-node-script scripts.ts - -# Equivalent to ts-node --transpile-only -ts-node-transpile-only scripts.ts -``` - -![TypeScript REPL](/img/screenshot.png) - -### Shebang - -```typescript -#!/usr/bin/env ts-node-script - -console.log("Hello, world!") -``` - -`ts-node-script` is recommended because it enables `--script-mode`, discovering `tsconfig.json` relative to the script's location instead of `process.cwd()`. This makes scripts more portable. - -Passing CLI arguments via shebang is allowed on Mac but not Linux. For example, the following will fail on Linux: - -``` -#!/usr/bin/env ts-node --script-mode --transpile-only --files -// This shebang is not portable. It only works on Mac -``` - -### Programmatic - -You can require `ts-node` and register the loader for future requires by using `require('ts-node').register({ /* options */ })`. You can also use file shortcuts - `node -r ts-node/register` or `node -r ts-node/register/transpile-only` - depending on your preferences. - -**Note:** If you need to use advanced node.js CLI arguments (e.g. `--inspect`), use them with `node -r ts-node/register` instead of the `ts-node` CLI. - -#### Developers - -**TS Node** exports a `create()` function that can be used to initialize a TypeScript compiler that isn't registered to `require.extensions`, and it uses the same code as `register`. - -## Help! My Types Are Missing! - -**TypeScript Node** does _not_ use `files`, `include` or `exclude`, by default. This is because a large majority projects do not use all of the files in a project directory (e.g. `Gulpfile.ts`, runtime vs tests) and parsing every file for types slows startup time. Instead, `ts-node` starts with the script file (e.g. `ts-node index.ts`) and TypeScript resolves dependencies based on imports and references. - -For global definitions, you can use the `typeRoots` compiler option. This requires that your type definitions be structured as type packages (not loose TypeScript definition files). More details on how this works can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types). - -Example `tsconfig.json`: - -```json -{ - "compilerOptions": { - "typeRoots" : ["./node_modules/@types", "./typings"] - } -} -``` - -Example project structure: - -```text -/ --- tsconfig.json --- typings/ - -- / - -- index.d.ts -``` - -Example module declaration file: - -```typescript -declare module '' { - // module definitions go here -} -``` - -For module definitions, you can use [`paths`](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping): - -```json -{ - "compilerOptions": { - "baseUrl": ".", - "paths": { - "custom-module-type": ["types/custom-module-type"] - } - } -} -``` - -An alternative approach for definitions of third-party libraries are [triple-slash directives](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html). This may be helpful if you prefer not to change your TypeScript `compilerOptions` or structure your custom type definitions when using `typeRoots`. Below is an example of the triple-slash directive as a relative path within your project: - -```typescript -/// -import UntypedJsLib from "untyped_js_lib" -``` - -**Tip:** If you _must_ use `files`, `include`, or `exclude`, enable `--files` flags or set `TS_NODE_FILES=true`. - -## Watching and Restarting - -**TypeScript Node** compiles source code via `require()`, watching files and code reloads are out of scope for the project. If you want to restart the `ts-node` process on file change, existing node.js tools such as [nodemon](https://github.com/remy/nodemon), [onchange](https://github.com/Qard/onchange) and [node-dev](https://github.com/fgnass/node-dev) work. - -There's also [`ts-node-dev`](https://github.com/whitecolor/ts-node-dev), a modified version of [`node-dev`](https://github.com/fgnass/node-dev) using `ts-node` for compilation that will restart the process on file change. - -## License - -MIT - -[npm-image]: https://img.shields.io/npm/v/ts-node.svg?style=flat -[npm-url]: https://npmjs.org/package/ts-node -[downloads-image]: https://img.shields.io/npm/dm/ts-node.svg?style=flat -[downloads-url]: https://npmjs.org/package/ts-node -[github-actions-image]: https://img.shields.io/github/workflow/status/TypeStrong/ts-node/Continuous%20Integration -[github-actions-url]: https://github.com/TypeStrong/ts-node/actions?query=workflow%3A%22Continuous+Integration%22 -[codecov-image]: https://codecov.io/gh/TypeStrong/ts-node/branch/main/graph/badge.svg -[codecov-url]: https://codecov.io/gh/TypeStrong/ts-node diff --git a/website/docs/how-it-works.md b/website/docs/how-it-works.md index c6ad03373..28dec08aa 100644 --- a/website/docs/how-it-works.md +++ b/website/docs/how-it-works.md @@ -2,13 +2,23 @@ title: How It Works --- -`ts-node` works by registering the TypeScript compiler for `.ts`, `.tsx`, `.js`, and `.jsx` extensions. `.js` and `.jsx` are only registered when [`allowJs`](https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options) is enabled. -`.tsx` and `.jsx` are only registered when [`jsx`](https://www.typescriptlang.org/docs/handbook/jsx.html) is enabled. +`ts-node` works by registering hooks for `.ts`, `.tsx`, `.js`, and/or `.jsx` extensions. -When node.js has an extension registered (via `require.extensions`), it will use the extension internally for module resolution. When an extension is unknown to node.js, it handles the file as `.js` (JavaScript). By default, **TypeScript Node** avoids compiling files in `/node_modules/` for three reasons: +Vanilla `node` loads `.js` by reading code from disk and executing it. Our hook runs in the middle, transforming code from TypeScript to JavaScript and passing the result to `node` for execution. This transformation will respect your `tsconfig.json` as if you had compiled via `tsc`. + +`.js` and `.jsx` are only transformed when [`allowJs`](https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options) is enabled. + +`.tsx` and `.jsx` are only transformed when [`jsx`](https://www.typescriptlang.org/docs/handbook/jsx.html) is enabled. + +> **Warning:** if a file is ignored or its file extension is not registered, node will either fail to resolve the file or will attempt to execute it as JavaScript without any transformation. This may cause syntax errors or other failures, because node does not understand TypeScript type syntax nor bleeding-edge ECMAScript features. + +> **Warning:** When `ts-node` is used with `allowJs`, all non-ignored JavaScript files are transformed using the TypeScript compiler. + +## Skipping `node_modules` + +By default, **TypeScript Node** avoids compiling files in `/node_modules/` for three reasons: 1. Modules should always be published in a format node.js can consume 2. Transpiling the entire dependency tree will make your project slower 3. Differing behaviours between TypeScript and node.js (e.g. ES2015 modules) can result in a project that works until you decide to support a feature natively from node.js -**P.S.** This means if you don't register an extension, it is compiled as JavaScript. When `ts-node` is used with `allowJs`, JavaScript files are transpiled using the TypeScript compiler. diff --git a/website/docs/imports.md b/website/docs/imports.md index b1a010ca2..2fa3bf345 100644 --- a/website/docs/imports.md +++ b/website/docs/imports.md @@ -1,14 +1,30 @@ --- -title: "Imports: CommonJS vs native modules" +title: "CommonJS vs native ECMAScript modules" --- -TypeScript should almost always be written using `import` and `export` syntax. You can either compile it to CommonJS or use node's native ESM support. You do not need to use node's native modules to use `import` syntax. +TypeScript is almost always written using modern `import` syntax, but you can choose to either transform to CommonJS or use node's native ESM support. Configuration is different for each. -### CommonJS (recommended) +Here is a brief comparison of the two. -We recommend compiling to CommonJS. To do this, you must set `"module": "CommonJS"` in your `tsconfig.json` or compiler options, and make sure your package.json does *not* have `"type": "module"`. +| CommonJS | Native ECMAScript modules | +|---|---| +| Write native `import` syntax | Write native `import` syntax | +| Transforms `import` into `require()` | Does not transform `import` | +| Node executes scripts using the classic [CommonJS loader](https://nodejs.org/dist/latest-v16.x/docs/api/modules.html) | Node executes scripts using the new [ESM loader](https://nodejs.org/dist/latest-v16.x/docs/api/esm.html) | +| Use any of:
`ts-node` CLI
`node -r ts-node/register`
`NODE_OPTIONS="ts-node/register" node`
`require('ts-node').register({/* options */})` | Must use the ESM loader via:
`node --loader ts-node/esm`
`NODE_OPTIONS="--loader ts-node/esm" node` | +## CommonJS + +Transforming to CommonJS is typically simpler and more widely supported because it is older. You must remove or set [`"type": "commonjs"`](https://nodejs.org/api/packages.html#packages_type) in `package.json` and [`"module": "CommonJS"`](https://www.typescriptlang.org/tsconfig/#module) in `tsconfig.json`. + +```json title="package.json" +{ + // This can be omitted; commonjs is the default + "type": "commonjs" +} ``` + +```json title="tsconfig.json" { "compilerOptions": { "module": "CommonJS" @@ -16,8 +32,40 @@ We recommend compiling to CommonJS. To do this, you must set `"module": "Common } ``` -### Native ECMAScript modules +If you must keep `"module": "ESNext"` for `tsc`, webpack, or another build tool, you can set an override for `ts-node`. + +```json title="tsconfig.json" +{ + "compilerOptions": { + "module": "ESNext" + }, + "ts-node": { + "compilerOptions": { + "module": "CommonJS" + } + } +} +``` + +## Native ECMAScript modules -Node's native ESM loader hooks are currently experimental and so is `ts-node`'s ESM loader hook. This means breaking changes may happen in minor and patch releases, and it is not recommended for production. +[Node's ESM loader hooks](https://nodejs.org/api/esm.html#esm_experimental_loaders) are [**experimental**](https://nodejs.org/api/documentation.html#documentation_stability_index) and subject to change. `ts-node`'s ESM support is also experimental. They may have +breaking changes in minor and patch releases and are not recommended for production. -For usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). +For complete usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). + +You must set [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type) in `package.json` and [`"module": "ESNext"`](https://www.typescriptlang.org/tsconfig/#module) in `tsconfig.json`. + +```json title="package.json" +{ + "type": "module" +} +``` + +```json title="tsconfig.json" +{ + "compilerOptions": { + "module": "ESNext" // or ES2015, ES2020 + } +} +``` diff --git a/website/docs/installation.md b/website/docs/installation.md new file mode 100644 index 000000000..4b22d54d3 --- /dev/null +++ b/website/docs/installation.md @@ -0,0 +1,18 @@ +--- +title: Installation +--- + +```shell +# Locally in your project. +npm install -D typescript +npm install -D ts-node + +# Or globally with TypeScript. +npm install -g typescript +npm install -g ts-node + +# Depending on configuration, you may also need these +npm install -D tslib @types/node +``` + +**Tip:** Installing modules locally allows you to control and share the versions through `package.json`. TS Node will always resolve the compiler from `cwd` before checking relative to its own installation. diff --git a/website/docs/integrations.md b/website/docs/integrations.md deleted file mode 100644 index 37a230c56..000000000 --- a/website/docs/integrations.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Integrations ---- - -Guides for using ts-node alongside test runners, build systems, and editors. - -### Mocha - -Mocha 6 - -```sh -mocha --require ts-node/register --watch-extensions ts,tsx "test/**/*.{ts,tsx}" [...args] -``` - -**Note:** `--watch-extensions` is only used in `--watch` mode. - -Mocha 7 - -```sh -mocha --require ts-node/register --extensions ts,tsx --watch --watch-files src 'tests/**/*.{ts,tsx}' [...args] -``` - -### Tape - -```sh -ts-node node_modules/tape/bin/tape [...args] -``` - -### Gulp - -```sh -# Create a `gulpfile.ts` and run `gulp`. -gulp -``` - -### Visual Studio Code - -Create a new node.js configuration, add `-r ts-node/register` to node args and move the `program` to the `args` list (so VS Code doesn't look for `outFiles`). - -```json -{ - "type": "node", - "request": "launch", - "name": "Launch Program", - "runtimeArgs": [ - "-r", - "ts-node/register" - ], - "args": [ - "${workspaceFolder}/index.ts" - ] -} -``` - -**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](configuration), and want to apply this same behavior when launching in VS Code, add an "env" key into the launch configuration: `"env": { "TS_NODE_PROJECT": "" }`. - -### IntelliJ (and WebStorm) - -Create a new Node.js configuration and add `-r ts-node/register` to "Node parameters." - -**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](configuration), and want to apply this same behavior when launching in IntelliJ, specify under "Environment Variables": `TS_NODE_PROJECT=`. - diff --git a/website/docs/options-table.md b/website/docs/options-table.md new file mode 100644 index 000000000..4be37a6e3 --- /dev/null +++ b/website/docs/options-table.md @@ -0,0 +1,196 @@ +--- +title: Options +--- + + + +`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). + + + +The API includes [additional options](https://typestrong.org/ts-node/api/interfaces/registeroptions.html) not shown below. + +_Environment variables, where available, are in `ALL_CAPS`_ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CLITSConfigDescription
Shell
-h, --help Prints the help text
-v, --version Prints the version. -vv prints node and typescript compiler versions, too
-e, --eval Evaluate code
-p, --print Print result of --eval
-i, --interactive Opens the REPL even if stdin does not appear to be a terminal
TSConfig
-P, --project [path] Path to TypeScript JSON project file
Env: TS_NODE_PROJECT
--skip-project Skip project config resolution and loading
Default: false
Env: TS_NODE_SKIP_PROJECT
-c, --cwd-mode Resolve config relative to the current directory instead of the directory of the entrypoint script
-O, --compiler-options [opts] compilerOptions JSON object to merge with compiler options
Env: TS_NODE_COMPILER_OPTIONS
--show-config Print resolved tsconfig.json, including ts-node options, and exit
Typechecking
-T, --transpile-only transpileOnly Use TypeScript's faster transpileModule
Default: false
Env: TS_NODE_TRANSPILE_ONLY
--type-check Opposite of --transpile-only
Default: true
Env: TS_NODE_TYPE_CHECK
-H, --compiler-host compilerHost Use TypeScript's compiler host API
Default: false
Env: TS_NODE_COMPILER_HOST
--files files Load files, include and exclude from tsconfig.json on startup
Default: false
Env: TS_NODE_FILES
-D, --ignore-diagnostics [code] ignoreDiagnostics Ignore TypeScript warnings by diagnostic code
Env: TS_NODE_IGNORE_DIAGNOSTICS
Transpilation
-I, --ignore [pattern] ignore Override the path patterns to skip compilation
Default: /node_modules/
Env: TS_NODE_IGNORE
--skip-ignore skipIgnore Skip ignore checks
Default: false
Env: TS_NODE_SKIP_IGNORE
-C, --compiler [name] compiler Specify a custom TypeScript compiler
Default: typescript
Env: TS_NODE_COMPILER
--transpiler [name] transpiler Specify a third-party, non-typechecking transpiler
--prefer-ts-exts preferTsExts Re-order file extensions so that TypeScript imports are preferred
Default: false
Env: TS_NODE_PREFER_TS_EXTS
Diagnostics
--log-error logError Logs TypeScript errors to stderr instead of throwing exceptions
Default: false
Env: TS_NODE_LOG_ERROR
--pretty pretty Use pretty diagnostic formatter
Default: false
Env: TS_NODE_PRETTY
Enable debug logging
Env: TS_NODE_DEBUG
Advanced
-r, --require [path] require Require a node module before execution
--cwd Behave as if invoked in this working directory
Default: process.cwd()
Env: TS_NODE_CWD
--emit emit Emit output files into .ts-node directory
Default: false
Env: TS_NODE_EMIT
Path to history file for REPL
Default: ~/.ts_node_repl_history
Env: TS_NODE_HISTORY
diff --git a/website/docs/options.md b/website/docs/options.md new file mode 100644 index 000000000..a8e0eaeef --- /dev/null +++ b/website/docs/options.md @@ -0,0 +1,56 @@ +--- +title: Options +--- + +`ts-node` supports `--print` (`-p`), `--eval` (`-e`), `--require` (`-r`) and `--interactive` (`-i`) similar to the [node.js CLI options](https://nodejs.org/api/cli.html). + +_Environment variables, where available, are in `ALL_CAPS`_ + +## Shell + +- `-h, --help` Prints the help text +- `-v, --version` Prints the version. `-vv` prints node and typescript compiler versions, too +- `-e, --eval` Evaluate code +- `-p, --print` Print result of `--eval` +- `-i, --interactive` Opens the REPL even if stdin does not appear to be a terminal + +## TSConfig + +- `-P, --project [path]` Path to TypeScript JSON project file
*Environment:* `TS_NODE_PROJECT` +- `--skip-project` Skip project config resolution and loading
*Default:* `false`
*Environment:* `TS_NODE_SKIP_PROJECT` +- `-c, --cwd-mode` Resolve config relative to the current directory instead of the directory of the entrypoint script +- `-O, --compiler-options [opts]` JSON object to merge with compiler options
*Environment:* `TS_NODE_COMPILER_OPTIONS` +- `--show-config` Print resolved `tsconfig.json`, including `ts-node` options, and exit + +## Typechecking + +- `-T, --transpile-only` Use TypeScript's faster `transpileModule`
*Default:* `false`
*Environment:* `TS_NODE_TRANSPILE_ONLY` +- `--type-check` Opposite of `--transpile-only`
*Default:* `true`
*Environment:* `TS_NODE_TYPE_CHECK` +- `-H, --compiler-host` Use TypeScript's compiler host API
*Default:* `false`
*Environment:* `TS_NODE_COMPILER_HOST` +- `--files` Load `files`, `include` and `exclude` from `tsconfig.json` on startup
*Default:* `false`
*Environment:* `TS_NODE_FILES` +- `-D, --ignore-diagnostics [code]` Ignore TypeScript warnings by diagnostic code
*Environment:* `TS_NODE_IGNORE_DIAGNOSTICS` + +## Transpilation + +- `-I, --ignore [pattern]` Override the path patterns to skip compilation
*Default:* `/node_modules/`
*Environment:* `TS_NODE_IGNORE` +- `--skip-ignore` Skip ignore checks
*Default:* `false`
*Environment:* `TS_NODE_SKIP_IGNORE` +- `-C, --compiler [name]` Specify a custom TypeScript compiler
*Default:* `typescript`
*Environment:* `TS_NODE_COMPILER` +- `--transpiler [name]` Specify a third-party, non-typechecking transpiler +- `--prefer-ts-exts` Re-order file extensions so that TypeScript imports are preferred
*Default:* `false`
*Environment:* `TS_NODE_PREFER_TS_EXTS` + +## Diagnostics + +- `--log-error` Logs TypeScript errors to stderr instead of throwing exceptions
*Default:* `false`
*Environment:* `TS_NODE_LOG_ERROR` +- `--pretty` Use pretty diagnostic formatter
*Default:* `false`
*Environment:* `TS_NODE_PRETTY` +- `TS_NODE_DEBUG` Enable debug logging
+ +## Advanced + +- `-r, --require [path]` Require a node module before execution +- `--cwd` Behave as if invoked in this working directory
*Default:* `process.cwd()`
*Environment:* `TS_NODE_CWD` +- `--emit` Emit output files into `.ts-node` directory
*Default:* `false`
*Environment:* `TS_NODE_EMIT` +- `TS_NODE_HISTORY` Path to history file for REPL
*Default:* `~/.ts_node_repl_history`
+ +## API + +The API includes [additional options](https://typestrong.org/ts-node/api/interfaces/registeroptions.html) not shown here. diff --git a/website/docs/overview.md b/website/docs/overview.md new file mode 100644 index 000000000..9835306f9 --- /dev/null +++ b/website/docs/overview.md @@ -0,0 +1,26 @@ +--- +title: Overview +slug: / +--- + +`ts-node` is a TypeScript execution engine and REPL for Node.js. + +It JIT transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling. +This is accomplished by hooking node's module loading APIs, enabling it to be used seamlessly alongside other Node.js +tools and libraries. + +## Features + +* Automatic sourcemaps in stack traces +* Automatic `tsconfig.json` parsing +* Automatic defaults to match your node version +* Typechecking (optional) +* REPL +* Write standalone scripts +* Native ESM loader +* Use third-party transpilers +* Use custom transformers +* Integrate with test runners, debuggers, and CLI tools +* Compatible with pre-compilation for production + +![TypeScript REPL](/img/screenshot.png) diff --git a/website/docs/paths.md b/website/docs/paths.md new file mode 100644 index 000000000..6bc60fecc --- /dev/null +++ b/website/docs/paths.md @@ -0,0 +1,26 @@ +--- +title: | + paths and baseUrl +--- + +You can use `ts-node` together with [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths) to load modules according to the `paths` section in `tsconfig.json`. + +```json title="tsconfig.json" +{ + "ts-node": { + // Do not forget to `npm i -D tsconfig-paths` + "require": ["tsconfig-paths/register"] + } +} +``` + +## Why is this not built-in to `ts-node`? + +The official TypeScript Handbook explains the intended purpose for `"paths"` in ["Additional module resolution flags"](https://www.typescriptlang.org/docs/handbook/module-resolution.html#additional-module-resolution-flags). + +> The TypeScript compiler has a set of additional flags to *inform* the compiler of transformations that are expected to happen to the sources to generate the final output. +> +> It is important to note that the compiler will not perform any of these transformations; it just uses these pieces of information to guide the process of resolving a module import to its definition file. + +This means `"paths"` are intended to describe mappings that the build tool or runtime *already* performs, not to tell the build tool or +runtime how to resolve modules. In other words, they intend us to write our imports in a way `node` already understands. For this reason, `ts-node` does not modify `node`'s module resolution behavior to implement `"paths"` mappings. diff --git a/website/docs/performance.md b/website/docs/performance.md new file mode 100644 index 000000000..625e1cd96 --- /dev/null +++ b/website/docs/performance.md @@ -0,0 +1,21 @@ +--- +title: Make it fast +--- + +These tricks will make `ts-node` faster. + +## Skip typechecking + +It is often better to use `tsc --noEmit` to typecheck once before your tests run or as a lint step. In these cases, `ts-node` can skip typechecking. + +* Enable [`transpileOnly`](./options.md) to skip typechecking +* Use our [`swc` integration](./transpilers.md#bundled-swc-integration) + * This is by far the fastest option + +## With typechecking + +* Avoid dynamic `require()` which may trigger repeated typechecking; prefer `import` +* Try with and without `--files`; one may be faster depending on your project +* Check `tsc --showConfig`; make sure all executed files are included +* Enable [`skipLibCheck`](https://www.typescriptlang.org/tsconfig#skipLibCheck) +* Set a [`types`](https://www.typescriptlang.org/tsconfig#types) array to avoid loading unnecessary `@types` diff --git a/website/docs/recipes/ava.md b/website/docs/recipes/ava.md new file mode 100644 index 000000000..945008ec0 --- /dev/null +++ b/website/docs/recipes/ava.md @@ -0,0 +1,42 @@ +--- +title: AVA +--- + +Assuming you are configuring AVA via your `package.json`, add one of the following configurations. + +## CommonJS + +Use this configuration if your `package.json` does not have `"type": "module"`. + +```json title"package.json" +{ + "ava": { + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + } +} +``` + +## Native ECMAScript modules + +This configuration is necessary if your `package.json` has `"type": "module"`. + +```json title"package.json" +{ + "ava": { + "extensions": { + "ts": "module" + }, + "nonSemVerExperiments": { + "configurableModuleFormat": true + }, + "nodeArguments": [ + "--loader=ts-node/esm" + ] + } +} +``` diff --git a/website/docs/recipes/gulp.md b/website/docs/recipes/gulp.md new file mode 100644 index 000000000..31f1b5805 --- /dev/null +++ b/website/docs/recipes/gulp.md @@ -0,0 +1,12 @@ +--- +title: Gulp +--- + +ts-node support is built-in to gulp. + +```sh +# Create a `gulpfile.ts` and run `gulp`. +gulp +``` + +See also: https://gulpjs.com/docs/en/getting-started/javascript-and-gulpfiles#transpilation diff --git a/website/docs/recipes/intellij.md b/website/docs/recipes/intellij.md new file mode 100644 index 000000000..1a8879db2 --- /dev/null +++ b/website/docs/recipes/intellij.md @@ -0,0 +1,7 @@ +--- +title: "IntelliJ and Webstorm" +--- + +Create a new Node.js configuration and add `-r ts-node/register` to "Node parameters." + +**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](../configuration.md), and want to apply this same behavior when launching in IntelliJ, specify under "Environment Variables": `TS_NODE_PROJECT=`. diff --git a/website/docs/recipes/mocha.md b/website/docs/recipes/mocha.md new file mode 100644 index 000000000..9f9c71827 --- /dev/null +++ b/website/docs/recipes/mocha.md @@ -0,0 +1,37 @@ +--- +title: Mocha +--- + +## Mocha 7 and newer + +```shell +mocha --require ts-node/register --extensions ts,tsx --watch --watch-files src 'tests/**/*.{ts,tsx}' [...args] +``` + +Or specify options via your mocha config file. + +```json title=".mocharc.json" +{ + // Specify "require" for CommonJS + "require": "ts-node/register", + // Specify "loader" for native ESM + "loader": "ts-node/esm", + "extensions": ["ts", "tsx"], + "spec": [ + "tests/**/*.spec.*" + ], + "watch-files": [ + "src" + ] +} +``` + +See also: https://mochajs.org/#configuring-mocha-nodejs + +## Mocha <=6 + +```shell +mocha --require ts-node/register --watch-extensions ts,tsx "test/**/*.{ts,tsx}" [...args] +``` + +**Note:** `--watch-extensions` is only used in `--watch` mode. diff --git a/website/docs/recipes/other.md b/website/docs/recipes/other.md new file mode 100644 index 000000000..2f93f853c --- /dev/null +++ b/website/docs/recipes/other.md @@ -0,0 +1,17 @@ +--- +title: Other +--- + +In many cases, setting [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#cli_node_options_options) will enable `ts-node` within other node tools, child processes, and worker threads. + +```shell +NODE_OPTIONS="-r ts-node/register" +``` + +Or, if you require native ESM support: + +```shell +NODE_OPTIONS="--loader ts-node/esm" +``` + +This tells any node processes which receive this environment variable to install `ts-node`'s hooks before executing other code. diff --git a/website/docs/recipes/tape.md b/website/docs/recipes/tape.md new file mode 100644 index 000000000..7280d9dc8 --- /dev/null +++ b/website/docs/recipes/tape.md @@ -0,0 +1,7 @@ +--- +title: Tape +--- + +```shell +ts-node node_modules/tape/bin/tape [...args] +``` diff --git a/website/docs/recipes/visual-studio-code.md b/website/docs/recipes/visual-studio-code.md new file mode 100644 index 000000000..1d8d44b7f --- /dev/null +++ b/website/docs/recipes/visual-studio-code.md @@ -0,0 +1,22 @@ +--- +title: Visual Studio Code +--- + +Create a new node.js configuration, add `-r ts-node/register` to node args and move the `program` to the `args` list (so VS Code doesn't look for `outFiles`). + +```json +{ + "type": "node", + "request": "launch", + "name": "Launch Program", + "runtimeArgs": [ + "-r", + "ts-node/register" + ], + "args": [ + "${workspaceFolder}/index.ts" + ] +} +``` + +**Note:** If you are using the `--project ` command line argument as per the [Configuration Options](../configuration.md), and want to apply this same behavior when launching in VS Code, add an "env" key into the launch configuration: `"env": { "TS_NODE_PROJECT": "" }`. diff --git a/website/docs/recipes/watching-and-restarting.md b/website/docs/recipes/watching-and-restarting.md new file mode 100644 index 000000000..82f0d909e --- /dev/null +++ b/website/docs/recipes/watching-and-restarting.md @@ -0,0 +1,7 @@ +--- +title: Watching and Restarting +--- + +**TypeScript Node** compiles source code via `require()`, watching files and code reloads are out of scope for the project. If you want to restart the `ts-node` process on file change, existing node.js tools such as [nodemon](https://github.com/remy/nodemon), [onchange](https://github.com/Qard/onchange) and [node-dev](https://github.com/fgnass/node-dev) work. + +There's also [`ts-node-dev`](https://github.com/whitecolor/ts-node-dev), a modified version of [`node-dev`](https://github.com/fgnass/node-dev) using `ts-node` for compilation that will restart the process on file change. diff --git a/website/docs/shebang.md b/website/docs/shebang.md deleted file mode 100644 index fef972020..000000000 --- a/website/docs/shebang.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Shebang ---- diff --git a/website/docs/transpilers.md b/website/docs/transpilers.md new file mode 100644 index 000000000..a3972c59f --- /dev/null +++ b/website/docs/transpilers.md @@ -0,0 +1,47 @@ +--- +title: Third-party transpilers +--- + +In transpile-only mode, we skip typechecking to speed up execution time. You can go a step further and use a +third-party transpiler to transform TypeScript into JavaScript even faster. You will still benefit from +`ts-node`'s automatic `tsconfig.json` discovery, sourcemap support, and global `ts-node` CLI. Integrations +can automatically derive an appropriate configuration from your existing `tsconfig.json` which simplifies project +boilerplate. + +> **What is the difference between a compiler and a transpiler?** +> +> For our purposes, a compiler implements TypeScript's API and can perform typechecking. +> A third-party transpiler does not. Both transform TypeScript into JavaScript. + +## Bundled `swc` integration + +We have bundled an experimental `swc` integration. + +[`swc`](https://swc.rs) is a TypeScript-compatible transpiler implemented in Rust. This makes it an order of magnitude faster +than `transpileModule`. + +To use it, first install `@swc/core` or `@swc/wasm`. If using `importHelpers`, also install `@swc/helpers`. + +```shell +npm i -D @swc/core @swc/helpers +``` + +Then add the following to your `tsconfig.json`. + +```json title="tsconfig.json" +{ + "ts-node": { + "transpileOnly": true, + "transpiler": "ts-node/transpilers/swc-experimental" + } +} +``` + +> `swc` uses `@swc/helpers` instead of `tslib`. If you have enabled `importHelpers`, you must also install `@swc/helpers`. + +## Writing your own integration + +To write your own transpiler integration, check our [API docs](https://typestrong.org/ts-node/api/interfaces/transpilermodule.html). + +Integrations are `require()`d, so they can be published to npm. The module must export a `create` function matching the +[`TranspilerModule`](https://typestrong.org/ts-node/api/interfaces/transpilermodule.html) interface. diff --git a/website/docs/troubleshooting.md b/website/docs/troubleshooting.md new file mode 100644 index 000000000..4ddac6910 --- /dev/null +++ b/website/docs/troubleshooting.md @@ -0,0 +1,84 @@ +--- +title: Troubleshooting +--- + +## Understanding configuration + +`ts-node` uses sensible default configurations to reduce boilerplate while still respecting `tsconfig.json` if you +have one. If you are unsure which configuration is used, you can log it with `ts-node --show-config`. This is similar to +`tsc --showConfig` but includes `"ts-node"` options as well. + +`ts-node` also respects your locally-installed `typescript` version, but global installations fallback to the globally-installed +`typescript`. If you are unsure which versions are used, `ts-node -vv` will log them. + +```shell +$ ts-node -vv +ts-node v10.0.0 +node v16.1.0 +compiler v4.2.2 + +$ ts-node --show-config +{ + "compilerOptions": { + "target": "es6", + "lib": [ + "es6", + "dom" + ], + "rootDir": "./src", + "outDir": "./.ts-node", + "module": "commonjs", + "moduleResolution": "node", + "strict": true, + "declaration": false, + "sourceMap": true, + "inlineSources": true, + "types": [ + "node" + ], + "stripInternal": true, + "incremental": true, + "skipLibCheck": true, + "importsNotUsedAsValues": "error", + "inlineSourceMap": false, + "noEmit": false + }, + "ts-node": { + "cwd": "/d/project", + "projectSearchDir": "/d/project", + "require": [], + "project": "/d/project/tsconfig.json" + } +} +``` + +## Understanding Errors + +It is important to differentiate between errors from `ts-node`, errors from the TypeScript compiler, and errors from `node`. It is also important to understand when errors are caused by a type error in your code, a bug in your code, or a flaw in your configuration. + +### `TSError` + +Type errors from the compiler are thrown as a `TSError`. These are the same as errors you get from `tsc`. + +### `SyntaxError` + +Any error that is not a `TSError` is from node.js (e.g. `SyntaxError`), and cannot be fixed by TypeScript or `ts-node`. These are bugs in your code or configuration. + +#### Unsupported JavaScript syntax + +Your version of `node` may not support all JavaScript syntax supported by TypeScript. The compiler must transform this syntax via "downleveling," which is controlled by +the [tsconfig `"target"` option](https://www.typescriptlang.org/tsconfig#target). Otherwise your code will compile fine, but node will throw a `SyntaxError`. + +For example, `node` 12 does not understand the `?.` optional chaining operator. If you use `"target": "esnext"`, then the following TypeScript syntax: + +```typescript +const bar: string | undefined = foo?.bar; +``` + +will compile into this JavaScript: + +```javascript +const a = foo?.bar; +``` + +When you try to run this code, node 12 will throw a `SyntaxError`. To fix this, you must switch to `"target": "es2019"` or lower so TypeScript transforms `?.` into something `node` can understand. diff --git a/website/docs/types.md b/website/docs/types.md new file mode 100644 index 000000000..168c5c6a7 --- /dev/null +++ b/website/docs/types.md @@ -0,0 +1,57 @@ +--- +title: "Help! My Types Are Missing!" +--- + +**TypeScript Node** does _not_ use `files`, `include` or `exclude`, by default. This is because a large majority projects do not use all of the files in a project directory (e.g. `Gulpfile.ts`, runtime vs tests) and parsing every file for types slows startup time. Instead, `ts-node` starts with the script file (e.g. `ts-node index.ts`) and TypeScript resolves dependencies based on imports and references. + +For global definitions, you can use the `typeRoots` compiler option. This requires that your type definitions be structured as type packages (not loose TypeScript definition files). More details on how this works can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types). + +Example `tsconfig.json`: + +```json +{ + "compilerOptions": { + "typeRoots" : ["./node_modules/@types", "./typings"] + } +} +``` + +Example project structure: + +```text +/ +-- tsconfig.json +-- typings/ + -- / + -- index.d.ts +``` + +Example module declaration file: + +```typescript +declare module '' { + // module definitions go here +} +``` + +For module definitions, you can use [`paths`](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping): + +```json +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "custom-module-type": ["types/custom-module-type"] + } + } +} +``` + +An alternative approach for definitions of third-party libraries are [triple-slash directives](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html). This may be helpful if you prefer not to change your TypeScript `compilerOptions` or structure your custom type definitions when using `typeRoots`. Below is an example of the triple-slash directive as a relative path within your project: + +```typescript +/// +import UntypedJsLib from "untyped_js_lib" +``` + +**Tip:** If you _must_ use `files`, `include`, or `exclude`, enable `--files` flags or set `TS_NODE_FILES=true`. diff --git a/website/docs/usage.md b/website/docs/usage.md new file mode 100644 index 000000000..76048706c --- /dev/null +++ b/website/docs/usage.md @@ -0,0 +1,55 @@ +--- +title: Usage +--- + +## Shell + +```shell +# Execute a script as `node` + `tsc`. +ts-node script.ts + +# Starts a TypeScript REPL. +ts-node + +# Execute code with TypeScript. +ts-node -e 'console.log("Hello, world!")' + +# Execute, and print, code with TypeScript. +ts-node -p -e '"Hello, world!"' + +# Pipe scripts to execute with TypeScript. +echo 'console.log("Hello, world!")' | ts-node + +# Equivalent to ts-node --transpile-only +ts-node-transpile-only script.ts + +# Equivalent to ts-node --cwd-mode +ts-node-cwd script.ts +``` + +## Shebang + +```typescript +#!/usr/bin/env ts-node + +console.log("Hello, world!") +``` + +Passing CLI arguments via shebang is allowed on Mac but not Linux. For example, the following will fail on Linux: + +``` +#!/usr/bin/env ts-node --files +// This shebang is not portable. It only works on Mac +``` + +Instead, specify all `ts-node` options in your `tsconfig.json`. + +## Programmatic + +You can require `ts-node` and register the loader for future requires by using `require('ts-node').register({ /* options */ })`. You can also use file shortcuts - `node -r ts-node/register` or `node -r ts-node/register/transpile-only` - depending on your preferences. + +**Note:** If you need to use advanced node.js CLI arguments (e.g. `--inspect`), use them with `node -r ts-node/register` instead of the `ts-node` CLI. + +### Developers + +`ts-node` exports a `create()` function that can be used to initialize a TypeScript compiler that isn't registered to `require.extensions`, and it uses the same code as `register`. diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 2e537ac83..ef85c93c1 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -9,6 +9,18 @@ module.exports = { organizationName: 'TypeStrong', // Usually your GitHub org/user name. projectName: 'ts-node', // Usually your repo name. themeConfig: { + image: 'img/opengraph.png', + announcementBar: { + id: 'website_wip', // Any value that will identify this message. + content: + 'This website is still under construction. It describes the latest, unreleased changes from our main branch. Until it is ready, official documentation lives in our README', + //backgroundColor: '#fafbfc', // Defaults to `#fff`. + //textColor: '#091E42', // Defaults to `#000`. + //isCloseable: false, // Defaults to `true`. + }, + colorMode: { + respectPrefersColorScheme: true + }, navbar: { title: 'ts-node', logo: { @@ -20,7 +32,7 @@ module.exports = { to: 'docs/', activeBasePath: 'docs', label: 'Docs', - position: 'left', + position: 'right', }, { href: 'https://typestrong.org/ts-node/api/', @@ -28,53 +40,83 @@ module.exports = { position: 'right', }, { - href: 'https://github.com/TypeStrong/ts-node', - label: 'GitHub', + href: 'https://github.com/TypeStrong/ts-node/releases', + label: 'Release Notes', position: 'right', }, - ], - }, - footer: { - style: 'dark', - links: [ { - title: 'Docs', - items: [ - { - label: 'Docs', - to: 'docs/', - } - ], + href: 'https://github.com/TypeStrong/ts-node/discussions', + label: 'Discuss', + position: 'right', }, { - title: 'Community', - items: [ - { - label: 'Discord', - href: 'https://discord.gg/typescript' - }, - { - label: 'Github Discussions', - href: 'https://github.com/TypeStrong/ts-node/discussions' - }, - ], + href: 'https://discord.gg/typescript', + label: 'Chat', + position: 'right', }, { - title: 'More', - items: [ - { - label: 'GitHub', - href: 'https://github.com/TypeStrong/ts-node', - }, - ], + href: 'https://github.com/TypeStrong/ts-node', + label: 'GitHub', + position: 'right', }, ], - // copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, }, + // footer: { + // style: 'dark', + // links: [ + // // { + // // title: 'Docs', + // // items: [ + // // { + // // label: 'Docs', + // // to: 'docs/', + // // } + // // ], + // // }, + // // { + // // title: 'Community', + // // items: [ + // // { + // // label: 'Discord', + // // href: 'https://discord.gg/typescript' + // // }, + // // { + // // label: 'Github Discussions', + // // href: 'https://github.com/TypeStrong/ts-node/discussions' + // // }, + // // ], + // // }, + // // { + // // title: 'More', + // // items: [ + // // { + // // label: 'GitHub', + // // href: 'https://github.com/TypeStrong/ts-node', + // // }, + // // ], + // // }, + // ], + // // copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + // }, prism: { // for syntax highlighting // additionalLanguages: ['powershell'], }, + algolia: { + apiKey: 'c882a0a136ef4e15aa99db604280caa6', + indexName: 'ts-node', + + // Optional: see doc section below + // contextualSearch: true, + + // Optional: see doc section below + // appId: 'YOUR_APP_ID', + + // Optional: Algolia search parameters + // searchParameters: {}, + + //... other Algolia params + }, }, presets: [ [ @@ -82,9 +124,8 @@ module.exports = { { docs: { sidebarPath: require.resolve('./sidebars.js'), - // Please change this to your repo. editUrl: - 'https://github.com/TypeStrong/ts-node/edit/main/website/', + 'https://github.com/TypeStrong/ts-node/edit/docs/website/', }, // blog: { // showReadingTime: true, diff --git a/website/package.json b/website/package.json index 13401da1a..2fd5884e8 100644 --- a/website/package.json +++ b/website/package.json @@ -9,15 +9,25 @@ "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "serve": "docusaurus serve", - "clear": "docusaurus clear" + "clear": "docusaurus clear", + "build-readme": "./scripts/build-readme.mjs" }, "dependencies": { - "@docusaurus/core": "2.0.0-alpha.70", - "@docusaurus/preset-classic": "2.0.0-alpha.70", + "@docusaurus/core": "2.0.0-alpha.75", + "@docusaurus/preset-classic": "2.0.0-alpha.75", + "@docusaurus/theme-search-algolia": "^2.0.0-alpha.75", "@mdx-js/react": "^1.6.21", "clsx": "^1.1.1", "react": "^16.8.4", - "react-dom": "^16.8.4" + "react-dom": "^16.8.4", + "remark": "^13.0.0", + "remark-behead": "^2.3.3", + "remark-frontmatter": "^3.0.0", + "remark-preset-lint-recommended": "^5.0.0", + "remark-toc": "^7.2.0", + "remark-validate-links": "^10.0.4", + "vfile": "^4.2.1", + "vfile-reporter": "^6.0.2" }, "browserslist": { "production": [ diff --git a/website/readme-sources/license.md b/website/readme-sources/license.md new file mode 100644 index 000000000..922e4fd93 --- /dev/null +++ b/website/readme-sources/license.md @@ -0,0 +1,9 @@ +--- +title: License +--- + +[MIT](https://github.com/TypeStrong/ts-node/blob/main/LICENSE) + +ts-node includes source code from Node.js which is licensed under the MIT license. [Node.js license information](https://raw.githubusercontent.com/nodejs/node/master/LICENSE) + +ts-node includes source code from the TypeScript compiler which is licensed under the Apache License 2.0. [TypeScript license information](https://github.com/microsoft/TypeScript/blob/master/LICENSE.txt) diff --git a/website/readme-sources/prefix.md b/website/readme-sources/prefix.md new file mode 100644 index 000000000..2b5fe41ab --- /dev/null +++ b/website/readme-sources/prefix.md @@ -0,0 +1,32 @@ +--- +omitHeaderOnMerge: true +--- + + + +# ![TypeScript Node](logo.svg?sanitize=true) + +[![NPM version](https://img.shields.io/npm/v/ts-node.svg?style=flat)](https://npmjs.org/package/ts-node) +[![NPM downloads](https://img.shields.io/npm/dm/ts-node.svg?style=flat)](https://npmjs.org/package/ts-node) +[![Build status](https://img.shields.io/github/workflow/status/TypeStrong/ts-node/Continuous%20Integration)](https://github.com/TypeStrong/ts-node/actions?query=workflow%3A%22Continuous+Integration%22) +[![Test coverage](https://codecov.io/gh/TypeStrong/ts-node/branch/main/graph/badge.svg)](https://codecov.io/gh/TypeStrong/ts-node) + +> TypeScript execution and REPL for node.js, with source map support. **Works with `typescript@>=2.7`**. + +The latest documentation can also be found on our website: [https://typestrong.org/ts-node](https://typestrong.org/ts-node) + +### *Experimental ESM support* + +Native ESM support is currently experimental. For usage, limitations, and to provide feedback, see [#1007](https://github.com/TypeStrong/ts-node/issues/1007). + +# Table of Contents diff --git a/website/scripts/build-readme.mjs b/website/scripts/build-readme.mjs new file mode 100755 index 000000000..b7cb22c48 --- /dev/null +++ b/website/scripts/build-readme.mjs @@ -0,0 +1,156 @@ +#!/usr/bin/env node +/* + * Render README by merging website's `.md` pages. + */ + +import fs from 'fs'; +import { fileURLToPath } from 'url'; +import Path from 'path'; + +import _ from 'lodash'; +import remark from 'remark'; +import remarkFrontmatter from 'remark-frontmatter'; +import remarkRecommended from 'remark-preset-lint-recommended'; +import remarkToc from 'remark-toc'; +import remarkBehead from 'remark-behead'; +import remarkValidateLinks from 'remark-validate-links'; +import visit from 'unist-util-visit'; +import vfile from 'vfile'; +import vfileReporter from 'vfile-reporter'; +import jsYaml from 'js-yaml'; + +const __websiteRoot = Path.resolve(fileURLToPath(import.meta.url), '../..'); +const __root = Path.resolve(__websiteRoot, '..'); +const readmePath = Path.resolve(__root, 'README.md'); +const generateReadmeHeadersForCategories = { + General: false, + Advanced: true, + Recipes: true +}; + +import sidebars from '../sidebars.js'; + +async function main() { + const readmeNodes = []; + + await appendMarkdownFileToReadmeAst({ + path: 'readme-sources/prefix.md', + headerLevel: 1 + }); + + const sidebar = sidebars.primarySidebar; + for(const category of sidebar) { + const generateReadmeHeader = generateReadmeHeadersForCategories[category.label]; + if(generateReadmeHeader) { + readmeNodes.push(headerNode(1, category.label)); + } else if(generateReadmeHeader == null) { + throw new Error(`Update ${ import.meta.url } to include all sidebar categories`); + } + for(const page of category.items) { + await appendMarkdownFileToReadmeAst({ + path: `docs/${ page }.md`, + headerLevel: 1 + !!generateReadmeHeader + }); + } + } + + appendMarkdownFileToReadmeAst({ + path: 'readme-sources/license.md', + headerLevel: 1 + }); + + async function appendMarkdownFileToReadmeAst({path, headerLevel}) { + const absPath = Path.resolve(__websiteRoot, path); + console.log(`Appending ${ path } at header level ${ headerLevel }`); + const markdownSource = fs.readFileSync(absPath, 'utf8'); + await remark() + .use(remarkFrontmatter, ['yaml']) + .use(parseFrontmatter) + .use(remarkBehead, { after: '', depth: headerLevel - 1 }) + .use(() => (ast) => { + const {frontmatter} = ast; + if(frontmatter && !frontmatter.omitHeaderOnMerge) { + readmeNodes.push(headerNode(headerLevel, frontmatter && frontmatter.title || Path.basename(absPath))); + } + readmeNodes.push(...ast.children); + }) + .process(markdownSource); + } + + const renderedReadme = await remark() + .use(() => (ast) => { + ast.children.push(...readmeNodes); + }) + .use(codeLanguageJsonToJsonc) + .use(rewritePageLinksToAnchorLinks) + .use(rewriteImgTargets) + .use(remarkToc, {tight: true}) + .process(vfile({ + path: readmePath, + contents: '' + })); + console.error(vfileReporter(renderedReadme)); + if(renderedReadme.messages.length) throw new Error('Aborting on diagnostics.'); + const lintResults = await remark() + .use(remarkValidateLinks) + .use(remarkRecommended) + .process(renderedReadme); + console.error(vfileReporter(lintResults)); + if(lintResults.messages.length) throw new Error('Aborting on diagnostics.'); + + fs.writeFileSync(readmePath, renderedReadme.contents); +} + +function parseFrontmatter() { + return (ast) => { + if(ast.children[0].type === 'yaml') { + ast.frontmatter = jsYaml.load(ast.children[0].value); + ast.children.splice(0, 1); + } + } +} + +function codeLanguageJsonToJsonc() { + return (ast) => { + visit(ast, 'code', node => { + if(node.lang === 'json') node.lang = 'jsonc'; + }) + } +} +function rewritePageLinksToAnchorLinks() { + return (ast) => { + visit(ast, 'link', node => { + if(node.url?.match?.(/^https?\:\/\//)) return; + // TODO take page title into account + node.url = node.url.replace(/^[\.\/]*(?:([^#]+)|.*#(.*))$/, '#$1$2'); + node.url = node.url.replace(/\.md$/, ''); + }); + } +} + +function rewriteImgTargets() { + return (ast) => { + visit(ast, 'image', node => { + node.url = node.url.replace(/^\//, 'website/static/'); + }); + } +} + +function headerNode(depth, value) { + return { + type: 'heading', + depth, + children: [{ + type: 'text', + value, + children: [] + }] + }; +} + +try { + await main(); +} catch(e) { + console.error(e.message); + process.exitCode = 1; +} diff --git a/website/sidebars.js b/website/sidebars.js index 3964a6eff..cda797347 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -1,13 +1,50 @@ module.exports = { - primarySidebar: { - Docs: [ - 'getting-started', - 'how-it-works', + primarySidebar: [{ + type: 'category', + label: 'General', + collapsed: false, + items: [ + 'overview', + 'installation', + 'usage', 'configuration', + 'options', 'imports', - 'integrations', - 'shebang', - 'errors', + 'troubleshooting', + 'performance', + ] + }, { + type: 'category', + label: 'Advanced', + collapsed: false, + items: [ + 'how-it-works', + 'paths', + 'types', + 'compilers', + 'transpilers' ], - }, + }, { + type: 'category', + label: 'Recipes', + collapsed: false, + items: [ + 'recipes/watching-and-restarting', + 'recipes/ava', + 'recipes/gulp', + 'recipes/intellij', + 'recipes/mocha', + 'recipes/tape', + 'recipes/visual-studio-code', + 'recipes/other' + ] + }], + hiddenSidebar: [{ + type: 'category', + label: 'Hidden pages', + collapsed: false, + items: [ + 'options-table', + ] + }], }; diff --git a/website/src/pages/index.js b/website/src/pages/index.js index d4434c13d..e476dc7a6 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -32,13 +32,22 @@ function Home() {

{siteConfig.tagline}

Get Started +