Compare commits

..

28 Commits

Author SHA1 Message Date
a4acfc0f6e 1.0.24 2017-06-23 11:40:26 +02:00
a934f3608f remove NeDB and update to use MongoDB Atlas for testing 2017-06-23 11:40:20 +02:00
a4f3f23bed update npmextra 2017-06-18 19:53:29 +02:00
2039f1c807 update ci 2017-06-18 19:52:54 +02:00
57d1a6dd0a added npmdocker for local development 2017-02-25 11:37:05 +01:00
d504e90e47 1.0.22 2016-11-18 13:56:18 +01:00
7079340657 refactor @saveable to @svDb() 2016-11-18 13:56:15 +01:00
63ceded1b8 1.0.21 2016-11-18 13:20:47 +01:00
b45e7ee206 fix mongodb startup 2016-11-18 13:20:43 +01:00
715709f3ec 1.0.20 2016-11-18 01:00:06 +01:00
0b8adea736 improve README 2016-11-18 00:59:57 +01:00
90d9a25b3f 1.0.19 2016-11-18 00:42:29 +01:00
e49811eecd now allows adding a saveable decorator 2016-11-18 00:42:25 +01:00
9cbdf317dc 1.0.18 2016-11-17 22:41:05 +01:00
d55339013a improve README 2016-11-17 22:41:01 +01:00
9acdbd2842 1.0.17 2016-11-17 22:36:16 +01:00
dfce8cfcc0 add NeDB support 2016-11-17 22:36:12 +01:00
38446fc79b 1.0.16 2016-11-17 12:20:56 +01:00
af8c41ad6c added nedb to the mix 2016-11-17 12:20:52 +01:00
3a24f829b4 improve README 2016-09-14 01:03:25 +02:00
67db1325c1 1.0.15 2016-09-14 01:02:23 +02:00
6683c05c22 added Decorator support for easy connection between classes and collections 2016-09-14 01:02:11 +02:00
f7f7852b7f 1.0.14 2016-09-13 22:53:27 +02:00
df4346e0a2 implenting dbDoc 2016-09-13 22:53:21 +02:00
eb54fbcd0d improve README 2016-09-13 10:38:00 +02:00
f13c12cd47 improve README 2016-09-13 10:35:51 +02:00
08d53f22f5 improve README 2016-09-13 10:31:14 +02:00
5b6523e6f4 improve README 2016-09-13 10:26:17 +02:00
31 changed files with 1675 additions and 396 deletions

5
.gitignore vendored
View File

@ -1,5 +1,4 @@
node_modules/
test/data
pages/
coverage/
public/
coverage/
.nogit/

View File

@ -1,19 +1,22 @@
image: hosttoday/ht-docker-node:npmts
# gitzone standard
image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .yarn/
key: "$CI_BUILD_STAGE"
stages:
- test
- release
before_script:
- apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
- echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.2.list
- apt-get update
- apt-get install -y mongodb-org
- trigger
- pages
testLEGACY:
stage: test
script:
- npmci test legacy
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
allow_failure: true
@ -22,6 +25,7 @@ testLTS:
stage: test
script:
- npmci test lts
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
@ -29,15 +33,40 @@ testSTABLE:
stage: test
script:
- npmci test stable
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
release:
stage: release
environment: npm_registry
script:
- npmci publish
only:
- tags
tags:
- docker
- docker
trigger:
stage: trigger
script:
- npmci trigger
only:
- tags
tags:
- docker
pages:
image: hosttoday/ht-docker-node:npmci
stage: pages
script:
- npmci command yarn global add npmpage
- npmci command npmpage
tags:
- docker
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

104
README.md
View File

