更新前端静态网页获取方式,放弃使用后端获取api

This commit is contained in:
2025-09-09 10:47:51 +08:00
parent 6889ca37e5
commit 44a4f1bae1
25558 changed files with 2463152 additions and 153 deletions

53
frontend/node_modules/resolve-url-loader/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,53 @@
# resolve-url-loader
## Version 4
**Features**
* Better resolution of the original source location - You can more successfully use `url()` in variables and mixins.
* Dependencies now accept a wider range and explicit dependency on `rework` and `rework-visit` has been removed.
**Breaking Changes**
* The `engine` option is deprecated which means the old `rework` engine is deprecated.
* The `keepQuery` behaviour is now the default, the `keepQuery` option has been removed.
* The `removeCR` option defaults to `true` when executing on Windows OS.
* The `absolute` option has been removed.
* The `join` option has changed.
**Migrating**
Remove the `engine` option if you are using it - the default "postcss" engine is much more reliable. The "rework" engine will still work for now but will be removed in the next major version.
Remove the `keepQuery` option if you are using it.
Remove the `absolute` option, webpack should work fine without it. If you have a specific need to rebase `url()` then you should use a separate loader.
If you use a custom `join` function then you will need to refactor it to the new API. Refer to the advanced usage documentation.
If you wish to still use `engine: "rework"` then note that `rework` and `rework-visit` packages are now `peerDependencies` that must be explicitly installed by you.
## Version 3
**Features**
* Use `postcss` parser by default. This is long overdue as the old `rework` parser doesn't cope with modern css.
* Lots of automated tests running actual webpack builds. If you have an interesting use-case let me know.
**Breaking Changes**
* Multiple options changed or deprecated.
* Removed file search "magic" in favour of `join` option.
* Errors always fail and are no longer swallowed.
* Processing absolute asset paths requires `root` option to be set.
**Migrating**
Initially set option `engine: 'rework'` for parity with your existing build. Once working you can remove this option **or** set `engine: 'postcss'` explicitly.
Retain `keepQuery` option if you are already using it.
The `root` option now has a different meaning. Previously it limited file search. Now it is the base path for absolute or root-relative URIs, consistent with `css-loader`. If you are already using it you can probably remove it.
If you build on Windows platform **and** your content contains absolute asset paths, then `css-loader` could fail. The `root` option here may fix the URIs before they get to `css-loader`. Try to leave it unspecified, otherwise (windows only) set to empty string `root: ''`.

21
frontend/node_modules/resolve-url-loader/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Ben Holloway
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.

140
frontend/node_modules/resolve-url-loader/README.md generated vendored Normal file
View File

