vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
253 lines (250 loc) • 33.9 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { createElementWithReact } from '../helpers/createElementWithReact.js';
import { React, ReactDOMServer } from '../vendor/vendor.server.js';
import { assertReactServer } from '../config/getCondition.js';
import { handleError } from '../error/handleError.js';
import { augmentClientReferenceError } from '../error/augmentClientReferenceError.js';
import { createStreamMetrics } from '../metrics/createStreamMetrics.js';
import { PassThrough } from 'node:stream';
assertReactServer();
const createRenderToPipeableStreamHandler = function _createRscStreamHandler(handlerOptions) {
const {
route,
logger,
verbose = false,
panicThreshold = "none",
rscStream,
serverPipeableStreamOptions = {},
// Component resolution options
PageComponent,
RootComponent,
HtmlComponent,
pageProps,
// CSS options
cssFiles = /* @__PURE__ */ new Map(),
globalCss = /* @__PURE__ */ new Map(),
// Stream reuse options
reuseHeadlessStreamId,
headlessStreamElements
} = handlerOptions;
const streamElements = headlessStreamElements;
if (verbose) {
logger?.info(`[createRscStream:${route}] Starting RSC stream creation`);
}
try {
let finalPageComponent = PageComponent;
if (reuseHeadlessStreamId && streamElements?.has(reuseHeadlessStreamId)) {
const reusableData = streamElements.get(reuseHeadlessStreamId);
if (reusableData && !reusableData.errored) {
finalPageComponent = reusableData.PageComponent;
if (verbose) {
logger?.info(`[createRscStream:${route}] Reusing Page component from headless stream ${reuseHeadlessStreamId}`);
}
}
}
const children = "children" in handlerOptions ? handlerOptions.children : createElementWithReact(React, {
...handlerOptions,
url: handlerOptions.url,
moduleBase: handlerOptions.moduleBase || "",
manifest: handlerOptions.manifest || {},
projectRoot: handlerOptions.projectRoot || process.cwd(),
PageComponent: finalPageComponent || React.Fragment,
RootComponent: RootComponent || React.Fragment,
HtmlComponent: HtmlComponent || React.Fragment,
pageProps,
cssFiles,
globalCss
});
if (verbose) {
logger?.info(
`[createRscStream:${route}] Created React element, starting RSC rendering`
);
}
const pipeableStreamOptions = {
...serverPipeableStreamOptions,
onError(rawError) {
const error = augmentClientReferenceError(rawError);
logger?.error(
`[createRscStream:${route}] onError: ${error instanceof Error ? error.message : String(error)}`
);
const panicError = handleError({
error,
logger,
panicThreshold,
context: `RSC stream onError for route ${route}`,
log: true
});
if (panicError != null) {
handlerOptions.onEvent?.({
type: "route.error",
data: {
route,
error: panicError,
isPanic: true,
panicThreshold
}
});
} else {
handlerOptions.onEvent?.({
type: "route.error",
data: {
route,
error
}
});
}
serverPipeableStreamOptions.onError?.(error);
},
onShellError(rawError) {
const error = augmentClientReferenceError(rawError);
logger?.error(
`[createRscStream:${route}] onShellError: ${error instanceof Error ? error.message : String(error)}`
);
const panicError = handleError({
error,
logger,
panicThreshold,
context: `RSC stream onShellError for route ${route}`,
log: true
});
if (panicError != null) {
handlerOptions.onEvent?.({
type: "route.error",
data: {
route,
error: panicError,
isPanic: true,
panicThreshold
}
});
} else {
handlerOptions.onEvent?.({
type: "route.error",
data: {
route,
error
}
});
}
serverPipeableStreamOptions.onShellError?.(error);
}
};
let result;
let finalChildren = children;
try {
if (!finalChildren && handlerOptions.PageComponent) {
finalChildren = React.createElement(handlerOptions.PageComponent);
if (verbose) {
logger?.info(
`[createRscStream:${route}] Using loaded PageComponent for rendering`
);
}
}
if (!finalChildren) {
throw new Error(
`[createRscStream:${route}] No children or elements provided for RSC rendering, and no PageComponent loaded`
);
}
const element = React.isValidElement(finalChildren) ? finalChildren : typeof finalChildren === "function" ? React.createElement(finalChildren) : typeof finalChildren === "string" ? React.createElement(React.Fragment, {}, finalChildren) : typeof finalChildren === "number" || typeof finalChildren === "bigint" || typeof finalChildren === "boolean" ? React.createElement(React.Fragment, {}, finalChildren) : React.createElement(React.Fragment, {}, finalChildren);
if (verbose) {
logger?.info(
`[createRscStream:${route}] RSC rendering started successfully`
);
}
result = ReactDOMServer.renderToPipeableStream(
element,
handlerOptions.moduleBasePath || "",
pipeableStreamOptions
);
} catch (rawError) {
const error = augmentClientReferenceError(rawError);
if (verbose) {
logger?.error(
`[createRscStream:${route}] Synchronous error from React rendering: ${error}`
);
}
const panicError = handleError({
error,
logger,
panicThreshold,
context: `RSC stream synchronous React error for route ${route}`
});
if (panicError != null) {
handlerOptions.onEvent?.({
type: "route.error",
data: {
route,
error: panicError,
isPanic: true
}
});
}
throw error;
}
if (typeof result !== "object" || typeof result.pipe !== "function" || typeof result.abort !== "function") {
throw new Error(
`[createRscStream:${route}] Invalid result from ReactDOMServer.renderToPipeableStream`
);
}
if (verbose) {
logger?.info(
`[createRscStream:${route}] Result type: ${typeof result}, has pipe: ${typeof result?.pipe}, has abort: ${typeof result?.abort}`
);
}
const passThrough = rscStream || new PassThrough();
result.pipe(passThrough);
if (verbose) {
logger?.info(
`[createRscStream:${route}] Using PipeableStream, relying on natural completion`
);
}
return {
type: "server",
pipe: (destination) => {
passThrough.pipe(destination);
return destination;
},
abort: (reason) => {
result.abort(new Error(String(reason || "Aborted RSC stream")));
passThrough.destroy(
new Error(String(reason || "Aborted RSC stream"))
);
},
cleanup: () => {
passThrough.removeAllListeners();
},
rscStream: passThrough,
elements: finalChildren,
metrics: createStreamMetrics()
// Provide empty metrics object
};
} catch (rawError) {
const error = augmentClientReferenceError(rawError);
if (verbose) {
logger?.error(
`[createRscStream:${route}] Error in RSC stream creation: ${error}`
);
}
const panicError = handleError({
error,
logger,
panicThreshold});
if (panicError != null) {
handlerOptions.onEvent?.({
type: "route.error",
data: {
route,
error: panicError,
isPanic: true
}
});
}
throw error;
}
};
export { createRenderToPipeableStreamHandler };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlUmVuZGVyVG9QaXBlYWJsZVN0cmVhbUhhbmRsZXIuc2VydmVyLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vc3RyZWFtL2NyZWF0ZVJlbmRlclRvUGlwZWFibGVTdHJlYW1IYW5kbGVyLnNlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVFbGVtZW50V2l0aFJlYWN0IH0gZnJvbSBcIi4uL2hlbHBlcnMvY3JlYXRlRWxlbWVudFdpdGhSZWFjdC5qc1wiO1xuaW1wb3J0IHsgUmVhY3QsIFJlYWN0RE9NU2VydmVyIH0gZnJvbSBcIi4uL3ZlbmRvci92ZW5kb3Iuc2VydmVyLmpzXCI7XG5pbXBvcnQgeyBhc3NlcnRSZWFjdFNlcnZlciB9IGZyb20gXCIuLi9jb25maWcvZ2V0Q29uZGl0aW9uLmpzXCI7XG5pbXBvcnQgeyBoYW5kbGVFcnJvciB9IGZyb20gXCIuLi9lcnJvci9oYW5kbGVFcnJvci5qc1wiO1xuaW1wb3J0IHsgYXVnbWVudENsaWVudFJlZmVyZW5jZUVycm9yIH0gZnJvbSBcIi4uL2Vycm9yL2F1Z21lbnRDbGllbnRSZWZlcmVuY2VFcnJvci5qc1wiO1xuaW1wb3J0IHsgY3JlYXRlU3RyZWFtTWV0cmljcyB9IGZyb20gXCIuLi9oZWxwZXJzL21ldHJpY3MuanNcIjtcbmltcG9ydCB0eXBlIHsgQ3JlYXRlUmVuZGVyVG9QaXBlYWJsZVN0cmVhbUhhbmRsZXJGbiB9IGZyb20gXCIuL2NyZWF0ZVJlbmRlclRvUGlwZWFibGVTdHJlYW1IYW5kbGVyLnR5cGVzLmpzXCI7XG5cbmltcG9ydCB7IFBhc3NUaHJvdWdoIH0gZnJvbSBcIm5vZGU6c3RyZWFtXCI7XG5cbmFzc2VydFJlYWN0U2VydmVyKCk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBSU0Mgc3RyZWFtIGZyb20gUmVhY3QgZWxlbWVudHMgdXNpbmcgUmVhY3RET01TZXJ2ZXIucmVuZGVyVG9QaXBlYWJsZVN0cmVhbS5cbiAqXG4gKiAqKlB1cnBvc2UqKjogQ29udmVydHMgUmVhY3QgZWxlbWVudHMgdG8gUmVhY3QgU2VydmVyIENvbXBvbmVudHMgKFJTQykgZm9ybWF0IGZvciBzZXJ2ZXItc2lkZSByZW5kZXJpbmcuXG4gKiAqKldoZW4gdG8gdXNlKio6XG4gKiAtIFlvdSBoYXZlIFJlYWN0IGVsZW1lbnRzIGFuZCBuZWVkIHRvIGNyZWF0ZSBSU0Mgc3RyZWFtc1xuICogLSBZb3UncmUgaW4gYSBzZXJ2ZXIgZW52aXJvbm1lbnQgKE5vZGUuanMgc2VydmVyIG9yIHNlcnZlci1zaWRlIHdvcmtlcilcbiAqIC0gWW91IG5lZWQgdG8gY3JlYXRlIC5yc2MgZmlsZXMgb3Igc2VydmUgUlNDIGNvbnRlbnRcbiAqIC0gWW91IHdhbnQgdG8gc2VyaWFsaXplIFJlYWN0IGNvbXBvbmVudHMgZm9yIGNsaWVudC1zaWRlIGh5ZHJhdGlvblxuICpcbiAqICoqRmxvdyoqOiBSZWFjdCBFbGVtZW50cyDihpIgUlNDIFN0cmVhbVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgUlNDIHN0cmVhbSBmcm9tIFJlYWN0IGVsZW1lbnRzXG4gKiBjb25zdCByc2NIYW5kbGVyID0gY3JlYXRlUmVuZGVyVG9QaXBlYWJsZVN0cmVhbUhhbmRsZXIoe1xuICogICByb3V0ZTogXCIvYWJvdXRcIixcbiAqICAgUGFnZUNvbXBvbmVudDogQWJvdXRQYWdlLFxuICogICBSb290Q29tcG9uZW50OiBSb290TGF5b3V0LFxuICogICBIdG1sQ29tcG9uZW50OiBIdG1sRG9jdW1lbnQsXG4gKiAgIHBhZ2VQcm9wczogeyB0aXRsZTogXCJBYm91dCBVc1wiIH0sXG4gKiAgIGxvZ2dlcjogbXlMb2dnZXIsXG4gKiB9KTtcbiAqXG4gKiAvLyBQaXBlIHRvIGZpbGUgb3IgcmVzcG9uc2VcbiAqIHJzY0hhbmRsZXIucGlwZShmaWxlU3RyZWFtKTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgaGVhZGxlc3MgUlNDIChubyBIVE1MIHdyYXBwZXIpXG4gKiBjb25zdCByc2NIZWFkbGVzcyA9IGNyZWF0ZVJlbmRlclRvUGlwZWFibGVTdHJlYW1IYW5kbGVyKHtcbiAqICAgcm91dGU6IFwiL2Fib3V0XCIsXG4gKiAgIFBhZ2VDb21wb25lbnQ6IEFib3V0UGFnZSxcbiAqICAgSHRtbENvbXBvbmVudDogUmVhY3QuRnJhZ21lbnQsIC8vIE5vIEhUTUwgd3JhcHBlclxuICogICBwYWdlUHJvcHM6IHsgdGl0bGU6IFwiQWJvdXQgVXNcIiB9LFxuICogfSk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gaGFuZGxlck9wdGlvbnMgLSBPcHRpb25zIGZvciBSU0Mgc3RyZWFtIGNyZWF0aW9uXG4gKiBAcmV0dXJucyBSU0Mgc3RyZWFtIHdpdGggcGlwZS9hYm9ydCBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVJlbmRlclRvUGlwZWFibGVTdHJlYW1IYW5kbGVyOiBDcmVhdGVSZW5kZXJUb1BpcGVhYmxlU3RyZWFtSGFuZGxlckZuPFwic2VydmVyXCI+ID1cbiAgZnVuY3Rpb24gX2NyZWF0ZVJzY1N0cmVhbUhhbmRsZXIoaGFuZGxlck9wdGlvbnMpIHtcbiAgICBjb25zdCB7XG4gICAgICByb3V0ZSxcbiAgICAgIGxvZ2dlcixcbiAgICAgIHZlcmJvc2UgPSBmYWxzZSxcbiAgICAgIHBhbmljVGhyZXNob2xkID0gXCJub25lXCIsXG4gICAgICByc2NTdHJlYW0sXG4gICAgICBzZXJ2ZXJQaXBlYWJsZVN0cmVhbU9wdGlvbnMgPSB7fSxcbiAgICAgIC8vIENvbXBvbmVudCByZXNvbHV0aW9uIG9wdGlvbnNcbiAgICAgIFBhZ2VDb21wb25lbnQsXG4gICAgICBSb290Q29tcG9uZW50LFxuICAgICAgSHRtbENvbXBvbmVudCxcbiAgICAgIHBhZ2VQcm9wcyxcbiAgICAgIC8vIENTUyBvcHRpb25zXG4gICAgICBjc3NGaWxlcyA9IG5ldyBNYXAoKSxcbiAgICAgIGdsb2JhbENzcyA9IG5ldyBNYXAoKSxcbiAgICAgIC8vIFN0cmVhbSByZXVzZSBvcHRpb25zXG4gICAgICByZXVzZUhlYWRsZXNzU3RyZWFtSWQsXG4gICAgICBoZWFkbGVzc1N0cmVhbUVsZW1lbnRzLFxuICAgIH0gPSBoYW5kbGVyT3B0aW9ucztcblxuICAgIC8vIFR5cGUgYXNzZXJ0aW9uIGZvciBoZWFkbGVzc1N0cmVhbUVsZW1lbnRzXG4gICAgY29uc3Qgc3RyZWFtRWxlbWVudHMgPSBoZWFkbGVzc1N0cmVhbUVsZW1lbnRzIGFzIE1hcDxzdHJpbmcsIHsgUGFnZUNvbXBvbmVudDogYW55OyBlcnJvcmVkOiBib29sZWFuIH0+IHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHZlcmJvc2UpIHtcbiAgICAgIGxvZ2dlcj8uaW5mbyhgW2NyZWF0ZVJzY1N0cmVhbToke3JvdXRlfV0gU3RhcnRpbmcgUlNDIHN0cmVhbSBjcmVhdGlvbmApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBpZiB3ZSBzaG91bGQgcmV1c2UgYSBQYWdlIGNvbXBvbmVudCBmcm9tIGEgaGVhZGxlc3Mgc3RyZWFtXG4gICAgICBsZXQgZmluYWxQYWdlQ29tcG9uZW50ID0gUGFnZUNvbXBvbmVudDtcbiAgICAgIGlmIChyZXVzZUhlYWRsZXNzU3RyZWFtSWQgJiYgc3RyZWFtRWxlbWVudHM/LmhhcyhyZXVzZUhlYWRsZXNzU3RyZWFtSWQpKSB7XG4gICAgICAgIGNvbnN0IHJldXNhYmxlRGF0YSA9IHN0cmVhbUVsZW1lbnRzLmdldChyZXVzZUhlYWRsZXNzU3RyZWFtSWQpO1xuICAgICAgICBpZiAocmV1c2FibGVEYXRhICYmICFyZXVzYWJsZURhdGEuZXJyb3JlZCkge1xuICAgICAgICAgIGZpbmFsUGFnZUNvbXBvbmVudCA9IHJldXNhYmxlRGF0YS5QYWdlQ29tcG9uZW50O1xuICAgICAgICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICAgICAgICBsb2dnZXI/LmluZm8oYFtjcmVhdGVSc2NTdHJlYW06JHtyb3V0ZX1dIFJldXNpbmcgUGFnZSBjb21wb25lbnQgZnJvbSBoZWFkbGVzcyBzdHJlYW0gJHtyZXVzZUhlYWRsZXNzU3RyZWFtSWR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENyZWF0ZSBSZWFjdCBlbGVtZW50IGZyb20gY29tcG9uZW50cyBhbmQgcHJvcHNcbiAgICAgIGNvbnN0IGNoaWxkcmVuID1cbiAgICAgICAgXCJjaGlsZHJlblwiIGluIGhhbmRsZXJPcHRpb25zXG4gICAgICAgICAgPyBoYW5kbGVyT3B0aW9ucy5jaGlsZHJlblxuICAgICAgICAgIDogY3JlYXRlRWxlbWVudFdpdGhSZWFjdChSZWFjdCwge1xuICAgICAgICAgICAgICAuLi5oYW5kbGVyT3B0aW9ucyxcbiAgICAgICAgICAgICAgdXJsOiBoYW5kbGVyT3B0aW9ucy51cmwsXG4gICAgICAgICAgICAgIG1vZHVsZUJhc2U6IGhhbmRsZXJPcHRpb25zLm1vZHVsZUJhc2UgfHwgXCJcIixcbiAgICAgICAgICAgICAgbWFuaWZlc3Q6IGhhbmRsZXJPcHRpb25zLm1hbmlmZXN0IHx8IHt9LFxuICAgICAgICAgICAgICBwcm9qZWN0Um9vdDogaGFuZGxlck9wdGlvbnMucHJvamVjdFJvb3QgfHwgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICAgICAgUGFnZUNvbXBvbmVudDogZmluYWxQYWdlQ29tcG9uZW50IHx8IFJlYWN0LkZyYWdtZW50LFxuICAgICAgICAgICAgICBSb290Q29tcG9uZW50OiBSb290Q29tcG9uZW50IHx8IFJlYWN0LkZyYWdtZW50LFxuICAgICAgICAgICAgICBIdG1sQ29tcG9uZW50OiBIdG1sQ29tcG9uZW50IHx8IFJlYWN0LkZyYWdtZW50LFxuICAgICAgICAgICAgICBwYWdlUHJvcHMsXG4gICAgICAgICAgICAgIGNzc0ZpbGVzLFxuICAgICAgICAgICAgICBnbG9iYWxDc3MsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgaWYgKHZlcmJvc2UpIHtcbiAgICAgICAgbG9nZ2VyPy5pbmZvKFxuICAgICAgICAgIGBbY3JlYXRlUnNjU3RyZWFtOiR7cm91dGV9XSBDcmVhdGVkIFJlYWN0IGVsZW1lbnQsIHN0YXJ0aW5nIFJTQyByZW5kZXJpbmdgXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbmZpZ3VyZSBwaXBlYWJsZSBzdHJlYW0gb3B0aW9ucyBmb3IgUlNDXG4gICAgICBjb25zdCBwaXBlYWJsZVN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgIC4uLnNlcnZlclBpcGVhYmxlU3RyZWFtT3B0aW9ucyxcblxuICAgICAgICBvbkVycm9yKHJhd0Vycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgLy8gQWRkIGFjdGlvbmFibGUgY29udGV4dCB0byBvcGFxdWUgY2xpZW50LXJlZmVyZW5jZSBmYWlsdXJlc1xuICAgICAgICAgIC8vIChcIm91dHNpZGUgdGhlIGhvc3RlZCByb290XCIgLyBtaXNzaW5nIGNsaWVudC1kaXIgbW9kdWxlKSBiZWZvcmVcbiAgICAgICAgICAvLyBhbnl0aGluZyBlbHNlIHNlZXMgdGhlIGVycm9yLlxuICAgICAgICAgIGNvbnN0IGVycm9yID0gYXVnbWVudENsaWVudFJlZmVyZW5jZUVycm9yKHJhd0Vycm9yKTtcbiAgICAgICAgICAvLyBBbHdheXMgbG9nOiBzdHJlYW0gZXJyb3JzIG90aGVyd2lzZSB2YW5pc2ggc2lsZW50bHkgYW5kIHRoZSBvbmx5XG4gICAgICAgICAgLy8gdXNlci12aXNpYmxlIHN5bXB0b20gaXMgYW4gZW1wdHkvaGFsZiBSU0MgcmVzcG9uc2UuXG4gICAgICAgICAgbG9nZ2VyPy5lcnJvcihcbiAgICAgICAgICAgIGBbY3JlYXRlUnNjU3RyZWFtOiR7cm91dGV9XSBvbkVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIEhhbmRsZSBlcnJvciBhY2NvcmRpbmcgdG8gcGFuaWMgdGhyZXNob2xkXG4gICAgICAgICAgY29uc3QgcGFuaWNFcnJvciA9IGhhbmRsZUVycm9yKHtcbiAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgIGxvZ2dlcjogbG9nZ2VyLFxuICAgICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IHBhbmljVGhyZXNob2xkLFxuICAgICAgICAgICAgY29udGV4dDogYFJTQyBzdHJlYW0gb25FcnJvciBmb3Igcm91dGUgJHtyb3V0ZX1gLFxuICAgICAgICAgICAgbG9nOiB0cnVlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKHBhbmljRXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHBhbmljIHRocmVzaG9sZCBlcnJvciwgZW1pdCBldmVudCB0byBub3RpZnkgcGFyZW50XG4gICAgICAgICAgICBoYW5kbGVyT3B0aW9ucy5vbkV2ZW50Py4oe1xuICAgICAgICAgICAgICB0eXBlOiBcInJvdXRlLmVycm9yXCIsXG4gICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICByb3V0ZTogcm91dGUsXG4gICAgICAgICAgICAgICAgZXJyb3I6IHBhbmljRXJyb3IsXG4gICAgICAgICAgICAgICAgaXNQYW5pYzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwYW5pY1RocmVzaG9sZDogcGFuaWNUaHJlc2hvbGQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gRm9yIG5vbi1wYW5pYyBlcnJvcnMsIGp1c3QgbG9nIGFuZCBzZW5kIGV2ZW50XG4gICAgICAgICAgICBoYW5kbGVyT3B0aW9ucy5vbkV2ZW50Py4oe1xuICAgICAgICAgICAgICB0eXBlOiBcInJvdXRlLmVycm9yXCIsXG4gICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICByb3V0ZTogcm91dGUsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQ2FsbCB0aGUgb3JpZ2luYWwgb25FcnJvciBoYW5kbGVyIGlmIGl0IGV4aXN0c1xuICAgICAgICAgIHNlcnZlclBpcGVhYmxlU3RyZWFtT3B0aW9ucy5vbkVycm9yPy4oZXJyb3IpO1xuICAgICAgICB9LFxuICAgICAgICBvblNoZWxsRXJyb3IocmF3RXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICBjb25zdCBlcnJvciA9IGF1Z21lbnRDbGllbnRSZWZlcmVuY2VFcnJvcihyYXdFcnJvcik7XG4gICAgICAgICAgLy8gQWx3YXlzIGxvZzogc2hlbGwgZXJyb3JzIG1lYW4gbm90aGluZyBoYXMgYmVlbiBmbHVzaGVkIHRvIHRoZVxuICAgICAgICAgIC8vIGNsaWVudCB5ZXQsIHNvIHdpdGhvdXQgYSBsb2cgdGhlcmUncyBubyBzaWduYWwgYXQgYWxsLlxuICAgICAgICAgIGxvZ2dlcj8uZXJyb3IoXG4gICAgICAgICAgICBgW2NyZWF0ZVJzY1N0cmVhbToke3JvdXRlfV0gb25TaGVsbEVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIEhhbmRsZSBzaGVsbCBlcnJvciBhY2NvcmRpbmcgdG8gcGFuaWMgdGhyZXNob2xkXG4gICAgICAgICAgY29uc3QgcGFuaWNFcnJvciA9IGhhbmRsZUVycm9yKHtcbiAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgIGxvZ2dlcjogbG9nZ2VyLFxuICAgICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IHBhbmljVGhyZXNob2xkLFxuICAgICAgICAgICAgY29udGV4dDogYFJTQyBzdHJlYW0gb25TaGVsbEVycm9yIGZvciByb3V0ZSAke3JvdXRlfWAsXG4gICAgICAgICAgICBsb2c6IHRydWUsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAocGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyBUaGlzIGlzIGEgcGFuaWMgdGhyZXNob2xkIGVycm9yLCBlbWl0IGV2ZW50IHRvIG5vdGlmeSBwYXJlbnRcbiAgICAgICAgICAgIGhhbmRsZXJPcHRpb25zLm9uRXZlbnQ/Lih7XG4gICAgICAgICAgICAgIHR5cGU6IFwicm91dGUuZXJyb3JcIixcbiAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHJvdXRlOiByb3V0ZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogcGFuaWNFcnJvcixcbiAgICAgICAgICAgICAgICBpc1BhbmljOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBhbmljVGhyZXNob2xkOiBwYW5pY1RocmVzaG9sZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBGb3Igbm9uLXBhbmljIGVycm9ycywganVzdCBsb2cgYW5kIHNlbmQgZXZlbnRcbiAgICAgICAgICAgIGhhbmRsZXJPcHRpb25zLm9uRXZlbnQ/Lih7XG4gICAgICAgICAgICAgIHR5cGU6IFwicm91dGUuZXJyb3JcIixcbiAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHJvdXRlOiByb3V0ZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAoc2VydmVyUGlwZWFibGVTdHJlYW1PcHRpb25zIGFzIGFueSkub25TaGVsbEVycm9yPy4oZXJyb3IpO1xuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgLy8gQ3JlYXRlIHRoZSBwaXBlYWJsZSBzdHJlYW1cbiAgICAgIGxldCByZXN1bHQ6IGFueTtcbiAgICAgIFxuICAgICAgLy8gR2V0IGNoaWxkcmVuIGZyb20gZWl0aGVyIHByb3ZpZGVkIGNoaWxkcmVuIG9yIGxvYWRlZCBQYWdlQ29tcG9uZW50XG4gICAgICBsZXQgZmluYWxDaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgICB0cnkge1xuICAgICAgICBcbiAgICAgICAgaWYgKCFmaW5hbENoaWxkcmVuICYmIGhhbmRsZXJPcHRpb25zLlBhZ2VDb21wb25lbnQpIHtcbiAgICAgICAgICAvLyBDcmVhdGUgUmVhY3QgZWxlbWVudCBmcm9tIHRoZSBsb2FkZWQgUGFnZUNvbXBvbmVudFxuICAgICAgICAgIGZpbmFsQ2hpbGRyZW4gPSBSZWFjdC5jcmVhdGVFbGVtZW50KGhhbmRsZXJPcHRpb25zLlBhZ2VDb21wb25lbnQpO1xuICAgICAgICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICAgICAgICBsb2dnZXI/LmluZm8oXG4gICAgICAgICAgICAgIGBbY3JlYXRlUnNjU3RyZWFtOiR7cm91dGV9XSBVc2luZyBsb2FkZWQgUGFnZUNvbXBvbmVudCBmb3IgcmVuZGVyaW5nYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmICghZmluYWxDaGlsZHJlbikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBbY3JlYXRlUnNjU3RyZWFtOiR7cm91dGV9XSBObyBjaGlsZHJlbiBvciBlbGVtZW50cyBwcm92aWRlZCBmb3IgUlNDIHJlbmRlcmluZywgYW5kIG5vIFBhZ2VDb21wb25lbnQgbG9hZGVkYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlbGVtZW50ID0gUmVhY3QuaXNWYWxpZEVsZW1lbnQoZmluYWxDaGlsZHJlbilcbiAgICAgICAgICA/IGZpbmFsQ2hpbGRyZW5cbiAgICAgICAgICA6IHR5cGVvZiBmaW5hbENoaWxkcmVuID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoZmluYWxDaGlsZHJlbilcbiAgICAgICAgICA6IHR5cGVvZiBmaW5hbENoaWxkcmVuID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0LkZyYWdtZW50LCB7fSwgZmluYWxDaGlsZHJlbilcbiAgICAgICAgICA6IHR5cGVvZiBmaW5hbENoaWxkcmVuID09PSBcIm51bWJlclwiIHx8IHR5cGVvZiBmaW5hbENoaWxkcmVuID09PSBcImJpZ2ludFwiIHx8IHR5cGVvZiBmaW5hbENoaWxkcmVuID09PSBcImJvb2xlYW5cIlxuICAgICAgICAgID8gUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdC5GcmFnbWVudCwge30sIGZpbmFsQ2hpbGRyZW4pXG4gICAgICAgICAgOiBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0LkZyYWdtZW50LCB7fSwgZmluYWxDaGlsZHJlbik7XG5cbiAgICAgICAgaWYgKHZlcmJvc2UpIHtcbiAgICAgICAgICBsb2dnZXI/LmluZm8oXG4gICAgICAgICAgICBgW2NyZWF0ZVJzY1N0cmVhbToke3JvdXRlfV0gUlNDIHJlbmRlcmluZyBzdGFydGVkIHN1Y2Nlc3NmdWxseWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0ID0gUmVhY3RET01TZXJ2ZXIucmVuZGVyVG9QaXBlYWJsZVN0cmVhbShcbiAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgIGhhbmRsZXJPcHRpb25zLm1vZHVsZUJhc2VQYXRoIHx8IFwiXCIsXG4gICAgICAgICAgcGlwZWFibGVTdHJlYW1PcHRpb25zXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChyYXdFcnJvcikge1xuICAgICAgICBjb25zdCBlcnJvciA9IGF1Z21lbnRDbGllbnRSZWZlcmVuY2VFcnJvcihyYXdFcnJvcik7XG4gICAgICAgIGlmICh2ZXJib3NlKSB7XG4gICAgICAgICAgbG9nZ2VyPy5lcnJvcihcbiAgICAgICAgICAgIGBbY3JlYXRlUnNjU3RyZWFtOiR7cm91dGV9XSBTeW5jaHJvbm91cyBlcnJvciBmcm9tIFJlYWN0IHJlbmRlcmluZzogJHtlcnJvcn1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhbmljRXJyb3IgPSBoYW5kbGVFcnJvcih7XG4gICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgIGxvZ2dlcjogbG9nZ2VyLFxuICAgICAgICAgIHBhbmljVGhyZXNob2xkOiBwYW5pY1RocmVzaG9sZCxcbiAgICAgICAgICBjb250ZXh0OiBgUlNDIHN0cmVhbSBzeW5jaHJvbm91cyBSZWFjdCBlcnJvciBmb3Igcm91dGUgJHtyb3V0ZX1gLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgaGFuZGxlck9wdGlvbnMub25FdmVudD8uKHtcbiAgICAgICAgICAgIHR5cGU6IFwicm91dGUuZXJyb3JcIixcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLFxuICAgICAgICAgICAgICBlcnJvcjogcGFuaWNFcnJvcixcbiAgICAgICAgICAgICAgaXNQYW5pYzogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgdGhlIHJlc3VsdFxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgcmVzdWx0ICE9PSBcIm9iamVjdFwiIHx8XG4gICAgICAgIHR5cGVvZiByZXN1bHQucGlwZSAhPT0gXCJmdW5jdGlvblwiIHx8XG4gICAgICAgIHR5cGVvZiByZXN1bHQuYWJvcnQgIT09IFwiZnVuY3Rpb25cIlxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgW2NyZWF0ZVJzY1N0cmVhbToke3JvdXRlfV0gSW52YWxpZCByZXN1bHQgZnJvbSBSZWFjdERPTVNlcnZlci5yZW5kZXJUb1BpcGVhYmxlU3RyZWFtYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAodmVyYm9zZSkge1xuICAgICAgICBsb2dnZXI/LmluZm8oXG4gICAgICAgICAgYFtjcmVhdGVSc2NTdHJlYW06JHtyb3V0ZX1dIFJlc3VsdCB0eXBlOiAke3R5cGVvZiByZXN1bHR9LCBoYXMgcGlwZTogJHt0eXBlb2YgcmVzdWx0Py5waXBlfSwgaGFzIGFib3J0OiAke3R5cGVvZiByZXN1bHQ/LmFib3J0fWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gVXNlIHByb3ZpZGVkIFJTQyBzdHJlYW0gb3IgY3JlYXRlIGEgbmV3IHBhc3MgdGhyb3VnaCBzdHJlYW1cbiAgICAgIGNvbnN0IHBhc3NUaHJvdWdoID0gcnNjU3RyZWFtIHx8IG5ldyBQYXNzVGhyb3VnaCgpO1xuXG4gICAgICAvLyBQaXBlIHRoZSBSZWFjdCBzdHJlYW0gdG8gb3VyIHBhc3MgdGhyb3VnaFxuICAgICAgcmVzdWx0LnBpcGUocGFzc1Rocm91Z2gpO1xuXG4gICAgICAvLyBUaGUgUGlwZWFibGVTdHJlYW0gZnJvbSBSZWFjdCBkb2Vzbid0IGhhdmUgJ29uJyBtZXRob2RzLCBzbyB3ZSByZWx5IG9uIG5hdHVyYWwgY29tcGxldGlvblxuICAgICAgLy8gVGhlIHN0cmVhbSB3aWxsIGVuZCB3aGVuIGFsbCBkYXRhIGlzIHdyaXR0ZW4gdG8gdGhlIGRlc3RpbmF0aW9uXG4gICAgICBpZiAodmVyYm9zZSkge1xuICAgICAgICBsb2dnZXI/LmluZm8oXG4gICAgICAgICAgYFtjcmVhdGVSc2NTdHJlYW06JHtyb3V0ZX1dIFVzaW5nIFBpcGVhYmxlU3RyZWFtLCByZWx5aW5nIG9uIG5hdHVyYWwgY29tcGxldGlvbmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJzZXJ2ZXJcIiBhcyBjb25zdCxcbiAgICAgICAgcGlwZTogPFdyaXRhYmxlIGV4dGVuZHMgTm9kZUpTLldyaXRhYmxlU3RyZWFtPihcbiAgICAgICAgICBkZXN0aW5hdGlvbjogV3JpdGFibGVcbiAgICAgICAgKSA9PiB7XG4gICAgICAgICAgcGFzc1Rocm91Z2gucGlwZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uO1xuICAgICAgICB9LFxuICAgICAgICBhYm9ydDogKHJlYXNvbj86IHVua25vd24pID0+IHtcbiAgICAgICAgICByZXN1bHQuYWJvcnQobmV3IEVycm9yKFN0cmluZyhyZWFzb24gfHwgXCJBYm9ydGVkIFJTQyBzdHJlYW1cIikpKTtcbiAgICAgICAgICBwYXNzVGhyb3VnaC5kZXN0cm95KFxuICAgICAgICAgICAgbmV3IEVycm9yKFN0cmluZyhyZWFzb24gfHwgXCJBYm9ydGVkIFJTQyBzdHJlYW1cIikpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgY2xlYW51cDogKCkgPT4ge1xuICAgICAgICAgIC8vIENsZWFuIHVwIGxpc3RlbmVycyBvbiB0aGUgUlNDIHN0cmVhbVxuICAgICAgICAgIHBhc3NUaHJvdWdoLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgICAgICB9LFxuICAgICAgICByc2NTdHJlYW06IHBhc3NUaHJvdWdoIGFzIFBhc3NUaHJvdWdoLFxuICAgICAgICBlbGVtZW50czogZmluYWxDaGlsZHJlbixcbiAgICAgICAgbWV0cmljczogY3JlYXRlU3RyZWFtTWV0cmljcygpLCAvLyBQcm92aWRlIGVtcHR5IG1ldHJpY3Mgb2JqZWN0XG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKHJhd0Vycm9yKSB7XG4gICAgICBjb25zdCBlcnJvciA9IGF1Z21lbnRDbGllbnRSZWZlcmVuY2VFcnJvcihyYXdFcnJvcik7XG4gICAgICBpZiAodmVyYm9zZSkge1xuICAgICAgICBsb2dnZXI/LmVycm9yKFxuICAgICAgICAgIGBbY3JlYXRlUnNjU3RyZWFtOiR7cm91dGV9XSBFcnJvciBpbiBSU0Mgc3RyZWFtIGNyZWF0aW9uOiAke2Vycm9yfWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFuaWNFcnJvciA9IGhhbmRsZUVycm9yKHtcbiAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICBsb2dnZXI6IGxvZ2dlcixcbiAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IHBhbmljVGhyZXNob2xkLFxuICAgICAgICBjb250ZXh0OiBgUlNDIHN0cmVhbSBjcmVhdGlvbiBlcnJvciBmb3Igcm91dGUgJHtyb3V0ZX1gLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChwYW5pY0Vycm9yICE9IG51bGwpIHtcbiAgICAgICAgaGFuZGxlck9wdGlvbnMub25FdmVudD8uKHtcbiAgICAgICAgICB0eXBlOiBcInJvdXRlLmVycm9yXCIsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgcm91dGU6IHJvdXRlLFxuICAgICAgICAgICAgZXJyb3I6IHBhbmljRXJyb3IsXG4gICAgICAgICAgICBpc1BhbmljOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH07XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQVVBLGlCQUFrQixFQUFBO0FBNENMLE1BQUEsbUNBQUEsR0FDWCxTQUFTLHVCQUFBLENBQXdCLGNBQWdCLEVBQUE7QUFDL0MsRUFBTSxNQUFBO0FBQUEsSUFDSixLQUFBO0FBQUEsSUFDQSxNQUFBO0FBQUEsSUFDQSxPQUFVLEdBQUEsS0FBQTtBQUFBLElBQ1YsY0FBaUIsR0FBQSxNQUFBO0FBQUEsSUFDakIsU0FBQTtBQUFBLElBQ0EsOEJBQThCLEVBQUM7QUFBQTtBQUFBLElBRS9CLGFBQUE7QUFBQSxJQUNBLGFBQUE7QUFBQSxJQUNBLGFBQUE7QUFBQSxJQUNBLFNBQUE7QUFBQTtBQUFBLElBRUEsUUFBQSx1QkFBZSxHQUFJLEVBQUE7QUFBQSxJQUNuQixTQUFBLHVCQUFnQixHQUFJLEVBQUE7QUFBQTtBQUFBLElBRXBCLHFCQUFBO0FBQUEsSUFDQTtBQUFBLEdBQ0UsR0FBQSxjQUFBO0FBR0osRUFBQSxN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