Compare commits

..

3 Commits

Author SHA1 Message Date
9e11301135 1.0.23 2017-06-23 11:24:54 +02:00
9ba29b7b81 update README 2017-06-23 11:24:51 +02:00
1540f443e6 remove NEDB and update to use mpngo db atlas for testing 2017-06-23 11:19:48 +02:00
33 changed files with 1698 additions and 2197 deletions

View File

@ -3,125 +3,66 @@ image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
- .yarn/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- metadata
- trigger
- pages
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testLEGACY:
stage: test
script:
- npmci node install legacy
- npmci npm install
- npmci npm test
- npmci test legacy
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
- docker
allow_failure: true
testLTS:
stage: test
script:
- npmci node install lts
- npmci npm install
- npmci npm test
- npmci test lts
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
- docker
testSTABLE:
stage: test
script:
- npmci node install stable
- npmci npm install
- npmci npm test
- npmci test stable
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
- docker
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
- npmci publish
only:
- tags
- tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags:
- docker
- priv
- docker
trigger:
stage: metadata
stage: trigger
script:
- npmci trigger
- npmci trigger
only:
- tags
- tags
tags:
- docker
- notpriv
- docker
pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata
stage: pages
script:
- npmci command npm install -g npmpage
- npmci command yarn global add npmpage
- npmci command npmpage
tags:
- docker
- notpriv
only:
- tags
artifacts:
@ -129,13 +70,3 @@ pages:
paths:
- public
allow_failure: true
windowsCompatibility:
image: stefanscherer/node-windows:10-build-tools
stage: metadata
script:
- npm install & npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- windows
allow_failure: true

106
README.md
View File