@ -1,89 +1,29 @@
# smartdata
do more with data
> Note: Still in Beta
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartdata)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartdata)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartdata)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartdata/)
smartdata is a ODM that adheres to TypeScript practices and uses classes to organize data.
It uses MongoDB as persistent storage.
## Status for master
[![build status](https://GitLab.com/pushrocks/smartdata/badges/master/build.svg)](https://GitLab.com/pushrocks/smartdata/commits/master)
[![coverage report](https://GitLab.com/pushrocks/smartdata/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartdata/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/smartdata.svg)](https://www.npmjs.com/package/smartdata)
[![Dependency Status](https://david-dm.org/pushrocks/smartdata.svg)](https://david-dm.org/pushrocks/smartdata)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartdata/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartdata/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartdata/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartdata)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Intention
There are many ODMs out there, however when we searched for a ODM that uses TypeScript,
acts smart while still embracing an easy the NoSQL idea we didn't find a matching solution.
This is why we started smartdata
## Usage
Use TypeScript for best in class instellisense.
How MongoDB terms map to smartdata classes
For further information read the linked docs at the top of this README.
MongoDB term | smartdata class
--- | ---
Database | smartdata.Db
Collection | smartdata.DbCollection
Document | smartdata.DbDoc
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
### class Db
represents a Database. Naturally it has .connect() etc. methods on it.
Since it is a class you can have multiple DBs defined.
```typescript
import * as smartdata from 'smartdata'
let myDb1 = new smartdata.Db('someConnectionUrl')
let myDb2 = new smartdata.Db('someConnectionUrl')
myDb1.connect()
myDb2.connect()
// continues in next block...
```
### class DbCollection
represents a collection of objects.
A collection is defined by the object class (that is extending smartdata.dbdoc) it respresents
So to get to get access to a specific collection you document
```typescript
// continues from the block before...
class myObject extends smartdata.DbDoc { // read the next block about DbDoc
property1:string
property2:number
constructor(optionsArg:{
queryArg?:any,
dataArg?:{
property1:string,
property2:number
}
}) {
super(this,optionsArg)
}
}
let myCollection = myDb1.getCollection(myObject)
```
> Alert: You NEVER instantiate a collection.
This is done for you!!!
### class DbDoc
represents a individual document in a collection
and thereby is ideally suited to extend the class you want to actually store.
DbDoc extends your class with the following methods:
* `.save()` will save (or update) the object you call it on only. Any referenced non-savable objects will not get stored.
* `.saveDeep()` does the same like `.save()`.
In addition it will look for properties that reference an object
that extends DbDoc as well and call .saveDeep() on them as well.
Loops are prevented
So now we can **store** instances of classes to Db...
How do we **get** a new class instance from a Doc in the DB?
Easy! Take a look at the constructor. When you specify `optionsArg.queryArg`
smartdata will fill in the data from the database!
But when you specify a `optionsArg.dataArg` instead
the data for the class is taken from there :)
## TypeScript
How does TypeScript play into this?
Since you define your classes in TapeScript and types flow through smartdata in a generic way
you should get all the Intellisense and type checking you love when using smartdata.
smartdata itself also bundles typings.
So you don't need to install any additional types whenimporting smartdata.
[![npm](https://push.rocks/assets/repo-header.svg)](https://push.rocks)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

3
dist/index.d.ts vendored
View File

@ -1,2 +1,3 @@
export * from './smartdata.classes.dbcollection';
export * from './smartdata.classes.db';
export * from './smartdata.classes.dbcollection';
export * from './smartdata.classes.dbdoc';

8
dist/index.js vendored
View File

@ -2,6 +2,8 @@
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
__export(require('./smartdata.classes.dbcollection'));
__export(require('./smartdata.classes.db'));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBRUEsaUJBQWMsa0NBQ2QsQ0FBQyxFQUQrQztBQUNoRCxpQkFBYyx3QkFDZCxDQUFDLEVBRHFDIn0=
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./smartdata.classes.db"));
__export(require("./smartdata.classes.dbcollection"));
__export(require("./smartdata.classes.dbdoc"));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLDRDQUFzQztBQUN0QyxzREFBZ0Q7QUFDaEQsK0NBQXlDIn0=

View File

@ -1,11 +1,32 @@
/// <reference types="q" />
import * as plugins from './smartdata.plugins';
import { Objectmap } from 'lik';
import { DbCollection } from './smartdata.classes.dbcollection';
/**
* interface - indicates the connection status of the db
*/
export declare type TConnectionStatus = 'disconnected' | 'connected' | 'failed';
export declare class Db {
dbUrl: string;
db: plugins.mongodb.Db;
status: TConnectionStatus;
constructor(dbUrl: string);
connect(): plugins.q.Promise<any>;
close(): plugins.q.Promise<any>;
classCollections: Objectmap<DbCollection<any>>;
objectCollections: Objectmap<DbCollection<any>>;
constructor(dbUrlArg: string);
/**
* connects to the database that was specified during instance creation
*/
connect(): Promise<any>;
/**
* closes the connection to the databse
*/
close(): Promise<any>;
/**
* gets a class based collection by name: string
*/
getClassCollectionByName<T>(nameArg: string): Promise<DbCollection<T>>;
/**
* gets an object collection by name
*/
getObjectCollectionByName<T>(nameArg: string, dbArg: Db, makeNewArg?: boolean): Promise<DbCollection<T>>;
addCollection(dbCollectionArg: DbCollection<any>): void;
}

View File

@ -1,11 +1,28 @@
"use strict";
const plugins = require('./smartdata.plugins');
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartdata.plugins");
const lik_1 = require("lik");
const smartdata_classes_dbobjectdoc_1 = require("./smartdata.classes.dbobjectdoc");
class Db {
constructor(dbUrl) {
this.dbUrl = dbUrl;
constructor(dbUrlArg) {
this.classCollections = new lik_1.Objectmap();
this.objectCollections = new lik_1.Objectmap();
this.dbUrl = dbUrlArg;
}
// basic connection stuff ----------------------------------------------
/**
* connects to the database that was specified during instance creation
*/
connect() {
let done = plugins.q.defer();
let done = plugins.smartq.defer();
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
if (err) {
console.log(err);
@ -17,13 +34,48 @@ class Db {
});
return done.promise;
}
/**
* closes the connection to the databse
*/
close() {
let done = plugins.q.defer();
let done = plugins.smartq.defer();
this.db.close();
plugins.beautylog.ok(`disconnected to database at ${this.dbUrl}`);
done.resolve();
return done.promise;
}
// advanced communication with the database --------------------------------
/**
* gets a class based collection by name: string
*/
getClassCollectionByName(nameArg) {
return __awaiter(this, void 0, void 0, function* () {
let resultCollection = this.classCollections.find((dbCollectionArg) => {
return dbCollectionArg.name === nameArg;
});
return resultCollection;
});
}
/**
* gets an object collection by name
*/
getObjectCollectionByName(nameArg, dbArg, makeNewArg = false) {
return __awaiter(this, void 0, void 0, function* () {
let resultCollection = this.objectCollections.find((dbCollectionArg) => {
return dbCollectionArg.name === nameArg;
});
if (!resultCollection && makeNewArg) {
resultCollection = smartdata_classes_dbobjectdoc_1.getObjectDoc(nameArg, this).collection;
return resultCollection;
}
else {
return resultCollection;
}
});
}
addCollection(dbCollectionArg) {
this.classCollections.add(dbCollectionArg);
}
}
exports.Db = Db;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBWSxPQUFPLFdBQU0scUJBRXpCLENBQUMsQ0FGNkM7QUFJOUM7SUFLSSxZQUFZLEtBQWE7UUFDckIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7SUFDdEIsQ0FBQztJQUVELE9BQU87UUFDSCxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQzVCLE9BQU8sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDcEQsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQUMsQ0FBQztZQUM3QixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7WUFDL0IsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUE7WUFDWixPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7WUFDbkUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDekIsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQsS0FBSztRQUNELElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDNUIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNmLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLCtCQUErQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtRQUNqRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0FBQ0wsQ0FBQztBQTVCWSxVQUFFLEtBNEJkLENBQUEifQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsK0NBQThDO0FBQzlDLDZCQUErQjtBQUcvQixtRkFBOEQ7QUFPOUQ7SUFPRSxZQUFhLFFBQWdCO1FBSDdCLHFCQUFnQixHQUFHLElBQUksZUFBUyxFQUFxQixDQUFBO1FBQ3JELHNCQUFpQixHQUFHLElBQUksZUFBUyxFQUFxQixDQUFBO1FBR3BELElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFBO0lBQ3ZCLENBQUM7SUFFRCx3RUFBd0U7SUFFeEU7O09BRUc7SUFDSCxPQUFPO1FBQ0wsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNqQyxPQUFPLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3RELEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUFDLENBQUM7WUFDN0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBQy9CLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFBO1lBQ1osT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsNEJBQTRCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO1lBQ25FLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ3ZCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDckIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSztRQUNILElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDakMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNmLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLCtCQUErQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtRQUNqRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUNyQixDQUFDO0lBRUQsNEVBQTRFO0lBRTVFOztPQUVHO0lBQ0csd0JBQXdCLENBQUssT0FBZTs7WUFDaEQsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsZUFBZTtnQkFDaEUsTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFBO1lBQ3pDLENBQUMsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFBO1FBQ3pCLENBQUM7S0FBQTtJQUVEOztPQUVHO0lBQ0cseUJBQXlCLENBQUssT0FBZSxFQUFFLEtBQVMsRUFBRyxhQUFzQixLQUFLOztZQUMxRixJQUFJLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlO2dCQUNqRSxNQUFNLENBQUMsZUFBZSxDQUFDLElBQUksS0FBSyxPQUFPLENBQUE7WUFDekMsQ0FBQyxDQUFDLENBQUE7WUFDRixFQUFFLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLGdCQUFnQixHQUFHLDRDQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQTtnQkFDekQsTUFBTSxDQUFDLGdCQUFnQixDQUFBO1lBQ3pCLENBQUM7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixNQUFNLENBQUMsZ0JBQWdCLENBQUE7WUFDekIsQ0FBQztRQUNILENBQUM7S0FBQTtJQUVELGFBQWEsQ0FBRSxlQUFrQztRQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFBO0lBQzVDLENBQUM7Q0FFRjtBQXRFRCxnQkFzRUMifQ==

View File

@ -1,24 +1,42 @@
/// <reference types="q" />
import * as plugins from './smartdata.plugins';
import { Db } from './smartdata.classes.db';
import { DbDoc } from './smartdata.classes.dbDoc';
export interface IFindOptions {
limit?: number;
}
export interface IDocValidation<T> {
(doc: T): boolean;
}
export declare function Collection(db: Db): (constructor: any) => void;
export declare class DbCollection<T> {
/**
* the collection that is used, defaults to mongodb collection,
* can be nedb datastore (sub api of mongodb)
*/
collection: plugins.mongodb.Collection;
constructor(nameArg: string, dbArg: Db);
collectedClass: T & DbDoc<T>;
objectValidation: IDocValidation<T>;
name: string;
db: Db;
constructor(collectedClassArg: T & DbDoc<T>, dbArg: Db);
/**
* adds a validation function that all newly inserted and updated objects have to pass
*/
addObjectValidation(funcArg: any): void;
addDocValidation(funcArg: IDocValidation<T>): void;
/**
* finds an object in the DbCollection
*/
find(docMatchArg: T | any): plugins.q.Promise<T[]>;
find(docMatchArg: T | any, optionsArg?: IFindOptions): Promise<T[]>;
/**
* inserts object into the DbCollection
* inserts object into the DbCollection
*/
insertOne(docArg: T): plugins.q.Promise<void>;
insertOne(docArg: T): Promise<void>;
/**
* inserts many objects at once into the DbCollection
*/
insertMany(docArrayArg: T[]): plugins.q.Promise<void>;
private checkDoc(doc);
insertMany(docArrayArg: T[]): Promise<void>;
/**
* checks a Doc for constraints
*/
private checkDoc(docArg);
}

View File

@ -1,20 +1,44 @@
"use strict";
const plugins = require('./smartdata.plugins');
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartdata.plugins");
function Collection(db) {
return function (constructor) {
constructor['dbCollection'] = new DbCollection(constructor, db);
};
}
exports.Collection = Collection;
class DbCollection {
constructor(nameArg, dbArg) {
this.collection = dbArg.db.collection(nameArg);
constructor(collectedClassArg, dbArg) {
this.objectValidation = null;
// tell the collection where it belongs
this.collectedClass = collectedClassArg;
this.name = collectedClassArg.name;
this.db = dbArg;
// make sure it actually exists
this.collection = dbArg.db.collection(this.name);
// tell the db class about it (important since Db uses different systems under the hood)
this.db.addCollection(this);
}
/**
* adds a validation function that all newly inserted and updated objects have to pass
*/
addObjectValidation(funcArg) { }
addDocValidation(funcArg) {
this.objectValidation = funcArg;
}
/**
* finds an object in the DbCollection
*/
find(docMatchArg) {
let done = plugins.q.defer();
this.collection.find(docMatchArg).toArray((err, docs) => {
find(docMatchArg, optionsArg) {
let done = plugins.smartq.defer();
let findCursor = this.collection.find(docMatchArg);
if (optionsArg) {
if (optionsArg.limit) {
findCursor = findCursor.limit(1);
}
}
findCursor.toArray((err, docs) => {
if (err) {
done.reject(err);
throw err;
}
done.resolve(docs);
@ -22,13 +46,15 @@ class DbCollection {
return done.promise;
}
/**
* inserts object into the DbCollection
* inserts object into the DbCollection
*/
insertOne(docArg) {
let done = plugins.q.defer();
let done = plugins.smartq.defer();
this.checkDoc(docArg).then(() => {
this.collection.insertOne(docArg)
.then(() => { done.resolve(); });
}, () => {
done.reject(new Error('one the docs did not pass validation'));
});
return done.promise;
}
@ -36,22 +62,34 @@ class DbCollection {
* inserts many objects at once into the DbCollection
*/
insertMany(docArrayArg) {
let done = plugins.q.defer();
let done = plugins.smartq.defer();
let checkDocPromiseArray = [];
for (let docArg of docArrayArg) {
checkDocPromiseArray.push(this.checkDoc(docArg));
}
plugins.q.all(checkDocPromiseArray).then(() => {
Promise.all(checkDocPromiseArray).then(() => {
this.collection.insertMany(docArrayArg)
.then(() => { done.resolve(); });
});
return done.promise;
}
checkDoc(doc) {
let done = plugins.q.defer();
done.resolve();
/**
* checks a Doc for constraints
*/
checkDoc(docArg) {
let done = plugins.smartq.defer();
let validationResult = true;
if (this.objectValidation) {
validationResult = this.objectValidation(docArg);
}
if (validationResult) {
done.resolve();
}
else {
done.reject('validation of object did not pass');
}
return done.promise;
}
}
exports.DbCollection = DbCollection;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxNQUFZLE9BQU8sV0FBTSxxQkFDekIsQ0FBQyxDQUQ2QztBQUc5QztJQUVJLFlBQVksT0FBZSxFQUFFLEtBQVM7UUFDbEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxtQkFBbUIsQ0FBQyxPQUFPLElBQUksQ0FBQztJQUVoQzs7T0FFRztJQUNILElBQUksQ0FBQyxXQUFvQjtRQUNyQixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBTyxDQUFBO1FBQ2pDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJO1lBQ2hELEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQUMsTUFBTSxHQUFHLENBQUE7WUFBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDdEIsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTLENBQUMsTUFBUztRQUNmLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFRLENBQUE7UUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO2lCQUM1QixJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUN2QyxDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVUsQ0FBQyxXQUFnQjtRQUN2QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBUSxDQUFBO1FBQ2xDLElBQUksb0JBQW9CLEdBQThCLEVBQUUsQ0FBQTtRQUN4RCxHQUFHLENBQUMsQ0FBQyxJQUFJLE1BQU0sSUFBSSxXQUFXLENBQUMsQ0FBQSxDQUFDO1lBQzVCLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDcEQsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQztpQkFDbEMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdkMsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRU8sUUFBUSxDQUFDLEdBQU07UUFDbkIsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQVEsQ0FBQTtRQUNsQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0FBQ0wsQ0FBQztBQXhEWSxvQkFBWSxlQXdEeEIsQ0FBQSJ9
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0NBQThDO0FBWTlDLG9CQUE0QixFQUFNO0lBQ2hDLE1BQU0sQ0FBQyxVQUFVLFdBQVc7UUFDMUIsV0FBVyxDQUFFLGNBQWMsQ0FBRSxHQUFHLElBQUksWUFBWSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNuRSxDQUFDLENBQUE7QUFDSCxDQUFDO0FBSkQsZ0NBSUM7QUFFRDtJQVdFLFlBQWEsaUJBQStCLEVBQUUsS0FBUztRQUp2RCxxQkFBZ0IsR0FBc0IsSUFBSSxDQUFBO1FBS3hDLHVDQUF1QztRQUN2QyxJQUFJLENBQUMsY0FBYyxHQUFHLGlCQUFpQixDQUFBO1FBQ3ZDLElBQUksQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFBO1FBRWYsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRWhELHdGQUF3RjtRQUN4RixJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxnQkFBZ0IsQ0FBRSxPQUEwQjtRQUMxQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFBO0lBQ2pDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksQ0FBRSxXQUFvQixFQUFFLFVBQXlCO1FBQ25ELElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFPLENBQUE7UUFDdEMsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FB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

View File

@ -0,0 +1,39 @@
import { Objectmap } from 'lik';
import { DbCollection } from './smartdata.classes.dbcollection';
export declare type TDocCreation = 'db' | 'new' | 'mixed';
/**
* saveable - saveable decorator to be used on class properties
*/
export declare function svDb(): (target: DbDoc<any>, key: string) => void;
export declare class DbDoc<T> {
/**
* the collection object an Doc belongs to
*/
collection: DbCollection<T>;
/**
* how the Doc in memory was created, may prove useful later.
*/
creationType: TDocCreation;
/**
* an array of saveable properties of a doc
*/
saveableProperties: string[];
/**
* name
*/
name: string;
/**
* class constructor
*/
constructor();
/**
* saves this instance but not any connected items
* may lead to data inconsistencies, but is faster
*/
save(): void;
/**
* also store any referenced objects to DB
* better for data consistency
*/
saveDeep(savedMapArg?: Objectmap<DbDoc<any>>): void;
}

View File

@ -1 +1,61 @@
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJkb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYmRvYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const lik_1 = require("lik");
/**
* saveable - saveable decorator to be used on class properties
*/
function svDb() {
return (target, key) => {
console.log('called sva');
if (!target.saveableProperties) {
target.saveableProperties = [];
}
target.saveableProperties.push(key);
};
}
exports.svDb = svDb;
class DbDoc {
/**
* class constructor
*/
constructor() {
this.name = this.constructor['name'];
this.collection = this.constructor['dbCollection'];
}
/**
* saves this instance but not any connected items
* may lead to data inconsistencies, but is faster
*/
save() {
let saveableObject = {}; // is not exposed to outside, so any is ok here
for (let propertyNameString of this.saveableProperties) {
saveableObject[propertyNameString] = this[propertyNameString];
}
switch (this.creationType) {
case 'db':
this.collection; // TODO implement collection.update()
break;
case 'new':
this.collection.insertOne(saveableObject);
}
}
/**
* also store any referenced objects to DB
* better for data consistency
*/
saveDeep(savedMapArg = null) {
if (!savedMapArg) {
savedMapArg = new lik_1.Objectmap();
}
savedMapArg.add(this);
this.save();
for (let propertyKey in this) {
let property = this[propertyKey];
if (property instanceof DbDoc && !savedMapArg.checkForObject(property)) {
property.saveDeep(savedMapArg);
}
}
}
}
exports.DbDoc = DbDoc;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJEb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYkRvYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLDZCQUErQjtBQU8vQjs7R0FFRztBQUNIO0lBQ0UsTUFBTSxDQUFDLENBQUMsTUFBa0IsRUFBRSxHQUFXO1FBQ3JDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUE7UUFDekIsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1lBQUMsTUFBTSxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQTtRQUFDLENBQUM7UUFDbEUsTUFBTSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNyQyxDQUFDLENBQUE7QUFDSCxDQUFDO0FBTkQsb0JBTUM7QUFFRDtJQXNCRTs7T0FFRztJQUNIO1FBQ0UsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3BDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBRSxjQUFjLENBQUUsQ0FBQTtJQUN0RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSTtRQUNGLElBQUksY0FBYyxHQUFRLEVBQUUsQ0FBQSxDQUFDLCtDQUErQztRQUM1RSxHQUFHLENBQUMsQ0FBQyxJQUFJLGtCQUFrQixJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7WUFDdkQsY0FBYyxDQUFFLGtCQUFrQixDQUFFLEdBQUcsSUFBSSxDQUFFLGtCQUFrQixDQUFFLENBQUE7UUFDbkUsQ0FBQztRQUNELE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQzFCLEtBQUssSUFBSTtnQkFDUCxJQUFJLENBQUMsVUFBVSxDQUFBLENBQUMscUNBQXFDO2dCQUNyRCxLQUFLLENBQUE7WUFDUCxLQUFLLEtBQUs7Z0JBQ1IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDN0MsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxRQUFRLENBQUMsY0FBcUMsSUFBSTtRQUNoRCxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDakIsV0FBVyxHQUFHLElBQUksZUFBUyxFQUFjLENBQUE7UUFDM0MsQ0FBQztRQUNELFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDckIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ1gsR0FBRyxDQUFDLENBQUMsSUFBSSxXQUFXLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM3QixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUUsV0FBVyxDQUFFLENBQUE7WUFDbEMsRUFBRSxDQUFDLENBQUMsUUFBUSxZQUFZLEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2RSxRQUFRLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBQ2hDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBakVELHNCQWlFQyJ9

View File

@ -0,0 +1,3 @@
import { Db } from './smartdata.classes.db';
import { DbDoc } from './smartdata.classes.dbdoc';
export declare let getObjectDoc: (nameArg: any, dbArg: Db) => DbDoc<{}>;

11
dist/smartdata.classes.dbobjectdoc.js vendored Normal file
View File

@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const smartdata_classes_dbdoc_1 = require("./smartdata.classes.dbdoc");
const smartdata_classes_dbcollection_1 = require("./smartdata.classes.dbcollection");
exports.getObjectDoc = (nameArg, dbArg) => {
let objectDoc = new smartdata_classes_dbdoc_1.DbDoc();
objectDoc.name = nameArg;
objectDoc.collection = new smartdata_classes_dbcollection_1.DbCollection(objectDoc, dbArg);
return objectDoc;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJvYmplY3Rkb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYm9iamVjdGRvYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUdBLHVFQUFpRDtBQUNqRCxxRkFBK0Q7QUFFcEQsUUFBQSxZQUFZLEdBQUcsQ0FBQyxPQUFPLEVBQUMsS0FBUztJQUMxQyxJQUFJLFNBQVMsR0FBRyxJQUFJLCtCQUFLLEVBQUUsQ0FBQTtJQUMzQixTQUFTLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQTtJQUN4QixTQUFTLENBQUMsVUFBVSxHQUFHLElBQUksNkNBQVksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFDekQsTUFBTSxDQUFDLFNBQVMsQ0FBQTtBQUNsQixDQUFDLENBQUEifQ==

View File

@ -1,5 +1,7 @@
import 'typings-global';
export import assert = require('assert');
export import beautylog = require('beautylog');
export import mongodb = require('mongodb');
export import q = require('q');
import * as assert from 'assert';
import * as beautylog from 'beautylog';
import * as lodash from 'lodash';
import * as mongodb from 'mongodb';
import * as smartq from 'smartq';
export { assert, beautylog, lodash, mongodb, smartq };

View File

@ -1,7 +1,14 @@
"use strict";
require('typings-global');
exports.assert = require('assert');
exports.beautylog = require('beautylog');
exports.mongodb = require('mongodb');
exports.q = require('q');
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsUUFBTyxnQkFDUCxDQUFDLENBRHNCO0FBQ1QsY0FBTSxXQUFXLFFBQVEsQ0FBQyxDQUFBO0FBQzFCLGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUE7QUFDaEMsZUFBTyxXQUFXLFNBQVMsQ0FBQyxDQUFBO0FBQzVCLFNBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQSJ9
Object.defineProperty(exports, "__esModule", { value: true });
require("typings-global");
const assert = require("assert");
exports.assert = assert;
const beautylog = require("beautylog");
exports.beautylog = beautylog;
const lodash = require("lodash");
exports.lodash = lodash;
const mongodb = require("mongodb");
exports.mongodb = mongodb;
const smartq = require("smartq");
exports.smartq = smartq;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDBCQUF1QjtBQUN2QixpQ0FBZ0M7QUFPNUIsd0JBQU07QUFOVix1Q0FBc0M7QUFPbEMsOEJBQVM7QUFOYixpQ0FBZ0M7QUFPNUIsd0JBQU07QUFOVixtQ0FBa0M7QUFPOUIsMEJBQU87QUFOWCxpQ0FBZ0M7QUFPNUIsd0JBQU0ifQ==

View File

@ -1,19 +1,113 @@
# smartdata
do more with data
smartdata is a ODM that adheres to TypeScript practices and uses classes to organize data.
It uses MongoDB as persistent storage.
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartdata)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartdata)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartdata)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartdata/)
## Status for master
[![build status](https://GitLab.com/pushrocks/smartdata/badges/master/build.svg)](https://GitLab.com/pushrocks/smartdata/commits/master)
[![coverage report](https://GitLab.com/pushrocks/smartdata/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartdata/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/smartdata.svg)](https://www.npmjs.com/package/smartdata)
[![Dependency Status](https://david-dm.org/pushrocks/smartdata.svg)](https://david-dm.org/pushrocks/smartdata)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartdata/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartdata/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartdata/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartdata)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
smartdata is an ODM that adheres to TypeScript practices and uses classes to organize data.
It uses MongoDB or NeDb as persistent storage.
## Intention
There are many ODMs out there, however when we searched for a ODM that uses TypeScript,
acts smart while still embracing an easy the NoSQL idea we didn't find a matching solution.
This is why we started smartdata
There are many ODMs out there, however when we searched for an ODM that uses TypeScript,
acts smart while still embracing the NoSQL idea we didn't find a matching solution.
This is why we started smartdata.
How MongoDB terms map to smartdata classes
MongoDB term | smartdata class
--- | ---
Database | smartdata.DbConnection
Database | smartdata.Db
Collection | smartdata.DbCollection
Document | smartdata.DbDoc
[![npm](https://push.rocks/assets/repo-header.svg)](https://push.rocks)
### class Db
represents a Database. Naturally it has .connect() etc. methods on it.
Since it is a class you can have multiple DBs defined.
```javascript
import * as smartdata from 'smartdata'
// mongodb
let myDb1 = new smartdata.Db('someConnectionUrl')
let myDb2 = new smartdata.Db('someConnectionUrl')
// nedb
let myDb3 = new smartdata('/some/path/for/persistence', 'nedb') // you may set first argument to null for just in memory db
myDb1.connect()
myDb2.connect()
// continues in next block...
```
### class DbCollection
represents a collection of objects.
A collection is defined by the object class (that is extending smartdata.dbdoc) it respresents
So to get to get access to a specific collection you document
```javascript
// continues from the block before...
@Collection(myDb1)
class myObject extends smartdata.DbDoc<myObject> { // read the next block about DbDoc
@smartdata.svDb() property1: string // @smartdata.svDb() marks the property for db save
property2: number // this one is not marked, so it won't be save upon calling this.save()
constructor(optionsArg:{
property1: string,
property2: number
}) {
super()
}
}
let myCollection = myDb1.getCollectionByName<myObject>(myObject)
// start to instantiate classes from scratch or database
```
> Alert: You NEVER instantiate a collection.
This is done for you!!!
### class DbDoc
represents a individual document in a collection
and thereby is ideally suited to extend the class you want to actually store.
DbDoc extends your class with the following methods:
* `.save()` will save (or update) the object you call it on only. Any referenced non-savable objects will not get stored.
* `.saveDeep()` does the same like `.save()`.
In addition it will look for properties that reference an object
that extends DbDoc as well and call .saveDeep() on them as well.
Loops are prevented
So now we can **store** instances of classes to Db...
How do we **get** a new class instance from a Doc in the DB?
## TypeScript
How does TypeScript play into this?
Since you define your classes in TypeScript and types flow through smartdata in a generic way
you should get all the Intellisense and type checking you love when using smartdata.
smartdata itself also bundles typings.
So you don't need to install any additional types when importing smartdata.
For further information read the linked docs at the top of this README.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

17
npmextra.json Normal file
View File

@ -0,0 +1,17 @@
{
"npmdocker": {
"baseImage": "hosttoday/ht-docker-node:mongo",
"command": "npmci test stable",
"dockerSock": false
},
"npmci": {
"globalNpmTools": [
"npmts"
]
},
"npmts": {
"testConfig": {
"parallel": false
}
}
}

View File

@ -1,12 +1,12 @@
{
"name": "smartdata",
"version": "1.0.13",
"version": "1.0.24",
"description": "do more with data",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "(npm run prepareMongo && npmts)",
"prepareMongo": "(rm -rf ./test/data && mkdir ./test/data/)"
"test": "(npmts)",
"testLocal": "(npmdocker)"
},
"repository": {
"type": "git",
@ -19,19 +19,21 @@
},
"homepage": "https://gitlab.com/pushrocks/smartdata#README",
"dependencies": {
"@types/mongodb": "^2.1.32",
"@types/q": "0.0.30",
"beautylog": "^5.0.23",
"mongodb": "^2.2.9",
"q": "^1.4.1",
"typings-global": "^1.0.14"
"@types/lodash": "^4.14.66",
"@types/mongodb": "^2.2.6",
"beautylog": "^6.1.10",
"lik": "^1.0.32",
"lodash": "^4.17.4",
"mongodb": "^2.2.29",
"runtime-type-checks": "0.0.4",
"smartq": "^1.1.1",
"typings-global": "^1.0.19"
},
"devDependencies": {
"@types/shelljs": "^0.3.30",
"@types/should": "^8.1.29",
"shelljs": "^0.7.4",
"should": "^11.1.0",
"smartstring": "^2.0.17",
"typings-test": "^1.0.3"
"@types/shelljs": "^0.7.2",
"qenv": "^1.1.7",
"shelljs": "^0.7.8",
"smartstring": "^2.0.24",
"tapbundle": "^1.0.14"
}
}

4
qenv.yml Normal file
View File

@ -0,0 +1,4 @@
vars:
- MONGO_USER
- MONGO_PASS
- MONGO_DATABASE

52
test/test.class.ts Normal file
View File

@ -0,0 +1,52 @@
import { tap, expect } from 'tapbundle'
import * as smartq from 'smartq'
import { Qenv } from 'qenv'
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/')
// the tested module
import * as smartdata from '../dist/index'
let mongoChildProcess
let testDb: smartdata.Db
tap.test('should establish a connection to mongodb', async () => {
testDb = new smartdata.Db(`mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASS}@sandbox-shard-00-00-uyw7y.mongodb.net:27017,sandbox-shard-00-01-uyw7y.mongodb.net:27017,sandbox-shard-00-02-uyw7y.mongodb.net:27017/${process.env.MONGO_DATABASE}?ssl=true&replicaSet=sandbox-shard-0&authSource=admin`)
await testDb.connect()
})
let testCarInstance
tap.test('should create an extended class', async () => {
@smartdata.Collection(testDb)
class TestCar extends smartdata.DbDoc<TestCar> {
@smartdata.svDb()
color: string
constructor (optionsArg: {
color: string,
property2: number
}) {
super()
this.color = optionsArg.color
}
}
testCarInstance = new TestCar({
color: 'red',
property2: 2
})
expect(testCarInstance.name).to.equal('TestCar')
expect(testCarInstance.saveableProperties[ 0 ]).equal('color')
expect(testCarInstance.collection).be.instanceof(smartdata.DbCollection)
expect(testCarInstance).be.instanceof(smartdata.DbDoc)
if (!process.env.CI) { console.log(TestCar) }
})
tap.test('should save testCar', async () => {
await testCarInstance.save()
})
tap.test('should close the db Connection', async () => {
await testDb.close()
})
tap.start()

1
test/test.d.ts vendored
View File

@ -1 +0,0 @@
import 'typings-test';

View File

@ -1,79 +0,0 @@
"use strict";
require('typings-test');
const shelljs = require('shelljs');
const should = require('should');
const smartstring = require('smartstring');
// the tested module
const smartdata = require('../dist/index');
let mongoChildProcess;
let testDb;
let testDbCollection;
class testCar {
constructor(colorArg) {
this.color = colorArg;
}
}
describe('mongodb', function () {
it('should start mongodb', function (done) {
this.timeout(30000);
mongoChildProcess = shelljs.exec('mongod --dbpath=./test/data --port 27017', { async: true, silent: true });
let doneCalled = false;
mongoChildProcess.stdout.on('data', function (data) {
console.log(smartstring.indent.indentWithPrefix(data, "*** MongoDB Process *** : "));
if (!doneCalled) {
if (/waiting for connections on port 27017/.test(data)) {
doneCalled = true;
done();
}
}
});
});
});
describe('smartdata', function () {
it('should establish a connection to mongodb', function (done) {
testDb = new smartdata.Db('mongodb://localhost:27017/smartdata');
testDb.connect().then(() => { done(); });
});
it('should create a collection', function () {
testDbCollection = new smartdata.DbCollection('something', testDb);
});
it('should insert a doc into the collection', function (done) {
testDbCollection.insertOne({ value1: 'test' }).then(() => { done(); });
});
it('should find all docs of testDbCollection', function (done) {
testDbCollection.find({}).then((resultArray) => {
console.log(resultArray);
should(resultArray[0].value1).equal('test');
done();
});
});
it('should insert many docs into the collection', function (done) {
testDbCollection.insertMany([
{ value1: 'test2' },
{ value1: 'test', value2: 3, value3: 'hi' }
]).then(() => { done(); });
});
it('should find a specified doc', function (done) {
testDbCollection.find({ 'value3': { '$exists': true } }).then((resultArray) => {
console.log(resultArray);
should(resultArray[0].value3).equal('hi');
done();
}).catch(console.log);
});
it('should close the db Connection', function () {
testDb.close();
});
});
describe('mongodb', function () {
it('should kill mongodb', function (done) {
this.timeout(30000);
mongoChildProcess.stdout.on('data', function (data) {
if (/dbexit: rc: 0/.test(data)) {
done();
}
});
shelljs.exec('mongod --dbpath=./test/data --shutdown');
mongoChildProcess.kill('SIGTERM');
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sY0FFUCxDQUFDLENBRm9CO0FBRXJCLE1BQVksT0FBTyxXQUFNLFNBQ3pCLENBQUMsQ0FEaUM7QUFDbEMsTUFBWSxNQUFNLFdBQU0sUUFDeEIsQ0FBQyxDQUQrQjtBQUNoQyxNQUFZLFdBQVcsV0FBTSxhQUc3QixDQUFDLENBSHlDO0FBRTFDLG9CQUFvQjtBQUNwQixNQUFZLFNBQVMsV0FBTSxlQUUzQixDQUFDLENBRnlDO0FBRTFDLElBQUksaUJBQWlCLENBQUE7QUFDckIsSUFBSSxNQUFvQixDQUFBO0FBUXhCLElBQUksZ0JBQXNELENBQUE7QUFFMUQ7SUFFSSxZQUFZLFFBQWU7UUFDdkIsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUE7SUFDekIsQ0FBQztBQUNMLENBQUM7QUFHRCxRQUFRLENBQUMsU0FBUyxFQUFFO0lBQ2hCLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxVQUFVLElBQUk7UUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNuQixpQkFBaUIsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUMzRyxJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUE7UUFDdEIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxJQUFJO1lBQzlDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLENBQUMsQ0FBQyxDQUFBO1lBQ3BGLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDZCxFQUFFLENBQUMsQ0FBQyx1Q0FBdUMsQ0FBQyxJQUFJ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

View File

@ -1,8 +1,8 @@
import 'typings-test'
import { tap, expect } from 'tapbundle'
import * as smartq from 'smartq'
import { Qenv } from 'qenv'
import * as shelljs from 'shelljs'
import * as should from 'should'
import * as smartstring from 'smartstring'
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/')
// the tested module
import * as smartdata from '../dist/index'
@ -11,83 +11,55 @@ let mongoChildProcess
let testDb: smartdata.Db
interface ITestObject1 {
value1: string
value2?: number
value3?: string
value1: string
value2?: number
value3?: string
}
tap.test('should establish a connection to mongodb', async () => {
testDb = new smartdata.Db(`mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASS}@sandbox-shard-00-00-uyw7y.mongodb.net:27017,sandbox-shard-00-01-uyw7y.mongodb.net:27017,sandbox-shard-00-02-uyw7y.mongodb.net:27017/${process.env.MONGO_DATABASE}?ssl=true&replicaSet=sandbox-shard-0&authSource=admin`)
await testDb.connect()
})
// =======================================
// The actual tests
// =======================================
let testDbCollection: smartdata.DbCollection<ITestObject1>
class testCar {
color: string
constructor(colorArg:string) {
this.color = colorArg
}
}
describe('mongodb', function () {
it('should start mongodb', function (done) {
this.timeout(30000)
mongoChildProcess = shelljs.exec('mongod --dbpath=./test/data --port 27017', { async: true, silent: true })
let doneCalled = false
mongoChildProcess.stdout.on('data', function (data) {
console.log(smartstring.indent.indentWithPrefix(data, "*** MongoDB Process *** : "))
if (!doneCalled) {
if (/waiting for connections on port 27017/.test(data)) {
doneCalled = true
done()
}
}
})
})
tap.test('should give me a collection', async () => {
testDbCollection = await testDb.getObjectCollectionByName<ITestObject1>('TestValue', testDb, true)
})
describe('smartdata', function () {
it('should establish a connection to mongodb', function (done) {
testDb = new smartdata.Db('mongodb://localhost:27017/smartdata')
testDb.connect().then(() => { done() })
})
it('should create a collection', function () {
testDbCollection = new smartdata.DbCollection<ITestObject1>('something', testDb)
})
it('should insert a doc into the collection', function (done) {
testDbCollection.insertOne({ value1: 'test' }).then(() => { done() })
})
it('should find all docs of testDbCollection', function (done) {
testDbCollection.find({}).then((resultArray) => {
console.log(resultArray)
should(resultArray[0].value1).equal('test')
done()
})
})
it('should insert many docs into the collection', function (done) {
testDbCollection.insertMany([
{ value1: 'test2' },
{ value1: 'test', value2: 3, value3: 'hi' }
]).then(() => { done() })
})
it('should find a specified doc', function (done) {
testDbCollection.find({'value3': {'$exists': true}}).then((resultArray) => {
console.log(resultArray)
should(resultArray[0].value3).equal('hi')
done()
}).catch(console.log)
})
it('should close the db Connection', function () {
testDb.close()
})
tap.test('should insert a doc into the collection', async () => {
await testDbCollection.insertOne({ value1: 'test' })
})
describe('mongodb', function () {
it('should kill mongodb', function (done) {
this.timeout(30000)
mongoChildProcess.stdout.on('data', function (data) {
if (/dbexit: rc: 0/.test(data)) {
done()
}
})
shelljs.exec('mongod --dbpath=./test/data --shutdown')
mongoChildProcess.kill('SIGTERM')
})
tap.test('should find all docs of testDbCollection', async () => {
await testDbCollection.find({}).then(async (resultArray) => {
console.log(resultArray)
expect(resultArray[ 0 ].value1).equal('test')
})
})
tap.test('should insert many docs into the collection', async () => {
await testDbCollection.insertMany([
{ value1: 'test2' },
{ value1: 'test', value2: 3, value3: 'hi' }
])
})
tap.test('should find a specified doc', async () => {
await testDbCollection.find({ 'value3': { '$exists': true } }).then((resultArray) => {
console.log(resultArray)
expect(resultArray[ 0 ].value3).equal('hi')
})
})
tap.test('should close the db Connection', async () => {
await testDb.close()
})
tap.start()

View File

@ -1,4 +1,5 @@
import * as plugins from './smartdata.plugins'
export * from './smartdata.classes.dbcollection'
export * from './smartdata.classes.db'
export * from './smartdata.classes.dbcollection'
export * from './smartdata.classes.dbdoc'

View File

@ -1,33 +1,82 @@
import * as plugins from './smartdata.plugins'
import { Objectmap } from 'lik'
import { DbCollection } from './smartdata.classes.dbcollection'
import { getObjectDoc } from './smartdata.classes.dbobjectdoc'
/**
* interface - indicates the connection status of the db
*/
export type TConnectionStatus = 'disconnected' | 'connected' | 'failed'
export class Db {
dbUrl: string
db: plugins.mongodb.Db
status: TConnectionStatus
dbUrl: string
db: plugins.mongodb.Db
status: TConnectionStatus
classCollections = new Objectmap<DbCollection<any>>()
objectCollections = new Objectmap<DbCollection<any>>()
constructor(dbUrl: string) {
this.dbUrl = dbUrl
}
constructor (dbUrlArg: string) {
this.dbUrl = dbUrlArg
}
connect(): plugins.q.Promise<any> {
let done = plugins.q.defer()
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
if (err) { console.log(err) }
plugins.assert.equal(null, err)
this.db = db
plugins.beautylog.success(`connected to database at ${this.dbUrl}`)
done.resolve(this.db)
})
return done.promise
}
// basic connection stuff ----------------------------------------------
close(): plugins.q.Promise<any> {
let done = plugins.q.defer()
this.db.close()
plugins.beautylog.ok(`disconnected to database at ${this.dbUrl}`)
done.resolve()
return done.promise
/**
* connects to the database that was specified during instance creation
*/
connect (): Promise<any> {
let done = plugins.smartq.defer()
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
if (err) { console.log(err) }
plugins.assert.equal(null, err)
this.db = db
plugins.beautylog.success(`connected to database at ${this.dbUrl}`)
done.resolve(this.db)
})
return done.promise
}
/**
* closes the connection to the databse
*/
close (): Promise<any> {
let done = plugins.smartq.defer()
this.db.close()
plugins.beautylog.ok(`disconnected to database at ${this.dbUrl}`)
done.resolve()
return done.promise
}
// advanced communication with the database --------------------------------
/**
* gets a class based collection by name: string
*/
async getClassCollectionByName<T> (nameArg: string): Promise<DbCollection<T>> {
let resultCollection = this.classCollections.find((dbCollectionArg) => {
return dbCollectionArg.name === nameArg
})
return resultCollection
}
/**
* gets an object collection by name
*/
async getObjectCollectionByName<T> (nameArg: string, dbArg: Db , makeNewArg: boolean = false): Promise<DbCollection<T>> {
let resultCollection = this.objectCollections.find((dbCollectionArg) => {
return dbCollectionArg.name === nameArg
})
if (!resultCollection && makeNewArg) {
resultCollection = getObjectDoc(nameArg, this).collection
return resultCollection
} else {
return resultCollection
}
}
addCollection (dbCollectionArg: DbCollection<any>) {
this.classCollections.add(dbCollectionArg)
}
}

View File

@ -1,60 +1,117 @@
import * as plugins from './smartdata.plugins'
import { Db } from './smartdata.classes.db'
import { DbDoc } from './smartdata.classes.dbDoc'
export interface IFindOptions {
limit?: number
}
export interface IDocValidation<T> {
(doc: T): boolean
}
export function Collection (db: Db) {
return function (constructor) {
constructor[ 'dbCollection' ] = new DbCollection(constructor, db)
}
}
export class DbCollection<T> {
collection: plugins.mongodb.Collection
constructor(nameArg: string, dbArg: Db) {
this.collection = dbArg.db.collection(nameArg)
}
/**
* the collection that is used, defaults to mongodb collection,
* can be nedb datastore (sub api of mongodb)
*/
collection: plugins.mongodb.Collection
collectedClass: T & DbDoc<T>
objectValidation: IDocValidation<T> = null
name: string
db: Db
/**
* adds a validation function that all newly inserted and updated objects have to pass
*/
addObjectValidation(funcArg) { }
constructor (collectedClassArg: T & DbDoc<T>, dbArg: Db) {
// tell the collection where it belongs
this.collectedClass = collectedClassArg
this.name = collectedClassArg.name
this.db = dbArg
/**
* finds an object in the DbCollection
*/
find(docMatchArg: T | any): plugins.q.Promise<T[]> {
let done = plugins.q.defer<T[]>()
this.collection.find(docMatchArg).toArray((err, docs) => {
if (err) { throw err }
done.resolve(docs)
})
return done.promise
}
// make sure it actually exists
this.collection = dbArg.db.collection(this.name)
/**
* inserts object into the DbCollection
*/
insertOne(docArg: T): plugins.q.Promise<void> {
let done = plugins.q.defer<void>()
this.checkDoc(docArg).then(() => {
this.collection.insertOne(docArg)
.then(() => { done.resolve() })
})
return done.promise
}
// tell the db class about it (important since Db uses different systems under the hood)
this.db.addCollection(this)
}
/**
* inserts many objects at once into the DbCollection
*/
insertMany(docArrayArg: T[]): plugins.q.Promise<void> {
let done = plugins.q.defer<void>()
let checkDocPromiseArray: plugins.q.Promise<void>[] = []
for (let docArg of docArrayArg){
checkDocPromiseArray.push(this.checkDoc(docArg))
}
plugins.q.all(checkDocPromiseArray).then(() => {
this.collection.insertMany(docArrayArg)
.then(() => { done.resolve() })
})
return done.promise
}
/**
* adds a validation function that all newly inserted and updated objects have to pass
*/
addDocValidation (funcArg: IDocValidation<T>) {
this.objectValidation = funcArg
}
private checkDoc(doc: T): plugins.q.Promise<void> {
let done = plugins.q.defer<void>()
done.resolve()
return done.promise
/**
* finds an object in the DbCollection
*/
find (docMatchArg: T | any, optionsArg?: IFindOptions): Promise<T[]> {
let done = plugins.smartq.defer<T[]>()
let findCursor = this.collection.find(docMatchArg)
if (optionsArg) {
if (optionsArg.limit) { findCursor = findCursor.limit(1) }
}
findCursor.toArray((err, docs) => {
if (err) {
done.reject(err)
throw err
}
done.resolve(docs)
})
return done.promise
}
/**
* inserts object into the DbCollection
*/
insertOne (docArg: T): Promise<void> {
let done = plugins.smartq.defer<void>()
this.checkDoc(docArg).then(
() => {
this.collection.insertOne(docArg)
.then(() => { done.resolve() })
},
() => {
done.reject(new Error('one the docs did not pass validation'))
})
return done.promise
}
/**
* inserts many objects at once into the DbCollection
*/
insertMany (docArrayArg: T[]): Promise<void> {
let done = plugins.smartq.defer<void>()
let checkDocPromiseArray: Promise<void>[] = []
for (let docArg of docArrayArg) {
checkDocPromiseArray.push(this.checkDoc(docArg))
}
Promise.all(checkDocPromiseArray).then(() => {
this.collection.insertMany(docArrayArg)
.then(() => { done.resolve() })
})
return done.promise
}
/**
* checks a Doc for constraints
*/
private checkDoc (docArg: T): Promise<void> {
let done = plugins.smartq.defer<void>()
let validationResult = true
if (this.objectValidation) {
validationResult = this.objectValidation(docArg)
}
if (validationResult) {
done.resolve()
} else {
done.reject('validation of object did not pass')
}
return done.promise
}
}

View File

@ -0,0 +1,86 @@
import * as plugins from './smartdata.plugins'
import { Objectmap } from 'lik'
import { Db } from './smartdata.classes.db'
import { DbCollection } from './smartdata.classes.dbcollection'
export type TDocCreation = 'db' | 'new' | 'mixed'
/**
* saveable - saveable decorator to be used on class properties
*/
export function svDb() {
return (target: DbDoc<any>, key: string) => {
console.log('called sva')
if (!target.saveableProperties) { target.saveableProperties = [] }
target.saveableProperties.push(key)
}
}
export class DbDoc<T> {
/**
* the collection object an Doc belongs to
*/
collection: DbCollection<T>
/**
* how the Doc in memory was created, may prove useful later.
*/
creationType: TDocCreation
/**
* an array of saveable properties of a doc
*/
saveableProperties: string[]
/**
* name
*/
name: string
/**
* class constructor
*/
constructor () {
this.name = this.constructor['name']
this.collection = this.constructor[ 'dbCollection' ]
}
/**
* saves this instance but not any connected items
* may lead to data inconsistencies, but is faster
*/
save() {
let saveableObject: any = {} // is not exposed to outside, so any is ok here
for (let propertyNameString of this.saveableProperties) {
saveableObject[ propertyNameString ] = this[ propertyNameString ]
}
switch (this.creationType) {
case 'db':
this.collection // TODO implement collection.update()
break
case 'new':
this.collection.insertOne(saveableObject)
}
}
/**
* also store any referenced objects to DB
* better for data consistency
*/
saveDeep(savedMapArg: Objectmap<DbDoc<any>> = null) {
if (!savedMapArg) {
savedMapArg = new Objectmap<DbDoc<any>>()
}
savedMapArg.add(this)
this.save()
for (let propertyKey in this) {
let property = this[ propertyKey ]
if (property instanceof DbDoc && !savedMapArg.checkForObject(property)) {
property.saveDeep(savedMapArg)
}
}
}
}

View File

@ -0,0 +1,12 @@
import * as plugins from './smartdata.plugins'
import { Db } from './smartdata.classes.db'
import { DbDoc } from './smartdata.classes.dbdoc'
import { DbCollection } from './smartdata.classes.dbcollection'
export let getObjectDoc = (nameArg,dbArg: Db) => {
let objectDoc = new DbDoc()
objectDoc.name = nameArg
objectDoc.collection = new DbCollection(objectDoc, dbArg)
return objectDoc
}

View File

@ -1,5 +1,14 @@
import 'typings-global'
export import assert = require('assert')
export import beautylog = require('beautylog')
export import mongodb = require('mongodb')
export import q = require('q')
import * as assert from 'assert'
import * as beautylog from 'beautylog'
import * as lodash from 'lodash'
import * as mongodb from 'mongodb'
import * as smartq from 'smartq'
export {
assert,
beautylog,
lodash,
mongodb,
smartq
}

8
tsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"lib": [
"es2015"
]
}
}

774
yarn.lock Normal file
View File

@ -0,0 +1,774 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/bson@*":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/bson/-/bson-1.0.3.tgz#6c26f0876bf9d8cbb06edd4019e29354bf3a03e0"
dependencies:
"@types/node" "*"
"@types/chai-as-promised@0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-0.0.29.tgz#43d52892aa998e185a3de3e2477edb8573be1d77"
dependencies:
"@types/chai" "*"
"@types/promises-a-plus" "*"
"@types/chai-string@^1.1.30":
version "1.1.30"
resolved "https://registry.yarnpkg.com/@types/chai-string/-/chai-string-1.1.30.tgz#4d8744b31a5a2295fc01c981ed1e2d4c8a070f0a"
dependencies:
"@types/chai" "*"
"@types/chai@*", "@types/chai@^3.4.35":
version "3.5.2"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-3.5.2.tgz#c11cd2817d3a401b7ba0f5a420f35c56139b1c1e"
"@types/fs-extra@3.x.x":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-3.0.3.tgz#1d66eb670ebf657e57c0fda014df340c19d8aa0c"
dependencies:
"@types/node" "*"
"@types/lodash@^4.14.55", "@types/lodash@^4.14.62", "@types/lodash@^4.14.66":
version "4.14.66"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.66.tgz#3dbb83477becf130611f8fac82a8fdb199805981"
"@types/minimatch@2.x.x":
version "2.0.29"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-2.0.29.tgz#5002e14f75e2d71e564281df0431c8c1b4a2a36a"
"@types/mongodb@^2.2.6":
version "2.2.6"
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-2.2.6.tgz#cd7cb4c439219af1dfba5860d302eeaf2b0a13e4"
dependencies:
"@types/bson" "*"
"@types/node" "*"
"@types/node@*":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.1.tgz#89c271e0c3b9ebb6a3756dd601336970b6228b77"
"@types/promises-a-plus@*":
version "0.0.27"
resolved "https://registry.yarnpkg.com/@types/promises-a-plus/-/promises-a-plus-0.0.27.tgz#c64651134614c84b8f5d7114ce8901d36a609780"
"@types/q@1.x.x":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.0.1.tgz#dbccb01bd8f0f801a12a4604c7d7af59bb02ae2f"
"@types/shelljs@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.6.0.tgz#090b705c102ce7fc5c0c5ea9b524418ff15840df"
dependencies:
"@types/node" "*"
"@types/shelljs@^0.7.2":
version "0.7.2"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.2.tgz#c2bdb3fe80cd7a3da08750ca898ae44c589671f3"
dependencies:
"@types/node" "*"
"@types/vinyl@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.0.tgz#fd213bf7f4136dde21fe1895500b12c186f8c268"
dependencies:
"@types/node" "*"
"@types/which@^1.0.28":
version "1.0.28"
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
ansi-256-colors@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz#910de50efcc7c09e3d82f2f87abd6b700c18818a"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
sprintf-js "~1.0.2"
assertion-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
beautycolor@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/beautycolor/-/beautycolor-1.0.7.tgz#a4715738ac4c8221371e9cbeb5a6cc6d11ecbf7c"
dependencies:
ansi-256-colors "^1.1.0"
typings-global "^1.0.14"
beautylog@^6.1.10:
version "6.1.10"
resolved "https://registry.yarnpkg.com/beautylog/-/beautylog-6.1.10.tgz#9c27e566937684cb689f9372d98cfa5415d50b72"
dependencies:
"@types/lodash" "^4.14.55"
beautycolor "^1.0.7"
figlet "^1.2.0"
lodash "^4.17.4"
ora "^1.1.0"
smartenv "^2.0.0"
smartq "^1.1.1"
typings-global "^1.0.14"
bindings@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
bson@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.4.tgz#93c10d39eaa5b58415cbc4052f3e53e562b0b72c"
buffer-shims@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
chai-as-promised@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-6.0.0.tgz#1a02a433a6f24dafac63b9c96fa1684db1aa8da6"
dependencies:
check-error "^1.0.2"
chai-string@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.4.0.tgz#359140c051d36a4e4b1a5fc6b910152f438a8d49"
chai@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247"
dependencies:
assertion-error "^1.0.1"
deep-eql "^0.1.3"
type-detect "^1.0.0"
chalk@^1.0.0, chalk@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
cli-spinners@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.0.0.tgz#ef987ed3d48391ac3dab9180b406a742180d6e6a"
clone-buffer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
clone-stats@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
clone@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
cloneable-readable@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117"
dependencies:
inherits "^2.0.1"
process-nextick-args "^1.0.6"
through2 "^2.0.1"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
deep-eql@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2"
dependencies:
type-detect "0.1.1"
early@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/early/-/early-2.1.1.tgz#841e23254ea5dc54d8afaeee82f5ab65c00ee23c"
dependencies:
beautycolor "^1.0.7"
smartq "^1.1.1"
typings-global "^1.0.16"
es6-error@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.2.tgz#eec5c726eacef51b7f6b73c20db6e1b13b069c98"
es6-promise@3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
esprima@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
figlet@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.2.0.tgz#6c46537378fab649146b5a6143dda019b430b410"
first-chunk-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
dependencies:
readable-stream "^2.0.2"
fs-extra@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
dependencies:
graceful-fs "^4.1.2"
jsonfile "^3.0.0"
universalify "^0.1.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
glob@^7.0.0, glob@^7.1.1:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
home@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/home/-/home-1.0.1.tgz#96a423ceb49b98378ff5ef3ceae059a557f9dd35"
dependencies:
os-homedir "^1.0.1"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.1, inherits@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
interpret@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
is-utf8@^0.2.0, is-utf8@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
js-base64@^2.1.9:
version "2.1.9"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce"
js-yaml@^3.8.3:
version "3.8.4"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6"
dependencies:
argparse "^1.0.7"
esprima "^3.1.1"
jsonfile@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.0.tgz#92e7c7444e5ffd5fa32e6a9ae8b85034df8347d0"
optionalDependencies:
graceful-fs "^4.1.6"
leakage@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/leakage/-/leakage-0.3.0.tgz#15d698abdc76bbc6439601f4f3020e77e2d50c39"
dependencies:
es6-error "^4.0.2"
left-pad "^1.1.3"
memwatch-next "^0.3.0"
minimist "^1.2.0"
pretty-bytes "^4.0.2"
left-pad@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.1.3.tgz#612f61c033f3a9e08e939f1caebeea41b6f3199a"
lik@^1.0.32:
version "1.0.32"
resolved "https://registry.yarnpkg.com/lik/-/lik-1.0.32.tgz#41ee6c8edd483eaa11bd089775263955f5555060"
dependencies:
"@types/lodash" "^4.14.62"
"@types/minimatch" "2.x.x"
"@types/q" "1.x.x"
lodash "^4.17.4"
minimatch "^3.0.3"
q "^1.5.0"
rxjs "^5.3.0"
smartq "^1.1.1"
tapbundle "^1.0.14"
typings-global "^1.0.14"
lodash@^4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
dependencies:
chalk "^1.0.0"
memwatch-next@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/memwatch-next/-/memwatch-next-0.3.0.tgz#2111050f9a906e0aa2d72a4ec0f0089c78726f8f"
dependencies:
bindings "^1.2.1"
nan "^2.3.2"
mimic-fn@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
minimatch@^3.0.3, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
mongodb-core@2.1.13:
version "2.1.13"
resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.13.tgz#771ef638270ac993ab42984689ab824251b96a88"
dependencies:
bson "~1.0.4"
require_optional "~1.0.0"
mongodb@^2.2.29:
version "2.2.29"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.29.tgz#36b244126f26766c5ebd6465b8ab5b542d6833c5"
dependencies:
es6-promise "3.2.1"
mongodb-core "2.1.13"
readable-stream "2.2.7"
nan@^2.3.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
dependencies:
mimic-fn "^1.0.0"
ora@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-1.3.0.tgz#80078dd2b92a934af66a3ad72a5b910694ede51a"
dependencies:
chalk "^1.1.1"
cli-cursor "^2.1.0"
cli-spinners "^1.0.0"
log-symbols "^1.0.2"
os-homedir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
pretty-bytes@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
process-nextick-args@^1.0.6, process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
q@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
qenv@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/qenv/-/qenv-1.1.7.tgz#d03f8bf8fe37494cf08d0919fe765dca84d9afae"
dependencies:
lodash "^4.17.4"
smartfile "^4.2.11"
typings-global "^1.0.16"
readable-stream@2.2.7, readable-stream@^2.0.2, readable-stream@^2.1.5:
version "2.2.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1"
dependencies:
buffer-shims "~1.0.0"
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~1.0.0"
util-deprecate "~1.0.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
dependencies:
resolve "^1.1.6"
reflect-metadata@^0.1.2:
version "0.1.10"
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a"
remove-trailing-separator@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511"
replace-ext@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
require-reload@0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/require-reload/-/require-reload-0.2.2.tgz#29a7591846caf91b6e8a3cda991683f95f8d7d42"
require_optional@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e"
dependencies:
resolve-from "^2.0.0"
semver "^5.1.0"
resolve-from@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
resolve@^1.1.6:
version "1.3.3"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
dependencies:
path-parse "^1.0.5"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
dependencies:
onetime "^2.0.0"
signal-exit "^3.0.2"
runtime-type-checks@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/runtime-type-checks/-/runtime-type-checks-0.0.4.tgz#5682baf2ffe53f955fe3e065b40a0a09943845c8"
dependencies:
reflect-metadata "^0.1.2"
rxjs@^5.3.0:
version "5.4.1"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.1.tgz#b62f757f279445d265a18a58fb0a70dc90e91626"
dependencies:
symbol-observable "^1.0.1"
safe-buffer@~5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
semver@^5.1.0, semver@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
shelljs@^0.7.6, shelljs@^0.7.8:
version "0.7.8"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
smartchai@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-1.0.3.tgz#de6d010bb8b5aef24cb70b31a5f5334e8c41b72f"
dependencies:
"@types/chai" "^3.4.35"
"@types/chai-as-promised" "0.0.29"
"@types/chai-string" "^1.1.30"
chai "^3.5.0"
chai-as-promised "^6.0.0"
chai-string "^1.3.0"
smartdelay@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/smartdelay/-/smartdelay-1.0.3.tgz#5fd44dad77262d110702f0293efa80c072cfb579"
dependencies:
smartq "^1.1.1"
typings-global "^1.0.16"
smartenv@^2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/smartenv/-/smartenv-2.0.6.tgz#b38c679b0c151b9af548f68c3a072c29d1417e8d"
dependencies:
lodash "^4.17.4"
smartq "^1.1.1"
typings-global "^1.0.14"
smartfile@^4.2.11:
version "4.2.17"
resolved "https://registry.yarnpkg.com/smartfile/-/smartfile-4.2.17.tgz#9eba8f65eea7e4db51aa30562f6039815a88b125"
dependencies:
"@types/fs-extra" "3.x.x"
"@types/vinyl" "^2.0.0"
fs-extra "^3.0.1"
glob "^7.1.1"
js-yaml "^3.8.3"
require-reload "0.2.2"
smartpath "^3.2.8"
smartq "^1.1.1"
smartrequest "^1.0.4"
typings-global "^1.0.16"
vinyl "^2.0.2"
vinyl-file "^3.0.0"
smartpath@^3.2.8:
version "3.2.8"
resolved "https://registry.yarnpkg.com/smartpath/-/smartpath-3.2.8.tgz#4834bd3a8bae2295baacadba23c87a501952f940"
dependencies:
home "^1.0.1"
typings-global "^1.0.14"
smartq@^1.1.0, smartq@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/smartq/-/smartq-1.1.1.tgz#efb358705260d41ae18aef7ffd815f7b6fe17dd3"
dependencies:
typed-promisify "^0.3.0"
typings-global "^1.0.14"
smartrequest@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/smartrequest/-/smartrequest-1.0.6.tgz#a006454332453b0a70d38a003a29963d039a7783"
dependencies:
smartq "^1.1.1"
typings-global "^1.0.17"
smartshell@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/smartshell/-/smartshell-1.0.6.tgz#27b1c79029784abe72ac7e91fe698b7ebecc6629"
dependencies:
"@types/shelljs" "^0.6.0"
"@types/which" "^1.0.28"
shelljs "^0.7.6"
smartq "^1.1.0"
which "^1.2.12"
smartstring@^2.0.24:
version "2.0.24"
resolved "https://registry.yarnpkg.com/smartstring/-/smartstring-2.0.24.tgz#dc1c5efb738c10a2d7daeea3d800ad2ecc65a26c"
dependencies:
js-base64 "^2.1.9"
typings-global "^1.0.14"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
string_decoder@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
strip-bom-buf@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572"
dependencies:
is-utf8 "^0.2.1"
strip-bom-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
dependencies:
first-chunk-stream "^2.0.0"
strip-bom "^2.0.0"
strip-bom@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
dependencies:
is-utf8 "^0.2.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
symbol-observable@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
tapbundle@^1.0.14:
version "1.0.14"
resolved "https://registry.yarnpkg.com/tapbundle/-/tapbundle-1.0.14.tgz#75827e335fcb02216f0267a26a26d702ddc02e3c"
dependencies:
early "^2.1.1"
leakage "^0.3.0"
smartchai "^1.0.3"
smartdelay "^1.0.3"
smartq "^1.1.1"
typings-global "^1.0.16"
through2@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
dependencies:
readable-stream "^2.1.5"
xtend "~4.0.1"
type-detect@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822"
type-detect@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
typed-promisify@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/typed-promisify/-/typed-promisify-0.3.0.tgz#1ba0af5e444c87d8047406f18ce49092a1191853"
typings-global@^1.0.14, typings-global@^1.0.16, typings-global@^1.0.17, typings-global@^1.0.19:
version "1.0.19"
resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.19.tgz#3376a72d4de1e5541bf5702248ff64c3e6ea316c"
dependencies:
semver "^5.3.0"
smartshell "^1.0.6"
universalify@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.0.tgz#9eb1c4651debcc670cc94f1a75762332bb967778"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
vinyl-file@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-3.0.0.tgz#b104d9e4409ffa325faadd520642d0a3b488b365"
dependencies:
graceful-fs "^4.1.2"
pify "^2.3.0"
strip-bom-buf "^1.0.0"
strip-bom-stream "^2.0.0"
vinyl "^2.0.1"
vinyl@^2.0.1, vinyl@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c"
dependencies:
clone "^1.0.0"
clone-buffer "^1.0.0"
clone-stats "^1.0.0"
cloneable-readable "^1.0.0"
is-stream "^1.1.0"
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
which@^1.2.12:
version "1.2.14"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
dependencies:
isexe "^2.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"