UNPKG

@webiny/api-tenancy-so-ddb

Version:
286 lines (280 loc) 7.48 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.createStorageOperations = void 0; var _dbDynamodb = require("@webiny/db-dynamodb"); var _query = require("@webiny/db-dynamodb/utils/query"); var _error = _interopRequireDefault(require("@webiny/error")); var _table = require("./definitions/table"); var _tenantEntity = require("./definitions/tenantEntity"); var _systemEntity = require("./definitions/systemEntity"); var _domainEntity = require("./definitions/domainEntity"); var _types = require("./types"); const setTenantDefaults = item => { if (!item.tags) { item.tags = []; } if (!item.description) { item.description = ""; } return item; }; const createStorageOperations = params => { const { table, documentClient } = params; const tableInstance = (0, _table.createTable)({ table, documentClient }); const entities = { tenants: (0, _tenantEntity.createTenantEntity)({ entityName: _types.ENTITIES.TENANT, table: tableInstance }), domains: (0, _domainEntity.createDomainEntity)({ entityName: _types.ENTITIES.DOMAIN, table: tableInstance }), system: (0, _systemEntity.createSystemEntity)({ entityName: _types.ENTITIES.SYSTEM, table: tableInstance }) }; const systemKeys = { PK: "T#root#SYSTEM", SK: "TENANCY" }; const createNewDomainsRecords = (tenant, existingDomains = []) => { return tenant.settings.domains.map(({ fqdn }) => { // If domain is already in the DB, skip it. if (existingDomains.find(d => d.fqdn === fqdn)) { return null; } // Add a new domain. return { PK: `DOMAIN#${fqdn}`, SK: `A`, GSI1_PK: `DOMAINS`, GSI1_SK: `T#${tenant.id}#${fqdn}`, tenant: tenant.id, fqdn, webinyVersion: tenant.webinyVersion }; }).filter(Boolean); }; return { getTable() { return tableInstance; }, getEntities() { return entities; }, async createSystemData(data) { try { await (0, _dbDynamodb.put)({ entity: entities.system, item: { ...data, ...systemKeys } }); return data; } catch (err) { throw _error.default.from(err, { message: "Could not create system record.", code: "CREATE_SYSTEM_ERROR", data: { keys: systemKeys, data } }); } }, async getSystemData() { try { return await (0, _dbDynamodb.getClean)({ entity: entities.system, keys: systemKeys }); } catch (err) { throw _error.default.from(err, { message: "Could not load system record.", code: "GET_SYSTEM_ERROR", data: { keys: systemKeys } }); } }, async updateSystemData(data) { try { await (0, _dbDynamodb.put)({ entity: entities.system, item: { ...data, ...systemKeys } }); return data; } catch (err) { throw _error.default.from(err, { message: "Could not update system record.", code: "UPDATE_SYSTEM_ERROR", data: { keys: systemKeys, data } }); } }, async getTenantsByIds(ids) { const items = ids.map(id => entities.tenants.getBatch({ PK: `T#${id}`, SK: "A" })); const tenants = await (0, _dbDynamodb.batchReadAll)({ table: tableInstance, items }); return tenants.map(item => item.data).map(item => setTenantDefaults(item)); }, async listTenants(params = {}) { const { parent } = params; const options = { index: "GSI1" }; if (parent) { options.beginsWith = `T#${parent}#`; } else { options.gt = " "; } const tenants = await (0, _query.queryAll)({ entity: entities.tenants, partitionKey: `TENANTS`, options }); return tenants.map(item => item.data).map(item => setTenantDefaults(item)); }, async createTenant(data) { const keys = { PK: `T#${data.id}`, SK: "A", GSI1_PK: "TENANTS", GSI1_SK: `T#${data.parent}#${data.createdOn}` }; try { const tableWrite = (0, _dbDynamodb.createTableWriteBatch)({ table: tableInstance }); tableWrite.put(entities.tenants, { TYPE: "tenancy.tenant", ...keys, data }); const newDomains = createNewDomainsRecords(data); for (const domain of newDomains) { tableWrite.put(entities.domains, domain); } await tableWrite.execute(); return data; } catch (err) { throw _error.default.from(err, { message: "Could not create tenant record.", code: "CREATE_TENANT_ERROR", data: { keys, data } }); } }, async updateTenant(data) { const tenantPK = `T#${data.id}`; const keys = { PK: tenantPK, SK: "A", GSI1_PK: "TENANTS", GSI1_SK: `T#${data.parent}#${data.createdOn}` }; const existingDomains = await (0, _query.queryAll)({ entity: entities.domains, partitionKey: "DOMAINS", options: { index: "GSI1", beginsWith: `T#${data.id}` } }); const newDomains = createNewDomainsRecords(data, existingDomains); const tableWrite = (0, _dbDynamodb.createTableWriteBatch)({ table: tableInstance }); tableWrite.put(entities.tenants, { ...keys, data }); // Delete domains that are in the DB but are NOT in the settings. for (const { fqdn } of existingDomains) { if (data.settings.domains.some(d => d.fqdn === fqdn)) { continue; } tableWrite.delete(entities.domains, { PK: `DOMAIN#${fqdn}`, SK: `A` }); } for (const domain of newDomains) { tableWrite.put(entities.domains, domain); } try { await tableWrite.execute(); return data; } catch (err) { throw _error.default.from(err, { message: "Could not update tenant record.", code: "CREATE_TENANT_ERROR", data: { keys, data } }); } }, async deleteTenant(id) { const existingDomains = await (0, _query.queryAll)({ entity: entities.domains, partitionKey: "DOMAINS", options: { index: "GSI1", beginsWith: `T#${id}` } }); const batchWrite = (0, _dbDynamodb.createEntityWriteBatch)({ entity: entities.tenants, delete: [{ PK: `T#${id}`, SK: "A" }] }); for (const domain of existingDomains) { batchWrite.delete({ PK: domain.PK, SK: domain.SK }); } // Delete tenant and domain items await batchWrite.execute(); } }; }; exports.createStorageOperations = createStorageOperations; //# sourceMappingURL=index.js.map