openreplay/sourcemap-reader/servers/sourcemaps-handler.js
Taha Yassine Kraiem f1a158e2a3 feat(sourcemaps-reader): read sourcemap from URL
feat(chalice): look for sourcemap in URL if not found in bucket
2022-10-19 20:27:50 +02:00

151 lines
No EOL
6.1 KiB
JavaScript

'use strict';
const fs = require('fs');
const sourceMap = require('source-map');
const AWS = require('aws-sdk');
const URL = require('url');
const request = require('request');
const wasm = fs.readFileSync(process.env.MAPPING_WASM || '/mappings.wasm');
sourceMap.SourceMapConsumer.initialize({
"lib/mappings.wasm": wasm
});
console.log(`>sourceMap initialised using ${process.env.MAPPING_WASM || '/mappings.wasm'}`);
function parseSourcemap(sourcemap, event, options, resolve, reject) {
const getObjectEnd = Date.now();
try {
return new sourceMap.SourceMapConsumer(sourcemap)
.then(consumer => {
let results = [];
for (let i = 0; i < event.positions.length; i++) {
let original = consumer.originalPositionFor({
line: event.positions[i].line,
column: event.positions[i].column
});
let url = URL.parse("");
let preview = [];
if (original.source) {
preview = consumer.sourceContentFor(original.source, true);
if (preview !== null) {
preview = preview.split("\n")
.map((line, i) => [i + 1, line]);
if (event.padding) {
let start = original.line < event.padding ? 0 : original.line - event.padding;
preview = preview.slice(start, original.line + event.padding);
}
} else {
console.log(`[SR] source not found, null preview for: ${original.source}`);
preview = []
}
url = URL.parse(original.source);
} else {
console.log("[SR] couldn't find original position of: " + JSON.stringify({
line: event.positions[i].line,
column: event.positions[i].column
}));
}
let result = {
"absPath": url.href,
"filename": url.pathname,
"lineNo": original.line,
"colNo": original.column,
"function": original.name,
"context": preview
};
// console.log(result);
results.push(result);
}
consumer = undefined;
options.sourcemapProcessingTime = (Date.now() - getObjectEnd) / 1000;
options.sourcemapProcessingTimeUnit = 's';
if (options.fileSize >= 3 || options.sourcemapProcessingTime > 2) {
console.log("[SR] " + JSON.stringify(options));
}
// Use this code if you don't use the http event with the LAMBDA-PROXY integration
return resolve(results);
})
.catch(err => {
return reject(err);
})
.finally(() => {
sourcemap = undefined;
});
} catch (err) {
reject(err);
}
}
module.exports.sourcemapReader = async event => {
if (event.isURL) {
let options = {
URL: event.key
};
return new Promise(function (resolve, reject) {
const getObjectStart = Date.now();
return request.get(options.URL, (err, response, sourcemap) => {
if (err || response.statusCode !== 200) {
console.error("[SR] Getting file from URL failed");
console.error("err:");
console.error(err);
console.error("response:");
if (err) {
return reject(err);
}
return reject(response);
}
const getObjectEnd = Date.now();
options.fileSize = (response.headers['content-length'] / 1024) / 1024;
options.fileSizeUnit = 'Mb';
options.downloadTime = (getObjectEnd - getObjectStart) / 1000;
options.downloadTimeUnit = 's';
if (options.fileSize >= 3) {
console.log("[SR] large file:" + JSON.stringify(options));
}
return parseSourcemap(sourcemap, event, options, resolve, reject);
});
});
} else {
let s3;
if (process.env.S3_HOST) {
s3 = new AWS.S3({
endpoint: process.env.S3_HOST,
accessKeyId: process.env.S3_KEY,
secretAccessKey: process.env.S3_SECRET,
s3ForcePathStyle: true, // needed with minio?
signatureVersion: 'v4'
});
} else {
s3 = new AWS.S3({
'AccessKeyID': process.env.aws_access_key_id,
'SecretAccessKey': process.env.aws_secret_access_key,
'Region': process.env.aws_region
});
}
let options = {
Bucket: event.bucket,
Key: event.key
};
return new Promise(function (resolve, reject) {
const getObjectStart = Date.now();
s3.getObject(options, (err, data) => {
if (err) {
console.error("[SR] Get S3 object failed");
console.error(err);
return reject(err);
}
const getObjectEnd = Date.now();
options.fileSize = (data.ContentLength / 1024) / 1024;
options.fileSizeUnit = 'Mb';
options.downloadTime = (getObjectEnd - getObjectStart) / 1000;
options.downloadTimeUnit = 's';
if (options.fileSize >= 3) {
console.log("[SR] large file:" + JSON.stringify(options));
}
let sourcemap = data.Body.toString();
return parseSourcemap(sourcemap, event, options, resolve, reject);
});
});
}
};