dev: add dedupe_name option for app creation

This commit is contained in:
KernelDeimos 2024-10-18 20:42:25 -04:00
parent 4ce2dccc76
commit 66e8b37f70
4 changed files with 26 additions and 14 deletions

View File

@ -91,26 +91,26 @@ class EntityStoreImplementation extends Driver {
this.service = service; this.service = service;
} }
static METHODS = { static METHODS = {
create: async function ({ object }) { create: async function ({ object, options }) {
const svc_es = this.services.get(this.service); const svc_es = this.services.get(this.service);
if ( object.hasOwnProperty(svc_es.om.primary_identifier) ) { if ( object.hasOwnProperty(svc_es.om.primary_identifier) ) {
throw APIError.create('field_not_allowed_for_create', null, { key: svc_es.om.primary_identifier }); throw APIError.create('field_not_allowed_for_create', null, { key: svc_es.om.primary_identifier });
} }
const entity = await Entity.create({ om: svc_es.om }, object); const entity = await Entity.create({ om: svc_es.om }, object);
return await svc_es.create(entity); return await svc_es.create(entity, options);
}, },
update: async function ({ object, id }) { update: async function ({ object, id, options }) {
const svc_es = this.services.get(this.service); const svc_es = this.services.get(this.service);
// if ( ! object.hasOwnProperty(svc_es.om.primary_identifier) ) { // if ( ! object.hasOwnProperty(svc_es.om.primary_identifier) ) {
// throw APIError.create('field_required_for_update', null, { key: svc_es.om.primary_identifier }); // throw APIError.create('field_required_for_update', null, { key: svc_es.om.primary_identifier });
// } // }
const entity = await Entity.create({ om: svc_es.om }, object); const entity = await Entity.create({ om: svc_es.om }, object);
return await svc_es.update(entity, id); return await svc_es.update(entity, id, options);
}, },
upsert: async function ({ object, id }) { upsert: async function ({ object, id, options }) {
const svc_es = this.services.get(this.service); const svc_es = this.services.get(this.service);
const entity = await Entity.create({ om: svc_es.om }, object); const entity = await Entity.create({ om: svc_es.om }, object);
return await svc_es.upsert(entity, id); return await svc_es.upsert(entity, id, options);
}, },
read: async function ({ uid, id }) { read: async function ({ uid, id }) {
if ( ! uid && ! id ) { if ( ! uid && ! id ) {

View File

@ -89,12 +89,21 @@ class AppES extends BaseES {
const { old_entity } = extra; const { old_entity } = extra;
const throw_it = ( ! old_entity ) || const throw_it = ( ! old_entity ) ||
( await old_entity.get('name') !== await entity.get('name') ); ( await old_entity.get('name') !== await entity.get('name') );
if ( throw_it ) { if ( throw_it && extra.options && extra.options.dedupe_name ) {
const base = await entity.get('name');
let number = 0;
while ( await app_name_exists(`${base}-${number}`) ) {
number++;
}
await entity.set('name', `${base}-${number}`)
}
else if ( throw_it ) {
throw APIError.create('app_name_already_in_use', null, { throw APIError.create('app_name_already_in_use', null, {
name: await entity.get('name') name: await entity.get('name')
}); });
} else {
entity.del('name');
} }
entity.del('name');
} }
const subdomain_id = await this.maybe_insert_subdomain_(entity); const subdomain_id = await this.maybe_insert_subdomain_(entity);

View File

@ -41,8 +41,8 @@ class EntityStoreService extends BaseService {
} }
// TODO: can replace these with MethodProxyFeature // TODO: can replace these with MethodProxyFeature
async create (entity) { async create (entity, options) {
return await this.upstream.upsert(entity, { old_entity: null }); return await this.upstream.upsert(entity, { old_entity: null, options });
} }
async read (uid) { async read (uid) {
return await this.upstream.read(uid); return await this.upstream.read(uid);
@ -56,7 +56,7 @@ class EntityStoreService extends BaseService {
if ( ! predicate) predicate = new Null(); if ( ! predicate) predicate = new Null();
return await this.upstream.select({ predicate, ...rest }); return await this.upstream.select({ predicate, ...rest });
} }
async update (entity, id) { async update (entity, id, options) {
let old_entity = await this.read( let old_entity = await this.read(
await entity.get(this.om.primary_identifier)); await entity.get(this.om.primary_identifier));
@ -84,9 +84,9 @@ class EntityStoreService extends BaseService {
const id_prop = this.om.properties[this.om.primary_identifier]; const id_prop = this.om.properties[this.om.primary_identifier];
await entity.set(id_prop.name, await old_entity.get(id_prop.name)); await entity.set(id_prop.name, await old_entity.get(id_prop.name));
return await this.upstream.upsert(entity, { old_entity }); return await this.upstream.upsert(entity, { old_entity, options });
} }
async upsert (entity, id) { async upsert (entity, id, options) {
let old_entity = await this.read( let old_entity = await this.read(
await entity.get(this.om.primary_identifier)); await entity.get(this.om.primary_identifier));
@ -110,7 +110,7 @@ class EntityStoreService extends BaseService {
await entity.set(id_prop.name, await old_entity.get(id_prop.name)); await entity.set(id_prop.name, await old_entity.get(id_prop.name));
} }
return await this.upstream.upsert(entity, { old_entity }); return await this.upstream.upsert(entity, { old_entity, options });
} }
async delete (uid) { async delete (uid) {
const old_entity = await this.read(uid); const old_entity = await this.read(uid);

View File

@ -25,6 +25,7 @@ const ENTITY_STORAGE_INTERFACE = {
subtype: 'object', subtype: 'object',
required: true, required: true,
}, },
options: { type: 'json' },
} }
}, },
read: { read: {
@ -48,6 +49,7 @@ const ENTITY_STORAGE_INTERFACE = {
subtype: 'object', subtype: 'object',
required: true, required: true,
}, },
options: { type: 'json' },
} }
}, },
upsert: { upsert: {
@ -58,6 +60,7 @@ const ENTITY_STORAGE_INTERFACE = {
subtype: 'object', subtype: 'object',
required: true, required: true,
}, },
options: { type: 'json' },
} }
}, },
delete: { delete: {