This commit is contained in:
2023-08-11 10:45:20 +08:00
commit 161ca982f3
31850 changed files with 2706500 additions and 0 deletions

20
node_modules/terser-webpack-plugin/LICENSE generated vendored Normal file
View File

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

934
node_modules/terser-webpack-plugin/README.md generated vendored Normal file
View File

@ -0,0 +1,934 @@
<div align="center">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![tests][tests]][tests-url]
[![cover][cover]][cover-url]
[![discussion][discussion]][discussion-url]
[![size][size]][size-url]
# terser-webpack-plugin
This plugin uses [terser](https://github.com/terser/terser) to minify/minimize your JavaScript.
## Getting Started
Webpack v5 comes with the latest `terser-webpack-plugin` out of the box. If you are using Webpack v5 or above and wish to customize the options, you will still need to install `terser-webpack-plugin`. Using Webpack v4, you have to install `terser-webpack-plugin` v4.
To begin, you'll need to install `terser-webpack-plugin`:
```console
npm install terser-webpack-plugin --save-dev
```
or
```console
yarn add -D terser-webpack-plugin
```
or
```console
pnpm add -D terser-webpack-plugin
```
Then add the plugin to your `webpack` config. For example:
**webpack.config.js**
```js
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
};
```
And run `webpack` via your preferred method.
## Note about source maps
**Works only with `source-map`, `inline-source-map`, `hidden-source-map` and `nosources-source-map` values for the [`devtool`](https://webpack.js.org/configuration/devtool/) option.**
Why?
- `eval` wraps modules in `eval("string")` and the minimizer does not handle strings.
- `cheap` has not column information and minimizer generate only a single line, which leave only a single mapping.
Using supported `devtool` values enable source map generation.
## Options
- **[`test`](#test)**
- **[`include`](#include)**
- **[`exclude`](#exclude)**
- **[`parallel`](#parallel)**
- **[`minify`](#minify)**
- **[`terserOptions`](#terseroptions)**
- **[`extractComments`](#extractcomments)**
### `test`
Type:
```ts
type test = string | RegExp | Array<string | RegExp>;
```
Default: `/\.m?js(\?.*)?$/i`
Test to match files against.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
}),
],
},
};
```
### `include`
Type:
```ts
type include = string | RegExp | Array<string | RegExp>;
```
Default: `undefined`
Files to include.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\/includes/,
}),
],
},
};
```
### `exclude`
Type:
```ts
type exclude = string | RegExp | Array<string | RegExp>;
```
Default: `undefined`
Files to exclude.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
exclude: /\/excludes/,
}),
],
},
};
```
### `parallel`
Type:
```ts
type parallel = boolean | number;
```
Default: `true`
Use multi-process parallel running to improve the build speed.
Default number of concurrent runs: `os.cpus().length - 1`.
> **Note**
>
> Parallelization can speedup your build significantly and is therefore **highly recommended**.
> **Warning**
>
> If you use **Circle CI** or any other environment that doesn't provide real available count of CPUs then you need to setup explicitly number of CPUs to avoid `Error: Call retries were exceeded` (see [#143](https://github.com/webpack-contrib/terser-webpack-plugin/issues/143), [#202](https://github.com/webpack-contrib/terser-webpack-plugin/issues/202)).
#### `boolean`
Enable/disable multi-process parallel running.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
};
```
#### `number`
Enable multi-process parallel running and set number of concurrent runs.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 4,
}),
],
},
};
```
### `minify`
Type:
```ts
type minify = (
input: {
[file: string]: string;
},
sourceMap: import("@jridgewell/trace-mapping").SourceMapInput | undefined,
minifyOptions: {
module?: boolean | undefined;
ecma?: import("terser").ECMA | undefined;
},
extractComments:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
}
| undefined
) => Promise<{
code: string;
map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
errors?: (string | Error)[] | undefined;
warnings?: (string | Error)[] | undefined;
extractedComments?: string[] | undefined;
}>;
```
Default: `TerserPlugin.terserMinify`
Allows you to override default minify function.
By default plugin uses [terser](https://github.com/terser/terser) package.
Useful for using and testing unpublished versions or forks.
> **Warning**
>
> **Always use `require` inside `minify` function when `parallel` option enabled**.
**webpack.config.js**
```js
// Can be async
const minify = (input, sourceMap, minimizerOptions, extractsComments) => {
// The `minimizerOptions` option contains option from the `terserOptions` option
// You can use `minimizerOptions.myCustomOption`
// Custom logic for extract comments
const { map, code } = require("uglify-module") // Or require('./path/to/uglify-module')
.minify(input, {
/* Your options for minification */
});
return { map, code, warnings: [], errors: [], extractedComments: [] };
};
// Used to regenerate `fullhash`/`chunkhash` between different implementation
// Example: you fix a bug in custom minimizer/custom function, but unfortunately webpack doesn't know about it, so you will get the same fullhash/chunkhash
// to avoid this you can provide version of your custom minimizer
// You don't need if you use only `contenthash`
minify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
packageJson = require("uglify-module/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
myCustomOption: true,
},
minify,
}),
],
},
};
```
### `terserOptions`
Type:
```ts
type terserOptions = {
compress?: boolean | CompressOptions;
ecma?: ECMA;
enclose?: boolean | string;
ie8?: boolean;
keep_classnames?: boolean | RegExp;
keep_fnames?: boolean | RegExp;
mangle?: boolean | MangleOptions;
module?: boolean;
nameCache?: object;
format?: FormatOptions;
/** @deprecated */
output?: FormatOptions;
parse?: ParseOptions;
safari10?: boolean;
sourceMap?: boolean | SourceMapOptions;
toplevel?: boolean;
};
```
Default: [default](https://github.com/terser/terser#minify-options)
Terser [options](https://github.com/terser/terser#minify-options).
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
},
};
```
### `extractComments`
Type:
```ts
type extractComments =
| boolean
| string
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| {
condition?:
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined;
filename?: string | ((fileData: any) => string) | undefined;
banner?:
| string
| boolean
| ((commentsFile: string) => string)
| undefined;
};
```
Default: `true`
Whether comments shall be extracted to a separate file, (see [details](https://github.com/webpack/webpack/commit/71933e979e51c533b432658d5e37917f9e71595a)).
By default extract only comments using `/^\**!|@preserve|@license|@cc_on/i` regexp condition and remove remaining comments.
If the original file is named `foo.js`, then the comments will be stored to `foo.js.LICENSE.txt`.
The `terserOptions.format.comments` option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted.
#### `boolean`
Enable/disable extracting comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
}),
],
},
};
```
#### `string`
Extract `all` or `some` (use `/^\**!|@preserve|@license|@cc_on/i` RegExp) comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: "all",
}),
],
},
};
```
#### `RegExp`
All comments that match the given expression will be extracted to the separate file.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: /@extract/i,
}),
],
},
};
```
#### `function`
All comments that match the given expression will be extracted to the separate file.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: (astNode, comment) => {
if (/@extract/i.test(comment.value)) {
return true;
}
return false;
},
}),
],
},
};
```
#### `object`
Allow to customize condition for extract comments, specify extracted file name and banner.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```
##### `condition`
Type:
```ts
type condition =
| boolean
| "all"
| "some"
| RegExp
| ((
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean)
| undefined;
```
Condition what comments you need extract.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: "some",
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```
##### `filename`
Type:
```ts
type filename = string | ((fileData: any) => string) | undefined;
```
Default: `[file].LICENSE.txt[query]`
Available placeholders: `[file]`, `[query]` and `[filebase]` (`[base]` for webpack 5).
The file where the extracted comments will be stored.
Default is to append the suffix `.LICENSE.txt` to the original filename.
> **Warning**
>
> We highly recommend using the `txt` extension. Using `js`/`cjs`/`mjs` extensions may conflict with existing assets which leads to broken code.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
filename: "extracted-comments.js",
banner: (licenseFile) => {
return `License information can be found in ${licenseFile}`;
},
},
}),
],
},
};
```
##### `banner`
Type:
```ts
type banner = string | boolean | ((commentsFile: string) => string) | undefined;
```
Default: `/*! For license information please see ${commentsFile} */`
The banner text that points to the extracted file and will be added on top of the original file.
Can be `false` (no banner), a `String`, or a `Function<(string) -> String>` that will be called with the filename where extracted comments have been stored.
Will be wrapped into comment.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: {
condition: true,
filename: (fileData) => {
// The "fileData" argument contains object with "filename", "basename", "query" and "hash"
return `${fileData.filename}.LICENSE.txt${fileData.query}`;
},
banner: (commentsFile) => {
return `My custom banner about license information ${commentsFile}`;
},
},
}),
],
},
};
```
## Examples
### Preserve Comments
Extract all legal comments (i.e. `/^\**!|@preserve|@license|@cc_on/i`) and preserve `/@license/i` comments.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: /@license/i,
},
},
extractComments: true,
}),
],
},
};
```
### Remove Comments
If you avoid building with comments, use this config:
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
}),
],
},
};
```
### [`uglify-js`](https://github.com/mishoo/UglifyJS)
[`UglifyJS`](https://github.com/mishoo/UglifyJS) is a JavaScript parser, minifier, compressor and beautifier toolkit.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.uglifyJsMinify,
// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
terserOptions: {},
}),
],
},
};
```
### [`swc`](https://github.com/swc-project/swc)
[`swc`](https://github.com/swc-project/swc) is a super-fast compiler written in rust; producing widely-supported javascript from modern standards and typescript.
> **Warning**
>
> the `extractComments` option is not supported and all comments will be removed by default, it will be fixed in future
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.swcMinify,
// `terserOptions` options will be passed to `swc` (`@swc/core`)
// Link to options - https://swc.rs/docs/config-js-minify
terserOptions: {},
}),
],
},
};
```
### [`esbuild`](https://github.com/evanw/esbuild)
[`esbuild`](https://github.com/evanw/esbuild) is an extremely fast JavaScript bundler and minifier.
> **Warning**
>
> the `extractComments` option is not supported and all legal comments (i.e. copyright, licenses and etc) will be preserved
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.esbuildMinify,
// `terserOptions` options will be passed to `esbuild`
// Link to options - https://esbuild.github.io/api/#minify
// Note: the `minify` options is true by default (and override other `minify*` options), so if you want to disable the `minifyIdentifiers` option (or other `minify*` options) please use:
// terserOptions: {
// minify: false,
// minifyWhitespace: true,
// minifyIdentifiers: false,
// minifySyntax: true,
// },
terserOptions: {},
}),
],
},
};
```
### Custom Minify Function
Override default minify function - use `uglify-js` for minification.
**webpack.config.js**
```js
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: (file, sourceMap) => {
// https://github.com/mishoo/UglifyJS2#minify-options
const uglifyJsOptions = {
/* your `uglify-js` package options */
};
if (sourceMap) {
uglifyJsOptions.sourceMap = {
content: sourceMap,
};
}
return require("uglify-js").minify(file, uglifyJsOptions);
},
}),
],
},
};
```
### Typescript
With default terser minify function:
```ts
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
},
}),
],
},
};
```
With built-in minify functions:
```ts
import type { JsMinifyOptions as SwcOptions } from "@swc/core";
import type { MinifyOptions as UglifyJSOptions } from "uglify-js";
import type { TransformOptions as EsbuildOptions } from "esbuild";
import type { MinifyOptions as TerserOptions } from "terser";
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin<SwcOptions>({
minify: TerserPlugin.swcMinify,
terserOptions: {
// `swc` options
},
}),
new TerserPlugin<UglifyJSOptions>({
minify: TerserPlugin.uglifyJsMinify,
terserOptions: {
// `uglif-js` options
},
}),
new TerserPlugin<EsbuildOptions>({
minify: TerserPlugin.esbuildMinify,
terserOptions: {
// `esbuild` options
},
}),
// Alternative usage:
new TerserPlugin<TerserOptions>({
minify: TerserPlugin.terserMinify,
terserOptions: {
// `terser` options
},
}),
],
},
};
```
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/terser-webpack-plugin.svg
[npm-url]: https://npmjs.com/package/terser-webpack-plugin
[node]: https://img.shields.io/node/v/terser-webpack-plugin.svg
[node-url]: https://nodejs.org
[tests]: https://github.com/webpack-contrib/terser-webpack-plugin/workflows/terser-webpack-plugin/badge.svg
[tests-url]: https://github.com/webpack-contrib/terser-webpack-plugin/actions
[cover]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/terser-webpack-plugin
[discussion]: https://img.shields.io/github/discussions/webpack/webpack
[discussion-url]: https://github.com/webpack/webpack/discussions
[size]: https://packagephobia.now.sh/badge?p=terser-webpack-plugin
[size-url]: https://packagephobia.now.sh/result?p=terser-webpack-plugin

713
node_modules/terser-webpack-plugin/dist/index.js generated vendored Normal file
View File

@ -0,0 +1,713 @@
"use strict";
const path = require("path");
const os = require("os");
const {
validate
} = require("schema-utils");
const {
throttleAll,
terserMinify,
uglifyJsMinify,
swcMinify,
esbuildMinify
} = require("./utils");
const schema = require("./options.json");
const {
minify
} = require("./minify");
/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */
/** @typedef {import("webpack").Compiler} Compiler */
/** @typedef {import("webpack").Compilation} Compilation */
/** @typedef {import("webpack").WebpackError} WebpackError */
/** @typedef {import("webpack").Asset} Asset */
/** @typedef {import("./utils.js").TerserECMA} TerserECMA */
/** @typedef {import("./utils.js").TerserOptions} TerserOptions */
/** @typedef {import("jest-worker").Worker} JestWorker */
/** @typedef {import("@jridgewell/trace-mapping").SourceMapInput} SourceMapInput */
/** @typedef {import("@jridgewell/trace-mapping").TraceMap} TraceMap */
/** @typedef {RegExp | string} Rule */
/** @typedef {Rule[] | Rule} Rules */
/**
* @callback ExtractCommentsFunction
* @param {any} astNode
* @param {{ value: string, type: 'comment1' | 'comment2' | 'comment3' | 'comment4', pos: number, line: number, col: number }} comment
* @returns {boolean}
*/
/**
* @typedef {boolean | 'all' | 'some' | RegExp | ExtractCommentsFunction} ExtractCommentsCondition
*/
/**
* @typedef {string | ((fileData: any) => string)} ExtractCommentsFilename
*/
/**
* @typedef {boolean | string | ((commentsFile: string) => string)} ExtractCommentsBanner
*/
/**
* @typedef {Object} ExtractCommentsObject
* @property {ExtractCommentsCondition} [condition]
* @property {ExtractCommentsFilename} [filename]
* @property {ExtractCommentsBanner} [banner]
*/
/**
* @typedef {ExtractCommentsCondition | ExtractCommentsObject} ExtractCommentsOptions
*/
/**
* @typedef {Object} MinimizedResult
* @property {string} code
* @property {SourceMapInput} [map]
* @property {Array<Error | string>} [errors]
* @property {Array<Error | string>} [warnings]
* @property {Array<string>} [extractedComments]
*/
/**
* @typedef {{ [file: string]: string }} Input
*/
/**
* @typedef {{ [key: string]: any }} CustomOptions
*/
/**
* @template T
* @typedef {T extends infer U ? U : CustomOptions} InferDefaultType
*/
/**
* @typedef {Object} PredefinedOptions
* @property {boolean} [module]
* @property {TerserECMA} [ecma]
*/
/**
* @template T
* @typedef {PredefinedOptions & InferDefaultType<T>} MinimizerOptions
*/
/**
* @template T
* @callback BasicMinimizerImplementation
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {MinimizerOptions<T>} minifyOptions
* @param {ExtractCommentsOptions | undefined} extractComments
* @returns {Promise<MinimizedResult>}
*/
/**
* @typedef {object} MinimizeFunctionHelpers
* @property {() => string | undefined} [getMinimizerVersion]
*/
/**
* @template T
* @typedef {BasicMinimizerImplementation<T> & MinimizeFunctionHelpers} MinimizerImplementation
*/
/**
* @template T
* @typedef {Object} InternalOptions
* @property {string} name
* @property {string} input
* @property {SourceMapInput | undefined} inputSourceMap
* @property {ExtractCommentsOptions | undefined} extractComments
* @property {{ implementation: MinimizerImplementation<T>, options: MinimizerOptions<T> }} minimizer
*/
/**
* @template T
* @typedef {JestWorker & { transform: (options: string) => MinimizedResult, minify: (options: InternalOptions<T>) => MinimizedResult }} MinimizerWorker
*/
/**
* @typedef {undefined | boolean | number} Parallel
*/
/**
* @typedef {Object} BasePluginOptions
* @property {Rules} [test]
* @property {Rules} [include]
* @property {Rules} [exclude]
* @property {ExtractCommentsOptions} [extractComments]
* @property {Parallel} [parallel]
*/
/**
* @template T
* @typedef {T extends TerserOptions ? { minify?: MinimizerImplementation<T> | undefined, terserOptions?: MinimizerOptions<T> | undefined } : { minify: MinimizerImplementation<T>, terserOptions?: MinimizerOptions<T> | undefined }} DefinedDefaultMinimizerAndOptions
*/
/**
* @template T
* @typedef {BasePluginOptions & { minimizer: { implementation: MinimizerImplementation<T>, options: MinimizerOptions<T> } }} InternalPluginOptions
*/
/**
* @template T
* @param fn {(function(): any) | undefined}
* @returns {function(): T}
*/
const memoize = fn => {
let cache = false;
/** @type {T} */
let result;
return () => {
if (cache) {
return result;
}
result = /** @type {function(): any} */fn();
cache = true;
// Allow to clean up memory for fn
// and all dependent resources
// eslint-disable-next-line no-undefined, no-param-reassign
fn = undefined;
return result;
};
};
const getTraceMapping = memoize(() =>
// eslint-disable-next-line global-require
require("@jridgewell/trace-mapping"));
const getSerializeJavascript = memoize(() =>
// eslint-disable-next-line global-require
require("serialize-javascript"));
/**
* @template [T=TerserOptions]
*/
class TerserPlugin {
/**
* @param {BasePluginOptions & DefinedDefaultMinimizerAndOptions<T>} [options]
*/
constructor(options) {
validate( /** @type {Schema} */schema, options || {}, {
name: "Terser Plugin",
baseDataPath: "options"
});
// TODO make `minimizer` option instead `minify` and `terserOptions` in the next major release, also rename `terserMinify` to `terserMinimize`
const {
minify = /** @type {MinimizerImplementation<T>} */terserMinify,
terserOptions = /** @type {MinimizerOptions<T>} */{},
test = /\.[cm]?js(\?.*)?$/i,
extractComments = true,
parallel = true,
include,
exclude
} = options || {};
/**
* @private
* @type {InternalPluginOptions<T>}
*/
this.options = {
test,
extractComments,
parallel,
include,
exclude,
minimizer: {
implementation: minify,
options: terserOptions
}
};
}
/**
* @private
* @param {any} input
* @returns {boolean}
*/
static isSourceMap(input) {
// All required options for `new TraceMap(...options)`
// https://github.com/jridgewell/trace-mapping#usage
return Boolean(input && input.version && input.sources && Array.isArray(input.sources) && typeof input.mappings === "string");
}
/**
* @private
* @param {unknown} warning
* @param {string} file
* @returns {Error}
*/
static buildWarning(warning, file) {
/**
* @type {Error & { hideStack: true, file: string }}
*/
// @ts-ignore
const builtWarning = new Error(warning.toString());
builtWarning.name = "Warning";
builtWarning.hideStack = true;
builtWarning.file = file;
return builtWarning;
}
/**
* @private
* @param {any} error
* @param {string} file
* @param {TraceMap} [sourceMap]
* @param {Compilation["requestShortener"]} [requestShortener]
* @returns {Error}
*/
static buildError(error, file, sourceMap, requestShortener) {
/**
* @type {Error & { file?: string }}
*/
let builtError;
if (typeof error === "string") {
builtError = new Error(`${file} from Terser plugin\n${error}`);
builtError.file = file;
return builtError;
}
if (error.line) {
const original = sourceMap && getTraceMapping().originalPositionFor(sourceMap, {
line: error.line,
column: error.col
});
if (original && original.source && requestShortener) {
builtError = new Error(`${file} from Terser plugin\n${error.message} [${requestShortener.shorten(original.source)}:${original.line},${original.column}][${file}:${error.line},${error.col}]${error.stack ? `\n${error.stack.split("\n").slice(1).join("\n")}` : ""}`);
builtError.file = file;
return builtError;
}
builtError = new Error(`${file} from Terser plugin\n${error.message} [${file}:${error.line},${error.col}]${error.stack ? `\n${error.stack.split("\n").slice(1).join("\n")}` : ""}`);
builtError.file = file;
return builtError;
}
if (error.stack) {
builtError = new Error(`${file} from Terser plugin\n${typeof error.message !== "undefined" ? error.message : ""}\n${error.stack}`);
builtError.file = file;
return builtError;
}
builtError = new Error(`${file} from Terser plugin\n${error.message}`);
builtError.file = file;
return builtError;
}
/**
* @private
* @param {Parallel} parallel
* @returns {number}
*/
static getAvailableNumberOfCores(parallel) {
// In some cases cpus() returns undefined
// https://github.com/nodejs/node/issues/19022
const cpus = os.cpus() || {
length: 1
};
return parallel === true ? cpus.length - 1 : Math.min(Number(parallel) || 0, cpus.length - 1);
}
/**
* @private
* @param {Compiler} compiler
* @param {Compilation} compilation
* @param {Record<string, import("webpack").sources.Source>} assets
* @param {{availableNumberOfCores: number}} optimizeOptions
* @returns {Promise<void>}
*/
async optimize(compiler, compilation, assets, optimizeOptions) {
const cache = compilation.getCache("TerserWebpackPlugin");
let numberOfAssets = 0;
const assetsForMinify = await Promise.all(Object.keys(assets).filter(name => {
const {
info
} = /** @type {Asset} */compilation.getAsset(name);
if (
// Skip double minimize assets from child compilation
info.minimized ||
// Skip minimizing for extracted comments assets
info.extractedComments) {
return false;
}
if (!compiler.webpack.ModuleFilenameHelpers.matchObject.bind(
// eslint-disable-next-line no-undefined
undefined, this.options)(name)) {
return false;
}
return true;
}).map(async name => {
const {
info,
source
} = /** @type {Asset} */
compilation.getAsset(name);
const eTag = cache.getLazyHashedEtag(source);
const cacheItem = cache.getItemCache(name, eTag);
const output = await cacheItem.getPromise();
if (!output) {
numberOfAssets += 1;
}
return {
name,
info,
inputSource: source,
output,
cacheItem
};
}));
if (assetsForMinify.length === 0) {
return;
}
/** @type {undefined | (() => MinimizerWorker<T>)} */
let getWorker;
/** @type {undefined | MinimizerWorker<T>} */
let initializedWorker;
/** @type {undefined | number} */
let numberOfWorkers;
if (optimizeOptions.availableNumberOfCores > 0) {
// Do not create unnecessary workers when the number of files is less than the available cores, it saves memory
numberOfWorkers = Math.min(numberOfAssets, optimizeOptions.availableNumberOfCores);
// eslint-disable-next-line consistent-return
getWorker = () => {
if (initializedWorker) {
return initializedWorker;
}
// eslint-disable-next-line global-require
const {
Worker
} = require("jest-worker");
initializedWorker = /** @type {MinimizerWorker<T>} */
new Worker(require.resolve("./minify"), {
numWorkers: numberOfWorkers,
enableWorkerThreads: true
});
// https://github.com/facebook/jest/issues/8872#issuecomment-524822081
const workerStdout = initializedWorker.getStdout();
if (workerStdout) {
workerStdout.on("data", chunk => process.stdout.write(chunk));
}
const workerStderr = initializedWorker.getStderr();
if (workerStderr) {
workerStderr.on("data", chunk => process.stderr.write(chunk));
}
return initializedWorker;
};
}
const {
SourceMapSource,
ConcatSource,
RawSource
} = compiler.webpack.sources;
/** @typedef {{ extractedCommentsSource : import("webpack").sources.RawSource, commentsFilename: string }} ExtractedCommentsInfo */
/** @type {Map<string, ExtractedCommentsInfo>} */
const allExtractedComments = new Map();
const scheduledTasks = [];
for (const asset of assetsForMinify) {
scheduledTasks.push(async () => {
const {
name,
inputSource,
info,
cacheItem
} = asset;
let {
output
} = asset;
if (!output) {
let input;
/** @type {SourceMapInput | undefined} */
let inputSourceMap;
const {
source: sourceFromInputSource,
map
} = inputSource.sourceAndMap();
input = sourceFromInputSource;
if (map) {
if (!TerserPlugin.isSourceMap(map)) {
compilation.warnings.push( /** @type {WebpackError} */
new Error(`${name} contains invalid source map`));
} else {
inputSourceMap = /** @type {SourceMapInput} */map;
}
}
if (Buffer.isBuffer(input)) {
input = input.toString();
}
/**
* @type {InternalOptions<T>}
*/
const options = {
name,
input,
inputSourceMap,
minimizer: {
implementation: this.options.minimizer.implementation,
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/10727
options: {
...this.options.minimizer.options
}
},
extractComments: this.options.extractComments
};
if (typeof options.minimizer.options.module === "undefined") {
if (typeof info.javascriptModule !== "undefined") {
options.minimizer.options.module = info.javascriptModule;
} else if (/\.mjs(\?.*)?$/i.test(name)) {
options.minimizer.options.module = true;
} else if (/\.cjs(\?.*)?$/i.test(name)) {
options.minimizer.options.module = false;
}
}
if (typeof options.minimizer.options.ecma === "undefined") {
options.minimizer.options.ecma = TerserPlugin.getEcmaVersion(compiler.options.output.environment || {});
}
try {
output = await (getWorker ? getWorker().transform(getSerializeJavascript()(options)) : minify(options));
} catch (error) {
const hasSourceMap = inputSourceMap && TerserPlugin.isSourceMap(inputSourceMap);
compilation.errors.push( /** @type {WebpackError} */
TerserPlugin.buildError(error, name, hasSourceMap ? new (getTraceMapping().TraceMap)( /** @type {SourceMapInput} */inputSourceMap) :
// eslint-disable-next-line no-undefined
undefined,
// eslint-disable-next-line no-undefined
hasSourceMap ? compilation.requestShortener : undefined));
return;
}
if (typeof output.code === "undefined") {
compilation.errors.push( /** @type {WebpackError} */
new Error(`${name} from Terser plugin\nMinimizer doesn't return result`));
return;
}
if (output.warnings && output.warnings.length > 0) {
output.warnings = output.warnings.map(
/**
* @param {Error | string} item
*/
item => TerserPlugin.buildWarning(item, name));
}
if (output.errors && output.errors.length > 0) {
const hasSourceMap = inputSourceMap && TerserPlugin.isSourceMap(inputSourceMap);
output.errors = output.errors.map(
/**
* @param {Error | string} item
*/
item => TerserPlugin.buildError(item, name, hasSourceMap ? new (getTraceMapping().TraceMap)( /** @type {SourceMapInput} */inputSourceMap) :
// eslint-disable-next-line no-undefined
undefined,
// eslint-disable-next-line no-undefined
hasSourceMap ? compilation.requestShortener : undefined));
}
let shebang;
if ( /** @type {ExtractCommentsObject} */
this.options.extractComments.banner !== false && output.extractedComments && output.extractedComments.length > 0 && output.code.startsWith("#!")) {
const firstNewlinePosition = output.code.indexOf("\n");
shebang = output.code.substring(0, firstNewlinePosition);
output.code = output.code.substring(firstNewlinePosition + 1);
}
if (output.map) {
output.source = new SourceMapSource(output.code, name, output.map, input, /** @type {SourceMapInput} */inputSourceMap, true);
} else {
output.source = new RawSource(output.code);
}
if (output.extractedComments && output.extractedComments.length > 0) {
const commentsFilename = /** @type {ExtractCommentsObject} */
this.options.extractComments.filename || "[file].LICENSE.txt[query]";
let query = "";
let filename = name;
const querySplit = filename.indexOf("?");
if (querySplit >= 0) {
query = filename.slice(querySplit);
filename = filename.slice(0, querySplit);
}
const lastSlashIndex = filename.lastIndexOf("/");
const basename = lastSlashIndex === -1 ? filename : filename.slice(lastSlashIndex + 1);
const data = {
filename,
basename,
query
};
output.commentsFilename = compilation.getPath(commentsFilename, data);
let banner;
// Add a banner to the original file
if ( /** @type {ExtractCommentsObject} */
this.options.extractComments.banner !== false) {
banner = /** @type {ExtractCommentsObject} */
this.options.extractComments.banner || `For license information please see ${path.relative(path.dirname(name), output.commentsFilename).replace(/\\/g, "/")}`;
if (typeof banner === "function") {
banner = banner(output.commentsFilename);
}
if (banner) {
output.source = new ConcatSource(shebang ? `${shebang}\n` : "", `/*! ${banner} */\n`, output.source);
}
}
const extractedCommentsString = output.extractedComments.sort().join("\n\n");
output.extractedCommentsSource = new RawSource(`${extractedCommentsString}\n`);
}
await cacheItem.storePromise({
source: output.source,
errors: output.errors,
warnings: output.warnings,
commentsFilename: output.commentsFilename,
extractedCommentsSource: output.extractedCommentsSource
});
}
if (output.warnings && output.warnings.length > 0) {
for (const warning of output.warnings) {
compilation.warnings.push( /** @type {WebpackError} */warning);
}
}
if (output.errors && output.errors.length > 0) {
for (const error of output.errors) {
compilation.errors.push( /** @type {WebpackError} */error);
}
}
/** @type {Record<string, any>} */
const newInfo = {
minimized: true
};
const {
source,
extractedCommentsSource
} = output;
// Write extracted comments to commentsFilename
if (extractedCommentsSource) {
const {
commentsFilename
} = output;
newInfo.related = {
license: commentsFilename
};
allExtractedComments.set(name, {
extractedCommentsSource,
commentsFilename
});
}
compilation.updateAsset(name, source, newInfo);
});
}
const limit = getWorker && numberOfAssets > 0 ? /** @type {number} */numberOfWorkers : scheduledTasks.length;
await throttleAll(limit, scheduledTasks);
if (initializedWorker) {
await initializedWorker.end();
}
/** @typedef {{ source: import("webpack").sources.Source, commentsFilename: string, from: string }} ExtractedCommentsInfoWIthFrom */
await Array.from(allExtractedComments).sort().reduce(
/**
* @param {Promise<unknown>} previousPromise
* @param {[string, ExtractedCommentsInfo]} extractedComments
* @returns {Promise<ExtractedCommentsInfoWIthFrom>}
*/
async (previousPromise, [from, value]) => {
const previous = /** @type {ExtractedCommentsInfoWIthFrom | undefined} **/
await previousPromise;
const {
commentsFilename,
extractedCommentsSource
} = value;
if (previous && previous.commentsFilename === commentsFilename) {
const {
from: previousFrom,
source: prevSource
} = previous;
const mergedName = `${previousFrom}|${from}`;
const name = `${commentsFilename}|${mergedName}`;
const eTag = [prevSource, extractedCommentsSource].map(item => cache.getLazyHashedEtag(item)).reduce((previousValue, currentValue) => cache.mergeEtags(previousValue, currentValue));
let source = await cache.getPromise(name, eTag);
if (!source) {
source = new ConcatSource(Array.from(new Set([... /** @type {string}*/prevSource.source().split("\n\n"), ... /** @type {string}*/extractedCommentsSource.source().split("\n\n")])).join("\n\n"));
await cache.storePromise(name, eTag, source);
}
compilation.updateAsset(commentsFilename, source);
return {
source,
commentsFilename,
from: mergedName
};
}
const existingAsset = compilation.getAsset(commentsFilename);
if (existingAsset) {
return {
source: existingAsset.source,
commentsFilename,
from: commentsFilename
};
}
compilation.emitAsset(commentsFilename, extractedCommentsSource, {
extractedComments: true
});
return {
source: extractedCommentsSource,
commentsFilename,
from
};
}, /** @type {Promise<unknown>} */Promise.resolve());
}
/**
* @private
* @param {any} environment
* @returns {TerserECMA}
*/
static getEcmaVersion(environment) {
// ES 6th
if (environment.arrowFunction || environment.const || environment.destructuring || environment.forOf || environment.module) {
return 2015;
}
// ES 11th
if (environment.bigIntLiteral || environment.dynamicImport) {
return 2020;
}
return 5;
}
/**
* @param {Compiler} compiler
* @returns {void}
*/
apply(compiler) {
const pluginName = this.constructor.name;
const availableNumberOfCores = TerserPlugin.getAvailableNumberOfCores(this.options.parallel);
compiler.hooks.compilation.tap(pluginName, compilation => {
const hooks = compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation);
const data = getSerializeJavascript()({
minimizer: typeof this.options.minimizer.implementation.getMinimizerVersion !== "undefined" ? this.options.minimizer.implementation.getMinimizerVersion() || "0.0.0" : "0.0.0",
options: this.options.minimizer.options
});
hooks.chunkHash.tap(pluginName, (chunk, hash) => {
hash.update("TerserPlugin");
hash.update(data);
});
compilation.hooks.processAssets.tapPromise({
name: pluginName,
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
additionalAssets: true
}, assets => this.optimize(compiler, compilation, assets, {
availableNumberOfCores
}));
compilation.hooks.statsPrinter.tap(pluginName, stats => {
stats.hooks.print.for("asset.info.minimized").tap("terser-webpack-plugin", (minimized, {
green,
formatFlag
}) => minimized ? /** @type {Function} */green( /** @type {Function} */formatFlag("minimized")) : "");
});
});
}
}
TerserPlugin.terserMinify = terserMinify;
TerserPlugin.uglifyJsMinify = uglifyJsMinify;
TerserPlugin.swcMinify = swcMinify;
TerserPlugin.esbuildMinify = esbuildMinify;
module.exports = TerserPlugin;

