212 lines
27 KiB
JavaScript
212 lines
27 KiB
JavaScript
import process from 'node:process';
|
|
import { AmplifyError, AmplifyFault, CDKContextKey, } from '@aws-amplify/platform-core';
|
|
import path from 'path';
|
|
import { MemoryContext, StackSelectionStrategy, } from '@aws-cdk/toolkit-lib';
|
|
import { tsImport } from 'tsx/esm/api';
|
|
import { CloudAssembly } from 'aws-cdk-lib/cx-api';
|
|
import { pathToFileURL } from 'url';
|
|
import { AssetStaging } from 'aws-cdk-lib/core';
|
|
import { Worker } from 'node:worker_threads';
|
|
/**
|
|
* Invokes CDK command via execa
|
|
*/
|
|
export class CDKDeployer {
|
|
cdkErrorMapper;
|
|
backendLocator;
|
|
packageManagerController;
|
|
cdkToolkit;
|
|
ioHost;
|
|
absoluteCloudAssemblyLocation = path.resolve(process.cwd(), '.amplify/artifacts/cdk.out');
|
|
/**
|
|
* Instantiates instance of CDKDeployer
|
|
*/
|
|
constructor(cdkErrorMapper, backendLocator, packageManagerController, cdkToolkit, ioHost) {
|
|
this.cdkErrorMapper = cdkErrorMapper;
|
|
this.backendLocator = backendLocator;
|
|
this.packageManagerController = packageManagerController;
|
|
this.cdkToolkit = cdkToolkit;
|
|
this.ioHost = ioHost;
|
|
}
|
|
/**
|
|
* Invokes cdk deploy API
|
|
*/
|
|
deploy = async (backendId, deployProps) => {
|
|
// Hack?? CDK uses global asset cache that is not cleared if assets are
|
|
// changing within the same process (which now happens with CDK Toolkit APIs)
|
|
// See https://github.com/aws/aws-cdk-cli/issues/236
|
|
AssetStaging.clearAssetHashCache();
|
|
const cx = await this.getCdkCloudAssembly(backendId, deployProps?.secretLastUpdated?.getTime());
|
|
// Initiate synth for the cloud executable and send a message for display.
|
|
const synthStartTime = Date.now();
|
|
let synthAssembly, synthError = undefined;
|
|
await this.ioHost.notify({
|
|
message: `Backend synthesis started`,
|
|
code: 'SYNTH_STARTED',
|
|
action: 'amplify',
|
|
time: new Date(),
|
|
level: 'info',
|
|
data: undefined,
|
|
});
|
|
try {
|
|
synthAssembly = await this.cdkToolkit.synth(cx, {
|
|
stacks: {
|
|
strategy: StackSelectionStrategy.ALL_STACKS,
|
|
},
|
|
});
|
|
}
|
|
catch (error) {
|
|
synthError = error;
|
|
}
|
|
const synthTimeSeconds = Math.floor((Date.now() - synthStartTime) / 10) / 100;
|
|
await this.ioHost.notify({
|
|
message: `Backend synthesized in ${synthTimeSeconds} seconds`,
|
|
code: 'SYNTH_FINISHED',
|
|
action: 'amplify',
|
|
time: new Date(),
|
|
level: 'result',
|
|
data: undefined,
|
|
});
|
|
// Typescript compilation. For type related errors, we prefer to show errors from TS to customers rather than synth
|
|
const typeCheckStartTime = Date.now();
|
|
await this.ioHost.notify({
|
|
message: `Backend type checks started`,
|
|
code: 'TS_STARTED',
|
|
action: 'amplify',
|
|
time: new Date(),
|
|
level: 'info',
|
|
data: undefined,
|
|
});
|
|
if (deployProps?.validateAppSources) {
|
|
try {
|
|
await this.compileProject(path.dirname(this.backendLocator.locate()));
|
|
}
|
|
catch (typeError) {
|
|
if (synthError &&
|
|
AmplifyError.isAmplifyError(typeError) &&
|
|
typeError.name === 'FunctionEnvVarFileNotGeneratedError') {
|
|
// synth has failed and we don't have auto generated function environment definition files. This
|
|
// resulted in the exception caught here, which is not very useful for the customers.
|
|
// We instead throw the synth error for customers to fix what caused the synth to fail.
|
|
throw this.cdkErrorMapper.getAmplifyError(synthError, backendId.type);
|
|
}
|
|
throw typeError;
|
|
}
|
|
finally {
|
|
const typeCheckTimeSeconds = Math.floor((Date.now() - typeCheckStartTime) / 10) / 100;
|
|
await this.ioHost.notify({
|
|
message: `Type checks completed in ${typeCheckTimeSeconds} seconds`,
|
|
code: 'TS_FINISHED',
|
|
action: 'amplify',
|
|
time: new Date(),
|
|
level: 'result',
|
|
data: undefined,
|
|
});
|
|
}
|
|
}
|
|
// If typescript compilation was successful but synth had failed, we throw synth error
|
|
if (synthError) {
|
|
throw this.cdkErrorMapper.getAmplifyError(synthError, backendId.type);
|
|
}
|
|
// Perform actual deployment. CFN or hotswap
|
|
const deployStartTime = Date.now();
|
|
try {
|
|
await this.cdkToolkit.deploy(synthAssembly, {
|
|
stacks: {
|
|
strategy: StackSelectionStrategy.ALL_STACKS,
|
|
},
|
|
deploymentMethod: backendId.type === 'sandbox'
|
|
? { method: 'hotswap', fallback: { method: 'direct' } }
|
|
: { method: 'direct' },
|
|
});
|
|
}
|
|
catch (error) {
|
|
await this.ioHost.notify({
|
|
message: 'Deployment failed',
|
|
code: 'DEPLOY_FAILED',
|
|
action: 'amplify',
|
|
time: new Date(),
|
|
level: 'error',
|
|
data: undefined,
|
|
});
|
|
throw this.cdkErrorMapper.getAmplifyError(error, backendId.type);
|
|
}
|
|
finally {
|
|
await synthAssembly?.dispose();
|
|
}
|
|
return {
|
|
deploymentTimes: {
|
|
synthesisTime: synthTimeSeconds,
|
|
totalTime: synthTimeSeconds +
|
|
Math.floor((Date.now() - deployStartTime) / 10) / 100,
|
|
},
|
|
};
|
|
};
|
|
/**
|
|
* Invokes cdk destroy API
|
|
*/
|
|
destroy = async (backendId) => {
|
|
const deploymentStartTime = Date.now();
|
|
try {
|
|
await this.cdkToolkit.destroy(await this.getCdkCloudAssembly(backendId), {
|
|
stacks: {
|
|
strategy: StackSelectionStrategy.ALL_STACKS,
|
|
},
|
|
});
|
|
return {
|
|
deploymentTimes: {
|
|
totalTime: Math.floor((Date.now() - deploymentStartTime) / 10) / 100,
|
|
},
|
|
};
|
|
}
|
|
catch (error) {
|
|
throw this.cdkErrorMapper.getAmplifyError(error, backendId.type);
|
|
}
|
|
};
|
|
compileProject = (projectDirectory) => {
|
|
return new Promise((resolve, reject) => {
|
|
const worker = new Worker(new URL('ts_compiler.js', import.meta.url), {
|
|
workerData: { projectDirectory },
|
|
});
|
|
worker.on('message', () => {
|
|
// do nothing
|
|
});
|
|
worker.on('error', reject);
|
|
worker.on('exit', (code) => {
|
|
if (code !== 0) {
|
|
reject(new AmplifyFault('TSCompilerWorkerFault', {
|
|
message: `Worker stopped with exit code ${code}`,
|
|
}));
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
};
|
|
/**
|
|
* Build cloud executable from dynamically importing the cdk ts file, i.e. backend.ts
|
|
*/
|
|
getCdkCloudAssembly = (backendId, secretLastUpdated) => {
|
|
const contextParams = {};
|
|
if (backendId.type === 'sandbox') {
|
|
if (secretLastUpdated) {
|
|
contextParams['secretLastUpdated'] = secretLastUpdated;
|
|
}
|
|
}
|
|
contextParams[CDKContextKey.BACKEND_NAMESPACE] = backendId.namespace;
|
|
contextParams[CDKContextKey.BACKEND_NAME] = backendId.name;
|
|
contextParams[CDKContextKey.DEPLOYMENT_TYPE] = backendId.type;
|
|
return this.cdkToolkit.fromAssemblyBuilder(async () => {
|
|
await tsImport(pathToFileURL(this.backendLocator.locate()).toString(), import.meta.url);
|
|
/**
|
|
By not having a child process with toolkit lib, the `process.on('beforeExit')` does not execute
|
|
on the CDK side resulting in the app not getting synthesized properly. So we send a signal/message
|
|
to the same process and catch it in backend package where App is initialized to explicitly perform synth
|
|
*/
|
|
process.emit('message', 'amplifySynth', undefined);
|
|
return new CloudAssembly(this.absoluteCloudAssemblyLocation);
|
|
}, {
|
|
contextStore: new MemoryContext(contextParams),
|
|
outdir: this.absoluteCloudAssemblyLocation,
|
|
});
|
|
};
|
|
}
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrX2RlcGxveWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Nka19kZXBsb3llci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFZbkMsT0FBTyxFQUNMLFlBQVksRUFDWixZQUFZLEVBRVosYUFBYSxHQUNkLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFDTCxhQUFhLEVBQ2Isc0JBQXNCLEdBRXZCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTdDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFVSDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBYkYsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FDM0QsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUNiLDRCQUE0QixDQUM3QixDQUFDO0lBRUY7O09BRUc7SUFDSCxZQUNtQixjQUE4QixFQUM5QixjQUE4QixFQUM5Qix3QkFBa0QsRUFDbEQsVUFBbUIsRUFDbkIsTUFBcUI7UUFKckIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5Qiw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELGVBQVUsR0FBVixVQUFVLENBQVM7UUFDbkIsV0FBTSxHQUFOLE1BQU0sQ0FBZTtJQUNyQyxDQUFDO0lBRUo7O09BRUc7SUFDSCxNQUFNLEdBQUcsS0FB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WUFDakMsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO2dCQUN0QixhQUFhLENBQUMsbUJBQW1CLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztZQUN6RCxDQUFDO1FBQ0gsQ0FBQztRQUVELGFBQWEsQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQ3JFLGFBQWEsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztRQUMzRCxhQUFhLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7UUFDOUQsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUN4QyxLQUFLLElBQUksRUFBRTtZQUNULE1BQU0sUUFBUSxDQUNaLGFBQWEsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQ3RELE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNoQixDQUFDO1lBRUY7Ozs7ZUFJRztZQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGNBQWMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNuRCxPQUFPLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQy9ELENBQUMsRUFDRDtZQUNFLFlBQVksRUFBRSxJQUFJLGFBQWEsQ0FBQyxhQUFhLENBQUM7WUFDOUMsTUFBTSxFQUFFLElBQUksQ0FBQyw2QkFBNkI7U0FDM0MsQ0FDRixDQUFDO0lBQ0osQ0FBQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQge1xuICBCYWNrZW5kRGVwbG95ZXIsXG4gIERlcGxveVByb3BzLFxufSBmcm9tICcuL2Nka19kZXBsb3llcl9zaW5nbGV0b25fZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBDZGtFcnJvck1hcHBlciB9IGZyb20gJy4vY2RrX2Vycm9yX21hcHBlci5qcyc7XG5pbXBvcnQge1xuICBBbXBsaWZ5SU9Ib3N0LFxuICBCYWNrZW5kSWRlbnRpZmllcixcbiAgdHlwZSBQYWNrYWdlTWFuYWdlckNvbnRyb2xsZXIsXG59IGZyb20gJ0Bhd3MtYW1wbGlmeS9wbHVnaW4tdHlwZXMnO1xuaW1wb3J0IHtcbiAgQW1wbGlmeUVycm9yLFxuICBBbXBsaWZ5RmF1bHQsXG4gIEJhY2tlbmRMb2NhdG9yLFxuICBDREtDb250ZXh0S2V5LFxufSBmcm9tICdAYXdzLWFtcGxpZnkvcGxhdGZvcm0tY29yZSc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIE1lbW9yeUNvbnRleHQsXG4gIFN0YWNrU2VsZWN0aW9uU3RyYXRlZ3ksXG4gIFRvb2xraXQsXG59IGZyb20gJ0Bhd3MtY2RrL3Rvb2xraXQtbGliJztcbmltcG9ydCB7IHRzSW1wb3J0IH0gZnJvbSAndHN4L2VzbS9hcGknO1xuaW1wb3J0IHsgQ2xvdWRBc3NlbWJseSB9IGZyb20gJ2F3cy1jZGstbGliL2N4LWFwaSc7XG5pbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSAndXJsJztcbmltcG9ydCB7IEFzc2V0U3RhZ2luZyB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUnO1xuaW1wb3J0IHsgV29ya2VyIH0gZnJvbSAnbm9kZTp3b3JrZXJfdGhyZWFkcyc7XG5cbi8qKlxuICogSW52b2tlcyBDREsgY29tbWFuZCB2aWEgZXhlY2FcbiAqL1xuZXhwb3J0IGNsYXNzIENES0RlcGxveWVyIGltcGxlbWVudHMgQmFja2VuZERlcGxveWVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhYnNvbHV0ZUNsb3VkQXNzZW1ibHlMb2NhdGlvbiA9IHBhdGgucmVzb2x2ZShcbiAgICBwcm9jZXNzLmN3ZCgpLFxuICAgICcuYW1wbGlmeS9hcnRpZmFjdHMvY2RrLm91dCcsXG4gICk7XG5cbiAgLyoqXG4gICAqIEluc3RhbnRpYXRlcyBpbnN0YW5jZSBvZiBDREtEZXBsb3llclxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZGtFcnJvck1hcHBlcjogQ2RrRXJyb3JNYXBwZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBiYWNrZW5kTG9jYXRvcjogQmFja2VuZExvY2F0b3IsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYWNrYWdlTWFuYWdlckNvbnRyb2xsZXI6IFBhY2thZ2VNYW5hZ2VyQ29udHJvbGxlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNka1Rvb2xraXQ6IFRvb2xraXQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBpb0hvc3Q6IEFtcGxpZnlJT0hvc3QsXG4gICkge31cblxuICAvKipcbiAgICogSW52b2tlcyBjZGsgZGVwbG95IEFQSVxuICAgKi9cbiAgZGVwbG95ID0gYXN5bmMgKGJhY2tlbmRJZDogQmFja2VuZElkZW50aWZpZXIsIGRlcGxveVByb3BzPzogRGVwbG95UHJvcHMpID0+IHtcbiAgICAvLyBIYWNrPz8gQ0RLIHVzZXMgZ2xvYmFsIGFzc2V0IGNhY2hlIHRoYXQgaXMgbm90IGNsZWFyZWQgaWYgYXNzZXRzIGFyZVxuICAgIC8vIGNoYW5naW5nIHdpdGhpbiB0aGUgc2FtZSBwcm9jZXNzICh3aGljaCBub3cgaGFwcGVucyB3aXRoIENESyBUb29sa2l0IEFQSXMpXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay1jbGkvaXNzdWVzLzIzNlxuICAgIEFzc2V0U3RhZ2luZy5jbGVhckFzc2V0SGFzaENhY2hlKCk7XG5cbiAgICBjb25zdCBjeCA9IGF3YWl0IHRoaXMuZ2V0Q2RrQ2xvdWRBc3NlbWJseShcbiAgICAgIGJhY2tlbmRJZCxcbiAgICAgIGRlcGxveVByb3BzPy5zZWNyZXRMYXN0VXBkYXRlZD8uZ2V0VGltZSgpLFxuICAgICk7XG4gICAgLy8gSW5pdGlhdGUgc3ludGggZm9yIHRoZSBjbG91ZCBleGVjdXRhYmxlIGFuZCBzZW5kIGEgbWVzc2FnZSBmb3IgZGlzcGxheS5cbiAgICBjb25zdCBzeW50aFN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgbGV0IHN5bnRoQXNzZW1ibHksXG4gICAgICBzeW50aEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBhd2FpdCB0aGlzLmlvSG9zdC5ub3RpZnkoe1xuICAgICAgbWVzc2FnZTogYEJhY2tlbmQgc3ludGhlc2lzIHN0YXJ0ZWRgLFxuICAgICAgY29kZTogJ1NZTlRIX1NUQVJURUQnLFxuICAgICAgYWN0aW9uOiAnYW1wbGlmeScsXG4gICAgICB0aW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgbGV2ZWw6ICdpbmZvJyxcbiAgICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICBzeW50aEFzc2VtYmx5ID0gYXdhaXQgdGhpcy5jZGtUb29sa2l0LnN5bnRoKGN4LCB7XG4gICAgICAgIHN0YWNrczoge1xuICAgICAgICAgIHN0cmF0ZWd5OiBTdGFja1NlbGVjdGlvblN0cmF0ZWd5LkFMTF9TVEFDS1MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgc3ludGhFcnJvciA9IGVycm9yIGFzIEVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IHN5bnRoVGltZVNlY29uZHMgPVxuICAgICAgTWF0aC5mbG9vcigoRGF0ZS5ub3coKSAtIHN5bnRoU3RhcnRUaW1lKSAvIDEwKSAvIDEwMDtcblxuICAgIGF3YWl0IHRoaXMuaW9Ib3N0Lm5vdGlmeSh7XG4gICAgICBtZXNzYWdlOiBgQmFja2VuZCBzeW50aGVzaXplZCBpbiAke3N5bnRoVGltZVNlY29uZHN9IHNlY29uZHNgLFxuICAgICAgY29kZTogJ1NZTlRIX0ZJTklTSEVEJyxcbiAgICAgIGFjdGlvbjogJ2FtcGxpZnknLFxuICAgICAgdGltZTogbmV3IERhdGUoKSxcbiAgICAgIGxldmVsOiAncmVzdWx0JyxcbiAgICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIC8vIFR5cGVzY3JpcHQgY29tcGlsYXRpb24uIEZvciB0eXBlIHJlbGF0ZWQgZXJyb3JzLCB3ZSBwcmVmZXIgdG8gc2hvdyBlcnJvcnMgZnJvbSBUUyB0byBjdXN0b21lcnMgcmF0aGVyIHRoYW4gc3ludGhcbiAgICBjb25zdCB0eXBlQ2hlY2tTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGF3YWl0IHRoaXMuaW9Ib3N0Lm5vdGlmeSh7XG4gICAgICBtZXNzYWdlOiBgQmFja2VuZCB0eXBlIGNoZWNrcyBzdGFydGVkYCxcbiAgICAgIGNvZGU6ICdUU19TVEFSVEVEJyxcbiAgICAgIGFjdGlvbjogJ2FtcGxpZnknLFxuICAgICAgdGltZTogbmV3IERhdGUoKSxcbiAgICAgIGxldmVsOiAnaW5mbycsXG4gICAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgfSk7XG5cbiAgICBpZiAoZGVwbG95UHJvcHM/LnZhbGlkYXRlQXBwU291cmNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jb21waWxlUHJvamVjdChwYXRoLmRpcm5hbWUodGhpcy5iYWNrZW5kTG9jYXRvci5sb2NhdGUoKSkpO1xuICAgICAgfSBjYXRjaCAodHlwZUVycm9yKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzeW50aEVycm9yICYmXG4gICAgICAgICAgQW1wbGlmeUVycm9yLmlzQW1wbGlmeUVycm9yKHR5cGVFcnJvcikgJiZcbiAgICAgICAgICB0eXBlRXJyb3IubmFtZSA9PT0gJ0Z1bmN0aW9uRW52VmFyRmlsZU5vdEdlbmVyYXRlZEVycm9yJ1xuICAgICAgICApIHtcbiAgICAgICAgICAvLyBzeW50aCBoYXMgZmFpbGVkIGFuZCB3ZSBkb24ndCBoYXZlIGF1dG8gZ2VuZXJhdGVkIGZ1bmN0aW9uIGVudmlyb25tZW50IGRlZmluaXRpb24gZmlsZXMuIFRoaXNcbiAgICAgICAgICAvLyByZXN1bHRlZCBpbiB0aGUgZXhjZXB0aW9uIGNhdWdodCBoZXJlLCB3aGljaCBpcyBub3QgdmVyeSB1c2VmdWwgZm9yIHRoZSBjdXN0b21lcnMuXG4gICAgICAgICAgLy8gV2UgaW5zdGVhZCB0aHJvdyB0aGUgc3ludGggZXJyb3IgZm9yIGN1c3RvbWVycyB0byBmaXggd2hhdCBjYXVzZWQgdGhlIHN5bnRoIHRvIGZhaWwuXG4gICAgICAgICAgdGhyb3cgdGhpcy5jZGtFcnJvck1hcHBlci5nZXRBbXBsaWZ5RXJyb3Ioc3ludGhFcnJvciwgYmFja2VuZElkLnR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IHR5cGVFcnJvcjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGNvbnN0IHR5cGVDaGVja1RpbWVTZWNvbmRzID1cbiAgICAgICAgICBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdHlwZUNoZWNrU3RhcnRUaW1lKSAvIDEwKSAvIDEwMDtcbiAgICAgICAgYXdhaXQgdGhpcy5pb0hvc3Qubm90aWZ5KHtcbiAgICAgICAgICBtZXNzYWdlOiBgVHlwZSBjaGVja3MgY29tcGxldGVkIGluICR7dHlwZUNoZWNrVGltZVNlY29uZHN9IHNlY29uZHNgLFxuICAgICAgICAgIGNvZGU6ICdUU19GSU5JU0hFRCcsXG4gICAgICAgICAgYWN0aW9uOiAnYW1wbGlmeScsXG4gICAgICAgICAgdGltZTogbmV3IERhdGUoKSxcbiAgICAgICAgICBsZXZlbDogJ3Jlc3VsdCcsXG4gICAgICAgICAgZGF0YTogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB0eXBlc2NyaXB0IGNvbXBpbGF0aW9uIHdhcyBzdWNjZXNzZnVsIGJ1dCBzeW50aCBoYWQgZmFpbGVkLCB3ZSB0aHJvdyBzeW50aCBlcnJvclxuICAgIGlmIChzeW50aEVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLmNka0Vycm9yTWFwcGVyLmdldEFtcGxpZnlFcnJvcihzeW50aEVycm9yLCBiYWNrZW5kSWQudHlwZSk7XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybSBhY3R1YWwgZGVwbG95bWVudC4gQ0ZOIG9yIGhvdHN3YXBcbiAgICBjb25zdCBkZXBsb3lTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNka1Rvb2xraXQuZGVwbG95KHN5bnRoQXNzZW1ibHkhLCB7XG4gICAgICAgIHN0YWNrczoge1xuICAgICAgICAgIHN0cmF0ZWd5OiBTdGFja1NlbGVjdGlvblN0cmF0ZWd5LkFMTF9TVEFDS1MsXG4gICAgICAgIH0sXG4gICAgICAgIGRlcGxveW1lbnRNZXRob2Q6XG4gICAgICAgICAgYmFja2VuZElkLnR5cGUgPT09ICdzYW5kYm94J1xuICAgICAgICAgICAgPyB7IG1ldGhvZDogJ2hvdHN3YXAnLCBmYWxsYmFjazogeyBtZXRob2Q6ICdkaXJlY3QnIH0gfVxuICAgICAgICAgICAgOiB7IG1ldGhvZDogJ2RpcmVjdCcgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLmlvSG9zdC5ub3RpZnkoe1xuICAgICAgICBtZXNzYWdlOiAnRGVwbG95bWVudCBmYWlsZWQnLFxuICAgICAgICBjb2RlOiAnREVQTE9ZX0ZBSUxFRCcsXG4gICAgICAgIGFjdGlvbjogJ2FtcGxpZnknLFxuICAgICAgICB0aW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgZGF0YTogdW5kZWZpbmVkLFxuICAgICAgfSk7XG4gICAgICB0aHJvdyB0aGlzLmNka0Vycm9yTWFwcGVyLmdldEFtcGxpZnlFcnJvcihlcnJvciBhcyBFcnJvciwgYmFja2VuZElkLnR5cGUpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBzeW50aEFzc2VtYmx5Py5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRlcGxveW1lbnRUaW1lczoge1xuICAgICAgICBzeW50aGVzaXNUaW1lOiBzeW50aFRpbWVTZWNvbmRzLFxuICAgICAgICB0b3RhbFRpbWU6XG4gICAgICAgICAgc3ludGhUaW1lU2Vjb25kcyArXG4gICAgICAgICAgTWF0aC5mbG9vcigoRGF0ZS5ub3coKSAtIGRlcGxveVN0YXJ0VGltZSkgLyAxMCkgLyAxMDAsXG4gICAgICB9LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIEludm9rZXMgY2RrIGRlc3Ryb3kgQVBJXG4gICAqL1xuICBkZXN0cm95ID0gYXN5bmMgKGJhY2tlbmRJZDogQmFja2VuZElkZW50aWZpZXIpID0+IHtcbiAgICBjb25zdCBkZXBsb3ltZW50U3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jZGtUb29sa2l0LmRlc3Ryb3koYXdhaXQgdGhpcy5nZXRDZGtDbG91ZEFzc2VtYmx5KGJhY2tlbmRJZCksIHtcbiAgICAgICAgc3RhY2tzOiB7XG4gICAgICAgICAgc3RyYXRlZ3k6IFN0YWNrU2VsZWN0aW9uU3RyYXRlZ3kuQUxMX1NUQUNLUyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGVwbG95bWVudFRpbWVzOiB7XG4gICAgICAgICAgdG90YWxUaW1lOiBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gZGVwbG95bWVudFN0YXJ0VGltZSkgLyAxMCkgLyAxMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLmNka0Vycm9yTWFwcGVyLmdldEFtcGxpZnlFcnJvcihlcnJvciBhcyBFcnJvciwgYmFja2VuZElkLnR5cGUpO1xuICAgIH1cbiAgfTtcblxuICBjb21waWxlUHJvamVjdCA9IChwcm9qZWN0RGlyZWN0b3J5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgd29ya2VyID0gbmV3IFdvcmtlcihuZXcgVVJMKCd0c19jb21waWxlci5qcycsIGltcG9ydC5tZXRhLnVybCksIHtcbiAgICAgICAgd29ya2VyRGF0YTogeyBwcm9qZWN0RGlyZWN0b3J5IH0sXG4gICAgICB9KTtcbiAgICAgIHdvcmtlci5vbignbWVzc2FnZScsICgpID0+IHtcbiAgICAgICAgLy8gZG8gbm90aGluZ1xuICAgICAgfSk7XG4gICAgICB3b3JrZXIub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIHdvcmtlci5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgICAgIGlmIChjb2RlICE9PSAwKSB7XG4gICAgICAgICAgcmVqZWN0KFxuICAgICAgICAgICAgbmV3IEFtcGxpZnlGYXVsdCgnVFNDb21waWxlcldvcmtlckZhdWx0Jywge1xuICAgICAgICAgICAgICBtZXNzYWdlOiBgV29ya2VyIHN0b3BwZWQgd2l0aCBleGl0IGNvZGUgJHtjb2RlfWAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBCdWlsZCBjbG91ZCBleGVjdXRhYmxlIGZyb20gZHluYW1pY2FsbHkgaW1wb3J0aW5nIHRoZSBjZGsgdHMgZmlsZSwgaS5lLiBiYWNrZW5kLnRzXG4gICAqL1xuICBwcml2YXRlIGdldENka0Nsb3VkQXNzZW1ibHkgPSAoXG4gICAgYmFja2VuZElkOiBCYWNrZW5kSWRlbnRpZmllcixcbiAgICBzZWNyZXRMYXN0VXBkYXRlZD86IG51bWJlcixcbiAgKSA9PiB7XG4gICAgY29uc3QgY29udGV4dFBhcmFtczoge1xuICAgICAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbiAgICB9ID0ge307XG5cbiAgICBpZiAoYmFja2VuZElkLnR5cGUgPT09ICdzYW5kYm94Jykge1xuICAgICAgaWYgKHNlY3JldExhc3RVcGRhdGVkKSB7XG4gICAgICAgIGNvbnRleHRQYXJhbXNbJ3NlY3JldExhc3RVcGRhdGVkJ10gPSBzZWNyZXRMYXN0VXBkYXRlZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb250ZXh0UGFyYW1zW0NES0NvbnRleHRLZXkuQkFDS0VORF9OQU1FU1BBQ0VdID0gYmFja2VuZElkLm5hbWVzcGFjZTtcbiAgICBjb250ZXh0UGFyYW1zW0NES0NvbnRleHRLZXkuQkFDS0VORF9OQU1FXSA9IGJhY2tlbmRJZC5uYW1lO1xuICAgIGNvbnRleHRQYXJhbXNbQ0RLQ29udGV4dEtleS5ERVBMT1lNRU5UX1RZUEVdID0gYmFja2VuZElkLnR5cGU7XG4gICAgcmV0dXJuIHRoaXMuY2RrVG9vbGtpdC5mcm9tQXNzZW1ibHlCdWlsZGVyKFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0c0ltcG9ydChcbiAgICAgICAgICBwYXRoVG9GaWxlVVJMKHRoaXMuYmFja2VuZExvY2F0b3IubG9jYXRlKCkpLnRvU3RyaW5nKCksXG4gICAgICAgICAgaW1wb3J0Lm1ldGEudXJsLFxuICAgICAgICApO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgIEJ5IG5vdCBoYXZpbmcgYSBjaGlsZCBwcm9jZXNzIHdpdGggdG9vbGtpdCBsaWIsIHRoZSBgcHJvY2Vzcy5vbignYmVmb3JlRXhpdCcpYCBkb2VzIG5vdCBleGVjdXRlXG4gICAgICAgICAgb24gdGhlIENESyBzaWRlIHJlc3VsdGluZyBpbiB0aGUgYXBwIG5vdCBnZXR0aW5nIHN5bnRoZXNpemVkIHByb3Blcmx5LiBTbyB3ZSBzZW5kIGEgc2lnbmFsL21lc3NhZ2VcbiAgICAgICAgICB0byB0aGUgc2FtZSBwcm9jZXNzIGFuZCBjYXRjaCBpdCBpbiBiYWNrZW5kIHBhY2thZ2Ugd2hlcmUgQXBwIGlzIGluaXRpYWxpemVkIHRvIGV4cGxpY2l0bHkgcGVyZm9ybSBzeW50aFxuICAgICAgICAgKi9cbiAgICAgICAgcHJvY2Vzcy5lbWl0KCdtZXNzYWdlJywgJ2FtcGxpZnlTeW50aCcsIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiBuZXcgQ2xvdWRBc3NlbWJseSh0aGlzLmFic29sdXRlQ2xvdWRBc3NlbWJseUxvY2F0aW9uKTtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGNvbnRleHRTdG9yZTogbmV3IE1lbW9yeUNvbnRleHQoY29udGV4dFBhcmFtcyksXG4gICAgICAgIG91dGRpcjogdGhpcy5hYnNvbHV0ZUNsb3VkQXNzZW1ibHlMb2NhdGlvbixcbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcbn1cbiJdfQ==
|