Skip to content

Commit d763e1f

Browse files
committed
feat: try re-generating snapshot [run ci]
1 parent 0f4e836 commit d763e1f

20 files changed

+2119
-33
lines changed

packages/resolve-dist/lib/index.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict'
2+
Object.defineProperty(exports, '__esModule', { value: true })
3+
exports.getPathToDesktopIndex = exports.getPathToIndex = exports.getRunnerCrossOriginInjectionContents = exports.getRunnerInjectionContents = exports.getPathToDist = exports.resolveFromPackages = void 0
4+
5+
const tslib_1 = require('tslib')
6+
const path_1 = tslib_1.__importDefault(require('path'))
7+
let fs
8+
const resolveFromPackages = (...args) => {
9+
return path_1.default.join(...[__dirname, '..', '..', ...args])
10+
}
11+
12+
exports.resolveFromPackages = resolveFromPackages
13+
14+
const getRunnerContents = (filename) => {
15+
fs !== null && fs !== void 0 ? fs : (fs = require('fs-extra'))
16+
17+
return fs.readFile((0, exports.getPathToDist)('runner', filename))
18+
}
19+
const getPathToDist = (folder, ...args) => {
20+
return path_1.default.join(...[__dirname, '..', '..', folder, 'dist', ...args])
21+
}
22+
23+
exports.getPathToDist = getPathToDist
24+
25+
const getRunnerInjectionContents = () => {
26+
return getRunnerContents('injection.js')
27+
}
28+
29+
exports.getRunnerInjectionContents = getRunnerInjectionContents
30+
31+
const getRunnerCrossOriginInjectionContents = () => {
32+
return getRunnerContents('injection_cross_origin.js')
33+
}
34+
35+
exports.getRunnerCrossOriginInjectionContents = getRunnerCrossOriginInjectionContents
36+
37+
const getPathToIndex = (pkg) => {
38+
return (0, exports.getPathToDist)(pkg, 'index.html')
39+
}
40+
41+
exports.getPathToIndex = getPathToIndex
42+
43+
const getPathToDesktopIndex = (graphqlPort) => {
44+
return `http://localhost:${graphqlPort}/__launchpad/index.html`
45+
}
46+
47+
exports.getPathToDesktopIndex = getPathToDesktopIndex
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict'
2+
Object.defineProperty(exports, '__esModule', { value: true })
3+
exports.rewriteJsSourceMapAsync = exports.rewriteJsAsync = exports.rewriteHtmlJsAsync = void 0
4+
5+
const threads_1 = require('./threads')
6+
7+
// these functions are not included in `./js` or `./html` because doing so
8+
// would mean that `./threads/worker` would unnecessarily end up loading in the
9+
// `./threads` module for each worker
10+
function rewriteHtmlJsAsync (url, html, deferSourceMapRewrite) {
11+
return (0, threads_1.queueRewriting)({
12+
url,
13+
deferSourceMapRewrite,
14+
source: html,
15+
isHtml: true,
16+
})
17+
}
18+
exports.rewriteHtmlJsAsync = rewriteHtmlJsAsync
19+
20+
function rewriteJsAsync (url, js, deferSourceMapRewrite) {
21+
return (0, threads_1.queueRewriting)({
22+
url,
23+
deferSourceMapRewrite,
24+
source: js,
25+
})
26+
}
27+
exports.rewriteJsAsync = rewriteJsAsync
28+
29+
function rewriteJsSourceMapAsync (url, js, inputSourceMap) {
30+
return (0, threads_1.queueRewriting)({
31+
url,
32+
inputSourceMap,
33+
sourceMap: true,
34+
source: js,
35+
})
36+
}
37+
exports.rewriteJsSourceMapAsync = rewriteJsSourceMapAsync
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
'use strict'
2+
Object.defineProperty(exports, '__esModule', { value: true })
3+
exports.DeferredSourceMapCache = void 0
4+
5+
const tslib_1 = require('tslib')
6+
const lodash_1 = tslib_1.__importDefault(require('lodash'))
7+
const debug_1 = tslib_1.__importDefault(require('debug'))
8+
const async_rewriters_1 = require('./async-rewriters')
9+
const sourceMaps = tslib_1.__importStar(require('./util/source-maps'))
10+
const url_1 = tslib_1.__importDefault(require('url'))
11+
const debug = (0, debug_1.default)('cypress:rewriter:deferred-source-map-cache')
12+
const caseInsensitiveGet = (obj, lowercaseProperty) => {
13+
for (let key of Object.keys(obj)) {
14+
if (key.toLowerCase() === lowercaseProperty) {
15+
return obj[key]
16+
}
17+
}
18+
}
19+
const getSourceMapHeader = (headers) => {
20+
// sourcemap has precedence
21+
// @see https://searchfox.org/mozilla-central/rev/dc4560dcaafd79375b9411fdbbaaebb0a59a93ac/devtools/shared/DevToolsUtils.js#611-619
22+
return caseInsensitiveGet(headers, 'sourcemap') || caseInsensitiveGet(headers, 'x-sourcemap')
23+
}
24+
25+
/**
26+
* Holds on to data necessary to rewrite user JS to maybe generate a sourcemap at a later time,
27+
* potentially composed with the user's own sourcemap if one is present.
28+
*
29+
* The purpose of this is to avoid wasting CPU time and network I/O on generating, composing, and
30+
* sending a sourcemap along with every single rewritten JS snippet, since the source maps are
31+
* going to be unused and discarded most of the time.
32+
*/
33+
class DeferredSourceMapCache {
34+
constructor (requestLib) {
35+
this._idCounter = 0
36+
this.requests = []
37+
this.defer = (request) => {
38+
if (this._getRequestById(request.uniqueId)) {
39+
// prevent duplicate uniqueIds from ever existing
40+
throw new Error(`Deferred sourcemap key "${request.uniqueId}" is not unique`)
41+
}
42+
43+
// remove existing requests for this URL since they will not be loaded again
44+
this._removeRequestsByUrl(request.url)
45+
this.requests.push(request)
46+
}
47+
48+
this.requestLib = requestLib
49+
}
50+
_removeRequestsByUrl (url) {
51+
lodash_1.default.remove(this.requests, { url })
52+
}
53+
_getRequestById (uniqueId) {
54+
return lodash_1.default.find(this.requests, { uniqueId })
55+
}
56+
async _getInputSourceMap (request, headers) {
57+
// prefer inline sourceMappingURL over headers
58+
const sourceMapUrl = sourceMaps.getMappingUrl(request.js) || getSourceMapHeader(request.resHeaders)
59+
60+
if (!sourceMapUrl) {
61+
return
62+
}
63+
64+
// try to decode it as a base64 string
65+
const inline = sourceMaps.tryDecodeInlineUrl(sourceMapUrl)
66+
67+
if (inline) {
68+
return inline
69+
}
70+
71+
// try to load it from the web
72+
const req = {
73+
url: url_1.default.resolve(request.url, sourceMapUrl),
74+
// TODO: this assumes that the sourcemap is on the same base domain, so it's safe to send the same headers
75+
// the browser sent for this sourcemap request - but if sourcemap is on a different domain, this will not
76+
// be true. need to use browser's cookiejar instead.
77+
headers,
78+
timeout: 5000,
79+
}
80+
81+
try {
82+
const { body } = await this.requestLib(req, true)
83+
84+
return body
85+
} catch (error) {
86+
// eslint-disable-next-line no-console
87+
debug('got an error loading user-provided sourcemap, serving proxy-generated sourcemap only %o', { url: request.url, headers, error })
88+
}
89+
}
90+
async resolve (uniqueId, headers) {
91+
const request = this._getRequestById(uniqueId)
92+
93+
if (!request) {
94+
throw new Error(`Missing request with ID '${uniqueId}'`)
95+
}
96+
97+
if (request.sourceMap) {
98+
return request.sourceMap
99+
}
100+
101+
if (!request.js) {
102+
throw new Error('Missing JS for source map rewrite')
103+
}
104+
105+
const inputSourceMap = await this._getInputSourceMap(request, headers)
106+
107+
// cache the sourceMap so we don't need to regenerate it
108+
request.sourceMap = await (0, async_rewriters_1.rewriteJsSourceMapAsync)(request.url, request.js, inputSourceMap)
109+
delete request.js // won't need this again
110+
delete request.resHeaders
111+
112+
return request.sourceMap
113+
}
114+
}
115+
exports.DeferredSourceMapCache = DeferredSourceMapCache

