Checks for dependencies during deletion.
This commit is contained in:
parent
0a08088893
commit
efbfa2b366
20 changed files with 246 additions and 121 deletions
|
@ -105,8 +105,15 @@ export class DeleteModalDialog extends Component {
|
||||||
const t = props.t;
|
const t = props.t;
|
||||||
|
|
||||||
this.entityTypeLabels = {
|
this.entityTypeLabels = {
|
||||||
|
'namespace': t('Namespace'),
|
||||||
|
'list': t('List'),
|
||||||
|
'customForm': t('Custom forms'),
|
||||||
'campaign': t('Campaign'),
|
'campaign': t('Campaign'),
|
||||||
'template': t('Template')
|
'template': t('Template'),
|
||||||
|
'sendConfiguration': t('Send configuration'),
|
||||||
|
'report': t('Report'),
|
||||||
|
'reportTemplate': t('Report template'),
|
||||||
|
'mosaicoTemplate': t('Mosaico template')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,8 +148,12 @@ export class DeleteModalDialog extends Component {
|
||||||
<p>{t('Cannote delete "{{name}}" due to the following dependencies:', {name, nsSeparator: '|'})}</p>
|
<p>{t('Cannote delete "{{name}}" due to the following dependencies:', {name, nsSeparator: '|'})}</p>
|
||||||
<ul className={styles.dependenciesList}>
|
<ul className={styles.dependenciesList}>
|
||||||
{err.data.dependencies.map(dep =>
|
{err.data.dependencies.map(dep =>
|
||||||
<li key={dep.link}><Link to={dep.link}>{this.entityTypeLabels[dep.entityTypeId]}: {dep.name}</Link></li>
|
dep.link ?
|
||||||
|
<li key={dep.link}><Link to={dep.link}>{this.entityTypeLabels[dep.entityTypeId]}: {dep.name}</Link></li>
|
||||||
|
: // if no dep.link is present, it means the user has no permission to view the entity, thus only id without the link is shown
|
||||||
|
<li key={dep.id}>{this.entityTypeLabels[dep.entityTypeId]}: [{dep.id}]</li>
|
||||||
)}
|
)}
|
||||||
|
{err.data.andMore && <li>{t('... and more')}</li>}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
.mt-treetable-container.mt-treetable-inactivable>table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td span.fancytree-title,
|
.mt-treetable-container.mt-treetable-inactivable>table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td span.fancytree-title,
|
||||||
.mt-treetable-container.mt-treetable-inactivable>table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td span.fancytree-expander,
|
.mt-treetable-container.mt-treetable-inactivable>table.fancytree-ext-table.fancytree-container>tbody>tr.fancytree-active>td span.fancytree-expander,
|
||||||
.mt-treetable-container.mt-treetable-inactivable .fancytree-container span.fancytree-node.fancytree-active span.fancytree-title {
|
.mt-treetable-container.mt-treetable-inactivable .fancytree-container span.fancytree-node.fancytree-active span.fancytree-title,
|
||||||
|
.mt-treetable-container.mt-treetable-inactivable .fancytree-container>tbody>tr.fancytree-active>td {
|
||||||
outline: 0px none;
|
outline: 0px none;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ class TreeTable extends Component {
|
||||||
const data = [];
|
const data = [];
|
||||||
for (const unsafeEntry of unsafeData) {
|
for (const unsafeEntry of unsafeData) {
|
||||||
const entry = Object.assign({}, unsafeEntry);
|
const entry = Object.assign({}, unsafeEntry);
|
||||||
|
entry.unsanitizedTitle = entry.title;
|
||||||
entry.title = ReactDOMServer.renderToStaticMarkup(<div>{entry.title}</div>);
|
entry.title = ReactDOMServer.renderToStaticMarkup(<div>{entry.title}</div>);
|
||||||
entry.description = ReactDOMServer.renderToStaticMarkup(<div>{entry.description}</div>);
|
entry.description = ReactDOMServer.renderToStaticMarkup(<div>{entry.description}</div>);
|
||||||
if (entry.children) {
|
if (entry.children) {
|
||||||
|
@ -137,15 +138,32 @@ class TreeTable extends Component {
|
||||||
const linksContainer = jQuery(`<span class="${styles.actionLinks}"/>`);
|
const linksContainer = jQuery(`<span class="${styles.actionLinks}"/>`);
|
||||||
|
|
||||||
const actions = this.props.actions(node);
|
const actions = this.props.actions(node);
|
||||||
for (const {label, link} of actions) {
|
|
||||||
const lnkHtml = ReactDOMServer.renderToStaticMarkup(<a href={link}>{label}</a>);
|
for (const action of actions) {
|
||||||
const lnk = jQuery(lnkHtml);
|
if (action.action) {
|
||||||
lnk.click((evt) => {
|
const html = ReactDOMServer.renderToStaticMarkup(<a href="">{action.label}</a>);
|
||||||
evt.preventDefault();
|
const elem = jQuery(html);
|
||||||
this.navigateTo(link)
|
elem.click((evt) => { evt.preventDefault(); action.action(this) });
|
||||||
});
|
linksContainer.append(elem);
|
||||||
linksContainer.append(lnk);
|
|
||||||
|
} else if (action.link) {
|
||||||
|
const html = ReactDOMServer.renderToStaticMarkup(<a href={action.link}>{action.label}</a>);
|
||||||
|
const elem = jQuery(html);
|
||||||
|
elem.click((evt) => { evt.preventDefault(); this.navigateTo(action.link) });
|
||||||
|
linksContainer.append(elem);
|
||||||
|
|
||||||
|
} else if (action.href) {
|
||||||
|
const html = ReactDOMServer.renderToStaticMarkup(<a href={action.href}>{action.label}</a>);
|
||||||
|
const elem = jQuery(html);
|
||||||
|
linksContainer.append(elem);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const html = ReactDOMServer.renderToStaticMarkup(<span>{action.label}</span>);
|
||||||
|
const elem = jQuery(html);
|
||||||
|
linksContainer.append(elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tdList.eq(tdIdx).html(linksContainer);
|
tdList.eq(tdIdx).html(linksContainer);
|
||||||
tdIdx += 1;
|
tdIdx += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ export default class CUD extends Component {
|
||||||
this.state = {};
|
this.state = {};
|
||||||
|
|
||||||
this.initForm();
|
this.initForm();
|
||||||
this.hasChildren = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -42,10 +41,6 @@ export default class CUD extends Component {
|
||||||
const entry = data[idx];
|
const entry = data[idx];
|
||||||
|
|
||||||
if (entry.key === this.props.entity.id) {
|
if (entry.key === this.props.entity.id) {
|
||||||
if (entry.children.length > 0) {
|
|
||||||
this.hasChildren = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.splice(idx, 1);
|
data.splice(idx, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -158,25 +153,10 @@ export default class CUD extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onDeleteError(error) {
|
|
||||||
if (error instanceof interoperableErrors.ChildDetectedError) {
|
|
||||||
this.disableForm();
|
|
||||||
this.setFormStatusMessage('danger',
|
|
||||||
<span>
|
|
||||||
<strong>{t('The namespace cannot be deleted.')}</strong>{' '}
|
|
||||||
{t('There has been a child namespace found. This is most likely because someone else has changed the parent of some namespace in the meantime. Refresh your page to start anew with fresh data.')}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const t = this.props.t;
|
const t = this.props.t;
|
||||||
const isEdit = !!this.props.entity;
|
const isEdit = !!this.props.entity;
|
||||||
const canDelete = isEdit && !this.isEditGlobal() && !this.hasChildren && this.props.entity.permissions.includes('delete');
|
const canDelete = isEdit && !this.isEditGlobal() && this.props.entity.permissions.includes('delete');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -188,8 +168,7 @@ export default class CUD extends Component {
|
||||||
backUrl={`/namespaces/${this.props.entity.id}/edit`}
|
backUrl={`/namespaces/${this.props.entity.id}/edit`}
|
||||||
successUrl="/namespaces"
|
successUrl="/namespaces"
|
||||||
deletingMsg={t('Deleting namespace ...')}
|
deletingMsg={t('Deleting namespace ...')}
|
||||||
deletedMsg={t('Namespace deleted')}
|
deletedMsg={t('Namespace deleted')} />
|
||||||
onErrorAsync={::this.onDeleteError}/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<Title>{isEdit ? t('Edit Namespace') : t('Create Namespace')}</Title>
|
<Title>{isEdit ? t('Edit Namespace') : t('Create Namespace')}</Title>
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
tableDeleteDialogInit,
|
tableDeleteDialogInit,
|
||||||
tableDeleteDialogRender
|
tableDeleteDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
||||||
|
|
||||||
@translate()
|
@translate()
|
||||||
@withErrorHandling
|
@withErrorHandling
|
||||||
|
@ -50,7 +51,6 @@ export default class List extends Component {
|
||||||
|
|
||||||
const actions = node => {
|
const actions = node => {
|
||||||
const actions = [];
|
const actions = [];
|
||||||
console.log(node);
|
|
||||||
|
|
||||||
if (node.data.permissions.includes('edit')) {
|
if (node.data.permissions.includes('edit')) {
|
||||||
actions.push({
|
actions.push({
|
||||||
|
@ -66,7 +66,9 @@ export default class List extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
tableDeleteDialogAddDeleteButton(actions, this, node.data.permissions, node.key, node.key);
|
if (Number.parseInt(node.key) !== getGlobalNamespaceId()) {
|
||||||
|
tableDeleteDialogAddDeleteButton(actions, this, node.data.permissions, node.key, node.data.unsanitizedTitle);
|
||||||
|
}
|
||||||
|
|
||||||
return actions;
|
return actions;
|
||||||
};
|
};
|
||||||
|
|
58
lib/dependency-helpers.js
Normal file
58
lib/dependency-helpers.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const knex = require('./knex');
|
||||||
|
const interoperableErrors = require('../shared/interoperable-errors');
|
||||||
|
const entitySettings = require('./entity-settings');
|
||||||
|
const shares = require('../models/shares');
|
||||||
|
const { enforce } = require('./helpers');
|
||||||
|
|
||||||
|
const defaultNoOfDependenciesReported = 20;
|
||||||
|
|
||||||
|
async function ensureNoDependencies(tx, context, id, depSpecs) {
|
||||||
|
|
||||||
|
const deps = [];
|
||||||
|
let andMore = false;
|
||||||
|
|
||||||
|
for (const depSpec of depSpecs) {
|
||||||
|
const entityType = entitySettings.getEntityType(depSpec.entityTypeId);
|
||||||
|
|
||||||
|
let rows;
|
||||||
|
|
||||||
|
if (depSpec.query) {
|
||||||
|
rows = await depSpec.query(tx).limit(defaultNoOfDependenciesReported + 1);
|
||||||
|
} else if (depSpec.column) {
|
||||||
|
rows = await tx(entityType.entitiesTable).where(depSpec.column, id).select(['id', 'name']).limit(defaultNoOfDependenciesReported + 1);
|
||||||
|
} else if (depSpec.rows) {
|
||||||
|
rows = await depSpec.rows(tx, defaultNoOfDependenciesReported + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const row of rows) {
|
||||||
|
if (deps.length === defaultNoOfDependenciesReported) {
|
||||||
|
andMore = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await shares.checkEntityPermissionTx(tx, context, depSpec.entityTypeId, row.id, 'view')) {
|
||||||
|
deps.push({
|
||||||
|
entityTypeId: depSpec.entityTypeId,
|
||||||
|
name: row.name,
|
||||||
|
link: entityType.clientLink(row.id)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
deps.push({
|
||||||
|
entityTypeId: depSpec.entityTypeId,
|
||||||
|
id: row.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deps.length > 0) {
|
||||||
|
throw new interoperableErrors.DependencyPresentError('', {
|
||||||
|
dependencies: deps,
|
||||||
|
andMore
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.ensureNoDependencies = ensureNoDependencies
|
|
@ -10,17 +10,20 @@ const entityTypes = {
|
||||||
namespace: {
|
namespace: {
|
||||||
entitiesTable: 'namespaces',
|
entitiesTable: 'namespaces',
|
||||||
sharesTable: 'shares_namespace',
|
sharesTable: 'shares_namespace',
|
||||||
permissionsTable: 'permissions_namespace'
|
permissionsTable: 'permissions_namespace',
|
||||||
|
clientLink: id => `/namespaces/${id}`
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
entitiesTable: 'lists',
|
entitiesTable: 'lists',
|
||||||
sharesTable: 'shares_list',
|
sharesTable: 'shares_list',
|
||||||
permissionsTable: 'permissions_list'
|
permissionsTable: 'permissions_list',
|
||||||
|
clientLink: id => `/lists/${id}`
|
||||||
},
|
},
|
||||||
customForm: {
|
customForm: {
|
||||||
entitiesTable: 'custom_forms',
|
entitiesTable: 'custom_forms',
|
||||||
sharesTable: 'shares_custom_form',
|
sharesTable: 'shares_custom_form',
|
||||||
permissionsTable: 'permissions_custom_form'
|
permissionsTable: 'permissions_custom_form',
|
||||||
|
clientLink: id => `/lists/forms/${id}`
|
||||||
},
|
},
|
||||||
campaign: {
|
campaign: {
|
||||||
entitiesTable: 'campaigns',
|
entitiesTable: 'campaigns',
|
||||||
|
@ -43,7 +46,8 @@ const entityTypes = {
|
||||||
},
|
},
|
||||||
defaultReplacementBehavior: ReplacementBehavior.NONE
|
defaultReplacementBehavior: ReplacementBehavior.NONE
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
clientLink: id => `/campaigns/${id}`
|
||||||
},
|
},
|
||||||
template: {
|
template: {
|
||||||
entitiesTable: 'templates',
|
entitiesTable: 'templates',
|
||||||
|
@ -58,22 +62,26 @@ const entityTypes = {
|
||||||
},
|
},
|
||||||
defaultReplacementBehavior: ReplacementBehavior.REPLACE
|
defaultReplacementBehavior: ReplacementBehavior.REPLACE
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
clientLink: id => `/templates/${id}`
|
||||||
},
|
},
|
||||||
sendConfiguration: {
|
sendConfiguration: {
|
||||||
entitiesTable: 'send_configurations',
|
entitiesTable: 'send_configurations',
|
||||||
sharesTable: 'shares_send_configuration',
|
sharesTable: 'shares_send_configuration',
|
||||||
permissionsTable: 'permissions_send_configuration'
|
permissionsTable: 'permissions_send_configuration',
|
||||||
|
clientLink: id => `/send-configurations/${id}`
|
||||||
},
|
},
|
||||||
report: {
|
report: {
|
||||||
entitiesTable: 'reports',
|
entitiesTable: 'reports',
|
||||||
sharesTable: 'shares_report',
|
sharesTable: 'shares_report',
|
||||||
permissionsTable: 'permissions_report'
|
permissionsTable: 'permissions_report',
|
||||||
|
clientLink: id => `/reports/${id}`
|
||||||
},
|
},
|
||||||
reportTemplate: {
|
reportTemplate: {
|
||||||
entitiesTable: 'report_templates',
|
entitiesTable: 'report_templates',
|
||||||
sharesTable: 'shares_report_template',
|
sharesTable: 'shares_report_template',
|
||||||
permissionsTable: 'permissions_report_template'
|
permissionsTable: 'permissions_report_template',
|
||||||
|
clientLink: id => `/reports/templates/${id}`
|
||||||
},
|
},
|
||||||
mosaicoTemplate: {
|
mosaicoTemplate: {
|
||||||
entitiesTable: 'mosaico_templates',
|
entitiesTable: 'mosaico_templates',
|
||||||
|
@ -96,14 +104,31 @@ const entityTypes = {
|
||||||
},
|
},
|
||||||
defaultReplacementBehavior: ReplacementBehavior.REPLACE
|
defaultReplacementBehavior: ReplacementBehavior.REPLACE
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
clientLink: id => `/templates/mosaico/${id}`
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
entitiesTable: 'users',
|
||||||
|
clientLink: id => `/users/${id}`
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const entityTypesWithPermissions = {};
|
||||||
|
for (const key in entityTypes) {
|
||||||
|
if (entityTypes[key].permissionsTable) {
|
||||||
|
entityTypesWithPermissions[key] = entityTypes[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function getEntityTypes() {
|
function getEntityTypes() {
|
||||||
return entityTypes;
|
return entityTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEntityTypesWithPermissions() {
|
||||||
|
return entityTypesWithPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
function getEntityType(entityTypeId) {
|
function getEntityType(entityTypeId) {
|
||||||
const entityType = entityTypes[entityTypeId];
|
const entityType = entityTypes[entityTypeId];
|
||||||
|
|
||||||
|
@ -116,6 +141,7 @@ function getEntityType(entityTypeId) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getEntityTypes,
|
getEntityTypes,
|
||||||
|
getEntityTypesWithPermissions,
|
||||||
getEntityType,
|
getEntityType,
|
||||||
ReplacementBehavior
|
ReplacementBehavior
|
||||||
}
|
}
|
|
@ -467,7 +467,12 @@ async function remove(context, id) {
|
||||||
return new interoperableErrors.InvalidStateError;
|
return new interoperableErrors.InvalidStateError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - deal with deletion of dependent entities (files)
|
await files.removeAllTx(tx, context, 'campaign', 'file', id);
|
||||||
|
await files.removeAllTx(tx, context, 'campaign', 'attachment', id);
|
||||||
|
|
||||||
|
await tx('campaign_lists').where('campaign', id).del();
|
||||||
|
await tx('campaign_messages').where('campaign', id).del();
|
||||||
|
await tx('campaign_links').where('campaign', id).del();
|
||||||
|
|
||||||
await triggers.removeAllByCampaignIdTx(tx, context, id);
|
await triggers.removeAllByCampaignIdTx(tx, context, id);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ const path = require('path');
|
||||||
const mjml = require('mjml');
|
const mjml = require('mjml');
|
||||||
const _ = require('../lib/translate')._;
|
const _ = require('../lib/translate')._;
|
||||||
const lists = require('./lists');
|
const lists = require('./lists');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const formAllowedKeys = new Set([
|
const formAllowedKeys = new Set([
|
||||||
'name',
|
'name',
|
||||||
|
@ -173,7 +174,9 @@ async function remove(context, id) {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'customForm', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'customForm', id, 'delete');
|
||||||
|
|
||||||
await lists.removeFormFromAllTx(tx, context, id);
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
|
{ entityTypeId: 'list', column: 'default_form' }
|
||||||
|
]);
|
||||||
|
|
||||||
await tx('custom_forms_data').where('form', id).del();
|
await tx('custom_forms_data').where('form', id).del();
|
||||||
await tx('custom_forms').where('id', id).del();
|
await tx('custom_forms').where('id', id).del();
|
||||||
|
|
|
@ -10,7 +10,9 @@ const shares = require('./shares');
|
||||||
const namespaceHelpers = require('../lib/namespace-helpers');
|
const namespaceHelpers = require('../lib/namespace-helpers');
|
||||||
const fields = require('./fields');
|
const fields = require('./fields');
|
||||||
const segments = require('./segments');
|
const segments = require('./segments');
|
||||||
|
const imports = require('./imports');
|
||||||
const entitySettings = require('../lib/entity-settings');
|
const entitySettings = require('../lib/entity-settings');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const UnsubscriptionMode = require('../shared/lists').UnsubscriptionMode;
|
const UnsubscriptionMode = require('../shared/lists').UnsubscriptionMode;
|
||||||
|
|
||||||
|
@ -176,23 +178,23 @@ async function remove(context, id) {
|
||||||
|
|
||||||
await fields.removeAllByListIdTx(tx, context, id);
|
await fields.removeAllByListIdTx(tx, context, id);
|
||||||
await segments.removeAllByListIdTx(tx, context, id);
|
await segments.removeAllByListIdTx(tx, context, id);
|
||||||
|
await imports.removeAllByListIdTx(tx, context, id);
|
||||||
|
|
||||||
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
|
{
|
||||||
|
entityTypeId: 'campaign',
|
||||||
|
query: tx => tx('campaign_lists')
|
||||||
|
.where('campaign_lists.list', id)
|
||||||
|
.innerJoin('campaigns', 'campaign_lists.campaign', 'campaigns.id')
|
||||||
|
.select(['campaigns.id', 'campaigns.name'])
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
await tx('lists').where('id', id).del();
|
await tx('lists').where('id', id).del();
|
||||||
await knex.schema.dropTableIfExists('subscription__' + id);
|
await knex.schema.dropTableIfExists('subscription__' + id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeFormFromAllTx(tx, context, formId) {
|
|
||||||
await knex.transaction(async tx => {
|
|
||||||
const entities = tx('lists').where('default_form', formId).select(['id']);
|
|
||||||
|
|
||||||
for (const entity of entities) {
|
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'list', entity.id, 'edit');
|
|
||||||
await tx('lists').where('id', entity.id).update({default_form: null});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getMergeTags(context, id) {
|
async function getMergeTags(context, id) {
|
||||||
return await knex.transaction(async tx => {
|
return await knex.transaction(async tx => {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'list', id, ['view']);
|
await shares.enforceEntityPermissionTx(tx, context, 'list', id, ['view']);
|
||||||
|
@ -224,5 +226,4 @@ module.exports.getByCid = getByCid;
|
||||||
module.exports.create = create;
|
module.exports.create = create;
|
||||||
module.exports.updateWithConsistencyCheck = updateWithConsistencyCheck;
|
module.exports.updateWithConsistencyCheck = updateWithConsistencyCheck;
|
||||||
module.exports.remove = remove;
|
module.exports.remove = remove;
|
||||||
module.exports.removeFormFromAllTx = removeFormFromAllTx;
|
|
||||||
module.exports.getMergeTags = getMergeTags;
|
module.exports.getMergeTags = getMergeTags;
|
||||||
|
|
|
@ -7,6 +7,8 @@ const dtHelpers = require('../lib/dt-helpers');
|
||||||
const interoperableErrors = require('../shared/interoperable-errors');
|
const interoperableErrors = require('../shared/interoperable-errors');
|
||||||
const namespaceHelpers = require('../lib/namespace-helpers');
|
const namespaceHelpers = require('../lib/namespace-helpers');
|
||||||
const shares = require('./shares');
|
const shares = require('./shares');
|
||||||
|
const files = require('./files');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const allowedKeys = new Set(['name', 'description', 'type', 'data', 'namespace']);
|
const allowedKeys = new Set(['name', 'description', 'type', 'data', 'namespace']);
|
||||||
|
|
||||||
|
@ -84,22 +86,34 @@ async function updateWithConsistencyCheck(context, entity) {
|
||||||
async function remove(context, id) {
|
async function remove(context, id) {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
const deps = [];
|
const deps = [];
|
||||||
const tmpls = await tx('templates').where('type', 'mosaico').select(['id', 'name', 'data']);
|
|
||||||
for (const row of tmpls) {
|
|
||||||
const data = JSON.parse(row.data);
|
|
||||||
if (data.mosaicoTemplate === id) {
|
|
||||||
deps.push({ entityTypeId: 'template', name: row.name, link: `templates/${row.id}` });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deps.length > 0) {
|
|
||||||
throw new interoperableErrors.DependencyPresentError('', {
|
|
||||||
dependencies: deps
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'mosaicoTemplate', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'mosaicoTemplate', id, 'delete');
|
||||||
|
|
||||||
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
|
{
|
||||||
|
entityTypeId: 'template',
|
||||||
|
rows: async (tx, limit) => {
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
const tmpls = await tx('templates').where('type', 'mosaico').select(['id', 'name', 'data']);
|
||||||
|
for (const tmpl of tmpls) {
|
||||||
|
const data = JSON.parse(tmpl.data);
|
||||||
|
if (data.mosaicoTemplate === id) {
|
||||||
|
result.push(tmpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
limit -= 1;
|
||||||
|
if (limit <= 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
await files.removeAllTx(tx, context, 'mosaicoTemplate', 'file', id);
|
||||||
|
await files.removeAllTx(tx, context, 'mosaicoTemplate', 'block', id);
|
||||||
|
|
||||||
await tx('mosaico_templates').where('id', id).del();
|
await tx('mosaico_templates').where('id', id).del();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ const interoperableErrors = require('../shared/interoperable-errors');
|
||||||
const shares = require('./shares');
|
const shares = require('./shares');
|
||||||
const entitySettings = require('../lib/entity-settings');
|
const entitySettings = require('../lib/entity-settings');
|
||||||
const namespaceHelpers = require('../lib/namespace-helpers');
|
const namespaceHelpers = require('../lib/namespace-helpers');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
|
|
||||||
const allowedKeys = new Set(['name', 'description', 'namespace']);
|
const allowedKeys = new Set(['name', 'description', 'namespace']);
|
||||||
|
@ -176,12 +177,8 @@ async function remove(context, id) {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'namespace', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'namespace', id, 'delete');
|
||||||
|
|
||||||
const childNs = await tx('namespaces').where('namespace', id).first();
|
const entityTypesWithNamespace = Object.keys(entitySettings.getEntityTypes());
|
||||||
if (childNs) {
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, entityTypesWithNamespace.map(entityTypeId => ({ entityTypeId: entityTypeId, column: 'namespace' })));
|
||||||
throw new interoperableErrors.ChildDetectedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME - Remove all contained entities first
|
|
||||||
|
|
||||||
await tx('namespaces').where('id', id).del();
|
await tx('namespaces').where('id', id).del();
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ const interoperableErrors = require('../shared/interoperable-errors');
|
||||||
const namespaceHelpers = require('../lib/namespace-helpers');
|
const namespaceHelpers = require('../lib/namespace-helpers');
|
||||||
const shares = require('./shares');
|
const shares = require('./shares');
|
||||||
const reports = require('./reports');
|
const reports = require('./reports');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const allowedKeys = new Set(['name', 'description', 'mime_type', 'user_fields', 'js', 'hbs', 'namespace']);
|
const allowedKeys = new Set(['name', 'description', 'mime_type', 'user_fields', 'js', 'hbs', 'namespace']);
|
||||||
|
|
||||||
|
@ -77,7 +78,9 @@ async function remove(context, id) {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'reportTemplate', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'reportTemplate', id, 'delete');
|
||||||
|
|
||||||
await reports.removeAllByReportTemplateIdTx(tx, context, id);
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
|
{ entityTypeId: 'report', column: 'report_template' }
|
||||||
|
]);
|
||||||
|
|
||||||
await tx('report_templates').where('id', id).del();
|
await tx('report_templates').where('id', id).del();
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,8 @@ const interoperableErrors = require('../shared/interoperable-errors');
|
||||||
const fields = require('./fields');
|
const fields = require('./fields');
|
||||||
const namespaceHelpers = require('../lib/namespace-helpers');
|
const namespaceHelpers = require('../lib/namespace-helpers');
|
||||||
const shares = require('./shares');
|
const shares = require('./shares');
|
||||||
|
const reportHelpers = require('../lib/report-helpers');
|
||||||
|
const fs = require('fs-extra-promise');
|
||||||
|
|
||||||
const ReportState = require('../shared/reports').ReportState;
|
const ReportState = require('../shared/reports').ReportState;
|
||||||
|
|
||||||
|
@ -114,9 +116,12 @@ async function updateWithConsistencyCheck(context, entity) {
|
||||||
async function removeTx(tx, context, id) {
|
async function removeTx(tx, context, id) {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'report', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'report', id, 'delete');
|
||||||
|
|
||||||
await tx('reports').where('id', id).del();
|
const report = tx('reports').where('id', id).first();
|
||||||
|
|
||||||
// FIXME: Remove generated files
|
await fs.removeAsync(reportHelpers.getReportContentFile(report));
|
||||||
|
await fs.removeAsync(reportHelpers.getReportOutputFile(report));
|
||||||
|
|
||||||
|
await tx('reports').where('id', id).del();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function remove(context, id) {
|
async function remove(context, id) {
|
||||||
|
@ -125,14 +130,6 @@ async function remove(context, id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeAllByReportTemplateIdTx(tx, context, templateId) {
|
|
||||||
const entities = await tx('reports').where('report_template', templateId).select(['id']);
|
|
||||||
for (const entity of entities) {
|
|
||||||
await removeTx(tx, context, entity.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function updateFields(id, fields) {
|
async function updateFields(id, fields) {
|
||||||
return await knex('reports').where('id', id).update(fields);
|
return await knex('reports').where('id', id).update(fields);
|
||||||
}
|
}
|
||||||
|
@ -203,7 +200,6 @@ module.exports.listDTAjax = listDTAjax;
|
||||||
module.exports.create = create;
|
module.exports.create = create;
|
||||||
module.exports.updateWithConsistencyCheck = updateWithConsistencyCheck;
|
module.exports.updateWithConsistencyCheck = updateWithConsistencyCheck;
|
||||||
module.exports.remove = remove;
|
module.exports.remove = remove;
|
||||||
module.exports.removeAllByReportTemplateIdTx = removeAllByReportTemplateIdTx;
|
|
||||||
module.exports.updateFields = updateFields;
|
module.exports.updateFields = updateFields;
|
||||||
module.exports.listByState = listByState;
|
module.exports.listByState = listByState;
|
||||||
module.exports.bulkChangeState = bulkChangeState;
|
module.exports.bulkChangeState = bulkChangeState;
|
||||||
|
|
|
@ -9,6 +9,7 @@ const hasher = require('node-object-hash')();
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const fields = require('./fields');
|
const fields = require('./fields');
|
||||||
const subscriptions = require('./subscriptions');
|
const subscriptions = require('./subscriptions');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const { parseDate, parseBirthday, DateFormat } = require('../shared/date');
|
const { parseDate, parseBirthday, DateFormat } = require('../shared/date');
|
||||||
|
|
||||||
|
@ -331,7 +332,15 @@ async function updateWithConsistencyCheck(context, listId, entity) {
|
||||||
async function removeTx(tx, context, listId, id) {
|
async function removeTx(tx, context, listId, id) {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'list', listId, 'manageSegments');
|
await shares.enforceEntityPermissionTx(tx, context, 'list', listId, 'manageSegments');
|
||||||
|
|
||||||
// FIXME - check dependencies: campaigns
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
|
{
|
||||||
|
entityTypeId: 'campaign',
|
||||||
|
query: tx => tx('campaign_lists')
|
||||||
|
.where('campaign_lists.segment', id)
|
||||||
|
.innerJoin('campaigns', 'campaign_lists.campaign', 'campaigns.id')
|
||||||
|
.select(['campaigns.id', 'campaigns.name'])
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
// The listId "where" is here to prevent deleting segment of a list for which a user does not have permission
|
// The listId "where" is here to prevent deleting segment of a list for which a user does not have permission
|
||||||
await tx('segments').where({list: listId, id}).del();
|
await tx('segments').where({list: listId, id}).del();
|
||||||
|
|
|
@ -12,6 +12,7 @@ const {MailerType, getSystemSendConfigurationId} = require('../shared/send-confi
|
||||||
const contextHelpers = require('../lib/context-helpers');
|
const contextHelpers = require('../lib/context-helpers');
|
||||||
const mailers = require('../lib/mailers');
|
const mailers = require('../lib/mailers');
|
||||||
const senders = require('../lib/senders');
|
const senders = require('../lib/senders');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const allowedKeys = new Set(['name', 'description', 'from_email', 'from_email_overridable', 'from_name', 'from_name_overridable', 'reply_to', 'reply_to_overridable', 'subject', 'subject_overridable', 'x_mailer', 'verp_hostname', 'mailer_type', 'mailer_settings', 'namespace']);
|
const allowedKeys = new Set(['name', 'description', 'from_email', 'from_email_overridable', 'from_name', 'from_name_overridable', 'reply_to', 'reply_to_overridable', 'subject', 'subject_overridable', 'x_mailer', 'verp_hostname', 'mailer_type', 'mailer_settings', 'namespace']);
|
||||||
|
|
||||||
|
@ -147,9 +148,11 @@ async function remove(context, id) {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'sendConfiguration', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'sendConfiguration', id, 'delete');
|
||||||
|
|
||||||
await tx('lists').update({send_configuration: null}).where('send_configuration', id);
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
|
{ entityTypeId: 'campaign', column: 'send_configuration' },
|
||||||
|
{ entityTypeId: 'list', column: 'send_configuration' }
|
||||||
|
]);
|
||||||
|
|
||||||
// If any campaign with the send configuration exists, this fails due to sql foreign key
|
|
||||||
await tx('send_configurations').where('id', id).del();
|
await tx('send_configurations').where('id', id).del();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ async function rebuildPermissionsTx(tx, restriction) {
|
||||||
[restriction.entityTypeId]: entityType
|
[restriction.entityTypeId]: entityType
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
restrictedEntityTypes = entitySettings.getEntityTypes();
|
restrictedEntityTypes = entitySettings.getEntityTypesWithPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ async function regenerateRoleNamesTable() {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
await tx('generated_role_names').del();
|
await tx('generated_role_names').del();
|
||||||
|
|
||||||
const entityTypeIds = ['global', ...Object.keys(entitySettings.getEntityTypes())];
|
const entityTypeIds = ['global', ...Object.keys(entitySettings.getEntityTypesWithPermissions())];
|
||||||
|
|
||||||
for (const entityTypeId of entityTypeIds) {
|
for (const entityTypeId of entityTypeIds) {
|
||||||
const roles = config.roles[entityTypeId];
|
const roles = config.roles[entityTypeId];
|
||||||
|
@ -539,6 +539,14 @@ async function checkEntityPermission(context, entityTypeId, entityId, requiredOp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkEntityPermissionTx(tx, context, entityTypeId, entityId, requiredOperations) {
|
||||||
|
if (!entityId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _checkPermissionTx(tx, context, entityTypeId, entityId, requiredOperations);
|
||||||
|
}
|
||||||
|
|
||||||
async function checkTypePermission(context, entityTypeId, requiredOperations) {
|
async function checkTypePermission(context, entityTypeId, requiredOperations) {
|
||||||
return await knex.transaction(async tx => {
|
return await knex.transaction(async tx => {
|
||||||
return await _checkPermissionTx(tx, context, entityTypeId, null, requiredOperations);
|
return await _checkPermissionTx(tx, context, entityTypeId, null, requiredOperations);
|
||||||
|
@ -626,6 +634,7 @@ module.exports.enforceEntityPermission = enforceEntityPermission;
|
||||||
module.exports.enforceEntityPermissionTx = enforceEntityPermissionTx;
|
module.exports.enforceEntityPermissionTx = enforceEntityPermissionTx;
|
||||||
module.exports.enforceTypePermission = enforceTypePermission;
|
module.exports.enforceTypePermission = enforceTypePermission;
|
||||||
module.exports.enforceTypePermissionTx = enforceTypePermissionTx;
|
module.exports.enforceTypePermissionTx = enforceTypePermissionTx;
|
||||||
|
module.exports.checkEntityPermissionTx = checkEntityPermissionTx;
|
||||||
module.exports.checkEntityPermission = checkEntityPermission;
|
module.exports.checkEntityPermission = checkEntityPermission;
|
||||||
module.exports.checkTypePermission = checkTypePermission;
|
module.exports.checkTypePermission = checkTypePermission;
|
||||||
module.exports.enforceGlobalPermission = enforceGlobalPermission;
|
module.exports.enforceGlobalPermission = enforceGlobalPermission;
|
||||||
|
|
|
@ -9,6 +9,7 @@ const namespaceHelpers = require('../lib/namespace-helpers');
|
||||||
const shares = require('./shares');
|
const shares = require('./shares');
|
||||||
const reports = require('./reports');
|
const reports = require('./reports');
|
||||||
const files = require('./files');
|
const files = require('./files');
|
||||||
|
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||||
|
|
||||||
const allowedKeys = new Set(['name', 'description', 'type', 'data', 'html', 'text', 'namespace']);
|
const allowedKeys = new Set(['name', 'description', 'type', 'data', 'html', 'text', 'namespace']);
|
||||||
|
|
||||||
|
@ -97,17 +98,15 @@ async function remove(context, id) {
|
||||||
await knex.transaction(async tx => {
|
await knex.transaction(async tx => {
|
||||||
await shares.enforceEntityPermissionTx(tx, context, 'template', id, 'delete');
|
await shares.enforceEntityPermissionTx(tx, context, 'template', id, 'delete');
|
||||||
|
|
||||||
const depCampaigns = await tx('template_dep_campaigns')
|
await dependencyHelpers.ensureNoDependencies(tx, context, id, [
|
||||||
.where('template_dep_campaigns.template', id)
|
{
|
||||||
.innerJoin('campaigns', 'template_dep_campaigns.campaign', 'campaigns.id')
|
entityTypeId: 'campaign',
|
||||||
.limit(interoperableErrors.defaultNoOfDependenciesReported)
|
query: tx => tx('template_dep_campaigns')
|
||||||
.select(['campaigns.id', 'campaigns.name']);
|
.where('template_dep_campaigns.template', id)
|
||||||
|
.innerJoin('campaigns', 'template_dep_campaigns.campaign', 'campaigns.id')
|
||||||
if (depCampaigns.length > 0) {
|
.select(['campaigns.id', 'campaigns.name'])
|
||||||
throw new interoperableErrors.DependencyPresentError('', {
|
}
|
||||||
dependencies: depCampaigns.map(row => ({ entityTypeId: 'campaign', name: row.name, link: `campaigns/${row.id}` }))
|
]);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await files.removeAllTx(tx, context, 'template', 'file', id);
|
await files.removeAllTx(tx, context, 'template', 'file', id);
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,15 @@ const contextHelpers = require('../../../lib/context-helpers');
|
||||||
const mosaicoTemplates = require('../../../shared/mosaico-templates');
|
const mosaicoTemplates = require('../../../shared/mosaico-templates');
|
||||||
const {getGlobalNamespaceId} = require('../../../shared/namespaces');
|
const {getGlobalNamespaceId} = require('../../../shared/namespaces');
|
||||||
const {getAdminId} = require('../../../shared/users');
|
const {getAdminId} = require('../../../shared/users');
|
||||||
const entityTypesAddNamespace = ['list', 'custom_form', 'template', 'campaign', 'report', 'report_template', 'user'];
|
|
||||||
const shareableEntityTypes = ['list', 'custom_form', 'template', 'campaign', 'report', 'report_template', 'namespace', 'send_configuration', 'mosaico_template'];
|
|
||||||
const { MailerType, getSystemSendConfigurationId, getSystemSendConfigurationCid } = require('../../../shared/send-configurations');
|
const { MailerType, getSystemSendConfigurationId, getSystemSendConfigurationCid } = require('../../../shared/send-configurations');
|
||||||
const { enforce } = require('../../../lib/helpers');
|
const { enforce } = require('../../../lib/helpers');
|
||||||
const { EntityVals: TriggerEntityVals, EventVals: TriggerEventVals } = require('../../../shared/triggers');
|
const { EntityVals: TriggerEntityVals, EventVals: TriggerEventVals } = require('../../../shared/triggers');
|
||||||
const { SubscriptionSource } = require('../../../shared/lists');
|
const { SubscriptionSource } = require('../../../shared/lists');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const entityTypesAddNamespace = ['list', 'custom_form', 'template', 'campaign', 'report', 'report_template', 'user'];
|
||||||
|
const shareableEntityTypes = ['list', 'custom_form', 'template', 'campaign', 'report', 'report_template', 'namespace', 'send_configuration', 'mosaico_template'];
|
||||||
|
|
||||||
const entityTypesWithFiles = {
|
const entityTypesWithFiles = {
|
||||||
campaign: {
|
campaign: {
|
||||||
file: 'files_campaign_file',
|
file: 'files_campaign_file',
|
||||||
|
@ -895,9 +896,9 @@ async function migrateCampaigns(knex) {
|
||||||
|
|
||||||
await knex.schema.createTable('campaign_lists', table => {
|
await knex.schema.createTable('campaign_lists', table => {
|
||||||
table.increments('id').primary();
|
table.increments('id').primary();
|
||||||
table.integer('campaign').unsigned().notNullable().references('campaigns.id').onDelete('CASCADE');
|
table.integer('campaign').unsigned().notNullable().references('campaigns.id');
|
||||||
table.integer('list').unsigned().notNullable().references('lists.id').onDelete('CASCADE');
|
table.integer('list').unsigned().notNullable().references('lists.id');
|
||||||
table.integer('segment').unsigned().references('segments.id').onDelete('CASCADE');
|
table.integer('segment').unsigned().references('segments.id');
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('template_dep_campaigns', table => {
|
await knex.schema.createTable('template_dep_campaigns', table => {
|
||||||
|
|
|
@ -33,12 +33,6 @@ class LoopDetectedError extends InteroperableError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChildDetectedError extends InteroperableError {
|
|
||||||
constructor(msg, data) {
|
|
||||||
super('ChildDetectedError', msg, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DuplicitNameError extends InteroperableError {
|
class DuplicitNameError extends InteroperableError {
|
||||||
constructor(msg, data) {
|
constructor(msg, data) {
|
||||||
super('DuplicitNameError', msg, data);
|
super('DuplicitNameError', msg, data);
|
||||||
|
@ -106,8 +100,6 @@ class InvalidConfirmationForUnsubscriptionError extends InteroperableError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultNoOfDependenciesReported = 20;
|
|
||||||
|
|
||||||
class DependencyPresentError extends InteroperableError {
|
class DependencyPresentError extends InteroperableError {
|
||||||
constructor(msg, data) {
|
constructor(msg, data) {
|
||||||
super('DependencyPresentError', msg, data);
|
super('DependencyPresentError', msg, data);
|
||||||
|
@ -127,7 +119,6 @@ const errorTypes = {
|
||||||
ChangedError,
|
ChangedError,
|
||||||
NotFoundError,
|
NotFoundError,
|
||||||
LoopDetectedError,
|
LoopDetectedError,
|
||||||
ChildDetectedError,
|
|
||||||
DuplicitNameError,
|
DuplicitNameError,
|
||||||
DuplicitEmailError,
|
DuplicitEmailError,
|
||||||
DuplicitKeyError,
|
DuplicitKeyError,
|
||||||
|
@ -156,6 +147,5 @@ function deserialize(errorObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Object.assign({}, errorTypes, {
|
module.exports = Object.assign({}, errorTypes, {
|
||||||
defaultNoOfDependenciesReported,
|
|
||||||
deserialize
|
deserialize
|
||||||
});
|
});
|
Loading…
Reference in a new issue