@riddance/aws-host
Version:
This is `@riddance/aws-host`, a TypeScript AWS Lambda host adapter for the Riddance serverless framework. It provides AWS-specific implementations for HTTP, event, timer, and context handling in Lambda functions by providing Lambda entry points that trans
89 lines • 15.4 kB
JavaScript
import { missing } from '@riddance/fetch';
import { handle } from '@riddance/host/event';
import { measure } from '@riddance/host/lib/event';
import { getHandlers } from '@riddance/host/registry';
import { brotliDecompress } from 'node:zlib';
import { createAwsContext } from './context.js';
export { setMeta } from '@riddance/host/registry';
export * from '@riddance/service/event';
async function asyncIndex(event, awsContext, callback) {
const [handler] = getHandlers('event');
if (!handler) {
throw new Error('No event handler registered.');
}
const { log, context, success, flush } = createAwsContext(awsContext, { default: 150 }, {}, clientFromAttributes(event.Records[0]?.Sns.MessageAttributes), handler.config, handler.meta, awsContext.invokedFunctionArn.split(':')[4]);
const events = await Promise.allSettled(event.Records.map(async (r) => ({
subject: r.Sns.Subject ?? missing('subject'),
timestamp: new Date(r.Sns.Timestamp),
messageId: r.Sns.MessageId,
event: await eventFromMessage(r.Sns.Message, r.Sns.MessageAttributes),
})));
const malformedEvents = events.filter(e => e.status === 'rejected');
for (const failed of malformedEvents) {
log.fatal('Error parsing event.', failed.reason);
}
const sent = await Promise.allSettled(events
.filter(e => e.status === 'fulfilled')
.map(e => handle(log, context, handler, e.value, success)));
const notSent = sent.filter(e => e.status === 'rejected');
for (const failed of notSent) {
log.fatal('Error sending event.', failed.reason);
}
if (malformedEvents.length !== 0 ||
notSent.length !== 0 ||
sent.some(e => e.status === 'fulfilled' && !e.value)) {
callback(new AggregateError([...malformedEvents, ...notSent], 'Error handling event.'));
await measure(log, 'flush', flush);
return;
}
try {
callback(undefined);
}
catch (e) {
log.fatal('Error sending result to Lambda.', e);
}
await measure(log.enrichReserved({ meta: handler.meta }), 'flush', flush);
}
function clientFromAttributes(attributes) {
if (!attributes) {
return {};
}
return {
clientId: attributes.clientId?.Value,
clientIp: attributes.clientIp?.Value,
clientPort: Number(attributes.clientPort?.Value) || undefined,
operationId: attributes.operationId?.Value,
userAgent: attributes.userAgent?.Value,
};
}
async function eventFromMessage(message, attributes) {
if (!message) {
return undefined;
}
const messageToParse = await getMessageToParse(message, attributes);
return JSON.parse(messageToParse);
}
async function getMessageToParse(message, attributes) {
const isCompressed = attributes?.['content-encoding']?.Value === 'br';
if (!isCompressed) {
return message;
}
const decompressed = await decompress(Buffer.from(message, 'base64'));
return decompressed.toString('utf8');
}
function decompress(data) {
return new Promise((resolve, reject) => {
brotliDecompress(data, (err, result) => {
if (err) {
reject(err);
return;
}
resolve(result);
});
});
}
export function awsHandler(event, context, callback) {
context.callbackWaitsForEmptyEventLoop = false;
asyncIndex(event, context, callback).catch((e) => setImmediate(callback, e));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJldmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFFekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQWEsTUFBTSwwQkFBMEIsQ0FBQTtBQUM3RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDckQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQzVDLE9BQU8sRUFBYyxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUUzRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDakQsY0FBYyx5QkFBeUIsQ0FBQTtBQXVDdkMsS0FBSyxVQUFVLFVBQVUsQ0FDckIsS0FBZSxFQUNmLFVBQXNCLEVBQ3RCLFFBQWtDO0lBRWxDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDdEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBQ25ELENBQUM7SUFDRCxNQUFNLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsZ0JBQWdCLENBQ3JELFVBQVUsRUFDVixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFDaEIsRUFBRSxFQUNGLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLGlCQUFpQixDQUFDLEVBQzdELE9BQU8sQ0FBQyxNQUFNLEVBQ2QsT0FBTyxDQUFDLElBQUksRUFDWixVQUFVLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENB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RyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ25DLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ04sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNYLE9BQU07WUFDVixDQUFDO1lBQ0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ25CLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FDdEIsS0FBZSxFQUNmLE9BQW1CLEVBQ25CLFFBQWtDO0lBRWxDLE9BQU8sQ0FBQyw4QkFBOEIsR0FBRyxLQUFLLENBQUE7SUFDOUMsVUFBVSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDekYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1pc3NpbmcgfSBmcm9tICdAcmlkZGFuY2UvZmV0Y2gnXG5pbXBvcnQgdHlwZSB7IENsaWVudEluZm8gfSBmcm9tICdAcmlkZGFuY2UvaG9zdC9jb250ZXh0J1xuaW1wb3J0IHsgaGFuZGxlIH0gZnJvbSAnQHJpZGRhbmNlL2hvc3QvZXZlbnQnXG5pbXBvcnQgeyBtZWFzdXJlLCB0eXBlIEpzb24gfSBmcm9tICdAcmlkZGFuY2UvaG9zdC9saWIvZXZlbnQnXG5pbXBvcnQgeyBnZXRIYW5kbGVycyB9IGZyb20gJ0ByaWRkYW5jZS9ob3N0L3JlZ2lzdHJ5J1xuaW1wb3J0IHsgYnJvdGxpRGVjb21wcmVzcyB9IGZyb20gJ25vZGU6emxpYidcbmltcG9ydCB7IEF3c0NvbnRleHQsIGNyZWF0ZUF3c0NvbnRleHQgfSBmcm9tICcuL2NvbnRleHQuanMnXG5cbmV4cG9ydCB7IHNldE1ldGEgfSBmcm9tICdAcmlkZGFuY2UvaG9zdC9yZWdpc3RyeSdcbmV4cG9ydCAqIGZyb20gJ0ByaWRkYW5jZS9zZXJ2aWNlL2V2ZW50J1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vRGVmaW5pdGVseVR5cGVkL0RlZmluaXRlbHlUeXBlZC9ibG9iL2I5NjlmODkwMDAwZmY5NTc0MGZkN2I4NzljZGYzYjczZTFlYTBmZTgvdHlwZXMvYXdzLWxhbWJkYS90cmlnZ2VyL3Nucy5kLnRzXG5cbnR5cGUgU05TTWVzc2FnZUF0dHJpYnV0ZSA9IHtcbiAgICBUeXBlOiBzdHJpbmdcbiAgICBWYWx1ZTogc3RyaW5nXG59XG5cbnR5cGUgU05TTWVzc2FnZUF0dHJpYnV0ZXMgPSB7XG4gICAgW25hbWU6IHN0cmluZ106IFNOU01lc3NhZ2VBdHRyaWJ1dGVcbn1cblxudHlwZSBTTlNNZXNzYWdlID0ge1xuICAgIFNpZ25hdHVyZVZlcnNpb246IHN0cmluZ1xuICAgIFRpbWVzdGFtcDogc3RyaW5nXG4gICAgU2lnbmF0dXJlOiBzdHJpbmdcbiAgICBTaWduaW5nQ2VydFVybDogc3RyaW5nXG4gICAgTWVzc2FnZUlkOiBzdHJpbmdcbiAgICBNZXNzYWdlOiBzdHJpbmdcbiAgICBNZXNzYWdlQXR0cmlidXRlczogU05TTWVzc2FnZUF0dHJpYnV0ZXNcbiAgICBUeXBlOiBzdHJpbmdcbiAgICBVbnN1YnNjcmliZVVybDogc3RyaW5nXG4gICAgVG9waWNBcm46IHN0cmluZ1xuICAgIFN1YmplY3Q/OiBzdHJpbmdcbiAgICBUb2tlbj86IHN0cmluZ1xufVxuXG50eXBlIFNOU0V2ZW50UmVjb3JkID0ge1xuICAgIEV2ZW50VmVyc2lvbjogc3RyaW5nXG4gICAgRXZlbnRTdWJzY3JpcHRpb25Bcm46IHN0cmluZ1xuICAgIEV2ZW50U291cmNlOiBzdHJpbmdcbiAgICBTbnM6IFNOU01lc3NhZ2Vcbn1cblxudHlwZSBTTlNFdmVudCA9IHtcbiAgICBSZWNvcmRzOiBTTlNFdmVudFJlY29yZFtdXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFzeW5jSW5kZXgoXG4gICAgZXZlbnQ6IFNOU0V2ZW50LFxuICAgIGF3c0NvbnRleHQ6IEF3c0NvbnRleHQsXG4gICAgY2FsbGJhY2s6IChlcnJvcjogdW5rbm93bikgPT4gdm9pZCxcbikge1xuICAgIGNvbnN0IFtoYW5kbGVyXSA9IGdldEhhbmRsZXJzKCdldmVudCcpXG4gICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gZXZlbnQgaGFuZGxlciByZWdpc3RlcmVkLicpXG4gICAgfVxuICAgIGNvbnN0IHsgbG9nLCBjb250ZXh0LCBzdWNjZXNzLCBmbHVzaCB9ID0gY3JlYXRlQXdzQ29udGV4dChcbiAgICAgICAgYXdzQ29udGV4dCxcbiAgICAgICAgeyBkZWZhdWx0OiAxNTAgfSxcbiAgICAgICAge30sXG4gICAgICAgIGNsaWVudEZyb21BdHRyaWJ1dGVzKGV2ZW50LlJlY29yZHNbMF0/LlNucy5NZXNzYWdlQXR0cmlidXRlcyksXG4gICAgICAgIGhhbmRsZXIuY29uZmlnLFxuICAgICAgICBoYW5kbGVyLm1ldGEsXG4gICAgICAgIGF3c0NvbnRleHQuaW52b2tlZEZ1bmN0aW9uQXJuLnNwbGl0KCc6JylbNF0sXG4gICAgKVxuXG4gICAgY29uc3QgZXZlbnRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgICBldmVudC5SZWNvcmRzLm1hcChhc3luYyByID0+ICh7XG4gICAgICAgICAgICBzdWJqZWN0OiByLlNucy5TdWJqZWN0ID8/IG1pc3NpbmcoJ3N1YmplY3QnKSxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoci5TbnMuVGltZXN0YW1wKSxcbiAgICAgICAgICAgIG1lc3NhZ2VJZDogci5TbnMuTWVzc2FnZUlkLFxuICAgICAgICAgICAgZXZlbnQ6IGF3YWl0IGV2ZW50RnJvbU1lc3NhZ2Uoci5TbnMuTWVzc2FnZSwgci5TbnMuTWVzc2FnZUF0dHJpYnV0ZXMpLFxuICAgICAgICB9KSksXG4gICAgKVxuICAgIGNvbnN0IG1hbGZvcm1lZEV2ZW50cyA9IGV2ZW50cy5maWx0ZXIoZSA9PiBlLnN0YXR1cyA9PT0gJ3JlamVjdGVkJylcbiAgICBmb3IgKGNvbnN0IGZhaWxlZCBvZiBtYWxmb3JtZWRFdmVudHMpIHtcbiAgICAgICAgbG9nLmZhdGFsKCdFcnJvciBwYXJzaW5nIGV2ZW50LicsIGZhaWxlZC5yZWFzb24pXG4gICAgfVxuXG4gICAgY29uc3Qgc2VudCA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgICAgZXZlbnRzXG4gICAgICAgICAgICAuZmlsdGVyKGUgPT4gZS5zdGF0dXMgPT09ICdmdWxmaWxsZWQnKVxuICAgICAgICAgICAgLm1hcChlID0+IGhhbmRsZShsb2csIGNvbnRleHQsIGhhbmRsZXIsIGUudmFsdWUsIHN1Y2Nlc3MpKSxcbiAgICApXG4gICAgY29uc3Qgbm90U2VudCA9IHNlbnQuZmlsdGVyKGUgPT4gZS5zdGF0dXMgPT09ICdyZWplY3RlZCcpXG4gICAgZm9yIChjb25zdCBmYWlsZWQgb2Ygbm90U2VudCkge1xuICAgICAgICBsb2cuZmF0YWwoJ0Vycm9yIHNlbmRpbmcgZXZlbnQuJywgZmFpbGVkLnJlYXNvbilcbiAgICB9XG4gICAgaWYgKFxuICAgICAgICBtYWxmb3JtZWRFdmVudHMubGVuZ3RoICE9PSAwIHx8XG4gICAgICAgIG5vdFNlbnQubGVuZ3RoICE9PSAwIHx8XG4gICAgICAgIHNlbnQuc29tZShlID0+IGUuc3RhdHVzID09PSAnZnVsZmlsbGVkJyAmJiAhZS52YWx1ZSlcbiAgICApIHtcbiAgICAgICAgY2FsbGJhY2sobmV3IEFnZ3JlZ2F0ZUVycm9yKFsuLi5tYWxmb3JtZWRFdmVudHMsIC4uLm5vdFNlbnRdLCAnRXJyb3IgaGFuZGxpbmcgZXZlbnQuJykpXG4gICAgICAgIGF3YWl0IG1lYXN1cmUobG9nLCAnZmx1c2gnLCBmbHVzaClcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY2FsbGJhY2sodW5kZWZpbmVkKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nLmZhdGFsKCdFcnJvciBzZW5kaW5nIHJlc3VsdCB0byBMYW1iZGEuJywgZSlcbiAgICB9XG5cbiAgICBhd2FpdCBtZWFzdXJlKGxvZy5lbnJpY2hSZXNlcnZlZCh7IG1ldGE6IGhhbmRsZXIubWV0YSB9KSwgJ2ZsdXNoJywgZmx1c2gpXG59XG5cbmZ1bmN0aW9uIGNsaWVudEZyb21BdHRyaWJ1dGVzKGF0dHJpYnV0ZXM6IFNOU01lc3NhZ2VBdHRyaWJ1dGVzIHwgdW5kZWZpbmVkKTogQ2xpZW50SW5mbyB7XG4gICAgaWYgKCFhdHRyaWJ1dGVzKSB7XG4gICAgICAgIHJldHVybiB7fVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBjbGllbnRJZDogYXR0cmlidXRlcy5jbGllbnRJZD8uVmFsdWUsXG4gICAgICAgIGNsaWVudElwOiBhdHRyaWJ1dGVzLmNsaWVudElwPy5WYWx1ZSxcbiAgICAgICAgY2xpZW50UG9ydDogTnVtYmVyKGF0dHJpYnV0ZXMuY2xpZW50UG9ydD8uVmFsdWUpIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgb3BlcmF0aW9uSWQ6IGF0dHJpYnV0ZXMub3BlcmF0aW9uSWQ/LlZhbHVlLFxuICAgICAgICB1c2VyQWdlbnQ6IGF0dHJpYnV0ZXMudXNlckFnZW50Py5WYWx1ZSxcbiAgICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV2ZW50RnJvbU1lc3NhZ2UobWVzc2FnZTogc3RyaW5nLCBhdHRyaWJ1dGVzPzogU05TTWVzc2FnZUF0dHJpYnV0ZXMpIHtcbiAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2VUb1BhcnNlID0gYXdhaXQgZ2V0TWVzc2FnZVRvUGFyc2UobWVzc2FnZSwgYXR0cmlidXRlcylcbiAgICByZXR1cm4gSlNPTi5wYXJzZShtZXNzYWdlVG9QYXJzZSkgYXMge1xuICAgICAgICByZWFkb25seSBba2V5OiBzdHJpbmddOiBKc29uXG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRNZXNzYWdlVG9QYXJzZShtZXNzYWdlOiBzdHJpbmcsIGF0dHJpYnV0ZXM/OiBTTlNNZXNzYWdlQXR0cmlidXRlcykge1xuICAgIGNvbnN0IGlzQ29tcHJlc3NlZCA9IGF0dHJpYnV0ZXM/LlsnY29udGVudC1lbmNvZGluZyddPy5WYWx1ZSA9PT0gJ2JyJ1xuICAgIGlmICghaXNDb21wcmVzc2VkKSB7XG4gICAgICAgIHJldHVybiBtZXNzYWdlXG4gICAgfVxuICAgIGNvbnN0IGRlY29tcHJlc3NlZCA9IGF3YWl0IGRlY29tcHJlc3MoQnVmZmVyLmZyb20obWVzc2FnZSwgJ2Jhc2U2NCcpKVxuICAgIHJldHVybiBkZWNvbXByZXNzZWQudG9TdHJpbmcoJ3V0ZjgnKVxufVxuXG5mdW5jdGlvbiBkZWNvbXByZXNzKGRhdGE6IEJ1ZmZlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxCdWZmZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgYnJvdGxpRGVjb21wcmVzcyhkYXRhLCAoZXJyLCByZXN1bHQpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpXG4gICAgICAgIH0pXG4gICAgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF3c0hhbmRsZXIoXG4gICAgZXZlbnQ6IFNOU0V2ZW50LFxuICAgIGNvbnRleHQ6IEF3c0NvbnRleHQsXG4gICAgY2FsbGJhY2s6IChlcnJvcjogdW5rbm93bikgPT4gdm9pZCxcbikge1xuICAgIGNvbnRleHQuY2FsbGJhY2tXYWl0c0ZvckVtcHR5RXZlbnRMb29wID0gZmFsc2VcbiAgICBhc3luY0luZGV4KGV2ZW50LCBjb250ZXh0LCBjYWxsYmFjaykuY2F0Y2goKGU6IHVua25vd24pID0+IHNldEltbWVkaWF0ZShjYWxsYmFjaywgZSkpXG59XG4iXX0=