Socket
Socket
Sign inDemoInstall

type-mongodb

Package Overview
Dependencies
18
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1-beta7 to 0.0.1-beta8

61

lib/document/DocumentTransformer.d.ts

@@ -1,45 +0,34 @@

import { DocumentClass, Newable } from '../types';
import { DocumentClass, Newable } from '..';
import { AbstractDocumentMetadata } from '../metadata/AbstractDocumentMetadata';
export declare class DocumentTransformer {
/**
* Creates a model from model properties.
*/
static init<T, D extends Newable = DocumentClass>(meta: AbstractDocumentMetadata<T, D>, props: Partial<T> | {
import { OptionalId } from '../types';
export declare type DocumentTransformerCompiledFunction = (target: any, source: any, parent?: any) => any;
export declare class DocumentTransformer<T = any, D extends Newable = DocumentClass> {
private meta;
private isCompiled;
private compiledToDB;
private compiledFromDB;
private compiledMerge;
private constructor();
static readonly transformers: Map<any, DocumentTransformer<any, Newable<any>>>;
static create<T = any, D extends Newable = DocumentClass>(meta: AbstractDocumentMetadata<T, D>): DocumentTransformer<T, D>;
static compile(): void;
compile(): void;
init(props: OptionalId<Partial<T>> | {
[key: string]: any;
}): T;
/**
* Merges props into the given model
*/
static merge<T, D extends Newable = DocumentClass>(meta: AbstractDocumentMetadata<T, D>, model: T, props: Partial<T> | {
}, parent?: any): T;
merge(model: T, props: Partial<T> | {
[key: string]: any;
}): T;
/**
* Maps model fields to a mongodb document.
*/
static toDB<T, D extends Newable = DocumentClass>(meta: AbstractDocumentMetadata<T, D>, model: Partial<T> | {
}, parent?: any): T;
fromDB(doc: Partial<T> | {
[key: string]: any;
}, parent?: any): T;
toDB(model: Partial<T> | {
[key: string]: any;
}): T & {
[key: string]: any;
};
/**
* Maps mongodb document(s) to a model.
*/
static fromDB<T, D extends Newable = DocumentClass>(meta: AbstractDocumentMetadata<T, D>, doc: Partial<T> | {
[key: string]: any;
}): T;
protected static getInstance<T>(meta: AbstractDocumentMetadata<T>, prepare?: boolean): T;
protected static createParentMapper<T>(map: (meta: AbstractDocumentMetadata<T>, value: any) => T): (meta: AbstractDocumentMetadata<T>, value: any, parent: any) => T;
/**
* Iterates over the fields for mapping between different types
*/
protected static mapDataInto<T>(opts: {
meta: AbstractDocumentMetadata<T>;
into: any;
intoField: 'fieldName' | 'propertyName';
data: any;
dataField: 'fieldName' | 'propertyName';
map: (meta: AbstractDocumentMetadata<T>, value: any, parent: any) => any;
}): T;
protected static prepare<T>(meta: AbstractDocumentMetadata<T>, object: any): T;
private createCompiler;
private prepare;
private assertIsCompiled;
}
//# sourceMappingURL=DocumentTransformer.d.ts.map
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DocumentTransformer = void 0;
// simple helper to create unique variable names
let variableCount = 0;
function reserveVariable(name) {
return `${name}_${++variableCount}`;
}
class DocumentTransformer {
/**
* Creates a model from model properties.
*/
static init(meta, props) {
return this.mapDataInto({
meta,
into: this.getInstance(meta),
intoField: 'propertyName',
data: props,
dataField: 'propertyName',
map: this.createParentMapper(this.init.bind(this)),
});
constructor(meta) {
this.meta = meta;
this.isCompiled = false;
}
/**
* Merges props into the given model
*/
static merge(meta, model, props) {
return this.mapDataInto({
meta,
into: model,
intoField: 'propertyName',
data: props,
dataField: 'propertyName',
map: this.createParentMapper(this.init.bind(this)),
});
static create(meta) {
// create transformer if it does not exist
let transformer = DocumentTransformer.transformers.get(meta.DocumentClass);
if (!transformer) {
transformer = new DocumentTransformer(meta);
}
DocumentTransformer.transformers.set(meta.DocumentClass, transformer);
return transformer;
}
/**
* Maps model fields to a mongodb document.
*/
static toDB(meta, model) {
return this.mapDataInto({
meta,
into: {},
intoField: 'fieldName',
data: this.prepare(meta, model),
dataField: 'propertyName',
map: this.toDB.bind(this),
// compiles all of the transformers
static compile() {
DocumentTransformer.transformers.forEach((transformer) => {
transformer.compile();
});
}
/**
* Maps mongodb document(s) to a model.
*/
static fromDB(meta, doc) {
const instance = this.getInstance(meta, false);
const model = this.mapDataInto({
meta,
into: instance,
intoField: 'propertyName',
data: doc,
dataField: 'fieldName',
map: this.createParentMapper(this.fromDB.bind(this)),
});
return model;
compile() {
if (this.isCompiled) {
return;
}
this.compiledToDB = this.createCompiler(false, true);
this.compiledFromDB = this.createCompiler(true, false);
this.compiledMerge = this.createCompiler(false, false);
this.isCompiled = true;
}
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
static getInstance(meta, prepare = true) {
const instance = new meta.DocumentClass();
return prepare ? this.prepare(meta, instance) : instance;
init(props, parent) {
this.assertIsCompiled();
return this.compiledMerge(this.prepare(new this.meta.DocumentClass()), props, parent);
}
static createParentMapper(map) {
return (m, v, parent) => {
const model = map.bind(this)(m, v);
if (m.parent) {
model[m.parent.propertyName] = parent;
merge(model, props, parent) {
this.assertIsCompiled();
return this.compiledMerge(this.prepare(model), props, parent);
}
fromDB(doc, parent) {
this.assertIsCompiled();
return this.compiledFromDB(new this.meta.DocumentClass(), doc, parent);
}
toDB(model) {
this.assertIsCompiled();
return this.compiledToDB({}, this.prepare(model));
}
createCompiler(isFromDB, isToDB) {
const context = new Map();
const has = (accessor) => {
return `(source && "${accessor}" in source)`;
};
const getComparator = (fieldMetadata, accessor, setter) => {
const { embeddedMetadata, fieldName, isEmbeddedArray, isEmbedded } = fieldMetadata;
// simple getter/setter
if (!isEmbedded) {
return `
if (${has(accessor)}) {
target["${setter}"] = source["${accessor}"];
}
`;
}
return model;
const embeddedTransformer = DocumentTransformer.create(embeddedMetadata);
const transformerFnVar = reserveVariable(`${fieldName}_transformer`);
const transformerFn = isToDB
? embeddedTransformer.toDB
: embeddedTransformer.fromDB;
context.set(transformerFnVar, transformerFn.bind(embeddedTransformer));
if (isEmbeddedArray) {
return `
if (${has(accessor)} && Array.isArray(source["${accessor}"])) {
target["${setter}"] = source["${accessor}"].map(v => ${transformerFnVar}(v, target));
}
`;
}
return `
if (${has(accessor)}) {
target["${setter}"] = ${transformerFnVar}(source["${accessor}"], target);
}
`;
};
}
/**
* Iterates over the fields for mapping between different types
*/
static mapDataInto(opts) {
const { meta, into, intoField, data, dataField, map } = opts;
meta.fields.forEach((_a) => {
var { isEmbedded, isEmbeddedArray, embeddedMetadata } = _a, fieldMeta = __rest(_a, ["isEmbedded", "isEmbeddedArray", "embeddedMetadata"]);
const dataFieldName = fieldMeta[dataField];
const intoFieldName = fieldMeta[intoField];
if (typeof data !== 'undefined' &&
typeof data[dataFieldName] !== 'undefined') {
if (!isEmbedded) {
into[intoFieldName] = data[dataFieldName];
}
else if (isEmbeddedArray) {
into[intoFieldName] = (data[dataFieldName] || []).map((value) => value ? map(embeddedMetadata, value, into) : null);
}
else {
into[intoFieldName] = data[dataFieldName]
? map(embeddedMetadata, data[dataFieldName], into)
: null;
}
const props = [];
for (const fieldMetadata of this.meta.fields.values()) {
const { fieldName, propertyName } = fieldMetadata;
const accessor = isFromDB ? fieldName : propertyName;
const setter = isToDB ? fieldName : propertyName;
props.push(getComparator(fieldMetadata, accessor, setter));
}
const parentMapper = () => {
if (isToDB || !this.meta.parent) {
return '';
}
});
return into;
return `
target["${this.meta.parent.propertyName}"] = parent;
`;
};
const functionCode = `
return function(target, source, parent) {
${props.join('\n')}
${parentMapper()}
return target;
}
`;
const compiled = new Function(...context.keys(), functionCode);
return compiled(...context.values());
}
static prepare(meta, object) {
if (meta.hasId()) {
object._id = meta.id(object._id);
prepare(object) {
if (this.meta.hasId()) {
object._id = this.meta.id(object._id);
}
return object;
}
assertIsCompiled() {
if (!this.isCompiled) {
throw new Error('DocumentTransformers are not compiled');
}
}
}
exports.DocumentTransformer = DocumentTransformer;
DocumentTransformer.transformers = new Map();
//# sourceMappingURL=DocumentTransformer.js.map

@@ -31,3 +31,3 @@ import { MongoClient, SessionOptions } from 'mongodb';

readonly container: ContainerLike;
constructor(opts: DocumentManagerOptions);
private constructor();
buildMetadata(): Promise<void>;

@@ -34,0 +34,0 @@ buildSubscribers(): void;

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

const Session_1 = require("./transaction/Session");
const DocumentTransformer_1 = require("./document/DocumentTransformer");
const defaultContainer = {

@@ -151,2 +152,3 @@ get: (Service) => new Service()

dm.buildSubscribers();
DocumentTransformer_1.DocumentTransformer.compile();
return dm;

@@ -153,0 +155,0 @@ });

@@ -41,8 +41,8 @@ "use strict";

this.documentsWithSubscribers.clear();
const documents = Array.from(dm.metadataFactory.loadedDocumentMetadata.values()).map(meta => meta.DocumentClass);
this.subscribers.forEach(subscriber => {
const documents = Array.from(dm.metadataFactory.loadedDocumentMetadata.values()).map((meta) => meta.DocumentClass);
this.subscribers.forEach((subscriber) => {
const subscribedDocuments = typeof subscriber.getSubscribedDocuments === 'function'
? subscriber.getSubscribedDocuments(dm)
: null;
documents.forEach(DocumentClass => {
documents.forEach((DocumentClass) => {
if (!subscribedDocuments) {

@@ -94,3 +94,3 @@ this.attachSubscriberToDocument(DocumentClass, subscriber);

const subscribers = this.documentsWithSubscribers.get(DocumentClass);
Object.keys(interfaces_1.Events).forEach(event => {
Object.keys(interfaces_1.Events).forEach((event) => {
const fn = interfaces_1.Events[event];

@@ -97,0 +97,0 @@ if (typeof subscriber[fn] === 'function') {

import { ObjectId } from 'mongodb';
import { Newable, OptionalId } from '../types';
import { FieldMetadata } from './FieldMetadata';
import { DocumentTransformer } from '../document/DocumentTransformer';
import { ParentDefinition } from './definitions';

@@ -14,2 +15,3 @@ export declare type FieldsMetadata = Map<string, FieldMetadata>;

readonly fields: FieldsMetadata;
readonly transformer: DocumentTransformer;
readonly parent?: ParentDefinition;

@@ -16,0 +18,0 @@ constructor(DocumentClass: D, fields: FieldsMetadata, parent?: ParentDefinition);

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

this.parent = parent;
this.transformer = DocumentTransformer_1.DocumentTransformer.create(this);
}

@@ -46,3 +47,3 @@ // -------------------------------------------------------------------------

toDB(model) {
return DocumentTransformer_1.DocumentTransformer.toDB(this, model);
return this.transformer.toDB(model);
}

@@ -53,3 +54,3 @@ /**

fromDB(doc) {
return DocumentTransformer_1.DocumentTransformer.fromDB(this, doc);
return this.transformer.fromDB(doc);
}

@@ -60,3 +61,3 @@ /**

init(props) {
return DocumentTransformer_1.DocumentTransformer.init(this, props);
return this.transformer.merge(new this.DocumentClass(), props);
}

@@ -67,3 +68,3 @@ /**

merge(model, props) {
return DocumentTransformer_1.DocumentTransformer.merge(this, model, props);
return this.transformer.merge(model, props);
}

@@ -70,0 +71,0 @@ }

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

return __awaiter(this, void 0, void 0, function* () {
yield Promise.all(this.opts.documents.map(DocumentClass => {
yield Promise.all(this.opts.documents.map((DocumentClass) => {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {

@@ -140,3 +140,3 @@ try {

if (definitionStorage_1.definitionStorage.fields.has(target)) {
definitionStorage_1.definitionStorage.fields.get(target).forEach(prop => {
definitionStorage_1.definitionStorage.fields.get(target).forEach((prop) => {
if (!prop.isEmbedded) {

@@ -143,0 +143,0 @@ fields.set(prop.fieldName, new FieldMetadata_1.FieldMetadata(Object.assign(Object.assign({}, prop), { isEmbeddedArray: false })));

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

return this.find({
_id: { $in: ids.map((id) => this.id(id)) },
_id: { $in: ids.map((id) => this.id(id)) }
}, opts);

@@ -132,3 +132,3 @@ }

meta: this.metadata,
model: model,
model: model
}, () => this.collection.insertOne(doc, opts));

@@ -148,7 +148,7 @@ });

meta: this.metadata,
model: model,
model: model
}));
afterInsertEvents.push(this.manager.eventManager.dispatch(events_1.Events.AfterInsert, {
meta: this.metadata,
model: model,
model: model
}));

@@ -167,3 +167,3 @@ });

filter,
update,
update
}, () => __awaiter(this, void 0, void 0, function* () {

@@ -213,3 +213,3 @@ return this.findOneAnd('Update', filter, update, Object.assign({ returnOriginal: false }, opts));

meta: this.metadata,
filter,
filter
}, () => __awaiter(this, void 0, void 0, function* () { return this.findOneAnd('Delete', filter, opts); }));

@@ -238,3 +238,3 @@ });

filter,
update,
update
}, () => this.collection.updateOne(filter, update, opts));

@@ -253,3 +253,3 @@ });

filter,
update,
update
}, () => this.collection.updateMany(filter, update, opts));

@@ -277,3 +277,3 @@ });

meta: this.metadata,
filter,
filter
}, () => __awaiter(this, void 0, void 0, function* () {

@@ -294,3 +294,3 @@ const result = yield this.collection.deleteOne(filter, opts);

meta: this.metadata,
filter,
filter
}, () => this.collection.deleteMany(filter, opts));

@@ -297,0 +297,0 @@ });

@@ -11,3 +11,3 @@ import { WithId } from 'mongodb';

*/
export { Db, OptionalId, WithId, Collection, CollectionInsertManyOptions, InsertWriteOpResult, CommonOptions, CollectionInsertOneOptions, InsertOneWriteOpResult, FindOneAndDeleteOption, FindOneAndUpdateOption, FindOneAndReplaceOption, UpdateWriteOpResult, ReplaceWriteOpResult, DeleteWriteOpResultObject, FilterQuery, UpdateQuery, UpdateManyOptions, UpdateOneOptions, ReplaceOneOptions, } from 'mongodb';
export { Db, OptionalId, WithId, Collection, CollectionInsertManyOptions, InsertWriteOpResult, CommonOptions, CollectionInsertOneOptions, InsertOneWriteOpResult, FindOneAndDeleteOption, FindOneAndUpdateOption, FindOneAndReplaceOption, UpdateWriteOpResult, ReplaceWriteOpResult, DeleteWriteOpResultObject, FilterQuery, UpdateQuery, UpdateManyOptions, UpdateOneOptions, ReplaceOneOptions } from 'mongodb';
//# sourceMappingURL=index.d.ts.map

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

throw new Error(`No need to set field type on for: ObjectId, ${exports.builtins
.map(type => type.name)
.map((type) => type.name)
.join(', ')}`);

@@ -18,0 +18,0 @@ }

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

yield Promise.all(dm
.filterMetadata(meta => !!meta.collection)
.map(meta => meta.collection.deleteMany({})));
.filterMetadata((meta) => !!meta.collection)
.map((meta) => meta.collection.deleteMany({})));
});

@@ -21,0 +21,0 @@ }

{
"name": "type-mongodb",
"version": "0.0.1-beta7",
"version": "0.0.1-beta8",
"description": "A simple decorator based MongoDB ODM.",

@@ -26,10 +26,9 @@ "keywords": [],

},
"dependencies": {
"mongodb": "^3.5.9"
},
"devDependencies": {
"@types/jest": "^26.0.3",
"@types/mongodb": "3.5.25",
"benchmark": "^2.1.4",
"husky": "^4.2.5",
"jest": "^26.1.0",
"mongodb": "3.x.x",
"mongodb-runner": "^4.7.2",

@@ -43,6 +42,8 @@ "prettier": "^2.0.5",

"peerDependencies": {
"mongodb": "3.x.x",
"reflect-metadata": "^0.1.13"
},
"prettier": {
"singleQuote": true
"singleQuote": true,
"trailingComma": "none"
},

@@ -49,0 +50,0 @@ "husky": {

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc