@vercel/node
Version:
160 lines (159 loc) • 5.02 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.onDevRequest = exports.rawBody = void 0;
const entrypoint = process.env.VERCEL_DEV_ENTRYPOINT;
delete process.env.VERCEL_DEV_ENTRYPOINT;
const tsconfig = process.env.VERCEL_DEV_TSCONFIG;
delete process.env.VERCEL_DEV_TSCONFIG;
if (!entrypoint) {
throw new Error('`VERCEL_DEV_ENTRYPOINT` must be defined');
}
const path_1 = require("path");
const ts_node_1 = require("ts-node");
let useRequire = false;
if (!process.env.VERCEL_DEV_IS_ESM) {
const resolveTypescript = (p) => {
try {
return require.resolve('typescript', {
paths: [p],
});
}
catch (_) {
return '';
}
};
const requireTypescript = (p) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(p);
};
let ts = null;
// Assume Node.js 12 as the lowest common denominator
let target = 'ES2019';
const nodeMajor = Number(process.versions.node.split('.')[0]);
if (nodeMajor >= 14) {
target = 'ES2020';
}
// Use the project's version of Typescript if available and supports `target`
let compiler = resolveTypescript(process.cwd());
if (compiler) {
ts = requireTypescript(compiler);
if (!(target in ts.ScriptTarget)) {
ts = null;
}
}
// Otherwise fall back to using the copy that `@vercel/node` uses
if (!ts) {
compiler = resolveTypescript(path_1.join(__dirname, '..'));
ts = requireTypescript(compiler);
}
if (tsconfig) {
try {
const { config } = ts.readConfigFile(tsconfig, ts.sys.readFile);
if ((_a = config === null || config === void 0 ? void 0 : config.compilerOptions) === null || _a === void 0 ? void 0 : _a.target) {
target = config.compilerOptions.target;
}
}
catch (err) {
if (err.code !== 'ENOENT') {
console.error(`Error while parsing "${tsconfig}"`);
throw err;
}
}
}
ts_node_1.register({
compiler,
compilerOptions: {
allowJs: true,
esModuleInterop: true,
jsx: 'react',
module: 'commonjs',
target,
},
project: tsconfig || undefined,
transpileOnly: true,
});
useRequire = true;
}
const http_1 = require("http");
// @ts-ignore - copied to the `dist` output as-is
const launcher_js_1 = require("./launcher.js");
function listen(server, port, host) {
return new Promise(resolve => {
server.listen(port, host, () => {
resolve();
});
});
}
let bridge = undefined;
async function main() {
const config = JSON.parse(process.env.VERCEL_DEV_CONFIG || '{}');
delete process.env.VERCEL_DEV_CONFIG;
const buildEnv = JSON.parse(process.env.VERCEL_DEV_BUILD_ENV || '{}');
delete process.env.VERCEL_DEV_BUILD_ENV;
const shouldAddHelpers = !(config.helpers === false || buildEnv.NODEJS_HELPERS === '0');
const proxyServer = http_1.createServer(onDevRequest);
await listen(proxyServer, 0, '127.0.0.1');
const launcher = launcher_js_1.getVercelLauncher({
entrypointPath: path_1.join(process.cwd(), entrypoint),
helpersPath: './helpers.js',
shouldAddHelpers,
useRequire,
});
bridge = launcher();
const address = proxyServer.address();
if (typeof process.send === 'function') {
process.send(address);
}
else {
console.log('Dev server listening:', address);
}
}
function rawBody(readable) {
return new Promise((resolve, reject) => {
let bytes = 0;
const chunks = [];
readable.on('error', reject);
readable.on('data', chunk => {
chunks.push(chunk);
bytes += chunk.length;
});
readable.on('end', () => {
resolve(Buffer.concat(chunks, bytes));
});
});
}
exports.rawBody = rawBody;
async function onDevRequest(req, res) {
const body = await rawBody(req);
const event = {
Action: 'Invoke',
body: JSON.stringify({
method: req.method,
path: req.url,
headers: req.headers,
encoding: 'base64',
body: body.toString('base64'),
}),
};
if (!bridge) {
res.statusCode = 500;
res.end('Bridge is not ready, please try again');
return;
}
const result = await bridge.launcher(event, {
callbackWaitsForEmptyEventLoop: false,
});
res.statusCode = result.statusCode;
for (const [key, value] of Object.entries(result.headers)) {
if (typeof value !== 'undefined') {
res.setHeader(key, value);
}
}
res.end(Buffer.from(result.body, result.encoding));
}
exports.onDevRequest = onDevRequest;
main().catch(err => {
console.error(err);
process.exit(1);
});