Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

type-mongodb

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

type-mongodb - npm Package Compare versions

Comparing version 0.0.0-alpha to 0.0.1-beta1

lib/document/DocumentTransformer.d.ts

21

lib/connection/Connection.d.ts

@@ -1,8 +0,23 @@

import { MongoClient } from 'mongodb';
import { MongoClient, MongoClientOptions, Db } from 'mongodb';
export interface ConnectionOptions {
database: string;
client?: MongoClient;
uri?: string;
options?: MongoClientOptions;
}
export declare class Connection {
readonly client: MongoClient;
readonly name: string;
readonly database: string;
constructor(client: MongoClient, name: string, database: string);
private constructor();
getDatabase(connection: Connection, database?: string): Db;
/**
* Makes connections to all the configured databases.
*/
connect(): Promise<void>;
/**
* Closes all the open connections.
*/
close(force?: boolean): Promise<void>;
static create(opts: ConnectionOptions): Connection;
}
//# sourceMappingURL=Connection.d.ts.map
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const mongodb_1 = require("mongodb");
class Connection {
constructor(client, name, database) {
constructor(client, database) {
this.client = client;
this.name = name;
this.database = database;
}
getDatabase(connection, database) {
return this.client.db(database || connection.database);
}
/**
* Makes connections to all the configured databases.
*/
connect() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.client.isConnected()) {
yield this.client.connect();
}
});
}
/**
* Closes all the open connections.
*/
close(force) {
return __awaiter(this, void 0, void 0, function* () {
if (this.client.isConnected()) {
yield this.client.close(force);
}
});
}
static create(opts) {
if (!opts.client && !opts.uri) {
throw new Error('Invalid connection config. Missing "uri" or "client".');
}
const client = opts.client ||
new mongodb_1.MongoClient(opts.uri, Object.assign(Object.assign({}, (opts.options || {})), { useNewUrlParser: true, useUnifiedTopology: true }));
return new Connection(client, opts.database);
}
}
exports.Connection = Connection;
//# sourceMappingURL=Connection.js.map

@@ -0,9 +1,12 @@

import { Newable } from '../types';
import { Repository } from '../repository';
interface DocumentOptions {
connection?: string;
database?: string;
collection?: string;
extensions?: Record<any, any>;
repository?: () => Newable<Repository<any>>;
}
export declare function Document(options?: DocumentOptions): ClassDecorator;
interface FieldOptions {
name?: string;
extensions?: Record<any, any>;

@@ -13,3 +16,4 @@ }

export declare function Field(embedded?: () => any, options?: FieldOptions): PropertyDecorator;
export declare function Parent(): PropertyDecorator;
export {};
//# sourceMappingURL=index.d.ts.map

@@ -6,3 +6,3 @@ "use strict";

return (target) => {
definitionStorage_1.definitionStorage.documents.set(target, Object.assign(Object.assign({}, options), { DocumentClass: target, connection: options.connection || 'default', database: options.database, collection: options.collection || target.name }));
definitionStorage_1.definitionStorage.documents.set(target, Object.assign(Object.assign({}, options), { DocumentClass: target, repository: options.repository, database: options.database, collection: options.collection || target.name }));
};