@@ -0,0 +1,140 @@
# Resolve URL Loader
[![NPM](https://nodei.co/npm/resolve-url-loader.png)](https://www.npmjs.com/package/resolve-url-loader)
This **webpack loader** allows you to have a distributed set SCSS files and assets co-located with those SCSS files.
## Do you organise your SCSS and assets by feature?
Where are your assets?
* ✅ I want my assets all over the place, next to my SCSS files.
* ❌ My assets are in a single directory.
How complicated is your SASS?
* ✅ I have a deep SASS composition with partials importing other partials.
* ✅ My asset paths are constructed by functions or `@mixin`s.
* ❌ I have a single SCSS file. The asset paths are just explicit in that.
What asset paths are you using?
* ✅ Fully relative `url(./foo.png)` or `url(foo.png)`
* ❌ Root relative `url(/foo.png)`
* ❌ Relative to some package or webpack root `url(~stuff/foo.png`)
* ❌ Relative to some variable which is your single asset directory `url($variable/foo.png)`
What webpack errors are you getting?
* ✅ Webpack can't find the relative asset `foo.png` 😞
* ❌ Webpack says it doesn't have a loader for `fully/resolved/path/foo.png` 😕
If you can tick at least 1 item in **all of these questions** then use this loader. It will allow webpack to find assets with **fully relative paths**.
If for any question you can't tick _any_ items then webpack should be able to already find your assets. You don't need this loader. 🤷
Once webpack resolves your assets (even if it complains about loading them) then this loading is working correctly. 👍
## What's the problem with SASS?
When you use **fully relative paths** in `url()` statements then Webpack expects to find those assets next to the root SCSS file, regardless of where you specify the `url()`.
To illustrate here are 3 simple examples of SASS and Webpack _without_ `resolve-url-loader`.
[![the basic problem](https://raw.githubusercontent.com/bholloway/resolve-url-loader/v4-maintenance/packages/resolve-url-loader/docs/basic-problem.svg)](docs/basic-problem.svg)
The first 2 cases are trivial and work fine. The asset is specified in the root SCSS file and Webpack finds it.
But any practical SASS composition will have nested SCSS files, as in the 3rd case. Here Webpack cannot find the asset.
```
Module not found: Can't resolve './cool.png' in '/absolute/path/.../my-project/src/styles.scss'
```
The path we present to Webpack really needs to be `./subdir/cool.png` but we don't want to write that in our SCSS. 😒
Luckily we can use `resolve-url-loader` to do the **url re-writing** and make it work. 😊🎉
With functions and mixins and multiple nesting it gets more complicated. Read more detail in [how the loader works](docs/how-it-works.md). 🤓
## Getting started
> **Upgrading?** the [changelog](CHANGELOG.md) shows how to migrate your webpack config.
### Install
via npm
```bash
npm install resolve-url-loader --save-dev
```
via yarn
```bash
yarn add resolve-url-loader --dev
```
### Configure Webpack
The typical use case is `resolve-url-loader` between `sass-loader` and `css-loader`.
**⚠️ IMPORTANT**
* **source-maps required** for loaders preceding `resolve-url-loader` (regardless of `devtool`).
* Always use **full loader package name** (don't omit `-loader`) otherwise you can get errors that are hard to debug.
``` javascript
rules: [
{
test: /\.scss$/,
use: [
...
{
loader: 'css-loader',
options: {...}
}, {
loader: 'resolve-url-loader',
options: {...}
}, {
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false
}
}
]
},
...
]
```
## Options
The loader should work without options but use these as required.
| option | type | default | | description |
|-------------|----------------------------|-----------------------------------------|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `sourceMap` | boolean | `false` | | Generate an outgoing source-map. |
| `removeCR` | boolean | `true` Windows OS<br/>`false` otherwise | | Convert orphan CR to whitespace.<br/>See known issues below. |
| `debug` | boolean | `false` | | Display debug information. |
| `silent` | boolean | `false` | | Do **not** display warnings or deprecation messages. |
| `root` | string | _unset_ | | Similar to the (now defunct) option in `css-loader`.<br/>This string, possibly empty, is prepended to absolute URIs.<br/>Absolute URIs are only processed if this option is set. |
| `join` | function | _inbuilt_ | advanced | Custom join function.<br/>Use custom javascript to fix asset paths on a per-case basis.<br/>Refer to the [advanced features](docs/advanced-features.md) docs. |
| `engine` | `'rework'`<br/>`'postcss'` | `'postcss'` | deprecated | The css parser engine.<br/>Using this option produces a deprecation warning. |
## Limitations
### Compatiblity
Tested `macOS` and `Windows`.
All `webpack2`-`webpack4` with contemporaneous loaders/plugins using `node 8.9`. And `webpack5` with latest loaders/plugins using `node 10.0`.
Refer to `test` directory for full webpack configurations as used in automated tests.
Some edge cases with `libsass` on `Windows` (see [troubleshooting](docs/troubleshooting.md) docs).
### Known issues
Read the [troubleshooting](docs/troubleshooting.md) docs before raising an issue.

View File

@@ -0,0 +1,397 @@
# Advanced Features
All the advanced features of this loader involve customising the `join` option.
Jump to the **"how to"** section -
* [How to: change precedence of source locations](#how-to-change-precedence-of-source-locations)
* [How to: fallback to a theme or other global directory](#how-to-fallback-to-a-theme-or-other-global-directory)
* [How to: fallback to some other asset file](#how-to-fallback-to-some-other-asset-file)
* [How to: perform a file-system search for an asset](#how-to-perform-a-file-system-search-for-an-asset)
## What is the "join" function?
The "join" function determines how CSS URIs are combined with one of the possible base paths the algorithm has identified.
⚠️ **IMPORTANT** - First read how the [algorithm](./how-it-works.md#algorithm) works.
The "join" function is a higher-order function created using the `options` and `loader` reference. That gives a function that accepts a single `item` and synchronously returns an absolute asset path to substitute back into the original CSS.
```javascript
(options:{}, loader:{}) =>
(item:{ uri:string, query: string, isAbsolute: boolean, bases:{} }) =>
string | null
```
Where the `bases` are absolute directory paths `{ subString, value, property, selector }` per the [algorithm](./how-it-works.md#algorithm). Note that returning `null` implies no substitution, the original relative `uri` is retained.
The job of the "join" function is to consider possible locations for the asset based on the `bases` and determine which is most appropriate. This implies some order of precedence in these locations and some file-system operation to determine if the asset there.
The default implementation is suitable for most users but can be customised per the `join` option.
A custom `join` function from scratch is possible but we've provided some [building blocks](#building-blocks) to make the task easier.
## Building blocks
There are a number of utilities (defined in [`lib/join-function/index.js`](../lib/join-function/index.js)) to help construct a custom "join" function . These are conveniently re-exported as properties of the loader.
These utilities are used to create the `defaultJoin` as follows.
```javascript
const {
createJoinFunction,
createJoinImplementation,
defaultJoinGenerator,
} = require('resolve-url-loader');
// create a join function equivalent to "defaultJoin"
const myJoinFn = createJoinFunction(
'myJoinFn',
createJoinImplementation(defaultJoinGenerator),
});
```
🤓 If you have some very specific behaviour in mind you can specify your own implementation. This gives full control but still gives you `debug` logging for free.
```javascript
createJoinFunction = (name:string, implementation: function): function
```
For each item, the implementation needs to make multiple attempts at locating the asset. It has mixed concerns of itentifying locations to search and then evaluating those locates one by one.
👉 However its recommended to instead use `createJoinImplementation` to create the `implementation` using the `generator` concept.
```javascript
createJoinImplementation = (generator: function*): function
```
The `generator` has the single concern of identifying locations to search. The work of searching these locations is done by `createJoinImplementation`. Overall this means less boilerplate code for you to write.
Don't worry, you don't need to use `function*` semantics for the `generator` unless you want to.
## Simple customisation
It is relatively simple to change the precedence of values (from the [algorithm](./how-it-works.md#algorithm)) or add further locations to search for an asset. To do this we use `createJoinImplementation` and write a custom `generator`.
See the reference or jump directly to the [examples](#how-to-change-precedence-of-source-locations).
### Reference
The `generator` identifies `[base:string,uri:string]` tuples describing locations to search for an asset. It does **not** return the final asset path.
You may lazily generate tuples as `Iterator`. Refer to this [guide on Iterators and Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators).
```javascript
generator = function* (item: {}, options: {}, loader: {}): Iterator<[string,string]>
```
Or it can be simpler to write a function that returns `Array` and convert it to a generator using `asGenerator`.
```javascript
generator = asGenerator( function (item: {}, options: {}, loader: {}): Array<string> )
```
```javascript
generator = asGenerator( function (item: {}, options: {}, loader: {}): Array<[string,string]> )
```
When using `asGenerator` you may return elements as either `base:string` **or** `[base:string,uri:string]` tuples.
<details>
<summary>Arguments</summary>
* `item` consist of -
* `uri: string` is the argument to the `url()` as it appears in the source file.
* `query: string` is any query or hash string starting with `?` or `#` that suffixes the `uri`
* `isAbsolute: boolean` flag indicates whether the URI is considered an absolute file or root relative path by webpack's definition. Absolute URIs are only processed if the `root` option is specified.
* `bases: {}` are a hash where the keys are the sourcemap evaluation locations in the [algorithm](./how-it-works.md#algorithm) and the values are absolute paths that the sourcemap reports. These directories might not actually exist.
* `options` consist of -
* All documented options for the loader.
* Any other values you include in the loader configuration for your own purposes.
* `loader` consists of the webpack loader API, useful items include -
* `fs: {}` the virtual file-system from Webpack.
* `resourcePath: string` the source file currently being processed.
* returns an `Iterator` with elements of `[base:string,uri:string]` either intrinsically or by using `asGenerator`.
</details>
<details>
<summary>FAQ</summary>
* **Why a tuple?**
The primary pupose of this loader is to find the correct `base` path for your `uri`. By returning a list of paths to search we can better generate `debug` logging.
That said there are cases where you might want to amend the `uri`. The solution is to make each element a tuple of `base` and `uri` representing a potential location to find the asset.
If you're interested only in the `base` path and don't intend to vary the `uri` then the `asGenerator` utility saves you having to create repetative tuples (and from using `function*` semantics).
* **Can I vary the `query` using the tuple?**
No. We don't support amending the `query` in the final value. If you would like this enhancement please open an issue.
* **What about duplicate or falsey elements?**
The `createJoinImplementation` will eliminate any invalid elements regardless of whether you use `Array` or `Iterator`. This makes it possible to `&&` elements inline with a predicate value.
If you use `Array` then `asGenerator` will also remove duplicates.
* **When should I use `function*`?**
If you need lazy generation of values then you may return `Iterator` or use `function*` semantics. Refer to [this guide on Iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators).
But in most cases, when the values are known apriori, simply returning `Array` has simpler semantics making `asGenerator` preferable.
* **Why is this generator so complicated?**
The join function must make multiple attempts to join a `base` and `uri` and check that the file exists using webpack `fs`.
The `generator` is focussed on identifying locations to search. It is a more scalable concept where you wish to search many places. The traditional use case for the custom "join" function is a file-system search so the `generator` was designed to make this possible.
If you prefer a less abstract approach consider a full `implementation` per the [full customisation](#full-customisation) approach.
</details>
### How to: change precedence of source locations
Source-map sampling is limited to the locations defined in the [algorithm](./how-it-works.md#algorithm). You can't change these locations but you can preference them in a different order.
This example shows the default order which you can easily amend. Absolute URIs are rare in most projects but can be handled for completeness.
**Using `asGenerator`**
```javascript
const {
createJoinFunction,
createJoinImplementation,
asGenerator,
defaultJoinGenerator,
} = require('resolve-url-loader');
// order source-map sampling location by your preferred precedence (matches defaultJoinGenerator)
const myGenerator = asGenerator(
({ isAbsolute, bases: { substring, value, property, selector} }, { root }) =>
isAbsolute ? [root] : [subString, value, property, selector]
);
const myJoinFn = createJoinFunction(
'myJoinFn',
createJoinImplementation(myGenerator),
);
```
**Notes**
* The implementation is the default behaviour, so if you want this precedence do **not** customise the `join` option.
* Absolute URIs generally use the base path given in the `root` option as shown.
* The `asGenerator` utility allows us to return simple `Array<string>` of potential base paths.
### How to: fallback to a theme or other global directory
Additional locations can be added by decorating the default generator. This is popular for adding some sort of "theme" directory containing assets.
This example appends a static theme directory as a fallback location where the asset might reside. Absolute URIs are rare in most projects but can be handled for completeness.
**Using `asGenerator`**
```javascript
const path = require('path');
const {
createJoinFunction,
createJoinImplementation,
asGenerator,
defaultJoinGenerator,
} = require('resolve-url-loader');
const myThemeDirectory = path.resolve(...);
// call default generator then append any additional paths
const myGenerator = asGenerator(
(item, ...rest) => [
...defaultJoinGenerator(item, ...rest),
item.isAbsolute ? null : myThemeDirectory,
]
);
const myJoinFn = createJoinFunction(
'myJoinFn',
createJoinImplementation(myGenerator),
);
```
**Notes**
* By spreading the result of `defaultJoinGenerator` we are first trying the default behaviour. If that is unsuccessful we then try the theme location.
* It's assumed that theming doesn't apply to absolute URIs. Since falsey elements are ignored we can easily `null` the additional theme element inline as shown.
* The `asGenerator` utility allows us to return simple `Array<string>` of potential base paths.
### How to: fallback to some other asset file
Lets imagine we don't have high quality files for all our assets and must sometimes use a lower quality format. For each item we need to try the `uri` with different file extensions. We can do this by returning tuples of `[base:string,uri:string]`.
In this example we prefer the `.svg` asset we are happy to use any available `.png` or `.jpg` instead.
**Using `asGenerator`**
```javascript
const {
createJoinFunction,
createJoinImplementation,
asGenerator,
defaultJoinGenerator,
} = require('resolve-url-loader');
// call default generator then pair different variations of uri with each base
const myGenerator = asGenerator(
(item, ...rest) => {
const defaultTuples = [...defaultJoinGenerator(item, ...rest)];
return /\.svg$/.test(item.uri)
? ['.svg', '.png', 'jpg'].flatMap((ext) =>
defaultTuples.flatMap(([base, uri]) =>
[base, uri.replace(/\.svg$/, ext)]
})
)
: defaultTuples;
}
);
const myJoinFn = createJoinFunction(
'myJoinFn',
createJoinImplementation(myGenerator),
);
```
**Using `function*`**
```javascript
const {
createJoinFunction,
createJoinImplementation,
defaultJoinGenerator,
} = require('resolve-url-loader');
// call default generator then pair different variations of uri with each base
const myGenerator = function* (item, ...rest) {
if (/\.svg$/.test(item.uri)) {
for (let ext of ['.svg', '.png', 'jpg']) {
for (let [base, uri] of defaultJoinGenerator(item, ...rest)) {
yield [base, uri.replace(/\.svg$/, ext)];
}
}
} else {
for (let value of defaultJoinGenerator(item, ...rest)) {
yield value;
}
}
}
const myJoinFn = createJoinFunction(
'myJoinFn',
createJoinImplementation(myGenerator),
);
```
**Notes**
* Existing generators such as `defaultJoinGenerator` will always return `[string,string]` tuples so we can destruture `base` and `uri` values with confidence.
* This implementation attempts all extensions for a given `base` before moving to the next `base`. Obviously we may change the nesting and instead do the oposite, attempt all bases for a single extension before moving on to the next extension
* The `asGenerator` utility allows us to return `Array<[string, string]>` but is **not** needed when we use `function*` semantics.
### How to: perform a file-system search for an asset
⚠️ **IMPORTANT** - This example is indicative only and is **not** advised.
When this loader was originally released it was very common for packages be broken to the point that a full file search was needed to locate assets referred to in CSS. While this was not performant some users really liked it. By customising the `generator` we can once again lazily search the file-system.
In this example we search the parent directories of the base paths, continuing upwards until we hit a package boundary. Absolute URIs are rare in most projects but can be handled for completeness.
**Using `function*`**
```javascript
const path = require('path');
const {
createJoinFunction,
createJoinImplementation,
webpackExistsSync
} = require('resolve-url-loader');
// search up from the initial base path until you hit a package boundary
const myGenerator = function* (
{ uri, isAbsolute, bases: { substring, value, property, selector } },
{ root, attempts = 1e3 },
{ fs },
) {
if (isAbsolute) {
yield [root, uri];
} else {
for (let base of [subString, value, property, selector]) {
for (let isDone = false, i = 0; !isDone && i < attempts; i++) {
yield [base, uri];
// unfortunately fs.existsSync() is not present so we must shim it
const maybePkg = path.normalize(path.join(base, 'package.json'));
try {
isDone = fs.statSync(maybePkg).isFile();
} catch (error) {
isDone = false;
}
base = base.split(/(\\\/)/).slice(0, -2).join('');
}
}
}
};
const myJoinFn = createJoinFunction(
'myJoinFn',
createJoinImplementation(myGenerator),
);
```
**Notes**
* This implementation is nether tested nor robust, it would need further safeguards to avoid searching the entire file system.
* By using `function*` the generator is lazy. We only walk the file-system directory tree as necessary.
* The webpack file-system is provided by the `enhanced-resolver-plugin` and does **not** contain `fs.existsSync()`. We must use `fs.statsSync()` instead and catch any error where the file isn't present.
* You may set additional `options` when you configure the loader in webpack and then access them in your `generator`. In this case we add an `attempts` option to limit the file search.
## Full customisation
The `createJoinFunction` can give you full control over how the `base` and `uri` are joined to create an absolute file path **and** the definitiion of success for that combination.
It provides additional logging when using `debug` option so is a better choice then writing a "join" function from scratch.
Limited documentation is given here since it is rare to require a full customisation. Refer to the source code for further information.
### Reference
The `implementation` synchronously returns the final asset path or some fallback value. It makes a number of attempts to search for the given item and returns an element describing each attempt.
```javascript
implementation = function (item: {}, options: {}, loader: {}):
Array<{
base : string,
uri : string,
joined : string,
isSuccess : boolean,
isFallback: boolean,
}>
```
<details>
<summary>Arguments</summary>
* `item` consist of -
* `uri: string` is the argument to the `url()` as it appears in the source file.
* `query: string` is any string starting with `?` or `#` that suffixes the `uri`
* `isAbsolute: boolean` flag indicates whether the URI is considered an absolute file or root relative path by webpack's definition. Absolute URIs are only processed if the `root` option is specified.
* `bases: {}` are a hash where the keys are the sourcemap evaluation locations in the [algorithm](./how-it-works.md#algorithm) and the values are absolute paths that the sourcemap reports. These directories might not actually exist.
* `options` consist of -
* All documented options for the loader.
* Any other values you include in the loader configuration for your own purposes.
* `loader` consists of the webpack loader API, useful items include -
* `fs: {}` the virtual file-system from Webpack.
* `resourcePath: string` the source file currently being processed.
* returns an array of attempts that were made in resolving the URI -
* `base` the base path
* `uri` the uri path
* `joined` the absolute path created from the joining the `base` and `uri` paths.
* `isSuccess` indicates the asset was found and that `joined` should be the final result
* `isFallback` indicates the asset was not found but that `joined` kis suitable as a fallback value
</details>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1 @@
# Contributing

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,159 @@
# How it works
## The problem
The `resolve-url-loader` is typically used where SASS source files are transpiled to CSS. CSS being a format that webpack can readily ingest. So let's look at a basic example where the structure is basically CSS but is composed using SASS features.
Working backwards, this is the final CSS we are after. Just a single rule with a single declaration.
```css
.cool {
background-image: url(cool.png);
}
```
When using SASS it's common for rules to come from different [partials](https://sass-lang.com/documentation/at-rules/import#partials), and for declarations to be composed using mixins and functions. Consider this more complicated project with imported files.
<img src="detailed-problem.svg" alt="the detailed problem" width="363px" height="651px">
All the subdirectories here contributed something to the rule, so we could reasonably place the asset in any of them. And any of these locations might be the "correct" to our way of thinking.
There could actually be a separate `cool.png` in each of the subdirectories! 🤯 In that case, which one gets used?
The answer: none. 😞 Webpack expects asset paths to be relative to the root SASS file `src/styles.scss`. So for the CSS `url(cool.png)` it will look for `src/cool.png` which is not present. 💥
All our assets are in subdirecties `src/foo/cool.png` or `src/foo/bar/cool.png` or `src/foo/bar/baz/cool.png`. We need to re-write the `url()` to point to the one we intend. But right now that's pretty ambiguous.
Worse still, Webpack doesn't know any of these nested SCSS files were part of the SASS composition. Meaing it doesn't know there _are_ nested directories in the first place. How do we rewite to something we don't know about?
**The problem:** How to identify contributing directectories and look for the asset in those directories in some well-defined priority order?
**The crux:** How to identify what contributed to the SASS compilation, internally and post factum, but from within Webpack? 😫
## The solution
Sourcemaps! 😃
Wait, don't run away! Sourcemaps might sound scary, but they solve our problem reasonably well. 👍
The SASS compiler source-map can tell us which original SCSS file contributed each character in the resulting CSS.
The SASS source-map is also something we can access from within Webpack.
### concept
Continuing with the example let's compile SASS on the command line. You can do this several different ways but I prefer [npx](https://blog.npmjs.org/post/162869356040/introducing-npx-an-npm-package-runner).
```sh
> npx node-sass src/styles.scss --output . --output-style expanded --source-map true
```
Using the experimental `sourcemap-to-string` package (also in this repository) we can visualise the SASS source on the left vs the output CSS on the right.
```
src/styles.scss
-------------------------------------------------------------------------------
src/foo/_partial.scss
-------------------------------------------------------------------------------
3:01 .cool░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1:01 .cool░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
3:06 ░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1:06 ░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░
3:07 ░░░░░░{⏎ 1:07 ░░░░░░{⏎
@include cool-background-image;⏎ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
}░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
-:-- ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 3:02 ░⏎
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ⏎
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ /*# sourceMappingURL=styles.css.ma
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ p */░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
src/foo/bar/_mixins.scss
-------------------------------------------------------------------------------
4:03 ░░background-image░░░░░░░░░░░░░░░░ 2:03 ░░background-image░░░░░░░░░░░░░░░░
4:19 ░░░░░░░░░░░░░░░░░░: get-url("cool" 2:19 ░░░░░░░░░░░░░░░░░░: ░░░░░░░░░░░░░░
);⏎ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
}⏎ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
src/foo/bar/baz/_functions.scss
-------------------------------------------------------------------------------
2:11 ░░░░░░░░░░url(#░░░░░░░░░░░░░░░░░░░ 2:21 ░░░░░░░░░░░░░░░░░░░░url(cool.png)░
2:16 ░░░░░░░░░░░░░░░{$temp}.png);⏎ 2:34 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░;
}░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ⏎
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ }░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
```
As expected, the pure CSS portions are essentially the same in the source and the output.
Meanwhile the indirect `@mixin` and `funtion` substitutes values into the output. But we can still clearly see where in the source that final value originated from.
### algorithm
Now we know the original SCSS sources we can use a CSS parser such as `postcss` to process all the declaration values that contain `url()` and rewrite any file paths we find there.
1. Enumerate all declaration values
2. Split the value into path substrings
3. Evaluate the source-map at that location, find the original source file
4. Rebase the path to that original source file.
For our example, this algorithm will always give us the asset located in the `baz` subdirectory. Clearly evaluating the source-map at just one location is not enough. Any of the directories that contributed source files to the rule-set might be considered the "correct" place to store the asset and all these files contributed different parts of the rule-set, not just the declaration value.
We stop short of evaluating the source-map for _every characer_ in the rule-set and instead we chose a small number of meaningful points.
| | label | sampling location | in the example | implies asset |
|---|-----------|------------------------------------------|---------------------------|--------------------------------------------------|
| 1 | subString | start of **argument** to the `url()` | `c` in `cool.png` | `src/foo/bar/baz/cool.png` |
| 2 | value | start of **value** in the declaration | `u` in `url(...)` | `src/foo/bar/baz/cool.png` |
| 3 | property | start of **property** in the declaration | `b` in `background-image` | `src/foo/bar/cool.png` |
| 4 | selector | start of **selector** in the rule-set | `.` in `.selector` | `src/foo/cool.png` |
These locations are tested in order. If an asset of the correct filename is found then we break and use that result.
Note it is a quirk of the example that the `value` and `subString` locations imply the same file. In a more complex example this may not be true.
If necessary the order can be customised or a custom file search (starting at each location) be implemented. Refer to the [advanced features](advanced-features.md).
### webpack
To operate on the `sass-loader` output, both **CSS** and **source-map**, we introduce `resolve-url-loader` containing the algorithm above.
The `resolve-url-loader` rewrites asset paths found in `url()` notation using the `postcss` parser.
This webpack configuration outlines some important points.
```javascript
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'css-loader' // <-- assets are identified here
}, {
loader: 'resolve-url-loader' // <-- receives CSS and source-map from SASS compile
}, {
loader: 'sass-loader',
options: {
sourceMap: true, // <-- IMPORTANT!
sourceMapContents: false
}
}
],
},
...
{
test: /\.png$/, // <-- assets needs their own loader configuration
use: [ ... ]
}
]
```
Its essential to explicitly configure the `sass-loader` for `sourceMap: true`. That way we definitely get a sourcemap from upstream SASS loader all the time, not just in developement mode or where `devtool` is used.
Once the CSS reaches the `css-loader` webpack becomes aware of each of the asset files and will try to separately load and process them. You will need more Webpack configuration to make that work. Refer to the [troubleshooting docs](troubleshooting.md) before raising an issue.
### beyond...?
The implementation here is limited to the webpack loader but it's plausible the algorithm could be realised as a `postcss` plugin in isolation using the [root.input.map](https://postcss.org/api/#postcss-input) property to access the incomming source-map.
As a separate plugin it could be combined with other plugins in a single `postcss-loader` step. Processing multiple plugins together in this way without reparsing would arguably be more efficient.
However as a Webpack loader we have full access to the loader API and the virtual file-system. This means maximum compatibility with `webpack-dev-server` and the rest of the Webpack ecosystem.

View File

@@ -0,0 +1,71 @@
# Troubleshooting
Webpack is difficult to configure simply because it is so powerful. If you face a problem it is important to raise it in the right place.
Possibly whatever problem you are facing is _not_ an issue with this loader, so please work this list before raising an issue.
**Working with a framework**
1. Check to see if that framework is still using an older version with the `rework` engine. This will not support modern CSS and is the source of most problems. Usually there is an existing issue raised in that framework and there may be workarounds there.
2. Hack the framework code in your `node_modules` to diagose the root cause.
**Creating your own webpack config**
1. Do the checklist at the top of the page - do you _need_ to use this loader?
2. Read and understand the detail on [how the loader works](how-it-works.md).
3. Check the known-issues below.
4. Use the `debug` option to see where the loader is looking for your assets.
5. Temporarily remove this loader and use non-relative asset paths to check if the problem is something else.
6. Check [stack overflow](http://stackoverflow.com/search?q=resolve-url-loader) for an answer.
7. Review [previous issues](/issues?utf8=%E2%9C%93&q=is%3Aissue) that may be similar.
8. Try to recreate the problem with a minimum breaking example project.
I'm happy this loader helps so many people. Open-source is provided as-is and I'm currently **not** [dogfooding](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) this loader in my own work, so please try not project your frustrations. There are some really great people who follow this project who can help.
## Known issues
### Support for `image-set()`
Right now this loader only rewrites `url()` statements.
If you need other statements processed, such as `image-set()`, then please upvote [issue #119](issues/119).
### Absolute URIs
By "absolute URIs" we more correctly mean assets with root-relative URLs or absolute file paths. These paths are **not** processed unless a `root` is specified.
However any paths that _are_ processed will have windows back-slash converted to posix forward-slash. This can be useful since some webpack loaders can choke on windows paths. By using `root: ''` then `resolve-url-loader` effectively does nothing to absolute paths except change the windows backslash.
**💡 Protip** In **windows** if your downstream loaders are choking on windows paths using `root: ''` can help.
Also it be useful to process absolute URIs if you have a custom `join` function and want to process all the paths. Although this is perhaps better done with some separate `postcss` plugin.
### Windows line breaks
Normal windows linebreaks are `CRLF`. But sometimes libsass will output single `CR` characters.
This problem is specific to multiline declarations. Refer to the [libsass bug #2693](https://github.com/sass/libsass/issues/2693).
If you have _any_ such multiline declarations preceding `url()` statements it will fail your build.
Libsass doesn't consider these orphan `CR` to be newlines but `postcss` engine does. The result being an offset in source-map line-numbers which crashes `resolve-url-loader`.
```
Module build failed: Error: resolve-url-loader: error processing CSS
source-map information is not available at url() declaration
```
Some users find the node-sass `linefeed` option solves the problem.
**Solutions**
* Try the node-sass [linefeed](https://github.com/sass/node-sass#linefeed--v300) option by way of `sass-loader`.
**Work arounds**
* Enable `removeCR` option [here](../README.md#options) (enabled by default on Window OS).
* Remove linebreaks in declarations in your `.scss` sources.
**Diagnosis**
1. Run a stand-alone sass build `npx node-sass index.scss output.css`.
2. Use a hex editor to check line endings `Format-Hex output.css`.
3. Expect `0DOA` (or desired) line endings. Single `0D` confirms this problem.

305
frontend/node_modules/resolve-url-loader/index.js generated vendored Normal file
View File

@@ -0,0 +1,305 @@
/*
* MIT License http://opensource.org/licenses/MIT
* Author: Ben Holloway @bholloway
*/
'use strict';
var os = require('os'),
path = require('path'),
fs = require('fs'),
util = require('util'),
loaderUtils = require('loader-utils'),
SourceMapConsumer = require('source-map').SourceMapConsumer;
var adjustSourceMap = require('adjust-sourcemap-loader/lib/process');
var valueProcessor = require('./lib/value-processor'),
joinFn = require('./lib/join-function'),
logToTestHarness = require('./lib/log-to-test-harness');
const DEPRECATED_OPTIONS = {
engine: [
'DEP_RESOLVE_URL_LOADER_OPTION_ENGINE',
'the "engine" option is deprecated, "postcss" engine is the default, using "rework" engine is not advised'
],
keepQuery: [
'DEP_RESOLVE_URL_LOADER_OPTION_KEEP_QUERY',
'"keepQuery" option has been removed, the query and/or hash are now always retained'
],
absolute: [
'DEP_RESOLVE_URL_LOADER_OPTION_ABSOLUTE',
'"absolute" option has been removed, consider the "join" option if absolute paths must be processed'
],
attempts: [
'DEP_RESOLVE_URL_LOADER_OPTION_ATTEMPTS',
'"attempts" option has been removed, consider the "join" option if search is needed'
],
includeRoot: [
'DEP_RESOLVE_URL_LOADER_OPTION_INCLUDE_ROOT',
'"includeRoot" option has been removed, consider the "join" option if search is needed'
],
fail: [
'DEP_RESOLVE_URL_LOADER_OPTION_FAIL',
'"fail" option has been removed'
]
};
/**
* A webpack loader that resolves absolute url() paths relative to their original source file.
* Requires source-maps to do any meaningful work.
* @param {string} content Css content
* @param {object} sourceMap The source-map
* @returns {string|String}
*/
function resolveUrlLoader(content, sourceMap) {
/* jshint validthis:true */
// details of the file being processed
var loader = this;
// a relative loader.context is a problem
if (/^\./.test(loader.context)) {
return handleAsError(
'webpack misconfiguration',
'loader.context is relative, expected absolute'
);
}
// infer webpack version from new loader features
var isWebpackGte5 = 'getOptions' in loader && typeof loader.getOptions === 'function';
// webpack 1: prefer loader query, else options object
// webpack 2: prefer loader options
// webpack 3: deprecate loader.options object
// webpack 4: loader.options no longer defined
var rawOptions = loaderUtils.getOptions(loader),
options = Object.assign(
{
sourceMap: loader.sourceMap,
engine : 'postcss',
silent : false,
removeCR : os.EOL.includes('\r'),
root : false,
debug : false,
join : joinFn.defaultJoin
},
rawOptions
);
// maybe log options for the test harness
if (process.env.RESOLVE_URL_LOADER_TEST_HARNESS) {
logToTestHarness(
process[process.env.RESOLVE_URL_LOADER_TEST_HARNESS],
options
);
}
// deprecated options
var deprecatedItems = Object.entries(DEPRECATED_OPTIONS).filter(([key]) => key in rawOptions);
if (deprecatedItems.length) {
deprecatedItems.forEach(([, value]) => handleAsDeprecated(...value));
}
// validate join option
if (typeof options.join !== 'function') {
return handleAsError(
'loader misconfiguration',
'"join" option must be a Function'
);
} else if (options.join.length !== 2) {
return handleAsError(
'loader misconfiguration',
'"join" Function must take exactly 2 arguments (options, loader)'
);
}
// validate the result of calling the join option
var joinProper = options.join(options, loader);
if (typeof joinProper !== 'function') {
return handleAsError(
'loader misconfiguration',
'"join" option must itself return a Function when it is called'
);
} else if (joinProper.length !== 1) {
return handleAsError(
'loader misconfiguration',
'"join" Function must create a function that takes exactly 1 arguments (item)'
);
}
// validate root option
if (typeof options.root === 'string') {
var isValid = (options.root === '') ||
(path.isAbsolute(options.root) && fs.existsSync(options.root) && fs.statSync(options.root).isDirectory());
if (!isValid) {
return handleAsError(
'loader misconfiguration',
'"root" option must be an empty string or an absolute path to an existing directory'
);
}
} else if (options.root !== false) {
handleAsWarning(
'loader misconfiguration',
'"root" option must be string where used or false where unused'
);
}
// loader result is cacheable
loader.cacheable();
// incoming source-map
var sourceMapConsumer, absSourceMap;
if (sourceMap) {
// support non-standard string encoded source-map (per less-loader)
if (typeof sourceMap === 'string') {
try {
sourceMap = JSON.parse(sourceMap);
}
catch (exception) {
return handleAsError(
'source-map error',
'cannot parse source-map string (from less-loader?)'
);
}
}
// leverage adjust-sourcemap-loader's codecs to avoid having to make any assumptions about the sourcemap
// historically this is a regular source of breakage
try {
absSourceMap = adjustSourceMap(loader, {format: 'absolute'}, sourceMap);
}
catch (exception) {
return handleAsError(
'source-map error',
exception.message
);
}
// prepare the adjusted sass source-map for later look-ups
sourceMapConsumer = new SourceMapConsumer(absSourceMap);
} else {
handleAsWarning(
'webpack misconfiguration',
'webpack or the upstream loader did not supply a source-map'
);
}
// choose a CSS engine
var enginePath = /^[\w-]+$/.test(options.engine) && path.join(__dirname, 'lib', 'engine', options.engine + '.js');
var isValidEngine = fs.existsSync(enginePath);
if (!isValidEngine) {
return handleAsError(
'loader misconfiguration',
'"engine" option is not valid'
);
}
// allow engine to throw at initialisation
var engine;
try {
engine = require(enginePath);
} catch (error) {
return handleAsError(
'error initialising',
error
);
}
// process async
var callback = loader.async();
Promise
.resolve(engine(loader.resourcePath, content, {
outputSourceMap : !!options.sourceMap,
absSourceMap : absSourceMap,
sourceMapConsumer : sourceMapConsumer,
removeCR : options.removeCR,
transformDeclaration: valueProcessor({
join : joinProper,
root : options.root,
directory: path.dirname(loader.resourcePath)
})
}))
.catch(onFailure)
.then(onSuccess);
function onFailure(error) {
callback(encodeError('error processing CSS', error));
}
function onSuccess(result) {
if (result) {
// complete with source-map
// webpack4 and earlier: source-map sources are relative to the file being processed
// webpack5: source-map sources are relative to the project root but without a leading slash
if (options.sourceMap) {
var finalMap = adjustSourceMap(loader, {
format: isWebpackGte5 ? 'projectRelative' : 'sourceRelative'
}, result.map);
callback(null, result.content, finalMap);
}
// complete without source-map
else {
callback(null, result.content);
}
}
}
/**
* Trigger a node deprecation message for the given exception and return the original content.
* @param {string} code Deprecation code
* @param {string} message Deprecation message
* @returns {string} The original CSS content
*/
function handleAsDeprecated(code, message) {
if (!options.silent) {
util.deprecate(() => undefined, message, code)();
}
return content;
}
/**
* Push a warning for the given exception and return the original content.
* @param {string} label Summary of the error
* @param {string|Error} [exception] Optional extended error details
* @returns {string} The original CSS content
*/
function handleAsWarning(label, exception) {
if (!options.silent) {
loader.emitWarning(encodeError(label, exception));
}
return content;
}
/**
* Push a warning for the given exception and return the original content.
* @param {string} label Summary of the error
* @param {string|Error} [exception] Optional extended error details
* @returns {string} The original CSS content
*/
function handleAsError(label, exception) {
loader.emitError(encodeError(label, exception));
return content;
}
function encodeError(label, exception) {
return new Error(
[
'resolve-url-loader',
': ',
[label]
.concat(
(typeof exception === 'string') && exception ||
Array.isArray(exception) && exception ||
(exception instanceof Error) && [exception.message, exception.stack.split('\n')[1].trim()] ||
[]
)
.filter(Boolean)
.join('\n ')
].join('')
);
}
}
module.exports = Object.assign(resolveUrlLoader, joinFn);

View File

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

View File

@@ -0,0 +1,123 @@
# convert-source-map [![Build Status][ci-image]][ci-url]
Converts a source-map from/to different formats and allows adding/changing properties.
```js
var convert = require('convert-source-map');
var json = convert
.fromComment('//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQvZm9vLm1pbi5qcyIsInNvdXJjZXMiOlsic3JjL2Zvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIvIn0=')
.toJSON();
var modified = convert
.fromComment('//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQvZm9vLm1pbi5qcyIsInNvdXJjZXMiOlsic3JjL2Zvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIvIn0=')
.setProperty('sources', [ 'SRC/FOO.JS' ])
.toJSON();
console.log(json);
console.log(modified);
```
```json
{"version":3,"file":"build/foo.min.js","sources":["src/foo.js"],"names":[],"mappings":"AAAA","sourceRoot":"/"}
{"version":3,"file":"build/foo.min.js","sources":["SRC/FOO.JS"],"names":[],"mappings":"AAAA","sourceRoot":"/"}
```
## API
### fromObject(obj)
Returns source map converter from given object.
### fromJSON(json)
Returns source map converter from given json string.
### fromBase64(base64)
Returns source map converter from given base64 encoded json string.
### fromComment(comment)
Returns source map converter from given base64 encoded json string prefixed with `//# sourceMappingURL=...`.
### fromMapFileComment(comment, mapFileDir)
Returns source map converter from given `filename` by parsing `//# sourceMappingURL=filename`.
`filename` must point to a file that is found inside the `mapFileDir`. Most tools store this file right next to the
generated file, i.e. the one containing the source map.
### fromSource(source)
Finds last sourcemap comment in file and returns source map converter or returns null if no source map comment was found.
### fromMapFileSource(source, mapFileDir)
Finds last sourcemap comment in file and returns source map converter or returns null if no source map comment was
found.
The sourcemap will be read from the map file found by parsing `# sourceMappingURL=file` comment. For more info see
fromMapFileComment.
### toObject()
Returns a copy of the underlying source map.
### toJSON([space])
Converts source map to json string. If `space` is given (optional), this will be passed to
[JSON.stringify](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify) when the
JSON string is generated.
### toBase64()
Converts source map to base64 encoded json string.
### toComment([options])
Converts source map to an inline comment that can be appended to the source-file.
By default, the comment is formatted like: `//# sourceMappingURL=...`, which you would
normally see in a JS source file.
When `options.multiline == true`, the comment is formatted like: `/*# sourceMappingURL=... */`, which you would find in a CSS source file.
### addProperty(key, value)
Adds given property to the source map. Throws an error if property already exists.
### setProperty(key, value)
Sets given property to the source map. If property doesn't exist it is added, otherwise its value is updated.
### getProperty(key)
Gets given property of the source map.
### removeComments(src)
Returns `src` with all source map comments removed
### removeMapFileComments(src)
Returns `src` with all source map comments pointing to map files removed.
### commentRegex
Provides __a fresh__ RegExp each time it is accessed. Can be used to find source map comments.
### mapFileCommentRegex
Provides __a fresh__ RegExp each time it is accessed. Can be used to find source map comments pointing to map files.
### generateMapFileComment(file, [options])
Returns a comment that links to an external source map via `file`.
By default, the comment is formatted like: `//# sourceMappingURL=...`, which you would normally see in a JS source file.
When `options.multiline == true`, the comment is formatted like: `/*# sourceMappingURL=... */`, which you would find in a CSS source file.
[ci-url]: https://github.com/thlorenz/convert-source-map/actions?query=workflow:ci
[ci-image]: https://img.shields.io/github/workflow/status/thlorenz/convert-source-map/CI?style=flat-square

View File

@@ -0,0 +1,179 @@
'use strict';
var fs = require('fs');
var path = require('path');
Object.defineProperty(exports, 'commentRegex', {
get: function getCommentRegex () {
return /^\s*\/(?:\/|\*)[@#]\s+sourceMappingURL=data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(?:.*)$/mg;
}
});
Object.defineProperty(exports, 'mapFileCommentRegex', {
get: function getMapFileCommentRegex () {
// Matches sourceMappingURL in either // or /* comment styles.
return /(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"`]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/){1}[ \t]*$)/mg;
}
});
var decodeBase64;
if (typeof Buffer !== 'undefined') {
if (typeof Buffer.from === 'function') {
decodeBase64 = decodeBase64WithBufferFrom;
} else {
decodeBase64 = decodeBase64WithNewBuffer;
}
} else {
decodeBase64 = decodeBase64WithAtob;
}
function decodeBase64WithBufferFrom(base64) {
return Buffer.from(base64, 'base64').toString();
}
function decodeBase64WithNewBuffer(base64) {
if (typeof value === 'number') {
throw new TypeError('The value to decode must not be of type number.');
}
return new Buffer(base64, 'base64').toString();
}
function decodeBase64WithAtob(base64) {
return decodeURIComponent(escape(atob(base64)));
}
function stripComment(sm) {
return sm.split(',').pop();
}
function readFromFileMap(sm, dir) {
// NOTE: this will only work on the server since it attempts to read the map file
var r = exports.mapFileCommentRegex.exec(sm);
// for some odd reason //# .. captures in 1 and /* .. */ in 2
var filename = r[1] || r[2];
var filepath = path.resolve(dir, filename);
try {
return fs.readFileSync(filepath, 'utf8');
} catch (e) {
throw new Error('An error occurred while trying to read the map file at ' + filepath + '\n' + e);
}
}
function Converter (sm, opts) {
opts = opts || {};
if (opts.isFileComment) sm = readFromFileMap(sm, opts.commentFileDir);
if (opts.hasComment) sm = stripComment(sm);
if (opts.isEncoded) sm = decodeBase64(sm);
if (opts.isJSON || opts.isEncoded) sm = JSON.parse(sm);
this.sourcemap = sm;
}
Converter.prototype.toJSON = function (space) {
return JSON.stringify(this.sourcemap, null, space);
};
if (typeof Buffer !== 'undefined') {
if (typeof Buffer.from === 'function') {
Converter.prototype.toBase64 = encodeBase64WithBufferFrom;
} else {
Converter.prototype.toBase64 = encodeBase64WithNewBuffer;
}
} else {
Converter.prototype.toBase64 = encodeBase64WithBtoa;
}
function encodeBase64WithBufferFrom() {
var json = this.toJSON();
return Buffer.from(json, 'utf8').toString('base64');
}
function encodeBase64WithNewBuffer() {
var json = this.toJSON();
if (typeof json === 'number') {
throw new TypeError('The json to encode must not be of type number.');
}
return new Buffer(json, 'utf8').toString('base64');
}
function encodeBase64WithBtoa() {
var json = this.toJSON();
return btoa(unescape(encodeURIComponent(json)));
}
Converter.prototype.toComment = function (options) {
var base64 = this.toBase64();
var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
return options && options.multiline ? '/*# ' + data + ' */' : '//# ' + data;
};
// returns copy instead of original
Converter.prototype.toObject = function () {
return JSON.parse(this.toJSON());
};
Converter.prototype.addProperty = function (key, value) {
if (this.sourcemap.hasOwnProperty(key)) throw new Error('property "' + key + '" already exists on the sourcemap, use set property instead');
return this.setProperty(key, value);
};
Converter.prototype.setProperty = function (key, value) {
this.sourcemap[key] = value;
return this;
};
Converter.prototype.getProperty = function (key) {
return this.sourcemap[key];
};
exports.fromObject = function (obj) {
return new Converter(obj);
};
exports.fromJSON = function (json) {
return new Converter(json, { isJSON: true });
};
exports.fromBase64 = function (base64) {
return new Converter(base64, { isEncoded: true });
};
exports.fromComment = function (comment) {
comment = comment
.replace(/^\/\*/g, '//')
.replace(/\*\/$/g, '');
return new Converter(comment, { isEncoded: true, hasComment: true });
};
exports.fromMapFileComment = function (comment, dir) {
return new Converter(comment, { commentFileDir: dir, isFileComment: true, isJSON: true });
};
// Finds last sourcemap comment in file or returns null if none was found
exports.fromSource = function (content) {
var m = content.match(exports.commentRegex);
return m ? exports.fromComment(m.pop()) : null;
};
// Finds last sourcemap comment in file or returns null if none was found
exports.fromMapFileSource = function (content, dir) {
var m = content.match(exports.mapFileCommentRegex);
return m ? exports.fromMapFileComment(m.pop(), dir) : null;
};
exports.removeComments = function (src) {
return src.replace(exports.commentRegex, '');
};
exports.removeMapFileComments = function (src) {
return src.replace(exports.mapFileCommentRegex, '');
};
exports.generateMapFileComment = function (file, options) {
var data = 'sourceMappingURL=' + file;
return options && options.multiline ? '/*# ' + data + ' */' : '//# ' + data;
};

View File

@@ -0,0 +1,41 @@
{
"name": "convert-source-map",
"version": "1.9.0",
"description": "Converts a source-map from/to different formats and allows adding/changing properties.",
"main": "index.js",
"scripts": {
"test": "tap test/*.js --color"
},
"repository": {
"type": "git",
"url": "git://github.com/thlorenz/convert-source-map.git"
},
"homepage": "https://github.com/thlorenz/convert-source-map",
"devDependencies": {
"inline-source-map": "~0.6.2",
"tap": "~9.0.0"
},
"keywords": [
"convert",
"sourcemap",
"source",
"map",
"browser",
"debug"
],
"author": {
"name": "Thorsten Lorenz",
"email": "thlorenz@gmx.de",
"url": "http://thlorenz.com"
},
"license": "MIT",
"engine": {
"node": ">=0.6"
},
"files": [
"index.js"
],
"browser": {
"fs": false
}
}

View File

@@ -0,0 +1,15 @@
ISC License
Copyright (c) 2021 Alexey Raspopov, Kostiantyn Denysov, Anton Verinov
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,23 @@
# picocolors
npm install picocolors
A tinier and faster alternative to [nanocolors](https://github.com/ai/nanocolors). Andrey, are you even trying?
```javascript
import pc from "picocolors";
console.log(pc.green(`How are ${pc.italic(`you`)} doing?`));
```
- Up to [2x faster and 2x smaller](#benchmarks) than alternatives
- 3x faster and 10x smaller than `chalk`
- [TypeScript](https://www.typescriptlang.org/) support
- [`NO_COLOR`](https://no-color.org/) friendly
- Node.js v6+ & browsers support
- The same API, but faster, much faster
- No `String.prototype` modifications (anyone still doing it?)
- No dependencies and the smallest `node_modules` footprint
## Docs
Read **[full docs](https://github.com/alexeyraspopov/picocolors#readme)** on GitHub.

View File

@@ -0,0 +1,25 @@
{
"name": "picocolors",
"version": "0.2.1",
"main": "./picocolors.js",
"types": "./picocolors.d.ts",
"browser": {
"./picocolors.js": "./picocolors.browser.js"
},
"sideEffects": false,
"description": "The tiniest and the fastest coloring library ever",
"files": [
"picocolors.*",
"types.ts"
],
"keywords": [
"terminal",
"colors",
"formatting",
"cli",
"console"
],
"author": "Alexey Raspopov",
"repository": "alexeyraspopov/picocolors",
"license": "ISC"
}

View File

@@ -0,0 +1,4 @@
var x=String;
var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x}};
module.exports=create();
module.exports.createColors = create;

View File

@@ -0,0 +1,5 @@
import { Colors } from "./types"
declare const picocolors: Colors & { createColors: (enabled: boolean) => Colors }
export = picocolors

View File

@@ -0,0 +1,60 @@
let tty = require("tty")
let isColorSupported =
!("NO_COLOR" in process.env || process.argv.includes("--no-color")) &&
("FORCE_COLOR" in process.env ||
process.argv.includes("--color") ||
process.platform === "win32" ||
(tty.isatty(1) && process.env.TERM !== "dumb") ||
"CI" in process.env)
function formatter(open, close, replace = open) {
return (input) => {
let string = "" + input
let index = string.indexOf(close, open.length)
return !~index
? open + string + close
: open + replaceClose(string, close, replace, index) + close
}
}
function replaceClose(string, close, replace, index) {
let start = string.substring(0, index) + replace
let end = string.substring(index + close.length)
let nextIndex = end.indexOf(close)
return !~nextIndex ? start + end : start + replaceClose(end, close, replace, nextIndex)
}
function createColors(enabled = isColorSupported) {
return {
isColorSupported: enabled,
reset: enabled ? (s) => `\x1b[0m${s}\x1b[0m` : String,
bold: enabled ? formatter("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m") : String,
dim: enabled ? formatter("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m") : String,
italic: enabled ? formatter("\x1b[3m", "\x1b[23m") : String,
underline: enabled ? formatter("\x1b[4m", "\x1b[24m") : String,
inverse: enabled ? formatter("\x1b[7m", "\x1b[27m") : String,
hidden: enabled ? formatter("\x1b[8m", "\x1b[28m") : String,
strikethrough: enabled ? formatter("\x1b[9m", "\x1b[29m") : String,
black: enabled ? formatter("\x1b[30m", "\x1b[39m") : String,
red: enabled ? formatter("\x1b[31m", "\x1b[39m") : String,
green: enabled ? formatter("\x1b[32m", "\x1b[39m") : String,
yellow: enabled ? formatter("\x1b[33m", "\x1b[39m") : String,
blue: enabled ? formatter("\x1b[34m", "\x1b[39m") : String,
magenta: enabled ? formatter("\x1b[35m", "\x1b[39m") : String,
cyan: enabled ? formatter("\x1b[36m", "\x1b[39m") : String,
white: enabled ? formatter("\x1b[37m", "\x1b[39m") : String,
gray: enabled ? formatter("\x1b[90m", "\x1b[39m") : String,
bgBlack: enabled ? formatter("\x1b[40m", "\x1b[49m") : String,
bgRed: enabled ? formatter("\x1b[41m", "\x1b[49m") : String,
bgGreen: enabled ? formatter("\x1b[42m", "\x1b[49m") : String,
bgYellow: enabled ? formatter("\x1b[43m", "\x1b[49m") : String,
bgBlue: enabled ? formatter("\x1b[44m", "\x1b[49m") : String,
bgMagenta: enabled ? formatter("\x1b[45m", "\x1b[49m") : String,
bgCyan: enabled ? formatter("\x1b[46m", "\x1b[49m") : String,
bgWhite: enabled ? formatter("\x1b[47m", "\x1b[49m") : String,
}
}
module.exports = createColors()
module.exports.createColors = createColors

View File

@@ -0,0 +1,30 @@
export type Formatter = (input: string | number | null | undefined) => string
export interface Colors {
isColorSupported: boolean
reset: Formatter
bold: Formatter
dim: Formatter
italic: Formatter
underline: Formatter
inverse: Formatter
hidden: Formatter
strikethrough: Formatter
black: Formatter
red: Formatter
green: Formatter
yellow: Formatter
blue: Formatter
magenta: Formatter
cyan: Formatter
white: Formatter
gray: Formatter
bgBlack: Formatter
bgRed: Formatter
bgGreen: Formatter
bgYellow: Formatter
bgBlue: Formatter
bgMagenta: Formatter
bgCyan: Formatter
bgWhite: Formatter
}

View File

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

View File

@@ -0,0 +1,43 @@
# PostCSS [![Gitter][chat-img]][chat]
<img align="right" width="95" height="95"
alt="Philosophers stone, logo of PostCSS"
src="http://postcss.github.io/postcss/logo.svg">
[chat-img]: https://img.shields.io/badge/Gitter-Join_the_PostCSS_chat-brightgreen.svg
[chat]: https://gitter.im/postcss/postcss
PostCSS is a tool for transforming styles with JS plugins.
These plugins can lint your CSS, support variables and mixins,
transpile future CSS syntax, inline images, and more.
PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba,
and JetBrains. The [Autoprefixer] PostCSS plugin is one of the most popular
CSS processors.
PostCSS takes a CSS file and provides an API to analyze and modify its rules
(by transforming them into an [Abstract Syntax Tree]).
This API can then be used by [plugins] to do a lot of useful things,
e.g. to find errors automatically insert vendor prefixes.
**Support / Discussion:** [Gitter](https://gitter.im/postcss/postcss)<br>
**Twitter account:** [@postcss](https://twitter.com/postcss)<br>
**VK.com page:** [postcss](https://vk.com/postcss)<br>
**中文翻译**: [`README-cn.md`](./README-cn.md)
For PostCSS commercial support (consulting, improving the front-end culture
of your company, PostCSS plugins), contact [Evil Martians]
at <surrender@evilmartians.com>.
[Abstract Syntax Tree]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
[Evil Martians]: https://evilmartians.com/?utm_source=postcss
[Autoprefixer]: https://github.com/postcss/autoprefixer
[plugins]: https://github.com/postcss/postcss#plugins
<a href="https://evilmartians.com/?utm_source=postcss">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54">
</a>
## Docs
Read **[full docs](https://github.com/postcss/postcss#readme)** on GitHub.

View File

@@ -0,0 +1,37 @@
{
"name": "postcss",
"version": "7.0.39",
"description": "Tool for transforming styles with JS plugins",
"engines": {
"node": ">=6.0.0"
},
"keywords": [
"css",
"postcss",
"rework",
"preprocessor",
"parser",
"source map",
"transform",
"manipulation",
"transpiler"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
"author": "Andrey Sitnik <andrey@sitnik.ru>",
"license": "MIT",
"homepage": "https://postcss.org/",
"repository": "postcss/postcss",
"dependencies": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
},
"main": "lib/postcss",
"types": "lib/postcss.d.ts",
"browser": {
"./lib/terminal-highlight": false,
"fs": false
}
}

View File

@@ -0,0 +1,301 @@
# Change Log
## 0.5.6
* Fix for regression when people were using numbers as names in source maps. See
#236.
## 0.5.5
* Fix "regression" of unsupported, implementation behavior that half the world
happens to have come to depend on. See #235.
* Fix regression involving function hoisting in SpiderMonkey. See #233.
## 0.5.4
* Large performance improvements to source-map serialization. See #228 and #229.
## 0.5.3
* Do not include unnecessary distribution files. See
commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86.
## 0.5.2
* Include browser distributions of the library in package.json's `files`. See
issue #212.
## 0.5.1
* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See
ff05274becc9e6e1295ed60f3ea090d31d843379.
## 0.5.0
* Node 0.8 is no longer supported.
* Use webpack instead of dryice for bundling.
* Big speedups serializing source maps. See pull request #203.
* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that
explicitly start with the source root. See issue #199.
## 0.4.4
* Fix an issue where using a `SourceMapGenerator` after having created a
`SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See
issue #191.
* Fix an issue with where `SourceMapGenerator` would mistakenly consider
different mappings as duplicates of each other and avoid generating them. See
issue #192.
## 0.4.3
* A very large number of performance improvements, particularly when parsing
source maps. Collectively about 75% of time shaved off of the source map
parsing benchmark!
* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy
searching in the presence of a column option. See issue #177.
* Fix a bug with joining a source and its source root when the source is above
the root. See issue #182.
* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to
determine when all sources' contents are inlined into the source map. See
issue #190.
## 0.4.2
* Add an `.npmignore` file so that the benchmarks aren't pulled down by
dependent projects. Issue #169.
* Add an optional `column` argument to
`SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines
with no mappings. Issues #172 and #173.
## 0.4.1
* Fix accidentally defining a global variable. #170.
## 0.4.0
* The default direction for fuzzy searching was changed back to its original
direction. See #164.
* There is now a `bias` option you can supply to `SourceMapConsumer` to control
the fuzzy searching direction. See #167.
* About an 8% speed up in parsing source maps. See #159.
* Added a benchmark for parsing and generating source maps.
## 0.3.0
* Change the default direction that searching for positions fuzzes when there is
not an exact match. See #154.
* Support for environments using json2.js for JSON serialization. See #156.
## 0.2.0
* Support for consuming "indexed" source maps which do not have any remote
sections. See pull request #127. This introduces a minor backwards
incompatibility if you are monkey patching `SourceMapConsumer.prototype`
methods.
## 0.1.43
* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue
#148 for some discussion and issues #150, #151, and #152 for implementations.
## 0.1.42
* Fix an issue where `SourceNode`s from different versions of the source-map
library couldn't be used in conjunction with each other. See issue #142.
## 0.1.41
* Fix a bug with getting the source content of relative sources with a "./"
prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768).
* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the
column span of each mapping.
* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find
all generated positions associated with a given original source and line.
## 0.1.40
* Performance improvements for parsing source maps in SourceMapConsumer.
## 0.1.39
* Fix a bug where setting a source's contents to null before any source content
had been set before threw a TypeError. See issue #131.
## 0.1.38
* Fix a bug where finding relative paths from an empty path were creating
absolute paths. See issue #129.
## 0.1.37
* Fix a bug where if the source root was an empty string, relative source paths
would turn into absolute source paths. Issue #124.
## 0.1.36
* Allow the `names` mapping property to be an empty string. Issue #121.
## 0.1.35
* A third optional parameter was added to `SourceNode.fromStringWithSourceMap`
to specify a path that relative sources in the second parameter should be
relative to. Issue #105.
* If no file property is given to a `SourceMapGenerator`, then the resulting
source map will no longer have a `null` file property. The property will
simply not exist. Issue #104.
* Fixed a bug where consecutive newlines were ignored in `SourceNode`s.
Issue #116.
## 0.1.34
* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103.
* Fix bug involving source contents and the
`SourceMapGenerator.prototype.applySourceMap`. Issue #100.
## 0.1.33
* Fix some edge cases surrounding path joining and URL resolution.
* Add a third parameter for relative path to
`SourceMapGenerator.prototype.applySourceMap`.
* Fix issues with mappings and EOLs.
## 0.1.32
* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns
(issue 92).
* Fixed test runner to actually report number of failed tests as its process
exit code.
* Fixed a typo when reporting bad mappings (issue 87).
## 0.1.31
* Delay parsing the mappings in SourceMapConsumer until queried for a source
location.
* Support Sass source maps (which at the time of writing deviate from the spec
in small ways) in SourceMapConsumer.
## 0.1.30
* Do not join source root with a source, when the source is a data URI.
* Extend the test runner to allow running single specific test files at a time.
* Performance improvements in `SourceNode.prototype.walk` and
`SourceMapConsumer.prototype.eachMapping`.
* Source map browser builds will now work inside Workers.
* Better error messages when attempting to add an invalid mapping to a
`SourceMapGenerator`.
## 0.1.29
* Allow duplicate entries in the `names` and `sources` arrays of source maps
(usually from TypeScript) we are parsing. Fixes github issue 72.
## 0.1.28
* Skip duplicate mappings when creating source maps from SourceNode; github
issue 75.
## 0.1.27
* Don't throw an error when the `file` property is missing in SourceMapConsumer,
we don't use it anyway.
## 0.1.26
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70.
## 0.1.25
* Make compatible with browserify
## 0.1.24
* Fix issue with absolute paths and `file://` URIs. See
https://bugzilla.mozilla.org/show_bug.cgi?id=885597
## 0.1.23
* Fix issue with absolute paths and sourcesContent, github issue 64.
## 0.1.22
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21.
## 0.1.21
* Fixed handling of sources that start with a slash so that they are relative to
the source root's host.
## 0.1.20
* Fixed github issue #43: absolute URLs aren't joined with the source root
anymore.
## 0.1.19
* Using Travis CI to run tests.
## 0.1.18
* Fixed a bug in the handling of sourceRoot.
## 0.1.17
* Added SourceNode.fromStringWithSourceMap.
## 0.1.16
* Added missing documentation.
* Fixed the generating of empty mappings in SourceNode.
## 0.1.15
* Added SourceMapGenerator.applySourceMap.
## 0.1.14
* The sourceRoot is now handled consistently.
## 0.1.13
* Added SourceMapGenerator.fromSourceMap.
## 0.1.12
* SourceNode now generates empty mappings too.
## 0.1.11
* Added name support to SourceNode.
## 0.1.10
* Added sourcesContent support to the customer and generator.

View File

@@ -0,0 +1,28 @@
Copyright (c) 2009-2011, Mozilla Foundation and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the Mozilla Foundation nor the names of project
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,742 @@
# Source Map
[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
[![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map)
This is a library to generate and consume the source map format
[described here][format].
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
## Use with Node
$ npm install source-map
## Use on the Web
<script src="https://raw.githubusercontent.com/mozilla/source-map/master/dist/source-map.min.js" defer></script>
--------------------------------------------------------------------------------
<!-- `npm run toc` to regenerate the Table of Contents -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of Contents
- [Examples](#examples)
- [Consuming a source map](#consuming-a-source-map)
- [Generating a source map](#generating-a-source-map)
- [With SourceNode (high level API)](#with-sourcenode-high-level-api)
- [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api)
- [API](#api)
- [SourceMapConsumer](#sourcemapconsumer)
- [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
- [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans)
- [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition)
- [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition)
- [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition)
- [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources)
- [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing)
- [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order)
- [SourceMapGenerator](#sourcemapgenerator)
- [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap)
- [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer)
- [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping)
- [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent)
- [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath)
- [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring)
- [SourceNode](#sourcenode)
- [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name)
- [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath)
- [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk)
- [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk)
- [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent)
- [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn)
- [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn)
- [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep)
- [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement)
- [SourceNode.prototype.toString()](#sourcenodeprototypetostring)
- [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Examples
### Consuming a source map
```js
var rawSourceMap = {
version: 3,
file: 'min.js',
names: ['bar', 'baz', 'n'],
sources: ['one.js', 'two.js'],
sourceRoot: 'http://example.com/www/js/',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
var smc = new SourceMapConsumer(rawSourceMap);
console.log(smc.sources);
// [ 'http://example.com/www/js/one.js',
// 'http://example.com/www/js/two.js' ]
console.log(smc.originalPositionFor({
line: 2,
column: 28
}));
// { source: 'http://example.com/www/js/two.js',
// line: 2,
// column: 10,
// name: 'n' }
console.log(smc.generatedPositionFor({
source: 'http://example.com/www/js/two.js',
line: 2,
column: 10
}));
// { line: 2, column: 28 }
smc.eachMapping(function (m) {
// ...
});
```
### Generating a source map
In depth guide:
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
#### With SourceNode (high level API)
```js
function compile(ast) {
switch (ast.type) {
case 'BinaryExpression':
return new SourceNode(
ast.location.line,
ast.location.column,
ast.location.source,
[compile(ast.left), " + ", compile(ast.right)]
);
case 'Literal':
return new SourceNode(
ast.location.line,
ast.location.column,
ast.location.source,
String(ast.value)
);
// ...
default:
throw new Error("Bad AST");
}
}
var ast = parse("40 + 2", "add.js");
console.log(compile(ast).toStringWithSourceMap({
file: 'add.js'
}));
// { code: '40 + 2',
// map: [object SourceMapGenerator] }
```
#### With SourceMapGenerator (low level API)
```js
var map = new SourceMapGenerator({
file: "source-mapped.js"
});
map.addMapping({
generated: {
line: 10,
column: 35
},
source: "foo.js",
original: {
line: 33,
column: 2
},
name: "christopher"
});
console.log(map.toString());
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
```
## API
Get a reference to the module:
```js
// Node.js
var sourceMap = require('source-map');
// Browser builds
var sourceMap = window.sourceMap;
// Inside Firefox
const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");
```
### SourceMapConsumer
A SourceMapConsumer instance represents a parsed source map which we can query
for information about the original file positions by giving it a file position
in the generated source.
#### new SourceMapConsumer(rawSourceMap)
The only parameter is the raw source map (either as a string which can be
`JSON.parse`'d, or an object). According to the spec, source maps have the
following attributes:
* `version`: Which version of the source map spec this map is following.
* `sources`: An array of URLs to the original source files.
* `names`: An array of identifiers which can be referenced by individual
mappings.
* `sourceRoot`: Optional. The URL root from which all sources are relative.
* `sourcesContent`: Optional. An array of contents of the original source files.
* `mappings`: A string of base64 VLQs which contain the actual mappings.
* `file`: Optional. The generated filename this source map is associated with.
```js
var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
```
#### SourceMapConsumer.prototype.computeColumnSpans()
Compute the last column for each generated mapping. The last column is
inclusive.
```js
// Before:
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
// [ { line: 2,
// column: 1 },
// { line: 2,
// column: 10 },
// { line: 2,
// column: 20 } ]
consumer.computeColumnSpans();
// After:
consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" })
// [ { line: 2,
// column: 1,
// lastColumn: 9 },
// { line: 2,
// column: 10,
// lastColumn: 19 },
// { line: 2,
// column: 20,
// lastColumn: Infinity } ]
```
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
Returns the original source, line, and column information for the generated
source's line and column positions provided. The only argument is an object with
the following properties:
* `line`: The line number in the generated source. Line numbers in
this library are 1-based (note that the underlying source map
specification uses 0-based line numbers -- this library handles the
translation).
* `column`: The column number in the generated source. Column numbers
in this library are 0-based.
* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
`SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
element that is smaller than or greater than the one we are searching for,
respectively, if the exact element cannot be found. Defaults to
`SourceMapConsumer.GREATEST_LOWER_BOUND`.
and an object is returned with the following properties:
* `source`: The original source file, or null if this information is not
available.
* `line`: The line number in the original source, or null if this information is
not available. The line number is 1-based.
* `column`: The column number in the original source, or null if this
information is not available. The column number is 0-based.
* `name`: The original identifier, or null if this information is not available.
```js
consumer.originalPositionFor({ line: 2, column: 10 })
// { source: 'foo.coffee',
// line: 2,
// column: 2,
// name: null }
consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 })
// { source: null,
// line: null,
// column: null,
// name: null }
```
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
Returns the generated line and column information for the original source,
line, and column positions provided. The only argument is an object with
the following properties:
* `source`: The filename of the original source.
* `line`: The line number in the original source. The line number is
1-based.
* `column`: The column number in the original source. The column
number is 0-based.
and an object is returned with the following properties:
* `line`: The line number in the generated source, or null. The line
number is 1-based.
* `column`: The column number in the generated source, or null. The
column number is 0-based.
```js
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
// { line: 1,
// column: 56 }
```
#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)
Returns all generated line and column information for the original source, line,
and column provided. If no column is provided, returns all mappings
corresponding to a either the line we are searching for or the next closest line
that has any mappings. Otherwise, returns all mappings corresponding to the
given line and either the column we are searching for or the next closest column
that has any offsets.
The only argument is an object with the following properties:
* `source`: The filename of the original source.
* `line`: The line number in the original source. The line number is
1-based.
* `column`: Optional. The column number in the original source. The
column number is 0-based.
and an array of objects is returned, each with the following properties:
* `line`: The line number in the generated source, or null. The line
number is 1-based.
* `column`: The column number in the generated source, or null. The
column number is 0-based.
```js
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
// [ { line: 2,
// column: 1 },
// { line: 2,
// column: 10 },
// { line: 2,
// column: 20 } ]
```
#### SourceMapConsumer.prototype.hasContentsOfAllSources()
Return true if we have the embedded source content for every source listed in
the source map, false otherwise.
In other words, if this method returns `true`, then
`consumer.sourceContentFor(s)` will succeed for every source `s` in
`consumer.sources`.
```js
// ...
if (consumer.hasContentsOfAllSources()) {
consumerReadyCallback(consumer);
} else {
fetchSources(consumer, consumerReadyCallback);
}
// ...
```
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])
Returns the original source content for the source provided. The only
argument is the URL of the original source file.
If the source content for the given source is not found, then an error is
thrown. Optionally, pass `true` as the second param to have `null` returned
instead.
```js
consumer.sources
// [ "my-cool-lib.clj" ]
consumer.sourceContentFor("my-cool-lib.clj")
// "..."
consumer.sourceContentFor("this is not in the source map");
// Error: "this is not in the source map" is not in the source map
consumer.sourceContentFor("this is not in the source map", true);
// null
```
#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
Iterate over each mapping between an original source/line/column and a
generated line/column in this source map.
* `callback`: The function that is called with each mapping. Mappings have the
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
name }`
* `context`: Optional. If specified, this object will be the value of `this`
every time that `callback` is called.
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
the mappings sorted by the generated file's line/column order or the
original's source/line/column order, respectively. Defaults to
`SourceMapConsumer.GENERATED_ORDER`.
```js
consumer.eachMapping(function (m) { console.log(m); })
// ...
// { source: 'illmatic.js',
// generatedLine: 1,
// generatedColumn: 0,
// originalLine: 1,
// originalColumn: 0,
// name: null }
// { source: 'illmatic.js',
// generatedLine: 2,
// generatedColumn: 0,
// originalLine: 2,
// originalColumn: 0,
// name: null }
// ...
```
### SourceMapGenerator
An instance of the SourceMapGenerator represents a source map which is being
built incrementally.
#### new SourceMapGenerator([startOfSourceMap])
You may pass an object with the following properties:
* `file`: The filename of the generated source that this source map is
associated with.
* `sourceRoot`: A root for all relative URLs in this source map.
* `skipValidation`: Optional. When `true`, disables validation of mappings as
they are added. This can improve performance but should be used with
discretion, as a last resort. Even then, one should avoid using this flag when
running tests, if possible.
```js
var generator = new sourceMap.SourceMapGenerator({
file: "my-generated-javascript-file.js",
sourceRoot: "http://example.com/app/js/"
});
```
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance.
* `sourceMapConsumer` The SourceMap.
```js
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);
```
#### SourceMapGenerator.prototype.addMapping(mapping)
Add a single mapping from original source line and column to the generated
source's line and column for this source map being created. The mapping object
should have the following properties:
* `generated`: An object with the generated line and column positions.
* `original`: An object with the original line and column positions.
* `source`: The original source file (relative to the sourceRoot).
* `name`: An optional original token name for this mapping.
```js
generator.addMapping({
source: "module-one.scm",
original: { line: 128, column: 0 },
generated: { line: 3, column: 456 }
})
```
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
Set the source content for an original source file.
* `sourceFile` the URL of the original source file.
* `sourceContent` the content of the source file.
```js
generator.setSourceContent("module-one.scm",
fs.readFileSync("path/to/module-one.scm"))
```
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])
Applies a SourceMap for a source file to the SourceMap.
Each mapping to the supplied source file is rewritten using the
supplied SourceMap. Note: The resolution for the resulting mappings
is the minimum of this map and the supplied map.
* `sourceMapConsumer`: The SourceMap to be applied.
* `sourceFile`: Optional. The filename of the source file.
If omitted, sourceMapConsumer.file will be used, if it exists.
Otherwise an error will be thrown.
* `sourceMapPath`: Optional. The dirname of the path to the SourceMap
to be applied. If relative, it is relative to the SourceMap.
This parameter is needed when the two SourceMaps aren't in the same
directory, and the SourceMap to be applied contains relative source
paths. If so, those relative source paths need to be rewritten
relative to the SourceMap.
If omitted, it is assumed that both SourceMaps are in the same directory,
thus not needing any rewriting. (Supplying `'.'` has the same effect.)
#### SourceMapGenerator.prototype.toString()
Renders the source map being generated to a string.
```js
generator.toString()
// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'
```
### SourceNode
SourceNodes provide a way to abstract over interpolating and/or concatenating
snippets of generated JavaScript source code, while maintaining the line and
column information associated between those snippets and the original source
code. This is useful as the final intermediate representation a compiler might
use before outputting the generated JS and source map.
#### new SourceNode([line, column, source[, chunk[, name]]])
* `line`: The original line number associated with this source node, or null if
it isn't associated with an original line. The line number is 1-based.
* `column`: The original column number associated with this source node, or null
if it isn't associated with an original column. The column number
is 0-based.
* `source`: The original source's filename; null if no filename is provided.
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
below.
* `name`: Optional. The original identifier.
```js
var node = new SourceNode(1, 2, "a.cpp", [
new SourceNode(3, 4, "b.cpp", "extern int status;\n"),
new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"),
new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"),
]);
```
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])
Creates a SourceNode from generated code and a SourceMapConsumer.
* `code`: The generated code
* `sourceMapConsumer` The SourceMap for the generated code
* `relativePath` The optional path that relative sources in `sourceMapConsumer`
should be relative to.
```js
var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"),
consumer);
```
#### SourceNode.prototype.add(chunk)
Add a chunk of generated JS to this source node.
* `chunk`: A string snippet of generated JS code, another instance of
`SourceNode`, or an array where each member is one of those things.
```js
node.add(" + ");
node.add(otherNode);
node.add([leftHandOperandNode, " + ", rightHandOperandNode]);
```
#### SourceNode.prototype.prepend(chunk)
Prepend a chunk of generated JS to this source node.
* `chunk`: A string snippet of generated JS code, another instance of
`SourceNode`, or an array where each member is one of those things.
```js
node.prepend("/** Build Id: f783haef86324gf **/\n\n");
```
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
Set the source content for a source file. This will be added to the
`SourceMap` in the `sourcesContent` field.
* `sourceFile`: The filename of the source file
* `sourceContent`: The content of the source file
```js
node.setSourceContent("module-one.scm",
fs.readFileSync("path/to/module-one.scm"))
```
#### SourceNode.prototype.walk(fn)
Walk over the tree of JS snippets in this node and its children. The walking
function is called once for each snippet of JS and is passed that snippet and
the its original associated source's line/column location.
* `fn`: The traversal function.
```js
var node = new SourceNode(1, 2, "a.js", [
new SourceNode(3, 4, "b.js", "uno"),
"dos",
[
"tres",
new SourceNode(5, 6, "c.js", "quatro")
]
]);
node.walk(function (code, loc) { console.log("WALK:", code, loc); })
// WALK: uno { source: 'b.js', line: 3, column: 4, name: null }
// WALK: dos { source: 'a.js', line: 1, column: 2, name: null }
// WALK: tres { source: 'a.js', line: 1, column: 2, name: null }
// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }
```
#### SourceNode.prototype.walkSourceContents(fn)
Walk over the tree of SourceNodes. The walking function is called for each
source file content and is passed the filename and source content.
* `fn`: The traversal function.
```js
var a = new SourceNode(1, 2, "a.js", "generated from a");
a.setSourceContent("a.js", "original a");
var b = new SourceNode(1, 2, "b.js", "generated from b");
b.setSourceContent("b.js", "original b");
var c = new SourceNode(1, 2, "c.js", "generated from c");
c.setSourceContent("c.js", "original c");
var node = new SourceNode(null, null, null, [a, b, c]);
node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); })
// WALK: a.js : original a
// WALK: b.js : original b
// WALK: c.js : original c
```
#### SourceNode.prototype.join(sep)
Like `Array.prototype.join` except for SourceNodes. Inserts the separator
between each of this source node's children.
* `sep`: The separator.
```js
var lhs = new SourceNode(1, 2, "a.rs", "my_copy");
var operand = new SourceNode(3, 4, "a.rs", "=");
var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()");
var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]);
var joinedNode = node.join(" ");
```
#### SourceNode.prototype.replaceRight(pattern, replacement)
Call `String.prototype.replace` on the very right-most source snippet. Useful
for trimming white space from the end of a source node, etc.
* `pattern`: The pattern to replace.
* `replacement`: The thing to replace the pattern with.
```js
// Trim trailing white space.
node.replaceRight(/\s*$/, "");
```
#### SourceNode.prototype.toString()
Return the string representation of this source node. Walks over the tree and
concatenates all the various snippets together to one string.
```js
var node = new SourceNode(1, 2, "a.js", [
new SourceNode(3, 4, "b.js", "uno"),
"dos",
[
"tres",
new SourceNode(5, 6, "c.js", "quatro")
]
]);
node.toString()
// 'unodostresquatro'
```
#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])
Returns the string representation of this tree of source nodes, plus a
SourceMapGenerator which contains all the mappings between the generated and
original sources.
The arguments are the same as those to `new SourceMapGenerator`.
```js
var node = new SourceNode(1, 2, "a.js", [
new SourceNode(3, 4, "b.js", "uno"),
"dos",
[
"tres",
new SourceNode(5, 6, "c.js", "quatro")
]
]);
node.toStringWithSourceMap({ file: "my-output-file.js" })
// { code: 'unodostresquatro',
// map: [object SourceMapGenerator] }
```

View File

@@ -0,0 +1,73 @@
{
"name": "source-map",
"description": "Generates and consumes source maps",
"version": "0.6.1",
"homepage": "https://github.com/mozilla/source-map",
"author": "Nick Fitzgerald <nfitzgerald@mozilla.com>",
"contributors": [
"Tobias Koppers <tobias.koppers@googlemail.com>",
"Duncan Beevers <duncan@dweebd.com>",
"Stephen Crane <scrane@mozilla.com>",
"Ryan Seddon <seddon.ryan@gmail.com>",
"Miles Elam <miles.elam@deem.com>",
"Mihai Bazon <mihai.bazon@gmail.com>",
"Michael Ficarra <github.public.email@michael.ficarra.me>",
"Todd Wolfson <todd@twolfson.com>",
"Alexander Solovyov <alexander@solovyov.net>",
"Felix Gnass <fgnass@gmail.com>",
"Conrad Irwin <conrad.irwin@gmail.com>",
"usrbincc <usrbincc@yahoo.com>",
"David Glasser <glasser@davidglasser.net>",
"Chase Douglas <chase@newrelic.com>",
"Evan Wallace <evan.exe@gmail.com>",
"Heather Arthur <fayearthur@gmail.com>",
"Hugh Kennedy <hughskennedy@gmail.com>",
"David Glasser <glasser@davidglasser.net>",
"Simon Lydell <simon.lydell@gmail.com>",
"Jmeas Smith <jellyes2@gmail.com>",
"Michael Z Goddard <mzgoddard@gmail.com>",
"azu <azu@users.noreply.github.com>",
"John Gozde <john@gozde.ca>",
"Adam Kirkton <akirkton@truefitinnovation.com>",
"Chris Montgomery <christopher.montgomery@dowjones.com>",
"J. Ryan Stinnett <jryans@gmail.com>",
"Jack Herrington <jherrington@walmartlabs.com>",
"Chris Truter <jeffpalentine@gmail.com>",
"Daniel Espeset <daniel@danielespeset.com>",
"Jamie Wong <jamie.lf.wong@gmail.com>",
"Eddy Bruël <ejpbruel@mozilla.com>",
"Hawken Rives <hawkrives@gmail.com>",
"Gilad Peleg <giladp007@gmail.com>",
"djchie <djchie.dev@gmail.com>",
"Gary Ye <garysye@gmail.com>",
"Nicolas Lalevée <nicolas.lalevee@hibnet.org>"
],
"repository": {
"type": "git",
"url": "http://github.com/mozilla/source-map.git"
},
"main": "./source-map.js",
"files": [
"source-map.js",
"source-map.d.ts",
"lib/",
"dist/source-map.debug.js",
"dist/source-map.js",
"dist/source-map.min.js",
"dist/source-map.min.js.map"
],
"engines": {
"node": ">=0.10.0"
},
"license": "BSD-3-Clause",
"scripts": {
"test": "npm run build && node test/run-tests.js",
"build": "webpack --color",
"toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md"
},
"devDependencies": {
"doctoc": "^0.15.0",
"webpack": "^1.12.0"
},
"typings": "source-map"
}

View File

@@ -0,0 +1,98 @@
export interface StartOfSourceMap {
file?: string;
sourceRoot?: string;
}
export interface RawSourceMap extends StartOfSourceMap {
version: string;
sources: string[];
names: string[];
sourcesContent?: string[];
mappings: string;
}
export interface Position {
line: number;
column: number;
}
export interface LineRange extends Position {
lastColumn: number;
}
export interface FindPosition extends Position {
// SourceMapConsumer.GREATEST_LOWER_BOUND or SourceMapConsumer.LEAST_UPPER_BOUND
bias?: number;
}
export interface SourceFindPosition extends FindPosition {
source: string;
}
export interface MappedPosition extends Position {
source: string;
name?: string;
}
export interface MappingItem {
source: string;
generatedLine: number;
generatedColumn: number;
originalLine: number;
originalColumn: number;
name: string;
}
export class SourceMapConsumer {
static GENERATED_ORDER: number;
static ORIGINAL_ORDER: number;
static GREATEST_LOWER_BOUND: number;
static LEAST_UPPER_BOUND: number;
constructor(rawSourceMap: RawSourceMap);
computeColumnSpans(): void;
originalPositionFor(generatedPosition: FindPosition): MappedPosition;
generatedPositionFor(originalPosition: SourceFindPosition): LineRange;
allGeneratedPositionsFor(originalPosition: MappedPosition): Position[];
hasContentsOfAllSources(): boolean;
sourceContentFor(source: string, returnNullOnMissing?: boolean): string;
eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void;
}
export interface Mapping {
generated: Position;
original: Position;
source: string;
name?: string;
}
export class SourceMapGenerator {
constructor(startOfSourceMap?: StartOfSourceMap);
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
addMapping(mapping: Mapping): void;
setSourceContent(sourceFile: string, sourceContent: string): void;
applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void;
toString(): string;
}
export interface CodeWithSourceMap {
code: string;
map: SourceMapGenerator;
}
export class SourceNode {
constructor();
constructor(line: number, column: number, source: string);
constructor(line: number, column: number, source: string, chunk?: string, name?: string);
static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode;
add(chunk: string): void;
prepend(chunk: string): void;
setSourceContent(sourceFile: string, sourceContent: string): void;
walk(fn: (chunk: string, mapping: MappedPosition) => void): void;
walkSourceContents(fn: (file: string, content: string) => void): void;
join(sep: string): SourceNode;
replaceRight(pattern: string, replacement: string): SourceNode;
toString(): string;
toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap;
}

View File

@@ -0,0 +1,8 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./lib/source-node').SourceNode;

56
frontend/node_modules/resolve-url-loader/package.json generated vendored Normal file
View File

@@ -0,0 +1,56 @@
{
"name": "resolve-url-loader",
"version": "4.0.0",
"description": "Webpack loader that resolves relative paths in url() statements based on the original source file",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/bholloway/resolve-url-loader.git",
"directory": "packages/resolve-url-loader"
},
"keywords": [
"webpack",
"loader",
"css",
"normalize",
"rewrite",
"resolve",
"url",
"sass",
"relative",
"file"
],
"author": "bholloway",
"license": "MIT",
"bugs": {
"url": "https://github.com/bholloway/resolve-url-loader/issues"
},
"homepage": "https://github.com/bholloway/resolve-url-loader/tree/v4-maintenance/packages/resolve-url-loader",
"engines": {
"node": ">=8.9"
},
"files": [
"index.js",
"lib/**/+([a-z-]).js",
"docs/**/*.*"
],
"dependencies": {
"adjust-sourcemap-loader": "^4.0.0",
"convert-source-map": "^1.7.0",
"loader-utils": "^2.0.0",
"postcss": "^7.0.35",
"source-map": "0.6.1"
},
"peerDependencies": {
"rework": "1.0.1",
"rework-visit": "1.0.0"
},
"peerDependenciesMeta": {
"rework": {
"optional": true
},
"rework-visit": {
"optional": true
}
}
}