first commit

This commit is contained in:
DanielRamirezGe
2020-01-14 20:43:08 -06:00
parent 3557894f7f
commit 5eecfbf6cd
26326 changed files with 2434803 additions and 0 deletions
+300
View File
@@ -0,0 +1,300 @@
# 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.
## [3.9.0](https://github.com/webpack/webpack-dev-server/compare/v3.8.2...v3.9.0) (2019-10-22)
### Bug Fixes
* add `hostname` and `port` to bonjour name to prevent name collisions ([#2276](https://github.com/webpack/webpack-dev-server/issues/2276)) ([d8af2d9](https://github.com/webpack/webpack-dev-server/commit/d8af2d9))
* add `extKeyUsage` to self-signed cert ([#2274](https://github.com/webpack/webpack-dev-server/issues/2274)) ([a4dbc3b](https://github.com/webpack/webpack-dev-server/commit/a4dbc3b))
### Features
* add multiple `openPage` support ([#2266](https://github.com/webpack/webpack-dev-server/issues/2266)) ([c9e9178](https://github.com/webpack/webpack-dev-server/commit/c9e9178))
### [3.8.2](https://github.com/webpack/webpack-dev-server/compare/v3.8.1...v3.8.2) (2019-10-02)
### Security
* update `selfsigned` package
### [3.8.1](https://github.com/webpack/webpack-dev-server/compare/v3.8.0...v3.8.1) (2019-09-16)
### Bug Fixes
* add null check for connection.headers ([#2200](https://github.com/webpack/webpack-dev-server/issues/2200)) ([7964997](https://github.com/webpack/webpack-dev-server/commit/7964997))
* false positive for an absolute path in the `ContentBase` option on windows ([#2202](https://github.com/webpack/webpack-dev-server/issues/2202)) ([68ecf78](https://github.com/webpack/webpack-dev-server/commit/68ecf78))
* add status in quiet log level ([#2235](https://github.com/webpack/webpack-dev-server/issues/2235)) ([7e2224e](https://github.com/webpack/webpack-dev-server/commit/7e2224e))
* scriptHost in client ([#2246](https://github.com/webpack/webpack-dev-server/issues/2246)) ([00903f6](https://github.com/webpack/webpack-dev-server/commit/00903f6))
## [3.8.0](https://github.com/webpack/webpack-dev-server/compare/v3.7.2...v3.8.0) (2019-08-09)
### Bug Fixes
* **server:** fix setupExitSignals usage ([#2181](https://github.com/webpack/webpack-dev-server/issues/2181)) ([bbe410e](https://github.com/webpack/webpack-dev-server/commit/bbe410e))
* **server:** set port before instantiating server ([#2143](https://github.com/webpack/webpack-dev-server/issues/2143)) ([cfbf229](https://github.com/webpack/webpack-dev-server/commit/cfbf229))
* check for name of HotModuleReplacementPlugin to avoid RangeError ([#2146](https://github.com/webpack/webpack-dev-server/issues/2146)) ([4579775](https://github.com/webpack/webpack-dev-server/commit/4579775))
* **server:** check for external urls in array ([#1980](https://github.com/webpack/webpack-dev-server/issues/1980)) ([fa78347](https://github.com/webpack/webpack-dev-server/commit/fa78347))
* **server:** fix header check for socket server ([#2077](https://github.com/webpack/webpack-dev-server/issues/2077)) ([7f51859](https://github.com/webpack/webpack-dev-server/commit/7f51859))
* **server:** stricter headers security check ([#2092](https://github.com/webpack/webpack-dev-server/issues/2092)) ([078ddca](https://github.com/webpack/webpack-dev-server/commit/078ddca))
### Features
* **server:** add transportMode ([#2116](https://github.com/webpack/webpack-dev-server/issues/2116)) ([b5b9cb4](https://github.com/webpack/webpack-dev-server/commit/b5b9cb4))
* **server:** serverMode 'ws' option ([#2082](https://github.com/webpack/webpack-dev-server/issues/2082)) ([04483f4](https://github.com/webpack/webpack-dev-server/commit/04483f4))
* **server/client:** made progress option available to API ([#1961](https://github.com/webpack/webpack-dev-server/issues/1961)) ([56274e4](https://github.com/webpack/webpack-dev-server/commit/56274e4))
### Potential Breaking changes
We have migrated `serverMode` and `clientMode` to `transportMode` as an experimental option. If you want to use this feature, you have to change your settings.
Related PR: https://github.com/webpack/webpack-dev-server/pull/2116
### [3.7.2](https://github.com/webpack/webpack-dev-server/compare/v3.7.1...v3.7.2) (2019-06-17)
### Bug Fixes
* **client:** add default fallback for client ([#2015](https://github.com/webpack/webpack-dev-server/issues/2015)) ([d26b444](https://github.com/webpack/webpack-dev-server/commit/d26b444))
* **open:** set `wait: false` to run server.close successfully ([#2001](https://github.com/webpack/webpack-dev-server/issues/2001)) ([2b4cb52](https://github.com/webpack/webpack-dev-server/commit/2b4cb52))
* **test:** fixed ProvidePlugin.test.js ([#2002](https://github.com/webpack/webpack-dev-server/issues/2002)) ([47453cb](https://github.com/webpack/webpack-dev-server/commit/47453cb))
### [3.7.1](https://github.com/webpack/webpack-dev-server/compare/v3.7.0...v3.7.1) (2019-06-07)
### Bug Fixes
* retry finding port when port is null and get ports in sequence ([#1993](https://github.com/webpack/webpack-dev-server/issues/1993)) ([bc57514](https://github.com/webpack/webpack-dev-server/commit/bc57514))
## [3.7.0](https://github.com/webpack/webpack-dev-server/compare/v3.6.0...v3.7.0) (2019-06-06)
### Bug Fixes
* change clientLogLevel order to be called first ([#1973](https://github.com/webpack/webpack-dev-server/issues/1973)) ([57c8c92](https://github.com/webpack/webpack-dev-server/commit/57c8c92))
* es6 syntax in client ([#1982](https://github.com/webpack/webpack-dev-server/issues/1982)) ([802aa30](https://github.com/webpack/webpack-dev-server/commit/802aa30))
## [3.6.0](https://github.com/webpack/webpack-dev-server/compare/v3.5.1...v3.6.0) (2019-06-05)
### Bug Fixes
* **config:** enable `--overlay` ([#1968](https://github.com/webpack/webpack-dev-server/issues/1968)) ([dc81e23](https://github.com/webpack/webpack-dev-server/commit/dc81e23))
* **server:** don't ignore node_modules by default ([#1970](https://github.com/webpack/webpack-dev-server/issues/1970)) ([699f8b4](https://github.com/webpack/webpack-dev-server/commit/699f8b4)), closes [#1794](https://github.com/webpack/webpack-dev-server/issues/1794)
### Features
* **server:** add serverMode option ([#1937](https://github.com/webpack/webpack-dev-server/issues/1937)) ([44a8cde](https://github.com/webpack/webpack-dev-server/commit/44a8cde))
### [3.5.1](https://github.com/webpack/webpack-dev-server/compare/v3.5.0...v3.5.1) (2019-06-01)
### Bug Fixes
* allow passing promise function of webpack.config.js ([#1947](https://github.com/webpack/webpack-dev-server/issues/1947)) ([8cf1053](https://github.com/webpack/webpack-dev-server/commit/8cf1053))
## [3.5.0](https://github.com/webpack/webpack-dev-server/compare/v3.4.1...v3.5.0) (2019-05-31)
### Bug Fixes
* add client code for `electron-renderer` target ([#1935](https://github.com/webpack/webpack-dev-server/issues/1935)) ([9297988](https://github.com/webpack/webpack-dev-server/commit/9297988))
* add client code for `node-webkit` target ([#1942](https://github.com/webpack/webpack-dev-server/issues/1942)) ([c6b2b1f](https://github.com/webpack/webpack-dev-server/commit/c6b2b1f))
### Features
* **server:** `onListening` option ([#1930](https://github.com/webpack/webpack-dev-server/issues/1930)) ([61d0cdf](https://github.com/webpack/webpack-dev-server/commit/61d0cdf))
* **server:** add callback support for invalidate ([#1900](https://github.com/webpack/webpack-dev-server/issues/1900)) ([cd218ef](https://github.com/webpack/webpack-dev-server/commit/cd218ef))
* **server:** add `WEBPACK_DEV_SERVER` env variable ([#1929](https://github.com/webpack/webpack-dev-server/issues/1929)) ([856169e](https://github.com/webpack/webpack-dev-server/commit/856169e))
### [3.4.1](https://github.com/webpack/webpack-dev-server/compare/v3.4.0...v3.4.1) (2019-05-17)
### Bug Fixes
* add none and warning to clientLogLevel ([#1901](https://github.com/webpack/webpack-dev-server/issues/1901)) ([0ae9be8](https://github.com/webpack/webpack-dev-server/commit/0ae9be8))
* broken hot reload ([#1903](https://github.com/webpack/webpack-dev-server/issues/1903)) ([6a444cd](https://github.com/webpack/webpack-dev-server/commit/6a444cd))
## [3.4.0](https://github.com/webpack/webpack-dev-server/compare/v3.3.1...v3.4.0) (2019-05-17)
### Bug Fixes
* don't use self.location.port ([#1838](https://github.com/webpack/webpack-dev-server/issues/1838)) ([6d31984](https://github.com/webpack/webpack-dev-server/commit/6d31984))
* do not include config files in dist ([#1883](https://github.com/webpack/webpack-dev-server/issues/1883)) ([c535bb2](https://github.com/webpack/webpack-dev-server/commit/c535bb2))
* only add client entry to web targets ([#1775](https://github.com/webpack/webpack-dev-server/issues/1775)) ([cf4d0d0](https://github.com/webpack/webpack-dev-server/commit/cf4d0d0))
* update clientLogLevel to match docs and error ([#1825](https://github.com/webpack/webpack-dev-server/issues/1825)) ([7f52bbf](https://github.com/webpack/webpack-dev-server/commit/7f52bbf))
* add errors-warnings preset ([#1895](https://github.com/webpack/webpack-dev-server/issues/1895)) ([2a81ad2](https://github.com/webpack/webpack-dev-server/commit/2a81ad2))
### Features
* added injectClient option ([#1775](https://github.com/webpack/webpack-dev-server/issues/1775)) ([cf4d0d0](https://github.com/webpack/webpack-dev-server/commit/cf4d0d0))
* added injectHot option ([#1775](https://github.com/webpack/webpack-dev-server/issues/1775)) ([cf4d0d0](https://github.com/webpack/webpack-dev-server/commit/cf4d0d0))
* added sockPort option ([#1792](https://github.com/webpack/webpack-dev-server/issues/1792)) ([58d1682](https://github.com/webpack/webpack-dev-server/commit/58d1682))
* added sockHost option ([#1858](https://github.com/webpack/webpack-dev-server/issues/1858)) ([f47dff2](https://github.com/webpack/webpack-dev-server/commit/f47dff2))
* support HEAD method ([#1875](https://github.com/webpack/webpack-dev-server/issues/1875)) ([c2360e4](https://github.com/webpack/webpack-dev-server/commit/c2360e4))
* added liveReload option ([#1889](https://github.com/webpack/webpack-dev-server/issues/1889)) ([fc4fe32](https://github.com/webpack/webpack-dev-server/commit/fc4fe32))
* update express to 4.17 version
## [3.3.1](https://github.com/webpack/webpack-dev-server/compare/v3.3.0...v3.3.1) (2019-04-09)
### Bug Fixes
* **regression:** always get necessary stats for hmr ([#1780](https://github.com/webpack/webpack-dev-server/issues/1780)) ([66b04a9](https://github.com/webpack/webpack-dev-server/commit/66b04a9))
* **regression:** host and port can be undefined or null ([#1779](https://github.com/webpack/webpack-dev-server/issues/1779)) ([028ceee](https://github.com/webpack/webpack-dev-server/commit/028ceee))
* only add entries after compilers have been created ([#1774](https://github.com/webpack/webpack-dev-server/issues/1774)) ([b31cbaa](https://github.com/webpack/webpack-dev-server/commit/b31cbaa))
# [3.3.0](https://github.com/webpack/webpack-dev-server/compare/v3.2.1...v3.3.0) (2019-04-08)
### Bug Fixes
* compatibility with webpack-cli@3.3 ([#1754](https://github.com/webpack/webpack-dev-server/issues/1754)) ([fd7cb0d](https://github.com/webpack/webpack-dev-server/commit/fd7cb0d))
* ignore proxy when bypass return false ([#1696](https://github.com/webpack/webpack-dev-server/issues/1696)) ([aa7de77](https://github.com/webpack/webpack-dev-server/commit/aa7de77))
* respect stats option from webpack config ([#1665](https://github.com/webpack/webpack-dev-server/issues/1665)) ([efaa740](https://github.com/webpack/webpack-dev-server/commit/efaa740))
* use location.port when location.hostname is used to infer HMR socket URL ([#1664](https://github.com/webpack/webpack-dev-server/issues/1664)) ([2f7f052](https://github.com/webpack/webpack-dev-server/commit/2f7f052))
* don't crash with express.static.mime.types ([#1765](https://github.com/webpack/webpack-dev-server/issues/1765)) ([919ff77](https://github.com/webpack/webpack-dev-server/commit/919ff77))
### Features
* add option "serveIndex" to enable/disable serveIndex middleware ([#1752](https://github.com/webpack/webpack-dev-server/issues/1752)) ([d5d60cb](https://github.com/webpack/webpack-dev-server/commit/d5d60cb))
* add webpack as argument to before and after options ([#1760](https://github.com/webpack/webpack-dev-server/issues/1760)) ([0984d4b](https://github.com/webpack/webpack-dev-server/commit/0984d4b))
* http2 option to enable/disable HTTP/2 with HTTPS ([#1721](https://github.com/webpack/webpack-dev-server/issues/1721)) ([dcd2434](https://github.com/webpack/webpack-dev-server/commit/dcd2434))
* random port retry logic ([#1692](https://github.com/webpack/webpack-dev-server/issues/1692)) ([419f02e](https://github.com/webpack/webpack-dev-server/commit/419f02e))
* relax depth limit from chokidar for content base ([#1697](https://github.com/webpack/webpack-dev-server/issues/1697)) ([7ea9ab9](https://github.com/webpack/webpack-dev-server/commit/7ea9ab9))
## [3.2.1](https://github.com/webpack/webpack-dev-server/compare/v3.2.0...v3.2.1) (2019-02-25)
### Bug Fixes
* deprecation message about `setup` now warning about `v4` ([#1684](https://github.com/webpack/webpack-dev-server/issues/1684)) ([523a6ec](https://github.com/webpack/webpack-dev-server/commit/523a6ec))
* **regression:** allow `ca`, `key` and `cert` will be string ([#1676](https://github.com/webpack/webpack-dev-server/issues/1676)) ([b8d5c1e](https://github.com/webpack/webpack-dev-server/commit/b8d5c1e))
* **regression:** handle `key`, `cert`, `cacert` and `pfx` in CLI ([#1688](https://github.com/webpack/webpack-dev-server/issues/1688)) ([4b2076c](https://github.com/webpack/webpack-dev-server/commit/4b2076c))
* **regression:** problem with `idb-connector` after update `internal-ip` ([#1691](https://github.com/webpack/webpack-dev-server/issues/1691)) ([eb48691](https://github.com/webpack/webpack-dev-server/commit/eb48691))
<a name="3.1.14"></a>
## [3.1.14](https://github.com/webpack/webpack-dev-server/compare/v3.1.13...v3.1.14) (2018-12-24)
### Bug Fixes
* add workaround for Origin header in sockjs ([#1608](https://github.com/webpack/webpack-dev-server/issues/1608)) ([1dfd4fb](https://github.com/webpack/webpack-dev-server/commit/1dfd4fb))
<a name="3.1.13"></a>
## [3.1.13](https://github.com/webpack/webpack-dev-server/compare/v3.1.12...v3.1.13) (2018-12-22)
### Bug Fixes
* delete a comma for Node.js <= v7.x ([#1609](https://github.com/webpack/webpack-dev-server/issues/1609)) ([0bab1c0](https://github.com/webpack/webpack-dev-server/commit/0bab1c0))
<a name="3.1.12"></a>
## [3.1.12](https://github.com/webpack/webpack-dev-server/compare/v3.1.11...v3.1.12) (2018-12-22)
### Bug Fixes
* regression in `checkHost` for checking Origin header ([#1606](https://github.com/webpack/webpack-dev-server/issues/1606)) ([8bb3ca8](https://github.com/webpack/webpack-dev-server/commit/8bb3ca8))
<a name="3.1.11"></a>
## [3.1.11](https://github.com/webpack/webpack-dev-server/compare/v3.1.10...v3.1.11) (2018-12-21)
### Bug Fixes
* **bin/options:** correct check for color support (`options.color`) ([#1555](https://github.com/webpack/webpack-dev-server/issues/1555)) ([55398b5](https://github.com/webpack/webpack-dev-server/commit/55398b5))
* **package:** update `spdy` v3.4.1...4.0.0 (assertion error) ([#1491](https://github.com/webpack/webpack-dev-server/issues/1491)) ([#1563](https://github.com/webpack/webpack-dev-server/issues/1563)) ([7a3a257](https://github.com/webpack/webpack-dev-server/commit/7a3a257))
* **Server:** correct `node` version checks ([#1543](https://github.com/webpack/webpack-dev-server/issues/1543)) ([927a2b3](https://github.com/webpack/webpack-dev-server/commit/927a2b3))
* **Server:** mime type for wasm in contentBase directory ([#1575](https://github.com/webpack/webpack-dev-server/issues/1575)) ([#1580](https://github.com/webpack/webpack-dev-server/issues/1580)) ([fadae5d](https://github.com/webpack/webpack-dev-server/commit/fadae5d))
* add url for compatibility with webpack@5 ([#1598](https://github.com/webpack/webpack-dev-server/issues/1598)) ([#1599](https://github.com/webpack/webpack-dev-server/issues/1599)) ([68dd49a](https://github.com/webpack/webpack-dev-server/commit/68dd49a))
* check origin header for websocket connection ([#1603](https://github.com/webpack/webpack-dev-server/issues/1603)) ([b3217ca](https://github.com/webpack/webpack-dev-server/commit/b3217ca))
<a name="3.1.10"></a>
## [3.1.10](https://github.com/webpack/webpack-dev-server/compare/v3.1.9...v3.1.10) (2018-10-23)
### Bug Fixes
* **options:** add `writeToDisk` option to schema ([#1520](https://github.com/webpack/webpack-dev-server/issues/1520)) ([d2f4902](https://github.com/webpack/webpack-dev-server/commit/d2f4902))
* **package:** update `sockjs-client` v1.1.5...1.3.0 (`url-parse` vulnerability) ([#1537](https://github.com/webpack/webpack-dev-server/issues/1537)) ([e719959](https://github.com/webpack/webpack-dev-server/commit/e719959))
* **Server:** set `tls.DEFAULT_ECDH_CURVE` to `'auto'` ([#1531](https://github.com/webpack/webpack-dev-server/issues/1531)) ([c12def3](https://github.com/webpack/webpack-dev-server/commit/c12def3))
<a name="3.1.9"></a>
## [3.1.9](https://github.com/webpack/webpack-dev-server/compare/v3.1.8...v3.1.9) (2018-09-24)
<a name="3.1.8"></a>
## [3.1.8](https://github.com/webpack/webpack-dev-server/compare/v3.1.7...v3.1.8) (2018-09-06)
### Bug Fixes
* **package:** `yargs` security vulnerability (`dependencies`) ([#1492](https://github.com/webpack/webpack-dev-server/issues/1492)) ([8fb67c9](https://github.com/webpack/webpack-dev-server/commit/8fb67c9))
* **utils/createLogger:** ensure `quiet` always takes precedence (`options.quiet`) ([#1486](https://github.com/webpack/webpack-dev-server/issues/1486)) ([7a6ca47](https://github.com/webpack/webpack-dev-server/commit/7a6ca47))
<a name="3.1.7"></a>
## [3.1.7](https://github.com/webpack/webpack-dev-server/compare/v3.1.6...v3.1.7) (2018-08-29)
### Bug Fixes
* **Server:** don't use `spdy` on `node >= v10.0.0` ([#1451](https://github.com/webpack/webpack-dev-server/issues/1451)) ([8ab9eb6](https://github.com/webpack/webpack-dev-server/commit/8ab9eb6))
<a name="3.1.6"></a>
## [3.1.6](https://github.com/webpack/webpack-dev-server/compare/v3.1.5...v3.1.6) (2018-08-26)
### Bug Fixes
* **bin:** handle `process` signals correctly when the server isn't ready yet ([#1432](https://github.com/webpack/webpack-dev-server/issues/1432)) ([334c3a5](https://github.com/webpack/webpack-dev-server/commit/334c3a5))
* **examples/cli:** correct template path in `open-page` example ([#1401](https://github.com/webpack/webpack-dev-server/issues/1401)) ([df30727](https://github.com/webpack/webpack-dev-server/commit/df30727))
* **schema:** allow the `output` filename to be a `{Function}` ([#1409](https://github.com/webpack/webpack-dev-server/issues/1409)) ([e2220c4](https://github.com/webpack/webpack-dev-server/commit/e2220c4))
+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.
+163
View File
@@ -0,0 +1,163 @@
<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]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![downloads][downloads]][npm-url]
[![contributors][contributors]][contributors-url]
# webpack-dev-server
Use [webpack](https://webpack.js.org) with a development server that provides
live reloading. This should be used for **development only**.
It uses [webpack-dev-middleware][middleware-url] under the hood, which provides
fast in-memory access to the webpack assets.
## Table of Contents
- [Getting Started](#getting-started)
- [Usage](#usage)
- [With the CLI](#with-the-cli)
- [With NPM Scripts](#with-npm-scripts)
- [The Result](#the-result)
- [Browser Support](#browser-support)
- [Support](#support)
- [Contributing](#contributing)
- [Attribution](#attribution)
- [License](#license)
## Getting Started
First things first, install the module:
```console
npm install webpack-dev-server --save-dev
```
_Note: While you can install and run webpack-dev-server globally, we recommend
installing it locally. webpack-dev-server will always use a local installation
over a global one._
## Usage
There are two main, recommended methods of using the module:
### With the CLI
The easiest way to use it is with the CLI. In the directory where your
`webpack.config.js` is, run:
```console
node_modules/.bin/webpack-dev-server
```
_**Note**: Many CLI options are available with `webpack-dev-server`. Explore this [link](https://webpack.js.org/configuration/dev-server/)._
### With NPM Scripts
NPM package.json scripts are a convenient and useful means to run locally installed
binaries without having to be concerned about their full paths. Simply define a
script as such:
```json
"scripts": {
"start:dev": "webpack-dev-server"
}
```
And run the following in your terminal/console:
```console
npm run start:dev
```
NPM will automagically reference the binary in `node_modules` for you, and
execute the file or command.
### The Result
Either method will start a server instance and begin listening for connections
from `localhost` on port `8080`.
webpack-dev-server is configured by default to support live-reload of files as
you edit your assets while the server is running.
See [**the documentation**][docs-url] for more use cases and options.
## Browser Support
While `webpack-dev-server` transpiles the client (browser) scripts to an ES5
state, the project only officially supports the _last two versions of major
browsers_. We simply don't have the resources to support every whacky
browser out there.
If you find a bug with an obscure / old browser, we would actively welcome a
Pull Request to resolve the bug.
## Support
We do our best to keep Issues in the repository focused on bugs, features, and
needed modifications to the code for the module. Because of that, we ask users
with general support, "how-to", or "why isn't this working" questions to try one
of the other support channels that are available.
Your first-stop-shop for support for webpack-dev-server should by the excellent
[documentation][docs-url] for the module. If you see an opportunity for improvement
of those docs, please head over to the [webpack.js.org repo][wjo-url] and open a
pull request.
From there, we encourage users to visit the [webpack Gitter chat][chat-url] and
talk to the fine folks there. If your quest for answers comes up dry in chat,
head over to [StackOverflow][stack-url] and do a quick search or open a new
question. Remember; It's always much easier to answer questions that include your
`webpack.config.js` and relevant files!
If you're twitter-savvy you can tweet [#webpack][hash-url] with your question
and someone should be able to reach out and lend a hand.
If you have discovered a :bug:, have a feature suggestion, or would like to see
a modification, please feel free to create an issue on Github. _Note: The issue
template isn't optional, so please be sure not to remove it, and please fill it
out completely._
## Contributing
We welcome your contributions! Please have a read of [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to get involved.
## Attribution
This project is heavily inspired by [peerigon/nof5](https://github.com/peerigon/nof5).
## License
#### [MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/webpack-dev-server.svg
[npm-url]: https://npmjs.com/package/webpack-dev-server
[node]: https://img.shields.io/node/v/webpack-dev-server.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack/webpack-dev-server.svg
[deps-url]: https://david-dm.org/webpack/webpack-dev-server
[tests]: https://dev.azure.com/webpack/webpack-dev-server/_apis/build/status/webpack.webpack-dev-server?branchName=master
[tests-url]: https://dev.azure.com/webpack/webpack-dev-server/_build/latest?definitionId=7&branchName=master
[cover]: https://codecov.io/gh/webpack/webpack-dev-server/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/webpack-dev-server
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[docs-url]: https://webpack.js.org/configuration/dev-server/#devserver
[hash-url]: https://twitter.com/search?q=webpack
[middleware-url]: https://github.com/webpack/webpack-dev-middleware
[stack-url]: https://stackoverflow.com/questions/tagged/webpack-dev-server
[uglify-url]: https://github.com/webpack-contrib/uglifyjs-webpack-plugin
[wjo-url]: https://github.com/webpack/webpack.js.org
[downloads]: https://img.shields.io/npm/dm/webpack-dev-server.svg
[contributors-url]: https://github.com/webpack/webpack-dev-server/graphs/contributors
[contributors]: https://img.shields.io/github/contributors/webpack/webpack-dev-server.svg
+195
View File
@@ -0,0 +1,195 @@
'use strict';
const ADVANCED_GROUP = 'Advanced options:';
const DISPLAY_GROUP = 'Stats options:';
const SSL_GROUP = 'SSL options:';
const CONNECTION_GROUP = 'Connection options:';
const RESPONSE_GROUP = 'Response options:';
const BASIC_GROUP = 'Basic options:';
module.exports = {
devServer: [
{
name: 'bonjour',
type: Boolean,
describe: 'Broadcasts the server via ZeroConf networking on start',
},
{
name: 'lazy',
type: Boolean,
describe: 'Lazy',
},
{
name: 'liveReload',
type: Boolean,
defaultValue: true,
describe: 'Enables/Disables live reloading on changing files',
},
{
name: 'serveIndex',
type: Boolean,
describe: 'Enables/Disables serveIndex middleware',
defaultValue: true,
},
{
name: 'inline',
type: Boolean,
defaultValue: true,
describe:
'Inline mode (set to false to disable including client scripts like livereload)',
},
{
name: 'profile',
type: Boolean,
describe: 'Print compilation profile data for progress steps',
},
{
name: 'progress',
type: Boolean,
describe: 'Print compilation progress in percentage',
group: BASIC_GROUP,
},
{
name: 'hot-only',
type: Boolean,
describe: 'Do not refresh page if HMR fails',
group: ADVANCED_GROUP,
},
{
name: 'stdin',
type: Boolean,
describe: 'close when stdin ends',
},
{
name: 'open',
type: String,
describe:
'Open the default browser, or optionally specify a browser name',
},
{
name: 'useLocalIp',
type: Boolean,
describe: 'Open default browser with local IP',
},
{
name: 'open-page',
type: String,
describe: 'Open default browser with the specified page',
},
{
name: 'client-log-level',
type: String,
group: DISPLAY_GROUP,
defaultValue: 'info',
describe:
'Log level in the browser (trace, debug, info, warn, error or silent)',
},
{
name: 'https',
type: Boolean,
group: SSL_GROUP,
describe: 'HTTPS',
},
{
name: 'http2',
type: Boolean,
group: SSL_GROUP,
describe: 'HTTP/2, must be used with HTTPS',
},
{
name: 'key',
type: String,
describe: 'Path to a SSL key.',
group: SSL_GROUP,
},
{
name: 'cert',
type: String,
describe: 'Path to a SSL certificate.',
group: SSL_GROUP,
},
{
name: 'cacert',
type: String,
describe: 'Path to a SSL CA certificate.',
group: SSL_GROUP,
},
{
name: 'pfx',
type: String,
describe: 'Path to a SSL pfx file.',
group: SSL_GROUP,
},
{
name: 'pfx-passphrase',
type: String,
describe: 'Passphrase for pfx file.',
group: SSL_GROUP,
},
{
name: 'content-base',
type: String,
describe: 'A directory or URL to serve HTML content from.',
group: RESPONSE_GROUP,
},
{
name: 'watch-content-base',
type: Boolean,
describe: 'Enable live-reloading of the content-base.',
group: RESPONSE_GROUP,
},
{
name: 'history-api-fallback',
type: Boolean,
describe: 'Fallback to /index.html for Single Page Applications.',
group: RESPONSE_GROUP,
},
{
name: 'compress',
type: Boolean,
describe: 'Enable gzip compression',
group: RESPONSE_GROUP,
},
// findPort is currently not set up
{
name: 'port',
type: Number,
describe: 'The port',
group: CONNECTION_GROUP,
},
{
name: 'disable-host-check',
type: Boolean,
describe: 'Will not check the host',
group: CONNECTION_GROUP,
},
{
name: 'socket',
type: String,
describe: 'Socket to listen',
group: CONNECTION_GROUP,
},
{
name: 'public',
type: String,
describe: 'The public hostname/ip address of the server',
group: CONNECTION_GROUP,
},
{
name: 'host',
type: String,
describe: 'The hostname/ip address the server will bind to',
group: CONNECTION_GROUP,
},
// use command-line-args "multiple" option, allowing the usage: --allowed-hosts host1 host2 host3
// instead of the old, comma-separated syntax: --allowed-hosts host1,host2,host3
{
name: 'allowed-hosts',
type: String,
describe:
'A list of hosts that are allowed to access the dev server, separated by spaces',
group: CONNECTION_GROUP,
multiple: true,
},
],
};
+187
View File
@@ -0,0 +1,187 @@
'use strict';
/* eslint-disable
multiline-ternary,
space-before-function-paren
*/
const ADVANCED_GROUP = 'Advanced options:';
const DISPLAY_GROUP = 'Stats options:';
const SSL_GROUP = 'SSL options:';
const CONNECTION_GROUP = 'Connection options:';
const RESPONSE_GROUP = 'Response options:';
const BASIC_GROUP = 'Basic options:';
const options = {
bonjour: {
type: 'boolean',
describe: 'Broadcasts the server via ZeroConf networking on start',
},
lazy: {
type: 'boolean',
describe: 'Lazy',
},
liveReload: {
type: 'boolean',
describe: 'Enables/Disables live reloading on changing files',
default: true,
},
serveIndex: {
type: 'boolean',
describe: 'Enables/Disables serveIndex middleware',
default: true,
},
inline: {
type: 'boolean',
default: true,
describe:
'Inline mode (set to false to disable including client scripts like livereload)',
},
profile: {
type: 'boolean',
describe: 'Print compilation profile data for progress steps',
},
progress: {
type: 'boolean',
describe: 'Print compilation progress in percentage',
group: BASIC_GROUP,
},
'hot-only': {
type: 'boolean',
describe: 'Do not refresh page if HMR fails',
group: ADVANCED_GROUP,
},
stdin: {
type: 'boolean',
describe: 'close when stdin ends',
},
open: {
type: 'string',
describe: 'Open the default browser, or optionally specify a browser name',
},
useLocalIp: {
type: 'boolean',
describe: 'Open default browser with local IP',
},
'open-page': {
type: 'string',
describe: 'Open default browser with the specified page',
requiresArg: true,
},
color: {
type: 'boolean',
alias: 'colors',
default: function supportsColor() {
// Use `require('supports-color').stdout` for supports-color >= 5.0.0.
// See https://github.com/webpack/webpack-dev-server/pull/1555.
return require('supports-color').stdout;
},
group: DISPLAY_GROUP,
describe: 'Enables/Disables colors on the console',
},
info: {
type: 'boolean',
group: DISPLAY_GROUP,
default: true,
describe: 'Info',
},
quiet: {
type: 'boolean',
group: DISPLAY_GROUP,
describe: 'Quiet',
},
'client-log-level': {
type: 'string',
group: DISPLAY_GROUP,
default: 'info',
describe:
'Log level in the browser (trace, debug, info, warn, error or silent)',
},
https: {
type: 'boolean',
group: SSL_GROUP,
describe: 'HTTPS',
},
http2: {
type: 'boolean',
group: SSL_GROUP,
describe: 'HTTP/2, must be used with HTTPS',
},
key: {
type: 'string',
describe: 'Path to a SSL key.',
group: SSL_GROUP,
},
cert: {
type: 'string',
describe: 'Path to a SSL certificate.',
group: SSL_GROUP,
},
cacert: {
type: 'string',
describe: 'Path to a SSL CA certificate.',
group: SSL_GROUP,
},
pfx: {
type: 'string',
describe: 'Path to a SSL pfx file.',
group: SSL_GROUP,
},
'pfx-passphrase': {
type: 'string',
describe: 'Passphrase for pfx file.',
group: SSL_GROUP,
},
'content-base': {
type: 'string',
describe: 'A directory or URL to serve HTML content from.',
group: RESPONSE_GROUP,
},
'watch-content-base': {
type: 'boolean',
describe: 'Enable live-reloading of the content-base.',
group: RESPONSE_GROUP,
},
'history-api-fallback': {
type: 'boolean',
describe: 'Fallback to /index.html for Single Page Applications.',
group: RESPONSE_GROUP,
},
compress: {
type: 'boolean',
describe: 'Enable gzip compression',
group: RESPONSE_GROUP,
},
port: {
describe: 'The port',
group: CONNECTION_GROUP,
},
'disable-host-check': {
type: 'boolean',
describe: 'Will not check the host',
group: CONNECTION_GROUP,
},
socket: {
type: 'String',
describe: 'Socket to listen',
group: CONNECTION_GROUP,
},
public: {
type: 'string',
describe: 'The public hostname/ip address of the server',
group: CONNECTION_GROUP,
},
host: {
type: 'string',
default: 'localhost',
describe: 'The hostname/ip address the server will bind to',
group: CONNECTION_GROUP,
},
'allowed-hosts': {
type: 'string',
describe:
'A comma-delimited string of hosts that are allowed to access the dev server',
group: CONNECTION_GROUP,
},
};
module.exports = options;
+167
View File
@@ -0,0 +1,167 @@
#!/usr/bin/env node
'use strict';
/* eslint-disable no-shadow, no-console */
const fs = require('fs');
const net = require('net');
const debug = require('debug')('webpack-dev-server');
const importLocal = require('import-local');
const yargs = require('yargs');
const webpack = require('webpack');
const Server = require('../lib/Server');
const setupExitSignals = require('../lib/utils/setupExitSignals');
const colors = require('../lib/utils/colors');
const processOptions = require('../lib/utils/processOptions');
const createLogger = require('../lib/utils/createLogger');
const getVersions = require('../lib/utils/getVersions');
const options = require('./options');
let server;
const serverData = {
server: null,
};
// we must pass an object that contains the server object as a property so that
// we can update this server property later, and setupExitSignals will be able to
// recognize that the server has been instantiated, because we will set
// serverData.server to the new server object.
setupExitSignals(serverData);
// Prefer the local installation of webpack-dev-server
if (importLocal(__filename)) {
debug('Using local install of webpack-dev-server');
return;
}
try {
require.resolve('webpack-cli');
} catch (err) {
console.error('The CLI moved into a separate package: webpack-cli');
console.error(
"Please install 'webpack-cli' in addition to webpack itself to use the CLI"
);
console.error('-> When using npm: npm i -D webpack-cli');
console.error('-> When using yarn: yarn add -D webpack-cli');
process.exitCode = 1;
}
yargs.usage(
`${getVersions()}\nUsage: https://webpack.js.org/configuration/dev-server/`
);
// webpack-cli@3.3 path : 'webpack-cli/bin/config/config-yargs'
let configYargsPath;
try {
require.resolve('webpack-cli/bin/config/config-yargs');
configYargsPath = 'webpack-cli/bin/config/config-yargs';
} catch (e) {
configYargsPath = 'webpack-cli/bin/config-yargs';
}
// eslint-disable-next-line import/no-extraneous-dependencies
// eslint-disable-next-line import/no-dynamic-require
require(configYargsPath)(yargs);
// It is important that this is done after the webpack yargs config,
// so it overrides webpack's version info.
yargs.version(getVersions());
yargs.options(options);
const argv = yargs.argv;
// webpack-cli@3.3 path : 'webpack-cli/bin/utils/convert-argv'
let convertArgvPath;
try {
require.resolve('webpack-cli/bin/utils/convert-argv');
convertArgvPath = 'webpack-cli/bin/utils/convert-argv';
} catch (e) {
convertArgvPath = 'webpack-cli/bin/convert-argv';
}
// eslint-disable-next-line import/no-extraneous-dependencies
// eslint-disable-next-line import/no-dynamic-require
const config = require(convertArgvPath)(yargs, argv, {
outputFilename: '/bundle.js',
});
function startDevServer(config, options) {
const log = createLogger(options);
let compiler;
try {
compiler = webpack(config);
} catch (err) {
if (err instanceof webpack.WebpackOptionsValidationError) {
log.error(colors.error(options.stats.colors, err.message));
// eslint-disable-next-line no-process-exit
process.exit(1);
}
throw err;
}
try {
server = new Server(compiler, options, log);
serverData.server = server;
} catch (err) {
if (err.name === 'ValidationError') {
log.error(colors.error(options.stats.colors, err.message));
// eslint-disable-next-line no-process-exit
process.exit(1);
}
throw err;
}
if (options.socket) {
server.listeningApp.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
const clientSocket = new net.Socket();
clientSocket.on('error', (err) => {
if (err.code === 'ECONNREFUSED') {
// No other server listening on this socket so it can be safely removed
fs.unlinkSync(options.socket);
server.listen(options.socket, options.host, (error) => {
if (error) {
throw error;
}
});
}
});
clientSocket.connect({ path: options.socket }, () => {
throw new Error('This socket is already used');
});
}
});
server.listen(options.socket, options.host, (err) => {
if (err) {
throw err;
}
// chmod 666 (rw rw rw)
const READ_WRITE = 438;
fs.chmod(options.socket, READ_WRITE, (err) => {
if (err) {
throw err;
}
});
});
} else {
server.listen(options.port, options.host, (err) => {
if (err) {
throw err;
}
});
}
}
processOptions(config, argv, (config, options) => {
startDevServer(config, options);
});
+27
View File
@@ -0,0 +1,27 @@
'use strict';
/* eslint-disable
no-unused-vars
*/
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
module.exports =
/*#__PURE__*/
function () {
function BaseClient() {
_classCallCheck(this, BaseClient);
}
_createClass(BaseClient, null, [{
key: "getClientPath",
value: function getClientPath(options) {
throw new Error('Client needs implementation');
}
}]);
return BaseClient;
}();
+74
View File
@@ -0,0 +1,74 @@
'use strict';
/* eslint-disable
no-unused-vars
*/
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var SockJS = require('sockjs-client/dist/sockjs');
var BaseClient = require('./BaseClient');
module.exports =
/*#__PURE__*/
function (_BaseClient) {
_inherits(SockJSClient, _BaseClient);
function SockJSClient(url) {
var _this;
_classCallCheck(this, SockJSClient);
_this = _possibleConstructorReturn(this, _getPrototypeOf(SockJSClient).call(this));
_this.sock = new SockJS(url);
_this.sock.onerror = function (err) {// TODO: use logger to log the error event once client and client-src
// are reorganized to have the same directory structure
};
return _this;
}
_createClass(SockJSClient, [{
key: "onOpen",
value: function onOpen(f) {
this.sock.onopen = f;
}
}, {
key: "onClose",
value: function onClose(f) {
this.sock.onclose = f;
} // call f with the message string as the first argument
}, {
key: "onMessage",
value: function onMessage(f) {
this.sock.onmessage = function (e) {
f(e.data);
};
}
}], [{
key: "getClientPath",
value: function getClientPath(options) {
return require.resolve('./SockJSClient');
}
}]);
return SockJSClient;
}(BaseClient);
+74
View File
@@ -0,0 +1,74 @@
'use strict';
/* global WebSocket */
/* eslint-disable
no-unused-vars
*/
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var BaseClient = require('./BaseClient');
module.exports =
/*#__PURE__*/
function (_BaseClient) {
_inherits(WebsocketClient, _BaseClient);
function WebsocketClient(url) {
var _this;
_classCallCheck(this, WebsocketClient);
_this = _possibleConstructorReturn(this, _getPrototypeOf(WebsocketClient).call(this));
_this.client = new WebSocket(url.replace(/^http/, 'ws'));
_this.client.onerror = function (err) {// TODO: use logger to log the error event once client and client-src
// are reorganized to have the same directory structure
};
return _this;
}
_createClass(WebsocketClient, [{
key: "onOpen",
value: function onOpen(f) {
this.client.onopen = f;
}
}, {
key: "onClose",
value: function onClose(f) {
this.client.onclose = f;
} // call f with the message string as the first argument
}, {
key: "onMessage",
value: function onMessage(f) {
this.client.onmessage = function (e) {
f(e.data);
};
}
}], [{
key: "getClientPath",
value: function getClientPath(options) {
return require.resolve('./WebsocketClient');
}
}]);
return WebsocketClient;
}(BaseClient);
File diff suppressed because one or more lines are too long
+176
View File
@@ -0,0 +1,176 @@
'use strict';
/* global __resourceQuery WorkerGlobalScope self */
/* eslint prefer-destructuring: off */
var stripAnsi = require('strip-ansi');
var socket = require('./socket');
var overlay = require('./overlay');
var _require = require('./utils/log'),
log = _require.log,
setLogLevel = _require.setLogLevel;
var sendMessage = require('./utils/sendMessage');
var reloadApp = require('./utils/reloadApp');
var createSocketUrl = require('./utils/createSocketUrl');
var status = {
isUnloading: false,
currentHash: ''
};
var options = {
hot: false,
hotReload: true,
liveReload: false,
initial: true,
useWarningOverlay: false,
useErrorOverlay: false,
useProgress: false
};
var socketUrl = createSocketUrl(__resourceQuery);
self.addEventListener('beforeunload', function () {
status.isUnloading = true;
});
if (typeof window !== 'undefined') {
var qs = window.location.search.toLowerCase();
options.hotReload = qs.indexOf('hotreload=false') === -1;
}
var onSocketMessage = {
hot: function hot() {
options.hot = true;
log.info('[WDS] Hot Module Replacement enabled.');
},
liveReload: function liveReload() {
options.liveReload = true;
log.info('[WDS] Live Reloading enabled.');
},
invalid: function invalid() {
log.info('[WDS] App updated. Recompiling...'); // fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
if (options.useWarningOverlay || options.useErrorOverlay) {
overlay.clear();
}
sendMessage('Invalid');
},
hash: function hash(_hash) {
status.currentHash = _hash;
},
'still-ok': function stillOk() {
log.info('[WDS] Nothing changed.');
if (options.useWarningOverlay || options.useErrorOverlay) {
overlay.clear();
}
sendMessage('StillOk');
},
'log-level': function logLevel(level) {
var hotCtx = require.context('webpack/hot', false, /^\.\/log$/);
if (hotCtx.keys().indexOf('./log') !== -1) {
hotCtx('./log').setLogLevel(level);
}
setLogLevel(level);
},
overlay: function overlay(value) {
if (typeof document !== 'undefined') {
if (typeof value === 'boolean') {
options.useWarningOverlay = false;
options.useErrorOverlay = value;
} else if (value) {
options.useWarningOverlay = value.warnings;
options.useErrorOverlay = value.errors;
}
}
},
progress: function progress(_progress) {
if (typeof document !== 'undefined') {
options.useProgress = _progress;
}
},
'progress-update': function progressUpdate(data) {
if (options.useProgress) {
log.info("[WDS] ".concat(data.percent, "% - ").concat(data.msg, "."));
}
sendMessage('Progress', data);
},
ok: function ok() {
sendMessage('Ok');
if (options.useWarningOverlay || options.useErrorOverlay) {
overlay.clear();
}
if (options.initial) {
return options.initial = false;
} // eslint-disable-line no-return-assign
reloadApp(options, status);
},
'content-changed': function contentChanged() {
log.info('[WDS] Content base changed. Reloading...');
self.location.reload();
},
warnings: function warnings(_warnings) {
log.warn('[WDS] Warnings while compiling.');
var strippedWarnings = _warnings.map(function (warning) {
return stripAnsi(warning);
});
sendMessage('Warnings', strippedWarnings);
for (var i = 0; i < strippedWarnings.length; i++) {
log.warn(strippedWarnings[i]);
}
if (options.useWarningOverlay) {
overlay.showMessage(_warnings);
}
if (options.initial) {
return options.initial = false;
} // eslint-disable-line no-return-assign
reloadApp(options, status);
},
errors: function errors(_errors) {
log.error('[WDS] Errors while compiling. Reload prevented.');
var strippedErrors = _errors.map(function (error) {
return stripAnsi(error);
});
sendMessage('Errors', strippedErrors);
for (var i = 0; i < strippedErrors.length; i++) {
log.error(strippedErrors[i]);
}
if (options.useErrorOverlay) {
overlay.showMessage(_errors);
}
options.initial = false;
},
error: function error(_error) {
log.error(_error);
},
close: function close() {
log.error('[WDS] Disconnected!');
sendMessage('Close');
}
};
socket(socketUrl, onSocketMessage);
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/><script type="text/javascript" charset="utf-8" src="/__webpack_dev_server__/live.bundle.js"></script></head><body></body></html>
+120
View File
@@ -0,0 +1,120 @@
'use strict'; // The error overlay is inspired (and mostly copied) from Create React App (https://github.com/facebookincubator/create-react-app)
// They, in turn, got inspired by webpack-hot-middleware (https://github.com/glenjamin/webpack-hot-middleware).
var ansiHTML = require('ansi-html');
var _require = require('html-entities'),
AllHtmlEntities = _require.AllHtmlEntities;
var entities = new AllHtmlEntities();
var colors = {
reset: ['transparent', 'transparent'],
black: '181818',
red: 'E36049',
green: 'B3CB74',
yellow: 'FFD080',
blue: '7CAFC2',
magenta: '7FACCA',
cyan: 'C3C2EF',
lightgrey: 'EBE7E3',
darkgrey: '6D7891'
};
var overlayIframe = null;
var overlayDiv = null;
var lastOnOverlayDivReady = null;
ansiHTML.setColors(colors);
function createOverlayIframe(onIframeLoad) {
var iframe = document.createElement('iframe');
iframe.id = 'webpack-dev-server-client-overlay';
iframe.src = 'about:blank';
iframe.style.position = 'fixed';
iframe.style.left = 0;
iframe.style.top = 0;
iframe.style.right = 0;
iframe.style.bottom = 0;
iframe.style.width = '100vw';
iframe.style.height = '100vh';
iframe.style.border = 'none';
iframe.style.zIndex = 9999999999;
iframe.onload = onIframeLoad;
return iframe;
}
function addOverlayDivTo(iframe) {
var div = iframe.contentDocument.createElement('div');
div.id = 'webpack-dev-server-client-overlay-div';
div.style.position = 'fixed';
div.style.boxSizing = 'border-box';
div.style.left = 0;
div.style.top = 0;
div.style.right = 0;
div.style.bottom = 0;
div.style.width = '100vw';
div.style.height = '100vh';
div.style.backgroundColor = 'rgba(0, 0, 0, 0.85)';
div.style.color = '#E8E8E8';
div.style.fontFamily = 'Menlo, Consolas, monospace';
div.style.fontSize = 'large';
div.style.padding = '2rem';
div.style.lineHeight = '1.2';
div.style.whiteSpace = 'pre-wrap';
div.style.overflow = 'auto';
iframe.contentDocument.body.appendChild(div);
return div;
}
function ensureOverlayDivExists(onOverlayDivReady) {
if (overlayDiv) {
// Everything is ready, call the callback right away.
onOverlayDivReady(overlayDiv);
return;
} // Creating an iframe may be asynchronous so we'll schedule the callback.
// In case of multiple calls, last callback wins.
lastOnOverlayDivReady = onOverlayDivReady;
if (overlayIframe) {
// We've already created it.
return;
} // Create iframe and, when it is ready, a div inside it.
overlayIframe = createOverlayIframe(function () {
overlayDiv = addOverlayDivTo(overlayIframe); // Now we can talk!
lastOnOverlayDivReady(overlayDiv);
}); // Zalgo alert: onIframeLoad() will be called either synchronously
// or asynchronously depending on the browser.
// We delay adding it so `overlayIframe` is set when `onIframeLoad` fires.
document.body.appendChild(overlayIframe);
} // Successful compilation.
function clear() {
if (!overlayDiv) {
// It is not there in the first place.
return;
} // Clean up and reset internal state.
document.body.removeChild(overlayIframe);
overlayDiv = null;
overlayIframe = null;
lastOnOverlayDivReady = null;
} // Compilation with errors (e.g. syntax error or missing modules).
function showMessage(messages) {
ensureOverlayDivExists(function (div) {
// Make it look similar to our terminal.
div.innerHTML = "<span style=\"color: #".concat(colors.red, "\">Failed to compile.</span><br><br>").concat(ansiHTML(entities.encode(messages[0])));
});
}
module.exports = {
clear: clear,
showMessage: showMessage
};
+52
View File
@@ -0,0 +1,52 @@
'use strict';
/* global __webpack_dev_server_client__ */
/* eslint-disable
camelcase
*/
// this SockJSClient is here as a default fallback, in case inline mode
// is off or the client is not injected. This will be switched to
// WebsocketClient when it becomes the default
// important: the path to SockJSClient here is made to work in the 'client'
// directory, but is updated via the webpack compilation when compiled from
// the 'client-src' directory
var Client = typeof __webpack_dev_server_client__ !== 'undefined' ? __webpack_dev_server_client__ : // eslint-disable-next-line import/no-unresolved
require('./clients/SockJSClient');
var retries = 0;
var client = null;
var socket = function initSocket(url, handlers) {
client = new Client(url);
client.onOpen(function () {
retries = 0;
});
client.onClose(function () {
if (retries === 0) {
handlers.close();
} // Try to reconnect.
client = null; // After 10 retries stop trying, to prevent logspam.
if (retries <= 10) {
// Exponentially increase timeout to reconnect.
// Respectfully copied from the package `got`.
// eslint-disable-next-line no-mixed-operators, no-restricted-properties
var retryInMs = 1000 * Math.pow(2, retries) + Math.random() * 100;
retries += 1;
setTimeout(function () {
socket(url, handlers);
}, retryInMs);
}
});
client.onMessage(function (data) {
var msg = JSON.parse(data);
if (handlers[msg.type]) {
handlers[msg.type](msg.data);
}
});
};
module.exports = socket;
File diff suppressed because one or more lines are too long
+86
View File
@@ -0,0 +1,86 @@
'use strict';
/* global self */
var url = require('url');
var querystring = require('querystring');
var getCurrentScriptSource = require('./getCurrentScriptSource');
function createSocketUrl(resourceQuery) {
var urlParts;
if (typeof resourceQuery === 'string' && resourceQuery !== '') {
// If this bundle is inlined, use the resource query to get the correct url.
urlParts = url.parse(resourceQuery.substr(1));
} else {
// Else, get the url from the <script> this file was called with.
var scriptHost = getCurrentScriptSource();
if (scriptHost) {
// eslint-disable-next-line no-useless-escape
scriptHost = scriptHost.replace(/\/[^\/]+$/, '');
}
urlParts = url.parse(scriptHost || '/', false, true);
}
if (!urlParts.port || urlParts.port === '0') {
urlParts.port = self.location.port;
}
var _urlParts = urlParts,
auth = _urlParts.auth,
path = _urlParts.path;
var _urlParts2 = urlParts,
hostname = _urlParts2.hostname,
protocol = _urlParts2.protocol; // check ipv4 and ipv6 `all hostname`
// why do we need this check?
// hostname n/a for file protocol (example, when using electron, ionic)
// see: https://github.com/webpack/webpack-dev-server/pull/384
var isAnyHostname = (hostname === '0.0.0.0' || hostname === '::') && self.location.hostname && // eslint-disable-next-line no-bitwise
!!~self.location.protocol.indexOf('http');
if (isAnyHostname) {
hostname = self.location.hostname;
} // `hostname` can be empty when the script path is relative. In that case, specifying
// a protocol would result in an invalid URL.
// When https is used in the app, secure websockets are always necessary
// because the browser doesn't accept non-secure websockets.
if (hostname && (self.location.protocol === 'https:' || urlParts.hostname === '0.0.0.0')) {
protocol = self.location.protocol;
} // default values of the sock url if they are not provided
var sockHost = hostname;
var sockPath = '/sockjs-node';
var sockPort = urlParts.port; // eslint-disable-next-line no-undefined
var shouldParsePath = path !== null && path !== undefined && path !== '/';
if (shouldParsePath) {
var parsedQuery = querystring.parse(path); // all of these sock url params are optionally passed in through
// resourceQuery, so we need to fall back to the default if
// they are not provided
sockHost = parsedQuery.sockHost || sockHost;
sockPath = parsedQuery.sockPath || sockPath;
sockPort = parsedQuery.sockPort || sockPort;
}
return url.format({
protocol: protocol,
auth: auth,
hostname: sockHost,
port: sockPort,
// If sockPath is provided it'll be passed in via the resourceQuery as a
// query param so it has to be parsed out of the querystring in order for the
// client to open the socket to the correct location.
pathname: sockPath
});
}
module.exports = createSocketUrl;
+22
View File
@@ -0,0 +1,22 @@
'use strict';
function getCurrentScriptSource() {
// `document.currentScript` is the most accurate way to find the current script,
// but is not supported in all browsers.
if (document.currentScript) {
return document.currentScript.getAttribute('src');
} // Fall back to getting all scripts in the document.
var scriptElements = document.scripts || [];
var currentScript = scriptElements[scriptElements.length - 1];
if (currentScript) {
return currentScript.getAttribute('src');
} // Fail as there was no script to use.
throw new Error('[WDS] Failed to get current script source.');
}
module.exports = getCurrentScriptSource;
+49
View File
@@ -0,0 +1,49 @@
'use strict';
var log = require('loglevel').getLogger('webpack-dev-server');
var INFO = 'info';
var WARN = 'warn';
var ERROR = 'error';
var DEBUG = 'debug';
var TRACE = 'trace';
var SILENT = 'silent'; // deprecated
// TODO: remove these at major released
// https://github.com/webpack/webpack-dev-server/pull/1825
var WARNING = 'warning';
var NONE = 'none'; // Set the default log level
log.setDefaultLevel(INFO);
function setLogLevel(level) {
switch (level) {
case INFO:
case WARN:
case ERROR:
case DEBUG:
case TRACE:
log.setLevel(level);
break;
// deprecated
case WARNING:
// loglevel's warning name is different from webpack's
log.setLevel('warn');
break;
// deprecated
case NONE:
case SILENT:
log.disableAll();
break;
default:
log.error("[WDS] Unknown clientLogLevel '".concat(level, "'"));
}
}
module.exports = {
log: log,
setLogLevel: setLogLevel
};
+55
View File
@@ -0,0 +1,55 @@
'use strict';
/* global WorkerGlobalScope self */
var _require = require('./log'),
log = _require.log;
function reloadApp(_ref, _ref2) {
var hotReload = _ref.hotReload,
hot = _ref.hot,
liveReload = _ref.liveReload;
var isUnloading = _ref2.isUnloading,
currentHash = _ref2.currentHash;
if (isUnloading || !hotReload) {
return;
}
if (hot) {
log.info('[WDS] App hot update...');
var hotEmitter = require('webpack/hot/emitter');
hotEmitter.emit('webpackHotUpdate', currentHash);
if (typeof self !== 'undefined' && self.window) {
// broadcast update to window
self.postMessage("webpackHotUpdate".concat(currentHash), '*');
}
} // allow refreshing the page only if liveReload isn't disabled
else if (liveReload) {
var rootWindow = self; // use parent window for reload (in case we're in an iframe with no valid src)
var intervalId = self.setInterval(function () {
if (rootWindow.location.protocol !== 'about:') {
// reload immediately if protocol is valid
applyReload(rootWindow, intervalId);
} else {
rootWindow = rootWindow.parent;
if (rootWindow.parent === rootWindow) {
// if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
applyReload(rootWindow, intervalId);
}
}
});
}
function applyReload(rootWindow, intervalId) {
clearInterval(intervalId);
log.info('[WDS] App updated. Reloading...');
rootWindow.location.reload();
}
}
module.exports = reloadApp;
+14
View File
@@ -0,0 +1,14 @@
'use strict';
/* global __resourceQuery WorkerGlobalScope self */
// Send messages to the outside, so plugins can consume it.
function sendMsg(type, data) {
if (typeof self !== 'undefined' && (typeof WorkerGlobalScope === 'undefined' || !(self instanceof WorkerGlobalScope))) {
self.postMessage({
type: "webpack".concat(type),
data: data
}, '*');
}
}
module.exports = sendMsg;
+998
View File
@@ -0,0 +1,998 @@
'use strict';
/* eslint-disable
no-shadow,
no-undefined,
func-names
*/
const fs = require('fs');
const path = require('path');
const tls = require('tls');
const url = require('url');
const http = require('http');
const https = require('https');
const ip = require('ip');
const semver = require('semver');
const killable = require('killable');
const chokidar = require('chokidar');
const express = require('express');
const httpProxyMiddleware = require('http-proxy-middleware');
const historyApiFallback = require('connect-history-api-fallback');
const compress = require('compression');
const serveIndex = require('serve-index');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const validateOptions = require('schema-utils');
const isAbsoluteUrl = require('is-absolute-url');
const normalizeOptions = require('./utils/normalizeOptions');
const updateCompiler = require('./utils/updateCompiler');
const createLogger = require('./utils/createLogger');
const getCertificate = require('./utils/getCertificate');
const status = require('./utils/status');
const createDomain = require('./utils/createDomain');
const runBonjour = require('./utils/runBonjour');
const routes = require('./utils/routes');
const getSocketServerImplementation = require('./utils/getSocketServerImplementation');
const schema = require('./options.json');
// Workaround for node ^8.6.0, ^9.0.0
// DEFAULT_ECDH_CURVE is default to prime256v1 in these version
// breaking connection when certificate is not signed with prime256v1
// change it to auto allows OpenSSL to select the curve automatically
// See https://github.com/nodejs/node/issues/16196 for more information
if (semver.satisfies(process.version, '8.6.0 - 9')) {
tls.DEFAULT_ECDH_CURVE = 'auto';
}
if (!process.env.WEBPACK_DEV_SERVER) {
process.env.WEBPACK_DEV_SERVER = true;
}
class Server {
constructor(compiler, options = {}, _log) {
if (options.lazy && !options.filename) {
throw new Error("'filename' option must be set in lazy mode.");
}
validateOptions(schema, options, 'webpack Dev Server');
this.compiler = compiler;
this.options = options;
this.log = _log || createLogger(options);
if (this.options.transportMode !== undefined) {
this.log.warn(
'transportMode is an experimental option, meaning its usage could potentially change without warning'
);
}
normalizeOptions(this.compiler, this.options);
updateCompiler(this.compiler, this.options);
// this.SocketServerImplementation is a class, so it must be instantiated before use
this.socketServerImplementation = getSocketServerImplementation(
this.options
);
this.originalStats =
this.options.stats && Object.keys(this.options.stats).length
? this.options.stats
: {};
this.sockets = [];
this.contentBaseWatchers = [];
// TODO this.<property> is deprecated (remove them in next major release.) in favor this.options.<property>
this.hot = this.options.hot || this.options.hotOnly;
this.headers = this.options.headers;
this.progress = this.options.progress;
this.serveIndex = this.options.serveIndex;
this.clientOverlay = this.options.overlay;
this.clientLogLevel = this.options.clientLogLevel;
this.publicHost = this.options.public;
this.allowedHosts = this.options.allowedHosts;
this.disableHostCheck = !!this.options.disableHostCheck;
this.watchOptions = options.watchOptions || {};
// Replace leading and trailing slashes to normalize path
this.sockPath = `/${
this.options.sockPath
? this.options.sockPath.replace(/^\/|\/$/g, '')
: 'sockjs-node'
}`;
if (this.progress) {
this.setupProgressPlugin();
}
this.setupHooks();
this.setupApp();
this.setupCheckHostRoute();
this.setupDevMiddleware();
// set express routes
routes(this.app, this.middleware, this.options);
// Keep track of websocket proxies for external websocket upgrade.
this.websocketProxies = [];
this.setupFeatures();
this.setupHttps();
this.createServer();
killable(this.listeningApp);
// Proxy websockets without the initial http request
// https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
this.websocketProxies.forEach(function(wsProxy) {
this.listeningApp.on('upgrade', wsProxy.upgrade);
}, this);
}
setupProgressPlugin() {
// for CLI output
new webpack.ProgressPlugin({
profile: !!this.options.profile,
}).apply(this.compiler);
// for browser console output
new webpack.ProgressPlugin((percent, msg, addInfo) => {
percent = Math.floor(percent * 100);
if (percent === 100) {
msg = 'Compilation completed';
}
if (addInfo) {
msg = `${msg} (${addInfo})`;
}
this.sockWrite(this.sockets, 'progress-update', { percent, msg });
}).apply(this.compiler);
}
setupApp() {
// Init express server
// eslint-disable-next-line new-cap
this.app = new express();
}
setupHooks() {
// Listening for events
const invalidPlugin = () => {
this.sockWrite(this.sockets, 'invalid');
};
const addHooks = (compiler) => {
const { compile, invalid, done } = compiler.hooks;
compile.tap('webpack-dev-server', invalidPlugin);
invalid.tap('webpack-dev-server', invalidPlugin);
done.tap('webpack-dev-server', (stats) => {
this._sendStats(this.sockets, this.getStats(stats));
this._stats = stats;
});
};
if (this.compiler.compilers) {
this.compiler.compilers.forEach(addHooks);
} else {
addHooks(this.compiler);
}
}
setupCheckHostRoute() {
this.app.all('*', (req, res, next) => {
if (this.checkHost(req.headers)) {
return next();
}
res.send('Invalid Host header');
});
}
setupDevMiddleware() {
// middleware for serving webpack bundle
this.middleware = webpackDevMiddleware(
this.compiler,
Object.assign({}, this.options, { logLevel: this.log.options.level })
);
}
setupCompressFeature() {
this.app.use(compress());
}
setupProxyFeature() {
/**
* Assume a proxy configuration specified as:
* proxy: {
* 'context': { options }
* }
* OR
* proxy: {
* 'context': 'target'
* }
*/
if (!Array.isArray(this.options.proxy)) {
if (Object.prototype.hasOwnProperty.call(this.options.proxy, 'target')) {
this.options.proxy = [this.options.proxy];
} else {
this.options.proxy = Object.keys(this.options.proxy).map((context) => {
let proxyOptions;
// For backwards compatibility reasons.
const correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');
if (typeof this.options.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: this.options.proxy[context],
};
} else {
proxyOptions = Object.assign({}, this.options.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions;
});
}
}
const getProxyMiddleware = (proxyConfig) => {
const context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return httpProxyMiddleware(context, proxyConfig);
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
this.options.proxy.forEach((proxyConfigOrCallback) => {
let proxyMiddleware;
let proxyConfig =
typeof proxyConfigOrCallback === 'function'
? proxyConfigOrCallback()
: proxyConfigOrCallback;
proxyMiddleware = getProxyMiddleware(proxyConfig);
if (proxyConfig.ws) {
this.websocketProxies.push(proxyMiddleware);
}
this.app.use((req, res, next) => {
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();
if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
const isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
const bypassUrl = isByPassFuncDefined
? proxyConfig.bypass(req, res, proxyConfig)
: null;
if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
});
});
}
setupHistoryApiFallbackFeature() {
const fallback =
typeof this.options.historyApiFallback === 'object'
? this.options.historyApiFallback
: null;
// Fall back to /index.html if nothing else matches.
this.app.use(historyApiFallback(fallback));
}
setupStaticFeature() {
const contentBase = this.options.contentBase;
if (Array.isArray(contentBase)) {
contentBase.forEach((item) => {
this.app.get('*', express.static(item));
});
} else if (isAbsoluteUrl(String(contentBase))) {
this.log.warn(
'Using a URL as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'
);
this.log.warn(
'proxy: {\n\t"*": "<your current contentBase configuration>"\n}'
);
// Redirect every request to contentBase
this.app.get('*', (req, res) => {
res.writeHead(302, {
Location: contentBase + req.path + (req._parsedUrl.search || ''),
});
res.end();
});
} else if (typeof contentBase === 'number') {
this.log.warn(
'Using a number as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'
);
this.log.warn(
'proxy: {\n\t"*": "//localhost:<your current contentBase configuration>"\n}'
);
// Redirect every request to the port contentBase
this.app.get('*', (req, res) => {
res.writeHead(302, {
Location: `//localhost:${contentBase}${req.path}${req._parsedUrl
.search || ''}`,
});
res.end();
});
} else {
// route content request
this.app.get(
'*',
express.static(contentBase, this.options.staticOptions)
);
}
}
setupServeIndexFeature() {
const contentBase = this.options.contentBase;
if (Array.isArray(contentBase)) {
contentBase.forEach((item) => {
this.app.get('*', serveIndex(item));
});
} else if (
typeof contentBase !== 'number' &&
!isAbsoluteUrl(String(contentBase))
) {
this.app.get('*', serveIndex(contentBase));
}
}
setupWatchStaticFeature() {
const contentBase = this.options.contentBase;
if (isAbsoluteUrl(String(contentBase)) || typeof contentBase === 'number') {
throw new Error('Watching remote files is not supported.');
} else if (Array.isArray(contentBase)) {
contentBase.forEach((item) => {
if (isAbsoluteUrl(String(item)) || typeof item === 'number') {
throw new Error('Watching remote files is not supported.');
}
this._watch(item);
});
} else {
this._watch(contentBase);
}
}
setupBeforeFeature() {
// Todo rename onBeforeSetupMiddleware in next major release
// Todo pass only `this` argument
this.options.before(this.app, this, this.compiler);
}
setupMiddleware() {
this.app.use(this.middleware);
}
setupAfterFeature() {
// Todo rename onAfterSetupMiddleware in next major release
// Todo pass only `this` argument
this.options.after(this.app, this, this.compiler);
}
setupHeadersFeature() {
this.app.all('*', this.setContentHeaders.bind(this));
}
setupMagicHtmlFeature() {
this.app.get('*', this.serveMagicHtml.bind(this));
}
setupSetupFeature() {
this.log.warn(
'The `setup` option is deprecated and will be removed in v4. Please update your config to use `before`'
);
this.options.setup(this.app, this);
}
setupFeatures() {
const features = {
compress: () => {
if (this.options.compress) {
this.setupCompressFeature();
}
},
proxy: () => {
if (this.options.proxy) {
this.setupProxyFeature();
}
},
historyApiFallback: () => {
if (this.options.historyApiFallback) {
this.setupHistoryApiFallbackFeature();
}
},
// Todo rename to `static` in future major release
contentBaseFiles: () => {
this.setupStaticFeature();
},
// Todo rename to `serveIndex` in future major release
contentBaseIndex: () => {
this.setupServeIndexFeature();
},
// Todo rename to `watchStatic` in future major release
watchContentBase: () => {
this.setupWatchStaticFeature();
},
before: () => {
if (typeof this.options.before === 'function') {
this.setupBeforeFeature();
}
},
middleware: () => {
// include our middleware to ensure
// it is able to handle '/index.html' request after redirect
this.setupMiddleware();
},
after: () => {
if (typeof this.options.after === 'function') {
this.setupAfterFeature();
}
},
headers: () => {
this.setupHeadersFeature();
},
magicHtml: () => {
this.setupMagicHtmlFeature();
},
setup: () => {
if (typeof this.options.setup === 'function') {
this.setupSetupFeature();
}
},
};
const runnableFeatures = [];
// compress is placed last and uses unshift so that it will be the first middleware used
if (this.options.compress) {
runnableFeatures.push('compress');
}
runnableFeatures.push('setup', 'before', 'headers', 'middleware');
if (this.options.proxy) {
runnableFeatures.push('proxy', 'middleware');
}
if (this.options.contentBase !== false) {
runnableFeatures.push('contentBaseFiles');
}
if (this.options.historyApiFallback) {
runnableFeatures.push('historyApiFallback', 'middleware');
if (this.options.contentBase !== false) {
runnableFeatures.push('contentBaseFiles');
}
}
// checking if it's set to true or not set (Default : undefined => true)
this.serveIndex = this.serveIndex || this.serveIndex === undefined;
if (this.options.contentBase && this.serveIndex) {
runnableFeatures.push('contentBaseIndex');
}
if (this.options.watchContentBase) {
runnableFeatures.push('watchContentBase');
}
runnableFeatures.push('magicHtml');
if (this.options.after) {
runnableFeatures.push('after');
}
(this.options.features || runnableFeatures).forEach((feature) => {
features[feature]();
});
}
setupHttps() {
// if the user enables http2, we can safely enable https
if (this.options.http2 && !this.options.https) {
this.options.https = true;
}
if (this.options.https) {
// for keep supporting CLI parameters
if (typeof this.options.https === 'boolean') {
this.options.https = {
ca: this.options.ca,
pfx: this.options.pfx,
key: this.options.key,
cert: this.options.cert,
passphrase: this.options.pfxPassphrase,
requestCert: this.options.requestCert || false,
};
}
for (const property of ['ca', 'pfx', 'key', 'cert']) {
const value = this.options.https[property];
const isBuffer = value instanceof Buffer;
if (value && !isBuffer) {
let stats = null;
try {
stats = fs.lstatSync(fs.realpathSync(value)).isFile();
} catch (error) {
// ignore error
}
// It is file
this.options.https[property] = stats
? fs.readFileSync(path.resolve(value))
: value;
}
}
let fakeCert;
if (!this.options.https.key || !this.options.https.cert) {
fakeCert = getCertificate(this.log);
}
this.options.https.key = this.options.https.key || fakeCert;
this.options.https.cert = this.options.https.cert || fakeCert;
// note that options.spdy never existed. The user was able
// to set options.https.spdy before, though it was not in the
// docs. Keep options.https.spdy if the user sets it for
// backwards compatibility, but log a deprecation warning.
if (this.options.https.spdy) {
// for backwards compatibility: if options.https.spdy was passed in before,
// it was not altered in any way
this.log.warn(
'Providing custom spdy server options is deprecated and will be removed in the next major version.'
);
} else {
// if the normal https server gets this option, it will not affect it.
this.options.https.spdy = {
protocols: ['h2', 'http/1.1'],
};
}
}
}
createServer() {
if (this.options.https) {
// Only prevent HTTP/2 if http2 is explicitly set to false
const isHttp2 = this.options.http2 !== false;
// `spdy` is effectively unmaintained, and as a consequence of an
// implementation that extensively relies on Nodes non-public APIs, broken
// on Node 10 and above. In those cases, only https will be used for now.
// Once express supports Node's built-in HTTP/2 support, migrating over to
// that should be the best way to go.
// The relevant issues are:
// - https://github.com/nodejs/node/issues/21665
// - https://github.com/webpack/webpack-dev-server/issues/1449
// - https://github.com/expressjs/express/issues/3388
if (semver.gte(process.version, '10.0.0') || !isHttp2) {
if (this.options.http2) {
// the user explicitly requested http2 but is not getting it because
// of the node version.
this.log.warn(
'HTTP/2 is currently unsupported for Node 10.0.0 and above, but will be supported once Express supports it'
);
}
this.listeningApp = https.createServer(this.options.https, this.app);
} else {
// The relevant issues are:
// https://github.com/spdy-http2/node-spdy/issues/350
// https://github.com/webpack/webpack-dev-server/issues/1592
this.listeningApp = require('spdy').createServer(
this.options.https,
this.app
);
}
} else {
this.listeningApp = http.createServer(this.app);
}
}
createSocketServer() {
const SocketServerImplementation = this.socketServerImplementation;
this.socketServer = new SocketServerImplementation(this);
this.socketServer.onConnection((connection, headers) => {
if (!connection) {
return;
}
if (!headers) {
this.log.warn(
'transportMode.server implementation must pass headers to the callback of onConnection(f) ' +
'via f(connection, headers) in order for clients to pass a headers security check'
);
}
if (!headers || !this.checkHost(headers) || !this.checkOrigin(headers)) {
this.sockWrite([connection], 'error', 'Invalid Host/Origin header');
this.socketServer.close(connection);
return;
}
this.sockets.push(connection);
this.socketServer.onConnectionClose(connection, () => {
const idx = this.sockets.indexOf(connection);
if (idx >= 0) {
this.sockets.splice(idx, 1);
}
});
if (this.clientLogLevel) {
this.sockWrite([connection], 'log-level', this.clientLogLevel);
}
if (this.hot) {
this.sockWrite([connection], 'hot');
}
// TODO: change condition at major version
if (this.options.liveReload !== false) {
this.sockWrite([connection], 'liveReload', this.options.liveReload);
}
if (this.progress) {
this.sockWrite([connection], 'progress', this.progress);
}
if (this.clientOverlay) {
this.sockWrite([connection], 'overlay', this.clientOverlay);
}
if (!this._stats) {
return;
}
this._sendStats([connection], this.getStats(this._stats), true);
});
}
showStatus() {
const suffix =
this.options.inline !== false || this.options.lazy === true
? '/'
: '/webpack-dev-server/';
const uri = `${createDomain(this.options, this.listeningApp)}${suffix}`;
status(
uri,
this.options,
this.log,
this.options.stats && this.options.stats.colors
);
}
listen(port, hostname, fn) {
this.hostname = hostname;
return this.listeningApp.listen(port, hostname, (err) => {
this.createSocketServer();
if (this.options.bonjour) {
runBonjour(this.options);
}
this.showStatus();
if (fn) {
fn.call(this.listeningApp, err);
}
if (typeof this.options.onListening === 'function') {
this.options.onListening(this);
}
});
}
close(cb) {
this.sockets.forEach((socket) => {
this.socketServer.close(socket);
});
this.sockets = [];
this.contentBaseWatchers.forEach((watcher) => {
watcher.close();
});
this.contentBaseWatchers = [];
this.listeningApp.kill(() => {
this.middleware.close(cb);
});
}
static get DEFAULT_STATS() {
return {
all: false,
hash: true,
assets: true,
warnings: true,
errors: true,
errorDetails: false,
};
}
getStats(statsObj) {
const stats = Server.DEFAULT_STATS;
if (this.originalStats.warningsFilter) {
stats.warningsFilter = this.originalStats.warningsFilter;
}
return statsObj.toJson(stats);
}
use() {
// eslint-disable-next-line
this.app.use.apply(this.app, arguments);
}
setContentHeaders(req, res, next) {
if (this.headers) {
// eslint-disable-next-line
for (const name in this.headers) {
res.setHeader(name, this.headers[name]);
}
}
next();
}
checkHost(headers) {
return this.checkHeaders(headers, 'host');
}
checkOrigin(headers) {
return this.checkHeaders(headers, 'origin');
}
checkHeaders(headers, headerToCheck) {
// allow user to opt-out this security check, at own risk
if (this.disableHostCheck) {
return true;
}
if (!headerToCheck) {
headerToCheck = 'host';
}
// get the Host header and extract hostname
// we don't care about port not matching
const hostHeader = headers[headerToCheck];
if (!hostHeader) {
return false;
}
// use the node url-parser to retrieve the hostname from the host-header.
const hostname = url.parse(
// if hostHeader doesn't have scheme, add // for parsing.
/^(.+:)?\/\//.test(hostHeader) ? hostHeader : `//${hostHeader}`,
false,
true
).hostname;
// always allow requests with explicit IPv4 or IPv6-address.
// A note on IPv6 addresses:
// hostHeader will always contain the brackets denoting
// an IPv6-address in URLs,
// these are removed from the hostname in url.parse(),
// so we have the pure IPv6-address in hostname.
// always allow localhost host, for convenience (hostname === 'localhost')
// allow hostname of listening address (hostname === this.hostname)
const isValidHostname =
ip.isV4Format(hostname) ||
ip.isV6Format(hostname) ||
hostname === 'localhost' ||
hostname === this.hostname;
if (isValidHostname) {
return true;
}
// always allow localhost host, for convenience
// allow if hostname is in allowedHosts
if (this.allowedHosts && this.allowedHosts.length) {
for (let hostIdx = 0; hostIdx < this.allowedHosts.length; hostIdx++) {
const allowedHost = this.allowedHosts[hostIdx];
if (allowedHost === hostname) {
return true;
}
// support "." as a subdomain wildcard
// e.g. ".example.com" will allow "example.com", "www.example.com", "subdomain.example.com", etc
if (allowedHost[0] === '.') {
// "example.com" (hostname === allowedHost.substring(1))
// "*.example.com" (hostname.endsWith(allowedHost))
if (
hostname === allowedHost.substring(1) ||
hostname.endsWith(allowedHost)
) {
return true;
}
}
}
}
// also allow public hostname if provided
if (typeof this.publicHost === 'string') {
const idxPublic = this.publicHost.indexOf(':');
const publicHostname =
idxPublic >= 0 ? this.publicHost.substr(0, idxPublic) : this.publicHost;
if (hostname === publicHostname) {
return true;
}
}
// disallow
return false;
}
// eslint-disable-next-line
sockWrite(sockets, type, data) {
sockets.forEach((socket) => {
this.socketServer.send(socket, JSON.stringify({ type, data }));
});
}
serveMagicHtml(req, res, next) {
const _path = req.path;
try {
const isFile = this.middleware.fileSystem
.statSync(this.middleware.getFilenameFromUrl(`${_path}.js`))
.isFile();
if (!isFile) {
return next();
}
// Serve a page that executes the javascript
const queries = req._parsedUrl.search || '';
const responsePage = `<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body><script type="text/javascript" charset="utf-8" src="${_path}.js${queries}"></script></body></html>`;
res.send(responsePage);
} catch (err) {
return next();
}
}
// send stats to a socket or multiple sockets
_sendStats(sockets, stats, force) {
const shouldEmit =
!force &&
stats &&
(!stats.errors || stats.errors.length === 0) &&
stats.assets &&
stats.assets.every((asset) => !asset.emitted);
if (shouldEmit) {
return this.sockWrite(sockets, 'still-ok');
}
this.sockWrite(sockets, 'hash', stats.hash);
if (stats.errors.length > 0) {
this.sockWrite(sockets, 'errors', stats.errors);
} else if (stats.warnings.length > 0) {
this.sockWrite(sockets, 'warnings', stats.warnings);
} else {
this.sockWrite(sockets, 'ok');
}
}
_watch(watchPath) {
// duplicate the same massaging of options that watchpack performs
// https://github.com/webpack/watchpack/blob/master/lib/DirectoryWatcher.js#L49
// this isn't an elegant solution, but we'll improve it in the future
const usePolling = this.watchOptions.poll ? true : undefined;
const interval =
typeof this.watchOptions.poll === 'number'
? this.watchOptions.poll
: undefined;
const watchOptions = {
ignoreInitial: true,
persistent: true,
followSymlinks: false,
atomic: false,
alwaysStat: true,
ignorePermissionErrors: true,
ignored: this.watchOptions.ignored,
usePolling,
interval,
};
const watcher = chokidar.watch(watchPath, watchOptions);
// disabling refreshing on changing the content
if (this.options.liveReload !== false) {
watcher.on('change', () => {
this.sockWrite(this.sockets, 'content-changed');
});
}
this.contentBaseWatchers.push(watcher);
}
invalidate(callback) {
if (this.middleware) {
this.middleware.invalidate(callback);
}
}
}
// Export this logic,
// so that other implementations,
// like task-runners can use it
Server.addDevServerEntrypoints = require('./utils/addEntries');
module.exports = Server;
+481
View File
@@ -0,0 +1,481 @@
{
"type": "object",
"properties": {
"after": {
"instanceof": "Function"
},
"allowedHosts": {
"type": "array",
"items": {
"type": "string"
}
},
"before": {
"instanceof": "Function"
},
"bonjour": {
"type": "boolean"
},
"ca": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Buffer"
}
]
},
"cert": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Buffer"
}
]
},
"clientLogLevel": {
"enum": [
"info",
"warn",
"error",
"debug",
"trace",
"silent",
"none",
"warning"
]
},
"compress": {
"type": "boolean"
},
"contentBase": {
"anyOf": [
{
"enum": [false]
},
{
"type": "number"
},
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
]
},
"disableHostCheck": {
"type": "boolean"
},
"features": {
"type": "array",
"items": {
"type": "string"
}
},
"filename": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
}
]
},
"fs": {
"type": "object"
},
"headers": {
"type": "object"
},
"historyApiFallback": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "object"
}
]
},
"host": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"hot": {
"type": "boolean"
},
"hotOnly": {
"type": "boolean"
},
"http2": {
"type": "boolean"
},
"https": {
"anyOf": [
{
"type": "object"
},
{
"type": "boolean"
}
]
},
"index": {
"type": "string"
},
"injectClient": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"injectHot": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"inline": {
"type": "boolean"
},
"key": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Buffer"
}
]
},
"lazy": {
"type": "boolean"
},
"liveReload": {
"type": "boolean"
},
"log": {
"instanceof": "Function"
},
"logLevel": {
"enum": ["info", "warn", "error", "debug", "trace", "silent"]
},
"logTime": {
"type": "boolean"
},
"mimeTypes": {
"type": "object"
},
"noInfo": {
"type": "boolean"
},
"onListening": {
"instanceof": "Function"
},
"open": {
"anyOf": [
{
"type": "string"
},
{
"type": "boolean"
}
]
},
"openPage": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
]
},
"overlay": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"properties": {
"errors": {
"type": "boolean"
},
"warnings": {
"type": "boolean"
}
}
}
]
},
"pfx": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Buffer"
}
]
},
"pfxPassphrase": {
"type": "string"
},
"port": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
}
]
},
"profile": {
"type": "boolean"
},
"progress": {
"type": "boolean"
},
"proxy": {
"anyOf": [
{
"type": "object"
},
{
"type": "array",
"items": {
"anyOf": [
{
"type": "object"
},
{
"instanceof": "Function"
}
]
},
"minItems": 1
}
]
},
"public": {
"type": "string"
},
"publicPath": {
"type": "string"
},
"quiet": {
"type": "boolean"
},
"reporter": {
"instanceof": "Function"
},
"requestCert": {
"type": "boolean"
},
"serveIndex": {
"type": "boolean"
},
"serverSideRender": {
"type": "boolean"
},
"setup": {
"instanceof": "Function"
},
"sockHost": {
"type": "string"
},
"sockPath": {
"type": "string"
},
"sockPort": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
}
]
},
"socket": {
"type": "string"
},
"staticOptions": {
"type": "object"
},
"stats": {
"anyOf": [
{
"type": "object"
},
{
"type": "boolean"
},
{
"enum": [
"none",
"errors-only",
"errors-warnings",
"minimal",
"normal",
"verbose"
]
}
]
},
"transportMode": {
"anyOf": [
{
"type": "object",
"properties": {
"client": {
"type": "string"
},
"server": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
}
},
"additionalProperties": false
},
{
"enum": ["sockjs", "ws"]
}
]
},
"useLocalIp": {
"type": "boolean"
},
"warn": {
"instanceof": "Function"
},
"watchContentBase": {
"type": "boolean"
},
"watchOptions": {
"type": "object"
},
"writeToDisk": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
}
},
"errorMessage": {
"properties": {
"after": "should be {Function} (https://webpack.js.org/configuration/dev-server/#devserverafter)",
"allowedHosts": "should be {Array} (https://webpack.js.org/configuration/dev-server/#devserverallowedhosts)",
"before": "should be {Function} (https://webpack.js.org/configuration/dev-server/#devserverbefore)",
"bonjour": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverbonjour)",
"ca": "should be {String|Buffer}",
"cert": "should be {String|Buffer}",
"clientLogLevel": "should be {String} and equal to one of the allowed values\n\n [ 'none', 'silent', 'info', 'debug', 'trace', 'error', 'warning', 'warn' ]\n\n (https://webpack.js.org/configuration/dev-server/#devserverclientloglevel)",
"compress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devservercompress)",
"contentBase": "should be {Number|String|Array} (https://webpack.js.org/configuration/dev-server/#devservercontentbase)",
"disableHostCheck": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverdisablehostcheck)",
"features": "should be {Array}",
"filename": "should be {String|RegExp|Function} (https://webpack.js.org/configuration/dev-server/#devserverfilename-)",
"fs": "should be {Object} (https://github.com/webpack/webpack-dev-middleware#fs)",
"headers": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverheaders-)",
"historyApiFallback": "should be {Boolean|Object} (https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback)",
"host": "should be {String|Null} (https://webpack.js.org/configuration/dev-server/#devserverhost)",
"hot": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverhot)",
"hotOnly": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverhotonly)",
"http2": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverhttp2)",
"https": "should be {Object|Boolean} (https://webpack.js.org/configuration/dev-server/#devserverhttps)",
"index": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverindex)",
"injectClient": "should be {Boolean|Function} (https://webpack.js.org/configuration/dev-server/#devserverinjectclient)",
"injectHot": "should be {Boolean|Function} (https://webpack.js.org/configuration/dev-server/#devserverinjecthot)",
"inline": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverinline)",
"key": "should be {String|Buffer}",
"lazy": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverlazy-)",
"liveReload": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverlivereload-)",
"log": "should be {Function}",
"logLevel": "should be {String} and equal to one of the allowed values\n\n [ 'info', 'warn', 'error', 'debug', 'trace', 'silent' ]\n\n (https://github.com/webpack/webpack-dev-middleware#loglevel)",
"logTime": "should be {Boolean} (https://github.com/webpack/webpack-dev-middleware#logtime)",
"mimeTypes": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devservermimetypes-)",
"noInfo": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devservernoinfo-)",
"onListening": "should be {Function} (https://webpack.js.org/configuration/dev-server/#onlistening)",
"open": "should be {String|Boolean} (https://webpack.js.org/configuration/dev-server/#devserveropen)",
"openPage": "should be {String|Array} (https://webpack.js.org/configuration/dev-server/#devserveropenpage)",
"overlay": "should be {Boolean|Object} (https://webpack.js.org/configuration/dev-server/#devserveroverlay)",
"pfx": "should be {String|Buffer} (https://webpack.js.org/configuration/dev-server/#devserverpfx)",
"pfxPassphrase": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpfxpassphrase)",
"port": "should be {Number|String|Null} (https://webpack.js.org/configuration/dev-server/#devserverport)",
"profile": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprofile)",
"progress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprogress---cli-only)",
"proxy": "should be {Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverproxy)",
"public": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublic)",
"publicPath": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublicpath-)",
"quiet": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverquiet-)",
"reporter": "should be {Function} (https://github.com/webpack/webpack-dev-middleware#reporter)",
"requestCert": "should be {Boolean}",
"serveIndex": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverserveindex)",
"serverSideRender": "should be {Boolean} (https://github.com/webpack/webpack-dev-middleware#serversiderender)",
"setup": "should be {Function} (https://webpack.js.org/configuration/dev-server/#devserversetup)",
"sockHost": "should be {String|Null} (https://webpack.js.org/configuration/dev-server/#devserversockhost)",
"sockPath": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserversockpath)",
"sockPort": "should be {Number|String|Null} (https://webpack.js.org/configuration/dev-server/#devserversockport)",
"socket": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserversocket)",
"staticOptions": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverstaticoptions)",
"stats": "should be {Object|Boolean} (https://webpack.js.org/configuration/dev-server/#devserverstats-)",
"transportMode": "should be {String|Object} (https://webpack.js.org/configuration/dev-server/#devservertransportmode)",
"useLocalIp": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserveruselocalip)",
"warn": "should be {Function}",
"watchContentBase": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverwatchcontentbase)",
"watchOptions": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverwatchoptions-)",
"writeToDisk": "should be {Boolean|Function} (https://webpack.js.org/configuration/dev-server/#devserverwritetodisk-)"
}
},
"additionalProperties": false
}
+9
View File
@@ -0,0 +1,9 @@
'use strict';
// base class that users should extend if they are making their own
// server implementation
module.exports = class BaseServer {
constructor(server) {
this.server = server;
}
};
+74
View File
@@ -0,0 +1,74 @@
'use strict';
/* eslint-disable
class-methods-use-this,
func-names
*/
const sockjs = require('sockjs');
const BaseServer = require('./BaseServer');
// Workaround for sockjs@~0.3.19
// sockjs will remove Origin header, however Origin header is required for checking host.
// See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
{
const SockjsSession = require('sockjs/lib/transport').Session;
const decorateConnection = SockjsSession.prototype.decorateConnection;
SockjsSession.prototype.decorateConnection = function(req) {
decorateConnection.call(this, req);
const connection = this.connection;
if (
connection.headers &&
!('origin' in connection.headers) &&
'origin' in req.headers
) {
connection.headers.origin = req.headers.origin;
}
};
}
module.exports = class SockJSServer extends BaseServer {
// options has: error (function), debug (function), server (http/s server), path (string)
constructor(server) {
super(server);
this.socket = sockjs.createServer({
// Use provided up-to-date sockjs-client
sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js',
// Limit useless logs
log: (severity, line) => {
if (severity === 'error') {
this.server.log.error(line);
} else {
this.server.log.debug(line);
}
},
});
this.socket.installHandlers(this.server.listeningApp, {
prefix: this.server.sockPath,
});
}
send(connection, message) {
// prevent cases where the server is trying to send data while connection is closing
if (connection.readyState !== 1) {
return;
}
connection.write(message);
}
close(connection) {
connection.close();
}
// f should be passed the resulting connection and the connection headers
onConnection(f) {
this.socket.on('connection', (connection) => {
f(connection, connection ? connection.headers : null);
});
}
onConnectionClose(connection, f) {
connection.on('close', f);
}
};
+45
View File
@@ -0,0 +1,45 @@
'use strict';
/* eslint-disable
class-methods-use-this
*/
const ws = require('ws');
const BaseServer = require('./BaseServer');
module.exports = class WebsocketServer extends BaseServer {
constructor(server) {
super(server);
this.wsServer = new ws.Server({
server: this.server.listeningApp,
path: this.server.sockPath,
});
this.wsServer.on('error', (err) => {
this.server.log.error(err.message);
});
}
send(connection, message) {
// prevent cases where the server is trying to send data while connection is closing
if (connection.readyState !== 1) {
return;
}
connection.send(message);
}
close(connection) {
connection.close();
}
// f should be passed the resulting connection and the connection headers
onConnection(f) {
this.wsServer.on('connection', (connection, req) => {
f(connection, req.headers);
});
}
onConnectionClose(connection, f) {
connection.on('close', f);
}
};
+153
View File
@@ -0,0 +1,153 @@
'use strict';
const webpack = require('webpack');
const createDomain = require('./createDomain');
/**
* A Entry, it can be of type string or string[] or Object<string | string[],string>
* @typedef {(string[] | string | Object<string | string[],string>)} Entry
*/
/**
* Add entries Method
* @param {?Object} config - Webpack config
* @param {?Object} options - Dev-Server options
* @param {?Object} server
* @returns {void}
*/
function addEntries(config, options, server) {
if (options.inline !== false) {
// we're stubbing the app in this method as it's static and doesn't require
// a server to be supplied. createDomain requires an app with the
// address() signature.
const app = server || {
address() {
return { port: options.port };
},
};
/** @type {string} */
const domain = createDomain(options, app);
/** @type {string} */
const sockHost = options.sockHost ? `&sockHost=${options.sockHost}` : '';
/** @type {string} */
const sockPath = options.sockPath ? `&sockPath=${options.sockPath}` : '';
/** @type {string} */
const sockPort = options.sockPort ? `&sockPort=${options.sockPort}` : '';
/** @type {string} */
const clientEntry = `${require.resolve(
'../../client/'
)}?${domain}${sockHost}${sockPath}${sockPort}`;
/** @type {(string[] | string)} */
let hotEntry;
if (options.hotOnly) {
hotEntry = require.resolve('webpack/hot/only-dev-server');
} else if (options.hot) {
hotEntry = require.resolve('webpack/hot/dev-server');
}
/**
* prependEntry Method
* @param {Entry} originalEntry
* @param {Entry} additionalEntries
* @returns {Entry}
*/
const prependEntry = (originalEntry, additionalEntries) => {
if (typeof originalEntry === 'function') {
return () =>
Promise.resolve(originalEntry()).then((entry) =>
prependEntry(entry, additionalEntries)
);
}
if (typeof originalEntry === 'object' && !Array.isArray(originalEntry)) {
/** @type {Object<string,string>} */
const clone = {};
Object.keys(originalEntry).forEach((key) => {
// entry[key] should be a string here
clone[key] = prependEntry(originalEntry[key], additionalEntries);
});
return clone;
}
// in this case, entry is a string or an array.
// make sure that we do not add duplicates.
/** @type {Entry} */
const entriesClone = additionalEntries.slice(0);
[].concat(originalEntry).forEach((newEntry) => {
if (!entriesClone.includes(newEntry)) {
entriesClone.push(newEntry);
}
});
return entriesClone;
};
/**
*
* Description of the option for checkInject method
* @typedef {Function} checkInjectOptionsParam
* @param {Object} _config - compilerConfig
* @return {Boolean}
*/
/**
*
* @param {Boolean | checkInjectOptionsParam} option - inject(Hot|Client) it is Boolean | fn => Boolean
* @param {Object} _config
* @param {Boolean} defaultValue
* @return {Boolean}
*/
// eslint-disable-next-line no-shadow
const checkInject = (option, _config, defaultValue) => {
if (typeof option === 'boolean') return option;
if (typeof option === 'function') return option(_config);
return defaultValue;
};
// eslint-disable-next-line no-shadow
[].concat(config).forEach((config) => {
/** @type {Boolean} */
const webTarget = [
'web',
'webworker',
'electron-renderer',
'node-webkit',
undefined, // eslint-disable-line
null,
].includes(config.target);
/** @type {Entry} */
const additionalEntries = checkInject(
options.injectClient,
config,
webTarget
)
? [clientEntry]
: [];
if (hotEntry && checkInject(options.injectHot, config, true)) {
additionalEntries.push(hotEntry);
}
config.entry = prependEntry(config.entry || './src', additionalEntries);
if (options.hot || options.hotOnly) {
config.plugins = config.plugins || [];
if (
!config.plugins.find(
// Check for the name rather than the constructor reference in case
// there are multiple copies of webpack installed
(plugin) => plugin.constructor.name === 'HotModuleReplacementPlugin'
)
) {
config.plugins.push(new webpack.HotModuleReplacementPlugin());
}
}
});
}
}
module.exports = addEntries;
+22
View File
@@ -0,0 +1,22 @@
'use strict';
const colors = {
info(useColor, msg) {
if (useColor) {
// Make text blue and bold, so it *pops*
return `\u001b[1m\u001b[34m${msg}\u001b[39m\u001b[22m`;
}
return msg;
},
error(useColor, msg) {
if (useColor) {
// Make text red and bold, so it *pops*
return `\u001b[1m\u001b[31m${msg}\u001b[39m\u001b[22m`;
}
return msg;
},
};
module.exports = colors;
+69
View File
@@ -0,0 +1,69 @@
'use strict';
const selfsigned = require('selfsigned');
function createCertificate(attributes) {
return selfsigned.generate(attributes, {
algorithm: 'sha256',
days: 30,
keySize: 2048,
extensions: [
{
name: 'basicConstraints',
cA: true,
},
{
name: 'keyUsage',
keyCertSign: true,
digitalSignature: true,
nonRepudiation: true,
keyEncipherment: true,
dataEncipherment: true,
},
{
name: 'extKeyUsage',
serverAuth: true,
clientAuth: true,
codeSigning: true,
timeStamping: true,
},
{
name: 'subjectAltName',
altNames: [
{
// type 2 is DNS
type: 2,
value: 'localhost',
},
{
type: 2,
value: 'localhost.localdomain',
},
{
type: 2,
value: 'lvh.me',
},
{
type: 2,
value: '*.lvh.me',
},
{
type: 2,
value: '[::1]',
},
{
// type 7 is IP
type: 7,
ip: '127.0.0.1',
},
{
type: 7,
ip: 'fe80::1',
},
],
},
],
});
}
module.exports = createCertificate;
+233
View File
@@ -0,0 +1,233 @@
'use strict';
const path = require('path');
const isAbsoluteUrl = require('is-absolute-url');
const defaultTo = require('./defaultTo');
function createConfig(config, argv, { port }) {
const firstWpOpt = Array.isArray(config) ? config[0] : config;
const options = firstWpOpt.devServer || {};
// This updates both config and firstWpOpt
firstWpOpt.mode = defaultTo(firstWpOpt.mode, 'development');
if (argv.bonjour) {
options.bonjour = true;
}
if (argv.host && (argv.host !== 'localhost' || !options.host)) {
options.host = argv.host;
}
if (argv.allowedHosts) {
options.allowedHosts = argv.allowedHosts.split(',');
}
if (argv.public) {
options.public = argv.public;
}
if (argv.socket) {
options.socket = argv.socket;
}
if (argv.sockHost) {
options.sockHost = argv.sockHost;
}
if (argv.sockPath) {
options.sockPath = argv.sockPath;
}
if (argv.sockPort) {
options.sockPort = argv.sockPort;
}
if (argv.liveReload === false) {
options.liveReload = false;
}
if (argv.profile) {
options.profile = argv.profile;
}
if (argv.progress) {
options.progress = argv.progress;
}
if (argv.overlay) {
options.overlay = argv.overlay;
}
if (!options.publicPath) {
// eslint-disable-next-line
options.publicPath =
(firstWpOpt.output && firstWpOpt.output.publicPath) || '';
if (
!isAbsoluteUrl(String(options.publicPath)) &&
options.publicPath[0] !== '/'
) {
options.publicPath = `/${options.publicPath}`;
}
}
if (!options.filename && firstWpOpt.output && firstWpOpt.output.filename) {
options.filename = firstWpOpt.output && firstWpOpt.output.filename;
}
if (!options.watchOptions && firstWpOpt.watchOptions) {
options.watchOptions = firstWpOpt.watchOptions;
}
if (argv.stdin) {
process.stdin.on('end', () => {
// eslint-disable-next-line no-process-exit
process.exit(0);
});
process.stdin.resume();
}
// TODO https://github.com/webpack/webpack-dev-server/issues/616 (v4)
// We should prefer CLI arg under config, now we always prefer `hot` from `devServer`
if (!options.hot) {
options.hot = argv.hot;
}
// TODO https://github.com/webpack/webpack-dev-server/issues/616 (v4)
// We should prefer CLI arg under config, now we always prefer `hotOnly` from `devServer`
if (!options.hotOnly) {
options.hotOnly = argv.hotOnly;
}
// TODO https://github.com/webpack/webpack-dev-server/issues/616 (v4)
// We should prefer CLI arg under config, now we always prefer `clientLogLevel` from `devServer`
if (!options.clientLogLevel && argv.clientLogLevel) {
options.clientLogLevel = argv.clientLogLevel;
}
if (argv.contentBase) {
options.contentBase = argv.contentBase;
if (Array.isArray(options.contentBase)) {
options.contentBase = options.contentBase.map((p) => path.resolve(p));
} else if (/^[0-9]$/.test(options.contentBase)) {
options.contentBase = +options.contentBase;
} else if (!isAbsoluteUrl(String(options.contentBase))) {
options.contentBase = path.resolve(options.contentBase);
}
}
// It is possible to disable the contentBase by using
// `--no-content-base`, which results in arg["content-base"] = false
else if (argv.contentBase === false) {
options.contentBase = false;
}
if (argv.watchContentBase) {
options.watchContentBase = true;
}
if (!options.stats) {
options.stats = defaultTo(firstWpOpt.stats, {
cached: false,
cachedAssets: false,
});
}
if (
typeof options.stats === 'object' &&
typeof options.stats.colors === 'undefined' &&
argv.color
) {
options.stats = Object.assign({}, options.stats, { colors: argv.color });
}
if (argv.lazy) {
options.lazy = true;
}
// TODO remove in `v4`
if (!argv.info) {
options.noInfo = true;
}
// TODO remove in `v4`
if (argv.quiet) {
options.quiet = true;
}
if (argv.https) {
options.https = true;
}
if (argv.http2) {
options.http2 = true;
}
if (argv.key) {
options.key = argv.key;
}
if (argv.cert) {
options.cert = argv.cert;
}
if (argv.cacert) {
options.ca = argv.cacert;
}
if (argv.pfx) {
options.pfx = argv.pfx;
}
if (argv.pfxPassphrase) {
options.pfxPassphrase = argv.pfxPassphrase;
}
if (argv.inline === false) {
options.inline = false;
}
if (argv.historyApiFallback) {
options.historyApiFallback = true;
}
if (argv.compress) {
options.compress = true;
}
if (argv.disableHostCheck) {
options.disableHostCheck = true;
}
if (argv.openPage) {
options.open = true;
options.openPage = argv.openPage.split(',');
}
if (typeof argv.open !== 'undefined') {
options.open = argv.open !== '' ? argv.open : true;
}
if (options.open && !options.openPage) {
options.openPage = '';
}
if (argv.useLocalIp) {
options.useLocalIp = true;
}
// Kind of weird, but ensures prior behavior isn't broken in cases
// that wouldn't throw errors. E.g. both argv.port and options.port
// were specified, but since argv.port is 8080, options.port will be
// tried first instead.
options.port =
argv.port === port
? defaultTo(options.port, argv.port)
: defaultTo(argv.port, options.port);
return options;
}
module.exports = createConfig;
+29
View File
@@ -0,0 +1,29 @@
'use strict';
const url = require('url');
const ip = require('internal-ip');
function createDomain(options, server) {
const protocol = options.https ? 'https' : 'http';
const hostname = options.useLocalIp
? ip.v4.sync() || 'localhost'
: options.host || 'localhost';
// eslint-disable-next-line no-nested-ternary
const port = options.socket ? 0 : server ? server.address().port : 0;
// use explicitly defined public url
// (prefix with protocol if not explicitly given)
if (options.public) {
return /^[a-zA-Z]+:\/\//.test(options.public)
? `${options.public}`
: `${protocol}://${options.public}`;
}
// the formatted domain (url without path) of the webpack server
return url.format({
protocol,
hostname,
port,
});
}
module.exports = createDomain;
+23
View File
@@ -0,0 +1,23 @@
'use strict';
const log = require('webpack-log');
function createLogger(options = {}) {
let level = options.logLevel || 'info';
if (options.noInfo === true) {
level = 'warn';
}
if (options.quiet === true) {
level = 'silent';
}
return log({
name: 'wds',
level,
timestamp: options.logTime,
});
}
module.exports = createLogger;
+3
View File
@@ -0,0 +1,3 @@
'use strict';
module.exports = 8080;
+7
View File
@@ -0,0 +1,7 @@
'use strict';
function defaultTo(value, def) {
return value == null ? def : value;
}
module.exports = defaultTo;
+39
View File
@@ -0,0 +1,39 @@
'use strict';
const pRetry = require('p-retry');
const portfinder = require('portfinder');
const defaultPort = require('./defaultPort');
const defaultTo = require('./defaultTo');
const tryParseInt = require('./tryParseInt');
function runPortFinder() {
return new Promise((resolve, reject) => {
portfinder.basePort = defaultPort;
portfinder.getPort((error, port) => {
if (error) {
return reject(error);
}
return resolve(port);
});
});
}
function findPort(port) {
if (port) {
return Promise.resolve(port);
}
// Try to find unused port and listen on it for 3 times,
// if port is not specified in options.
// Because NaN == null is false, defaultTo fails if parseInt returns NaN
// so the tryParseInt function is introduced to handle NaN
const defaultPortRetry = defaultTo(
tryParseInt(process.env.DEFAULT_PORT_RETRY),
3
);
return pRetry(runPortFinder, { retries: defaultPortRetry });
}
module.exports = findPort;
+45
View File
@@ -0,0 +1,45 @@
'use strict';
const path = require('path');
const fs = require('fs');
const del = require('del');
const createCertificate = require('./createCertificate');
function getCertificate(logger) {
// Use a self-signed certificate if no certificate was configured.
// Cycle certs every 24 hours
const certificatePath = path.join(__dirname, '../../ssl/server.pem');
let certificateExists = fs.existsSync(certificatePath);
if (certificateExists) {
const certificateTtl = 1000 * 60 * 60 * 24;
const certificateStat = fs.statSync(certificatePath);
const now = new Date();
// cert is more than 30 days old, kill it with fire
if ((now - certificateStat.ctime) / certificateTtl > 30) {
logger.info('SSL Certificate is more than 30 days old. Removing.');
del.sync([certificatePath], { force: true });
certificateExists = false;
}
}
if (!certificateExists) {
logger.info('Generating SSL Certificate');
const attributes = [{ name: 'commonName', value: 'localhost' }];
const pems = createCertificate(attributes);
fs.writeFileSync(certificatePath, pems.private + pems.cert, {
encoding: 'utf8',
});
}
return fs.readFileSync(certificatePath);
}
module.exports = getCertificate;
+37
View File
@@ -0,0 +1,37 @@
'use strict';
function getSocketClientPath(options) {
let ClientImplementation;
let clientImplFound = true;
switch (typeof options.transportMode.client) {
case 'string':
// could be 'sockjs', 'ws', or a path that should be required
if (options.transportMode.client === 'sockjs') {
ClientImplementation = require('../../client/clients/SockJSClient');
} else if (options.transportMode.client === 'ws') {
ClientImplementation = require('../../client/clients/WebsocketClient');
} else {
try {
// eslint-disable-next-line import/no-dynamic-require
ClientImplementation = require(options.transportMode.client);
} catch (e) {
clientImplFound = false;
}
}
break;
default:
clientImplFound = false;
}
if (!clientImplFound) {
throw new Error(
"transportMode.client must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to " +
'a JS file which exports a class extending BaseClient (webpack-dev-server/client-src/clients/BaseClient) ' +
'via require.resolve(...)'
);
}
return ClientImplementation.getClientPath(options);
}
module.exports = getSocketClientPath;
@@ -0,0 +1,42 @@
'use strict';
function getSocketServerImplementation(options) {
let ServerImplementation;
let serverImplFound = true;
switch (typeof options.transportMode.server) {
case 'string':
// could be 'sockjs', in the future 'ws', or a path that should be required
if (options.transportMode.server === 'sockjs') {
ServerImplementation = require('../servers/SockJSServer');
} else if (options.transportMode.server === 'ws') {
ServerImplementation = require('../servers/WebsocketServer');
} else {
try {
// eslint-disable-next-line import/no-dynamic-require
ServerImplementation = require(options.transportMode.server);
} catch (e) {
serverImplFound = false;
}
}
break;
case 'function':
// potentially do more checks here to confirm that the user implemented this properlly
// since errors could be difficult to understand
ServerImplementation = options.transportMode.server;
break;
default:
serverImplFound = false;
}
if (!serverImplFound) {
throw new Error(
"transportMode.server must be a string denoting a default implementation (e.g. 'sockjs', 'ws'), a full path to " +
'a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer) ' +
'via require.resolve(...), or the class itself which extends BaseServer'
);
}
return ServerImplementation;
}
module.exports = getSocketServerImplementation;
+10
View File
@@ -0,0 +1,10 @@
'use strict';
function getVersions() {
return (
`webpack-dev-server ${require('../../package.json').version}\n` +
`webpack ${require('webpack/package.json').version}`
);
}
module.exports = getVersions;
+38
View File
@@ -0,0 +1,38 @@
'use strict';
/* eslint-disable
no-undefined
*/
function normalizeOptions(compiler, options) {
// Setup default value
options.contentBase =
options.contentBase !== undefined ? options.contentBase : process.cwd();
// normalize transportMode option
if (options.transportMode === undefined) {
options.transportMode = {
server: 'sockjs',
client: 'sockjs',
};
} else {
switch (typeof options.transportMode) {
case 'string':
options.transportMode = {
server: options.transportMode,
client: options.transportMode,
};
break;
// if not a string, it is an object
default:
options.transportMode.server = options.transportMode.server || 'sockjs';
options.transportMode.client = options.transportMode.client || 'sockjs';
}
}
if (!options.watchOptions) {
options.watchOptions = {};
}
}
module.exports = normalizeOptions;
+44
View File
@@ -0,0 +1,44 @@
'use strict';
const createConfig = require('./createConfig');
const defaultPort = require('./defaultPort');
const findPort = require('./findPort');
function processOptions(config, argv, callback) {
// processOptions {Promise}
if (typeof config.then === 'function') {
config
.then((conf) => processOptions(conf, argv, callback))
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err.stack || err);
// eslint-disable-next-line no-process-exit
process.exit(1);
});
return;
}
// Taken out of yargs because we must know if
// it wasn't given by the user, in which case
// we should use portfinder.
const options = createConfig(config, argv, { port: defaultPort });
if (options.socket) {
callback(config, options);
} else {
findPort(options.port)
.then((port) => {
options.port = port;
callback(config, options);
})
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err.stack || err);
// eslint-disable-next-line no-process-exit
process.exit(1);
});
}
}
module.exports = processOptions;
+89
View File
@@ -0,0 +1,89 @@
'use strict';
const { createReadStream } = require('fs');
const { join } = require('path');
const clientBasePath = join(__dirname, '..', '..', 'client');
function routes(app, middleware, options) {
app.get('/__webpack_dev_server__/live.bundle.js', (req, res) => {
res.setHeader('Content-Type', 'application/javascript');
createReadStream(join(clientBasePath, 'live.bundle.js')).pipe(res);
});
app.get('/__webpack_dev_server__/sockjs.bundle.js', (req, res) => {
res.setHeader('Content-Type', 'application/javascript');
createReadStream(join(clientBasePath, 'sockjs.bundle.js')).pipe(res);
});
app.get('/webpack-dev-server.js', (req, res) => {
res.setHeader('Content-Type', 'application/javascript');
createReadStream(join(clientBasePath, 'index.bundle.js')).pipe(res);
});
app.get('/webpack-dev-server/*', (req, res) => {
res.setHeader('Content-Type', 'text/html');
createReadStream(join(clientBasePath, 'live.html')).pipe(res);
});
app.get('/webpack-dev-server', (req, res) => {
res.setHeader('Content-Type', 'text/html');
res.write(
'<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>'
);
const outputPath = middleware.getFilenameFromUrl(options.publicPath || '/');
const filesystem = middleware.fileSystem;
writeDirectory(options.publicPath || '/', outputPath);
res.end('</body></html>');
function writeDirectory(baseUrl, basePath) {
const content = filesystem.readdirSync(basePath);
res.write('<ul>');
content.forEach((item) => {
const p = `${basePath}/${item}`;
if (filesystem.statSync(p).isFile()) {
res.write(`<li><a href="${baseUrl + item}">${item}</a></li>`);
if (/\.js$/.test(item)) {
const html = item.substr(0, item.length - 3);
const containerHref = baseUrl + html;
const magicHtmlHref =
baseUrl.replace(
// eslint-disable-next-line
/(^(https?:\/\/[^\/]+)?\/)/,
'$1webpack-dev-server/'
) + html;
res.write(
`<li><a href="${containerHref}">${html}</a>` +
` (magic html for ${item}) (<a href="${magicHtmlHref}">webpack-dev-server</a>)` +
`</li>`
);
}
} else {
res.write(`<li>${item}<br>`);
writeDirectory(`${baseUrl + item}/`, p);
res.write('</li>');
}
});
res.write('</ul>');
}
});
}
module.exports = routes;
+21
View File
@@ -0,0 +1,21 @@
'use strict';
function runBonjour({ port }) {
const bonjour = require('bonjour')();
const os = require('os');
bonjour.publish({
name: `Webpack Dev Server ${os.hostname()}:${port}`,
port,
type: 'http',
subtypes: ['webpack'],
});
process.on('exit', () => {
bonjour.unpublishAll(() => {
bonjour.destroy();
});
});
}
module.exports = runBonjour;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
const open = require('opn');
const isAbsoluteUrl = require('is-absolute-url');
function runOpen(uri, options, log) {
// https://github.com/webpack/webpack-dev-server/issues/1990
let openOptions = { wait: false };
let openOptionValue = '';
if (typeof options.open === 'string') {
openOptions = Object.assign({}, openOptions, { app: options.open });
openOptionValue = `: "${options.open}"`;
}
const pages =
typeof options.openPage === 'string'
? [options.openPage]
: options.openPage || [''];
return Promise.all(
pages.map((page) => {
const pageUrl = page && isAbsoluteUrl(page) ? page : `${uri}${page}`;
return open(pageUrl, openOptions).catch(() => {
log.warn(
`Unable to open "${pageUrl}" in browser${openOptionValue}. If you are running in a headless environment, please do not use the --open flag`
);
});
})
);
}
module.exports = runOpen;
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const signals = ['SIGINT', 'SIGTERM'];
function setupExitSignals(serverData) {
signals.forEach((signal) => {
process.on(signal, () => {
if (serverData.server) {
serverData.server.close(() => {
// eslint-disable-next-line no-process-exit
process.exit();
});
} else {
// eslint-disable-next-line no-process-exit
process.exit();
}
});
});
}
module.exports = setupExitSignals;
+61
View File
@@ -0,0 +1,61 @@
'use strict';
const logger = require('webpack-log');
const colors = require('./colors');
const runOpen = require('./runOpen');
// TODO: don't emit logs when webpack-dev-server is used via Node.js API
function status(uri, options, log, useColor) {
if (options.quiet === true) {
// Add temporary logger to output just the status of the dev server
log = logger({
name: 'wds',
level: 'info',
timestamp: options.logTime,
});
}
const contentBase = Array.isArray(options.contentBase)
? options.contentBase.join(', ')
: options.contentBase;
if (options.socket) {
log.info(`Listening to socket at ${colors.info(useColor, options.socket)}`);
} else {
log.info(`Project is running at ${colors.info(useColor, uri)}`);
}
log.info(
`webpack output is served from ${colors.info(useColor, options.publicPath)}`
);
if (contentBase) {
log.info(
`Content not from webpack is served from ${colors.info(
useColor,
contentBase
)}`
);
}
if (options.historyApiFallback) {
log.info(
`404s will fallback to ${colors.info(
useColor,
options.historyApiFallback.index || '/index.html'
)}`
);
}
if (options.bonjour) {
log.info(
'Broadcasting "http" with subtype of "webpack" via ZeroConf DNS (Bonjour)'
);
}
if (options.open) {
runOpen(uri, options, log);
}
}
module.exports = status;
+13
View File
@@ -0,0 +1,13 @@
'use strict';
function tryParseInt(input) {
const output = parseInt(input, 10);
if (Number.isNaN(output)) {
return null;
}
return output;
}
module.exports = tryParseInt;
+73
View File
@@ -0,0 +1,73 @@
'use strict';
/* eslint-disable
no-shadow,
no-undefined
*/
const webpack = require('webpack');
const addEntries = require('./addEntries');
const getSocketClientPath = require('./getSocketClientPath');
function updateCompiler(compiler, options) {
if (options.inline !== false) {
const findHMRPlugin = (config) => {
if (!config.plugins) {
return undefined;
}
return config.plugins.find(
(plugin) => plugin.constructor === webpack.HotModuleReplacementPlugin
);
};
const compilers = [];
const compilersWithoutHMR = [];
let webpackConfig;
if (compiler.compilers) {
webpackConfig = [];
compiler.compilers.forEach((compiler) => {
webpackConfig.push(compiler.options);
compilers.push(compiler);
if (!findHMRPlugin(compiler.options)) {
compilersWithoutHMR.push(compiler);
}
});
} else {
webpackConfig = compiler.options;
compilers.push(compiler);
if (!findHMRPlugin(compiler.options)) {
compilersWithoutHMR.push(compiler);
}
}
// it's possible that we should clone the config before doing
// this, but it seems safe not to since it actually reflects
// the changes we are making to the compiler
// important: this relies on the fact that addEntries now
// prevents duplicate new entries.
addEntries(webpackConfig, options);
compilers.forEach((compiler) => {
const config = compiler.options;
compiler.hooks.entryOption.call(config.context, config.entry);
const providePlugin = new webpack.ProvidePlugin({
__webpack_dev_server_client__: getSocketClientPath(options),
});
providePlugin.apply(compiler);
});
// do not apply the plugin unless it didn't exist before.
if (options.hot || options.hotOnly) {
compilersWithoutHMR.forEach((compiler) => {
// addDevServerEntrypoints above should have added the plugin
// to the compiler options
const plugin = findHMRPlugin(compiler.options);
if (plugin) {
plugin.apply(compiler);
}
});
}
}
}
module.exports = updateCompiler;
+1
View File
@@ -0,0 +1 @@
../semver/bin/semver.js
+4
View File
@@ -0,0 +1,4 @@
'use strict';
module.exports = function () {
return /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g;
};
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
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.
+108
View File
@@ -0,0 +1,108 @@
{
"_from": "ansi-regex@^2.0.0",
"_id": "ansi-regex@2.1.1",
"_inBundle": false,
"_integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"_location": "/webpack-dev-server/ansi-regex",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "ansi-regex@^2.0.0",
"name": "ansi-regex",
"escapedName": "ansi-regex",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/webpack-dev-server/strip-ansi"
],
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"_shasum": "c3b33ab5ee360d86e0e628f0468ae7ef27d654df",
"_spec": "ansi-regex@^2.0.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/strip-ansi",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/chalk/ansi-regex/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Regular expression for matching ANSI escape codes",
"devDependencies": {
"ava": "0.17.0",
"xo": "0.16.0"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/ansi-regex#readme",
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"license": "MIT",
"maintainers": [
{
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
{
"name": "Joshua Appelman",
"email": "jappelman@xebia.com",
"url": "jbnicolai.com"
},
{
"name": "JD Ballard",
"email": "i.am.qix@gmail.com",
"url": "github.com/qix-"
}
],
"name": "ansi-regex",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/ansi-regex.git"
},
"scripts": {
"test": "xo && ava --verbose",
"view-supported": "node fixtures/view-codes.js"
},
"version": "2.1.1",
"xo": {
"rules": {
"guard-for-in": 0,
"no-loop-func": 0
}
}
}
+39
View File
@@ -0,0 +1,39 @@
# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex)
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```
$ npm install --save ansi-regex
```
## Usage
```js
const ansiRegex = require('ansi-regex');
ansiRegex().test('\u001b[4mcake\u001b[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
//=> ['\u001b[4m', '\u001b[0m']
```
## FAQ
### Why do you test for codes not in the ECMA 48 standard?
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. If I recall correctly, we test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)
+51
View File
@@ -0,0 +1,51 @@
# 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.
<a name="4.1.0"></a>
# [4.1.0](https://github.com/yargs/cliui/compare/v4.0.0...v4.1.0) (2018-04-23)
### Features
* add resetOutput method ([#57](https://github.com/yargs/cliui/issues/57)) ([7246902](https://github.com/yargs/cliui/commit/7246902))
<a name="4.0.0"></a>
# [4.0.0](https://github.com/yargs/cliui/compare/v3.2.0...v4.0.0) (2017-12-18)
### Bug Fixes
* downgrades strip-ansi to version 3.0.1 ([#54](https://github.com/yargs/cliui/issues/54)) ([5764c46](https://github.com/yargs/cliui/commit/5764c46))
* set env variable FORCE_COLOR. ([#56](https://github.com/yargs/cliui/issues/56)) ([7350e36](https://github.com/yargs/cliui/commit/7350e36))
### Chores
* drop support for node < 4 ([#53](https://github.com/yargs/cliui/issues/53)) ([b105376](https://github.com/yargs/cliui/commit/b105376))
### Features
* add fallback for window width ([#45](https://github.com/yargs/cliui/issues/45)) ([d064922](https://github.com/yargs/cliui/commit/d064922))
### BREAKING CHANGES
* officially drop support for Node < 4
<a name="3.2.0"></a>
# [3.2.0](https://github.com/yargs/cliui/compare/v3.1.2...v3.2.0) (2016-04-11)
### Bug Fixes
* reduces tarball size ([acc6c33](https://github.com/yargs/cliui/commit/acc6c33))
### Features
* adds standard-version for release management ([ff84e32](https://github.com/yargs/cliui/commit/ff84e32))
+14
View File
@@ -0,0 +1,14 @@
Copyright (c) 2015, 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.
+115
View File
@@ -0,0 +1,115 @@
# cliui
[![Build Status](https://travis-ci.org/yargs/cliui.svg)](https://travis-ci.org/yargs/cliui)
[![Coverage Status](https://coveralls.io/repos/yargs/cliui/badge.svg?branch=)](https://coveralls.io/r/yargs/cliui?branch=)
[![NPM version](https://img.shields.io/npm/v/cliui.svg)](https://www.npmjs.com/package/cliui)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
easily create complex multi-column command-line-interfaces.
## Example
```js
var ui = require('cliui')()
ui.div('Usage: $0 [command] [options]')
ui.div({
text: 'Options:',
padding: [2, 0, 2, 0]
})
ui.div(
{
text: "-f, --file",
width: 20,
padding: [0, 4, 0, 4]
},
{
text: "the file to load." +
chalk.green("(if this description is long it wraps).")
,
width: 20
},
{
text: chalk.red("[required]"),
align: 'right'
}
)
console.log(ui.toString())
```
<img width="500" src="screenshot.png">
## Layout DSL
cliui exposes a simple layout DSL:
If you create a single `ui.row`, passing a string rather than an
object:
* `\n`: characters will be interpreted as new rows.
* `\t`: characters will be interpreted as new columns.
* `\s`: characters will be interpreted as padding.
**as an example...**
```js
var ui = require('./')({
width: 60
})
ui.div(
'Usage: node ./bin/foo.js\n' +
' <regex>\t provide a regex\n' +
' <glob>\t provide a glob\t [required]'
)
console.log(ui.toString())
```
**will output:**
```shell
Usage: node ./bin/foo.js
<regex> provide a regex
<glob> provide a glob [required]
```
## Methods
```js
cliui = require('cliui')
```
### cliui({width: integer})
Specify the maximum width of the UI being generated.
If no width is provided, cliui will try to get the current window's width and use it, and if that doesn't work, width will be set to `80`.
### cliui({wrap: boolean})
Enable or disable the wrapping of text in a column.
### cliui.div(column, column, column)
Create a row with any number of columns, a column
can either be a string, or an object with the following
options:
* **text:** some text to place in the column.
* **width:** the width of a column.
* **align:** alignment, `right` or `center`.
* **padding:** `[top, right, bottom, left]`.
* **border:** should a border be placed around the div?
### cliui.span(column, column, column)
Similar to `div`, except the next row will be appended without
a new line being created.
### cliui.resetOutput()
Resets the UI elements of the current cliui instance, maintaining the values
set for `width` and `wrap`.
+324
View File
@@ -0,0 +1,324 @@
var stringWidth = require('string-width')
var stripAnsi = require('strip-ansi')
var wrap = require('wrap-ansi')
var align = {
right: alignRight,
center: alignCenter
}
var top = 0
var right = 1
var bottom = 2
var left = 3
function UI (opts) {
this.width = opts.width
this.wrap = opts.wrap
this.rows = []
}
UI.prototype.span = function () {
var cols = this.div.apply(this, arguments)
cols.span = true
}
UI.prototype.resetOutput = function () {
this.rows = []
}
UI.prototype.div = function () {
if (arguments.length === 0) this.div('')
if (this.wrap && this._shouldApplyLayoutDSL.apply(this, arguments)) {
return this._applyLayoutDSL(arguments[0])
}
var cols = []
for (var i = 0, arg; (arg = arguments[i]) !== undefined; i++) {
if (typeof arg === 'string') cols.push(this._colFromString(arg))
else cols.push(arg)
}
this.rows.push(cols)
return cols
}
UI.prototype._shouldApplyLayoutDSL = function () {
return arguments.length === 1 && typeof arguments[0] === 'string' &&
/[\t\n]/.test(arguments[0])
}
UI.prototype._applyLayoutDSL = function (str) {
var _this = this
var rows = str.split('\n')
var leftColumnWidth = 0
// simple heuristic for layout, make sure the
// second column lines up along the left-hand.
// don't allow the first column to take up more
// than 50% of the screen.
rows.forEach(function (row) {
var columns = row.split('\t')
if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
leftColumnWidth = Math.min(
Math.floor(_this.width * 0.5),
stringWidth(columns[0])
)
}
})
// generate a table:
// replacing ' ' with padding calculations.
// using the algorithmically generated width.
rows.forEach(function (row) {
var columns = row.split('\t')
_this.div.apply(_this, columns.map(function (r, i) {
return {
text: r.trim(),
padding: _this._measurePadding(r),
width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined
}
}))
})
return this.rows[this.rows.length - 1]
}
UI.prototype._colFromString = function (str) {
return {
text: str,
padding: this._measurePadding(str)
}
}
UI.prototype._measurePadding = function (str) {
// measure padding without ansi escape codes
var noAnsi = stripAnsi(str)
return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]
}
UI.prototype.toString = function () {
var _this = this
var lines = []
_this.rows.forEach(function (row, i) {
_this.rowToString(row, lines)
})
// don't display any lines with the
// hidden flag set.
lines = lines.filter(function (line) {
return !line.hidden
})
return lines.map(function (line) {
return line.text
}).join('\n')
}
UI.prototype.rowToString = function (row, lines) {
var _this = this
var padding
var rrows = this._rasterize(row)
var str = ''
var ts
var width
var wrapWidth
rrows.forEach(function (rrow, r) {
str = ''
rrow.forEach(function (col, c) {
ts = '' // temporary string used during alignment/padding.
width = row[c].width // the width with padding.
wrapWidth = _this._negatePadding(row[c]) // the width without padding.
ts += col
for (var i = 0; i < wrapWidth - stringWidth(col); i++) {
ts += ' '
}
// align the string within its column.
if (row[c].align && row[c].align !== 'left' && _this.wrap) {
ts = align[row[c].align](ts, wrapWidth)
if (stringWidth(ts) < wrapWidth) ts += new Array(width - stringWidth(ts)).join(' ')
}
// apply border and padding to string.
padding = row[c].padding || [0, 0, 0, 0]
if (padding[left]) str += new Array(padding[left] + 1).join(' ')
str += addBorder(row[c], ts, '| ')
str += ts
str += addBorder(row[c], ts, ' |')
if (padding[right]) str += new Array(padding[right] + 1).join(' ')
// if prior row is span, try to render the
// current row on the prior line.
if (r === 0 && lines.length > 0) {
str = _this._renderInline(str, lines[lines.length - 1])
}
})
// remove trailing whitespace.
lines.push({
text: str.replace(/ +$/, ''),
span: row.span
})
})
return lines
}
function addBorder (col, ts, style) {
if (col.border) {
if (/[.']-+[.']/.test(ts)) return ''
else if (ts.trim().length) return style
else return ' '
}
return ''
}
// if the full 'source' can render in
// the target line, do so.
UI.prototype._renderInline = function (source, previousLine) {
var leadingWhitespace = source.match(/^ */)[0].length
var target = previousLine.text
var targetTextWidth = stringWidth(target.trimRight())
if (!previousLine.span) return source
// if we're not applying wrapping logic,
// just always append to the span.
if (!this.wrap) {
previousLine.hidden = true
return target + source
}
if (leadingWhitespace < targetTextWidth) return source
previousLine.hidden = true
return target.trimRight() + new Array(leadingWhitespace - targetTextWidth + 1).join(' ') + source.trimLeft()
}
UI.prototype._rasterize = function (row) {
var _this = this
var i
var rrow
var rrows = []
var widths = this._columnWidths(row)
var wrapped
// word wrap all columns, and create
// a data-structure that is easy to rasterize.
row.forEach(function (col, c) {
// leave room for left and right padding.
col.width = widths[c]
if (_this.wrap) wrapped = wrap(col.text, _this._negatePadding(col), { hard: true }).split('\n')
else wrapped = col.text.split('\n')
if (col.border) {
wrapped.unshift('.' + new Array(_this._negatePadding(col) + 3).join('-') + '.')
wrapped.push("'" + new Array(_this._negatePadding(col) + 3).join('-') + "'")
}
// add top and bottom padding.
if (col.padding) {
for (i = 0; i < (col.padding[top] || 0); i++) wrapped.unshift('')
for (i = 0; i < (col.padding[bottom] || 0); i++) wrapped.push('')
}
wrapped.forEach(function (str, r) {
if (!rrows[r]) rrows.push([])
rrow = rrows[r]
for (var i = 0; i < c; i++) {
if (rrow[i] === undefined) rrow.push('')
}
rrow.push(str)
})
})
return rrows
}
UI.prototype._negatePadding = function (col) {
var wrapWidth = col.width
if (col.padding) wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0)
if (col.border) wrapWidth -= 4
return wrapWidth
}
UI.prototype._columnWidths = function (row) {
var _this = this
var widths = []
var unset = row.length
var unsetWidth
var remainingWidth = this.width
// column widths can be set in config.
row.forEach(function (col, i) {
if (col.width) {
unset--
widths[i] = col.width
remainingWidth -= col.width
} else {
widths[i] = undefined
}
})
// any unset widths should be calculated.
if (unset) unsetWidth = Math.floor(remainingWidth / unset)
widths.forEach(function (w, i) {
if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text)
else if (w === undefined) widths[i] = Math.max(unsetWidth, _minWidth(row[i]))
})
return widths
}
// calculates the minimum width of
// a column, based on padding preferences.
function _minWidth (col) {
var padding = col.padding || []
var minWidth = 1 + (padding[left] || 0) + (padding[right] || 0)
if (col.border) minWidth += 4
return minWidth
}
function getWindowWidth () {
if (typeof process === 'object' && process.stdout && process.stdout.columns) return process.stdout.columns
}
function alignRight (str, width) {
str = str.trim()
var padding = ''
var strWidth = stringWidth(str)
if (strWidth < width) {
padding = new Array(width - strWidth + 1).join(' ')
}
return padding + str
}
function alignCenter (str, width) {
str = str.trim()
var padding = ''
var strWidth = stringWidth(str.trim())
if (strWidth < width) {
padding = new Array(parseInt((width - strWidth) / 2, 10) + 1).join(' ')
}
return padding + str
}
module.exports = function (opts) {
opts = opts || {}
return new UI({
width: (opts || {}).width || getWindowWidth() || 80,
wrap: typeof opts.wrap === 'boolean' ? opts.wrap : true
})
}
@@ -0,0 +1,10 @@
'use strict';
module.exports = () => {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, 'g');
};
@@ -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,85 @@
{
"_from": "ansi-regex@^3.0.0",
"_id": "ansi-regex@3.0.0",
"_inBundle": false,
"_integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"_location": "/webpack-dev-server/cliui/ansi-regex",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "ansi-regex@^3.0.0",
"name": "ansi-regex",
"escapedName": "ansi-regex",
"rawSpec": "^3.0.0",
"saveSpec": null,
"fetchSpec": "^3.0.0"
},
"_requiredBy": [
"/webpack-dev-server/cliui/strip-ansi"
],
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"_shasum": "ed0317c322064f79466c02966bddb605ab37d998",
"_spec": "ansi-regex@^3.0.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/chalk/ansi-regex/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Regular expression for matching ANSI escape codes",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/ansi-regex#readme",
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"license": "MIT",
"name": "ansi-regex",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/ansi-regex.git"
},
"scripts": {
"test": "xo && ava",
"view-supported": "node fixtures/view-codes.js"
},
"version": "3.0.0"
}
@@ -0,0 +1,46 @@
# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex)
> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```
$ npm install ansi-regex
```
## Usage
```js
const ansiRegex = require('ansi-regex');
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
```
## FAQ
### Why do you test for codes not in the ECMA 48 standard?
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT
@@ -0,0 +1,4 @@
'use strict';
const ansiRegex = require('ansi-regex');
module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input;
@@ -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,84 @@
{
"_from": "strip-ansi@^4.0.0",
"_id": "strip-ansi@4.0.0",
"_inBundle": false,
"_integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"_location": "/webpack-dev-server/cliui/strip-ansi",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "strip-ansi@^4.0.0",
"name": "strip-ansi",
"escapedName": "strip-ansi",
"rawSpec": "^4.0.0",
"saveSpec": null,
"fetchSpec": "^4.0.0"
},
"_requiredBy": [
"/webpack-dev-server/cliui"
],
"_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"_shasum": "a8479022eb1ac368a871389b635262c505ee368f",
"_spec": "strip-ansi@^4.0.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/cliui",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/chalk/strip-ansi/issues"
},
"bundleDependencies": false,
"dependencies": {
"ansi-regex": "^3.0.0"
},
"deprecated": false,
"description": "Strip ANSI escape codes",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/strip-ansi#readme",
"keywords": [
"strip",
"trim",
"remove",
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"license": "MIT",
"name": "strip-ansi",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/strip-ansi.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "4.0.0"
}
@@ -0,0 +1,39 @@
# strip-ansi [![Build Status](https://travis-ci.org/chalk/strip-ansi.svg?branch=master)](https://travis-ci.org/chalk/strip-ansi)
> Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```
$ npm install strip-ansi
```
## Usage
```js
const stripAnsi = require('strip-ansi');
stripAnsi('\u001B[4mUnicorn\u001B[0m');
//=> 'Unicorn'
```
## Related
- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT
+99
View File
@@ -0,0 +1,99 @@
{
"_from": "cliui@^4.0.0",
"_id": "cliui@4.1.0",
"_inBundle": false,
"_integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
"_location": "/webpack-dev-server/cliui",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "cliui@^4.0.0",
"name": "cliui",
"escapedName": "cliui",
"rawSpec": "^4.0.0",
"saveSpec": null,
"fetchSpec": "^4.0.0"
},
"_requiredBy": [
"/webpack-dev-server/yargs"
],
"_resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
"_shasum": "348422dbe82d800b3022eef4f6ac10bf2e4d1b49",
"_spec": "cliui@^4.0.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/yargs",
"author": {
"name": "Ben Coe",
"email": "ben@npmjs.com"
},
"bugs": {
"url": "https://github.com/yargs/cliui/issues"
},
"bundleDependencies": false,
"config": {
"blanket": {
"pattern": [
"index.js"
],
"data-cover-never": [
"node_modules",
"test"
],
"output-reporter": "spec"
}
},
"dependencies": {
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0",
"wrap-ansi": "^2.0.0"
},
"deprecated": false,
"description": "easily create complex multi-column command-line-interfaces",
"devDependencies": {
"chai": "^3.5.0",
"chalk": "^1.1.2",
"coveralls": "^2.11.8",
"mocha": "^3.0.0",
"nyc": "^10.0.0",
"standard": "^8.0.0",
"standard-version": "^3.0.0"
},
"engine": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/yargs/cliui#readme",
"keywords": [
"cli",
"command-line",
"layout",
"design",
"console",
"wrap",
"table"
],
"license": "ISC",
"main": "index.js",
"name": "cliui",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/yargs/cliui.git"
},
"scripts": {
"coverage": "nyc --reporter=text-lcov mocha | coveralls",
"pretest": "standard",
"release": "standard-version",
"test": "nyc mocha"
},
"standard": {
"ignore": [
"**/example/**"
],
"globals": [
"it"
]
},
"version": "4.1.0"
}
@@ -0,0 +1,6 @@
ISC License (ISC)
Copyright 2018 Stefan Penner
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.
@@ -0,0 +1,4 @@
# get-caller-file
[![Build Status](https://travis-ci.org/stefanpenner/get-caller-file.svg?branch=master)](https://travis-ci.org/stefanpenner/get-caller-file)
[![Build status](https://ci.appveyor.com/api/projects/status/ol2q94g1932cy14a/branch/master?svg=true)](https://ci.appveyor.com/project/embercli/get-caller-file/branch/master)
+20
View File
@@ -0,0 +1,20 @@
'use strict';
// Call this function in a another function to find out the file from
// which that function was called from. (Inspects the v8 stack trace)
//
// Inspired by http://stackoverflow.com/questions/13227489
module.exports = function getCallerFile(_position) {
var oldPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = function(err, stack) { return stack; };
var stack = new Error().stack;
Error.prepareStackTrace = oldPrepareStackTrace;
var position = _position ? _position : 2;
// stack[0] holds this file
// stack[1] holds where this function was called
// stack[2] holds the file we're interested in
return stack[position] ? stack[position].getFileName() : undefined;
};
@@ -0,0 +1,58 @@
{
"_from": "get-caller-file@^1.0.1",
"_id": "get-caller-file@1.0.3",
"_inBundle": false,
"_integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"_location": "/webpack-dev-server/get-caller-file",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "get-caller-file@^1.0.1",
"name": "get-caller-file",
"escapedName": "get-caller-file",
"rawSpec": "^1.0.1",
"saveSpec": null,
"fetchSpec": "^1.0.1"
},
"_requiredBy": [
"/webpack-dev-server/yargs"
],
"_resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
"_shasum": "f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a",
"_spec": "get-caller-file@^1.0.1",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/yargs",
"author": {
"name": "Stefan Penner"
},
"bugs": {
"url": "https://github.com/stefanpenner/get-caller-file/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "[![Build Status](https://travis-ci.org/stefanpenner/get-caller-file.svg?branch=master)](https://travis-ci.org/stefanpenner/get-caller-file) [![Build status](https://ci.appveyor.com/api/projects/status/ol2q94g1932cy14a/branch/master?svg=true)](https://ci.appveyor.com/project/embercli/get-caller-file/branch/master)",
"devDependencies": {
"chai": "^4.1.2",
"ensure-posix-path": "^1.0.1",
"mocha": "^5.2.0"
},
"directories": {
"test": "tests"
},
"files": [
"index.js"
],
"homepage": "https://github.com/stefanpenner/get-caller-file#readme",
"license": "ISC",
"main": "index.js",
"name": "get-caller-file",
"repository": {
"type": "git",
"url": "git+https://github.com/stefanpenner/get-caller-file.git"
},
"scripts": {
"test": "mocha test",
"test:debug": "mocha test"
},
"version": "1.0.3"
}
@@ -0,0 +1,22 @@
/**
Check if a URL is absolute.
@param url - The URL to check.
@example
```
import isAbsoluteUrl = require('is-absolute-url');
isAbsoluteUrl('http://sindresorhus.com/foo/bar');
//=> true
isAbsoluteUrl('//sindresorhus.com');
//=> false
isAbsoluteUrl('foo/bar');
//=> false
```
*/
declare function isAbsoluteUrl(url: string): boolean;
export = isAbsoluteUrl;
+16
View File
@@ -0,0 +1,16 @@
'use strict';
module.exports = url => {
if (typeof url !== 'string') {
throw new TypeError(`Expected a \`string\`, got \`${typeof url}\``);
}
// Don't match Windows paths `c:\`
if (/^[a-zA-Z]:\\/.test(url)) {
return false;
}
// Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
// Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
return /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(url);
};
+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,67 @@
{
"_from": "is-absolute-url@^3.0.3",
"_id": "is-absolute-url@3.0.3",
"_inBundle": false,
"_integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
"_location": "/webpack-dev-server/is-absolute-url",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "is-absolute-url@^3.0.3",
"name": "is-absolute-url",
"escapedName": "is-absolute-url",
"rawSpec": "^3.0.3",
"saveSpec": null,
"fetchSpec": "^3.0.3"
},
"_requiredBy": [
"/webpack-dev-server"
],
"_resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
"_shasum": "96c6a22b6a23929b11ea0afb1836c36ad4a5d698",
"_spec": "is-absolute-url@^3.0.3",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/is-absolute-url/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Check if a URL is absolute",
"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/is-absolute-url#readme",
"keywords": [
"url",
"absolute",
"relative",
"uri",
"is",
"check"
],
"license": "MIT",
"name": "is-absolute-url",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/is-absolute-url.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "3.0.3"
}
+44
View File
@@ -0,0 +1,44 @@
# is-absolute-url [![Build Status](https://travis-ci.org/sindresorhus/is-absolute-url.svg?branch=master)](https://travis-ci.org/sindresorhus/is-absolute-url)
> Check if a URL is absolute
## Install
```
$ npm install is-absolute-url
```
## Usage
```js
const isAbsoluteUrl = require('is-absolute-url');
isAbsoluteUrl('https://sindresorhus.com/foo/bar');
//=> true
isAbsoluteUrl('//sindresorhus.com');
//=> false
isAbsoluteUrl('foo/bar');
//=> false
```
## Related
See [is-relative-url](https://github.com/sindresorhus/is-relative-url) for the inverse.
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-is-absolute-url?utm_source=npm-is-absolute-url&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>
@@ -0,0 +1,46 @@
'use strict';
var numberIsNan = require('number-is-nan');
module.exports = function (x) {
if (numberIsNan(x)) {
return false;
}
// https://github.com/nodejs/io.js/blob/cff7300a578be1b10001f2d967aaedc88aee6402/lib/readline.js#L1369
// code points are derived from:
// http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
if (x >= 0x1100 && (
x <= 0x115f || // Hangul Jamo
0x2329 === x || // LEFT-POINTING ANGLE BRACKET
0x232a === x || // RIGHT-POINTING ANGLE BRACKET
// CJK Radicals Supplement .. Enclosed CJK Letters and Months
(0x2e80 <= x && x <= 0x3247 && x !== 0x303f) ||
// Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
0x3250 <= x && x <= 0x4dbf ||
// CJK Unified Ideographs .. Yi Radicals
0x4e00 <= x && x <= 0xa4c6 ||
// Hangul Jamo Extended-A
0xa960 <= x && x <= 0xa97c ||
// Hangul Syllables
0xac00 <= x && x <= 0xd7a3 ||
// CJK Compatibility Ideographs
0xf900 <= x && x <= 0xfaff ||
// Vertical Forms
0xfe10 <= x && x <= 0xfe19 ||
// CJK Compatibility Forms .. Small Form Variants
0xfe30 <= x && x <= 0xfe6b ||
// Halfwidth and Fullwidth Forms
0xff01 <= x && x <= 0xff60 ||
0xffe0 <= x && x <= 0xffe6 ||
// Kana Supplement
0x1b000 <= x && x <= 0x1b001 ||
// Enclosed Ideographic Supplement
0x1f200 <= x && x <= 0x1f251 ||
// CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
0x20000 <= x && x <= 0x3fffd)) {
return true;
}
return false;
}
@@ -0,0 +1,21 @@
The MIT License (MIT)
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,77 @@
{
"_from": "is-fullwidth-code-point@^1.0.0",
"_id": "is-fullwidth-code-point@1.0.0",
"_inBundle": false,
"_integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"_location": "/webpack-dev-server/is-fullwidth-code-point",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "is-fullwidth-code-point@^1.0.0",
"name": "is-fullwidth-code-point",
"escapedName": "is-fullwidth-code-point",
"rawSpec": "^1.0.0",
"saveSpec": null,
"fetchSpec": "^1.0.0"
},
"_requiredBy": [
"/webpack-dev-server/wrap-ansi/string-width"
],
"_resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"_shasum": "ef9e31386f031a7f0d643af82fde50c457ef00cb",
"_spec": "is-fullwidth-code-point@^1.0.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/string-width",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/is-fullwidth-code-point/issues"
},
"bundleDependencies": false,
"dependencies": {
"number-is-nan": "^1.0.0"
},
"deprecated": false,
"description": "Check if the character represented by a given Unicode code point is fullwidth",
"devDependencies": {
"ava": "0.0.4",
"code-point-at": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/is-fullwidth-code-point#readme",
"keywords": [
"fullwidth",
"full-width",
"full",
"width",
"unicode",
"character",
"char",
"string",
"str",
"codepoint",
"code",
"point",
"is",
"detect",
"check"
],
"license": "MIT",
"name": "is-fullwidth-code-point",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/is-fullwidth-code-point.git"
},
"scripts": {
"test": "node test.js"
},
"version": "1.0.0"
}
@@ -0,0 +1,39 @@
# is-fullwidth-code-point [![Build Status](https://travis-ci.org/sindresorhus/is-fullwidth-code-point.svg?branch=master)](https://travis-ci.org/sindresorhus/is-fullwidth-code-point)
> Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms)
## Install
```
$ npm install --save is-fullwidth-code-point
```
## Usage
```js
var isFullwidthCodePoint = require('is-fullwidth-code-point');
isFullwidthCodePoint('谢'.codePointAt());
//=> true
isFullwidthCodePoint('a'.codePointAt());
//=> false
```
## API
### isFullwidthCodePoint(input)
#### input
Type: `number`
[Code point](https://en.wikipedia.org/wiki/Code_point) of a character.
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)
@@ -0,0 +1,3 @@
node_modules
.DS_Store
.nyc_output
@@ -0,0 +1,8 @@
language: node_js
os:
- linux
node_js:
- "0.10"
- "0.12"
- "4.1"
- "node"
@@ -0,0 +1,14 @@
Copyright (c) 2016, 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.
@@ -0,0 +1,26 @@
# require-main-filename
[![Build Status](https://travis-ci.org/yargs/require-main-filename.png)](https://travis-ci.org/yargs/require-main-filename)
[![Coverage Status](https://coveralls.io/repos/yargs/require-main-filename/badge.svg?branch=master)](https://coveralls.io/r/yargs/require-main-filename?branch=master)
[![NPM version](https://img.shields.io/npm/v/require-main-filename.svg)](https://www.npmjs.com/package/require-main-filename)
`require.main.filename` is great for figuring out the entry
point for the current application. This can be combined with a module like
[pkg-conf](https://www.npmjs.com/package/pkg-conf) to, _as if by magic_, load
top-level configuration.
Unfortunately, `require.main.filename` sometimes fails when an application is
executed with an alternative process manager, e.g., [iisnode](https://github.com/tjanczuk/iisnode).
`require-main-filename` is a shim that addresses this problem.
## Usage
```js
var main = require('require-main-filename')()
// use main as an alternative to require.main.filename.
```
## License
ISC
@@ -0,0 +1,18 @@
module.exports = function (_require) {
_require = _require || require
var main = _require.main
if (main && isIISNode(main)) return handleIISNode(main)
else return main ? main.filename : process.cwd()
}
function isIISNode (main) {
return /\\iisnode\\/.test(main.filename)
}
function handleIISNode (main) {
if (!main.children.length) {
return main.filename
} else {
return main.children[0].filename
}
}
@@ -0,0 +1,58 @@
{
"_from": "require-main-filename@^1.0.1",
"_id": "require-main-filename@1.0.1",
"_inBundle": false,
"_integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"_location": "/webpack-dev-server/require-main-filename",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "require-main-filename@^1.0.1",
"name": "require-main-filename",
"escapedName": "require-main-filename",
"rawSpec": "^1.0.1",
"saveSpec": null,
"fetchSpec": "^1.0.1"
},
"_requiredBy": [
"/webpack-dev-server/yargs"
],
"_resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
"_shasum": "97f717b69d48784f5f526a6c5aa8ffdda055a4d1",
"_spec": "require-main-filename@^1.0.1",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server/node_modules/yargs",
"author": {
"name": "Ben Coe",
"email": "ben@npmjs.com"
},
"bugs": {
"url": "https://github.com/yargs/require-main-filename/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "shim for require.main.filename() that works in as many environments as possible",
"devDependencies": {
"chai": "^3.5.0",
"standard": "^6.0.5",
"tap": "^5.2.0"
},
"homepage": "https://github.com/yargs/require-main-filename#readme",
"keywords": [
"require",
"shim",
"iisnode"
],
"license": "ISC",
"main": "index.js",
"name": "require-main-filename",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/yargs/require-main-filename.git"
},
"scripts": {
"pretest": "standard",
"test": "tap --coverage test.js"
},
"version": "1.0.1"
}
@@ -0,0 +1,36 @@
/* global describe, it */
var requireMainFilename = require('./')
require('tap').mochaGlobals()
require('chai').should()
describe('require-main-filename', function () {
it('returns require.main.filename in normal circumstances', function () {
requireMainFilename().should.match(/test\.js/)
})
it('should use children[0].filename when running on iisnode', function () {
var main = {
filename: 'D:\\Program Files (x86)\\iisnode\\interceptor.js',
children: [ {filename: 'D:\\home\\site\\wwwroot\\server.js'} ]
}
requireMainFilename({
main: main
}).should.match(/server\.js/)
})
it('should not use children[0] if no children exist', function () {
var main = {
filename: 'D:\\Program Files (x86)\\iisnode\\interceptor.js',
children: []
}
requireMainFilename({
main: main
}).should.match(/interceptor\.js/)
})
it('should default to process.cwd() if require.main is undefined', function () {
requireMainFilename({}).should.match(/require-main-filename/)
})
})
+134
View File
@@ -0,0 +1,134 @@
# 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.
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/schema-utils/compare/v0.4.7...v1.0.0) (2018-08-07)
### Features
* **src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))
<a name="0.4.7"></a>
## [0.4.7](https://github.com/webpack-contrib/schema-utils/compare/v0.4.6...v0.4.7) (2018-08-07)
### Bug Fixes
* **src:** `node >= v4.0.0` support ([#32](https://github.com/webpack-contrib/schema-utils/issues/32)) ([cb13dd4](https://github.com/webpack-contrib/schema-utils/commit/cb13dd4))
<a name="0.4.6"></a>
## [0.4.6](https://github.com/webpack-contrib/schema-utils/compare/v0.4.5...v0.4.6) (2018-08-06)
### Bug Fixes
* **package:** remove lockfile ([#28](https://github.com/webpack-contrib/schema-utils/issues/28)) ([69f1a81](https://github.com/webpack-contrib/schema-utils/commit/69f1a81))
* **package:** remove unnecessary `webpack` dependency ([#26](https://github.com/webpack-contrib/schema-utils/issues/26)) ([532eaa5](https://github.com/webpack-contrib/schema-utils/commit/532eaa5))
<a name="0.4.5"></a>
## [0.4.5](https://github.com/webpack-contrib/schema-utils/compare/v0.4.4...v0.4.5) (2018-02-13)
### Bug Fixes
* **CHANGELOG:** update broken links ([4483b9f](https://github.com/webpack-contrib/schema-utils/commit/4483b9f))
* **package:** update broken links ([f2494ba](https://github.com/webpack-contrib/schema-utils/commit/f2494ba))
<a name="0.4.4"></a>
## [0.4.4](https://github.com/webpack-contrib/schema-utils/compare/v0.4.3...v0.4.4) (2018-02-13)
### Bug Fixes
* **package:** update `dependencies` ([#22](https://github.com/webpack-contrib/schema-utils/issues/22)) ([3aecac6](https://github.com/webpack-contrib/schema-utils/commit/3aecac6))
<a name="0.4.3"></a>
## [0.4.3](https://github.com/webpack-contrib/schema-utils/compare/v0.4.2...v0.4.3) (2017-12-14)
### Bug Fixes
* **validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
* **ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))
<a name="0.4.2"></a>
## [0.4.2](https://github.com/webpack-contrib/schema-utils/compare/v0.4.1...v0.4.2) (2017-11-09)
### Bug Fixes
* **validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))
<a name="0.4.1"></a>
## [0.4.1](https://github.com/webpack-contrib/schema-utils/compare/v0.4.0...v0.4.1) (2017-11-03)
### Bug Fixes
* **ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))
<a name="0.4.0"></a>
# [0.4.0](https://github.com/webpack-contrib/schema-utils/compare/v0.3.0...v0.4.0) (2017-10-28)
### Features
* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))
<a name="0.3.0"></a>
# [0.3.0](https://github.com/webpack-contrib/schema-utils/compare/v0.2.1...v0.3.0) (2017-04-29)
### Features
* add ValidationError ([#8](https://github.com/webpack-contrib/schema-utils/issues/8)) ([d48f0fb](https://github.com/webpack-contrib/schema-utils/commit/d48f0fb))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/webpack-contrib/schema-utils/compare/v0.2.0...v0.2.1) (2017-03-13)
### Bug Fixes
* Include .babelrc to `files` ([28f0363](https://github.com/webpack-contrib/schema-utils/commit/28f0363))
* Include source to `files` ([43b0f2f](https://github.com/webpack-contrib/schema-utils/commit/43b0f2f))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/webpack-contrib/schema-utils/compare/v0.1.0...v0.2.0) (2017-03-12)
<a name="0.1.0"></a>
# 0.1.0 (2017-03-07)
### Features
* **validations:** add validateOptions module ([ae9b47b](https://github.com/webpack-contrib/schema-utils/commit/ae9b47b))
# 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.
+149
View File
@@ -0,0 +1,149 @@
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![test][test]][test-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
<div align="center">
<a href="http://json-schema.org">
<img width="160" height="160"
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/docs/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>
<h1>Schema Utils</h1>
</div>
<h2 align="center">Install</h2>
```bash
npm i schema-utils
```
<h2 align="center">Usage</h2>
### `validateOptions`
**`schema.json`**
```js
{
"type": "object",
"properties": {
// Options...
},
"additionalProperties": false
}
```
#### Error Messages (Custom)
**`schema.json`**
```js
{
"type": "object",
"properties": {
"option": {
"type": [ "boolean" ]
}
},
// Overrides the default err.message for option
"errorMessage": {
"option": "should be {Boolean} (https:/github.com/org/repo#anchor)"
}
"additionalProperties": false
}
```
```js
import schema from 'path/to/schema.json'
import validateOptions from 'schema-utils'
validateOptions(schema, options, 'Loader/Plugin Name')
```
<h2 align="center">Examples</h2>
**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 validateOptions from 'schema-utils'
import schema from 'path/to/schema.json'
function loader (src, map) {
const options = getOptions(this) || {}
validateOptions(schema, options, 'Loader Name')
// Code...
}
```
### `Plugin`
```js
import validateOptions from 'schema-utils'
import schema from 'path/to/schema.json'
class Plugin {
constructor (options) {
validateOptions(schema, options, 'Plugin Name')
this.options = options
}
apply (compiler) {
// Code...
}
}
```
[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-contrib/schema-utils.svg
[deps-url]: https://david-dm.org/webpack-contrib/schema-utils
[test]: http://img.shields.io/travis/webpack-contrib/schema-utils.svg
[test-url]: https://travis-ci.org/webpack-contrib/schema-utils
[cover]: https://codecov.io/gh/webpack-contrib/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/schema-utils
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[chat-url]: https://gitter.im/webpack/webpack
+74
View File
@@ -0,0 +1,74 @@
{
"_from": "schema-utils@^1.0.0",
"_id": "schema-utils@1.0.0",
"_inBundle": false,
"_integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"_location": "/webpack-dev-server/schema-utils",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "schema-utils@^1.0.0",
"name": "schema-utils",
"escapedName": "schema-utils",
"rawSpec": "^1.0.0",
"saveSpec": null,
"fetchSpec": "^1.0.0"
},
"_requiredBy": [
"/webpack-dev-server"
],
"_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"_shasum": "0b79a93204d7b600d4b2850d1f66c2a34951c770",
"_spec": "schema-utils@^1.0.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server",
"author": {
"name": "webpack Contrib",
"url": "https://github.com/webpack-contrib"
},
"bugs": {
"url": "https://github.com/webpack-contrib/schema-utils/issues"
},
"bundleDependencies": false,
"dependencies": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
},
"deprecated": false,
"description": "webpack Validation Utils",
"devDependencies": {
"@commitlint/cli": "^7.0.0",
"@commitlint/config-conventional": "^7.0.0",
"@webpack-contrib/eslint-config-webpack": "^2.0.0",
"del-cli": "^1.0.0",
"eslint": "^5.0.0",
"eslint-plugin-import": "^2.0.0",
"eslint-plugin-prettier": "^2.0.0",
"jest": "^21.0.0",
"prettier": "^1.0.0",
"standard-version": "^4.0.0"
},
"engines": {
"node": ">= 4"
},
"files": [
"src"
],
"homepage": "https://github.com/webpack-contrib/schema-utils",
"license": "MIT",
"main": "src/index.js",
"name": "schema-utils",
"repository": {
"type": "git",
"url": "git+https://github.com/webpack-contrib/schema-utils.git"
},
"scripts": {
"clean": "del-cli coverage",
"commits": "commitlint --from $(git rev-list --tags --max-count=1)",
"lint": "eslint --cache src test",
"release": "npm run commits && standard-version",
"test": "jest --env node --verbose --coverage"
},
"version": "1.0.0"
}
@@ -0,0 +1,30 @@
/* eslint-disable
strict,
no-param-reassign
*/
'use strict';
class ValidationError extends Error {
constructor(errors, name) {
super();
this.name = 'ValidationError';
this.message = `${name || ''} Invalid Options\n\n`;
this.errors = errors.map((err) => {
err.dataPath = err.dataPath.replace(/\//g, '.');
return err;
});
this.errors.forEach((err) => {
this.message += `options${err.dataPath} ${err.message}\n`;
});
Error.captureStackTrace(this, this.constructor);
}
}
module.exports = ValidationError;
@@ -0,0 +1,9 @@
/* eslint-disable
strict
*/
'use strict';
const validateOptions = require('./validateOptions');
module.exports = validateOptions;
@@ -0,0 +1,38 @@
/* eslint-disable
strict,
no-param-reassign
*/
'use strict';
const fs = require('fs');
const path = require('path');
const Ajv = require('ajv');
const errors = require('ajv-errors');
const keywords = require('ajv-keywords');
const ValidationError = require('./ValidationError');
const ajv = new Ajv({
allErrors: true,
jsonPointers: true,
});
errors(ajv);
keywords(ajv, ['instanceof', 'typeof']);
const validateOptions = (schema, options, name) => {
if (typeof schema === 'string') {
schema = fs.readFileSync(path.resolve(schema), 'utf8');
schema = JSON.parse(schema);
}
if (!ajv.validate(schema, options)) {
throw new ValidationError(ajv.errors, name);
}
return true;
};
module.exports = validateOptions;
+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'))
}
+60
View File
@@ -0,0 +1,60 @@
{
"_from": "semver@^6.3.0",
"_id": "semver@6.3.0",
"_inBundle": false,
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"_location": "/webpack-dev-server/semver",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "semver@^6.3.0",
"name": "semver",
"escapedName": "semver",
"rawSpec": "^6.3.0",
"saveSpec": null,
"fetchSpec": "^6.3.0"
},
"_requiredBy": [
"/webpack-dev-server"
],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_shasum": "ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
"_spec": "semver@^6.3.0",
"_where": "/home/george/citwa/red_de_investigacion_front/first/node_modules/webpack-dev-server",
"bin": {
"semver": "./bin/semver.js"
},
"bugs": {
"url": "https://github.com/npm/node-semver/issues"
},
"bundleDependencies": false,
"deprecated": false,
"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

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