@@ -21,3 +21,3 @@ }

}
const meta = Object.assign(Object.assign({}, options), { DocumentClass: target.constructor, fieldName: field, isEmbedded: typeof embedded !== 'undefined', embedded });
const meta = Object.assign(Object.assign({}, options), { DocumentClass: target.constructor, propertyName: field, fieldName: options.name || field, isEmbedded: typeof embedded !== 'undefined', embedded });
if (definitionStorage_1.definitionStorage.fields.has(meta.DocumentClass)) {

@@ -32,2 +32,15 @@ definitionStorage_1.definitionStorage.fields.get(meta.DocumentClass).set(field, meta);

exports.Field = Field;
function Parent() {
return (target, propertyName) => {
const meta = {
DocumentClass: target.constructor,
propertyName
};
if (definitionStorage_1.definitionStorage.parents.has(meta.DocumentClass)) {
throw new Error(`Parent already exists for "${target.constructor.name}"`);
}
definitionStorage_1.definitionStorage.parents.set(meta.DocumentClass, meta);
};
}
exports.Parent = Parent;
//# sourceMappingURL=index.js.map

82

lib/DocumentManager.d.ts

@@ -1,13 +0,19 @@

import { Collection, Db } from 'mongodb';
import { Newable, Cursor, OptionalId, InsertOneOptions, InsertOneResult, InsertManyOptions, InsertManyResult, FilterQuery, FindOptions, FindOneOptions, FindOneAndDeleteOptions, FindOneAndUpdateOptions, UpdateQuery, FindOneAndReplaceOptions, UpdateManyResult, UpdateManyOptions, UpdateOneResult, UpdateOneOptions, ReplaceOneResult, ReplaceOneOptions, DeleteOptions, DeleteResult, FieldsOf, WithId } from './common/types';
import { MongoClient, SessionOptions } from 'mongodb';
import { DocumentClass, Collection, Db, Newable } from './types';
import { DocumentMetadataFactory } from './metadata/DocumentMetadataFactory';
import { DocumentMetadata } from './metadata/DocumentMetadata';
import { ConnectionManager, ConnectionManagerOptions } from './connection/ConnectionManager';
import { Connection, ConnectionOptions } from './connection/Connection';
import { EventSubscriber } from './events/interfaces';
import { EventManager } from './events';
import { Repository } from './repository/Repository';
import { Session } from './transaction/Session';
import { EmbeddedDocumentMetadata } from './metadata/EmbeddedDocumentMetadata';
export interface ContainerLike {
get: <T = any>(service: Newable<T>) => T;
}
export interface DocumentManagerOptions {
connections?: ConnectionManagerOptions[];
connection?: ConnectionManagerOptions;
documents: Newable<any>[];
connection: ConnectionOptions;
documents: DocumentClass<any>[];
subscribers?: EventSubscriber[];
container?: ContainerLike;
}

@@ -22,4 +28,5 @@ /**

readonly metadataFactory: DocumentMetadataFactory;
readonly connectionManager: ConnectionManager;
readonly connection: Connection;
readonly eventManager: EventManager;
readonly container: ContainerLike;
constructor(opts: DocumentManagerOptions);

@@ -31,10 +38,27 @@ buildMetadata(): void;

*/
getMetadataFor<M, D = FieldsOf<M>>(DocumentClass: Newable<M>): DocumentMetadata<M, D>;
getMetadataFor<T>(DocumentClass: DocumentClass<T>): DocumentMetadata<T>;
/**
* Gets the EmbeddedDocumentMetadata for the given class.
*/
getEmbeddedMetadataFor<T>(EmbeddedDocumentClass: Newable<T>): EmbeddedDocumentMetadata<T>;
/**
* Gets the DocumentMetadata for the given class.
*/
getAnyMetadata<T>(Cls: DocumentClass<T> | Newable<T>): DocumentMetadata<T> | EmbeddedDocumentMetadata<T>;
/**
* Filters metadata by given criteria.
*/
filterMetadata(filter: (value: DocumentMetadata) => boolean): DocumentMetadata[];
toDB<M, D = FieldsOf<M>>(DocumentClass: Newable<M>, model: M): D;
fromDB<M, D = FieldsOf<M>>(DocumentClass: Newable<M>, doc: D): M;
init<M>(DocumentClass: Newable<M>, props: Partial<M>): M;
init<T>(DocumentClass: DocumentClass<T> | Newable<T>, props: Partial<T> | {
[key: string]: any;
}): T;
merge<T>(DocumentClass: DocumentClass<T> | Newable<T>, model: T, props: Partial<T> | {
[key: string]: any;
}): T;
toDB<T>(DocumentClass: DocumentClass<T> | Newable<T>, model: T): T & {
[key: string]: any;
};
fromDB<T>(DocumentClass: DocumentClass<T> | Newable<T>, doc: Partial<T> | {
[key: string]: any;
}): T;
/**

@@ -45,2 +69,6 @@ * Connects to all configured MongoClients.

/**
* Gets the mongo database for the class.
*/
client(): MongoClient;
/**
* Closes to all MongoClients.

@@ -52,35 +80,11 @@ */

*/
db(target: Newable): Db;
db<T>(target: DocumentClass<T>): Db;
/**
* Gets the mongo Collection for the class.
*/
collection<M = any, D = FieldsOf<M>>(target: Newable<M>): Collection<M>;
find<M = any>(target: Newable<M>, query?: FilterQuery<M>): Cursor<M>;
find<M = any>(target: Newable<M>, query: FilterQuery<M>, options?: FindOptions): Cursor<M>;
findById<M = any>(target: Newable<M>, id: any): Promise<M | null>;
findByIdOrFail<M = any>(target: Newable<M>, id: any): Promise<M>;
findOne<M = any>(target: Newable<M>, filter: FilterQuery<WithId<M>>, opts?: FindOneOptions): Promise<M | null>;
findOneOrFail<M = any>(target: Newable<M>, filter: FilterQuery<M>, opts?: FindOneOptions): Promise<M | null>;
create<M = any, D = FieldsOf<M>>(target: Newable<M>, props: OptionalId<D>, opts?: InsertOneOptions): Promise<M>;
create<M = any, D = FieldsOf<M>>(target: Newable<M>, props: OptionalId<D>[], opts?: InsertManyOptions): Promise<M[]>;
insertOne<M = any>(model: OptionalId<M>, opts?: InsertOneOptions): Promise<InsertOneResult>;
insertMany<M = any>(target: Newable<M>, models: OptionalId<M>[], opts?: InsertManyOptions): Promise<InsertManyResult>;
findOneAndUpdate<M = any>(target: Newable<M>, filter: FilterQuery<M>, update: UpdateQuery<M>, opts?: FindOneAndUpdateOptions): Promise<M | null>;
findOneAndReplace<M = any, D = FieldsOf<M>>(target: Newable<M>, filter: FilterQuery<M>, props: OptionalId<D>, opts?: FindOneAndReplaceOptions): Promise<M | null>;
findOneAndDelete<M = any>(target: Newable<M>, filter: FilterQuery<M>, opts?: FindOneAndDeleteOptions): Promise<M | null>;
updateOne<M = any>(target: Newable<M>, filter: FilterQuery<M>, update: UpdateQuery<M>, opts?: UpdateOneOptions): Promise<UpdateOneResult>;
updateMany<M = any>(target: Newable<M>, filter: FilterQuery<M>, update: UpdateQuery<M>, opts?: UpdateManyOptions): Promise<UpdateManyResult>;
replaceOne<M = any, D = FieldsOf<M>>(target: Newable<M>, filter: FilterQuery<M>, props: OptionalId<D>, opts?: ReplaceOneOptions): Promise<ReplaceOneResult>;
deleteOne<M = any>(target: Newable<M>, filter: FilterQuery<M>, opts?: DeleteOptions & {
bypassDocumentValidation?: boolean;
}): Promise<boolean>;
deleteMany<M = any>(target: Newable<M>, filter: FilterQuery<M>, opts?: DeleteOptions): Promise<DeleteResult>;
protected findOneForMeta<M = any>(meta: DocumentMetadata<M>, filter: any, opts?: FindOneOptions): Promise<M | null>;
protected failIfEmpty<M>(meta: DocumentMetadata<M>, criteria: FilterQuery<any>, value: any): any;
protected mapResultFromDB<M = any>(data: {
ok?: number;
value?: any;
}, meta: DocumentMetadata<M>): M | null;
collection<T>(target: DocumentClass<T>): Collection<T>;
getRepository<T extends Repository<any>>(target: DocumentClass): T;
startSession(opts?: SessionOptions): Session;
static create(opts: DocumentManagerOptions): Promise<DocumentManager>;
}
//# sourceMappingURL=DocumentManager.d.ts.map

