forked from daren.hsu/line_push
update
This commit is contained in:
+227
-184
@@ -25,11 +25,6 @@ Some of the benefits of using this middleware include:
|
||||
has completed.
|
||||
- Supports hot module reload (HMR).
|
||||
|
||||
## Requirements
|
||||
|
||||
This module requires a minimum of Node v6.9.0 and Webpack v4.0.0, and must be used with a
|
||||
server that accepts express-style middleware.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First thing's first, install the module:
|
||||
@@ -43,12 +38,12 @@ _Note: We do not recommend installing this module globally._
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const webpack = require('webpack');
|
||||
const middleware = require('webpack-dev-middleware');
|
||||
const webpack = require("webpack");
|
||||
const middleware = require("webpack-dev-middleware");
|
||||
const compiler = webpack({
|
||||
// webpack options
|
||||
});
|
||||
const express = require('express');
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
|
||||
app.use(
|
||||
@@ -57,195 +52,145 @@ app.use(
|
||||
})
|
||||
);
|
||||
|
||||
app.listen(3000, () => console.log('Example app listening on port 3000!'));
|
||||
app.listen(3000, () => console.log("Example app listening on port 3000!"));
|
||||
```
|
||||
|
||||
See [below](#other-servers) for an example of use with fastify.
|
||||
|
||||
## Options
|
||||
|
||||
The middleware accepts an `options` Object. The following is a property reference
|
||||
for the Object.
|
||||
|
||||
_Note: The `publicPath` property is required, whereas all other options are optional_
|
||||
The middleware accepts an `options` Object. The following is a property reference for the Object.
|
||||
|
||||
### methods
|
||||
|
||||
Type: `Array`
|
||||
Default: `[ 'GET', 'HEAD' ]`
|
||||
|
||||
This property allows a user to pass the list of HTTP request methods accepted by the server.
|
||||
This property allows a user to pass the list of HTTP request methods accepted by the middleware\*\*.
|
||||
|
||||
### headers
|
||||
|
||||
Type: `Object`
|
||||
Type: `Object|Function`
|
||||
Default: `undefined`
|
||||
|
||||
This property allows a user to pass custom HTTP headers on each request. eg.
|
||||
`{ "X-Custom-Header": "yes" }`
|
||||
This property allows a user to pass custom HTTP headers on each request.
|
||||
eg. `{ "X-Custom-Header": "yes" }`
|
||||
|
||||
or
|
||||
|
||||
```js
|
||||
webpackDevMiddleware(compiler, {
|
||||
headers: () => {
|
||||
return {
|
||||
"Last-Modified": new Date(),
|
||||
};
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```js
|
||||
webpackDevMiddleware(compiler, {
|
||||
headers: (req, res, context) => {
|
||||
res.setHeader("Last-Modified", new Date());
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### index
|
||||
|
||||
Type: `String`
|
||||
Default: `undefined`
|
||||
Type: `Boolean|String`
|
||||
Default: `index.html`
|
||||
|
||||
"index.html",
|
||||
// The index path for web server, defaults to "index.html".
|
||||
// If falsy (but not undefined), the server will not respond to requests to the root URL.
|
||||
|
||||
### lazy
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `undefined`
|
||||
|
||||
This option instructs the module to operate in 'lazy' mode, meaning that it won't
|
||||
recompile when files change, but rather on each request.
|
||||
|
||||
### logger
|
||||
|
||||
Type: `Object`
|
||||
Default: [`webpack-log`](https://github.com/webpack-contrib/webpack-log/blob/master/index.js)
|
||||
|
||||
In the rare event that a user would like to provide a custom logging interface,
|
||||
this property allows the user to assign one. The module leverages
|
||||
[`webpack-log`](https://github.com/webpack-contrib/webpack-log#readme)
|
||||
for creating the [`loglevelnext`](https://github.com/shellscape/loglevelnext#readme)
|
||||
logging management by default. Any custom logger must adhere to the same
|
||||
exports for compatibility. Specifically, all custom loggers must have the
|
||||
following exported methods at a minimum:
|
||||
|
||||
- `log.trace`
|
||||
- `log.debug`
|
||||
- `log.info`
|
||||
- `log.warn`
|
||||
- `log.error`
|
||||
|
||||
Please see the documentation for `loglevel` for more information.
|
||||
|
||||
### logLevel
|
||||
|
||||
Type: `String`
|
||||
Default: `'info'`
|
||||
|
||||
This property defines the level of messages that the module will log. Valid levels
|
||||
include:
|
||||
|
||||
- `trace`
|
||||
- `debug`
|
||||
- `info`
|
||||
- `warn`
|
||||
- `error`
|
||||
- `silent`
|
||||
|
||||
Setting a log level means that all other levels below it will be visible in the
|
||||
console. Setting `logLevel: 'silent'` will hide all console output. The module
|
||||
leverages [`webpack-log`](https://github.com/webpack-contrib/webpack-log#readme)
|
||||
for logging management, and more information can be found on its page.
|
||||
|
||||
### logTime
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `false`
|
||||
|
||||
If `true` the log output of the module will be prefixed by a timestamp in the
|
||||
`HH:mm:ss` format.
|
||||
If `false` (but not `undefined`), the server will not respond to requests to the root URL.
|
||||
|
||||
### mimeTypes
|
||||
|
||||
Type: `Object`
|
||||
Default: `null`
|
||||
Default: `undefined`
|
||||
|
||||
This property allows a user to register custom mime types or extension mappings.
|
||||
eg. `mimeTypes: { 'text/html': [ 'phtml' ] }`.
|
||||
eg. `mimeTypes: { phtml: 'text/html' }`.
|
||||
|
||||
By default node-mime will throw an error if you try to map a type to an extension
|
||||
that is already assigned to another type. Passing `force: true` will suppress this behavior
|
||||
(overriding any previous mapping).
|
||||
eg. `mimeTypes: { typeMap: { 'text/html': [ 'phtml' ] } }, force: true }`.
|
||||
|
||||
Please see the documentation for
|
||||
[`node-mime`](https://github.com/broofa/node-mime#mimedefinetypemap-force--false) for more information.
|
||||
Please see the documentation for [`mime-types`](https://github.com/jshttp/mime-types) for more information.
|
||||
|
||||
### publicPath
|
||||
|
||||
Type: `String`
|
||||
_Required_
|
||||
Type: `String`
|
||||
Default: `output.publicPath` (from a configuration)
|
||||
|
||||
The public path that the middleware is bound to. _Best Practice: use the same
|
||||
`publicPath` defined in your webpack config. For more information about
|
||||
`publicPath`, please see
|
||||
[the webpack documentation](https://webpack.js.org/guides/public-path)._
|
||||
The public path that the middleware is bound to.
|
||||
|
||||
### reporter
|
||||
_Best Practice: use the same `publicPath` defined in your webpack config. For more information about `publicPath`, please see [the webpack documentation](https://webpack.js.org/guides/public-path)._
|
||||
|
||||
Type: `Object`
|
||||
Default: `undefined`
|
||||
### stats
|
||||
|
||||
Allows users to provide a custom reporter to handle logging within the module.
|
||||
Please see the [default reporter](/lib/reporter.js)
|
||||
for an example.
|
||||
Type: `Boolean|String|Object`
|
||||
Default: `stats` (from a configuration)
|
||||
|
||||
Stats options object or preset name.
|
||||
|
||||
### serverSideRender
|
||||
|
||||
Type: `Boolean`
|
||||
Default: `undefined`
|
||||
|
||||
Instructs the module to enable or disable the server-side rendering mode. Please
|
||||
see [Server-Side Rendering](#server-side-rendering) for more information.
|
||||
|
||||
### stats
|
||||
|
||||
Type: `Object`
|
||||
Default: `{ context: process.cwd() }`
|
||||
|
||||
Options for formatting statistics displayed during and after compile. For more
|
||||
information and property details, please see the
|
||||
[webpack documentation](https://webpack.js.org/configuration/stats/#stats).
|
||||
|
||||
### watchOptions
|
||||
|
||||
Type: `Object`
|
||||
Default: `{ aggregateTimeout: 200 }`
|
||||
|
||||
The module accepts an `Object` containing options for file watching, which is
|
||||
passed directly to the compiler provided. For more information on watch options
|
||||
please see the [webpack documentation](https://webpack.js.org/configuration/watch/#watchoptions)
|
||||
Instructs the module to enable or disable the server-side rendering mode.
|
||||
Please see [Server-Side Rendering](#server-side-rendering) for more information.
|
||||
|
||||
### writeToDisk
|
||||
|
||||
Type: `Boolean|Function`
|
||||
Default: `false`
|
||||
|
||||
If `true`, the option will instruct the module to write files to the configured
|
||||
location on disk as specified in your `webpack` config file. _Setting
|
||||
`writeToDisk: true` won't change the behavior of the `webpack-dev-middleware`,
|
||||
and bundle files accessed through the browser will still be served from memory._
|
||||
This option provides the same capabilities as the
|
||||
[`WriteFilePlugin`](https://github.com/gajus/write-file-webpack-plugin/pulls).
|
||||
If `true`, the option will instruct the module to write files to the configured location on disk as specified in your `webpack` config file.
|
||||
_Setting `writeToDisk: true` won't change the behavior of the `webpack-dev-middleware`, and bundle files accessed through the browser will still be served from memory._
|
||||
This option provides the same capabilities as the [`WriteFilePlugin`](https://github.com/gajus/write-file-webpack-plugin/pulls).
|
||||
|
||||
This option also accepts a `Function` value, which can be used to filter which
|
||||
files are written to disk. The function follows the same premise as
|
||||
[`Array#filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
|
||||
in which a return value of `false` _will not_ write the file, and a return value
|
||||
of `true` _will_ write the file to disk. eg.
|
||||
This option also accepts a `Function` value, which can be used to filter which files are written to disk.
|
||||
The function follows the same premise as [`Array#filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) in which a return value of `false` _will not_ write the file, and a return value of `true` _will_ write the file to disk. eg.
|
||||
|
||||
```js
|
||||
{
|
||||
const webpack = require("webpack");
|
||||
const configuration = {
|
||||
/* Webpack configuration */
|
||||
};
|
||||
const compiler = webpack(configuration);
|
||||
|
||||
middleware(compiler, {
|
||||
writeToDisk: (filePath) => {
|
||||
return /superman\.css$/.test(filePath);
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### fs
|
||||
### outputFileSystem
|
||||
|
||||
Type: `Object`
|
||||
Default: `MemoryFileSystem`
|
||||
Default: [memfs](https://github.com/streamich/memfs)
|
||||
|
||||
Set the default file system which will be used by webpack as primary destination of generated files. Default is set to webpack's default file system: [memory-fs](https://github.com/webpack/memory-fs). This option isn't affected by the [writeToDisk](#writeToDisk) option.
|
||||
Set the default file system which will be used by webpack as primary destination of generated files.
|
||||
This option isn't affected by the [writeToDisk](#writeToDisk) option.
|
||||
|
||||
**Note:** As of 3.5.x version of the middleware you have to provide `.join()` method to the `fs` instance manually. This can be done simply by using `path.join`:
|
||||
You have to provide `.join()` and `mkdirp` method to the `outputFileSystem` instance manually for compatibility with `webpack@4`.
|
||||
|
||||
This can be done simply by using `path.join`:
|
||||
|
||||
```js
|
||||
fs.join = path.join; // no need to bind
|
||||
const webpack = require("webpack");
|
||||
const path = require("path");
|
||||
const myOutputFileSystem = require("my-fs");
|
||||
const mkdirp = require("mkdirp");
|
||||
|
||||
myOutputFileSystem.join = path.join.bind(path); // no need to bind
|
||||
myOutputFileSystem.mkdirp = mkdirp.bind(mkdirp); // no need to bind
|
||||
|
||||
const compiler = webpack({
|
||||
/* Webpack configuration */
|
||||
});
|
||||
|
||||
middleware(compiler, { outputFileSystem: myOutputFileSystem });
|
||||
```
|
||||
|
||||
## API
|
||||
@@ -255,33 +200,65 @@ interact with the middleware at runtime:
|
||||
|
||||
### `close(callback)`
|
||||
|
||||
Instructs a webpack-dev-middleware instance to stop watching for file changes.
|
||||
Instructs `webpack-dev-middleware` instance to stop watching for file changes.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
#### callback
|
||||
##### `callback`
|
||||
|
||||
Type: `Function`
|
||||
Required: `No`
|
||||
|
||||
A function executed once the middleware has stopped watching.
|
||||
|
||||
### `invalidate()`
|
||||
|
||||
Instructs a webpack-dev-middleware instance to recompile the bundle.
|
||||
e.g. after a change to the configuration.
|
||||
|
||||
```js
|
||||
const webpack = require('webpack');
|
||||
const compiler = webpack({ ... });
|
||||
const middleware = require('webpack-dev-middleware');
|
||||
const express = require("express");
|
||||
const webpack = require("webpack");
|
||||
const compiler = webpack({
|
||||
/* Webpack configuration */
|
||||
});
|
||||
const middleware = require("webpack-dev-middleware");
|
||||
const instance = middleware(compiler);
|
||||
|
||||
const app = new express();
|
||||
|
||||
app.use(instance);
|
||||
|
||||
setTimeout(() => {
|
||||
// After a short delay the configuration is changed and a banner plugin is added
|
||||
// to the config
|
||||
compiler.apply(new webpack.BannerPlugin('A new banner'));
|
||||
// Says `webpack` to stop watch changes
|
||||
instance.close();
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
### `invalidate(callback)`
|
||||
|
||||
Instructs `webpack-dev-middleware` instance to recompile the bundle, e.g. after a change to the configuration.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### `callback`
|
||||
|
||||
Type: `Function`
|
||||
Required: `No`
|
||||
|
||||
A function executed once the middleware has invalidated.
|
||||
|
||||
```js
|
||||
const express = require("express");
|
||||
const webpack = require("webpack");
|
||||
const compiler = webpack({
|
||||
/* Webpack configuration */
|
||||
});
|
||||
const middleware = require("webpack-dev-middleware");
|
||||
const instance = middleware(compiler);
|
||||
|
||||
const app = new express();
|
||||
|
||||
app.use(instance);
|
||||
|
||||
setTimeout(() => {
|
||||
// After a short delay the configuration is changed and a banner plugin is added to the config
|
||||
new webpack.BannerPlugin("A new banner").apply(compiler);
|
||||
|
||||
// Recompile the bundle with the banner plugin:
|
||||
instance.invalidate();
|
||||
@@ -293,25 +270,64 @@ setTimeout(() => {
|
||||
Executes a callback function when the compiler bundle is valid, typically after
|
||||
compilation.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
#### callback
|
||||
##### `callback`
|
||||
|
||||
Type: `Function`
|
||||
Required: `No`
|
||||
|
||||
A function executed when the bundle becomes valid. If the bundle is
|
||||
valid at the time of calling, the callback is executed immediately.
|
||||
A function executed when the bundle becomes valid.
|
||||
If the bundle is valid at the time of calling, the callback is executed immediately.
|
||||
|
||||
```js
|
||||
const webpack = require('webpack');
|
||||
const compiler = webpack({ ... });
|
||||
const middleware = require('webpack-dev-middleware');
|
||||
const express = require("express");
|
||||
const webpack = require("webpack");
|
||||
const compiler = webpack({
|
||||
/* Webpack configuration */
|
||||
});
|
||||
const middleware = require("webpack-dev-middleware");
|
||||
const instance = middleware(compiler);
|
||||
|
||||
const app = new express();
|
||||
|
||||
app.use(instance);
|
||||
|
||||
instance.waitUntilValid(() => {
|
||||
console.log('Package is in a valid state');
|
||||
console.log("Package is in a valid state");
|
||||
});
|
||||
```
|
||||
|
||||
### `getFilenameFromUrl(url)`
|
||||
|
||||
Get filename from URL.
|
||||
|
||||
#### Parameters
|
||||
|
||||
##### `url`
|
||||
|
||||
Type: `String`
|
||||
Required: `Yes`
|
||||
|
||||
URL for the requested file.
|
||||
|
||||
```js
|
||||
const express = require("express");
|
||||
const webpack = require("webpack");
|
||||
const compiler = webpack({
|
||||
/* Webpack configuration */
|
||||
});
|
||||
const middleware = require("webpack-dev-middleware");
|
||||
const instance = middleware(compiler);
|
||||
|
||||
const app = new express();
|
||||
|
||||
app.use(instance);
|
||||
|
||||
instance.waitUntilValid(() => {
|
||||
const filename = instance.getFilenameFromUrl("/bundle.js");
|
||||
|
||||
console.log(`Filename is ${filename}`);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,7 +335,7 @@ instance.waitUntilValid(() => {
|
||||
|
||||
### Multiple Successive Builds
|
||||
|
||||
Watching (by means of `lazy: false`) will frequently cause multiple compilations
|
||||
Watching will frequently cause multiple compilations
|
||||
as the bundle changes during compilation. This is due in part to cross-platform
|
||||
differences in file watchers, so that webpack doesn't loose file changes when
|
||||
watched files change rapidly. If you run into this situation, please make use of
|
||||
@@ -333,9 +349,9 @@ In order to develop an app using server-side rendering, we need access to the
|
||||
[`stats`](https://github.com/webpack/docs/wiki/node.js-api#stats), which is
|
||||
generated with each build.
|
||||
|
||||
With server-side rendering enabled, `webpack-dev-middleware` sets the `stat` to
|
||||
`res.locals.webpackStats` and the memory filesystem to `res.locals.fs` before invoking the next middleware, allowing a
|
||||
developer to render the page body and manage the response to clients.
|
||||
With server-side rendering enabled, `webpack-dev-middleware` sets the `stats` to `res.locals.webpack.devMiddleware.stats`
|
||||
and the filesystem to `res.locals.webpack.devMiddleware.outputFileSystem` before invoking the next middleware,
|
||||
allowing a developer to render the page body and manage the response to clients.
|
||||
|
||||
_Note: Requests for bundle files will still be handled by
|
||||
`webpack-dev-middleware` and all requests will be pending until the build
|
||||
@@ -344,12 +360,15 @@ process is finished with server-side rendering enabled._
|
||||
Example Implementation:
|
||||
|
||||
```js
|
||||
const webpack = require('webpack');
|
||||
const express = require("express");
|
||||
const webpack = require("webpack");
|
||||
const compiler = webpack({
|
||||
// webpack options
|
||||
/* Webpack configuration */
|
||||
});
|
||||
const isObject = require('is-object');
|
||||
const middleware = require('webpack-dev-middleware');
|
||||
const isObject = require("is-object");
|
||||
const middleware = require("webpack-dev-middleware");
|
||||
|
||||
const app = new express();
|
||||
|
||||
// This function makes server rendering of asset references consistent with different webpack chunk/entry configurations
|
||||
function normalizeAssets(assets) {
|
||||
@@ -364,11 +383,12 @@ app.use(middleware(compiler, { serverSideRender: true }));
|
||||
|
||||
// The following middleware would not be invoked until the latest build is finished.
|
||||
app.use((req, res) => {
|
||||
const assetsByChunkName = res.locals.webpackStats.toJson().assetsByChunkName;
|
||||
const fs = res.locals.fs;
|
||||
const outputPath = res.locals.webpackStats.toJson().outputPath;
|
||||
const { devMiddleware } = res.locals.webpack;
|
||||
const outputFileSystem = devMiddleware.outputFileSystem;
|
||||
const jsonWebpackStats = devMiddleware.stats.toJson();
|
||||
const { assetsByChunkName, outputPath } = jsonWebpackStats;
|
||||
|
||||
// then use `assetsByChunkName` for server-sider rendering
|
||||
// Then use `assetsByChunkName` for server-side rendering
|
||||
// For example, if you have only one main chunk:
|
||||
res.send(`
|
||||
<html>
|
||||
@@ -376,17 +396,17 @@ app.use((req, res) => {
|
||||
<title>My App</title>
|
||||
<style>
|
||||
${normalizeAssets(assetsByChunkName.main)
|
||||
.filter((path) => path.endsWith('.css'))
|
||||
.map((path) => fs.readFileSync(outputPath + '/' + path))
|
||||
.join('\n')}
|
||||
.filter((path) => path.endsWith(".css"))
|
||||
.map((path) => outputFileSystem.readFileSync(path.join(outputPath, path)))
|
||||
.join("\n")}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
${normalizeAssets(assetsByChunkName.main)
|
||||
.filter((path) => path.endsWith('.js'))
|
||||
.filter((path) => path.endsWith(".js"))
|
||||
.map((path) => `<script src="${path}"></script>`)
|
||||
.join('\n')}
|
||||
.join("\n")}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
@@ -419,11 +439,35 @@ 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._
|
||||
|
||||
## Other servers
|
||||
|
||||
Examples of use with other servers will follow here.
|
||||
|
||||
### Fastify
|
||||
|
||||
Fastify interop will require the use of `fastify-express` instead of `middie` for providing middleware support. As the authors of `fastify-express` recommend, this should only be used as a stopgap while full Fastify support is worked on.
|
||||
|
||||
```js
|
||||
const fastify = require("fastify")();
|
||||
const webpack = require("webpack");
|
||||
const webpackConfig = require("./webpack.config.js");
|
||||
const devMiddleware = require("webpack-dev-middleware");
|
||||
|
||||
const compiler = webpack(webpackConfig);
|
||||
const { publicPath } = webpackConfig.output;
|
||||
|
||||
(async () => {
|
||||
await fastify.register(require("fastify-express"));
|
||||
await fastify.use(devMiddleware(compiler, { publicPath }));
|
||||
await fastify.listen(3000);
|
||||
})();
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please take a moment to read our contributing guidelines if you haven't yet done so.
|
||||
|
||||
[CONTRIBUTING](./.github/CONTRIBUTING.md)
|
||||
[CONTRIBUTING](./CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
@@ -435,17 +479,16 @@ Please take a moment to read our contributing guidelines if you haven't yet done
|
||||
[node-url]: https://nodejs.org
|
||||
[deps]: https://david-dm.org/webpack/webpack-dev-middleware.svg
|
||||
[deps-url]: https://david-dm.org/webpack/webpack-dev-middleware
|
||||
[tests]: https://dev.azure.com/webpack/webpack-dev-middleware/_apis/build/status/webpack.webpack-dev-middleware?branchName=master
|
||||
[tests-url]: https://dev.azure.com/webpack/webpack-dev-middleware/_build/latest?definitionId=8&branchName=master
|
||||
[tests]: https://github.com/webpack/webpack-dev-middleware/workflows/webpack-dev-middleware/badge.svg
|
||||
[tests-url]: https://github.com/webpack/webpack-dev-middleware/actions
|
||||
[cover]: https://codecov.io/gh/webpack/webpack-dev-middleware/branch/master/graph/badge.svg
|
||||
[cover-url]: https://codecov.io/gh/webpack/webpack-dev-middleware
|
||||
[chat]: https://badges.gitter.im/webpack/webpack.svg
|
||||
[chat-url]: https://gitter.im/webpack/webpack
|
||||
[size]: https://packagephobia.now.sh/badge?p=webpack-dev-middleware
|
||||
[size-url]: https://packagephobia.now.sh/result?p=webpack-dev-middleware
|
||||
[size]: https://packagephobia.com/badge?p=webpack-dev-middleware
|
||||
[size-url]: https://packagephobia.com/result?p=webpack-dev-middleware
|
||||
[docs-url]: https://webpack.js.org/guides/development/#using-webpack-dev-middleware
|
||||
[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-middleware
|
||||
[uglify-url]: https://github.com/webpack-contrib/uglifyjs-webpack-plugin
|
||||
[wjo-url]: https://github.com/webpack/webpack.js.org
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const middleware = require("./index");
|
||||
|
||||
module.exports = middleware.default;
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = wdm;
|
||||
|
||||
var _schemaUtils = require("schema-utils");
|
||||
|
||||
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
||||
|
||||
var _middleware = _interopRequireDefault(require("./middleware"));
|
||||
|
||||
var _getFilenameFromUrl = _interopRequireDefault(require("./utils/getFilenameFromUrl"));
|
||||
|
||||
var _setupHooks = _interopRequireDefault(require("./utils/setupHooks"));
|
||||
|
||||
var _setupWriteToDisk = _interopRequireDefault(require("./utils/setupWriteToDisk"));
|
||||
|
||||
var _setupOutputFileSystem = _interopRequireDefault(require("./utils/setupOutputFileSystem"));
|
||||
|
||||
var _ready = _interopRequireDefault(require("./utils/ready"));
|
||||
|
||||
var _options = _interopRequireDefault(require("./options.json"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
function wdm(compiler, options = {}) {
|
||||
(0, _schemaUtils.validate)(_options.default, options, {
|
||||
name: "Dev Middleware",
|
||||
baseDataPath: "options"
|
||||
});
|
||||
const {
|
||||
mimeTypes
|
||||
} = options;
|
||||
|
||||
if (mimeTypes) {
|
||||
const {
|
||||
types
|
||||
} = _mimeTypes.default; // mimeTypes from user provided options should take priority
|
||||
// over existing, known types
|
||||
|
||||
_mimeTypes.default.types = { ...types,
|
||||
...mimeTypes
|
||||
};
|
||||
}
|
||||
|
||||
const context = {
|
||||
state: false,
|
||||
stats: null,
|
||||
callbacks: [],
|
||||
options,
|
||||
compiler,
|
||||
watching: null
|
||||
}; // eslint-disable-next-line no-param-reassign
|
||||
|
||||
context.logger = context.compiler.getInfrastructureLogger("webpack-dev-middleware");
|
||||
(0, _setupHooks.default)(context);
|
||||
|
||||
if (options.writeToDisk) {
|
||||
(0, _setupWriteToDisk.default)(context);
|
||||
}
|
||||
|
||||
(0, _setupOutputFileSystem.default)(context); // Start watching
|
||||
|
||||
if (context.compiler.watching) {
|
||||
context.watching = context.compiler.watching;
|
||||
} else {
|
||||
let watchOptions;
|
||||
|
||||
if (Array.isArray(context.compiler.compilers)) {
|
||||
watchOptions = context.compiler.compilers.map(childCompiler => childCompiler.options.watchOptions || {});
|
||||
} else {
|
||||
watchOptions = context.compiler.options.watchOptions || {};
|
||||
}
|
||||
|
||||
context.watching = context.compiler.watch(watchOptions, error => {
|
||||
if (error) {
|
||||
// TODO: improve that in future
|
||||
// For example - `writeToDisk` can throw an error and right now it is ends watching.
|
||||
// We can improve that and keep watching active, but it is require API on webpack side.
|
||||
// Let's implement that in webpack@5 because it is rare case.
|
||||
context.logger.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const instance = (0, _middleware.default)(context); // API
|
||||
|
||||
instance.getFilenameFromUrl = url => (0, _getFilenameFromUrl.default)(context, url);
|
||||
|
||||
instance.waitUntilValid = (callback = noop) => {
|
||||
(0, _ready.default)(context, callback);
|
||||
};
|
||||
|
||||
instance.invalidate = (callback = noop) => {
|
||||
(0, _ready.default)(context, callback);
|
||||
context.watching.invalidate();
|
||||
};
|
||||
|
||||
instance.close = (callback = noop) => {
|
||||
context.watching.close(callback);
|
||||
};
|
||||
|
||||
instance.context = context;
|
||||
return instance;
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = wrapper;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
||||
|
||||
var _getFilenameFromUrl = _interopRequireDefault(require("./utils/getFilenameFromUrl"));
|
||||
|
||||
var _handleRangeHeaders = _interopRequireDefault(require("./utils/handleRangeHeaders"));
|
||||
|
||||
var _ready = _interopRequireDefault(require("./utils/ready"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function wrapper(context) {
|
||||
return async function middleware(req, res, next) {
|
||||
const acceptedMethods = context.options.methods || ["GET", "HEAD"]; // fixes #282. credit @cexoso. in certain edge situations res.locals is undefined.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
res.locals = res.locals || {};
|
||||
|
||||
if (!acceptedMethods.includes(req.method)) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
(0, _ready.default)(context, processRequest, req);
|
||||
|
||||
async function goNext() {
|
||||
if (!context.options.serverSideRender) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
(0, _ready.default)(context, () => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.locals.webpack = {
|
||||
devMiddleware: context
|
||||
};
|
||||
resolve(next());
|
||||
}, req);
|
||||
});
|
||||
}
|
||||
|
||||
async function processRequest() {
|
||||
const filename = (0, _getFilenameFromUrl.default)(context, req.url);
|
||||
let {
|
||||
headers
|
||||
} = context.options;
|
||||
|
||||
if (typeof headers === "function") {
|
||||
headers = headers(req, res, context);
|
||||
}
|
||||
|
||||
let content;
|
||||
|
||||
if (!filename) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
content = context.outputFileSystem.readFileSync(filename);
|
||||
} catch (_ignoreError) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
|
||||
const contentTypeHeader = res.get ? res.get("Content-Type") : res.getHeader("Content-Type");
|
||||
|
||||
if (!contentTypeHeader) {
|
||||
// content-type name(like application/javascript; charset=utf-8) or false
|
||||
const contentType = _mimeTypes.default.contentType(_path.default.extname(filename)); // Only set content-type header if media type is known
|
||||
// https://tools.ietf.org/html/rfc7231#section-3.1.1.5
|
||||
|
||||
|
||||
if (contentType) {
|
||||
// Express API
|
||||
if (res.set) {
|
||||
res.set("Content-Type", contentType);
|
||||
} // Node.js API
|
||||
else {
|
||||
res.setHeader("Content-Type", contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (headers) {
|
||||
const names = Object.keys(headers);
|
||||
|
||||
for (const name of names) {
|
||||
// Express API
|
||||
if (res.set) {
|
||||
res.set(name, headers[name]);
|
||||
} // Node.js API
|
||||
else {
|
||||
res.setHeader(name, headers[name]);
|
||||
}
|
||||
}
|
||||
} // Buffer
|
||||
|
||||
|
||||
content = (0, _handleRangeHeaders.default)(context, content, req, res); // Express API
|
||||
|
||||
if (res.send) {
|
||||
res.send(content);
|
||||
} // Node.js API
|
||||
else {
|
||||
res.setHeader("Content-Length", content.length);
|
||||
|
||||
if (req.method === "HEAD") {
|
||||
res.end();
|
||||
} else {
|
||||
res.end(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mimeTypes": {
|
||||
"description": "Allows a user to register custom mime types or extension mappings.",
|
||||
"type": "object"
|
||||
},
|
||||
"writeToDisk": {
|
||||
"description": "Allows to write generated files on disk.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"methods": {
|
||||
"description": "Allows to pass the list of HTTP request methods accepted by the middleware.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minlength": "1"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"publicPath": {
|
||||
"description": "The `publicPath` specifies the public URL address of the output files when referenced in a browser.",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": ["auto"]
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stats": {
|
||||
"description": "Stats options object or preset name.",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": [
|
||||
"none",
|
||||
"summary",
|
||||
"errors-only",
|
||||
"errors-warnings",
|
||||
"minimal",
|
||||
"normal",
|
||||
"detailed",
|
||||
"verbose"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"serverSideRender": {
|
||||
"description": "Instructs the module to enable or disable the server-side rendering mode.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"outputFileSystem": {
|
||||
"description": "Set the default file system which will be used by webpack as primary destination of generated files.",
|
||||
"type": "object"
|
||||
},
|
||||
"index": {
|
||||
"description": "Allows to serve an index of the directory.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"minlength": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = getFilenameFromUrl;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _url = require("url");
|
||||
|
||||
var _querystring = _interopRequireDefault(require("querystring"));
|
||||
|
||||
var _mem = _interopRequireDefault(require("mem"));
|
||||
|
||||
var _getPaths = _interopRequireDefault(require("./getPaths"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const memoizedParse = (0, _mem.default)(_url.parse);
|
||||
|
||||
function getFilenameFromUrl(context, url) {
|
||||
const {
|
||||
options
|
||||
} = context;
|
||||
const paths = (0, _getPaths.default)(context);
|
||||
let foundFilename;
|
||||
let urlObject;
|
||||
|
||||
try {
|
||||
// The `url` property of the `request` is contains only `pathname`, `search` and `hash`
|
||||
urlObject = memoizedParse(url, false, true);
|
||||
} catch (_ignoreError) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const {
|
||||
publicPath,
|
||||
outputPath
|
||||
} of paths) {
|
||||
let filename;
|
||||
let publicPathObject;
|
||||
|
||||
try {
|
||||
publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (urlObject.pathname && urlObject.pathname.startsWith(publicPathObject.pathname)) {
|
||||
filename = outputPath; // Strip the `pathname` property from the `publicPath` option from the start of requested url
|
||||
// `/complex/foo.js` => `foo.js`
|
||||
|
||||
const pathname = urlObject.pathname.substr(publicPathObject.pathname.length);
|
||||
|
||||
if (pathname) {
|
||||
filename = _path.default.join(outputPath, _querystring.default.unescape(pathname));
|
||||
}
|
||||
|
||||
let fsStats;
|
||||
|
||||
try {
|
||||
fsStats = context.outputFileSystem.statSync(filename);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fsStats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
} else if (fsStats.isDirectory() && (typeof options.index === "undefined" || options.index)) {
|
||||
const indexValue = typeof options.index === "undefined" || typeof options.index === "boolean" ? "index.html" : options.index;
|
||||
filename = _path.default.join(filename, indexValue);
|
||||
|
||||
try {
|
||||
fsStats = context.outputFileSystem.statSync(filename);
|
||||
} catch (__ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fsStats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // eslint-disable-next-line consistent-return
|
||||
|
||||
|
||||
return foundFilename;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = getPaths;
|
||||
|
||||
function getPaths(context) {
|
||||
const {
|
||||
stats,
|
||||
options
|
||||
} = context;
|
||||
const childStats = stats.stats ? stats.stats : [stats];
|
||||
const publicPaths = [];
|
||||
|
||||
for (const {
|
||||
compilation
|
||||
} of childStats) {
|
||||
// The `output.path` is always present and always absolute
|
||||
const outputPath = compilation.getPath(compilation.outputOptions.path);
|
||||
const publicPath = options.publicPath ? compilation.getPath(options.publicPath) : compilation.outputOptions.publicPath ? compilation.getPath(compilation.outputOptions.publicPath) : "";
|
||||
publicPaths.push({
|
||||
outputPath,
|
||||
publicPath
|
||||
});
|
||||
}
|
||||
|
||||
return publicPaths;
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = handleRangeHeaders;
|
||||
|
||||
var _rangeParser = _interopRequireDefault(require("range-parser"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function handleRangeHeaders(context, content, req, res) {
|
||||
// assumes express API. For other servers, need to add logic to access
|
||||
// alternative header APIs
|
||||
if (res.set) {
|
||||
res.set("Accept-Ranges", "bytes");
|
||||
} else {
|
||||
res.setHeader("Accept-Ranges", "bytes");
|
||||
}
|
||||
|
||||
let range; // Express API
|
||||
|
||||
if (req.get) {
|
||||
range = req.get("range");
|
||||
} // Node.js API
|
||||
else {
|
||||
({
|
||||
range
|
||||
} = req.headers);
|
||||
}
|
||||
|
||||
if (range) {
|
||||
const ranges = (0, _rangeParser.default)(content.length, range); // unsatisfiable
|
||||
|
||||
if (ranges === -1) {
|
||||
// Express API
|
||||
if (res.set) {
|
||||
res.set("Content-Range", `bytes */${content.length}`);
|
||||
res.status(416);
|
||||
} // Node.js API
|
||||
else {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.statusCode = 416;
|
||||
res.setHeader("Content-Range", `bytes */${content.length}`);
|
||||
}
|
||||
} else if (ranges === -2) {
|
||||
// malformed header treated as regular response
|
||||
context.logger.error("A malformed Range header was provided. A regular response will be sent for this request.");
|
||||
} else if (ranges.length !== 1) {
|
||||
// multiple ranges treated as regular response
|
||||
context.logger.error("A Range header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.");
|
||||
} else {
|
||||
// valid range header
|
||||
const {
|
||||
length
|
||||
} = content; // Express API
|
||||
|
||||
if (res.set) {
|
||||
// Content-Range
|
||||
res.status(206);
|
||||
res.set("Content-Range", `bytes ${ranges[0].start}-${ranges[0].end}/${length}`);
|
||||
} // Node.js API
|
||||
else {
|
||||
// Content-Range
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.statusCode = 206;
|
||||
res.setHeader("Content-Range", `bytes ${ranges[0].start}-${ranges[0].end}/${length}`);
|
||||
} // eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
content = content.slice(ranges[0].start, ranges[0].end + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = ready;
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
function ready(context, callback, req) {
|
||||
if (context.state) {
|
||||
return callback(context.stats);
|
||||
}
|
||||
|
||||
const name = req && req.url || callback.name;
|
||||
context.logger.info(`wait until bundle finished${name ? `: ${name}` : ""}`);
|
||||
context.callbacks.push(callback);
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = setupHooks;
|
||||
|
||||
var _webpack = _interopRequireDefault(require("webpack"));
|
||||
|
||||
var _colorette = _interopRequireDefault(require("colorette"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function setupHooks(context) {
|
||||
function invalid() {
|
||||
if (context.state) {
|
||||
context.logger.log("Compilation starting...");
|
||||
} // We are now in invalid state
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
context.state = false; // eslint-disable-next-line no-param-reassign, no-undefined
|
||||
|
||||
context.stats = undefined;
|
||||
}
|
||||
|
||||
const statsForWebpack4 = _webpack.default.Stats && _webpack.default.Stats.presetToOptions;
|
||||
|
||||
function normalizeStatsOptions(statsOptions) {
|
||||
if (statsForWebpack4) {
|
||||
if (typeof statsOptions === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {};
|
||||
} else if (typeof statsOptions === "boolean" || typeof statsOptions === "string") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = _webpack.default.Stats.presetToOptions(statsOptions);
|
||||
}
|
||||
|
||||
return statsOptions;
|
||||
}
|
||||
|
||||
if (typeof statsOptions === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {
|
||||
preset: "normal"
|
||||
};
|
||||
} else if (typeof statsOptions === "boolean") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = statsOptions ? {
|
||||
preset: "normal"
|
||||
} : {
|
||||
preset: "none"
|
||||
};
|
||||
} else if (typeof statsOptions === "string") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {
|
||||
preset: statsOptions
|
||||
};
|
||||
}
|
||||
|
||||
return statsOptions;
|
||||
}
|
||||
|
||||
function done(stats) {
|
||||
// We are now on valid state
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.state = true; // eslint-disable-next-line no-param-reassign
|
||||
|
||||
context.stats = stats; // Do the stuff in nextTick, because bundle may be invalidated if a change happened while compiling
|
||||
|
||||
process.nextTick(() => {
|
||||
const {
|
||||
compiler,
|
||||
logger,
|
||||
options,
|
||||
state,
|
||||
callbacks
|
||||
} = context; // Check if still in valid state
|
||||
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log("Compilation finished");
|
||||
const isMultiCompilerMode = Boolean(compiler.compilers);
|
||||
let statsOptions;
|
||||
|
||||
if (typeof options.stats !== "undefined") {
|
||||
statsOptions = isMultiCompilerMode ? {
|
||||
children: compiler.compilers.map(() => options.stats)
|
||||
} : options.stats;
|
||||
} else {
|
||||
statsOptions = isMultiCompilerMode ? {
|
||||
children: compiler.compilers.map(child => child.options.stats)
|
||||
} : compiler.options.stats;
|
||||
}
|
||||
|
||||
if (isMultiCompilerMode) {
|
||||
statsOptions.children = statsOptions.children.map(childStatsOptions => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
childStatsOptions = normalizeStatsOptions(childStatsOptions);
|
||||
|
||||
if (typeof childStatsOptions.colors === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
childStatsOptions.colors = Boolean(_colorette.default.options.enabled);
|
||||
}
|
||||
|
||||
return childStatsOptions;
|
||||
});
|
||||
} else {
|
||||
statsOptions = normalizeStatsOptions(statsOptions);
|
||||
|
||||
if (typeof statsOptions.colors === "undefined") {
|
||||
statsOptions.colors = Boolean(_colorette.default.options.enabled);
|
||||
}
|
||||
} // TODO webpack@4 doesn't support `{ children: [{ colors: true }, { colors: true }] }` for stats
|
||||
|
||||
|
||||
if (compiler.compilers && statsForWebpack4) {
|
||||
statsOptions.colors = statsOptions.children.some(child => child.colors);
|
||||
}
|
||||
|
||||
const printedStats = stats.toString(statsOptions); // Avoid extra empty line when `stats: 'none'`
|
||||
|
||||
if (printedStats) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(printedStats);
|
||||
} // eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
context.callbacks = []; // Execute callback that are delayed
|
||||
|
||||
callbacks.forEach(callback => {
|
||||
callback(stats);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
context.compiler.hooks.watchRun.tap("webpack-dev-middleware", invalid);
|
||||
context.compiler.hooks.invalid.tap("webpack-dev-middleware", invalid);
|
||||
(context.compiler.webpack ? context.compiler.hooks.afterDone : context.compiler.hooks.done).tap("webpack-dev-middleware", done);
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = setupOutputFileSystem;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _memfs = require("memfs");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function setupOutputFileSystem(context) {
|
||||
let outputFileSystem;
|
||||
|
||||
if (context.options.outputFileSystem) {
|
||||
// eslint-disable-next-line no-shadow
|
||||
const {
|
||||
outputFileSystem: outputFileSystemFromOptions
|
||||
} = context.options; // Todo remove when we drop webpack@4 support
|
||||
|
||||
if (typeof outputFileSystemFromOptions.join !== "function") {
|
||||
throw new Error("Invalid options: options.outputFileSystem.join() method is expected");
|
||||
} // Todo remove when we drop webpack@4 support
|
||||
|
||||
|
||||
if (typeof outputFileSystemFromOptions.mkdirp !== "function") {
|
||||
throw new Error("Invalid options: options.outputFileSystem.mkdirp() method is expected");
|
||||
}
|
||||
|
||||
outputFileSystem = outputFileSystemFromOptions;
|
||||
} else {
|
||||
outputFileSystem = (0, _memfs.createFsFromVolume)(new _memfs.Volume()); // TODO: remove when we drop webpack@4 support
|
||||
|
||||
outputFileSystem.join = _path.default.join.bind(_path.default);
|
||||
}
|
||||
|
||||
const compilers = context.compiler.compilers || [context.compiler];
|
||||
|
||||
for (const compiler of compilers) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
compiler.outputFileSystem = outputFileSystem;
|
||||
} // eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
context.outputFileSystem = outputFileSystem;
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = setupWriteToDisk;
|
||||
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function setupWriteToDisk(context) {
|
||||
const compilers = context.compiler.compilers || [context.compiler];
|
||||
|
||||
for (const compiler of compilers) {
|
||||
compiler.hooks.emit.tap("DevMiddleware", compilation => {
|
||||
if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
compiler.hooks.assetEmitted.tapAsync("DevMiddleware", (file, info, callback) => {
|
||||
let targetPath = null;
|
||||
let content = null; // webpack@5
|
||||
|
||||
if (info.compilation) {
|
||||
({
|
||||
targetPath,
|
||||
content
|
||||
} = info);
|
||||
} else {
|
||||
let targetFile = file;
|
||||
const queryStringIdx = targetFile.indexOf("?");
|
||||
|
||||
if (queryStringIdx >= 0) {
|
||||
targetFile = targetFile.substr(0, queryStringIdx);
|
||||
}
|
||||
|
||||
let {
|
||||
outputPath
|
||||
} = compiler;
|
||||
outputPath = compilation.getPath(outputPath, {});
|
||||
content = info;
|
||||
targetPath = _path.default.join(outputPath, targetFile);
|
||||
}
|
||||
|
||||
const {
|
||||
writeToDisk: filter
|
||||
} = context.options;
|
||||
const allowWrite = filter && typeof filter === "function" ? filter(targetPath) : true;
|
||||
|
||||
if (!allowWrite) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
const dir = _path.default.dirname(targetPath);
|
||||
|
||||
const name = compiler.options.name ? `Child "${compiler.options.name}": ` : "";
|
||||
return _fs.default.mkdir(dir, {
|
||||
recursive: true
|
||||
}, mkdirError => {
|
||||
if (mkdirError) {
|
||||
context.logger.error(`${name}Unable to write "${dir}" directory to disk:\n${mkdirError}`);
|
||||
return callback(mkdirError);
|
||||
}
|
||||
|
||||
return _fs.default.writeFile(targetPath, content, writeFileError => {
|
||||
if (writeFileError) {
|
||||
context.logger.error(`${name}Unable to write "${targetPath}" asset to disk:\n${writeFileError}`);
|
||||
return callback(writeFileError);
|
||||
}
|
||||
|
||||
context.logger.log(`${name}Asset written to disk: "${targetPath}"`);
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
Copyright JS Foundation and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
<div align="center">
|
||||
<a href="http://json-schema.org">
|
||||
<img width="160" height="160"
|
||||
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/.github/assets/logo.png">
|
||||
</a>
|
||||
<a href="https://github.com/webpack/webpack">
|
||||
<img width="200" height="200"
|
||||
src="https://webpack.js.org/assets/icon-square-big.svg">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[![npm][npm]][npm-url]
|
||||
[![node][node]][node-url]
|
||||
[![deps][deps]][deps-url]
|
||||
[![tests][tests]][tests-url]
|
||||
[![coverage][cover]][cover-url]
|
||||
[![chat][chat]][chat-url]
|
||||
[![size][size]][size-url]
|
||||
|
||||
# schema-utils
|
||||
|
||||
Package for validate options in loaders and plugins.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To begin, you'll need to install `schema-utils`:
|
||||
|
||||
```console
|
||||
npm install schema-utils
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
**schema.json**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"option": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { option: true };
|
||||
const configuration = { name: "Loader Name/Plugin Name/Name" };
|
||||
|
||||
validate(schema, options, configuration);
|
||||
```
|
||||
|
||||
### `schema`
|
||||
|
||||
Type: `String`
|
||||
|
||||
JSON schema.
|
||||
|
||||
Simple example of schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "This is description of option.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
### `options`
|
||||
|
||||
Type: `Object`
|
||||
|
||||
Object with options.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, { name: 123 }, { name: "MyPlugin" });
|
||||
```
|
||||
|
||||
### `configuration`
|
||||
|
||||
Allow to configure validator.
|
||||
|
||||
There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
|
||||
For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "My Loader options",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "This is description of option.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
The last word used for the `baseDataPath` option, other words used for the `name` option.
|
||||
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
|
||||
|
||||
#### `name`
|
||||
|
||||
Type: `Object`
|
||||
Default: `"Object"`
|
||||
|
||||
Allow to setup name in validation errors.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, options, { name: "MyPlugin" });
|
||||
```
|
||||
|
||||
```shell
|
||||
Invalid configuration object. MyPlugin has been initialised using a configuration object that does not match the API schema.
|
||||
- configuration.optionName should be a integer.
|
||||
```
|
||||
|
||||
#### `baseDataPath`
|
||||
|
||||
Type: `String`
|
||||
Default: `"configuration"`
|
||||
|
||||
Allow to setup base data path in validation errors.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, options, { name: "MyPlugin", baseDataPath: "options" });
|
||||
```
|
||||
|
||||
```shell
|
||||
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
|
||||
- options.optionName should be a integer.
|
||||
```
|
||||
|
||||
#### `postFormatter`
|
||||
|
||||
Type: `Function`
|
||||
Default: `undefined`
|
||||
|
||||
Allow to reformat errors.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, options, {
|
||||
name: "MyPlugin",
|
||||
postFormatter: (formattedError, error) => {
|
||||
if (error.keyword === "type") {
|
||||
return `${formattedError}\nAdditional Information.`;
|
||||
}
|
||||
|
||||
return formattedError;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```shell
|
||||
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
|
||||
- options.optionName should be a integer.
|
||||
Additional Information.
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
**schema.json**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"test": {
|
||||
"anyOf": [
|
||||
{ "type": "array" },
|
||||
{ "type": "string" },
|
||||
{ "instanceof": "RegExp" }
|
||||
]
|
||||
},
|
||||
"transform": {
|
||||
"instanceof": "Function"
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
### `Loader`
|
||||
|
||||
```js
|
||||
import { getOptions } from "loader-utils";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
import schema from "path/to/schema.json";
|
||||
|
||||
function loader(src, map) {
|
||||
const options = getOptions(this);
|
||||
|
||||
validate(schema, options, {
|
||||
name: "Loader Name",
|
||||
baseDataPath: "options",
|
||||
});
|
||||
|
||||
// Code...
|
||||
}
|
||||
|
||||
export default loader;
|
||||
```
|
||||
|
||||
### `Plugin`
|
||||
|
||||
```js
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
import schema from "path/to/schema.json";
|
||||
|
||||
class Plugin {
|
||||
constructor(options) {
|
||||
validate(schema, options, {
|
||||
name: "Plugin Name",
|
||||
baseDataPath: "options",
|
||||
});
|
||||
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
// Code...
|
||||
}
|
||||
}
|
||||
|
||||
export default Plugin;
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please take a moment to read our contributing guidelines if you haven't yet done so.
|
||||
|
||||
[CONTRIBUTING](./.github/CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE)
|
||||
|
||||
[npm]: https://img.shields.io/npm/v/schema-utils.svg
|
||||
[npm-url]: https://npmjs.com/package/schema-utils
|
||||
[node]: https://img.shields.io/node/v/schema-utils.svg
|
||||
[node-url]: https://nodejs.org
|
||||
[deps]: https://david-dm.org/webpack/schema-utils.svg
|
||||
[deps-url]: https://david-dm.org/webpack/schema-utils
|
||||
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
|
||||
[tests-url]: https://github.com/webpack/schema-utils/actions
|
||||
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
|
||||
[cover-url]: https://codecov.io/gh/webpack/schema-utils
|
||||
[chat]: https://badges.gitter.im/webpack/webpack.svg
|
||||
[chat-url]: https://gitter.im/webpack/webpack
|
||||
[size]: https://packagephobia.com/badge?p=schema-utils
|
||||
[size-url]: https://packagephobia.com/result?p=schema-utils
|
||||
Generated
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
export default ValidationError;
|
||||
export type JSONSchema6 = import("json-schema").JSONSchema6;
|
||||
export type JSONSchema7 = import("json-schema").JSONSchema7;
|
||||
export type Schema = import("./validate").Schema;
|
||||
export type ValidationErrorConfiguration =
|
||||
import("./validate").ValidationErrorConfiguration;
|
||||
export type PostFormatter = import("./validate").PostFormatter;
|
||||
export type SchemaUtilErrorObject = import("./validate").SchemaUtilErrorObject;
|
||||
declare class ValidationError extends Error {
|
||||
/**
|
||||
* @param {Array<SchemaUtilErrorObject>} errors
|
||||
* @param {Schema} schema
|
||||
* @param {ValidationErrorConfiguration} configuration
|
||||
*/
|
||||
constructor(
|
||||
errors: Array<SchemaUtilErrorObject>,
|
||||
schema: Schema,
|
||||
configuration?: ValidationErrorConfiguration
|
||||
);
|
||||
/** @type {Array<SchemaUtilErrorObject>} */
|
||||
errors: Array<SchemaUtilErrorObject>;
|
||||
/** @type {Schema} */
|
||||
schema: Schema;
|
||||
/** @type {string} */
|
||||
headerName: string;
|
||||
/** @type {string} */
|
||||
baseDataPath: string;
|
||||
/** @type {PostFormatter | null} */
|
||||
postFormatter: PostFormatter | null;
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Schema}
|
||||
*/
|
||||
getSchemaPart(path: string): Schema;
|
||||
/**
|
||||
* @param {Schema} schema
|
||||
* @param {boolean} logic
|
||||
* @param {Array<Object>} prevSchemas
|
||||
* @returns {string}
|
||||
*/
|
||||
formatSchema(
|
||||
schema: Schema,
|
||||
logic?: boolean,
|
||||
prevSchemas?: Array<Object>
|
||||
): string;
|
||||
/**
|
||||
* @param {Schema=} schemaPart
|
||||
* @param {(boolean | Array<string>)=} additionalPath
|
||||
* @param {boolean=} needDot
|
||||
* @param {boolean=} logic
|
||||
* @returns {string}
|
||||
*/
|
||||
getSchemaPartText(
|
||||
schemaPart?: Schema | undefined,
|
||||
additionalPath?: (boolean | Array<string>) | undefined,
|
||||
needDot?: boolean | undefined,
|
||||
logic?: boolean | undefined
|
||||
): string;
|
||||
/**
|
||||
* @param {Schema=} schemaPart
|
||||
* @returns {string}
|
||||
*/
|
||||
getSchemaPartDescription(schemaPart?: Schema | undefined): string;
|
||||
/**
|
||||
* @param {SchemaUtilErrorObject} error
|
||||
* @returns {string}
|
||||
*/
|
||||
formatValidationError(error: SchemaUtilErrorObject): string;
|
||||
/**
|
||||
* @param {Array<SchemaUtilErrorObject>} errors
|
||||
* @returns {string}
|
||||
*/
|
||||
formatValidationErrors(errors: Array<SchemaUtilErrorObject>): string;
|
||||
}
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { validate } from "./validate";
|
||||
import { ValidationError } from "./validate";
|
||||
export { validate, ValidationError };
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
export default addAbsolutePathKeyword;
|
||||
export type Ajv = import("ajv").Ajv;
|
||||
export type ValidateFunction = import("ajv").ValidateFunction;
|
||||
export type SchemaUtilErrorObject = import("../validate").SchemaUtilErrorObject;
|
||||
/**
|
||||
*
|
||||
* @param {Ajv} ajv
|
||||
* @returns {Ajv}
|
||||
*/
|
||||
declare function addAbsolutePathKeyword(ajv: Ajv): Ajv;
|
||||
Generated
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
export = Range;
|
||||
/**
|
||||
* @typedef {[number, boolean]} RangeValue
|
||||
*/
|
||||
/**
|
||||
* @callback RangeValueCallback
|
||||
* @param {RangeValue} rangeValue
|
||||
* @returns {boolean}
|
||||
*/
|
||||
declare class Range {
|
||||
/**
|
||||
* @param {"left" | "right"} side
|
||||
* @param {boolean} exclusive
|
||||
* @returns {">" | ">=" | "<" | "<="}
|
||||
*/
|
||||
static getOperator(
|
||||
side: "left" | "right",
|
||||
exclusive: boolean
|
||||
): ">" | ">=" | "<" | "<=";
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @param {boolean} exclusive is range exclusive
|
||||
* @returns {string}
|
||||
*/
|
||||
static formatRight(value: number, logic: boolean, exclusive: boolean): string;
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @param {boolean} exclusive is range exclusive
|
||||
* @returns {string}
|
||||
*/
|
||||
static formatLeft(value: number, logic: boolean, exclusive: boolean): string;
|
||||
/**
|
||||
* @param {number} start left side value
|
||||
* @param {number} end right side value
|
||||
* @param {boolean} startExclusive is range exclusive from left side
|
||||
* @param {boolean} endExclusive is range exclusive from right side
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @returns {string}
|
||||
*/
|
||||
static formatRange(
|
||||
start: number,
|
||||
end: number,
|
||||
startExclusive: boolean,
|
||||
endExclusive: boolean,
|
||||
logic: boolean
|
||||
): string;
|
||||
/**
|
||||
* @param {Array<RangeValue>} values
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @return {RangeValue} computed value and it's exclusive flag
|
||||
*/
|
||||
static getRangeValue(values: Array<RangeValue>, logic: boolean): RangeValue;
|
||||
/** @type {Array<RangeValue>} */
|
||||
_left: Array<RangeValue>;
|
||||
/** @type {Array<RangeValue>} */
|
||||
_right: Array<RangeValue>;
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean=} exclusive
|
||||
*/
|
||||
left(value: number, exclusive?: boolean | undefined): void;
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean=} exclusive
|
||||
*/
|
||||
right(value: number, exclusive?: boolean | undefined): void;
|
||||
/**
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @return {string} "smart" range string representation
|
||||
*/
|
||||
format(logic?: boolean): string;
|
||||
}
|
||||
declare namespace Range {
|
||||
export { RangeValue, RangeValueCallback };
|
||||
}
|
||||
type RangeValue = [number, boolean];
|
||||
type RangeValueCallback = (rangeValue: RangeValue) => boolean;
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export function stringHints(schema: Schema, logic: boolean): string[];
|
||||
export function numberHints(schema: Schema, logic: boolean): string[];
|
||||
export type Schema = import("../validate").Schema;
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
export type JSONSchema4 = import("json-schema").JSONSchema4;
|
||||
export type JSONSchema6 = import("json-schema").JSONSchema6;
|
||||
export type JSONSchema7 = import("json-schema").JSONSchema7;
|
||||
export type ErrorObject = import("ajv").ErrorObject;
|
||||
export type Extend = {
|
||||
formatMinimum?: number | undefined;
|
||||
formatMaximum?: number | undefined;
|
||||
formatExclusiveMinimum?: boolean | undefined;
|
||||
formatExclusiveMaximum?: boolean | undefined;
|
||||
link?: string | undefined;
|
||||
};
|
||||
export type Schema = (JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend;
|
||||
export type SchemaUtilErrorObject = ErrorObject & {
|
||||
children?: Array<ErrorObject>;
|
||||
};
|
||||
export type PostFormatter = (
|
||||
formattedError: string,
|
||||
error: SchemaUtilErrorObject
|
||||
) => string;
|
||||
export type ValidationErrorConfiguration = {
|
||||
name?: string | undefined;
|
||||
baseDataPath?: string | undefined;
|
||||
postFormatter?: PostFormatter | undefined;
|
||||
};
|
||||
/**
|
||||
* @param {Schema} schema
|
||||
* @param {Array<object> | object} options
|
||||
* @param {ValidationErrorConfiguration=} configuration
|
||||
* @returns {void}
|
||||
*/
|
||||
export function validate(
|
||||
schema: Schema,
|
||||
options: Array<object> | object,
|
||||
configuration?: ValidationErrorConfiguration | undefined
|
||||
): void;
|
||||
import ValidationError from "./ValidationError";
|
||||
export { ValidationError };
|
||||
Generated
Vendored
+1271
File diff suppressed because it is too large
Load Diff
+11
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
validate,
|
||||
ValidationError
|
||||
} = require("./validate");
|
||||
|
||||
module.exports = {
|
||||
validate,
|
||||
ValidationError
|
||||
};
|
||||
Generated
Vendored
+93
@@ -0,0 +1,93 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
/** @typedef {import("ajv").Ajv} Ajv */
|
||||
|
||||
/** @typedef {import("ajv").ValidateFunction} ValidateFunction */
|
||||
|
||||
/** @typedef {import("../validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @param {object} schema
|
||||
* @param {string} data
|
||||
* @returns {SchemaUtilErrorObject}
|
||||
*/
|
||||
function errorMessage(message, schema, data) {
|
||||
return {
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undefined
|
||||
dataPath: undefined,
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undefined
|
||||
schemaPath: undefined,
|
||||
keyword: "absolutePath",
|
||||
params: {
|
||||
absolutePath: data
|
||||
},
|
||||
message,
|
||||
parentSchema: schema
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {boolean} shouldBeAbsolute
|
||||
* @param {object} schema
|
||||
* @param {string} data
|
||||
* @returns {SchemaUtilErrorObject}
|
||||
*/
|
||||
|
||||
|
||||
function getErrorFor(shouldBeAbsolute, schema, data) {
|
||||
const message = shouldBeAbsolute ? `The provided value ${JSON.stringify(data)} is not an absolute path!` : `A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
|
||||
return errorMessage(message, schema, data);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {Ajv} ajv
|
||||
* @returns {Ajv}
|
||||
*/
|
||||
|
||||
|
||||
function addAbsolutePathKeyword(ajv) {
|
||||
ajv.addKeyword("absolutePath", {
|
||||
errors: true,
|
||||
type: "string",
|
||||
|
||||
compile(schema, parentSchema) {
|
||||
/** @type {ValidateFunction} */
|
||||
const callback = data => {
|
||||
let passes = true;
|
||||
const isExclamationMarkPresent = data.includes("!");
|
||||
|
||||
if (isExclamationMarkPresent) {
|
||||
callback.errors = [errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`, parentSchema, data)];
|
||||
passes = false;
|
||||
} // ?:[A-Za-z]:\\ - Windows absolute path
|
||||
// \\\\ - Windows network absolute path
|
||||
// \/ - Unix-like OS absolute path
|
||||
|
||||
|
||||
const isCorrectAbsolutePath = schema === /^(?:[A-Za-z]:(\\|\/)|\\\\|\/)/.test(data);
|
||||
|
||||
if (!isCorrectAbsolutePath) {
|
||||
callback.errors = [getErrorFor(schema, parentSchema, data)];
|
||||
passes = false;
|
||||
}
|
||||
|
||||
return passes;
|
||||
};
|
||||
|
||||
callback.errors = [];
|
||||
return callback;
|
||||
}
|
||||
|
||||
});
|
||||
return ajv;
|
||||
}
|
||||
|
||||
var _default = addAbsolutePathKeyword;
|
||||
exports.default = _default;
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @typedef {[number, boolean]} RangeValue
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback RangeValueCallback
|
||||
* @param {RangeValue} rangeValue
|
||||
* @returns {boolean}
|
||||
*/
|
||||
class Range {
|
||||
/**
|
||||
* @param {"left" | "right"} side
|
||||
* @param {boolean} exclusive
|
||||
* @returns {">" | ">=" | "<" | "<="}
|
||||
*/
|
||||
static getOperator(side, exclusive) {
|
||||
if (side === "left") {
|
||||
return exclusive ? ">" : ">=";
|
||||
}
|
||||
|
||||
return exclusive ? "<" : "<=";
|
||||
}
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @param {boolean} exclusive is range exclusive
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
|
||||
static formatRight(value, logic, exclusive) {
|
||||
if (logic === false) {
|
||||
return Range.formatLeft(value, !logic, !exclusive);
|
||||
}
|
||||
|
||||
return `should be ${Range.getOperator("right", exclusive)} ${value}`;
|
||||
}
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @param {boolean} exclusive is range exclusive
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
|
||||
static formatLeft(value, logic, exclusive) {
|
||||
if (logic === false) {
|
||||
return Range.formatRight(value, !logic, !exclusive);
|
||||
}
|
||||
|
||||
return `should be ${Range.getOperator("left", exclusive)} ${value}`;
|
||||
}
|
||||
/**
|
||||
* @param {number} start left side value
|
||||
* @param {number} end right side value
|
||||
* @param {boolean} startExclusive is range exclusive from left side
|
||||
* @param {boolean} endExclusive is range exclusive from right side
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
|
||||
static formatRange(start, end, startExclusive, endExclusive, logic) {
|
||||
let result = "should be";
|
||||
result += ` ${Range.getOperator(logic ? "left" : "right", logic ? startExclusive : !startExclusive)} ${start} `;
|
||||
result += logic ? "and" : "or";
|
||||
result += ` ${Range.getOperator(logic ? "right" : "left", logic ? endExclusive : !endExclusive)} ${end}`;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* @param {Array<RangeValue>} values
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @return {RangeValue} computed value and it's exclusive flag
|
||||
*/
|
||||
|
||||
|
||||
static getRangeValue(values, logic) {
|
||||
let minMax = logic ? Infinity : -Infinity;
|
||||
let j = -1;
|
||||
const predicate = logic ?
|
||||
/** @type {RangeValueCallback} */
|
||||
([value]) => value <= minMax :
|
||||
/** @type {RangeValueCallback} */
|
||||
([value]) => value >= minMax;
|
||||
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
if (predicate(values[i])) {
|
||||
[minMax] = values[i];
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (j > -1) {
|
||||
return values[j];
|
||||
}
|
||||
|
||||
return [Infinity, true];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
/** @type {Array<RangeValue>} */
|
||||
this._left = [];
|
||||
/** @type {Array<RangeValue>} */
|
||||
|
||||
this._right = [];
|
||||
}
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean=} exclusive
|
||||
*/
|
||||
|
||||
|
||||
left(value, exclusive = false) {
|
||||
this._left.push([value, exclusive]);
|
||||
}
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {boolean=} exclusive
|
||||
*/
|
||||
|
||||
|
||||
right(value, exclusive = false) {
|
||||
this._right.push([value, exclusive]);
|
||||
}
|
||||
/**
|
||||
* @param {boolean} logic is not logic applied
|
||||
* @return {string} "smart" range string representation
|
||||
*/
|
||||
|
||||
|
||||
format(logic = true) {
|
||||
const [start, leftExclusive] = Range.getRangeValue(this._left, logic);
|
||||
const [end, rightExclusive] = Range.getRangeValue(this._right, !logic);
|
||||
|
||||
if (!Number.isFinite(start) && !Number.isFinite(end)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const realStart = leftExclusive ? start + 1 : start;
|
||||
const realEnd = rightExclusive ? end - 1 : end; // e.g. 5 < x < 7, 5 < x <= 6, 6 <= x <= 6
|
||||
|
||||
if (realStart === realEnd) {
|
||||
return `should be ${logic ? "" : "!"}= ${realStart}`;
|
||||
} // e.g. 4 < x < ∞
|
||||
|
||||
|
||||
if (Number.isFinite(start) && !Number.isFinite(end)) {
|
||||
return Range.formatLeft(start, logic, leftExclusive);
|
||||
} // e.g. ∞ < x < 4
|
||||
|
||||
|
||||
if (!Number.isFinite(start) && Number.isFinite(end)) {
|
||||
return Range.formatRight(end, logic, rightExclusive);
|
||||
}
|
||||
|
||||
return Range.formatRange(start, end, leftExclusive, rightExclusive, logic);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Range;
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
"use strict";
|
||||
|
||||
const Range = require("./Range");
|
||||
/** @typedef {import("../validate").Schema} Schema */
|
||||
|
||||
/**
|
||||
* @param {Schema} schema
|
||||
* @param {boolean} logic
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
||||
|
||||
module.exports.stringHints = function stringHints(schema, logic) {
|
||||
const hints = [];
|
||||
let type = "string";
|
||||
const currentSchema = { ...schema
|
||||
};
|
||||
|
||||
if (!logic) {
|
||||
const tmpLength = currentSchema.minLength;
|
||||
const tmpFormat = currentSchema.formatMinimum;
|
||||
const tmpExclusive = currentSchema.formatExclusiveMaximum;
|
||||
currentSchema.minLength = currentSchema.maxLength;
|
||||
currentSchema.maxLength = tmpLength;
|
||||
currentSchema.formatMinimum = currentSchema.formatMaximum;
|
||||
currentSchema.formatMaximum = tmpFormat;
|
||||
currentSchema.formatExclusiveMaximum = !currentSchema.formatExclusiveMinimum;
|
||||
currentSchema.formatExclusiveMinimum = !tmpExclusive;
|
||||
}
|
||||
|
||||
if (typeof currentSchema.minLength === "number") {
|
||||
if (currentSchema.minLength === 1) {
|
||||
type = "non-empty string";
|
||||
} else {
|
||||
const length = Math.max(currentSchema.minLength - 1, 0);
|
||||
hints.push(`should be longer than ${length} character${length > 1 ? "s" : ""}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof currentSchema.maxLength === "number") {
|
||||
if (currentSchema.maxLength === 0) {
|
||||
type = "empty string";
|
||||
} else {
|
||||
const length = currentSchema.maxLength + 1;
|
||||
hints.push(`should be shorter than ${length} character${length > 1 ? "s" : ""}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSchema.pattern) {
|
||||
hints.push(`should${logic ? "" : " not"} match pattern ${JSON.stringify(currentSchema.pattern)}`);
|
||||
}
|
||||
|
||||
if (currentSchema.format) {
|
||||
hints.push(`should${logic ? "" : " not"} match format ${JSON.stringify(currentSchema.format)}`);
|
||||
}
|
||||
|
||||
if (currentSchema.formatMinimum) {
|
||||
hints.push(`should be ${currentSchema.formatExclusiveMinimum ? ">" : ">="} ${JSON.stringify(currentSchema.formatMinimum)}`);
|
||||
}
|
||||
|
||||
if (currentSchema.formatMaximum) {
|
||||
hints.push(`should be ${currentSchema.formatExclusiveMaximum ? "<" : "<="} ${JSON.stringify(currentSchema.formatMaximum)}`);
|
||||
}
|
||||
|
||||
return [type].concat(hints);
|
||||
};
|
||||
/**
|
||||
* @param {Schema} schema
|
||||
* @param {boolean} logic
|
||||
* @return {string[]}
|
||||
*/
|
||||
|
||||
|
||||
module.exports.numberHints = function numberHints(schema, logic) {
|
||||
const hints = [schema.type === "integer" ? "integer" : "number"];
|
||||
const range = new Range();
|
||||
|
||||
if (typeof schema.minimum === "number") {
|
||||
range.left(schema.minimum);
|
||||
}
|
||||
|
||||
if (typeof schema.exclusiveMinimum === "number") {
|
||||
range.left(schema.exclusiveMinimum, true);
|
||||
}
|
||||
|
||||
if (typeof schema.maximum === "number") {
|
||||
range.right(schema.maximum);
|
||||
}
|
||||
|
||||
if (typeof schema.exclusiveMaximum === "number") {
|
||||
range.right(schema.exclusiveMaximum, true);
|
||||
}
|
||||
|
||||
const rangeFormat = range.format(logic);
|
||||
|
||||
if (rangeFormat) {
|
||||
hints.push(rangeFormat);
|
||||
}
|
||||
|
||||
if (typeof schema.multipleOf === "number") {
|
||||
hints.push(`should${logic ? "" : " not"} be multiple of ${schema.multipleOf}`);
|
||||
}
|
||||
|
||||
return hints;
|
||||
};
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.validate = validate;
|
||||
Object.defineProperty(exports, "ValidationError", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _ValidationError.default;
|
||||
}
|
||||
});
|
||||
|
||||
var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));
|
||||
|
||||
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
// Use CommonJS require for ajv libs so TypeScript consumers aren't locked into esModuleInterop (see #110).
|
||||
const Ajv = require("ajv");
|
||||
|
||||
const ajvKeywords = require("ajv-keywords");
|
||||
/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
|
||||
|
||||
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
|
||||
|
||||
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
|
||||
|
||||
/** @typedef {import("ajv").ErrorObject} ErrorObject */
|
||||
|
||||
/**
|
||||
* @typedef {Object} Extend
|
||||
* @property {number=} formatMinimum
|
||||
* @property {number=} formatMaximum
|
||||
* @property {boolean=} formatExclusiveMinimum
|
||||
* @property {boolean=} formatExclusiveMaximum
|
||||
* @property {string=} link
|
||||
*/
|
||||
|
||||
/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend} Schema */
|
||||
|
||||
/** @typedef {ErrorObject & { children?: Array<ErrorObject>}} SchemaUtilErrorObject */
|
||||
|
||||
/**
|
||||
* @callback PostFormatter
|
||||
* @param {string} formattedError
|
||||
* @param {SchemaUtilErrorObject} error
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ValidationErrorConfiguration
|
||||
* @property {string=} name
|
||||
* @property {string=} baseDataPath
|
||||
* @property {PostFormatter=} postFormatter
|
||||
*/
|
||||
|
||||
|
||||
const ajv = new Ajv({
|
||||
allErrors: true,
|
||||
verbose: true,
|
||||
$data: true
|
||||
});
|
||||
ajvKeywords(ajv, ["instanceof", "formatMinimum", "formatMaximum", "patternRequired"]); // Custom keywords
|
||||
|
||||
(0, _absolutePath.default)(ajv);
|
||||
/**
|
||||
* @param {Schema} schema
|
||||
* @param {Array<object> | object} options
|
||||
* @param {ValidationErrorConfiguration=} configuration
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
function validate(schema, options, configuration) {
|
||||
let errors = [];
|
||||
|
||||
if (Array.isArray(options)) {
|
||||
errors = Array.from(options, nestedOptions => validateObject(schema, nestedOptions));
|
||||
errors.forEach((list, idx) => {
|
||||
const applyPrefix =
|
||||
/**
|
||||
* @param {SchemaUtilErrorObject} error
|
||||
*/
|
||||
error => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
error.dataPath = `[${idx}]${error.dataPath}`;
|
||||
|
||||
if (error.children) {
|
||||
error.children.forEach(applyPrefix);
|
||||
}
|
||||
};
|
||||
|
||||
list.forEach(applyPrefix);
|
||||
});
|
||||
errors = errors.reduce((arr, items) => {
|
||||
arr.push(...items);
|
||||
return arr;
|
||||
}, []);
|
||||
} else {
|
||||
errors = validateObject(schema, options);
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
throw new _ValidationError.default(errors, schema, configuration);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {Schema} schema
|
||||
* @param {Array<object> | object} options
|
||||
* @returns {Array<SchemaUtilErrorObject>}
|
||||
*/
|
||||
|
||||
|
||||
function validateObject(schema, options) {
|
||||
const compiledSchema = ajv.compile(schema);
|
||||
const valid = compiledSchema(options);
|
||||
if (valid) return [];
|
||||
return compiledSchema.errors ? filterErrors(compiledSchema.errors) : [];
|
||||
}
|
||||
/**
|
||||
* @param {Array<ErrorObject>} errors
|
||||
* @returns {Array<SchemaUtilErrorObject>}
|
||||
*/
|
||||
|
||||
|
||||
function filterErrors(errors) {
|
||||
/** @type {Array<SchemaUtilErrorObject>} */
|
||||
let newErrors = [];
|
||||
|
||||
for (const error of
|
||||
/** @type {Array<SchemaUtilErrorObject>} */
|
||||
errors) {
|
||||
const {
|
||||
dataPath
|
||||
} = error;
|
||||
/** @type {Array<SchemaUtilErrorObject>} */
|
||||
|
||||
let children = [];
|
||||
newErrors = newErrors.filter(oldError => {
|
||||
if (oldError.dataPath.includes(dataPath)) {
|
||||
if (oldError.children) {
|
||||
children = children.concat(oldError.children.slice(0));
|
||||
} // eslint-disable-next-line no-undefined, no-param-reassign
|
||||
|
||||
|
||||
oldError.children = undefined;
|
||||
children.push(oldError);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (children.length) {
|
||||
error.children = children;
|
||||
}
|
||||
|
||||
newErrors.push(error);
|
||||
}
|
||||
|
||||
return newErrors;
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"schema-utils@3.1.1",
|
||||
"/home/node/nuxt"
|
||||
]
|
||||
],
|
||||
"_from": "schema-utils@3.1.1",
|
||||
"_id": "schema-utils@3.1.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
|
||||
"_location": "/webpack-dev-middleware/schema-utils",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "schema-utils@3.1.1",
|
||||
"name": "schema-utils",
|
||||
"escapedName": "schema-utils",
|
||||
"rawSpec": "3.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/webpack-dev-middleware"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
|
||||
"_spec": "3.1.1",
|
||||
"_where": "/home/node/nuxt",
|
||||
"author": {
|
||||
"name": "webpack Contrib",
|
||||
"url": "https://github.com/webpack-contrib"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/webpack/schema-utils/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"description": "webpack Validation Utils",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.14.3",
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"@commitlint/cli": "^12.1.4",
|
||||
"@commitlint/config-conventional": "^12.1.4",
|
||||
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
|
||||
"babel-jest": "^27.0.6",
|
||||
"cross-env": "^7.0.3",
|
||||
"del": "^6.0.0",
|
||||
"del-cli": "^3.0.1",
|
||||
"eslint": "^7.31.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.23.4",
|
||||
"husky": "^6.0.0",
|
||||
"jest": "^27.0.6",
|
||||
"lint-staged": "^11.0.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.3.2",
|
||||
"standard-version": "^9.3.1",
|
||||
"typescript": "^4.3.5",
|
||||
"webpack": "^5.45.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"declarations"
|
||||
],
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"homepage": "https://github.com/webpack/schema-utils",
|
||||
"keywords": [
|
||||
"webpack"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"name": "schema-utils",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/webpack/schema-utils.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm-run-all -p \"build:**\"",
|
||||
"build:code": "cross-env NODE_ENV=production babel src -d dist --copy-files",
|
||||
"build:types": "tsc --declaration --emitDeclarationOnly --outDir declarations && prettier \"declarations/**/*.ts\" --write",
|
||||
"clean": "del-cli dist declarations",
|
||||
"commitlint": "commitlint --from=master",
|
||||
"fix": "npm-run-all fix:js fmt",
|
||||
"fix:js": "npm run lint:js -- --fix",
|
||||
"fmt": "npm run fmt:check -- --write",
|
||||
"fmt:check": "prettier \"{**/*,*}.{js,json,md,yml,css,ts}\" --list-different",
|
||||
"lint": "npm-run-all lint:js lint:types fmt:check",
|
||||
"lint:js": "eslint --cache .",
|
||||
"lint:types": "tsc --pretty --noEmit",
|
||||
"prebuild": "npm run clean",
|
||||
"prepare": "npm run build && husky install",
|
||||
"pretest": "npm run lint",
|
||||
"release": "standard-version",
|
||||
"security": "npm audit --production",
|
||||
"start": "npm run build -- -w",
|
||||
"test": "npm run test:coverage",
|
||||
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
|
||||
"test:only": "cross-env NODE_ENV=test jest",
|
||||
"test:watch": "npm run test:only -- --watch"
|
||||
},
|
||||
"types": "declarations/index.d.ts",
|
||||
"version": "3.1.1"
|
||||
}
|
||||
+68
-51
@@ -1,32 +1,36 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"webpack-dev-middleware@3.7.2",
|
||||
"/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series"
|
||||
"webpack-dev-middleware@4.3.0",
|
||||
"/home/node/nuxt"
|
||||
]
|
||||
],
|
||||
"_from": "webpack-dev-middleware@3.7.2",
|
||||
"_id": "webpack-dev-middleware@3.7.2",
|
||||
"_from": "webpack-dev-middleware@4.3.0",
|
||||
"_id": "webpack-dev-middleware@4.3.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==",
|
||||
"_integrity": "sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==",
|
||||
"_location": "/webpack-dev-middleware",
|
||||
"_phantomChildren": {},
|
||||
"_phantomChildren": {
|
||||
"@types/json-schema": "7.0.11",
|
||||
"ajv": "6.12.6",
|
||||
"ajv-keywords": "3.5.2"
|
||||
},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "webpack-dev-middleware@3.7.2",
|
||||
"raw": "webpack-dev-middleware@4.3.0",
|
||||
"name": "webpack-dev-middleware",
|
||||
"escapedName": "webpack-dev-middleware",
|
||||
"rawSpec": "3.7.2",
|
||||
"rawSpec": "4.3.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.7.2"
|
||||
"fetchSpec": "4.3.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@nuxt/webpack"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz",
|
||||
"_spec": "3.7.2",
|
||||
"_where": "/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series",
|
||||
"_resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz",
|
||||
"_spec": "4.3.0",
|
||||
"_where": "/home/node/nuxt",
|
||||
"author": {
|
||||
"name": "Tobias Koppers @sokra"
|
||||
},
|
||||
@@ -34,74 +38,87 @@
|
||||
"url": "https://github.com/webpack/webpack-dev-middleware/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"memory-fs": "^0.4.1",
|
||||
"mime": "^2.4.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"colorette": "^1.2.2",
|
||||
"mem": "^8.1.1",
|
||||
"memfs": "^3.2.2",
|
||||
"mime-types": "^2.1.30",
|
||||
"range-parser": "^1.2.1",
|
||||
"webpack-log": "^2.0.0"
|
||||
"schema-utils": "^3.0.0"
|
||||
},
|
||||
"description": "A development middleware for webpack",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.6.2",
|
||||
"@babel/core": "^7.6.2",
|
||||
"@babel/preset-env": "^7.6.2",
|
||||
"@commitlint/cli": "^8.2.0",
|
||||
"@commitlint/config-conventional": "^8.2.0",
|
||||
"@webpack-contrib/defaults": "^5.0.2",
|
||||
"@babel/cli": "^7.14.3",
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/preset-env": "^7.14.2",
|
||||
"@commitlint/cli": "^12.1.4",
|
||||
"@commitlint/config-conventional": "^12.1.4",
|
||||
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
|
||||
"babel-jest": "^24.9.0",
|
||||
"commitlint-azure-pipelines-cli": "^1.0.2",
|
||||
"cross-env": "^5.2.1",
|
||||
"del": "^4.1.1",
|
||||
"del-cli": "^1.1.0",
|
||||
"eslint": "^6.4.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"babel-jest": "^26.6.3",
|
||||
"chokidar": "^3.5.1",
|
||||
"connect": "^3.7.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"deepmerge": "^4.2.2",
|
||||
"del": "^6.0.0",
|
||||
"del-cli": "^3.0.1",
|
||||
"eslint": "^7.26.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"execa": "^5.0.0",
|
||||
"express": "^4.17.1",
|
||||
"file-loader": "^4.2.0",
|
||||
"husky": "^3.0.7",
|
||||
"jest": "^24.9.0",
|
||||
"jest-junit": "^8.0.0",
|
||||
"lint-staged": "^9.4.0",
|
||||
"prettier": "^1.18.2",
|
||||
"standard-version": "^7.0.0",
|
||||
"supertest": "^4.0.2",
|
||||
"webpack": "^4.41.0"
|
||||
"file-loader": "^6.2.0",
|
||||
"husky": "^6.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"lint-staged": "^11.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.3.0",
|
||||
"standard-version": "^9.3.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"supertest": "^6.1.3",
|
||||
"webpack": "^5.37.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
"node": ">= v10.23.3"
|
||||
},
|
||||
"files": [
|
||||
"lib",
|
||||
"index.js"
|
||||
"dist"
|
||||
],
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"homepage": "https://github.com/webpack/webpack-dev-middleware",
|
||||
"keywords": [
|
||||
"webpack",
|
||||
"middleware",
|
||||
"develompent"
|
||||
"development"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"main": "dist/cjs.js",
|
||||
"name": "webpack-dev-middleware",
|
||||
"peerDependencies": {
|
||||
"webpack": "^4.0.0"
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/webpack/webpack-dev-middleware.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "del dist && babel src -d dist --copy-files",
|
||||
"commitlint": "commitlint --from=master",
|
||||
"defaults": "webpack-defaults",
|
||||
"lint": "eslint --cache lib test",
|
||||
"fix": "npm-run-all fix:js fix:prettier",
|
||||
"fix:js": "npm run lint:js -- --fix",
|
||||
"fix:prettier": "npm run lint:prettier -- --write",
|
||||
"lint": "npm-run-all -l -p \"lint:**\"",
|
||||
"lint:js": "eslint --cache src test",
|
||||
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css}\" --list-different",
|
||||
"prepare": "husky install && npm run build",
|
||||
"pretest": "npm run lint",
|
||||
"release": "standard-version",
|
||||
"security": "npm audit",
|
||||
"test": "npm run test:coverage",
|
||||
"test:coverage": "npm run test:only -- --coverage",
|
||||
"test:only": "jest",
|
||||
"test:watch": "npm run test:only --watch"
|
||||
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
|
||||
"test:only": "cross-env NODE_ENV=test jest",
|
||||
"test:watch": "npm run test:only -- --watch"
|
||||
},
|
||||
"version": "3.7.2"
|
||||
"version": "4.3.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user