vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
157 lines (154 loc) • 22.3 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { toError } from '../error/toError.js';
import { logError } from '../error/logError.js';
import { join } from 'node:path';
function parseServerActionRequestBody(body, url) {
const parsed = JSON.parse(body);
if (Array.isArray(parsed)) {
return {
args: parsed,
id: url?.split("?")[0] ?? ""
};
} else if (parsed && typeof parsed === "object" && "id" in parsed) {
return {
id: parsed.id,
args: parsed.args ?? []
};
}
throw new Error("Invalid server action request format");
}
function createServerActionResponse(result, error) {
return {
type: "server-action-response",
returnValue: error ? { success: false, error } : result
};
}
function setupServerActionHeaders(res) {
res.setHeader("Content-Type", "text/x-component; charset=utf-8");
res.setHeader("Transfer-Encoding", "chunked");
res.setHeader("Connection", "keep-alive");
}
async function parseServerActionRequest(req, verbose = false, logger) {
let id = req.headers["x-rsc-action"] ?? req.url?.split("?")[0] ?? "";
if (verbose) {
logger?.info(`[handleServerActionHelper] Parsing request at ${req.url}`);
logger?.info(`[handleServerActionHelper] Action ID from header: ${req.headers["x-rsc-action"]}`);
}
let args;
try {
const chunks = [];
for await (const chunk of req) {
chunks.push(chunk);
}
const body = Buffer.concat(chunks).toString();
if (verbose) {
logger?.info(`[handleServerActionHelper] Request body length: ${body.length}`);
}
try {
const parsed = JSON.parse(body);
if (Array.isArray(parsed)) {
args = parsed;
if (verbose) {
logger?.info(`[handleServerActionHelper] Parsed args as array`);
}
} else if (parsed && typeof parsed === "object" && "id" in parsed) {
id = parsed.id;
args = parsed.args ?? [];
} else {
throw new Error("Invalid server action request format");
}
} catch {
if (verbose) {
logger?.info(`[handleServerActionHelper] Body is not JSON, passing raw body`);
}
args = [body];
}
} catch (error) {
throw new Error(`Failed to parse server action request`, {
cause: error
});
}
if (!id) {
throw new Error("Server action ID is required");
}
if (verbose) {
logger?.info(
`[handleServerActionHelper] Server action request for ${id} with args: ${JSON.stringify(args)}`
);
}
return { id, args };
}
function resolveServerAction(id, projectRoot, verbose = false, logger) {
const [filePath, exportName] = id.split("#");
if (!filePath || !exportName) {
throw new Error(
`Invalid server action ID format: ${id}. Expected format: "path/to/file.ts#exportName"`
);
}
const actionPath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
const fullPath = join(projectRoot, actionPath);
if (verbose) {
logger?.info(
`[handleServerActionHelper] Resolved file path: id=${id}, actionPath=${actionPath}, projectRoot=${projectRoot}, filePath=${fullPath}, exportName=${exportName}`
);
}
return { filePath: actionPath, exportName, fullPath };
}
async function loadServerAction(fullPath, exportName, ssrLoadModule, verbose = false, logger) {
if (verbose) {
logger?.info(`[handleServerActionHelper] Loading module: ${fullPath}`);
}
const module = await ssrLoadModule(fullPath);
if (verbose) {
logger?.info(
`[handleServerActionHelper] Looking for action: ${exportName} in module with exports: ${Object.keys(module).join(", ")}`
);
}
const action = module[exportName];
if (typeof action !== "function") {
if (verbose) {
logger?.info(
`[handleServerActionHelper] Export ${exportName} is not a function: ${typeof action}`
);
}
throw new Error(
`Server action ${exportName} is not a function. Found: ${typeof action}`
);
}
return action;
}
async function executeServerAction(action, args, verbose = false, logger) {
if (verbose) {
logger?.info(`[handleServerActionHelper] Executing action with args: ${JSON.stringify(args)}`);
}
const result = await action(...args);
if (verbose) {
logger?.info(`[handleServerActionHelper] Action executed successfully: ${JSON.stringify(result)}`);
}
return result;
}
function sendServerActionResponse(res, result, verbose = false, logger) {
if (verbose) {
logger?.info(`[handleServerActionHelper] Sending response: ${JSON.stringify(result)}`);
}
res.setHeader("Content-Type", "text/x-component");
res.end(`0:${JSON.stringify(result)}
`);
}
function handleServerActionError(error, res, logger) {
const err = toError(error);
logError(err, logger);
res.statusCode = 500;
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({
success: false,
error: err.message,
stack: err.stack
}));
}
export { createServerActionResponse, executeServerAction, handleServerActionError, loadServerAction, parseServerActionRequest, parseServerActionRequestBody, resolveServerAction, sendServerActionResponse, setupServerActionHeaders };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlU2VydmVyQWN0aW9uSGVscGVyLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vaGVscGVycy9oYW5kbGVTZXJ2ZXJBY3Rpb25IZWxwZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9nRXJyb3IsIHRvRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3IvaW5kZXguanNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IExvZ2dlciB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgdHlwZSB7IFNlcnZlclJlc3BvbnNlIH0gZnJvbSBcIm5vZGU6aHR0cFwiO1xuaW1wb3J0IHR5cGUgeyBJbmNvbWluZ01lc3NhZ2UgfSBmcm9tIFwibm9kZTpodHRwXCI7XG5cbmV4cG9ydCB0eXBlIFNlcnZlckFjdGlvbkhhbmRsZXJPcHRpb25zID0ge1xuICBwcm9qZWN0Um9vdDogc3RyaW5nO1xuICB2ZXJib3NlPzogYm9vbGVhbjtcbiAgbG9nZ2VyPzogTG9nZ2VyO1xuICBzc3JMb2FkTW9kdWxlPzogKHBhdGg6IHN0cmluZykgPT4gUHJvbWlzZTxhbnk+O1xufTtcblxuZXhwb3J0IHR5cGUgU2VydmVyQWN0aW9uUmVxdWVzdCA9IHtcbiAgaWQ6IHN0cmluZztcbiAgYXJnczogdW5rbm93bltdO1xufTtcblxuLyoqXG4gKiBQYXJzZXMgYSBzZXJ2ZXIgYWN0aW9uIHJlcXVlc3QgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICogU3VwcG9ydHMgdHdvIGZvcm1hdHM6XG4gKiAxLiBEaXJlY3QgYXJncyBhcnJheTogW2FyZzEsIGFyZzIsIC4uLl1cbiAqIDIuIE9iamVjdCB3aXRoIGlkIGFuZCBhcmdzOiB7IGlkOiBzdHJpbmcsIGFyZ3M6IHVua25vd25bXSB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNlcnZlckFjdGlvblJlcXVlc3RCb2R5KGJvZHk6IHN0cmluZywgdXJsPzogc3RyaW5nKTogU2VydmVyQWN0aW9uUmVxdWVzdCB7XG4gIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoYm9keSk7XG4gIFxuICBpZiAoQXJyYXkuaXNBcnJheShwYXJzZWQpKSB7XG4gICAgLy8gRm9ybWF0IDE6IERpcmVjdCBhcmdzIGFycmF5XG4gICAgcmV0dXJuIHtcbiAgICAgIGFyZ3M6IHBhcnNlZCxcbiAgICAgIGlkOiB1cmw/LnNwbGl0KFwiP1wiKVswXSA/PyBcIlwiLFxuICAgIH07XG4gIH0gZWxzZSBpZiAocGFyc2VkICYmIHR5cGVvZiBwYXJzZWQgPT09IFwib2JqZWN0XCIgJiYgXCJpZFwiIGluIHBhcnNlZCkge1xuICAgIC8vIEZvcm1hdCAyOiBPYmplY3Qgd2l0aCBpZCBhbmQgYXJnc1xuICAgIHJldHVybiB7XG4gICAgICBpZDogcGFyc2VkLmlkLFxuICAgICAgYXJnczogcGFyc2VkLmFyZ3MgPz8gW10sXG4gICAgfTtcbiAgfVxuICBcbiAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBzZXJ2ZXIgYWN0aW9uIHJlcXVlc3QgZm9ybWF0XCIpO1xufVxuXG5leHBvcnQgdHlwZSBTZXJ2ZXJBY3Rpb25SZXNwb25zZSA9IHtcbiAgdHlwZTogXCJzZXJ2ZXItYWN0aW9uLXJlc3BvbnNlXCI7XG4gIHJldHVyblZhbHVlOiB1bmtub3duO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc2VydmVyIGFjdGlvbiByZXNwb25zZSB3aXRoIHRoZSBnaXZlbiByZXN1bHQgb3IgZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZXJ2ZXJBY3Rpb25SZXNwb25zZShyZXN1bHQ/OiB1bmtub3duLCBlcnJvcj86IHN0cmluZyk6IFNlcnZlckFjdGlvblJlc3BvbnNlIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBcInNlcnZlci1hY3Rpb24tcmVzcG9uc2VcIixcbiAgICByZXR1cm5WYWx1ZTogZXJyb3IgXG4gICAgICA/IHsgc3VjY2VzczogZmFsc2UsIGVycm9yIH1cbiAgICAgIDogcmVzdWx0XG4gIH07XG59XG5cbi8qKlxuICogU2V0cyB1cCBjb21tb24gcmVzcG9uc2UgaGVhZGVycyBmb3Igc2VydmVyIGFjdGlvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXR1cFNlcnZlckFjdGlvbkhlYWRlcnMocmVzOiBTZXJ2ZXJSZXNwb25zZSkge1xuICByZXMuc2V0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsIFwidGV4dC94LWNvbXBvbmVudDsgY2hhcnNldD11dGYtOFwiKTtcbiAgcmVzLnNldEhlYWRlcihcIlRyYW5zZmVyLUVuY29kaW5nXCIsIFwiY2h1bmtlZFwiKTtcbiAgcmVzLnNldEhlYWRlcihcIkNvbm5lY3Rpb25cIiwgXCJrZWVwLWFsaXZlXCIpO1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIHNlcnZlciBhY3Rpb24gcmVxdWVzdCBmcm9tIHRoZSByZXF1ZXN0IGJvZHkgYW5kIFVSTFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGFyc2VTZXJ2ZXJBY3Rpb25SZXF1ZXN0KFxuICByZXE6IEluY29taW5nTWVzc2FnZSxcbiAgdmVyYm9zZSA9IGZhbHNlLFxuICBsb2dnZXI/OiBMb2dnZXJcbik6IFByb21pc2U8U2VydmVyQWN0aW9uUmVxdWVzdD4ge1xuICAvLyBHZXQgYWN0aW9uIElEIGZyb20geC1yc2MtYWN0aW9uIGhlYWRlciAocHJlZmVycmVkKSBvciBVUkxcbiAgbGV0IGlkID0gKHJlcS5oZWFkZXJzW1wieC1yc2MtYWN0aW9uXCJdIGFzIHN0cmluZykgPz8gcmVxLnVybD8uc3BsaXQoXCI/XCIpWzBdID8/IFwiXCI7XG4gIFxuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ2dlcj8uaW5mbyhgW2hhbmRsZVNlcnZlckFjdGlvbkhlbHBlcl0gUGFyc2luZyByZXF1ZXN0IGF0ICR7cmVxLnVybH1gKTtcbiAgICBsb2dnZXI/LmluZm8oYFtoYW5kbGVTZXJ2ZXJBY3Rpb25IZWxwZXJdIEFjdGlvbiBJRCBmcm9tIGhlYWRlcjogJHtyZXEuaGVhZGVyc1tcIngtcnNjLWFjdGlvblwiXX1gKTtcbiAgfVxuXG4gIC8vIFBhcnNlIHRoZSByZXF1ZXN0IGJvZHlcbiAgbGV0IGFyZ3M6IHVua25vd25bXTtcbiAgdHJ5IHtcbiAgICBjb25zdCBjaHVua3M6IEJ1ZmZlcltdID0gW107XG4gICAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiByZXEpIHtcbiAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKS50b1N0cmluZygpO1xuICAgIFxuICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICBsb2dnZXI/LmluZm8oYFtoYW5kbGVTZXJ2ZXJBY3Rpb25IZWxwZXJdIFJlcXVlc3QgYm9keSBsZW5ndGg6ICR7Ym9keS5sZW5ndGh9YCk7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHBhcnNlIGFzIEpTT04gZmlyc3QgKGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSlcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShib2R5KTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcnNlZCkpIHtcbiAgICAgICAgLy8gRm9ybWF0IDE6IERpcmVjdCBhcmdzIGFycmF5XG4gICAgICAgIGFyZ3MgPSBwYXJzZWQ7XG4gICAgICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICAgICAgbG9nZ2VyPy5pbmZvKGBbaGFuZGxlU2VydmVyQWN0aW9uSGVscGVyXSBQYXJzZWQgYXJncyBhcyBhcnJheWApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHBhcnNlZCAmJiB0eXBlb2YgcGFyc2VkID09PSBcIm9iamVjdFwiICYmIFwiaWRcIiBpbiBwYXJzZWQpIHtcbiAgICAgICAgLy8gRm9ybWF0IDI6IE9iamVjdCB3aXRoIGlkIGFuZCBhcmdzIChsZWdhY3kgZm9ybWF0KVxuICAgICAgICBpZCA9IHBhcnNlZC5pZDtcbiAgICAgICAgYXJncyA9IHBhcnNlZC5hcmdzID8/IFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBzZXJ2ZXIgYWN0aW9uIHJlcXVlc3QgZm9ybWF0XCIpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gTm90IEpTT04gLSBhc3N1bWUgaXQncyBSZWFjdCdzIGVuY29kZWQgZm9ybWF0XG4gICAgICAvLyBGb3Igbm93LCBwYXNzIHRoZSByYXcgYm9keSB0byB0aGUgd29ya2VyIHdoaWNoIGNhbiBkZWNvZGUgaXRcbiAgICAgIC8vIHVzaW5nIGRlY29kZVJlcGx5IGZyb20gcmVhY3Qtc2VydmVyLWRvbS1lc20vc2VydmVyXG4gICAgICBpZiAodmVyYm9zZSkge1xuICAgICAgICBsb2dnZXI/LmluZm8oYFtoYW5kbGVTZXJ2ZXJBY3Rpb25IZWxwZXJdIEJvZHkgaXMgbm90IEpTT04sIHBhc3NpbmcgcmF3IGJvZHlgKTtcbiAgICAgIH1cbiAgICAgIGFyZ3MgPSBbYm9keV07IC8vIFBhc3MgcmF3IGJvZHkgYXMgZmlyc3QgYXJnLCB3b3JrZXIgd2lsbCBkZWNvZGVcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcGFyc2Ugc2VydmVyIGFjdGlvbiByZXF1ZXN0YCwge1xuICAgICAgY2F1c2U6IGVycm9yLFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKCFpZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlNlcnZlciBhY3Rpb24gSUQgaXMgcmVxdWlyZWRcIik7XG4gIH1cblxuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ2dlcj8uaW5mbyhcbiAgICAgIGBbaGFuZGxlU2VydmVyQWN0aW9uSGVscGVyXSBTZXJ2ZXIgYWN0aW9uIHJlcXVlc3QgZm9yICR7aWR9IHdpdGggYXJnczogJHtKU09OLnN0cmluZ2lmeShhcmdzKX1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiB7IGlkLCBhcmdzIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgYSBzZXJ2ZXIgYWN0aW9uIElEIHRvIGZpbGUgcGF0aCBhbmQgZXhwb3J0IG5hbWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTZXJ2ZXJBY3Rpb24oXG4gIGlkOiBzdHJpbmcsXG4gIHByb2plY3RSb290OiBzdHJpbmcsXG4gIHZlcmJvc2UgPSBmYWxzZSxcbiAgbG9nZ2VyPzogTG9nZ2VyXG4pOiB7IGZpbGVQYXRoOiBzdHJpbmc7IGV4cG9ydE5hbWU6IHN0cmluZzsgZnVsbFBhdGg6IHN0cmluZyB9IHtcbiAgLy8gUGFyc2UgdGhlIHNlcnZlciBhY3Rpb24gSUQgdG8gZ2V0IHRoZSBmaWxlIHBhdGggYW5kIGV4cG9ydCBuYW1lXG4gIGNvbnN0IFtmaWxlUGF0aCwgZXhwb3J0TmFtZV0gPSBpZC5zcGxpdChcIiNcIik7XG4gIGlmICghZmlsZVBhdGggfHwgIWV4cG9ydE5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgSW52YWxpZCBzZXJ2ZXIgYWN0aW9uIElEIGZvcm1hdDogJHtpZH0uIEV4cGVjdGVkIGZvcm1hdDogXCJwYXRoL3RvL2ZpbGUudHMjZXhwb3J0TmFtZVwiYFxuICAgICk7XG4gIH1cblxuICAvLyBDb252ZXJ0IHRoZSBzZXJ2ZXIgYWN0aW9uIElEIHRvIGEgZmlsZSBwYXRoXG4gIGNvbnN0IGFjdGlvblBhdGggPSBmaWxlUGF0aC5zdGFydHNXaXRoKFwiL1wiKSA/IGZpbGVQYXRoLnNsaWNlKDEpIDogZmlsZVBhdGg7XG4gIGNvbnN0IGZ1bGxQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgYWN0aW9uUGF0aCk7XG4gIFxuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ2dlcj8uaW5mbyhcbiAgICAgIGBbaGFuZGxlU2VydmVyQWN0aW9uSGVscGVyXSBSZXNvbHZlZCBmaWxlIHBhdGg6IGlkPSR7aWR9LCBhY3Rpb25QYXRoPSR7YWN0aW9uUGF0aH0sIHByb2plY3RSb290PSR7cHJvamVjdFJvb3R9LCBmaWxlUGF0aD0ke2Z1bGxQYXRofSwgZXhwb3J0TmFtZT0ke2V4cG9ydE5hbWV9YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4geyBmaWxlUGF0aDogYWN0aW9uUGF0aCwgZXhwb3J0TmFtZSwgZnVsbFBhdGggfTtcbn1cblxuLyoqXG4gKiBMb2FkcyBhbmQgdmFsaWRhdGVzIGEgc2VydmVyIGFjdGlvbiBmcm9tIGEgbW9kdWxlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkU2VydmVyQWN0aW9uKFxuICBmdWxsUGF0aDogc3RyaW5nLFxuICBleHBvcnROYW1lOiBzdHJpbmcsXG4gIHNzckxvYWRNb2R1bGU6IChwYXRoOiBzdHJpbmcpID0+IFByb21pc2U8YW55PixcbiAgdmVyYm9zZSA9IGZhbHNlLFxuICBsb2dnZXI/OiBMb2dnZXJcbik6IFByb21pc2U8RnVuY3Rpb24+IHtcbiAgaWYgKHZlcmJvc2UpIHtcbiAgICBsb2dnZXI/LmluZm8oYFtoYW5kbGVTZXJ2ZXJBY3Rpb25IZWxwZXJdIExvYWRpbmcgbW9kdWxlOiAke2Z1bGxQYXRofWApO1xuICB9XG4gIFxuICBjb25zdCBtb2R1bGUgPSBhd2FpdCBzc3JMb2FkTW9kdWxlKGZ1bGxQYXRoKTtcbiAgXG4gIGlmICh2ZXJib3NlKSB7XG4gICAgbG9nZ2VyPy5pbmZvKFxuICAgICAgYFtoYW5kbGVTZXJ2ZXJBY3Rpb25IZWxwZXJdIExvb2tpbmcgZm9yIGFjdGlvbjogJHtleHBvcnROYW1lfSBpbiBtb2R1bGUgd2l0aCBleHBvcnRzOiAke09iamVjdC5rZXlzKG1vZHVsZSkuam9pbihcIiwgXCIpfWBcbiAgICApO1xuICB9XG4gIFxuICBjb25zdCBhY3Rpb24gPSBtb2R1bGVbZXhwb3J0TmFtZV07XG5cbiAgaWYgKHR5cGVvZiBhY3Rpb24gIT09IFwiZnVuY3Rpb25cIikge1xuICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICBsb2dnZXI/LmluZm8oXG4gICAgICAgIGBbaGFuZGxlU2VydmVyQWN0aW9uSGVscGVyXSBFeHBvcnQgJHtleHBvcnROYW1lfSBpcyBub3QgYSBmdW5jdGlvbjogJHt0eXBlb2YgYWN0aW9ufWBcbiAgICAgICk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBTZXJ2ZXIgYWN0aW9uICR7ZXhwb3J0TmFtZX0gaXMgbm90IGEgZnVuY3Rpb24uIEZvdW5kOiAke3R5cGVvZiBhY3Rpb259YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gYWN0aW9uO1xufVxuXG4vKipcbiAqIEV4ZWN1dGVzIGEgc2VydmVyIGFjdGlvbiB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4ZWN1dGVTZXJ2ZXJBY3Rpb24oXG4gIGFjdGlvbjogRnVuY3Rpb24sXG4gIGFyZ3M6IHVua25vd25bXSxcbiAgdmVyYm9zZSA9IGZhbHNlLFxuICBsb2dnZXI/OiBMb2dnZXJcbik6IFByb21pc2U8dW5rbm93bj4ge1xuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ2dlcj8uaW5mbyhgW2hhbmRsZVNlcnZlckFjdGlvbkhlbHBlcl0gRXhlY3V0aW5nIGFjdGlvbiB3aXRoIGFyZ3M6ICR7SlNPTi5zdHJpbmdpZnkoYXJncyl9YCk7XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBhY3Rpb24oLi4uYXJncyk7XG4gIFxuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ2dlcj8uaW5mbyhgW2hhbmRsZVNlcnZlckFjdGlvbkhlbHBlcl0gQWN0aW9uIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseTogJHtKU09OLnN0cmluZ2lmeShyZXN1bHQpfWApO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTZW5kcyBhIHNlcnZlciBhY3Rpb24gcmVzcG9uc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlbmRTZXJ2ZXJBY3Rpb25SZXNwb25zZShcbiAgcmVzOiBTZXJ2ZXJSZXNwb25zZSxcbiAgcmVzdWx0OiB1bmtub3duLFxuICB2ZXJib3NlID0gZmFsc2UsXG4gIGxvZ2dlcj86IExvZ2dlclxuKTogdm9pZCB7XG4gIGlmICh2ZXJib3NlKSB7XG4gICAgbG9nZ2VyPy5pbmZvKGBbaGFuZGxlU2VydmVyQWN0aW9uSGVscGVyXSBTZW5kaW5nIHJlc3BvbnNlOiAke0pTT04uc3RyaW5naWZ5KHJlc3VsdCl9YCk7XG4gIH1cblxuICAvLyBTZW5kIGluIFJTQyB3aXJlIGZvcm1hdCBmb3IgY3JlYXRlRnJvbUZldGNoIGNvbXBhdGliaWxpdHlcbiAgcmVzLnNldEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcInRleHQveC1jb21wb25lbnRcIik7XG4gIHJlcy5lbmQoYDA6JHtKU09OLnN0cmluZ2lmeShyZXN1bHQpfVxcbmApO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgc2VydmVyIGFjdGlvbiBlcnJvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVNlcnZlckFjdGlvbkVycm9yKFxuICBlcnJvcjogdW5rbm93bixcbiAgcmVzOiBTZXJ2ZXJSZXNwb25zZSxcbiAgbG9nZ2VyPzogTG9nZ2VyXG4pOiB2b2lkIHtcbiAgY29uc3QgZXJyID0gdG9FcnJvcihlcnJvcik7XG4gIGxvZ0Vycm9yKGVyciwgbG9nZ2VyKTtcbiAgXG4gIHJlcy5zdGF0dXNDb2RlID0gNTAwO1xuICByZXMuc2V0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsIFwiYXBwbGljYXRpb24vanNvblwiKTtcbiAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7IFxuICAgIHN1Y2Nlc3M6IGZhbHNlLCBcbiAgICBlcnJvcjogZXJyLm1lc3NhZ2UsXG4gICAgc3RhY2s6IGVyci5zdGFjayBcbiAgfSkpO1xufSAiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBd0JPLFNBQVMsNEJBQUEsQ0FBNkIsTUFBYyxHQUFtQyxFQUFBO0FBQzVGLEVBQU0sTUFBQSxNQUFBLEdBQVMsSUFBSyxDQUFBLEtBQUEsQ0FBTSxJQUFJLENBQUE7QUFFOUIsRUFBSSxJQUFBLEtBQUEsQ0FBTSxPQUFRLENBQUEsTUFBTSxDQUFHLEVBQUE7QUFFekIsSUFBTyxPQUFBO0FBQUEsTUFDTCxJQUFNLEVBQUEsTUFBQTtBQUFB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