packages/rewriter/lib/html-rules.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict'
2+
Object.defineProperty(exports, '__esModule', { value: true })
3+
exports.install = void 0
4+
5+
const tslib_1 = require('tslib')
6+
const find_1 = tslib_1.__importDefault(require('lodash/find'))
7+
const constants_json_1 = require('./constants.json')
8+
const js = tslib_1.__importStar(require('./js'))
9+
10+
function install (url, rewriter, deferSourceMapRewrite) {
11+
let currentlyInsideJsScriptTag = false
12+
let inlineJsIndex = 0
13+
14+
rewriter.on('startTag', (startTag, raw) => {
15+
if (startTag.tagName !== 'script') {
16+
currentlyInsideJsScriptTag = false
17+
18+
return rewriter.emitRaw(raw)
19+
}
20+
21+
const typeAttr = (0, find_1.default)(startTag.attrs, { name: 'type' })
22+
23+
if (typeAttr && typeAttr.value !== 'text/javascript' && typeAttr.value !== 'module') {
24+
// we don't care about intercepting non-JS <script> tags
25+
currentlyInsideJsScriptTag = false
26+
27+
return rewriter.emitRaw(raw)
28+
}
29+
30+
currentlyInsideJsScriptTag = true
31+
// rename subresource integrity attr since cypress's rewriting will invalidate SRI hashes
32+
// @see https://github.com/cypress-io/cypress/issues/2393
33+
const sriAttr = (0, find_1.default)(startTag.attrs, { name: 'integrity' })
34+
35+
if (sriAttr) {
36+
sriAttr.name = constants_json_1.STRIPPED_INTEGRITY_TAG
37+
}
38+
39+
return rewriter.emitStartTag(startTag)
40+
})
41+
42+
rewriter.on('endTag', (_endTag, raw) => {
43+
currentlyInsideJsScriptTag = false
44+
45+
return rewriter.emitRaw(raw)
46+
})
47+
48+
rewriter.on('text', (_textToken, raw) => {
49+
if (!currentlyInsideJsScriptTag) {
50+
return rewriter.emitRaw(raw)
51+
}
52+
53+
// rewrite inline JS in <script> tags
54+
// create a unique filename per inline script
55+
const fakeJsUrl = [url, inlineJsIndex++].join(':')
56+
57+
return rewriter.emitRaw(js.rewriteJs(fakeJsUrl, raw, deferSourceMapRewrite))
58+
})
59+
}
60+
exports.install = install

