Skip to content

Commit a1a6ffa

Browse files
committed
feat: add a proxy transform entity before a save operation. This allow transform decorators to be executed before save.
1 parent 9c63a54 commit a1a6ffa

File tree

4 files changed

+19
-28
lines changed

4 files changed

+19
-28
lines changed

src/decorators.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,6 @@ export function SlugDecorator<T>(
115115
target,
116116
key
117117
);
118-
119-
Object.defineProperty(target, key, {
120-
enumerable: true,
121-
get() {
122-
return slugify(seed(this), config.options);
123-
}
124-
});
125118
}
126119

127120
export function Slugify<T = any>(config: ISlugifyOptions<T>) {

src/manager.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -152,37 +152,42 @@ export class MongoManager {
152152
await this.validate(entity, options.validatorOptions, true);
153153
}
154154
const collection = this.getCollection(entity, options.database);
155+
156+
const Model = this.getModel(entityName);
157+
if (Model === undefined) {
158+
throw new Error(`Can not find model ${entityName}`);
159+
}
160+
const proxy = this.merge(new Model(), entity);
161+
155162
let operation: any;
156-
if (!isEmpty(entity._id)) {
157-
entity.updatedAt = new Date();
163+
if (!isEmpty(proxy._id)) {
164+
proxy.updatedAt = new Date();
158165

159166
const $unset: any = {};
160167
for (const p in entity) {
161168
if (
162-
Object.prototype.hasOwnProperty.call(entity, p) === true
169+
Object.prototype.hasOwnProperty.call(proxy, p) === true
163170
) {
164-
const v: any = entity[p];
171+
const v: any = proxy[p];
165172
if (v === undefined) {
166173
$unset[p] = 1;
167174
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
168-
delete entity[p];
175+
delete proxy[p];
169176
}
170177
}
171178
}
172179

173180
const sets: any = { $set: entity };
174-
175181
if (Object.keys($unset).length > 0) {
176182
sets.$unset = $unset;
177183
}
178-
179-
operation = collection.updateOne({ _id: entity._id }, sets, {
184+
operation = collection.updateOne({ _id: proxy._id }, sets, {
180185
upsert: false,
181186
...options.mongoOperationOptions
182187
});
183188
} else {
184189
operation = collection.insertOne(
185-
entity,
190+
proxy,
186191
options.mongoOperationOptions
187192
);
188193
}
@@ -193,19 +198,18 @@ export class MongoManager {
193198

194199
// new id
195200
if (insertedId instanceof ObjectId) {
196-
entity._id = insertedId;
201+
proxy._id = insertedId;
197202
}
198203

204+
// merge the proxy changes back to the entity
205+
this.merge(entity, proxy);
199206
this.dataloaderService.update(dataloaderName, entity);
200-
201207
return entity;
202208
} catch (e) {
203209
this.log('error saving %s', entityName);
204-
205210
if (entity._id instanceof ObjectId) {
206211
this.dataloaderService.delete(dataloaderName, entity);
207212
}
208-
209213
throw e;
210214
}
211215
}
@@ -525,6 +529,6 @@ export class MongoManager {
525529
options?: ClassTransformOptions
526530
): Model {
527531
this.log('%s transform merge', getObjectName(entity));
528-
return merge(entity, data, options);
532+
return merge(data, entity, options);
529533
}
530534
}

src/test/decorators.spec.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,4 @@ describe('Slug decorator', () => {
1111
expect(target.slug).toEqual('john-smith');
1212
expect(target.slug2).toEqual('john-smith');
1313
});
14-
15-
test('should handle options.generate and options.keys on new class call', () => {
16-
const target = new EntitySlugTest('John', 'Smith');
17-
expect(target.slug).toEqual('john-smith');
18-
expect(target.slug2).toEqual('john-smith');
19-
});
2014
});

src/transformers/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function merge<Model extends EntityInterface>(
2020
data: any,
2121
options?: ClassTransformOptions
2222
) {
23-
return classToClassFromExist(data, entity, {
23+
return classToClassFromExist(entity, data, {
2424
excludePrefixes: EXCLUDED_PREFIXES,
2525
...options
2626
});

0 commit comments

Comments
 (0)