This commit is contained in:
2022-07-21 03:28:35 +00:00
parent d7c883d6df
commit 51b34b0e1d
30103 changed files with 4152204 additions and 23 deletions
+526
View File
@@ -0,0 +1,526 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [4.3.0](https://github.com/webpack-contrib/css-loader/compare/v4.2.2...v4.3.0) (2020-09-08)
### Features
* the `importLoaders` can be `string` ([#1178](https://github.com/webpack-contrib/css-loader/issues/1178)) ([ec58a7c](https://github.com/webpack-contrib/css-loader/commit/ec58a7cfda46443e35539d66b86685195fa5db03))
### Bug Fixes
* line breaks in `url` function ([88b8ddc](https://github.com/webpack-contrib/css-loader/commit/88b8ddc1d78a2b6a917ed2dfe2f2a37cf6a84190))
### [4.2.2](https://github.com/webpack-contrib/css-loader/compare/v4.2.1...v4.2.2) (2020-08-24)
### Bug Fixes
* source maps generation, source from source maps are now relative to `compiler.context` and use `webpack://` protocol ([#1169](https://github.com/webpack-contrib/css-loader/issues/1169)) ([fb5c53d](https://github.com/webpack-contrib/css-loader/commit/fb5c53d80b10ee698762238bb7b122aec8c5048d))
### [4.2.1](https://github.com/webpack-contrib/css-loader/compare/v4.2.0...v4.2.1) (2020-08-06)
### Bug Fixes
* regression with the `exportOnlyLocals` option, now `locals` are not exported under the `locals` name, it was big regression, we apologize for that ([24c0a12](https://github.com/webpack-contrib/css-loader/commit/24c0a122d1396c08326a24f6184f5da09cf52ccc))
## [4.2.0](https://github.com/webpack-contrib/css-loader/compare/v4.1.1...v4.2.0) (2020-07-31)
### Features
* add `module.type` option, the `icss` option is deprecated ([#1150](https://github.com/webpack-contrib/css-loader/issues/1150)) ([68f72af](https://github.com/webpack-contrib/css-loader/commit/68f72af2a09111f74dcacbf7af019fe7eb40cb6c))
### [4.1.1](https://github.com/webpack-contrib/css-loader/compare/v4.1.0...v4.1.1) (2020-07-30)
### Bug Fixes
* remove unnecessary `console` call ([#1148](https://github.com/webpack-contrib/css-loader/issues/1148)) ([b1b90ca](https://github.com/webpack-contrib/css-loader/commit/b1b90caaea8eb045177749729340c7906454a84b))
## [4.1.0](https://github.com/webpack-contrib/css-loader/compare/v4.0.0...v4.1.0) (2020-07-29)
### Features
* add `icss` option ([#1140](https://github.com/webpack-contrib/css-loader/issues/1140)) ([a8ec7da](https://github.com/webpack-contrib/css-loader/commit/a8ec7da42234e0b2eb061d2a920669940bcbdf05))
* support absolute paths ([f9ba0ce](https://github.com/webpack-contrib/css-loader/commit/f9ba0ce11789770c4c9220478e9c98dbd432a5d6))
### Bug Fixes
* do not crash with `data` URLs ([#1142](https://github.com/webpack-contrib/css-loader/issues/1142)) ([91bc64b](https://github.com/webpack-contrib/css-loader/commit/91bc64b81abfeffd174639a8fdf2366412c11426))
* performance ([#1144](https://github.com/webpack-contrib/css-loader/issues/1144)) ([4f1baa2](https://github.com/webpack-contrib/css-loader/commit/4f1baa211eb27b0b281ba9f262fa12e8aaefc0ba))
## [4.0.0](https://github.com/webpack-contrib/css-loader/compare/v3.6.0...v4.0.0) (2020-07-25)
### ⚠ BREAKING CHANGES
* minimum required `Node.js` version is `10.13.0`
* minimum required `webpack` version is `4.27.0`
* the `esModule` option is `true` by default
* default value of the `sourceMap` option depends on the `devtool` option
* `icss` plugin disable by default, you need to setup the `modules` option to enable it
* the `modules` option is `true` by default for all files matching `/\.module\.\w+$/i.test(filename)` regular expression, `module.auto` is `true` by default
* the `modules.context` option was renamed to the `modules.localIdentContext` option
* default the `modules.localIdentContext` value is `compiler.context` for the `module.getLocalIdent` option
* the `modules.hashPrefix` option was renamed to the `modules.localIdentHashPrefix` option
* the `localsConvention` option was moved and renamed to the `modules.exportLocalsConvention` option
* the `getLocalIndent` option should be always `Function` and should always return `String` value
* the `onlyLocals` option was moved and renamed to the `modules.exportOnlyLocals` option
* function arguments of the `import` option were changed, it is now `function(url, media, resourcePath) {}`
* inline syntax was changed, please write `~` before the file request, i.e. rewrite `url(~!!loader!package/img.png)` to `url(!!loader!~package/img.png)`
### Features
* `@value` supports importing `url()` ([#1126](https://github.com/webpack-contrib/css-loader/issues/1126)) ([7f49a0a](https://github.com/webpack-contrib/css-loader/commit/7f49a0a6047846bb2e432558365e19d4a0dfb366))
* improve `url()` resolving algorithm ([bc19ddd](https://github.com/webpack-contrib/css-loader/commit/bc19ddd8779dafbc2a420870a3cb841041ce9c7c))
* named export for locals ([#1108](https://github.com/webpack-contrib/css-loader/issues/1108)) ([d139ec1](https://github.com/webpack-contrib/css-loader/commit/d139ec1d763f9944550b31f2a75183e488dd1224))
* respected the `style` field from package.json ([#1099](https://github.com/webpack-contrib/css-loader/issues/1099)) ([edf5347](https://github.com/webpack-contrib/css-loader/commit/edf5347e4203a62e50b87248a83da198afdc6eba))
* support `file:` protocol ([5604205](https://github.com/webpack-contrib/css-loader/commit/560420567eb0e1a635648b7f4ff0365db475384c))
* support server relative URLs
### Bug Fixes
* resolution algorithm, you don't need `~` inside packages in `node_modules` ([76f1480](https://github.com/webpack-contrib/css-loader/commit/76f1480b14265369ac5dc8dbbce467cfb8e814c5))
## [3.6.0](https://github.com/webpack-contrib/css-loader/compare/v3.5.3...v3.6.0) (2020-06-13)
### Features
* allow `modules.auto` to be a filter function ([#1086](https://github.com/webpack-contrib/css-loader/issues/1086)) ([0902353](https://github.com/webpack-contrib/css-loader/commit/0902353c328d4d18e8ed2755fe9c83c03c53df81))
### [3.5.3](https://github.com/webpack-contrib/css-loader/compare/v3.5.2...v3.5.3) (2020-04-24)
### Bug Fixes
* add file from an error to file dependencies ([841423f](https://github.com/webpack-contrib/css-loader/commit/841423fca2932c18f8ac0cf0a1f0012fc0a62fb6))
* avoid query string in source maps ([#1082](https://github.com/webpack-contrib/css-loader/issues/1082)) ([f64de13](https://github.com/webpack-contrib/css-loader/commit/f64de13f7377eff9501348cf26213212ca696913))
### [3.5.2](https://github.com/webpack-contrib/css-loader/compare/v3.5.1...v3.5.2) (2020-04-10)
### Bug Fixes
* schema for the `modules.auto` option ([#1075](https://github.com/webpack-contrib/css-loader/issues/1075)) ([8c9ffe7](https://github.com/webpack-contrib/css-loader/commit/8c9ffe7c6df11232b63173c757baa71ed36f6145))
### [3.5.1](https://github.com/webpack-contrib/css-loader/compare/v3.5.0...v3.5.1) (2020-04-07)
### Bug Fixes
* don't generate an invalid code for `locals` ([#1072](https://github.com/webpack-contrib/css-loader/issues/1072)) ([866b84a](https://github.com/webpack-contrib/css-loader/commit/866b84acd7fd47651f741ca1e6cf7081c2bbe357))
## [3.5.0](https://github.com/webpack-contrib/css-loader/compare/v3.4.2...v3.5.0) (2020-04-06)
### Features
* accept semver compatible postcss AST ([#1049](https://github.com/webpack-contrib/css-loader/issues/1049)) ([14c4faa](https://github.com/webpack-contrib/css-loader/commit/14c4faae87305c9b965de4f468bb1e118f6b84cc))
* allow to determinate css modules using the `modules.auto` option, please look at an [example](https://github.com/webpack-contrib/css-loader#pure-css-css-modules-and-postcss) of how you can simplify the configuration. ([#1067](https://github.com/webpack-contrib/css-loader/issues/1067)) ([c673cf4](https://github.com/webpack-contrib/css-loader/commit/c673cf418e901c5050bc697eb45401dc9a42c477))
* the `modules.exportGlobals` option for export global classes and ids ([#1069](https://github.com/webpack-contrib/css-loader/issues/1069)) ([519e5f4](https://github.com/webpack-contrib/css-loader/commit/519e5f41539f4c87ec96db0a908aaadecc284a6c))
* the `modules.mode` option may be a function ([#1065](https://github.com/webpack-contrib/css-loader/issues/1065)) ([0d8ac3b](https://github.com/webpack-contrib/css-loader/commit/0d8ac3bcb831bc747657c914aba106b93840737e))
### [3.4.2](https://github.com/webpack-contrib/css-loader/compare/v3.4.1...v3.4.2) (2020-01-10)
### Bug Fixes
* do not duplicate css on `composes` ([#1040](https://github.com/webpack-contrib/css-loader/issues/1040)) ([df79602](https://github.com/webpack-contrib/css-loader/commit/df7960277be20ec80e9be1a41ac53baf69847fa0))
### [3.4.1](https://github.com/webpack-contrib/css-loader/compare/v3.4.0...v3.4.1) (2020-01-03)
### Bug Fixes
* do not output `undefined` when sourceRoot is unavailable ([#1036](https://github.com/webpack-contrib/css-loader/issues/1036)) ([ded2a79](https://github.com/webpack-contrib/css-loader/commit/ded2a797271f2adf864bf92300621c024974bc79))
* don't output invalid es5 code when locals do not exists ([#1035](https://github.com/webpack-contrib/css-loader/issues/1035)) ([b60e62a](https://github.com/webpack-contrib/css-loader/commit/b60e62a655719cc1779fae7d577af6ad6cf42135))
## [3.4.0](https://github.com/webpack-contrib/css-loader/compare/v3.3.1...v3.4.0) (2019-12-17)
### Features
* `esModule` option ([#1026](https://github.com/webpack-contrib/css-loader/issues/1026)) ([d358cdb](https://github.com/webpack-contrib/css-loader/commit/d358cdbe2c026afafa0279003cb6c8a3eff4c419))
### Bug Fixes
* logic for order and media queries for imports ([#1018](https://github.com/webpack-contrib/css-loader/issues/1018)) ([65450d9](https://github.com/webpack-contrib/css-loader/commit/65450d9c04790ccc9fb06eac81ea6d8f3cdbfaac))
### [3.3.2](https://github.com/webpack-contrib/css-loader/compare/v3.3.1...v3.3.2) (2019-12-12)
### Bug Fixes
* logic for order and media queries for imports ([1fb5134](https://github.com/webpack-contrib/css-loader/commit/1fb51340a7719b6f5b517cb71ea85ec5d45c1199))
### [3.3.1](https://github.com/webpack-contrib/css-loader/compare/v3.3.0...v3.3.1) (2019-12-12)
### Bug Fixes
* better handling url functions and an url in `@import` at-rules
* reduce count of `require` ([#1014](https://github.com/webpack-contrib/css-loader/issues/1014)) ([e091d27](https://github.com/webpack-contrib/css-loader/commit/e091d2709c29ac57ed0106af8ec3b581cbda7a9c))
## [3.3.0](https://github.com/webpack-contrib/css-loader/compare/v3.2.1...v3.3.0) (2019-12-09)
### Features
* support `pure` css modules ([#1008](https://github.com/webpack-contrib/css-loader/issues/1008)) ([6177af5](https://github.com/webpack-contrib/css-loader/commit/6177af5596566fead13a8f66d5abcb4dc2b744db))
### Bug Fixes
* do not crash when an assert return `null` or `undefined` ([#1006](https://github.com/webpack-contrib/css-loader/issues/1006)) ([6769783](https://github.com/webpack-contrib/css-loader/commit/67697833725e1cff12a14663390bbe4c65ea36d2))
* reduce count of `require` ([#1004](https://github.com/webpack-contrib/css-loader/issues/1004)) ([80e9662](https://github.com/webpack-contrib/css-loader/commit/80e966280f2477c5c0e4553d3be3a04511fea381))
### [3.2.1](https://github.com/webpack-contrib/css-loader/compare/v3.2.0...v3.2.1) (2019-12-02)
### Bug Fixes
* add an additional space after the escape sequence ([#998](https://github.com/webpack-contrib/css-loader/issues/998)) ([0961304](https://github.com/webpack-contrib/css-loader/commit/0961304020832fc9ca70cc708f4366e1f868e765))
* compatibility with ES modules syntax and hash in `url` function ([#1001](https://github.com/webpack-contrib/css-loader/issues/1001)) ([8f4d6f5](https://github.com/webpack-contrib/css-loader/commit/8f4d6f508187513347106a436eda993f874065f1))
## [3.2.0](https://github.com/webpack-contrib/css-loader/compare/v3.1.0...v3.2.0) (2019-08-06)
### Bug Fixes
* replace `.` characters in localIndent to `-` character (regression) ([#982](https://github.com/webpack-contrib/css-loader/issues/982)) ([967fb66](https://github.com/webpack-contrib/css-loader/commit/967fb66))
### Features
* support es modules for assets loader ([#984](https://github.com/webpack-contrib/css-loader/issues/984)) ([9c5126c](https://github.com/webpack-contrib/css-loader/commit/9c5126c))
## [3.1.0](https://github.com/webpack-contrib/css-loader/compare/v3.0.0...v3.1.0) (2019-07-18)
### Bug Fixes
* converting all (including reserved and control) filesystem characters to `-` (it was regression in `3.0.0` version) ([#972](https://github.com/webpack-contrib/css-loader/issues/972)) ([f51859b](https://github.com/webpack-contrib/css-loader/commit/f51859b))
* default context should be undefined instead of null ([#965](https://github.com/webpack-contrib/css-loader/issues/965)) ([9c32885](https://github.com/webpack-contrib/css-loader/commit/9c32885))
### Features
* allow `modules.getLocalIdent` to return a falsy value ([#963](https://github.com/webpack-contrib/css-loader/issues/963)) ([9c3571c](https://github.com/webpack-contrib/css-loader/commit/9c3571c))
* improved validation error messages ([65e4fc0](https://github.com/webpack-contrib/css-loader/commit/65e4fc0))
## [3.0.0](https://github.com/webpack-contrib/css-loader/compare/v2.1.1...v3.0.0) (2019-06-11)
### Bug Fixes
* avoid the "from" argument must be of type string error ([#908](https://github.com/webpack-contrib/css-loader/issues/908)) ([e5dfd23](https://github.com/webpack-contrib/css-loader/commit/e5dfd23))
* invert `Function` behavior for `url` and `import` options ([#939](https://github.com/webpack-contrib/css-loader/issues/939)) ([e9eb5ad](https://github.com/webpack-contrib/css-loader/commit/e9eb5ad))
* properly export locals with escaped characters ([#917](https://github.com/webpack-contrib/css-loader/issues/917)) ([a0efcda](https://github.com/webpack-contrib/css-loader/commit/a0efcda))
* property handle non css characters in localIdentName ([#920](https://github.com/webpack-contrib/css-loader/issues/920)) ([d3a0a3c](https://github.com/webpack-contrib/css-loader/commit/d3a0a3c))
### Features
* modules options now accepts object config ([#937](https://github.com/webpack-contrib/css-loader/issues/937)) ([1d7a464](https://github.com/webpack-contrib/css-loader/commit/1d7a464))
* support `@value` at-rule in selectors ([#941](https://github.com/webpack-contrib/css-loader/issues/941)) ([05a42e2](https://github.com/webpack-contrib/css-loader/commit/05a42e2))
### BREAKING CHANGES
* minimum required nodejs version is 8.9.0
* `@value` at rules now support in `selector`, recommends checking all `@values` at-rule usage (hint: you can add prefix to all `@value` at-rules, for example `@value v-foo: black;` or `@value m-foo: screen and (max-width: 12450px)`, and then do upgrade)
* invert `{Function}` behavior for `url` and `import` options (need return `true` when you want handle `url`/`@import` and return `false` if not)
* `camelCase` option was remove in favor `localsConvention` option, also it is accept only `{String}` value (use `camelCase` value if you previously value was `true` and `asIs` if you previously value was `false`)
* `exportOnlyLocals` option was remove in favor `onlyLocals` option
* `modules` option now can be `{Object}` and allow to setup `CSS Modules` options:
* `localIdentName` option was removed in favor `modules.localIdentName` option
* `context` option was remove in favor `modules.context` option
* `hashPrefix` option was removed in favor `modules.hashPrefix` option
* `getLocalIdent` option was removed in favor `modules.getLocalIdent` option
* `localIdentRegExp` option was removed in favor `modules.localIdentRegExp` option
<a name="2.1.1"></a>
## [2.1.1](https://github.com/webpack-contrib/css-loader/compare/v2.1.0...v2.1.1) (2019-03-07)
### Bug Fixes
* do not break selector with escaping ([#896](https://github.com/webpack-contrib/css-loader/issues/896)) ([0ba8c66](https://github.com/webpack-contrib/css-loader/commit/0ba8c66))
* source map generation when `sourceRoot` is present ([#901](https://github.com/webpack-contrib/css-loader/issues/901)) ([e9ce745](https://github.com/webpack-contrib/css-loader/commit/e9ce745))
* sourcemap generating when previous loader pass sourcemap as string ([#905](https://github.com/webpack-contrib/css-loader/issues/905)) ([3797e4d](https://github.com/webpack-contrib/css-loader/commit/3797e4d))
<a name="2.1.0"></a>
# [2.1.0](https://github.com/webpack-contrib/css-loader/compare/v2.0.2...v2.1.0) (2018-12-25)
### Features
* support `image-set` without `url` ([#879](https://github.com/webpack-contrib/css-loader/issues/879)) ([21884e2](https://github.com/webpack-contrib/css-loader/commit/21884e2))
<a name="2.0.2"></a>
## [2.0.2](https://github.com/webpack-contrib/css-loader/compare/v2.0.1...v2.0.2) (2018-12-21)
### Bug Fixes
* inappropriate modification of animation keywords ([#876](https://github.com/webpack-contrib/css-loader/issues/876)) ([dfb2f8e](https://github.com/webpack-contrib/css-loader/commit/dfb2f8e))
<a name="2.0.1"></a>
# [2.0.1](https://github.com/webpack-contrib/css-loader/compare/v2.0.0...v2.0.1) (2018-12-14)
### Bug Fixes
* safe checking if params are present for at rule ([#871](https://github.com/webpack-contrib/css-loader/issues/871)) ([a88fed1](https://github.com/webpack-contrib/css-loader/commit/a88fed1))
* `getLocalIdent` now accepts `false` value ([#865](https://github.com/webpack-contrib/css-loader/issues/865)) ([1825e8a](https://github.com/webpack-contrib/css-loader/commit/1825e8a))
<a name="2.0.0"></a>
# [2.0.0](https://github.com/webpack-contrib/css-loader/compare/v1.0.1...v2.0.0) (2018-12-07)
### Bug Fixes
* broken unucode characters ([#850](https://github.com/webpack-contrib/css-loader/issues/850)) ([f599c70](https://github.com/webpack-contrib/css-loader/commit/f599c70))
* correctly processing `urls()` with `?#hash` ([#803](https://github.com/webpack-contrib/css-loader/issues/803)) ([417d105](https://github.com/webpack-contrib/css-loader/commit/417d105))
* don't break loader on invalid or not exists url or import token ([#827](https://github.com/webpack-contrib/css-loader/issues/827)) ([9e52d26](https://github.com/webpack-contrib/css-loader/commit/9e52d26))
* don't duplicate import with same media in different case ([#819](https://github.com/webpack-contrib/css-loader/issues/819)) ([9f66e33](https://github.com/webpack-contrib/css-loader/commit/9f66e33))
* emit warnings on broken `import` at-rules ([#806](https://github.com/webpack-contrib/css-loader/issues/806)) ([4bdf08b](https://github.com/webpack-contrib/css-loader/commit/4bdf08b))
* handle uppercase `URL` in `import` at-rules ([#818](https://github.com/webpack-contrib/css-loader/issues/818)) ([3ebdcd5](https://github.com/webpack-contrib/css-loader/commit/3ebdcd5))
* inconsistent generate class names for css modules on difference os ([#812](https://github.com/webpack-contrib/css-loader/issues/812)) ([0bdf9b7](https://github.com/webpack-contrib/css-loader/commit/0bdf9b7))
* reduce number of `require` for `urls()` ([#854](https://github.com/webpack-contrib/css-loader/issues/854)) ([3338656](https://github.com/webpack-contrib/css-loader/commit/3338656))
* support deduplication of string module ids (optimization.namedModules) ([#789](https://github.com/webpack-contrib/css-loader/issues/789)) ([e3bb83a](https://github.com/webpack-contrib/css-loader/commit/e3bb83a))
* support module resolution in `composes` ([#845](https://github.com/webpack-contrib/css-loader/issues/845)) ([453248f](https://github.com/webpack-contrib/css-loader/commit/453248f))
* same `urls()` resolving logic for `modules` (`local` and `global`) and without modules ([#843](https://github.com/webpack-contrib/css-loader/issues/843)) ([fdcf687](https://github.com/webpack-contrib/css-loader/commit/fdcf687))
### Features
* allow to disable css modules and **disable their by default** ([#842](https://github.com/webpack-contrib/css-loader/issues/842)) ([889dc7f](https://github.com/webpack-contrib/css-loader/commit/889dc7f))
* disable `import` option doesn't affect on `composes` ([#822](https://github.com/webpack-contrib/css-loader/issues/822)) ([f9aa73c](https://github.com/webpack-contrib/css-loader/commit/f9aa73c))
* allow to filter `urls` ([#856](https://github.com/webpack-contrib/css-loader/issues/856)) ([5e702e7](https://github.com/webpack-contrib/css-loader/commit/5e702e7))
* allow to filter `import` at-rules ([#857](https://github.com/webpack-contrib/css-loader/issues/857)) ([5e6034c](https://github.com/webpack-contrib/css-loader/commit/5e6034c))
* emit warning on invalid `urls()` ([#832](https://github.com/webpack-contrib/css-loader/issues/832)) ([da95db8](https://github.com/webpack-contrib/css-loader/commit/da95db8))
* added `exportOnlyLocals` option ([#824](https://github.com/webpack-contrib/css-loader/issues/824)) ([e9327c0](https://github.com/webpack-contrib/css-loader/commit/e9327c0))
* reuse `postcss` ast from other loaders (i.e `postcss-loader`) ([#840](https://github.com/webpack-contrib/css-loader/issues/840)) ([1dad1fb](https://github.com/webpack-contrib/css-loader/commit/1dad1fb))
* schema options ([b97d997](https://github.com/webpack-contrib/css-loader/commit/b97d997))
### BREAKING CHANGES
* resolving logic for `url()` and `import` at-rules works the same everywhere, it does not matter whether css modules are enabled (with `global` and `local` module) or not. Examples - `url('image.png')` as `require('./image.png')`, `url('./image.png')` as `require('./image.png')`, `url('~module/image.png')` as `require('module/image.png')`.
* by default css modules are disabled (now `modules: false` disable all css modules features), you can return old behaviour change this on `modules: 'global'`
* `css-loader/locals` was dropped in favor `exportOnlyLocals` option
* `import` option only affect on `import` at-rules and doesn't affect on `composes` declarations
* invalid `@import` at rules now emit warnings
* use `postcss@7`
<a name="1.0.1"></a>
## [1.0.1](https://github.com/webpack-contrib/css-loader/compare/v1.0.0...v1.0.1) (2018-10-29)
### Bug Fixes
* **loader:** trim unquoted import urls ([#783](https://github.com/webpack-contrib/css-loader/issues/783)) ([21fcddf](https://github.com/webpack-contrib/css-loader/commit/21fcddf))
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/css-loader/compare/v0.28.11...v1.0.0) (2018-07-06)
### BREAKING CHANGES
* remove `minimize` option, use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`cssnano`](https://github.com/cssnano/cssnano) or use [`optimize-cssnano-plugin`](https://github.com/intervolga/optimize-cssnano-plugin) plugin
* remove `module` option, use `modules` option instead
* remove `camelcase` option, use `camelCase` option instead
* remove `root` option, use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`postcss-url`](https://github.com/postcss/postcss-url) plugin
* remove `alias` option, use [`resolve.alias`](https://webpack.js.org/configuration/resolve/) feature or use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`postcss-url`](https://github.com/postcss/postcss-url) plugin
* update `postcss` to `6` version
* minimum require `nodejs` version is `6.9`
* minimum require `webpack` version is `4`
<a name="0.28.11"></a>
## [0.28.11](https://github.com/webpack-contrib/css-loader/compare/v0.28.10...v0.28.11) (2018-03-16)
### Bug Fixes
* **lib/processCss:** don't check `mode` for `url` handling (`options.modules`) ([#698](https://github.com/webpack-contrib/css-loader/issues/698)) ([c788450](https://github.com/webpack-contrib/css-loader/commit/c788450))
<a name="0.28.10"></a>
## [0.28.10](https://github.com/webpack-contrib/css-loader/compare/v0.28.9...v0.28.10) (2018-02-22)
### Bug Fixes
* **getLocalIdent:** add `rootContext` support (`webpack >= v4.0.0`) ([#681](https://github.com/webpack-contrib/css-loader/issues/681)) ([9f876d2](https://github.com/webpack-contrib/css-loader/commit/9f876d2))
<a name="0.28.9"></a>
## [0.28.9](https://github.com/webpack-contrib/css-loader/compare/v0.28.8...v0.28.9) (2018-01-17)
### Bug Fixes
* ignore invalid URLs (`url()`) ([#663](https://github.com/webpack-contrib/css-loader/issues/663)) ([d1d8221](https://github.com/webpack-contrib/css-loader/commit/d1d8221))
<a name="0.28.8"></a>
## [0.28.8](https://github.com/webpack-contrib/css-loader/compare/v0.28.7...v0.28.8) (2018-01-05)
### Bug Fixes
* **loader:** correctly check if source map is `undefined` ([#641](https://github.com/webpack-contrib/css-loader/issues/641)) ([0dccfa9](https://github.com/webpack-contrib/css-loader/commit/0dccfa9))
* proper URL escaping and wrapping (`url()`) ([#627](https://github.com/webpack-contrib/css-loader/issues/627)) ([8897d44](https://github.com/webpack-contrib/css-loader/commit/8897d44))
<a name="0.28.7"></a>
## [0.28.7](https://github.com/webpack/css-loader/compare/v0.28.6...v0.28.7) (2017-08-30)
### Bug Fixes
* pass resolver to `localsLoader` (`options.alias`) ([#601](https://github.com/webpack/css-loader/issues/601)) ([8f1b57c](https://github.com/webpack/css-loader/commit/8f1b57c))
<a name="0.28.6"></a>
## [0.28.6](https://github.com/webpack/css-loader/compare/v0.28.5...v0.28.6) (2017-08-30)
### Bug Fixes
* add support for aliases starting with `/` (`options.alias`) ([#597](https://github.com/webpack/css-loader/issues/597)) ([63567f2](https://github.com/webpack/css-loader/commit/63567f2))
<a name="0.28.5"></a>
## [0.28.5](https://github.com/webpack/css-loader/compare/v0.28.4...v0.28.5) (2017-08-17)
### Bug Fixes
* match mutliple dashes (`options.camelCase`) ([#556](https://github.com/webpack/css-loader/issues/556)) ([1fee601](https://github.com/webpack/css-loader/commit/1fee601))
* stricter `[@import](https://github.com/import)` tolerance ([#593](https://github.com/webpack/css-loader/issues/593)) ([2e4ec09](https://github.com/webpack/css-loader/commit/2e4ec09))
<a name="0.28.4"></a>
## [0.28.4](https://github.com/webpack/css-loader/compare/v0.28.3...v0.28.4) (2017-05-30)
### Bug Fixes
* preserve leading underscore in class names ([#543](https://github.com/webpack/css-loader/issues/543)) ([f6673c8](https://github.com/webpack/css-loader/commit/f6673c8))
<a name="0.28.3"></a>
## [0.28.3](https://github.com/webpack/css-loader/compare/v0.28.2...v0.28.3) (2017-05-25)
### Bug Fixes
* correct plugin order for CSS Modules ([#534](https://github.com/webpack/css-loader/issues/534)) ([b90f492](https://github.com/webpack/css-loader/commit/b90f492))
<a name="0.28.2"></a>
## [0.28.2](https://github.com/webpack/css-loader/compare/v0.28.1...v0.28.2) (2017-05-22)
### Bug Fixes
* source maps path on `windows` ([#532](https://github.com/webpack/css-loader/issues/532)) ([c3d0d91](https://github.com/webpack/css-loader/commit/c3d0d91))
<a name="0.28.1"></a>
## [0.28.1](https://github.com/webpack/css-loader/compare/v0.28.0...v0.28.1) (2017-05-02)
### Bug Fixes
* allow to specify a full hostname as a root URL ([#521](https://github.com/webpack/css-loader/issues/521)) ([06d27a1](https://github.com/webpack/css-loader/commit/06d27a1))
* case insensitivity of [@import](https://github.com/import) ([#514](https://github.com/webpack/css-loader/issues/514)) ([de4356b](https://github.com/webpack/css-loader/commit/de4356b))
* don't handle empty [@import](https://github.com/import) and url() ([#513](https://github.com/webpack/css-loader/issues/513)) ([868fc94](https://github.com/webpack/css-loader/commit/868fc94))
* imported variables are replaced in exports if followed by a comma ([#504](https://github.com/webpack/css-loader/issues/504)) ([956bad7](https://github.com/webpack/css-loader/commit/956bad7))
* loader now correctly handles `url` with space(s) ([#495](https://github.com/webpack/css-loader/issues/495)) ([534ea55](https://github.com/webpack/css-loader/commit/534ea55))
* url with a trailing space is now handled correctly ([#494](https://github.com/webpack/css-loader/issues/494)) ([e1ec4f2](https://github.com/webpack/css-loader/commit/e1ec4f2))
* use `btoa` instead `Buffer` ([#501](https://github.com/webpack/css-loader/issues/501)) ([fbb0714](https://github.com/webpack/css-loader/commit/fbb0714))
### Performance Improvements
* generate source maps only when explicitly set ([#478](https://github.com/webpack/css-loader/issues/478)) ([b8f5c8f](https://github.com/webpack/css-loader/commit/b8f5c8f))
<a name="0.28.0"></a>
# [0.28.0](https://github.com/webpack/css-loader/compare/v0.27.3...v0.28.0) (2017-03-30)
### Features
* add alias feature to rewrite URLs ([#274](https://github.com/webpack/css-loader/issues/274)) ([c8db489](https://github.com/webpack/css-loader/commit/c8db489))
<a name="0.27.3"></a>
## [0.27.3](https://github.com/webpack/css-loader/compare/v0.27.2...v0.27.3) (2017-03-13)
<a name="0.27.2"></a>
# [0.27.2](https://github.com/webpack/css-loader/compare/v0.27.1...v0.27.2) (2017-03-12)
<a name="0.27.1"></a>
# [0.27.1](https://github.com/webpack/css-loader/compare/v0.27.0...v0.27.1) (2017-03-10)
<a name="0.27.0"></a>
# [0.27.0](https://github.com/webpack/css-loader/compare/v0.26.2...v0.27.0) (2017-03-10)
### Bug Fixes
* **sourcemaps:** use abs paths & remove sourceRoot ([c769ac3](https://github.com/webpack/css-loader/commit/c769ac3))
* `minimizeOptions` should be `query.minimize`! ([16c0858](https://github.com/webpack/css-loader/commit/16c0858))
* do not export duplicate keys ([#420](https://github.com/webpack/css-loader/issues/420)) ([a2b85d7](https://github.com/webpack/css-loader/commit/a2b85d7))
### Features
* allow removal of original class name ([#445](https://github.com/webpack/css-loader/issues/445)) ([3f78361](https://github.com/webpack/css-loader/commit/3f78361))
* Include the sourceMappingURL & sourceURL when toString() ([6da7e90](https://github.com/webpack/css-loader/commit/6da7e90))
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+1374
View File
File diff suppressed because it is too large Load Diff
+38
View File
@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class CssSyntaxError extends Error {
constructor(error) {
super(error);
const {
reason,
line,
column
} = error;
this.name = 'CssSyntaxError'; // Based on https://github.com/postcss/postcss/blob/master/lib/css-syntax-error.es6#L132
// We don't need `plugin` and `file` properties.
this.message = `${this.name}\n\n`;
if (typeof line !== 'undefined') {
this.message += `(${line}:${column}) `;
}
this.message += `${reason}`;
const code = error.showSourceCode();
if (code) {
this.message += `\n\n${code}\n`;
} // We don't need stack https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#31-dont-show-js-stack-for-csssyntaxerror
this.stack = false;
}
}
exports.default = CssSyntaxError;
+32
View File
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class Warning extends Error {
constructor(warning) {
super(warning);
const {
text,
line,
column
} = warning;
this.name = 'Warning'; // Based on https://github.com/postcss/postcss/blob/master/lib/warning.es6#L74
// We don't need `plugin` properties.
this.message = `${this.name}\n\n`;
if (typeof line !== 'undefined') {
this.message += `(${line}:${column}) `;
}
this.message += `${text}`; // We don't need stack https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#31-dont-show-js-stack-for-csssyntaxerror
this.stack = false;
}
}
exports.default = Warning;
+5
View File
@@ -0,0 +1,5 @@
"use strict";
const loader = require('./index');
module.exports = loader.default;
+176
View File
@@ -0,0 +1,176 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = loader;
var _loaderUtils = require("loader-utils");
var _postcss = _interopRequireDefault(require("postcss"));
var _package = _interopRequireDefault(require("postcss/package.json"));
var _schemaUtils = _interopRequireDefault(require("schema-utils"));
var _semver = require("semver");
var _CssSyntaxError = _interopRequireDefault(require("./CssSyntaxError"));
var _Warning = _interopRequireDefault(require("./Warning"));
var _options = _interopRequireDefault(require("./options.json"));
var _plugins = require("./plugins");
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
async function loader(content, map, meta) {
const rawOptions = (0, _loaderUtils.getOptions)(this);
(0, _schemaUtils.default)(_options.default, rawOptions, {
name: 'CSS Loader',
baseDataPath: 'options'
});
const plugins = [];
const callback = this.async();
let options;
try {
options = (0, _utils.normalizeOptions)(rawOptions, this);
} catch (error) {
callback(error);
return;
}
const replacements = [];
const exports = [];
if ((0, _utils.shouldUseModulesPlugins)(options)) {
plugins.push(...(0, _utils.getModulesPlugins)(options, this));
}
const importPluginImports = [];
const importPluginApi = [];
if ((0, _utils.shouldUseImportPlugin)(options)) {
const resolver = this.getResolve({
conditionNames: ['style'],
extensions: ['.css'],
mainFields: ['css', 'style', 'main', '...'],
mainFiles: ['index', '...'],
restrictions: [/\.css$/i]
});
plugins.push((0, _plugins.importParser)({
imports: importPluginImports,
api: importPluginApi,
context: this.context,
rootContext: this.rootContext,
filter: (0, _utils.getFilter)(options.import, this.resourcePath),
resolver,
urlHandler: url => (0, _loaderUtils.stringifyRequest)(this, (0, _utils.getPreRequester)(this)(options.importLoaders) + url)
}));
}
const urlPluginImports = [];
if ((0, _utils.shouldUseURLPlugin)(options)) {
const urlResolver = this.getResolve({
conditionNames: ['asset'],
mainFields: ['asset'],
mainFiles: [],
extensions: []
});
plugins.push((0, _plugins.urlParser)({
imports: urlPluginImports,
replacements,
context: this.context,
rootContext: this.rootContext,
filter: (0, _utils.getFilter)(options.url, this.resourcePath),
resolver: urlResolver,
urlHandler: url => (0, _loaderUtils.stringifyRequest)(this, url)
}));
}
const icssPluginImports = [];
const icssPluginApi = [];
if ((0, _utils.shouldUseIcssPlugin)(options)) {
const icssResolver = this.getResolve({
conditionNames: ['style'],
extensions: [],
mainFields: ['css', 'style', 'main', '...'],
mainFiles: ['index', '...']
});
plugins.push((0, _plugins.icssParser)({
imports: icssPluginImports,
api: icssPluginApi,
replacements,
exports,
context: this.context,
rootContext: this.rootContext,
resolver: icssResolver,
urlHandler: url => (0, _loaderUtils.stringifyRequest)(this, (0, _utils.getPreRequester)(this)(options.importLoaders) + url)
}));
} // Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
if (meta) {
const {
ast
} = meta;
if (ast && ast.type === 'postcss' && (0, _semver.satisfies)(ast.version, `^${_package.default.version}`)) {
// eslint-disable-next-line no-param-reassign
content = ast.root;
}
}
const {
resourcePath
} = this;
let result;
try {
result = await (0, _postcss.default)(plugins).process(content, {
from: resourcePath,
to: resourcePath,
map: options.sourceMap ? {
prev: map ? (0, _utils.normalizeSourceMap)(map, resourcePath) : null,
inline: false,
annotation: false
} : false
});
} catch (error) {
if (error.file) {
this.addDependency(error.file);
}
callback(error.name === 'CssSyntaxError' ? new _CssSyntaxError.default(error) : error);
return;
}
for (const warning of result.warnings()) {
this.emitWarning(new _Warning.default(warning));
}
const imports = [].concat(icssPluginImports.sort(_utils.sort)).concat(importPluginImports.sort(_utils.sort)).concat(urlPluginImports.sort(_utils.sort));
const api = [].concat(importPluginApi.sort(_utils.sort)).concat(icssPluginApi.sort(_utils.sort));
if (options.modules.exportOnlyLocals !== true) {
imports.unshift({
importName: '___CSS_LOADER_API_IMPORT___',
url: (0, _loaderUtils.stringifyRequest)(this, require.resolve('./runtime/api'))
});
}
const importCode = (0, _utils.getImportCode)(imports, options);
const moduleCode = (0, _utils.getModuleCode)(result, api, replacements, options, this);
const exportCode = (0, _utils.getExportCode)(exports, replacements, options);
callback(null, `${importCode}${moduleCode}${exportCode}`);
}
+153
View File
@@ -0,0 +1,153 @@
{
"additionalProperties": false,
"properties": {
"url": {
"description": "Enables/Disables 'url'/'image-set' functions handling (https://github.com/webpack-contrib/css-loader#url).",
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"import": {
"description": "Enables/Disables '@import' at-rules handling (https://github.com/webpack-contrib/css-loader#import).",
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"modules": {
"description": "Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).",
"anyOf": [
{
"type": "boolean"
},
{
"enum": ["local", "global", "pure"]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"compileType": {
"description": "Controls the extent to which css-loader will process module code (https://github.com/webpack-contrib/css-loader#type)",
"enum": ["module", "icss"]
},
"auto": {
"description": "Allows auto enable CSS modules based on filename (https://github.com/webpack-contrib/css-loader#auto).",
"anyOf": [
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
},
{
"type": "boolean"
}
]
},
"mode": {
"description": "Setup `mode` option (https://github.com/webpack-contrib/css-loader#mode).",
"anyOf": [
{
"enum": ["local", "global", "pure"]
},
{
"instanceof": "Function"
}
]
},
"localIdentName": {
"description": "Allows to configure the generated local ident name (https://github.com/webpack-contrib/css-loader#localidentname).",
"type": "string",
"minLength": 1
},
"localIdentContext": {
"description": "Allows to redefine basic loader context for local ident name (https://github.com/webpack-contrib/css-loader#localidentcontext).",
"type": "string",
"minLength": 1
},
"localIdentHashPrefix": {
"description": "Allows to add custom hash to generate more unique classes (https://github.com/webpack-contrib/css-loader#localidenthashprefix).",
"type": "string",
"minLength": 1
},
"localIdentRegExp": {
"description": "Allows to specify custom RegExp for local ident name (https://github.com/webpack-contrib/css-loader#localidentregexp).",
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"instanceof": "RegExp"
}
]
},
"getLocalIdent": {
"description": "Allows to specify a function to generate the classname (https://github.com/webpack-contrib/css-loader#getlocalident).",
"instanceof": "Function"
},
"namedExport": {
"description": "Enables/disables ES modules named export for locals (https://github.com/webpack-contrib/css-loader#namedexport).",
"type": "boolean"
},
"exportGlobals": {
"description": "Allows to export names from global class or id, so you can use that as local name (https://github.com/webpack-contrib/css-loader#exportglobals).",
"type": "boolean"
},
"exportLocalsConvention": {
"description": "Style of exported classnames (https://github.com/webpack-contrib/css-loader#localsconvention).",
"enum": [
"asIs",
"camelCase",
"camelCaseOnly",
"dashes",
"dashesOnly"
]
},
"exportOnlyLocals": {
"description": "Export only locals (https://github.com/webpack-contrib/css-loader#exportonlylocals).",
"type": "boolean"
}
}
}
]
},
"icss": {
"description": "Enables/Disables handling the CSS module interoperable import/export format ((https://github.com/webpack-contrib/css-loader#icss)",
"type": "boolean"
},
"sourceMap": {
"description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/css-loader#sourcemap).",
"type": "boolean"
},
"importLoaders": {
"description": "Enables/Disables or setups number of loaders applied before CSS loader (https://github.com/webpack-contrib/css-loader#importloaders).",
"anyOf": [
{
"type": "boolean"
},
{
"type": "string"
},
{
"type": "integer"
}
]
},
"esModule": {
"description": "Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule).",
"type": "boolean"
}
},
"type": "object"
}
+31
View File
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "importParser", {
enumerable: true,
get: function () {
return _postcssImportParser.default;
}
});
Object.defineProperty(exports, "icssParser", {
enumerable: true,
get: function () {
return _postcssIcssParser.default;
}
});
Object.defineProperty(exports, "urlParser", {
enumerable: true,
get: function () {
return _postcssUrlParser.default;
}
});
var _postcssImportParser = _interopRequireDefault(require("./postcss-import-parser"));
var _postcssIcssParser = _interopRequireDefault(require("./postcss-icss-parser"));
var _postcssUrlParser = _interopRequireDefault(require("./postcss-url-parser"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+113
View File
@@ -0,0 +1,113 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _icssUtils = require("icss-utils");
var _utils = require("../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = _postcss.default.plugin('postcss-icss-parser', options => async css => {
const importReplacements = Object.create(null);
const {
icssImports,
icssExports
} = (0, _icssUtils.extractICSS)(css);
const imports = new Map();
const tasks = []; // eslint-disable-next-line guard-for-in
for (const url in icssImports) {
const tokens = icssImports[url];
if (Object.keys(tokens).length === 0) {
// eslint-disable-next-line no-continue
continue;
}
let normalizedUrl = url;
let prefix = '';
const queryParts = normalizedUrl.split('!');
if (queryParts.length > 1) {
normalizedUrl = queryParts.pop();
prefix = queryParts.join('!');
}
const request = (0, _utils.requestify)((0, _utils.normalizeUrl)(normalizedUrl, true), options.rootContext);
const doResolve = async () => {
const {
resolver,
context
} = options;
const resolvedUrl = await (0, _utils.resolveRequests)(resolver, context, [...new Set([normalizedUrl, request])]);
return {
url: resolvedUrl,
prefix,
tokens
};
};
tasks.push(doResolve());
}
const results = await Promise.all(tasks);
for (let index = 0; index <= results.length - 1; index++) {
const {
url,
prefix,
tokens
} = results[index];
const newUrl = prefix ? `${prefix}!${url}` : url;
const importKey = newUrl;
let importName = imports.get(importKey);
if (!importName) {
importName = `___CSS_LOADER_ICSS_IMPORT_${imports.size}___`;
imports.set(importKey, importName);
options.imports.push({
importName,
url: options.urlHandler(newUrl),
icss: true,
index
});
options.api.push({
importName,
dedupe: true,
index
});
}
for (const [replacementIndex, token] of Object.keys(tokens).entries()) {
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${index}_REPLACEMENT_${replacementIndex}___`;
const localName = tokens[token];
importReplacements[token] = replacementName;
options.replacements.push({
replacementName,
importName,
localName
});
}
}
if (Object.keys(importReplacements).length > 0) {
(0, _icssUtils.replaceSymbols)(css, importReplacements);
}
for (const name of Object.keys(icssExports)) {
const value = (0, _icssUtils.replaceValueSymbols)(icssExports[name], importReplacements);
options.exports.push({
name,
value
});
}
});
exports.default = _default;
+214
View File
@@ -0,0 +1,214 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _util = require("util");
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
var _utils = require("../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pluginName = 'postcss-import-parser';
function walkAtRules(css, result, options, callback) {
const accumulator = [];
css.walkAtRules(/^import$/i, atRule => {
// Convert only top-level @import
if (atRule.parent.type !== 'root') {
return;
} // Nodes do not exists - `@import url('http://') :root {}`
if (atRule.nodes) {
result.warn("It looks like you didn't end your @import statement correctly. Child nodes are attached to it.", {
node: atRule
});
return;
}
const {
nodes: paramsNodes
} = (0, _postcssValueParser.default)(atRule.params); // No nodes - `@import ;`
// Invalid type - `@import foo-bar;`
if (paramsNodes.length === 0 || paramsNodes[0].type !== 'string' && paramsNodes[0].type !== 'function') {
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
node: atRule
});
return;
}
let isStringValue;
let url;
if (paramsNodes[0].type === 'string') {
isStringValue = true;
url = paramsNodes[0].value;
} else {
// Invalid function - `@import nourl(test.css);`
if (paramsNodes[0].value.toLowerCase() !== 'url') {
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
node: atRule
});
return;
}
isStringValue = paramsNodes[0].nodes.length !== 0 && paramsNodes[0].nodes[0].type === 'string';
url = isStringValue ? paramsNodes[0].nodes[0].value : _postcssValueParser.default.stringify(paramsNodes[0].nodes);
} // Empty url - `@import "";` or `@import url();`
if (url.trim().length === 0) {
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
node: atRule
});
return;
}
accumulator.push({
atRule,
url,
isStringValue,
mediaNodes: paramsNodes.slice(1)
});
});
callback(null, accumulator);
}
const asyncWalkAtRules = (0, _util.promisify)(walkAtRules);
var _default = _postcss.default.plugin(pluginName, options => async (css, result) => {
const parsedResults = await asyncWalkAtRules(css, result, options);
if (parsedResults.length === 0) {
return Promise.resolve();
}
const imports = new Map();
const tasks = [];
for (const parsedResult of parsedResults) {
const {
atRule,
url,
isStringValue,
mediaNodes
} = parsedResult;
let normalizedUrl = url;
let prefix = '';
const isRequestable = (0, _utils.isUrlRequestable)(normalizedUrl);
if (isRequestable) {
const queryParts = normalizedUrl.split('!');
if (queryParts.length > 1) {
normalizedUrl = queryParts.pop();
prefix = queryParts.join('!');
}
normalizedUrl = (0, _utils.normalizeUrl)(normalizedUrl, isStringValue); // Empty url after normalize - `@import '\
// \
// \
// ';
if (normalizedUrl.trim().length === 0) {
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
node: atRule
}); // eslint-disable-next-line no-continue
continue;
}
}
let media;
if (mediaNodes.length > 0) {
media = _postcssValueParser.default.stringify(mediaNodes).trim().toLowerCase();
}
if (options.filter && !options.filter(normalizedUrl, media)) {
// eslint-disable-next-line no-continue
continue;
}
atRule.remove();
if (isRequestable) {
const request = (0, _utils.requestify)(normalizedUrl, options.rootContext);
tasks.push((async () => {
const {
resolver,
context
} = options;
const resolvedUrl = await (0, _utils.resolveRequests)(resolver, context, [...new Set([request, normalizedUrl])]);
return {
url: resolvedUrl,
media,
prefix,
isRequestable
};
})());
} else {
tasks.push({
url,
media,
prefix,
isRequestable
});
}
}
const results = await Promise.all(tasks);
for (let index = 0; index <= results.length - 1; index++) {
const {
url,
isRequestable,
media
} = results[index];
if (isRequestable) {
const {
prefix
} = results[index];
const newUrl = prefix ? `${prefix}!${url}` : url;
const importKey = newUrl;
let importName = imports.get(importKey);
if (!importName) {
importName = `___CSS_LOADER_AT_RULE_IMPORT_${imports.size}___`;
imports.set(importKey, importName);
options.imports.push({
importName,
url: options.urlHandler(newUrl),
index
});
}
options.api.push({
importName,
media,
index
}); // eslint-disable-next-line no-continue
continue;
}
options.api.push({
url,
media,
index
});
}
return Promise.resolve();
});
exports.default = _default;
+257
View File
@@ -0,0 +1,257 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _util = require("util");
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
var _utils = require("../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pluginName = 'postcss-url-parser';
const isUrlFunc = /url/i;
const isImageSetFunc = /^(?:-webkit-)?image-set$/i;
const needParseDecl = /(?:url|(?:-webkit-)?image-set)\(/i;
function getNodeFromUrlFunc(node) {
return node.nodes && node.nodes[0];
}
function shouldHandleRule(rule, decl, result) {
// https://www.w3.org/TR/css-syntax-3/#typedef-url-token
if (rule.url.replace(/^[\s]+|[\s]+$/g, '').length === 0) {
result.warn(`Unable to find uri in '${decl.toString()}'`, {
node: decl
});
return false;
}
if (!(0, _utils.isUrlRequestable)(rule.url)) {
return false;
}
return true;
}
function walkCss(css, result, options, callback) {
const accumulator = [];
css.walkDecls(decl => {
if (!needParseDecl.test(decl.value)) {
return;
}
const parsed = (0, _postcssValueParser.default)(decl.value);
parsed.walk(node => {
if (node.type !== 'function') {
return;
}
if (isUrlFunc.test(node.value)) {
const {
nodes
} = node;
const isStringValue = nodes.length !== 0 && nodes[0].type === 'string';
const url = isStringValue ? nodes[0].value : _postcssValueParser.default.stringify(nodes);
const rule = {
node: getNodeFromUrlFunc(node),
url,
needQuotes: false,
isStringValue
};
if (shouldHandleRule(rule, decl, result)) {
accumulator.push({
decl,
rule,
parsed
});
} // Do not traverse inside `url`
// eslint-disable-next-line consistent-return
return false;
} else if (isImageSetFunc.test(node.value)) {
for (const nNode of node.nodes) {
const {
type,
value
} = nNode;
if (type === 'function' && isUrlFunc.test(value)) {
const {
nodes
} = nNode;
const isStringValue = nodes.length !== 0 && nodes[0].type === 'string';
const url = isStringValue ? nodes[0].value : _postcssValueParser.default.stringify(nodes);
const rule = {
node: getNodeFromUrlFunc(nNode),
url,
needQuotes: false,
isStringValue
};
if (shouldHandleRule(rule, decl, result)) {
accumulator.push({
decl,
rule,
parsed
});
}
} else if (type === 'string') {
const rule = {
node: nNode,
url: value,
needQuotes: true,
isStringValue: true
};
if (shouldHandleRule(rule, decl, result)) {
accumulator.push({
decl,
rule,
parsed
});
}
}
} // Do not traverse inside `image-set`
// eslint-disable-next-line consistent-return
return false;
}
});
});
callback(null, accumulator);
}
const asyncWalkCss = (0, _util.promisify)(walkCss);
var _default = _postcss.default.plugin(pluginName, options => async (css, result) => {
const parsedResults = await asyncWalkCss(css, result, options);
if (parsedResults.length === 0) {
return Promise.resolve();
}
const tasks = [];
const imports = new Map();
const replacements = new Map();
let hasUrlImportHelper = false;
for (const parsedResult of parsedResults) {
const {
url,
isStringValue
} = parsedResult.rule;
let normalizedUrl = url;
let prefix = '';
const queryParts = normalizedUrl.split('!');
if (queryParts.length > 1) {
normalizedUrl = queryParts.pop();
prefix = queryParts.join('!');
}
normalizedUrl = (0, _utils.normalizeUrl)(normalizedUrl, isStringValue);
if (!options.filter(normalizedUrl)) {
// eslint-disable-next-line no-continue
continue;
}
if (!hasUrlImportHelper) {
options.imports.push({
importName: '___CSS_LOADER_GET_URL_IMPORT___',
url: options.urlHandler(require.resolve('../runtime/getUrl.js')),
index: -1
});
hasUrlImportHelper = true;
}
const splittedUrl = normalizedUrl.split(/(\?)?#/);
const [pathname, query, hashOrQuery] = splittedUrl;
let hash = query ? '?' : '';
hash += hashOrQuery ? `#${hashOrQuery}` : '';
const request = (0, _utils.requestify)(pathname, options.rootContext);
tasks.push((async () => {
const {
resolver,
context
} = options;
const resolvedUrl = await (0, _utils.resolveRequests)(resolver, context, [...new Set([request, normalizedUrl])]);
return {
url: resolvedUrl,
prefix,
hash,
parsedResult
};
})());
}
const results = await Promise.all(tasks);
for (let index = 0; index <= results.length - 1; index++) {
const {
url,
prefix,
hash,
parsedResult: {
decl,
rule,
parsed
}
} = results[index];
const newUrl = prefix ? `${prefix}!${url}` : url;
const importKey = newUrl;
let importName = imports.get(importKey);
if (!importName) {
importName = `___CSS_LOADER_URL_IMPORT_${imports.size}___`;
imports.set(importKey, importName);
options.imports.push({
importName,
url: options.urlHandler(newUrl),
index
});
}
const {
needQuotes
} = rule;
const replacementKey = JSON.stringify({
newUrl,
hash,
needQuotes
});
let replacementName = replacements.get(replacementKey);
if (!replacementName) {
replacementName = `___CSS_LOADER_URL_REPLACEMENT_${replacements.size}___`;
replacements.set(replacementKey, replacementName);
options.replacements.push({
replacementName,
importName,
hash,
needQuotes
});
} // eslint-disable-next-line no-param-reassign
rule.node.type = 'word'; // eslint-disable-next-line no-param-reassign
rule.node.value = replacementName; // eslint-disable-next-line no-param-reassign
decl.value = parsed.toString();
}
return Promise.resolve();
});
exports.default = _default;
+94
View File
@@ -0,0 +1,94 @@
"use strict";
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
// eslint-disable-next-line func-names
module.exports = function (useSourceMap) {
var list = []; // return the list of modules as css string
list.toString = function toString() {
return this.map(function (item) {
var content = cssWithMappingToString(item, useSourceMap);
if (item[2]) {
return "@media ".concat(item[2], " {").concat(content, "}");
}
return content;
}).join('');
}; // import a list of modules into the list
// eslint-disable-next-line func-names
list.i = function (modules, mediaQuery, dedupe) {
if (typeof modules === 'string') {
// eslint-disable-next-line no-param-reassign
modules = [[null, modules, '']];
}
var alreadyImportedModules = {};
if (dedupe) {
for (var i = 0; i < this.length; i++) {
// eslint-disable-next-line prefer-destructuring
var id = this[i][0];
if (id != null) {
alreadyImportedModules[id] = true;
}
}
}
for (var _i = 0; _i < modules.length; _i++) {
var item = [].concat(modules[_i]);
if (dedupe && alreadyImportedModules[item[0]]) {
// eslint-disable-next-line no-continue
continue;
}
if (mediaQuery) {
if (!item[2]) {
item[2] = mediaQuery;
} else {
item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
}
}
list.push(item);
}
};
return list;
};
function cssWithMappingToString(item, useSourceMap) {
var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring
var cssMapping = item[3];
if (!cssMapping) {
return content;
}
if (useSourceMap && typeof btoa === 'function') {
var sourceMapping = toComment(cssMapping);
var sourceURLs = cssMapping.sources.map(function (source) {
return "/*# sourceURL=".concat(cssMapping.sourceRoot || '').concat(source, " */");
});
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
}
return [content].join('\n');
} // Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
// eslint-disable-next-line no-undef
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
return "/*# ".concat(data, " */");
}
+34
View File
@@ -0,0 +1,34 @@
"use strict";
module.exports = function (url, options) {
if (!options) {
// eslint-disable-next-line no-param-reassign
options = {};
} // eslint-disable-next-line no-underscore-dangle, no-param-reassign
url = url && url.__esModule ? url.default : url;
if (typeof url !== 'string') {
return url;
} // If url is already wrapped in quotes, remove them
if (/^['"].*['"]$/.test(url)) {
// eslint-disable-next-line no-param-reassign
url = url.slice(1, -1);
}
if (options.hash) {
// eslint-disable-next-line no-param-reassign
url += options.hash;
} // Should url be wrapped?
// See https://drafts.csswg.org/css-values-3/#urls
if (/["'() \t\n]/.test(url) || options.needQuotes) {
return "\"".concat(url.replace(/"/g, '\\"').replace(/\n/g, '\\n'), "\"");
}
return url;
};
+613
View File
@@ -0,0 +1,613 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.normalizeOptions = normalizeOptions;
exports.shouldUseModulesPlugins = shouldUseModulesPlugins;
exports.shouldUseImportPlugin = shouldUseImportPlugin;
exports.shouldUseURLPlugin = shouldUseURLPlugin;
exports.shouldUseIcssPlugin = shouldUseIcssPlugin;
exports.normalizeUrl = normalizeUrl;
exports.requestify = requestify;
exports.getFilter = getFilter;
exports.getModulesOptions = getModulesOptions;
exports.getModulesPlugins = getModulesPlugins;
exports.normalizeSourceMap = normalizeSourceMap;
exports.getPreRequester = getPreRequester;
exports.getImportCode = getImportCode;
exports.getModuleCode = getModuleCode;
exports.getExportCode = getExportCode;
exports.resolveRequests = resolveRequests;
exports.isUrlRequestable = isUrlRequestable;
exports.sort = sort;
var _url = require("url");
var _path = _interopRequireDefault(require("path"));
var _loaderUtils = require("loader-utils");
var _cssesc = _interopRequireDefault(require("cssesc"));
var _postcssModulesValues = _interopRequireDefault(require("postcss-modules-values"));
var _postcssModulesLocalByDefault = _interopRequireDefault(require("postcss-modules-local-by-default"));
var _postcssModulesExtractImports = _interopRequireDefault(require("postcss-modules-extract-imports"));
var _postcssModulesScope = _interopRequireDefault(require("postcss-modules-scope"));
var _camelcase = _interopRequireDefault(require("camelcase"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
const whitespace = '[\\x20\\t\\r\\n\\f]';
const unescapeRegExp = new RegExp(`\\\\([\\da-f]{1,6}${whitespace}?|(${whitespace})|.)`, 'ig');
const matchNativeWin32Path = /^[A-Z]:[/\\]|^\\\\/i;
function unescape(str) {
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
const high = `0x${escaped}` - 0x10000;
/* eslint-disable line-comment-position */
// NaN means non-codepoint
// Workaround erroneous numeric interpretation of +"0x"
// eslint-disable-next-line no-self-compare
return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint
String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair)
// eslint-disable-next-line no-bitwise
String.fromCharCode(high >> 10 | 0xd800, high & 0x3ff | 0xdc00);
/* eslint-enable line-comment-position */
});
}
function normalizePath(file) {
return _path.default.sep === '\\' ? file.replace(/\\/g, '/') : file;
} // eslint-disable-next-line no-control-regex
const filenameReservedRegex = /[<>:"/\\|?*]/g; // eslint-disable-next-line no-control-regex
const reControlChars = /[\u0000-\u001f\u0080-\u009f]/g;
function defaultGetLocalIdent(loaderContext, localIdentName, localName, options) {
const {
context,
hashPrefix
} = options;
const {
resourcePath
} = loaderContext;
const request = normalizePath(_path.default.relative(context, resourcePath)); // eslint-disable-next-line no-param-reassign
options.content = `${hashPrefix + request}\x00${unescape(localName)}`; // Using `[path]` placeholder outputs `/` we need escape their
// Also directories can contains invalid characters for css we need escape their too
return (0, _cssesc.default)((0, _loaderUtils.interpolateName)(loaderContext, localIdentName, options) // For `[hash]` placeholder
.replace(/^((-?[0-9])|--)/, '_$1').replace(filenameReservedRegex, '-').replace(reControlChars, '-').replace(/\./g, '-'), {
isIdentifier: true
}).replace(/\\\[local\\]/gi, localName);
}
function normalizeUrl(url, isStringValue) {
let normalizedUrl = url;
if (isStringValue && /\\(\n|\r\n|\r|\f)/.test(normalizedUrl)) {
normalizedUrl = normalizedUrl.replace(/\\(\n|\r\n|\r|\f)/g, '');
}
if (matchNativeWin32Path.test(url)) {
return decodeURIComponent(normalizedUrl);
}
return decodeURIComponent(unescape(normalizedUrl));
}
function requestify(url, rootContext) {
if (/^file:/i.test(url)) {
return (0, _url.fileURLToPath)(url);
}
return url.charAt(0) === '/' ? (0, _loaderUtils.urlToRequest)(url, rootContext) : (0, _loaderUtils.urlToRequest)(url);
}
function getFilter(filter, resourcePath) {
return (...args) => {
if (typeof filter === 'function') {
return filter(...args, resourcePath);
}
return true;
};
}
const moduleRegExp = /\.module\.\w+$/i;
function getModulesOptions(rawOptions, loaderContext) {
const {
resourcePath
} = loaderContext;
if (typeof rawOptions.modules === 'undefined') {
const isModules = moduleRegExp.test(resourcePath);
if (!isModules) {
return false;
}
} else if (typeof rawOptions.modules === 'boolean' && rawOptions.modules === false) {
return false;
}
let modulesOptions = {
compileType: rawOptions.icss ? 'icss' : 'module',
auto: true,
mode: 'local',
exportGlobals: false,
localIdentName: '[hash:base64]',
localIdentContext: loaderContext.rootContext,
localIdentHashPrefix: '',
// eslint-disable-next-line no-undefined
localIdentRegExp: undefined,
getLocalIdent: defaultGetLocalIdent,
namedExport: false,
exportLocalsConvention: 'asIs',
exportOnlyLocals: false
};
if (typeof rawOptions.modules === 'boolean' || typeof rawOptions.modules === 'string') {
modulesOptions.mode = typeof rawOptions.modules === 'string' ? rawOptions.modules : 'local';
} else {
if (rawOptions.modules) {
if (typeof rawOptions.modules.auto === 'boolean') {
const isModules = rawOptions.modules.auto && moduleRegExp.test(resourcePath);
if (!isModules) {
return false;
}
} else if (rawOptions.modules.auto instanceof RegExp) {
const isModules = rawOptions.modules.auto.test(resourcePath);
if (!isModules) {
return false;
}
} else if (typeof rawOptions.modules.auto === 'function') {
const isModule = rawOptions.modules.auto(resourcePath);
if (!isModule) {
return false;
}
}
if (rawOptions.modules.namedExport === true && typeof rawOptions.modules.exportLocalsConvention === 'undefined') {
modulesOptions.exportLocalsConvention = 'camelCaseOnly';
}
}
modulesOptions = { ...modulesOptions,
...(rawOptions.modules || {})
};
}
if (typeof modulesOptions.mode === 'function') {
modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath);
}
if (modulesOptions.namedExport === true) {
if (rawOptions.esModule === false) {
throw new Error('The "modules.namedExport" option requires the "esModules" option to be enabled');
}
if (modulesOptions.exportLocalsConvention !== 'camelCaseOnly') {
throw new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly"');
}
}
return modulesOptions;
}
function normalizeOptions(rawOptions, loaderContext) {
if (rawOptions.icss) {
loaderContext.emitWarning(new Error('The "icss" option is deprecated, use "modules.compileType: "icss"" instead'));
}
const modulesOptions = getModulesOptions(rawOptions, loaderContext);
return {
url: typeof rawOptions.url === 'undefined' ? true : rawOptions.url,
import: typeof rawOptions.import === 'undefined' ? true : rawOptions.import,
modules: modulesOptions,
// TODO remove in the next major release
icss: typeof rawOptions.icss === 'undefined' ? false : rawOptions.icss,
sourceMap: typeof rawOptions.sourceMap === 'boolean' ? rawOptions.sourceMap : loaderContext.sourceMap,
importLoaders: typeof rawOptions.importLoaders === 'string' ? parseInt(rawOptions.importLoaders, 10) : rawOptions.importLoaders,
esModule: typeof rawOptions.esModule === 'undefined' ? true : rawOptions.esModule
};
}
function shouldUseImportPlugin(options) {
if (options.modules.exportOnlyLocals) {
return false;
}
if (typeof options.import === 'boolean') {
return options.import;
}
return true;
}
function shouldUseURLPlugin(options) {
if (options.modules.exportOnlyLocals) {
return false;
}
if (typeof options.url === 'boolean') {
return options.url;
}
return true;
}
function shouldUseModulesPlugins(options) {
return options.modules.compileType === 'module';
}
function shouldUseIcssPlugin(options) {
return options.icss === true || Boolean(options.modules);
}
function getModulesPlugins(options, loaderContext) {
const {
mode,
getLocalIdent,
localIdentName,
localIdentContext,
localIdentHashPrefix,
localIdentRegExp
} = options.modules;
let plugins = [];
try {
plugins = [_postcssModulesValues.default, (0, _postcssModulesLocalByDefault.default)({
mode
}), (0, _postcssModulesExtractImports.default)(), (0, _postcssModulesScope.default)({
generateScopedName(exportName) {
return getLocalIdent(loaderContext, localIdentName, exportName, {
context: localIdentContext,
hashPrefix: localIdentHashPrefix,
regExp: localIdentRegExp
});
},
exportGlobals: options.modules.exportGlobals
})];
} catch (error) {
loaderContext.emitError(error);
}
return plugins;
}
const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i;
function getURLType(source) {
if (source[0] === '/') {
if (source[1] === '/') {
return 'scheme-relative';
}
return 'path-absolute';
}
if (IS_NATIVE_WIN32_PATH.test(source)) {
return 'path-absolute';
}
return ABSOLUTE_SCHEME.test(source) ? 'absolute' : 'path-relative';
}
function normalizeSourceMap(map, resourcePath) {
let newMap = map; // Some loader emit source map as string
// Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
if (typeof newMap === 'string') {
newMap = JSON.parse(newMap);
}
delete newMap.file;
const {
sourceRoot
} = newMap;
delete newMap.sourceRoot;
if (newMap.sources) {
// Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
// We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
newMap.sources = newMap.sources.map(source => {
// Non-standard syntax from `postcss`
if (source.indexOf('<') === 0) {
return source;
}
const sourceType = getURLType(source); // Do no touch `scheme-relative` and `absolute` URLs
if (sourceType === 'path-relative' || sourceType === 'path-absolute') {
const absoluteSource = sourceType === 'path-relative' && sourceRoot ? _path.default.resolve(sourceRoot, normalizePath(source)) : normalizePath(source);
return _path.default.relative(_path.default.dirname(resourcePath), absoluteSource);
}
return source;
});
}
return newMap;
}
function getPreRequester({
loaders,
loaderIndex
}) {
const cache = Object.create(null);
return number => {
if (cache[number]) {
return cache[number];
}
if (number === false) {
cache[number] = '';
} else {
const loadersRequest = loaders.slice(loaderIndex, loaderIndex + 1 + (typeof number !== 'number' ? 0 : number)).map(x => x.request).join('!');
cache[number] = `-!${loadersRequest}!`;
}
return cache[number];
};
}
function getImportCode(imports, options) {
let code = '';
for (const item of imports) {
const {
importName,
url,
icss
} = item;
if (options.esModule) {
if (icss && options.modules.namedExport) {
code += `import ${options.modules.exportOnlyLocals ? '' : `${importName}, `}* as ${importName}_NAMED___ from ${url};\n`;
} else {
code += `import ${importName} from ${url};\n`;
}
} else {
code += `var ${importName} = require(${url});\n`;
}
}
return code ? `// Imports\n${code}` : '';
}
function normalizeSourceMapForRuntime(map, loaderContext) {
const resultMap = map ? map.toJSON() : null;
if (resultMap) {
delete resultMap.file;
resultMap.sourceRoot = '';
resultMap.sources = resultMap.sources.map(source => {
// Non-standard syntax from `postcss`
if (source.indexOf('<') === 0) {
return source;
}
const sourceType = getURLType(source);
if (sourceType !== 'path-relative') {
return source;
}
const resourceDirname = _path.default.dirname(loaderContext.resourcePath);
const absoluteSource = _path.default.resolve(resourceDirname, source);
const contextifyPath = normalizePath(_path.default.relative(loaderContext.rootContext, absoluteSource));
return `webpack://${contextifyPath}`;
});
}
return JSON.stringify(resultMap);
}
function getModuleCode(result, api, replacements, options, loaderContext) {
if (options.modules.exportOnlyLocals === true) {
return '';
}
const sourceMapValue = options.sourceMap ? `,${normalizeSourceMapForRuntime(result.map, loaderContext)}` : '';
let code = JSON.stringify(result.css);
let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap});\n`;
for (const item of api) {
const {
url,
media,
dedupe
} = item;
beforeCode += url ? `___CSS_LOADER_EXPORT___.push([module.id, ${JSON.stringify(`@import url(${url});`)}${media ? `, ${JSON.stringify(media)}` : ''}]);\n` : `___CSS_LOADER_EXPORT___.i(${item.importName}${media ? `, ${JSON.stringify(media)}` : dedupe ? ', ""' : ''}${dedupe ? ', true' : ''});\n`;
}
for (const item of replacements) {
const {
replacementName,
importName,
localName
} = item;
if (localName) {
code = code.replace(new RegExp(replacementName, 'g'), () => options.modules.namedExport ? `" + ${importName}_NAMED___[${JSON.stringify((0, _camelcase.default)(localName))}] + "` : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`);
} else {
const {
hash,
needQuotes
} = item;
const getUrlOptions = [].concat(hash ? [`hash: ${JSON.stringify(hash)}`] : []).concat(needQuotes ? 'needQuotes: true' : []);
const preparedOptions = getUrlOptions.length > 0 ? `, { ${getUrlOptions.join(', ')} }` : '';
beforeCode += `var ${replacementName} = ___CSS_LOADER_GET_URL_IMPORT___(${importName}${preparedOptions});\n`;
code = code.replace(new RegExp(replacementName, 'g'), () => `" + ${replacementName} + "`);
}
}
return `${beforeCode}// Module\n___CSS_LOADER_EXPORT___.push([module.id, ${code}, ""${sourceMapValue}]);\n`;
}
function dashesCamelCase(str) {
return str.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
}
function getExportCode(exports, replacements, options) {
let code = '// Exports\n';
let localsCode = '';
const addExportToLocalsCode = (name, value) => {
if (options.modules.namedExport) {
localsCode += `export const ${(0, _camelcase.default)(name)} = ${JSON.stringify(value)};\n`;
} else {
if (localsCode) {
localsCode += `,\n`;
}
localsCode += `\t${JSON.stringify(name)}: ${JSON.stringify(value)}`;
}
};
for (const {
name,
value
} of exports) {
switch (options.modules.exportLocalsConvention) {
case 'camelCase':
{
addExportToLocalsCode(name, value);
const modifiedName = (0, _camelcase.default)(name);
if (modifiedName !== name) {
addExportToLocalsCode(modifiedName, value);
}
break;
}
case 'camelCaseOnly':
{
addExportToLocalsCode((0, _camelcase.default)(name), value);
break;
}
case 'dashes':
{
addExportToLocalsCode(name, value);
const modifiedName = dashesCamelCase(name);
if (modifiedName !== name) {
addExportToLocalsCode(modifiedName, value);
}
break;
}
case 'dashesOnly':
{
addExportToLocalsCode(dashesCamelCase(name), value);
break;
}
case 'asIs':
default:
addExportToLocalsCode(name, value);
break;
}
}
for (const item of replacements) {
const {
replacementName,
localName
} = item;
if (localName) {
const {
importName
} = item;
localsCode = localsCode.replace(new RegExp(replacementName, 'g'), () => {
if (options.modules.namedExport) {
return `" + ${importName}_NAMED___[${JSON.stringify((0, _camelcase.default)(localName))}] + "`;
} else if (options.modules.exportOnlyLocals) {
return `" + ${importName}[${JSON.stringify(localName)}] + "`;
}
return `" + ${importName}.locals[${JSON.stringify(localName)}] + "`;
});
} else {
localsCode = localsCode.replace(new RegExp(replacementName, 'g'), () => `" + ${replacementName} + "`);
}
}
if (options.modules.exportOnlyLocals) {
code += options.modules.namedExport ? localsCode : `${options.esModule ? 'export default' : 'module.exports ='} {\n${localsCode}\n};\n`;
return code;
}
if (localsCode) {
code += options.modules.namedExport ? localsCode : `___CSS_LOADER_EXPORT___.locals = {\n${localsCode}\n};\n`;
}
code += `${options.esModule ? 'export default' : 'module.exports ='} ___CSS_LOADER_EXPORT___;\n`;
return code;
}
async function resolveRequests(resolve, context, possibleRequests) {
return resolve(context, possibleRequests[0]).then(result => {
return result;
}).catch(error => {
const [, ...tailPossibleRequests] = possibleRequests;
if (tailPossibleRequests.length === 0) {
throw error;
}
return resolveRequests(resolve, context, tailPossibleRequests);
});
}
function isUrlRequestable(url) {
// Protocol-relative URLs
if (/^\/\//.test(url)) {
return false;
} // `file:` protocol
if (/^file:/i.test(url)) {
return true;
} // Absolute URLs
if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !matchNativeWin32Path.test(url)) {
return false;
} // `#` URLs
if (/^#/.test(url)) {
return false;
}
return true;
}
function sort(a, b) {
return a.index - b.index;
}
+103
View File
@@ -0,0 +1,103 @@
declare namespace camelcase {
interface Options {
/**
Uppercase the first character: `foo-bar` → `FooBar`.
@default false
*/
readonly pascalCase?: boolean;
/**
Preserve the consecutive uppercase characters: `foo-BAR` → `FooBAR`.
@default false
*/
readonly preserveConsecutiveUppercase?: boolean;
/**
The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.
Setting `locale: false` ignores the platform locale and uses the [Unicode Default Case Conversion](https://unicode-org.github.io/icu/userguide/transforms/casemappings.html#simple-single-character-case-mapping) algorithm.
Default: The host environments current locale.
@example
```
import camelCase = require('camelcase');
camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
camelCase('lorem-ipsum', {locale: 'tr-TR'});
//=> 'loremİpsum'
camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
//=> 'loremIpsum'
camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
//=> 'loremİpsum'
```
*/
readonly locale?: false | string | readonly string[];
}
}
/**
Convert a dash/dot/underscore/space separated string to camelCase or PascalCase: `foo-bar` → `fooBar`.
Correctly handles Unicode strings.
@param input - String to convert to camel case.
@example
```
import camelCase = require('camelcase');
camelCase('foo-bar');
//=> 'fooBar'
camelCase('foo_bar');
//=> 'fooBar'
camelCase('Foo-Bar');
//=> 'fooBar'
camelCase('розовый_пушистый_единорог');
//=> 'розовыйПушистыйЕдинорог'
camelCase('Foo-Bar', {pascalCase: true});
//=> 'FooBar'
camelCase('--foo.bar', {pascalCase: false});
//=> 'fooBar'
camelCase('Foo-BAR', {preserveConsecutiveUppercase: true});
//=> 'fooBAR'
camelCase('fooBAR', {pascalCase: true, preserveConsecutiveUppercase: true}));
//=> 'FooBAR'
camelCase('foo bar');
//=> 'fooBar'
console.log(process.argv[3]);
//=> '--foo-bar'
camelCase(process.argv[3]);
//=> 'fooBar'
camelCase(['foo', 'bar']);
//=> 'fooBar'
camelCase(['__foo__', '--bar'], {pascalCase: true});
//=> 'FooBar'
camelCase(['foo', 'BAR'], {pascalCase: true, preserveConsecutiveUppercase: true})
//=> 'FooBAR'
camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
```
*/
declare function camelcase(
input: string | readonly string[],
options?: camelcase.Options
): string;
export = camelcase;
+113
View File
@@ -0,0 +1,113 @@
'use strict';
const UPPERCASE = /[\p{Lu}]/u;
const LOWERCASE = /[\p{Ll}]/u;
const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
const SEPARATORS = /[_.\- ]+/;
const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');
const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');
const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
let isLastCharLower = false;
let isLastCharUpper = false;
let isLastLastCharUpper = false;
for (let i = 0; i < string.length; i++) {
const character = string[i];
if (isLastCharLower && UPPERCASE.test(character)) {
string = string.slice(0, i) + '-' + string.slice(i);
isLastCharLower = false;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = true;
i++;
} else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = false;
isLastCharLower = true;
} else {
isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
}
}
return string;
};
const preserveConsecutiveUppercase = (input, toLowerCase) => {
LEADING_CAPITAL.lastIndex = 0;
return input.replace(LEADING_CAPITAL, m1 => toLowerCase(m1));
};
const postProcess = (input, toUpperCase) => {
SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
NUMBERS_AND_IDENTIFIER.lastIndex = 0;
return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier))
.replace(NUMBERS_AND_IDENTIFIER, m => toUpperCase(m));
};
const camelCase = (input, options) => {
if (!(typeof input === 'string' || Array.isArray(input))) {
throw new TypeError('Expected the input to be `string | string[]`');
}
options = {
pascalCase: false,
preserveConsecutiveUppercase: false,
...options
};
if (Array.isArray(input)) {
input = input.map(x => x.trim())
.filter(x => x.length)
.join('-');
} else {
input = input.trim();
}
if (input.length === 0) {
return '';
}
const toLowerCase = options.locale === false ?
string => string.toLowerCase() :
string => string.toLocaleLowerCase(options.locale);
const toUpperCase = options.locale === false ?
string => string.toUpperCase() :
string => string.toLocaleUpperCase(options.locale);
if (input.length === 1) {
return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
}
const hasUpperCase = input !== toLowerCase(input);
if (hasUpperCase) {
input = preserveCamelCase(input, toLowerCase, toUpperCase);
}
input = input.replace(LEADING_SEPARATORS, '');
if (options.preserveConsecutiveUppercase) {
input = preserveConsecutiveUppercase(input, toLowerCase);
} else {
input = toLowerCase(input);
}
if (options.pascalCase) {
input = toUpperCase(input.charAt(0)) + input.slice(1);
}
return postProcess(input, toUpperCase);
};
module.exports = camelCase;
// TODO: Remove this for the next major release
module.exports.default = camelCase;
+9
View File
@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+79
View File
@@ -0,0 +1,79 @@
{
"_args": [
[
"camelcase@6.3.0",
"/home/node/nuxt"
]
],
"_from": "camelcase@6.3.0",
"_id": "camelcase@6.3.0",
"_inBundle": false,
"_integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"_location": "/css-loader/camelcase",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "camelcase@6.3.0",
"name": "camelcase",
"escapedName": "camelcase",
"rawSpec": "6.3.0",
"saveSpec": null,
"fetchSpec": "6.3.0"
},
"_requiredBy": [
"/css-loader"
],
"_resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"_spec": "6.3.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/camelcase/issues"
},
"description": "Convert a dash/dot/underscore/space separated string to camelCase or PascalCase: `foo-bar` → `fooBar`",
"devDependencies": {
"ava": "^1.4.1",
"tsd": "^0.11.0",
"xo": "^0.28.3"
},
"engines": {
"node": ">=10"
},
"files": [
"index.js",
"index.d.ts"
],
"funding": "https://github.com/sponsors/sindresorhus",
"homepage": "https://github.com/sindresorhus/camelcase#readme",
"keywords": [
"camelcase",
"camel-case",
"camel",
"case",
"dash",
"hyphen",
"dot",
"underscore",
"separator",
"string",
"text",
"convert",
"pascalcase",
"pascal-case"
],
"license": "MIT",
"name": "camelcase",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/camelcase.git"
},
"scripts": {
"test": "xo && ava && tsd"
},
"version": "6.3.0"
}
+144
View File
@@ -0,0 +1,144 @@
# camelcase
> Convert a dash/dot/underscore/space separated string to camelCase or PascalCase: `foo-bar` → `fooBar`
Correctly handles Unicode strings.
If you use this on untrusted user input, don't forget to limit the length to something reasonable.
## Install
```
$ npm install camelcase
```
*If you need to support Firefox < 78, stay on version 5 as version 6 uses regex features not available in Firefox < 78.*
## Usage
```js
const camelCase = require('camelcase');
camelCase('foo-bar');
//=> 'fooBar'
camelCase('foo_bar');
//=> 'fooBar'
camelCase('Foo-Bar');
//=> 'fooBar'
camelCase('розовый_пушистый_единорог');
//=> 'розовыйПушистыйЕдинорог'
camelCase('Foo-Bar', {pascalCase: true});
//=> 'FooBar'
camelCase('--foo.bar', {pascalCase: false});
//=> 'fooBar'
camelCase('Foo-BAR', {preserveConsecutiveUppercase: true});
//=> 'fooBAR'
camelCase('fooBAR', {pascalCase: true, preserveConsecutiveUppercase: true}));
//=> 'FooBAR'
camelCase('foo bar');
//=> 'fooBar'
console.log(process.argv[3]);
//=> '--foo-bar'
camelCase(process.argv[3]);
//=> 'fooBar'
camelCase(['foo', 'bar']);
//=> 'fooBar'
camelCase(['__foo__', '--bar'], {pascalCase: true});
//=> 'FooBar'
camelCase(['foo', 'BAR'], {pascalCase: true, preserveConsecutiveUppercase: true})
//=> 'FooBAR'
camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
```
## API
### camelCase(input, options?)
#### input
Type: `string | string[]`
String to convert to camel case.
#### options
Type: `object`
##### pascalCase
Type: `boolean`\
Default: `false`
Uppercase the first character: `foo-bar``FooBar`
##### preserveConsecutiveUppercase
Type: `boolean`\
Default: `false`
Preserve the consecutive uppercase characters: `foo-BAR``FooBAR`.
##### locale
Type: `false | string | string[]`\
Default: The host environments current locale.
The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.
```js
const camelCase = require('camelcase');
camelCase('lorem-ipsum', {locale: 'en-US'});
//=> 'loremIpsum'
camelCase('lorem-ipsum', {locale: 'tr-TR'});
//=> 'loremİpsum'
camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
//=> 'loremIpsum'
camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
//=> 'loremİpsum'
```
Setting `locale: false` ignores the platform locale and uses the [Unicode Default Case Conversion](https://unicode-org.github.io/icu/userguide/transforms/casemappings.html#simple-single-character-case-mapping) algorithm:
```js
const camelCase = require('camelcase');
// On a platform with 'tr-TR'
camelCase('lorem-ipsum');
//=> 'loremİpsum'
camelCase('lorem-ipsum', {locale: false});
//=> 'loremIpsum'
```
## camelcase for enterprise
Available as part of the Tidelift Subscription.
The maintainers of camelcase and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-camelcase?utm_source=npm-camelcase&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
## Related
- [decamelize](https://github.com/sindresorhus/decamelize) - The inverse of this module
- [uppercamelcase](https://github.com/SamVerschueren/uppercamelcase) - Like this module, but to PascalCase instead of camelCase
- [titleize](https://github.com/sindresorhus/titleize) - Capitalize every word in string
- [humanize-string](https://github.com/sindresorhus/humanize-string) - Convert a camelized/dasherized/underscored string into a humanized one
- [camelcase-keys](https://github.com/sindresorhus/camelcase-keys) - Convert object keys to camel case
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+275
View File
@@ -0,0 +1,275 @@
# loader-utils
## Methods
### `getOptions`
Recommended way to retrieve the options of a loader invocation:
```javascript
// inside your loader
const options = loaderUtils.getOptions(this);
```
1. If `this.query` is a string:
- Tries to parse the query string and returns a new object
- Throws if it's not a valid query string
2. If `this.query` is object-like, it just returns `this.query`
3. In any other case, it just returns `null`
**Please note:** The returned `options` object is *read-only*. It may be re-used across multiple invocations.
If you pass it on to another library, make sure to make a *deep copy* of it:
```javascript
const options = Object.assign(
{},
defaultOptions,
loaderUtils.getOptions(this) // it is safe to pass null to Object.assign()
);
// don't forget nested objects or arrays
options.obj = Object.assign({}, options.obj);
options.arr = options.arr.slice();
someLibrary(options);
```
[clone](https://www.npmjs.com/package/clone) is a good library to make a deep copy of the options.
#### Options as query strings
If the loader options have been passed as loader query string (`loader?some&params`), the string is parsed by using [`parseQuery`](#parsequery).
### `parseQuery`
Parses a passed string (e.g. `loaderContext.resourceQuery`) as a query string, and returns an object.
``` javascript
const params = loaderUtils.parseQuery(this.resourceQuery); // resource: `file?param1=foo`
if (params.param1 === "foo") {
// do something
}
```
The string is parsed like this:
``` text
-> Error
? -> {}
?flag -> { flag: true }
?+flag -> { flag: true }
?-flag -> { flag: false }
?xyz=test -> { xyz: "test" }
?xyz=1 -> { xyz: "1" } // numbers are NOT parsed
?xyz[]=a -> { xyz: ["a"] }
?flag1&flag2 -> { flag1: true, flag2: true }
?+flag1,-flag2 -> { flag1: true, flag2: false }
?xyz[]=a,xyz[]=b -> { xyz: ["a", "b"] }
?a%2C%26b=c%2C%26d -> { "a,&b": "c,&d" }
?{data:{a:1},isJSON5:true} -> { data: { a: 1 }, isJSON5: true }
```
### `stringifyRequest`
Turns a request into a string that can be used inside `require()` or `import` while avoiding absolute paths.
Use it instead of `JSON.stringify(...)` if you're generating code inside a loader.
**Why is this necessary?** Since webpack calculates the hash before module paths are translated into module ids, we must avoid absolute paths to ensure
consistent hashes across different compilations.
This function:
- resolves absolute requests into relative requests if the request and the module are on the same hard drive
- replaces `\` with `/` if the request and the module are on the same hard drive
- won't change the path at all if the request and the module are on different hard drives
- applies `JSON.stringify` to the result
```javascript
loaderUtils.stringifyRequest(this, "./test.js");
// "\"./test.js\""
loaderUtils.stringifyRequest(this, ".\\test.js");
// "\"./test.js\""
loaderUtils.stringifyRequest(this, "test");
// "\"test\""
loaderUtils.stringifyRequest(this, "test/lib/index.js");
// "\"test/lib/index.js\""
loaderUtils.stringifyRequest(this, "otherLoader?andConfig!test?someConfig");
// "\"otherLoader?andConfig!test?someConfig\""
loaderUtils.stringifyRequest(this, require.resolve("test"));
// "\"../node_modules/some-loader/lib/test.js\""
loaderUtils.stringifyRequest(this, "C:\\module\\test.js");
// "\"../../test.js\"" (on Windows, in case the module and the request are on the same drive)
loaderUtils.stringifyRequest(this, "C:\\module\\test.js");
// "\"C:\\module\\test.js\"" (on Windows, in case the module and the request are on different drives)
loaderUtils.stringifyRequest(this, "\\\\network-drive\\test.js");
// "\"\\\\network-drive\\\\test.js\"" (on Windows, in case the module and the request are on different drives)
```
### `urlToRequest`
Converts some resource URL to a webpack module request.
> i Before call `urlToRequest` you need call `isUrlRequest` to ensure it is requestable url
```javascript
const url = "path/to/module.js";
if (loaderUtils.isUrlRequest(url)) {
// Logic for requestable url
const request = loaderUtils.urlToRequest(url);
} else {
// Logic for not requestable url
}
```
Simple example:
```javascript
const url = "path/to/module.js";
const request = loaderUtils.urlToRequest(url); // "./path/to/module.js"
```
#### Module URLs
Any URL containing a `~` will be interpreted as a module request. Anything after the `~` will be considered the request path.
```javascript
const url = "~path/to/module.js";
const request = loaderUtils.urlToRequest(url); // "path/to/module.js"
```
#### Root-relative URLs
URLs that are root-relative (start with `/`) can be resolved relative to some arbitrary path by using the `root` parameter:
```javascript
const url = "/path/to/module.js";
const root = "./root";
const request = loaderUtils.urlToRequest(url, root); // "./root/path/to/module.js"
```
To convert a root-relative URL into a module URL, specify a `root` value that starts with `~`:
```javascript
const url = "/path/to/module.js";
const root = "~";
const request = loaderUtils.urlToRequest(url, root); // "path/to/module.js"
```
### `interpolateName`
Interpolates a filename template using multiple placeholders and/or a regular expression.
The template and regular expression are set as query params called `name` and `regExp` on the current loader's context.
```javascript
const interpolatedName = loaderUtils.interpolateName(loaderContext, name, options);
```
The following tokens are replaced in the `name` parameter:
* `[ext]` the extension of the resource
* `[name]` the basename of the resource
* `[path]` the path of the resource relative to the `context` query parameter or option.
* `[folder]` the folder the resource is in
* `[query]` the queryof the resource, i.e. `?foo=bar`
* `[emoji]` a random emoji representation of `options.content`
* `[emoji:<length>]` same as above, but with a customizable number of emojis
* `[contenthash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md4 hash)
* `[<hashType>:contenthash:<digestType>:<length>]` optionally one can configure
* other `hashType`s, i. e. `sha1`, `md4`, `md5`, `sha256`, `sha512`
* other `digestType`s, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
* and `length` the length in chars
* `[hash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md4 hash)
* `[<hashType>:hash:<digestType>:<length>]` optionally one can configure
* other `hashType`s, i. e. `sha1`, `md4`, `md5`, `sha256`, `sha512`
* other `digestType`s, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
* and `length` the length in chars
* `[N]` the N-th match obtained from matching the current file name against `options.regExp`
In loader context `[hash]` and `[contenthash]` are the same, but we recommend using `[contenthash]` for avoid misleading.
Examples
``` javascript
// loaderContext.resourcePath = "/absolute/path/to/app/js/javascript.js"
loaderUtils.interpolateName(loaderContext, "js/[hash].script.[ext]", { content: ... });
// => js/9473fdd0d880a43c21b7778d34872157.script.js
// loaderContext.resourcePath = "/absolute/path/to/app/js/javascript.js"
// loaderContext.resourceQuery = "?foo=bar"
loaderUtils.interpolateName(loaderContext, "js/[hash].script.[ext][query]", { content: ... });
// => js/9473fdd0d880a43c21b7778d34872157.script.js?foo=bar
// loaderContext.resourcePath = "/absolute/path/to/app/js/javascript.js"
loaderUtils.interpolateName(loaderContext, "js/[contenthash].script.[ext]", { content: ... });
// => js/9473fdd0d880a43c21b7778d34872157.script.js
// loaderContext.resourcePath = "/absolute/path/to/app/page.html"
loaderUtils.interpolateName(loaderContext, "html-[hash:6].html", { content: ... });
// => html-9473fd.html
// loaderContext.resourcePath = "/absolute/path/to/app/flash.txt"
loaderUtils.interpolateName(loaderContext, "[hash]", { content: ... });
// => c31e9820c001c9c4a86bce33ce43b679
// loaderContext.resourcePath = "/absolute/path/to/app/img/image.gif"
loaderUtils.interpolateName(loaderContext, "[emoji]", { content: ... });
// => 👍
// loaderContext.resourcePath = "/absolute/path/to/app/img/image.gif"
loaderUtils.interpolateName(loaderContext, "[emoji:4]", { content: ... });
// => 🙍🏢📤🐝
// loaderContext.resourcePath = "/absolute/path/to/app/img/image.png"
loaderUtils.interpolateName(loaderContext, "[sha512:hash:base64:7].[ext]", { content: ... });
// => 2BKDTjl.png
// use sha512 hash instead of md4 and with only 7 chars of base64
// loaderContext.resourcePath = "/absolute/path/to/app/img/myself.png"
// loaderContext.query.name =
loaderUtils.interpolateName(loaderContext, "picture.png");
// => picture.png
// loaderContext.resourcePath = "/absolute/path/to/app/dir/file.png"
loaderUtils.interpolateName(loaderContext, "[path][name].[ext]?[hash]", { content: ... });
// => /app/dir/file.png?9473fdd0d880a43c21b7778d34872157
// loaderContext.resourcePath = "/absolute/path/to/app/js/page-home.js"
loaderUtils.interpolateName(loaderContext, "script-[1].[ext]", { regExp: "page-(.*)\\.js", content: ... });
// => script-home.js
// loaderContext.resourcePath = "/absolute/path/to/app/js/javascript.js"
// loaderContext.resourceQuery = "?foo=bar"
loaderUtils.interpolateName(
loaderContext,
(resourcePath, resourceQuery) => {
// resourcePath - `/app/js/javascript.js`
// resourceQuery - `?foo=bar`
return "js/[hash].script.[ext]";
},
{ content: ... }
);
// => js/9473fdd0d880a43c21b7778d34872157.script.js
```
### `getHashDigest`
``` javascript
const digestString = loaderUtils.getHashDigest(buffer, hashType, digestType, maxLength);
```
* `buffer` the content that should be hashed
* `hashType` one of `sha1`, `md4`, `md5`, `sha256`, `sha512` or any other node.js supported hash type
* `digestType` one of `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
* `maxLength` the maximum length in chars
## License
MIT (http://www.opensource.org/licenses/mit-license.php)
@@ -0,0 +1,16 @@
'use strict';
function getCurrentRequest(loaderContext) {
if (loaderContext.currentRequest) {
return loaderContext.currentRequest;
}
const request = loaderContext.loaders
.slice(loaderContext.loaderIndex)
.map((obj) => obj.request)
.concat([loaderContext.resource]);
return request.join('!');
}
module.exports = getCurrentRequest;
+91
View File
@@ -0,0 +1,91 @@
'use strict';
const baseEncodeTables = {
26: 'abcdefghijklmnopqrstuvwxyz',
32: '123456789abcdefghjkmnpqrstuvwxyz', // no 0lio
36: '0123456789abcdefghijklmnopqrstuvwxyz',
49: 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', // no lIO
52: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
58: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', // no 0lIO
62: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
64: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
};
function encodeBufferToBase(buffer, base) {
const encodeTable = baseEncodeTables[base];
if (!encodeTable) {
throw new Error('Unknown encoding base' + base);
}
const readLength = buffer.length;
const Big = require('big.js');
Big.RM = Big.DP = 0;
let b = new Big(0);
for (let i = readLength - 1; i >= 0; i--) {
b = b.times(256).plus(buffer[i]);
}
let output = '';
while (b.gt(0)) {
output = encodeTable[b.mod(base)] + output;
b = b.div(base);
}
Big.DP = 20;
Big.RM = 1;
return output;
}
let createMd4 = undefined;
let BatchedHash = undefined;
function getHashDigest(buffer, hashType, digestType, maxLength) {
hashType = hashType || 'md4';
maxLength = maxLength || 9999;
let hash;
try {
hash = require('crypto').createHash(hashType);
} catch (error) {
if (error.code === 'ERR_OSSL_EVP_UNSUPPORTED' && hashType === 'md4') {
if (createMd4 === undefined) {
createMd4 = require('./hash/md4');
if (BatchedHash === undefined) {
BatchedHash = require('./hash/BatchedHash');
}
}
hash = new BatchedHash(createMd4());
}
if (!hash) {
throw error;
}
}
hash.update(buffer);
if (
digestType === 'base26' ||
digestType === 'base32' ||
digestType === 'base36' ||
digestType === 'base49' ||
digestType === 'base52' ||
digestType === 'base58' ||
digestType === 'base62'
) {
return encodeBufferToBase(hash.digest(), digestType.substr(4)).substr(
0,
maxLength
);
} else {
return hash.digest(digestType || 'hex').substr(0, maxLength);
}
}
module.exports = getHashDigest;
+20
View File
@@ -0,0 +1,20 @@
'use strict';
const parseQuery = require('./parseQuery');
function getOptions(loaderContext) {
const query = loaderContext.query;
if (typeof query === 'string' && query !== '') {
return parseQuery(loaderContext.query);
}
if (!query || typeof query !== 'object') {
// Not object-like queries are not supported.
return {};
}
return query;
}
module.exports = getOptions;
@@ -0,0 +1,16 @@
'use strict';
function getRemainingRequest(loaderContext) {
if (loaderContext.remainingRequest) {
return loaderContext.remainingRequest;
}
const request = loaderContext.loaders
.slice(loaderContext.loaderIndex + 1)
.map((obj) => obj.request)
.concat([loaderContext.resource]);
return request.join('!');
}
module.exports = getRemainingRequest;
@@ -0,0 +1,64 @@
const MAX_SHORT_STRING = require('./wasm-hash').MAX_SHORT_STRING;
class BatchedHash {
constructor(hash) {
this.string = undefined;
this.encoding = undefined;
this.hash = hash;
}
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @param {string|Buffer} data data
* @param {string=} inputEncoding data encoding
* @returns {this} updated hash
*/
update(data, inputEncoding) {
if (this.string !== undefined) {
if (
typeof data === 'string' &&
inputEncoding === this.encoding &&
this.string.length + data.length < MAX_SHORT_STRING
) {
this.string += data;
return this;
}
this.hash.update(this.string, this.encoding);
this.string = undefined;
}
if (typeof data === 'string') {
if (
data.length < MAX_SHORT_STRING &&
// base64 encoding is not valid since it may contain padding chars
(!inputEncoding || !inputEncoding.startsWith('ba'))
) {
this.string = data;
this.encoding = inputEncoding;
} else {
this.hash.update(data, inputEncoding);
}
} else {
this.hash.update(data);
}
return this;
}
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @param {string=} encoding encoding of the return value
* @returns {string|Buffer} digest
*/
digest(encoding) {
if (this.string !== undefined) {
this.hash.update(this.string, this.encoding);
}
return this.hash.digest(encoding);
}
}
module.exports = BatchedHash;
+20
View File
@@ -0,0 +1,20 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
'use strict';
const create = require('./wasm-hash');
//#region wasm code: md4 (../../../assembly/hash/md4.asm.ts) --initialMemory 1
const md4 = new WebAssembly.Module(
Buffer.from(
// 2150 bytes
'AGFzbQEAAAABCAJgAX8AYAAAAwUEAQAAAAUDAQABBhoFfwFBAAt/AUEAC38BQQALfwFBAAt/AUEACwciBARpbml0AAAGdXBkYXRlAAIFZmluYWwAAwZtZW1vcnkCAAqFEAQmAEGBxpS6BiQBQYnXtv5+JAJB/rnrxXkkA0H2qMmBASQEQQAkAAvMCgEYfyMBIQojAiEGIwMhByMEIQgDQCAAIAVLBEAgBSgCCCINIAcgBiAFKAIEIgsgCCAHIAUoAgAiDCAKIAggBiAHIAhzcXNqakEDdyIDIAYgB3Nxc2pqQQd3IgEgAyAGc3FzampBC3chAiAFKAIUIg8gASACIAUoAhAiCSADIAEgBSgCDCIOIAYgAyACIAEgA3Nxc2pqQRN3IgQgASACc3FzampBA3ciAyACIARzcXNqakEHdyEBIAUoAiAiEiADIAEgBSgCHCIRIAQgAyAFKAIYIhAgAiAEIAEgAyAEc3FzampBC3ciAiABIANzcXNqakETdyIEIAEgAnNxc2pqQQN3IQMgBSgCLCIVIAQgAyAFKAIoIhQgAiAEIAUoAiQiEyABIAIgAyACIARzcXNqakEHdyIBIAMgBHNxc2pqQQt3IgIgASADc3FzampBE3chBCAPIBAgCSAVIBQgEyAFKAI4IhYgAiAEIAUoAjQiFyABIAIgBSgCMCIYIAMgASAEIAEgAnNxc2pqQQN3IgEgAiAEc3FzampBB3ciAiABIARzcXNqakELdyIDIAkgAiAMIAEgBSgCPCIJIAQgASADIAEgAnNxc2pqQRN3IgEgAiADcnEgAiADcXJqakGZ84nUBWpBA3ciAiABIANycSABIANxcmpqQZnzidQFakEFdyIEIAEgAnJxIAEgAnFyaiASakGZ84nUBWpBCXciAyAPIAQgCyACIBggASADIAIgBHJxIAIgBHFyampBmfOJ1AVqQQ13IgEgAyAEcnEgAyAEcXJqakGZ84nUBWpBA3ciAiABIANycSABIANxcmpqQZnzidQFakEFdyIEIAEgAnJxIAEgAnFyampBmfOJ1AVqQQl3IgMgECAEIAIgFyABIAMgAiAEcnEgAiAEcXJqakGZ84nUBWpBDXciASADIARycSADIARxcmogDWpBmfOJ1AVqQQN3IgIgASADcnEgASADcXJqakGZ84nUBWpBBXciBCABIAJycSABIAJxcmpqQZnzidQFakEJdyIDIBEgBCAOIAIgFiABIAMgAiAEcnEgAiAEcXJqakGZ84nUBWpBDXciASADIARycSADIARxcmpqQZnzidQFakEDdyICIAEgA3JxIAEgA3FyampBmfOJ1AVqQQV3IgQgASACcnEgASACcXJqakGZ84nUBWpBCXciAyAMIAIgAyAJIAEgAyACIARycSACIARxcmpqQZnzidQFakENdyIBcyAEc2pqQaHX5/YGakEDdyICIAQgASACcyADc2ogEmpBodfn9gZqQQl3IgRzIAFzampBodfn9gZqQQt3IgMgAiADIBggASADIARzIAJzampBodfn9gZqQQ93IgFzIARzaiANakGh1+f2BmpBA3ciAiAUIAQgASACcyADc2pqQaHX5/YGakEJdyIEcyABc2pqQaHX5/YGakELdyIDIAsgAiADIBYgASADIARzIAJzampBodfn9gZqQQ93IgFzIARzampBodfn9gZqQQN3IgIgEyAEIAEgAnMgA3NqakGh1+f2BmpBCXciBHMgAXNqakGh1+f2BmpBC3chAyAKIA4gAiADIBcgASADIARzIAJzampBodfn9gZqQQ93IgFzIARzampBodfn9gZqQQN3IgJqIQogBiAJIAEgESADIAIgFSAEIAEgAnMgA3NqakGh1+f2BmpBCXciBHMgAXNqakGh1+f2BmpBC3ciAyAEcyACc2pqQaHX5/YGakEPd2ohBiADIAdqIQcgBCAIaiEIIAVBQGshBQwBCwsgCiQBIAYkAiAHJAMgCCQECw0AIAAQASMAIABqJAAL/wQCA38BfiMAIABqrUIDhiEEIABByABqQUBxIgJBCGshAyAAIgFBAWohACABQYABOgAAA0AgACACSUEAIABBB3EbBEAgAEEAOgAAIABBAWohAAwBCwsDQCAAIAJJBEAgAEIANwMAIABBCGohAAwBCwsgAyAENwMAIAIQAUEAIwGtIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEIIwKtIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEQIwOtIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEYIwStIgRC//8DgyAEQoCA/P8Pg0IQhoQiBEL/gYCA8B+DIARCgP6DgIDgP4NCCIaEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAAs=',
'base64'
)
);
//#endregion
module.exports = create.bind(null, md4, [], 64, 32);
+208
View File
@@ -0,0 +1,208 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
'use strict';
// 65536 is the size of a wasm memory page
// 64 is the maximum chunk size for every possible wasm hash implementation
// 4 is the maximum number of bytes per char for string encoding (max is utf-8)
// ~3 makes sure that it's always a block of 4 chars, so avoid partially encoded bytes for base64
const MAX_SHORT_STRING = Math.floor((65536 - 64) / 4) & ~3;
class WasmHash {
/**
* @param {WebAssembly.Instance} instance wasm instance
* @param {WebAssembly.Instance[]} instancesPool pool of instances
* @param {number} chunkSize size of data chunks passed to wasm
* @param {number} digestSize size of digest returned by wasm
*/
constructor(instance, instancesPool, chunkSize, digestSize) {
const exports = /** @type {any} */ (instance.exports);
exports.init();
this.exports = exports;
this.mem = Buffer.from(exports.memory.buffer, 0, 65536);
this.buffered = 0;
this.instancesPool = instancesPool;
this.chunkSize = chunkSize;
this.digestSize = digestSize;
}
reset() {
this.buffered = 0;
this.exports.init();
}
/**
* @param {Buffer | string} data data
* @param {BufferEncoding=} encoding encoding
* @returns {this} itself
*/
update(data, encoding) {
if (typeof data === 'string') {
while (data.length > MAX_SHORT_STRING) {
this._updateWithShortString(data.slice(0, MAX_SHORT_STRING), encoding);
data = data.slice(MAX_SHORT_STRING);
}
this._updateWithShortString(data, encoding);
return this;
}
this._updateWithBuffer(data);
return this;
}
/**
* @param {string} data data
* @param {BufferEncoding=} encoding encoding
* @returns {void}
*/
_updateWithShortString(data, encoding) {
const { exports, buffered, mem, chunkSize } = this;
let endPos;
if (data.length < 70) {
if (!encoding || encoding === 'utf-8' || encoding === 'utf8') {
endPos = buffered;
for (let i = 0; i < data.length; i++) {
const cc = data.charCodeAt(i);
if (cc < 0x80) {
mem[endPos++] = cc;
} else if (cc < 0x800) {
mem[endPos] = (cc >> 6) | 0xc0;
mem[endPos + 1] = (cc & 0x3f) | 0x80;
endPos += 2;
} else {
// bail-out for weird chars
endPos += mem.write(data.slice(i), endPos, encoding);
break;
}
}
} else if (encoding === 'latin1') {
endPos = buffered;
for (let i = 0; i < data.length; i++) {
const cc = data.charCodeAt(i);
mem[endPos++] = cc;
}
} else {
endPos = buffered + mem.write(data, buffered, encoding);
}
} else {
endPos = buffered + mem.write(data, buffered, encoding);
}
if (endPos < chunkSize) {
this.buffered = endPos;
} else {
const l = endPos & ~(this.chunkSize - 1);
exports.update(l);
const newBuffered = endPos - l;
this.buffered = newBuffered;
if (newBuffered > 0) {
mem.copyWithin(0, l, endPos);
}
}
}
/**
* @param {Buffer} data data
* @returns {void}
*/
_updateWithBuffer(data) {
const { exports, buffered, mem } = this;
const length = data.length;
if (buffered + length < this.chunkSize) {
data.copy(mem, buffered, 0, length);
this.buffered += length;
} else {
const l = (buffered + length) & ~(this.chunkSize - 1);
if (l > 65536) {
let i = 65536 - buffered;
data.copy(mem, buffered, 0, i);
exports.update(65536);
const stop = l - buffered - 65536;
while (i < stop) {
data.copy(mem, 0, i, i + 65536);
exports.update(65536);
i += 65536;
}
data.copy(mem, 0, i, l - buffered);
exports.update(l - buffered - i);
} else {
data.copy(mem, buffered, 0, l - buffered);
exports.update(l);
}
const newBuffered = length + buffered - l;
this.buffered = newBuffered;
if (newBuffered > 0) {
data.copy(mem, 0, length - newBuffered, length);
}
}
}
digest(type) {
const { exports, buffered, mem, digestSize } = this;
exports.final(buffered);
this.instancesPool.push(this);
const hex = mem.toString('latin1', 0, digestSize);
if (type === 'hex') {
return hex;
}
if (type === 'binary' || !type) {
return Buffer.from(hex, 'hex');
}
return Buffer.from(hex, 'hex').toString(type);
}
}
const create = (wasmModule, instancesPool, chunkSize, digestSize) => {
if (instancesPool.length > 0) {
const old = instancesPool.pop();
old.reset();
return old;
} else {
return new WasmHash(
new WebAssembly.Instance(wasmModule),
instancesPool,
chunkSize,
digestSize
);
}
};
module.exports = create;
module.exports.MAX_SHORT_STRING = MAX_SHORT_STRING;
+23
View File
@@ -0,0 +1,23 @@
'use strict';
const getOptions = require('./getOptions');
const parseQuery = require('./parseQuery');
const stringifyRequest = require('./stringifyRequest');
const getRemainingRequest = require('./getRemainingRequest');
const getCurrentRequest = require('./getCurrentRequest');
const isUrlRequest = require('./isUrlRequest');
const urlToRequest = require('./urlToRequest');
const parseString = require('./parseString');
const getHashDigest = require('./getHashDigest');
const interpolateName = require('./interpolateName');
exports.getOptions = getOptions;
exports.parseQuery = parseQuery;
exports.stringifyRequest = stringifyRequest;
exports.getRemainingRequest = getRemainingRequest;
exports.getCurrentRequest = getCurrentRequest;
exports.isUrlRequest = isUrlRequest;
exports.urlToRequest = urlToRequest;
exports.parseString = parseString;
exports.getHashDigest = getHashDigest;
exports.interpolateName = interpolateName;
@@ -0,0 +1,151 @@
'use strict';
const path = require('path');
const emojisList = require('emojis-list');
const getHashDigest = require('./getHashDigest');
const emojiRegex = /[\uD800-\uDFFF]./;
const emojiList = emojisList.filter((emoji) => emojiRegex.test(emoji));
const emojiCache = {};
function encodeStringToEmoji(content, length) {
if (emojiCache[content]) {
return emojiCache[content];
}
length = length || 1;
const emojis = [];
do {
if (!emojiList.length) {
throw new Error('Ran out of emoji');
}
const index = Math.floor(Math.random() * emojiList.length);
emojis.push(emojiList[index]);
emojiList.splice(index, 1);
} while (--length > 0);
const emojiEncoding = emojis.join('');
emojiCache[content] = emojiEncoding;
return emojiEncoding;
}
function interpolateName(loaderContext, name, options) {
let filename;
const hasQuery =
loaderContext.resourceQuery && loaderContext.resourceQuery.length > 1;
if (typeof name === 'function') {
filename = name(
loaderContext.resourcePath,
hasQuery ? loaderContext.resourceQuery : undefined
);
} else {
filename = name || '[hash].[ext]';
}
const context = options.context;
const content = options.content;
const regExp = options.regExp;
let ext = 'bin';
let basename = 'file';
let directory = '';
let folder = '';
let query = '';
if (loaderContext.resourcePath) {
const parsed = path.parse(loaderContext.resourcePath);
let resourcePath = loaderContext.resourcePath;
if (parsed.ext) {
ext = parsed.ext.substr(1);
}
if (parsed.dir) {
basename = parsed.name;
resourcePath = parsed.dir + path.sep;
}
if (typeof context !== 'undefined') {
directory = path
.relative(context, resourcePath + '_')
.replace(/\\/g, '/')
.replace(/\.\.(\/)?/g, '_$1');
directory = directory.substr(0, directory.length - 1);
} else {
directory = resourcePath.replace(/\\/g, '/').replace(/\.\.(\/)?/g, '_$1');
}
if (directory.length === 1) {
directory = '';
} else if (directory.length > 1) {
folder = path.basename(directory);
}
}
if (loaderContext.resourceQuery && loaderContext.resourceQuery.length > 1) {
query = loaderContext.resourceQuery;
const hashIdx = query.indexOf('#');
if (hashIdx >= 0) {
query = query.substr(0, hashIdx);
}
}
let url = filename;
if (content) {
// Match hash template
url = url
// `hash` and `contenthash` are same in `loader-utils` context
// let's keep `hash` for backward compatibility
.replace(
/\[(?:([^:\]]+):)?(?:hash|contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi,
(all, hashType, digestType, maxLength) =>
getHashDigest(content, hashType, digestType, parseInt(maxLength, 10))
)
.replace(/\[emoji(?::(\d+))?\]/gi, (all, length) =>
encodeStringToEmoji(content, parseInt(length, 10))
);
}
url = url
.replace(/\[ext\]/gi, () => ext)
.replace(/\[name\]/gi, () => basename)
.replace(/\[path\]/gi, () => directory)
.replace(/\[folder\]/gi, () => folder)
.replace(/\[query\]/gi, () => query);
if (regExp && loaderContext.resourcePath) {
const match = loaderContext.resourcePath.match(new RegExp(regExp));
match &&
match.forEach((matched, i) => {
url = url.replace(new RegExp('\\[' + i + '\\]', 'ig'), matched);
});
}
if (
typeof loaderContext.options === 'object' &&
typeof loaderContext.options.customInterpolateName === 'function'
) {
url = loaderContext.options.customInterpolateName.call(
loaderContext,
url,
name,
options
);
}
return url;
}
module.exports = interpolateName;
+31
View File
@@ -0,0 +1,31 @@
'use strict';
const path = require('path');
function isUrlRequest(url, root) {
// An URL is not an request if
// 1. It's an absolute url and it is not `windows` path like `C:\dir\file`
if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !path.win32.isAbsolute(url)) {
return false;
}
// 2. It's a protocol-relative
if (/^\/\//.test(url)) {
return false;
}
// 3. It's some kind of url for a template
if (/^[{}[\]#*;,'§$%&(=?`´^°<>]/.test(url)) {
return false;
}
// 4. It's also not an request if root isn't set and it's a root-relative url
if ((root === undefined || root === false) && /^\//.test(url)) {
return false;
}
return true;
}
module.exports = isUrlRequest;
+69
View File
@@ -0,0 +1,69 @@
'use strict';
const JSON5 = require('json5');
const specialValues = {
null: null,
true: true,
false: false,
};
function parseQuery(query) {
if (query.substr(0, 1) !== '?') {
throw new Error(
"A valid query string passed to parseQuery should begin with '?'"
);
}
query = query.substr(1);
if (!query) {
return {};
}
if (query.substr(0, 1) === '{' && query.substr(-1) === '}') {
return JSON5.parse(query);
}
const queryArgs = query.split(/[,&]/g);
const result = {};
queryArgs.forEach((arg) => {
const idx = arg.indexOf('=');
if (idx >= 0) {
let name = arg.substr(0, idx);
let value = decodeURIComponent(arg.substr(idx + 1));
// eslint-disable-next-line no-prototype-builtins
if (specialValues.hasOwnProperty(value)) {
value = specialValues[value];
}
if (name.substr(-2) === '[]') {
name = decodeURIComponent(name.substr(0, name.length - 2));
if (!Array.isArray(result[name])) {
result[name] = [];
}
result[name].push(value);
} else {
name = decodeURIComponent(name);
result[name] = value;
}
} else {
if (arg.substr(0, 1) === '-') {
result[decodeURIComponent(arg.substr(1))] = false;
} else if (arg.substr(0, 1) === '+') {
result[decodeURIComponent(arg.substr(1))] = true;
} else {
result[decodeURIComponent(arg)] = true;
}
}
});
return result;
}
module.exports = parseQuery;
+23
View File
@@ -0,0 +1,23 @@
'use strict';
function parseString(str) {
try {
if (str[0] === '"') {
return JSON.parse(str);
}
if (str[0] === "'" && str.substr(str.length - 1) === "'") {
return parseString(
str
.replace(/\\.|"/g, (x) => (x === '"' ? '\\"' : x))
.replace(/^'|'$/g, '"')
);
}
return JSON.parse('"' + str + '"');
} catch (e) {
return str;
}
}
module.exports = parseString;
@@ -0,0 +1,51 @@
'use strict';
const path = require('path');
const matchRelativePath = /^\.\.?[/\\]/;
function isAbsolutePath(str) {
return path.posix.isAbsolute(str) || path.win32.isAbsolute(str);
}
function isRelativePath(str) {
return matchRelativePath.test(str);
}
function stringifyRequest(loaderContext, request) {
const splitted = request.split('!');
const context =
loaderContext.context ||
(loaderContext.options && loaderContext.options.context);
return JSON.stringify(
splitted
.map((part) => {
// First, separate singlePath from query, because the query might contain paths again
const splittedPart = part.match(/^(.*?)(\?.*)/);
const query = splittedPart ? splittedPart[2] : '';
let singlePath = splittedPart ? splittedPart[1] : part;
if (isAbsolutePath(singlePath) && context) {
singlePath = path.relative(context, singlePath);
if (isAbsolutePath(singlePath)) {
// If singlePath still matches an absolute path, singlePath was on a different drive than context.
// In this case, we leave the path platform-specific without replacing any separators.
// @see https://github.com/webpack/loader-utils/pull/14
return singlePath + query;
}
if (isRelativePath(singlePath) === false) {
// Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules).
singlePath = './' + singlePath;
}
}
return singlePath.replace(/\\/g, '/') + query;
})
.join('!')
);
}
module.exports = stringifyRequest;
+60
View File
@@ -0,0 +1,60 @@
'use strict';
// we can't use path.win32.isAbsolute because it also matches paths starting with a forward slash
const matchNativeWin32Path = /^[A-Z]:[/\\]|^\\\\/i;
function urlToRequest(url, root) {
// Do not rewrite an empty url
if (url === '') {
return '';
}
const moduleRequestRegex = /^[^?]*~/;
let request;
if (matchNativeWin32Path.test(url)) {
// absolute windows path, keep it
request = url;
} else if (root !== undefined && root !== false && /^\//.test(url)) {
// if root is set and the url is root-relative
switch (typeof root) {
// 1. root is a string: root is prefixed to the url
case 'string':
// special case: `~` roots convert to module request
if (moduleRequestRegex.test(root)) {
request = root.replace(/([^~/])$/, '$1/') + url.slice(1);
} else {
request = root + url;
}
break;
// 2. root is `true`: absolute paths are allowed
// *nix only, windows-style absolute paths are always allowed as they doesn't start with a `/`
case 'boolean':
request = url;
break;
default:
throw new Error(
"Unexpected parameters to loader-utils 'urlToRequest': url = " +
url +
', root = ' +
root +
'.'
);
}
} else if (/^\.\.?\//.test(url)) {
// A relative url stays
request = url;
} else {
// every other url is threaded like a relative url
request = './' + url;
}
// A `~` makes the url an module
if (moduleRequestRegex.test(request)) {
request = request.replace(moduleRequestRegex, '');
}
return request;
}
module.exports = urlToRequest;
+73
View File
@@ -0,0 +1,73 @@
{
"_args": [
[
"loader-utils@2.0.2",
"/home/node/nuxt"
]
],
"_from": "loader-utils@2.0.2",
"_id": "loader-utils@2.0.2",
"_inBundle": false,
"_integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"_location": "/css-loader/loader-utils",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "loader-utils@2.0.2",
"name": "loader-utils",
"escapedName": "loader-utils",
"rawSpec": "2.0.2",
"saveSpec": null,
"fetchSpec": "2.0.2"
},
"_requiredBy": [
"/css-loader"
],
"_resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"_spec": "2.0.2",
"_where": "/home/node/nuxt",
"author": {
"name": "Tobias Koppers @sokra"
},
"bugs": {
"url": "https://github.com/webpack/loader-utils/issues"
},
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"description": "utils for webpack loaders",
"devDependencies": {
"coveralls": "^3.0.9",
"eslint": "^6.8.0",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^3.1.2",
"jest": "^25.1.0",
"prettier": "^1.19.1",
"standard-version": "^7.1.0"
},
"engines": {
"node": ">=8.9.0"
},
"files": [
"lib"
],
"homepage": "https://github.com/webpack/loader-utils#readme",
"license": "MIT",
"main": "lib/index.js",
"name": "loader-utils",
"repository": {
"type": "git",
"url": "git+https://github.com/webpack/loader-utils.git"
},
"scripts": {
"lint": "eslint lib test",
"pretest": "yarn lint",
"release": "yarn test && standard-version",
"test": "jest",
"test:ci": "jest --coverage"
},
"version": "2.0.2"
}
+286
View File
@@ -0,0 +1,286 @@
# 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.
### [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.
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+276
View File
@@ -0,0 +1,276 @@
<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
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
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
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
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 validateOptions from 'schema-utils';
import schema from 'path/to/schema.json';
function loader(src, map) {
const options = getOptions(this) || {};
validateOptions(schema, options, {
name: 'Loader Name',
baseDataPath: 'options',
});
// Code...
}
export default loader;
```
### `Plugin`
```js
import validateOptions from 'schema-utils';
import schema from 'path/to/schema.json';
class Plugin {
constructor(options) {
validateOptions(schema, options, {
name: 'Plugin Name',
baseDataPath: 'options',
});
this.options = options;
}
apply(compiler) {
// Code...
}
}
export default Plugin;
```
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack/schema-utils.svg
[deps-url]: https://david-dm.org/webpack/schema-utils
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
[tests-url]: https://github.com/webpack/schema-utils/actions
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/schema-utils
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.com/badge?p=schema-utils
[size-url]: https://packagephobia.com/result?p=schema-utils
@@ -0,0 +1,88 @@
export default ValidationError;
export type JSONSchema6 = import('json-schema').JSONSchema6;
export type JSONSchema7 = import('json-schema').JSONSchema7;
export type Schema =
| (import('json-schema').JSONSchema4 & import('./validate').Extend)
| (import('json-schema').JSONSchema6 & import('./validate').Extend)
| (import('json-schema').JSONSchema7 & import('./validate').Extend);
export type ValidationErrorConfiguration = {
name?: string | undefined;
baseDataPath?: string | undefined;
postFormatter?: import('./validate').PostFormatter | undefined;
};
export type PostFormatter = (
formattedError: string,
error: import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
}
) => string;
export type SchemaUtilErrorObject = import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
};
export type SPECIFICITY = number;
declare class ValidationError extends Error {
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @param {Schema} schema
* @param {ValidationErrorConfiguration} configuration
*/
constructor(
errors: Array<SchemaUtilErrorObject>,
schema: Schema,
configuration?: ValidationErrorConfiguration
);
/** @type {Array<SchemaUtilErrorObject>} */
errors: Array<SchemaUtilErrorObject>;
/** @type {Schema} */
schema: Schema;
/** @type {string} */
headerName: string;
/** @type {string} */
baseDataPath: string;
/** @type {PostFormatter | null} */
postFormatter: PostFormatter | null;
/**
* @param {string} path
* @returns {Schema}
*/
getSchemaPart(path: string): Schema;
/**
* @param {Schema} schema
* @param {boolean} logic
* @param {Array<Object>} prevSchemas
* @returns {string}
*/
formatSchema(
schema: Schema,
logic?: boolean,
prevSchemas?: Array<Object>
): string;
/**
* @param {Schema=} schemaPart
* @param {(boolean | Array<string>)=} additionalPath
* @param {boolean=} needDot
* @param {boolean=} logic
* @returns {string}
*/
getSchemaPartText(
schemaPart?: Schema | undefined,
additionalPath?: (boolean | Array<string>) | undefined,
needDot?: boolean | undefined,
logic?: boolean | undefined
): string;
/**
* @param {Schema=} schemaPart
* @returns {string}
*/
getSchemaPartDescription(schemaPart?: Schema | undefined): string;
/**
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
formatValidationError(error: SchemaUtilErrorObject): string;
/**
* @param {Array<SchemaUtilErrorObject>} errors
* @returns {string}
*/
formatValidationErrors(errors: Array<SchemaUtilErrorObject>): string;
}
@@ -0,0 +1,2 @@
declare const _exports: typeof import('./validate').default;
export = _exports;
@@ -0,0 +1,12 @@
export default addAbsolutePathKeyword;
export type Ajv = import('ajv').Ajv;
export type ValidateFunction = import('ajv').ValidateFunction;
export type SchemaUtilErrorObject = import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
};
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
declare function addAbsolutePathKeyword(ajv: Ajv): Ajv;
@@ -0,0 +1,82 @@
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<[number, boolean]>,
logic: boolean
): [number, boolean];
/** @type {Array<RangeValue>} */
_left: Array<[number, boolean]>;
/** @type {Array<RangeValue>} */
_right: Array<[number, boolean]>;
/**
* @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: [number, boolean]) => boolean;
@@ -0,0 +1,6 @@
export function stringHints(schema: Schema, logic: boolean): string[];
export function numberHints(schema: Schema, logic: boolean): string[];
export type Schema =
| (import('json-schema').JSONSchema4 & import('../validate').Extend)
| (import('json-schema').JSONSchema6 & import('../validate').Extend)
| (import('json-schema').JSONSchema7 & import('../validate').Extend);
@@ -0,0 +1,43 @@
export default validate;
export type JSONSchema4 = import('json-schema').JSONSchema4;
export type JSONSchema6 = import('json-schema').JSONSchema6;
export type JSONSchema7 = import('json-schema').JSONSchema7;
export type ErrorObject = import('ajv').ErrorObject;
export type Extend = {
formatMinimum?: number | undefined;
formatMaximum?: number | undefined;
formatExclusiveMinimum?: boolean | undefined;
formatExclusiveMaximum?: boolean | undefined;
};
export type Schema =
| (import('json-schema').JSONSchema4 & Extend)
| (import('json-schema').JSONSchema6 & Extend)
| (import('json-schema').JSONSchema7 & Extend);
export type SchemaUtilErrorObject = import('ajv').ErrorObject & {
children?: import('ajv').ErrorObject[] | undefined;
};
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}
*/
declare function validate(
schema: Schema,
options: Array<object> | object,
configuration?: ValidationErrorConfiguration | undefined
): void;
declare namespace validate {
export { ValidationError };
export { ValidationError as ValidateError };
}
import ValidationError from './ValidationError';
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
"use strict";
const validate = require('./validate');
module.exports = validate.default;
@@ -0,0 +1,93 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/** @typedef {import("ajv").Ajv} Ajv */
/** @typedef {import("ajv").ValidateFunction} ValidateFunction */
/** @typedef {import("../validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
/**
* @param {string} message
* @param {object} schema
* @param {string} data
* @returns {SchemaUtilErrorObject}
*/
function errorMessage(message, schema, data) {
return {
// @ts-ignore
// eslint-disable-next-line no-undefined
dataPath: undefined,
// @ts-ignore
// eslint-disable-next-line no-undefined
schemaPath: undefined,
keyword: 'absolutePath',
params: {
absolutePath: data
},
message,
parentSchema: schema
};
}
/**
* @param {boolean} shouldBeAbsolute
* @param {object} schema
* @param {string} data
* @returns {SchemaUtilErrorObject}
*/
function getErrorFor(shouldBeAbsolute, schema, data) {
const message = shouldBeAbsolute ? `The provided value ${JSON.stringify(data)} is not an absolute path!` : `A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
return errorMessage(message, schema, data);
}
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
function addAbsolutePathKeyword(ajv) {
ajv.addKeyword('absolutePath', {
errors: true,
type: 'string',
compile(schema, parentSchema) {
/** @type {ValidateFunction} */
const callback = data => {
let passes = true;
const isExclamationMarkPresent = data.includes('!');
if (isExclamationMarkPresent) {
callback.errors = [errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`, parentSchema, data)];
passes = false;
} // ?:[A-Za-z]:\\ - Windows absolute path
// \\\\ - Windows network absolute path
// \/ - Unix-like OS absolute path
const isCorrectAbsolutePath = schema === /^(?:[A-Za-z]:(\\|\/)|\\\\|\/)/.test(data);
if (!isCorrectAbsolutePath) {
callback.errors = [getErrorFor(schema, parentSchema, data)];
passes = false;
}
return passes;
};
callback.errors = [];
return callback;
}
});
return ajv;
}
var _default = addAbsolutePathKeyword;
exports.default = _default;
+163
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;
+105
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;
};
+162
View File
@@ -0,0 +1,162 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Use CommonJS require for ajv libs so TypeScript consumers aren't locked into esModuleInterop (see #110).
const Ajv = require('ajv');
const ajvKeywords = require('ajv-keywords');
/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("ajv").ErrorObject} ErrorObject */
/**
* @typedef {Object} Extend
* @property {number=} formatMinimum
* @property {number=} formatMaximum
* @property {boolean=} formatExclusiveMinimum
* @property {boolean=} formatExclusiveMaximum
*/
/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend} Schema */
/** @typedef {ErrorObject & { children?: Array<ErrorObject>}} SchemaUtilErrorObject */
/**
* @callback PostFormatter
* @param {string} formattedError
* @param {SchemaUtilErrorObject} error
* @returns {string}
*/
/**
* @typedef {Object} ValidationErrorConfiguration
* @property {string=} name
* @property {string=} baseDataPath
* @property {PostFormatter=} postFormatter
*/
const ajv = new Ajv({
allErrors: true,
verbose: true,
$data: true
});
ajvKeywords(ajv, ['instanceof', 'formatMinimum', 'formatMaximum', 'patternRequired']); // Custom keywords
(0, _absolutePath.default)(ajv);
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @param {ValidationErrorConfiguration=} configuration
* @returns {void}
*/
function validate(schema, options, configuration) {
let errors = [];
if (Array.isArray(options)) {
errors = Array.from(options, nestedOptions => validateObject(schema, nestedOptions));
errors.forEach((list, idx) => {
const applyPrefix =
/**
* @param {SchemaUtilErrorObject} error
*/
error => {
// eslint-disable-next-line no-param-reassign
error.dataPath = `[${idx}]${error.dataPath}`;
if (error.children) {
error.children.forEach(applyPrefix);
}
};
list.forEach(applyPrefix);
});
errors = errors.reduce((arr, items) => {
arr.push(...items);
return arr;
}, []);
} else {
errors = validateObject(schema, options);
}
if (errors.length > 0) {
throw new _ValidationError.default(errors, schema, configuration);
}
}
/**
* @param {Schema} schema
* @param {Array<object> | object} options
* @returns {Array<SchemaUtilErrorObject>}
*/
function validateObject(schema, options) {
const compiledSchema = ajv.compile(schema);
const valid = compiledSchema(options);
if (valid) return [];
return compiledSchema.errors ? filterErrors(compiledSchema.errors) : [];
}
/**
* @param {Array<ErrorObject>} errors
* @returns {Array<SchemaUtilErrorObject>}
*/
function filterErrors(errors) {
/** @type {Array<SchemaUtilErrorObject>} */
let newErrors = [];
for (const error of
/** @type {Array<SchemaUtilErrorObject>} */
errors) {
const {
dataPath
} = error;
/** @type {Array<SchemaUtilErrorObject>} */
let children = [];
newErrors = newErrors.filter(oldError => {
if (oldError.dataPath.includes(dataPath)) {
if (oldError.children) {
children = children.concat(oldError.children.slice(0));
} // eslint-disable-next-line no-undefined, no-param-reassign
oldError.children = undefined;
children.push(oldError);
return false;
}
return true;
});
if (children.length) {
error.children = children;
}
newErrors.push(error);
}
return newErrors;
} // TODO change after resolve https://github.com/microsoft/TypeScript/issues/34994
validate.ValidationError = _ValidationError.default;
validate.ValidateError = _ValidationError.default;
var _default = validate;
exports.default = _default;
+112
View File
@@ -0,0 +1,112 @@
{
"_args": [
[
"schema-utils@2.7.1",
"/home/node/nuxt"
]
],
"_from": "schema-utils@2.7.1",
"_id": "schema-utils@2.7.1",
"_inBundle": false,
"_integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
"_location": "/css-loader/schema-utils",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "schema-utils@2.7.1",
"name": "schema-utils",
"escapedName": "schema-utils",
"rawSpec": "2.7.1",
"saveSpec": null,
"fetchSpec": "2.7.1"
},
"_requiredBy": [
"/css-loader"
],
"_resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
"_spec": "2.7.1",
"_where": "/home/node/nuxt",
"author": {
"name": "webpack Contrib",
"url": "https://github.com/webpack-contrib"
},
"bugs": {
"url": "https://github.com/webpack/schema-utils/issues"
},
"dependencies": {
"@types/json-schema": "^7.0.5",
"ajv": "^6.12.4",
"ajv-keywords": "^3.5.2"
},
"description": "webpack Validation Utils",
"devDependencies": {
"@babel/cli": "^7.10.5",
"@babel/core": "^7.11.4",
"@babel/preset-env": "^7.11.0",
"@commitlint/cli": "^10.0.0",
"@commitlint/config-conventional": "^10.0.0",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^25.5.1",
"cross-env": "^6.0.3",
"del": "^5.1.0",
"del-cli": "^3.0.1",
"eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.22.0",
"husky": "^4.2.5",
"jest": "^25.5.4",
"lint-staged": "^10.2.13",
"npm-run-all": "^4.1.5",
"prettier": "^1.19.1",
"standard-version": "^9.0.0",
"typescript": "^4.0.2"
},
"engines": {
"node": ">= 8.9.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",
"defaults": "webpack-defaults",
"lint": "npm-run-all -l -p \"lint:**\"",
"lint:js": "eslint --cache .",
"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css,ts}\" --list-different",
"lint:types": "tsc --pretty --noEmit",
"prebuild": "npm run clean",
"prepare": "npm run build",
"pretest": "npm run lint",
"release": "standard-version",
"security": "npm audit",
"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": "2.7.1"
}
+146
View File
@@ -0,0 +1,146 @@
{
"_args": [
[
"css-loader@4.3.0",
"/home/node/nuxt"
]
],
"_from": "css-loader@4.3.0",
"_id": "css-loader@4.3.0",
"_inBundle": false,
"_integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==",
"_location": "/css-loader",
"_phantomChildren": {
"@types/json-schema": "7.0.11",
"ajv": "6.12.6",
"ajv-keywords": "3.5.2",
"big.js": "5.2.2",
"emojis-list": "3.0.0",
"json5": "2.2.1"
},
"_requested": {
"type": "version",
"registry": true,
"raw": "css-loader@4.3.0",
"name": "css-loader",
"escapedName": "css-loader",
"rawSpec": "4.3.0",
"saveSpec": null,
"fetchSpec": "4.3.0"
},
"_requiredBy": [
"/@nuxt/webpack"
],
"_resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz",
"_spec": "4.3.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Tobias Koppers @sokra"
},
"bugs": {
"url": "https://github.com/webpack-contrib/css-loader/issues"
},
"dependencies": {
"camelcase": "^6.0.0",
"cssesc": "^3.0.0",
"icss-utils": "^4.1.1",
"loader-utils": "^2.0.0",
"postcss": "^7.0.32",
"postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^3.0.3",
"postcss-modules-scope": "^2.2.0",
"postcss-modules-values": "^3.0.0",
"postcss-value-parser": "^4.1.0",
"schema-utils": "^2.7.1",
"semver": "^7.3.2"
},
"description": "css loader module for webpack",
"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@commitlint/cli": "^11.0.0",
"@commitlint/config-conventional": "^11.0.0",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^26.1.0",
"cross-env": "^7.0.2",
"del": "^5.1.0",
"del-cli": "^3.0.1",
"es-check": "^5.1.0",
"eslint": "^7.8.1",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.22.0",
"file-loader": "^6.1.0",
"husky": "^4.3.0",
"jest": "^26.4.2",
"less": "^3.12.2",
"less-loader": "^7.0.1",
"lint-staged": "^10.3.0",
"memfs": "^3.2.0",
"mini-css-extract-plugin": "^0.11.0",
"npm-run-all": "^4.1.5",
"postcss-loader": "^4.0.0",
"postcss-preset-env": "^6.7.0",
"prettier": "^2.1.1",
"sass": "^1.26.10",
"sass-loader": "^10.0.2",
"standard-version": "^9.0.0",
"strip-ansi": "^6.0.0",
"style-loader": "^1.2.1",
"stylus": "^0.54.8",
"stylus-loader": "^3.0.2",
"url-loader": "^4.1.0",
"webpack": "^4.44.1"
},
"engines": {
"node": ">= 10.13.0"
},
"files": [
"dist"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"homepage": "https://github.com/webpack-contrib/css-loader",
"keywords": [
"webpack",
"css",
"loader",
"url",
"import"
],
"license": "MIT",
"main": "dist/cjs.js",
"name": "css-loader",
"peerDependencies": {
"webpack": "^4.27.0 || ^5.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/webpack-contrib/css-loader.git"
},
"scripts": {
"build": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"clean": "del-cli dist",
"commitlint": "commitlint --from=master",
"defaults": "webpack-defaults",
"lint": "npm-run-all -l -p \"lint:**\"",
"lint:js": "eslint --cache .",
"lint:prettier": "prettier --list-different .",
"postbuild": "npm run validate:runtime",
"prebuild": "npm run clean",
"prepare": "npm run build",
"pretest": "npm run lint",
"release": "standard-version",
"security": "npm audit",
"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",
"validate:runtime": "es-check es5 \"dist/runtime/**/*.js\""
},
"version": "4.3.0"
}