Compare commits

...

65 Commits

Author SHA1 Message Date
3f714b1a33 3.1.26 2020-02-19 18:30:35 +00:00
e58fa57525 fix(core): update 2020-02-19 18:30:34 +00:00
8e7ad5210f 3.1.25 2020-02-08 14:37:45 +00:00
cea6c662ac fix(core): update 2020-02-08 14:37:44 +00:00
6eb43a4b9f 3.1.24 2020-02-08 14:01:55 +00:00
7f89cbeecd fix(core): update 2020-02-08 14:01:55 +00:00
a042a589a0 3.1.23 2019-09-11 12:36:03 +02:00
75b5f6af08 fix(core): update 2019-09-11 12:36:02 +02:00
e6a36f22ac 3.1.22 2019-09-11 12:12:51 +02:00
246e3486f0 fix(id field now properly populated): update 2019-09-11 12:12:50 +02:00
c1c4a29415 3.1.21 2019-09-11 11:56:41 +02:00
6448516aa0 fix(core): update 2019-09-11 11:56:41 +02:00
24a7b2dbd3 3.1.20 2019-09-04 17:41:53 +02:00
afa7c2fe61 fix(core): update 2019-09-04 17:41:53 +02:00
b768896fbe 3.1.19 2019-09-04 17:25:50 +02:00
8d7d9adef1 fix(core): update 2019-09-04 17:25:50 +02:00
ca6d3c60c0 3.1.18 2019-09-02 16:58:19 +02:00
38c1fcd53a fix(core): update 2019-09-02 16:58:19 +02:00
e433b9e212 3.1.17 2019-09-02 16:51:22 +02:00
bf3656f792 fix(core): update 2019-09-02 16:51:22 +02:00
7e9fc62ce7 3.1.16 2019-09-02 16:50:23 +02:00
670a0c63fb fix(core): update 2019-09-02 16:50:22 +02:00
64e76b3ed1 3.1.15 2019-09-02 16:42:30 +02:00
25803330de fix(core): update 2019-09-02 16:42:29 +02:00
c6cbff1308 3.1.14 2019-02-13 22:08:58 +01:00
3eeac7b936 fix(structure): format 2019-02-13 22:08:58 +01:00
761b742e21 3.1.13 2019-01-08 19:55:14 +01:00
e56def621c fix(core): update 2019-01-08 19:55:13 +01:00
ab1799f4f2 3.1.12 2019-01-08 18:59:36 +01:00
9985b849d1 3.1.11 2019-01-08 18:45:31 +01:00
1800273b25 fix(core): update 2019-01-08 18:45:30 +01:00
e715cc6d37 3.1.10 2019-01-08 18:22:48 +01:00
f7abc175aa fix(core): update 2019-01-08 18:22:48 +01:00
bbcb3a614e 3.1.9 2019-01-08 14:37:17 +01:00
941d2f0902 fix(core): update 2019-01-08 14:37:17 +01:00
5c78f83a28 3.1.8 2019-01-08 13:52:09 +01:00
124f117352 fix(core): update 2019-01-08 13:52:08 +01:00
f67da898ae 3.1.7 2019-01-08 12:39:00 +01:00
3c8f70f77e fix(core): update 2019-01-08 12:38:59 +01:00
3674d7d9a5 3.1.6 2019-01-08 00:09:43 +01:00
fe2a622488 3.1.5 2019-01-07 02:50:10 +01:00
f092eefbf3 fix(core): update 2019-01-07 02:50:09 +01:00
8d0aa361f9 3.1.4 2019-01-07 02:41:38 +01:00
692a1223a8 fix(core): update 2019-01-07 02:41:38 +01:00
ae7d101ab9 3.1.3 2019-01-07 02:38:30 +01:00
3825b15a65 fix(core): update 2019-01-07 02:38:30 +01:00
3fc41678d2 3.1.2 2018-07-10 21:45:26 +02:00
39f1b7ada1 fix(test): fix import 2018-07-10 21:45:26 +02:00
f763de2403 3.1.1 2018-07-10 21:33:49 +02:00
cba1d031b6 fix(ci): fix tools install 2018-07-10 21:33:49 +02:00
d31e6a5931 3.1.0 2018-07-10 21:27:17 +02:00
46514a2743 feat(SmartdataDoc): add custom unique indexes 2018-07-10 21:27:16 +02:00
1cf02157c4 3.0.5 2018-07-10 00:19:23 +02:00
72efa14da8 fix(test): update npmts 2018-07-10 00:19:22 +02:00
a73c2084c0 3.0.4 2018-07-10 00:17:17 +02:00
5ed557a21a fix(test): test now throws correctly 2018-07-10 00:17:16 +02:00
2b6c30ff55 3.0.3 2018-07-10 00:02:39 +02:00
12ef599333 3.0.2 2018-07-10 00:02:10 +02:00
191ea5d3c6 update to mongodb 2018-07-10 00:02:04 +02:00
bdf33ed1ca 3.0.1 2018-07-08 23:49:05 +02:00
1c76905dcd fix(structure): clean 2018-07-08 23:49:05 +02:00
4d88cea69d 3.0.0 2018-07-08 23:48:15 +02:00
8b4f7169ff BREAKING CHANGE(scope/db driver): switched to pushrocks scope and from rethinkdb to mongodb as db 2018-07-08 23:48:14 +02:00
2a1c45608f 2.0.7 2018-01-16 00:40:12 +01:00
85a6444263 feat(IConnectionOptions): export ConnectionOptions 2018-01-16 00:40:08 +01:00
33 changed files with 3497 additions and 1910 deletions

24
.gitignore vendored
View File

@ -1,4 +1,22 @@
node_modules/
public/
coverage/
.nogit/
# artifacts
coverage/
public/
pages/
# installs
node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_web/
dist_serve/
dist_ts_web/
# custom

View File

@ -1,54 +1,115 @@
# gitzone standard
image: hosttoday/ht-docker-node:npmci
# gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .yarn/
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- trigger
- pages
testSTABLE:
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testStable:
stage: test
script:
- npmci node install stable
- npmci npm install
- npmci npm test
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- docker
- priv
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install lts
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
release:
stage: release
script:
- npmci npm prepare
- npmci npm publish
- npmci node install lts
- npmci npm publish
only:
- tags
- tags
tags:
- docker
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
script:
- npmci command npm install -g tslint typescript
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- docker
- priv
trigger:
stage: trigger
stage: metadata
script:
- npmci trigger
- npmci trigger
only:
- tags
- tags
tags:
- docker
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: pages
image: hosttoday/ht-docker-dbase:npmci
services:
- docker:stable-dind
stage: metadata
script:
- npmci command yarn global add npmpage
- npmci command npmpage
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags:
- docker
- notpriv
only:
- tags
artifacts:

View File

@ -1,3 +0,0 @@
{
"parser": "typescript"
}

113
README.md
View File

