This commit is contained in:
2022-07-21 03:28:35 +00:00
parent d7c883d6df
commit 51b34b0e1d
30103 changed files with 4152204 additions and 23 deletions
+428
View File
@@ -0,0 +1,428 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [4.2.3](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v4.2.2...v4.2.3) (2020-10-07)
### Bug Fixes
* better minimizing `mjs` assets ([#329](https://github.com/webpack-contrib/terser-webpack-plugin/issues/329)) ([041b392](https://github.com/webpack-contrib/terser-webpack-plugin/commit/041b39208d364c8af9cd2b3f8e503b05a77ae067))
* minify `cjs` assets ([#328](https://github.com/webpack-contrib/terser-webpack-plugin/issues/328)) ([b9c694d](https://github.com/webpack-contrib/terser-webpack-plugin/commit/b9c694d2c1193438d3ef72fed8d1789d9a48a367))
### [4.2.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v4.2.1...v4.2.2) (2020-09-19)
### Bug Fixes
* related asset info ([a75dc8b](https://github.com/webpack-contrib/terser-webpack-plugin/commit/a75dc8bed97daecc509387a23a72699620695ab2))
### [4.2.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v4.2.0...v4.2.1) (2020-09-15)
### Bug Fixes
* cache for extracted comments ([#314](https://github.com/webpack-contrib/terser-webpack-plugin/issues/314)) ([5340814](https://github.com/webpack-contrib/terser-webpack-plugin/commit/5340814188d53031b0444b8f588995dcbede88fc))
* compatibility with webpack@5 ([f5bd8f8](https://github.com/webpack-contrib/terser-webpack-plugin/commit/f5bd8f8b1c0fc807fd00c57207e449056aeea35d))
## [4.2.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v4.1.0...v4.2.0) (2020-09-11)
### Features
* improve caching ([defde64](https://github.com/webpack-contrib/terser-webpack-plugin/commit/defde640c8a2448fe7a5fee95a516af6e1bba8e4))
* pass the `terserOptions` to the `minify` option ([#311](https://github.com/webpack-contrib/terser-webpack-plugin/issues/311)) ([4bd622c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/4bd622cdaeb51be5d5151925f64ac1054298a214))
### Bug Fixes
* compatibility with webpack@5 ([#301](https://github.com/webpack-contrib/terser-webpack-plugin/issues/301)) ([9d861d8](https://github.com/webpack-contrib/terser-webpack-plugin/commit/9d861d8484eb36fa62c67f03b980cad2a43c3d2a))
## [4.1.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v4.0.0...v4.1.0) (2020-08-10)
### Features
* pass license files as related assets for webpack@5 ([7d3ae95](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7d3ae95bc890a5211efe234301050815ef8e687e))
### Bug Fixes
* compatibility with `10.13` version of `Node.js`
## [4.0.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.1.0...v4.0.0) (2020-08-04)
### ⚠ BREAKING CHANGES
* the `warningsFilter` option was removed without replacement,
* `terser` version is `5`,
* return value of the `minify` option was changed, only `code`/`map`/`extractedComments` are valid
### Features
* improved compatibility with webpack@5
## [3.1.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.8...v3.1.0) (2020-08-03)
### Features
* show minimized assets in stats for webpack@5 ([#289](https://github.com/webpack-contrib/terser-webpack-plugin/issues/289)) ([d59eae2](https://github.com/webpack-contrib/terser-webpack-plugin/commit/d59eae2108ba43f3f7ce6c83195a8438634a9b55))
### Bug Fixes
* compatibility cache feature with webpack@5 ([5d2bd29](https://github.com/webpack-contrib/terser-webpack-plugin/commit/5d2bd29403f614296795664a81e437712469bc05))
* skip double compression for child compilation ([37cc813](https://github.com/webpack-contrib/terser-webpack-plugin/commit/37cc8132df50ad7b374ec2606df1d0e202a579d1))
### [3.0.8](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.7...v3.0.8) (2020-07-27)
### Bug Fixes
* compatibility with child compilations ([9da4add](https://github.com/webpack-contrib/terser-webpack-plugin/commit/9da4add75390a583366b7f030d366c437a52137b))
### [3.0.7](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.6...v3.0.7) (2020-07-16)
### Bug Fixes
* uglify additional assets ([100e38e](https://github.com/webpack-contrib/terser-webpack-plugin/commit/100e38e0db035f6eb21bbec2bbc1f8b12aee9f60))
### [3.0.6](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.5...v3.0.6) (2020-06-18)
### Bug Fixes
* do not crash on buffer assets ([3c67023](https://github.com/webpack-contrib/terser-webpack-plugin/commit/3c670238952ddd5cbbf17f223e13a921f3b76521))
### [3.0.5](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.4...v3.0.5) (2020-06-15)
### Bug Fixes
* multi-compiler crash ([f6499af](https://github.com/webpack-contrib/terser-webpack-plugin/commit/f6499afb40f7a3b434c880d555261d62e0de4fd7))
### [3.0.4](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.3...v3.0.4) (2020-06-13)
### Chore
* update `p-limit` and `serialize-javascript` packages
### [3.0.3](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.1...v3.0.3) (2020-06-03)
### Bug Fixes
* compatibility with `>= 10.13` versions of Node.js
* security problem ([#259](https://github.com/webpack-contrib/terser-webpack-plugin/issues/259)) ([522aa2c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/522aa2cd4e9c4b508b268eef99572c7c808fe0b6))
### [3.0.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.1...v3.0.2) (2020-05-26)
### Bug Fixes
* compatibility with webpack@5 ([#250](https://github.com/webpack-contrib/terser-webpack-plugin/issues/250)) ([d3ff61c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/d3ff61cbb714da8fb6ee1f7659bf6796774ab4cc))
### [3.0.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v3.0.0...v3.0.1) (2020-05-06)
### Bug Fixes
* parallelism in multi compilation mode ([0ee7ed2](https://github.com/webpack-contrib/terser-webpack-plugin/commit/0ee7ed270b8cbf6312cc1009c5aa5f909fc7fbb7))
* remove redundant code for the `chunkFilter` option ([#243](https://github.com/webpack-contrib/terser-webpack-plugin/issues/243)) ([7220734](https://github.com/webpack-contrib/terser-webpack-plugin/commit/722073494ae708e7cd94cdb9df26fb483e93e8de))
## [3.0.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.6...v3.0.0) (2020-05-01)
### ⚠ BREAKING CHANGES
* minimum supported Node.js version is `10.13`
* the `chunkFilter` was removed, please use `test`/`include`/`exclude` options
* change arguments order for the `warningFilter` option from `Function<(warning, file, source) -> Boolean>` to `Function<(file, warning, source) -> Boolean>`
* when the `extractComments.filename` option is a function it pass only one argument and it is object with `filename`, `basename`, `query` and `hash` properties
* if the value from the `extractComments.filename` option conflicts with existing assets, an error will be thrown instead of a warning
* use the `optimizeAssets` hook for webpack@5
### [2.3.6](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.5...v2.3.6) (2020-04-25)
### Bug Fixes
* preserve `@license` comments starting with `//` ([d3f0c81](https://github.com/webpack-contrib/terser-webpack-plugin/commit/d3f0c811672920b658edaa99815de9204716fa21))
### [2.3.5](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.4...v2.3.5) (2020-02-14)
### Bug Fixes
* do not break code with shebang ([fac58cb](https://github.com/webpack-contrib/terser-webpack-plugin/commit/fac58cb1ee7935710b3b38662c3abbf8dc12a862))
### [2.3.4](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.3...v2.3.4) (2020-01-30)
### Bug Fixes
* respect stdout and stderr of workers and do not create warnings ([#215](https://github.com/webpack-contrib/terser-webpack-plugin/issues/215)) ([5708574](https://github.com/webpack-contrib/terser-webpack-plugin/commit/5708574d3337158a02d60a81275467900da5f42d))
* use webpack hash options rather than hard-code MD4 ([#213](https://github.com/webpack-contrib/terser-webpack-plugin/issues/213)) ([330c1f6](https://github.com/webpack-contrib/terser-webpack-plugin/commit/330c1f6cf3468fd6312e86960b272df1591f1a64))
### [2.3.3](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.2...v2.3.3) (2020-01-28)
### Bug Fixes
* license files now have .txt suffix by default ([#210](https://github.com/webpack-contrib/terser-webpack-plugin/issues/210)) ([de02f7b](https://github.com/webpack-contrib/terser-webpack-plugin/commit/de02f7b229a6ef91baa353681b1c546784672ab6))
* reduce memory usage ([abfd950](https://github.com/webpack-contrib/terser-webpack-plugin/commit/abfd9506207cf392de63a0629de82145efff2361))
### [2.3.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.1...v2.3.2) (2020-01-09)
### Bug Fixes
* show error message from jest-worker ([#203](https://github.com/webpack-contrib/terser-webpack-plugin/issues/203)) ([3b28007](https://github.com/webpack-contrib/terser-webpack-plugin/commit/3b280070cde3b233ae703fe2e0ac75b350cb2da7))
### [2.3.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.3.0...v2.3.1) (2019-12-17)
### Bug Fixes
* performance ([#200](https://github.com/webpack-contrib/terser-webpack-plugin/issues/200)) ([d2acd75](https://github.com/webpack-contrib/terser-webpack-plugin/commit/d2acd75f4b630af38d2c272f800e755fe395b2dd))
## [2.3.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.2.3...v2.3.0) (2019-12-12)
### Features
* support webpack@5 cache ([3649b3d](https://github.com/webpack-contrib/terser-webpack-plugin/commit/3649b3d0bf697288661676b47b33ae88226eb6f5))
### [2.2.3](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.2.2...v2.2.3) (2019-12-11)
### SECURITY
* update `serialize-javascript` to `2.1.2` version.
### [2.2.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.2.1...v2.2.2) (2019-12-06)
### SECURITY
* update `serialize-javascript` to `2.1.1` version.
### [2.2.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.2.0...v2.2.1) (2019-10-22)
### Bug Fixes
* get rid deprecation warnings for webpack@5 ([#181](https://github.com/webpack-contrib/terser-webpack-plugin/issues/181)) ([0e9b780](https://github.com/webpack-contrib/terser-webpack-plugin/commit/0e9b780390826a9b9f58368f24b39452ca34f00e))
## [2.2.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.1.3...v2.2.0) (2019-10-22)
### Features
* map `webpack@5` options to `terser` options ([#177](https://github.com/webpack-contrib/terser-webpack-plugin/issues/177)) ([f4c47aa](https://github.com/webpack-contrib/terser-webpack-plugin/commit/f4c47aa0e3de27bbab3ae0a90a461841bbce5988))
* pass an asset path for the `warningsFilter` option ([#176](https://github.com/webpack-contrib/terser-webpack-plugin/issues/176)) ([9a0a575](https://github.com/webpack-contrib/terser-webpack-plugin/commit/9a0a575585be21118cb4e3611d30e665a6337c3d))
* propagate an error stacktrace from `terser` ([#179](https://github.com/webpack-contrib/terser-webpack-plugin/issues/179)) ([a11e66b](https://github.com/webpack-contrib/terser-webpack-plugin/commit/a11e66b17ae2bb146ded4e64c948d5eece834378))
* enable the `sourceMap` option when the `SourceMapDevToolPlugin` plugin used (non cheap) ([#178](https://github.com/webpack-contrib/terser-webpack-plugin/issues/178)) ([d01c1b5](https://github.com/webpack-contrib/terser-webpack-plugin/commit/d01c1b5fef7f0593c91c1be3d4eb36220c3f465d))
### Bug Fixes
* get rid deprecation warnings for `webpack@5` ([#180](https://github.com/webpack-contrib/terser-webpack-plugin/issues/180)) ([504ea8b](https://github.com/webpack-contrib/terser-webpack-plugin/commit/504ea8b2017e6fa9b8a5f2123025ee5b7b4d80b1))
### [2.1.3](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.1.2...v2.1.3) (2019-10-10)
### Bug Fixes
* invalidate cache when a file name was changed ([#171](https://github.com/webpack-contrib/terser-webpack-plugin/issues/171)) ([7e1d370](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7e1d370ce2520c7c23689c19b22cfbea0265957e))
### [2.1.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.1.1...v2.1.2) (2019-09-28)
### Bug Fixes
* regexp for `some` comments ([#168](https://github.com/webpack-contrib/terser-webpack-plugin/issues/168)) ([4c4b1f1](https://github.com/webpack-contrib/terser-webpack-plugin/commit/4c4b1f1))
### [2.1.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.1.0...v2.1.1) (2019-09-27)
### Bug Fixes
* logic for extracting and preserving comments ([#166](https://github.com/webpack-contrib/terser-webpack-plugin/issues/166)) ([6bdee64](https://github.com/webpack-contrib/terser-webpack-plugin/commit/6bdee64))
## [2.1.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.0.1...v2.1.0) (2019-09-16)
### Bug Fixes
* correct interpretation url for extracted comment file ([#157](https://github.com/webpack-contrib/terser-webpack-plugin/issues/157)) ([aba8ba7](https://github.com/webpack-contrib/terser-webpack-plugin/commit/aba8ba7))
### Features
* emit warning when comment file conlict with an existing asset ([#156](https://github.com/webpack-contrib/terser-webpack-plugin/issues/156)) ([2b4d2a4](https://github.com/webpack-contrib/terser-webpack-plugin/commit/2b4d2a4))
* improve naming of extracted file with comments ([#154](https://github.com/webpack-contrib/terser-webpack-plugin/issues/154)) ([5fe3337](https://github.com/webpack-contrib/terser-webpack-plugin/commit/5fe3337))
### [2.0.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.0.0...v2.0.1) (2019-09-06)
### Bug Fixes
* reduce memory usage ([#145](https://github.com/webpack-contrib/terser-webpack-plugin/issues/145)) ([815e533](https://github.com/webpack-contrib/terser-webpack-plugin/commit/815e533))
* revert do not run parallel mode when you have only one file ([#146](https://github.com/webpack-contrib/terser-webpack-plugin/issues/146)) ([6613a97](https://github.com/webpack-contrib/terser-webpack-plugin/commit/6613a97))
## [2.0.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.4.1...v2.0.0) (2019-09-05)
### ⚠ BREAKING CHANGES
* minimum require Node.js version is `8.9.0`
* the `extractComments` option is `true` by default
* the `cache` option is `true` by default
* the `parallel` option is `true` by default
* using the `extractComments.condition` option with `true` value extract only `some` comments
* the `sourceMap` option now defaults to depending on the `devtool` Webpack option
### Bug Fixes
* do not run parallel mode when you have only one file ([#134](https://github.com/webpack-contrib/terser-webpack-plugin/issues/134)) ([8b88b39](https://github.com/webpack-contrib/terser-webpack-plugin/commit/8b88b39))
* make `extractComments` API more consistent ([#129](https://github.com/webpack-contrib/terser-webpack-plugin/issues/129)) ([37d2df0](https://github.com/webpack-contrib/terser-webpack-plugin/commit/37d2df0))
* parallel on wsl ([#138](https://github.com/webpack-contrib/terser-webpack-plugin/issues/138)) ([0537591](https://github.com/webpack-contrib/terser-webpack-plugin/commit/0537591))
### Features
* enable the cache option by default ([#132](https://github.com/webpack-contrib/terser-webpack-plugin/issues/132)) ([960d249](https://github.com/webpack-contrib/terser-webpack-plugin/commit/960d249))
* enable the extractComments option by default ([ad2471c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/ad2471c))
* enable the parallel option by default ([#131](https://github.com/webpack-contrib/terser-webpack-plugin/issues/131)) ([7b342af](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7b342af))
* respect `devtool` values for source map generation ([#140](https://github.com/webpack-contrib/terser-webpack-plugin/issues/140)) ([dd37ca1](https://github.com/webpack-contrib/terser-webpack-plugin/commit/dd37ca1))
### [1.4.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.4.0...v1.4.1) (2019-07-31)
### Bug Fixes
* removed unnecessary dependency ([#111](https://github.com/webpack-contrib/terser-webpack-plugin/issues/111)) ([bc19b72](https://github.com/webpack-contrib/terser-webpack-plugin/commit/bc19b72))
## [1.4.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.3.0...v1.4.0) (2019-07-31)
### Features
* generate higher quality SourceMaps ([#109](https://github.com/webpack-contrib/terser-webpack-plugin/issues/109)) ([9d777f0](https://github.com/webpack-contrib/terser-webpack-plugin/commit/9d777f0))
## [1.3.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.2.4...v1.3.0) (2019-05-24)
### Features
* update terser to 4 version ([#97](https://github.com/webpack-contrib/terser-webpack-plugin/issues/97)) ([15d1595](https://github.com/webpack-contrib/terser-webpack-plugin/commit/15d1595))
### [1.2.4](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.2.3...v1.2.4) (2019-05-15)
### Bug Fixes
* disable parallel on WSL due bugs ([#90](https://github.com/webpack-contrib/terser-webpack-plugin/issues/90)) ([d9533dd](https://github.com/webpack-contrib/terser-webpack-plugin/commit/d9533dd))
* fallback for cache directory ([#86](https://github.com/webpack-contrib/terser-webpack-plugin/issues/86)) ([3cdd2ed](https://github.com/webpack-contrib/terser-webpack-plugin/commit/3cdd2ed))
<a name="1.2.3"></a>
## [1.2.3](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.2.2...v1.2.3) (2019-02-25)
### Bug Fixes
* invalidate cache after changing node version ([675edfd](https://github.com/webpack-contrib/terser-webpack-plugin/commit/675edfd))
<a name="1.2.2"></a>
## [1.2.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.2.1...v1.2.2) (2019-02-04)
### Bug Fixes
* cannot read property 'minify' of undefined ([#69](https://github.com/webpack-contrib/terser-webpack-plugin/issues/69)) ([0593d7c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/0593d7c))
<a name="1.2.1"></a>
## [1.2.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.2.0...v1.2.1) (2018-12-27)
### Bug Fixes
* don't crash when no extracted comments ([#49](https://github.com/webpack-contrib/terser-webpack-plugin/issues/49)) ([efad586](https://github.com/webpack-contrib/terser-webpack-plugin/commit/efad586))
<a name="1.2.0"></a>
# [1.2.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.1.0...v1.2.0) (2018-12-22)
### Bug Fixes
* `chunks` is a `Set` in webpack@5 ([#19](https://github.com/webpack-contrib/terser-webpack-plugin/issues/19)) ([df8c425](https://github.com/webpack-contrib/terser-webpack-plugin/commit/df8c425))
* catch `work-farm` errors ([#35](https://github.com/webpack-contrib/terser-webpack-plugin/issues/35)) ([2bdcd38](https://github.com/webpack-contrib/terser-webpack-plugin/commit/2bdcd38))
* dedupe extracted comments ([#40](https://github.com/webpack-contrib/terser-webpack-plugin/issues/40)) ([7f4a159](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7f4a159))
* more consistent cache ([#43](https://github.com/webpack-contrib/terser-webpack-plugin/issues/43)) ([36f5f3c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/36f5f3c))
* regenerate `contenthash` when assets was uglified ([#44](https://github.com/webpack-contrib/terser-webpack-plugin/issues/44)) ([7e6f8b1](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7e6f8b1))
### Features
* `chunkFilter` option for filtering chunks ([#38](https://github.com/webpack-contrib/terser-webpack-plugin/issues/38)) ([7ffe57c](https://github.com/webpack-contrib/terser-webpack-plugin/commit/7ffe57c))
* uglify `mjs` by default ([#39](https://github.com/webpack-contrib/terser-webpack-plugin/issues/39)) ([1644620](https://github.com/webpack-contrib/terser-webpack-plugin/commit/1644620))
<a name="1.1.0"></a>
# [1.1.0](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.0.1...v1.1.0) (2018-09-14)
### Bug Fixes
* extract comment conditions is case insensitivity ([19e1e43](https://github.com/webpack-contrib/terser-webpack-plugin/commit/19e1e43))
### Features
* full coverage schema options validation ([#8](https://github.com/webpack-contrib/terser-webpack-plugin/issues/8)) ([68e531e](https://github.com/webpack-contrib/terser-webpack-plugin/commit/68e531e))
<a name="1.0.2"></a>
## [1.0.2](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.0.1...v1.0.2) (2018-08-16)
### Internal
* migrate from `@webpack-contrib/schema-utils` to `schema-utils` ([a5432da](https://github.com/webpack-contrib/terser-webpack-plugin/commit/a5432da))
<a name="1.0.1"></a>
## [1.0.1](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v1.0.0...v1.0.1) (2018-08-15)
### Bug Fixes
* `cpus` length in a chroot environment (`os.cpus()`) ([#4](https://github.com/webpack-contrib/terser-webpack-plugin/issues/4)) ([9375646](https://github.com/webpack-contrib/terser-webpack-plugin/commit/9375646))
<a name="1.0.0"></a>
# 1.0.0 (2018-08-02)
Initial publish release
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+698
View File
@@ -0,0 +1,698 @@
<div align="center">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![cover][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# terser-webpack-plugin
This plugin uses [terser](https://github.com/terser-js/terser) to minify your JavaScript.
## Getting Started
To begin, you'll need to install `terser-webpack-plugin`:
```console
$ npm install terser-webpack-plugin --save-dev
```
Then add the plugin to your `webpack` config. For example:
**webpack.config.js**
```js
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
```
And run `webpack` via your preferred method.
## Options
### `test`
Type: `String|RegExp|Array<String|RegExp>`
Default: `/\.m?js(\?.*)?$/i`
Test to match files against.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
```
### `include`
Type: `String|RegExp|Array<String|RegExp>`
Default: `undefined`
Files to include.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
```
### `exclude`
Type: `String|RegExp|Array<String|RegExp>`
Default: `undefined`
Files to exclude.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
```
### `cache`
> ⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: `Boolean|String`
Default: `true`
Enable file caching.
Default path to cache directory: `node_modules/.cache/terser-webpack-plugin`.
> ️ If you use your own `minify` function please read the `minify` section for cache invalidation correctly.
#### `Boolean`
Enable/disable file caching.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
cache: true,
}),
],
},
};
```
#### `String`
Enable file caching and set path to cache directory.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
cache: 'path/to/cache',
}),
],
},
};
```
### `cacheKeys`
> ⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
Type: `Function<(defaultCacheKeys, file) -> Object>`
Default: `defaultCacheKeys => defaultCacheKeys`
Allows you to override default cache keys.
Default cache keys:
```js
({
terser: require('terser/package.json').version, // terser version
'terser-webpack-plugin': require('../package.json').version, // plugin version
'terser-webpack-plugin-options': this.options, // plugin options
nodeVersion: process.version, // Node.js version
name: file, // asset path
contentHash: crypto.createHash('md4').update(input).digest('hex'), // source file hash
});
```
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
cache: true,
cacheKeys: (defaultCacheKeys, file) => {
defaultCacheKeys.myCacheKey = 'myCacheKeyValue';
return defaultCacheKeys;
},
}),
],
},
};
```
### `parallel`
Type: `Boolean|Number`
Default: `true`
Use multi-process parallel running to improve the build speed.
Default number of concurrent runs: `os.cpus().length - 1`.
> ️ Parallelization can speedup your build significantly and is therefore **highly recommended**.
> ⚠️ If you use **Circle CI** or any other environment that doesn't provide real available count of CPUs then you need to setup explicitly number of CPUs to avoid `Error: Call retries were exceeded` (see [#143](https://github.com/webpack-contrib/terser-webpack-plugin/issues/143), [#202](https://github.com/webpack-contrib/terser-webpack-plugin/issues/202)).
#### `Boolean`
Enable/disable multi-process parallel running.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
```
#### `Number`
Enable multi-process parallel running and set number of concurrent runs.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
```
### `sourceMap`
Type: `Boolean`
Default: `false` (see below for details around `devtool` value and `SourceMapDevToolPlugin` plugin)
**Works only with `source-map`, `inline-source-map`, `hidden-source-map` and `nosources-source-map` values for the [`devtool`](https://webpack.js.org/configuration/devtool/) option.**
Why?
- `eval` wraps modules in `eval("string")` and the minimizer does not handle strings.
- `cheap` has not column information and minimizer generate only a single line, which leave only a single mapping.
The plugin respect the [`devtool`](https://webpack.js.org/configuration/devtool/) and using the `SourceMapDevToolPlugin` plugin.
Using supported `devtool` values enable source map generation.
Using `SourceMapDevToolPlugin` with enabled the `columns` option enables source map generation.
Use source maps to map error message locations to modules (this slows down the compilation).
If you use your own `minify` function please read the `minify` section for handling source maps correctly.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
sourceMap: true,
}),
],
},
};
```
### `minify`
Type: `Function`
Default: `undefined`
Allows you to override default minify function.
By default plugin uses [terser](https://github.com/terser-js/terser) package.
Useful for using and testing unpublished versions or forks.
> ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
myCustomOption: true,
},
// Can be async
minify: (file, sourceMap, minimizerOptions) => {
// The `minimizerOptions` option contains option from the `terserOptions` option
// You can use `minimizerOptions.myCustomOption`
const extractedComments = [];
// Custom logic for extract comments
const { map, code } = require('uglify-module') // Or require('./path/to/uglify-module')
.minify(file, {
/* Your options for minification */
});
return { map, code, extractedComments };
},
}),
],
},
};
```
### `terserOptions`
Type: `Object`
Default: [default](https://github.com/terser-js/terser#minify-options)
Terser minify [options](https://github.com/terser-js/terser#minify-options).
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
```
### `extractComments`
Type: `Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>|Object`
Default: `true`
Whether comments shall be extracted to a separate file, (see [details](https://github.com/webpack/webpack/commit/71933e979e51c533b432658d5e37917f9e71595a)).
By default extract only comments using `/^\**!|@preserve|@license|@cc_on/i` regexp condition and remove remaining comments.
If the original file is named `foo.js`, then the comments will be stored to `foo.js.LICENSE.txt`.
The `terserOptions.output.comments` option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted.
#### `Boolean`
Enable/disable extracting comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
```
#### `String`
Extract `all` or `some` (use `/^\**!|@preserve|@license|@cc_on/i` RegExp) comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: 'all',
}),
],
},
};
```
#### `RegExp`
All comments that match the given expression will be extracted to the separate file.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
```
#### `Function<(node, comment) -> Boolean>`
All comments that match the given expression will be extracted to the separate file.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
```
#### `Object`
Allow to customize condition for extract comments, specify extracted file name and banner.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```
##### `condition`
Type: `Boolean|String|RegExp|Function<(node, comment) -> Boolean|Object>`
Condition what comments you need extract.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: 'some',
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```
##### `filename`
Type: `String|Function<(string) -> String>`
Default: `[file].LICENSE.txt[query]`
Available placeholders: `[file]`, `[query]` and `[filebase]` (`[base]` for webpack 5).
The file where the extracted comments will be stored.
Default is to append the suffix `.LICENSE.txt` to the original filename.
> ⚠️ We highly recommend using the `txt` extension. Using `js`/`cjs`/`mjs` extensions may conflict with existing assets which leads to broken code.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: 'extracted-comments.js',
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```
##### `banner`
Type: `Boolean|String|Function<(string) -> String>`
Default: `/*! For license information please see ${commentsFile} */`
The banner text that points to the extracted file and will be added on top of the original file.
Can be `false` (no banner), a `String`, or a `Function<(string) -> String>` that will be called with the filename where extracted comments have been stored.
Will be wrapped into comment.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (commentsFile) => {
return `My custom banner about license information ${commentsFile}`;
},
},
}),
],
},
};
```
## Examples
### Preserve Comments
Extract all legal comments (i.e. `/^\**!|@preserve|@license|@cc_on/i`) and preserve `/@license/i` comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
```
### Remove Comments
If you avoid building with comments, use this config:
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
```
### Custom Minify Function
Override default minify function - use `uglify-js` for minification.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
// Uncomment lines below for cache invalidation correctly
// cache: true,
// cacheKeys: (defaultCacheKeys) => {
// delete defaultCacheKeys.terser;
//
// return Object.assign(
// {},
// defaultCacheKeys,
// { 'uglify-js': require('uglify-js/package.json').version },
// );
// },
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options
const uglifyJsOptions = {
/* your `uglify-js` package options */
};
if (sourceMap) {
uglifyJsOptions.sourceMap = {
content: sourceMap,
};
}
return require('uglify-js').minify(file, uglifyJsOptions);
},
}),
],
},
};
```
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/terser-webpack-plugin.svg
[npm-url]: https://npmjs.com/package/terser-webpack-plugin
[node]: https://img.shields.io/node/v/terser-webpack-plugin.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/terser-webpack-plugin.svg
[deps-url]: https://david-dm.org/webpack-contrib/terser-webpack-plugin
[tests]: https://github.com/webpack-contrib/terser-webpack-plugin/workflows/terser-webpack-plugin/badge.svg
[tests-url]: https://github.com/webpack-contrib/terser-webpack-plugin/actions
[cover]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.now.sh/badge?p=terser-webpack-plugin
[size-url]: https://packagephobia.now.sh/result?p=terser-webpack-plugin
+134
View File
@@ -0,0 +1,134 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _os = _interopRequireDefault(require("os"));
var _cacache = _interopRequireDefault(require("cacache"));
var _findCacheDir = _interopRequireDefault(require("find-cache-dir"));
var _serializeJavascript = _interopRequireDefault(require("serialize-javascript"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Webpack4Cache {
constructor(compilation, options, weakCache) {
this.cache = options.cache === true ? Webpack4Cache.getCacheDirectory() : options.cache;
this.weakCache = weakCache;
}
static getCacheDirectory() {
return (0, _findCacheDir.default)({
name: 'terser-webpack-plugin'
}) || _os.default.tmpdir();
}
async get(cacheData, {
RawSource,
ConcatSource,
SourceMapSource
}) {
if (!this.cache) {
// eslint-disable-next-line no-undefined
return undefined;
}
const weakOutput = this.weakCache.get(cacheData.inputSource);
if (weakOutput) {
return weakOutput;
} // eslint-disable-next-line no-param-reassign
cacheData.cacheIdent = cacheData.cacheIdent || (0, _serializeJavascript.default)(cacheData.cacheKeys);
let cachedResult;
try {
cachedResult = await _cacache.default.get(this.cache, cacheData.cacheIdent);
} catch (ignoreError) {
// eslint-disable-next-line no-undefined
return undefined;
}
cachedResult = JSON.parse(cachedResult.data);
if (cachedResult.target === 'comments') {
return new ConcatSource(cachedResult.value);
}
const {
code,
name,
map,
input,
inputSourceMap,
extractedComments,
banner,
shebang
} = cachedResult;
if (map) {
cachedResult.source = new SourceMapSource(code, name, map, input, inputSourceMap, true);
} else {
cachedResult.source = new RawSource(code);
}
if (banner) {
cachedResult.source = new ConcatSource(shebang ? `${shebang}\n` : '', `/*! ${banner} */\n`, cachedResult.source);
}
if (extractedComments) {
cachedResult.extractedCommentsSource = new RawSource(extractedComments);
}
return cachedResult;
}
async store(cacheData) {
if (!this.cache) {
// eslint-disable-next-line no-undefined
return undefined;
}
if (!this.weakCache.has(cacheData.inputSource)) {
if (cacheData.target === 'comments') {
this.weakCache.set(cacheData.inputSource, cacheData.output);
} else {
this.weakCache.set(cacheData.inputSource, cacheData);
}
}
let data;
if (cacheData.target === 'comments') {
data = {
target: cacheData.target,
value: cacheData.output.source()
};
} else {
data = {
code: cacheData.code,
name: cacheData.name,
map: cacheData.map,
input: cacheData.input,
inputSourceMap: cacheData.inputSourceMap,
banner: cacheData.banner,
shebang: cacheData.shebang
};
if (cacheData.extractedCommentsSource) {
data.extractedComments = cacheData.extractedCommentsSource.source();
data.commentsFilename = cacheData.commentsFilename;
}
}
return _cacache.default.put(this.cache, cacheData.cacheIdent, JSON.stringify(data));
}
}
exports.default = Webpack4Cache;
+37
View File
@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class Cache {
constructor(compilation) {
this.cache = compilation.getCache('TerserWebpackPlugin');
}
async get(cacheData) {
// eslint-disable-next-line no-param-reassign
cacheData.eTag = cacheData.eTag || Array.isArray(cacheData.inputSource) ? cacheData.inputSource.map(item => this.cache.getLazyHashedEtag(item)).reduce((previousValue, currentValue) => this.cache.mergeEtags(previousValue, currentValue)) : this.cache.getLazyHashedEtag(cacheData.inputSource);
return this.cache.getPromise(cacheData.name, cacheData.eTag);
}
async store(cacheData) {
let data;
if (cacheData.target === 'comments') {
data = cacheData.output;
} else {
data = {
source: cacheData.source,
extractedCommentsSource: cacheData.extractedCommentsSource,
commentsFilename: cacheData.commentsFilename
};
}
return this.cache.storePromise(cacheData.name, cacheData.eTag, data);
}
}
exports.default = Cache;
+5
View File
@@ -0,0 +1,5 @@
"use strict";
const plugin = require('./index');
module.exports = plugin.default;
+594
View File
@@ -0,0 +1,594 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _path = _interopRequireDefault(require("path"));
var _os = _interopRequireDefault(require("os"));
var _sourceMap = require("source-map");
var _webpack = _interopRequireWildcard(require("webpack"));
var _RequestShortener = _interopRequireDefault(require("webpack/lib/RequestShortener"));
var _schemaUtils = require("schema-utils");
var _serializeJavascript = _interopRequireDefault(require("serialize-javascript"));
var _package = _interopRequireDefault(require("terser/package.json"));
var _pLimit = _interopRequireDefault(require("p-limit"));
var _jestWorker = _interopRequireDefault(require("jest-worker"));
var _options = _interopRequireDefault(require("./options.json"));
var _minify = require("./minify");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// webpack 5 exposes the sources property to ensure the right version of webpack-sources is used
const {
SourceMapSource,
RawSource,
ConcatSource
} = // eslint-disable-next-line global-require
_webpack.default.sources || require('webpack-sources');
class TerserPlugin {
constructor(options = {}) {
(0, _schemaUtils.validate)(_options.default, options, {
name: 'Terser Plugin',
baseDataPath: 'options'
});
const {
minify,
terserOptions = {},
test = /\.[cm]?js(\?.*)?$/i,
extractComments = true,
sourceMap,
cache = true,
cacheKeys = defaultCacheKeys => defaultCacheKeys,
parallel = true,
include,
exclude
} = options;
this.options = {
test,
extractComments,
sourceMap,
cache,
cacheKeys,
parallel,
include,
exclude,
minify,
terserOptions
};
}
static isSourceMap(input) {
// All required options for `new SourceMapConsumer(...options)`
// https://github.com/mozilla/source-map#new-sourcemapconsumerrawsourcemap
return Boolean(input && input.version && input.sources && Array.isArray(input.sources) && typeof input.mappings === 'string');
}
static buildError(error, file, sourceMap, requestShortener) {
if (error.line) {
const original = sourceMap && sourceMap.originalPositionFor({
line: error.line,
column: error.col
});
if (original && original.source && requestShortener) {
return new Error(`${file} from Terser\n${error.message} [${requestShortener.shorten(original.source)}:${original.line},${original.column}][${file}:${error.line},${error.col}]${error.stack ? `\n${error.stack.split('\n').slice(1).join('\n')}` : ''}`);
}
return new Error(`${file} from Terser\n${error.message} [${file}:${error.line},${error.col}]${error.stack ? `\n${error.stack.split('\n').slice(1).join('\n')}` : ''}`);
}
if (error.stack) {
return new Error(`${file} from Terser\n${error.stack}`);
}
return new Error(`${file} from Terser\n${error.message}`);
}
static isWebpack4() {
return _webpack.version[0] === '4';
}
static getAvailableNumberOfCores(parallel) {
// In some cases cpus() returns undefined
// https://github.com/nodejs/node/issues/19022
const cpus = _os.default.cpus() || {
length: 1
};
return parallel === true ? cpus.length - 1 : Math.min(Number(parallel) || 0, cpus.length - 1);
} // eslint-disable-next-line consistent-return
static getAsset(compilation, name) {
// New API
if (compilation.getAsset) {
return compilation.getAsset(name);
}
/* istanbul ignore next */
if (compilation.assets[name]) {
return {
name,
source: compilation.assets[name],
info: {}
};
}
}
static emitAsset(compilation, name, source, assetInfo) {
// New API
if (compilation.emitAsset) {
compilation.emitAsset(name, source, assetInfo);
} // eslint-disable-next-line no-param-reassign
compilation.assets[name] = source;
}
static updateAsset(compilation, name, newSource, assetInfo) {
// New API
if (compilation.updateAsset) {
compilation.updateAsset(name, newSource, assetInfo);
} // eslint-disable-next-line no-param-reassign
compilation.assets[name] = newSource;
}
async optimize(compiler, compilation, assets, CacheEngine, weakCache) {
let assetNames;
if (TerserPlugin.isWebpack4()) {
assetNames = [].concat(Array.from(compilation.additionalChunkAssets || [])).concat( // In webpack@4 it is `chunks`
Array.from(assets).reduce((acc, chunk) => acc.concat(Array.from(chunk.files || [])), [])).concat(Object.keys(compilation.assets)).filter((assetName, index, existingAssets) => existingAssets.indexOf(assetName) === index).filter(assetName => _webpack.ModuleFilenameHelpers.matchObject.bind( // eslint-disable-next-line no-undefined
undefined, this.options)(assetName));
} else {
assetNames = Object.keys(assets).filter(assetName => _webpack.ModuleFilenameHelpers.matchObject.bind( // eslint-disable-next-line no-undefined
undefined, this.options)(assetName));
}
if (assetNames.length === 0) {
return;
}
const availableNumberOfCores = TerserPlugin.getAvailableNumberOfCores(this.options.parallel);
let concurrency = Infinity;
let worker;
if (availableNumberOfCores > 0) {
// Do not create unnecessary workers when the number of files is less than the available cores, it saves memory
const numWorkers = Math.min(assetNames.length, availableNumberOfCores);
concurrency = numWorkers;
worker = new _jestWorker.default(require.resolve('./minify'), {
numWorkers
}); // https://github.com/facebook/jest/issues/8872#issuecomment-524822081
const workerStdout = worker.getStdout();
if (workerStdout) {
workerStdout.on('data', chunk => {
return process.stdout.write(chunk);
});
}
const workerStderr = worker.getStderr();
if (workerStderr) {
workerStderr.on('data', chunk => {
return process.stderr.write(chunk);
});
}
}
const limit = (0, _pLimit.default)(concurrency);
const cache = new CacheEngine(compilation, {
cache: this.options.cache
}, weakCache);
const allExtractedComments = new Map();
const scheduledTasks = [];
for (const name of assetNames) {
scheduledTasks.push(limit(async () => {
const {
info,
source: inputSource
} = TerserPlugin.getAsset(compilation, name); // Skip double minimize assets from child compilation
if (info.minimized) {
return;
}
let input;
let inputSourceMap; // TODO refactor after drop webpack@4, webpack@5 always has `sourceAndMap` on sources
if (this.options.sourceMap && inputSource.sourceAndMap) {
const {
source,
map
} = inputSource.sourceAndMap();
input = source;
if (map) {
if (TerserPlugin.isSourceMap(map)) {
inputSourceMap = map;
} else {
inputSourceMap = map;
compilation.warnings.push(new Error(`${name} contains invalid source map`));
}
}
} else {
input = inputSource.source();
inputSourceMap = null;
}
if (Buffer.isBuffer(input)) {
input = input.toString();
}
const cacheData = {
name,
inputSource
};
if (TerserPlugin.isWebpack4()) {
if (this.options.cache) {
const {
outputOptions: {
hashSalt,
hashDigest,
hashDigestLength,
hashFunction
}
} = compilation;
const hash = _webpack.util.createHash(hashFunction);
if (hashSalt) {
hash.update(hashSalt);
}
hash.update(input);
const digest = hash.digest(hashDigest);
cacheData.input = input;
cacheData.inputSourceMap = inputSourceMap;
cacheData.cacheKeys = this.options.cacheKeys({
terser: _package.default.version,
// eslint-disable-next-line global-require
'terser-webpack-plugin': require('../package.json').version,
'terser-webpack-plugin-options': this.options,
name,
contentHash: digest.substr(0, hashDigestLength)
}, name);
}
}
let output = await cache.get(cacheData, {
RawSource,
ConcatSource,
SourceMapSource
});
if (!output) {
const minimizerOptions = {
name,
input,
inputSourceMap,
minify: this.options.minify,
minimizerOptions: this.options.terserOptions,
extractComments: this.options.extractComments
};
if (/\.mjs(\?.*)?$/i.test(name)) {
this.options.terserOptions.module = true;
}
try {
output = await (worker ? worker.transform((0, _serializeJavascript.default)(minimizerOptions)) : (0, _minify.minify)(minimizerOptions));
} catch (error) {
compilation.errors.push(TerserPlugin.buildError(error, name, inputSourceMap && TerserPlugin.isSourceMap(inputSourceMap) ? new _sourceMap.SourceMapConsumer(inputSourceMap) : null, new _RequestShortener.default(compiler.context)));
return;
}
let shebang;
if (this.options.extractComments.banner !== false && output.extractedComments && output.extractedComments.length > 0 && output.code.startsWith('#!')) {
const firstNewlinePosition = output.code.indexOf('\n');
shebang = output.code.substring(0, firstNewlinePosition);
output.code = output.code.substring(firstNewlinePosition + 1);
}
if (output.map) {
output.source = new SourceMapSource(output.code, name, output.map, input, inputSourceMap, true);
} else {
output.source = new RawSource(output.code);
}
let commentsFilename;
if (output.extractedComments && output.extractedComments.length > 0) {
commentsFilename = this.options.extractComments.filename || '[file].LICENSE.txt[query]';
let query = '';
let filename = name;
const querySplit = filename.indexOf('?');
if (querySplit >= 0) {
query = filename.substr(querySplit);
filename = filename.substr(0, querySplit);
}
const lastSlashIndex = filename.lastIndexOf('/');
const basename = lastSlashIndex === -1 ? filename : filename.substr(lastSlashIndex + 1);
const data = {
filename,
basename,
query
};
commentsFilename = compilation.getPath(commentsFilename, data);
output.commentsFilename = commentsFilename;
let banner; // Add a banner to the original file
if (this.options.extractComments.banner !== false) {
banner = this.options.extractComments.banner || `For license information please see ${_path.default.relative(_path.default.dirname(name), commentsFilename).replace(/\\/g, '/')}`;
if (typeof banner === 'function') {
banner = banner(commentsFilename);
}
if (banner) {
output.source = new ConcatSource(shebang ? `${shebang}\n` : '', `/*! ${banner} */\n`, output.source);
output.banner = banner;
output.shebang = shebang;
}
}
const extractedCommentsString = output.extractedComments.sort().join('\n\n');
output.extractedCommentsSource = new RawSource(`${extractedCommentsString}\n`);
}
await cache.store({ ...output,
...cacheData
});
} // TODO `...` required only for webpack@4
const newInfo = { ...info,
minimized: true
};
const {
source,
extractedCommentsSource
} = output; // Write extracted comments to commentsFilename
if (extractedCommentsSource) {
const {
commentsFilename
} = output; // TODO `...` required only for webpack@4
newInfo.related = {
license: commentsFilename,
...info.related
};
allExtractedComments.set(name, {
extractedCommentsSource,
commentsFilename
});
}
TerserPlugin.updateAsset(compilation, name, source, newInfo);
}));
}
await Promise.all(scheduledTasks);
if (worker) {
await worker.end();
}
await Array.from(allExtractedComments).sort().reduce(async (previousPromise, [from, value]) => {
const previous = await previousPromise;
const {
commentsFilename,
extractedCommentsSource
} = value;
if (previous && previous.commentsFilename === commentsFilename) {
const {
from: previousFrom,
source: prevSource
} = previous;
const mergedName = `${previousFrom}|${from}`;
const cacheData = {
target: 'comments'
};
if (TerserPlugin.isWebpack4()) {
const {
outputOptions: {
hashSalt,
hashDigest,
hashDigestLength,
hashFunction
}
} = compilation;
const previousHash = _webpack.util.createHash(hashFunction);
const hash = _webpack.util.createHash(hashFunction);
if (hashSalt) {
previousHash.update(hashSalt);
hash.update(hashSalt);
}
previousHash.update(prevSource.source());
hash.update(extractedCommentsSource.source());
const previousDigest = previousHash.digest(hashDigest);
const digest = hash.digest(hashDigest);
cacheData.cacheKeys = {
mergedName,
previousContentHash: previousDigest.substr(0, hashDigestLength),
contentHash: digest.substr(0, hashDigestLength)
};
cacheData.inputSource = extractedCommentsSource;
} else {
const mergedInputSource = [prevSource, extractedCommentsSource];
cacheData.name = `${commentsFilename}|${mergedName}`;
cacheData.inputSource = mergedInputSource;
}
let output = await cache.get(cacheData, {
ConcatSource
});
if (!output) {
output = new ConcatSource(Array.from(new Set([...prevSource.source().split('\n\n'), ...extractedCommentsSource.source().split('\n\n')])).join('\n\n'));
await cache.store({ ...cacheData,
output
});
}
TerserPlugin.updateAsset(compilation, commentsFilename, output);
return {
commentsFilename,
from: mergedName,
source: output
};
}
const existingAsset = TerserPlugin.getAsset(compilation, commentsFilename);
if (existingAsset) {
return {
commentsFilename,
from: commentsFilename,
source: existingAsset.source
};
}
TerserPlugin.emitAsset(compilation, commentsFilename, extractedCommentsSource);
return {
commentsFilename,
from,
source: extractedCommentsSource
};
}, Promise.resolve());
}
static getEcmaVersion(environment) {
// ES 6th
if (environment.arrowFunction || environment.const || environment.destructuring || environment.forOf || environment.module) {
return 2015;
} // ES 11th
if (environment.bigIntLiteral || environment.dynamicImport) {
return 2020;
}
return 5;
}
apply(compiler) {
const {
devtool,
output,
plugins
} = compiler.options;
this.options.sourceMap = typeof this.options.sourceMap === 'undefined' ? devtool && !devtool.includes('eval') && !devtool.includes('cheap') && (devtool.includes('source-map') || // Todo remove when `webpack@4` support will be dropped
devtool.includes('sourcemap')) || plugins && plugins.some(plugin => plugin instanceof _webpack.SourceMapDevToolPlugin && plugin.options && plugin.options.columns) : Boolean(this.options.sourceMap);
if (typeof this.options.terserOptions.module === 'undefined' && typeof output.module !== 'undefined') {
this.options.terserOptions.module = output.module;
}
if (typeof this.options.terserOptions.ecma === 'undefined') {
this.options.terserOptions.ecma = TerserPlugin.getEcmaVersion(output.environment || {});
}
const pluginName = this.constructor.name;
const weakCache = TerserPlugin.isWebpack4() && (this.options.cache === true || typeof this.options.cache === 'string') ? new WeakMap() : // eslint-disable-next-line no-undefined
undefined;
compiler.hooks.compilation.tap(pluginName, compilation => {
if (this.options.sourceMap) {
compilation.hooks.buildModule.tap(pluginName, moduleArg => {
// to get detailed location info about errors
// eslint-disable-next-line no-param-reassign
moduleArg.useSourceMap = true;
});
}
if (TerserPlugin.isWebpack4()) {
// eslint-disable-next-line global-require
const CacheEngine = require('./Webpack4Cache').default;
const {
mainTemplate,
chunkTemplate
} = compilation;
const data = (0, _serializeJavascript.default)({
terser: _package.default.version,
terserOptions: this.options.terserOptions
}); // Regenerate `contenthash` for minified assets
for (const template of [mainTemplate, chunkTemplate]) {
template.hooks.hashForChunk.tap(pluginName, hash => {
hash.update('TerserPlugin');
hash.update(data);
});
}
compilation.hooks.optimizeChunkAssets.tapPromise(pluginName, assets => this.optimize(compiler, compilation, assets, CacheEngine, weakCache));
} else {
// eslint-disable-next-line global-require
const CacheEngine = require('./Webpack5Cache').default; // eslint-disable-next-line global-require
const Compilation = require('webpack/lib/Compilation');
const hooks = _webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation);
const data = (0, _serializeJavascript.default)({
terser: _package.default.version,
terserOptions: this.options.terserOptions
});
hooks.chunkHash.tap(pluginName, (chunk, hash) => {
hash.update('TerserPlugin');
hash.update(data);
});
compilation.hooks.processAssets.tapPromise({
name: pluginName,
stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE
}, assets => this.optimize(compiler, compilation, assets, CacheEngine));
compilation.hooks.statsPrinter.tap(pluginName, stats => {
stats.hooks.print.for('asset.info.minimized').tap('terser-webpack-plugin', (minimized, {
green,
formatFlag
}) => // eslint-disable-next-line no-undefined
minimized ? green(formatFlag('minimized')) : undefined);
});
}
});
}
}
var _default = TerserPlugin;
exports.default = _default;
+179
View File
@@ -0,0 +1,179 @@
"use strict";
const {
minify: terserMinify
} = require('terser');
const buildTerserOptions = ({
ecma,
parse = {},
compress = {},
mangle,
module,
output,
toplevel,
nameCache,
ie8,
/* eslint-disable camelcase */
keep_classnames,
keep_fnames,
/* eslint-enable camelcase */
safari10
} = {}) => ({
parse: { ...parse
},
compress: typeof compress === 'boolean' ? compress : { ...compress
},
// eslint-disable-next-line no-nested-ternary
mangle: mangle == null ? true : typeof mangle === 'boolean' ? mangle : { ...mangle
},
output: {
beautify: false,
...output
},
// Ignoring sourceMap from options
sourceMap: null,
ecma,
keep_classnames,
keep_fnames,
ie8,
module,
nameCache,
safari10,
toplevel
});
function isObject(value) {
const type = typeof value;
return value != null && (type === 'object' || type === 'function');
}
const buildComments = (extractComments, terserOptions, extractedComments) => {
const condition = {};
const {
comments
} = terserOptions.output;
condition.preserve = typeof comments !== 'undefined' ? comments : false;
if (typeof extractComments === 'boolean' && extractComments) {
condition.extract = 'some';
} else if (typeof extractComments === 'string' || extractComments instanceof RegExp) {
condition.extract = extractComments;
} else if (typeof extractComments === 'function') {
condition.extract = extractComments;
} else if (isObject(extractComments)) {
condition.extract = typeof extractComments.condition === 'boolean' && extractComments.condition ? 'some' : typeof extractComments.condition !== 'undefined' ? extractComments.condition : 'some';
} else {
// No extract
// Preserve using "commentsOpts" or "some"
condition.preserve = typeof comments !== 'undefined' ? comments : 'some';
condition.extract = false;
} // Ensure that both conditions are functions
['preserve', 'extract'].forEach(key => {
let regexStr;
let regex;
switch (typeof condition[key]) {
case 'boolean':
condition[key] = condition[key] ? () => true : () => false;
break;
case 'function':
break;
case 'string':
if (condition[key] === 'all') {
condition[key] = () => true;
break;
}
if (condition[key] === 'some') {
condition[key] = (astNode, comment) => {
return (comment.type === 'comment2' || comment.type === 'comment1') && /@preserve|@lic|@cc_on|^\**!/i.test(comment.value);
};
break;
}
regexStr = condition[key];
condition[key] = (astNode, comment) => {
return new RegExp(regexStr).test(comment.value);
};
break;
default:
regex = condition[key];
condition[key] = (astNode, comment) => regex.test(comment.value);
}
}); // Redefine the comments function to extract and preserve
// comments according to the two conditions
return (astNode, comment) => {
if (condition.extract(astNode, comment)) {
const commentText = comment.type === 'comment2' ? `/*${comment.value}*/` : `//${comment.value}`; // Don't include duplicate comments
if (!extractedComments.includes(commentText)) {
extractedComments.push(commentText);
}
}
return condition.preserve(astNode, comment);
};
};
async function minify(options) {
const {
name,
input,
inputSourceMap,
minify: minifyFn,
minimizerOptions
} = options;
if (minifyFn) {
return minifyFn({
[name]: input
}, inputSourceMap, minimizerOptions);
} // Copy terser options
const terserOptions = buildTerserOptions(minimizerOptions); // Let terser generate a SourceMap
if (inputSourceMap) {
terserOptions.sourceMap = {
asObject: true
};
}
const extractedComments = [];
const {
extractComments
} = options;
terserOptions.output.comments = buildComments(extractComments, terserOptions, extractedComments);
const result = await terserMinify({
[name]: input
}, terserOptions);
return { ...result,
extractedComments
};
}
function transform(options) {
// 'use strict' => this === undefined (Clean Scope)
// Safer for possible security issues, albeit not critical at all here
// eslint-disable-next-line no-new-func, no-param-reassign
options = new Function('exports', 'require', 'module', '__filename', '__dirname', `'use strict'\nreturn ${options}`)(exports, require, module, __filename, __dirname);
return minify(options);
}
module.exports.minify = minify;
module.exports.transform = transform;
+166
View File
@@ -0,0 +1,166 @@
{
"definitions": {
"Rule": {
"description": "Filtering rule as regex or string.",
"anyOf": [
{
"instanceof": "RegExp",
"tsType": "RegExp"
},
{
"type": "string",
"minLength": 1
}
]
},
"Rules": {
"description": "Filtering rules.",
"anyOf": [
{
"type": "array",
"items": {
"description": "A rule condition.",
"oneOf": [
{
"$ref": "#/definitions/Rule"
}
]
}
},
{
"$ref": "#/definitions/Rule"
}
]
}
},
"title": "TerserPluginOptions",
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"description": "Include all modules that pass test assertion.",
"oneOf": [
{
"$ref": "#/definitions/Rules"
}
]
},
"include": {
"description": "Include all modules matching any of these conditions.",
"oneOf": [
{
"$ref": "#/definitions/Rules"
}
]
},
"exclude": {
"description": "Exclude all modules matching any of these conditions.",
"oneOf": [
{
"$ref": "#/definitions/Rules"
}
]
},
"cache": {
"description": "Enable file caching. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "string"
}
]
},
"cacheKeys": {
"description": "Allows you to override default cache keys. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache.",
"instanceof": "Function"
},
"parallel": {
"description": "Use multi-process parallel running to improve the build speed.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "integer"
}
]
},
"sourceMap": {
"description": "Enables/Disables generation of source maps.",
"type": "boolean"
},
"minify": {
"description": "Allows you to override default minify function.",
"instanceof": "Function"
},
"terserOptions": {
"description": "Options for `terser`.",
"additionalProperties": true,
"type": "object"
},
"extractComments": {
"description": "Whether comments shall be extracted to a separate file.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "string"
},
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
},
{
"additionalProperties": false,
"properties": {
"condition": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string"
},
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
}
]
},
"filename": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"banner": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string"
},
{
"instanceof": "Function"
}
]
}
},
"type": "object"
}
]
}
}
}
+1
View File
@@ -0,0 +1 @@
../acorn/bin/acorn
+1
View File
@@ -0,0 +1 @@
../semver/bin/semver.js
+1
View File
@@ -0,0 +1 @@
../terser/bin/terser
+798
View File
@@ -0,0 +1,798 @@
## 8.7.1 (2021-04-26)
### Bug fixes
Stop handling `"use strict"` directives in ECMAScript versions before 5.
Fix an issue where duplicate quoted export names in `export *` syntax were incorrectly checked.
Add missing type for `tokTypes`.
## 8.7.0 (2021-12-27)
### New features
Support quoted export names.
Upgrade to Unicode 14.
Add support for Unicode 13 properties in regular expressions.
### Bug fixes
Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code.
## 8.6.0 (2021-11-18)
### Bug fixes
Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment.
### New features
Support class private fields with the `in` operator.
## 8.5.0 (2021-09-06)
### Bug fixes
Improve context-dependent tokenization in a number of corner cases.
Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number).
Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators.
Fix wrong end locations stored on SequenceExpression nodes.
Implement restriction that `for`/`of` loop LHS can't start with `let`.
### New features
Add support for ES2022 class static blocks.
Allow multiple input files to be passed to the CLI tool.
## 8.4.1 (2021-06-24)
### Bug fixes
Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources.
## 8.4.0 (2021-06-11)
### New features
A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context.
## 8.3.0 (2021-05-31)
### New features
Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher.
Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag.
## 8.2.4 (2021-05-04)
### Bug fixes
Fix spec conformity in corner case 'for await (async of ...)'.
## 8.2.3 (2021-05-04)
### Bug fixes
Fix an issue where the library couldn't parse 'for (async of ...)'.
Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances.
## 8.2.2 (2021-04-29)
### Bug fixes
Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield.
## 8.2.1 (2021-04-24)
### Bug fixes
Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse.
## 8.2.0 (2021-04-24)
### New features
Add support for ES2022 class fields and private methods.
## 8.1.1 (2021-04-12)
### Various
Stop shipping source maps in the NPM package.
## 8.1.0 (2021-03-09)
### Bug fixes
Fix a spurious error in nested destructuring arrays.
### New features
Expose `allowAwaitOutsideFunction` in CLI interface.
Make `allowImportExportAnywhere` also apply to `import.meta`.
## 8.0.5 (2021-01-25)
### Bug fixes
Adjust package.json to work with Node 12.16.0 and 13.0-13.6.
## 8.0.4 (2020-10-05)
### Bug fixes
Make `await x ** y` an error, following the spec.
Fix potentially exponential regular expression.
## 8.0.3 (2020-10-02)
### Bug fixes
Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`.
## 8.0.2 (2020-09-30)
### Bug fixes
Make the TypeScript types reflect the current allowed values for `ecmaVersion`.
Fix another regexp/division tokenizer issue.
## 8.0.1 (2020-08-12)
### Bug fixes
Provide the correct value in the `version` export.
## 8.0.0 (2020-08-12)
### Bug fixes
Disallow expressions like `(a = b) = c`.
Make non-octal escape sequences a syntax error in strict mode.
### New features
The package can now be loaded directly as an ECMAScript module in node 13+.
Update to the set of Unicode properties from ES2021.
### Breaking changes
The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release.
Some changes to method signatures that may be used by plugins.
## 7.4.0 (2020-08-03)
### New features
Add support for logical assignment operators.
Add support for numeric separators.
## 7.3.1 (2020-06-11)
### Bug fixes
Make the string in the `version` export match the actual library version.
## 7.3.0 (2020-06-11)
### Bug fixes
Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail.
### New features
Add support for optional chaining (`?.`).
## 7.2.0 (2020-05-09)
### Bug fixes
Fix precedence issue in parsing of async arrow functions.
### New features
Add support for nullish coalescing.
Add support for `import.meta`.
Support `export * as ...` syntax.
Upgrade to Unicode 13.
## 6.4.1 (2020-03-09)
### Bug fixes
More carefully check for valid UTF16 surrogate pairs in regexp validator.
## 7.1.1 (2020-03-01)
### Bug fixes
Treat `\8` and `\9` as invalid escapes in template strings.
Allow unicode escapes in property names that are keywords.
Don't error on an exponential operator expression as argument to `await`.
More carefully check for valid UTF16 surrogate pairs in regexp validator.
## 7.1.0 (2019-09-24)
### Bug fixes
Disallow trailing object literal commas when ecmaVersion is less than 5.
### New features
Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on.
## 7.0.0 (2019-08-13)
### Breaking changes
Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression).
Makes 10 (ES2019) the default value for the `ecmaVersion` option.
## 6.3.0 (2019-08-12)
### New features
`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard.
## 6.2.1 (2019-07-21)
### Bug fixes
Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such.
Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances.
## 6.2.0 (2019-07-04)
### Bug fixes
Improve valid assignment checking in `for`/`in` and `for`/`of` loops.
Disallow binding `let` in patterns.
### New features
Support bigint syntax with `ecmaVersion` >= 11.
Support dynamic `import` syntax with `ecmaVersion` >= 11.
Upgrade to Unicode version 12.
## 6.1.1 (2019-02-27)
### Bug fixes
Fix bug that caused parsing default exports of with names to fail.
## 6.1.0 (2019-02-08)
### Bug fixes
Fix scope checking when redefining a `var` as a lexical binding.
### New features
Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins.
## 6.0.7 (2019-02-04)
### Bug fixes
Check that exported bindings are defined.
Don't treat `\u180e` as a whitespace character.
Check for duplicate parameter names in methods.
Don't allow shorthand properties when they are generators or async methods.
Forbid binding `await` in async arrow function's parameter list.
## 6.0.6 (2019-01-30)
### Bug fixes
The content of class declarations and expressions is now always parsed in strict mode.
Don't allow `let` or `const` to bind the variable name `let`.
Treat class declarations as lexical.
Don't allow a generator function declaration as the sole body of an `if` or `else`.
Ignore `"use strict"` when after an empty statement.
Allow string line continuations with special line terminator characters.
Treat `for` bodies as part of the `for` scope when checking for conflicting bindings.
Fix bug with parsing `yield` in a `for` loop initializer.
Implement special cases around scope checking for functions.
## 6.0.5 (2019-01-02)
### Bug fixes
Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type.
Don't treat `let` as a keyword when the next token is `{` on the next line.
Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on.
## 6.0.4 (2018-11-05)
### Bug fixes
Further improvements to tokenizing regular expressions in corner cases.
## 6.0.3 (2018-11-04)
### Bug fixes
Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression.
Remove stray symlink in the package tarball.
## 6.0.2 (2018-09-26)
### Bug fixes
Fix bug where default expressions could fail to parse inside an object destructuring assignment expression.
## 6.0.1 (2018-09-14)
### Bug fixes
Fix wrong value in `version` export.
## 6.0.0 (2018-09-14)
### Bug fixes
Better handle variable-redefinition checks for catch bindings and functions directly under if statements.
Forbid `new.target` in top-level arrow functions.
Fix issue with parsing a regexp after `yield` in some contexts.
### New features
The package now comes with TypeScript definitions.
### Breaking changes
The default value of the `ecmaVersion` option is now 9 (2018).
Plugins work differently, and will have to be rewritten to work with this version.
The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`).
## 5.7.3 (2018-09-10)
### Bug fixes
Fix failure to tokenize regexps after expressions like `x.of`.
Better error message for unterminated template literals.
## 5.7.2 (2018-08-24)
### Bug fixes
Properly handle `allowAwaitOutsideFunction` in for statements.
Treat function declarations at the top level of modules like let bindings.
Don't allow async function declarations as the only statement under a label.
## 5.7.0 (2018-06-15)
### New features
Upgraded to Unicode 11.
## 5.6.0 (2018-05-31)
### New features
Allow U+2028 and U+2029 in string when ECMAVersion >= 10.
Allow binding-less catch statements when ECMAVersion >= 10.
Add `allowAwaitOutsideFunction` option for parsing top-level `await`.
## 5.5.3 (2018-03-08)
### Bug fixes
A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps.
## 5.5.2 (2018-03-08)
### Bug fixes
A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0.
## 5.5.1 (2018-03-06)
### Bug fixes
Fix misleading error message for octal escapes in template strings.
## 5.5.0 (2018-02-27)
### New features
The identifier character categorization is now based on Unicode version 10.
Acorn will now validate the content of regular expressions, including new ES9 features.
## 5.4.0 (2018-02-01)
### Bug fixes
Disallow duplicate or escaped flags on regular expressions.
Disallow octal escapes in strings in strict mode.
### New features
Add support for async iteration.
Add support for object spread and rest.
## 5.3.0 (2017-12-28)
### Bug fixes
Fix parsing of floating point literals with leading zeroes in loose mode.
Allow duplicate property names in object patterns.
Don't allow static class methods named `prototype`.
Disallow async functions directly under `if` or `else`.
Parse right-hand-side of `for`/`of` as an assignment expression.
Stricter parsing of `for`/`in`.
Don't allow unicode escapes in contextual keywords.
### New features
Parsing class members was factored into smaller methods to allow plugins to hook into it.
## 5.2.1 (2017-10-30)
### Bug fixes
Fix a token context corruption bug.
## 5.2.0 (2017-10-30)
### Bug fixes
Fix token context tracking for `class` and `function` in property-name position.
Make sure `%*` isn't parsed as a valid operator.
Allow shorthand properties `get` and `set` to be followed by default values.
Disallow `super` when not in callee or object position.
### New features
Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements.
## 5.1.2 (2017-09-04)
### Bug fixes
Disable parsing of legacy HTML-style comments in modules.
Fix parsing of async methods whose names are keywords.
## 5.1.1 (2017-07-06)
### Bug fixes
Fix problem with disambiguating regexp and division after a class.
## 5.1.0 (2017-07-05)
### Bug fixes
Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`.
Parse zero-prefixed numbers with non-octal digits as decimal.
Allow object/array patterns in rest parameters.
Don't error when `yield` is used as a property name.
Allow `async` as a shorthand object property.
### New features
Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9.
## 5.0.3 (2017-04-01)
### Bug fixes
Fix spurious duplicate variable definition errors for named functions.
## 5.0.2 (2017-03-30)
### Bug fixes
A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error.
## 5.0.0 (2017-03-28)
### Bug fixes
Raise an error for duplicated lexical bindings.
Fix spurious error when an assignement expression occurred after a spread expression.
Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions.
Allow labels in front or `var` declarations, even in strict mode.
### Breaking changes
Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`.
## 4.0.11 (2017-02-07)
### Bug fixes
Allow all forms of member expressions to be parenthesized as lvalue.
## 4.0.10 (2017-02-07)
### Bug fixes
Don't expect semicolons after default-exported functions or classes, even when they are expressions.
Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode.
## 4.0.9 (2017-02-06)
### Bug fixes
Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again.
## 4.0.8 (2017-02-03)
### Bug fixes
Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet.
## 4.0.7 (2017-02-02)
### Bug fixes
Accept invalidly rejected code like `(x).y = 2` again.
Don't raise an error when a function _inside_ strict code has a non-simple parameter list.
## 4.0.6 (2017-02-02)
### Bug fixes
Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check.
## 4.0.5 (2017-02-02)
### Bug fixes
Disallow parenthesized pattern expressions.
Allow keywords as export names.
Don't allow the `async` keyword to be parenthesized.
Properly raise an error when a keyword contains a character escape.
Allow `"use strict"` to appear after other string literal expressions.
Disallow labeled declarations.
## 4.0.4 (2016-12-19)
### Bug fixes
Fix crash when `export` was followed by a keyword that can't be
exported.
## 4.0.3 (2016-08-16)
### Bug fixes
Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode.
Properly parse properties named `async` in ES2017 mode.
Fix bug where reserved words were broken in ES2017 mode.
## 4.0.2 (2016-08-11)
### Bug fixes
Don't ignore period or 'e' characters after octal numbers.
Fix broken parsing for call expressions in default parameter values of arrow functions.
## 4.0.1 (2016-08-08)
### Bug fixes
Fix false positives in duplicated export name errors.
## 4.0.0 (2016-08-07)
### Breaking changes
The default `ecmaVersion` option value is now 7.
A number of internal method signatures changed, so plugins might need to be updated.
### Bug fixes
The parser now raises errors on duplicated export names.
`arguments` and `eval` can now be used in shorthand properties.
Duplicate parameter names in non-simple argument lists now always produce an error.
### New features
The `ecmaVersion` option now also accepts year-style version numbers
(2015, etc).
Support for `async`/`await` syntax when `ecmaVersion` is >= 8.
Support for trailing commas in call expressions when `ecmaVersion` is >= 8.
## 3.3.0 (2016-07-25)
### Bug fixes
Fix bug in tokenizing of regexp operator after a function declaration.
Fix parser crash when parsing an array pattern with a hole.
### New features
Implement check against complex argument lists in functions that enable strict mode in ES7.
## 3.2.0 (2016-06-07)
### Bug fixes
Improve handling of lack of unicode regexp support in host
environment.
Properly reject shorthand properties whose name is a keyword.
### New features
Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object.
## 3.1.0 (2016-04-18)
### Bug fixes
Properly tokenize the division operator directly after a function expression.
Allow trailing comma in destructuring arrays.
## 3.0.4 (2016-02-25)
### Fixes
Allow update expressions as left-hand-side of the ES7 exponential operator.
## 3.0.2 (2016-02-10)
### Fixes
Fix bug that accidentally made `undefined` a reserved word when parsing ES7.
## 3.0.0 (2016-02-10)
### Breaking changes
The default value of the `ecmaVersion` option is now 6 (used to be 5).
Support for comprehension syntax (which was dropped from the draft spec) has been removed.
### Fixes
`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code.
A parenthesized class or function expression after `export default` is now parsed correctly.
### New features
When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`).
The identifier character ranges are now based on Unicode 8.0.0.
Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled.
## 2.7.0 (2016-01-04)
### Fixes
Stop allowing rest parameters in setters.
Disallow `y` rexexp flag in ES5.
Disallow `\00` and `\000` escapes in strict mode.
Raise an error when an import name is a reserved word.
## 2.6.2 (2015-11-10)
### Fixes
Don't crash when no options object is passed.
## 2.6.0 (2015-11-09)
### Fixes
Add `await` as a reserved word in module sources.
Disallow `yield` in a parameter default value for a generator.
Forbid using a comma after a rest pattern in an array destructuring.
### New features
Support parsing stdin in command-line tool.
## 2.5.0 (2015-10-27)
### Fixes
Fix tokenizer support in the command-line tool.
Stop allowing `new.target` outside of functions.
Remove legacy `guard` and `guardedHandler` properties from try nodes.
Stop allowing multiple `__proto__` properties on an object literal in strict mode.
Don't allow rest parameters to be non-identifier patterns.
Check for duplicate paramter names in arrow functions.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (C) 2012-2022 by various contributors (see AUTHORS)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+273
View File
@@ -0,0 +1,273 @@
# Acorn
A tiny, fast JavaScript parser written in JavaScript.
## Community
Acorn is open source software released under an
[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE).
You are welcome to
[report bugs](https://github.com/acornjs/acorn/issues) or create pull
requests on [github](https://github.com/acornjs/acorn). For questions
and discussion, please use the
[Tern discussion forum](https://discuss.ternjs.net).
## Installation
The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):
```sh
npm install acorn
```
Alternately, you can download the source and build acorn yourself:
```sh
git clone https://github.com/acornjs/acorn.git
cd acorn
npm install
```
## Interface
**parse**`(input, options)` is the main interface to the library. The
`input` parameter is a string, `options` must be an object setting
some of the options listed below. The return value will be an abstract
syntax tree object as specified by the [ESTree
spec](https://github.com/estree/estree).
```javascript
let acorn = require("acorn");
console.log(acorn.parse("1 + 1", {ecmaVersion: 2020}));
```
When encountering a syntax error, the parser will raise a
`SyntaxError` object with a meaningful message. The error object will
have a `pos` property that indicates the string offset at which the
error occurred, and a `loc` object that contains a `{line, column}`
object referring to that same position.
Options are provided by in a second argument, which should be an
object containing any of these fields (only `ecmaVersion` is
required):
- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be
either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019),
11 (2020), 12 (2021), 13 (2022, partial support)
or `"latest"` (the latest the library supports). This influences
support for strict mode, the set of reserved words, and support
for new syntax features.
**NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
implemented by Acorn. Other proposed new features must be
implemented through plugins.
- **sourceType**: Indicate the mode the code should be parsed in. Can be
either `"script"` or `"module"`. This influences global strict mode
and parsing of `import` and `export` declarations.
**NOTE**: If set to `"module"`, then static `import` / `export` syntax
will be valid, even if `ecmaVersion` is less than 6.
- **onInsertedSemicolon**: If given a callback, that callback will be
called whenever a missing semicolon is inserted by the parser. The
callback will be given the character offset of the point where the
semicolon is inserted as argument, and if `locations` is on, also a
`{line, column}` object representing this position.
- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
commas.
- **allowReserved**: If `false`, using a reserved word will generate
an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
versions. When given the value `"never"`, reserved words and
keywords can also not be used as property names (as in Internet
Explorer's old parser).
- **allowReturnOutsideFunction**: By default, a return statement at
the top level raises an error. Set this to `true` to accept such
code.
- **allowImportExportEverywhere**: By default, `import` and `export`
declarations can only appear at a program's top level. Setting this
option to `true` allows them anywhere where a statement is allowed,
and also allows `import.meta` expressions to appear in scripts
(when `sourceType` is not `"module"`).
- **allowAwaitOutsideFunction**: If `false`, `await` expressions can
only appear inside `async` functions. Defaults to `true` for
`ecmaVersion` 2022 and later, `false` for lower versions. Setting this option to
`true` allows to have top-level `await` expressions. They are
still not allowed in non-`async` functions, though.
- **allowSuperOutsideMethod**: By default, `super` outside a method
raises an error. Set this to `true` to accept such code.
- **allowHashBang**: When this is enabled (off by default), if the
code starts with the characters `#!` (as in a shellscript), the
first line will be treated as a comment.
- **locations**: When `true`, each node has a `loc` object attached
with `start` and `end` subobjects, each of which contains the
one-based line and zero-based column numbers in `{line, column}`
form. Default is `false`.
- **onToken**: If a function is passed for this option, each found
token will be passed in same format as tokens returned from
`tokenizer().getToken()`.
If array is passed, each found token is pushed to it.
Note that you are not allowed to call the parser from the
callback—that will corrupt its internal state.
- **onComment**: If a function is passed for this option, whenever a
comment is encountered the function will be called with the
following parameters:
- `block`: `true` if the comment is a block comment, false if it
is a line comment.
- `text`: The content of the comment.
- `start`: Character offset of the start of the comment.
- `end`: Character offset of the end of the comment.
When the `locations` options is on, the `{line, column}` locations
of the comments start and end are passed as two additional
parameters.
If array is passed for this option, each found comment is pushed
to it as object in Esprima format:
```javascript
{
"type": "Line" | "Block",
"value": "comment text",
"start": Number,
"end": Number,
// If `locations` option is on:
"loc": {
"start": {line: Number, column: Number}
"end": {line: Number, column: Number}
},
// If `ranges` option is on:
"range": [Number, Number]
}
```
Note that you are not allowed to call the parser from the
callback—that will corrupt its internal state.
- **ranges**: Nodes have their start and end characters offsets
recorded in `start` and `end` properties (directly on the node,
rather than the `loc` object, which holds line/column data. To also
add a
[semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678)
`range` property holding a `[start, end]` array with the same
numbers, set the `ranges` option to `true`.
- **program**: It is possible to parse multiple files into a single
AST by passing the tree produced by parsing the first file as the
`program` option in subsequent parses. This will add the toplevel
forms of the parsed file to the "Program" (top) node of an existing
parse tree.
- **sourceFile**: When the `locations` option is `true`, you can pass
this option to add a `source` attribute in every nodes `loc`
object. Note that the contents of this option are not examined or
processed in any way; you are free to use whatever format you
choose.
- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
will be added (regardless of the `location` option) directly to the
nodes, rather than the `loc` object.
- **preserveParens**: If this option is `true`, parenthesized expressions
are represented by (non-standard) `ParenthesizedExpression` nodes
that have a single `expression` property containing the expression
inside parentheses.
**parseExpressionAt**`(input, offset, options)` will parse a single
expression in a string, and return its AST. It will not complain if
there is more of the string left after the expression.
**tokenizer**`(input, options)` returns an object with a `getToken`
method that can be called repeatedly to get the next token, a `{start,
end, type, value}` object (with added `loc` property when the
`locations` option is enabled and `range` property when the `ranges`
option is enabled). When the token's type is `tokTypes.eof`, you
should stop calling the method, since it will keep returning that same
token forever.
In ES6 environment, returned result can be used as any other
protocol-compliant iterable:
```javascript
for (let token of acorn.tokenizer(str)) {
// iterate over the tokens
}
// transform code to array of tokens:
var tokens = [...acorn.tokenizer(str)];
```
**tokTypes** holds an object mapping names to the token type objects
that end up in the `type` properties of tokens.
**getLineInfo**`(input, offset)` can be used to get a `{line,
column}` object for a given program string and offset.
### The `Parser` class
Instances of the **`Parser`** class contain all the state and logic
that drives a parse. It has static methods `parse`,
`parseExpressionAt`, and `tokenizer` that match the top-level
functions by the same name.
When extending the parser with plugins, you need to call these methods
on the extended version of the class. To extend a parser with plugins,
you can use its static `extend` method.
```javascript
var acorn = require("acorn");
var jsx = require("acorn-jsx");
var JSXParser = acorn.Parser.extend(jsx());
JSXParser.parse("foo(<bar/>)", {ecmaVersion: 2020});
```
The `extend` method takes any number of plugin values, and returns a
new `Parser` class that includes the extra parser logic provided by
the plugins.
## Command line interface
The `bin/acorn` utility can be used to parse a file from the command
line. It accepts as arguments its input file and the following
options:
- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version
to parse. Default is version 9.
- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
- `--locations`: Attaches a "loc" object to each node with "start" and
"end" subobjects, each of which contains the one-based line and
zero-based column numbers in `{line, column}` form.
- `--allow-hash-bang`: If the code starts with the characters #! (as
in a shellscript), the first line will be treated as a comment.
- `--allow-await-outside-function`: Allows top-level `await` expressions.
See the `allowAwaitOutsideFunction` option for more information.
- `--compact`: No whitespace is used in the AST output.
- `--silent`: Do not output the AST, just return the exit status.
- `--help`: Print the usage information and quit.
The utility spits out the syntax tree as JSON data.
## Existing plugins
- [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env node
"use strict"
require("../dist/bin.js")
+252
View File
@@ -0,0 +1,252 @@
export as namespace acorn
export = acorn
declare namespace acorn {
function parse(input: string, options: Options): Node
function parseExpressionAt(input: string, pos: number, options: Options): Node
function tokenizer(input: string, options: Options): {
getToken(): Token
[Symbol.iterator](): Iterator<Token>
}
type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 'latest'
interface Options {
ecmaVersion: ecmaVersion
sourceType?: 'script' | 'module'
onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
allowReserved?: boolean | 'never'
allowReturnOutsideFunction?: boolean
allowImportExportEverywhere?: boolean
allowAwaitOutsideFunction?: boolean
allowSuperOutsideMethod?: boolean
allowHashBang?: boolean
locations?: boolean
onToken?: ((token: Token) => any) | Token[]
onComment?: ((
isBlock: boolean, text: string, start: number, end: number, startLoc?: Position,
endLoc?: Position
) => void) | Comment[]
ranges?: boolean
program?: Node
sourceFile?: string
directSourceFile?: string
preserveParens?: boolean
}
class Parser {
// state.js
lineStart: number;
options: Options;
curLine: number;
start: number;
end: number;
input: string;
type: TokenType;
// state.js
constructor(options: Options, input: string, startPos?: number)
parse(this: Parser): Node
// tokenize.js
next(): void;
nextToken(): void;
// statement.js
parseTopLevel(node: Node): Node;
// node.js
finishNode(node: Node, type: string): Node;
finishNodeAt(node: Node, type: string, pos: number, loc: Position): Node;
// location.js
raise(pos: number, message: string) : void;
raiseRecoverable?(pos: number, message: string) : void;
// parseutils.js
unexpected(pos: number) : void;
// index.js
static acorn: typeof acorn;
// state.js
static parse(this: typeof Parser, input: string, options: Options): Node
static parseExpressionAt(this: typeof Parser, input: string, pos: number, options: Options): Node
static tokenizer(this: typeof Parser, input: string, options: Options): {
getToken(): Token
[Symbol.iterator](): Iterator<Token>
}
static extend(this: typeof Parser, ...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser
}
interface Position { line: number; column: number; offset: number }
const defaultOptions: Options
function getLineInfo(input: string, offset: number): Position
class SourceLocation {
start: Position
end: Position
source?: string | null
constructor(p: Parser, start: Position, end: Position)
}
class Node {
type: string
start: number
end: number
loc?: SourceLocation
sourceFile?: string
range?: [number, number]
constructor(parser: Parser, pos: number, loc?: SourceLocation)
}
class TokenType {
label: string
keyword: string
beforeExpr: boolean
startsExpr: boolean
isLoop: boolean
isAssign: boolean
prefix: boolean
postfix: boolean
binop: number
updateContext?: (prevType: TokenType) => void
constructor(label: string, conf?: any)
}
const tokTypes: {
num: TokenType
regexp: TokenType
string: TokenType
name: TokenType
privateId: TokenType
eof: TokenType
bracketL: TokenType
bracketR: TokenType
braceL: TokenType
braceR: TokenType
parenL: TokenType
parenR: TokenType
comma: TokenType
semi: TokenType
colon: TokenType
dot: TokenType
question: TokenType
questionDot: TokenType
arrow: TokenType
template: TokenType
invalidTemplate: TokenType
ellipsis: TokenType
backQuote: TokenType
dollarBraceL: TokenType
eq: TokenType
assign: TokenType
incDec: TokenType
prefix: TokenType
logicalOR: TokenType
logicalAND: TokenType
bitwiseOR: TokenType
bitwiseXOR: TokenType
bitwiseAND: TokenType
equality: TokenType
relational: TokenType
bitShift: TokenType
plusMin: TokenType
modulo: TokenType
star: TokenType
slash: TokenType
starstar: TokenType
coalesce: TokenType
_break: TokenType
_case: TokenType
_catch: TokenType
_continue: TokenType
_debugger: TokenType
_default: TokenType
_do: TokenType
_else: TokenType
_finally: TokenType
_for: TokenType
_function: TokenType
_if: TokenType
_return: TokenType
_switch: TokenType
_throw: TokenType
_try: TokenType
_var: TokenType
_const: TokenType
_while: TokenType
_with: TokenType
_new: TokenType
_this: TokenType
_super: TokenType
_class: TokenType
_extends: TokenType
_export: TokenType
_import: TokenType
_null: TokenType
_true: TokenType
_false: TokenType
_in: TokenType
_instanceof: TokenType
_typeof: TokenType
_void: TokenType
_delete: TokenType
}
class TokContext {
constructor(token: string, isExpr: boolean, preserveSpace: boolean, override?: (p: Parser) => void)
}
const tokContexts: {
b_stat: TokContext
b_expr: TokContext
b_tmpl: TokContext
p_stat: TokContext
p_expr: TokContext
q_tmpl: TokContext
f_expr: TokContext
f_stat: TokContext
f_expr_gen: TokContext
f_gen: TokContext
}
function isIdentifierStart(code: number, astral?: boolean): boolean
function isIdentifierChar(code: number, astral?: boolean): boolean
interface AbstractToken {
}
interface Comment extends AbstractToken {
type: string
value: string
start: number
end: number
loc?: SourceLocation
range?: [number, number]
}
class Token {
type: TokenType
value: any
start: number
end: number
loc?: SourceLocation
range?: [number, number]
constructor(p: Parser)
}
function isNewLine(code: number): boolean
const lineBreak: RegExp
const lineBreakG: RegExp
const version: string
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,2 @@
import * as acorn from "./acorn";
export = acorn;
+91
View File
@@ -0,0 +1,91 @@
'use strict';
var path = require('path');
var fs = require('fs');
var acorn = require('./acorn.js');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var acorn__namespace = /*#__PURE__*/_interopNamespace(acorn);
var inputFilePaths = [], forceFileName = false, fileMode = false, silent = false, compact = false, tokenize = false;
var options = {};
function help(status) {
var print = (status === 0) ? console.log : console.error;
print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|...|--ecma2015|--ecma2016|--ecma2017|--ecma2018|...]");
print(" [--tokenize] [--locations] [--allow-hash-bang] [--allow-await-outside-function] [--compact] [--silent] [--module] [--help] [--] [<infile>...]");
process.exit(status);
}
for (var i = 2; i < process.argv.length; ++i) {
var arg = process.argv[i];
if (arg[0] !== "-" || arg === "-") { inputFilePaths.push(arg); }
else if (arg === "--") {
inputFilePaths.push.apply(inputFilePaths, process.argv.slice(i + 1));
forceFileName = true;
break
} else if (arg === "--locations") { options.locations = true; }
else if (arg === "--allow-hash-bang") { options.allowHashBang = true; }
else if (arg === "--allow-await-outside-function") { options.allowAwaitOutsideFunction = true; }
else if (arg === "--silent") { silent = true; }
else if (arg === "--compact") { compact = true; }
else if (arg === "--help") { help(0); }
else if (arg === "--tokenize") { tokenize = true; }
else if (arg === "--module") { options.sourceType = "module"; }
else {
var match = arg.match(/^--ecma(\d+)$/);
if (match)
{ options.ecmaVersion = +match[1]; }
else
{ help(1); }
}
}
function run(codeList) {
var result = [], fileIdx = 0;
try {
codeList.forEach(function (code, idx) {
fileIdx = idx;
if (!tokenize) {
result = acorn__namespace.parse(code, options);
options.program = result;
} else {
var tokenizer = acorn__namespace.tokenizer(code, options), token;
do {
token = tokenizer.getToken();
result.push(token);
} while (token.type !== acorn__namespace.tokTypes.eof)
}
});
} catch (e) {
console.error(fileMode ? e.message.replace(/\(\d+:\d+\)$/, function (m) { return m.slice(0, 1) + inputFilePaths[fileIdx] + " " + m.slice(1); }) : e.message);
process.exit(1);
}
if (!silent) { console.log(JSON.stringify(result, null, compact ? null : 2)); }
}
if (fileMode = inputFilePaths.length && (forceFileName || !inputFilePaths.includes("-") || inputFilePaths.length !== 1)) {
run(inputFilePaths.map(function (path) { return fs.readFileSync(path, "utf8"); }));
} else {
var code = "";
process.stdin.resume();
process.stdin.on("data", function (chunk) { return code += chunk; });
process.stdin.on("end", function () { return run([code]); });
}
+81
View File
@@ -0,0 +1,81 @@
{
"_args": [
[
"acorn@8.7.1",
"/home/node/nuxt"
]
],
"_from": "acorn@8.7.1",
"_id": "acorn@8.7.1",
"_inBundle": false,
"_integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
"_location": "/terser-webpack-plugin/acorn",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "acorn@8.7.1",
"name": "acorn",
"escapedName": "acorn",
"rawSpec": "8.7.1",
"saveSpec": null,
"fetchSpec": "8.7.1"
},
"_requiredBy": [
"/terser-webpack-plugin/terser"
],
"_resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
"_spec": "8.7.1",
"_where": "/home/node/nuxt",
"bin": {
"acorn": "bin/acorn"
},
"bugs": {
"url": "https://github.com/acornjs/acorn/issues"
},
"description": "ECMAScript parser",
"engines": {
"node": ">=0.4.0"
},
"exports": {
".": [
{
"import": "./dist/acorn.mjs",
"require": "./dist/acorn.js",
"default": "./dist/acorn.js"
},
"./dist/acorn.js"
],
"./package.json": "./package.json"
},
"homepage": "https://github.com/acornjs/acorn",
"license": "MIT",
"main": "dist/acorn.js",
"maintainers": [
{
"name": "Marijn Haverbeke",
"email": "marijnh@gmail.com",
"url": "https://marijnhaverbeke.nl"
},
{
"name": "Ingvar Stepanyan",
"email": "me@rreverser.com",
"url": "https://rreverser.com/"
},
{
"name": "Adrian Heine",
"url": "http://adrianheine.de"
}
],
"module": "dist/acorn.mjs",
"name": "acorn",
"repository": {
"type": "git",
"url": "git+https://github.com/acornjs/acorn.git"
},
"scripts": {
"prepare": "cd ..; npm run build:main"
},
"types": "dist/acorn.d.ts",
"version": "8.7.1"
}
@@ -0,0 +1,67 @@
'use strict';
const path = require('path');
const fs = require('fs');
const commonDir = require('commondir');
const pkgDir = require('pkg-dir');
const makeDir = require('make-dir');
const {env, cwd} = process;
const isWritable = path => {
try {
fs.accessSync(path, fs.constants.W_OK);
return true;
} catch (_) {
return false;
}
};
function useDirectory(directory, options) {
if (options.create) {
makeDir.sync(directory);
}
if (options.thunk) {
return (...arguments_) => path.join(directory, ...arguments_);
}
return directory;
}
function getNodeModuleDirectory(directory) {
const nodeModules = path.join(directory, 'node_modules');
if (
!isWritable(nodeModules) &&
(fs.existsSync(nodeModules) || !isWritable(path.join(directory)))
) {
return;
}
return nodeModules;
}
module.exports = (options = {}) => {
if (env.CACHE_DIR && !['true', 'false', '1', '0'].includes(env.CACHE_DIR)) {
return useDirectory(path.join(env.CACHE_DIR, options.name), options);
}
let {cwd: directory = cwd()} = options;
if (options.files) {
directory = commonDir(directory, options.files);
}
directory = pkgDir.sync(directory);
if (!directory) {
return;
}
const nodeModules = getNodeModuleDirectory(directory);
if (!nodeModules) {
return undefined;
}
return useDirectory(path.join(directory, 'node_modules', '.cache', options.name), options);
};
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,79 @@
{
"_args": [
[
"find-cache-dir@3.3.2",
"/home/node/nuxt"
]
],
"_from": "find-cache-dir@3.3.2",
"_id": "find-cache-dir@3.3.2",
"_inBundle": false,
"_integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"_location": "/terser-webpack-plugin/find-cache-dir",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "find-cache-dir@3.3.2",
"name": "find-cache-dir",
"escapedName": "find-cache-dir",
"rawSpec": "3.3.2",
"saveSpec": null,
"fetchSpec": "3.3.2"
},
"_requiredBy": [
"/terser-webpack-plugin"
],
"_resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"_spec": "3.3.2",
"_where": "/home/node/nuxt",
"bugs": {
"url": "https://github.com/avajs/find-cache-dir/issues"
},
"dependencies": {
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
},
"description": "Finds the common standard cache directory",
"devDependencies": {
"ava": "^2.4.0",
"coveralls": "^3.0.9",
"del": "^4.0.0",
"nyc": "^15.0.0",
"tempy": "^0.4.0",
"xo": "^0.25.3"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js"
],
"funding": "https://github.com/avajs/find-cache-dir?sponsor=1",
"homepage": "https://github.com/avajs/find-cache-dir#readme",
"keywords": [
"cache",
"directory",
"dir",
"caching",
"find",
"search"
],
"license": "MIT",
"name": "find-cache-dir",
"nyc": {
"reporter": [
"lcov",
"text"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/avajs/find-cache-dir.git"
},
"scripts": {
"test": "xo && nyc ava"
},
"version": "3.3.2"
}
@@ -0,0 +1,123 @@
# find-cache-dir [![Coverage Status](https://codecov.io/gh/avajs/find-cache-dir/branch/master/graph/badge.svg)](https://codecov.io/gh/avajs/find-cache-dir/branch/master)
> Finds the common standard cache directory
The [`nyc`](https://github.com/istanbuljs/nyc) and [`AVA`](https://ava.li) projects decided to standardize on a common directory structure for storing cache information:
```sh
# nyc
./node_modules/.cache/nyc
# ava
./node_modules/.cache/ava
# your-module
./node_modules/.cache/your-module
```
This module makes it easy to correctly locate the cache directory according to this shared spec. If this pattern becomes ubiquitous, clearing the cache for multiple dependencies becomes easy and consistent:
```
rm -rf ./node_modules/.cache
```
If you decide to adopt this pattern, please file a PR adding your name to the list of adopters below.
## Install
```
$ npm install find-cache-dir
```
## Usage
```js
const findCacheDir = require('find-cache-dir');
findCacheDir({name: 'unicorns'});
//=> '/user/path/node-modules/.cache/unicorns'
```
## API
### findCacheDir(options?)
Finds the cache directory using the supplied options. The algorithm checks for the `CACHE_DIR` environmental variable and uses it if it is not set to `true`, `false`, `1` or `0`. If one is not found, it tries to find a `package.json` file, searching every parent directory of the `cwd` specified (or implied from other options). It returns a `string` containing the absolute path to the cache directory, or `undefined` if `package.json` was never found or if the `node_modules` directory is unwritable.
#### options
Type: `object`
##### name
*Required*\
Type: `string`
Should be the same as your project name in `package.json`.
##### files
Type: `string[] | string`
An array of files that will be searched for a common parent directory. This common parent directory will be used in lieu of the `cwd` option below.
##### cwd
Type: `string`\
Default `process.cwd()`
Directory to start searching for a `package.json` from.
##### create
Type: `boolean`\
Default `false`
If `true`, the directory will be created synchronously before returning.
##### thunk
Type: `boolean`\
Default `false`
If `true`, this modifies the return type to be a function that is a thunk for `path.join(theFoundCacheDirectory)`.
```js
const thunk = findCacheDir({name: 'foo', thunk: true});
thunk();
//=> '/some/path/node_modules/.cache/foo'
thunk('bar.js')
//=> '/some/path/node_modules/.cache/foo/bar.js'
thunk('baz', 'quz.js')
//=> '/some/path/node_modules/.cache/foo/baz/quz.js'
```
This is helpful for actually putting actual files in the cache!
## Tips
- To test modules using `find-cache-dir`, set the `CACHE_DIR` environment variable to temporarily override the directory that is resolved.
## Adopters
- [`ava`](https://avajs.dev)
- [`nyc`](https://github.com/istanbuljs/nyc)
- [`storybook`](https://github.com/storybookjs/storybook)
- [`babel-loader`](https://github.com/babel/babel-loader)
- [`eslint-loader`](https://github.com/MoOx/eslint-loader)
- [More…](https://www.npmjs.com/browse/depended/find-cache-dir)
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-find_cache-dir?utm_source=npm-find-cache-dir&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>
+137
View File
@@ -0,0 +1,137 @@
import {Options as LocatePathOptions} from 'locate-path';
declare const stop: unique symbol;
declare namespace findUp {
interface Options extends LocatePathOptions {}
type StopSymbol = typeof stop;
type Match = string | StopSymbol | undefined;
}
declare const findUp: {
/**
Find a file or directory by walking up parent directories.
@param name - Name of the file or directory to find. Can be multiple.
@returns The first path found (by respecting the order of `name`s) or `undefined` if none could be found.
@example
```
// /
// └── Users
// └── sindresorhus
// ├── unicorn.png
// └── foo
// └── bar
// ├── baz
// └── example.js
// example.js
import findUp = require('find-up');
(async () => {
console.log(await findUp('unicorn.png'));
//=> '/Users/sindresorhus/unicorn.png'
console.log(await findUp(['rainbow.png', 'unicorn.png']));
//=> '/Users/sindresorhus/unicorn.png'
})();
```
*/
(name: string | string[], options?: findUp.Options): Promise<string | undefined>;
/**
Find a file or directory by walking up parent directories.
@param matcher - Called for each directory in the search. Return a path or `findUp.stop` to stop the search.
@returns The first path found or `undefined` if none could be found.
@example
```
import path = require('path');
import findUp = require('find-up');
(async () => {
console.log(await findUp(async directory => {
const hasUnicorns = await findUp.exists(path.join(directory, 'unicorn.png'));
return hasUnicorns && directory;
}, {type: 'directory'}));
//=> '/Users/sindresorhus'
})();
```
*/
(matcher: (directory: string) => (findUp.Match | Promise<findUp.Match>), options?: findUp.Options): Promise<string | undefined>;
sync: {
/**
Synchronously find a file or directory by walking up parent directories.
@param name - Name of the file or directory to find. Can be multiple.
@returns The first path found (by respecting the order of `name`s) or `undefined` if none could be found.
*/
(name: string | string[], options?: findUp.Options): string | undefined;
/**
Synchronously find a file or directory by walking up parent directories.
@param matcher - Called for each directory in the search. Return a path or `findUp.stop` to stop the search.
@returns The first path found or `undefined` if none could be found.
@example
```
import path = require('path');
import findUp = require('find-up');
console.log(findUp.sync(directory => {
const hasUnicorns = findUp.sync.exists(path.join(directory, 'unicorn.png'));
return hasUnicorns && directory;
}, {type: 'directory'}));
//=> '/Users/sindresorhus'
```
*/
(matcher: (directory: string) => findUp.Match, options?: findUp.Options): string | undefined;
/**
Synchronously check if a path exists.
@param path - Path to the file or directory.
@returns Whether the path exists.
@example
```
import findUp = require('find-up');
console.log(findUp.sync.exists('/Users/sindresorhus/unicorn.png'));
//=> true
```
*/
exists(path: string): boolean;
}
/**
Check if a path exists.
@param path - Path to a file or directory.
@returns Whether the path exists.
@example
```
import findUp = require('find-up');
(async () => {
console.log(await findUp.exists('/Users/sindresorhus/unicorn.png'));
//=> true
})();
```
*/
exists(path: string): Promise<boolean>;
/**
Return this in a `matcher` function to stop the search and force `findUp` to immediately return `undefined`.
*/
readonly stop: findUp.StopSymbol;
};
export = findUp;
+89
View File
@@ -0,0 +1,89 @@
'use strict';
const path = require('path');
const locatePath = require('locate-path');
const pathExists = require('path-exists');
const stop = Symbol('findUp.stop');
module.exports = async (name, options = {}) => {
let directory = path.resolve(options.cwd || '');
const {root} = path.parse(directory);
const paths = [].concat(name);
const runMatcher = async locateOptions => {
if (typeof name !== 'function') {
return locatePath(paths, locateOptions);
}
const foundPath = await name(locateOptions.cwd);
if (typeof foundPath === 'string') {
return locatePath([foundPath], locateOptions);
}
return foundPath;
};
// eslint-disable-next-line no-constant-condition
while (true) {
// eslint-disable-next-line no-await-in-loop
const foundPath = await runMatcher({...options, cwd: directory});
if (foundPath === stop) {
return;
}
if (foundPath) {
return path.resolve(directory, foundPath);
}
if (directory === root) {
return;
}
directory = path.dirname(directory);
}
};
module.exports.sync = (name, options = {}) => {
let directory = path.resolve(options.cwd || '');
const {root} = path.parse(directory);
const paths = [].concat(name);
const runMatcher = locateOptions => {
if (typeof name !== 'function') {
return locatePath.sync(paths, locateOptions);
}
const foundPath = name(locateOptions.cwd);
if (typeof foundPath === 'string') {
return locatePath.sync([foundPath], locateOptions);
}
return foundPath;
};
// eslint-disable-next-line no-constant-condition
while (true) {
const foundPath = runMatcher({...options, cwd: directory});
if (foundPath === stop) {
return;
}
if (foundPath) {
return path.resolve(directory, foundPath);
}
if (directory === root) {
return;
}
directory = path.dirname(directory);
}
};
module.exports.exists = pathExists;
module.exports.sync.exists = pathExists.sync;
module.exports.stop = stop;
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+88
View File
@@ -0,0 +1,88 @@
{
"_args": [
[
"find-up@4.1.0",
"/home/node/nuxt"
]
],
"_from": "find-up@4.1.0",
"_id": "find-up@4.1.0",
"_inBundle": false,
"_integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"_location": "/terser-webpack-plugin/find-up",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "find-up@4.1.0",
"name": "find-up",
"escapedName": "find-up",
"rawSpec": "4.1.0",
"saveSpec": null,
"fetchSpec": "4.1.0"
},
"_requiredBy": [
"/terser-webpack-plugin/pkg-dir"
],
"_resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"_spec": "4.1.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/find-up/issues"
},
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"description": "Find a file or directory by walking up parent directories",
"devDependencies": {
"ava": "^2.1.0",
"is-path-inside": "^2.1.0",
"tempy": "^0.3.0",
"tsd": "^0.7.3",
"xo": "^0.24.0"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js",
"index.d.ts"
],
"homepage": "https://github.com/sindresorhus/find-up#readme",
"keywords": [
"find",
"up",
"find-up",
"findup",
"look-up",
"look",
"file",
"search",
"match",
"package",
"resolve",
"parent",
"parents",
"folder",
"directory",
"walk",
"walking",
"path"
],
"license": "MIT",
"name": "find-up",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/find-up.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "4.1.0"
}
+156
View File
@@ -0,0 +1,156 @@
# find-up [![Build Status](https://travis-ci.org/sindresorhus/find-up.svg?branch=master)](https://travis-ci.org/sindresorhus/find-up)
> Find a file or directory by walking up parent directories
## Install
```
$ npm install find-up
```
## Usage
```
/
└── Users
└── sindresorhus
├── unicorn.png
└── foo
└── bar
├── baz
└── example.js
```
`example.js`
```js
const path = require('path');
const findUp = require('find-up');
(async () => {
console.log(await findUp('unicorn.png'));
//=> '/Users/sindresorhus/unicorn.png'
console.log(await findUp(['rainbow.png', 'unicorn.png']));
//=> '/Users/sindresorhus/unicorn.png'
console.log(await findUp(async directory => {
const hasUnicorns = await findUp.exists(path.join(directory, 'unicorn.png'));
return hasUnicorns && directory;
}, {type: 'directory'}));
//=> '/Users/sindresorhus'
})();
```
## API
### findUp(name, options?)
### findUp(matcher, options?)
Returns a `Promise` for either the path or `undefined` if it couldn't be found.
### findUp([...name], options?)
Returns a `Promise` for either the first path found (by respecting the order of the array) or `undefined` if none could be found.
### findUp.sync(name, options?)
### findUp.sync(matcher, options?)
Returns a path or `undefined` if it couldn't be found.
### findUp.sync([...name], options?)
Returns the first path found (by respecting the order of the array) or `undefined` if none could be found.
#### name
Type: `string`
Name of the file or directory to find.
#### matcher
Type: `Function`
A function that will be called with each directory until it returns a `string` with the path, which stops the search, or the root directory has been reached and nothing was found. Useful if you want to match files with certain patterns, set of permissions, or other advanced use-cases.
When using async mode, the `matcher` may optionally be an async or promise-returning function that returns the path.
#### options
Type: `object`
##### cwd
Type: `string`<br>
Default: `process.cwd()`
Directory to start from.
##### type
Type: `string`<br>
Default: `'file'`<br>
Values: `'file'` `'directory'`
The type of paths that can match.
##### allowSymlinks
Type: `boolean`<br>
Default: `true`
Allow symbolic links to match if they point to the chosen path type.
### findUp.exists(path)
Returns a `Promise<boolean>` of whether the path exists.
### findUp.sync.exists(path)
Returns a `boolean` of whether the path exists.
#### path
Type: `string`
Path to a file or directory.
### findUp.stop
A [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) that can be returned by a `matcher` function to stop the search and cause `findUp` to immediately return `undefined`. Useful as a performance optimization in case the current working directory is deeply nested in the filesystem.
```js
const path = require('path');
const findUp = require('find-up');
(async () => {
await findUp(directory => {
return path.basename(directory) === 'work' ? findUp.stop : 'logo.png';
});
})();
```
## Related
- [find-up-cli](https://github.com/sindresorhus/find-up-cli) - CLI for this module
- [pkg-up](https://github.com/sindresorhus/pkg-up) - Find the closest package.json file
- [pkg-dir](https://github.com/sindresorhus/pkg-dir) - Find the root directory of an npm package
- [resolve-from](https://github.com/sindresorhus/resolve-from) - Resolve the path of a module like `require.resolve()` but from a given path
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-find-up?utm_source=npm-find-up&utm_medium=referral&utm_campaign=readme">Get professional support for 'find-up' with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>
+83
View File
@@ -0,0 +1,83 @@
declare namespace locatePath {
interface Options {
/**
Current working directory.
@default process.cwd()
*/
readonly cwd?: string;
/**
Type of path to match.
@default 'file'
*/
readonly type?: 'file' | 'directory';
/**
Allow symbolic links to match if they point to the requested path type.
@default true
*/
readonly allowSymlinks?: boolean;
}
interface AsyncOptions extends Options {
/**
Number of concurrently pending promises. Minimum: `1`.
@default Infinity
*/
readonly concurrency?: number;
/**
Preserve `paths` order when searching.
Disable this to improve performance if you don't care about the order.
@default true
*/
readonly preserveOrder?: boolean;
}
}
declare const locatePath: {
/**
Get the first path that exists on disk of multiple paths.
@param paths - Paths to check.
@returns The first path that exists or `undefined` if none exists.
@example
```
import locatePath = require('locate-path');
const files = [
'unicorn.png',
'rainbow.png', // Only this one actually exists on disk
'pony.png'
];
(async () => {
console(await locatePath(files));
//=> 'rainbow'
})();
```
*/
(paths: Iterable<string>, options?: locatePath.AsyncOptions): Promise<
string | undefined
>;
/**
Synchronously get the first path that exists on disk of multiple paths.
@param paths - Paths to check.
@returns The first path that exists or `undefined` if none exists.
*/
sync(
paths: Iterable<string>,
options?: locatePath.Options
): string | undefined;
};
export = locatePath;
+65
View File
@@ -0,0 +1,65 @@
'use strict';
const path = require('path');
const fs = require('fs');
const {promisify} = require('util');
const pLocate = require('p-locate');
const fsStat = promisify(fs.stat);
const fsLStat = promisify(fs.lstat);
const typeMappings = {
directory: 'isDirectory',
file: 'isFile'
};
function checkType({type}) {
if (type in typeMappings) {
return;
}
throw new Error(`Invalid type specified: ${type}`);
}
const matchType = (type, stat) => type === undefined || stat[typeMappings[type]]();
module.exports = async (paths, options) => {
options = {
cwd: process.cwd(),
type: 'file',
allowSymlinks: true,
...options
};
checkType(options);
const statFn = options.allowSymlinks ? fsStat : fsLStat;
return pLocate(paths, async path_ => {
try {
const stat = await statFn(path.resolve(options.cwd, path_));
return matchType(options.type, stat);
} catch (_) {
return false;
}
}, options);
};
module.exports.sync = (paths, options) => {
options = {
cwd: process.cwd(),
allowSymlinks: true,
type: 'file',
...options
};
checkType(options);
const statFn = options.allowSymlinks ? fs.statSync : fs.lstatSync;
for (const path_ of paths) {
try {
const stat = statFn(path.resolve(options.cwd, path_));
if (matchType(options.type, stat)) {
return path_;
}
} catch (_) {
}
}
};
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,80 @@
{
"_args": [
[
"locate-path@5.0.0",
"/home/node/nuxt"
]
],
"_from": "locate-path@5.0.0",
"_id": "locate-path@5.0.0",
"_inBundle": false,
"_integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"_location": "/terser-webpack-plugin/locate-path",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "locate-path@5.0.0",
"name": "locate-path",
"escapedName": "locate-path",
"rawSpec": "5.0.0",
"saveSpec": null,
"fetchSpec": "5.0.0"
},
"_requiredBy": [
"/terser-webpack-plugin/find-up"
],
"_resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"_spec": "5.0.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/locate-path/issues"
},
"dependencies": {
"p-locate": "^4.1.0"
},
"description": "Get the first path that exists on disk of multiple paths",
"devDependencies": {
"ava": "^1.4.1",
"tsd": "^0.7.2",
"xo": "^0.24.0"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js",
"index.d.ts"
],
"homepage": "https://github.com/sindresorhus/locate-path#readme",
"keywords": [
"locate",
"path",
"paths",
"file",
"files",
"exists",
"find",
"finder",
"search",
"searcher",
"array",
"iterable",
"iterator"
],
"license": "MIT",
"name": "locate-path",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/locate-path.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "5.0.0"
}
+122
View File
@@ -0,0 +1,122 @@
# locate-path [![Build Status](https://travis-ci.org/sindresorhus/locate-path.svg?branch=master)](https://travis-ci.org/sindresorhus/locate-path)
> Get the first path that exists on disk of multiple paths
## Install
```
$ npm install locate-path
```
## Usage
Here we find the first file that exists on disk, in array order.
```js
const locatePath = require('locate-path');
const files = [
'unicorn.png',
'rainbow.png', // Only this one actually exists on disk
'pony.png'
];
(async () => {
console(await locatePath(files));
//=> 'rainbow'
})();
```
## API
### locatePath(paths, [options])
Returns a `Promise<string>` for the first path that exists or `undefined` if none exists.
#### paths
Type: `Iterable<string>`
Paths to check.
#### options
Type: `Object`
##### concurrency
Type: `number`<br>
Default: `Infinity`<br>
Minimum: `1`
Number of concurrently pending promises.
##### preserveOrder
Type: `boolean`<br>
Default: `true`
Preserve `paths` order when searching.
Disable this to improve performance if you don't care about the order.
##### cwd
Type: `string`<br>
Default: `process.cwd()`
Current working directory.
##### type
Type: `string`<br>
Default: `file`<br>
Values: `file` `directory`
The type of paths that can match.
##### allowSymlinks
Type: `boolean`<br>
Default: `true`
Allow symbolic links to match if they point to the chosen path type.
### locatePath.sync(paths, [options])
Returns the first path that exists or `undefined` if none exists.
#### paths
Type: `Iterable<string>`
Paths to check.
#### options
Type: `Object`
##### cwd
Same as above.
##### type
Same as above.
##### allowSymlinks
Same as above.
## Related
- [path-exists](https://github.com/sindresorhus/path-exists) - Check if a path exists
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)
+66
View File
@@ -0,0 +1,66 @@
/// <reference types="node"/>
import * as fs from 'fs';
declare namespace makeDir {
interface Options {
/**
Directory [permissions](https://x-team.com/blog/file-system-permissions-umask-node-js/).
@default 0o777
*/
readonly mode?: number;
/**
Use a custom `fs` implementation. For example [`graceful-fs`](https://github.com/isaacs/node-graceful-fs).
Using a custom `fs` implementation will block the use of the native `recursive` option if `fs.mkdir` or `fs.mkdirSync` is not the native function.
@default require('fs')
*/
readonly fs?: typeof fs;
}
}
declare const makeDir: {
/**
Make a directory and its parents if needed - Think `mkdir -p`.
@param path - Directory to create.
@returns The path to the created directory.
@example
```
import makeDir = require('make-dir');
(async () => {
const path = await makeDir('unicorn/rainbow/cake');
console.log(path);
//=> '/Users/sindresorhus/fun/unicorn/rainbow/cake'
// Multiple directories:
const paths = await Promise.all([
makeDir('unicorn/rainbow'),
makeDir('foo/bar')
]);
console.log(paths);
// [
// '/Users/sindresorhus/fun/unicorn/rainbow',
// '/Users/sindresorhus/fun/foo/bar'
// ]
})();
```
*/
(path: string, options?: makeDir.Options): Promise<string>;
/**
Synchronously make a directory and its parents if needed - Think `mkdir -p`.
@param path - Directory to create.
@returns The path to the created directory.
*/
sync(path: string, options?: makeDir.Options): string;
};
export = makeDir;
+156
View File
@@ -0,0 +1,156 @@
'use strict';
const fs = require('fs');
const path = require('path');
const {promisify} = require('util');
const semver = require('semver');
const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0');
// https://github.com/nodejs/node/issues/8987
// https://github.com/libuv/libuv/pull/1088
const checkPath = pth => {
if (process.platform === 'win32') {
const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, ''));
if (pathHasInvalidWinCharacters) {
const error = new Error(`Path contains invalid characters: ${pth}`);
error.code = 'EINVAL';
throw error;
}
}
};
const processOptions = options => {
// https://github.com/sindresorhus/make-dir/issues/18
const defaults = {
mode: 0o777,
fs
};
return {
...defaults,
...options
};
};
const permissionError = pth => {
// This replicates the exception of `fs.mkdir` with native the
// `recusive` option when run on an invalid drive under Windows.
const error = new Error(`operation not permitted, mkdir '${pth}'`);
error.code = 'EPERM';
error.errno = -4048;
error.path = pth;
error.syscall = 'mkdir';
return error;
};
const makeDir = async (input, options) => {
checkPath(input);
options = processOptions(options);
const mkdir = promisify(options.fs.mkdir);
const stat = promisify(options.fs.stat);
if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) {
const pth = path.resolve(input);
await mkdir(pth, {
mode: options.mode,
recursive: true
});
return pth;
}
const make = async pth => {
try {
await mkdir(pth, options.mode);
return pth;
} catch (error) {
if (error.code === 'EPERM') {
throw error;
}
if (error.code === 'ENOENT') {
if (path.dirname(pth) === pth) {
throw permissionError(pth);
}
if (error.message.includes('null bytes')) {
throw error;
}
await make(path.dirname(pth));
return make(pth);
}
try {
const stats = await stat(pth);
if (!stats.isDirectory()) {
throw new Error('The path is not a directory');
}
} catch (_) {
throw error;
}
return pth;
}
};
return make(path.resolve(input));
};
module.exports = makeDir;
module.exports.sync = (input, options) => {
checkPath(input);
options = processOptions(options);
if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) {
const pth = path.resolve(input);
fs.mkdirSync(pth, {
mode: options.mode,
recursive: true
});
return pth;
}
const make = pth => {
try {
options.fs.mkdirSync(pth, options.mode);
} catch (error) {
if (error.code === 'EPERM') {
throw error;
}
if (error.code === 'ENOENT') {
if (path.dirname(pth) === pth) {
throw permissionError(pth);
}
if (error.message.includes('null bytes')) {
throw error;
}
make(path.dirname(pth));
return make(pth);
}
try {
if (!options.fs.statSync(pth).isDirectory()) {
throw new Error('The path is not a directory');
}
} catch (_) {
throw error;
}
}
return pth;
};
return make(path.resolve(input));
};
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+94
View File
@@ -0,0 +1,94 @@
{
"_args": [
[
"make-dir@3.1.0",
"/home/node/nuxt"
]
],
"_from": "make-dir@3.1.0",
"_id": "make-dir@3.1.0",
"_inBundle": false,
"_integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"_location": "/terser-webpack-plugin/make-dir",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "make-dir@3.1.0",
"name": "make-dir",
"escapedName": "make-dir",
"rawSpec": "3.1.0",
"saveSpec": null,
"fetchSpec": "3.1.0"
},
"_requiredBy": [
"/terser-webpack-plugin/find-cache-dir"
],
"_resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"_spec": "3.1.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/make-dir/issues"
},
"dependencies": {
"semver": "^6.0.0"
},
"description": "Make a directory and its parents if needed - Think `mkdir -p`",
"devDependencies": {
"@types/graceful-fs": "^4.1.3",
"@types/node": "^13.7.1",
"ava": "^1.4.0",
"codecov": "^3.2.0",
"graceful-fs": "^4.1.15",
"nyc": "^15.0.0",
"path-type": "^4.0.0",
"tempy": "^0.2.1",
"tsd": "^0.11.0",
"xo": "^0.25.4"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js",
"index.d.ts"
],
"funding": "https://github.com/sponsors/sindresorhus",
"homepage": "https://github.com/sindresorhus/make-dir#readme",
"keywords": [
"mkdir",
"mkdirp",
"make",
"directories",
"dir",
"dirs",
"folders",
"directory",
"folder",
"path",
"parent",
"parents",
"intermediate",
"recursively",
"recursive",
"create",
"fs",
"filesystem",
"file-system"
],
"license": "MIT",
"name": "make-dir",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/make-dir.git"
},
"scripts": {
"test": "xo && nyc ava && tsd"
},
"version": "3.1.0"
}
+125
View File
@@ -0,0 +1,125 @@
# make-dir [![Build Status](https://travis-ci.org/sindresorhus/make-dir.svg?branch=master)](https://travis-ci.org/sindresorhus/make-dir) [![codecov](https://codecov.io/gh/sindresorhus/make-dir/branch/master/graph/badge.svg)](https://codecov.io/gh/sindresorhus/make-dir)
> Make a directory and its parents if needed - Think `mkdir -p`
## Advantages over [`mkdirp`](https://github.com/substack/node-mkdirp)
- Promise API *(Async/await ready!)*
- Fixes many `mkdirp` issues: [#96](https://github.com/substack/node-mkdirp/pull/96) [#70](https://github.com/substack/node-mkdirp/issues/70) [#66](https://github.com/substack/node-mkdirp/issues/66)
- 100% test coverage
- CI-tested on macOS, Linux, and Windows
- Actively maintained
- Doesn't bundle a CLI
- Uses the native `fs.mkdir/mkdirSync` [`recursive` option](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_mkdir_path_options_callback) in Node.js >=10.12.0 unless [overridden](#fs)
## Install
```
$ npm install make-dir
```
## Usage
```
$ pwd
/Users/sindresorhus/fun
$ tree
.
```
```js
const makeDir = require('make-dir');
(async () => {
const path = await makeDir('unicorn/rainbow/cake');
console.log(path);
//=> '/Users/sindresorhus/fun/unicorn/rainbow/cake'
})();
```
```
$ tree
.
└── unicorn
└── rainbow
└── cake
```
Multiple directories:
```js
const makeDir = require('make-dir');
(async () => {
const paths = await Promise.all([
makeDir('unicorn/rainbow'),
makeDir('foo/bar')
]);
console.log(paths);
/*
[
'/Users/sindresorhus/fun/unicorn/rainbow',
'/Users/sindresorhus/fun/foo/bar'
]
*/
})();
```
## API
### makeDir(path, options?)
Returns a `Promise` for the path to the created directory.
### makeDir.sync(path, options?)
Returns the path to the created directory.
#### path
Type: `string`
Directory to create.
#### options
Type: `object`
##### mode
Type: `integer`\
Default: `0o777`
Directory [permissions](https://x-team.com/blog/file-system-permissions-umask-node-js/).
##### fs
Type: `object`\
Default: `require('fs')`
Use a custom `fs` implementation. For example [`graceful-fs`](https://github.com/isaacs/node-graceful-fs).
Using a custom `fs` implementation will block the use of the native `recursive` option if `fs.mkdir` or `fs.mkdirSync` is not the native function.
## Related
- [make-dir-cli](https://github.com/sindresorhus/make-dir-cli) - CLI for this module
- [del](https://github.com/sindresorhus/del) - Delete files and directories
- [globby](https://github.com/sindresorhus/globby) - User-friendly glob matching
- [cpy](https://github.com/sindresorhus/cpy) - Copy files
- [cpy-cli](https://github.com/sindresorhus/cpy-cli) - Copy files on the command-line
- [move-file](https://github.com/sindresorhus/move-file) - Move a file
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-make-dir?utm_source=npm-make-dir&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>
+42
View File
@@ -0,0 +1,42 @@
declare namespace pLimit {
interface Limit {
/**
The number of promises that are currently running.
*/
readonly activeCount: number;
/**
The number of promises that are waiting to run (i.e. their internal `fn` was not called yet).
*/
readonly pendingCount: number;
/**
Discard pending promises that are waiting to run.
This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.
Note: This does not cancel promises that are already running.
*/
clearQueue: () => void;
/**
@param fn - Promise-returning/async function.
@param arguments - Any arguments to pass through to `fn`. Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a lot of functions.
@returns The promise returned by calling `fn(...arguments)`.
*/
<Arguments extends unknown[], ReturnType>(
fn: (...arguments: Arguments) => PromiseLike<ReturnType> | ReturnType,
...arguments: Arguments
): Promise<ReturnType>;
}
}
/**
Run multiple promise-returning & async functions with limited concurrency.
@param concurrency - Concurrency limit. Minimum: `1`.
@returns A `limit` function.
*/
declare function pLimit(concurrency: number): pLimit.Limit;
export = pLimit;
+71
View File
@@ -0,0 +1,71 @@
'use strict';
const Queue = require('yocto-queue');
const pLimit = concurrency => {
if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
}
const queue = new Queue();
let activeCount = 0;
const next = () => {
activeCount--;
if (queue.size > 0) {
queue.dequeue()();
}
};
const run = async (fn, resolve, ...args) => {
activeCount++;
const result = (async () => fn(...args))();
resolve(result);
try {
await result;
} catch {}
next();
};
const enqueue = (fn, resolve, ...args) => {
queue.enqueue(run.bind(null, fn, resolve, ...args));
(async () => {
// This function needs to wait until the next microtask before comparing
// `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
// when the run function is dequeued and called. The comparison in the if-statement
// needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
await Promise.resolve();
if (activeCount < concurrency && queue.size > 0) {
queue.dequeue()();
}
})();
};
const generator = (fn, ...args) => new Promise(resolve => {
enqueue(fn, resolve, ...args);
});
Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.size
},
clearQueue: {
value: () => {
queue.clear();
}
}
});
return generator;
};
module.exports = pLimit;
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+87
View File
@@ -0,0 +1,87 @@
{
"_args": [
[
"p-limit@3.1.0",
"/home/node/nuxt"
]
],
"_from": "p-limit@3.1.0",
"_id": "p-limit@3.1.0",
"_inBundle": false,
"_integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"_location": "/terser-webpack-plugin/p-limit",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "p-limit@3.1.0",
"name": "p-limit",
"escapedName": "p-limit",
"rawSpec": "3.1.0",
"saveSpec": null,
"fetchSpec": "3.1.0"
},
"_requiredBy": [
"/terser-webpack-plugin"
],
"_resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"_spec": "3.1.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/p-limit/issues"
},
"dependencies": {
"yocto-queue": "^0.1.0"
},
"description": "Run multiple promise-returning & async functions with limited concurrency",
"devDependencies": {
"ava": "^2.4.0",
"delay": "^4.4.0",
"in-range": "^2.0.0",
"random-int": "^2.0.1",
"time-span": "^4.0.0",
"tsd": "^0.13.1",
"xo": "^0.35.0"
},
"engines": {
"node": ">=10"
},
"files": [
"index.js",
"index.d.ts"
],
"funding": "https://github.com/sponsors/sindresorhus",
"homepage": "https://github.com/sindresorhus/p-limit#readme",
"keywords": [
"promise",
"limit",
"limited",
"concurrency",
"throttle",
"throat",
"rate",
"batch",
"ratelimit",
"task",
"queue",
"async",
"await",
"promises",
"bluebird"
],
"license": "MIT",
"name": "p-limit",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/p-limit.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "3.1.0"
}
+101
View File
@@ -0,0 +1,101 @@
# p-limit
> Run multiple promise-returning & async functions with limited concurrency
## Install
```
$ npm install p-limit
```
## Usage
```js
const pLimit = require('p-limit');
const limit = pLimit(1);
const input = [
limit(() => fetchSomething('foo')),
limit(() => fetchSomething('bar')),
limit(() => doSomething())
];
(async () => {
// Only one promise is run at once
const result = await Promise.all(input);
console.log(result);
})();
```
## API
### pLimit(concurrency)
Returns a `limit` function.
#### concurrency
Type: `number`\
Minimum: `1`\
Default: `Infinity`
Concurrency limit.
### limit(fn, ...args)
Returns the promise returned by calling `fn(...args)`.
#### fn
Type: `Function`
Promise-returning/async function.
#### args
Any arguments to pass through to `fn`.
Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a *lot* of functions.
### limit.activeCount
The number of promises that are currently running.
### limit.pendingCount
The number of promises that are waiting to run (i.e. their internal `fn` was not called yet).
### limit.clearQueue()
Discard pending promises that are waiting to run.
This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.
Note: This does not cancel promises that are already running.
## FAQ
### How is this different from the [`p-queue`](https://github.com/sindresorhus/p-queue) package?
This package is only about limiting the number of concurrent executions, while `p-queue` is a fully featured queue implementation with lots of different options, introspection, and ability to pause the queue.
## Related
- [p-queue](https://github.com/sindresorhus/p-queue) - Promise queue with concurrency control
- [p-throttle](https://github.com/sindresorhus/p-throttle) - Throttle promise-returning & async functions
- [p-debounce](https://github.com/sindresorhus/p-debounce) - Debounce promise-returning & async functions
- [p-all](https://github.com/sindresorhus/p-all) - Run promise-returning & async functions concurrently with optional limited concurrency
- [More…](https://github.com/sindresorhus/promise-fun)
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-p-limit?utm_source=npm-p-limit&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>
+64
View File
@@ -0,0 +1,64 @@
declare namespace pLocate {
interface Options {
/**
Number of concurrently pending promises returned by `tester`. Minimum: `1`.
@default Infinity
*/
readonly concurrency?: number;
/**
Preserve `input` order when searching.
Disable this to improve performance if you don't care about the order.
@default true
*/
readonly preserveOrder?: boolean;
}
}
declare const pLocate: {
/**
Get the first fulfilled promise that satisfies the provided testing function.
@param input - An iterable of promises/values to test.
@param tester - This function will receive resolved values from `input` and is expected to return a `Promise<boolean>` or `boolean`.
@returns A `Promise` that is fulfilled when `tester` resolves to `true` or the iterable is done, or rejects if any of the promises reject. The fulfilled value is the current iterable value or `undefined` if `tester` never resolved to `true`.
@example
```
import pathExists = require('path-exists');
import pLocate = require('p-locate');
const files = [
'unicorn.png',
'rainbow.png', // Only this one actually exists on disk
'pony.png'
];
(async () => {
const foundPath = await pLocate(files, file => pathExists(file));
console.log(foundPath);
//=> 'rainbow'
})();
```
*/
<ValueType>(
input: Iterable<PromiseLike<ValueType> | ValueType>,
tester: (element: ValueType) => PromiseLike<boolean> | boolean,
options?: pLocate.Options
): Promise<ValueType | undefined>;
// TODO: Remove this for the next major release, refactor the whole definition to:
// declare function pLocate<ValueType>(
// input: Iterable<PromiseLike<ValueType> | ValueType>,
// tester: (element: ValueType) => PromiseLike<boolean> | boolean,
// options?: pLocate.Options
// ): Promise<ValueType | undefined>;
// export = pLocate;
default: typeof pLocate;
};
export = pLocate;
+52
View File
@@ -0,0 +1,52 @@
'use strict';
const pLimit = require('p-limit');
class EndError extends Error {
constructor(value) {
super();
this.value = value;
}
}
// The input can also be a promise, so we await it
const testElement = async (element, tester) => tester(await element);
// The input can also be a promise, so we `Promise.all()` them both
const finder = async element => {
const values = await Promise.all(element);
if (values[1] === true) {
throw new EndError(values[0]);
}
return false;
};
const pLocate = async (iterable, tester, options) => {
options = {
concurrency: Infinity,
preserveOrder: true,
...options
};
const limit = pLimit(options.concurrency);
// Start all the promises concurrently with optional limit
const items = [...iterable].map(element => [element, limit(testElement, element, tester)]);
// Check the promises either serially or concurrently
const checkLimit = pLimit(options.preserveOrder ? 1 : Infinity);
try {
await Promise.all(items.map(element => checkLimit(finder, element)));
} catch (error) {
if (error instanceof EndError) {
return error.value;
}
throw error;
}
};
module.exports = pLocate;
// TODO: Remove this for the next major release
module.exports.default = pLocate;
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,38 @@
export interface Limit {
/**
@param fn - Promise-returning/async function.
@param arguments - Any arguments to pass through to `fn`. Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a lot of functions.
@returns The promise returned by calling `fn(...arguments)`.
*/
<Arguments extends unknown[], ReturnType>(
fn: (...arguments: Arguments) => PromiseLike<ReturnType> | ReturnType,
...arguments: Arguments
): Promise<ReturnType>;
/**
The number of promises that are currently running.
*/
readonly activeCount: number;
/**
The number of promises that are waiting to run (i.e. their internal `fn` was not called yet).
*/
readonly pendingCount: number;
/**
Discard pending promises that are waiting to run.
This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.
Note: This does not cancel promises that are already running.
*/
clearQueue(): void;
}
/**
Run multiple promise-returning & async functions with limited concurrency.
@param concurrency - Concurrency limit. Minimum: `1`.
@returns A `limit` function.
*/
export default function pLimit(concurrency: number): Limit;
@@ -0,0 +1,57 @@
'use strict';
const pTry = require('p-try');
const pLimit = concurrency => {
if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
return Promise.reject(new TypeError('Expected `concurrency` to be a number from 1 and up'));
}
const queue = [];
let activeCount = 0;
const next = () => {
activeCount--;
if (queue.length > 0) {
queue.shift()();
}
};
const run = (fn, resolve, ...args) => {
activeCount++;
const result = pTry(fn, ...args);
resolve(result);
result.then(next, next);
};
const enqueue = (fn, resolve, ...args) => {
if (activeCount < concurrency) {
run(fn, resolve, ...args);
} else {
queue.push(run.bind(null, fn, resolve, ...args));
}
};
const generator = (fn, ...args) => new Promise(resolve => enqueue(fn, resolve, ...args));
Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.length
},
clearQueue: {
value: () => {
queue.length = 0;
}
}
});
return generator;
};
module.exports = pLimit;
module.exports.default = pLimit;
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,87 @@
{
"_args": [
[
"p-limit@2.3.0",
"/home/node/nuxt"
]
],
"_from": "p-limit@2.3.0",
"_id": "p-limit@2.3.0",
"_inBundle": false,
"_integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"_location": "/terser-webpack-plugin/p-locate/p-limit",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "p-limit@2.3.0",
"name": "p-limit",
"escapedName": "p-limit",
"rawSpec": "2.3.0",
"saveSpec": null,
"fetchSpec": "2.3.0"
},
"_requiredBy": [
"/terser-webpack-plugin/p-locate"
],
"_resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"_spec": "2.3.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/p-limit/issues"
},
"dependencies": {
"p-try": "^2.0.0"
},
"description": "Run multiple promise-returning & async functions with limited concurrency",
"devDependencies": {
"ava": "^1.2.1",
"delay": "^4.1.0",
"in-range": "^1.0.0",
"random-int": "^1.0.0",
"time-span": "^2.0.0",
"tsd-check": "^0.3.0",
"xo": "^0.24.0"
},
"engines": {
"node": ">=6"
},
"files": [
"index.js",
"index.d.ts"
],
"funding": "https://github.com/sponsors/sindresorhus",
"homepage": "https://github.com/sindresorhus/p-limit#readme",
"keywords": [
"promise",
"limit",
"limited",
"concurrency",
"throttle",
"throat",
"rate",
"batch",
"ratelimit",
"task",
"queue",
"async",
"await",
"promises",
"bluebird"
],
"license": "MIT",
"name": "p-limit",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/p-limit.git"
},
"scripts": {
"test": "xo && ava && tsd-check"
},
"version": "2.3.0"
}
@@ -0,0 +1,101 @@
# p-limit [![Build Status](https://travis-ci.org/sindresorhus/p-limit.svg?branch=master)](https://travis-ci.org/sindresorhus/p-limit)
> Run multiple promise-returning & async functions with limited concurrency
## Install
```
$ npm install p-limit
```
## Usage
```js
const pLimit = require('p-limit');
const limit = pLimit(1);
const input = [
limit(() => fetchSomething('foo')),
limit(() => fetchSomething('bar')),
limit(() => doSomething())
];
(async () => {
// Only one promise is run at once
const result = await Promise.all(input);
console.log(result);
})();
```
## API
### pLimit(concurrency)
Returns a `limit` function.
#### concurrency
Type: `number`\
Minimum: `1`\
Default: `Infinity`
Concurrency limit.
### limit(fn, ...args)
Returns the promise returned by calling `fn(...args)`.
#### fn
Type: `Function`
Promise-returning/async function.
#### args
Any arguments to pass through to `fn`.
Support for passing arguments on to the `fn` is provided in order to be able to avoid creating unnecessary closures. You probably don't need this optimization unless you're pushing a *lot* of functions.
### limit.activeCount
The number of promises that are currently running.
### limit.pendingCount
The number of promises that are waiting to run (i.e. their internal `fn` was not called yet).
### limit.clearQueue()
Discard pending promises that are waiting to run.
This might be useful if you want to teardown the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.
Note: This does not cancel promises that are already running.
## FAQ
### How is this different from the [`p-queue`](https://github.com/sindresorhus/p-queue) package?
This package is only about limiting the number of concurrent executions, while `p-queue` is a fully featured queue implementation with lots of different options, introspection, and ability to pause the queue.
## Related
- [p-queue](https://github.com/sindresorhus/p-queue) - Promise queue with concurrency control
- [p-throttle](https://github.com/sindresorhus/p-throttle) - Throttle promise-returning & async functions
- [p-debounce](https://github.com/sindresorhus/p-debounce) - Debounce promise-returning & async functions
- [p-all](https://github.com/sindresorhus/p-all) - Run promise-returning & async functions concurrently with optional limited concurrency
- [More…](https://github.com/sindresorhus/promise-fun)
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-p-limit?utm_source=npm-p-limit&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>
+90
View File
@@ -0,0 +1,90 @@
{
"_args": [
[
"p-locate@4.1.0",
"/home/node/nuxt"
]
],
"_from": "p-locate@4.1.0",
"_id": "p-locate@4.1.0",
"_inBundle": false,
"_integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"_location": "/terser-webpack-plugin/p-locate",
"_phantomChildren": {
"p-try": "2.2.0"
},
"_requested": {
"type": "version",
"registry": true,
"raw": "p-locate@4.1.0",
"name": "p-locate",
"escapedName": "p-locate",
"rawSpec": "4.1.0",
"saveSpec": null,
"fetchSpec": "4.1.0"
},
"_requiredBy": [
"/terser-webpack-plugin/locate-path"
],
"_resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"_spec": "4.1.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/p-locate/issues"
},
"dependencies": {
"p-limit": "^2.2.0"
},
"description": "Get the first fulfilled promise that satisfies the provided testing function",
"devDependencies": {
"ava": "^1.4.1",
"delay": "^4.1.0",
"in-range": "^1.0.0",
"time-span": "^3.0.0",
"tsd": "^0.7.2",
"xo": "^0.24.0"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js",
"index.d.ts"
],
"homepage": "https://github.com/sindresorhus/p-locate#readme",
"keywords": [
"promise",
"locate",
"find",
"finder",
"search",
"searcher",
"test",
"array",
"collection",
"iterable",
"iterator",
"race",
"fulfilled",
"fastest",
"async",
"await",
"promises",
"bluebird"
],
"license": "MIT",
"name": "p-locate",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/p-locate.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "4.1.0"
}
+90
View File
@@ -0,0 +1,90 @@
# p-locate [![Build Status](https://travis-ci.org/sindresorhus/p-locate.svg?branch=master)](https://travis-ci.org/sindresorhus/p-locate)
> Get the first fulfilled promise that satisfies the provided testing function
Think of it like an async version of [`Array#find`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find).
## Install
```
$ npm install p-locate
```
## Usage
Here we find the first file that exists on disk, in array order.
```js
const pathExists = require('path-exists');
const pLocate = require('p-locate');
const files = [
'unicorn.png',
'rainbow.png', // Only this one actually exists on disk
'pony.png'
];
(async () => {
const foundPath = await pLocate(files, file => pathExists(file));
console.log(foundPath);
//=> 'rainbow'
})();
```
*The above is just an example. Use [`locate-path`](https://github.com/sindresorhus/locate-path) if you need this.*
## API
### pLocate(input, tester, [options])
Returns a `Promise` that is fulfilled when `tester` resolves to `true` or the iterable is done, or rejects if any of the promises reject. The fulfilled value is the current iterable value or `undefined` if `tester` never resolved to `true`.
#### input
Type: `Iterable<Promise | unknown>`
An iterable of promises/values to test.
#### tester(element)
Type: `Function`
This function will receive resolved values from `input` and is expected to return a `Promise<boolean>` or `boolean`.
#### options
Type: `Object`
##### concurrency
Type: `number`<br>
Default: `Infinity`<br>
Minimum: `1`
Number of concurrently pending promises returned by `tester`.
##### preserveOrder
Type: `boolean`<br>
Default: `true`
Preserve `input` order when searching.
Disable this to improve performance if you don't care about the order.
## Related
- [p-map](https://github.com/sindresorhus/p-map) - Map over promises concurrently
- [p-filter](https://github.com/sindresorhus/p-filter) - Filter promises concurrently
- [p-any](https://github.com/sindresorhus/p-any) - Wait for any promise to be fulfilled
- [More…](https://github.com/sindresorhus/promise-fun)
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)
+28
View File
@@ -0,0 +1,28 @@
declare const pathExists: {
/**
Check if a path exists.
@returns Whether the path exists.
@example
```
// foo.ts
import pathExists = require('path-exists');
(async () => {
console.log(await pathExists('foo.ts'));
//=> true
})();
```
*/
(path: string): Promise<boolean>;
/**
Synchronously check if a path exists.
@returns Whether the path exists.
*/
sync(path: string): boolean;
};
export = pathExists;
+23
View File
@@ -0,0 +1,23 @@
'use strict';
const fs = require('fs');
const {promisify} = require('util');
const pAccess = promisify(fs.access);
module.exports = async path => {
try {
await pAccess(path);
return true;
} catch (_) {
return false;
}
};
module.exports.sync = path => {
try {
fs.accessSync(path);
return true;
} catch (_) {
return false;
}
};
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,74 @@
{
"_args": [
[
"path-exists@4.0.0",
"/home/node/nuxt"
]
],
"_from": "path-exists@4.0.0",
"_id": "path-exists@4.0.0",
"_inBundle": false,
"_integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"_location": "/terser-webpack-plugin/path-exists",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "path-exists@4.0.0",
"name": "path-exists",
"escapedName": "path-exists",
"rawSpec": "4.0.0",
"saveSpec": null,
"fetchSpec": "4.0.0"
},
"_requiredBy": [
"/terser-webpack-plugin/find-up"
],
"_resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"_spec": "4.0.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/path-exists/issues"
},
"description": "Check if a path exists",
"devDependencies": {
"ava": "^1.4.1",
"tsd": "^0.7.2",
"xo": "^0.24.0"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js",
"index.d.ts"
],
"homepage": "https://github.com/sindresorhus/path-exists#readme",
"keywords": [
"path",
"exists",
"exist",
"file",
"filepath",
"fs",
"filesystem",
"file-system",
"access",
"stat"
],
"license": "MIT",
"name": "path-exists",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/path-exists.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "4.0.0"
}
+52
View File
@@ -0,0 +1,52 @@
# path-exists [![Build Status](https://travis-ci.org/sindresorhus/path-exists.svg?branch=master)](https://travis-ci.org/sindresorhus/path-exists)
> Check if a path exists
NOTE: `fs.existsSync` has been un-deprecated in Node.js since 6.8.0. If you only need to check synchronously, this module is not needed.
While [`fs.exists()`](https://nodejs.org/api/fs.html#fs_fs_exists_path_callback) is being [deprecated](https://github.com/iojs/io.js/issues/103), there's still a genuine use-case of being able to check if a path exists for other purposes than doing IO with it.
Never use this before handling a file though:
> In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to `fs.exists()` and `fs.open()`. Just open the file and handle the error when it's not there.
## Install
```
$ npm install path-exists
```
## Usage
```js
// foo.js
const pathExists = require('path-exists');
(async () => {
console.log(await pathExists('foo.js'));
//=> true
})();
```
## API
### pathExists(path)
Returns a `Promise<boolean>` of whether the path exists.
### pathExists.sync(path)
Returns a `boolean` of whether the path exists.
## Related
- [path-exists-cli](https://github.com/sindresorhus/path-exists-cli) - CLI for this module
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)
+44
View File
@@ -0,0 +1,44 @@
declare const pkgDir: {
/**
Find the root directory of a Node.js project or npm package.
@param cwd - Directory to start from. Default: `process.cwd()`.
@returns The project root path or `undefined` if it couldn't be found.
@example
```
// /
// └── Users
// └── sindresorhus
// └── foo
// ├── package.json
// └── bar
// ├── baz
// └── example.js
// example.js
import pkgDir = require('pkg-dir');
(async () => {
const rootDir = await pkgDir(__dirname);
console.log(rootDir);
//=> '/Users/sindresorhus/foo'
})();
```
*/
(cwd?: string): Promise<string | undefined>;
/**
Synchronously find the root directory of a Node.js project or npm package.
@param cwd - Directory to start from. Default: `process.cwd()`.
@returns The project root path or `undefined` if it couldn't be found.
*/
sync(cwd?: string): string | undefined;
// TODO: Remove this for the next major release
default: typeof pkgDir;
};
export = pkgDir;
+17
View File
@@ -0,0 +1,17 @@
'use strict';
const path = require('path');
const findUp = require('find-up');
const pkgDir = async cwd => {
const filePath = await findUp('package.json', {cwd});
return filePath && path.dirname(filePath);
};
module.exports = pkgDir;
// TODO: Remove this for the next major release
module.exports.default = pkgDir;
module.exports.sync = cwd => {
const filePath = findUp.sync('package.json', {cwd});
return filePath && path.dirname(filePath);
};
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+91
View File
@@ -0,0 +1,91 @@
{
"_args": [
[
"pkg-dir@4.2.0",
"/home/node/nuxt"
]
],
"_from": "pkg-dir@4.2.0",
"_id": "pkg-dir@4.2.0",
"_inBundle": false,
"_integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"_location": "/terser-webpack-plugin/pkg-dir",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "pkg-dir@4.2.0",
"name": "pkg-dir",
"escapedName": "pkg-dir",
"rawSpec": "4.2.0",
"saveSpec": null,
"fetchSpec": "4.2.0"
},
"_requiredBy": [
"/terser-webpack-plugin/find-cache-dir"
],
"_resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"_spec": "4.2.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/pkg-dir/issues"
},
"dependencies": {
"find-up": "^4.0.0"
},
"description": "Find the root directory of a Node.js project or npm package",
"devDependencies": {
"ava": "^1.4.1",
"tempy": "^0.3.0",
"tsd": "^0.7.2",
"xo": "^0.24.0"
},
"engines": {
"node": ">=8"
},
"files": [
"index.js",
"index.d.ts"
],
"homepage": "https://github.com/sindresorhus/pkg-dir#readme",
"keywords": [
"package",
"json",
"root",
"npm",
"entry",
"find",
"up",
"find-up",
"findup",
"look-up",
"look",
"file",
"search",
"match",
"resolve",
"parent",
"parents",
"folder",
"directory",
"dir",
"walk",
"walking",
"path"
],
"license": "MIT",
"name": "pkg-dir",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/pkg-dir.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "4.2.0"
}
+66
View File
@@ -0,0 +1,66 @@
# pkg-dir [![Build Status](https://travis-ci.org/sindresorhus/pkg-dir.svg?branch=master)](https://travis-ci.org/sindresorhus/pkg-dir)
> Find the root directory of a Node.js project or npm package
## Install
```
$ npm install pkg-dir
```
## Usage
```
/
└── Users
└── sindresorhus
└── foo
├── package.json
└── bar
├── baz
└── example.js
```
```js
// example.js
const pkgDir = require('pkg-dir');
(async () => {
const rootDir = await pkgDir(__dirname);
console.log(rootDir);
//=> '/Users/sindresorhus/foo'
})();
```
## API
### pkgDir([cwd])
Returns a `Promise` for either the project root path or `undefined` if it couldn't be found.
### pkgDir.sync([cwd])
Returns the project root path or `undefined` if it couldn't be found.
#### cwd
Type: `string`<br>
Default: `process.cwd()`
Directory to start from.
## Related
- [pkg-dir-cli](https://github.com/sindresorhus/pkg-dir-cli) - CLI for this module
- [pkg-up](https://github.com/sindresorhus/pkg-up) - Find the closest package.json file
- [find-up](https://github.com/sindresorhus/find-up) - Find a file by walking up parent directories
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+290
View File
@@ -0,0 +1,290 @@
<div align="center">
<a href="http://json-schema.org">
<img width="160" height="160"
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/.github/assets/logo.png">
</a>
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# schema-utils
Package for validate options in loaders and plugins.
## Getting Started
To begin, you'll need to install `schema-utils`:
```console
npm install schema-utils
```
## API
**schema.json**
```json
{
"type": "object",
"properties": {
"option": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { option: true };
const configuration = { name: "Loader Name/Plugin Name/Name" };
validate(schema, options, configuration);
```
### `schema`
Type: `String`
JSON schema.
Simple example of schema:
```json
{
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
### `options`
Type: `Object`
Object with options.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, { name: 123 }, { name: "MyPlugin" });
```
### `configuration`
Allow to configure validator.
There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
For example:
```json
{
"title": "My Loader options",
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
The last word used for the `baseDataPath` option, other words used for the `name` option.
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
#### `name`
Type: `Object`
Default: `"Object"`
Allow to setup name in validation errors.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, options, { name: "MyPlugin" });
```
```shell
Invalid configuration object. MyPlugin has been initialised using a configuration object that does not match the API schema.
- configuration.optionName should be a integer.
```
#### `baseDataPath`
Type: `String`
Default: `"configuration"`
Allow to setup base data path in validation errors.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, options, { name: "MyPlugin", baseDataPath: "options" });
```
```shell
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
- options.optionName should be a integer.
```
#### `postFormatter`
Type: `Function`
Default: `undefined`
Allow to reformat errors.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, options, {
name: "MyPlugin",
postFormatter: (formattedError, error) => {
if (error.keyword === "type") {
return `${formattedError}\nAdditional Information.`;
}
return formattedError;
},
});
```
```shell
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
- options.optionName should be a integer.
Additional Information.
```
## Examples
**schema.json**
```json
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"test": {
"anyOf": [
{ "type": "array" },
{ "type": "string" },
{ "instanceof": "RegExp" }
]
},
"transform": {
"instanceof": "Function"
},
"sourceMap": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
### `Loader`
```js
import { getOptions } from "loader-utils";
import { validate } from "schema-utils";
import schema from "path/to/schema.json";
function loader(src, map) {
const options = getOptions(this);
validate(schema, options, {
name: "Loader Name",
baseDataPath: "options",
});
// Code...
}
export default loader;
```
### `Plugin`
```js
import { validate } from "schema-utils";
import schema from "path/to/schema.json";
class Plugin {
constructor(options) {
validate(schema, options, {
name: "Plugin Name",
baseDataPath: "options",
});
this.options = options;
}
apply(compiler) {
// Code...
}
}
export default Plugin;
```
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack/schema-utils.svg
[deps-url]: https://david-dm.org/webpack/schema-utils
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
[tests-url]: https://github.com/webpack/schema-utils/actions
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/schema-utils
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.com/badge?p=schema-utils
[size-url]: https://packagephobia.com/result?p=schema-utils
@@ -0,0 +1,74 @@
export default ValidationError;
export type JSONSchema6 = import("json-schema").JSONSchema6;
export type JSONSchema7 = import("json-schema").JSONSchema7;
export type Schema = import("./validate").Schema;
export type ValidationErrorConfiguration =
import("./validate").ValidationErrorConfiguration;
export type PostFormatter = import("./validate").PostFormatter;
export type SchemaUtilErrorObject = import("./validate").SchemaUtilErrorObject;
declare class ValidationError extends Error {
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @param {Schema} schema
* @param {ValidationErrorConfiguration} configuration
*/
constructor(
errors: Array<SchemaUtilErrorObject>,
schema: Schema,
configuration?: ValidationErrorConfiguration
);
/** @type {Array<SchemaUtilErrorObject>} */
errors: Array<SchemaUtilErrorObject>;
/** @type {Schema} */
schema: Schema;
/** @type {string} */
headerName: string;
/** @type {string} */
baseDataPath: string;
/** @type {PostFormatter | null} */
postFormatter: PostFormatter | null;
/**
* @param {string} path
* @returns {Schema}
*/
getSchemaPart(path: string): Schema;
/**
* @param {Schema} schema
* @param {boolean} logic
* @param {Array<Object>} prevSchemas
* @returns {string}
*/
formatSchema(
schema: Schema,
logic?: boolean,
prevSchemas?: Array<Object>
): string;
/**
* @param {Schema=} schemaPart
* @param {(boolean | Array<string>)=} additionalPath
* @param {boolean=} needDot
* @param {boolean=} logic
* @returns {string}
*/
getSchemaPartText(
schemaPart?: Schema | undefined,
additionalPath?: (boolean | Array<string>) | undefined,
needDot?: boolean | undefined,
logic?: boolean | undefined
): string;
/**
* @param {Schema=} schemaPart
* @returns {string}
*/
getSchemaPartDescription(schemaPart?: Schema | undefined): string;
/**
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
formatValidationError(error: SchemaUtilErrorObject): string;
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @returns {string}
*/
formatValidationErrors(errors: Array<SchemaUtilErrorObject>): string;
}
@@ -0,0 +1,3 @@
import { validate } from "./validate";
import { ValidationError } from "./validate";
export { validate, ValidationError };
@@ -0,0 +1,10 @@
export default addAbsolutePathKeyword;
export type Ajv = import("ajv").Ajv;
export type ValidateFunction = import("ajv").ValidateFunction;
export type SchemaUtilErrorObject = import("../validate").SchemaUtilErrorObject;
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
declare function addAbsolutePathKeyword(ajv: Ajv): Ajv;
@@ -0,0 +1,79 @@
export = Range;
/**
* @typedef {[number, boolean]} RangeValue
*/
/**
* @callback RangeValueCallback
* @param {RangeValue} rangeValue
* @returns {boolean}
*/
declare class Range {
/**
* @param {"left" | "right"} side
* @param {boolean} exclusive
* @returns {">" | ">=" | "<" | "<="}
*/
static getOperator(
side: "left" | "right",
exclusive: boolean
): ">" | ">=" | "<" | "<=";
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatRight(value: number, logic: boolean, exclusive: boolean): string;
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatLeft(value: number, logic: boolean, exclusive: boolean): string;
/**
* @param {number} start left side value
* @param {number} end right side value
* @param {boolean} startExclusive is range exclusive from left side
* @param {boolean} endExclusive is range exclusive from right side
* @param {boolean} logic is not logic applied
* @returns {string}
*/
static formatRange(
start: number,
end: number,
startExclusive: boolean,
endExclusive: boolean,
logic: boolean
): string;
/**
* @param {Array<RangeValue>} values
* @param {boolean} logic is not logic applied
* @return {RangeValue} computed value and it's exclusive flag
*/
static getRangeValue(values: Array<RangeValue>, logic: boolean): RangeValue;
/** @type {Array<RangeValue>} */
_left: Array<RangeValue>;
/** @type {Array<RangeValue>} */
_right: Array<RangeValue>;
/**
* @param {number} value
* @param {boolean=} exclusive
*/
left(value: number, exclusive?: boolean | undefined): void;
/**
* @param {number} value
* @param {boolean=} exclusive
*/
right(value: number, exclusive?: boolean | undefined): void;
/**
* @param {boolean} logic is not logic applied
* @return {string} "smart" range string representation
*/
format(logic?: boolean): string;
}
declare namespace Range {
export { RangeValue, RangeValueCallback };
}
type RangeValue = [number, boolean];
type RangeValueCallback = (rangeValue: RangeValue) => boolean;
@@ -0,0 +1,3 @@
export function stringHints(schema: Schema, logic: boolean): string[];
export function numberHints(schema: Schema, logic: boolean): string[];
export type Schema = import("../validate").Schema;
@@ -0,0 +1,37 @@
export type JSONSchema4 = import("json-schema").JSONSchema4;
export type JSONSchema6 = import("json-schema").JSONSchema6;
export type JSONSchema7 = import("json-schema").JSONSchema7;
export type ErrorObject = import("ajv").ErrorObject;
export type Extend = {
formatMinimum?: number | undefined;
formatMaximum?: number | undefined;
formatExclusiveMinimum?: boolean | undefined;
formatExclusiveMaximum?: boolean | undefined;
link?: string | undefined;
};
export type Schema = (JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend;
export type SchemaUtilErrorObject = ErrorObject & {
children?: Array<ErrorObject>;
};
export type PostFormatter = (
formattedError: string,
error: SchemaUtilErrorObject
) => string;
export type ValidationErrorConfiguration = {
name?: string | undefined;
baseDataPath?: string | undefined;
postFormatter?: PostFormatter | undefined;
};
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
export function validate(
schema: Schema,
options: Array<object> | object,
configuration?: ValidationErrorConfiguration | undefined
): void;
import ValidationError from "./ValidationError";
export { ValidationError };
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,11 @@
"use strict";
const {
validate,
ValidationError
} = require("./validate");
module.exports = {
validate,
ValidationError
};
@@ -0,0 +1,93 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/** @typedef {import("ajv").Ajv} Ajv */
/** @typedef {import("ajv").ValidateFunction} ValidateFunction */
/** @typedef {import("../validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
/**
* @param {string} message
* @param {object} schema
* @param {string} data
* @returns {SchemaUtilErrorObject}
*/
function errorMessage(message, schema, data) {
return {
// @ts-ignore
// eslint-disable-next-line no-undefined
dataPath: undefined,
// @ts-ignore
// eslint-disable-next-line no-undefined
schemaPath: undefined,
keyword: "absolutePath",
params: {
absolutePath: data
},
message,
parentSchema: schema
};
}
/**
* @param {boolean} shouldBeAbsolute
* @param {object} schema
* @param {string} data
* @returns {SchemaUtilErrorObject}
*/
function getErrorFor(shouldBeAbsolute, schema, data) {
const message = shouldBeAbsolute ? `The provided value ${JSON.stringify(data)} is not an absolute path!` : `A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
return errorMessage(message, schema, data);
}
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
function addAbsolutePathKeyword(ajv) {
ajv.addKeyword("absolutePath", {
errors: true,
type: "string",
compile(schema, parentSchema) {
/** @type {ValidateFunction} */
const callback = data => {
let passes = true;
const isExclamationMarkPresent = data.includes("!");
if (isExclamationMarkPresent) {
callback.errors = [errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`, parentSchema, data)];
passes = false;
} // ?:[A-Za-z]:\\ - Windows absolute path
// \\\\ - Windows network absolute path
// \/ - Unix-like OS absolute path
const isCorrectAbsolutePath = schema === /^(?:[A-Za-z]:(\\|\/)|\\\\|\/)/.test(data);
if (!isCorrectAbsolutePath) {
callback.errors = [getErrorFor(schema, parentSchema, data)];
passes = false;
}
return passes;
};
callback.errors = [];
return callback;
}
});
return ajv;
}
var _default = addAbsolutePathKeyword;
exports.default = _default;
@@ -0,0 +1,163 @@
"use strict";
/**
* @typedef {[number, boolean]} RangeValue
*/
/**
* @callback RangeValueCallback
* @param {RangeValue} rangeValue
* @returns {boolean}
*/
class Range {
/**
* @param {"left" | "right"} side
* @param {boolean} exclusive
* @returns {">" | ">=" | "<" | "<="}
*/
static getOperator(side, exclusive) {
if (side === "left") {
return exclusive ? ">" : ">=";
}
return exclusive ? "<" : "<=";
}
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatRight(value, logic, exclusive) {
if (logic === false) {
return Range.formatLeft(value, !logic, !exclusive);
}
return `should be ${Range.getOperator("right", exclusive)} ${value}`;
}
/**
* @param {number} value
* @param {boolean} logic is not logic applied
* @param {boolean} exclusive is range exclusive
* @returns {string}
*/
static formatLeft(value, logic, exclusive) {
if (logic === false) {
return Range.formatRight(value, !logic, !exclusive);
}
return `should be ${Range.getOperator("left", exclusive)} ${value}`;
}
/**
* @param {number} start left side value
* @param {number} end right side value
* @param {boolean} startExclusive is range exclusive from left side
* @param {boolean} endExclusive is range exclusive from right side
* @param {boolean} logic is not logic applied
* @returns {string}
*/
static formatRange(start, end, startExclusive, endExclusive, logic) {
let result = "should be";
result += ` ${Range.getOperator(logic ? "left" : "right", logic ? startExclusive : !startExclusive)} ${start} `;
result += logic ? "and" : "or";
result += ` ${Range.getOperator(logic ? "right" : "left", logic ? endExclusive : !endExclusive)} ${end}`;
return result;
}
/**
* @param {Array<RangeValue>} values
* @param {boolean} logic is not logic applied
* @return {RangeValue} computed value and it's exclusive flag
*/
static getRangeValue(values, logic) {
let minMax = logic ? Infinity : -Infinity;
let j = -1;
const predicate = logic ?
/** @type {RangeValueCallback} */
([value]) => value <= minMax :
/** @type {RangeValueCallback} */
([value]) => value >= minMax;
for (let i = 0; i < values.length; i++) {
if (predicate(values[i])) {
[minMax] = values[i];
j = i;
}
}
if (j > -1) {
return values[j];
}
return [Infinity, true];
}
constructor() {
/** @type {Array<RangeValue>} */
this._left = [];
/** @type {Array<RangeValue>} */
this._right = [];
}
/**
* @param {number} value
* @param {boolean=} exclusive
*/
left(value, exclusive = false) {
this._left.push([value, exclusive]);
}
/**
* @param {number} value
* @param {boolean=} exclusive
*/
right(value, exclusive = false) {
this._right.push([value, exclusive]);
}
/**
* @param {boolean} logic is not logic applied
* @return {string} "smart" range string representation
*/
format(logic = true) {
const [start, leftExclusive] = Range.getRangeValue(this._left, logic);
const [end, rightExclusive] = Range.getRangeValue(this._right, !logic);
if (!Number.isFinite(start) && !Number.isFinite(end)) {
return "";
}
const realStart = leftExclusive ? start + 1 : start;
const realEnd = rightExclusive ? end - 1 : end; // e.g. 5 < x < 7, 5 < x <= 6, 6 <= x <= 6
if (realStart === realEnd) {
return `should be ${logic ? "" : "!"}= ${realStart}`;
} // e.g. 4 < x < ∞
if (Number.isFinite(start) && !Number.isFinite(end)) {
return Range.formatLeft(start, logic, leftExclusive);
} // e.g. ∞ < x < 4
if (!Number.isFinite(start) && Number.isFinite(end)) {
return Range.formatRight(end, logic, rightExclusive);
}
return Range.formatRange(start, end, leftExclusive, rightExclusive, logic);
}
}
module.exports = Range;
@@ -0,0 +1,105 @@
"use strict";
const Range = require("./Range");
/** @typedef {import("../validate").Schema} Schema */
/**
* @param {Schema} schema
* @param {boolean} logic
* @return {string[]}
*/
module.exports.stringHints = function stringHints(schema, logic) {
const hints = [];
let type = "string";
const currentSchema = { ...schema
};
if (!logic) {
const tmpLength = currentSchema.minLength;
const tmpFormat = currentSchema.formatMinimum;
const tmpExclusive = currentSchema.formatExclusiveMaximum;
currentSchema.minLength = currentSchema.maxLength;
currentSchema.maxLength = tmpLength;
currentSchema.formatMinimum = currentSchema.formatMaximum;
currentSchema.formatMaximum = tmpFormat;
currentSchema.formatExclusiveMaximum = !currentSchema.formatExclusiveMinimum;
currentSchema.formatExclusiveMinimum = !tmpExclusive;
}
if (typeof currentSchema.minLength === "number") {
if (currentSchema.minLength === 1) {
type = "non-empty string";
} else {
const length = Math.max(currentSchema.minLength - 1, 0);
hints.push(`should be longer than ${length} character${length > 1 ? "s" : ""}`);
}
}
if (typeof currentSchema.maxLength === "number") {
if (currentSchema.maxLength === 0) {
type = "empty string";
} else {
const length = currentSchema.maxLength + 1;
hints.push(`should be shorter than ${length} character${length > 1 ? "s" : ""}`);
}
}
if (currentSchema.pattern) {
hints.push(`should${logic ? "" : " not"} match pattern ${JSON.stringify(currentSchema.pattern)}`);
}
if (currentSchema.format) {
hints.push(`should${logic ? "" : " not"} match format ${JSON.stringify(currentSchema.format)}`);
}
if (currentSchema.formatMinimum) {
hints.push(`should be ${currentSchema.formatExclusiveMinimum ? ">" : ">="} ${JSON.stringify(currentSchema.formatMinimum)}`);
}
if (currentSchema.formatMaximum) {
hints.push(`should be ${currentSchema.formatExclusiveMaximum ? "<" : "<="} ${JSON.stringify(currentSchema.formatMaximum)}`);
}
return [type].concat(hints);
};
/**
* @param {Schema} schema
* @param {boolean} logic
* @return {string[]}
*/
module.exports.numberHints = function numberHints(schema, logic) {
const hints = [schema.type === "integer" ? "integer" : "number"];
const range = new Range();
if (typeof schema.minimum === "number") {
range.left(schema.minimum);
}
if (typeof schema.exclusiveMinimum === "number") {
range.left(schema.exclusiveMinimum, true);
}
if (typeof schema.maximum === "number") {
range.right(schema.maximum);
}
if (typeof schema.exclusiveMaximum === "number") {
range.right(schema.exclusiveMaximum, true);
}
const rangeFormat = range.format(logic);
if (rangeFormat) {
hints.push(rangeFormat);
}
if (typeof schema.multipleOf === "number") {
hints.push(`should${logic ? "" : " not"} be multiple of ${schema.multipleOf}`);
}
return hints;
};
@@ -0,0 +1,163 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validate = validate;
Object.defineProperty(exports, "ValidationError", {
enumerable: true,
get: function () {
return _ValidationError.default;
}
});
var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Use CommonJS require for ajv libs so TypeScript consumers aren't locked into esModuleInterop (see #110).
const Ajv = require("ajv");
const ajvKeywords = require("ajv-keywords");
/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("ajv").ErrorObject} ErrorObject */
/**
* @typedef {Object} Extend
* @property {number=} formatMinimum
* @property {number=} formatMaximum
* @property {boolean=} formatExclusiveMinimum
* @property {boolean=} formatExclusiveMaximum
* @property {string=} link
*/
/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend} Schema */
/** @typedef {ErrorObject & { children?: Array<ErrorObject>}} SchemaUtilErrorObject */
/**
* @callback PostFormatter
* @param {string} formattedError
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
/**
* @typedef {Object} ValidationErrorConfiguration
* @property {string=} name
* @property {string=} baseDataPath
* @property {PostFormatter=} postFormatter
*/
const ajv = new Ajv({
allErrors: true,
verbose: true,
$data: true
});
ajvKeywords(ajv, ["instanceof", "formatMinimum", "formatMaximum", "patternRequired"]); // Custom keywords
(0, _absolutePath.default)(ajv);
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
function validate(schema, options, configuration) {
let errors = [];
if (Array.isArray(options)) {
errors = Array.from(options, nestedOptions => validateObject(schema, nestedOptions));
errors.forEach((list, idx) => {
const applyPrefix =
/**
* @param {SchemaUtilErrorObject} error
*/
error => {
// eslint-disable-next-line no-param-reassign
error.dataPath = `[${idx}]${error.dataPath}`;
if (error.children) {
error.children.forEach(applyPrefix);
}
};
list.forEach(applyPrefix);
});
errors = errors.reduce((arr, items) => {
arr.push(...items);
return arr;
}, []);
} else {
errors = validateObject(schema, options);
}
if (errors.length > 0) {
throw new _ValidationError.default(errors, schema, configuration);
}
}
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @returns {Array<SchemaUtilErrorObject>}
*/
function validateObject(schema, options) {
const compiledSchema = ajv.compile(schema);
const valid = compiledSchema(options);
if (valid) return [];
return compiledSchema.errors ? filterErrors(compiledSchema.errors) : [];
}
/**
* @param {Array<ErrorObject>} errors
* @returns {Array<SchemaUtilErrorObject>}
*/
function filterErrors(errors) {
/** @type {Array<SchemaUtilErrorObject>} */
let newErrors = [];
for (const error of
/** @type {Array<SchemaUtilErrorObject>} */
errors) {
const {
dataPath
} = error;
/** @type {Array<SchemaUtilErrorObject>} */
let children = [];
newErrors = newErrors.filter(oldError => {
if (oldError.dataPath.includes(dataPath)) {
if (oldError.children) {
children = children.concat(oldError.children.slice(0));
} // eslint-disable-next-line no-undefined, no-param-reassign
oldError.children = undefined;
children.push(oldError);
return false;
}
return true;
});
if (children.length) {
error.children = children;
}
newErrors.push(error);
}
return newErrors;
}
@@ -0,0 +1,114 @@
{
"_args": [
[
"schema-utils@3.1.1",
"/home/node/nuxt"
]
],
"_from": "schema-utils@3.1.1",
"_id": "schema-utils@3.1.1",
"_inBundle": false,
"_integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
"_location": "/terser-webpack-plugin/schema-utils",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "schema-utils@3.1.1",
"name": "schema-utils",
"escapedName": "schema-utils",
"rawSpec": "3.1.1",
"saveSpec": null,
"fetchSpec": "3.1.1"
},
"_requiredBy": [
"/terser-webpack-plugin"
],
"_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
"_spec": "3.1.1",
"_where": "/home/node/nuxt",
"author": {
"name": "webpack Contrib",
"url": "https://github.com/webpack-contrib"
},
"bugs": {
"url": "https://github.com/webpack/schema-utils/issues"
},
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"description": "webpack Validation Utils",
"devDependencies": {
"@babel/cli": "^7.14.3",
"@babel/core": "^7.14.6",
"@babel/preset-env": "^7.14.7",
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^27.0.6",
"cross-env": "^7.0.3",
"del": "^6.0.0",
"del-cli": "^3.0.1",
"eslint": "^7.31.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4",
"husky": "^6.0.0",
"jest": "^27.0.6",
"lint-staged": "^11.0.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.3.2",
"standard-version": "^9.3.1",
"typescript": "^4.3.5",
"webpack": "^5.45.1"
},
"engines": {
"node": ">= 10.13.0"
},
"files": [
"dist",
"declarations"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"homepage": "https://github.com/webpack/schema-utils",
"keywords": [
"webpack"
],
"license": "MIT",
"main": "dist/index.js",
"name": "schema-utils",
"repository": {
"type": "git",
"url": "git+https://github.com/webpack/schema-utils.git"
},
"scripts": {
"build": "npm-run-all -p \"build:**\"",
"build:code": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"build:types": "tsc --declaration --emitDeclarationOnly --outDir declarations && prettier \"declarations/**/*.ts\" --write",
"clean": "del-cli dist declarations",
"commitlint": "commitlint --from=master",
"fix": "npm-run-all fix:js fmt",
"fix:js": "npm run lint:js -- --fix",
"fmt": "npm run fmt:check -- --write",
"fmt:check": "prettier \"{**/*,*}.{js,json,md,yml,css,ts}\" --list-different",
"lint": "npm-run-all lint:js lint:types fmt:check",
"lint:js": "eslint --cache .",
"lint:types": "tsc --pretty --noEmit",
"prebuild": "npm run clean",
"prepare": "npm run build && husky install",
"pretest": "npm run lint",
"release": "standard-version",
"security": "npm audit --production",
"start": "npm run build -- -w",
"test": "npm run test:coverage",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch"
},
"types": "declarations/index.d.ts",
"version": "3.1.1"
}
+70
View File
@@ -0,0 +1,70 @@
# changes log
## 6.2.0
* Coerce numbers to strings when passed to semver.coerce()
* Add `rtl` option to coerce from right to left
## 6.1.3
* Handle X-ranges properly in includePrerelease mode
## 6.1.2
* Do not throw when testing invalid version strings
## 6.1.1
* Add options support for semver.coerce()
* Handle undefined version passed to Range.test
## 6.1.0
* Add semver.compareBuild function
* Support `*` in semver.intersects
## 6.0
* Fix `intersects` logic.
This is technically a bug fix, but since it is also a change to behavior
that may require users updating their code, it is marked as a major
version increment.
## 5.7
* Add `minVersion` method
## 5.6
* Move boolean `loose` param to an options object, with
backwards-compatibility protection.
* Add ability to opt out of special prerelease version handling with
the `includePrerelease` option flag.
## 5.5
* Add version coercion capabilities
## 5.4
* Add intersection checking
## 5.3
* Add `minSatisfying` method
## 5.2
* Add `prerelease(v)` that returns prerelease components
## 5.1
* Add Backus-Naur for ranges
* Remove excessively cute inspection methods
## 5.0
* Remove AMD/Browserified build artifacts
* Fix ltr and gtr when using the `*` range
* Fix for range `*` with a prerelease identifier
+15
View File
@@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+443
View File
@@ -0,0 +1,443 @@
semver(1) -- The semantic versioner for npm
===========================================
## Install
```bash
npm install semver
````
## Usage
As a node module:
```js
const semver = require('semver')
semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
semver.minVersion('>=1.0.0') // '1.0.0'
semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
```
As a command-line utility:
```
$ semver -h
A JavaScript implementation of the https://semver.org/ specification
Copyright Isaac Z. Schlueter
Usage: semver [options] <version> [<version> [...]]
Prints valid versions sorted by SemVer precedence
Options:
-r --range <range>
Print versions that match the specified range.
-i --increment [<level>]
Increment a version by the specified level. Level can
be one of: major, minor, patch, premajor, preminor,
prepatch, or prerelease. Default level is 'patch'.
Only one version may be specified.
--preid <identifier>
Identifier to be used to prefix premajor, preminor,
prepatch or prerelease version increments.
-l --loose
Interpret versions and ranges loosely
-p --include-prerelease
Always include prerelease versions in range matching
-c --coerce
Coerce a string into SemVer if possible
(does not imply --loose)
--rtl
Coerce version strings right to left
--ltr
Coerce version strings left to right (default)
Program exits successfully if any valid version satisfies
all supplied ranges, and prints all satisfying versions.
If no satisfying versions are found, then exits failure.
Versions are printed in ascending order, so supplying
multiple versions to the utility will just sort them.
```
## Versions
A "version" is described by the `v2.0.0` specification found at
<https://semver.org/>.
A leading `"="` or `"v"` character is stripped off and ignored.
## Ranges
A `version range` is a set of `comparators` which specify versions
that satisfy the range.
A `comparator` is composed of an `operator` and a `version`. The set
of primitive `operators` is:
* `<` Less than
* `<=` Less than or equal to
* `>` Greater than
* `>=` Greater than or equal to
* `=` Equal. If no operator is specified, then equality is assumed,
so this operator is optional, but MAY be included.
For example, the comparator `>=1.2.7` would match the versions
`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6`
or `1.1.0`.
Comparators can be joined by whitespace to form a `comparator set`,
which is satisfied by the **intersection** of all of the comparators
it includes.
A range is composed of one or more comparator sets, joined by `||`. A
version matches a range if and only if every comparator in at least
one of the `||`-separated comparator sets is satisfied by the version.
For example, the range `>=1.2.7 <1.3.0` would match the versions
`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`,
or `1.1.0`.
The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`,
`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`.
### Prerelease Tags
If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then
it will only be allowed to satisfy comparator sets if at least one
comparator with the same `[major, minor, patch]` tuple also has a
prerelease tag.
For example, the range `>1.2.3-alpha.3` would be allowed to match the
version `1.2.3-alpha.7`, but it would *not* be satisfied by
`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater
than" `1.2.3-alpha.3` according to the SemVer sort rules. The version
range only accepts prerelease tags on the `1.2.3` version. The
version `3.4.5` *would* satisfy the range, because it does not have a
prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`.
The purpose for this behavior is twofold. First, prerelease versions
frequently are updated very quickly, and contain many breaking changes
that are (by the author's design) not yet fit for public consumption.
Therefore, by default, they are excluded from range matching
semantics.
Second, a user who has opted into using a prerelease version has
clearly indicated the intent to use *that specific* set of
alpha/beta/rc versions. By including a prerelease tag in the range,
the user is indicating that they are aware of the risk. However, it
is still not appropriate to assume that they have opted into taking a
similar risk on the *next* set of prerelease versions.
Note that this behavior can be suppressed (treating all prerelease
versions as if they were normal versions, for the purpose of range
matching) by setting the `includePrerelease` flag on the options
object to any
[functions](https://github.com/npm/node-semver#functions) that do
range matching.
#### Prerelease Identifiers
The method `.inc` takes an additional `identifier` string argument that
will append the value of the string as a prerelease identifier:
```javascript
semver.inc('1.2.3', 'prerelease', 'beta')
// '1.2.4-beta.0'
```
command-line example:
```bash
$ semver 1.2.3 -i prerelease --preid beta
1.2.4-beta.0
```
Which then can be used to increment further:
```bash
$ semver 1.2.4-beta.0 -i prerelease
1.2.4-beta.1
```
### Advanced Range Syntax
Advanced range syntax desugars to primitive comparators in
deterministic ways.
Advanced ranges may be combined in the same way as primitive
comparators using white space or `||`.
#### Hyphen Ranges `X.Y.Z - A.B.C`
Specifies an inclusive set.
* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`
If a partial version is provided as the first version in the inclusive
range, then the missing pieces are replaced with zeroes.
* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4`
If a partial version is provided as the second version in the
inclusive range, then all versions that start with the supplied parts
of the tuple are accepted, but nothing that would be greater than the
provided tuple parts.
* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0`
* `1.2.3 - 2` := `>=1.2.3 <3.0.0`
#### X-Ranges `1.2.x` `1.X` `1.2.*` `*`
Any of `X`, `x`, or `*` may be used to "stand in" for one of the
numeric values in the `[major, minor, patch]` tuple.
* `*` := `>=0.0.0` (Any version satisfies)
* `1.x` := `>=1.0.0 <2.0.0` (Matching major version)
* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions)
A partial version range is treated as an X-Range, so the special
character is in fact optional.
* `""` (empty string) := `*` := `>=0.0.0`
* `1` := `1.x.x` := `>=1.0.0 <2.0.0`
* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0`
#### Tilde Ranges `~1.2.3` `~1.2` `~1`
Allows patch-level changes if a minor version is specified on the
comparator. Allows minor-level changes if not.
* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0`
* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`)
* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`)
* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0`
* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`)
* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`)
* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in
the `1.2.3` version will be allowed, if they are greater than or
equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but
`1.2.4-beta.2` would not, because it is a prerelease of a
different `[major, minor, patch]` tuple.
#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4`
Allows changes that do not modify the left-most non-zero element in the
`[major, minor, patch]` tuple. In other words, this allows patch and
minor updates for versions `1.0.0` and above, patch updates for
versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`.
Many authors treat a `0.x` version as if the `x` were the major
"breaking-change" indicator.
Caret ranges are ideal when an author may make breaking changes
between `0.2.4` and `0.3.0` releases, which is a common practice.
However, it presumes that there will *not* be breaking changes between
`0.2.4` and `0.2.5`. It allows for changes that are presumed to be
additive (but non-breaking), according to commonly observed practices.
* `^1.2.3` := `>=1.2.3 <2.0.0`
* `^0.2.3` := `>=0.2.3 <0.3.0`
* `^0.0.3` := `>=0.0.3 <0.0.4`
* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in
the `1.2.3` version will be allowed, if they are greater than or
equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but
`1.2.4-beta.2` would not, because it is a prerelease of a
different `[major, minor, patch]` tuple.
* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the
`0.0.3` version *only* will be allowed, if they are greater than or
equal to `beta`. So, `0.0.3-pr.2` would be allowed.
When parsing caret ranges, a missing `patch` value desugars to the
number `0`, but will allow flexibility within that value, even if the
major and minor versions are both `0`.
* `^1.2.x` := `>=1.2.0 <2.0.0`
* `^0.0.x` := `>=0.0.0 <0.1.0`
* `^0.0` := `>=0.0.0 <0.1.0`
A missing `minor` and `patch` values will desugar to zero, but also
allow flexibility within those values, even if the major version is
zero.
* `^1.x` := `>=1.0.0 <2.0.0`
* `^0.x` := `>=0.0.0 <1.0.0`
### Range Grammar
Putting all this together, here is a Backus-Naur grammar for ranges,
for the benefit of parser authors:
```bnf
range-set ::= range ( logical-or range ) *
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
range ::= hyphen | simple ( ' ' simple ) * | ''
hyphen ::= partial ' - ' partial
simple ::= primitive | partial | tilde | caret
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr ::= 'x' | 'X' | '*' | nr
nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
tilde ::= '~' partial
caret ::= '^' partial
qualifier ::= ( '-' pre )? ( '+' build )?
pre ::= parts
build ::= parts
parts ::= part ( '.' part ) *
part ::= nr | [-0-9A-Za-z]+
```
## Functions
All methods and classes take a final `options` object argument. All
options in this object are `false` by default. The options supported
are:
- `loose` Be more forgiving about not-quite-valid semver strings.
(Any resulting output will always be 100% strict compliant, of
course.) For backwards compatibility reasons, if the `options`
argument is a boolean value instead of an object, it is interpreted
to be the `loose` param.
- `includePrerelease` Set to suppress the [default
behavior](https://github.com/npm/node-semver#prerelease-tags) of
excluding prerelease tagged versions from ranges unless they are
explicitly opted into.
Strict-mode Comparators and Ranges will be strict about the SemVer
strings that they parse.
* `valid(v)`: Return the parsed version, or null if it's not valid.
* `inc(v, release)`: Return the version incremented by the release
type (`major`, `premajor`, `minor`, `preminor`, `patch`,
`prepatch`, or `prerelease`), or null if it's not valid
* `premajor` in one call will bump the version up to the next major
version and down to a prerelease of that major version.
`preminor`, and `prepatch` work the same way.
* If called from a non-prerelease version, the `prerelease` will work the
same as `prepatch`. It increments the patch version, then makes a
prerelease. If the input version is already a prerelease it simply
increments it.
* `prerelease(v)`: Returns an array of prerelease components, or null
if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]`
* `major(v)`: Return the major version number.
* `minor(v)`: Return the minor version number.
* `patch(v)`: Return the patch version number.
* `intersects(r1, r2, loose)`: Return true if the two supplied ranges
or comparators intersect.
* `parse(v)`: Attempt to parse a string as a semantic version, returning either
a `SemVer` object or `null`.
### Comparison
* `gt(v1, v2)`: `v1 > v2`
* `gte(v1, v2)`: `v1 >= v2`
* `lt(v1, v2)`: `v1 < v2`
* `lte(v1, v2)`: `v1 <= v2`
* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent,
even if they're not the exact same string. You already know how to
compare strings.
* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`.
* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call
the corresponding function above. `"==="` and `"!=="` do simple
string comparison, but are included for completeness. Throws if an
invalid comparison string is provided.
* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if
`v2` is greater. Sorts in ascending order if passed to `Array.sort()`.
* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions
in descending order when passed to `Array.sort()`.
* `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions
are equal. Sorts in ascending order if passed to `Array.sort()`.
`v2` is greater. Sorts in ascending order if passed to `Array.sort()`.
* `diff(v1, v2)`: Returns difference between two versions by the release type
(`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`),
or null if the versions are the same.
### Comparators
* `intersects(comparator)`: Return true if the comparators intersect
### Ranges
* `validRange(range)`: Return the valid range or null if it's not valid
* `satisfies(version, range)`: Return true if the version satisfies the
range.
* `maxSatisfying(versions, range)`: Return the highest version in the list
that satisfies the range, or `null` if none of them do.
* `minSatisfying(versions, range)`: Return the lowest version in the list
that satisfies the range, or `null` if none of them do.
* `minVersion(range)`: Return the lowest version that can possibly match
the given range.
* `gtr(version, range)`: Return `true` if version is greater than all the
versions possible in the range.
* `ltr(version, range)`: Return `true` if version is less than all the
versions possible in the range.
* `outside(version, range, hilo)`: Return true if the version is outside
the bounds of the range in either the high or low direction. The
`hilo` argument must be either the string `'>'` or `'<'`. (This is
the function called by `gtr` and `ltr`.)
* `intersects(range)`: Return true if any of the ranges comparators intersect
Note that, since ranges may be non-contiguous, a version might not be
greater than a range, less than a range, *or* satisfy a range! For
example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9`
until `2.0.0`, so the version `1.2.10` would not be greater than the
range (because `2.0.1` satisfies, which is higher), nor less than the
range (since `1.2.8` satisfies, which is lower), and it also does not
satisfy the range.
If you want to know if a version satisfies or does not satisfy a
range, use the `satisfies(version, range)` function.
### Coercion
* `coerce(version, options)`: Coerces a string to semver if possible
This aims to provide a very forgiving translation of a non-semver string to
semver. It looks for the first digit in a string, and consumes all
remaining characters which satisfy at least a partial semver (e.g., `1`,
`1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer
versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All
surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes
`3.4.0`). Only text which lacks digits will fail coercion (`version one`
is not valid). The maximum length for any semver component considered for
coercion is 16 characters; longer components will be ignored
(`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any
semver component is `Integer.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value
components are invalid (`9999999999999999.4.7.4` is likely invalid).
If the `options.rtl` flag is set, then `coerce` will return the right-most
coercible tuple that does not share an ending index with a longer coercible
tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not
`4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of
any other overlapping SemVer tuple.
### Clean
* `clean(version)`: Clean a string to be a valid semver if possible
This will return a cleaned and trimmed semver version. If the provided version is not valid a null will be returned. This does not work for ranges.
ex.
* `s.clean(' = v 2.1.5foo')`: `null`
* `s.clean(' = v 2.1.5foo', { loose: true })`: `'2.1.5-foo'`
* `s.clean(' = v 2.1.5-foo')`: `null`
* `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'`
* `s.clean('=v2.1.5')`: `'2.1.5'`
* `s.clean(' =v2.1.5')`: `2.1.5`
* `s.clean(' 2.1.5 ')`: `'2.1.5'`
* `s.clean('~1.0.0')`: `null`
+174
View File
@@ -0,0 +1,174 @@
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.
var argv = process.argv.slice(2)
var versions = []
var range = []
var inc = null
var version = require('../package.json').version
var loose = false
var includePrerelease = false
var coerce = false
var rtl = false
var identifier
var semver = require('../semver')
var reverse = false
var options = {}
main()
function main () {
if (!argv.length) return help()
while (argv.length) {
var a = argv.shift()
var indexOfEqualSign = a.indexOf('=')
if (indexOfEqualSign !== -1) {
a = a.slice(0, indexOfEqualSign)
argv.unshift(a.slice(indexOfEqualSign + 1))
}
switch (a) {
case '-rv': case '-rev': case '--rev': case '--reverse':
reverse = true
break
case '-l': case '--loose':
loose = true
break
case '-p': case '--include-prerelease':
includePrerelease = true
break
case '-v': case '--version':
versions.push(argv.shift())
break
case '-i': case '--inc': case '--increment':
switch (argv[0]) {
case 'major': case 'minor': case 'patch': case 'prerelease':
case 'premajor': case 'preminor': case 'prepatch':
inc = argv.shift()
break
default:
inc = 'patch'
break
}
break
case '--preid':
identifier = argv.shift()
break
case '-r': case '--range':
range.push(argv.shift())
break
case '-c': case '--coerce':
coerce = true
break
case '--rtl':
rtl = true
break
case '--ltr':
rtl = false
break
case '-h': case '--help': case '-?':
return help()
default:
versions.push(a)
break
}
}
var options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl }
versions = versions.map(function (v) {
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
}).filter(function (v) {
return semver.valid(v)
})
if (!versions.length) return fail()
if (inc && (versions.length !== 1 || range.length)) { return failInc() }
for (var i = 0, l = range.length; i < l; i++) {
versions = versions.filter(function (v) {
return semver.satisfies(v, range[i], options)
})
if (!versions.length) return fail()
}
return success(versions)
}
function failInc () {
console.error('--inc can only be used on a single version with no range')
fail()
}
function fail () { process.exit(1) }
function success () {
var compare = reverse ? 'rcompare' : 'compare'
versions.sort(function (a, b) {
return semver[compare](a, b, options)
}).map(function (v) {
return semver.clean(v, options)
}).map(function (v) {
return inc ? semver.inc(v, inc, options, identifier) : v
}).forEach(function (v, i, _) { console.log(v) })
}
function help () {
console.log(['SemVer ' + version,
'',
'A JavaScript implementation of the https://semver.org/ specification',
'Copyright Isaac Z. Schlueter',
'',
'Usage: semver [options] <version> [<version> [...]]',
'Prints valid versions sorted by SemVer precedence',
'',
'Options:',
'-r --range <range>',
' Print versions that match the specified range.',
'',
'-i --increment [<level>]',
' Increment a version by the specified level. Level can',
' be one of: major, minor, patch, premajor, preminor,',
" prepatch, or prerelease. Default level is 'patch'.",
' Only one version may be specified.',
'',
'--preid <identifier>',
' Identifier to be used to prefix premajor, preminor,',
' prepatch or prerelease version increments.',
'',
'-l --loose',
' Interpret versions and ranges loosely',
'',
'-p --include-prerelease',
' Always include prerelease versions in range matching',
'',
'-c --coerce',
' Coerce a string into SemVer if possible',
' (does not imply --loose)',
'',
'--rtl',
' Coerce version strings right to left',
'',
'--ltr',
' Coerce version strings left to right (default)',
'',
'Program exits successfully if any valid version satisfies',
'all supplied ranges, and prints all satisfying versions.',
'',
'If no satisfying versions are found, then exits failure.',
'',
'Versions are printed in ascending order, so supplying',
'multiple versions to the utility will just sort them.'
].join('\n'))
}
+63
View File
@@ -0,0 +1,63 @@
{
"_args": [
[
"semver@6.3.0",
"/home/node/nuxt"
]
],
"_from": "semver@6.3.0",
"_id": "semver@6.3.0",
"_inBundle": false,
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"_location": "/terser-webpack-plugin/semver",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "semver@6.3.0",
"name": "semver",
"escapedName": "semver",
"rawSpec": "6.3.0",
"saveSpec": null,
"fetchSpec": "6.3.0"
},
"_requiredBy": [
"/terser-webpack-plugin/make-dir"
],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_spec": "6.3.0",
"_where": "/home/node/nuxt",
"bin": {
"semver": "bin/semver.js"
},
"bugs": {
"url": "https://github.com/npm/node-semver/issues"
},
"description": "The semantic version parser used by npm.",
"devDependencies": {
"tap": "^14.3.1"
},
"files": [
"bin",
"range.bnf",
"semver.js"
],
"homepage": "https://github.com/npm/node-semver#readme",
"license": "ISC",
"main": "semver.js",
"name": "semver",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/node-semver.git"
},
"scripts": {
"postpublish": "git push origin --follow-tags",
"postversion": "npm publish",
"preversion": "npm test",
"test": "tap"
},
"tap": {
"check-coverage": true
},
"version": "6.3.0"
}
+16
View File
@@ -0,0 +1,16 @@
range-set ::= range ( logical-or range ) *
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
range ::= hyphen | simple ( ' ' simple ) * | ''
hyphen ::= partial ' - ' partial
simple ::= primitive | partial | tilde | caret
primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr ::= 'x' | 'X' | '*' | nr
nr ::= '0' | [1-9] ( [0-9] ) *
tilde ::= '~' partial
caret ::= '^' partial
qualifier ::= ( '-' pre )? ( '+' build )?
pre ::= parts
build ::= parts
parts ::= part ( '.' part ) *
part ::= nr | [-0-9A-Za-z]+
File diff suppressed because it is too large Load Diff
+515
View File
@@ -0,0 +1,515 @@
# Changelog
## v5.14.2
- Security fix for RegExps that should not be evaluated (regexp DDOS)
- Source maps improvements (#1211)
- Performance improvements in long property access evaluation (#1213)
## v5.14.1
- keep_numbers option added to TypeScript defs (#1208)
- Fixed parsing of nested template strings (#1204)
## v5.14.0
- Switched to @jridgewell/source-map for sourcemap generation (#1190, #1181)
- Fixed source maps with non-terminated segments (#1106)
- Enabled typescript types to be imported from the package (#1194)
- Extra DOM props have been added (#1191)
- Delete the AST while generating code, as a means to save RAM
## v5.13.1
- Removed self-assignments (`varname=varname`) (closes #1081)
- Separated inlining code (for inlining things into references, or removing IIFEs)
- Allow multiple identifiers with the same name in `var` destructuring (eg `var { a, a } = x`) (#1176)
## v5.13.0
- All calls to eval() were removed (#1171, #1184)
- `source-map` was updated to 0.8.0-beta.0 (#1164)
- NavigatorUAData was added to domprops to avoid property mangling (#1166)
## v5.12.1
- Fixed an issue with function definitions inside blocks (#1155)
- Fixed parens of `new` in some situations (closes #1159)
## v5.12.0
- `TERSER_DEBUG_DIR` environment variable
- @copyright comments are now preserved with the comments="some" option (#1153)
## v5.11.0
- Unicode code point escapes (`\u{abcde}`) are not emitted inside RegExp literals anymore (#1147)
- acorn is now a regular dependency
## v5.10.0
- Massive optimization to max_line_len (#1109)
- Basic support for import assertions
- Marked ES2022 Object.hasOwn as a pure function
- Fix `delete optional?.property`
- New CI/CD pipeline with github actions (#1057)
- Fix reordering of switch branches (#1092), (#1084)
- Fix error when creating a class property called `get`
- Acorn dependency is now an optional peerDependency
- Fix mangling collision with exported variables (#1072)
- Fix an issue with `return someVariable = (async () => { ... })()` (#1073)
## v5.9.0
- Collapsing switch cases with the same bodies (even if they're not next to each other) (#1070).
- Fix evaluation of optional chain expressions (#1062)
- Fix mangling collision in ESM exports (#1063)
- Fix issue with mutating function objects after a second pass (#1047)
- Fix for inlining object spread `{ ...obj }` (#1071)
- Typescript typings fix (#1069)
## v5.8.0
- Fixed shadowing variables while moving code in some cases (#1065)
- Stop mangling computed & quoted properties when keep_quoted is enabled.
- Fix for mangling private getter/setter and .#private access (#1060, #1068)
- Array.from has a new optimization when the unsafe option is set (#737)
- Mangle/propmangle let you generate your own identifiers through the nth_identifier option (#1061)
- More optimizations to switch statements (#1044)
## v5.7.2
- Fixed issues with compressing functions defined in `global_defs` option (#1036)
- New recipe for using Terser in gulp was added to RECIPES.md (#1035)
- Fixed issues with `??` and `?.` (#1045)
- Future reserved words such as `package` no longer require you to disable strict mode to be used as names.
- Refactored huge compressor file into multiple more focused files.
- Avoided unparenthesized `in` operator in some for loops (it breaks parsing because of for..in loops)
- Improved documentation (#1021, #1025)
- More type definitions (#1021)
## v5.7.1
- Avoided collapsing assignments together if it would place a chain assignment on the left hand side, which is invalid syntax (`a?.b = c`)
- Removed undefined from object expansions (`{ ...void 0 }` -> `{}`)
- Fix crash when checking if something is nullish or undefined (#1009)
- Fixed comparison of private class properties (#1015)
- Minor performance improvements (#993)
- Fixed scope of function defs in strict mode (they are block scoped)
## v5.7.0
- Several compile-time evaluation and inlining fixes
- Allow `reduce_funcs` to be disabled again.
- Add `spidermonkey` options to parse and format (#974)
- Accept `{get = "default val"}` and `{set = "default val"}` in destructuring arguments.
- Change package.json export map to help require.resolve (#971)
- Improve docs
- Fix `export default` of an anonymous class with `extends`
## v5.6.1
- Mark assignments to the `.prototype` of a class as pure
- Parenthesize `await` on the left of `**` (while accepting legacy non-parenthesised input)
- Avoided outputting NUL bytes in optimized RegExps, to stop the output from breaking other tools
- Added `exports` to domprops (#939)
- Fixed a crash when spreading `...this`
- Fixed the computed size of arrow functions, which improves their inlining
## v5.6.0
- Added top-level await
- Beautify option has been removed in #895
- Private properties, getters and setters have been added in #913 and some more commits
- Docs improvements: #896, #903, #916
## v5.5.1
- Fixed object properties with unicode surrogates on safari.
## v5.5.0
- Fixed crash when inlining uninitialized variable into template string.
- The sourcemap for dist was removed for being too large.
## v5.4.0
- Logical assignment
- Change `let x = undefined` to just `let x`
- Removed some optimizations for template strings, placing them behind `unsafe` options. Reason: adding strings is not equivalent to template strings, due to valueOf differences.
- The AST_Token class was slimmed down in order to use less memory.
## v5.3.8
- Restore node 13 support
## v5.3.7
Hotfix release, fixes package.json "engines" syntax
## v5.3.6
- Fixed parentheses when outputting `??` mixed with `||` and `&&`
- Improved hygiene of the symbol generator
## v5.3.5
- Avoid moving named functions into default exports.
- Enabled transform() for chain expressions. This allows AST transformers to reach inside chain expressions.
## v5.3.4
- Fixed a crash when hoisting (with `hoist_vars`) a destructuring variable declaration
## v5.3.3
- `source-map` library has been updated, bringing memory usage and CPU time improvements when reading input source maps (the SourceMapConsumer is now WASM based).
- The `wrap_func_args` option now also wraps arrow functions, as opposed to only function expressions.
## v5.3.2
- Prevented spread operations from being expanded when the expanded array/object contains getters, setters, or array holes.
- Fixed _very_ slow self-recursion in some cases of removing extraneous parentheses from `+` operations.
## v5.3.1
- An issue with destructuring declarations when `pure_getters` is enabled has been fixed
- Fixed a crash when chain expressions need to be shallowly compared
- Made inlining functions more conservative to make sure a function that contains a reference to itself isn't moved into a place that can create multiple instances of itself.
## v5.3.0
- Fixed a crash when compressing object spreads in some cases
- Fixed compiletime evaluation of optional chains (caused typeof a?.b to always return "object")
- domprops has been updated to contain every single possible prop
## v5.2.1
- The parse step now doesn't accept an `ecma` option, so that all ES code is accepted.
- Optional dotted chains now accept keywords, just like dotted expressions (`foo?.default`)
## v5.2.0
- Optional chaining syntax is now supported.
- Consecutive await expressions don't have unnecessary parens
- Taking the variable name's length (after mangling) into consideration when deciding to inline
## v5.1.0
- `import.meta` is now supported
- Typescript typings have been improved
## v5.0.0
- `in` operator now taken into account during property mangle.
- Fixed infinite loop in face of a reference loop in some situations.
- Kept exports and imports around even if there's something which will throw before them.
- The main exported bundle for commonjs, dist/bundle.min.js is no longer minified.
## v5.0.0-beta.0
- BREAKING: `minify()` is now async and rejects a promise instead of returning an error.
- BREAKING: Internal AST is no longer exposed, so that it can be improved without releasing breaking changes.
- BREAKING: Lowest supported node version is 10
- BREAKING: There are no more warnings being emitted
- Module is now distributed as a dual package - You can `import` and `require()` too.
- Inline improvements were made
-----
## v4.8.1 (backport)
- Security fix for RegExps that should not be evaluated (regexp DDOS)
## v4.8.0
- Support for numeric separators (`million = 1_000_000`) was added.
- Assigning properties to a class is now assumed to be pure.
- Fixed bug where `yield` wasn't considered a valid property key in generators.
## v4.7.0
- A bug was fixed where an arrow function would have the wrong size
- `arguments` object is now considered safe to retrieve properties from (useful for `length`, or `0`) even when `pure_getters` is not set.
- Fixed erroneous `const` declarations without value (which is invalid) in some corner cases when using `collapse_vars`.
## v4.6.13
- Fixed issue where ES5 object properties were being turned into ES6 object properties due to more lax unicode rules.
- Fixed parsing of BigInt with lowercase `e` in them.
## v4.6.12
- Fixed subtree comparison code, making it see that `[1,[2, 3]]` is different from `[1, 2, [3]]`
- Printing of unicode identifiers has been improved
## v4.6.11
- Read unused classes' properties and method keys, to figure out if they use other variables.
- Prevent inlining into block scopes when there are name collisions
- Functions are no longer inlined into parameter defaults, because they live in their own special scope.
- When inlining identity functions, take into account the fact they may be used to drop `this` in function calls.
- Nullish coalescing operator (`x ?? y`), plus basic optimization for it.
- Template literals in binary expressions such as `+` have been further optimized
## v4.6.10
- Do not use reduce_vars when classes are present
## v4.6.9
- Check if block scopes actually exist in blocks
## v4.6.8
- Take into account "executed bits" of classes like static properties or computed keys, when checking if a class evaluation might throw or have side effects.
## v4.6.7
- Some new performance gains through a `AST_Node.size()` method which measures a node's source code length without printing it to a string first.
- An issue with setting `--comments` to `false` in the CLI has been fixed.
- Fixed some issues with inlining
- `unsafe_symbols` compress option was added, which turns `Symbol("name")` into just `Symbol()`
- Brought back compress performance improvement through the `AST_Node.equivalent_to(other)` method (which was reverted in v4.6.6).
## v4.6.6
(hotfix release)
- Reverted code to 4.6.4 to allow for more time to investigate an issue.
## v4.6.5 (REVERTED)
- Improved compress performance through using a new method to see if two nodes are equivalent, instead of printing them to a string.
## v4.6.4
- The `"some"` value in the `comments` output option now preserves `@lic` and other important comments when using `//`
- `</script>` is now better escaped in regex, and in comments, when using the `inline_script` output option
- Fixed an issue when transforming `new RegExp` into `/.../` when slashes are included in the source
- `AST_Node.prototype.constructor` now exists, allowing for easier debugging of crashes
- Multiple if statements with the same consequents are now collapsed
- Typescript typings improvements
- Optimizations while looking for surrogate pairs in strings
## v4.6.3
- Annotations such as `/*#__NOINLINE__*/` and `/*#__PURE__*/` may now be preserved using the `preserve_annotations` output option
- A TypeScript definition update for the `keep_quoted` output option.
## v4.6.2
- A bug where functions were inlined into other functions with scope conflicts has been fixed.
- `/*#__NOINLINE__*/` annotation fixed for more use cases where inlining happens.
## v4.6.1
- Fixed an issue where a class is duplicated by reduce_vars when there's a recursive reference to the class.
## v4.6.0
- Fixed issues with recursive class references.
- BigInt evaluation has been prevented, stopping Terser from evaluating BigInts like it would do regular numbers.
- Class property support has been added
## v4.5.1
(hotfix release)
- Fixed issue where `() => ({})[something]` was not parenthesised correctly.
## v4.5.0
- Inlining has been improved
- An issue where keep_fnames combined with functions declared through variables was causing name shadowing has been fixed
- You can now set the ES version through their year
- The output option `keep_numbers` has been added, which prevents Terser from turning `1000` into `1e3` and such
- Internal small optimisations and refactors
## v4.4.3
- Number and BigInt parsing has been fixed
- `/*#__INLINE__*/` annotation fixed for arrow functions with non-block bodies.
- Functional tests have been added, using [this repository](https://github.com/terser/terser-functional-tests).
- A memory leak, where the entire AST lives on after compression, has been plugged.
## v4.4.2
- Fixed a problem with inlining identity functions
## v4.4.1
*note:* This introduced a feature, therefore it should have been a minor release.
- Fixed a crash when `unsafe` was enabled.
- An issue has been fixed where `let` statements might be collapsed out of their scope.
- Some error messages have been improved by adding quotes around variable names.
## v4.4.0
- Added `/*#__INLINE__*/` and `/*#__NOINLINE__*/` annotations for calls. If a call has one of these, it either forces or forbids inlining.
## v4.3.11
- Fixed a problem where `window` was considered safe to access, even though there are situations where it isn't (Node.js, workers...)
- Fixed an error where `++` and `--` were considered side-effect free
- `Number(x)` now needs both `unsafe` and and `unsafe_math` to be compressed into `+x` because `x` might be a `BigInt`
- `keep_fnames` now correctly supports regexes when the function is in a variable declaration
## v4.3.10
- Fixed syntax error when repeated semicolons were encountered in classes
- Fixed invalid output caused by the creation of empty sequences internally
- Scopes are now updated when scopes are inlined into them
## v4.3.9
- Fixed issue with mangle's `keep_fnames` option, introduced when adding code to keep variable names of anonymous functions
## v4.3.8
- Typescript typings fix
## v4.3.7
- Parsing of regex options in the CLI (which broke in v4.3.5) was fixed.
- typescript definition updates
## v4.3.6
(crash hotfix)
## v4.3.5
- Fixed an issue with DOS line endings strings separated by `\` and a new line.
- Improved fix for the output size regression related to unused references within the extends section of a class.
- Variable names of anonymous functions (eg: `const x = () => { ... }` or `var func = function () {...}`) are now preserved when keep_fnames is true.
- Fixed performance degradation introduced for large payloads in v4.2.0
## v4.3.4
- Fixed a regression where the output size was increased when unused classes were referred to in the extends clause of a class.
- Small typescript typings fixes.
- Comments with `@preserve`, `@license`, `@cc_on` as well as comments starting with `/*!` and `/**!` are now preserved by default.
## v4.3.3
- Fixed a problem where parsing template strings would mix up octal notation and a slash followed by a zero representing a null character.
- Started accepting the name `async` in destructuring arguments with default value.
- Now Terser takes into account side effects inside class `extends` clauses.
- Added parens whenever there's a comment between a return statement and the returned value, to prevent issues with ASI.
- Stopped using raw RegExp objects, since the spec is going to continue to evolve. This ensures Terser is able to process new, unknown RegExp flags and features. This is a breaking change in the AST node AST_RegExp.
## v4.3.2
- Typescript typing fix
- Ensure that functions can't be inlined, by reduce_vars, into places where they're accessing variables with the same name, but from somewhere else.
## v4.3.1
- Fixed an issue from 4.3.0 where any block scope within a for loop erroneously had its parent set to the function scopee
- Fixed an issue where compressing IIFEs with argument expansions would result in some parameters becoming undefined
- addEventListener options argument's properties are now part of the DOM properties list.
## v4.3.0
- Do not drop computed object keys with side effects
- Functions passed to other functions in calls are now wrapped in parentheses by default, which speeds up loading most modules
- Objects with computed properties are now less likely to be hoisted
- Speed and memory efficiency optimizations
- Fixed scoping issues with `try` and `switch`
## v4.2.1
- Minor refactors
- Fixed a bug similar to #369 in collapse_vars
- Functions can no longer be inlined into a place where they're going to be compared with themselves.
- reduce_funcs option is now legacy, as using reduce_vars without reduce_funcs caused some weird corner cases. As a result, it is now implied in reduce_vars and can't be turned off without turning off reduce_vars.
- Bug which would cause a random stack overflow has now been fixed.
## v4.2.0
- When the source map URL is `inline`, don't write it to a file.
- Fixed output parens when a lambda literal is the tag on a tagged template string.
- The `mangle.properties.undeclared` option was added. This enables the property mangler to mangle properties of variables which can be found in the name cache, but whose properties are not known to this Terser run.
- The v8 bug where the toString and source representations of regexes like `RegExp("\\\n")` includes an actual newline is now fixed.
- Now we're guaranteed to not have duplicate comments in the output
- Domprops updates
## v4.1.4
- Fixed a crash when inlining a function into somewhere else when it has interdependent, non-removable variables.
## v4.1.3
- Several issues with the `reduce_vars` option were fixed.
- Starting this version, we only have a dist/bundle.min.js
## v4.1.2
- The hotfix was hotfixed
## v4.1.1
- Fixed a bug where toplevel scopes were being mixed up with lambda scopes
## v4.1.0
- Internal functions were replaced by `Object.assign`, `Array.prototype.some`, `Array.prototype.find` and `Array.prototype.every`.
- A serious issue where some ESM-native code was broken was fixed.
- Performance improvements were made.
- Support for BigInt was added.
- Inline efficiency was improved. Functions are now being inlined more proactively instead of being inlined only after another Compressor pass.
## v4.0.2
(Hotfix release. Reverts unmapped segments PR [#342](https://github.com/terser/terser/pull/342), which will be put back on Terser when the upstream issue is resolved)
## v4.0.1
- Collisions between the arguments of inlined functions and names in the outer scope are now being avoided while inlining
- Unmapped segments are now preserved when compressing a file which has source maps
- Default values of functions are now correctly converted from Mozilla AST to Terser AST
- JSON ⊂ ECMAScript spec (if you don't know what this is you don't need to)
- Export AST_* classes to library users
- Fixed issue with `collapse_vars` when functions are created with the same name as a variable which already exists
- Added `MutationObserverInit` (Object with options for initialising a mutation observer) properties to the DOM property list
- Custom `Error` subclasses are now internally used instead of old-school Error inheritance hacks.
- Documentation fixes
- Performance optimizations
## v4.0.0
- **breaking change**: The `variables` property of all scopes has become a standard JavaScript `Map` as opposed to the old bespoke `Dictionary` object.
- Typescript definitions were fixed
- `terser --help` was fixed
- The public interface was cleaned up
- Fixed optimisation of `Array` and `new Array`
- Added the `keep_quoted=strict` mode to mangle_props, which behaves more like Google Closure Compiler by mangling all unquoted property names, instead of reserving quoted property names automatically.
- Fixed parent functions' parameters being shadowed in some cases
- Allowed Terser to run in a situation where there are custom functions attached to Object.prototype
- And more bug fixes, optimisations and internal changes
## v3.17.0
- More DOM properties added to --mangle-properties's DOM property list
- Closed issue where if 2 functions had the same argument name, Terser would not inline them together properly
- Fixed issue with `hasOwnProperty.call`
- You can now list files to minify in a Terser config file
- Started replacing `new Array(<number>)` with an array literal
- Started using ES6 capabilities like `Set` and the `includes` method for strings and arrays
## v3.16.1
- Fixed issue where Terser being imported with `import` would cause it not to work due to the `__esModule` property. (PR #254 was submitted, which was nice, but since it wasn't a pure commonJS approach I decided to go with my own solution)
## v3.16.0
- No longer leaves names like Array or Object or window as a SimpleStatement (statement which is just a single expression).
- Add support for sections sourcemaps (IndexedSourceMapConsumer)
- Drops node.js v4 and starts using commonJS
- Is now built with rollup
## v3.15.0
- Inlined spread syntax (`[...[1, 2, 3], 4, 5] => [1, 2, 3, 4, 5]`) in arrays and objects.
- Fixed typo in compressor warning
- Fixed inline source map input bug
- Fixed parsing of template literals with unnecessary escapes (Like `\\a`)
+29
View File
@@ -0,0 +1,29 @@
Terser is released under the BSD license:
Copyright 2012-2018 (c) Mihai Bazon <mihai.bazon@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
+15
View File
@@ -0,0 +1,15 @@
# Our patrons
These are the first-tier patrons from [Patreon](https://www.patreon.com/fabiosantoscode). My appreciation goes to everyone on this list for supporting the project!
* 38elements
* Alan Orozco
* Aria Buckles
* CKEditor
* Mariusz Nowak
* Nakshatra Mukhopadhyay
* Philippe Léger
* Piotrek Koszuliński
* Serhiy Shyyko
* Viktor Hubert
* 龙腾道
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,10 @@
{
"name": "bin",
"private": true,
"version": "1.0.0",
"main": "terser",
"type": "commonjs",
"author": "",
"license": "BSD-2-Clause",
"description": "A package to hold the Terser bin bundle as commonjs while keeping the rest of it ESM."
}
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env node
"use strict";
require("../tools/exit.cjs");
try {
require("source-map-support").install();
} catch (err) {}
const fs = require("fs");
const path = require("path");
const program = require("commander");
const packageJson = require("../package.json");
const { _run_cli: run_cli } = require("..");
run_cli({ program, packageJson, fs, path }).catch((error) => {
console.error(error);
process.exitCode = 1;
});
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/env node
// -*- js -*-
/* eslint-env node */
"use strict";
process.stderr.write( "DEPRECATION WARNING: uglifyjs binary will soon be discontinued!\n");
process.stderr.write("Please use \"terser\" instead.\n\n");
require("./terser");
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
{
"name": "dist",
"private": true,
"version": "1.0.0",
"main": "bundle.min.js",
"type": "commonjs",
"author": "",
"license": "BSD-2-Clause",
"description": "A package to hold the Terser dist bundle as commonjs while keeping the rest of it ESM. Nothing to see here."
}
File diff suppressed because it is too large Load Diff
+479
View File
@@ -0,0 +1,479 @@
import { minify, _default_options } from "../main.js";
import { parse } from "./parse.js";
import {
AST_Assign,
AST_Array,
AST_Constant,
AST_Node,
AST_PropAccess,
AST_RegExp,
AST_Sequence,
AST_Symbol,
AST_Token,
walk
} from "./ast.js";
import { OutputStream } from "./output.js";
export async function run_cli({ program, packageJson, fs, path }) {
const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]);
var files = {};
var options = {
compress: false,
mangle: false
};
const default_options = await _default_options();
program.version(packageJson.name + " " + packageJson.version);
program.parseArgv = program.parse;
program.parse = undefined;
if (process.argv.includes("ast")) program.helpInformation = describe_ast;
else if (process.argv.includes("options")) program.helpInformation = function() {
var text = [];
for (var option in default_options) {
text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:");
text.push(format_object(default_options[option]));
text.push("");
}
return text.join("\n");
};
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
program.option("-f, --format [options]", "Format options.", parse_js());
program.option("-b, --beautify [options]", "Alias for --format.", parse_js());
program.option("-o, --output <file>", "Output file (default STDOUT).");
program.option("--comments [filter]", "Preserve copyright comments in the output.");
program.option("--config-file <file>", "Read minify() options from JSON file.");
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
program.option("--ecma <version>", "Specify ECMAScript release: 5, 2015, 2016 or 2017...");
program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values.");
program.option("--ie8", "Support non-standard Internet Explorer 8.");
program.option("--keep-classnames", "Do not mangle/drop class names.");
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
program.option("--module", "Input is an ES6 module");
program.option("--name-cache <file>", "File to hold mangled name mappings.");
program.option("--rename", "Force symbol expansion.");
program.option("--no-rename", "Disable symbol expansion.");
program.option("--safari10", "Support non-standard Safari 10.");
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
program.option("--timings", "Display operations run time on STDERR.");
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
program.arguments("[files...]").parseArgv(process.argv);
if (program.configFile) {
options = JSON.parse(read_file(program.configFile));
}
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
fatal("ERROR: cannot write source map to STDOUT");
}
[
"compress",
"enclose",
"ie8",
"mangle",
"module",
"safari10",
"sourceMap",
"toplevel",
"wrap"
].forEach(function(name) {
if (name in program) {
options[name] = program[name];
}
});
if ("ecma" in program) {
if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
const ecma = program.ecma | 0;
if (ecma > 5 && ecma < 2015)
options.ecma = ecma + 2009;
else
options.ecma = ecma;
}
if (program.format || program.beautify) {
const chosenOption = program.format || program.beautify;
options.format = typeof chosenOption === "object" ? chosenOption : {};
}
if (program.comments) {
if (typeof options.format != "object") options.format = {};
options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some";
}
if (program.define) {
if (typeof options.compress != "object") options.compress = {};
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
for (var expr in program.define) {
options.compress.global_defs[expr] = program.define[expr];
}
}
if (program.keepClassnames) {
options.keep_classnames = true;
}
if (program.keepFnames) {
options.keep_fnames = true;
}
if (program.mangleProps) {
if (program.mangleProps.domprops) {
delete program.mangleProps.domprops;
} else {
if (typeof program.mangleProps != "object") program.mangleProps = {};
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
}
if (typeof options.mangle != "object") options.mangle = {};
options.mangle.properties = program.mangleProps;
}
if (program.nameCache) {
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
}
if (program.output == "ast") {
options.format = {
ast: true,
code: false
};
}
if (program.parse) {
if (!program.parse.acorn && !program.parse.spidermonkey) {
options.parse = program.parse;
} else if (program.sourceMap && program.sourceMap.content == "inline") {
fatal("ERROR: inline source map only works with built-in parser");
}
}
if (~program.rawArgs.indexOf("--rename")) {
options.rename = true;
} else if (!program.rename) {
options.rename = false;
}
let convert_path = name => name;
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
convert_path = function() {
var base = program.sourceMap.base;
delete options.sourceMap.base;
return function(name) {
return path.relative(base, name);
};
}();
}
let filesList;
if (options.files && options.files.length) {
filesList = options.files;
delete options.files;
} else if (program.args.length) {
filesList = program.args;
}
if (filesList) {
simple_glob(filesList).forEach(function(name) {
files[convert_path(name)] = read_file(name);
});
} else {
await new Promise((resolve) => {
var chunks = [];
process.stdin.setEncoding("utf8");
process.stdin.on("data", function(chunk) {
chunks.push(chunk);
}).on("end", function() {
files = [ chunks.join("") ];
resolve();
});
process.stdin.resume();
});
}
await run_cli();
function convert_ast(fn) {
return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
}
async function run_cli() {
var content = program.sourceMap && program.sourceMap.content;
if (content && content !== "inline") {
options.sourceMap.content = read_file(content, content);
}
if (program.timings) options.timings = true;
try {
if (program.parse) {
if (program.parse.acorn) {
files = convert_ast(function(toplevel, name) {
return require("acorn").parse(files[name], {
ecmaVersion: 2018,
locations: true,
program: toplevel,
sourceFile: name,
sourceType: options.module || program.parse.module ? "module" : "script"
});
});
} else if (program.parse.spidermonkey) {
files = convert_ast(function(toplevel, name) {
var obj = JSON.parse(files[name]);
if (!toplevel) return obj;
toplevel.body = toplevel.body.concat(obj.body);
return toplevel;
});
}
}
} catch (ex) {
fatal(ex);
}
let result;
try {
result = await minify(files, options, fs);
} catch (ex) {
if (ex.name == "SyntaxError") {
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
var col = ex.col;
var lines = files[ex.filename].split(/\r?\n/);
var line = lines[ex.line - 1];
if (!line && !col) {
line = lines[ex.line - 2];
col = line.length;
}
if (line) {
var limit = 70;
if (col > limit) {
line = line.slice(col - limit);
col = limit;
}
print_error(line.slice(0, 80));
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
}
}
if (ex.defs) {
print_error("Supported options:");
print_error(format_object(ex.defs));
}
fatal(ex);
return;
}
if (program.output == "ast") {
if (!options.compress && !options.mangle) {
result.ast.figure_out_scope({});
}
console.log(JSON.stringify(result.ast, function(key, value) {
if (value) switch (key) {
case "thedef":
return symdef(value);
case "enclosed":
return value.length ? value.map(symdef) : undefined;
case "variables":
case "globals":
return value.size ? collect_from_map(value, symdef) : undefined;
}
if (skip_keys.has(key)) return;
if (value instanceof AST_Token) return;
if (value instanceof Map) return;
if (value instanceof AST_Node) {
var result = {
_class: "AST_" + value.TYPE
};
if (value.block_scope) {
result.variables = value.block_scope.variables;
result.enclosed = value.block_scope.enclosed;
}
value.CTOR.PROPS.forEach(function(prop) {
result[prop] = value[prop];
});
return result;
}
return value;
}, 2));
} else if (program.output == "spidermonkey") {
try {
const minified = await minify(
result.code,
{
compress: false,
mangle: false,
format: {
ast: true,
code: false
}
},
fs
);
console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
} catch (ex) {
fatal(ex);
return;
}
} else if (program.output) {
fs.writeFileSync(program.output, result.code);
if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) {
fs.writeFileSync(program.output + ".map", result.map);
}
} else {
console.log(result.code);
}
if (program.nameCache) {
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
}
if (result.timings) for (var phase in result.timings) {
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
}
}
function fatal(message) {
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:");
print_error(message);
process.exit(1);
}
// A file glob function that only supports "*" and "?" wildcards in the basename.
// Example: "foo/bar/*baz??.*.js"
// Argument `glob` may be a string or an array of strings.
// Returns an array of strings. Garbage in, garbage out.
function simple_glob(glob) {
if (Array.isArray(glob)) {
return [].concat.apply([], glob.map(simple_glob));
}
if (glob && glob.match(/[*?]/)) {
var dir = path.dirname(glob);
try {
var entries = fs.readdirSync(dir);
} catch (ex) {}
if (entries) {
var pattern = "^" + path.basename(glob)
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
.replace(/\*/g, "[^/\\\\]*")
.replace(/\?/g, "[^/\\\\]") + "$";
var mod = process.platform === "win32" ? "i" : "";
var rx = new RegExp(pattern, mod);
var results = entries.filter(function(name) {
return rx.test(name);
}).map(function(name) {
return path.join(dir, name);
});
if (results.length) return results;
}
}
return [ glob ];
}
function read_file(path, default_value) {
try {
return fs.readFileSync(path, "utf8");
} catch (ex) {
if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value;
fatal(ex);
}
}
function parse_js(flag) {
return function(value, options) {
options = options || {};
try {
walk(parse(value, { expression: true }), node => {
if (node instanceof AST_Assign) {
var name = node.left.print_to_string();
var value = node.right;
if (flag) {
options[name] = value;
} else if (value instanceof AST_Array) {
options[name] = value.elements.map(to_string);
} else if (value instanceof AST_RegExp) {
value = value.value;
options[name] = new RegExp(value.source, value.flags);
} else {
options[name] = to_string(value);
}
return true;
}
if (node instanceof AST_Symbol || node instanceof AST_PropAccess) {
var name = node.print_to_string();
options[name] = true;
return true;
}
if (!(node instanceof AST_Sequence)) throw node;
function to_string(value) {
return value instanceof AST_Constant ? value.getValue() : value.print_to_string({
quote_keys: true
});
}
});
} catch(ex) {
if (flag) {
fatal("Error parsing arguments for '" + flag + "': " + value);
} else {
options[value] = null;
}
}
return options;
};
}
function symdef(def) {
var ret = (1e6 + def.id) + " " + def.name;
if (def.mangled_name) ret += " " + def.mangled_name;
return ret;
}
function collect_from_map(map, callback) {
var result = [];
map.forEach(function (def) {
result.push(callback(def));
});
return result;
}
function format_object(obj) {
var lines = [];
var padding = "";
Object.keys(obj).map(function(name) {
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
return [ name, JSON.stringify(obj[name]) ];
}).forEach(function(tokens) {
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
});
return lines.join("\n");
}
function print_error(msg) {
process.stderr.write(msg);
process.stderr.write("\n");
}
function describe_ast() {
var out = OutputStream({ beautify: true });
function doitem(ctor) {
out.print("AST_" + ctor.TYPE);
const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop));
if (props.length > 0) {
out.space();
out.with_parens(function() {
props.forEach(function(prop, i) {
if (i) out.space();
out.print(prop);
});
});
}
if (ctor.documentation) {
out.space();
out.print_string(ctor.documentation);
}
if (ctor.SUBCLASSES.length > 0) {
out.space();
out.with_block(function() {
ctor.SUBCLASSES.forEach(function(ctor) {
out.indent();
doitem(ctor);
out.newline();
});
});
}
}
doitem(AST_Node);
return out + "\n";
}
}

Some files were not shown because too many files have changed in this diff Show More