Skip to content

Commit

Permalink
feat(): add definitions factory
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed May 6, 2020
1 parent 686f62e commit acbf36c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 63 deletions.
13 changes: 4 additions & 9 deletions lib/decorators/prop.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@ export type PropOptions =
*/
export function Prop(options?: PropOptions): PropertyDecorator {
return (target: object, propertyKey: string | symbol) => {
options = options || {};
if (!options) {
options = {};

const schemaTypeOpts = options as mongoose.SchemaTypeOpts<unknown>;
if (!schemaTypeOpts.type) {
const type = Reflect.getMetadata(
TYPE_METADATA_KEY,
target.constructor,
propertyKey,
);
const type = Reflect.getMetadata(TYPE_METADATA_KEY, target, propertyKey);
if (type) {
schemaTypeOpts.type = type;
options.type = type;
}
}

Expand Down
38 changes: 38 additions & 0 deletions lib/factories/definitions.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Type } from '@nestjs/common';
import { isUndefined } from '@nestjs/common/utils/shared.utils';
import * as mongoose from 'mongoose';
import { TypeMetadataStorage } from '../storages/type-metadata.storage';

export class DefinitionsFactory {
static createForClass(target: Type<unknown>): mongoose.SchemaDefinition {
if (!target) {
throw new Error(
`Target class "${target}" passed in to the "DefinitionsFactory#createForClass()" method is "undefined".`,
);
}
let schemaDefinition: mongoose.SchemaDefinition = {};
let parent: Function = target;

while (!isUndefined(parent.prototype)) {
if (parent === Function.prototype) {
break;
}
const schemaMetadata = TypeMetadataStorage.getSchemaMetadataByTarget(
parent as Type<unknown>,
);
if (!schemaMetadata) {
parent = Object.getPrototypeOf(parent);
continue;
}
schemaMetadata.properties?.forEach(item => {
schemaDefinition = {
[item.propertyKey]: item.options,
...schemaDefinition,
};
});
parent = Object.getPrototypeOf(parent);
}

return schemaDefinition;
}
}
1 change: 1 addition & 0 deletions lib/factories/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './definitions.factory';
export * from './schema.factory';
31 changes: 6 additions & 25 deletions lib/factories/schema.factory.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
import { Type } from '@nestjs/common';
import { isUndefined } from '@nestjs/common/utils/shared.utils';
import * as mongoose from 'mongoose';
import { TypeMetadataStorage } from '../storages/type-metadata.storage';
import { DefinitionsFactory } from './definitions.factory';

export class SchemaFactory {
static createForClass(target: Type<unknown>) {
if (!target) {
throw new Error('');
}
const schemaDefinition = DefinitionsFactory.createForClass(target);
const schemaMetadata = TypeMetadataStorage.getSchemaMetadataByTarget(
target,
);
if (!schemaMetadata) {
throw new Error('no');
}

let schemaDefinition: mongoose.SchemaDefinition = {};
let parent: Function = target;

while (!isUndefined(parent.prototype)) {
parent = Object.getPrototypeOf(parent);
if (parent === Function.prototype) {
break;
}
schemaMetadata.properties?.forEach(item => {
schemaDefinition = {
[item.propertyKey]: item.options,
...schemaDefinition,
};
});
}

return new mongoose.Schema(schemaDefinition, schemaMetadata.options);
return new mongoose.Schema(
schemaDefinition,
schemaMetadata && schemaMetadata.options,
);
}
}
15 changes: 10 additions & 5 deletions lib/mongoose-core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ export class MongooseCoreModule implements OnApplicationShutdown {
useFactory: async (): Promise<any> =>
await defer(async () =>
mongooseConnectionFactory(
mongoose.createConnection(uri, mongooseOptions),
mongoose.createConnection(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
...mongooseOptions,
}),
mongooseConnectionName,
),
)
Expand Down Expand Up @@ -96,10 +100,11 @@ export class MongooseCoreModule implements OnApplicationShutdown {

return await defer(async () =>
mongooseConnectionFactory(
mongoose.createConnection(
mongooseModuleOptions.uri as string,
mongooseOptions,
),
mongoose.createConnection(mongooseModuleOptions.uri as string, {
useNewUrlParser: true,
useUnifiedTopology: true,
...mongooseOptions,
}),
mongooseConnectionName,
),
)
Expand Down
29 changes: 6 additions & 23 deletions lib/storages/type-metadata.storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,21 @@ export class TypeMetadataStorageHost {
this.properties.push(metadata);
}

getPropertiesMetadata(): PropertyMetadata[] {
return this.properties;
}

addSchemaMetadata(metadata: SchemaMetadata) {
this.compileClassMetadata(metadata);
this.schemas.push(metadata);
}

getSchemasMetadata(): SchemaMetadata[] {
return this.schemas;
}

getSchemaMetadataByTarget(target: Type<unknown>): SchemaMetadata | undefined {
return this.schemas.find(item => item.target === target);
}

compile() {
this.compileClassMetadata(this.schemas);
}

private compileClassMetadata(metadata: SchemaMetadata[]) {
metadata.forEach(item => {
const belongsToClass = isTargetEqual.bind(undefined, item);

if (!item.properties) {
item.properties = this.getClassFieldsByPredicate(belongsToClass);
}
});
}
private compileClassMetadata(metadata: SchemaMetadata) {
const belongsToClass = isTargetEqual.bind(undefined, metadata);

clear() {
Object.assign(this, new TypeMetadataStorageHost());
if (!metadata.properties) {
metadata.properties = this.getClassFieldsByPredicate(belongsToClass);
}
}

private getClassFieldsByPredicate(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestjs/mongoose",
"version": "6.4.0",
"version": "6.5.0-next.2",
"description": "Nest - modern, fast, powerful node.js web framework (@mongoose)",
"author": "Kamil Mysliwiec",
"repository": "https://github.com/nestjs/mongoose.git",
Expand Down

0 comments on commit acbf36c

Please sign in to comment.