48
node_modules/terser-webpack-plugin/dist/minify.js generated vendored Normal file
View File

@ -0,0 +1,48 @@
"use strict";
/** @typedef {import("./index.js").MinimizedResult} MinimizedResult */
/** @typedef {import("./index.js").CustomOptions} CustomOptions */
/**
* @template T
* @param {import("./index.js").InternalOptions<T>} options
* @returns {Promise<MinimizedResult>}
*/
async function minify(options) {
const {
name,
input,
inputSourceMap,
extractComments
} = options;
const {
implementation,
options: minimizerOptions
} = options.minimizer;
return implementation({
[name]: input
}, inputSourceMap, minimizerOptions, extractComments);
}
/**
* @param {string} options
* @returns {Promise<MinimizedResult>}
*/
async function transform(options) {
// 'use strict' => this === undefined (Clean Scope)
// Safer for possible security issues, albeit not critical at all here
// eslint-disable-next-line no-param-reassign
const evaluatedOptions =
/**
* @template T
* @type {import("./index.js").InternalOptions<T>}
* */
// eslint-disable-next-line no-new-func
new Function("exports", "require", "module", "__filename", "__dirname", `'use strict'\nreturn ${options}`)(exports, require, module, __filename, __dirname);
return minify(evaluatedOptions);
}
module.exports = {
minify,
transform
};

