1 | ;
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const testcafe_hammerhead_1 = __importDefault(require("testcafe-hammerhead"));
|
7 | const asyncToGenerator_1 = __importDefault(require("babel-runtime/helpers/asyncToGenerator"));
|
8 | const lodash_1 = require("lodash");
|
9 | const load_babel_libs_1 = __importDefault(require("./load-babel-libs"));
|
10 | const runtime_1 = require("../errors/runtime");
|
11 | const types_1 = require("../errors/types");
|
12 | const ANONYMOUS_FN_RE = /^function\s*\*?\s*\(/;
|
13 | const ES6_OBJ_METHOD_NAME_RE = /^(\S+?)\s*\(/;
|
14 | const USE_STRICT_RE = /^('|")use strict('|");?/;
|
15 | const TRAILING_SEMICOLON_RE = /;\s*$/;
|
16 | const REGENERATOR_FOOTPRINTS_RE = /(_index\d+\.default|_regenerator\d+\.default|regeneratorRuntime)\.wrap\(function _callee\$\(_context\)/;
|
17 | const ASYNC_TO_GENERATOR_OUTPUT_CODE = asyncToGenerator_1.default(lodash_1.noop).toString();
|
18 | const babelArtifactPolyfills = {
|
19 | 'Promise': {
|
20 | re: /_promise(\d+)\.default/,
|
21 | getCode: match => `var _promise${match[1]} = { default: Promise };`,
|
22 | removeMatchingCode: false
|
23 | },
|
24 | 'Object.keys()': {
|
25 | re: /_keys(\d+)\.default/,
|
26 | getCode: match => `var _keys${match[1]} = { default: Object.keys };`,
|
27 | removeMatchingCode: false
|
28 | },
|
29 | 'JSON.stringify()': {
|
30 | re: /_stringify(\d+)\.default/,
|
31 | getCode: match => `var _stringify${match[1]} = { default: JSON.stringify };`,
|
32 | removeMatchingCode: false
|
33 | }
|
34 | };
|
35 | function getBabelOptions() {
|
36 | const { presetFallback, transformForOfAsArray } = load_babel_libs_1.default();
|
37 | return {
|
38 | presets: [{ plugins: [transformForOfAsArray] }, presetFallback],
|
39 | sourceMaps: false,
|
40 | retainLines: true,
|
41 | ast: false,
|
42 | babelrc: false,
|
43 | highlightCode: false
|
44 | };
|
45 | }
|
46 | function downgradeES(fnCode) {
|
47 | const { babel } = load_babel_libs_1.default();
|
48 | const opts = getBabelOptions();
|
49 | const compiled = babel.transform(fnCode, opts);
|
50 | return compiled.code
|
51 | .replace(USE_STRICT_RE, '')
|
52 | .trim();
|
53 | }
|
54 | function addBabelArtifactsPolyfills(fnCode, dependenciesDefinition) {
|
55 | let modifiedFnCode = fnCode;
|
56 | const polyfills = Object
|
57 | .values(babelArtifactPolyfills)
|
58 | .reduce((polyfillsCode, polyfill) => {
|
59 | const match = fnCode.match(polyfill.re);
|
60 | if (match) {
|
61 | if (polyfill.removeMatchingCode)
|
62 | modifiedFnCode = modifiedFnCode.replace(polyfill.re, '');
|
63 | return polyfillsCode + polyfill.getCode(match);
|
64 | }
|
65 | return polyfillsCode;
|
66 | }, '');
|
67 | return `(function(){${dependenciesDefinition}${polyfills} return ${modifiedFnCode}})();`;
|
68 | }
|
69 | function getDependenciesDefinition(dependencies) {
|
70 | return Object
|
71 | .keys(dependencies)
|
72 | .reduce((code, name) => {
|
73 | return code + `var ${name}=__dependencies$['${name}'];`;
|
74 | }, '');
|
75 | }
|
76 | function makeFnCodeSuitableForParsing(fnCode) {
|
77 | // NOTE: 'function() {}' -> '(function() {})'
|
78 | if (ANONYMOUS_FN_RE.test(fnCode))
|
79 | return `(${fnCode})`;
|
80 | // NOTE: 'myFn () {}' -> 'function myFn() {}'
|
81 | const match = fnCode.match(ES6_OBJ_METHOD_NAME_RE);
|
82 | if (match && match[1] !== 'function')
|
83 | return `function ${fnCode}`;
|
84 | return fnCode;
|
85 | }
|
86 | function compileClientFunction(fnCode, dependencies, instantiationCallsiteName, compilationCallsiteName) {
|
87 | if (fnCode === ASYNC_TO_GENERATOR_OUTPUT_CODE)
|
88 | throw new runtime_1.ClientFunctionAPIError(compilationCallsiteName, instantiationCallsiteName, types_1.RUNTIME_ERRORS.regeneratorInClientFunctionCode);
|
89 | fnCode = makeFnCodeSuitableForParsing(fnCode);
|
90 | // NOTE: we need to recompile ES6 code for the browser if we are on newer versions of Node.
|
91 | fnCode = downgradeES(fnCode);
|
92 | fnCode = testcafe_hammerhead_1.default.processScript(fnCode, false);
|
93 | // NOTE: check compiled code for regenerator injection: we have either generator
|
94 | // recompiled in Node.js 4+ for client or async function declared in function code.
|
95 | if (REGENERATOR_FOOTPRINTS_RE.test(fnCode))
|
96 | throw new runtime_1.ClientFunctionAPIError(compilationCallsiteName, instantiationCallsiteName, types_1.RUNTIME_ERRORS.regeneratorInClientFunctionCode);
|
97 | if (!TRAILING_SEMICOLON_RE.test(fnCode))
|
98 | fnCode += ';';
|
99 | const dependenciesDefinition = dependencies ? getDependenciesDefinition(dependencies) : '';
|
100 | return addBabelArtifactsPolyfills(fnCode, dependenciesDefinition);
|
101 | }
|
102 | exports.default = compileClientFunction;
|
103 | module.exports = exports.default;
|
104 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS1jbGllbnQtZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tcGlsZXIvY29tcGlsZS1jbGllbnQtZnVuY3Rpb24uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4RUFBNkM7QUFDN0MsOEZBQXNFO0FBQ3RFLG1DQUE4QjtBQUM5Qix3RUFBOEM7QUFDOUMsK0NBQTJEO0FBQzNELDJDQUFpRDtBQUVqRCxNQUFNLGVBQWUsR0FBa0Isc0JBQXNCLENBQUM7QUFDOUQsTUFBTSxzQkFBc0IsR0FBVyxjQUFjLENBQUM7QUFDdEQsTUFBTSxhQUFhLEdBQW9CLHlCQUF5QixDQUFDO0FBQ2pFLE1BQU0scUJBQXFCLEdBQVksT0FBTyxDQUFDO0FBQy9DLE1BQU0seUJBQXlCLEdBQVEsd0dBQXdHLENBQUM7QUFDaEosTUFBTSw4QkFBOEIsR0FBRywwQkFBZ0IsQ0FBQyxhQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUV6RSxNQUFNLHNCQUFzQixHQUFHO0lBQzNCLFNBQVMsRUFBRTtRQUNQLEVBQUUsRUFBa0Isd0JBQXdCO1FBQzVDLE9BQU8sRUFBYSxLQUFLLENBQUMsRUFBRSxDQUFDLGVBQWUsS0FBSyxDQUFDLENBQUMsQ0FBQywwQkFBMEI7UUFDOUUsa0JBQWtCLEVBQUUsS0FBSztLQUM1QjtJQUVELGVBQWUsRUFBRTtRQUNiLEVBQUUsRUFBa0IscUJBQXFCO1FBQ3pDLE9BQU8sRUFBYSxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyw4QkFBOEI7UUFDL0Usa0JBQWtCLEVBQUUsS0FBSztLQUM1QjtJQUVELGtCQUFrQixFQUFFO1FBQ2hCLEVBQUUsRUFBa0IsMEJBQTBCO1FBQzlDLE9BQU8sRUFBYSxLQUFLLENBQUMsRUFBRSxDQUFDLGlCQUFpQixLQUFLLENBQUMsQ0FBQyxDQUFDLGlDQUFpQztRQUN2RixrQkFBa0IsRUFBRSxLQUFLO0tBQzVCO0NB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QUMsQ0FBQztJQUU5QywyRkFBMkY7SUFDM0YsTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3QixNQUFNLEdBQUcsNkJBQVUsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBRWpELGdGQUFnRjtJQUNoRixtRkFBbUY7SUFDbkYsSUFBSSx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3RDLE1BQU0sSUFBSSxnQ0FBc0IsQ0FBQyx1QkFBdUIsRUFBRSx5QkFBeUIsRUFBRSxzQkFBYyxDQUFDLCtCQUErQixDQUFDLENBQUM7SUFFekksSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDbkMsTUFBTSxJQUFJLEdBQUcsQ0FBQztJQUVsQixNQUFNLHNCQUFzQixHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMseUJBQXlCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUUzRixPQUFPLDBCQUEwQixDQUFDLE1BQU0sRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0FBQ3RFLENBQUM7QUFyQkQsd0NBcUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGhhbW1lcmhlYWQgZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgYXN5bmNUb0dlbmVyYXRvciBmcm9tICdiYWJlbC1ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvcic7XG5pbXBvcnQgeyBub29wIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBsb2FkQmFiZWxMaWJzIGZyb20gJy4vbG9hZC1iYWJlbC1saWJzJztcbmltcG9ydCB7IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uL2Vycm9ycy90eXBlcyc7XG5cbmNvbnN0IEFOT05ZTU9VU19GTl9SRSAgICAgICAgICAgICAgICA9IC9eZnVuY3Rpb25cXHMqXFwqP1xccypcXCgvO1xuY29uc3QgRVM2X09CSl9NRVRIT0RfTkFNRV9SRSAgICAgICAgID0gL14oXFxTKz8pXFxzKlxcKC87XG5jb25zdCBVU0VfU1RSSUNUX1JFICAgICAgICAgICAgICAgICAgPSAvXignfFwiKXVzZSBzdHJpY3QoJ3xcIik7Py87XG5jb25zdCBUUkFJTElOR19TRU1JQ09MT05fUkUgICAgICAgICAgPSAvO1xccyokLztcbmNvbnN0IFJFR0VORVJBVE9SX0ZPT1RQUklOVFNfUkUgICAgICA9IC8oX2luZGV4XFxkK1xcLmRlZmF1bHR8X3JlZ2VuZXJhdG9yXFxkK1xcLmRlZmF1bHR8cmVnZW5lcmF0b3JSdW50aW1lKVxcLndyYXBcXChmdW5jdGlvbiBfY2FsbGVlXFwkXFwoX2NvbnRleHRcXCkvO1xuY29uc3QgQVNZTkNfVE9fR0VORVJBVE9SX09VVFBVVF9DT0RFID0gYXN5bmNUb0dlbmVyYXRvcihub29wKS50b1N0cmluZygpO1xuXG5jb25zdCBiYWJlbEFydGlmYWN0UG9seWZpbGxzID0ge1xuICAgICdQcm9taXNlJzoge1xuICAgICAgICByZTogICAgICAgICAgICAgICAgIC9fcHJvbWlzZShcXGQrKVxcLmRlZmF1bHQvLFxuICAgICAgICBnZXRDb2RlOiAgICAgICAgICAgIG1hdGNoID0+IGB2YXIgX3Byb21pc2Uke21hdGNoWzFdfSA9IHsgZGVmYXVsdDogUHJvbWlzZSB9O2AsXG4gICAgICAgIHJlbW92ZU1hdGNoaW5nQ29kZTogZmFsc2VcbiAgICB9LFxuXG4gICAgJ09iamVjdC5rZXlzKCknOiB7XG4gICAgICAgIHJlOiAgICAgICAgICAgICAgICAgL19rZXlzKFxcZCspXFwuZGVmYXVsdC8sXG4gICAgICAgIGdldENvZGU6ICAgICAgICAgICAgbWF0Y2ggPT4gYHZhciBfa2V5cyR7bWF0Y2hbMV19ID0geyBkZWZhdWx0OiBPYmplY3Qua2V5cyB9O2AsXG4gICAgICAgIHJlbW92ZU1hdGNoaW5nQ29kZTogZmFsc2VcbiAgICB9LFxuXG4gICAgJ0pTT04uc3RyaW5naWZ5KCknOiB7XG4gICAgICAgIHJlOiAgICAgICAgICAgICAgICAgL19zdHJpbmdpZnkoXFxkKylcXC5kZWZhdWx0LyxcbiAgICAgICAgZ2V0Q29kZTogICAgICAgICAgICBtYXRjaCA9PiBgdmFyIF9zdHJpbmdpZnkke21hdGNoWzFdfSA9IHsgZGVmYXVsdDogSlNPTi5zdHJpbmdpZnkgfTtgLFxuICAgICAgICByZW1vdmVNYXRjaGluZ0NvZGU6IGZhbHNlXG4gICAgfVxufTtcblxuXG5mdW5jdGlvbiBnZXRCYWJlbE9wdGlvbnMgKCkge1xuICAgIGNvbnN0IHsgcHJlc2V0RmFsbGJhY2ssIHRyYW5zZm9ybUZvck9mQXNBcnJheSB9ID0gbG9hZEJhYmVsTGlicygpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgcHJlc2V0czogICAgICAgW3sgcGx1Z2luczogW3RyYW5zZm9ybUZvck9mQXNBcnJheV0gfSwgcHJlc2V0RmFsbGJhY2tdLFxuICAgICAgICBzb3VyY2VNYXBzOiAgICBmYWxzZSxcbiAgICAgICAgcmV0YWluTGluZXM6ICAgdHJ1ZSxcbiAgICAgICAgYXN0OiAgICAgICAgICAgZmFsc2UsXG4gICAgICAgIGJhYmVscmM6ICAgICAgIGZhbHNlLFxuICAgICAgICBoaWdobGlnaHRDb2RlOiBmYWxzZVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGRvd25ncmFkZUVTIChmbkNvZGUpIHtcbiAgICBjb25zdCB7IGJhYmVsIH0gPSBsb2FkQmFiZWxMaWJzKCk7XG5cbiAgICBjb25zdCBvcHRzICAgICA9IGdldEJhYmVsT3B0aW9ucygpO1xuICAgIGNvbnN0IGNvbXBpbGVkID0gYmFiZWwudHJhbnNmb3JtKGZuQ29kZSwgb3B0cyk7XG5cbiAgICByZXR1cm4gY29tcGlsZWQuY29kZVxuICAgICAgICAucmVwbGFjZShVU0VfU1RSSUNUX1JFLCAnJylcbiAgICAgICAgLnRyaW0oKTtcbn1cblxuZnVuY3Rpb24gYWRkQmFiZWxBcnRpZmFjdHNQb2x5ZmlsbHMgKGZuQ29kZSwgZGVwZW5kZW5jaWVzRGVmaW5pdGlvbikge1xuICAgIGxldCBtb2RpZmllZEZuQ29kZSA9IGZuQ29kZTtcblxuICAgIGNvbnN0IHBvbHlmaWxscyA9IE9iamVjdFxuICAgICAgICAudmFsdWVzKGJhYmVsQXJ0aWZhY3RQb2x5ZmlsbHMpXG4gICAgICAgIC5yZWR1Y2UoKHBvbHlmaWxsc0NvZGUsIHBvbHlmaWxsKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IGZuQ29kZS5tYXRjaChwb2x5ZmlsbC5yZSk7XG5cbiAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgIGlmIChwb2x5ZmlsbC5yZW1vdmVNYXRjaGluZ0NvZGUpXG4gICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkRm5Db2RlID0gbW9kaWZpZWRGbkNvZGUucmVwbGFjZShwb2x5ZmlsbC5yZSwgJycpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvbHlmaWxsc0NvZGUgKyBwb2x5ZmlsbC5nZXRDb2RlKG1hdGNoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHBvbHlmaWxsc0NvZGU7XG4gICAgICAgIH0sICcnKTtcblxuICAgIHJldHVybiBgKGZ1bmN0aW9uKCl7JHtkZXBlbmRlbmNpZXNEZWZpbml0aW9ufSR7cG9seWZpbGxzfSByZXR1cm4gJHttb2RpZmllZEZuQ29kZX19KSgpO2A7XG59XG5cbmZ1bmN0aW9uIGdldERlcGVuZGVuY2llc0RlZmluaXRpb24gKGRlcGVuZGVuY2llcykge1xuICAgIHJldHVybiBPYmplY3RcbiAgICAgICAgLmtleXMoZGVwZW5kZW5jaWVzKVxuICAgICAgICAucmVkdWNlKChjb2RlLCBuYW1lKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gY29kZSArIGB2YXIgJHtuYW1lfT1fX2RlcGVuZGVuY2llcyRbJyR7bmFtZX0nXTtgO1xuICAgICAgICB9LCAnJyk7XG59XG5cbmZ1bmN0aW9uIG1ha2VGbkNvZGVTdWl0YWJsZUZvclBhcnNpbmcgKGZuQ29kZSkge1xuICAgIC8vIE5PVEU6ICdmdW5jdGlvbigpIHt9JyAtPiAnKGZ1bmN0aW9uKCkge30pJ1xuICAgIGlmIChBTk9OWU1PVVNfRk5fUkUudGVzdChmbkNvZGUpKVxuICAgICAgICByZXR1cm4gYCgke2ZuQ29kZX0pYDtcblxuICAgIC8vIE5PVEU6ICdteUZuICgpIHt9JyAtPiAnZnVuY3Rpb24gbXlGbigpIHt9J1xuICAgIGNvbnN0IG1hdGNoID0gZm5Db2RlLm1hdGNoKEVTNl9PQkpfTUVUSE9EX05BTUVfUkUpO1xuXG4gICAgaWYgKG1hdGNoICYmIG1hdGNoWzFdICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICByZXR1cm4gYGZ1bmN0aW9uICR7Zm5Db2RlfWA7XG5cbiAgICByZXR1cm4gZm5Db2RlO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21waWxlQ2xpZW50RnVuY3Rpb24gKGZuQ29kZSwgZGVwZW5kZW5jaWVzLCBpbnN0YW50aWF0aW9uQ2FsbHNpdGVOYW1lLCBjb21waWxhdGlvbkNhbGxzaXRlTmFtZSkge1xuICAgIGlmIChmbkNvZGUgPT09IEFTWU5DX1RPX0dFTkVSQVRPUl9PVVRQVVRfQ09ERSlcbiAgICAgICAgdGhyb3cgbmV3IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IoY29tcGlsYXRpb25DYWxsc2l0ZU5hbWUsIGluc3RhbnRpYXRpb25DYWxsc2l0ZU5hbWUsIFJVTlRJTUVfRVJST1JTLnJlZ2VuZXJhdG9ySW5DbGllbnRGdW5jdGlvbkNvZGUpO1xuXG4gICAgZm5Db2RlID0gbWFrZUZuQ29kZVN1aXRhYmxlRm9yUGFyc2luZyhmbkNvZGUpO1xuXG4gICAgLy8gTk9URTogd2UgbmVlZCB0byByZWNvbXBpbGUgRVM2IGNvZGUgZm9yIHRoZSBicm93c2VyIGlmIHdlIGFyZSBvbiBuZXdlciB2ZXJzaW9ucyBvZiBOb2RlLlxuICAgIGZuQ29kZSA9IGRvd25ncmFkZUVTKGZuQ29kZSk7XG4gICAgZm5Db2RlID0gaGFtbWVyaGVhZC5wcm9jZXNzU2NyaXB0KGZuQ29kZSwgZmFsc2UpO1xuXG4gICAgLy8gTk9URTogY2hlY2sgY29tcGlsZWQgY29kZSBmb3IgcmVnZW5lcmF0b3IgaW5qZWN0aW9uOiB3ZSBoYXZlIGVpdGhlciBnZW5lcmF0b3JcbiAgICAvLyByZWNvbXBpbGVkIGluIE5vZGUuanMgNCsgZm9yIGNsaWVudCBvciBhc3luYyBmdW5jdGlvbiBkZWNsYXJlZCBpbiBmdW5jdGlvbiBjb2RlLlxuICAgIGlmIChSRUdFTkVSQVRPUl9GT09UUFJJTlRTX1JFLnRlc3QoZm5Db2RlKSlcbiAgICAgICAgdGhyb3cgbmV3IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IoY29tcGlsYXRpb25DYWxsc2l0ZU5hbWUsIGluc3RhbnRpYXRpb25DYWxsc2l0ZU5hbWUsIFJVTlRJTUVfRVJST1JTLnJlZ2VuZXJhdG9ySW5DbGllbnRGdW5jdGlvbkNvZGUpO1xuXG4gICAgaWYgKCFUUkFJTElOR19TRU1JQ09MT05fUkUudGVzdChmbkNvZGUpKVxuICAgICAgICBmbkNvZGUgKz0gJzsnO1xuXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzRGVmaW5pdGlvbiA9IGRlcGVuZGVuY2llcyA/IGdldERlcGVuZGVuY2llc0RlZmluaXRpb24oZGVwZW5kZW5jaWVzKSA6ICcnO1xuXG4gICAgcmV0dXJuIGFkZEJhYmVsQXJ0aWZhY3RzUG9seWZpbGxzKGZuQ29kZSwgZGVwZW5kZW5jaWVzRGVmaW5pdGlvbik7XG59XG4iXX0= |
\ | No newline at end of file |