UNPKG

@aws/cloudfront-hosting-toolkit

Version:

CloudFront Hosting Toolkit offers the convenience of a managed frontend hosting service while retaining full control over the hosting and deployment infrastructure to make it your own.

184 lines (181 loc) 30.5 kB
#!/usr/bin/env node "use strict"; /* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getUserDomainPreference = exports.copyCffIfNotExists = exports.copyBuildConfigIfNotExists = exports.init_s3 = exports.saveAndLogConfiguration = exports.init_repository = void 0; const fs_1 = __importDefault(require("fs")); const prompt_questions_1 = require("../utils/prompt_questions"); const helper_1 = require("../utils/helper"); const constants_1 = require("../shared/constants"); async function handleInitCommand(s3) { s3 ? await init_s3() : await init_repository(); } exports.default = handleInitCommand; async function init_repository() { console.log("\n--------------------- Static hosting configuration wizard : GitHub Source Code Repository Based -------------------\n"); let currentHostingConfig = { repoUrl: "", branchName: "", framework: "", domainName: undefined, hostedZoneId: undefined, }; if ((0, helper_1.doesHostingConfigurationFileExist)()) { const loadedConfig = await (0, helper_1.loadHostingConfiguration)(); if ((0, helper_1.isRepoConfig)(loadedConfig)) { currentHostingConfig = loadedConfig; } } console.log(`\n\n To facilitate the deployment of the necessary infrastructure for website hosting, certain information is required.\n ${constants_1.TOOL_NAME} will aim to find as much relevant data as possible.\n\n`); let identifiedRepositoryUrl, identifiedBranchName, identifiedFrameworkName; //check github configuration console.log("Collecting information about the GitHub repository from " + (0, helper_1.getCLIExecutionFolder)()); identifiedRepositoryUrl = (0, helper_1.getGitRemote)(); identifiedBranchName = (0, helper_1.getGitBranch)(); const repoQuestions = await (0, helper_1.startPrompt)((0, prompt_questions_1.getGithubRepositoryQuestions)(currentHostingConfig.repoUrl ? currentHostingConfig.repoUrl : identifiedRepositoryUrl, currentHostingConfig.branchName ? currentHostingConfig.branchName : identifiedBranchName)); console.log("\nCollecting information about the frontend framework used to enable the provision of the appropriate build configuration."); identifiedFrameworkName = await (0, helper_1.detectFrontendFramework)((0, helper_1.getCLIExecutionFolder)()); const frameworkSelection = await (0, helper_1.startPrompt)((0, prompt_questions_1.getFrameworkSelectionQuestions)(currentHostingConfig.framework ? currentHostingConfig.framework : identifiedFrameworkName)); const repositoryUrl = repoQuestions.repoUrl; const branchName = repoQuestions.branchName; const frameworkName = frameworkSelection.framework; if (frameworkName === "exit") { process.exit(0); } console.log("\n"); const { domainName, hostedZoneId } = await getUserDomainPreference(currentHostingConfig); console.log("\n----------------------------------------------------"); console.log(`Here is the configuration that has been generated and saved to ${constants_1.TOOL_NAME}/${constants_1.CONFIG_FILE_NAME} file.:`); console.log("> GitHub repository: " + repositoryUrl + "/" + branchName); console.log("> Framework: " + frameworkName); console.log("> Domain name: " + (domainName ? domainName : "No")); console.log(hostedZoneId ? "> Hosted zone ID: " + hostedZoneId : ""); console.log("\n--"); copyBuildConfigIfNotExists("hosting_" + frameworkName + ".yml"); copyCffIfNotExists("index_" + frameworkName + ".js"); const newHostingConfiguration = { repoUrl: repositoryUrl, branchName: branchName, framework: frameworkName, ...(domainName ? { domainName } : {}), ...(hostedZoneId ? { hostedZoneId } : {}), }; saveAndLogConfiguration(newHostingConfiguration); } exports.init_repository = init_repository; function saveAndLogConfiguration(newHostingConfiguration) { const jsonHostingConfiguration = JSON.stringify(newHostingConfiguration, null, 2); fs_1.default.writeFileSync((0, helper_1.getConfigFilePath)(), jsonHostingConfiguration); console.log(`> Configuration file generated ${(0, helper_1.getConfigFilePath)()}`); console.log(`> Build configuration generated ${(0, helper_1.getBuildConfigFilePath)()}`); console.log(`> CloudFront Function source code generated ${(0, helper_1.getCffConfigFilePath)()}`); console.log(`\n\nThe initialization process has been completed. You may now execute '${constants_1.TOOL_NAME} deploy' to deploy the infrastructure.\n`); } exports.saveAndLogConfiguration = saveAndLogConfiguration; async function init_s3() { console.log("\n--------------------- Static hosting configuration wizard: S3 Source Code Repository Based -------------------\n"); let currentHostingConfig = { s3bucket: "", s3path: "", domainName: undefined, hostedZoneId: undefined, }; if ((0, helper_1.doesHostingConfigurationFileExist)()) { const loadedConfig = await (0, helper_1.loadHostingConfiguration)(); if ((0, helper_1.isS3Config)(loadedConfig)) { currentHostingConfig = loadedConfig; } } const s3questions = await (0, helper_1.startPrompt)((0, prompt_questions_1.getS3BucketConfigurationQuestions)(currentHostingConfig.s3bucket, currentHostingConfig.s3path)); const { domainName, hostedZoneId } = await getUserDomainPreference(currentHostingConfig); console.log("\n----------------------------------------------------"); console.log("Please review the following captured information:"); console.log("> S3 Bucket: " + s3questions.s3bucket); console.log("> S3 Prefix: " + s3questions.s3path); console.log("> Domain name: " + (domainName ? domainName : "No")); console.log(hostedZoneId ? "> Hosted zone ID: " + hostedZoneId : ""); console.log("\n--"); copyBuildConfigIfNotExists("s3_build_config.yml"); copyCffIfNotExists("index_basic.js"); const newHostingConfiguration = { s3bucket: s3questions.s3bucket, s3path: s3questions.s3path, ...(domainName ? { domainName } : {}), ...(hostedZoneId ? { hostedZoneId } : {}), }; saveAndLogConfiguration(newHostingConfiguration); } exports.init_s3 = init_s3; /** * Copies a build configuration template to the tool folder if it does not already exist. * * @param frameworkName - The name of the framework to determine the source build configuration file. */ function copyBuildConfigIfNotExists(fileName) { const srcBuildConfigFile = (0, helper_1.getBuildConfigTemplatesFolder)() + "/" + fileName; if (!fs_1.default.existsSync((0, helper_1.getToolFolder)())) { fs_1.default.mkdirSync((0, helper_1.getToolFolder)()); } if (!fs_1.default.existsSync((0, helper_1.getBuildConfigFilePath)())) { fs_1.default.copyFileSync(srcBuildConfigFile, (0, helper_1.getBuildConfigFilePath)()); } } exports.copyBuildConfigIfNotExists = copyBuildConfigIfNotExists; function copyCffIfNotExists(fileName) { const srcBuildConfigFile = (0, helper_1.getCffTemplatesFolder)() + "/" + fileName; if (!fs_1.default.existsSync((0, helper_1.getToolFolder)())) { fs_1.default.mkdirSync((0, helper_1.getToolFolder)()); } if (!fs_1.default.existsSync((0, helper_1.getCffConfigFilePath)())) { fs_1.default.copyFileSync(srcBuildConfigFile, (0, helper_1.getCffConfigFilePath)()); } } exports.copyCffIfNotExists = copyCffIfNotExists; async function getUserDomainPreference(currentHostingConfig) { const withDomainName = await (0, helper_1.startPrompt)((0, prompt_questions_1.getDomainNameQuestion)(currentHostingConfig.domainName)); if (withDomainName.value === "yes") { const domainNamePrompt = await (0, helper_1.startPrompt)((0, prompt_questions_1.domainNameDetailsQuestions)(currentHostingConfig.domainName)); if (domainNamePrompt.registrar === "current") { const hostedZone = await (0, helper_1.startPrompt)((0, prompt_questions_1.hostedZoneIdQuestion)(currentHostingConfig.hostedZoneId)); return { domainName: domainNamePrompt.domainName, hostedZoneId: hostedZone.hostedZoneId, }; } else { return { domainName: domainNamePrompt.domainName, hostedZoneId: undefined, }; } } else { return { domainName: undefined, hostedZoneId: undefined, }; } } exports.getUserDomainPreference = getUserDomainPreference; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImluaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7RUFjRTs7Ozs7O0FBRUYsNENBQW9CO0FBRXBCLGdFQU9tQztBQUVuQyw0Q0FnQnlCO0FBQ3pCLG1EQUFrRTtBQUduRCxLQUFLLFVBQVUsaUJBQWlCLENBQUMsRUFBVztJQUN6RCxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sZUFBZSxFQUFFLENBQUM7QUFDakQsQ0FBQztBQUZELG9DQUVDO0FBRU0sS0FBSyxVQUFVLGVBQWU7SUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FDVCx5SEFBeUgsQ0FDMUgsQ0FBQztJQUVGLElBQUksb0JBQW9CLEdBQXlCO1FBQy9DLE9BQU8sRUFBRSxFQUFFO1FBQ1gsVUFBVSxFQUFFLEVBQUU7UUFDZCxTQUFTLEVBQUUsRUFBRTtRQUNiLFVBQVUsRUFBRSxTQUFTO1FBQ3JCLFlBQVksRUFBRSxTQUFTO0tBQ3hCLENBQUM7SUFFRixJQUFJLElBQUEsMENBQWlDLEdBQUUsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBQSxpQ0FBd0IsR0FBRSxDQUFDO1FBRXRELElBQUksSUFBQSxxQkFBWSxFQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDL0Isb0JBQW9CLEdBQUcsWUFBWSxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FDVCw2SEFBNkgscUJBQVMsMERBQTBELENBQ2pNLENBQUM7SUFFRixJQUFJLHVCQUErQixFQUNqQyxvQkFBNEIsRUFDNUIsdUJBQStCLENBQUM7SUFFbEMsNEJBQTRCO0lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQ1QsMERBQTBEO1FBQ3hELElBQUEsOEJBQXFCLEdBQUUsQ0FDMUIsQ0FBQztJQUNGLHVCQUF1QixHQUFHLElBQUEscUJBQVksR0FB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SUFFRixJQUFJLGNBQWMsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDbkMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUEsb0JBQVcsRUFDeEMsSUFBQSw2Q0FBMEIsRUFBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FDNUQsQ0FBQztRQUVGLElBQUksZ0JBQWdCLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzdDLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBQSxvQkFBVyxFQUNsQyxJQUFBLHVDQUFvQixFQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxDQUN4RCxDQUFDO1lBRUYsT0FBTztnQkFDTCxVQUFVLEVBQUUsZ0JBQWdCLENBQUMsVUFBVTtnQkFDdkMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxZQUFZO2FBQ3RDLENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU87Z0JBQ0wsVUFBVSxFQUFFLGdCQUFnQixDQUFDLFVBQVU7Z0JBQ3ZDLFlBQVksRUFBRSxTQUFTO2FBQ3hCLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPO1lBQ0wsVUFBVSxFQUFFLFNBQVM7WUFDckIsWUFBWSxFQUFFLFNBQVM7U0FDeEIsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBakNELDBEQWlDQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcclxuLypcclxuICBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICBcclxuICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpLlxyXG4gIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICBcclxuICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAgXHJcbiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxyXG4gIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcclxuICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cclxuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXHJcbiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiovXHJcblxyXG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XHJcblxyXG5pbXBvcnQge1xyXG4gIGdldEZyYW1ld29ya1NlbGVjdGlvblF1ZXN0aW9ucyxcclxuICBkb21haW5OYW1lRGV0YWlsc1F1ZXN0aW9ucyxcclxuICBnZXRHaXRodWJSZXBvc2l0b3J5UXVlc3Rpb25zLFxyXG4gIGdldFMzQnVja2V0Q29uZmlndXJhdGlvblF1ZXN0aW9ucyxcclxuICBnZXREb21haW5OYW1lUXVlc3Rpb24sXHJcbiAgaG9zdGVkWm9uZUlkUXVlc3Rpb24sXHJcbn0gZnJvbSBcIi4uL3V0aWxzL3Byb21wdF9xdWVzdGlvbnNcIjtcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0Q0xJRXhlY3V0aW9uRm9sZGVyLFxyXG4gIGdldFRvb2xGb2xkZXIsXHJcbiAgZ2V0Q29uZmlnRmlsZVBhdGgsXHJcbiAgZ2V0QnVpbGRDb25maWdGaWxlUGF0aCxcclxuICBnZXRCdWlsZENvbmZpZ1RlbXBsYXRlc0ZvbGRlcixcclxuICBzdGFydFByb21wdCxcclxuICBsb2FkSG9zdGluZ0NvbmZpZ3VyYXRpb24sXHJcbiAgaXNSZXBvQ29uZmlnLFxyXG4gIGlzUzNDb25maWcsXHJcbiAgZ2V0R2l0UmVtb3RlLFxyXG4gIGdldEdpdEJyYW5jaCxcclxuICBkb2VzSG9zdGluZ0NvbmZpZ3VyYXRpb25GaWxlRXhpc3QsXHJcbiAgZGV0ZWN0RnJvbnRlbmRGcmFtZXdvcmssXHJcbiAgZ2V0Q2ZmVGVtcGxhdGVzRm9sZGVyLFxyXG4gIGdldENmZkNvbmZpZ0ZpbGVQYXRoLFxyXG59IGZyb20gXCIuLi91dGlscy9oZWxwZXJcIjtcclxuaW1wb3J0IHsgQ09ORklHX0ZJTEVfTkFNRSwgVE9PTF9OQU1FIH0gZnJvbSBcIi4uL3NoYXJlZC9jb25zdGFudHNcIjtcclxuaW1wb3J0IHsgSG9zdGluZ0NvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi4vc2hhcmVkL3R5cGVzXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiBoYW5kbGVJbml0Q29tbWFuZChzMzogYm9vbGVhbikge1xyXG4gIHMzID8gYXdhaXQgaW5pdF9zMygpIDogYXdhaXQgaW5pdF9yZXBvc2l0b3J5KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbml0X3JlcG9zaXRvcnkoKSB7XHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBcIlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLSBTdGF0aWMgaG9zdGluZyBjb25maWd1cmF0aW9uIHdpemFyZCA6IEdpdEh1YiBTb3VyY2UgQ29kZSBSZXBvc2l0b3J5IEJhc2VkIC0tLS0tLS0tLS0tLS0tLS0tLS1cXG5cIlxyXG4gICk7XHJcblxyXG4gIGxldCBjdXJyZW50SG9zdGluZ0NvbmZpZzogSG9zdGluZ0NvbmZpZ3VyYXRpb24gPSB7XHJcbiAgICByZXBvVXJsOiBcIlwiLFxyXG4gICAgYnJhbmNoTmFtZTogXCJcIixcclxuICAgIGZyYW1ld29yazogXCJcIixcclxuICAgIGRvbWFpbk5hbWU6IHVuZGVmaW5lZCxcclxuICAgIGhvc3RlZFpvbmVJZDogdW5kZWZpbmVkLFxyXG4gIH07XHJcblxyXG4gIGlmIChkb2VzSG9zdGluZ0NvbmZpZ3VyYXRpb25GaWxlRXhpc3QoKSkge1xyXG4gICAgY29uc3QgbG9hZGVkQ29uZmlnID0gYXdhaXQgbG9hZEhvc3RpbmdDb25maWd1cmF0aW9uKCk7XHJcblxyXG4gICAgaWYgKGlzUmVwb0NvbmZpZyhsb2FkZWRDb25maWcpKSB7XHJcbiAgICAgIGN1cnJlbnRIb3N0aW5nQ29uZmlnID0gbG9hZGVkQ29uZmlnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBgXFxuXFxuIFRvIGZhY2lsaXRhdGUgdGhlIGRlcGxveW1lbnQgb2YgdGhlIG5lY2Vzc2FyeSBpbmZyYXN0cnVjdHVyZSBmb3Igd2Vic2l0ZSBob3N0aW5nLCBjZXJ0YWluIGluZm9ybWF0aW9uIGlzIHJlcXVpcmVkLlxcbiAke1RPT0xfTkFNRX0gd2lsbCBhaW0gdG8gZmluZCBhcyBtdWNoIHJlbGV2YW50IGRhdGEgYXMgcG9zc2libGUuXFxuXFxuYFxyXG4gICk7XHJcblxyXG4gIGxldCBpZGVudGlmaWVkUmVwb3NpdG9yeVVybDogc3RyaW5nLFxyXG4gICAgaWRlbnRpZmllZEJyYW5jaE5hbWU6IHN0cmluZyxcclxuICAgIGlkZW50aWZpZWRGcmFtZXdvcmtOYW1lOiBzdHJpbmc7XHJcblxyXG4gIC8vY2hlY2sgZ2l0aHViIGNvbmZpZ3VyYXRpb25cclxuICBjb25zb2xlLmxvZyhcclxuICAgIFwiQ29sbGVjdGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgR2l0SHViIHJlcG9zaXRvcnkgZnJvbSBcIiArXHJcbiAgICAgIGdldENMSUV4ZWN1dGlvbkZvbGRlcigpXHJcbiAgKTtcclxuICBpZGVudGlmaWVkUmVwb3NpdG9yeVVybCA9IGdldEdpdFJlbW90ZSgpO1xyXG5cclxuICBpZGVudGlmaWVkQnJhbmNoTmFtZSA9IGdldEdpdEJyYW5jaCgpO1xyXG5cclxuICBjb25zdCByZXBvUXVlc3Rpb25zID0gYXdhaXQgc3RhcnRQcm9tcHQoXHJcbiAgICBnZXRHaXRodWJSZXBvc2l0b3J5UXVlc3Rpb25zKFxyXG4gICAgICBjdXJyZW50SG9zdGluZ0NvbmZpZy5yZXBvVXJsXHJcbiAgICAgICAgPyBjdXJyZW50SG9zdGluZ0NvbmZpZy5yZXBvVXJsXHJcbiAgICAgICAgOiBpZGVudGlmaWVkUmVwb3NpdG9yeVVybCxcclxuICAgICAgY3VycmVudEhvc3RpbmdDb25maWcuYnJhbmNoTmFtZVxyXG4gICAgICAgID8gY3VycmVudEhvc3RpbmdDb25maWcuYnJhbmNoTmFtZVxyXG4gICAgICAgIDogaWRlbnRpZmllZEJyYW5jaE5hbWVcclxuICAgIClcclxuICApO1xyXG5cclxuICBjb25zb2xlLmxvZyhcclxuICAgIFwiXFxuQ29sbGVjdGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZnJvbnRlbmQgZnJhbWV3b3JrIHVzZWQgdG8gZW5hYmxlIHRoZSBwcm92aXNpb24gb2YgdGhlIGFwcHJvcHJpYXRlIGJ1aWxkIGNvbmZpZ3VyYXRpb24uXCJcclxuICApO1xyXG4gIGlkZW50aWZpZWRGcmFtZXdvcmtOYW1lID0gYXdhaXQgZGV0ZWN0RnJvbnRlbmRGcmFtZXdvcmsoXHJcbiAgICBnZXRDTElFeGVjdXRpb25Gb2xkZXIoKVxyXG4gICk7XHJcblxyXG5cclxuICAgICBcclxuXHJcbiAgY29uc3QgZnJhbWV3b3JrU2VsZWN0aW9uID0gYXdhaXQgc3RhcnRQcm9tcHQoXHJcbiAgICBnZXRGcmFtZXdvcmtTZWxlY3Rpb25RdWVzdGlvbnMoXHJcbiAgICAgIGN1cnJlbnRIb3N0aW5nQ29uZmlnLmZyYW1ld29ya1xyXG4gICAgICAgID8gY3VycmVudEhvc3RpbmdDb25maWcuZnJhbWV3b3JrXHJcbiAgICAgICAgOiBpZGVudGlmaWVkRnJhbWV3b3JrTmFtZVxyXG4gICAgKVxyXG4gICk7XHJcblxyXG4gIGNvbnN0IHJlcG9zaXRvcnlVcmwgPSByZXBvUXVlc3Rpb25zLnJlcG9Vcmw7XHJcbiAgY29uc3QgYnJhbmNoTmFtZSA9IHJlcG9RdWVzdGlvbnMuYnJhbmNoTmFtZTtcclxuICBjb25zdCBmcmFtZXdvcmtOYW1lID0gZnJhbWV3b3JrU2VsZWN0aW9uLmZyYW1ld29yaztcclxuICBpZihmcmFtZXdvcmtOYW1lID09PSBcImV4aXRcIil7XHJcbiAgICBwcm9jZXNzLmV4aXQoMCk7XHJcbiAgfVxyXG4gIGNvbnNvbGUubG9nKFwiXFxuXCIpO1xyXG4gIGNvbnN0IHsgZG9tYWluTmFtZSwgaG9zdGVkWm9uZUlkIH0gPSBhd2FpdCBnZXRVc2VyRG9tYWluUHJlZmVyZW5jZShcclxuICAgIGN1cnJlbnRIb3N0aW5nQ29uZmlnXHJcbiAgKTtcclxuXHJcbiAgY29uc29sZS5sb2coXCJcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXCIpO1xyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgYEhlcmUgaXMgdGhlIGNvbmZpZ3VyYXRpb24gdGhhdCBoYXMgYmVlbiBnZW5lcmF0ZWQgYW5kIHNhdmVkIHRvICR7VE9PTF9OQU1FfS8ke0NPTkZJR19GSUxFX05BTUV9IGZpbGUuOmBcclxuICApO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBHaXRIdWIgcmVwb3NpdG9yeTogXCIgKyByZXBvc2l0b3J5VXJsICsgXCIvXCIgKyBicmFuY2hOYW1lKTtcclxuICBjb25zb2xlLmxvZyhcIj4gICAgICAgRnJhbWV3b3JrOiBcIiArIGZyYW1ld29ya05hbWUpO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBEb21haW4gbmFtZTogXCIgKyAoZG9tYWluTmFtZSA/IGRvbWFpbk5hbWUgOiBcIk5vXCIpKTtcclxuICBjb25zb2xlLmxvZyhob3N0ZWRab25lSWQgPyBcIj4gICAgICAgSG9zdGVkIHpvbmUgSUQ6IFwiICsgaG9zdGVkWm9uZUlkIDogXCJcIik7XHJcblxyXG4gIGNvbnNvbGUubG9nKFwiXFxuLS1cIik7XHJcblxyXG4gIGNvcHlCdWlsZENvbmZpZ0lmTm90RXhpc3RzKFwiaG9zdGluZ19cIiArIGZyYW1ld29ya05hbWUgKyBcIi55bWxcIik7XHJcbiAgY29weUNmZklmTm90RXhpc3RzKFwiaW5kZXhfXCIgKyBmcmFtZXdvcmtOYW1lICsgXCIuanNcIilcclxuXHJcblxyXG4gIGNvbnN0IG5ld0hvc3RpbmdDb25maWd1cmF0aW9uOiBIb3N0aW5nQ29uZmlndXJhdGlvbiA9IHtcclxuICAgIHJlcG9Vcmw6IHJlcG9zaXRvcnlVcmwsXHJcbiAgICBicmFuY2hOYW1lOiBicmFuY2hOYW1lLFxyXG4gICAgZnJhbWV3b3JrOiBmcmFtZXdvcmtOYW1lLFxyXG4gICAgLi4uKGRvbWFpbk5hbWUgPyB7IGRvbWFpbk5hbWUgfSA6IHt9KSxcclxuICAgIC4uLihob3N0ZWRab25lSWQgPyB7IGhvc3RlZFpvbmVJZCB9IDoge30pLFxyXG4gIH07XHJcblxyXG4gIHNhdmVBbmRMb2dDb25maWd1cmF0aW9uKG5ld0hvc3RpbmdDb25maWd1cmF0aW9uKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNhdmVBbmRMb2dDb25maWd1cmF0aW9uKFxyXG4gIG5ld0hvc3RpbmdDb25maWd1cmF0aW9uOiBIb3N0aW5nQ29uZmlndXJhdGlvblxyXG4pOiB2b2lkIHtcclxuICBjb25zdCBqc29uSG9zdGluZ0NvbmZpZ3VyYXRpb24gPSBKU09OLnN0cmluZ2lmeShcclxuICAgIG5ld0hvc3RpbmdDb25maWd1cmF0aW9uLFxyXG4gICAgbnVsbCxcclxuICAgIDJcclxuICApO1xyXG5cclxuICBmcy53cml0ZUZpbGVTeW5jKGdldENvbmZpZ0ZpbGVQYXRoKCksIGpzb25Ib3N0aW5nQ29uZmlndXJhdGlvbik7XHJcblxyXG4gIGNvbnNvbGUubG9nKGA+ICAgICAgIENvbmZpZ3VyYXRpb24gZmlsZSBnZW5lcmF0ZWQgJHtnZXRDb25maWdGaWxlUGF0aCgpfWApO1xyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgYD4gICAgICAgQnVpbGQgY29uZmlndXJhdGlvbiBnZW5lcmF0ZWQgJHtnZXRCdWlsZENvbmZpZ0ZpbGVQYXRoKCl9YFxyXG4gICk7XHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBgPiAgICAgICBDbG91ZEZyb250IEZ1bmN0aW9uIHNvdXJjZSBjb2RlIGdlbmVyYXRlZCAke2dldENmZkNvbmZpZ0ZpbGVQYXRoKCl9YFxyXG4gICk7XHJcblxyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgYFxcblxcblRoZSBpbml0aWFsaXphdGlvbiBwcm9jZXNzIGhhcyBiZWVuIGNvbXBsZXRlZC4gWW91IG1heSBub3cgZXhlY3V0ZSAnJHtUT09MX05BTUV9IGRlcGxveScgdG8gZGVwbG95IHRoZSBpbmZyYXN0cnVjdHVyZS5cXG5gXHJcbiAgKTtcclxuXHJcbiAgXHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbml0X3MzKCkge1xyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgXCJcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU3RhdGljIGhvc3RpbmcgY29uZmlndXJhdGlvbiB3aXphcmQ6IFMzIFNvdXJjZSBDb2RlIFJlcG9zaXRvcnkgQmFzZWQgLS0tLS0tLS0tLS0tLS0tLS0tLVxcblwiXHJcbiAgKTtcclxuICBsZXQgY3VycmVudEhvc3RpbmdDb25maWc6IEhvc3RpbmdDb25maWd1cmF0aW9uID0ge1xyXG4gICAgczNidWNrZXQ6IFwiXCIsXHJcbiAgICBzM3BhdGg6IFwiXCIsXHJcbiAgICBkb21haW5OYW1lOiB1bmRlZmluZWQsXHJcbiAgICBob3N0ZWRab25lSWQ6IHVuZGVmaW5lZCxcclxuICB9O1xyXG5cclxuICBpZiAoZG9lc0hvc3RpbmdDb25maWd1cmF0aW9uRmlsZUV4aXN0KCkpIHtcclxuICAgIGNvbnN0IGxvYWRlZENvbmZpZyA9IGF3YWl0IGxvYWRIb3N0aW5nQ29uZmlndXJhdGlvbigpO1xyXG5cclxuICAgIGlmIChpc1MzQ29uZmlnKGxvYWRlZENvbmZpZykpIHtcclxuICAgICAgY3VycmVudEhvc3RpbmdDb25maWcgPSBsb2FkZWRDb25maWc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb25zdCBzM3F1ZXN0aW9ucyA9IGF3YWl0IHN0YXJ0UHJvbXB0KFxyXG4gICAgZ2V0UzNCdWNrZXRDb25maWd1cmF0aW9uUXVlc3Rpb25zKFxyXG4gICAgICBjdXJyZW50SG9zdGluZ0NvbmZpZy5zM2J1Y2tldCxcclxuICAgICAgY3VycmVudEhvc3RpbmdDb25maWcuczNwYXRoXHJcbiAgICApXHJcbiAgKTtcclxuXHJcbiAgY29uc3QgeyBkb21haW5OYW1lLCBob3N0ZWRab25lSWQgfSA9IGF3YWl0IGdldFVzZXJEb21haW5QcmVmZXJlbmNlKFxyXG4gICAgY3VycmVudEhvc3RpbmdDb25maWdcclxuICApO1xyXG5cclxuICBjb25zb2xlLmxvZyhcIlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cIik7XHJcbiAgY29uc29sZS5sb2coXCJQbGVhc2UgcmV2aWV3IHRoZSBmb2xsb3dpbmcgY2FwdHVyZWQgaW5mb3JtYXRpb246XCIpO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBTMyBCdWNrZXQ6IFwiICsgczNxdWVzdGlvbnMuczNidWNrZXQpO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBTMyBQcmVmaXg6IFwiICsgczNxdWVzdGlvbnMuczNwYXRoKTtcclxuICBjb25zb2xlLmxvZyhcIj4gICAgICAgRG9tYWluIG5hbWU6IFwiICsgKGRvbWFpbk5hbWUgPyBkb21haW5OYW1lIDogXCJOb1wiKSk7XHJcbiAgY29uc29sZS5sb2coaG9zdGVkWm9uZUlkID8gXCI+ICAgICAgIEhvc3RlZCB6b25lIElEOiBcIiArIGhvc3RlZFpvbmVJZCA6IFwiXCIpO1xyXG5cclxuICBjb25zb2xlLmxvZyhcIlxcbi0tXCIpO1xyXG5cclxuICBjb3B5QnVpbGRDb25maWdJZk5vdEV4aXN0cyhcInMzX2J1aWxkX2NvbmZpZy55bWxcIik7XHJcbiAgY29weUNmZklmTm90RXhpc3RzKFwiaW5kZXhfYmFzaWMuanNcIilcclxuXHJcbiAgY29uc3QgbmV3SG9zdGluZ0NvbmZpZ3VyYXRpb246IEhvc3RpbmdDb25maWd1cmF0aW9uID0ge1xyXG4gICAgczNidWNrZXQ6IHMzcXVlc3Rpb25zLnMzYnVja2V0LFxyXG4gICAgczNwYXRoOiBzM3F1ZXN0aW9ucy5zM3BhdGgsXHJcbiAgICAuLi4oZG9tYWluTmFtZSA/IHsgZG9tYWluTmFtZSB9IDoge30pLFxyXG4gICAgLi4uKGhvc3RlZFpvbmVJZCA/IHsgaG9zdGVkWm9uZUlkIH0gOiB7fSksXHJcbiAgfTtcclxuXHJcbiAgc2F2ZUFuZExvZ0NvbmZpZ3VyYXRpb24obmV3SG9zdGluZ0NvbmZpZ3VyYXRpb24pO1xyXG59XHJcblxyXG4vKipcclxuICogQ29waWVzIGEgYnVpbGQgY29uZmlndXJhdGlvbiB0ZW1wbGF0ZSB0byB0aGUgdG9vbCBmb2xkZXIgaWYgaXQgZG9lcyBub3QgYWxyZWFkeSBleGlzdC5cclxuICpcclxuICogQHBhcmFtIGZyYW1ld29ya05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZnJhbWV3b3JrIHRvIGRldGVybWluZSB0aGUgc291cmNlIGJ1aWxkIGNvbmZpZ3VyYXRpb24gZmlsZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb3B5QnVpbGRDb25maWdJZk5vdEV4aXN0cyhmaWxlTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgY29uc3Qgc3JjQnVpbGRDb25maWdGaWxlOiBzdHJpbmcgPVxyXG4gICAgZ2V0QnVpbGRDb25maWdUZW1wbGF0ZXNGb2xkZXIoKSArIFwiL1wiICsgZmlsZU5hbWU7XHJcblxyXG4gIGlmICghZnMuZXhpc3RzU3luYyhnZXRUb29sRm9sZGVyKCkpKSB7XHJcbiAgICBmcy5ta2RpclN5bmMoZ2V0VG9vbEZvbGRlcigpKTtcclxuICB9XHJcblxyXG4gIGlmICghZnMuZXhpc3RzU3luYyhnZXRCdWlsZENvbmZpZ0ZpbGVQYXRoKCkpKSB7XHJcbiAgICBmcy5jb3B5RmlsZVN5bmMoc3JjQnVpbGRDb25maWdGaWxlLCBnZXRCdWlsZENvbmZpZ0ZpbGVQYXRoKCkpO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvcHlDZmZJZk5vdEV4aXN0cyhmaWxlTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcblxyXG4gIGNvbnN0IHNyY0J1aWxkQ29uZmlnRmlsZTogc3RyaW5nID1cclxuICAgIGdldENmZlRlbXBsYXRlc0ZvbGRlcigpICsgXCIvXCIgKyBmaWxlTmFtZTtcclxuXHJcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGdldFRvb2xGb2xkZXIoKSkpIHtcclxuICAgIGZzLm1rZGlyU3luYyhnZXRUb29sRm9sZGVyKCkpO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGdldENmZkNvbmZpZ0ZpbGVQYXRoKCkpKSB7XHJcbiAgICBmcy5jb3B5RmlsZVN5bmMoc3JjQnVpbGRDb25maWdGaWxlLCBnZXRDZmZDb25maWdGaWxlUGF0aCgpKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRVc2VyRG9tYWluUHJlZmVyZW5jZShcclxuICBjdXJyZW50SG9zdGluZ0NvbmZpZzogSG9zdGluZ0NvbmZpZ3VyYXRpb25cclxuKSB7XHJcbiAgY29uc3Qgd2l0aERvbWFpbk5hbWUgPSBhd2FpdCBzdGFydFByb21wdChcclxuICAgIGdldERvbWFpbk5hbWVRdWVzdGlvbihjdXJyZW50SG9zdGluZ0NvbmZpZy5kb21haW5OYW1lKVxyXG4gICk7XHJcblxyXG4gIGlmICh3aXRoRG9tYWluTmFtZS52YWx1ZSA9PT0gXCJ5ZXNcIikge1xyXG4gICAgY29uc3QgZG9tYWluTmFtZVByb21wdCA9IGF3YWl0IHN0YXJ0UHJvbXB0KFxyXG4gICAgICBkb21haW5OYW1lRGV0YWlsc1F1ZXN0aW9ucyhjdXJyZW50SG9zdGluZ0NvbmZpZy5kb21haW5OYW1lKVxyXG4gICAgKTtcclxuXHJcbiAgICBpZiAoZG9tYWluTmFtZVByb21wdC5yZWdpc3RyYXIgPT09IFwiY3VycmVudFwiKSB7XHJcbiAgICAgIGNvbnN0IGhvc3RlZFpvbmUgPSBhd2FpdCBzdGFydFByb21wdChcclxuICAgICAgICBob3N0ZWRab25lSWRRdWVzdGlvbihjdXJyZW50SG9zdGluZ0NvbmZpZy5ob3N0ZWRab25lSWQpXHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGRvbWFpbk5hbWU6IGRvbWFpbk5hbWVQcm9tcHQuZG9tYWluTmFtZSxcclxuICAgICAgICBob3N0ZWRab25lSWQ6IGhvc3RlZFpvbmUuaG9zdGVkWm9uZUlkLFxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBkb21haW5OYW1lOiBkb21haW5OYW1lUHJvbXB0LmRvbWFpbk5hbWUsXHJcbiAgICAgICAgaG9zdGVkWm9uZUlkOiB1bmRlZmluZWQsXHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGRvbWFpbk5hbWU6IHVuZGVmaW5lZCxcclxuICAgICAgaG9zdGVkWm9uZUlkOiB1bmRlZmluZWQsXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iXX0=