2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+115
View File
@@ -0,0 +1,115 @@
### uni-stacktracey 使用说明
#### 引用方式
```js
const {
sourcemap: { stacktracey, uniStracktraceyPreset, utsStracktraceyPreset },
} = require('${HBuilderX}/plugins/uniapp-cli-vite')
```
#### stacktracey 方法
**stacktracey 方法有两个参数:**
1. stacktrace
2. opts
##### stacktrace 参数说明
> 一个错误堆栈。String 类型
**示例**
```js
// js 错误堆栈
const uniErrorMsg = `Error: Sentry Error
at a.throwError(/static/js/pages-index-index.3ab0d0e5.js:1:567)
at click(/static/js/pages-index-index.3ab0d0e5.js:1:2745)
at ee(/static/js/chunk-vendors.75525bd5.js:34:11927)
at n(/static/js/chunk-vendors.75525bd5.js:34:13747)
at ee(/static/js/chunk-vendors.75525bd5.js:34:11927)
at HTMLElement.n(/static/js/chunk-vendors.75525bd5.js:34:13824)
at HTMLElement.o._wrapper(/static/js/chunk-vendors.75525bd5.js:34:53966)
at HTMLElement.i(/static/js/chunk-vendors.75525bd5.js:7:609894)`
// uts 错误堆栈
const utsErrorMsg = `e: DCloud-UTSPlugin/android/src/io/dcloud/uniplugin/TestModule.kt: (9, 5): Unresolved reference: logxxxxxxx
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':nativeplugins:DCloud-UTSPlugin:compileReleaseKotlin'.
> Compilation error. See log for more details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
`
```
#### opts 参数说明
> 解析生成错误栈时需要用到的一些方法。
> 此处提供了生成该参数的两种预设方案:uniStracktraceyPreset、utsStracktraceyPreset
**预设一:`uniStracktraceyPreset`**
> 解析 js 错误栈的预设方案
```js
// 调用方式
stacktracey(uniErrorMsg, {
preset: uniStracktraceyPreset({
base: path.resolve(__dirname, './__UNI__APPID__/1.0.0/.sourcemap/h5/'),
sourceRoot: '',
}),
}).then((stacktrace) => {
// stacktrace 即为解析 sourcemap 后的错误信息
console.log('stacktrace :>> ', stacktrace)
})
```
**预设二:`utsStracktraceyPreset`**
> 解析 uts 错误栈的预设方案
```js
// 调用方式
stacktracey(utsErrorMsg, {
preset: utsStracktraceyPreset({
base: path.resolve(
__dirname,
'./nativeplugins-sourceMap/DCloud-UTSPlugin/'
),
sourceRoot: 'DCloud-UTSPlugin/android/src/',
}),
}).then((stacktrace) => {
// stacktrace 即为解析 sourcemap 后的错误信息
console.log('stacktrace :>> ', stacktrace)
})
```
**预设方案的参数说明**
> 需要使用 base 和 sourceRoot 从错误信息中生成 sourcemap 路径。sourceRoot 即为需要将 错误信息路径替换为 base 的部分。
1. `base`:当前项目 `sourcemap` 文件绝对路径。如果由 `http:、https:` 开头,则会发送网络请求获取
2. `sourceRoot`:当前项目资源路径
3. 详细说明
> 由上述 stacktrace 参数说明中 `utsErrorMsg` 为例
>
> 错误信息为 e: DCloud-UTSPlugin/android/src/io/dcloud/uniplugin/TestModule.kt: (9, 5): Unresolved reference: logxxxxxxx
- 第一步:根据 `sourceRoot` 解析出包含 path 的 fileName
- 比如,`sourceRoot` 参数为:`DCloud-UTSPlugin/android/src/`
- 解析出的 `fileName` 为:`io/dcloud/uniplugin/TestModule.kt`
- 第二步:根据 `base + fileName` 参数拼接出 `sourcemap` 路径
- 比如,`base` 参数为:`C:/project/test-uni/.sourcemap/`
- 解析出的 `sourcemap` 路径为 `C:/project/test-uni/.sourcemap/io/dcloud/uniplugin/TestModule.kt.map`
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+28
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.
+822
View File
@@ -0,0 +1,822 @@
# Source Map
[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map)
[![Coverage Status](https://coveralls.io/repos/github/mozilla/source-map/badge.svg)](https://coveralls.io/github/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://unpkg.com/source-map@0.7.3/dist/source-map.js"></script>
<script>
sourceMap.SourceMapConsumer.initialize({
"lib/mappings.wasm": "https://unpkg.com/source-map@0.7.3/lib/mappings.wasm"
});
</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)
- [SourceMapConsumer.initialize(options)](#sourcemapconsumerinitializeoptions)
- [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap)
- [SourceMapConsumer.with](#sourcemapconsumerwith)
- [SourceMapConsumer.prototype.destroy()](#sourcemapconsumerprototypedestroy)
- [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
const 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'
};
const whatever = await SourceMapConsumer.with(rawSourceMap, null, consumer => {
console.log(consumer.sources);
// [ 'http://example.com/www/js/one.js',
// 'http://example.com/www/js/two.js' ]
console.log(consumer.originalPositionFor({
line: 2,
column: 28
}));
// { source: 'http://example.com/www/js/two.js',
// line: 2,
// column: 10,
// name: 'n' }
console.log(consumer.generatedPositionFor({
source: 'http://example.com/www/js/two.js',
line: 2,
column: 10
}));
// { line: 2, column: 28 }
consumer.eachMapping(function (m) {
// ...
});
return computeWhatever();
});
```
### 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.
#### SourceMapConsumer.initialize(options)
When using `SourceMapConsumer` outside of node.js, for example on the Web, it
needs to know from what URL to load `lib/mappings.wasm`. You must inform it by
calling `initialize` before constructing any `SourceMapConsumer`s.
The options object has the following properties:
* `"lib/mappings.wasm"`: A `String` containing the URL of the
`lib/mappings.wasm` file, or an `ArrayBuffer` with the contents of `lib/mappings.wasm`.
```js
sourceMap.SourceMapConsumer.initialize({
"lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm"
});
```
#### 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.
The promise of the constructed souce map consumer is returned.
When the `SourceMapConsumer` will no longer be used anymore, you must call its
`destroy` method.
```js
const consumer = await new sourceMap.SourceMapConsumer(rawSourceMapJsonData);
doStuffWith(consumer);
consumer.destroy();
```
Alternatively, you can use `SourceMapConsumer.with` to avoid needing to remember
to call `destroy`.
#### SourceMapConsumer.with
Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl`
(see the `SourceMapConsumer` constructor for details. Then, invoke the `async
function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait
for `f` to complete, call `destroy` on the consumer, and return `f`'s return
value.
You must not use the consumer after `f` completes!
By using `with`, you do not have to remember to manually call `destroy` on
the consumer, since it will be called automatically once `f` completes.
```js
const xSquared = await SourceMapConsumer.with(
myRawSourceMap,
null,
async function (consumer) {
// Use `consumer` inside here and don't worry about remembering
// to call `destroy`.
const x = await whatever(consumer);
return x * x;
}
);
// You may not use that `consumer` anymore out here; it has
// been destroyed. But you can use `xSquared`.
console.log(xSquared);
```
#### SourceMapConsumer.prototype.destroy()
Free this source map consumer's associated wasm data that is manually-managed.
```js
consumer.destroy();
```
Alternatively, you can use `SourceMapConsumer.with` to avoid needing to remember
to call `destroy`.
#### 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
const consumer = await new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8"));
const 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] }
```
File diff suppressed because one or more lines are too long
+100
View File
@@ -0,0 +1,100 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
/**
* A data structure which is a combination of an array and a set. Adding a new
* member is O(1), testing for membership is O(1), and finding the index of an
* element is O(1). Removing elements from the set is not supported. Only
* strings are supported for membership.
*/
class ArraySet {
constructor() {
this._array = []
this._set = new Map()
}
/**
* Static method for creating ArraySet instances from an existing array.
*/
static fromArray(aArray, aAllowDuplicates) {
const set = new ArraySet()
for (let i = 0, len = aArray.length; i < len; i++) {
set.add(aArray[i], aAllowDuplicates)
}
return set
}
/**
* Return how many unique items are in this ArraySet. If duplicates have been
* added, than those do not count towards the size.
*
* @returns Number
*/
size() {
return this._set.size
}
/**
* Add the given string to this set.
*
* @param String aStr
*/
add(aStr, aAllowDuplicates) {
const isDuplicate = this.has(aStr)
const idx = this._array.length
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr)
}
if (!isDuplicate) {
this._set.set(aStr, idx)
}
}
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
has(aStr) {
return this._set.has(aStr)
}
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
indexOf(aStr) {
const idx = this._set.get(aStr)
if (idx >= 0) {
return idx
}
throw new Error('"' + aStr + '" is not in the set.')
}
/**
* What is the element at the given index?
*
* @param Number aIdx
*/
at(aIdx) {
if (aIdx >= 0 && aIdx < this._array.length) {
return this._array[aIdx]
}
throw new Error('No element indexed by ' + aIdx)
}
/**
* Returns the array representation of this set (which has the proper indices
* indicated by indexOf). Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state.
*/
toArray() {
return this._array.slice()
}
}
exports.ArraySet = ArraySet
+107
View File
@@ -0,0 +1,107 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler:
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors. 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 name of Google Inc. nor the names of its
* 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
* OWNER 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.
*/
const base64 = require('./base64')
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
const VLQ_BASE_SHIFT = 5
// binary: 100000
const VLQ_BASE = 1 << VLQ_BASE_SHIFT
// binary: 011111
const VLQ_BASE_MASK = VLQ_BASE - 1
// binary: 100000
const VLQ_CONTINUATION_BIT = VLQ_BASE
/**
* Converts from a two-complement value to a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0
}
/**
* Converts to a two-complement value from a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
// eslint-disable-next-line no-unused-vars
function fromVLQSigned(aValue) {
const isNegative = (aValue & 1) === 1
const shifted = aValue >> 1
return isNegative ? -shifted : shifted
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
let encoded = ''
let digit
let vlq = toVLQSigned(aValue)
do {
digit = vlq & VLQ_BASE_MASK
vlq >>>= VLQ_BASE_SHIFT
if (vlq > 0) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ_CONTINUATION_BIT
}
encoded += base64.encode(digit)
} while (vlq > 0)
return encoded
}
+19
View File
@@ -0,0 +1,19 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
const intToCharMap =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('')
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function (number) {
if (0 <= number && number < intToCharMap.length) {
return intToCharMap[number]
}
throw new TypeError('Must be between 0 and 63: ' + number)
}
@@ -0,0 +1,113 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.GREATEST_LOWER_BOUND = 1
exports.LEAST_UPPER_BOUND = 2
/**
* Recursive implementation of binary search.
*
* @param aLow Indices here and lower do not contain the needle.
* @param aHigh Indices here and higher do not contain the needle.
* @param aNeedle The element being searched for.
* @param aHaystack The non-empty array being searched.
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
* 'binarySearch.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.
*/
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
// This function terminates when one of the following is true:
//
// 1. We find the exact element we are looking for.
//
// 2. We did not find the exact element, but we can return the index of
// the next-closest element.
//
// 3. We did not find the exact element, and there is no next-closest
// element than the one we are searching for, so we return -1.
const mid = Math.floor((aHigh - aLow) / 2) + aLow
const cmp = aCompare(aNeedle, aHaystack[mid], true)
if (cmp === 0) {
// Found the element we are looking for.
return mid
} else if (cmp > 0) {
// Our needle is greater than aHaystack[mid].
if (aHigh - mid > 1) {
// The element is in the upper half.
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias)
}
// The exact needle element was not found in this haystack. Determine if
// we are in termination case (3) or (2) and return the appropriate thing.
if (aBias == exports.LEAST_UPPER_BOUND) {
return aHigh < aHaystack.length ? aHigh : -1
}
return mid
}
// Our needle is less than aHaystack[mid].
if (mid - aLow > 1) {
// The element is in the lower half.
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias)
}
// we are in termination case (3) or (2) and return the appropriate thing.
if (aBias == exports.LEAST_UPPER_BOUND) {
return mid
}
return aLow < 0 ? -1 : aLow
}
/**
* This is an implementation of binary search which will always try and return
* the index of the closest element if there is no exact hit. This is because
* mappings between original and generated line/col pairs are single points,
* and there is an implicit region between each of them, so a miss just means
* that you aren't on the very start of a region.
*
* @param aNeedle The element you are looking for.
* @param aHaystack The array that is being searched.
* @param aCompare A function which takes the needle and an element in the
* array and returns -1, 0, or 1 depending on whether the needle is less
* than, equal to, or greater than the element, respectively.
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
* 'binarySearch.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 'binarySearch.GREATEST_LOWER_BOUND'.
*/
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
if (aHaystack.length === 0) {
return -1
}
let index = recursiveSearch(
-1,
aHaystack.length,
aNeedle,
aHaystack,
aCompare,
aBias || exports.GREATEST_LOWER_BOUND
)
if (index < 0) {
return -1
}
// We have found either the exact element, or the next-closest element than
// the one we are searching for. However, there may be more than one such
// element. Make sure we always return the smallest of these.
while (index - 1 >= 0) {
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
break
}
--index
}
return index
}
@@ -0,0 +1,83 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2014 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
const util = require('./util')
/**
* Determine whether mappingB is after mappingA with respect to generated
* position.
*/
function generatedPositionAfter(mappingA, mappingB) {
// Optimized for most common case
const lineA = mappingA.generatedLine
const lineB = mappingB.generatedLine
const columnA = mappingA.generatedColumn
const columnB = mappingB.generatedColumn
return (
lineB > lineA ||
(lineB == lineA && columnB >= columnA) ||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0
)
}
/**
* A data structure to provide a sorted view of accumulated mappings in a
* performance conscious manner. It trades a negligible overhead in general
* case for a large speedup in case of mappings being added in order.
*/
class MappingList {
constructor() {
this._array = []
this._sorted = true
// Serves as infimum
this._last = { generatedLine: -1, generatedColumn: 0 }
}
/**
* Iterate through internal items. This method takes the same arguments that
* `Array.prototype.forEach` takes.
*
* NOTE: The order of the mappings is NOT guaranteed.
*/
unsortedForEach(aCallback, aThisArg) {
this._array.forEach(aCallback, aThisArg)
}
/**
* Add the given source mapping.
*
* @param Object aMapping
*/
add(aMapping) {
if (generatedPositionAfter(this._last, aMapping)) {
this._last = aMapping
this._array.push(aMapping)
} else {
this._sorted = false
this._array.push(aMapping)
}
}
/**
* Returns the flat, sorted array of mappings. The mappings are sorted by
* generated position.
*
* WARNING: This method returns internal data without copying, for
* performance. The return value must NOT be mutated, and should be treated as
* an immutable borrow. If you want to take ownership, you must make your own
* copy.
*/
toArray() {
if (!this._sorted) {
this._array.sort(util.compareByGeneratedPositionsInflated)
this._sorted = true
}
return this._array
}
}
exports.MappingList = MappingList
Binary file not shown.
+51
View File
@@ -0,0 +1,51 @@
/* Determine browser vs node environment by testing the default top level context. Solution courtesy of: https://stackoverflow.com/questions/17575790/environment-detection-node-js-or-browser */
if (__PLATFORM_WEB__) {
// Web version of reading a wasm file into an array buffer.
let mappingsWasm = null
module.exports = function readWasm() {
if (typeof mappingsWasm === 'string') {
return fetch(mappingsWasm).then((response) => response.arrayBuffer())
}
if (mappingsWasm instanceof ArrayBuffer) {
return Promise.resolve(mappingsWasm)
}
throw new Error(
'You must provide the string URL or ArrayBuffer contents ' +
'of lib/mappings.wasm by calling ' +
"SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) " +
'before using SourceMapConsumer'
)
}
module.exports.initialize = (input) => (mappingsWasm = input)
} else {
// Node version of reading a wasm file into an array buffer.
const fs = require('fs')
const path = require('path')
module.exports = function readWasm() {
return new Promise((resolve, reject) => {
const wasmPath = path.join(
__dirname,
'../lib/source-map/lib',
'mappings.wasm'
)
fs.readFile(wasmPath, null, (error, data) => {
if (error) {
reject(error)
return
}
resolve(data.buffer)
})
})
}
module.exports.initialize = (_) => {
console.debug(
'SourceMapConsumer.initialize is a no-op when running in node.js'
)
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,439 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
const base64VLQ = require('./base64-vlq')
const util = require('./util')
const ArraySet = require('./array-set').ArraySet
const MappingList = require('./mapping-list').MappingList
/**
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally. You may pass an object with the following
* properties:
*
* - file: The filename of the generated source.
* - sourceRoot: A root for all relative URLs in this source map.
*/
class SourceMapGenerator {
constructor(aArgs) {
if (!aArgs) {
aArgs = {}
}
this._file = util.getArg(aArgs, 'file', null)
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null)
this._skipValidation = util.getArg(aArgs, 'skipValidation', false)
this._sources = new ArraySet()
this._names = new ArraySet()
this._mappings = new MappingList()
this._sourcesContents = null
}
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param aSourceMapConsumer The SourceMap.
*/
static fromSourceMap(aSourceMapConsumer) {
const sourceRoot = aSourceMapConsumer.sourceRoot
const generator = new SourceMapGenerator({
file: aSourceMapConsumer.file,
sourceRoot,
})
aSourceMapConsumer.eachMapping(function (mapping) {
const newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn,
},
}
if (mapping.source != null) {
newMapping.source = mapping.source
if (sourceRoot != null) {
newMapping.source = util.relative(sourceRoot, newMapping.source)
}
newMapping.original = {
line: mapping.originalLine,
column: mapping.originalColumn,
}
if (mapping.name != null) {
newMapping.name = mapping.name
}
}
generator.addMapping(newMapping)
})
aSourceMapConsumer.sources.forEach(function (sourceFile) {
let sourceRelative = sourceFile
if (sourceRoot !== null) {
sourceRelative = util.relative(sourceRoot, sourceFile)
}
if (!generator._sources.has(sourceRelative)) {
generator._sources.add(sourceRelative)
}
const content = aSourceMapConsumer.sourceContentFor(sourceFile)
if (content != null) {
generator.setSourceContent(sourceFile, content)
}
})
return generator
}
/**
* 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.
*/
addMapping(aArgs) {
const generated = util.getArg(aArgs, 'generated')
const original = util.getArg(aArgs, 'original', null)
let source = util.getArg(aArgs, 'source', null)
let name = util.getArg(aArgs, 'name', null)
if (!this._skipValidation) {
this._validateMapping(generated, original, source, name)
}
if (source != null) {
source = String(source)
if (!this._sources.has(source)) {
this._sources.add(source)
}
}
if (name != null) {
name = String(name)
if (!this._names.has(name)) {
this._names.add(name)
}
}
this._mappings.add({
generatedLine: generated.line,
generatedColumn: generated.column,
originalLine: original != null && original.line,
originalColumn: original != null && original.column,
source,
name,
})
}
/**
* Set the source content for a source file.
*/
setSourceContent(aSourceFile, aSourceContent) {
let source = aSourceFile
if (this._sourceRoot != null) {
source = util.relative(this._sourceRoot, source)
}
if (aSourceContent != null) {
// Add the source content to the _sourcesContents map.
// Create a new _sourcesContents map if the property is null.
if (!this._sourcesContents) {
this._sourcesContents = Object.create(null)
}
this._sourcesContents[util.toSetString(source)] = aSourceContent
} else if (this._sourcesContents) {
// Remove the source file from the _sourcesContents map.
// If the _sourcesContents map is empty, set the property to null.
delete this._sourcesContents[util.toSetString(source)]
if (Object.keys(this._sourcesContents).length === 0) {
this._sourcesContents = null
}
}
}
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param aSourceMapConsumer The source map to be applied.
* @param aSourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
* @param aSourceMapPath Optional. The dirname of the path to the source map
* to be applied. If relative, it is relative to the SourceMapConsumer.
* This parameter is needed when the two source maps aren't in the same
* directory, and the source map to be applied contains relative source
* paths. If so, those relative source paths need to be rewritten
* relative to the SourceMapGenerator.
*/
applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
let sourceFile = aSourceFile
// If aSourceFile is omitted, we will use the file property of the SourceMap
if (aSourceFile == null) {
if (aSourceMapConsumer.file == null) {
throw new Error(
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
'or the source map\'s "file" property. Both were omitted.'
)
}
sourceFile = aSourceMapConsumer.file
}
const sourceRoot = this._sourceRoot
// Make "sourceFile" relative if an absolute Url is passed.
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile)
}
// Applying the SourceMap can add and remove items from the sources and
// the names array.
const newSources =
this._mappings.toArray().length > 0 ? new ArraySet() : this._sources
const newNames = new ArraySet()
// Find mappings for the "sourceFile"
this._mappings.unsortedForEach(function (mapping) {
if (mapping.source === sourceFile && mapping.originalLine != null) {
// Check if it can be mapped by the source map, then update the mapping.
const original = aSourceMapConsumer.originalPositionFor({
line: mapping.originalLine,
column: mapping.originalColumn,
})
if (original.source != null) {
// Copy mapping
mapping.source = original.source
if (aSourceMapPath != null) {
mapping.source = util.join(aSourceMapPath, mapping.source)
}
if (sourceRoot != null) {
mapping.source = util.relative(sourceRoot, mapping.source)
}
mapping.originalLine = original.line
mapping.originalColumn = original.column
if (original.name != null) {
mapping.name = original.name
}
}
}
const source = mapping.source
if (source != null && !newSources.has(source)) {
newSources.add(source)
}
const name = mapping.name
if (name != null && !newNames.has(name)) {
newNames.add(name)
}
}, this)
this._sources = newSources
this._names = newNames
// Copy sourcesContents of applied map.
aSourceMapConsumer.sources.forEach(function (srcFile) {
const content = aSourceMapConsumer.sourceContentFor(srcFile)
if (content != null) {
if (aSourceMapPath != null) {
srcFile = util.join(aSourceMapPath, srcFile)
}
if (sourceRoot != null) {
srcFile = util.relative(sourceRoot, srcFile)
}
this.setSourceContent(srcFile, content)
}
}, this)
}
/**
* A mapping can have one of the three levels of data:
*
* 1. Just the generated position.
* 2. The Generated position, original position, and original source.
* 3. Generated and original position, original source, as well as a name
* token.
*
* To maintain consistency, we validate that any new mapping being added falls
* in to one of these categories.
*/
_validateMapping(aGenerated, aOriginal, aSource, aName) {
// When aOriginal is truthy but has empty values for .line and .column,
// it is most likely a programmer error. In this case we throw a very
// specific error message to try to guide them the right way.
// For example: https://github.com/Polymer/polymer-bundler/pull/519
if (
aOriginal &&
typeof aOriginal.line !== 'number' &&
typeof aOriginal.column !== 'number'
) {
throw new Error(
'original.line and original.column are not numbers -- you probably meant to omit ' +
'the original mapping entirely and only map the generated position. If so, pass ' +
'null for the original mapping instead of an object with empty or null values.'
)
}
if (
aGenerated &&
'line' in aGenerated &&
'column' in aGenerated &&
aGenerated.line > 0 &&
aGenerated.column >= 0 &&
!aOriginal &&
!aSource &&
!aName
) {
// Case 1.
} else if (
aGenerated &&
'line' in aGenerated &&
'column' in aGenerated &&
aOriginal &&
'line' in aOriginal &&
'column' in aOriginal &&
aGenerated.line > 0 &&
aGenerated.column >= 0 &&
aOriginal.line > 0 &&
aOriginal.column >= 0 &&
aSource
) {
// Cases 2 and 3.
} else {
throw new Error(
'Invalid mapping: ' +
JSON.stringify({
generated: aGenerated,
source: aSource,
original: aOriginal,
name: aName,
})
)
}
}
/**
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format.
*/
_serializeMappings() {
let previousGeneratedColumn = 0
let previousGeneratedLine = 1
let previousOriginalColumn = 0
let previousOriginalLine = 0
let previousName = 0
let previousSource = 0
let result = ''
let next
let mapping
let nameIdx
let sourceIdx
const mappings = this._mappings.toArray()
for (let i = 0, len = mappings.length; i < len; i++) {
mapping = mappings[i]
next = ''
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0
while (mapping.generatedLine !== previousGeneratedLine) {
next += ';'
previousGeneratedLine++
}
} else if (i > 0) {
if (
!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])
) {
continue
}
next += ','
}
next += base64VLQ.encode(
mapping.generatedColumn - previousGeneratedColumn
)
previousGeneratedColumn = mapping.generatedColumn
if (mapping.source != null) {
sourceIdx = this._sources.indexOf(mapping.source)
next += base64VLQ.encode(sourceIdx - previousSource)
previousSource = sourceIdx
// lines are stored 0-based in SourceMap spec version 3
next += base64VLQ.encode(
mapping.originalLine - 1 - previousOriginalLine
)
previousOriginalLine = mapping.originalLine - 1
next += base64VLQ.encode(
mapping.originalColumn - previousOriginalColumn
)
previousOriginalColumn = mapping.originalColumn
if (mapping.name != null) {
nameIdx = this._names.indexOf(mapping.name)
next += base64VLQ.encode(nameIdx - previousName)
previousName = nameIdx
}
}
result += next
}
return result
}
_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null
}
if (aSourceRoot != null) {
source = util.relative(aSourceRoot, source)
}
const key = util.toSetString(source)
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
? this._sourcesContents[key]
: null
}, this)
}
/**
* Externalize the source map.
*/
toJSON() {
const map = {
version: this._version,
sources: this._sources.toArray(),
names: this._names.toArray(),
mappings: this._serializeMappings(),
}
if (this._file != null) {
map.file = this._file
}
if (this._sourceRoot != null) {
map.sourceRoot = this._sourceRoot
}
if (this._sourcesContents) {
map.sourcesContent = this._generateSourcesContent(
map.sources,
map.sourceRoot
)
}
return map
}
/**
* Render the source map being generated to a string.
*/
toString() {
return JSON.stringify(this.toJSON())
}
}
SourceMapGenerator.prototype._version = 3
exports.SourceMapGenerator = SourceMapGenerator
@@ -0,0 +1,430 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
const SourceMapGenerator = require('./source-map-generator').SourceMapGenerator
const util = require('./util')
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
const REGEX_NEWLINE = /(\r?\n)/
// Newline character code for charCodeAt() comparisons
const NEWLINE_CODE = 10
// Private symbol for identifying `SourceNode`s when multiple versions of
// the source-map library are loaded. This MUST NOT CHANGE across
// versions!
const isSourceNode = '$$$isSourceNode$$$'
/**
* SourceNodes provide a way to abstract over interpolating/concatenating
* snippets of generated JavaScript source code while maintaining the line and
* column information associated with the original source code.
*
* @param aLine The original line number.
* @param aColumn The original column number.
* @param aSource The original source's filename.
* @param aChunks Optional. An array of strings which are snippets of
* generated JS, or other SourceNodes.
* @param aName The original identifier.
*/
class SourceNode {
constructor(aLine, aColumn, aSource, aChunks, aName) {
this.children = []
this.sourceContents = {}
this.line = aLine == null ? null : aLine
this.column = aColumn == null ? null : aColumn
this.source = aSource == null ? null : aSource
this.name = aName == null ? null : aName
this[isSourceNode] = true
if (aChunks != null) this.add(aChunks)
}
/**
* Creates a SourceNode from generated code and a SourceMapConsumer.
*
* @param aGeneratedCode The generated code
* @param aSourceMapConsumer The SourceMap for the generated code
* @param aRelativePath Optional. The path that relative sources in the
* SourceMapConsumer should be relative to.
*/
static fromStringWithSourceMap(
aGeneratedCode,
aSourceMapConsumer,
aRelativePath
) {
// The SourceNode we want to fill with the generated code
// and the SourceMap
const node = new SourceNode()
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
// Processed fragments are accessed by calling `shiftNextLine`.
const remainingLines = aGeneratedCode.split(REGEX_NEWLINE)
let remainingLinesIndex = 0
const shiftNextLine = function () {
const lineContents = getNextLine()
// The last line of a file might not have a newline.
const newLine = getNextLine() || ''
return lineContents + newLine
function getNextLine() {
return remainingLinesIndex < remainingLines.length
? remainingLines[remainingLinesIndex++]
: undefined
}
}
// We need to remember the position of "remainingLines"
let lastGeneratedLine = 1,
lastGeneratedColumn = 0
// The generate SourceNodes we need a code range.
// To extract it current and last mapping is used.
// Here we store the last mapping.
let lastMapping = null
let nextLine
aSourceMapConsumer.eachMapping(function (mapping) {
if (lastMapping !== null) {
// We add the code from "lastMapping" to "mapping":
// First check if there is a new line in between.
if (lastGeneratedLine < mapping.generatedLine) {
// Associate first line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine())
lastGeneratedLine++
lastGeneratedColumn = 0
// The remaining code is added without mapping
} else {
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
nextLine = remainingLines[remainingLinesIndex] || ''
const code = nextLine.substr(
0,
mapping.generatedColumn - lastGeneratedColumn
)
remainingLines[remainingLinesIndex] = nextLine.substr(
mapping.generatedColumn - lastGeneratedColumn
)
lastGeneratedColumn = mapping.generatedColumn
addMappingWithCode(lastMapping, code)
// No more remaining code, continue
lastMapping = mapping
return
}
}
// We add the generated code until the first mapping
// to the SourceNode without any mapping.
// Each line is added as separate string.
while (lastGeneratedLine < mapping.generatedLine) {
node.add(shiftNextLine())
lastGeneratedLine++
}
if (lastGeneratedColumn < mapping.generatedColumn) {
nextLine = remainingLines[remainingLinesIndex] || ''
node.add(nextLine.substr(0, mapping.generatedColumn))
remainingLines[remainingLinesIndex] = nextLine.substr(
mapping.generatedColumn
)
lastGeneratedColumn = mapping.generatedColumn
}
lastMapping = mapping
}, this)
// We have processed all mappings.
if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine())
}
// and add the remaining lines without any mapping
node.add(remainingLines.splice(remainingLinesIndex).join(''))
}
// Copy sourcesContent into SourceNode
aSourceMapConsumer.sources.forEach(function (sourceFile) {
const content = aSourceMapConsumer.sourceContentFor(sourceFile)
if (content != null) {
if (aRelativePath != null) {
sourceFile = util.join(aRelativePath, sourceFile)
}
node.setSourceContent(sourceFile, content)
}
})
return node
function addMappingWithCode(mapping, code) {
if (mapping === null || mapping.source === undefined) {
node.add(code)
} else {
const source = aRelativePath
? util.join(aRelativePath, mapping.source)
: mapping.source
node.add(
new SourceNode(
mapping.originalLine,
mapping.originalColumn,
source,
code,
mapping.name
)
)
}
}
}
/**
* Add a chunk of generated JS to this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
add(aChunk) {
if (Array.isArray(aChunk)) {
aChunk.forEach(function (chunk) {
this.add(chunk)
}, this)
} else if (aChunk[isSourceNode] || typeof aChunk === 'string') {
if (aChunk) {
this.children.push(aChunk)
}
} else {
throw new TypeError(
'Expected a SourceNode, string, or an array of SourceNodes and strings. Got ' +
aChunk
)
}
return this
}
/**
* Add a chunk of generated JS to the beginning of this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
prepend(aChunk) {
if (Array.isArray(aChunk)) {
for (let i = aChunk.length - 1; i >= 0; i--) {
this.prepend(aChunk[i])
}
} else if (aChunk[isSourceNode] || typeof aChunk === 'string') {
this.children.unshift(aChunk)
} else {
throw new TypeError(
'Expected a SourceNode, string, or an array of SourceNodes and strings. Got ' +
aChunk
)
}
return this
}
/**
* 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.
*
* @param aFn The traversal function.
*/
walk(aFn) {
let chunk
for (let i = 0, len = this.children.length; i < len; i++) {
chunk = this.children[i]
if (chunk[isSourceNode]) {
chunk.walk(aFn)
} else if (chunk !== '') {
aFn(chunk, {
source: this.source,
line: this.line,
column: this.column,
name: this.name,
})
}
}
}
/**
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
* each of `this.children`.
*
* @param aSep The separator.
*/
join(aSep) {
let newChildren
let i
const len = this.children.length
if (len > 0) {
newChildren = []
for (i = 0; i < len - 1; i++) {
newChildren.push(this.children[i])
newChildren.push(aSep)
}
newChildren.push(this.children[i])
this.children = newChildren
}
return this
}
/**
* Call String.prototype.replace on the very right-most source snippet. Useful
* for trimming whitespace from the end of a source node, etc.
*
* @param aPattern The pattern to replace.
* @param aReplacement The thing to replace the pattern with.
*/
replaceRight(aPattern, aReplacement) {
const lastChild = this.children[this.children.length - 1]
if (lastChild[isSourceNode]) {
lastChild.replaceRight(aPattern, aReplacement)
} else if (typeof lastChild === 'string') {
this.children[this.children.length - 1] = lastChild.replace(
aPattern,
aReplacement
)
} else {
this.children.push(''.replace(aPattern, aReplacement))
}
return this
}
/**
* Set the source content for a source file. This will be added to the SourceMapGenerator
* in the sourcesContent field.
*
* @param aSourceFile The filename of the source file
* @param aSourceContent The content of the source file
*/
setSourceContent(aSourceFile, aSourceContent) {
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent
}
/**
* Walk over the tree of SourceNodes. The walking function is called for each
* source file content and is passed the filename and source content.
*
* @param aFn The traversal function.
*/
walkSourceContents(aFn) {
for (let i = 0, len = this.children.length; i < len; i++) {
if (this.children[i][isSourceNode]) {
this.children[i].walkSourceContents(aFn)
}
}
const sources = Object.keys(this.sourceContents)
for (let i = 0, len = sources.length; i < len; i++) {
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]])
}
}
/**
* Return the string representation of this source node. Walks over the tree
* and concatenates all the various snippets together to one string.
*/
toString() {
let str = ''
this.walk(function (chunk) {
str += chunk
})
return str
}
/**
* Returns the string representation of this source node along with a source
* map.
*/
toStringWithSourceMap(aArgs) {
const generated = {
code: '',
line: 1,
column: 0,
}
const map = new SourceMapGenerator(aArgs)
let sourceMappingActive = false
let lastOriginalSource = null
let lastOriginalLine = null
let lastOriginalColumn = null
let lastOriginalName = null
this.walk(function (chunk, original) {
generated.code += chunk
if (
original.source !== null &&
original.line !== null &&
original.column !== null
) {
if (
lastOriginalSource !== original.source ||
lastOriginalLine !== original.line ||
lastOriginalColumn !== original.column ||
lastOriginalName !== original.name
) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column,
},
generated: {
line: generated.line,
column: generated.column,
},
name: original.name,
})
}
lastOriginalSource = original.source
lastOriginalLine = original.line
lastOriginalColumn = original.column
lastOriginalName = original.name
sourceMappingActive = true
} else if (sourceMappingActive) {
map.addMapping({
generated: {
line: generated.line,
column: generated.column,
},
})
lastOriginalSource = null
sourceMappingActive = false
}
for (let idx = 0, length = chunk.length; idx < length; idx++) {
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
generated.line++
generated.column = 0
// Mappings end at eol
if (idx + 1 === length) {
lastOriginalSource = null
sourceMappingActive = false
} else if (sourceMappingActive) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column,
},
generated: {
line: generated.line,
column: generated.column,
},
name: original.name,
})
}
} else {
generated.column++
}
}
})
this.walkSourceContents(function (sourceFile, sourceContent) {
map.setSourceContent(sourceFile, sourceContent)
})
return { code: generated.code, map }
}
}
exports.SourceNode = SourceNode
+555
View File
@@ -0,0 +1,555 @@
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) {
return aArgs[aName]
} else if (arguments.length === 3) {
return aDefaultValue
}
throw new Error('"' + aName + '" is a required argument.')
}
exports.getArg = getArg
const urlRegexp =
/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/
const dataUrlRegexp = /^data:.+\,.+$/
function urlParse(aUrl) {
const match = aUrl.match(urlRegexp)
if (!match) {
return null
}
return {
scheme: match[1],
auth: match[2],
host: match[3],
port: match[4],
path: match[5],
}
}
exports.urlParse = urlParse
function urlGenerate(aParsedUrl) {
let url = ''
if (aParsedUrl.scheme) {
url += aParsedUrl.scheme + ':'
}
url += '//'
if (aParsedUrl.auth) {
url += aParsedUrl.auth + '@'
}
if (aParsedUrl.host) {
url += aParsedUrl.host
}
if (aParsedUrl.port) {
url += ':' + aParsedUrl.port
}
if (aParsedUrl.path) {
url += aParsedUrl.path
}
return url
}
exports.urlGenerate = urlGenerate
const MAX_CACHED_INPUTS = 32
/**
* Takes some function `f(input) -> result` and returns a memoized version of
* `f`.
*
* We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The
* memoization is a dumb-simple, linear least-recently-used cache.
*/
function lruMemoize(f) {
const cache = []
return function (input) {
for (let i = 0; i < cache.length; i++) {
if (cache[i].input === input) {
const temp = cache[0]
cache[0] = cache[i]
cache[i] = temp
return cache[0].result
}
}
const result = f(input)
cache.unshift({
input,
result,
})
if (cache.length > MAX_CACHED_INPUTS) {
cache.pop()
}
return result
}
}
/**
* Normalizes a path, or the path portion of a URL:
*
* - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
* Based on code in the Node.js 'path' core module.
*
* @param aPath The path or url to normalize.
*/
const normalize = lruMemoize(function normalize(aPath) {
let path = aPath
const url = urlParse(aPath)
if (url) {
if (!url.path) {
return aPath
}
path = url.path
}
const isAbsolute = exports.isAbsolute(path)
// Split the path into parts between `/` characters. This is much faster than
// using `.split(/\/+/g)`.
const parts = []
let start = 0
let i = 0
while (true) {
start = i
i = path.indexOf('/', start)
if (i === -1) {
parts.push(path.slice(start))
break
} else {
parts.push(path.slice(start, i))
while (i < path.length && path[i] === '/') {
i++
}
}
}
let up = 0
for (i = parts.length - 1; i >= 0; i--) {
const part = parts[i]
if (part === '.') {
parts.splice(i, 1)
} else if (part === '..') {
up++
} else if (up > 0) {
if (part === '') {
// The first part is blank if the path is absolute. Trying to go
// above the root is a no-op. Therefore we can remove all '..' parts
// directly after the root.
parts.splice(i + 1, up)
up = 0
} else {
parts.splice(i, 2)
up--
}
}
}
path = parts.join('/')
if (path === '') {
path = isAbsolute ? '/' : '.'
}
if (url) {
url.path = path
return urlGenerate(url)
}
return path
})
exports.normalize = normalize
/**
* Joins two paths/URLs.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be joined with the root.
*
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
* first.
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
* is updated with the result and aRoot is returned. Otherwise the result
* is returned.
* - If aPath is absolute, the result is aPath.
* - Otherwise the two paths are joined with a slash.
* - Joining for example 'http://' and 'www.example.com' is also supported.
*/
function join(aRoot, aPath) {
if (aRoot === '') {
aRoot = '.'
}
if (aPath === '') {
aPath = '.'
}
const aPathUrl = urlParse(aPath)
const aRootUrl = urlParse(aRoot)
if (aRootUrl) {
aRoot = aRootUrl.path || '/'
}
// `join(foo, '//www.example.org')`
if (aPathUrl && !aPathUrl.scheme) {
if (aRootUrl) {
aPathUrl.scheme = aRootUrl.scheme
}
return urlGenerate(aPathUrl)
}
if (aPathUrl || aPath.match(dataUrlRegexp)) {
return aPath
}
// `join('http://', 'www.example.com')`
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
aRootUrl.host = aPath
return urlGenerate(aRootUrl)
}
const joined =
aPath.charAt(0) === '/'
? aPath
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath)
if (aRootUrl) {
aRootUrl.path = joined
return urlGenerate(aRootUrl)
}
return joined
}
exports.join = join
exports.isAbsolute = function (aPath) {
return aPath.charAt(0) === '/' || urlRegexp.test(aPath)
}
/**
* Make a path relative to a URL or another path.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be made relative to aRoot.
*/
function relative(aRoot, aPath) {
if (aRoot === '') {
aRoot = '.'
}
aRoot = aRoot.replace(/\/$/, '')
// It is possible for the path to be above the root. In this case, simply
// checking whether the root is a prefix of the path won't work. Instead, we
// need to remove components from the root one by one, until either we find
// a prefix that fits, or we run out of components to remove.
let level = 0
while (aPath.indexOf(aRoot + '/') !== 0) {
const index = aRoot.lastIndexOf('/')
if (index < 0) {
return aPath
}
// If the only part of the root that is left is the scheme (i.e. http://,
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
// have exhausted all components, so the path is not relative to the root.
aRoot = aRoot.slice(0, index)
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
return aPath
}
++level
}
// Make sure we add a "../" for each component we removed from the root.
return Array(level + 1).join('../') + aPath.substr(aRoot.length + 1)
}
exports.relative = relative
const supportsNullProto = (function () {
const obj = Object.create(null)
return !('__proto__' in obj)
})()
function identity(s) {
return s
}
/**
* Because behavior goes wacky when you set `__proto__` on objects, we
* have to prefix all the strings in our set with an arbitrary character.
*
* See https://github.com/mozilla/source-map/pull/31 and
* https://github.com/mozilla/source-map/issues/30
*
* @param String aStr
*/
function toSetString(aStr) {
if (isProtoString(aStr)) {
return '$' + aStr
}
return aStr
}
exports.toSetString = supportsNullProto ? identity : toSetString
function fromSetString(aStr) {
if (isProtoString(aStr)) {
return aStr.slice(1)
}
return aStr
}
exports.fromSetString = supportsNullProto ? identity : fromSetString
function isProtoString(s) {
if (!s) {
return false
}
const length = s.length
if (length < 9 /* "__proto__".length */) {
return false
}
/* eslint-disable no-multi-spaces */
if (
s.charCodeAt(length - 1) !== 95 /* '_' */ ||
s.charCodeAt(length - 2) !== 95 /* '_' */ ||
s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
s.charCodeAt(length - 4) !== 116 /* 't' */ ||
s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
s.charCodeAt(length - 8) !== 95 /* '_' */ ||
s.charCodeAt(length - 9) !== 95 /* '_' */
) {
return false
}
/* eslint-enable no-multi-spaces */
for (let i = length - 10; i >= 0; i--) {
if (s.charCodeAt(i) !== 36 /* '$' */) {
return false
}
}
return true
}
/**
* Comparator between two mappings where the original positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same original source/line/column, but different generated
* line and column the same. Useful when searching for a mapping with a
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
let cmp = strcmp(mappingA.source, mappingB.source)
if (cmp !== 0) {
return cmp
}
cmp = mappingA.originalLine - mappingB.originalLine
if (cmp !== 0) {
return cmp
}
cmp = mappingA.originalColumn - mappingB.originalColumn
if (cmp !== 0 || onlyCompareOriginal) {
return cmp
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn
if (cmp !== 0) {
return cmp
}
cmp = mappingA.generatedLine - mappingB.generatedLine
if (cmp !== 0) {
return cmp
}
return strcmp(mappingA.name, mappingB.name)
}
exports.compareByOriginalPositions = compareByOriginalPositions
/**
* Comparator between two mappings with deflated source and name indices where
* the generated positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same generated line and column, but different
* source/name/original line and column the same. Useful when searching for a
* mapping with a stubbed out mapping.
*/
function compareByGeneratedPositionsDeflated(
mappingA,
mappingB,
onlyCompareGenerated
) {
let cmp = mappingA.generatedLine - mappingB.generatedLine
if (cmp !== 0) {
return cmp
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn
if (cmp !== 0 || onlyCompareGenerated) {
return cmp
}
cmp = strcmp(mappingA.source, mappingB.source)
if (cmp !== 0) {
return cmp
}
cmp = mappingA.originalLine - mappingB.originalLine
if (cmp !== 0) {
return cmp
}
cmp = mappingA.originalColumn - mappingB.originalColumn
if (cmp !== 0) {
return cmp
}
return strcmp(mappingA.name, mappingB.name)
}
exports.compareByGeneratedPositionsDeflated =
compareByGeneratedPositionsDeflated
function strcmp(aStr1, aStr2) {
if (aStr1 === aStr2) {
return 0
}
if (aStr1 === null) {
return 1 // aStr2 !== null
}
if (aStr2 === null) {
return -1 // aStr1 !== null
}
if (aStr1 > aStr2) {
return 1
}
return -1
}
/**
* Comparator between two mappings with inflated source and name strings where
* the generated positions are compared.
*/
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
let cmp = mappingA.generatedLine - mappingB.generatedLine
if (cmp !== 0) {
return cmp
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn
if (cmp !== 0) {
return cmp
}
cmp = strcmp(mappingA.source, mappingB.source)
if (cmp !== 0) {
return cmp
}
cmp = mappingA.originalLine - mappingB.originalLine
if (cmp !== 0) {
return cmp
}
cmp = mappingA.originalColumn - mappingB.originalColumn
if (cmp !== 0) {
return cmp
}
return strcmp(mappingA.name, mappingB.name)
}
exports.compareByGeneratedPositionsInflated =
compareByGeneratedPositionsInflated
/**
* Strip any JSON XSSI avoidance prefix from the string (as documented
* in the source maps specification), and then parse the string as
* JSON.
*/
function parseSourceMapInput(str) {
return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''))
}
exports.parseSourceMapInput = parseSourceMapInput
/**
* Compute the URL of a source given the the source root, the source's
* URL, and the source map's URL.
*/
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
sourceURL = sourceURL || ''
if (sourceRoot) {
// This follows what Chrome does.
if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
sourceRoot += '/'
}
// The spec says:
// Line 4: An optional source root, useful for relocating source
// files on a server or removing repeated values in the
// “sources” entry. This value is prepended to the individual
// entries in the “source” field.
sourceURL = sourceRoot + sourceURL
}
// Historically, SourceMapConsumer did not take the sourceMapURL as
// a parameter. This mode is still somewhat supported, which is why
// this code block is conditional. However, it's preferable to pass
// the source map URL to SourceMapConsumer, so that this function
// can implement the source URL resolution algorithm as outlined in
// the spec. This block is basically the equivalent of:
// new URL(sourceURL, sourceMapURL).toString()
// ... except it avoids using URL, which wasn't available in the
// older releases of node still supported by this library.
//
// The spec says:
// If the sources are not absolute URLs after prepending of the
// “sourceRoot”, the sources are resolved relative to the
// SourceMap (like resolving script src in a html document).
if (sourceMapURL) {
const parsed = urlParse(sourceMapURL)
if (!parsed) {
throw new Error('sourceMapURL could not be parsed')
}
if (parsed.path) {
// Strip the last path component, but keep the "/".
const index = parsed.path.lastIndexOf('/')
if (index >= 0) {
parsed.path = parsed.path.substring(0, index + 1)
}
}
sourceURL = join(urlGenerate(parsed), sourceURL)
}
return normalize(sourceURL)
}
exports.computeSourceURL = computeSourceURL
+138
View File
@@ -0,0 +1,138 @@
const readWasm = require('./read-wasm')
/**
* Provide the JIT with a nice shape / hidden class.
*/
function Mapping() {
this.generatedLine = 0
this.generatedColumn = 0
this.lastGeneratedColumn = null
this.source = null
this.originalLine = null
this.originalColumn = null
this.name = null
}
let cachedWasm = null
module.exports = function wasm() {
if (cachedWasm) {
return cachedWasm
}
const callbackStack = []
cachedWasm = readWasm()
.then((buffer) => {
return WebAssembly.instantiate(buffer, {
env: {
mapping_callback(
generatedLine,
generatedColumn,
hasLastGeneratedColumn,
lastGeneratedColumn,
hasOriginal,
source,
originalLine,
originalColumn,
hasName,
name
) {
const mapping = new Mapping()
// JS uses 1-based line numbers, wasm uses 0-based.
mapping.generatedLine = generatedLine + 1
mapping.generatedColumn = generatedColumn
if (hasLastGeneratedColumn) {
// JS uses inclusive last generated column, wasm uses exclusive.
mapping.lastGeneratedColumn = lastGeneratedColumn - 1
}
if (hasOriginal) {
mapping.source = source
// JS uses 1-based line numbers, wasm uses 0-based.
mapping.originalLine = originalLine + 1
mapping.originalColumn = originalColumn
if (hasName) {
mapping.name = name
}
}
callbackStack[callbackStack.length - 1](mapping)
},
start_all_generated_locations_for() {
console.time('all_generated_locations_for')
},
end_all_generated_locations_for() {
console.timeEnd('all_generated_locations_for')
},
start_compute_column_spans() {
console.time('compute_column_spans')
},
end_compute_column_spans() {
console.timeEnd('compute_column_spans')
},
start_generated_location_for() {
console.time('generated_location_for')
},
end_generated_location_for() {
console.timeEnd('generated_location_for')
},
start_original_location_for() {
console.time('original_location_for')
},
end_original_location_for() {
console.timeEnd('original_location_for')
},
start_parse_mappings() {
console.time('parse_mappings')
},
end_parse_mappings() {
console.timeEnd('parse_mappings')
},
start_sort_by_generated_location() {
console.time('sort_by_generated_location')
},
end_sort_by_generated_location() {
console.timeEnd('sort_by_generated_location')
},
start_sort_by_original_location() {
console.time('sort_by_original_location')
},
end_sort_by_original_location() {
console.timeEnd('sort_by_original_location')
},
},
})
})
.then((Wasm) => {
return {
exports: Wasm.instance.exports,
withMappingCallback: (mappingCallback, f) => {
callbackStack.push(mappingCallback)
try {
f()
} finally {
callbackStack.pop()
}
},
}
})
.then(null, (e) => {
cachedWasm = null
throw e
})
return cachedWasm
}
+91
View File
@@ -0,0 +1,91 @@
{
"name": "source-map",
"description": "Generates and consumes source maps",
"version": "0.7.4",
"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",
"types": "./source-map.d.ts",
"files": [
"source-map.js",
"source-map.d.ts",
"lib/",
"dist/source-map.js"
],
"engines": {
"node": ">= 8"
},
"license": "BSD-3-Clause",
"scripts": {
"lint": "eslint *.js lib/ test/",
"prebuild": "npm run lint",
"build": "webpack --color",
"pretest": "npm run build",
"test": "node test/run-tests.js",
"precoverage": "npm run build",
"coverage": "nyc node test/run-tests.js",
"setup": "mkdir -p coverage && cp -n .waiting.html coverage/index.html || true",
"dev:live": "live-server --port=4103 --ignorePattern='(js|css|png)$' coverage",
"dev:watch": "watch 'npm run coverage' lib/ test/",
"predev": "npm run setup",
"dev": "npm-run-all -p --silent dev:*",
"clean": "rm -rf coverage .nyc_output",
"toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md"
},
"devDependencies": {
"doctoc": "^1.3.1",
"eslint": "^4.19.1",
"live-server": "^1.2.0",
"npm-run-all": "^4.1.2",
"nyc": "^11.7.1",
"watch": "^1.0.2",
"webpack": "^4.9.1",
"webpack-cli": "^3.1"
},
"nyc": {
"reporter": "html"
},
"typings": "source-map"
}
+399
View File
@@ -0,0 +1,399 @@
// Type definitions for source-map 0.7
// Project: https://github.com/mozilla/source-map
// Definitions by: Morten Houston Ludvigsen <https://github.com/MortenHoustonLudvigsen>,
// Ron Buckton <https://github.com/rbuckton>,
// John Vilk <https://github.com/jvilk>
// Definitions: https://github.com/mozilla/source-map
export type SourceMapUrl = string
export interface StartOfSourceMap {
file?: string
sourceRoot?: string
skipValidation?: boolean
}
export interface RawSourceMap {
version: number
sources: string[]
names: string[]
sourceRoot?: string
sourcesContent?: string[]
mappings: string
file: string
}
export interface RawIndexMap extends StartOfSourceMap {
version: number
sections: RawSection[]
}
export interface RawSection {
offset: Position
map: RawSourceMap
}
export interface Position {
line: number
column: number
}
export interface NullablePosition {
line: number | null
column: number | null
lastColumn: number | null
}
export interface MappedPosition {
source: string
line: number
column: number
name?: string
}
export interface NullableMappedPosition {
source: string | null
line: number | null
column: number | null
name: string | null
}
export interface MappingItem {
source: string
generatedLine: number
generatedColumn: number
originalLine: number
originalColumn: number
name: string
}
export interface Mapping {
generated: Position
original: Position
source: string
name?: string
}
export interface CodeWithSourceMap {
code: string
map: SourceMapGenerator
}
export interface SourceMapConsumer {
/**
* Compute the last column for each generated mapping. The last column is
* inclusive.
*/
computeColumnSpans(): void
/**
* 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.
* - column: The column number in the generated source.
* - 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.
* - line: The line number in the original source, or null.
* - column: The column number in the original source, or null.
* - name: The original identifier, or null.
*/
originalPositionFor(
generatedPosition: Position & { bias?: number }
): NullableMappedPosition
/**
* 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.
* - column: The column number in the original source.
* - 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:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
generatedPositionFor(
originalPosition: MappedPosition & { bias?: number }
): NullablePosition
/**
* 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.
* - column: Optional. the column number in the original source.
*
* and an array of objects is returned, each with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
allGeneratedPositionsFor(originalPosition: MappedPosition): NullablePosition[]
/**
* Return true if we have the source content for every source in the source
* map, false otherwise.
*/
hasContentsOfAllSources(): boolean
/**
* Returns the original source content. The only argument is the url of the
* original source file. Returns null if no original source content is
* available.
*/
sourceContentFor(source: string, returnNullOnMissing?: boolean): string | null
/**
* Iterate over each mapping between an original source/line/column and a
* generated line/column in this source map.
*
* @param callback
* The function that is called with each mapping.
* @param context
* Optional. If specified, this object will be the value of `this` every
* time that `aCallback` is called.
* @param 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`.
*/
eachMapping(
callback: (mapping: MappingItem) => void,
context?: any,
order?: number
): void
/**
* Free this source map consumer's associated wasm data that is manually-managed.
* Alternatively, you can use SourceMapConsumer.with to avoid needing to remember to call destroy.
*/
destroy(): void
}
export interface SourceMapConsumerConstructor {
prototype: SourceMapConsumer
GENERATED_ORDER: number
ORIGINAL_ORDER: number
GREATEST_LOWER_BOUND: number
LEAST_UPPER_BOUND: number
new (
rawSourceMap: RawSourceMap,
sourceMapUrl?: SourceMapUrl
): Promise<BasicSourceMapConsumer>
new (
rawSourceMap: RawIndexMap,
sourceMapUrl?: SourceMapUrl
): Promise<IndexedSourceMapConsumer>
new (
rawSourceMap: RawSourceMap | RawIndexMap | string,
sourceMapUrl?: SourceMapUrl
): Promise<BasicSourceMapConsumer | IndexedSourceMapConsumer>
/**
* Create a BasicSourceMapConsumer from a SourceMapGenerator.
*
* @param sourceMap
* The source map that will be consumed.
*/
fromSourceMap(
sourceMap: SourceMapGenerator,
sourceMapUrl?: SourceMapUrl
): Promise<BasicSourceMapConsumer>
/**
* Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl`
* (see the `SourceMapConsumer` constructor for details. Then, invoke the `async
* function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait
* for `f` to complete, call `destroy` on the consumer, and return `f`'s return
* value.
*
* You must not use the consumer after `f` completes!
*
* By using `with`, you do not have to remember to manually call `destroy` on
* the consumer, since it will be called automatically once `f` completes.
*
* ```js
* const xSquared = await SourceMapConsumer.with(
* myRawSourceMap,
* null,
* async function (consumer) {
* // Use `consumer` inside here and don't worry about remembering
* // to call `destroy`.
*
* const x = await whatever(consumer);
* return x * x;
* }
* );
*
* // You may not use that `consumer` anymore out here; it has
* // been destroyed. But you can use `xSquared`.
* console.log(xSquared);
* ```
*/
with<T>(
rawSourceMap: RawSourceMap | RawIndexMap | string,
sourceMapUrl: SourceMapUrl | null | undefined,
callback: (
consumer: BasicSourceMapConsumer | IndexedSourceMapConsumer
) => Promise<T> | T
): Promise<T>
}
export const SourceMapConsumer: SourceMapConsumerConstructor
export interface BasicSourceMapConsumer extends SourceMapConsumer {
file: string
sourceRoot: string
sources: string[]
sourcesContent: string[]
}
export interface BasicSourceMapConsumerConstructor {
prototype: BasicSourceMapConsumer
new (rawSourceMap: RawSourceMap | string): Promise<BasicSourceMapConsumer>
/**
* Create a BasicSourceMapConsumer from a SourceMapGenerator.
*
* @param sourceMap
* The source map that will be consumed.
*/
fromSourceMap(sourceMap: SourceMapGenerator): Promise<BasicSourceMapConsumer>
}
export const BasicSourceMapConsumer: BasicSourceMapConsumerConstructor
export interface IndexedSourceMapConsumer extends SourceMapConsumer {
sources: string[]
}
export interface IndexedSourceMapConsumerConstructor {
prototype: IndexedSourceMapConsumer
new (rawSourceMap: RawIndexMap | string): Promise<IndexedSourceMapConsumer>
}
export const IndexedSourceMapConsumer: IndexedSourceMapConsumerConstructor
export class SourceMapGenerator {
constructor(startOfSourceMap?: StartOfSourceMap)
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param sourceMapConsumer The SourceMap.
*/
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator
/**
* 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.
*/
addMapping(mapping: Mapping): void
/**
* Set the source content for a source file.
*/
setSourceContent(sourceFile: string, sourceContent: string): void
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param sourceMapConsumer The source map to be applied.
* @param sourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
* @param sourceMapPath Optional. The dirname of the path to the source map
* to be applied. If relative, it is relative to the SourceMapConsumer.
* This parameter is needed when the two source maps aren't in the same
* directory, and the source map to be applied contains relative source
* paths. If so, those relative source paths need to be rewritten
* relative to the SourceMapGenerator.
*/
applySourceMap(
sourceMapConsumer: SourceMapConsumer,
sourceFile?: string,
sourceMapPath?: string
): void
toString(): string
toJSON(): RawSourceMap
}
export class SourceNode {
children: SourceNode[]
sourceContents: any
line: number
column: number
source: string
name: string
constructor()
constructor(
line: number | null,
column: number | null,
source: string | null,
chunks?: Array<string | SourceNode> | SourceNode | string,
name?: string
)
static fromStringWithSourceMap(
code: string,
sourceMapConsumer: SourceMapConsumer,
relativePath?: string
): SourceNode
add(chunk: Array<string | SourceNode> | SourceNode | string): SourceNode
prepend(chunk: Array<string | SourceNode> | SourceNode | string): SourceNode
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
}
+10
View File
@@ -0,0 +1,10 @@
/*
* 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
+1
View File
@@ -0,0 +1 @@
[https://dcloud.io/license/uni-app.html](https://dcloud.io/license/uni-app.html)
+25
View File
@@ -0,0 +1,25 @@
{
"name": "@dcloudio/uni-stacktracey",
"version": "3.0.0-4030620241128001",
"description": "@dcloudio/uni-stacktracey",
"main": "dist/uni-stacktracey.cjs.js",
"module": "dist/uni-stacktracey.es.js",
"files": [
"dist",
"lib"
],
"sideEffects": false,
"repository": {
"type": "git",
"url": "git+https://github.com/dcloudio/uni-app.git",
"directory": "packages/uni-stacktracey"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/dcloudio/uni-app/issues"
},
"gitHead": "33e807d66e1fe47e2ee08ad9c59247e37b8884da",
"devDependencies": {
"@dcloudio/types": "^2.6.12"
}
}