@ -1,129 +1,29 @@
# @pushrocks/smartdata
do more with data and RethinkDB
# smartdata
do more with data
## 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)
[![Known Vulnerabilities](https://snyk.io/test/npm/smartdata/badge.svg)](https://snyk.io/test/npm/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 RethinkDB as persistent storage.
## Intention
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 RethinkDB's terms map to the ones of smartdata:
| MongoDb term | smartdata class |
| -------------- | ------------------------------|
| Database | smartdata.SmartdataDb |
| Collection | smartdata.SmartdataCollection |
| Document | smartdata.SmartadataDoc |
### class Db
represents a Database. Naturally it has .connect() etc. methods on it.
```typescript
import * as smartdata from 'smartdata';
const smartdataDb = new smartdata.SmartdataDb({
mongoDbUrl: '//someurl',
mongoDbName: 'myDatabase',
mongoDbPass: 'mypassword'
});
smartdataDb.connect();
```
### 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...
@smartdata.Collection(smartdataDb)
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();
}
}
// start to instantiate instances of classes from scratch or database
let localObject = new MyObject({
property1: 'hi',
property2: 2
});
localObject.save(); // saves the object to the database
// start retrieving instances
MyObject.getInstance<MyObject>({
property: 'hi'
}); // outputs a new instance of MyObject with the values from db assigned
```
### class DbDoc
represents a individual document in a collection
and thereby is ideally suited to extend the class you want to actually store.
**sStore** instances of classes to Db:
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
**Get** a new class instance from a Doc in the DB:
DbDoc exposes a static method that allows you specify a filter to retrieve a cloned class of the one you used to that doc at some point later in time. Yes, let that sink in a minute :)
So you can just call `.getInstance({ /* filter props here */ })`.
## 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)
| 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)

3
dist/index.d.ts vendored Normal file
View File

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

9
dist/index.js vendored Normal file
View File

@ -0,0 +1,9 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
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=

32
dist/smartdata.classes.db.d.ts vendored Normal file
View File

@ -0,0 +1,32 @@
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;
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;
}

81
dist/smartdata.classes.db.js vendored Normal file
View File

@ -0,0 +1,81 @@
"use strict";
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(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.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() {
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsK0NBQThDO0FBQzlDLDZCQUErQjtBQUcvQixtRkFBOEQ7QUFPOUQ7SUFPRSxZQUFhLFFBQWdCO1FBSDdCLHFCQUFnQixHQUFHLElBQUksZUFBUyxFQUFxQixDQUFBO1FBQ3JELHNCQUFpQixHQUFHLElBQUksZUFBUyxFQUFxQixDQUFBO1FBR3BELElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFBO0lBQ3ZCLENBQUM7SUFFRCx3RUFBd0U7SUFFeEU7O09BRUc7SUFDSCxPQUFPO1FBQ0wsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNqQyxPQUFPLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3RELEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUFDLENBQUM7WUFDN0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBQy9CLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFBO1lBQ1osT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsNEJBQTRCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO1lBQ25FLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ3ZCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDckIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSztRQUNILElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDakMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNmLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLCtCQUErQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtRQUNqRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUNyQixDQUFDO0lBRUQsNEVBQTRFO0lBRTVFOztPQUVHO0lBQ0csd0JBQXdCLENBQUssT0FBZTs7WUFDaEQsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsZUFBZTtnQkFDaEUsTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFBO1lBQ3pDLENBQUMsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFBO1FBQ3pCLENBQUM7S0FBQTtJQUVEOztPQUVHO0lBQ0cseUJBQXlCLENBQUssT0FBZSxFQUFFLEtBQVMsRUFBRyxhQUFzQixLQUFLOztZQUMxRixJQUFJLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlO2dCQUNqRSxNQUFNLENBQUMsZUFBZSxDQUFDLElBQUksS0FBSyxPQUFPLENBQUE7WUFDekMsQ0FBQyxDQUFDLENBQUE7WUFDRixFQUFFLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLGdCQUFnQixHQUFHLDRDQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQTtnQkFDekQsTUFBTSxDQUFDLGdCQUFnQixDQUFBO1lBQ3pCLENBQUM7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixNQUFNLENBQUMsZ0JBQWdCLENBQUE7WUFDekIsQ0FBQztRQUNILENBQUM7S0FBQTtJQUVELGFBQWEsQ0FBRSxlQUFrQztRQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFBO0lBQzVDLENBQUM7Q0FFRjtBQXRFRCxnQkFzRUMifQ==

View File

@ -0,0 +1,42 @@
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;
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
*/
addDocValidation(funcArg: IDocValidation<T>): void;
/**
* finds an object in the DbCollection
*/
find(docMatchArg: T | any, optionsArg?: IFindOptions): Promise<T[]>;
/**
* inserts object into the DbCollection
*/
insertOne(docArg: T): Promise<void>;
/**
* inserts many objects at once into the DbCollection
*/
insertMany(docArrayArg: T[]): Promise<void>;
/**
* checks a Doc for constraints
*/
private checkDoc(docArg);
}

95
dist/smartdata.classes.dbcollection.js vendored Normal file
View File

@ -0,0 +1,95 @@
"use strict";
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(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
*/
addDocValidation(funcArg) {
this.objectValidation = funcArg;
}
/**
* finds an object in the DbCollection
*/
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);
});
return done.promise;
}
/**
* inserts object into the DbCollection
*/
insertOne(docArg) {
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;
}
/**
* inserts many objects at once into the DbCollection
*/
insertMany(docArrayArg) {
let done = plugins.smartq.defer();
let checkDocPromiseArray = [];
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
*/
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0NBQThDO0FBWTlDLG9CQUE0QixFQUFNO0lBQ2hDLE1BQU0sQ0FBQyxVQUFVLFdBQVc7UUFDMUIsV0FBVyxDQUFFLGNBQWMsQ0FBRSxHQUFHLElBQUksWUFBWSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNuRSxDQUFDLENBQUE7QUFDSCxDQUFDO0FBSkQsZ0NBSUM7QUFFRDtJQVdFLFlBQWEsaUJBQStCLEVBQUUsS0FBUztRQUp2RCxxQkFBZ0IsR0FBc0IsSUFBSSxDQUFBO1FBS3hDLHVDQUF1QztRQUN2QyxJQUFJLENBQUMsY0FBYyxHQUFHLGlCQUFpQixDQUFBO1FBQ3ZDLElBQUksQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFBO1FBRWYsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRWhELHdGQUF3RjtRQUN4RixJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxnQkFBZ0IsQ0FBRSxPQUEwQjtRQUMxQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFBO0lBQ2pDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksQ0FBRSxXQUFvQixFQUFFLFVBQXlCO1FBQ25ELElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFPLENBQUE7UUFDdEMsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDbEQsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUNmLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQUMsQ0FBQztRQUM1RCxDQUFDO1FBQ0QsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJO1lBQzNCLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ1IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDaEIsTUFBTSxHQUFHLENBQUE7WUFDWCxDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNwQixDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsQ0FBRSxNQUFTO1FBQ2xCLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFRLENBQUE7UUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQ3hCO1lBQ0UsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO2lCQUM5QixJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNuQyxDQUFDLEVBQ0Q7WUFDRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsQ0FBQTtRQUNoRSxDQUFDLENBQUMsQ0FBQTtRQUNKLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVUsQ0FBRSxXQUFnQjtRQUMxQixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBUSxDQUFBO1FBQ3ZDLElBQUksb0JBQW9CLEdBQW9CLEVBQUUsQ0FBQTtRQUM5QyxHQUFHLENBQUMsQ0FBQyxJQUFJLE1BQU0sSUFBSSxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQy9CLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDbEQsQ0FBQztRQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDckMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDO2lCQUNwQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNuQyxDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNLLFFBQVEsQ0FBRSxNQUFTO1FBQ3pCLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFRLENBQUE7UUFDdkMsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUE7UUFDM0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUMxQixnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbEQsQ0FBQztRQUNELEVBQUUsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUNyQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDaEIsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFBO1FBQ2xELENBQUM7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUNyQixDQUFDO0NBQ0Y7QUFsR0Qsb0NBa0dDIn0=

39
dist/smartdata.classes.dbdoc.d.ts vendored Normal file
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;
}

61
dist/smartdata.classes.dbdoc.js vendored Normal file
View File

@ -0,0 +1,61 @@
"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==

7
dist/smartdata.plugins.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
import 'typings-global';
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 };

14
dist/smartdata.plugins.js vendored Normal file
View File

@ -0,0 +1,14 @@
"use strict";
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,16 +1,13 @@
# smartdata
do more with data
## 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)
@ -21,9 +18,96 @@ do more with data
[![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 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.Db
Collection | smartdata.DbCollection
Document | smartdata.DbDoc
### 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)
| 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)

View File

@ -5,10 +5,9 @@
"dockerSock": false
},
"npmci": {
"npmGlobalTools": [
"@gitzone/npmts"
],
"npmAccessLevel": "public"
"globalNpmTools": [
"npmts"
]
},
"npmts": {
"testConfig": {

1558
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,12 @@
{
"name": "@pushrocks/smartdata",
"version": "3.1.2",
"private": false,
"name": "smartdata",
"version": "1.0.23",
"description": "do more with data",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "tsrun test/test.ts",
"testLocal": "(npmdocker)",
"build": "(npmts)"
"test": "(npmts)",
"testLocal": "(npmdocker)"
},
"repository": {
"type": "git",
@ -21,23 +19,21 @@
},
"homepage": "https://gitlab.com/pushrocks/smartdata#README",
"dependencies": {
"@pushrocks/smartlog": "^1.0.6",
"@pushrocks/smartpromise": "^2.0.5",
"@types/lodash": "^4.14.110",
"@types/mongodb": "^3.1.1",
"lik": "^2.0.5",
"lodash": "^4.17.10",
"mongodb": "^3.1.1",
"@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",
"smartstring": "^2.0.28"
"smartq": "^1.1.1",
"typings-global": "^1.0.19"
},
"devDependencies": {
"@gitzone/tsrun": "^1.1.2",
"@types/node": "^10.5.2",
"@types/shortid": "0.0.29",
"mongodb-memory-server": "^1.9.0",
"@types/shelljs": "^0.7.2",
"qenv": "^1.1.7",
"shortid": "^2.2.11",
"tapbundle": "^2.0.2"
"shelljs": "^0.7.8",
"smartstring": "^2.0.24",
"tapbundle": "^1.0.14"
}
}

View File

@ -1,4 +1,4 @@
vars:
- MONGO_URL
- MONGO_DBNAME
- 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()

View File

@ -1,65 +1,65 @@
import { tap, expect } from 'tapbundle';
import * as smartpromise from '@pushrocks/smartpromise';
import { Qenv } from 'qenv';
import { tap, expect } from 'tapbundle'
import * as smartq from 'smartq'
import { Qenv } from 'qenv'
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/');
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/')
// the tested module
import * as smartdata from '../ts/index';
import { smartstring } from '../ts/smartdata.plugins';
import * as shortid from 'shortid';
import * as smartdata from '../dist/index'
// =======================================
// Connecting to the database server
// =======================================
let mongoChildProcess
let testDb: smartdata.Db
let testDb = new smartdata.SmartdataDb({
mongoDbName: process.env.MONGO_DBNAME,
mongoDbUrl: process.env.MONGO_URL,
mongoDbPass: process.env.MONGO_PASS
});
interface ITestObject1 {
value1: string
value2?: number
value3?: string
}
tap.test('should establish a connection to the rethink Db cluster', async () => {
await testDb.connect();
});
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
// =======================================
// ------
// Collections
// ------
let testDbCollection: smartdata.DbCollection<ITestObject1>
@smartdata.Collection(testDb)
class Car extends smartdata.SmartDataDbDoc<Car> {
@smartdata.unI() index: string = shortid();
@smartdata.svDb() color: string;
@smartdata.svDb() brand: string;
constructor(colorArg: string, brandArg: string) {
super();
this.color = colorArg;
this.brand = brandArg;
}
}
tap.test('should give me a collection', async () => {
testDbCollection = await testDb.getObjectCollectionByName<ITestObject1>('TestValue', testDb, true)
})
tap.test('should save the car to the db', async () => {
const myCar = new Car('red', 'Volvo');
await myCar.save();
});
tap.test('should insert a doc into the collection', async () => {
await testDbCollection.insertOne({ value1: 'test' })
})
tap.test('expect to get instance of Car', async () => {
let myCars = await Car.getInstances<Car>({
brand: 'Volvo'
});
expect(myCars[0].color).to.equal('red');
});
tap.test('should find all docs of testDbCollection', async () => {
await testDbCollection.find({}).then(async (resultArray) => {
console.log(resultArray)
expect(resultArray[ 0 ].value1).equal('test')
})
})
// =======================================
// close the database connection
// =======================================
tap.test('should close the database connection', async tools => {
await testDb.close();
});
tap.test('should insert many docs into the collection', async () => {
await testDbCollection.insertMany([
{ value1: 'test2' },
{ value1: 'test', value2: 3, value3: 'hi' }
])
})
tap.start({throwOnError: true});
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,3 +1,5 @@
export * from './smartdata.classes.db';
export * from './smartdata.classes.collection';
export * from './smartdata.classes.doc';
import * as plugins from './smartdata.plugins'
export * from './smartdata.classes.db'
export * from './smartdata.classes.dbcollection'
export * from './smartdata.classes.dbdoc'

View File

@ -1,134 +0,0 @@
import * as plugins from './smartdata.plugins';
import { SmartdataDb } from './smartdata.classes.db';
import { SmartDataDbDoc } from './smartdata.classes.doc';
export interface IFindOptions {
limit?: number;
}
/**
*
*/
export interface IDocValidationFunc<T> {
(doc: T): boolean;
}
/**
* This is a decorator that will tell the decorated class what dbTable to use
* @param db
*/
export function Collection(db: SmartdataDb) {
return function(constructor) {
constructor['smartdataCollection'] = new SmartdataCollection(constructor, db);
};
}
export class SmartdataCollection<T> {
/**
* the collection that is used
*/
mongoDbCollection: plugins.mongodb.Collection;
objectValidation: IDocValidationFunc<T> = null;
collectionName: string;
smartdataDb: SmartdataDb;
uniqueIndexes: string[] = [];
constructor(collectedClassArg: T & SmartDataDbDoc<T>, smartDataDbArg: SmartdataDb) {
// tell the collection where it belongs
this.collectionName = collectedClassArg.name;
this.smartdataDb = smartDataDbArg;
// tell the db class about it (important since Db uses different systems under the hood)
this.smartdataDb.addTable(this);
}
/**
* makes sure a collection exists within MongoDb that maps to the SmartdataCollection
*/
async init() {
if (!this.mongoDbCollection) {
// connect this instance to a MongoDB collection
const availableMongoDbCollections = await this.smartdataDb.mongoDb.collections();
const wantedCollection = availableMongoDbCollections.find(collection => {
return collection.collectionName === this.collectionName;
});
if (!wantedCollection) {
await this.smartdataDb.mongoDb.createCollection(this.collectionName);
}
this.mongoDbCollection = await this.smartdataDb.mongoDb.collection(this.collectionName);
console.log(`Successfully initiated Collection ${this.collectionName}`)
}
}
/**
* mark unique index
*/
markUniqueIndexes(keyArrayArg: string[] = []) {
for(let key of keyArrayArg) {
if(!this.uniqueIndexes.includes(key)) {
this.mongoDbCollection.createIndex(key, {
unique: true
});
// make sure we only call this once and not for every doc we create
this.uniqueIndexes.push(key);
}
}
}
/**
* adds a validation function that all newly inserted and updated objects have to pass
*/
addDocValidation(funcArg: IDocValidationFunc<T>) {
this.objectValidation = funcArg;
}
/**
* finds an object in the DbCollection
*/
async find(filterObject: any): Promise<any> {
await this.init();
const result = await this.mongoDbCollection.find(filterObject).toArray();
return result;
}
/**
* create an object in the database
*/
async insert(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> {
await this.init();
await this.checkDoc(dbDocArg);
this.markUniqueIndexes(dbDocArg.uniqueIndexes);
const saveableObject = await dbDocArg.createSavableObject();
console.log(saveableObject);
const result = await this.mongoDbCollection.insertOne(saveableObject);
return result;
}
/**
* inserts object into the DbCollection
*/
async update(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> {
await this.init();
await this.checkDoc(dbDocArg);
const saveableObject = await dbDocArg.createSavableObject();
this.mongoDbCollection.updateOne(saveableObject.dbDocUniqueId, saveableObject);
}
/**
* checks a Doc for constraints
* if this.objectValidation is not set it passes.
*/
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

@ -1,42 +1,23 @@
import * as plugins from './smartdata.plugins';
import { Objectmap } from 'lik';
import * as plugins from './smartdata.plugins'
import { Objectmap } from 'lik'
import { SmartdataCollection } from './smartdata.classes.collection';
import * as mongoHelpers from './smartdata.mongohelpers';
import { DbCollection } from './smartdata.classes.dbcollection'
import { getObjectDoc } from './smartdata.classes.dbobjectdoc'
/**
* interface - indicates the connection status of the db
*/
export type TConnectionStatus = 'initial' | 'disconnected' | 'connected' | 'failed';
export type TConnectionStatus = 'disconnected' | 'connected' | 'failed'
export interface ISmartdataOptions {
/**
* the URL to connect to
*/
mongoDbUrl: string;
export class Db {
dbUrl: string
db: plugins.mongodb.Db
status: TConnectionStatus
classCollections = new Objectmap<DbCollection<any>>()
objectCollections = new Objectmap<DbCollection<any>>()
/**
* the db to use for the project
*/
mongoDbName: string;
/**
* an optional password that will be replace <PASSWORD> in the connection string
*/
mongoDbPass?: string;
}
export class SmartdataDb {
smartdataOptions: ISmartdataOptions;
mongoDbClient: plugins.mongodb.MongoClient;
mongoDb: plugins.mongodb.Db;
status: TConnectionStatus;
smartdataCollectionMap = new Objectmap<SmartdataCollection<any>>();
constructor(smartdataOptions: ISmartdataOptions) {
this.smartdataOptions = smartdataOptions;
this.status = 'initial';
constructor (dbUrlArg: string) {
this.dbUrl = dbUrlArg
}
// basic connection stuff ----------------------------------------------
@ -44,52 +25,58 @@ export class SmartdataDb {
/**
* connects to the database that was specified during instance creation
*/
async connect(): Promise<any> {
let finalConnectionUrl = this.smartdataOptions.mongoDbUrl;
if (this.smartdataOptions.mongoDbPass) {
finalConnectionUrl = mongoHelpers.addPassword(
this.smartdataOptions.mongoDbUrl,
this.smartdataOptions.mongoDbPass
);
}
console.log(finalConnectionUrl);
this.mongoDbClient = await plugins.mongodb.MongoClient.connect(
finalConnectionUrl,
{
useNewUrlParser: true
}
);
this.mongoDb = this.mongoDbClient.db(this.smartdataOptions.mongoDbName);
this.status = 'connected';
console.log(`Connected to database ${this.smartdataOptions.mongoDbName}`);
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
*/
async close(): Promise<any> {
await this.mongoDbClient.close();
this.status = 'disconnected';
plugins.smartlog
.getDefaultLogger()
.info(`disconnected from database ${this.smartdataOptions.mongoDbName}`);
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
}
// handle table to class distribution
// advanced communication with the database --------------------------------
addTable(SmartdataCollectionArg: SmartdataCollection<any>) {
this.smartdataCollectionMap.add(SmartdataCollectionArg);
/**
* 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 a collection's name and returns a SmartdataCollection instance
* @param nameArg
* @returns DbTable
* gets an object collection by name
*/
async getSmartdataCollectionByName<T>(nameArg: string): Promise<SmartdataCollection<T>> {
let resultCollection = this.smartdataCollectionMap.find(dbTableArg => {
return dbTableArg.collectionName === nameArg;
});
return resultCollection;
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

@ -0,0 +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> {
/**
* 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
constructor (collectedClassArg: T & DbDoc<T>, dbArg: Db) {
// 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
*/
addDocValidation (funcArg: IDocValidation<T>) {
this.objectValidation = funcArg
}
/**
* 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,151 +0,0 @@
import * as plugins from './smartdata.plugins';
import { Objectmap } from 'lik';
import { SmartdataDb } from './smartdata.classes.db';
import { SmartdataCollection } from './smartdata.classes.collection';
export type TDocCreation = 'db' | 'new' | 'mixed';
/**
* saveable - saveable decorator to be used on class properties
*/
export function svDb() {
return (target: SmartDataDbDoc<any>, key: string) => {
console.log(`called svDb() on ${key}`);
if (!target.saveableProperties) {
target.saveableProperties = [];
}
target.saveableProperties.push(key);
};
}
/**
* unique index - decorator to mark a unique index
*/
export function unI() {
return (target: SmartDataDbDoc<any>, key: string) => {
console.log('called unI');
// mark the index as unique
if (!target.uniqueIndexes) {
target.uniqueIndexes = [];
}
target.uniqueIndexes.push(key);
// and also save it
if (!target.saveableProperties) {
target.saveableProperties = [];
}
target.saveableProperties.push(key);
};
}
export class SmartDataDbDoc<T> {
/**
* the collection object an Doc belongs to
*/
collection: SmartdataCollection<T>;
/**
* how the Doc in memory was created, may prove useful later.
*/
creationStatus: TDocCreation = 'new';
/**
* unique indexes
*/
uniqueIndexes: string[];
/**
* an array of saveable properties of a doc
*/
saveableProperties: string[];
/**
* name
*/
name: string;
/**
* primary id in the database
*/
dbDocUniqueId: string;
/**
* class constructor
*/
constructor() {
this.name = this.constructor['name'];
this.collection = this.constructor['smartdataCollection'];
}
static async getInstances<T>(filterArg): Promise<T[]> {
let self: any = this; // fool typesystem
let referenceMongoDBCollection: SmartdataCollection<T> = self.smartdataCollection;
const foundDocs = await referenceMongoDBCollection.find(filterArg);
const returnArray = [];
for (let item of foundDocs) {
let newInstance = new this();
for (let key in item) {
if (key !== 'id') {
newInstance[key] = item[key];
}
}
returnArray.push(newInstance);
}
return returnArray;
}
static async getInstance<T>(filterArg): Promise<T> {
let result = await this.getInstances<T>(filterArg);
if (result && result.length > 0) {
return result[0];
}
}
/**
* saves this instance but not any connected items
* may lead to data inconsistencies, but is faster
*/
async save() {
let self: any = this;
switch (this.creationStatus) {
case 'db':
await this.collection.update(self);
break;
case 'new':
let writeResult = await this.collection.insert(self);
this.creationStatus = 'db';
break;
default:
console.error('neither new nor in db?');
}
}
/**
* also store any referenced objects to DB
* better for data consistency
*/
saveDeep(savedMapArg: Objectmap<SmartDataDbDoc<any>> = null) {
if (!savedMapArg) {
savedMapArg = new Objectmap<SmartDataDbDoc<any>>();
}
savedMapArg.add(this);
this.save();
for (let propertyKey in this) {
let property: any = this[propertyKey];
if (property instanceof SmartDataDbDoc && !savedMapArg.checkForObject(property)) {
property.saveDeep(savedMapArg);
}
}
}
async createSavableObject() {
let saveableObject: any = {}; // is not exposed to outside, so any is ok here
for (let propertyNameString of this.saveableProperties) {
saveableObject[propertyNameString] = this[propertyNameString];
}
return saveableObject;
}
}

View File

@ -1,3 +0,0 @@
export const addPassword = (mongoUrlArg: string, passwordArg: string): string => {
return mongoUrlArg.replace('<PASSWORD>', passwordArg);
};

View File

@ -1,8 +1,14 @@
import * as assert from 'assert';
import * as smartlog from '@pushrocks/smartlog';
import * as lodash from 'lodash';
import * as mongodb from 'mongodb';
import * as smartq from 'smartq';
import * as smartstring from 'smartstring';
import 'typings-global'
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, smartlog, lodash, smartq, mongodb, smartstring };
export {
assert,
beautylog,
lodash,
mongodb,
smartq
}

View File

@ -1,7 +1,8 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es2017",
"module": "commonjs"
}
"compilerOptions": {
"experimentalDecorators": true,
"lib": [
"es2015"
]
}
}

3
tslint.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "tslint-config-standard"
}

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"