@maka/meteor-sdk 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/isopackets/combined/npm/node_modules/meteor/babel-compiler/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/boilerplate-generator/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/constraint-solver/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/ddp-client/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/ecmascript/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/ecmascript-runtime/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/ecmascript-runtime-client/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/ecmascript-runtime-server/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/fetch/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/inter-process-messaging/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/logging/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/logic-solver/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/meteor/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/modules/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/modules-runtime/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/npm-mongo/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/package-version-parser/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/promise/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/react-fast-refresh/node_modules/.package-lock.json +1 -1
- package/isopackets/combined/npm/node_modules/meteor/socket-stream-client/node_modules/.package-lock.json +1 -1
- package/package.json +2 -3
- package/src/bootstrap.js +42 -0
- package/tools/tool-env/source-map-retriever-stack.js +5 -1
- package/tools/vendor/source-map-support/LICENSE.md +21 -0
- package/tools/vendor/source-map-support/README.md +17 -0
- package/tools/vendor/source-map-support/source-map-support.js +433 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/meteor-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Programmatic Node API over the Meteor build tool (bundle/run/create/etc.) -- for driving Meteor's build system from plain Node code instead of shelling out to a meteor CLI (there isn't one anymore; see README.md). \"dependencies\" is generated by scripts/write-tool-package-json.js from scripts/dev-bundle-tool-package.js at the monorepo root -- do not hand-edit that field, edit that file and re-run the script instead.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -41,13 +41,12 @@
|
|
|
41
41
|
"babel-runtime": "7.0.0-beta.3",
|
|
42
42
|
"@types/underscore": "1.11.15",
|
|
43
43
|
"underscore": "1.13.7",
|
|
44
|
-
"source-map-
|
|
44
|
+
"source-map-v01": "npm:source-map@0.1.32",
|
|
45
45
|
"@types/semver": "7.5.8",
|
|
46
46
|
"semver": "7.6.3",
|
|
47
47
|
"request": "2.88.2",
|
|
48
48
|
"uuid": "8.3.2",
|
|
49
49
|
"graceful-fs": "4.2.11",
|
|
50
|
-
"fstream": "https://github.com/meteor/fstream/tarball/cf4ea6c175355cec7bee38311e170d08c4078a5d",
|
|
51
50
|
"tar": "6.1.11",
|
|
52
51
|
"tar-fs": "2.1.1",
|
|
53
52
|
"source-map": "0.7.4",
|
package/src/bootstrap.js
CHANGED
|
@@ -79,6 +79,47 @@ async function ensureRuntimeReady(offline) {
|
|
|
79
79
|
await catalog.official.initialize({ offline: !!offline });
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// Compatibility shim for build plugins that introspect the running
|
|
83
|
+
// meteor-tool through `process.mainModule` -- zodern:types' bundled
|
|
84
|
+
// tools-imports.js is the known case in the wild: it does
|
|
85
|
+
// `process.mainModule.filename` to locate the tool's directory, then
|
|
86
|
+
// `process.mainModule.require(<abs path>)` to load isobuild/
|
|
87
|
+
// package-source, project-context, and packaging/tropohouse from it.
|
|
88
|
+
// Under the classic CLI that worked because the entry script was
|
|
89
|
+
// tools/index.js (CJS); an SDK host is typically an ESM entry (or some
|
|
90
|
+
// unrelated CJS file), where process.mainModule is undefined (or points
|
|
91
|
+
// somewhere useless), so any such plugin crashes with "Cannot read
|
|
92
|
+
// properties of undefined (reading 'filename')" while loading -- which
|
|
93
|
+
// also silently disables every file handler that plugin registers
|
|
94
|
+
// (e.g. zodern:types' *.d.ts handler, in turn breaking any package
|
|
95
|
+
// published with d.ts resources, like alanning:roles).
|
|
96
|
+
//
|
|
97
|
+
// The shim only fills in the undefined case (never clobbers a real CJS
|
|
98
|
+
// main module), with `filename` pointing into this package's own tools/
|
|
99
|
+
// (the index.js there need not exist -- plugins only dirname it) and a
|
|
100
|
+
// `require` that resolves the absolute paths plugins compute against
|
|
101
|
+
// it. Those are the exact same files this SDK itself requires, so the
|
|
102
|
+
// require cache serves back the same singletons the running tool uses.
|
|
103
|
+
// Note Node aliases newly-created CJS modules' `require.main` to
|
|
104
|
+
// process.mainModule at load time, so late-loaded CJS sees the shim
|
|
105
|
+
// there too -- harmless (nothing in tools/ reads either; audited).
|
|
106
|
+
function ensureMainModuleShim() {
|
|
107
|
+
if (process.mainModule) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const path = require("path");
|
|
111
|
+
const toolsDir = path.resolve(__dirname, "..", "tools");
|
|
112
|
+
process.mainModule = {
|
|
113
|
+
id: ".",
|
|
114
|
+
filename: path.join(toolsDir, "index.js"),
|
|
115
|
+
loaded: true,
|
|
116
|
+
exports: {},
|
|
117
|
+
children: [],
|
|
118
|
+
paths: [],
|
|
119
|
+
require: (request) => require(request),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
82
123
|
// Idempotent: safe to call from every public SDK entry point. The actual
|
|
83
124
|
// Babel require() hook installed by install-babel.js is itself naturally
|
|
84
125
|
// idempotent too (Node's own require() cache means requiring the same
|
|
@@ -107,6 +148,7 @@ async function bootstrap(options) {
|
|
|
107
148
|
// Must happen before install-babel.js (or anything else) has a chance
|
|
108
149
|
// to require tools/console/console.js -- see src/console.js's comment.
|
|
109
150
|
consoleAdapter.setHeadlessEnv();
|
|
151
|
+
ensureMainModuleShim();
|
|
110
152
|
require("../tools/tool-env/install-babel.js");
|
|
111
153
|
ensureAsyncLocalStorage();
|
|
112
154
|
consoleAdapter.patch();
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
// Vendored Meteor fork -- see tools/vendor/source-map-support/README.md
|
|
2
|
+
// for why this isn't the npm package (fork-only install({wrapCallSite})
|
|
3
|
+
// support) or a GitHub tarball URL anymore (npm 12 blocks those by
|
|
4
|
+
// default with EALLOWREMOTE, breaking consumers' installs).
|
|
5
|
+
import sourceMapSupport from '../vendor/source-map-support/source-map-support.js';
|
|
2
6
|
|
|
3
7
|
// Why this file exists:
|
|
4
8
|
// We have two places in the tool where we need to do source maps:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Evan Wallace
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Vendored copy of Meteor's source-map-support fork
|
|
2
|
+
(https://github.com/meteor/node-source-map-support, commit 1912478,
|
|
3
|
+
package version 0.3.2), previously consumed as a GitHub tarball-URL
|
|
4
|
+
dependency -- npm 12 defaults `allow-remote` to "none", which made every
|
|
5
|
+
`npm install` of a package depending on this SDK fail with EALLOWREMOTE.
|
|
6
|
+
|
|
7
|
+
The fork can't be replaced with the npm-published upstream: the tool
|
|
8
|
+
relies on fork-only behavior, most importantly `install({ wrapCallSite })`
|
|
9
|
+
(upstream doesn't accept a wrapCallSite override), used by
|
|
10
|
+
tools/tool-env/source-map-retriever-stack.js to strip meteor://.app/ URL
|
|
11
|
+
prefixes from stack frames.
|
|
12
|
+
|
|
13
|
+
The single edit vs. the fork: `require('source-map')` on line 1 became
|
|
14
|
+
`require('source-map-v01')` -- an npm alias for source-map@0.1.32 declared
|
|
15
|
+
in scripts/dev-bundle-tool-package.js, because this fork predates the
|
|
16
|
+
async SourceMapConsumer API of the source-map@0.7.x the tool itself
|
|
17
|
+
depends on.
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
var SourceMapConsumer = require('source-map-v01').SourceMapConsumer;
|
|
2
|
+
var path = require('path');
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
|
|
5
|
+
// Only install once if called multiple times
|
|
6
|
+
var alreadyInstalled = false;
|
|
7
|
+
|
|
8
|
+
// If true, the caches are reset before a stack trace formatting operation
|
|
9
|
+
var emptyCacheBetweenOperations = false;
|
|
10
|
+
|
|
11
|
+
// Maps a file path to a string containing the file contents
|
|
12
|
+
var fileContentsCache = {};
|
|
13
|
+
|
|
14
|
+
// Maps a file path to a source map for that file
|
|
15
|
+
var sourceMapCache = {};
|
|
16
|
+
|
|
17
|
+
// Regex for detecting source maps
|
|
18
|
+
var reSourceMap = /^data:application\/json[^,]+base64,/;
|
|
19
|
+
|
|
20
|
+
function isInBrowser() {
|
|
21
|
+
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function hasGlobalProcessEventEmitter() {
|
|
25
|
+
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function retrieveFile(path) {
|
|
29
|
+
// Trim the path to make sure there is no extra whitespace.
|
|
30
|
+
path = path.trim();
|
|
31
|
+
if (path in fileContentsCache) {
|
|
32
|
+
return fileContentsCache[path];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
// Use SJAX if we are in the browser
|
|
37
|
+
if (isInBrowser()) {
|
|
38
|
+
var xhr = new XMLHttpRequest();
|
|
39
|
+
xhr.open('GET', path, false);
|
|
40
|
+
xhr.send(null);
|
|
41
|
+
var contents = null
|
|
42
|
+
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
43
|
+
contents = xhr.responseText
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Otherwise, use the filesystem
|
|
48
|
+
else {
|
|
49
|
+
var contents = fs.readFileSync(path, 'utf8');
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
var contents = null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return fileContentsCache[path] = contents;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Support URLs relative to a directory, but be careful about a protocol prefix
|
|
59
|
+
// in case we are in the browser (i.e. directories may start with "http://")
|
|
60
|
+
function supportRelativeURL(file, url) {
|
|
61
|
+
if (!file) return url;
|
|
62
|
+
var dir = path.dirname(file);
|
|
63
|
+
var match = /^\w+:\/\/[^\/]*/.exec(dir);
|
|
64
|
+
var protocol = match ? match[0] : '';
|
|
65
|
+
return protocol + path.resolve(dir.slice(protocol.length), url);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function retrieveSourceMapURL(source) {
|
|
69
|
+
var fileData;
|
|
70
|
+
|
|
71
|
+
if (isInBrowser()) {
|
|
72
|
+
var xhr = new XMLHttpRequest();
|
|
73
|
+
xhr.open('GET', source, false);
|
|
74
|
+
xhr.send(null);
|
|
75
|
+
fileData = xhr.readyState === 4 ? xhr.responseText : null;
|
|
76
|
+
|
|
77
|
+
// Support providing a sourceMappingURL via the SourceMap header
|
|
78
|
+
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
|
|
79
|
+
xhr.getResponseHeader("X-SourceMap");
|
|
80
|
+
if (sourceMapHeader) {
|
|
81
|
+
return sourceMapHeader;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Get the URL of the source map
|
|
86
|
+
fileData = retrieveFile(source);
|
|
87
|
+
var re = /\/\/[#@]\s*sourceMappingURL=([^'"]+)\s*$/mg;
|
|
88
|
+
// Keep executing the search to find the *last* sourceMappingURL to avoid
|
|
89
|
+
// picking up sourceMappingURLs from comments, strings, etc.
|
|
90
|
+
var lastMatch, match;
|
|
91
|
+
while (match = re.exec(fileData)) lastMatch = match;
|
|
92
|
+
if (!lastMatch) return null;
|
|
93
|
+
return lastMatch[1];
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Can be overridden by the retrieveSourceMap option to install. Takes a
|
|
97
|
+
// generated source filename; returns a {map, optional url} object, or null if
|
|
98
|
+
// there is no source map. The map field may be either a string or the parsed
|
|
99
|
+
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
|
|
100
|
+
// constructor).
|
|
101
|
+
function retrieveSourceMap(source) {
|
|
102
|
+
var sourceMappingURL = retrieveSourceMapURL(source);
|
|
103
|
+
if (!sourceMappingURL) return null;
|
|
104
|
+
|
|
105
|
+
// Read the contents of the source map
|
|
106
|
+
var sourceMapData;
|
|
107
|
+
if (reSourceMap.test(sourceMappingURL)) {
|
|
108
|
+
// Support source map URL as a data url
|
|
109
|
+
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
|
|
110
|
+
sourceMapData = new Buffer(rawData, "base64").toString();
|
|
111
|
+
sourceMappingURL = null;
|
|
112
|
+
} else {
|
|
113
|
+
// Support source map URLs relative to the source URL
|
|
114
|
+
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
|
|
115
|
+
sourceMapData = retrieveFile(sourceMappingURL);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!sourceMapData) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
url: sourceMappingURL,
|
|
124
|
+
map: sourceMapData
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function mapSourcePosition(position) {
|
|
129
|
+
var sourceMap = sourceMapCache[position.source];
|
|
130
|
+
if (!sourceMap) {
|
|
131
|
+
// Call the (overrideable) retrieveSourceMap function to get the source map.
|
|
132
|
+
var urlAndMap = retrieveSourceMap(position.source);
|
|
133
|
+
if (urlAndMap) {
|
|
134
|
+
sourceMap = sourceMapCache[position.source] = {
|
|
135
|
+
url: urlAndMap.url,
|
|
136
|
+
map: new SourceMapConsumer(urlAndMap.map)
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Load all sources stored inline with the source map into the file cache
|
|
140
|
+
// to pretend like they are already loaded. They may not exist on disk.
|
|
141
|
+
if (sourceMap.map.sourcesContent) {
|
|
142
|
+
sourceMap.map.sources.forEach(function(source, i) {
|
|
143
|
+
var contents = sourceMap.map.sourcesContent[i];
|
|
144
|
+
if (contents) {
|
|
145
|
+
var url = supportRelativeURL(sourceMap.url, source);
|
|
146
|
+
fileContentsCache[url] = contents;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
sourceMap = sourceMapCache[position.source] = {
|
|
152
|
+
url: null,
|
|
153
|
+
map: null
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Resolve the source URL relative to the URL of the source map
|
|
159
|
+
if (sourceMap && sourceMap.map) {
|
|
160
|
+
var originalPosition = sourceMap.map.originalPositionFor(position);
|
|
161
|
+
|
|
162
|
+
// Only return the original position if a matching line was found. If no
|
|
163
|
+
// matching line is found then we return position instead, which will cause
|
|
164
|
+
// the stack trace to print the path and line for the compiled file. It is
|
|
165
|
+
// better to give a precise location in the compiled file than a vague
|
|
166
|
+
// location in the original file.
|
|
167
|
+
if (originalPosition.source !== null) {
|
|
168
|
+
originalPosition.source = supportRelativeURL(
|
|
169
|
+
sourceMap.url, originalPosition.source);
|
|
170
|
+
return originalPosition;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return position;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Parses code generated by FormatEvalOrigin(), a function inside V8:
|
|
178
|
+
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
|
179
|
+
function mapEvalOrigin(origin) {
|
|
180
|
+
// Most eval() calls are in this format
|
|
181
|
+
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
|
|
182
|
+
if (match) {
|
|
183
|
+
var position = mapSourcePosition({
|
|
184
|
+
source: match[2],
|
|
185
|
+
line: match[3],
|
|
186
|
+
column: match[4] - 1
|
|
187
|
+
});
|
|
188
|
+
return 'eval at ' + match[1] + ' (' + position.source + ':' +
|
|
189
|
+
position.line + ':' + (position.column + 1) + ')';
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Parse nested eval() calls using recursion
|
|
193
|
+
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
|
|
194
|
+
if (match) {
|
|
195
|
+
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Make sure we still return useful information if we didn't find anything
|
|
199
|
+
return origin;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// This is copied almost verbatim from the V8 source code at
|
|
203
|
+
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
|
|
204
|
+
// implementation of wrapCallSite() used to just forward to the actual source
|
|
205
|
+
// code of CallSite.prototype.toString but unfortunately a new release of V8
|
|
206
|
+
// did something to the prototype chain and broke the shim. The only fix I
|
|
207
|
+
// could find was copy/paste.
|
|
208
|
+
function CallSiteToString() {
|
|
209
|
+
var fileName;
|
|
210
|
+
var fileLocation = "";
|
|
211
|
+
if (this.isNative()) {
|
|
212
|
+
fileLocation = "native";
|
|
213
|
+
} else {
|
|
214
|
+
fileName = this.getScriptNameOrSourceURL();
|
|
215
|
+
if (!fileName && this.isEval()) {
|
|
216
|
+
fileLocation = this.getEvalOrigin();
|
|
217
|
+
fileLocation += ", "; // Expecting source position to follow.
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (fileName) {
|
|
221
|
+
fileLocation += fileName;
|
|
222
|
+
} else {
|
|
223
|
+
// Source code does not originate from a file and is not native, but we
|
|
224
|
+
// can still get the source position inside the source string, e.g. in
|
|
225
|
+
// an eval string.
|
|
226
|
+
fileLocation += "<anonymous>";
|
|
227
|
+
}
|
|
228
|
+
var lineNumber = this.getLineNumber();
|
|
229
|
+
if (lineNumber != null) {
|
|
230
|
+
fileLocation += ":" + lineNumber;
|
|
231
|
+
var columnNumber = this.getColumnNumber();
|
|
232
|
+
if (columnNumber) {
|
|
233
|
+
fileLocation += ":" + columnNumber;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
var line = "";
|
|
239
|
+
var functionName = this.getFunctionName();
|
|
240
|
+
var addSuffix = true;
|
|
241
|
+
var isConstructor = this.isConstructor();
|
|
242
|
+
var isMethodCall = !(this.isToplevel() || isConstructor);
|
|
243
|
+
if (isMethodCall) {
|
|
244
|
+
var typeName = this.getTypeName();
|
|
245
|
+
var methodName = this.getMethodName();
|
|
246
|
+
if (functionName) {
|
|
247
|
+
if (typeName && functionName.indexOf(typeName) != 0) {
|
|
248
|
+
line += typeName + ".";
|
|
249
|
+
}
|
|
250
|
+
line += functionName;
|
|
251
|
+
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
|
|
252
|
+
line += " [as " + methodName + "]";
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
line += typeName + "." + (methodName || "<anonymous>");
|
|
256
|
+
}
|
|
257
|
+
} else if (isConstructor) {
|
|
258
|
+
line += "new " + (functionName || "<anonymous>");
|
|
259
|
+
} else if (functionName) {
|
|
260
|
+
line += functionName;
|
|
261
|
+
} else {
|
|
262
|
+
line += fileLocation;
|
|
263
|
+
addSuffix = false;
|
|
264
|
+
}
|
|
265
|
+
if (addSuffix) {
|
|
266
|
+
line += " (" + fileLocation + ")";
|
|
267
|
+
}
|
|
268
|
+
return line;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function cloneCallSite(frame) {
|
|
272
|
+
var object = {};
|
|
273
|
+
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
|
|
274
|
+
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
|
|
275
|
+
});
|
|
276
|
+
object.toString = CallSiteToString;
|
|
277
|
+
return object;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function wrapCallSite(frame) {
|
|
281
|
+
// Most call sites will return the source file from getFileName(), but code
|
|
282
|
+
// passed to eval() ending in "//# sourceURL=..." will return the source file
|
|
283
|
+
// from getScriptNameOrSourceURL() instead
|
|
284
|
+
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
|
|
285
|
+
if (source) {
|
|
286
|
+
var line = frame.getLineNumber();
|
|
287
|
+
var column = frame.getColumnNumber() - 1;
|
|
288
|
+
|
|
289
|
+
// Fix position in Node where some (internal) code is prepended.
|
|
290
|
+
// See https://github.com/evanw/node-source-map-support/issues/36
|
|
291
|
+
if (line === 1 && !isInBrowser() && !frame.isEval()) {
|
|
292
|
+
column -= 62;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
var position = mapSourcePosition({
|
|
296
|
+
source: source,
|
|
297
|
+
line: line,
|
|
298
|
+
column: column
|
|
299
|
+
});
|
|
300
|
+
frame = cloneCallSite(frame);
|
|
301
|
+
frame.getFileName = function() { return position.source; };
|
|
302
|
+
frame.getLineNumber = function() { return position.line; };
|
|
303
|
+
frame.getColumnNumber = function() { return position.column + 1; };
|
|
304
|
+
frame.getScriptNameOrSourceURL = function() { return position.source; };
|
|
305
|
+
return frame;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Code called using eval() needs special handling
|
|
309
|
+
var origin = frame.isEval() && frame.getEvalOrigin();
|
|
310
|
+
if (origin) {
|
|
311
|
+
origin = mapEvalOrigin(origin);
|
|
312
|
+
frame = cloneCallSite(frame);
|
|
313
|
+
frame.getEvalOrigin = function() { return origin; };
|
|
314
|
+
return frame;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// If we get here then we were unable to change the source position
|
|
318
|
+
return frame;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// This function is part of the V8 stack trace API, for more info see:
|
|
322
|
+
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
|
|
323
|
+
function prepareStackTrace(error, stack) {
|
|
324
|
+
if (emptyCacheBetweenOperations) {
|
|
325
|
+
fileContentsCache = {};
|
|
326
|
+
sourceMapCache = {};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return error + stack.map(function(frame) {
|
|
330
|
+
return '\n at ' + wrapCallSite(frame);
|
|
331
|
+
}).join('');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Generate position and snippet of original source with pointer
|
|
335
|
+
function getErrorSource(error) {
|
|
336
|
+
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
|
|
337
|
+
if (match) {
|
|
338
|
+
var source = match[1];
|
|
339
|
+
var line = +match[2];
|
|
340
|
+
var column = +match[3];
|
|
341
|
+
|
|
342
|
+
// Support the inline sourceContents inside the source map
|
|
343
|
+
var contents = fileContentsCache[source];
|
|
344
|
+
|
|
345
|
+
// Support files on disk
|
|
346
|
+
if (!contents && fs.existsSync(source)) {
|
|
347
|
+
contents = fs.readFileSync(source, 'utf8');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Format the line from the original source code like node does
|
|
351
|
+
if (contents) {
|
|
352
|
+
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
|
|
353
|
+
if (code) {
|
|
354
|
+
return source + ':' + line + '\n' + code + '\n' +
|
|
355
|
+
new Array(column).join(' ') + '^';
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function printErrorAndExit (error) {
|
|
363
|
+
var source = getErrorSource(error);
|
|
364
|
+
|
|
365
|
+
if (source) {
|
|
366
|
+
console.error();
|
|
367
|
+
console.error(source);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
console.error(error.stack);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function shimEmitUncaughtException () {
|
|
375
|
+
var origEmit = process.emit;
|
|
376
|
+
|
|
377
|
+
process.emit = function (type) {
|
|
378
|
+
if (type === 'uncaughtException') {
|
|
379
|
+
var hasStack = (arguments[1] && arguments[1].stack);
|
|
380
|
+
var hasListeners = (this.listeners(type).length > 0);
|
|
381
|
+
|
|
382
|
+
if (hasStack && !hasListeners) {
|
|
383
|
+
return printErrorAndExit(arguments[1]);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return origEmit.apply(this, arguments);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
exports.wrapCallSite = wrapCallSite;
|
|
392
|
+
exports.getErrorSource = getErrorSource;
|
|
393
|
+
exports.mapSourcePosition = mapSourcePosition;
|
|
394
|
+
exports.retrieveSourceMap = retrieveSourceMap;
|
|
395
|
+
|
|
396
|
+
exports.install = function(options) {
|
|
397
|
+
if (!alreadyInstalled) {
|
|
398
|
+
alreadyInstalled = true;
|
|
399
|
+
Error.prepareStackTrace = prepareStackTrace;
|
|
400
|
+
|
|
401
|
+
// Configure options
|
|
402
|
+
options = options || {};
|
|
403
|
+
var installHandler = 'handleUncaughtExceptions' in options ?
|
|
404
|
+
options.handleUncaughtExceptions : true;
|
|
405
|
+
emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
|
|
406
|
+
options.emptyCacheBetweenOperations : false;
|
|
407
|
+
|
|
408
|
+
// Allow sources to be found by methods other than reading the files
|
|
409
|
+
// directly from disk.
|
|
410
|
+
if (options.retrieveFile)
|
|
411
|
+
retrieveFile = options.retrieveFile;
|
|
412
|
+
|
|
413
|
+
// Allow source maps to be found by methods other than reading the files
|
|
414
|
+
// directly from disk.
|
|
415
|
+
if (options.retrieveSourceMap)
|
|
416
|
+
retrieveSourceMap = options.retrieveSourceMap;
|
|
417
|
+
|
|
418
|
+
// Allow stack frames to be wrapped by custom methods.
|
|
419
|
+
if (options.wrapCallSite)
|
|
420
|
+
wrapCallSite = options.wrapCallSite;
|
|
421
|
+
|
|
422
|
+
// Provide the option to not install the uncaught exception handler. This is
|
|
423
|
+
// to support other uncaught exception handlers (in test frameworks, for
|
|
424
|
+
// example). If this handler is not installed and there are no other uncaught
|
|
425
|
+
// exception handlers, uncaught exceptions will be caught by node's built-in
|
|
426
|
+
// exception handler and the process will still be terminated. However, the
|
|
427
|
+
// generated JavaScript code will be shown above the stack trace instead of
|
|
428
|
+
// the original source code.
|
|
429
|
+
if (installHandler && hasGlobalProcessEventEmitter()) {
|
|
430
|
+
shimEmitUncaughtException();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
};
|