Skip to content
This repository has been archived by the owner on Jun 29, 2021. It is now read-only.

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hasezoey committed Aug 7, 2019
1 parent 0d68100 commit 7628b87
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 11 deletions.
66 changes: 55 additions & 11 deletions src/typegoose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export { getClassForDocument } from './utils';
export type InstanceType<T> = T & mongoose.Document;
export type ModelType<T> = mongoose.Model<InstanceType<T>> & T;

export interface GetModelForClassOptions {
export interface ModelForClassOptions {
/** An Existing Mongoose Connection */
existingMongoose?: mongoose.Mongoose;
/** Supports all Mongoose's Schema Options */
Expand All @@ -42,7 +42,7 @@ export class Typegoose {
*/
public getModelForClass<T>(
t: T,
{ existingMongoose, schemaOptions, existingConnection }: GetModelForClassOptions = {}
{ existingMongoose, schemaOptions, existingConnection }: ModelForClassOptions = {}
) {
const name = this.constructor.name;
if (!models[name]) {
Expand All @@ -68,23 +68,32 @@ export class Typegoose {
*/
public setModelForClass<T>(
t: T,
{ existingMongoose, schemaOptions, existingConnection }: GetModelForClassOptions = {}
{ existingMongoose, schemaOptions, existingConnection }: ModelForClassOptions = {}
) {
const name = this.constructor.name;

const sch = this.buildSchema<T>(t, { existingMongoose, schemaOptions });

let model = mongoose.model.bind(mongoose);
return this.buildModel(sch, { existingMongoose, existingConnection });
}

/**
* Build a model from the Given Schema
* @param sch The Schema to build from
* @param __namedParameters Options
*/
public buildModel<T>(
sch: mongoose.Schema<any>,
{ existingMongoose, existingConnection }: ModelForClassOptions = {}
) {
const name = this.constructor.name;

let model = mongoose.model.bind(mongoose) as typeof mongoose.model;
if (existingConnection) {
model = existingConnection.model.bind(existingConnection);
} else if (existingMongoose) {
model = existingMongoose.model.bind(existingMongoose);
}

models[name] = model(name, sch);
constructors[name] = this.constructor;

return models[name] as ModelType<this> & T;
return _buildModel(model(name, sch), name);
}

/**
Expand All @@ -93,7 +102,7 @@ export class Typegoose {
* @param schemaOptions Options for the Schema
* @returns Returns the Build Schema
*/
public buildSchema<T>(t: T, { schemaOptions }: GetModelForClassOptions = {}) {
public buildSchema<T>(t: T, { schemaOptions }: ModelForClassOptions = {}) {
const name = this.constructor.name;

// get schema of current model
Expand Down Expand Up @@ -188,3 +197,38 @@ function _buildSchema<T>(t: T, name: string, schemaOptions: any, sch?: mongoose.

return sch;
}

// This below are Functions that dont need to be in the class

/**
* Add a model to the models Array & the constructors Array
* @private
* @param model The Model to add
* @param param1
*/
function _buildModel<T extends mongoose.Model<any>>(model: T, name: string) {
models[name] = model;
constructors[name] = model.constructor;

return models[name] as ModelType<T> & T;
}

/**
* Build a Model from a given Schema & the given Discriminator
* @param from The Model to build From
* @param id The Identifier like in Mongoose
* @param sch The Build Schema (from .buildSchema)
* @param t Optional class to set the name, defaults to param id
*/
export function buildDiscriminator<T extends Typegoose, Z>(
from: ModelType<T>, id: string, sch: mongoose.Schema<T>, t?: Z
) {
const model = from.discriminator(id, sch);

let name = id;
if (t && t.constructor.name) {
name = t.constructor.name;
}

return _buildModel(model, name);
}
16 changes: 16 additions & 0 deletions test/models/discriminators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { buildDiscriminator, prop, Typegoose } from '../../src/typegoose';

export class DisMain extends Typegoose {
@prop({ required: true })
public main1: string;
}

export class DisAbove extends DisMain {
@prop({ required: true })
public above1: string;
}

export const DisMainModel = new DisMain().getModelForClass(DisMain);
export const DisAboveModel = buildDiscriminator(
DisMainModel, 'id_hello', new DisAbove().buildSchema(DisAbove), new DisAbove()
);

0 comments on commit 7628b87

Please sign in to comment.