@contrast/rewriter 1.39.0 → 1.40.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/lib/cache.js +0 -46
- package/lib/index.js +30 -34
- package/lib/rewrite-is-deadzoned.js +8 -0
- package/package.json +5 -6
package/lib/cache.js
CHANGED
|
@@ -141,52 +141,6 @@ module.exports.Cache = class Cache {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
/**
|
|
145
|
-
* Asynchronously looks up and returns the source map for a previously rewritten file.
|
|
146
|
-
* @param {string} filename
|
|
147
|
-
* @returns {Promise<string | undefined>}
|
|
148
|
-
*/
|
|
149
|
-
async readMap(filename) {
|
|
150
|
-
const filenameCached = this.getCachedFilename(filename);
|
|
151
|
-
const sourceMap = `${filenameCached}.map`;
|
|
152
|
-
|
|
153
|
-
try {
|
|
154
|
-
return fsPromises.readFile(sourceMap, 'utf8');
|
|
155
|
-
} catch (err) {
|
|
156
|
-
// @ts-expect-error ts treats errors poorly.
|
|
157
|
-
if (err.code !== 'ENOENT') {
|
|
158
|
-
this.logger.warn(
|
|
159
|
-
{ err, filename, filenameCached, sourceMap },
|
|
160
|
-
'An unexpected error occurred finding source map.'
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
return undefined;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Synchronously looks up and returns the source map for a previously rewritten file.
|
|
170
|
-
* @param {string} filename
|
|
171
|
-
* @returns {string | undefined}
|
|
172
|
-
*/
|
|
173
|
-
readMapSync(filename) {
|
|
174
|
-
const filenameCached = this.getCachedFilename(filename);
|
|
175
|
-
const sourceMap = `${filenameCached}.map`;
|
|
176
|
-
try {
|
|
177
|
-
return fs.readFileSync(sourceMap, 'utf8');
|
|
178
|
-
} catch (err) {
|
|
179
|
-
// @ts-expect-error ts treats errors poorly.
|
|
180
|
-
if (err.code !== 'ENOENT') {
|
|
181
|
-
this.logger.warn(
|
|
182
|
-
{ err, filename, filenameCached, sourceMap },
|
|
183
|
-
'An unexpected error occurred finding source map.'
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
return undefined;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
144
|
/**
|
|
191
145
|
* Looks up and returns the string content of a previously rewritten file
|
|
192
146
|
* synchronously. Used when we need to block on cache lookups.
|
package/lib/index.js
CHANGED
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
// @ts-check
|
|
16
16
|
'use strict';
|
|
17
17
|
const { arch, platform } = require('node:os');
|
|
18
|
-
|
|
19
|
-
const { SourceMapConsumer: SourceMapConsumerSync } = require('@contrast/synchronous-source-maps');
|
|
18
|
+
const { findSourceMap } = require('node:module');
|
|
20
19
|
const { parseSync, transform, transformSync } = require('@swc/core');
|
|
21
20
|
// @ts-expect-error `@contrast/agent-swc-plugin` .d.ts file doesn't exist.
|
|
22
21
|
const { defaultRewriter, defaultUnwriter } = require('@contrast/agent-swc-plugin');
|
|
@@ -70,7 +69,7 @@ class Rewriter {
|
|
|
70
69
|
*/
|
|
71
70
|
swcOptions(opts) {
|
|
72
71
|
const nodeCfg = this.core.config.agent.node;
|
|
73
|
-
const sourceMaps = nodeCfg.source_maps.enable;
|
|
72
|
+
const sourceMaps = nodeCfg.source_maps.inline ? 'inline' : nodeCfg.source_maps.enable;
|
|
74
73
|
const minify = opts.minify && nodeCfg.source_maps.enable && nodeCfg.rewrite.minify;
|
|
75
74
|
opts.minify = minify;
|
|
76
75
|
return {
|
|
@@ -110,22 +109,23 @@ class Rewriter {
|
|
|
110
109
|
* - result.map.sources array
|
|
111
110
|
* @param {RewriteOpts} rewriteOpts
|
|
112
111
|
* @param {import('@swc/core').Output} result
|
|
112
|
+
* @returns {import('@swc/core').Output}
|
|
113
113
|
*/
|
|
114
|
-
|
|
114
|
+
adjustResult(rewriteOpts, result) {
|
|
115
115
|
if (rewriteOpts.filename && result.map) {
|
|
116
116
|
const map = JSON.parse(result.map);
|
|
117
117
|
const cachedFilename = this.cache.getCachedFilename(rewriteOpts.filename);
|
|
118
|
-
const absoluteCachedMapName = `${cachedFilename}.map`;
|
|
119
|
-
const origMapURL = `${primordials.PathBasename(rewriteOpts.filename)}.map`;
|
|
120
|
-
const comment = `${MAGIC_COMMENT_PREFIX}${origMapURL}`;
|
|
121
118
|
|
|
122
119
|
// 1) magic comment
|
|
123
120
|
// https://github.com/nodejs/node/blob/main/lib/internal/source_map/source_map_cache.js#L134-L136
|
|
124
|
-
const i = result.code.lastIndexOf(
|
|
121
|
+
const i = result.code.lastIndexOf(MAGIC_COMMENT_PREFIX);
|
|
125
122
|
if (i >= 0) {
|
|
126
123
|
let code = primordials.StringPrototypeSubstr.call(result.code, 0, i);
|
|
127
|
-
code += `${MAGIC_COMMENT_PREFIX}${
|
|
124
|
+
code += `${MAGIC_COMMENT_PREFIX}${cachedFilename}.map`;
|
|
128
125
|
result.code = code;
|
|
126
|
+
} else {
|
|
127
|
+
// if the comment is missing entirely, add it
|
|
128
|
+
result.code += `${MAGIC_COMMENT_PREFIX}${cachedFilename}.map`;
|
|
129
129
|
}
|
|
130
130
|
// 2) map.sources array
|
|
131
131
|
for (let i = 0; i < map.sources?.length; i++) {
|
|
@@ -140,6 +140,8 @@ class Rewriter {
|
|
|
140
140
|
// reasign modified map
|
|
141
141
|
result.map = primordials.JSONStringify(map);
|
|
142
142
|
}
|
|
143
|
+
|
|
144
|
+
return result;
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
/**
|
|
@@ -153,9 +155,8 @@ class Rewriter {
|
|
|
153
155
|
async rewrite(content, opts = {}) {
|
|
154
156
|
const rewriteOpts = this.swcOptions(opts);
|
|
155
157
|
this.logger.trace({ opts }, 'rewriting %s', opts.filename);
|
|
156
|
-
const
|
|
157
|
-
this.
|
|
158
|
-
return ret;
|
|
158
|
+
const result = await transform(content, rewriteOpts);
|
|
159
|
+
return this.adjustResult(rewriteOpts, result);
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
/**
|
|
@@ -171,8 +172,7 @@ class Rewriter {
|
|
|
171
172
|
const rewriteOpts = this.swcOptions(opts);
|
|
172
173
|
this.logger.trace({ opts }, 'rewriting %s', opts.filename);
|
|
173
174
|
const result = transformSync(content, rewriteOpts);
|
|
174
|
-
this.
|
|
175
|
-
return result;
|
|
175
|
+
return this.adjustResult(rewriteOpts, result);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/**
|
|
@@ -198,18 +198,11 @@ class Rewriter {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
/**
|
|
201
|
-
*
|
|
202
|
-
* @
|
|
203
|
-
*/
|
|
204
|
-
async funcInfo(func) {
|
|
205
|
-
throw new Error('funcInfo is not implemented');
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* @param {function} func
|
|
201
|
+
* @param {Function} func
|
|
202
|
+
* @returns {any} replace with {import('@contrast/fn-inspect').FuncInfo} once exported from fn-inspect
|
|
210
203
|
*/
|
|
211
204
|
funcInfoSync(func) {
|
|
212
|
-
/** @type any */
|
|
205
|
+
/** @type {any} {import('@contrast/fn-inspect').FuncInfo} */
|
|
213
206
|
const fnInfo = funcInfo(func);
|
|
214
207
|
|
|
215
208
|
if (
|
|
@@ -219,17 +212,20 @@ class Rewriter {
|
|
|
219
212
|
!this.core.config.agent.node.source_maps.enable
|
|
220
213
|
) return fnInfo;
|
|
221
214
|
|
|
222
|
-
|
|
223
|
-
|
|
215
|
+
try {
|
|
216
|
+
const map = findSourceMap(fnInfo.file);
|
|
217
|
+
if (!map) return fnInfo;
|
|
224
218
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
219
|
+
const entry = map.findEntry(fnInfo.lineNumber, fnInfo.column);
|
|
220
|
+
if (entry) {
|
|
221
|
+
fnInfo.file = entry.originalSource ? primordials.PathResolve(fnInfo.file, '..', entry.originalSource) : fnInfo.file;
|
|
222
|
+
|
|
223
|
+
// fn-inspect and source map entries are 0 indexed, but stack traces display 1-indexed lines and columns.
|
|
224
|
+
fnInfo.lineNumber = entry.originalLine + 1;
|
|
225
|
+
fnInfo.column = entry.originalColumn + 1;
|
|
226
|
+
}
|
|
227
|
+
} catch (err) {
|
|
228
|
+
this.logger.debug({ err, fnInfo }, 'findSourceMap failed for %s', fnInfo.file);
|
|
233
229
|
}
|
|
234
230
|
|
|
235
231
|
return fnInfo;
|
|
@@ -60,12 +60,20 @@ const DEADZONED_PATHS = [
|
|
|
60
60
|
'moment-timezone',
|
|
61
61
|
'node-forge',
|
|
62
62
|
'node-webpack',
|
|
63
|
+
`@opentelemetry${sep}api`,
|
|
64
|
+
`@opentelemetry${sep}core`,
|
|
65
|
+
`@opentelemetry${sep}instrumentation`,
|
|
66
|
+
`@opentelemetry${sep}resources`,
|
|
67
|
+
`@opentelemetry${sep}sdk-metrics`,
|
|
68
|
+
`@opentelemetry${sep}sdk-trace-base`,
|
|
69
|
+
`@opentelemetry${sep}sdk-trace-node`,
|
|
63
70
|
'pem',
|
|
64
71
|
'react',
|
|
65
72
|
'react-dom', // doesn't this cover the next line?
|
|
66
73
|
//'react-dom/server',
|
|
67
74
|
'requirejs',
|
|
68
75
|
'semver',
|
|
76
|
+
'@sentry',
|
|
69
77
|
'strong-remoting',
|
|
70
78
|
'type-is',
|
|
71
79
|
'uglify-js',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/rewriter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.40.0",
|
|
4
4
|
"description": "A transpilation tool mainly used for instrumentation",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
|
|
@@ -21,12 +21,11 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@contrast/agent-swc-plugin": "3.2.0",
|
|
24
|
-
"@contrast/common": "1.41.
|
|
25
|
-
"@contrast/config": "1.
|
|
26
|
-
"@contrast/core": "1.
|
|
24
|
+
"@contrast/common": "1.41.1",
|
|
25
|
+
"@contrast/config": "1.58.0",
|
|
26
|
+
"@contrast/core": "1.63.0",
|
|
27
27
|
"@contrast/fn-inspect": "^5.0.2",
|
|
28
|
-
"@contrast/logger": "1.
|
|
29
|
-
"@contrast/synchronous-source-maps": "^1.1.5",
|
|
28
|
+
"@contrast/logger": "1.36.0",
|
|
30
29
|
"@swc/core": "1.13.3"
|
|
31
30
|
}
|
|
32
31
|
}
|