smipper 27.0.0 → 28.0.0
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/dist/Cache.js +105 -0
- package/dist/Smipper.js +2 -0
- package/dist/buildStackLine.js +7 -0
- package/dist/index.js +23 -0
- package/dist/init.js +118 -0
- package/dist/load.js +41 -0
- package/dist/loadUri.js +98 -0
- package/dist/processFrame.js +73 -0
- package/dist/rewriteLocalControl.js +34 -0
- package/dist/run.js +45 -0
- package/dist/runJSON.js +40 -0
- package/dist/types.js +2 -0
- package/package.json +4 -4
- package/index.js +0 -403
package/dist/Cache.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Cache = exports.CacheEntry = void 0;
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const path = __importStar(require("path"));
|
|
29
|
+
class CacheEntry {
|
|
30
|
+
constructor(key, smipper, trim) {
|
|
31
|
+
this.key = key;
|
|
32
|
+
this.smipper = smipper;
|
|
33
|
+
this.entries = new Map();
|
|
34
|
+
this.trim = trim;
|
|
35
|
+
}
|
|
36
|
+
add(url, contents) {
|
|
37
|
+
this.entries.set(url, contents);
|
|
38
|
+
}
|
|
39
|
+
write() {
|
|
40
|
+
if (!this.entries.size) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const tempdir = fs.mkdtempSync(this.smipper.cacheDir);
|
|
44
|
+
try {
|
|
45
|
+
for (const [url, contents] of this.entries) {
|
|
46
|
+
const encoded = encodeURIComponent(url);
|
|
47
|
+
fs.writeFileSync(path.join(tempdir, encoded), contents);
|
|
48
|
+
}
|
|
49
|
+
const dest = path.join(this.smipper.cacheDir, `smipper:${encodeURIComponent(this.key)}`);
|
|
50
|
+
fs.renameSync(tempdir, dest);
|
|
51
|
+
this.smipper.verbose("Moved", this.entries.keys(), "from", tempdir, "to", dest);
|
|
52
|
+
this.trim();
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
this.smipper.verbose("Got error writing file(s)", err);
|
|
56
|
+
fs.rmSync(tempdir, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.CacheEntry = CacheEntry;
|
|
61
|
+
class Cache {
|
|
62
|
+
constructor(smipper) {
|
|
63
|
+
this.smipper = smipper;
|
|
64
|
+
this.smipper.verbose("Created cache", this.smipper.cacheDir, this.smipper.cacheSize);
|
|
65
|
+
if (!fs.existsSync(smipper.cacheDir)) {
|
|
66
|
+
fs.mkdirSync(smipper.cacheDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.trim();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
trim() {
|
|
73
|
+
try {
|
|
74
|
+
const dirs = fs
|
|
75
|
+
.readdirSync(this.smipper.cacheDir, { withFileTypes: true })
|
|
76
|
+
.filter((x) => x.isDirectory() && x.name.startsWith("smipper:"))
|
|
77
|
+
.map((x) => path.join(this.smipper.cacheDir, x.name))
|
|
78
|
+
.sort((l, r) => fs.statSync(l).mtimeMs - fs.statSync(r).mtimeMs);
|
|
79
|
+
this.smipper.verbose("trim", this.smipper.cacheDir, this.smipper.cacheSize, "=>", dirs);
|
|
80
|
+
while (dirs.length > this.smipper.cacheSize) {
|
|
81
|
+
const dir = dirs[0] || "";
|
|
82
|
+
this.smipper.verbose("removing directory", dir);
|
|
83
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
84
|
+
dirs.shift();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
/* */
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
get(key, url) {
|
|
92
|
+
const file = path.join(this.smipper.cacheDir, `smipper:${encodeURIComponent(key)}`, encodeURIComponent(url));
|
|
93
|
+
try {
|
|
94
|
+
return fs.readFileSync(file, "utf8");
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
this.smipper.verbose("Failed to read file", file, err);
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
create(key) {
|
|
102
|
+
return new CacheEntry(key, this.smipper, this.trim.bind(this));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.Cache = Cache;
|
package/dist/Smipper.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStackLine = void 0;
|
|
4
|
+
function buildStackLine(functionName, url, line, column) {
|
|
5
|
+
return `${functionName ? "at " + functionName + " " : ""}${url}:${line}:${column}`;
|
|
6
|
+
}
|
|
7
|
+
exports.buildStackLine = buildStackLine;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const init_1 = require("./init");
|
|
5
|
+
const run_1 = require("./run");
|
|
6
|
+
const smipper = (0, init_1.init)();
|
|
7
|
+
if (smipper.stack === undefined) {
|
|
8
|
+
console.error("Nothing to smip");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
(0, run_1.run)(smipper)
|
|
12
|
+
.then((output) => {
|
|
13
|
+
console.log(output);
|
|
14
|
+
if (smipper.cacheEntry) {
|
|
15
|
+
smipper.verbose("Writing cache entry");
|
|
16
|
+
smipper.cacheEntry.write();
|
|
17
|
+
}
|
|
18
|
+
process.exit(0);
|
|
19
|
+
})
|
|
20
|
+
.catch((error) => {
|
|
21
|
+
console.error(error.message);
|
|
22
|
+
process.exit(2);
|
|
23
|
+
});
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.init = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const os_1 = __importDefault(require("os"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const Cache_1 = require("./Cache");
|
|
11
|
+
function init() {
|
|
12
|
+
let smipper = {
|
|
13
|
+
verbose: () => { },
|
|
14
|
+
json: false,
|
|
15
|
+
jsc: 0,
|
|
16
|
+
cacheDir: path_1.default.join(os_1.default.homedir(), ".cache", "smipper", "cache"),
|
|
17
|
+
cacheSize: 10,
|
|
18
|
+
sourceMaps: {}
|
|
19
|
+
};
|
|
20
|
+
for (const key in process.env) {
|
|
21
|
+
switch (key) {
|
|
22
|
+
case "SMIPPER_CACHE_KEY":
|
|
23
|
+
smipper.cacheKey = process.env[key];
|
|
24
|
+
break;
|
|
25
|
+
case "SMIPPER_CACHE_SIZE":
|
|
26
|
+
smipper.cacheSize = process.env[key] ? parseInt(process.env[key] || "") : 0;
|
|
27
|
+
break;
|
|
28
|
+
case "SMIPPER_CACHE_DIR":
|
|
29
|
+
smipper.cacheDir = process.env[key] || "";
|
|
30
|
+
break;
|
|
31
|
+
case "SMIPPER_VERBOSE": {
|
|
32
|
+
const val = process.env[key];
|
|
33
|
+
if (val && val !== "false" && val !== "0") {
|
|
34
|
+
smipper.verbose = console.error.bind(console);
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const usage = "smipper [stack|-h|--help|-v|--verbose|--version|--jsc|--json|--file=@FILE@|-f=@FILE@|--cache-key=$CACHE_KEY$|--cache-dir=$CACHE_DIR$|--cache-size=$CACHE_SIZE$|-";
|
|
41
|
+
for (let i = 2; i < process.argv.length; ++i) {
|
|
42
|
+
try {
|
|
43
|
+
const arg = process.argv[i] || "";
|
|
44
|
+
smipper.verbose("got arg", arg);
|
|
45
|
+
if (arg === "-f" || arg === "--file") {
|
|
46
|
+
smipper.stack = fs_1.default.readFileSync(process.argv[++i]).toString();
|
|
47
|
+
}
|
|
48
|
+
else if (arg.startsWith("-f")) {
|
|
49
|
+
smipper.stack = fs_1.default.readFileSync(arg.substring(2)).toString();
|
|
50
|
+
}
|
|
51
|
+
else if (arg.startsWith("--file=")) {
|
|
52
|
+
smipper.stack = fs_1.default.readFileSync(arg.substring(7)).toString();
|
|
53
|
+
}
|
|
54
|
+
else if (arg === "--verbose" || arg === "-v") {
|
|
55
|
+
smipper.verbose = console.error.bind(console);
|
|
56
|
+
}
|
|
57
|
+
else if (arg === "--version") {
|
|
58
|
+
console.log(JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, "package.json"), "utf8")).version);
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
else if (arg === "--json") {
|
|
62
|
+
smipper.json = true;
|
|
63
|
+
}
|
|
64
|
+
else if (arg === "--cache-key") {
|
|
65
|
+
smipper.cacheKey = process.argv[++i] || "";
|
|
66
|
+
}
|
|
67
|
+
else if (arg.startsWith("--cache-key=")) {
|
|
68
|
+
smipper.cacheKey = arg.substring(12);
|
|
69
|
+
}
|
|
70
|
+
else if (arg === "--cache-size") {
|
|
71
|
+
smipper.cacheSize = parseInt(String(process.argv[++i]));
|
|
72
|
+
}
|
|
73
|
+
else if (arg.startsWith("--cache-size=")) {
|
|
74
|
+
smipper.cacheSize = parseInt(arg.substring(13));
|
|
75
|
+
}
|
|
76
|
+
else if (arg === "--cache-dir") {
|
|
77
|
+
smipper.cacheDir = String(process.argv[++i]);
|
|
78
|
+
}
|
|
79
|
+
else if (arg.startsWith("--cache-dir=")) {
|
|
80
|
+
smipper.cacheDir = arg.substring(12);
|
|
81
|
+
}
|
|
82
|
+
else if (arg === "--jsc") {
|
|
83
|
+
// jsc has the wrong column for some reason
|
|
84
|
+
smipper.jsc = 1;
|
|
85
|
+
}
|
|
86
|
+
else if (arg === "-h" || arg === "--help") {
|
|
87
|
+
console.log(usage);
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
else if (arg === "-") {
|
|
91
|
+
// stdin
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
smipper.stack = arg;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.error("Error: " + err.toString());
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (isNaN(smipper.cacheSize)) {
|
|
103
|
+
console.error(usage);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
if (smipper.cacheKey) {
|
|
107
|
+
smipper.cache = new Cache_1.Cache(smipper);
|
|
108
|
+
}
|
|
109
|
+
if (!smipper.stack) {
|
|
110
|
+
smipper.stack = fs_1.default.readFileSync("/dev/stdin").toString();
|
|
111
|
+
if (!smipper.stack) {
|
|
112
|
+
console.error("Nothing to do");
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return smipper;
|
|
117
|
+
}
|
|
118
|
+
exports.init = init;
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.load = void 0;
|
|
7
|
+
const rewriteLocalControl_1 = require("./rewriteLocalControl");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const got_1 = __importDefault(require("got"));
|
|
10
|
+
async function load(smipper, path) {
|
|
11
|
+
if (path.startsWith("http://localcontrol.netflix.com/")) {
|
|
12
|
+
return (0, rewriteLocalControl_1.rewriteLocalControl)(path);
|
|
13
|
+
}
|
|
14
|
+
if (path.startsWith("file:///")) {
|
|
15
|
+
return fs_1.default.readFileSync(path.substring(7), "utf8");
|
|
16
|
+
}
|
|
17
|
+
if (!path.startsWith("http://") && !path.startsWith("https://")) {
|
|
18
|
+
throw new Error("Not a url");
|
|
19
|
+
}
|
|
20
|
+
if (smipper.cache && smipper.cacheKey) {
|
|
21
|
+
const response = smipper.cache.get(smipper.cacheKey, path);
|
|
22
|
+
if (response) {
|
|
23
|
+
return response;
|
|
24
|
+
}
|
|
25
|
+
if (!smipper.cacheEntry) {
|
|
26
|
+
smipper.cacheEntry = smipper.cache.create(smipper.cacheKey);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// let retryIndex = 0;
|
|
30
|
+
async function get() {
|
|
31
|
+
const response = await got_1.default.get(path, { timeout: 10000 });
|
|
32
|
+
smipper.verbose(response.headers);
|
|
33
|
+
return response.body || "";
|
|
34
|
+
}
|
|
35
|
+
const response = await get();
|
|
36
|
+
if (smipper.cacheEntry) {
|
|
37
|
+
smipper.cacheEntry.add(path, response);
|
|
38
|
+
}
|
|
39
|
+
return response;
|
|
40
|
+
}
|
|
41
|
+
exports.load = load;
|
package/dist/loadUri.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.loadUri = void 0;
|
|
27
|
+
const sourceMap = __importStar(require("source-map"));
|
|
28
|
+
const load_1 = require("./load");
|
|
29
|
+
async function loadUri(smipper, path) {
|
|
30
|
+
if (path[0] === "/") {
|
|
31
|
+
path = "file://" + path;
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
smipper.verbose("loading", path);
|
|
35
|
+
if (!(path in smipper.sourceMaps)) {
|
|
36
|
+
smipper.sourceMaps[path] = {
|
|
37
|
+
resolvers: [resolve],
|
|
38
|
+
rejecters: [reject]
|
|
39
|
+
};
|
|
40
|
+
(0, load_1.load)(smipper, path)
|
|
41
|
+
.then((jsData) => {
|
|
42
|
+
const idx = jsData.lastIndexOf("//# sourceMappingURL=");
|
|
43
|
+
smipper.verbose("Got the file", jsData.length, idx);
|
|
44
|
+
if (idx == -1) {
|
|
45
|
+
return path + ".map";
|
|
46
|
+
}
|
|
47
|
+
const mapUrl = jsData.substring(idx + 21);
|
|
48
|
+
const match = /^(data:.+\/.+;)base64,/.exec(mapUrl);
|
|
49
|
+
if (match) {
|
|
50
|
+
return mapUrl.substring(match[1].length);
|
|
51
|
+
}
|
|
52
|
+
if (mapUrl.indexOf("://") != -1) {
|
|
53
|
+
return mapUrl;
|
|
54
|
+
}
|
|
55
|
+
// console.log(mapUrl);
|
|
56
|
+
return new URL(mapUrl, path).href;
|
|
57
|
+
})
|
|
58
|
+
.then((mapUrl) => {
|
|
59
|
+
// console.log(mapUrl.substring(0, 20));
|
|
60
|
+
if (mapUrl.startsWith("base64,")) {
|
|
61
|
+
return Buffer.from(mapUrl.substring(7), "base64").toString();
|
|
62
|
+
}
|
|
63
|
+
return (0, load_1.load)(smipper, mapUrl);
|
|
64
|
+
})
|
|
65
|
+
.then(async (sourceMapData) => {
|
|
66
|
+
const parsed = JSON.parse(sourceMapData);
|
|
67
|
+
const smap = await new sourceMap.SourceMapConsumer(parsed);
|
|
68
|
+
const pending = smipper.sourceMaps[path];
|
|
69
|
+
// sourceMaps.delete(path);
|
|
70
|
+
if (pending) {
|
|
71
|
+
pending.resolvers.forEach((func) => {
|
|
72
|
+
func(smap);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.catch((err) => {
|
|
77
|
+
const pending = smipper.sourceMaps[path];
|
|
78
|
+
if (!pending) {
|
|
79
|
+
throw new Error("Gotta have pending");
|
|
80
|
+
}
|
|
81
|
+
// sourceMaps.delete(path);
|
|
82
|
+
pending.rejecters.forEach((func) => {
|
|
83
|
+
func(err);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const cur = smipper.sourceMaps[path];
|
|
89
|
+
smipper.verbose("path is in source maps already", cur);
|
|
90
|
+
if (!cur) {
|
|
91
|
+
throw new Error("Gotta have cur");
|
|
92
|
+
}
|
|
93
|
+
cur.resolvers.push(resolve);
|
|
94
|
+
cur.rejecters.push(reject);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
exports.loadUri = loadUri;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.processFrame = void 0;
|
|
7
|
+
const loadUri_1 = require("./loadUri");
|
|
8
|
+
const buildStackLine_1 = require("./buildStackLine");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
function processFrame(smipper, functionName, url, line, column) {
|
|
11
|
+
smipper.verbose("got frame", functionName, url, line, column);
|
|
12
|
+
if (functionName.endsWith("@")) {
|
|
13
|
+
functionName = functionName.substring(0, functionName.length - 1);
|
|
14
|
+
}
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
let newUrl, newLine, newColumn;
|
|
17
|
+
smipper.verbose("calling loadUri", url);
|
|
18
|
+
if (!url.includes("://") && url[0] !== "/" && fs_1.default.existsSync(url)) {
|
|
19
|
+
url = `file://${process.cwd()}/${url}`;
|
|
20
|
+
}
|
|
21
|
+
return (0, loadUri_1.loadUri)(smipper, url)
|
|
22
|
+
.then((smap) => {
|
|
23
|
+
smipper.verbose("got map", url, Object.keys(smap));
|
|
24
|
+
// it appears that we're supposed to reduce the column
|
|
25
|
+
// number by 1 when we get this from jsc
|
|
26
|
+
const pos = smap.originalPositionFor({ line, column: column - smipper.jsc });
|
|
27
|
+
if (!pos.source) {
|
|
28
|
+
smipper.verbose("nothing here", pos);
|
|
29
|
+
throw new Error("Mapping not found");
|
|
30
|
+
}
|
|
31
|
+
// smc.sourceContentFor(pos.source);
|
|
32
|
+
newUrl = pos.source;
|
|
33
|
+
newLine = pos.line || 0;
|
|
34
|
+
newColumn = pos.column || 0;
|
|
35
|
+
})
|
|
36
|
+
.catch((err) => {
|
|
37
|
+
smipper.verbose("didn't get map", url, err);
|
|
38
|
+
// console.error(err);
|
|
39
|
+
})
|
|
40
|
+
.finally(() => {
|
|
41
|
+
if (smipper.json) {
|
|
42
|
+
const ret = {
|
|
43
|
+
functionName: functionName,
|
|
44
|
+
sourceURL: newUrl ? newUrl : url,
|
|
45
|
+
line: newUrl ? newLine : line,
|
|
46
|
+
column: newUrl ? newColumn : column
|
|
47
|
+
};
|
|
48
|
+
// if (newUrl) {
|
|
49
|
+
// ret.oldSourceURL = url;
|
|
50
|
+
// ret.oldLine = line;
|
|
51
|
+
// ret.oldColumn = column;
|
|
52
|
+
// }
|
|
53
|
+
// if (newUrl) {
|
|
54
|
+
// ret.newUrl = newUrl;
|
|
55
|
+
// ret.newLine = newLine;
|
|
56
|
+
// ret.newColumn = newColumn;
|
|
57
|
+
// }
|
|
58
|
+
resolve(ret);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
let str;
|
|
62
|
+
if (newUrl) {
|
|
63
|
+
str = `${(0, buildStackLine_1.buildStackLine)(functionName, newUrl, newLine, newColumn)} (${(0, buildStackLine_1.buildStackLine)("", url, line, column)})`;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
str = (0, buildStackLine_1.buildStackLine)(functionName, url, line, column);
|
|
67
|
+
}
|
|
68
|
+
resolve(str);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
exports.processFrame = processFrame;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.rewriteLocalControl = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function findFile(dir, fn) {
|
|
10
|
+
const list = fs_1.default.readdirSync(dir);
|
|
11
|
+
for (let file of list) {
|
|
12
|
+
const match = file === fn;
|
|
13
|
+
file = dir + "/" + file;
|
|
14
|
+
const stat = fs_1.default.statSync(file);
|
|
15
|
+
if (stat && stat.isDirectory()) {
|
|
16
|
+
const ret = findFile(file, fn);
|
|
17
|
+
if (ret) {
|
|
18
|
+
return ret;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else if (match) {
|
|
22
|
+
return "file://" + file;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
function rewriteLocalControl(url) {
|
|
28
|
+
const found = findFile(process.cwd(), path_1.default.basename(url.substring(6)));
|
|
29
|
+
if (found) {
|
|
30
|
+
return found;
|
|
31
|
+
}
|
|
32
|
+
throw new Error("Couldn't resolve localcontrol " + url);
|
|
33
|
+
}
|
|
34
|
+
exports.rewriteLocalControl = rewriteLocalControl;
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.run = void 0;
|
|
7
|
+
const processFrame_1 = require("./processFrame");
|
|
8
|
+
const assert_1 = __importDefault(require("assert"));
|
|
9
|
+
const runJSON_1 = require("./runJSON");
|
|
10
|
+
async function run(smipper) {
|
|
11
|
+
if (smipper.json) {
|
|
12
|
+
return (0, runJSON_1.runJSON)(smipper);
|
|
13
|
+
}
|
|
14
|
+
(0, assert_1.default)(smipper.stack !== undefined);
|
|
15
|
+
return Promise.all(smipper.stack
|
|
16
|
+
.split("\n")
|
|
17
|
+
.filter((x) => x)
|
|
18
|
+
.map((x) => {
|
|
19
|
+
x = x.trim();
|
|
20
|
+
let match = / *at *([^ ]*).* \(?([^ ]+):([0-9]+):([0-9]+)/.exec(x);
|
|
21
|
+
if (!match) {
|
|
22
|
+
match = /([^ ]+@)?(.*):([0-9]+):([0-9]+)/.exec(x);
|
|
23
|
+
}
|
|
24
|
+
smipper.verbose(x, " => ", match);
|
|
25
|
+
if (!match) {
|
|
26
|
+
const nolinecol = /([^ ]*)(.*)/.exec(x);
|
|
27
|
+
if (nolinecol) {
|
|
28
|
+
return nolinecol[0];
|
|
29
|
+
}
|
|
30
|
+
return x;
|
|
31
|
+
}
|
|
32
|
+
return (0, processFrame_1.processFrame)(smipper, match[1] || "", match[2] || "", parseInt(match[3] || ""), parseInt(match[4] || ""));
|
|
33
|
+
}))
|
|
34
|
+
.then((results) => {
|
|
35
|
+
if (!results.length) {
|
|
36
|
+
throw new Error("Empty output");
|
|
37
|
+
}
|
|
38
|
+
return results.join("\n");
|
|
39
|
+
})
|
|
40
|
+
.catch((error) => {
|
|
41
|
+
console.error("Got an error", error);
|
|
42
|
+
process.exit(3);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
exports.run = run;
|
package/dist/runJSON.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runJSON = void 0;
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
const processFrame_1 = require("./processFrame");
|
|
9
|
+
async function runJSON(smipper) {
|
|
10
|
+
(0, assert_1.default)(smipper.json);
|
|
11
|
+
let parsed;
|
|
12
|
+
try {
|
|
13
|
+
(0, assert_1.default)(typeof smipper.stack === "string");
|
|
14
|
+
parsed = JSON.parse(smipper.stack);
|
|
15
|
+
if (!Array.isArray(parsed)) {
|
|
16
|
+
throw new Error("Expected array");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
throw new Error(`Can't parse json ${err}`);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const results = await Promise.all(parsed.map((frame) => {
|
|
24
|
+
smipper.verbose("got frame frame", frame);
|
|
25
|
+
return (0, processFrame_1.processFrame)(smipper, frame.functionName || "", frame.sourceURL || "", frame.line, frame.column);
|
|
26
|
+
}));
|
|
27
|
+
results.forEach((frame, index) => {
|
|
28
|
+
if (typeof frame !== "object") {
|
|
29
|
+
throw new Error("Huh?");
|
|
30
|
+
}
|
|
31
|
+
frame.index = index;
|
|
32
|
+
});
|
|
33
|
+
// console.log("shit", results);
|
|
34
|
+
return JSON.stringify(results, null, 4);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new Error(`Got an error: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.runJSON = runJSON;
|
package/dist/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smipper",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "28.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"smipper": "./index.js"
|
|
7
|
+
"smipper": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"
|
|
10
|
+
"dist"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "node ./node_modules/.bin/tsc index.ts && chmod +x ./index.js",
|
|
13
|
+
"build": "node ./node_modules/.bin/tsc --target es2020 --module node16 src/index.ts --outDir ./dist && chmod +x ./dist/index.js",
|
|
14
14
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
15
|
},
|
|
16
16
|
"author": "",
|
package/index.js
DELETED
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
13
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
14
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
15
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
16
|
-
function step(op) {
|
|
17
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
18
|
-
while (_) try {
|
|
19
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
20
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
21
|
-
switch (op[0]) {
|
|
22
|
-
case 0: case 1: t = op; break;
|
|
23
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
24
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
25
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
26
|
-
default:
|
|
27
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
28
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
29
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
30
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
31
|
-
if (t[2]) _.ops.pop();
|
|
32
|
-
_.trys.pop(); continue;
|
|
33
|
-
}
|
|
34
|
-
op = body.call(thisArg, _);
|
|
35
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
36
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
exports.__esModule = true;
|
|
40
|
-
var fs = require("fs");
|
|
41
|
-
var got = require("got");
|
|
42
|
-
var path = require("path");
|
|
43
|
-
var sourceMap = require("source-map");
|
|
44
|
-
var url = require("url");
|
|
45
|
-
var verbose = false;
|
|
46
|
-
var stack;
|
|
47
|
-
var json = false;
|
|
48
|
-
var retries = 3;
|
|
49
|
-
var jsc = 0;
|
|
50
|
-
for (var i = 2; i < process.argv.length; ++i) {
|
|
51
|
-
try {
|
|
52
|
-
var arg = process.argv[i] || "";
|
|
53
|
-
if (verbose) {
|
|
54
|
-
console.error("got arg", arg);
|
|
55
|
-
}
|
|
56
|
-
if (arg === "-f" || arg === "--file") {
|
|
57
|
-
stack = fs.readFileSync(process.argv[++i]).toString();
|
|
58
|
-
}
|
|
59
|
-
else if (arg.startsWith("-f")) {
|
|
60
|
-
stack = fs.readFileSync(arg.substring(2)).toString();
|
|
61
|
-
}
|
|
62
|
-
else if (arg.startsWith("--file=")) {
|
|
63
|
-
stack = fs.readFileSync(arg.substring(7)).toString();
|
|
64
|
-
}
|
|
65
|
-
else if (arg === "--verbose" || arg === "-v") {
|
|
66
|
-
verbose = true;
|
|
67
|
-
}
|
|
68
|
-
else if (arg === "--version") {
|
|
69
|
-
console.log(JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8")).version);
|
|
70
|
-
process.exit(0);
|
|
71
|
-
}
|
|
72
|
-
else if (arg === "--json") {
|
|
73
|
-
json = true;
|
|
74
|
-
}
|
|
75
|
-
else if (arg === "--jsc") {
|
|
76
|
-
// jsc has the wrong column for some reason
|
|
77
|
-
jsc = 1;
|
|
78
|
-
}
|
|
79
|
-
else if (arg.startsWith("--retries")) {
|
|
80
|
-
retries = parseInt(arg.substring(9));
|
|
81
|
-
if (isNaN(retries) || retries < 0) {
|
|
82
|
-
console.error("smipper [stack|-h|--help|-v|--verbose|--version|--retries=<number>|--jsc|--json|-f=@FILE@|-");
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else if (arg === "-h" || arg === "--help") {
|
|
87
|
-
console.error("smipper [stack|-h|--help|-v|--verbose|--version|--retries=<number>|--jsc|--json|-f=@FILE@|-");
|
|
88
|
-
process.exit(0);
|
|
89
|
-
}
|
|
90
|
-
else if (arg === "-") {
|
|
91
|
-
// stdin
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
stack = arg;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
console.error("Error: " + err.toString());
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (!stack) {
|
|
103
|
-
stack = fs.readFileSync("/dev/stdin").toString();
|
|
104
|
-
if (!stack) {
|
|
105
|
-
console.error("Nothing to do");
|
|
106
|
-
process.exit(0);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function build(functionName, url, line, column) {
|
|
110
|
-
return "".concat(functionName ? "at " + functionName + " " : "").concat(url, ":").concat(line, ":").concat(column);
|
|
111
|
-
}
|
|
112
|
-
function findFile(dir, fn) {
|
|
113
|
-
var list = fs.readdirSync(dir);
|
|
114
|
-
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
|
|
115
|
-
var file = list_1[_i];
|
|
116
|
-
var match = file === fn;
|
|
117
|
-
file = dir + "/" + file;
|
|
118
|
-
var stat = fs.statSync(file);
|
|
119
|
-
if (stat && stat.isDirectory()) {
|
|
120
|
-
var ret = findFile(file, fn);
|
|
121
|
-
if (ret) {
|
|
122
|
-
return ret;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
else if (match) {
|
|
126
|
-
return "file://" + file;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return undefined;
|
|
130
|
-
}
|
|
131
|
-
function rewriteLocalControl(url) {
|
|
132
|
-
var found = findFile(process.cwd(), path.basename(url.substring(6)));
|
|
133
|
-
if (found) {
|
|
134
|
-
return found;
|
|
135
|
-
}
|
|
136
|
-
throw new Error("Couldn't resolve localcontrol " + url);
|
|
137
|
-
}
|
|
138
|
-
function load(path) {
|
|
139
|
-
return new Promise(function (resolve, reject) {
|
|
140
|
-
if (path.startsWith("http://localcontrol.netflix.com/")) {
|
|
141
|
-
try {
|
|
142
|
-
path = rewriteLocalControl(path);
|
|
143
|
-
}
|
|
144
|
-
catch (err) {
|
|
145
|
-
reject(err);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (path.startsWith("file:///")) {
|
|
150
|
-
try {
|
|
151
|
-
resolve(fs.readFileSync(path.substring(7), "utf8"));
|
|
152
|
-
}
|
|
153
|
-
catch (err) {
|
|
154
|
-
reject(err);
|
|
155
|
-
}
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
if (!path.startsWith("http://") && !path.startsWith("https://")) {
|
|
159
|
-
reject(new Error("Not a url"));
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
// let retryIndex = 0;
|
|
163
|
-
function get() {
|
|
164
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
165
|
-
var response;
|
|
166
|
-
return __generator(this, function (_a) {
|
|
167
|
-
switch (_a.label) {
|
|
168
|
-
case 0: return [4 /*yield*/, got.get(path, { timeout: 10000 })];
|
|
169
|
-
case 1:
|
|
170
|
-
response = _a.sent();
|
|
171
|
-
if (verbose) {
|
|
172
|
-
console.error(response.headers);
|
|
173
|
-
}
|
|
174
|
-
return [2 /*return*/, response.body || ""];
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
get().then(resolve, reject);
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
var sourceMaps = {};
|
|
183
|
-
function loadUri(path) {
|
|
184
|
-
var _this = this;
|
|
185
|
-
if (path[0] === "/") {
|
|
186
|
-
path = "file://" + path;
|
|
187
|
-
}
|
|
188
|
-
return new Promise(function (resolve, reject) {
|
|
189
|
-
if (verbose) {
|
|
190
|
-
console.error("loading", path);
|
|
191
|
-
}
|
|
192
|
-
if (!(path in sourceMaps)) {
|
|
193
|
-
sourceMaps[path] = {
|
|
194
|
-
resolvers: [resolve],
|
|
195
|
-
rejecters: [reject]
|
|
196
|
-
};
|
|
197
|
-
load(path)
|
|
198
|
-
.then(function (jsData) {
|
|
199
|
-
var idx = jsData.lastIndexOf("//# sourceMappingURL=");
|
|
200
|
-
if (verbose) {
|
|
201
|
-
console.error("Got the file", jsData.length, idx);
|
|
202
|
-
}
|
|
203
|
-
if (idx == -1) {
|
|
204
|
-
return path + ".map";
|
|
205
|
-
}
|
|
206
|
-
var mapUrl = jsData.substring(idx + 21);
|
|
207
|
-
var match = /^(data:.+\/.+;)base64,/.exec(mapUrl);
|
|
208
|
-
if (match) {
|
|
209
|
-
return mapUrl.substring(match[1].length);
|
|
210
|
-
}
|
|
211
|
-
if (mapUrl.indexOf("://") != -1) {
|
|
212
|
-
return mapUrl;
|
|
213
|
-
}
|
|
214
|
-
// console.log(mapUrl);
|
|
215
|
-
return new url.URL(mapUrl, path).href;
|
|
216
|
-
})
|
|
217
|
-
.then(function (mapUrl) {
|
|
218
|
-
// console.log(mapUrl.substring(0, 20));
|
|
219
|
-
if (mapUrl.startsWith("base64,")) {
|
|
220
|
-
return Buffer.from(mapUrl.substring(7), "base64").toString();
|
|
221
|
-
}
|
|
222
|
-
return load(mapUrl);
|
|
223
|
-
})
|
|
224
|
-
.then(function (sourceMapData) { return __awaiter(_this, void 0, void 0, function () {
|
|
225
|
-
var parsed, smap, pending;
|
|
226
|
-
return __generator(this, function (_a) {
|
|
227
|
-
switch (_a.label) {
|
|
228
|
-
case 0:
|
|
229
|
-
parsed = JSON.parse(sourceMapData);
|
|
230
|
-
return [4 /*yield*/, new sourceMap.SourceMapConsumer(parsed)];
|
|
231
|
-
case 1:
|
|
232
|
-
smap = _a.sent();
|
|
233
|
-
pending = sourceMaps[path];
|
|
234
|
-
// sourceMaps.delete(path);
|
|
235
|
-
if (pending) {
|
|
236
|
-
pending.resolvers.forEach(function (func) {
|
|
237
|
-
func(smap);
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
return [2 /*return*/];
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}); })["catch"](function (err) {
|
|
244
|
-
var pending = sourceMaps[path];
|
|
245
|
-
if (!pending) {
|
|
246
|
-
throw new Error("Gotta have pending");
|
|
247
|
-
}
|
|
248
|
-
// sourceMaps.delete(path);
|
|
249
|
-
pending.rejecters.forEach(function (func) {
|
|
250
|
-
func(err);
|
|
251
|
-
});
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
var cur = sourceMaps[path];
|
|
256
|
-
if (verbose) {
|
|
257
|
-
console.error("path is in source maps already", cur);
|
|
258
|
-
}
|
|
259
|
-
if (!cur) {
|
|
260
|
-
throw new Error("Gotta have cur");
|
|
261
|
-
}
|
|
262
|
-
cur.resolvers.push(resolve);
|
|
263
|
-
cur.rejecters.push(reject);
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
function processFrame(functionName, url, line, column) {
|
|
268
|
-
if (verbose) {
|
|
269
|
-
console.error("got frame", functionName, url, line, column);
|
|
270
|
-
}
|
|
271
|
-
if (functionName.endsWith("@")) {
|
|
272
|
-
functionName = functionName.substring(0, functionName.length - 1);
|
|
273
|
-
}
|
|
274
|
-
return new Promise(function (resolve) {
|
|
275
|
-
var newUrl, newLine, newColumn;
|
|
276
|
-
if (verbose) {
|
|
277
|
-
console.error("calling loadUri", url);
|
|
278
|
-
}
|
|
279
|
-
if (!url.includes("://") && url[0] !== "/" && fs.existsSync(url)) {
|
|
280
|
-
url = "file://".concat(process.cwd(), "/").concat(url);
|
|
281
|
-
}
|
|
282
|
-
return loadUri(url)
|
|
283
|
-
.then(function (smap) {
|
|
284
|
-
if (verbose) {
|
|
285
|
-
console.error("got map", url, Object.keys(smap));
|
|
286
|
-
}
|
|
287
|
-
// it appears that we're supposed to reduce the column
|
|
288
|
-
// number by 1 when we get this from jsc
|
|
289
|
-
var pos = smap.originalPositionFor({ line: line, column: column - jsc });
|
|
290
|
-
if (!pos.source) {
|
|
291
|
-
if (verbose) {
|
|
292
|
-
console.error("nothing here", pos);
|
|
293
|
-
}
|
|
294
|
-
throw new Error("Mapping not found");
|
|
295
|
-
}
|
|
296
|
-
// smc.sourceContentFor(pos.source);
|
|
297
|
-
newUrl = pos.source;
|
|
298
|
-
newLine = pos.line || 0;
|
|
299
|
-
newColumn = pos.column || 0;
|
|
300
|
-
})["catch"](function (err) {
|
|
301
|
-
if (verbose) {
|
|
302
|
-
console.error("didn't get map", url, err);
|
|
303
|
-
}
|
|
304
|
-
// console.error(err);
|
|
305
|
-
})["finally"](function () {
|
|
306
|
-
if (json) {
|
|
307
|
-
var ret = {
|
|
308
|
-
functionName: functionName,
|
|
309
|
-
sourceURL: newUrl ? newUrl : url,
|
|
310
|
-
line: newUrl ? newLine : line,
|
|
311
|
-
column: newUrl ? newColumn : column
|
|
312
|
-
};
|
|
313
|
-
// if (newUrl) {
|
|
314
|
-
// ret.oldSourceURL = url;
|
|
315
|
-
// ret.oldLine = line;
|
|
316
|
-
// ret.oldColumn = column;
|
|
317
|
-
// }
|
|
318
|
-
// if (newUrl) {
|
|
319
|
-
// ret.newUrl = newUrl;
|
|
320
|
-
// ret.newLine = newLine;
|
|
321
|
-
// ret.newColumn = newColumn;
|
|
322
|
-
// }
|
|
323
|
-
resolve(ret);
|
|
324
|
-
}
|
|
325
|
-
else {
|
|
326
|
-
var str = void 0;
|
|
327
|
-
if (newUrl) {
|
|
328
|
-
str = "".concat(build(functionName, newUrl, newLine, newColumn), " (").concat(build("", url, line, column), ")");
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
str = build(functionName, url, line, column);
|
|
332
|
-
}
|
|
333
|
-
resolve(str);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
if (json) {
|
|
339
|
-
var parsed = void 0;
|
|
340
|
-
try {
|
|
341
|
-
parsed = JSON.parse(stack);
|
|
342
|
-
if (!Array.isArray(parsed)) {
|
|
343
|
-
throw new Error("Expected array");
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
catch (err) {
|
|
347
|
-
console.error("Can't parse json ".concat(err));
|
|
348
|
-
process.exit(1);
|
|
349
|
-
}
|
|
350
|
-
Promise.all(parsed.map(function (frame) {
|
|
351
|
-
if (verbose) {
|
|
352
|
-
console.error("got frame frame", frame);
|
|
353
|
-
}
|
|
354
|
-
return processFrame(frame.functionName || "", frame.sourceURL || "", frame.line, frame.column);
|
|
355
|
-
}))
|
|
356
|
-
.then(function (results) {
|
|
357
|
-
results.forEach(function (frame, index) {
|
|
358
|
-
if (typeof frame !== "object") {
|
|
359
|
-
throw new Error("Huh?");
|
|
360
|
-
}
|
|
361
|
-
frame.index = index;
|
|
362
|
-
});
|
|
363
|
-
// console.log("shit", results);
|
|
364
|
-
console.log(JSON.stringify(results, null, 4));
|
|
365
|
-
})["catch"](function (error) {
|
|
366
|
-
console.error("Got an error", error);
|
|
367
|
-
process.exit(2);
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
Promise.all(stack
|
|
372
|
-
.split("\n")
|
|
373
|
-
.filter(function (x) { return x; })
|
|
374
|
-
.map(function (x) {
|
|
375
|
-
x = x.trim();
|
|
376
|
-
var match = / *at *([^ ]*).* \(?([^ ]+):([0-9]+):([0-9]+)/.exec(x);
|
|
377
|
-
if (!match) {
|
|
378
|
-
match = /([^ ]+@)?(.*):([0-9]+):([0-9]+)/.exec(x);
|
|
379
|
-
}
|
|
380
|
-
if (verbose) {
|
|
381
|
-
console.error(x, " => ", match);
|
|
382
|
-
}
|
|
383
|
-
if (!match) {
|
|
384
|
-
var nolinecol = /([^ ]*)(.*)/.exec(x);
|
|
385
|
-
if (nolinecol) {
|
|
386
|
-
return nolinecol[0];
|
|
387
|
-
}
|
|
388
|
-
return x;
|
|
389
|
-
}
|
|
390
|
-
return processFrame(match[1] || "", match[2], parseInt(match[3]), parseInt(match[4]));
|
|
391
|
-
}))
|
|
392
|
-
.then(function (results) {
|
|
393
|
-
if (!results.length) {
|
|
394
|
-
throw new Error("Empty output");
|
|
395
|
-
}
|
|
396
|
-
results.forEach(function (str) {
|
|
397
|
-
console.log(str);
|
|
398
|
-
});
|
|
399
|
-
})["catch"](function (error) {
|
|
400
|
-
console.error("Got an error", error);
|
|
401
|
-
process.exit(3);
|
|
402
|
-
});
|
|
403
|
-
}
|