import { compose, map, pick } from "ramda"; import { buildKeyConditionExpression, buildSetUpdateExpression, createEnhancedClient } from "./utils"; const { client, batchWrite } = createEnhancedClient(); const requestsTable = process.env.REQUESTS_TABLE_NAME; function normalizeData({ questionId, requester, chainId, ...rest }) { return { requestId: `${chainId}/${questionId}/${requester}`, chainId, ...rest, }; } function denormalizeData({ requestId, ...rest }) { const [chainId, questionId, requester] = requestId.split("/"); return { questionId, requester, chainId, ...rest }; } const extractStoredData = pick(["requestId", "chainId", "status", "arbitratorAnswer", "latestAnswer"]); export async function saveRequests(requests) { const createPutRequest = (item) => ({ PutRequest: { Item: item, }, }); const createBatchItem = compose(createPutRequest, extractStoredData, normalizeData); return compose(batchWrite(requestsTable), map(createBatchItem))(requests); } export async function fetchAllRequestIds() { const data = await client .scan({ TableName: requestsTable, ProjectionExpression: "requestId, chainId", }) .promise(); return map(denormalizeData, data.Items); } export async function deleteAllRequests() { const createDeleteRequest = (item) => ({ DeleteRequest: { Key: item, }, }); const data = await fetchAllRequestIds(); if (data.length === 0) { return; } return compose( batchWrite(requestsTable), map(compose(createDeleteRequest, pick(["requestId", "chainId"], normalizeData))) )(data); } export async function fetchRequestsByChainIdAndStatus({ chainId, status }) { const data = await client .query({ TableName: requestsTable, IndexName: "byChainIdAndStatus", ...buildKeyConditionExpression({ chainId, status }), }) .promise(); return map(denormalizeData, data.Items); } export async function fetchRequestsByChainId({ chainId }) { const data = await client .query({ TableName: requestsTable, IndexName: "byChainIdAndStatus", ...buildKeyConditionExpression({ chainId }), }) .promise(); return map(denormalizeData, data.Items); } export async function updateRequest(data) { const { requestId, chainId, ...attrs } = normalizeData(data); const result = await client .update({ TableName: requestsTable, Key: { requestId, chainId, }, ReturnValues: "ALL_NEW", ...buildSetUpdateExpression(extractStoredData(attrs)), }) .promise(); return denormalizeData(result.Attributes); } export async function removeRequest(data) { const { requestId, chainId } = normalizeData(data); const result = await client .delete({ TableName: requestsTable, Key: { requestId, chainId, }, ReturnValues: "ALL_OLD", }) .promise(); return denormalizeData(result.Attributes); }