@@ -13,6 +13,8 @@ "use strict";

const DocumentMetadataFactory_1 = require("./metadata/DocumentMetadataFactory");
const errors_1 = require("./errors");
const ConnectionManager_1 = require("./connection/ConnectionManager");
const interfaces_1 = require("./events/interfaces");
const Connection_1 = require("./connection/Connection");
const events_1 = require("./events");
const Session_1 = require("./transaction/Session");
const defaultContainer = {
get: (Service) => new Service()
};
/**

@@ -26,9 +28,6 @@ * DocumentManager is responsible for all mapped document classes.

this.opts = opts;
if (this.opts.connection && this.opts.connections) {
throw new Error('DocumentManager cannot have both "connection" and "connections" options.');
}
if (!this.opts.connection && !this.opts.connections) {
if (!this.opts.connection) {
throw new Error('DocumentManager needs a connection.');
}
this.connectionManager = ConnectionManager_1.ConnectionManager.create(this.opts.connection ? [this.opts.connection] : this.opts.connections);
this.connection = Connection_1.Connection.create(this.opts.connection);
this.metadataFactory = new DocumentMetadataFactory_1.DocumentMetadataFactory({

@@ -39,2 +38,3 @@ dm: this,

this.eventManager = new events_1.EventManager(this.opts.subscribers);
this.container = opts.container || defaultContainer;
}

@@ -57,2 +57,26 @@ // -------------------------------------------------------------------------

/**
* Gets the EmbeddedDocumentMetadata for the given class.
*/
getEmbeddedMetadataFor(EmbeddedDocumentClass) {
return this.metadataFactory.getEmbeddedMetadataFor(EmbeddedDocumentClass);
}
/**
* Gets the DocumentMetadata for the given class.
*/
getAnyMetadata(Cls) {
try {
return this.getMetadataFor(Cls);
}
catch (err) {
// no-op
}
try {
return this.getEmbeddedMetadataFor(Cls);
}
catch (err) {
// no-op
}
throw new Error(`Missing metadata for "${Cls.name}"`);
}
/**
* Filters metadata by given criteria.

@@ -63,11 +87,14 @@ */

}
init(DocumentClass, props) {
return this.getAnyMetadata(DocumentClass).init(props);
}
merge(DocumentClass, model, props) {
return this.getAnyMetadata(DocumentClass).merge(model, props);
}
toDB(DocumentClass, model) {
return this.metadataFactory.getMetadataFor(DocumentClass).toDB(model);
return this.getAnyMetadata(DocumentClass).toDB(model);
}
fromDB(DocumentClass, doc) {
return this.metadataFactory.getMetadataFor(DocumentClass).fromDB(doc);
return this.getAnyMetadata(DocumentClass).fromDB(doc);
}
init(DocumentClass, props) {
return this.metadataFactory.getMetadataFor(DocumentClass).init(props);
}
// -------------------------------------------------------------------------

@@ -80,9 +107,15 @@ // MongoDB specific methods

connect() {
return this.connectionManager.connect();
return this.connection.connect();
}
/**
* Gets the mongo database for the class.
*/
client() {
return this.connection.client;
}
/**
* Closes to all MongoClients.
*/
close(force) {
return this.connectionManager.close(force);
return this.connection.close(force);
}

