Skip to content

Commit

Permalink
feat(): add raw function, parse children definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed May 13, 2020
1 parent d6ffa5d commit 8bf77f8
Show file tree
Hide file tree
Showing 22 changed files with 8,392 additions and 2,190 deletions.
37 changes: 37 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,47 @@ jobs:
- run:
name: Build
command: npm run build
integration_tests:
working_directory: ~/nest
machine: true
steps:
- checkout
- run:
name: Prepare nvm
command: |
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
echo ' [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV
- run:
name: Upgrade Node.js
command: |
nvm install v12
node -v
nvm alias default v12
- run:
name: Install Docker Compose
command: |
curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` > ~/docker-compose
chmod +x ~/docker-compose
sudo mv ~/docker-compose /usr/local/bin/docker-compose
- *install-deps
- run:
name: Prepare
command: |
docker-compose up -d
sleep 10
- run:
name: List containers
command: docker ps
- run:
name: e2e tests
command: npm run test:e2e

workflows:
version: 2
build-and-test:
jobs:
- build
- integration_tests:
requires:
- build

9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: "3"

services:
mongodb:
image: mongo:latest
environment:
- MONGODB_DATABASE="test"
ports:
- 27017:27017
13 changes: 9 additions & 4 deletions lib/decorators/prop.decorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as mongoose from 'mongoose';
import { RAW_OBJECT_DEFINITION } from '../mongoose.constants';
import { TypeMetadataStorage } from '../storages/type-metadata.storage';

const TYPE_METADATA_KEY = 'design:type';
Expand All @@ -12,16 +13,20 @@ export type PropOptions =
| mongoose.SchemaType;

/**
* @Prop() decorator is used to mark a specific class property as a Mongoose property.
* @Prop decorator is used to mark a specific class property as a Mongoose property.
* Only properties decorated with this decorator will be defined in the schema.
*/
export function Prop(options?: PropOptions): PropertyDecorator {
return (target: object, propertyKey: string | symbol) => {
if (!options) {
options = {};
options = (options || {}) as mongoose.SchemaTypeOpts<unknown>;

const isRawDefinition = options[RAW_OBJECT_DEFINITION];
if (!options.type && !Array.isArray(options) && !isRawDefinition) {
const type = Reflect.getMetadata(TYPE_METADATA_KEY, target, propertyKey);
if (type) {

if (type === Array) {
options.type = [];
} else if (type && type !== Object) {
options.type = type;
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/decorators/schema.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { TypeMetadataStorage } from '../storages/type-metadata.storage';
export type SchemaOptions = mongoose.SchemaOptions;

/**
* @Schema() decorator is used to mark a class as a Mongoose schema.
* @Schema decorator is used to mark a class as a Mongoose schema.
* Only properties decorated with this decorator will be defined in the schema.
*/
export function Schema(options?: SchemaOptions): ClassDecorator {
Expand Down
41 changes: 39 additions & 2 deletions lib/factories/definitions.factory.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Type } from '@nestjs/common';
import { isUndefined } from '@nestjs/common/utils/shared.utils';
import * as mongoose from 'mongoose';
import { PropOptions } from '../decorators';
import { TypeMetadataStorage } from '../storages/type-metadata.storage';

const PRIMITIVE_TYPES: Function[] = [Boolean, Number, String];

export class DefinitionsFactory {
static createForClass(target: Type<unknown>): mongoose.SchemaDefinition {
if (!target) {
Expand All @@ -24,9 +27,10 @@ export class DefinitionsFactory {
parent = Object.getPrototypeOf(parent);
continue;
}
schemaMetadata.properties?.forEach(item => {
schemaMetadata.properties?.forEach((item) => {
const options = this.inspectTypeDefinition(item.options as any);
schemaDefinition = {
[item.propertyKey]: item.options,
[item.propertyKey]: options as any,
...schemaDefinition,
};
});
Expand All @@ -35,4 +39,37 @@ export class DefinitionsFactory {

return schemaDefinition;
}

private static inspectTypeDefinition(
options: mongoose.SchemaTypeOpts<unknown> | Function,
): PropOptions {
if (typeof options === 'function') {
if (this.isPrimitive(options)) {
return options;
} else if (this.isMongooseSchemaType(options)) {
return options;
}
return this.createForClass(options as Type<unknown>);
} else if (typeof options.type === 'function') {
options.type = this.inspectTypeDefinition(options.type);
return options;
} else if (Array.isArray(options)) {
return options.length > 0
? [this.inspectTypeDefinition(options[0])]
: options;
}
return options;
}

private static isPrimitive(type: Function) {
return PRIMITIVE_TYPES.includes(type);
}

private static isMongooseSchemaType(type: Function) {
if (!type || !type.prototype) {
return false;
}
const prototype = Object.getPrototypeOf(type.prototype);
return prototype && prototype.constructor === mongoose.SchemaType;
}
}
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './decorators';
export * from './factories';
export * from './interfaces';
export * from './mongoose.module';
export * from './utils';
2 changes: 2 additions & 0 deletions lib/mongoose.constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const DEFAULT_DB_CONNECTION = 'DatabaseConnection';
export const MONGOOSE_MODULE_OPTIONS = 'MongooseModuleOptions';
export const MONGOOSE_CONNECTION_NAME = 'MongooseConnectionName';

export const RAW_OBJECT_DEFINITION = 'RAW_OBJECT_DEFINITION';
1 change: 1 addition & 0 deletions lib/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './raw.util';
10 changes: 10 additions & 0 deletions lib/utils/raw.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { RAW_OBJECT_DEFINITION } from '../mongoose.constants';

export function raw(definition: Record<string, any>) {
Object.defineProperty(definition, RAW_OBJECT_DEFINITION, {
value: true,
enumerable: false,
configurable: false,
});
return definition;
}
Loading

0 comments on commit 8bf77f8

Please sign in to comment.