164
node_modules/terser-webpack-plugin/dist/options.json generated vendored Normal file
View File

@ -0,0 +1,164 @@
{
"definitions": {
"Rule": {
"description": "Filtering rule as regex or string.",
"anyOf": [
{
"instanceof": "RegExp",
"tsType": "RegExp"
},
{
"type": "string",
"minLength": 1
}
]
},
"Rules": {
"description": "Filtering rules.",
"anyOf": [
{
"type": "array",
"items": {
"description": "A rule condition.",
"oneOf": [
{
"$ref": "#/definitions/Rule"
}
]
}
},
{
"$ref": "#/definitions/Rule"
}
]
}
},
"title": "TerserPluginOptions",
"type": "object",
"additionalProperties": false,
"properties": {
"test": {
"description": "Include all modules that pass test assertion.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#test",
"oneOf": [
{
"$ref": "#/definitions/Rules"
}
]
},
"include": {
"description": "Include all modules matching any of these conditions.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#include",
"oneOf": [
{
"$ref": "#/definitions/Rules"
}
]
},
"exclude": {
"description": "Exclude all modules matching any of these conditions.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#exclude",
"oneOf": [
{
"$ref": "#/definitions/Rules"
}
]
},
"terserOptions": {
"description": "Options for `terser` (by default) or custom `minify` function.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions",
"additionalProperties": true,
"type": "object"
},
"extractComments": {
"description": "Whether comments shall be extracted to a separate file.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#extractcomments",
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"minLength": 1
},
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
},
{
"additionalProperties": false,
"properties": {
"condition": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"minLength": 1
},
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
}
],
"description": "Condition what comments you need extract.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#condition"
},
"filename": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"instanceof": "Function"
}
],
"description": "The file where the extracted comments will be stored. Default is to append the suffix .LICENSE.txt to the original filename.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#filename"
},
"banner": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"minLength": 1
},
{
"instanceof": "Function"
}
],
"description": "The banner text that points to the extracted file and will be added on top of the original file",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#banner"
}
},
"type": "object"
}
]
},
"parallel": {
"description": "Use multi-process parallel running to improve the build speed.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#parallel",
"anyOf": [
{
"type": "boolean"
},
{
"type": "integer"
}
]
},
"minify": {
"description": "Allows you to override default minify function.",
"link": "https://github.com/webpack-contrib/terser-webpack-plugin#number",
"instanceof": "Function"
}
}
}

