diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..92cc7bc --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,45 @@ +name: Continuous Integration +on: + # branches pushed by collaborators + push: + branches: + - master + # pull request from non-collaborators + pull_request: {} + # nightly + schedule: + - cron: '0 0 * * *' +jobs: + build: + name: "Test: ${{ matrix.os }}, node ${{ matrix.node }}" + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu, windows] + node: + - 16 + - 14 + - 12 + steps: + # checkout code + - uses: actions/checkout@v2 + # install node + - name: Use Node.js ${{ matrix.os }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + + # npm install with caching + - run: | + npm config set cache "$( node -p "process.cwd()" )/temp/npm-cache" + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: temp/npm-cache + key: npm-cache-${{ matrix.os }} ${{ matrix.node }}-${{ hashFiles('package-lock.json') }} + # restore-keys: npm-cache-${{ matrix.os }} ${{ matrix.node }}- + - run: npm install + + # Run tests + - run: npm test diff --git a/package.json b/package.json index 96dedd5..19322a3 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "test": "mocha" }, "dependencies": { - "buffer-from": "^1.0.0", "source-map": "^0.6.0" }, "devDependencies": { @@ -27,5 +26,8 @@ "bugs": { "url": "https://github.com/evanw/node-source-map-support/issues" }, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12" + } } diff --git a/source-map-support.js b/source-map-support.js index 4459386..097a133 100644 --- a/source-map-support.js +++ b/source-map-support.js @@ -12,8 +12,6 @@ try { /* nop */ } -var bufferFrom = require('buffer-from'); - /** * Requires a module which is protected against bundler minification. * @@ -171,7 +169,7 @@ retrieveMapHandlers.push(function(source) { if (reSourceMap.test(sourceMappingURL)) { // Support source map URL as a data url var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1); - sourceMapData = bufferFrom(rawData, "base64").toString(); + sourceMapData = Buffer.from(rawData, "base64").toString(); sourceMappingURL = source; } else { // Support source map URLs relative to the source URL @@ -408,6 +406,19 @@ function wrapCallSite(frame, state) { return frame; } +var kIsNodeError = undefined; +try { + // Get a deliberate ERR_INVALID_ARG_TYPE + // TODO is there a better way to reliably get an instance of NodeError? + path.resolve(123); +} catch(e) { + const symbols = Object.getOwnPropertySymbols(e); + const symbol = symbols.find(function (s) {return s.toString().indexOf('kIsNodeError') >= 0}); + if(symbol) kIsNodeError = symbol; +} + +const ErrorPrototypeToString = (err) =>Error.prototype.toString.call(err); + // This function is part of the V8 stack trace API, for more info see: // https://v8.dev/docs/stack-trace-api function prepareStackTrace(error, stack) { @@ -416,9 +427,21 @@ function prepareStackTrace(error, stack) { sourceMapCache = {}; } - var name = error.name || 'Error'; - var message = error.message || ''; - var errorString = name + ": " + message; + // node gives its own errors special treatment. Mimic that behavior + // https://github.com/nodejs/node/blob/3cbaabc4622df1b4009b9d026a1a970bdbae6e89/lib/internal/errors.js#L118-L128 + // https://github.com/nodejs/node/pull/39182 + var errorString; + if (kIsNodeError) { + if(kIsNodeError in error) { + errorString = `${error.name} [${error.code}]: ${error.message}`; + } else { + errorString = ErrorPrototypeToString(error); + } + } else { + var name = error.name || 'Error'; + var message = error.message || ''; + errorString = name + ": " + message; + } var state = { nextPosition: null, curPosition: null }; var processedStack = []; @@ -471,11 +494,10 @@ function printErrorAndExit (error) { } if (source) { - console.error(); console.error(source); } - console.error(error.stack); + console.error(error); process.exit(1); } diff --git a/test.js b/test.js index ef7ad55..797ebbd 100644 --- a/test.js +++ b/test.js @@ -6,7 +6,7 @@ var SourceMapGenerator = require('source-map').SourceMapGenerator; var child_process = require('child_process'); var assert = require('assert'); var fs = require('fs'); -var bufferFrom = require('buffer-from'); +var bufferFrom = Buffer.from; function compareLines(actual, expected) { assert(actual.length >= expected.length, 'got ' + actual.length + ' lines but expected at least ' + expected.length + ' lines'); @@ -86,7 +86,7 @@ function createMultiLineSourceMapWithSourcesContent() { function compareStackTrace(sourceMap, source, expected) { // Check once with a separate source map - fs.writeFileSync('.generated.js.map', sourceMap); + fs.writeFileSync('.generated.js.map', sourceMap.toString()); fs.writeFileSync('.generated.js', 'exports.test = function() {' + source.join('\n') + '};//@ sourceMappingURL=.generated.js.map'); try { @@ -113,7 +113,7 @@ function compareStackTrace(sourceMap, source, expected) { function compareStdout(done, sourceMap, source, expected) { fs.writeFileSync('.original.js', 'this is the original code'); - fs.writeFileSync('.generated.js.map', sourceMap); + fs.writeFileSync('.generated.js.map', sourceMap.toString()); fs.writeFileSync('.generated.js', source.join('\n') + '//@ sourceMappingURL=.generated.js.map'); child_process.exec('node ./.generated', function(error, stdout, stderr) { @@ -616,7 +616,7 @@ it('handleUncaughtExceptions is true with existing listener', function(done) { ]; fs.writeFileSync('.original.js', 'this is the original code'); - fs.writeFileSync('.generated.js.map', createSingleLineSourceMap()); + fs.writeFileSync('.generated.js.map', createSingleLineSourceMap().toString()); fs.writeFileSync('.generated.js', source.join('\n')); child_process.exec('node ./.generated', function(error, stdout, stderr) {