forked from cypress-io/cypress
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjs.ts
87 lines (68 loc) · 2.62 KB
/
js.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import * as astTypes from 'ast-types'
import Debug from 'debug'
import { jsRules } from './js-rules'
import * as recast from 'recast'
import * as sourceMaps from './util/source-maps'
const debug = Debug('cypress:rewriter:js')
const defaultPrintOpts: recast.Options = {
// will only affect reprinted quotes
quote: 'single',
}
type OriginalSourceInfo = { url: string, js: string }
function _generateDriverError (url: string, err: Error) {
const args = JSON.stringify({
errMessage: err.message,
errStack: err.stack,
url,
})
return `window.top.Cypress.utils.throwErrByPath('proxy.js_rewriting_failed', { args: ${args} })`
}
// a function that, given source info, returns an id that can be used to build the sourcemap later
export type DeferSourceMapRewriteFn = (sourceInfo: OriginalSourceInfo) => string
export function rewriteJsSourceMap (url: string, js: string, inputSourceMap: any): any {
try {
const { sourceFileName, sourceMapName, sourceRoot } = sourceMaps.getPaths(url)
const ast = recast.parse(js, { sourceFileName })
astTypes.visit(ast, jsRules)
return recast.print(ast, {
inputSourceMap,
sourceMapName,
sourceRoot,
...defaultPrintOpts,
}).map
} catch (err) {
debug('error while parsing JS %o', { err, js: js.slice ? js.slice(0, 500) : js })
return { err }
}
}
export function _rewriteJsUnsafe (url: string, js: string, deferSourceMapRewrite?: DeferSourceMapRewriteFn): string {
const ast = recast.parse(js)
try {
astTypes.visit(ast, jsRules)
} catch (err) {
// if visiting fails, it points to a bug in our rewriting logic, so raise the error to the driver
return _generateDriverError(url, err)
}
const { code } = recast.print(ast, defaultPrintOpts)
if (!deferSourceMapRewrite) {
// no sourcemaps
return sourceMaps.stripMappingUrl(code)
}
// get an ID that can be used to lazy-generate the source map later
const sourceMapId = deferSourceMapRewrite({ url, js })
return sourceMaps.urlFormatter(
// using a relative URL ensures that required cookies + other headers are sent along
// and can be reused if the user's sourcemap requires an HTTP request to be made
`/__cypress/source-maps/${sourceMapId}.map`,
code,
)
}
export function rewriteJs (url: string, js: string, deferSourceMapRewrite?: DeferSourceMapRewriteFn): string {
try {
// rewriting can throw on invalid JS or if there are bugs in the js-rules, so always wrap it
return _rewriteJsUnsafe(url, js, deferSourceMapRewrite)
} catch (err) {
debug('error while parsing JS %o', { err, js: js.slice ? js.slice(0, 500) : js })
return js
}
}