615
node_modules/terser-webpack-plugin/dist/utils.js generated vendored Normal file
View File

@ -0,0 +1,615 @@
"use strict";
/** @typedef {import("@jridgewell/trace-mapping").SourceMapInput} SourceMapInput */
/** @typedef {import("terser").FormatOptions} TerserFormatOptions */
/** @typedef {import("terser").MinifyOptions} TerserOptions */
/** @typedef {import("terser").CompressOptions} TerserCompressOptions */
/** @typedef {import("terser").ECMA} TerserECMA */
/** @typedef {import("./index.js").ExtractCommentsOptions} ExtractCommentsOptions */
/** @typedef {import("./index.js").ExtractCommentsFunction} ExtractCommentsFunction */
/** @typedef {import("./index.js").ExtractCommentsCondition} ExtractCommentsCondition */
/** @typedef {import("./index.js").Input} Input */
/** @typedef {import("./index.js").MinimizedResult} MinimizedResult */
/** @typedef {import("./index.js").PredefinedOptions} PredefinedOptions */
/** @typedef {import("./index.js").CustomOptions} CustomOptions */
/**
* @typedef {Array<string>} ExtractedComments
*/
const notSettled = Symbol(`not-settled`);
/**
* @template T
* @typedef {() => Promise<T>} Task
*/
/**
* Run tasks with limited concurrency.
* @template T
* @param {number} limit - Limit of tasks that run at once.
* @param {Task<T>[]} tasks - List of tasks to run.
* @returns {Promise<T[]>} A promise that fulfills to an array of the results
*/
function throttleAll(limit, tasks) {
if (!Number.isInteger(limit) || limit < 1) {
throw new TypeError(`Expected \`limit\` to be a finite number > 0, got \`${limit}\` (${typeof limit})`);
}
if (!Array.isArray(tasks) || !tasks.every(task => typeof task === `function`)) {
throw new TypeError(`Expected \`tasks\` to be a list of functions returning a promise`);
}
return new Promise((resolve, reject) => {
const result = Array(tasks.length).fill(notSettled);
const entries = tasks.entries();
const next = () => {
const {
done,
value
} = entries.next();
if (done) {
const isLast = !result.includes(notSettled);
if (isLast) resolve( /** @type{T[]} **/result);
return;
}
const [index, task] = value;
/**
* @param {T} x
*/
const onFulfilled = x => {
result[index] = x;
next();
};
task().then(onFulfilled, reject);
};
Array(limit).fill(0).forEach(next);
});
}
/* istanbul ignore next */
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @param {ExtractCommentsOptions | undefined} extractComments
* @return {Promise<MinimizedResult>}
*/
async function terserMinify(input, sourceMap, minimizerOptions, extractComments) {
/**
* @param {any} value
* @returns {boolean}
*/
const isObject = value => {
const type = typeof value;
return value != null && (type === "object" || type === "function");
};
/**
* @param {TerserOptions & { sourceMap: undefined } & ({ output: TerserFormatOptions & { beautify: boolean } } | { format: TerserFormatOptions & { beautify: boolean } })} terserOptions
* @param {ExtractedComments} extractedComments
* @returns {ExtractCommentsFunction}
*/
const buildComments = (terserOptions, extractedComments) => {
/** @type {{ [index: string]: ExtractCommentsCondition }} */
const condition = {};
let comments;
if (terserOptions.format) {
({
comments
} = terserOptions.format);
} else if (terserOptions.output) {
({
comments
} = terserOptions.output);
}
condition.preserve = typeof comments !== "undefined" ? comments : false;
if (typeof extractComments === "boolean" && extractComments) {
condition.extract = "some";
} else if (typeof extractComments === "string" || extractComments instanceof RegExp) {
condition.extract = extractComments;
} else if (typeof extractComments === "function") {
condition.extract = extractComments;
} else if (extractComments && isObject(extractComments)) {
condition.extract = typeof extractComments.condition === "boolean" && extractComments.condition ? "some" : typeof extractComments.condition !== "undefined" ? extractComments.condition : "some";
} else {
// No extract
// Preserve using "commentsOpts" or "some"
condition.preserve = typeof comments !== "undefined" ? comments : "some";
condition.extract = false;
}
// Ensure that both conditions are functions
["preserve", "extract"].forEach(key => {
/** @type {undefined | string} */
let regexStr;
/** @type {undefined | RegExp} */
let regex;
switch (typeof condition[key]) {
case "boolean":
condition[key] = condition[key] ? () => true : () => false;
break;
case "function":
break;
case "string":
if (condition[key] === "all") {
condition[key] = () => true;
break;
}
if (condition[key] === "some") {
condition[key] = /** @type {ExtractCommentsFunction} */
(astNode, comment) => (comment.type === "comment2" || comment.type === "comment1") && /@preserve|@lic|@cc_on|^\**!/i.test(comment.value);
break;
}
regexStr = /** @type {string} */condition[key];
condition[key] = /** @type {ExtractCommentsFunction} */
(astNode, comment) => new RegExp( /** @type {string} */regexStr).test(comment.value);
break;
default:
regex = /** @type {RegExp} */condition[key];
condition[key] = /** @type {ExtractCommentsFunction} */
(astNode, comment) => /** @type {RegExp} */regex.test(comment.value);
}
});
// Redefine the comments function to extract and preserve
// comments according to the two conditions
return (astNode, comment) => {
if ( /** @type {{ extract: ExtractCommentsFunction }} */
condition.extract(astNode, comment)) {
const commentText = comment.type === "comment2" ? `/*${comment.value}*/` : `//${comment.value}`;
// Don't include duplicate comments
if (!extractedComments.includes(commentText)) {
extractedComments.push(commentText);
}
}
return (/** @type {{ preserve: ExtractCommentsFunction }} */condition.preserve(astNode, comment)
);
};
};
/**
* @param {PredefinedOptions & TerserOptions} [terserOptions={}]
* @returns {TerserOptions & { sourceMap: undefined } & { compress: TerserCompressOptions } & ({ output: TerserFormatOptions & { beautify: boolean } } | { format: TerserFormatOptions & { beautify: boolean } })}
*/
const buildTerserOptions = (terserOptions = {}) => {
// Need deep copy objects to avoid https://github.com/terser/terser/issues/366
return {
...terserOptions,
compress: typeof terserOptions.compress === "boolean" ? terserOptions.compress ? {} : false : {
...terserOptions.compress
},
// ecma: terserOptions.ecma,
// ie8: terserOptions.ie8,
// keep_classnames: terserOptions.keep_classnames,
// keep_fnames: terserOptions.keep_fnames,
mangle: terserOptions.mangle == null ? true : typeof terserOptions.mangle === "boolean" ? terserOptions.mangle : {
...terserOptions.mangle
},
// module: terserOptions.module,
// nameCache: { ...terserOptions.toplevel },
// the `output` option is deprecated
...(terserOptions.format ? {
format: {
beautify: false,
...terserOptions.format
}
} : {
output: {
beautify: false,
...terserOptions.output
}
}),
parse: {
...terserOptions.parse
},
// safari10: terserOptions.safari10,
// Ignoring sourceMap from options
// eslint-disable-next-line no-undefined
sourceMap: undefined
// toplevel: terserOptions.toplevel
};
};
// eslint-disable-next-line global-require
const {
minify
} = require("terser");
// Copy `terser` options
const terserOptions = buildTerserOptions(minimizerOptions);
// Let terser generate a SourceMap
if (sourceMap) {
// @ts-ignore
terserOptions.sourceMap = {
asObject: true
};
}
/** @type {ExtractedComments} */
const extractedComments = [];
if (terserOptions.output) {
terserOptions.output.comments = buildComments(terserOptions, extractedComments);
} else if (terserOptions.format) {
terserOptions.format.comments = buildComments(terserOptions, extractedComments);
}
if (terserOptions.compress) {
// More optimizations
if (typeof terserOptions.compress.ecma === "undefined") {
terserOptions.compress.ecma = terserOptions.ecma;
}
// https://github.com/webpack/webpack/issues/16135
if (terserOptions.ecma === 5 && typeof terserOptions.compress.arrows === "undefined") {
terserOptions.compress.arrows = false;
}
}
const [[filename, code]] = Object.entries(input);
const result = await minify({
[filename]: code
}, terserOptions);
return {
code: /** @type {string} **/result.code,
// @ts-ignore
// eslint-disable-next-line no-undefined
map: result.map ? /** @type {SourceMapInput} **/result.map : undefined,
extractedComments
};
}
/**
* @returns {string | undefined}
*/
terserMinify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require
packageJson = require("terser/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
/* istanbul ignore next */
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @param {ExtractCommentsOptions | undefined} extractComments
* @return {Promise<MinimizedResult>}
*/
async function uglifyJsMinify(input, sourceMap, minimizerOptions, extractComments) {
/**
* @param {any} value
* @returns {boolean}
*/
const isObject = value => {
const type = typeof value;
return value != null && (type === "object" || type === "function");
};
/**
* @param {import("uglify-js").MinifyOptions & { sourceMap: undefined } & { output: import("uglify-js").OutputOptions & { beautify: boolean }}} uglifyJsOptions
* @param {ExtractedComments} extractedComments
* @returns {ExtractCommentsFunction}
*/
const buildComments = (uglifyJsOptions, extractedComments) => {
/** @type {{ [index: string]: ExtractCommentsCondition }} */
const condition = {};
const {
comments
} = uglifyJsOptions.output;
condition.preserve = typeof comments !== "undefined" ? comments : false;
if (typeof extractComments === "boolean" && extractComments) {
condition.extract = "some";
} else if (typeof extractComments === "string" || extractComments instanceof RegExp) {
condition.extract = extractComments;
} else if (typeof extractComments === "function") {
condition.extract = extractComments;
} else if (extractComments && isObject(extractComments)) {
condition.extract = typeof extractComments.condition === "boolean" && extractComments.condition ? "some" : typeof extractComments.condition !== "undefined" ? extractComments.condition : "some";
} else {
// No extract
// Preserve using "commentsOpts" or "some"
condition.preserve = typeof comments !== "undefined" ? comments : "some";
condition.extract = false;
}
// Ensure that both conditions are functions
["preserve", "extract"].forEach(key => {
/** @type {undefined | string} */
let regexStr;
/** @type {undefined | RegExp} */
let regex;
switch (typeof condition[key]) {
case "boolean":
condition[key] = condition[key] ? () => true : () => false;
break;
case "function":
break;
case "string":
if (condition[key] === "all") {
condition[key] = () => true;
break;
}
if (condition[key] === "some") {
condition[key] = /** @type {ExtractCommentsFunction} */
(astNode, comment) => (comment.type === "comment2" || comment.type === "comment1") && /@preserve|@lic|@cc_on|^\**!/i.test(comment.value);
break;
}
regexStr = /** @type {string} */condition[key];
condition[key] = /** @type {ExtractCommentsFunction} */
(astNode, comment) => new RegExp( /** @type {string} */regexStr).test(comment.value);
break;
default:
regex = /** @type {RegExp} */condition[key];
condition[key] = /** @type {ExtractCommentsFunction} */
(astNode, comment) => /** @type {RegExp} */regex.test(comment.value);
}
});
// Redefine the comments function to extract and preserve
// comments according to the two conditions
return (astNode, comment) => {
if ( /** @type {{ extract: ExtractCommentsFunction }} */
condition.extract(astNode, comment)) {
const commentText = comment.type === "comment2" ? `/*${comment.value}*/` : `//${comment.value}`;
// Don't include duplicate comments
if (!extractedComments.includes(commentText)) {
extractedComments.push(commentText);
}
}
return (/** @type {{ preserve: ExtractCommentsFunction }} */condition.preserve(astNode, comment)
);
};
};
/**
* @param {PredefinedOptions & import("uglify-js").MinifyOptions} [uglifyJsOptions={}]
* @returns {import("uglify-js").MinifyOptions & { sourceMap: undefined } & { output: import("uglify-js").OutputOptions & { beautify: boolean }}}
*/
const buildUglifyJsOptions = (uglifyJsOptions = {}) => {
// eslint-disable-next-line no-param-reassign
delete minimizerOptions.ecma;
// eslint-disable-next-line no-param-reassign
delete minimizerOptions.module;
// Need deep copy objects to avoid https://github.com/terser/terser/issues/366
return {
...uglifyJsOptions,
// warnings: uglifyJsOptions.warnings,
parse: {
...uglifyJsOptions.parse
},
compress: typeof uglifyJsOptions.compress === "boolean" ? uglifyJsOptions.compress : {
...uglifyJsOptions.compress
},
mangle: uglifyJsOptions.mangle == null ? true : typeof uglifyJsOptions.mangle === "boolean" ? uglifyJsOptions.mangle : {
...uglifyJsOptions.mangle
},
output: {
beautify: false,
...uglifyJsOptions.output
},
// Ignoring sourceMap from options
// eslint-disable-next-line no-undefined
sourceMap: undefined
// toplevel: uglifyJsOptions.toplevel
// nameCache: { ...uglifyJsOptions.toplevel },
// ie8: uglifyJsOptions.ie8,
// keep_fnames: uglifyJsOptions.keep_fnames,
};
};
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
const {
minify
} = require("uglify-js");
// Copy `uglify-js` options
const uglifyJsOptions = buildUglifyJsOptions(minimizerOptions);
// Let terser generate a SourceMap
if (sourceMap) {
// @ts-ignore
uglifyJsOptions.sourceMap = true;
}
/** @type {ExtractedComments} */
const extractedComments = [];
// @ts-ignore
uglifyJsOptions.output.comments = buildComments(uglifyJsOptions, extractedComments);
const [[filename, code]] = Object.entries(input);
const result = await minify({
[filename]: code
}, uglifyJsOptions);
return {
code: result.code,
// eslint-disable-next-line no-undefined
map: result.map ? JSON.parse(result.map) : undefined,
errors: result.error ? [result.error] : [],
warnings: result.warnings || [],
extractedComments
};
}
/**
* @returns {string | undefined}
*/
uglifyJsMinify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
packageJson = require("uglify-js/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
/* istanbul ignore next */
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @return {Promise<MinimizedResult>}
*/
async function swcMinify(input, sourceMap, minimizerOptions) {
/**
* @param {PredefinedOptions & import("@swc/core").JsMinifyOptions} [swcOptions={}]
* @returns {import("@swc/core").JsMinifyOptions & { sourceMap: undefined } & { compress: import("@swc/core").TerserCompressOptions }}
*/
const buildSwcOptions = (swcOptions = {}) => {
// Need deep copy objects to avoid https://github.com/terser/terser/issues/366
return {
...swcOptions,
compress: typeof swcOptions.compress === "boolean" ? swcOptions.compress ? {} : false : {
...swcOptions.compress
},
mangle: swcOptions.mangle == null ? true : typeof swcOptions.mangle === "boolean" ? swcOptions.mangle : {
...swcOptions.mangle
},
// ecma: swcOptions.ecma,
// keep_classnames: swcOptions.keep_classnames,
// keep_fnames: swcOptions.keep_fnames,
// module: swcOptions.module,
// safari10: swcOptions.safari10,
// toplevel: swcOptions.toplevel
// eslint-disable-next-line no-undefined
sourceMap: undefined
};
};
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
const swc = require("@swc/core");
// Copy `swc` options
const swcOptions = buildSwcOptions(minimizerOptions);
// Let `swc` generate a SourceMap
if (sourceMap) {
// @ts-ignore
swcOptions.sourceMap = true;
}
if (swcOptions.compress) {
// More optimizations
if (typeof swcOptions.compress.ecma === "undefined") {
swcOptions.compress.ecma = swcOptions.ecma;
}
// https://github.com/webpack/webpack/issues/16135
if (swcOptions.ecma === 5 && typeof swcOptions.compress.arrows === "undefined") {
swcOptions.compress.arrows = false;
}
}
const [[filename, code]] = Object.entries(input);
const result = await swc.minify(code, swcOptions);
let map;
if (result.map) {
map = JSON.parse(result.map);
// TODO workaround for swc because `filename` is not preset as in `swc` signature as for `terser`
map.sources = [filename];
delete map.sourcesContent;
}
return {
code: result.code,
map
};
}
/**
* @returns {string | undefined}
*/
swcMinify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
packageJson = require("@swc/core/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
/* istanbul ignore next */
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @return {Promise<MinimizedResult>}
*/
async function esbuildMinify(input, sourceMap, minimizerOptions) {
/**
* @param {PredefinedOptions & import("esbuild").TransformOptions} [esbuildOptions={}]
* @returns {import("esbuild").TransformOptions}
*/
const buildEsbuildOptions = (esbuildOptions = {}) => {
// eslint-disable-next-line no-param-reassign
delete esbuildOptions.ecma;
if (esbuildOptions.module) {
// eslint-disable-next-line no-param-reassign
esbuildOptions.format = "esm";
}
// eslint-disable-next-line no-param-reassign
delete esbuildOptions.module;
// Need deep copy objects to avoid https://github.com/terser/terser/issues/366
return {
minify: true,
legalComments: "inline",
...esbuildOptions,
sourcemap: false
};
};
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
const esbuild = require("esbuild");
// Copy `esbuild` options
const esbuildOptions = buildEsbuildOptions(minimizerOptions);
// Let `esbuild` generate a SourceMap
if (sourceMap) {
esbuildOptions.sourcemap = true;
esbuildOptions.sourcesContent = false;
}
const [[filename, code]] = Object.entries(input);
esbuildOptions.sourcefile = filename;
const result = await esbuild.transform(code, esbuildOptions);
return {
code: result.code,
// eslint-disable-next-line no-undefined
map: result.map ? JSON.parse(result.map) : undefined,
warnings: result.warnings.length > 0 ? result.warnings.map(item => {
const plugin = item.pluginName ? `\nPlugin Name: ${item.pluginName}` : "";
const location = item.location ? `\n\n${item.location.file}:${item.location.line}:${item.location.column}:\n ${item.location.line} | ${item.location.lineText}\n\nSuggestion: ${item.location.suggestion}` : "";
const notes = item.notes.length > 0 ? `\n\nNotes:\n${item.notes.map(note => `${note.location ? `[${note.location.file}:${note.location.line}:${note.location.column}] ` : ""}${note.text}${note.location ? `\nSuggestion: ${note.location.suggestion}` : ""}${note.location ? `\nLine text:\n${note.location.lineText}\n` : ""}`).join("\n")}` : "";
return `${item.text} [${item.id}]${plugin}${location}${item.detail ? `\nDetails:\n${item.detail}` : ""}${notes}`;
}) : []
};
}
/**
* @returns {string | undefined}
*/
esbuildMinify.getMinimizerVersion = () => {
let packageJson;
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
packageJson = require("esbuild/package.json");
} catch (error) {
// Ignore
}
return packageJson && packageJson.version;
};
module.exports = {
throttleAll,
terserMinify,
uglifyJsMinify,
swcMinify,
esbuildMinify
};

View File

@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../../../terser/bin/terser" "$@"
ret=$?
else
node "$basedir/../../../terser/bin/terser" "$@"
ret=$?
fi
exit $ret

View File

@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\..\..\terser\bin\terser" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\..\..\terser\bin\terser" %*
)

View File

@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../../../webpack/bin/webpack.js" "$@"
ret=$?
else
node "$basedir/../../../webpack/bin/webpack.js" "$@"
ret=$?
fi
exit $ret

View File

@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\..\..\webpack\bin\webpack.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\..\..\webpack\bin\webpack.js" %*
)

