Skip to content

Commit

Permalink
Add better version of szokodiakos#260
Browse files Browse the repository at this point in the history
- adding set option for nonVirtual setting functions

closes szokodiakos#260
  • Loading branch information
hasezoey committed Aug 4, 2019
1 parent 0d9cb8b commit a123c49
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 18 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typegoose",
"version": "6.0.0-8",
"version": "6.0.0-9",
"description": "Define Mongoose models using TypeScript classes.",
"main": "lib/typegoose.js",
"engines": {
Expand Down
32 changes: 27 additions & 5 deletions src/prop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type Validator =
message?: string;
};

export interface BasePropOptions {
export interface BasePropOptions<T = any> {
/** include this value?
* @default true (Implicitly)
*/
Expand Down Expand Up @@ -51,6 +51,7 @@ export interface BasePropOptions {
* @default true (Implicitly)
*/
_id?: boolean;
set?(value: T): T;
}

export interface PropOptions extends BasePropOptions {
Expand Down Expand Up @@ -159,25 +160,34 @@ function isWithNumberValidate(options: PropOptionsWithNumberValidate) {
*/
function baseProp(rawOptions: any, Type: any, target: any, key: string, whatis: WhatIsIt = WhatIsIt.NONE): void {
const name: string = target.constructor.name;
rawOptions = Object.assign(rawOptions, {});

if (!virtuals.get(name)) {
virtuals.set(name, new Map());
}

const isGetterSetter = Object.getOwnPropertyDescriptor(target, key);
if (isGetterSetter) {
if (!virtuals.get(name)) {
virtuals.set(name, new Map());
if (rawOptions.overwrite) {
virtuals.get(name).set(key, {
options: rawOptions
});
return;
}

if (isGetterSetter.get) {
virtuals.get(name).set(key, {
...virtuals.get(name).get(key),
get: isGetterSetter.get,
options: rawOptions,
options: rawOptions
});
}

if (isGetterSetter.set) {
virtuals.get(name).set(key, {
...virtuals.get(name).get(key),
set: isGetterSetter.set,
options: rawOptions,
options: rawOptions
});
}
return;
Expand All @@ -189,6 +199,18 @@ function baseProp(rawOptions: any, Type: any, target: any, key: string, whatis:
initAsObject(name, key);
}

if (rawOptions.set) {
/*
* Note:
* this dosnt have a check if prop & returntype of the function is the same, because it cant be accessed at runtime
*/
schemas.get(name)[key] = {
...schemas.get(name)[key],
type: Type,
set: rawOptions.set
};
}

const ref = rawOptions.ref;
if (typeof ref === 'string') {
schemas.get(name)[key] = {
Expand Down
13 changes: 13 additions & 0 deletions test/models/virtualprop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,16 @@ export class VirtualSub extends Typegoose {
@prop({ required: true })
public dummy: string;
}

function setNon(val: string) {
return val.toLowerCase();
}

export class NonVirtual extends Typegoose {
@prop({ set: setNon, default: 'hello_default' })
public non: string;
}

export const virtualModel = new Virtual().getModelForClass(Virtual);
export const virtualSubModel = new VirtualSub().getModelForClass(VirtualSub);
export const nonVirtualModel = new NonVirtual().getModelForClass(NonVirtual);
36 changes: 25 additions & 11 deletions test/tests/shouldAdd.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Alias, model as AliasModel } from '../models/alias';
import { model as InternetUser } from '../models/internet-user';
import { BeverageModel as Beverage, InventoryModel as Inventory, ScooterModel as Scooter } from '../models/inventory';
import { model as User } from '../models/user';
import { Virtual, VirtualSub } from '../models/virtualprop';
import { NonVirtual, nonVirtualModel, Virtual, virtualModel, VirtualSub, virtualSubModel } from '../models/virtualprop';

/**
* Function to pass into describe
Expand Down Expand Up @@ -41,22 +41,19 @@ export function suite() {
});

it('should add and populate the virtual properties', async () => {
const virtualModel = new Virtual().getModelForClass(Virtual);
const virtualSubModel = new VirtualSub().getModelForClass(VirtualSub);

const virtual1 = await new virtualModel({ dummyVirtual: 'dummyVirtual1' } as Virtual).save();
const virtualsub1 = await new virtualSubModel({
const virtual1 = await virtualModel.create({ dummyVirtual: 'dummyVirtual1' } as Virtual);
const virtualsub1 = await virtualSubModel.create({
dummy: 'virtualSub1',
virtual: virtual1._id
} as Partial<VirtualSub>).save();
const virtualsub2 = await new virtualSubModel({
} as Partial<VirtualSub>);
const virtualsub2 = await virtualSubModel.create({
dummy: 'virtualSub2',
virtual: mongoose.Types.ObjectId() as Ref<any>
} as Partial<VirtualSub>).save();
const virtualsub3 = await new virtualSubModel({
} as Partial<VirtualSub>);
const virtualsub3 = await virtualSubModel.create({
dummy: 'virtualSub3',
virtual: virtual1._id
} as Partial<VirtualSub>).save();
} as Partial<VirtualSub>);

const newfound = await virtualModel.findById(virtual1._id).populate('virtualSubs').exec();

Expand All @@ -69,6 +66,23 @@ export function suite() {
expect(newfound.virtualSubs).to.not.include(virtualsub2);
});

it('should add a nonVirtual setter to db', async () => {
{
// test if everything works
const doc = await nonVirtualModel.create({ non: 'HELLO THERE' } as Partial<NonVirtual>);

expect(doc.non).to.not.be.an('undefined');
expect(doc.non).to.be.equals('hello there');
}
{
// test if other options work too
const doc = await nonVirtualModel.create({});

expect(doc.non).to.not.be.an('undefined');
expect(doc.non).to.be.equals('hello_default');
}
});

it(`should add dynamic fields using map`, async () => {
const user = await InternetUser.create({
socialNetworks: {
Expand Down

0 comments on commit a123c49

Please sign in to comment.