@ -1,26 +1,20 @@
# smartdata
# @pushrocks/smartdata
do more with data
do more with data and RethinkDB
## 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/)
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartdata)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartdata)
* [github.com (source mirror)](https://github.com/pushrocks/smartdata)
* [docs (typedoc)](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/)
[![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/@pushrocks/smartdata.svg)](https://www.npmjs.com/package/@pushrocks/smartdata)
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/smartdata/badge.svg)](https://snyk.io/test/npm/@pushrocks/smartdata)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
## Usage
@ -37,31 +31,26 @@ This is why we started smartdata.
How RethinkDB's terms map to the ones of smartdata:
| RethinkDB term | smartdata class |
| -------------- | ----------------- |
| Database | smartdata.Db |
| Table | smartdata.DbTable |
| Document | smartdata.DbDoc |
| 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";
import * as smartdata from 'smartdata';
let myRethinkDb1 = new smartdata.Db({
db: "test",
host: "https://some",
user: "testuser",
password: "testpass",
port: 1234
const smartdataDb = new smartdata.SmartdataDb({
mongoDbUrl: '//someurl',
mongoDbName: 'myDatabase',
mongoDbPass: 'mypassword'
});
// in case you need to support a proprietory ssl cert (e.g. compose.com):
myRethinkDb1.setSsl(process.env.RDB_CERT, "base64");
myDb1.connect();
smartdataDb.connect();
```
### class DbCollection
@ -74,20 +63,23 @@ So to get to get access to a specific collection you document
```typescript
// continues from the block before...
@smartdata.Table(myRethinkDb1)
class MyObject extends smartdata.DbDoc<myObject> {
@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
@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();
constructor() {
super(); // the super call is important ;) But you probably know that.
}
}
// start to instantiate instances of classes from scratch or database
let localObject = new MyObject({
property1: "hi",
const localObject = new MyObject({
property1: 'hi',
property2: 2
});
localObject.save(); // saves the object to the database
@ -95,7 +87,7 @@ localObject.save(); // saves the object to the database
// start retrieving instances
MyObject.getInstance<MyObject>({
property: "hi"
property: 'hi'
}); // outputs a new instance of MyObject with the values from db assigned
```
@ -104,31 +96,42 @@ MyObject.getInstance<MyObject>({
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:
### CRUD operations
smartdata supports full CRUD operations
**Store** or **Update** instances of classes to MongoDB:
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()`.
- async `.save()` will save (or update) the object you call it on only. Any referenced non-savable objects will not get stored.
- async `.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 :)
**Get** a new class instance from MongoDB:
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:
* static async `.getInstance({ /* filter props here */ })` gets you an instance that has the data of the first matched document as properties.
* static async `getInstances({ /* filter props here */ })` get you an array instances (one instance for every matched document).
**Delete** instances from MongoDb:
smartdata extends your class with a method to easily delete the doucment from DB:
* async `.delete()`will delete the document from DB.
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.
smartdata itself also bundles typings. You don't need to install any additional types for smartdata.
For further information read the linked docs at the top of this README.
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)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

3
dist/index.d.ts vendored
View File

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

9
dist/index.js vendored
View File

@ -1,9 +0,0 @@
"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.dbtable"));
__export(require("./smartdata.classes.dbdoc"));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDRDQUF1QztBQUN2QyxpREFBNEM7QUFDNUMsK0NBQTBDIn0=

View File

@ -1,35 +0,0 @@
import * as plugins from "./smartdata.plugins";
import { Objectmap } from "lik";
import { DbTable } from "./smartdata.classes.dbtable";
import { ConnectionOptions } from "rethinkdb";
/**
* interface - indicates the connection status of the db
*/
export declare type TConnectionStatus = "initial" | "disconnected" | "connected" | "failed";
export declare class Db {
dbName: string;
connectionOptions: plugins.rethinkDb.ConnectionOptions;
dbConnection: plugins.rethinkDb.Connection;
status: TConnectionStatus;
dbTablesMap: Objectmap<DbTable<any>>;
constructor(connectionOptionsArg: ConnectionOptions);
/**
* supply additional SSl options needed to connect to certain Rethink DB servers (e.g. compose.io)
*/
setSsl(certificateStringArg: string, formatArg: "base64" | "clearText"): void;
/**
* connects to the database that was specified during instance creation
*/
connect(): Promise<any>;
/**
* closes the connection to the databse
*/
close(): Promise<any>;
addTable(dbTableArg: DbTable<any>): void;
/**
* Gets a table's name and returns smartdata's DbTable class
* @param nameArg
* @returns DbTable
*/
getDbTableByName<T>(nameArg: string): Promise<DbTable<T>>;
}

View File

@ -1,76 +0,0 @@
"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");
class Db {
constructor(connectionOptionsArg) {
this.dbTablesMap = new lik_1.Objectmap();
this.dbName = connectionOptionsArg.db;
this.connectionOptions = connectionOptionsArg;
this.status = "initial";
}
/**
* supply additional SSl options needed to connect to certain Rethink DB servers (e.g. compose.io)
*/
setSsl(certificateStringArg, formatArg) {
let certificateString;
if ((formatArg = "base64")) {
certificateString = plugins.smartstring.base64.decode(certificateStringArg);
}
else {
certificateString = certificateStringArg;
}
this.connectionOptions["ssl"] = {
ca: Buffer.from(certificateString)
};
}
// basic connection stuff ----------------------------------------------
/**
* connects to the database that was specified during instance creation
*/
connect() {
return __awaiter(this, void 0, void 0, function* () {
this.dbConnection = yield plugins.rethinkDb.connect(this.connectionOptions);
this.dbConnection.use(this.dbName);
this.status = "connected";
plugins.beautylog.ok(`Connected to database ${this.dbName}`);
});
}
/**
* closes the connection to the databse
*/
close() {
return __awaiter(this, void 0, void 0, function* () {
yield this.dbConnection.close();
this.status = "disconnected";
plugins.beautylog.ok(`disconnected from database ${this.dbName}`);
});
}
// handle table to class distribution
addTable(dbTableArg) {
this.dbTablesMap.add(dbTableArg);
}
/**
* Gets a table's name and returns smartdata's DbTable class
* @param nameArg
* @returns DbTable
*/
getDbTableByName(nameArg) {
return __awaiter(this, void 0, void 0, function* () {
let resultCollection = this.dbTablesMap.find(dbTableArg => {
return dbTableArg.tableName === nameArg;
});
return resultCollection;
});
}
}
exports.Db = Db;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsK0NBQStDO0FBQy9DLDZCQUFnQztBQWVoQztJQU9FLFlBQVksb0JBQXVDO1FBRm5ELGdCQUFXLEdBQUcsSUFBSSxlQUFTLEVBQWdCLENBQUM7UUFHMUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxvQkFBb0IsQ0FBQyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLG9CQUFvQixDQUFDO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxvQkFBNEIsRUFBRSxTQUFpQztRQUNwRSxJQUFJLGlCQUF5QixDQUFDO1FBQzlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzQixpQkFBaUIsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQ25ELG9CQUFvQixDQUNyQixDQUFDO1FBQ0osQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04saUJBQWlCLEdBQUcsb0JBQW9CLENBQUM7UUFDM0MsQ0FBQztRQUNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRztZQUM5QixFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztTQUNuQyxDQUFDO0lBQ0osQ0FBQztJQUVELHdFQUF3RTtJQUV4RTs7T0FFRztJQUNHLE9BQU87O1lBQ1gsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQzVFLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztZQUMxQixPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDL0QsQ0FBQztLQUFBO0lBRUQ7O09BRUc7SUFDRyxLQUFLOztZQUNULE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztZQUM3QixPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyw4QkFBOEIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDcEUsQ0FBQztLQUFBO0lBRUQscUNBQXFDO0lBRXJDLFFBQVEsQ0FBQyxVQUF3QjtRQUMvQixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNHLGdCQUFnQixDQUFJLE9BQWU7O1lBQ3ZDLElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7Z0JBQ3hELE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQztZQUMxQyxDQUFDLENBQUMsQ0FBQztZQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztRQUMxQixDQUFDO0tBQUE7Q0FDRjtBQXBFRCxnQkFvRUMifQ==

View File

@ -1,45 +0,0 @@
import { Objectmap } from "lik";
import { DbTable } from "./smartdata.classes.dbtable";
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: DbTable<T>;
/**
* how the Doc in memory was created, may prove useful later.
*/
creationStatus: TDocCreation;
/**
* an array of saveable properties of a doc
*/
saveableProperties: string[];
/**
* name
*/
name: string;
/**
* primary id in the database
*/
dbId: string;
/**
* class constructor
*/
constructor();
static getInstances<T>(filterArg: any): Promise<T[]>;
/**
* saves this instance but not any connected items
* may lead to data inconsistencies, but is faster
*/
save(): Promise<void>;
/**
* also store any referenced objects to DB
* better for data consistency
*/
saveDeep(savedMapArg?: Objectmap<DbDoc<any>>): void;
createSavableObject(): any;
}

View File

@ -1,101 +0,0 @@
"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 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() {
/**
* how the Doc in memory was created, may prove useful later.
*/
this.creationStatus = "new";
this.name = this.constructor["name"];
this.collection = this.constructor["dbTable"];
}
static getInstances(filterArg) {
return __awaiter(this, void 0, void 0, function* () {
let self = this; // fool typesystem
let referenceTable = self.dbTable;
const foundDocs = yield referenceTable.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;
});
}
/**
* saves this instance but not any connected items
* may lead to data inconsistencies, but is faster
*/
save() {
return __awaiter(this, void 0, void 0, function* () {
let self = this;
switch (this.creationStatus) {
case "db":
yield this.collection.update(self);
break;
case "new":
let writeResult = yield 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 = 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);
}
}
}
createSavableObject() {
let saveableObject = {}; // is not exposed to outside, so any is ok here
for (let propertyNameString of this.saveableProperties) {
saveableObject[propertyNameString] = this[propertyNameString];
}
return saveableObject;
}
}
exports.DbDoc = DbDoc;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJkb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYmRvYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsNkJBQWdDO0FBT2hDOztHQUVHO0FBQ0g7SUFDRSxNQUFNLENBQUMsQ0FBQyxNQUFrQixFQUFFLEdBQVcsRUFBRSxFQUFFO1FBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxFQUFFLENBQUM7UUFDakMsQ0FBQztRQUNELE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQVJELG9CQVFDO0FBRUQ7SUEwQkU7O09BRUc7SUFDSDtRQXZCQTs7V0FFRztRQUNILG1CQUFjLEdBQWlCLEtBQUssQ0FBQztRQXFCbkMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsTUFBTSxDQUFPLFlBQVksQ0FBSSxTQUFTOztZQUNwQyxJQUFJLElBQUksR0FBUSxJQUFJLENBQUMsQ0FBQyxrQkFBa0I7WUFDeEMsSUFBSSxjQUFjLEdBQWUsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUM5QyxNQUFNLFNBQVMsR0FBRyxNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdkQsTUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLElBQUksV0FBVyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQzdCLEdBQUcsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ3JCLEVBQUUsQ0FBQSxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUNoQixXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMvQixDQUFDO2dCQUNILENBQUM7Z0JBQ0QsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNoQyxDQUFDO1lBQ0QsTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUNyQixDQUFDO0tBQUE7SUFFRDs7O09BR0c7SUFDRyxJQUFJOztZQUNSLElBQUksSUFBSSxHQUFRLElBQUksQ0FBQztZQUNyQixNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztnQkFDNUIsS0FBSyxJQUFJO29CQUNQLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ25DLEtBQUssQ0FBQztnQkFDUixLQUFLLEtBQUs7b0JBQ1IsSUFBSSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDckQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7b0JBQzNCLEtBQUssQ0FBQztnQkFDUjtvQkFDRSxPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDNUMsQ0FBQztRQUNILENBQUM7S0FBQTtJQUVEOzs7T0FHRztJQUNILFFBQVEsQ0FBQyxjQUFxQyxJQUFJO1FBQ2hELEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNqQixXQUFXLEdBQUcsSUFBSSxlQUFTLEVBQWMsQ0FBQztRQUM1QyxDQUFDO1FBQ0QsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDWixHQUFHLENBQUMsQ0FBQyxJQUFJLFdBQVcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzdCLElBQUksUUFBUSxHQUFRLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN0QyxFQUFFLENBQUMsQ0FBQyxRQUFRLFlBQVksS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZFLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDakMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsbUJBQW1CO1FBQ2pCLElBQUksY0FBYyxHQUFRLEVBQUUsQ0FBQyxDQUFDLCtDQUErQztRQUM3RSxHQUFHLENBQUMsQ0FBQyxJQUFJLGtCQUFrQixJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7WUFDdkQsY0FBYyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUNELE1BQU0sQ0FBQyxjQUFjLENBQUM7SUFDeEIsQ0FBQztDQUNGO0FBL0ZELHNCQStGQyJ9

View File

@ -1,51 +0,0 @@
import * as plugins from "./smartdata.plugins";
import { Db } from "./smartdata.classes.db";
import { DbDoc } from "./smartdata.classes.dbdoc";
import { WriteResult } from "rethinkdb";
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 declare function Table(db: Db): (constructor: any) => void;
export declare class DbTable<T> {
/**
* the collection that is used
*/
table: plugins.rethinkDb.Table;
objectValidation: IDocValidationFunc<T>;
tableName: string;
db: Db;
constructor(collectedClassArg: T & DbDoc<T>, dbArg: Db);
init(): Promise<void>;
/**
* adds a validation function that all newly inserted and updated objects have to pass
*/
addDocValidation(funcArg: IDocValidationFunc<T>): void;
/**
* finds an object in the DbCollection
*/
find(filterObject: any): Promise<any>;
/**
* create an object in the database
*/
insert(dbDocArg: T & DbDoc<T>): Promise<WriteResult>;
/**
* inserts object into the DbCollection
*/
update(dbDocArg: T & DbDoc<T>): Promise<WriteResult>;
/**
* checks a Doc for constraints
* if this.objectValidation is not set it passes.
*/
private checkDoc(docArg);
extractKey(writeResult: WriteResult): void;
}

View File

@ -1,116 +0,0 @@
"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");
/**
* This is a decorator that will tell the decorated class what dbTable to use
* @param db
*/
function Table(db) {
return function (constructor) {
constructor["dbTable"] = new DbTable(constructor, db);
};
}
exports.Table = Table;
class DbTable {
constructor(collectedClassArg, dbArg) {
this.objectValidation = null;
// tell the collection where it belongs
this.tableName = collectedClassArg.name;
this.db = dbArg;
// tell the db class about it (important since Db uses different systems under the hood)
this.db.addTable(this);
}
init() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.table) {
// connect this instance to a RethinkDB table
const availableTables = yield plugins.rethinkDb
.db(this.db.dbName)
.tableList()
.run(this.db.dbConnection);
if (availableTables.indexOf(this.tableName)) {
yield plugins.rethinkDb
.db(this.db.dbName)
.tableCreate(this.tableName)
.run(this.db.dbConnection);
}
}
this.table = plugins.rethinkDb.table(this.tableName);
});
}
/**
* 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(filterObject) {
return __awaiter(this, void 0, void 0, function* () {
yield this.init();
let cursor = yield plugins.rethinkDb
.table(this.tableName)
.filter(filterObject)
.run(this.db.dbConnection);
return yield cursor.toArray();
});
}
/**
* create an object in the database
*/
insert(dbDocArg) {
return __awaiter(this, void 0, void 0, function* () {
yield this.init();
yield this.checkDoc(dbDocArg);
return yield plugins.rethinkDb
.table(this.tableName)
.insert(dbDocArg.createSavableObject())
.run(this.db.dbConnection);
});
}
/**
* inserts object into the DbCollection
*/
update(dbDocArg) {
return __awaiter(this, void 0, void 0, function* () {
yield this.init();
yield this.checkDoc(dbDocArg);
console.log(this.tableName, dbDocArg.createSavableObject());
return yield plugins.rethinkDb
.table(this.tableName)
.update(dbDocArg.createSavableObject())
.run(this.db.dbConnection);
});
}
/**
* checks a Doc for constraints
* if this.objectValidation is not set it passes.
*/
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;
}
extractKey(writeResult) { }
}
exports.DbTable = DbTable;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJ0YWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0ZGF0YS5jbGFzc2VzLmRidGFibGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLCtDQUErQztBQWtCL0M7OztHQUdHO0FBQ0gsZUFBc0IsRUFBTTtJQUMxQixNQUFNLENBQUMsVUFBUyxXQUFXO1FBQ3pCLFdBQVcsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUpELHNCQUlDO0FBRUQ7SUFTRSxZQUFZLGlCQUErQixFQUFFLEtBQVM7UUFKdEQscUJBQWdCLEdBQTBCLElBQUksQ0FBQztRQUs3Qyx1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUM7UUFDeEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFFaEIsd0ZBQXdGO1FBQ3hGLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFSyxJQUFJOztZQUNSLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2hCLDZDQUE2QztnQkFDN0MsTUFBTSxlQUFlLEdBQUcsTUFBTSxPQUFPLENBQUMsU0FBUztxQkFDNUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDO3FCQUNsQixTQUFTLEVBQUU7cUJBQ1gsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzdCLEVBQUUsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsTUFBTSxPQUFPLENBQUMsU0FBUzt5QkFDcEIsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDO3lCQUNsQixXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQzt5QkFDM0IsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQy9CLENBQUM7WUFDSCxDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkQsQ0FBQztLQUFBO0lBRUQ7O09BRUc7SUFDSCxnQkFBZ0IsQ0FBQyxPQUE4QjtRQUM3QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNHLElBQUksQ0FBQyxZQUFpQjs7WUFDMUIsTUFBTSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsSUFBSSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsU0FBUztpQkFDakMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7aUJBQ3JCLE1BQU0sQ0FBQyxZQUFZLENBQUM7aUJBQ3BCLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzdCLE1BQU0sQ0FBQyxNQUFNLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoQyxDQUFDO0tBQUE7SUFFRDs7T0FFRztJQUNHLE1BQU0sQ0FBQyxRQUFzQjs7WUFDakMsTUFBTSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxNQUFNLE9BQU8sQ0FBQyxTQUFTO2lCQUMzQixLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztpQkFDckIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2lCQUN0QyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMvQixDQUFDO0tBQUE7SUFFRDs7T0FFRztJQUNHLE1BQU0sQ0FBQyxRQUFzQjs7WUFDakMsTUFBTSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1lBQzVELE1BQU0sQ0FBQyxNQUFNLE9BQU8sQ0FBQyxTQUFTO2lCQUMzQixLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztpQkFDckIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2lCQUN0QyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMvQixDQUFDO0tBQUE7SUFFRDs7O09BR0c7SUFDSyxRQUFRLENBQUMsTUFBUztRQUN4QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBUSxDQUFDO1FBQ3hDLElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzVCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7WUFDMUIsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFDRCxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7WUFDckIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLElBQUksQ0FBQyxNQUFNLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELFVBQVUsQ0FBQyxXQUF3QixJQUFHLENBQUM7Q0FDeEM7QUFsR0QsMEJBa0dDIn0=

View File

@ -1,7 +0,0 @@
import * as assert from "assert";
import * as beautylog from "beautylog";
import * as lodash from "lodash";
import * as rethinkDb from "rethinkdb";
import * as smartq from "smartq";
import * as smartstring from "smartstring";
export { assert, beautylog, lodash, smartq, rethinkDb, smartstring };

View File

@ -1,15 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
exports.assert = assert;
const beautylog = require("beautylog");
exports.beautylog = beautylog;
const lodash = require("lodash");
exports.lodash = lodash;
const rethinkDb = require("rethinkdb");
exports.rethinkDb = rethinkDb;
const smartq = require("smartq");
exports.smartq = smartq;
const smartstring = require("smartstring");
exports.smartstring = smartstring;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlDQUFpQztBQU94Qix3QkFBTTtBQU5mLHVDQUF1QztBQU10Qiw4QkFBUztBQUwxQixpQ0FBaUM7QUFLTCx3QkFBTTtBQUpsQyx1Q0FBdUM7QUFJSyw4QkFBUztBQUhyRCxpQ0FBaUM7QUFHRyx3QkFBTTtBQUYxQywyQ0FBMkM7QUFFWSxrQ0FBVyJ9

View File

@ -1,26 +0,0 @@
# 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)
[![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/)
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)

View File

@ -5,13 +5,18 @@
"dockerSock": false
},
"npmci": {
"npmGlobalTools": [
"npmts"
]
"npmGlobalTools": [],
"npmAccessLevel": "public",
"npmRegistryUrl": "registry.npmjs.org"
},
"npmts": {
"testConfig": {
"parallel": false
"gitzone": {
"module": {
"githost": "gitlab.com",
"gitscope": "pushrocks",
"gitrepo": "smartdata",
"shortDescription": "do more with data",
"npmPackagename": "@pushrocks/smartdata",
"license": "MIT"
}
}
}
}

2879
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,14 @@
{
"name": "smartdata",
"version": "2.0.6",
"name": "@pushrocks/smartdata",
"version": "3.1.26",
"private": false,
"description": "do more with data",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "(npmts)",
"testLocal": "(npmdocker)"
"test": "(tstest test/)",
"testLocal": "(npmdocker)",
"build": "(tsbuild)"
},
"repository": {
"type": "git",
@ -19,27 +21,38 @@
},
"homepage": "https://gitlab.com/pushrocks/smartdata#README",
"dependencies": {
"@types/lodash": "^4.14.92",
"@types/rethinkdb": "^2.3.8",
"beautylog": "^6.1.10",
"lik": "^2.0.2",
"lodash": "^4.17.4",
"rethinkdb": "^2.3.3",
"runtime-type-checks": "0.0.4",
"smartq": "^1.1.6",
"smartstring": "^2.0.28"
"@pushrocks/lik": "^3.0.19",
"@pushrocks/smartlog": "^2.0.21",
"@pushrocks/smartpromise": "^3.0.6",
"@pushrocks/smartstring": "^3.0.18",
"@pushrocks/smartunique": "^3.0.1",
"@types/lodash": "^4.14.149",
"@types/mongodb": "^3.3.16",
"lodash": "^4.17.15",
"mongodb": "^3.5.3",
"runtime-type-checks": "0.0.4"
},
"devDependencies": {
"@types/node": "^8.5.7",
"@types/shelljs": "^0.7.4",
"cz-conventional-changelog": "^2.1.0",
"qenv": "^1.1.7",
"shelljs": "^0.7.8",
"tapbundle": "^1.1.1"
"@gitzone/tsbuild": "^2.1.17",
"@gitzone/tstest": "^1.0.28",
"@pushrocks/qenv": "^4.0.6",
"@pushrocks/tapbundle": "^3.2.0",
"@types/mongodb-memory-server": "^2.3.0",
"@types/node": "^13.7.2",
"@types/shortid": "0.0.29",
"mongodb-memory-server": "^6.2.4",
"tslint": "^6.0.0",
"tslint-config-prettier": "^1.18.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
"files": [
"ts/*",
"ts_web/*",
"dist/*",
"dist_web/*",
"dist_ts_web/*",
"assets/*",
"cli.js",
"npmextra.json",
"readme.md"
]
}

View File

@ -1,7 +1,4 @@
vars:
- RDB_DB
- RDB_HOST
- RDB_USER
- RDB_PASS
- RDB_PORT
- RDB_CERT
required:
- MONGO_URL
- MONGO_DBNAME
- MONGO_PASS

View File

@ -1,30 +1,37 @@
import { tap, expect } from 'tapbundle'
import * as smartq from 'smartq'
import { Qenv } from 'qenv'
import { tap, expect } from '@pushrocks/tapbundle';
import { Qenv } from '@pushrocks/qenv';
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/')
const testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/');
// the tested module
import * as smartdata from '../ts/index'
import * as smartdata from '../ts/index';
import { smartstring } from '../ts/smartdata.plugins';
import * as smartunique from '@pushrocks/smartunique';
import * as mongoPlugin from 'mongodb-memory-server';
// =======================================
// Connecting to the database server
// =======================================
let testDb = new smartdata.Db({
db: process.env.RDB_DB,
host: process.env.RDB_HOST,
user: process.env.RDB_USER,
password: process.env.RDB_PASS,
port: parseInt(process.env.RDB_PORT)
})
testDb.setSsl(process.env.RDB_CERT, 'base64')
let testDb: smartdata.SmartdataDb;
let smartdataOptions: smartdata.ISmartdataOptions;
let mongod: mongoPlugin.MongoMemoryServer;
tap.test('should create a testinstance as database', async () => {
mongod = new mongoPlugin.MongoMemoryServer();
smartdataOptions = {
mongoDbName: await mongod.getDbName(),
mongoDbPass: '',
mongoDbUrl: await mongod.getConnectionString()
};
console.log(smartdataOptions);
testDb = new smartdata.SmartdataDb(smartdataOptions);
});
tap.test('should establish a connection to the rethink Db cluster', async () => {
await testDb.connect()
})
await testDb.init();
});
// =======================================
// The actual tests
@ -34,36 +41,107 @@ tap.test('should establish a connection to the rethink Db cluster', async () =>
// Collections
// ------
@smartdata.Table(testDb)
class Car extends smartdata.DbDoc<Car> {
@smartdata.svDb() color: string
@smartdata.svDb() brand: string
constructor (colorArg: string, brandArg: string) {
super()
this.color = colorArg
this.brand = brandArg
@smartdata.Collection(() => {
return testDb;
})
class Car extends smartdata.SmartDataDbDoc<Car, Car> {
@smartdata.unI()
public index: string = smartunique.shortId();
@smartdata.svDb()
public color: string;
@smartdata.svDb()
public brand: string;
constructor(colorArg: string, brandArg: string) {
super();
this.color = colorArg;
this.brand = brandArg;
}
}
tap.test('should save the car to the db', async () => {
const myCar = new Car('red','Volvo')
await myCar.save()
})
const myCar = new Car('red', 'Volvo');
await myCar.save();
const myCar2 = new Car('red', 'Volvo');
await myCar2.save();
const myCar3 = new Car('red', 'Renault');
await myCar3.save();
});
tap.test('expect to get instance of Car', async () => {
let myCar = await Car.getInstances<Car>({
const myCars = await Car.getInstances<Car>({
brand: 'Volvo'
})
expect(myCar[0].color).to.equal('red')
});
expect(myCars[0].color).to.equal('red');
});
tap.test('expect to get instance of Car and update it', async () => {
const myCar = await Car.getInstance<Car>({
brand: 'Volvo'
});
expect(myCar.color).to.equal('red');
myCar.color = 'blue';
await myCar.save();
});
tap.test('should be able to delete an instance of car', async () => {
const myCar = await Car.getInstance<Car>({
brand: 'Volvo'
});
expect(myCar.color).to.equal('blue');
await myCar.delete();
const myCar2 = await Car.getInstance<Car>({
brand: 'Volvo'
});
expect(myCar2.color).to.equal('red');
});
// tslint:disable-next-line: max-classes-per-file
@smartdata.Collection(() => {
return testDb;
})
class Truck extends smartdata.SmartDataDbDoc<Car, Car> {
@smartdata.unI()
public id: string = smartunique.shortId();
@smartdata.svDb()
public color: string;
@smartdata.svDb()
public brand: string;
constructor(colorArg: string, brandArg: string) {
super();
this.color = colorArg;
this.brand = brandArg;
}
}
tap.test('should store a new Truck', async () => {
const truck = new Truck('blue', 'MAN');
await truck.save();
const myTruck = await Truck.getInstance<Truck>({color: 'blue'});
myTruck.id = 'foo';
await myTruck.save();
const myTruck2 = await Truck.getInstance<Truck>({color: 'blue'});
console.log(myTruck2);
});
// =======================================
// close the database connection
// =======================================
tap.test('should close the database connection', async (tools) => {
await testDb.close()
})
tap.test('should close the database connection', async tools => {
await testDb.close();
await mongod.stop();
});
tap.start()
tap.start({ throwOnError: true });

View File

@ -1,3 +1,5 @@
export * from "./smartdata.classes.db";
export * from "./smartdata.classes.dbtable";
export * from "./smartdata.classes.dbdoc";
export * from './smartdata.classes.db';
export * from './smartdata.classes.collection';
export * from './smartdata.classes.doc';
export { IMongoDescriptor } from './interfaces';

1
ts/interfaces/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './mongodescriptor';

View File

@ -0,0 +1,5 @@
export interface IMongoDescriptor {
mongoDbName: string;
mongoDbUrl: string;
mongoDbPass: string;
}

View File

@ -0,0 +1,163 @@
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;
}
export type TDelayedDbCreation = () => SmartdataDb;
/**
* This is a decorator that will tell the decorated class what dbTable to use
* @param dbArg
*/
export function Collection(dbArg: SmartdataDb | TDelayedDbCreation) {
return function(constructor) {
if (dbArg instanceof SmartdataDb) {
// tslint:disable-next-line: no-string-literal
constructor['smartdataCollection'] = new SmartdataCollection(constructor, dbArg);
} else {
constructor['smartdataDelayedCollection'] = () => {
return new SmartdataCollection(constructor, dbArg());
};
}
};
}
export class SmartdataCollection<T> {
/**
* the collection that is used
*/
public mongoDbCollection: plugins.mongodb.Collection;
public objectValidation: IDocValidationFunc<T> = null;
public collectionName: string;
public smartdataDb: SmartdataDb;
public uniqueIndexes: string[] = [];
constructor(collectedClassArg: T & SmartDataDbDoc<T, unknown>, 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
*/
public 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
*/
public markUniqueIndexes(keyArrayArg: string[] = []) {
for (const 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
*/
public addDocValidation(funcArg: IDocValidationFunc<T>) {
this.objectValidation = funcArg;
}
/**
* finds an object in the DbCollection
*/
public 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
*/
public async insert(dbDocArg: T & SmartDataDbDoc<T, unknown>): Promise<any> {
await this.init();
await this.checkDoc(dbDocArg);
this.markUniqueIndexes(dbDocArg.uniqueIndexes);
const saveableObject = await dbDocArg.createSavableObject();
const result = await this.mongoDbCollection.insertOne(saveableObject);
return result;
}
/**
* inserts object into the DbCollection
*/
public async update(dbDocArg: T & SmartDataDbDoc<T, unknown>): Promise<any> {
await this.init();
await this.checkDoc(dbDocArg);
const identifiableObject = await dbDocArg.createIdentifiableObject();
const saveableObject = await dbDocArg.createSavableObject();
const updateableObject: any = {};
for (const key of Object.keys(saveableObject)) {
if (identifiableObject[key]) {
continue;
}
updateableObject[key] = saveableObject[key];
}
this.mongoDbCollection.updateOne(
identifiableObject,
{ $set: updateableObject },
{ upsert: true }
);
}
public async delete(dbDocArg: T & SmartDataDbDoc<T, unknown>): Promise<any> {
await this.init();
await this.checkDoc(dbDocArg);
const identifiableObject = await dbDocArg.createIdentifiableObject();
await this.mongoDbCollection.deleteOne(identifiableObject, {
w: 1
});
}
/**
* checks a Doc for constraints
* if this.objectValidation is not set it passes.
*/
private checkDoc(docArg: T): Promise<void> {
const 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,47 +1,42 @@
import * as plugins from "./smartdata.plugins";
import { Objectmap } from "lik";
import * as plugins from './smartdata.plugins';
import { Objectmap } from '@pushrocks/lik';
import { DbTable } from "./smartdata.classes.dbtable";
import { SmartdataCollection } from './smartdata.classes.collection';
import { Connection as dbConnection, ConnectionOptions } from "rethinkdb";
import * as mongoHelpers from './smartdata.mongohelpers';
/**
* interface - indicates the connection status of the db
*/
export type TConnectionStatus =
| "initial"
| "disconnected"
| "connected"
| "failed";
export type TConnectionStatus = 'initial' | 'disconnected' | 'connected' | 'failed';
export class Db {
dbName: string;
connectionOptions: plugins.rethinkDb.ConnectionOptions;
dbConnection: plugins.rethinkDb.Connection;
status: TConnectionStatus;
dbTablesMap = new Objectmap<DbTable<any>>();
constructor(connectionOptionsArg: ConnectionOptions) {
this.dbName = connectionOptionsArg.db;
this.connectionOptions = connectionOptionsArg;
this.status = "initial";
}
export interface ISmartdataOptions {
/**
* the URL to connect to
*/
mongoDbUrl: string;
/**
* supply additional SSl options needed to connect to certain Rethink DB servers (e.g. compose.io)
* the db to use for the project
*/
setSsl(certificateStringArg: string, formatArg: "base64" | "clearText") {
let certificateString: string;
if ((formatArg = "base64")) {
certificateString = plugins.smartstring.base64.decode(
certificateStringArg
);
} else {
certificateString = certificateStringArg;
}
this.connectionOptions["ssl"] = {
ca: Buffer.from(certificateString)
};
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';
}
// basic connection stuff ----------------------------------------------
@ -49,36 +44,50 @@ export class Db {
/**
* connects to the database that was specified during instance creation
*/
async connect(): Promise<any> {
this.dbConnection = await plugins.rethinkDb.connect(this.connectionOptions);
this.dbConnection.use(this.dbName);
this.status = "connected";
plugins.beautylog.ok(`Connected to database ${this.dbName}`);
public async init(): Promise<any> {
let finalConnectionUrl = this.smartdataOptions.mongoDbUrl;
if (this.smartdataOptions.mongoDbPass) {
finalConnectionUrl = mongoHelpers.addPassword(
this.smartdataOptions.mongoDbUrl,
this.smartdataOptions.mongoDbPass
);
}
console.log(`connection Url: ${finalConnectionUrl}`);
this.mongoDbClient = await plugins.mongodb.MongoClient.connect(finalConnectionUrl, {
useNewUrlParser: true,
useUnifiedTopology: true
});
this.mongoDb = this.mongoDbClient.db(this.smartdataOptions.mongoDbName);
this.status = 'connected';
console.log(`Connected to database ${this.smartdataOptions.mongoDbName}`);
}
/**
* closes the connection to the databse
*/
async close(): Promise<any> {
await this.dbConnection.close();
this.status = "disconnected";
plugins.beautylog.ok(`disconnected from database ${this.dbName}`);
public async close(): Promise<any> {
await this.mongoDbClient.close();
this.status = 'disconnected';
plugins.smartlog.defaultLogger.log(
'info',
`disconnected from database ${this.smartdataOptions.mongoDbName}`
);
}
// handle table to class distribution
addTable(dbTableArg: DbTable<any>) {
this.dbTablesMap.add(dbTableArg);
public addTable(SmartdataCollectionArg: SmartdataCollection<any>) {
this.smartdataCollectionMap.add(SmartdataCollectionArg);
}
/**
* Gets a table's name and returns smartdata's DbTable class
* Gets a collection's name and returns a SmartdataCollection instance
* @param nameArg
* @returns DbTable
*/
async getDbTableByName<T>(nameArg: string): Promise<DbTable<T>> {
let resultCollection = this.dbTablesMap.find(dbTableArg => {
return dbTableArg.tableName === nameArg;
public async getSmartdataCollectionByName<T>(nameArg: string): Promise<SmartdataCollection<T>> {
const resultCollection = this.smartdataCollectionMap.find(dbTableArg => {
return dbTableArg.collectionName === nameArg;
});
return resultCollection;
}

View File

@ -1,125 +0,0 @@
import * as plugins from "./smartdata.plugins";
import { Objectmap } from "lik";
import { Db } from "./smartdata.classes.db";
import { DbTable } from "./smartdata.classes.dbtable";
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: DbTable<T>;
/**
* how the Doc in memory was created, may prove useful later.
*/
creationStatus: TDocCreation = "new";
/**
* an array of saveable properties of a doc
*/
saveableProperties: string[];
/**
* name
*/
name: string;
/**
* primary id in the database
*/
dbId: string;
/**
* class constructor
*/
constructor() {
this.name = this.constructor["name"];
this.collection = this.constructor["dbTable"];
}
static async getInstances<T>(filterArg): Promise<T[]> {
let self: any = this; // fool typesystem
let referenceTable: DbTable<T> = self.dbTable;
const foundDocs = await referenceTable.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<DbDoc<any>> = null) {
if (!savedMapArg) {
savedMapArg = new Objectmap<DbDoc<any>>();
}
savedMapArg.add(this);
this.save();
for (let propertyKey in this) {
let property: any = this[propertyKey];
if (property instanceof DbDoc && !savedMapArg.checkForObject(property)) {
property.saveDeep(savedMapArg);
}
}
}
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,127 +0,0 @@
import * as plugins from "./smartdata.plugins";
import { Db } from "./smartdata.classes.db";
import { DbDoc } from "./smartdata.classes.dbdoc";
// RethinkDb Interfaces
import { WriteResult, Cursor } from "rethinkdb";
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 Table(db: Db) {
return function(constructor) {
constructor["dbTable"] = new DbTable(constructor, db);
};
}
export class DbTable<T> {
/**
* the collection that is used
*/
table: plugins.rethinkDb.Table;
objectValidation: IDocValidationFunc<T> = null;
tableName: string;
db: Db;
constructor(collectedClassArg: T & DbDoc<T>, dbArg: Db) {
// tell the collection where it belongs
this.tableName = collectedClassArg.name;
this.db = dbArg;
// tell the db class about it (important since Db uses different systems under the hood)
this.db.addTable(this);
}
async init() {
if (!this.table) {
// connect this instance to a RethinkDB table
const availableTables = await plugins.rethinkDb
.db(this.db.dbName)
.tableList()
.run(this.db.dbConnection);
if (availableTables.indexOf(this.tableName)) {
await plugins.rethinkDb
.db(this.db.dbName)
.tableCreate(this.tableName)
.run(this.db.dbConnection);
}
}
this.table = plugins.rethinkDb.table(this.tableName);
}
/**
* 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();
let cursor = await plugins.rethinkDb
.table(this.tableName)
.filter(filterObject)
.run(this.db.dbConnection);
return await cursor.toArray();
}
/**
* create an object in the database
*/
async insert(dbDocArg: T & DbDoc<T>): Promise<WriteResult> {
await this.init();
await this.checkDoc(dbDocArg);
return await plugins.rethinkDb
.table(this.tableName)
.insert(dbDocArg.createSavableObject())
.run(this.db.dbConnection);
}
/**
* inserts object into the DbCollection
*/
async update(dbDocArg: T & DbDoc<T>): Promise<WriteResult> {
await this.init();
await this.checkDoc(dbDocArg);
console.log(this.tableName, dbDocArg.createSavableObject());
return await plugins.rethinkDb
.table(this.tableName)
.update(dbDocArg.createSavableObject())
.run(this.db.dbConnection);
}
/**
* 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;
}
extractKey(writeResult: WriteResult) {}
}

188
ts/smartdata.classes.doc.ts Normal file
View File

@ -0,0 +1,188 @@
import * as plugins from './smartdata.plugins';
import { Objectmap } from '@pushrocks/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<unknown, unknown>, 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<unknown, unknown>, 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, TImplements> {
/**
* the collection object an Doc belongs to
*/
public collection: SmartdataCollection<T>;
/**
* how the Doc in memory was created, may prove useful later.
*/
public creationStatus: TDocCreation = 'new';
/**
* unique indexes
*/
public uniqueIndexes: string[];
/**
* an array of saveable properties of a doc
*/
public saveableProperties: string[];
/**
* name
*/
public name: string;
/**
* primary id in the database
*/
public dbDocUniqueId: string;
/**
* class constructor
*/
constructor() {
this.name = this.constructor['name'];
if (this.constructor['smartdataCollection']) {
// tslint:disable-next-line: no-string-literal
this.collection = this.constructor['smartdataCollection'];
// tslint:disable-next-line: no-string-literal
} else if (typeof this.constructor['smartdataDelayedCollection'] === 'function') {
// tslint:disable-next-line: no-string-literal
this.collection = this.constructor['smartdataDelayedCollection']();
} else {
console.error('Could not determine collection for DbDoc');
}
}
public static async getInstances<T>(filterArg): Promise<T[]> {
const self: any = this; // fool typesystem
let referenceMongoDBCollection: SmartdataCollection<T>;
if (self.smartdataCollection) {
referenceMongoDBCollection = self.smartdataCollection;
} else if (self.smartdataDelayedCollection) {
referenceMongoDBCollection = self.smartdataDelayedCollection();
}
const foundDocs = await referenceMongoDBCollection.find(filterArg);
const returnArray = [];
for (const item of foundDocs) {
const newInstance = new this();
newInstance.creationStatus = 'db';
for (const key of Object.keys(item)) {
newInstance[key] = item[key];
}
returnArray.push(newInstance);
}
return returnArray;
}
public static async getInstance<T>(filterArg): Promise<T> {
const 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
*/
public async save() {
// tslint:disable-next-line: no-this-assignment
const self: any = this;
switch (this.creationStatus) {
case 'db':
await this.collection.update(self);
break;
case 'new':
const writeResult = await this.collection.insert(self);
this.creationStatus = 'db';
break;
default:
console.error('neither new nor in db?');
}
}
/**
* deletes a document from the database
*/
public async delete() {
const self: any = this;
await this.collection.delete(self);
}
/**
* also store any referenced objects to DB
* better for data consistency
*/
public saveDeep(savedMapArg: Objectmap<SmartDataDbDoc<any, any>> = null) {
if (!savedMapArg) {
savedMapArg = new Objectmap<SmartDataDbDoc<any, any>>();
}
savedMapArg.add(this);
this.save();
for (const propertyKey of Object.keys(this)) {
const property: any = this[propertyKey];
if (property instanceof SmartDataDbDoc && !savedMapArg.checkForObject(property)) {
property.saveDeep(savedMapArg);
}
}
}
/**
* creates a saveable object so the instance can be persisted as json in the database
*/
public async createSavableObject(): Promise<TImplements> {
const saveableObject: unknown = {}; // is not exposed to outside, so any is ok here
for (const propertyNameString of this.saveableProperties) {
saveableObject[propertyNameString] = this[propertyNameString];
}
return saveableObject as TImplements;
}
/**
* creates an identifiable object for operations that require filtering
*/
public async createIdentifiableObject() {
const identifiableObject: any = {}; // is not exposed to outside, so any is ok here
for (const propertyNameString of this.uniqueIndexes) {
identifiableObject[propertyNameString] = this[propertyNameString];
}
return identifiableObject;
}
}

View File

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

View File

@ -1,8 +1,9 @@
import * as assert from "assert";
import * as beautylog from "beautylog";
import * as lodash from "lodash";
import * as rethinkDb from "rethinkdb";
import * as smartq from "smartq";
import * as smartstring from "smartstring";
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 '@pushrocks/smartpromise';
import * as smartstring from '@pushrocks/smartstring';
import * as smartunique from '@pushrocks/smartunique';
export { assert, beautylog, lodash, smartq, rethinkDb, smartstring };
export { assert, smartlog, lodash, smartq, mongodb, smartstring, smartunique };

View File

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

17
tslint.json Normal file
View File

@ -0,0 +1,17 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}

788
yarn.lock
View File

@ -1,788 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/code@^4.0.3":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/code/-/code-4.0.3.tgz#9c4de39f86eb3eba070146d2dab7dbc3f8eac35f"
"@types/events@*":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.1.0.tgz#93b1be91f63c184450385272c47b6496fd028e02"
"@types/fs-extra@4.x.x":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.7.tgz#02533262386b5a6b9a49797dc82feffdf269140a"
dependencies:
"@types/node" "*"
"@types/glob@*":
version "5.0.34"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.34.tgz#ee626c9be3da877d717911c6101eee0a9871bbf4"
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
"@types/lodash@^4.14.55", "@types/lodash@^4.14.74", "@types/lodash@^4.14.92":
version "4.14.92"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.92.tgz#6e3cb0b71a1e12180a47a42a744e856c3ae99a57"
"@types/minimatch@*", "@types/minimatch@3.x.x":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/node@*", "@types/node@^8.0.33", "@types/node@^8.5.7":
version "8.5.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.7.tgz#9c498c35af354dcfbca3790fb2e81129e93cf0e2"
"@types/rethinkdb@^2.3.8":
version "2.3.8"
resolved "https://registry.yarnpkg.com/@types/rethinkdb/-/rethinkdb-2.3.8.tgz#961f78f0e731668631891bd1199722bb4a2258a8"
dependencies:
"@types/node" "*"
"@types/shelljs@^0.7.4":
version "0.7.7"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.7.tgz#1f7bfa28947661afea06365db9b1135bbc903ec4"
dependencies:
"@types/glob" "*"
"@types/node" "*"
"@types/vinyl@^2.0.1":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.2.tgz#4f3b8dae8f5828d3800ef709b0cff488ee852de3"
dependencies:
"@types/node" "*"
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"
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.11"
resolved "https://registry.yarnpkg.com/beautycolor/-/beautycolor-1.0.11.tgz#71c5568d5a7ed5c144d3a54f753ad1b08862aea5"
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.3.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7"
"bluebird@>= 2.3.2 < 3":
version "2.11.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
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"
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"
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.1.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06"
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@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb"
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"
code@^5.1.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/code/-/code-5.1.2.tgz#e3310c2078ca7dc0b49b9c39a8b0a7b06bd75efe"
dependencies:
hoek "5.x.x"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
conventional-commit-types@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz#5db95739d6c212acbe7b6f656a11b940baa68946"
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"
crypto-random-string@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
cz-conventional-changelog@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz#2f4bc7390e3244e4df293e6ba351e4c740a7c764"
dependencies:
conventional-commit-types "^2.0.0"
lodash.map "^4.5.1"
longest "^1.0.1"
right-pad "^1.0.1"
word-wrap "^1.0.3"
define-properties@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
dependencies:
foreach "^2.0.5"
object-keys "^1.0.8"
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"
es-abstract@^1.5.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
dependencies:
es-to-primitive "^1.1.1"
function-bind "^1.1.1"
has "^1.0.1"
is-callable "^1.1.3"
is-regex "^1.0.4"
es-to-primitive@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
dependencies:
is-callable "^1.1.1"
is-date-object "^1.0.1"
is-symbol "^1.0.1"
es6-error@^4.0.2:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
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@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
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"
foreach@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
fs-extra@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.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"
function-bind@^1.0.2, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
glob@^7.0.0, glob@^7.1.2:
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"
has@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
dependencies:
function-bind "^1.0.2"
hoek@5.x.x:
version "5.0.2"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.2.tgz#d2f2c95d36fe7189cf8aa8c237abc1950eca1378"
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.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
interpret@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
is-callable@^1.1.1, is-callable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
dependencies:
kind-of "^3.0.2"
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
dependencies:
has "^1.0.1"
is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
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"
js-base64@^2.3.2:
version "2.4.0"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
js-yaml@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
optionalDependencies:
graceful-fs "^4.1.6"
kind-of@^3.0.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
dependencies:
is-buffer "^1.1.5"
kind-of@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
dependencies:
is-buffer "^1.1.5"
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.2.0"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee"
lik@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/lik/-/lik-2.0.2.tgz#da4e67458ab81fac9e62848e8e76dc1efe1c646f"
dependencies:
"@types/lodash" "^4.14.74"
"@types/minimatch" "3.x.x"
lodash "^4.17.4"
minimatch "^3.0.4"
smartq "^1.1.6"
symbol-tree "^3.2.2"
typings-global "^1.0.20"
lodash.map@^4.5.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
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"
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
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.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"
nan@^2.3.2:
version "2.8.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
normalize-newline@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-newline/-/normalize-newline-3.0.0.tgz#1cbea804aba436001f83938ab21ec039d69ae9d3"
object-keys@^1.0.8:
version "1.0.11"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
dependencies:
define-properties "^1.1.2"
es-abstract "^1.5.1"
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"
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"
randomatic@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
dependencies:
is-number "^3.0.0"
kind-of "^4.0.0"
readable-stream@^2.0.2, readable-stream@^2.1.5:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
safe-buffer "~5.1.1"
string_decoder "~1.0.3"
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.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
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"
resolve@^1.1.6:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
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"
rethinkdb@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/rethinkdb/-/rethinkdb-2.3.3.tgz#3dc6586e22fa1dabee0d254e64bd0e379fad2f72"
dependencies:
bluebird ">= 2.3.2 < 3"
right-pad@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0"
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"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
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.8"
resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-1.0.8.tgz#a074836f4ddd4b98c50f1e7ae9e8e8ad9f6f1902"
dependencies:
"@types/code" "^4.0.3"
code "^5.1.0"
typings-global "^1.0.20"
smartdelay@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/smartdelay/-/smartdelay-1.0.4.tgz#791c1a4ee6770494064c10b1d2d2b8e6f3105b82"
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.26"
resolved "https://registry.yarnpkg.com/smartfile/-/smartfile-4.2.26.tgz#800f08b1089e153b7fd8e0ba165da465a071d407"
dependencies:
"@types/fs-extra" "4.x.x"
"@types/vinyl" "^2.0.1"
fs-extra "^4.0.2"
glob "^7.1.2"
js-yaml "^3.10.0"
require-reload "0.2.2"
smartpath "^3.2.8"
smartq "^1.1.6"
smartrequest "^1.0.6"
typings-global "^1.0.20"
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.1, smartq@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/smartq/-/smartq-1.1.6.tgz#0c1ff4336d95e95b4f1fdd8ccd7e2c5a323b8412"
dependencies:
typings-global "^1.0.19"
util.promisify "^1.0.0"
smartrequest@^1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/smartrequest/-/smartrequest-1.0.8.tgz#9af18dde34efa7d43b4ecfc92ccb157a98eda3b1"
dependencies:
smartq "^1.1.1"
smartstring@^2.0.28:
version "2.0.28"
resolved "https://registry.yarnpkg.com/smartstring/-/smartstring-2.0.28.tgz#384b808dc3780eff0031ce7925c1b1668abbcad5"
dependencies:
crypto-random-string "^1.0.0"
js-base64 "^2.3.2"
normalize-newline "^3.0.0"
randomatic "^1.1.7"
strip-indent "^2.0.0"
typings-global "^1.0.20"
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.3:
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"
strip-indent@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
tapbundle@^1.1.1:
version "1.1.8"
resolved "https://registry.yarnpkg.com/tapbundle/-/tapbundle-1.1.8.tgz#e08aee0e100a830d8a26a583a85d37ce53312e02"
dependencies:
"@types/node" "^8.0.33"
early "^2.1.1"
leakage "^0.3.0"
smartchai "^1.0.3"
smartdelay "^1.0.3"
smartq "^1.1.1"
typings-global "^1.0.19"
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"
typings-global@^1.0.14, typings-global@^1.0.16, typings-global@^1.0.19, typings-global@^1.0.20:
version "1.0.28"
resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.28.tgz#e28cc965476564cbc00e438739e0aa0735d323d4"
universalify@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
util.promisify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
dependencies:
define-properties "^1.1.2"
object.getownpropertydescriptors "^2.0.3"
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:
version "2.1.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c"
dependencies:
clone "^2.1.1"
clone-buffer "^1.0.0"
clone-stats "^1.0.0"
cloneable-readable "^1.0.0"
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
word-wrap@^1.0.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
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"