View File

@ -0,0 +1,340 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [3.3.0](https://github.com/webpack/schema-utils/compare/v3.2.0...v3.3.0) (2023-06-14)
### Features
* added API to disable and enable validation ([#183](https://github.com/webpack/schema-utils/issues/183)) ([d4d334f](https://github.com/webpack/schema-utils/commit/d4d334f0ba22eb6b6564b1119e8f3ea439e1f2bb))
### Bug Fixes
* **perf:** cache compiled schema ([#182](https://github.com/webpack/schema-utils/issues/182)) ([02aa068](https://github.com/webpack/schema-utils/commit/02aa068df80d99cc576a5ed385f947eb5204c5db))
## [3.2.0](https://github.com/webpack/schema-utils/compare/v3.1.2...v3.2.0) (2023-06-07)
### Features
* implement `undefinedAsNull` keyword for `enum` type ([#176](https://github.com/webpack/schema-utils/issues/176)) ([95826eb](https://github.com/webpack/schema-utils/commit/95826eb9e14bc4b10ab95f962ac2bdca447880a3))
### [3.1.2](https://github.com/webpack/schema-utils/compare/v3.1.1...v3.1.2) (2023-04-15)
### Bug Fixes
* **perf:** reduced initial start time ([#170](https://github.com/webpack/schema-utils/issues/170)) ([8d052e6](https://github.com/webpack/schema-utils/commit/8d052e6764dc9247e7d5b7b1ae8f87ca5047b2b0))
### [3.1.1](https://github.com/webpack/schema-utils/compare/v3.1.0...v3.1.1) (2021-07-19)
### Bug Fixes
* update error message for `integer` ([#136](https://github.com/webpack/schema-utils/issues/136)) ([2daa97e](https://github.com/webpack/schema-utils/commit/2daa97eae87e6790b92711746a6a527b859ac13b))
## [3.1.0](https://github.com/webpack/schema-utils/compare/v3.0.0...v3.1.0) (2021-06-30)
### Features
* added the `link` property in validation error ([589aa59](https://github.com/webpack/schema-utils/commit/589aa5993424a8bc45ec22b67dff55be92c456a9))
### Bug Fixes
* non-empty validation error message ([#116](https://github.com/webpack/schema-utils/issues/116)) ([c51abef](https://github.com/webpack/schema-utils/commit/c51abefa4d4d62e1346b3a105182d36675595077))
## [3.0.0](https://github.com/webpack/schema-utils/compare/v2.7.1...v3.0.0) (2020-10-05)
### ⚠ BREAKING CHANGES
* minimum supported `Node.js` version is `10.13.0`,
* the packages exports was changed, please use `const { validate } = require('schema-utils');`
* the `ValidateError` export was removed in favor the `ValidationError` export, please use `const { ValidationError } = require('schema-utils');`
### [2.7.1](https://github.com/webpack/schema-utils/compare/v2.7.0...v2.7.1) (2020-08-31)
### Bug Fixes
* remove esModuleInterop from tsconfig ([#110](https://github.com/webpack/schema-utils/issues/110)) ([#111](https://github.com/webpack/schema-utils/issues/111)) ([2f40154](https://github.com/webpack/schema-utils/commit/2f40154b91e45b393258ae9dd8f10cc3b8590b7d))
## [2.7.0](https://github.com/webpack/schema-utils/compare/v2.6.6...v2.7.0) (2020-05-29)
### Features
* improve hints ([a36e535](https://github.com/webpack/schema-utils/commit/a36e535faca1b01e27c3bfa3c8bee9227c3f836c))
* smart not case ([#101](https://github.com/webpack/schema-utils/issues/101)) ([698d8b0](https://github.com/webpack/schema-utils/commit/698d8b05462d86aadb217e25a45c7b953a79a52e))
### Bug Fixes
* move @types/json-schema from devDependencies to dependencies ([#97](https://github.com/webpack/schema-utils/issues/97)) ([#98](https://github.com/webpack/schema-utils/issues/98)) ([945e67d](https://github.com/webpack/schema-utils/commit/945e67db5e19baf7ec7df72813b0739dd56f950d))
### [2.6.6](https://github.com/webpack/schema-utils/compare/v2.6.5...v2.6.6) (2020-04-17)
### Bug Fixes
* improve perf
### [2.6.5](https://github.com/webpack/schema-utils/compare/v2.6.4...v2.6.5) (2020-03-11)
### Bug Fixes
* correct dots at end of sentence ([7284beb](https://github.com/webpack/schema-utils/commit/7284bebe00cd570f1bef2c15951a07b9794038e6))
### [2.6.4](https://github.com/webpack/schema-utils/compare/v2.6.3...v2.6.4) (2020-01-17)
### Bug Fixes
* change `initialised` to `initialized` ([#87](https://github.com/webpack/schema-utils/issues/87)) ([70f12d3](https://github.com/webpack/schema-utils/commit/70f12d33a8eaa27249bc9c1a27f886724cf91ea7))
### [2.6.3](https://github.com/webpack/schema-utils/compare/v2.6.2...v2.6.3) (2020-01-17)
### Bug Fixes
* prefer the `baseDataPath` option from arguments ([#86](https://github.com/webpack/schema-utils/issues/86)) ([e236859](https://github.com/webpack/schema-utils/commit/e236859e85b28e35e1294f86fc1ff596a5031cea))
### [2.6.2](https://github.com/webpack/schema-utils/compare/v2.6.1...v2.6.2) (2020-01-14)
### Bug Fixes
* better handle Windows absolute paths ([#85](https://github.com/webpack/schema-utils/issues/85)) ([1fa2930](https://github.com/webpack/schema-utils/commit/1fa2930a161e907b9fc53a7233d605910afdb883))
### [2.6.1](https://github.com/webpack/schema-utils/compare/v2.6.0...v2.6.1) (2019-11-28)
### Bug Fixes
* typescript declarations ([#84](https://github.com/webpack/schema-utils/issues/84)) ([89d55a9](https://github.com/webpack/schema-utils/commit/89d55a9a8edfa6a8ac8b112f226bb3154e260319))
## [2.6.0](https://github.com/webpack/schema-utils/compare/v2.5.0...v2.6.0) (2019-11-27)
### Features
* support configuration via title ([#81](https://github.com/webpack/schema-utils/issues/81)) ([afddc10](https://github.com/webpack/schema-utils/commit/afddc109f6891cd37a9f1835d50862d119a072bf))
### Bug Fixes
* typescript definitions ([#70](https://github.com/webpack/schema-utils/issues/70)) ([f38158d](https://github.com/webpack/schema-utils/commit/f38158d6d040e2c701622778ae8122fb26a4f990))
## [2.5.0](https://github.com/webpack/schema-utils/compare/v2.4.1...v2.5.0) (2019-10-15)
### Bug Fixes
* rework format for maxLength, minLength ([#67](https://github.com/webpack/schema-utils/issues/67)) ([0d12259](https://github.com/webpack/schema-utils/commit/0d12259))
* support all cases with one number in range ([#64](https://github.com/webpack/schema-utils/issues/64)) ([7fc8069](https://github.com/webpack/schema-utils/commit/7fc8069))
* typescript definition and export naming ([#69](https://github.com/webpack/schema-utils/issues/69)) ([a435b79](https://github.com/webpack/schema-utils/commit/a435b79))
### Features
* "smart" numbers range ([62fb107](https://github.com/webpack/schema-utils/commit/62fb107))
### [2.4.1](https://github.com/webpack/schema-utils/compare/v2.4.0...v2.4.1) (2019-09-27)
### Bug Fixes
* publish definitions ([#58](https://github.com/webpack/schema-utils/issues/58)) ([1885faa](https://github.com/webpack/schema-utils/commit/1885faa))
## [2.4.0](https://github.com/webpack/schema-utils/compare/v2.3.0...v2.4.0) (2019-09-26)
### Features
* better errors when the `type` keyword doesn't exist ([0988be2](https://github.com/webpack/schema-utils/commit/0988be2))
* support $data reference ([#56](https://github.com/webpack/schema-utils/issues/56)) ([d2f11d6](https://github.com/webpack/schema-utils/commit/d2f11d6))
* types definitions ([#52](https://github.com/webpack/schema-utils/issues/52)) ([facb431](https://github.com/webpack/schema-utils/commit/facb431))
## [2.3.0](https://github.com/webpack/schema-utils/compare/v2.2.0...v2.3.0) (2019-09-26)
### Features
* support `not` keyword ([#53](https://github.com/webpack/schema-utils/issues/53)) ([765f458](https://github.com/webpack/schema-utils/commit/765f458))
## [2.2.0](https://github.com/webpack/schema-utils/compare/v2.1.0...v2.2.0) (2019-09-02)
### Features
* better error output for `oneOf` and `anyOf` ([#48](https://github.com/webpack/schema-utils/issues/48)) ([#50](https://github.com/webpack/schema-utils/issues/50)) ([332242f](https://github.com/webpack/schema-utils/commit/332242f))
## [2.1.0](https://github.com/webpack-contrib/schema-utils/compare/v2.0.1...v2.1.0) (2019-08-07)
### Bug Fixes
* throw error on sparse arrays ([#47](https://github.com/webpack-contrib/schema-utils/issues/47)) ([b85ac38](https://github.com/webpack-contrib/schema-utils/commit/b85ac38))
### Features
* export `ValidateError` ([#46](https://github.com/webpack-contrib/schema-utils/issues/46)) ([ff781d7](https://github.com/webpack-contrib/schema-utils/commit/ff781d7))
### [2.0.1](https://github.com/webpack-contrib/schema-utils/compare/v2.0.0...v2.0.1) (2019-07-18)
### Bug Fixes
* error message for empty object ([#44](https://github.com/webpack-contrib/schema-utils/issues/44)) ([0b4b4a2](https://github.com/webpack-contrib/schema-utils/commit/0b4b4a2))
### [2.0.0](https://github.com/webpack-contrib/schema-utils/compare/v1.0.0...v2.0.0) (2019-07-17)
### BREAKING CHANGES
* drop support for Node.js < 8.9.0
* drop support `errorMessage`, please use `description` for links.
* api was changed, please look documentation.
* error messages was fully rewritten.
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/schema-utils/compare/v0.4.7...v1.0.0) (2018-08-07)
### Features
* **src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))
<a name="0.4.7"></a>
## [0.4.7](https://github.com/webpack-contrib/schema-utils/compare/v0.4.6...v0.4.7) (2018-08-07)
### Bug Fixes
* **src:** `node >= v4.0.0` support ([#32](https://github.com/webpack-contrib/schema-utils/issues/32)) ([cb13dd4](https://github.com/webpack-contrib/schema-utils/commit/cb13dd4))
<a name="0.4.6"></a>
## [0.4.6](https://github.com/webpack-contrib/schema-utils/compare/v0.4.5...v0.4.6) (2018-08-06)
### Bug Fixes
* **package:** remove lockfile ([#28](https://github.com/webpack-contrib/schema-utils/issues/28)) ([69f1a81](https://github.com/webpack-contrib/schema-utils/commit/69f1a81))
* **package:** remove unnecessary `webpack` dependency ([#26](https://github.com/webpack-contrib/schema-utils/issues/26)) ([532eaa5](https://github.com/webpack-contrib/schema-utils/commit/532eaa5))
<a name="0.4.5"></a>
## [0.4.5](https://github.com/webpack-contrib/schema-utils/compare/v0.4.4...v0.4.5) (2018-02-13)
### Bug Fixes
* **CHANGELOG:** update broken links ([4483b9f](https://github.com/webpack-contrib/schema-utils/commit/4483b9f))
* **package:** update broken links ([f2494ba](https://github.com/webpack-contrib/schema-utils/commit/f2494ba))
<a name="0.4.4"></a>
## [0.4.4](https://github.com/webpack-contrib/schema-utils/compare/v0.4.3...v0.4.4) (2018-02-13)
### Bug Fixes
* **package:** update `dependencies` ([#22](https://github.com/webpack-contrib/schema-utils/issues/22)) ([3aecac6](https://github.com/webpack-contrib/schema-utils/commit/3aecac6))
<a name="0.4.3"></a>
## [0.4.3](https://github.com/webpack-contrib/schema-utils/compare/v0.4.2...v0.4.3) (2017-12-14)
### Bug Fixes
* **validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
* **ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))
<a name="0.4.2"></a>
## [0.4.2](https://github.com/webpack-contrib/schema-utils/compare/v0.4.1...v0.4.2) (2017-11-09)
### Bug Fixes
* **validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))
<a name="0.4.1"></a>
## [0.4.1](https://github.com/webpack-contrib/schema-utils/compare/v0.4.0...v0.4.1) (2017-11-03)
### Bug Fixes
* **ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))
<a name="0.4.0"></a>
# [0.4.0](https://github.com/webpack-contrib/schema-utils/compare/v0.3.0...v0.4.0) (2017-10-28)
### Features
* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))
<a name="0.3.0"></a>
# [0.3.0](https://github.com/webpack-contrib/schema-utils/compare/v0.2.1...v0.3.0) (2017-04-29)
### Features
* add ValidationError ([#8](https://github.com/webpack-contrib/schema-utils/issues/8)) ([d48f0fb](https://github.com/webpack-contrib/schema-utils/commit/d48f0fb))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/webpack-contrib/schema-utils/compare/v0.2.0...v0.2.1) (2017-03-13)
### Bug Fixes
* Include .babelrc to `files` ([28f0363](https://github.com/webpack-contrib/schema-utils/commit/28f0363))
* Include source to `files` ([43b0f2f](https://github.com/webpack-contrib/schema-utils/commit/43b0f2f))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/webpack-contrib/schema-utils/compare/v0.1.0...v0.2.0) (2017-03-12)
<a name="0.1.0"></a>
# 0.1.0 (2017-03-07)
### Features
* **validations:** add validateOptions module ([ae9b47b](https://github.com/webpack-contrib/schema-utils/commit/ae9b47b))
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

View File

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

View File

@ -0,0 +1,290 @@
<div align="center">
<a href="http://json-schema.org">
<img width="160" height="160"
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/.github/assets/logo.png">
</a>
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# schema-utils
Package for validate options in loaders and plugins.
## Getting Started
To begin, you'll need to install `schema-utils`:
```console
npm install schema-utils
```
## API
**schema.json**
```json
{
"type": "object",
"properties": {
"option": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { option: true };
const configuration = { name: "Loader Name/Plugin Name/Name" };
validate(schema, options, configuration);
```
### `schema`
Type: `String`
JSON schema.
Simple example of schema:
```json
{
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
### `options`
Type: `Object`
Object with options.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, { name: 123 }, { name: "MyPlugin" });
```
### `configuration`
Allow to configure validator.
There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
For example:
```json
{
"title": "My Loader options",
"type": "object",
"properties": {
"name": {
"description": "This is description of option.",
"type": "string"
}
},
"additionalProperties": false
}
```
The last word used for the `baseDataPath` option, other words used for the `name` option.
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
#### `name`
Type: `Object`
Default: `"Object"`
Allow to setup name in validation errors.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, options, { name: "MyPlugin" });
```
```shell
Invalid configuration object. MyPlugin has been initialised using a configuration object that does not match the API schema.
- configuration.optionName should be a integer.
```
#### `baseDataPath`
Type: `String`
Default: `"configuration"`
Allow to setup base data path in validation errors.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, options, { name: "MyPlugin", baseDataPath: "options" });
```
```shell
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
- options.optionName should be a integer.
```
#### `postFormatter`
Type: `Function`
Default: `undefined`
Allow to reformat errors.
```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";
const options = { foo: "bar" };
validate(schema, options, {
name: "MyPlugin",
postFormatter: (formattedError, error) => {
if (error.keyword === "type") {
return `${formattedError}\nAdditional Information.`;
}
return formattedError;
},
});
```
```shell
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
- options.optionName should be a integer.
Additional Information.
```
## Examples
**schema.json**
```json
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"test": {
"anyOf": [
{ "type": "array" },
{ "type": "string" },
{ "instanceof": "RegExp" }
]
},
"transform": {
"instanceof": "Function"
},
"sourceMap": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
### `Loader`
```js
import { getOptions } from "loader-utils";
import { validate } from "schema-utils";
import schema from "path/to/schema.json";
function loader(src, map) {
const options = getOptions(this);
validate(schema, options, {
name: "Loader Name",
baseDataPath: "options",
});
// Code...
}
export default loader;
```
### `Plugin`
```js
import { validate } from "schema-utils";
import schema from "path/to/schema.json";
class Plugin {
constructor(options) {
validate(schema, options, {
name: "Plugin Name",
baseDataPath: "options",
});
this.options = options;
}
apply(compiler) {
// Code...
}
}
export default Plugin;
```
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack/schema-utils.svg
[deps-url]: https://david-dm.org/webpack/schema-utils
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
[tests-url]: https://github.com/webpack/schema-utils/actions
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/schema-utils
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.com/badge?p=schema-utils
[size-url]: https://packagephobia.com/result?p=schema-utils

View File

@ -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;
}

View File

@ -0,0 +1,12 @@
import { validate } from "./validate";
import { ValidationError } from "./validate";
import { enableValidation } from "./validate";
import { disableValidation } from "./validate";
import { needValidate } from "./validate";
export {
validate,
ValidationError,
enableValidation,
disableValidation,
needValidate,
};

View File

@ -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;

View File

@ -0,0 +1,8 @@
export default addUndefinedAsNullKeyword;
export type Ajv = import("ajv").Ajv;
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
declare function addUndefinedAsNullKeyword(ajv: Ajv): Ajv;

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,42 @@
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 ValidateFunction = import("ajv").ValidateFunction;
export type Extend = {
formatMinimum?: number | undefined;
formatMaximum?: number | undefined;
formatExclusiveMinimum?: boolean | undefined;
formatExclusiveMaximum?: boolean | undefined;
link?: string | undefined;
undefinedAsNull?: boolean | 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;
export function enableValidation(): void;
export function disableValidation(): void;
export function needValidate(): boolean;
import ValidationError from "./ValidationError";
export { ValidationError };

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
"use strict";
const {
validate,
ValidationError,
enableValidation,
disableValidation,
needValidate
} = require("./validate");
module.exports = {
validate,
ValidationError,
enableValidation,
disableValidation,
needValidate
};

View File

@ -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;

View File

@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/** @typedef {import("ajv").Ajv} Ajv */
/**
*
* @param {Ajv} ajv
* @param {string} keyword
* @param {any} definition
*/
function addKeyword(ajv, keyword, definition) {
let customRuleCode;
try {
// @ts-ignore
// eslint-disable-next-line global-require
customRuleCode = require("ajv/lib/dotjs/custom"); // @ts-ignore
const {
RULES
} = ajv;
let ruleGroup;
for (let i = 0; i < RULES.length; i++) {
const rg = RULES[i];
if (typeof rg.type === "undefined") {
ruleGroup = rg;
break;
}
}
const rule = {
keyword,
definition,
custom: true,
code: customRuleCode,
implements: definition.implements
};
ruleGroup.rules.unshift(rule);
RULES.custom[keyword] = rule;
RULES.keywords[keyword] = true;
RULES.all[keyword] = true;
} catch (e) {// Nothing, fallback
}
}
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
function addUndefinedAsNullKeyword(ajv) {
// There is workaround for old versions of ajv, where `before` is not implemented
addKeyword(ajv, "undefinedAsNull", {
modifying: true,
/**
* @param {boolean} kwVal
* @param {unknown} data
* @param {any} parentSchema
* @param {string} dataPath
* @param {unknown} parentData
* @param {number | string} parentDataProperty
* @return {boolean}
*/
validate(kwVal, data, parentSchema, dataPath, parentData, parentDataProperty) {
if (kwVal && parentSchema && typeof parentSchema.enum !== "undefined" && parentData && typeof parentDataProperty === "number") {
const idx =
/** @type {number} */
parentDataProperty;
const parentDataRef =
/** @type {any[]} */
parentData;
if (typeof parentDataRef[idx] === "undefined") {
parentDataRef[idx] = null;
}
}
return true;
}
});
return ajv;
}
var _default = addUndefinedAsNullKeyword;
exports.default = _default;

View File

@ -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;

View File

@ -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;
};

View File

@ -0,0 +1,258 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validate = validate;
exports.enableValidation = enableValidation;
exports.disableValidation = disableValidation;
exports.needValidate = needValidate;
Object.defineProperty(exports, "ValidationError", {
enumerable: true,
get: function () {
return _ValidationError.default;
}
});
var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));
var _undefinedAsNull = _interopRequireDefault(require("./keywords/undefinedAsNull"));
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @template T
* @param fn {(function(): any) | undefined}
* @returns {function(): T}
*/
const memoize = fn => {
let cache = false;
/** @type {T} */
let result;
return () => {
if (cache) {
return result;
}
result =
/** @type {function(): any} */
fn();
cache = true; // Allow to clean up memory for fn
// and all dependent resources
// eslint-disable-next-line no-undefined, no-param-reassign
fn = undefined;
return result;
};
};
const getAjv = memoize(() => {
// Use CommonJS require for ajv libs so TypeScript consumers aren't locked into esModuleInterop (see #110).
// eslint-disable-next-line global-require
const Ajv = require("ajv"); // eslint-disable-next-line global-require
const ajvKeywords = require("ajv-keywords");
const ajv = new Ajv({
allErrors: true,
verbose: true,
$data: true
});
ajvKeywords(ajv, ["instanceof", "formatMinimum", "formatMaximum", "patternRequired"]); // Custom keywords
(0, _absolutePath.default)(ajv);
(0, _undefinedAsNull.default)(ajv);
return ajv;
});
/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("ajv").ErrorObject} ErrorObject */
/** @typedef {import("ajv").ValidateFunction} ValidateFunction */
/**
* @typedef {Object} Extend
* @property {number=} formatMinimum
* @property {number=} formatMaximum
* @property {boolean=} formatExclusiveMinimum
* @property {boolean=} formatExclusiveMaximum
* @property {string=} link
* @property {boolean=} undefinedAsNull
*/
/** @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
*/
/**
* @param {SchemaUtilErrorObject} error
* @param {number} idx
* @returns {SchemaUtilErrorObject}
*/
function applyPrefix(error, idx) {
// eslint-disable-next-line no-param-reassign
error.dataPath = `[${idx}]${error.dataPath}`;
if (error.children) {
error.children.forEach(err => applyPrefix(err, idx));
}
return error;
}
let skipValidation = false; // We use `process.env.SKIP_VALIDATION` because you can have multiple `schema-utils` with different version,
// so we want to disable it globally, `process.env` doesn't supported by browsers, so we have the local `skipValidation` variables
// Enable validation
function enableValidation() {
skipValidation = false; // Disable validation for any versions
if (process && process.env) {
process.env.SKIP_VALIDATION = "n";
}
} // Disable validation
function disableValidation() {
skipValidation = true;
if (process && process.env) {
process.env.SKIP_VALIDATION = "y";
}
} // Check if we need to confirm
function needValidate() {
if (skipValidation) {
return false;
}
if (process && process.env && process.env.SKIP_VALIDATION) {
const value = process.env.SKIP_VALIDATION.trim();
if (/^(?:y|yes|true|1|on)$/i.test(value)) {
return false;
}
if (/^(?:n|no|false|0|off)$/i.test(value)) {
return true;
}
}
return true;
}
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
function validate(schema, options, configuration) {
if (!needValidate()) {
return;
}
let errors = [];
if (Array.isArray(options)) {
for (let i = 0; i <= options.length - 1; i++) {
errors.push(...validateObject(schema, options[i]).map(err => applyPrefix(err, i)));
}
} else {
errors = validateObject(schema, options);
}
if (errors.length > 0) {
throw new _ValidationError.default(errors, schema, configuration);
}
}
/** @typedef {WeakMap<Schema, ValidateFunction>} */
const schemaCache = new WeakMap();
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @returns {Array<SchemaUtilErrorObject>}
*/
function validateObject(schema, options) {
let compiledSchema = schemaCache.get(schema);
if (!compiledSchema) {
compiledSchema = getAjv().compile(schema);
schemaCache.set(schema, compiledSchema);
}
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;
}

View File

@ -0,0 +1,111 @@
{
"_from": "schema-utils@^3.1.1",
"_id": "schema-utils@3.3.0",
"_inBundle": false,
"_integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"_location": "/terser-webpack-plugin/schema-utils",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "schema-utils@^3.1.1",
"name": "schema-utils",
"escapedName": "schema-utils",
"rawSpec": "^3.1.1",
"saveSpec": null,
"fetchSpec": "^3.1.1"
},
"_requiredBy": [
"/terser-webpack-plugin"
],
"_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"_shasum": "f50a88877c3c01652a15b622ae9e9795df7a60fe",
"_spec": "schema-utils@^3.1.1",
"_where": "C:\\Users\\zhouxueli\\Desktop\\scheduling-app\\node_modules\\terser-webpack-plugin",
"author": {
"name": "webpack Contrib",
"url": "https://github.com/webpack-contrib"
},
"bugs": {
"url": "https://github.com/webpack/schema-utils/issues"
},
"bundleDependencies": false,
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"deprecated": false,
"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.3.0"
}

157
node_modules/terser-webpack-plugin/package.json generated vendored Normal file
View File

@ -0,0 +1,157 @@
{
"_from": "terser-webpack-plugin@^5.3.7",
"_id": "terser-webpack-plugin@5.3.9",
"_inBundle": false,
"_integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
"_location": "/terser-webpack-plugin",
"_phantomChildren": {
"@types/json-schema": "7.0.12",
"ajv": "6.12.6",
"ajv-keywords": "3.5.2"
},
"_requested": {
"type": "range",
"registry": true,
"raw": "terser-webpack-plugin@^5.3.7",
"name": "terser-webpack-plugin",
"escapedName": "terser-webpack-plugin",
"rawSpec": "^5.3.7",
"saveSpec": null,
"fetchSpec": "^5.3.7"
},
"_requiredBy": [
"/@vue/cli-service",
"/webpack"
],
"_resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
"_shasum": "832536999c51b46d468067f9e37662a3b96adfe1",
"_spec": "terser-webpack-plugin@^5.3.7",
"_where": "C:\\Users\\zhouxueli\\Desktop\\scheduling-app\\node_modules\\webpack",
"author": {
"name": "webpack Contrib Team"
},
"bugs": {
"url": "https://github.com/webpack-contrib/terser-webpack-plugin/issues"
},
"bundleDependencies": false,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
"schema-utils": "^3.1.1",
"serialize-javascript": "^6.0.1",
"terser": "^5.16.8"
},
"deprecated": false,
"description": "Terser plugin for webpack",
"devDependencies": {
"@babel/cli": "^7.21.0",
"@babel/core": "^7.21.4",
"@babel/preset-env": "^7.21.4",
"@commitlint/cli": "^17.5.1",
"@commitlint/config-conventional": "^17.4.4",
"@swc/core": "^1.3.44",
"@types/node": "^18.15.11",
"@types/serialize-javascript": "^5.0.2",
"@types/uglify-js": "^3.17.1",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^28.1.2",
"copy-webpack-plugin": "^9.0.1",
"cross-env": "^7.0.3",
"cspell": "^6.31.1",
"del": "^6.0.0",
"del-cli": "^3.0.1",
"esbuild": "^0.14.51",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"file-loader": "^6.2.0",
"husky": "^7.0.2",
"jest": "^27.5.1",
"lint-staged": "^13.2.0",
"memfs": "^3.4.13",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.7",
"standard-version": "^9.3.1",
"typescript": "^4.9.5",
"uglify-js": "^3.17.4",
"webpack": "^5.83.1",
"webpack-cli": "^4.10.0",
"worker-loader": "^3.0.8"
},
"engines": {
"node": ">= 10.13.0"
},
"files": [
"dist",
"types"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"homepage": "https://github.com/webpack-contrib/terser-webpack-plugin",
"keywords": [
"uglify",
"uglify-js",
"uglify-es",
"terser",
"webpack",
"webpack-plugin",
"minification",
"compress",
"compressor",
"min",
"minification",
"minifier",
"minify",
"optimize",
"optimizer"
],
"license": "MIT",
"main": "dist/index.js",
"name": "terser-webpack-plugin",
"peerDependencies": {
"webpack": "^5.1.0"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"uglify-js": {
"optional": true
},
"esbuild": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/webpack-contrib/terser-webpack-plugin.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 types && prettier \"types/**/*.ts\" --write",
"clean": "del-cli dist types",
"commitlint": "commitlint --from=master",
"fix": "npm-run-all -l 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 .",
"lint:prettier": "prettier --list-different .",
"lint:spelling": "cspell \"**/*.*\"",
"lint:types": "tsc --pretty --noEmit",
"prebuild": "npm run clean",
"prepare": "husky install && npm run build",
"pretest": "npm run lint",
"release": "standard-version",
"security": "npm audit --production",
"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": "types/index.d.ts",
"version": "5.3.9"
}

219
node_modules/terser-webpack-plugin/types/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,219 @@
export = TerserPlugin;
/**
* @template [T=TerserOptions]
*/
declare class TerserPlugin<T = import("terser").MinifyOptions> {
/**
* @private
* @param {any} input
* @returns {boolean}
*/
private static isSourceMap;
/**
* @private
* @param {unknown} warning
* @param {string} file
* @returns {Error}
*/
private static buildWarning;
/**
* @private
* @param {any} error
* @param {string} file
* @param {TraceMap} [sourceMap]
* @param {Compilation["requestShortener"]} [requestShortener]
* @returns {Error}
*/
private static buildError;
/**
* @private
* @param {Parallel} parallel
* @returns {number}
*/
private static getAvailableNumberOfCores;
/**
* @private
* @param {any} environment
* @returns {TerserECMA}
*/
private static getEcmaVersion;
/**
* @param {BasePluginOptions & DefinedDefaultMinimizerAndOptions<T>} [options]
*/
constructor(
options?:
| (BasePluginOptions & DefinedDefaultMinimizerAndOptions<T>)
| undefined
);
/**
* @private
* @type {InternalPluginOptions<T>}
*/
private options;
/**
* @private
* @param {Compiler} compiler
* @param {Compilation} compilation
* @param {Record<string, import("webpack").sources.Source>} assets
* @param {{availableNumberOfCores: number}} optimizeOptions
* @returns {Promise<void>}
*/
private optimize;
/**
* @param {Compiler} compiler
* @returns {void}
*/
apply(compiler: Compiler): void;
}
declare namespace TerserPlugin {
export {
terserMinify,
uglifyJsMinify,
swcMinify,
esbuildMinify,
Schema,
Compiler,
Compilation,
WebpackError,
Asset,
TerserECMA,
TerserOptions,
JestWorker,
SourceMapInput,
TraceMap,
Rule,
Rules,
ExtractCommentsFunction,
ExtractCommentsCondition,
ExtractCommentsFilename,
ExtractCommentsBanner,
ExtractCommentsObject,
ExtractCommentsOptions,
MinimizedResult,
Input,
CustomOptions,
InferDefaultType,
PredefinedOptions,
MinimizerOptions,
BasicMinimizerImplementation,
MinimizeFunctionHelpers,
MinimizerImplementation,
InternalOptions,
MinimizerWorker,
Parallel,
BasePluginOptions,
DefinedDefaultMinimizerAndOptions,
InternalPluginOptions,
};
}
type Compiler = import("webpack").Compiler;
type BasePluginOptions = {
test?: Rules | undefined;
include?: Rules | undefined;
exclude?: Rules | undefined;
extractComments?: ExtractCommentsOptions | undefined;
parallel?: Parallel;
};
type DefinedDefaultMinimizerAndOptions<T> = T extends TerserOptions
? {
minify?: MinimizerImplementation<T> | undefined;
terserOptions?: MinimizerOptions<T> | undefined;
}
: {
minify: MinimizerImplementation<T>;
terserOptions?: MinimizerOptions<T> | undefined;
};
import { terserMinify } from "./utils";
import { uglifyJsMinify } from "./utils";
import { swcMinify } from "./utils";
import { esbuildMinify } from "./utils";
type Schema = import("schema-utils/declarations/validate").Schema;
type Compilation = import("webpack").Compilation;
type WebpackError = import("webpack").WebpackError;
type Asset = import("webpack").Asset;
type TerserECMA = import("./utils.js").TerserECMA;
type TerserOptions = import("./utils.js").TerserOptions;
type JestWorker = import("jest-worker").Worker;
type SourceMapInput = import("@jridgewell/trace-mapping").SourceMapInput;
type TraceMap = import("@jridgewell/trace-mapping").TraceMap;
type Rule = RegExp | string;
type Rules = Rule[] | Rule;
type ExtractCommentsFunction = (
astNode: any,
comment: {
value: string;
type: "comment1" | "comment2" | "comment3" | "comment4";
pos: number;
line: number;
col: number;
}
) => boolean;
type ExtractCommentsCondition =
| boolean
| "all"
| "some"
| RegExp
| ExtractCommentsFunction;
type ExtractCommentsFilename = string | ((fileData: any) => string);
type ExtractCommentsBanner =
| string
| boolean
| ((commentsFile: string) => string);
type ExtractCommentsObject = {
condition?: ExtractCommentsCondition | undefined;
filename?: ExtractCommentsFilename | undefined;
banner?: ExtractCommentsBanner | undefined;
};
type ExtractCommentsOptions = ExtractCommentsCondition | ExtractCommentsObject;
type MinimizedResult = {
code: string;
map?: import("@jridgewell/trace-mapping").SourceMapInput | undefined;
errors?: (string | Error)[] | undefined;
warnings?: (string | Error)[] | undefined;
extractedComments?: string[] | undefined;
};
type Input = {
[file: string]: string;
};
type CustomOptions = {
[key: string]: any;
};
type InferDefaultType<T> = T extends infer U ? U : CustomOptions;
type PredefinedOptions = {
module?: boolean | undefined;
ecma?: import("terser").ECMA | undefined;
};
type MinimizerOptions<T> = PredefinedOptions & InferDefaultType<T>;
type BasicMinimizerImplementation<T> = (
input: Input,
sourceMap: SourceMapInput | undefined,
minifyOptions: MinimizerOptions<T>,
extractComments: ExtractCommentsOptions | undefined
) => Promise<MinimizedResult>;
type MinimizeFunctionHelpers = {
getMinimizerVersion?: (() => string | undefined) | undefined;
};
type MinimizerImplementation<T> = BasicMinimizerImplementation<T> &
MinimizeFunctionHelpers;
type InternalOptions<T> = {
name: string;
input: string;
inputSourceMap: SourceMapInput | undefined;
extractComments: ExtractCommentsOptions | undefined;
minimizer: {
implementation: MinimizerImplementation<T>;
options: MinimizerOptions<T>;
};
};
type MinimizerWorker<T> = import("jest-worker").Worker & {
transform: (options: string) => MinimizedResult;
minify: (options: InternalOptions<T>) => MinimizedResult;
};
type Parallel = undefined | boolean | number;
type InternalPluginOptions<T> = BasePluginOptions & {
minimizer: {
implementation: MinimizerImplementation<T>;
options: MinimizerOptions<T>;
};
};
import { minify } from "./minify";

17
node_modules/terser-webpack-plugin/types/minify.d.ts generated vendored Normal file
View File

@ -0,0 +1,17 @@
export type MinimizedResult = import("./index.js").MinimizedResult;
export type CustomOptions = import("./index.js").CustomOptions;
/** @typedef {import("./index.js").MinimizedResult} MinimizedResult */
/** @typedef {import("./index.js").CustomOptions} CustomOptions */
/**
* @template T
* @param {import("./index.js").InternalOptions<T>} options
* @returns {Promise<MinimizedResult>}
*/
export function minify<T>(
options: import("./index.js").InternalOptions<T>
): Promise<MinimizedResult>;
/**
* @param {string} options
* @returns {Promise<MinimizedResult>}
*/
export function transform(options: string): Promise<MinimizedResult>;

101
node_modules/terser-webpack-plugin/types/utils.d.ts generated vendored Normal file
View File

@ -0,0 +1,101 @@
export type Task<T> = () => Promise<T>;
export type SourceMapInput = import("@jridgewell/trace-mapping").SourceMapInput;
export type TerserFormatOptions = import("terser").FormatOptions;
export type TerserOptions = import("terser").MinifyOptions;
export type TerserCompressOptions = import("terser").CompressOptions;
export type TerserECMA = import("terser").ECMA;
export type ExtractCommentsOptions =
import("./index.js").ExtractCommentsOptions;
export type ExtractCommentsFunction =
import("./index.js").ExtractCommentsFunction;
export type ExtractCommentsCondition =
import("./index.js").ExtractCommentsCondition;
export type Input = import("./index.js").Input;
export type MinimizedResult = import("./index.js").MinimizedResult;
export type PredefinedOptions = import("./index.js").PredefinedOptions;
export type CustomOptions = import("./index.js").CustomOptions;
export type ExtractedComments = Array<string>;
/**
* @template T
* @typedef {() => Promise<T>} Task
*/
/**
* Run tasks with limited concurrency.
* @template T
* @param {number} limit - Limit of tasks that run at once.
* @param {Task<T>[]} tasks - List of tasks to run.
* @returns {Promise<T[]>} A promise that fulfills to an array of the results
*/
export function throttleAll<T>(limit: number, tasks: Task<T>[]): Promise<T[]>;
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @param {ExtractCommentsOptions | undefined} extractComments
* @return {Promise<MinimizedResult>}
*/
export function terserMinify(
input: Input,
sourceMap: SourceMapInput | undefined,
minimizerOptions: PredefinedOptions & CustomOptions,
extractComments: ExtractCommentsOptions | undefined
): Promise<MinimizedResult>;
export namespace terserMinify {
/**
* @returns {string | undefined}
*/
function getMinimizerVersion(): string | undefined;
}
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @param {ExtractCommentsOptions | undefined} extractComments
* @return {Promise<MinimizedResult>}
*/
export function uglifyJsMinify(
input: Input,
sourceMap: SourceMapInput | undefined,
minimizerOptions: PredefinedOptions & CustomOptions,
extractComments: ExtractCommentsOptions | undefined
): Promise<MinimizedResult>;
export namespace uglifyJsMinify {
/**
* @returns {string | undefined}
*/
function getMinimizerVersion(): string | undefined;
}
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @return {Promise<MinimizedResult>}
*/
export function swcMinify(
input: Input,
sourceMap: SourceMapInput | undefined,
minimizerOptions: PredefinedOptions & CustomOptions
): Promise<MinimizedResult>;
export namespace swcMinify {
/**
* @returns {string | undefined}
*/
function getMinimizerVersion(): string | undefined;
}
/**
* @param {Input} input
* @param {SourceMapInput | undefined} sourceMap
* @param {PredefinedOptions & CustomOptions} minimizerOptions
* @return {Promise<MinimizedResult>}
*/
export function esbuildMinify(
input: Input,
sourceMap: SourceMapInput | undefined,
minimizerOptions: PredefinedOptions & CustomOptions
): Promise<MinimizedResult>;
export namespace esbuildMinify {
/**
* @returns {string | undefined}
*/
function getMinimizerVersion(): string | undefined;
}