@@ -101,185 +134,12 @@ /**

}
find(target, query, opts) {
const meta = this.getMetadataFor(target);
const cursor = meta.collection.find(query, opts);
cursor.map((doc) => meta.fromDB(doc));
return cursor;
getRepository(target) {
return this.getMetadataFor(target).repository;
}
findById(target, id) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return this.findOneForMeta(meta, { _id: meta.id(id) });
});
}
findByIdOrFail(target, id) {
return __awaiter(this, void 0, void 0, function* () {
return this.failIfEmpty(this.getMetadataFor(target), { _id: id }, yield this.findById(target, id));
});
}
findOne(target, filter, opts) {
return __awaiter(this, void 0, void 0, function* () {
return this.findOneForMeta(this.getMetadataFor(target), filter, opts);
});
}
findOneOrFail(target, filter, opts) {
return __awaiter(this, void 0, void 0, function* () {
return this.failIfEmpty(this.getMetadataFor(target), filter, yield this.findOne(target, filter, opts));
});
}
create(target, props, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
if (!Array.isArray(props)) {
const model = meta.init(props);
const { result } = yield this.insertOne(model, opts);
return result && result.ok ? model : null;
}
const models = props.map(p => meta.init(p));
const { insertedIds } = yield this.insertMany(target, models, opts);
return Object.keys(insertedIds).map(i => models[i]);
});
}
insertOne(model, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(model.constructor);
if (!model._id) {
model._id = meta.id();
}
return this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeInsert, interfaces_1.Events.AfterInsert, {
meta,
model
}, () => meta.collection.insertOne(meta.toDB(model), opts));
});
}
insertMany(target, models, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
const beforeInsertEvents = [];
const afterInsertEvents = [];
models.forEach(model => {
if (!model._id) {
model._id = meta.id();
}
beforeInsertEvents.push(this.eventManager.dispatch(interfaces_1.Events.BeforeInsert, {
meta,
model
}));
afterInsertEvents.push(this.eventManager.dispatch(interfaces_1.Events.AfterInsert, {
meta,
model
}));
});
yield Promise.all(beforeInsertEvents);
const result = meta.collection.insertMany(models.map(model => {
if (!model._id) {
model._id = meta.id();
}
return meta.toDB(model);
}), opts);
yield Promise.all(afterInsertEvents);
return result;
});
}
findOneAndUpdate(target, filter, update, opts = {}) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return yield this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeUpdate, interfaces_1.Events.AfterUpdate, {
meta,
filter,
update
}, () => __awaiter(this, void 0, void 0, function* () {
const result = yield meta.collection.findOneAndUpdate(filter, update, Object.assign({ returnOriginal: false }, opts));
return this.mapResultFromDB(result, meta);
}));
});
}
findOneAndReplace(target, filter, props, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
const result = yield meta.collection.findOneAndReplace(filter, meta.init(props), Object.assign({ returnOriginal: false }, opts));
return this.mapResultFromDB(result, meta);
});
}
findOneAndDelete(target, filter, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return yield this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeDelete, interfaces_1.Events.AfterDelete, {
meta,
filter
}, () => __awaiter(this, void 0, void 0, function* () {
const result = yield meta.collection.findOneAndDelete(filter, opts);
return this.mapResultFromDB(result, meta);
}));
});
}
updateOne(target, filter, update, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeUpdate, interfaces_1.Events.AfterUpdate, {
filter,
meta,
update
}, () => meta.collection.updateOne(filter, update, opts));
});
}
updateMany(target, filter, update, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeUpdateMany, interfaces_1.Events.AfterUpdateMany, {
filter,
meta,
update
}, () => meta.collection.updateMany(filter, update, opts));
});
}
replaceOne(target, filter, props, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return yield meta.collection.replaceOne(filter, meta.toDB(meta.init(props)), opts);
});
}
deleteOne(target, filter, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return yield this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeDelete, interfaces_1.Events.AfterDelete, {
filter,
meta
}, () => __awaiter(this, void 0, void 0, function* () {
const result = yield meta.collection.deleteOne(filter, opts);
return result && result.deletedCount === 1;
}));
});
}
deleteMany(target, filter, opts) {
return __awaiter(this, void 0, void 0, function* () {
const meta = this.getMetadataFor(target);
return this.eventManager.dispatchBeforeAndAfter(interfaces_1.Events.BeforeDeleteMany, interfaces_1.Events.AfterDeleteMany, {
filter,
meta
}, () => this.getMetadataFor(target).collection.deleteMany(filter, opts));
});
}
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
findOneForMeta(meta, filter, opts) {
return __awaiter(this, void 0, void 0, function* () {
const found = yield meta.collection.findOne(filter, opts);
return found ? meta.fromDB(found) : null;
});
}
failIfEmpty(meta, criteria, value) {
if (!value) {
if (criteria &&
Object.keys(criteria).length === 1 &&
typeof criteria._id !== 'undefined') {
throw new errors_1.TypeMongoError(`"${meta.name}" with id "${criteria._id}" not found`);
}
throw new errors_1.TypeMongoError(`"${meta.name}" not found with criteria: '${JSON.stringify(criteria)}'`);
startSession(opts) {
const session = new Session_1.Session(this);
if (opts) {
session.setSessionOptions(opts);
}
return value;
return session;
}
mapResultFromDB(data, meta) {
return data && data.ok && data.value ? meta.fromDB(data.value) : null;
}
// -------------------------------------------------------------------------

@@ -286,0 +146,0 @@ // Static Methods

@@ -1,4 +0,3 @@

export declare class TypeMongoError extends Error {
constructor(message: string);
}
export * from './BaseError';
export * from './DocumentNotFound';
//# sourceMappingURL=index.d.ts.map
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
class TypeMongoError extends Error {
constructor(message) {
super(message);
Error.captureStackTrace(this, TypeMongoError);
}
}
exports.TypeMongoError = TypeMongoError;
__export(require("./BaseError"));
__export(require("./DocumentNotFound"));
//# sourceMappingURL=index.js.map
import { Events, EventSubscriber, InsertEvent, UpdateEvent, DeleteEvent } from './interfaces';
import { Newable } from '../common';
import { Newable } from '../types';
import { DocumentManager } from '../DocumentManager';

@@ -24,7 +24,11 @@ declare type EventSubscribers = Map<Events, EventSubscriber[]>;

build(dm: DocumentManager): void;
dispatchBeforeAndAfter<M = any, R = any>(before: Events, after: Events, e: InsertEvent<M> | UpdateEvent<M> | DeleteEvent<M>, run: () => Promise<R>): Promise<R>;
dispatchBeforeAndAfter<T1 = any, T2 = any>(before: Events.BeforeInsert, after: Events.AfterInsert, e: InsertEvent<T1>, run: () => Promise<T2>): Promise<T2>;
dispatchBeforeAndAfter<T1 = any, T2 = any>(before: Events.BeforeUpdate, after: Events.AfterUpdate, e: UpdateEvent<T1>, run: () => Promise<T2>): Promise<T2>;
dispatchBeforeAndAfter<T1 = any, T2 = any>(before: Events.BeforeDelete, after: Events.AfterDelete, e: DeleteEvent<T1>, run: () => Promise<T2>): Promise<T2>;
dispatchBeforeAndAfter<T1 = any, T2 = any>(before: Events.BeforeUpdateMany, after: Events.AfterUpdateMany, e: UpdateEvent<T1>, run: () => Promise<T2>): Promise<T2>;
dispatchBeforeAndAfter<T1 = any, T2 = any>(before: Events.BeforeDeleteMany, after: Events.AfterDeleteMany, e: DeleteEvent<T1>, run: () => Promise<T2>): Promise<T2>;
/**
* Dispatches the all the subscribed events for the document.
*/
dispatch<M = any>(type: Events, e: InsertEvent<M> | UpdateEvent<M> | DeleteEvent<M>): Promise<void>;
dispatch<T = any>(type: Events, e: InsertEvent<T> | UpdateEvent<T> | DeleteEvent<T>): Promise<void>;
/**

@@ -31,0 +35,0 @@ * Attaches the subscriber's defined methods to the document.

@@ -40,3 +40,3 @@ "use strict";

this.documentsWithSubscribers.clear();
const documents = Array.from(dm.metadataFactory.loadedMetadata.values()).map(meta => meta.DocumentClass);
const documents = Array.from(dm.metadataFactory.loadedDocumentMetadata.values()).map(meta => meta.DocumentClass);
this.subscribers.forEach(subscriber => {

@@ -43,0 +43,0 @@ const subscribedDocuments = typeof subscriber.getSubscribedDocuments === 'function'

import { DocumentMetadata } from '../metadata/DocumentMetadata';
import { DocumentManager } from '../DocumentManager';
import { FilterQuery } from '../common/types';
import { FilterQuery, UpdateQuery } from '../types';
export declare enum Events {

@@ -16,28 +16,28 @@ BeforeInsert = "beforeInsert",

}
export interface Event<M = any> {
meta: DocumentMetadata<M>;
export interface Event<T = any> {
meta: DocumentMetadata<T>;
}
export interface InsertEvent<M = any> extends Event<M> {
model: M;
export interface InsertEvent<T = any> extends Event<T> {
model: T;
}
export interface UpdateEvent<M = any> extends Event<M> {
update: any;
filter: FilterQuery<M>;
export interface UpdateEvent<T = any> extends Event<T> {
update: UpdateQuery<T>;
filter: FilterQuery<T>;
}
export interface DeleteEvent<M = any> extends Event<M> {
filter: FilterQuery<M>;
export interface DeleteEvent<T = any> extends Event<T> {
filter: FilterQuery<T>;
}
export interface EventSubscriber<M = any> {
export interface EventSubscriber<T = any> {
getSubscribedDocuments?(dm: DocumentManager): any[];
beforeInsert?(e: InsertEvent<M>): Promise<void> | void;
afterInsert?(e: InsertEvent<M>): Promise<void> | void;
beforeUpdate?(e: UpdateEvent<M>): Promise<void> | void;
afterUpdate?(e: UpdateEvent<M>): Promise<void> | void;
beforeDelete?(e: DeleteEvent<M>): Promise<void> | void;
afterDelete?(e: DeleteEvent<M>): Promise<void> | void;
beforeUpdateMany?(e: UpdateEvent<M>): Promise<void> | void;
afterUpdateMany?(e: UpdateEvent<M>): Promise<void> | void;
beforeDeleteMany?(e: DeleteEvent<M>): Promise<void> | void;
afterDeleteMany?(e: DeleteEvent<M>): Promise<void> | void;
beforeInsert?(e: InsertEvent<T>): Promise<void> | void;
afterInsert?(e: InsertEvent<T>): Promise<void> | void;
beforeUpdate?(e: UpdateEvent<T>): Promise<void> | void;
afterUpdate?(e: UpdateEvent<T>): Promise<void> | void;
beforeDelete?(e: DeleteEvent<T>): Promise<void> | void;
afterDelete?(e: DeleteEvent<T>): Promise<void> | void;
beforeUpdateMany?(e: UpdateEvent<T>): Promise<void> | void;
afterUpdateMany?(e: UpdateEvent<T>): Promise<void> | void;
beforeDeleteMany?(e: DeleteEvent<T>): Promise<void> | void;
afterDeleteMany?(e: DeleteEvent<T>): Promise<void> | void;
}
//# sourceMappingURL=interfaces.d.ts.map
export * from './decorators';
export * from './Model';
export * from './DocumentManager';
export * from './events/interfaces';
export { ObjectId, Cursor } from './common/types';
export * from './metadata/DocumentMetadata';
export * from './metadata/EmbeddedDocumentMetadata';
export * from './events';
export * from './repository';
export * from './types';
export * from './utils/testUtils';
//# sourceMappingURL=index.d.ts.map

@@ -7,8 +7,9 @@ "use strict";

__export(require("./decorators"));
__export(require("./Model"));
__export(require("./DocumentManager"));
__export(require("./events/interfaces"));
var types_1 = require("./common/types");
exports.ObjectId = types_1.ObjectId;
exports.Cursor = types_1.Cursor;
__export(require("./metadata/DocumentMetadata"));
__export(require("./metadata/EmbeddedDocumentMetadata"));
__export(require("./events"));
__export(require("./repository"));
__export(require("./types"));
__export(require("./utils/testUtils"));
//# sourceMappingURL=index.js.map

@@ -1,2 +0,3 @@

import { Newable } from '../common';
import { DocumentClass, Newable } from '../types';
import { Repository } from '../repository/Repository';
/**

@@ -7,4 +8,4 @@ * Definitions provide the metadata classes with the data to

export interface DocumentDefinition<T = any> {
DocumentClass: Newable<T>;
connection: string;
DocumentClass: DocumentClass<T>;
repository: () => Newable<Repository<T>>;
database?: string;

@@ -15,3 +16,4 @@ collection: string;

export interface FieldDefinition<T = any> {
DocumentClass: Newable<T>;
DocumentClass: DocumentClass<T>;
propertyName: string;
fieldName: string;

@@ -22,2 +24,6 @@ isEmbedded: boolean;

}
export interface ParentDefinition<T = any> {
DocumentClass: DocumentClass<T>;
propertyName: string;
}
//# sourceMappingURL=definitions.d.ts.map

@@ -1,11 +0,13 @@

import { Collection, Db, ObjectId } from 'mongodb';
import { Newable, FieldsOf } from '../common/types';
import { BaseDocumentMetadata, FieldsMetadata } from './BaseDocumentMetadata';
import { Collection, Db } from 'mongodb';
import { DocumentClass } from '../types';
import { AbstractDocumentMetadata, FieldsMetadata } from './AbstractDocumentMetadata';
import { Connection } from '../connection/Connection';
export interface DocumentMetadataOpts<M = any> {
DocumentClass: Newable<M>;
import { Repository } from '../repository/Repository';
export interface DocumentMetadataOpts<T = any> {
DocumentClass: DocumentClass<T>;
fields: FieldsMetadata;
connection: Connection;
db: Db;
collection: Collection<M>;
collection: Collection<T>;
repository: Repository<T>;
extensions?: Record<any, any>;

@@ -16,3 +18,3 @@ }

*/
export declare class DocumentMetadata<M = any, D = FieldsOf<M>> extends BaseDocumentMetadata<M, D> {
export declare class DocumentMetadata<T = any> extends AbstractDocumentMetadata<T, DocumentClass> {
readonly connection: Connection;

@@ -22,8 +24,5 @@ readonly db: Db;

readonly extensions: Record<any, any>;
constructor(opts: DocumentMetadataOpts<M>);
/**
* Creates the document _id.
*/
id(id?: string | ObjectId): ObjectId;
readonly repository: Repository<T>;
constructor(opts: DocumentMetadataOpts<T>);
}
//# sourceMappingURL=DocumentMetadata.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mongodb_1 = require("mongodb");
const BaseDocumentMetadata_1 = require("./BaseDocumentMetadata");
const AbstractDocumentMetadata_1 = require("./AbstractDocumentMetadata");
/**
* DocumentMetadata contains all the needed info for Document classes.
*/
class DocumentMetadata extends BaseDocumentMetadata_1.BaseDocumentMetadata {
class DocumentMetadata extends AbstractDocumentMetadata_1.AbstractDocumentMetadata {
constructor(opts) {

@@ -15,14 +14,7 @@ super(opts.DocumentClass, opts.fields);

this.extensions = opts.extensions || {};
this.repository = opts.repository;
this.repository.metadata = this;
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* Creates the document _id.
*/
id(id) {
return new mongodb_1.ObjectId(id);
}
}
exports.DocumentMetadata = DocumentMetadata;
//# sourceMappingURL=DocumentMetadata.js.map
import { DocumentMetadata } from './DocumentMetadata';
import { Newable, FieldsOf } from '../common/types';
import { DocumentClass, Newable } from '../types';
import { DocumentManager } from '../DocumentManager';
import { EmbeddedDocumentMetadata } from './EmbeddedDocumentMetadata';
import { FieldsMetadata } from './BaseDocumentMetadata';
import { FieldsMetadata } from './AbstractDocumentMetadata';
export interface BuildMetadataStorageOptions {
dm: DocumentManager;
documents: Newable<any>[];
documents: DocumentClass<any>[];
}

@@ -15,3 +15,4 @@ /**

readonly opts: BuildMetadataStorageOptions;
loadedMetadata: Map<Newable, DocumentMetadata<any, any>>;
loadedDocumentMetadata: Map<DocumentClass, DocumentMetadata<any>>;
loadedEmbeddedDocumentMetadata: Map<Newable, EmbeddedDocumentMetadata<any>>;
private isBuilt;

@@ -23,7 +24,15 @@ constructor(opts: BuildMetadataStorageOptions);

*/
getMetadataFor<M = any, D = FieldsOf<M>>(DocumentClass: Newable): DocumentMetadata<M, D>;
getMetadataFor<T>(DocumentClass: DocumentClass<T>): DocumentMetadata<T>;
/**
* Gets the DocumentMetadata for the given class.
*/
getEmbeddedMetadataFor<T>(EmbeddedDocumentClass: Newable<T>): EmbeddedDocumentMetadata<T>;
/**
* Filters metadata by given criteria.
*/
filterMetadata(filter: (value: DocumentMetadata) => boolean): DocumentMetadata[];
/**
* Filters metadata by given criteria.
*/
map<T>(fn: (value: DocumentMetadata, index: number, array: DocumentMetadata[]) => T): T[];
protected assertMetadataIsBuilt(): void;

@@ -37,9 +46,9 @@ /**

*/
protected buildMetadataForDocument(DocumentClass: Newable): DocumentMetadata;
protected buildEmbeddedDocumentMetadata(DocumentClass: Newable): EmbeddedDocumentMetadata;
protected buildMetadataForDocument(DocumentClass: DocumentClass): DocumentMetadata;
protected buildEmbeddedDocumentMetadata(DocumentClass: DocumentClass): EmbeddedDocumentMetadata;
/**
* Recursively adds fields to the DocumentMetadata.
*/
protected buildFields(target: Newable, fields?: FieldsMetadata): FieldsMetadata;
protected buildFields(target: DocumentClass, fields?: FieldsMetadata): FieldsMetadata;
}
//# sourceMappingURL=DocumentMetadataFactory.d.ts.map

@@ -6,4 +6,4 @@ "use strict";

const definitionStorage_1 = require("../utils/definitionStorage");
const errors_1 = require("../errors");
const EmbeddedDocumentMetadata_1 = require("./EmbeddedDocumentMetadata");
const repository_1 = require("../repository");
/**

@@ -15,3 +15,4 @@ * DocumentMetadataFactory builds and validates all the Document's metadata.

this.opts = opts;
this.loadedMetadata = new Map();
this.loadedDocumentMetadata = new Map();
this.loadedEmbeddedDocumentMetadata = new Map();
this.isBuilt = false;

@@ -24,3 +25,3 @@ }

if (this.isBuilt) {
throw new errors_1.TypeMongoError('DocumentMetadata already built');
throw new Error('DocumentMetadata already built');
}

@@ -35,10 +36,31 @@ this.buildDocuments();

this.assertMetadataIsBuilt();
return this.loadedMetadata.get(DocumentClass);
const meta = this.loadedDocumentMetadata.get(DocumentClass);
if (!meta) {
throw new Error(`DocumentMetadata for class "${DocumentClass.name}" does not exist`);
}
return meta;
}
/**
* Gets the DocumentMetadata for the given class.
*/
getEmbeddedMetadataFor(EmbeddedDocumentClass) {
this.assertMetadataIsBuilt();
const meta = this.loadedEmbeddedDocumentMetadata.get(EmbeddedDocumentClass);
if (!meta) {
throw new Error(`EmbeddedDocumentMetadata for class "${EmbeddedDocumentClass.name}" does not exist`);
}
return meta;
}
/**
* Filters metadata by given criteria.
*/
filterMetadata(filter) {
return Array.from(this.loadedMetadata.values()).filter(filter);
return Array.from(this.loadedDocumentMetadata.values()).filter(filter);
}
/**
* Filters metadata by given criteria.
*/
map(fn) {
return Array.from(this.loadedDocumentMetadata.values()).map(fn);
}
// -------------------------------------------------------------------------

@@ -49,3 +71,3 @@ // Protected Methods

if (!this.isBuilt) {
throw new errors_1.TypeMongoError('DocumentMetadata is not initialized');
throw new Error('DocumentMetadata is not initialized');
}

@@ -58,3 +80,3 @@ }

this.opts.documents.forEach(DocumentClass => {
this.loadedMetadata.set(DocumentClass, this.buildMetadataForDocument(DocumentClass));
this.loadedDocumentMetadata.set(DocumentClass, this.buildMetadataForDocument(DocumentClass));
});

@@ -67,12 +89,11 @@ }