packages/rewriter/lib/html.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict'
2+
Object.defineProperty(exports, '__esModule', { value: true })
3+
exports.rewriteHtmlJs = exports.HtmlJsRewriter = void 0
4+
5+
const tslib_1 = require('tslib')
6+
const parse5_html_rewriting_stream_1 = tslib_1.__importDefault(require('parse5-html-rewriting-stream'))
7+
const htmlRules = tslib_1.__importStar(require('./html-rules'))
8+
9+
// the HTML rewriter passes inline JS to the JS rewriter, hence
10+
// the lack of basic `rewriteHtml` or `HtmlRewriter` exports here
11+
function HtmlJsRewriter (url, deferSourceMapRewrite) {
12+
const rewriter = new parse5_html_rewriting_stream_1.default()
13+
14+
htmlRules.install(url, rewriter, deferSourceMapRewrite)
15+
16+
return rewriter
17+
}
18+
exports.HtmlJsRewriter = HtmlJsRewriter
19+
20+
function rewriteHtmlJs (url, html, deferSourceMapRewrite) {
21+
let out = ''
22+
const rewriter = HtmlJsRewriter(url, deferSourceMapRewrite)
23+
24+
rewriter.on('data', (chunk) => {
25+
out += chunk
26+
})
27+
28+
rewriter.end(html)
29+
30+
return new Promise((resolve) => {
31+
rewriter.on('end', () => {
32+
resolve(out)
33+
})
34+
})
35+
}
36+
exports.rewriteHtmlJs = rewriteHtmlJs

packages/rewriter/lib/index.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict'
2+
Object.defineProperty(exports, '__esModule', { value: true })
3+
exports.STRIPPED_INTEGRITY_TAG = exports.terminateAllWorkers = exports.createInitialWorkers = exports.DeferredSourceMapCache = exports.rewriteHtmlJsAsync = exports.rewriteJsAsync = exports.HtmlJsRewriter = void 0
4+
5+
let html_1 = require('./html')
6+
7+
Object.defineProperty(exports, 'HtmlJsRewriter', { enumerable: true, get () {
8+
return html_1.HtmlJsRewriter
9+
} })
10+
11+
let async_rewriters_1 = require('./async-rewriters')
12+
13+
Object.defineProperty(exports, 'rewriteJsAsync', { enumerable: true, get () {
14+
return async_rewriters_1.rewriteJsAsync
15+
} })
16+
17+
Object.defineProperty(exports, 'rewriteHtmlJsAsync', { enumerable: true, get () {
18+
return async_rewriters_1.rewriteHtmlJsAsync
19+
} })
20+
21+
let deferred_source_map_cache_1 = require('./deferred-source-map-cache')
22+
23+
Object.defineProperty(exports, 'DeferredSourceMapCache', { enumerable: true, get () {
24+
return deferred_source_map_cache_1.DeferredSourceMapCache
25+
} })
26+
27+
let threads_1 = require('./threads')
28+
29+
Object.defineProperty(exports, 'createInitialWorkers', { enumerable: true, get () {
30+
return threads_1.createInitialWorkers
31+
} })
32+
33+
Object.defineProperty(exports, 'terminateAllWorkers', { enumerable: true, get () {
34+
return threads_1.terminateAllWorkers
35+
} })
36+
37+
let constants_json_1 = require('./constants.json')
38+
39+
Object.defineProperty(exports, 'STRIPPED_INTEGRITY_TAG', { enumerable: true, get () {
40+
return constants_json_1.STRIPPED_INTEGRITY_TAG
41+
} })

0 commit comments

Comments
 (0)