UNPKG

noneasy

Version:

Biblioteca para encapsular Dynamoose e fornecer verificação automática de campos únicos.

112 lines (95 loc) 3.73 kB
const dynamoose = require("dynamoose"); class Manager { static #configured = false; static #models = {}; static configure(config) { if (Manager.#configured) return; if (!config || !config.region || !config.credentials?.accessKeyId || !config.credentials?.secretAccessKey) { throw new Error("Invalid AWS configuration."); } dynamoose.aws.ddb.set(new dynamoose.aws.ddb.DynamoDB(config)); Manager.#configured = true; } static #ensureConfigured() { if (!Manager.#configured) { throw new Error("Connection is not configured. Call Manager.configure() first."); } } static async describeTable(tableName) { Manager.#ensureConfigured(); const ddb = dynamoose.aws.ddb(); try { const tableInfo = await ddb.describeTable({ TableName: tableName }); return { table: tableInfo.Table, error: null }; } catch (error) { if (error.name === "ResourceNotFoundException") { return { table: null, error: "Table not found" }; } throw error; } } static define(modelName, schema, options = {}) { Manager.#ensureConfigured(); if (Manager.#models[modelName]) { return Manager.#models[modelName]; } const schemaInstance = new dynamoose.Schema(schema, options); const model = dynamoose.model(modelName, schemaInstance); const customMethods = { create: async (item) => { await Manager.#checkUniqueFields(model, schema, item); return model.create(item); }, save: async (item) => { await Manager.#checkUniqueFields(model, schema, item, item.id); return model.update(item); }, get: async (id) => { return model.get(id); }, update: async (id, updateData) => { if (!id) throw new Error("ID is required for updating."); const existingItem = await model.get(id); if (!existingItem) throw new Error("Item not found."); /** * @template T * @type {T & Partial<T>} */ const updatedItem = { ...existingItem.toJSON(), ...updateData, updatedAt: Date.now(), }; return model.update(updatedItem); }, delete: async (id) => { return model.delete(id); }, }; const modelAPI = new Proxy(model, { get(target, prop, receiver) { if (prop in customMethods) { return customMethods[prop]; } return Reflect.get(target, prop, receiver); }, }); Manager.#models[modelName] = modelAPI; return modelAPI; } static async #checkUniqueFields(model, schema, item, excludeId = null) { const uniqueFields = Object.keys(schema).filter(key => schema[key].unique); for (const field of uniqueFields) { const value = item[field]; if (value) { const existingItem = await model.scan({[field]: value}).exec(); if (existingItem.length > 0 && (!excludeId || existingItem[0].id !== excludeId)) { const error = new Error(`O valor '${value}' para o campo '${field}' já existe.`); error.code = 10001; throw error; } } } } } module.exports = {Manager};