@takeshape/vitest-docker-dynamodb
Version: 
Bootstrap vitest tests with docker-compose and dynamodb.
82 lines (81 loc) • 2.78 kB
JavaScript
import { setTimeout } from 'node:timers/promises';
import { DynamoDB } from '@aws-sdk/client-dynamodb';
import { marshall } from '@aws-sdk/util-dynamodb';
import { omit } from "./utils.js";
let connection;
export const dbConnection = (port) => {
    if (connection) {
        return connection;
    }
    connection = {
        dynamoDB: new DynamoDB({
            endpoint: `http://localhost:${port}`,
            region: 'local',
            maxAttempts: 0
        })
    };
    return connection;
};
const waitForTable = async (client, tableName) => {
    while (true) {
        const details = await client
            .describeTable({ TableName: tableName })
            .catch(() => undefined);
        if (details?.Table?.TableStatus === 'ACTIVE') {
            await setTimeout(10);
            break;
        }
        await setTimeout(10);
    }
};
/**
 * Poll the tables list to ensure that the given list of tables exists
 */
const waitForDeleted = async (client, tableName) => {
    while (true) {
        const details = await client
            .describeTable({ TableName: tableName })
            .catch((e) => e.name === 'ResourceInUseException');
        await setTimeout(100);
        if (!details) {
            break;
        }
    }
};
export const deleteTables = async (tableNames, port) => {
    const { dynamoDB } = dbConnection(port);
    await Promise.all(tableNames.map((table) => dynamoDB.deleteTable({ TableName: table }).catch(() => { })));
    await Promise.all(tableNames.map((table) => waitForDeleted(dynamoDB, table)));
};
export const listTables = async (port) => {
    const { dynamoDB } = dbConnection(port);
    const tables = await dynamoDB.listTables();
    return tables.TableNames ?? [];
};
export const createTables = async (tables, port) => {
    const { dynamoDB } = dbConnection(port);
    await Promise.all(tables.map((table) => dynamoDB.createTable(omit(table, 'data'))));
    await Promise.all(tables.map((table) => waitForTable(dynamoDB, table.TableName)));
    await Promise.all(tables.map((table) => table.data &&
        Promise.all(table.data.map((row) => dynamoDB
            .putItem({
            TableName: table.TableName,
            // biome-ignore lint/suspicious/noExplicitAny: fine here
            Item: marshall(row)
        })
            .catch((e) => {
            throw new Error(`Could not add ${JSON.stringify(row)} to "${table.TableName}": ${e.message}`);
        })))));
};
export const killConnection = () => {
    connection?.dynamoDB.destroy();
};
export const waitForConnection = async (port) => {
    const { dynamoDB } = dbConnection(port);
    while (true) {
        const tables = await dynamoDB.listTables().catch(() => undefined);
        if (tables) {
            break;
        }
    }
};