if (!definitionStorage_1.definitionStorage.documents.has(DocumentClass)) {
throw new errors_1.TypeMongoError(`"${DocumentClass.name}" is not a decorated @Document()`);
throw new Error(`"${DocumentClass.name}" is not a decorated @Document()`);
}
const def = definitionStorage_1.definitionStorage.documents.get(DocumentClass);
const connection = this.opts.dm.connectionManager.getConnection(def.connection);
const db = this.opts.dm.connectionManager.getDatabase(connection, def.database);
// Duck-type check if class is like the Model class for active-record style functionality
if (typeof def.DocumentClass.setDocumentManager === 'function') {
def.DocumentClass.setDocumentManager(this.opts.dm);
}
return new DocumentMetadata_1.DocumentMetadata({
const connection = this.opts.dm.connection;
const db = connection.getDatabase(connection, def.database);
const RepositoryClass = def.repository ? def.repository() : repository_1.Repository;
const repository = this.opts.dm.container.get(RepositoryClass);
repository.manager = this.opts.dm;
const meta = new DocumentMetadata_1.DocumentMetadata({
DocumentClass,

@@ -83,7 +104,9 @@ fields: this.buildFields(DocumentClass),

collection: db.collection(def.collection),
repository,
extensions: def.extensions || {}
});
return meta;
}
buildEmbeddedDocumentMetadata(DocumentClass) {
return new EmbeddedDocumentMetadata_1.EmbeddedDocumentMetadata(DocumentClass, this.buildFields(DocumentClass));
return new EmbeddedDocumentMetadata_1.EmbeddedDocumentMetadata(DocumentClass, this.buildFields(DocumentClass), definitionStorage_1.definitionStorage.parents.get(DocumentClass));
}

@@ -94,23 +117,32 @@ /**

buildFields(target, fields) {
if (!definitionStorage_1.definitionStorage.fields.has(target)) {
throw new errors_1.TypeMongoError(`"${target.name}" does not have any fields`);
}
fields = fields || new Map();
definitionStorage_1.definitionStorage.fields.get(target).forEach(prop => {
if (!prop.isEmbedded) {
fields.set(prop.fieldName, new FieldMetadata_1.FieldMetadata(Object.assign(Object.assign({}, prop), { isEmbeddedArray: false })));
}
else {
let embeddedType = prop.embedded();
const isEmbeddedArray = Array.isArray(embeddedType);
if (isEmbeddedArray) {
embeddedType = embeddedType[0];
if (definitionStorage_1.definitionStorage.fields.has(target)) {
definitionStorage_1.definitionStorage.fields.get(target).forEach(prop => {
if (!prop.isEmbedded) {
fields.set(prop.fieldName, new FieldMetadata_1.FieldMetadata(Object.assign(Object.assign({}, prop), { isEmbeddedArray: false })));
}
fields.set(prop.fieldName, new FieldMetadata_1.FieldMetadata(Object.assign(Object.assign({}, prop), { isEmbeddedArray, embeddedMetadata: this.buildEmbeddedDocumentMetadata(embeddedType), embeddedType })));
else {
let embeddedType = prop.embedded();
const isEmbeddedArray = Array.isArray(embeddedType);
if (isEmbeddedArray) {
embeddedType = embeddedType[0];
}
const embeddedMetadata = this.buildEmbeddedDocumentMetadata(embeddedType);
this.loadedEmbeddedDocumentMetadata.set(embeddedType, embeddedMetadata);
fields.set(prop.fieldName, new FieldMetadata_1.FieldMetadata(Object.assign(Object.assign({}, prop), { isEmbeddedArray,
embeddedMetadata,
embeddedType })));
}
});
}
let parent = Object.getPrototypeOf(target);
while (parent && parent.prototype) {
if (definitionStorage_1.definitionStorage.fields.has(parent)) {
this.buildFields(parent, fields);
}
});
const parent = Object.getPrototypeOf(target);
if (parent && definitionStorage_1.definitionStorage.documents.has(parent)) {
this.buildFields(parent, fields);
parent = Object.getPrototypeOf(parent);
}
if (!fields.size) {
throw new Error(`"${target.name}" does not have any fields`);
}
return fields;

@@ -117,0 +149,0 @@ }

@@ -1,8 +0,7 @@

import { FieldsOf } from '../common/types';
import { BaseDocumentMetadata } from './BaseDocumentMetadata';
import { AbstractDocumentMetadata } from './AbstractDocumentMetadata';
/**
* DocumentMetadata contains all the needed info for Document classes.
*/
export declare class EmbeddedDocumentMetadata<M = any, D = FieldsOf<M>> extends BaseDocumentMetadata<M, D> {
export declare class EmbeddedDocumentMetadata<T = any> extends AbstractDocumentMetadata<T> {
}
//# sourceMappingURL=EmbeddedDocumentMetadata.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const BaseDocumentMetadata_1 = require("./BaseDocumentMetadata");
const AbstractDocumentMetadata_1 = require("./AbstractDocumentMetadata");
/**
* DocumentMetadata contains all the needed info for Document classes.
*/
class EmbeddedDocumentMetadata extends BaseDocumentMetadata_1.BaseDocumentMetadata {
class EmbeddedDocumentMetadata extends AbstractDocumentMetadata_1.AbstractDocumentMetadata {
}
exports.EmbeddedDocumentMetadata = EmbeddedDocumentMetadata;
//# sourceMappingURL=EmbeddedDocumentMetadata.js.map

@@ -1,2 +0,2 @@

import { Newable } from '../common/types';
import { Newable } from '../types';
import { EmbeddedDocumentMetadata } from './EmbeddedDocumentMetadata';

@@ -9,4 +9,5 @@ import { FieldDefinition } from './definitions';

}
export declare class FieldMetadata<M = any> {
readonly DocumentClass: Newable<M>;
export declare class FieldMetadata<T = any> {
readonly DocumentClass: Newable<T>;
readonly propertyName: string;
readonly fieldName: string;

@@ -13,0 +14,0 @@ readonly database: string;

@@ -6,2 +6,3 @@ "use strict";

this.DocumentClass = opts.DocumentClass;
this.propertyName = opts.propertyName;
this.fieldName = opts.fieldName;

@@ -8,0 +9,0 @@ this.embedded = opts.embedded;

@@ -1,11 +0,13 @@

import { Newable } from '../common';
import { DocumentDefinition, FieldDefinition } from '../metadata/definitions';
import { DocumentClass } from '../types';
import { DocumentDefinition, FieldDefinition, ParentDefinition } from '../metadata/definitions';
declare type FieldName = string;
declare type DocumentStorage = Map<Newable<any>, DocumentDefinition>;
declare type FieldStorage = Map<Newable<any>, Map<FieldName, FieldDefinition>>;
declare type DocumentStorage = Map<DocumentClass<any>, DocumentDefinition>;
declare type FieldStorage = Map<DocumentClass<any>, Map<FieldName, FieldDefinition>>;
declare type ParentStorage = Map<DocumentClass<any>, ParentDefinition>;
export declare const definitionStorage: {
documents: DocumentStorage;
fields: FieldStorage;
parents: ParentStorage;
};
export {};
//# sourceMappingURL=definitionStorage.d.ts.map

@@ -5,4 +5,5 @@ "use strict";

documents: new Map(),
fields: new Map()
fields: new Map(),
parents: new Map()
};
//# sourceMappingURL=definitionStorage.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("../errors");
exports.builtins = [String, Number, Date, Boolean];

@@ -14,3 +13,3 @@ function isBuiltin(type) {

if (isBuiltin(type)) {
throw new errors_1.TypeMongoError(`No need to set field type on for: ObjectId, ${exports.builtins
throw new Error(`No need to set field type on for: ObjectId, ${exports.builtins
.map(type => type.name)

@@ -17,0 +16,0 @@ .join(', ')}`);

{
"name": "type-mongodb",
"version": "0.0.0-alpha",
"version": "0.0.1-beta1",
"description": "A simple decorator based MongoDB ODM.",

@@ -34,3 +34,3 @@ "keywords": [],

"@types/jest": "^24.0.18",
"@types/mongodb": "^3.3.1",
"@types/mongodb": "3.3.7",
"husky": "^3.0.5",

@@ -37,0 +37,0 @@ "jest": "^24.9.0",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc