@riddance/service
Version:
Too much code slows you down, creates risks, increases maintainability burdens, confuses AI. So let's commit less of it.
131 lines • 18.6 kB
JavaScript
import { clientFromHeaders, executeRequest } from '@riddance/host/http';
import { pathToRegExp } from '@riddance/host/http-registry';
import { getHandlers } from '@riddance/host/registry';
import { SignJWT } from 'jose/jwt/sign';
import assert from 'node:assert/strict';
import { createPrivateKey } from 'node:crypto';
import { getEnvironment } from './context.js';
import { createMockContext, jsonRoundtrip } from './setup.js';
export * from './context.js';
export async function request(options) {
if (options.uri.startsWith('/')) {
assert.strictEqual(options.uri, options.uri.slice(1), 'Path cannot start with slash.');
}
const handlers = getHandlers('http').map(withPathRegExp);
const matchingHandlers = handlers.filter(h => h[pathRegExp].test(options.uri) && h.method === (options.method ?? 'GET'));
const [handler] = matchingHandlers;
const { log, context, success, flush } = createMockContext(clientFromHeaders(options.headers), handler?.config, handler?.meta);
if (!handler) {
log.error('Request END', undefined, {
handlers: handlers.map(h => ({
pathPattern: h.pathPattern,
pathRegExp: h[pathRegExp].toString(),
method: h.method,
})),
response: {
status: 404,
},
});
return {
headers: {},
status: 404,
};
}
if (matchingHandlers.length !== 1) {
log.error('Multiple matching handlers.', undefined, {
matchingHandlers: matchingHandlers.map(h => ({
method: h.method,
pattern: h.pathPattern,
})),
});
log.error('Request END', undefined, {
handlers: handlers.map(h => ({
pathPattern: h.pathPattern,
pathRegExp: h[pathRegExp].toString(),
method: h.method,
})),
response: {
status: 500,
},
});
return {
headers: {},
status: 500,
};
}
log.trace('Found handler', undefined, {
handler: {
pathPattern: handler.pathPattern,
pathRegExp: handler[pathRegExp].toString(),
method: handler.method,
},
});
const response = await executeRequest(log, context, handler, {
...options,
...('json' in options && { json: jsonRoundtrip(options.json) }),
uri: 'http://localhost/' + options.uri,
}, success);
await flush();
return {
headers: response.headers,
status: response.status,
body: helpfulBody(response.body),
};
}
function helpfulBody(body) {
if (!body) {
return undefined;
}
if (Buffer.isBuffer(body)) {
try {
return JSON.parse(body.toString('utf-8'));
}
catch {
return body;
}
}
try {
return JSON.parse(body);
}
catch {
return body;
}
}
const pathRegExp = Symbol();
function withPathRegExp(handler) {
if (pathRegExp in handler) {
return handler;
}
handler[pathRegExp] = pathToRegExp(handler.pathPattern);
return handler;
}
export async function withBearer(payload, requestOptions) {
const token = createBearerToken(getEnvironment(), payload, {
issuer: 'https://riddance.example.com/oauth/',
audience: 'https://riddance.example.com/',
expiresIn: 60, // seconds
});
return {
...requestOptions,
headers: {
...requestOptions.headers,
authorization: `Bearer ${await token}`,
},
};
}
export async function createBearerToken(env, payload, options) {
const key = env.BEARER_PRIVATE_KEY;
if (!key) {
throw new Error('Please set the BEARER_PRIVATE_KEY environment variable to be able to create bearer tokens.');
}
const certificate = '-----BEGIN EC PRIVATE KEY-----\n' + key + '\n-----END EC PRIVATE KEY-----';
const now = Math.floor(Date.now() / 1000);
return await new SignJWT(payload)
.setProtectedHeader({ alg: 'ES384', typ: 'JWT' })
.setIssuedAt(now)
.setIssuer(options.issuer ?? 'https://riddance.example.com/oauth/')
.setAudience(options.audience ?? 'https://riddance.example.com/')
.setExpirationTime(now + options.expiresIn)
.sign(createPrivateKey({ key: certificate, format: 'pem', type: 'sec1' }));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImh0dHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQWUsTUFBTSw4QkFBOEIsQ0FBQTtBQUN4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFFckQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUN2QyxPQUFPLE1BQU0sTUFBTSxvQkFBb0IsQ0FBQTtBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFHOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBRTdELGNBQWMsY0FBYyxDQUFBO0FBMEI1QixNQUFNLENBQUMsS0FBSyxVQUFVLE9BQU8sQ0FBQyxPQUF1QjtJQUNqRCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDOUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLCtCQUErQixDQUFDLENBQUE7SUFDMUYsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUE7SUFDeEQsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUNwQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUss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ZGVycywgZXhlY3V0ZVJlcXVlc3QgfSBmcm9tICdAcmlkZGFuY2UvaG9zdC9odHRwJ1xuaW1wb3J0IHsgcGF0aFRvUmVnRXhwLCB0eXBlIE1ldGhvZCB9IGZyb20gJ0ByaWRkYW5jZS9ob3N0L2h0dHAtcmVnaXN0cnknXG5pbXBvcnQgeyBnZXRIYW5kbGVycyB9IGZyb20gJ0ByaWRkYW5jZS9ob3N0L3JlZ2lzdHJ5J1xuaW1wb3J0IHR5cGUgeyBKV1RQYXlsb2FkIH0gZnJvbSAnam9zZSdcbmltcG9ydCB7IFNpZ25KV1QgfSBmcm9tICdqb3NlL2p3dC9zaWduJ1xuaW1wb3J0IGFzc2VydCBmcm9tICdub2RlOmFzc2VydC9zdHJpY3QnXG5pbXBvcnQgeyBjcmVhdGVQcml2YXRlS2V5IH0gZnJvbSAnbm9kZTpjcnlwdG8nXG5pbXBvcnQgeyB0eXBlIEpzb25TYWZlIH0gZnJvbSAnLi4vY29udGV4dC5qcydcbmltcG9ydCB7IEVudmlyb25tZW50IH0gZnJvbSAnLi4vaHR0cC5qcydcbmltcG9ydCB7IGdldEVudmlyb25tZW50IH0gZnJvbSAnLi9jb250ZXh0LmpzJ1xuaW1wb3J0IHsgY3JlYXRlTW9ja0NvbnRleHQsIGpzb25Sb3VuZHRyaXAgfSBmcm9tICcuL3NldHVwLmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL2NvbnRleHQuanMnXG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0ge1xuICAgIGhlYWRlcnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH1cbiAgICBzdGF0dXM6IG51bWJlclxuICAgIC8vIFVzZWQgdG8gYXNzZXJ0IG9uIGluIHRlc3RzLCBzbyBubyBuZWVkIGZvciB0aGUgdHlwZSBzeXN0ZW0gdG8gZ2V0IGluIHRoZSB3YXlcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGJvZHk/OiBhbnlcbn1cblxudHlwZSBSZXF1ZXN0T3B0aW9ucyA9IEJvZHlsZXNzUmVxdWVzdE9wdGlvbnMgfCBTdHJpbmdSZXF1ZXN0T3B0aW9ucyB8IEpzb25SZXF1ZXN0T3B0aW9uc1xuXG50eXBlIEJvZHlsZXNzUmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgbWV0aG9kPzogTWV0aG9kXG4gICAgdXJpOiBzdHJpbmdcbiAgICBoZWFkZXJzPzogeyByZWFkb25seSBba2V5OiBzdHJpbmddOiBzdHJpbmcgfVxufVxuXG50eXBlIFN0cmluZ1JlcXVlc3RPcHRpb25zID0gQm9keWxlc3NSZXF1ZXN0T3B0aW9ucyAmIHtcbiAgICBib2R5OiBzdHJpbmdcbn1cblxudHlwZSBKc29uUmVxdWVzdE9wdGlvbnMgPSBCb2R5bGVzc1JlcXVlc3RPcHRpb25zICYge1xuICAgIGpzb246IEpzb25TYWZlXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXF1ZXN0KG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICAgIGlmIChvcHRpb25zLnVyaS5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG9wdGlvbnMudXJpLCBvcHRpb25zLnVyaS5zbGljZSgxKSwgJ1BhdGggY2Fubm90IHN0YXJ0IHdpdGggc2xhc2guJylcbiAgICB9XG4gICAgY29uc3QgaGFuZGxlcnMgPSBnZXRIYW5kbGVycygnaHR0cCcpLm1hcCh3aXRoUGF0aFJlZ0V4cClcbiAgICBjb25zdCBtYXRjaGluZ0hhbmRsZXJzID0gaGFuZGxlcnMuZmlsdGVyKFxuICAgICAgICBoID0+IGhbcGF0aFJlZ0V4cF0udGVzdChvcHRpb25zLnVyaSkgJiYgaC5tZXRob2QgPT09IChvcHRpb25zLm1ldGhvZCA/PyAnR0VUJyksXG4gICAgKVxuICAgIGNvbnN0IFtoYW5kbGVyXSA9IG1hdGNoaW5nSGFuZGxlcnNcbiAgICBjb25zdCB7IGxvZywgY29udGV4dCwgc3VjY2VzcywgZmx1c2ggfSA9IGNyZWF0ZU1vY2tDb250ZXh0KFxuICAgICAgICBjbGllbnRGcm9tSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpLFxuICAgICAgICBoYW5kbGVyPy5jb25maWcsXG4gICAgICAgIGhhbmRsZXI/Lm1ldGEsXG4gICAgKVxuICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICBsb2cuZXJyb3IoJ1JlcXVlc3QgRU5EJywgdW5kZWZpbmVkLCB7XG4gICAgICAgICAgICBoYW5kbGVyczogaGFuZGxlcnMubWFwKGggPT4gKHtcbiAgICAgICAgICAgICAgICBwYXRoUGF0dGVybjogaC5wYXRoUGF0dGVybixcbiAgICAgICAgICAgICAgICBwYXRoUmVnRXhwOiBoW3BhdGhSZWdFeHBdLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBoLm1ldGhvZCxcbiAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgICAgICAgc3RhdHVzOiA0MDQsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICBzdGF0dXM6IDQwNCxcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAobWF0Y2hpbmdIYW5kbGVycy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgbG9nLmVycm9yKCdNdWx0aXBsZSBtYXRjaGluZyBoYW5kbGVycy4nLCB1bmRlZmluZWQsIHtcbiAgICAgICAgICAgIG1hdGNoaW5nSGFuZGxlcnM6IG1hdGNoaW5nSGFuZGxlcnMubWFwKGggPT4gKHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6IGgubWV0aG9kLFxuICAgICAgICAgICAgICAgIHBhdHRlcm46IGgucGF0aFBhdHRlcm4sXG4gICAgICAgICAgICB9KSksXG4gICAgICAgIH0pXG4gICAgICAgIGxvZy5lcnJvcignUmVxdWVzdCBFTkQnLCB1bmRlZmluZWQsIHtcbiAgICAgICAgICAgIGhhbmRsZXJzOiBoYW5kbGVycy5tYXAoaCA9PiAoe1xuICAgICAgICAgICAgICAgIHBhdGhQYXR0ZXJuOiBoLnBhdGhQYXR0ZXJuLFxuICAgICAgICAgICAgICAgIHBhdGhSZWdFeHA6IGhbcGF0aFJlZ0V4cF0udG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IGgubWV0aG9kLFxuICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IDUwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7fSxcbiAgICAgICAgICAgIHN0YXR1czogNTAwLFxuICAgICAgICB9XG4gICAgfVxuICAgIGxvZy50cmFjZSgnRm91bmQgaGFuZGxlcicsIHVuZGVmaW5lZCwge1xuICAgICAgICBoYW5kbGVyOiB7XG4gICAgICAgICAgICBwYXRoUGF0dGVybjogaGFuZGxlci5wYXRoUGF0dGVybixcbiAgICAgICAgICAgIHBhdGhSZWdFeHA6IGhhbmRsZXJbcGF0aFJlZ0V4cF0udG9TdHJpbmcoKSxcbiAgICAgICAgICAgIG1ldGhvZDogaGFuZGxlci5tZXRob2QsXG4gICAgICAgIH0sXG4gICAgfSlcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZXhlY3V0ZVJlcXVlc3QoXG4gICAgICAgIGxvZyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgaGFuZGxlcixcbiAgICAgICAge1xuICAgICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICAgIC4uLignanNvbicgaW4gb3B0aW9ucyAmJiB7IGpzb246IGpzb25Sb3VuZHRyaXAob3B0aW9ucy5qc29uKSB9KSxcbiAgICAgICAgICAgIHVyaTogJ2h0dHA6Ly9sb2NhbGhvc3QvJyArIG9wdGlvbnMudXJpLFxuICAgICAgICB9LFxuICAgICAgICBzdWNjZXNzLFxuICAgIClcbiAgICBhd2FpdCBmbHVzaCgpXG5cbiAgICByZXR1cm4ge1xuICAgICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgYm9keTogaGVscGZ1bEJvZHkocmVzcG9uc2UuYm9keSksXG4gICAgfVxufVxuXG5mdW5jdGlvbiBoZWxwZnVsQm9keShib2R5OiBzdHJpbmcgfCBCdWZmZXIgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShib2R5LnRvU3RyaW5nKCd1dGYtOCcpKSBhcyBKU09OXG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGJvZHlcbiAgICAgICAgfVxuICAgIH1cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShib2R5KSBhcyBKU09OXG4gICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBib2R5XG4gICAgfVxufVxuXG5jb25zdCBwYXRoUmVnRXhwID0gU3ltYm9sKClcblxuZnVuY3Rpb24gd2l0aFBhdGhSZWdFeHA8VCBleHRlbmRzIHsgcGF0aFBhdHRlcm46IHN0cmluZzsgW3BhdGhSZWdFeHBdPzogUmVnRXhwIH0+KFxuICAgIGhhbmRsZXI6IFQsXG4pOiBUICYgeyBbcGF0aFJlZ0V4cF06IFJlZ0V4cCB9IHtcbiAgICBpZiAocGF0aFJlZ0V4cCBpbiBoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVyIGFzIFQgJiB7IFtwYXRoUmVnRXhwXTogUmVnRXhwIH1cbiAgICB9XG4gICAgaGFuZGxlcltwYXRoUmVnRXhwXSA9IHBhdGhUb1JlZ0V4cChoYW5kbGVyLnBhdGhQYXR0ZXJuKVxuICAgIHJldHVybiBoYW5kbGVyIGFzIFQgJiB7IFtwYXRoUmVnRXhwXTogUmVnRXhwIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhCZWFyZXIoXG4gICAgcGF5bG9hZDogb2JqZWN0LFxuICAgIHJlcXVlc3RPcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyxcbik6IFByb21pc2U8UmVxdWVzdE9wdGlvbnM+IHtcbiAgICBjb25zdCB0b2tlbiA9IGNyZWF0ZUJlYXJlclRva2VuKGdldEVudmlyb25tZW50KCksIHBheWxvYWQsIHtcbiAgICAgICAgaXNzdWVyOiAnaHR0cHM6Ly9yaWRkYW5jZS5leGFtcGxlLmNvbS9vYXV0aC8nLFxuICAgICAgICBhdWRpZW5jZTogJ2h0dHBzOi8vcmlkZGFuY2UuZXhhbXBsZS5jb20vJyxcbiAgICAgICAgZXhwaXJlc0luOiA2MCwgLy8gc2Vjb25kc1xuICAgIH0pXG4gICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVxdWVzdE9wdGlvbnMsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIC4uLnJlcXVlc3RPcHRpb25zLmhlYWRlcnMsXG4gICAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YXdhaXQgdG9rZW59YCxcbiAgICAgICAgfSxcbiAgICB9XG59XG5cbmV4cG9ydCB0eXBlIEJlYXJlclRva2VuT3B0aW9ucyA9IHtcbiAgICBpc3N1ZXI/OiBzdHJpbmdcbiAgICBhdWRpZW5jZT86IHN0cmluZyB8IHN0cmluZ1tdXG4gICAgc3ViamVjdD86IHN0cmluZ1xuICAgIGV4cGlyZXNJbjogbnVtYmVyXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVCZWFyZXJUb2tlbihcbiAgICBlbnY6IEVudmlyb25tZW50LFxuICAgIHBheWxvYWQ6IG9iamVjdCxcbiAgICBvcHRpb25zOiBCZWFyZXJUb2tlbk9wdGlvbnMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGtleSA9IGVudi5CRUFSRVJfUFJJVkFURV9LRVlcbiAgICBpZiAoIWtleSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnUGxlYXNlIHNldCB0aGUgQkVBUkVSX1BSSVZBVEVfS0VZIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIGJlIGFibGUgdG8gY3JlYXRlIGJlYXJlciB0b2tlbnMuJyxcbiAgICAgICAgKVxuICAgIH1cbiAgICBjb25zdCBjZXJ0aWZpY2F0ZSA9ICctLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS1cXG4nICsga2V5ICsgJ1xcbi0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0nXG4gICAgY29uc3Qgbm93ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMClcbiAgICByZXR1cm4gYXdhaXQgbmV3IFNpZ25KV1QocGF5bG9hZCBhcyBKV1RQYXlsb2FkKVxuICAgICAgICAuc2V0UHJvdGVjdGVkSGVhZGVyKHsgYWxnOiAnRVMzODQnLCB0eXA6ICdKV1QnIH0pXG4gICAgICAgIC5zZXRJc3N1ZWRBdChub3cpXG4gICAgICAgIC5zZXRJc3N1ZXIob3B0aW9ucy5pc3N1ZXIgPz8gJ2h0dHBzOi8vcmlkZGFuY2UuZXhhbXBsZS5jb20vb2F1dGgvJylcbiAgICAgICAgLnNldEF1ZGllbmNlKG9wdGlvbnMuYXVkaWVuY2UgPz8gJ2h0dHBzOi8vcmlkZGFuY2UuZXhhbXBsZS5jb20vJylcbiAgICAgICAgLnNldEV4cGlyYXRpb25UaW1lKG5vdyArIG9wdGlvbnMuZXhwaXJlc0luKVxuICAgICAgICAuc2lnbihjcmVhdGVQcml2YXRlS2V5KHsga2V5OiBjZXJ0aWZpY2F0ZSwgZm9ybWF0OiAncGVtJywgdHlwZTogJ3NlYzEnIH0pKVxufVxuIl19