Compare commits
81 Commits
Author | SHA1 | Date | |
---|---|---|---|
4d88cea69d | |||
8b4f7169ff | |||
2a1c45608f | |||
85a6444263 | |||
766ae1d1ff | |||
7630882312 | |||
4aec47f207 | |||
c2e3a1ae6e | |||
3d8f8646b1 | |||
aca9817c56 | |||
7e341f2b50 | |||
d2ca108ef8 | |||
e2d12f8c9c | |||
cfcd9ab386 | |||
3048035374 | |||
6c70cf05c4 | |||
04b0910883 | |||
3671fe4df4 | |||
bd30da1c4a | |||
05938bf2af | |||
cddb0caf1f | |||
1af51dd989 | |||
8101e49026 | |||
2d97ab9dc5 | |||
3ba2bc8446 | |||
5735ab8577 | |||
def671cbe4 | |||
14042151ba | |||
c74873d02c | |||
800cdd655a | |||
68c0ceeb14 | |||
154dc5c1b3 | |||
d5c027caf0 | |||
30776a7da0 | |||
fedc0bd8c8 | |||
7b78b47a1b | |||
a4acfc0f6e | |||
a934f3608f | |||
a4f3f23bed | |||
2039f1c807 | |||
57d1a6dd0a | |||
d504e90e47 | |||
7079340657 | |||
63ceded1b8 | |||
b45e7ee206 | |||
715709f3ec | |||
0b8adea736 | |||
90d9a25b3f | |||
e49811eecd | |||
9cbdf317dc | |||
d55339013a | |||
9acdbd2842 | |||
dfce8cfcc0 | |||
38446fc79b | |||
af8c41ad6c | |||
3a24f829b4 | |||
67db1325c1 | |||
6683c05c22 | |||
f7f7852b7f | |||
df4346e0a2 | |||
eb54fbcd0d | |||
f13c12cd47 | |||
08d53f22f5 | |||
5b6523e6f4 | |||
138290a7b8 | |||
036cafc282 | |||
7764ba5cb8 | |||
7f77634ea1 | |||
acf3c29939 | |||
925cd639b4 | |||
af8de58dcd | |||
f39703b8d9 | |||
fa1951b4dd | |||
8c37a367a0 | |||
37f388e998 | |||
78bdb6760e | |||
ce1dceb60c | |||
16add8bff0 | |||
11149b2712 | |||
e508a942e3 | |||
5b093c68e4 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,5 +1,4 @@
|
||||
node_modules/
|
||||
test/data
|
||||
pages/
|
||||
coverage/
|
||||
public/
|
||||
coverage/
|
||||
.nogit/
|
||||
|
120
.gitlab-ci.yml
120
.gitlab-ci.yml
@ -1,43 +1,141 @@
|
||||
image: hosttoday/ht-docker-node:npmts
|
||||
# gitzone standard
|
||||
image: hosttoday/ht-docker-node:npmci
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- .npmci_cache/
|
||||
key: "$CI_BUILD_STAGE"
|
||||
|
||||
stages:
|
||||
- security
|
||||
- test
|
||||
- release
|
||||
- metadata
|
||||
|
||||
before_script:
|
||||
- apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
|
||||
- echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.2.list
|
||||
- apt-get update
|
||||
- apt-get install -y mongodb-org
|
||||
# ====================
|
||||
# security stage
|
||||
# ====================
|
||||
mirror:
|
||||
stage: security
|
||||
script:
|
||||
- npmci git mirror
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
|
||||
snyk:
|
||||
stage: security
|
||||
script:
|
||||
- npmci command npm install -g snyk
|
||||
- npmci command npm install --ignore-scripts
|
||||
- npmci command snyk test
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
|
||||
# ====================
|
||||
# test stage
|
||||
# ====================
|
||||
testLEGACY:
|
||||
stage: test
|
||||
script:
|
||||
- npmci test legacy
|
||||
- npmci node install legacy
|
||||
- npmci npm install
|
||||
- npmci npm test
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
allow_failure: true
|
||||
|
||||
testLTS:
|
||||
stage: test
|
||||
script:
|
||||
- npmci test lts
|
||||
- npmci node install lts
|
||||
- npmci npm install
|
||||
- npmci npm test
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
|
||||
testSTABLE:
|
||||
stage: test
|
||||
script:
|
||||
- npmci test stable
|
||||
- npmci node install stable
|
||||
- npmci npm install
|
||||
- npmci npm test
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
|
||||
release:
|
||||
stage: release
|
||||
environment: npm_registry
|
||||
script:
|
||||
- npmci publish
|
||||
- npmci node install stable
|
||||
- npmci npm publish
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
|
||||
# ====================
|
||||
# metadata stage
|
||||
# ====================
|
||||
codequality:
|
||||
stage: metadata
|
||||
image: docker:stable
|
||||
allow_failure: true
|
||||
services:
|
||||
- docker:stable-dind
|
||||
script:
|
||||
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
|
||||
- docker run
|
||||
--env SOURCE_CODE="$PWD"
|
||||
--volume "$PWD":/code
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock
|
||||
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
|
||||
artifacts:
|
||||
paths: [codeclimate.json]
|
||||
tags:
|
||||
- docker
|
||||
- priv
|
||||
|
||||
trigger:
|
||||
stage: metadata
|
||||
script:
|
||||
- npmci trigger
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
|
||||
pages:
|
||||
image: hosttoday/ht-docker-node:npmci
|
||||
stage: metadata
|
||||
script:
|
||||
- npmci command npm install -g npmpage
|
||||
- npmci command npmpage
|
||||
tags:
|
||||
- docker
|
||||
- notpriv
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- public
|
||||
allow_failure: true
|
||||
|
||||
windowsCompatibility:
|
||||
image: stefanscherer/node-windows:10-build-tools
|
||||
stage: metadata
|
||||
script:
|
||||
- npm install & npm test
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- windows
|
||||
allow_failure: true
|
||||
|
136
README.md
136
README.md
@ -1,4 +1,134 @@
|
||||
# smartdata
|
||||
# @pushrocks/smartdata
|
||||
|
||||
smartdata is a ODM that adheres to TypeScript practices and uses classes to organize data.
|
||||
It uses MongoDB as persistent storage.
|
||||
do more with data and RethinkDB
|
||||
|
||||
## Availabililty
|
||||
|
||||
[](https://www.npmjs.com/package/smartdata)
|
||||
[](https://GitLab.com/pushrocks/smartdata)
|
||||
[](https://github.com/pushrocks/smartdata)
|
||||
[](https://pushrocks.gitlab.io/smartdata/)
|
||||
|
||||
## Status for master
|
||||
|
||||
[](https://GitLab.com/pushrocks/smartdata/commits/master)
|
||||
[](https://GitLab.com/pushrocks/smartdata/commits/master)
|
||||
[](https://www.npmjs.com/package/smartdata)
|
||||
[](https://david-dm.org/pushrocks/smartdata)
|
||||
[](https://www.bithound.io/github/pushrocks/smartdata/master/dependencies/npm)
|
||||
[](https://www.bithound.io/github/pushrocks/smartdata)
|
||||
[](https://snyk.io/test/npm/smartdata)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](http://standardjs.com/)
|
||||
|
||||
## Usage
|
||||
|
||||
Use TypeScript for best in class instellisense.
|
||||
|
||||
smartdata is an ODM that adheres to TypeScript practices and uses classes to organize data.
|
||||
It uses RethinkDB as persistent storage.
|
||||
|
||||
## Intention
|
||||
|
||||
There are many ODMs out there, however when we searched for an ODM that uses TypeScript,
|
||||
acts smart while still embracing the NoSQL idea we didn't find a matching solution.
|
||||
This is why we started smartdata.
|
||||
|
||||
How RethinkDB's terms map to the ones of smartdata:
|
||||
|
||||
| RethinkDB term | smartdata class |
|
||||
| -------------- | ----------------- |
|
||||
| Database | smartdata.Db |
|
||||
| Table | smartdata.DbTable |
|
||||
| Document | smartdata.DbDoc |
|
||||
|
||||
### class Db
|
||||
|
||||
represents a Database. Naturally it has .connect() etc. methods on it.
|
||||
|
||||
```typescript
|
||||
import * as smartdata from 'smartdata';
|
||||
|
||||
let myRethinkDb1 = new smartdata.Db({
|
||||
db: 'test',
|
||||
host: 'https://some',
|
||||
user: 'testuser',
|
||||
password: 'testpass',
|
||||
port: 1234
|
||||
});
|
||||
|
||||
// in case you need to support a proprietory ssl cert (e.g. compose.com):
|
||||
myRethinkDb1.setSsl(process.env.RDB_CERT, 'base64');
|
||||
|
||||
myDb1.connect();
|
||||
```
|
||||
|
||||
### class DbCollection
|
||||
|
||||
represents a collection of objects.
|
||||
A collection is defined by the object class (that is extending smartdata.dbdoc) it respresents
|
||||
|
||||
So to get to get access to a specific collection you document
|
||||
|
||||
```typescript
|
||||
// continues from the block before...
|
||||
|
||||
@smartdata.Table(myRethinkDb1)
|
||||
class MyObject extends smartdata.DbDoc<myObject> {
|
||||
// read the next block about DbDoc
|
||||
@smartdata.svDb() property1: string; // @smartdata.svDb() marks the property for db save
|
||||
property2: number; // this one is not marked, so it won't be save upon calling this.save()
|
||||
constructor(optionsArg: { property1: string; property2: number }) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
// start to instantiate instances of classes from scratch or database
|
||||
|
||||
let localObject = new MyObject({
|
||||
property1: 'hi',
|
||||
property2: 2
|
||||
});
|
||||
localObject.save(); // saves the object to the database
|
||||
|
||||
// start retrieving instances
|
||||
|
||||
MyObject.getInstance<MyObject>({
|
||||
property: 'hi'
|
||||
}); // outputs a new instance of MyObject with the values from db assigned
|
||||
```
|
||||
|
||||
### class DbDoc
|
||||
|
||||
represents a individual document in a collection
|
||||
and thereby is ideally suited to extend the class you want to actually store.
|
||||
|
||||
**sStore** instances of classes to Db:
|
||||
DbDoc extends your class with the following methods:
|
||||
|
||||
- `.save()` will save (or update) the object you call it on only. Any referenced non-savable objects will not get stored.
|
||||
- `.saveDeep()` does the same like `.save()`.
|
||||
In addition it will look for properties that reference an object
|
||||
that extends DbDoc as well and call .saveDeep() on them as well.
|
||||
Loops are prevented
|
||||
|
||||
**Get** a new class instance from a Doc in the DB:
|
||||
DbDoc exposes a static method that allows you specify a filter to retrieve a cloned class of the one you used to that doc at some point later in time. Yes, let that sink in a minute :)
|
||||
|
||||
So you can just call `.getInstance({ /* filter props here */ })`.
|
||||
|
||||
## TypeScript
|
||||
|
||||
How does TypeScript play into this?
|
||||
Since you define your classes in TypeScript and types flow through smartdata in a generic way
|
||||
you should get all the Intellisense and type checking you love when using smartdata.
|
||||
smartdata itself also bundles typings.
|
||||
So you don't need to install any additional types when importing smartdata.
|
||||
|
||||
For further information read the linked docs at the top of this README.
|
||||
|
||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
||||
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
|
||||
|
||||
[](https://push.rocks)
|
||||
|
5
dist/index.d.ts
vendored
5
dist/index.d.ts
vendored
@ -1,2 +1,3 @@
|
||||
export * from './smartdata.classes.dbcollection';
|
||||
export * from './smartdata.classes.dbconnection';
|
||||
export * from "./smartdata.classes.db";
|
||||
export * from "./smartdata.classes.dbtable";
|
||||
export * from "./smartdata.classes.dbdoc";
|
||||
|
8
dist/index.js
vendored
8
dist/index.js
vendored
@ -2,6 +2,8 @@
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
__export(require('./smartdata.classes.dbcollection'));
|
||||
__export(require('./smartdata.classes.dbconnection'));
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBRUEsaUJBQWMsa0NBQ2QsQ0FBQyxFQUQrQztBQUNoRCxpQkFBYyxrQ0FDZCxDQUFDLEVBRCtDIn0=
|
||||
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=
|
36
dist/smartdata.classes.db.d.ts
vendored
Normal file
36
dist/smartdata.classes.db.d.ts
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
import * as plugins from "./smartdata.plugins";
|
||||
import { Objectmap } from "lik";
|
||||
import { DbTable } from "./smartdata.classes.dbtable";
|
||||
import { ConnectionOptions as IConnectionOptions } from "rethinkdb";
|
||||
export { IConnectionOptions };
|
||||
/**
|
||||
* 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: IConnectionOptions);
|
||||
/**
|
||||
* 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>>;
|
||||
}
|
76
dist/smartdata.classes.db.js
vendored
Normal file
76
dist/smartdata.classes.db.js
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUEsK0NBQStDO0FBQy9DLDZCQUFnQztBQW1CaEM7SUFPRSxZQUFZLG9CQUF3QztRQUZwRCxnQkFBVyxHQUFHLElBQUksZUFBUyxFQUFnQixDQUFDO1FBRzFDLElBQUksQ0FBQyxNQUFNLEdBQUcsb0JBQW9CLENBQUMsRUFBRSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQztRQUM5QyxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsb0JBQTRCLEVBQUUsU0FBaUM7UUFDcEUsSUFBSSxpQkFBeUIsQ0FBQztRQUM5QixFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0IsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUNuRCxvQkFBb0IsQ0FDckIsQ0FBQztRQUNKLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLGlCQUFpQixHQUFHLG9CQUFvQixDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDOUIsRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUM7U0FDbkMsQ0FBQztJQUNKLENBQUM7SUFFRCx3RUFBd0U7SUFFeEU7O09BRUc7SUFDRyxPQUFPOztZQUNYLElBQUksQ0FBQyxZQUFZLEdBQUcsTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUM1RSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUM7WUFDMUIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMseUJBQXlCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQy9ELENBQUM7S0FBQTtJQUVEOztPQUVHO0lBQ0csS0FBSzs7WUFDVCxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxjQUFjLENBQUM7WUFDN0IsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsOEJBQThCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7S0FBQTtJQUVELHFDQUFxQztJQUVyQyxRQUFRLENBQUMsVUFBd0I7UUFDL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7O09BSUc7SUFDRyxnQkFBZ0IsQ0FBSSxPQUFlOztZQUN2QyxJQUFJLGdCQUFnQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFO2dCQUN4RCxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUM7WUFDMUMsQ0FBQyxDQUFDLENBQUM7WUFDSCxNQUFNLENBQUMsZ0JBQWdCLENBQUM7UUFDMUIsQ0FBQztLQUFBO0NBQ0Y7QUFwRUQsZ0JBb0VDIn0=
|
24
dist/smartdata.classes.dbcollection.d.ts
vendored
24
dist/smartdata.classes.dbcollection.d.ts
vendored
@ -1,24 +0,0 @@
|
||||
/// <reference types="q" />
|
||||
import * as plugins from './smartdata.plugins';
|
||||
import { DbConnection } from './smartdata.classes.dbconnection';
|
||||
export declare class DbCollection<T> {
|
||||
collection: plugins.mongodb.Collection;
|
||||
constructor(nameArg: string, dbConnectionArg: DbConnection);
|
||||
/**
|
||||
* adds a validation function that all newly inserted and updated objects have to pass
|
||||
*/
|
||||
addObjectValidation(funcArg: any): void;
|
||||
/**
|
||||
* finds an object in the DbCollection
|
||||
*/
|
||||
find(docMatchArg: T): plugins.q.Promise<T[]>;
|
||||
/**
|
||||
* inserts object into the DbCollection
|
||||
*/
|
||||
insertOne(docArg: T): plugins.q.Promise<void>;
|
||||
/**
|
||||
* inserts many objects at once into the DbCollection
|
||||
*/
|
||||
insertMany(docArrayArg: T[]): plugins.q.Promise<void>;
|
||||
private checkDoc(doc);
|
||||
}
|
56
dist/smartdata.classes.dbcollection.js
vendored
56
dist/smartdata.classes.dbcollection.js
vendored
@ -1,56 +0,0 @@
|
||||
"use strict";
|
||||
const plugins = require('./smartdata.plugins');
|
||||
class DbCollection {
|
||||
constructor(nameArg, dbConnectionArg) {
|
||||
this.collection = dbConnectionArg.db.collection(nameArg);
|
||||
}
|
||||
/**
|
||||
* adds a validation function that all newly inserted and updated objects have to pass
|
||||
*/
|
||||
addObjectValidation(funcArg) { }
|
||||
/**
|
||||
* finds an object in the DbCollection
|
||||
*/
|
||||
find(docMatchArg) {
|
||||
let done = plugins.q.defer();
|
||||
this.collection.find().toArray((err, docs) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
done.resolve(docs);
|
||||
});
|
||||
return done.promise;
|
||||
}
|
||||
/**
|
||||
* inserts object into the DbCollection
|
||||
*/
|
||||
insertOne(docArg) {
|
||||
let done = plugins.q.defer();
|
||||
this.checkDoc(docArg).then(() => {
|
||||
this.collection.insertOne(docArg)
|
||||
.then(() => { done.resolve(); });
|
||||
});
|
||||
return done.promise;
|
||||
}
|
||||
/**
|
||||
* inserts many objects at once into the DbCollection
|
||||
*/
|
||||
insertMany(docArrayArg) {
|
||||
let done = plugins.q.defer();
|
||||
let checkDocPromiseArray = [];
|
||||
for (let docArg of docArrayArg) {
|
||||
checkDocPromiseArray.push(this.checkDoc(docArg));
|
||||
}
|
||||
plugins.q.all(checkDocPromiseArray).then(() => {
|
||||
this.collection.insertMany(docArrayArg);
|
||||
});
|
||||
return done.promise;
|
||||
}
|
||||
checkDoc(doc) {
|
||||
let done = plugins.q.defer();
|
||||
done.resolve();
|
||||
return done.promise;
|
||||
}
|
||||
}
|
||||
exports.DbCollection = DbCollection;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRkYXRhLmNsYXNzZXMuZGJjb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxNQUFZLE9BQU8sV0FBTSxxQkFDekIsQ0FBQyxDQUQ2QztBQUc5QztJQUVJLFlBQVksT0FBZSxFQUFFLGVBQTZCO1FBQ3RELElBQUksQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDNUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsbUJBQW1CLENBQUMsT0FBTyxJQUFJLENBQUM7SUFFaEM7O09BRUc7SUFDSCxJQUFJLENBQUMsV0FBYztRQUNmLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFPLENBQUE7UUFDakMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSTtZQUNyQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUFDLE1BQU0sR0FBRyxDQUFBO1lBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3RCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLE1BQVM7UUFDZixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBUSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztpQkFDNUIsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdkMsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVLENBQUMsV0FBZ0I7UUFDdkIsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQVEsQ0FBQTtRQUNsQyxJQUFJLG9CQUFvQixHQUE4QixFQUFFLENBQUE7UUFDeEQsR0FBRyxDQUFDLENBQUMsSUFBSSxNQUFNLElBQUksV0FBVyxDQUFDLENBQUEsQ0FBQztZQUM1QixvQkFBb0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBQ3BELENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNyQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUMzQyxDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFTyxRQUFRLENBQUMsR0FBTTtRQUNuQixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBUSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUNkLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7QUFDTCxDQUFDO0FBdkRZLG9CQUFZLGVBdUR4QixDQUFBIn0=
|
11
dist/smartdata.classes.dbconnection.d.ts
vendored
11
dist/smartdata.classes.dbconnection.d.ts
vendored
@ -1,11 +0,0 @@
|
||||
/// <reference types="q" />
|
||||
import * as plugins from './smartdata.plugins';
|
||||
export declare type TDbConnectionStatus = 'disconnected' | 'connected' | 'failed';
|
||||
export declare class DbConnection {
|
||||
dbUrl: string;
|
||||
db: plugins.mongodb.Db;
|
||||
status: TDbConnectionStatus;
|
||||
constructor(dbUrl: string);
|
||||
connect(): plugins.q.Promise<any>;
|
||||
close(): plugins.q.Promise<any>;
|
||||
}
|
29
dist/smartdata.classes.dbconnection.js
vendored
29
dist/smartdata.classes.dbconnection.js
vendored
@ -1,29 +0,0 @@
|
||||
"use strict";
|
||||
const plugins = require('./smartdata.plugins');
|
||||
class DbConnection {
|
||||
constructor(dbUrl) {
|
||||
this.dbUrl = dbUrl;
|
||||
}
|
||||
connect() {
|
||||
let done = plugins.q.defer();
|
||||
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
plugins.assert.equal(null, err);
|
||||
this.db = db;
|
||||
plugins.beautylog.success(`connected to database at ${this.dbUrl}`);
|
||||
done.resolve(this.db);
|
||||
});
|
||||
return done.promise;
|
||||
}
|
||||
close() {
|
||||
let done = plugins.q.defer();
|
||||
this.db.close();
|
||||
plugins.beautylog.ok(`disconnected to database at ${this.dbUrl}`);
|
||||
done.resolve();
|
||||
return done.promise;
|
||||
}
|
||||
}
|
||||
exports.DbConnection = DbConnection;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJjb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRkYXRhLmNsYXNzZXMuZGJjb25uZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxNQUFZLE9BQU8sV0FBTSxxQkFFekIsQ0FBQyxDQUY2QztBQUk5QztJQUtJLFlBQVksS0FBYTtRQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQTtJQUN0QixDQUFDO0lBRUQsT0FBTztRQUNILElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDNUIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNwRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFBQyxDQUFDO1lBQzdCLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQTtZQUMvQixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQTtZQUNaLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLDRCQUE0QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtZQUNuRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUN6QixDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRCxLQUFLO1FBQ0QsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUM1QixJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ2YsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsK0JBQStCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO1FBQ2pFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUNkLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7QUFDTCxDQUFDO0FBNUJZLG9CQUFZLGVBNEJ4QixDQUFBIn0=
|
46
dist/smartdata.classes.dbdoc.d.ts
vendored
Normal file
46
dist/smartdata.classes.dbdoc.d.ts
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
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[]>;
|
||||
static getInstance<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;
|
||||
}
|
109
dist/smartdata.classes.dbdoc.js
vendored
Normal file
109
dist/smartdata.classes.dbdoc.js
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
"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;
|
||||
});
|
||||
}
|
||||
static getInstance(filterArg) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let result = yield this.getInstances(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
|
||||
*/
|
||||
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJkb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEuY2xhc3Nlcy5kYmRvYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUEsNkJBQWdDO0FBT2hDOztHQUVHO0FBQ0g7SUFDRSxNQUFNLENBQUMsQ0FBQyxNQUFrQixFQUFFLEdBQVcsRUFBRSxFQUFFO1FBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxFQUFFLENBQUM7UUFDakMsQ0FBQztRQUNELE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQVJELG9CQVFDO0FBRUQ7SUEwQkU7O09BRUc7SUFDSDtRQXZCQTs7V0FFRztRQUNILG1CQUFjLEdBQWlCLEtBQUssQ0FBQztRQXFCbkMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsTUFBTSxDQUFPLFlBQVksQ0FBSSxTQUFTOztZQUNwQyxJQUFJLElBQUksR0FBUSxJQUFJLENBQUMsQ0FBQyxrQkFBa0I7WUFDeEMsSUFBSSxjQUFjLEdBQWUsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUM5QyxNQUFNLFNBQVMsR0FBRyxNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdkQsTUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLFNBQVMs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
|
51
dist/smartdata.classes.dbtable.d.ts
vendored
Normal file
51
dist/smartdata.classes.dbtable.d.ts
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
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;
|
||||
}
|
116
dist/smartdata.classes.dbtable.js
vendored
Normal file
116
dist/smartdata.classes.dbtable.js
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLmNsYXNzZXMuZGJ0YWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0ZGF0YS5jbGFzc2VzLmRidGFibGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLCtDQUErQztBQWtCL0M7OztHQUdHO0FBQ0gsZUFBc0IsRUFBTTtJQUMxQixNQUFNLENBQUMsVUFBUyxXQUFXO1FBQ3pCLFdBQVcsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUpELHNCQUlDO0FBRUQ7SUFTRSxZQUFZLGlCQUErQixFQUFFLEtBQVM7UUFKdEQscUJBQWdCLEdBQTBCLElBQUksQ0FBQztRQUs3Qyx1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUM7UUFDeEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFFaEIsd0ZBQXdGO1FBQ3hGLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFSyxJQUFJOztZQUNSLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2hCLDZDQUE2QztnQkFDN0MsTUFBTSxlQUFlLEdBQUcsTUFBTSxPQUFPLENBQUMsU0FBUztxQkFDNUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDO3FCQUNsQixTQUFTLEVBQUU7cUJBQ1gsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzdCLEVBQUUsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsTUFBTSxPQUFPLENBQUMsU0FBUzt5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
|
12
dist/smartdata.plugins.d.ts
vendored
12
dist/smartdata.plugins.d.ts
vendored
@ -1,5 +1,7 @@
|
||||
import 'typings-global';
|
||||
export import assert = require('assert');
|
||||
export import beautylog = require('beautylog');
|
||||
export import mongodb = require('mongodb');
|
||||
export import q = require('q');
|
||||
import * as assert from "assert";
|
||||
import * as beautylog from "beautylog";
|
||||
import * as lodash from "lodash";
|
||||
import * as rethinkDb from "rethinkdb";
|
||||
import * as smartq from "smartq";
|
||||
import * as smartstring from "smartstring";
|
||||
export { assert, beautylog, lodash, smartq, rethinkDb, smartstring };
|
||||
|
20
dist/smartdata.plugins.js
vendored
20
dist/smartdata.plugins.js
vendored
@ -1,7 +1,15 @@
|
||||
"use strict";
|
||||
require('typings-global');
|
||||
exports.assert = require('assert');
|
||||
exports.beautylog = require('beautylog');
|
||||
exports.mongodb = require('mongodb');
|
||||
exports.q = require('q');
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRkYXRhLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGRhdGEucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsUUFBTyxnQkFDUCxDQUFDLENBRHNCO0FBQ1QsY0FBTSxXQUFXLFFBQVEsQ0FBQyxDQUFBO0FBQzFCLGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUE7QUFDaEMsZUFBTyxXQUFXLFNBQVMsQ0FBQyxDQUFBO0FBQzVCLFNBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQSJ9
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
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
|
29
docs/index.md
Normal file
29
docs/index.md
Normal file
@ -0,0 +1,29 @@
|
||||
# smartdata
|
||||
|
||||
do more with data
|
||||
|
||||
## Availabililty
|
||||
|
||||
[](https://www.npmjs.com/package/smartdata)
|
||||
[](https://GitLab.com/pushrocks/smartdata)
|
||||
[](https://github.com/pushrocks/smartdata)
|
||||
[](https://pushrocks.gitlab.io/smartdata/)
|
||||
|
||||
## Status for master
|
||||
|
||||
[](https://GitLab.com/pushrocks/smartdata/commits/master)
|
||||
[](https://GitLab.com/pushrocks/smartdata/commits/master)
|
||||
[](https://www.npmjs.com/package/smartdata)
|
||||
[](https://david-dm.org/pushrocks/smartdata)
|
||||
[](https://www.bithound.io/github/pushrocks/smartdata/master/dependencies/npm)
|
||||
[](https://www.bithound.io/github/pushrocks/smartdata)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](http://standardjs.com/)
|
||||
|
||||
For further information read the linked docs at the top of this README.
|
||||
|
||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
||||
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
|
||||
|
||||
[](https://push.rocks)
|
18
npmextra.json
Normal file
18
npmextra.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"npmdocker": {
|
||||
"baseImage": "hosttoday/ht-docker-node:mongo",
|
||||
"command": "npmci test stable",
|
||||
"dockerSock": false
|
||||
},
|
||||
"npmci": {
|
||||
"npmGlobalTools": [
|
||||
"npmts"
|
||||
],
|
||||
"npmAccessLevel": "public"
|
||||
},
|
||||
"npmts": {
|
||||
"testConfig": {
|
||||
"parallel": false
|
||||
}
|
||||
}
|
||||
}
|
1011
package-lock.json
generated
Normal file
1011
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
41
package.json
41
package.json
@ -1,12 +1,14 @@
|
||||
{
|
||||
"name": "smartdata",
|
||||
"version": "1.0.6",
|
||||
"name": "@pushrocks/smartdata",
|
||||
"version": "3.0.0",
|
||||
"private": false,
|
||||
"description": "do more with data",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "(npm run prepareMongo && npmts)",
|
||||
"prepareMongo": "(rm -rf ./test/data && mkdir ./test/data/)"
|
||||
"test": "(npmts)",
|
||||
"testLocal": "(npmdocker)",
|
||||
"build": "echo \"Not needed for now\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -19,19 +21,26 @@
|
||||
},
|
||||
"homepage": "https://gitlab.com/pushrocks/smartdata#README",
|
||||
"dependencies": {
|
||||
"@types/mongodb": "^2.1.32",
|
||||
"@types/q": "0.0.30",
|
||||
"beautylog": "^5.0.23",
|
||||
"mongodb": "^2.2.9",
|
||||
"q": "^1.4.1",
|
||||
"typings-global": "^1.0.14"
|
||||
"@pushrocks/smartlog": "^1.0.6",
|
||||
"@pushrocks/smartpromise": "^2.0.5",
|
||||
"@types/lodash": "^4.14.110",
|
||||
"@types/mongodb": "^3.1.1",
|
||||
"lik": "^2.0.5",
|
||||
"lodash": "^4.17.10",
|
||||
"mongodb": "^3.1.1",
|
||||
"runtime-type-checks": "0.0.4",
|
||||
"smartstring": "^2.0.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/shelljs": "^0.3.30",
|
||||
"@types/should": "^8.1.29",
|
||||
"shelljs": "^0.7.4",
|
||||
"should": "^11.1.0",
|
||||
"smartstring": "^2.0.17",
|
||||
"typings-test": "^1.0.3"
|
||||
"@types/node": "^10.5.2",
|
||||
"@types/shelljs": "^0.8.0",
|
||||
"qenv": "^1.1.7",
|
||||
"shelljs": "^0.8.2",
|
||||
"tapbundle": "^2.0.2"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
test/test.d.ts
vendored
1
test/test.d.ts
vendored
@ -1 +0,0 @@
|
||||
import 'typings-test';
|
61
test/test.js
61
test/test.js
@ -1,61 +0,0 @@
|
||||
"use strict";
|
||||
require('typings-test');
|
||||
const shelljs = require('shelljs');
|
||||
const should = require('should');
|
||||
const smartstring = require('smartstring');
|
||||
// the tested module
|
||||
const smartdata = require('../dist/index');
|
||||
let mongoChildProcess;
|
||||
let testDbConnection;
|
||||
let testDbCollection;
|
||||
describe('mongodb', function () {
|
||||
it('should start mongodb', function (done) {
|
||||
this.timeout(30000);
|
||||
mongoChildProcess = shelljs.exec('mongod --dbpath=./test/data --port 27017', { async: true, silent: true });
|
||||
let doneCalled = false;
|
||||
mongoChildProcess.stdout.on('data', function (data) {
|
||||
console.log(smartstring.indent.indentWithPrefix(data, "*** MongoDB Process *** : "));
|
||||
if (!doneCalled) {
|
||||
if (/waiting for connections on port 27017/.test(data)) {
|
||||
doneCalled = true;
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('smartdata', function () {
|
||||
it('should establish a connection to mongodb', function (done) {
|
||||
testDbConnection = new smartdata.DbConnection('mongodb://localhost:27017/smartdata');
|
||||
testDbConnection.connect().then(() => { done(); });
|
||||
});
|
||||
it('should create a collection', function () {
|
||||
testDbCollection = new smartdata.DbCollection('something', testDbConnection);
|
||||
});
|
||||
it('should insert something into the collection', function (done) {
|
||||
testDbCollection.insertOne({ hello: 'test' }).then(() => { done(); });
|
||||
});
|
||||
it('should find all instances of test', function (done) {
|
||||
testDbCollection.find({}).then((resultArray) => {
|
||||
console.log(resultArray);
|
||||
should(resultArray[0].hello).equal('test');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should close the db Connection', function () {
|
||||
testDbConnection.close();
|
||||
});
|
||||
});
|
||||
describe('mongodb', function () {
|
||||
it('should kill mongodb', function (done) {
|
||||
this.timeout(30000);
|
||||
mongoChildProcess.stdout.on('data', function (data) {
|
||||
if (/dbexit: rc: 0/.test(data)) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
shelljs.exec('mongod --dbpath=./test/data --shutdown');
|
||||
mongoChildProcess.kill('SIGTERM');
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sY0FFUCxDQUFDLENBRm9CO0FBRXJCLE1BQVksT0FBTyxXQUFNLFNBQ3pCLENBQUMsQ0FEaUM7QUFDbEMsTUFBWSxNQUFNLFdBQU0sUUFDeEIsQ0FBQyxDQUQrQjtBQUNoQyxNQUFZLFdBQVcsV0FBTSxhQUc3QixDQUFDLENBSHlDO0FBRTFDLG9CQUFvQjtBQUNwQixNQUFZLFNBQVMsV0FBTSxlQUUzQixDQUFDLENBRnlDO0FBRTFDLElBQUksaUJBQWlCLENBQUE7QUFDckIsSUFBSSxnQkFBd0MsQ0FBQTtBQUM1QyxJQUFJLGdCQUE2QyxDQUFBO0FBRWpELFFBQVEsQ0FBQyxTQUFTLEVBQUU7SUFDaEIsRUFBRSxDQUFDLHNCQUFzQixFQUFFLFVBQVUsSUFBSTtRQUNyQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsMENBQTBDLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1FBQzNHLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQTtRQUN0QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxVQUFVLElBQUk7WUFDOUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSw0QkFBNEIsQ0FBQyxDQUFDLENBQUE7WUFDcEYsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUNkLEVBQUUsQ0FBQyxDQUFDLHVDQUF1QyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3JELFVBQVUsR0FBRyxJQUFJLENBQUE7b0JBQ2pCLElBQUksRUFBRSxDQUFBO2dCQUNWLENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ0YsUUFBUSxDQUFDLFdBQVcsRUFBRTtJQUNsQixFQUFFLENBQUMsMENBQTBDLEVBQUUsVUFBVSxJQUFJO1FBQ3pELGdCQUFnQixHQUFHLElBQUksU0FBUyxDQUFDLFlBQVksQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFBO1FBQ3BGLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFBLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDckQsQ0FBQyxDQUFDLENBQUE7SUFDRixFQUFFLENBQUMsNEJBQTRCLEVBQUU7UUFDN0IsZ0JBQWdCLEdBQUcsSUFBSSxTQUFTLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO0lBQ2hGLENBQUMsQ0FBQyxDQUFBO0lBQ0YsRUFBRSxDQUFDLDZDQUE2QyxFQUFFLFVBQVUsSUFBSTtRQUM1RCxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3hFLENBQUMsQ0FBQyxDQUFBO0lBQ0YsRUFBRSxDQUFDLG1DQUFtQyxFQUFFLFVBQVUsSUFBSTtRQUNsRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVztZQUN2QyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBQ3hCLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQzFDLElBQUksRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtJQUNGLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRTtRQUNqQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUM1QixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQyxDQUFBO0FBRUYsUUFBUSxDQUFDLFNBQVMsRUFBRTtJQUNoQixFQUFFLENBQUMscUJBQXFCLEVBQUUsVUFBVSxJQUFJO1FBQ3BDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxJQUFJO1lBQzlDLEVBQUUsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLElBQUksRUFBRSxDQUFBO1lBQ1YsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFBO1FBQ0YsT0FBTyxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFBO1FBQ3RELGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNyQyxDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQyxDQUFBIn0=
|
111
test/test.ts
111
test/test.ts
@ -1,64 +1,63 @@
|
||||
import 'typings-test'
|
||||
import { tap, expect } from 'tapbundle';
|
||||
import * as smartpromise from '@pushrocks/smartpromise';
|
||||
import { Qenv } from 'qenv';
|
||||
|
||||
import * as shelljs from 'shelljs'
|
||||
import * as should from 'should'
|
||||
import * as smartstring from 'smartstring'
|
||||
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/');
|
||||
|
||||
// the tested module
|
||||
import * as smartdata from '../dist/index'
|
||||
import * as smartdata from '../ts/index';
|
||||
import { smartstring } from '../ts/smartdata.plugins';
|
||||
|
||||
let mongoChildProcess
|
||||
let testDbConnection: smartdata.DbConnection
|
||||
let testDbCollection: smartdata.DbCollection<any>
|
||||
// =======================================
|
||||
// Connecting to the database server
|
||||
// =======================================
|
||||
|
||||
describe('mongodb', function () {
|
||||
it('should start mongodb', function (done) {
|
||||
this.timeout(30000)
|
||||
mongoChildProcess = shelljs.exec('mongod --dbpath=./test/data --port 27017', { async: true, silent: true })
|
||||
let doneCalled = false
|
||||
mongoChildProcess.stdout.on('data', function (data) {
|
||||
console.log(smartstring.indent.indentWithPrefix(data, "*** MongoDB Process *** : "))
|
||||
if (!doneCalled) {
|
||||
if (/waiting for connections on port 27017/.test(data)) {
|
||||
doneCalled = true
|
||||
done()
|
||||
let testDb = new smartdata.SmartdataDb({
|
||||
mongoDbName: process.env.MONGO_DBNAME,
|
||||
mongoDbUrl: process.env.MONGO_URL,
|
||||
mongoPass: process.env.MONGO_PASS
|
||||
});
|
||||
|
||||
tap.test('should establish a connection to the rethink Db cluster', async () => {
|
||||
await testDb.connect();
|
||||
});
|
||||
|
||||
// =======================================
|
||||
// The actual tests
|
||||
// =======================================
|
||||
|
||||
// ------
|
||||
// Collections
|
||||
// ------
|
||||
|
||||
@smartdata.Table(testDb)
|
||||
class Car extends smartdata.smartDataDbDoc<Car> {
|
||||
@smartdata.svDb() color: string;
|
||||
@smartdata.svDb() brand: string;
|
||||
constructor(colorArg: string, brandArg: string) {
|
||||
super();
|
||||
this.color = colorArg;
|
||||
this.brand = brandArg;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('smartdata', function () {
|
||||
it('should establish a connection to mongodb', function (done) {
|
||||
testDbConnection = new smartdata.DbConnection('mongodb://localhost:27017/smartdata')
|
||||
testDbConnection.connect().then(() => { done() })
|
||||
})
|
||||
it('should create a collection', function () {
|
||||
testDbCollection = new smartdata.DbCollection('something', testDbConnection)
|
||||
})
|
||||
it('should insert something into the collection', function (done) {
|
||||
testDbCollection.insertOne({ hello: 'test' }).then(() => { done() })
|
||||
})
|
||||
it('should find all instances of test', function (done) {
|
||||
testDbCollection.find({}).then((resultArray) => {
|
||||
console.log(resultArray)
|
||||
should(resultArray[0].hello).equal('test')
|
||||
done()
|
||||
})
|
||||
})
|
||||
it('should close the db Connection', function () {
|
||||
testDbConnection.close()
|
||||
})
|
||||
})
|
||||
|
||||
describe('mongodb', function () {
|
||||
it('should kill mongodb', function (done) {
|
||||
this.timeout(30000)
|
||||
mongoChildProcess.stdout.on('data', function (data) {
|
||||
if (/dbexit: rc: 0/.test(data)) {
|
||||
done()
|
||||
}
|
||||
})
|
||||
shelljs.exec('mongod --dbpath=./test/data --shutdown')
|
||||
mongoChildProcess.kill('SIGTERM')
|
||||
})
|
||||
})
|
||||
tap.test('should save the car to the db', async () => {
|
||||
const myCar = new Car('red', 'Volvo');
|
||||
await myCar.save();
|
||||
});
|
||||
|
||||
tap.test('expect to get instance of Car', async () => {
|
||||
let myCar = await Car.getInstances<Car>({
|
||||
brand: 'Volvo'
|
||||
});
|
||||
expect(myCar[0].color).to.equal('red');
|
||||
});
|
||||
|
||||
// =======================================
|
||||
// close the database connection
|
||||
// =======================================
|
||||
tap.test('should close the database connection', async tools => {
|
||||
await testDb.close();
|
||||
});
|
||||
|
||||
tap.start();
|
||||
|
@ -1,4 +1,3 @@
|
||||
import * as plugins from './smartdata.plugins'
|
||||
|
||||
export * from './smartdata.classes.dbcollection'
|
||||
export * from './smartdata.classes.dbconnection'
|
||||
export * from './smartdata.classes.db';
|
||||
export * from './smartdata.classes.dbtable';
|
||||
export * from './smartdata.classes.dbdoc';
|
||||
|
94
ts/smartdata.classes.db.ts
Normal file
94
ts/smartdata.classes.db.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import * as plugins from './smartdata.plugins';
|
||||
import { Objectmap } from 'lik';
|
||||
|
||||
import { SmartdataCollection } from './smartdata.classes.dbtable';
|
||||
|
||||
import * as mongoHelpers from './smartdata.mongohelpers';
|
||||
|
||||
/**
|
||||
* interface - indicates the connection status of the db
|
||||
*/
|
||||
export type TConnectionStatus = 'initial' | 'disconnected' | 'connected' | 'failed';
|
||||
|
||||
export interface ISmartdataOptions {
|
||||
/**
|
||||
* the URL to connect to
|
||||
*/
|
||||
mongoDbUrl: string;
|
||||
|
||||
/**
|
||||
* the db to use for the project
|
||||
*/
|
||||
mongoDbName: string;
|
||||
|
||||
/**
|
||||
* an optional password that will be replace <PASSWORD> in the connection string
|
||||
*/
|
||||
mongoDbPass?: string;
|
||||
}
|
||||
|
||||
export class SmartdataDb {
|
||||
smartdataOptions: ISmartdataOptions;
|
||||
mongoDbClient: plugins.mongodb.MongoClient;
|
||||
mongoDb: plugins.mongodb.Db;
|
||||
status: TConnectionStatus;
|
||||
smartdataCollectionMap = new Objectmap<SmartdataCollection<any>>();
|
||||
|
||||
constructor(smartdataOptions: ISmartdataOptions) {
|
||||
this.smartdataOptions = smartdataOptions;
|
||||
this.status = 'initial';
|
||||
}
|
||||
|
||||
// basic connection stuff ----------------------------------------------
|
||||
|
||||
/**
|
||||
* connects to the database that was specified during instance creation
|
||||
*/
|
||||
async connect(): Promise<any> {
|
||||
let finalConnectionUrl = this.smartdataOptions.mongoDbUrl;
|
||||
if (this.smartdataOptions.mongoDbPass) {
|
||||
finalConnectionUrl = mongoHelpers.addPassword(
|
||||
this.smartdataOptions.mongoDbName,
|
||||
this.smartdataOptions.mongoDbPass
|
||||
);
|
||||
}
|
||||
this.mongoDbClient = await plugins.mongodb.MongoClient.connect(
|
||||
finalConnectionUrl,
|
||||
{}
|
||||
);
|
||||
this.mongoDb = this.mongoDbClient.db(this.smartdataOptions.mongoDbName);
|
||||
this.status = 'connected';
|
||||
plugins.smartlog
|
||||
.getDefaultLogger()
|
||||
.info(`Connected to database ${this.smartdataOptions.mongoDbName}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* closes the connection to the databse
|
||||
*/
|
||||
async close(): Promise<any> {
|
||||
await this.mongoDbClient.close();
|
||||
this.status = 'disconnected';
|
||||
plugins.smartlog
|
||||
.getDefaultLogger()
|
||||
.info(`disconnected from database ${this.smartdataOptions.mongoDbName}`);
|
||||
}
|
||||
|
||||
// handle table to class distribution
|
||||
|
||||
addTable(SmartdataCollectionArg: SmartdataCollection<any>) {
|
||||
this.smartdataCollectionMap.add(SmartdataCollectionArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a collection's name and returns a SmartdataCollection instance
|
||||
* @param nameArg
|
||||
* @returns DbTable
|
||||
*/
|
||||
async getSmartdataCollectionByName<T>(nameArg: string): Promise<SmartdataCollection<T>> {
|
||||
let resultCollection = this.smartdataCollectionMap.find(dbTableArg => {
|
||||
return dbTableArg.collectionName === nameArg;
|
||||
});
|
||||
return resultCollection;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import * as plugins from './smartdata.plugins'
|
||||
import { DbConnection } from './smartdata.classes.dbconnection'
|
||||
|
||||
export class DbCollection<T> {
|
||||
collection: plugins.mongodb.Collection
|
||||
constructor(nameArg: string, dbConnectionArg: DbConnection) {
|
||||
this.collection = dbConnectionArg.db.collection(nameArg)
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a validation function that all newly inserted and updated objects have to pass
|
||||
*/
|
||||
addObjectValidation(funcArg) { }
|
||||
|
||||
/**
|
||||
* finds an object in the DbCollection
|
||||
*/
|
||||
find(docMatchArg: T): plugins.q.Promise<T[]> {
|
||||
let done = plugins.q.defer<T[]>()
|
||||
this.collection.find().toArray((err, docs) => {
|
||||
if (err) { throw err }
|
||||
done.resolve(docs)
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts object into the DbCollection
|
||||
*/
|
||||
insertOne(docArg: T): plugins.q.Promise<void> {
|
||||
let done = plugins.q.defer<void>()
|
||||
this.checkDoc(docArg).then(() => {
|
||||
this.collection.insertOne(docArg)
|
||||
.then(() => { done.resolve() })
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts many objects at once into the DbCollection
|
||||
*/
|
||||
insertMany(docArrayArg: T[]): plugins.q.Promise<void> {
|
||||
let done = plugins.q.defer<void>()
|
||||
let checkDocPromiseArray: plugins.q.Promise<void>[] = []
|
||||
for (let docArg of docArrayArg){
|
||||
checkDocPromiseArray.push(this.checkDoc(docArg))
|
||||
}
|
||||
plugins.q.all(checkDocPromiseArray).then(() => {
|
||||
this.collection.insertMany(docArrayArg)
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
private checkDoc(doc: T): plugins.q.Promise<void> {
|
||||
let done = plugins.q.defer<void>()
|
||||
done.resolve()
|
||||
return done.promise
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import * as plugins from './smartdata.plugins'
|
||||
|
||||
export type TDbConnectionStatus = 'disconnected' | 'connected' | 'failed'
|
||||
|
||||
export class DbConnection {
|
||||
dbUrl: string
|
||||
db: plugins.mongodb.Db
|
||||
status: TDbConnectionStatus
|
||||
|
||||
constructor(dbUrl: string) {
|
||||
this.dbUrl = dbUrl
|
||||
}
|
||||
|
||||
connect(): plugins.q.Promise<any> {
|
||||
let done = plugins.q.defer()
|
||||
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
|
||||
if (err) { console.log(err) }
|
||||
plugins.assert.equal(null, err)
|
||||
this.db = db
|
||||
plugins.beautylog.success(`connected to database at ${this.dbUrl}`)
|
||||
done.resolve(this.db)
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
close(): plugins.q.Promise<any> {
|
||||
let done = plugins.q.defer()
|
||||
this.db.close()
|
||||
plugins.beautylog.ok(`disconnected to database at ${this.dbUrl}`)
|
||||
done.resolve()
|
||||
return done.promise
|
||||
}
|
||||
}
|
125
ts/smartdata.classes.dbdoc.ts
Normal file
125
ts/smartdata.classes.dbdoc.ts
Normal file
@ -0,0 +1,125 @@
|
||||
import * as plugins from './smartdata.plugins';
|
||||
|
||||
import { Objectmap } from 'lik';
|
||||
|
||||
import { SmartdataDb } from './smartdata.classes.db';
|
||||
import { SmartdataCollection } from './smartdata.classes.dbtable';
|
||||
|
||||
export type TDocCreation = 'db' | 'new' | 'mixed';
|
||||
|
||||
/**
|
||||
* saveable - saveable decorator to be used on class properties
|
||||
*/
|
||||
export function svDb() {
|
||||
return (target: smartDataDbDoc<any>, key: string) => {
|
||||
console.log('called sva');
|
||||
if (!target.saveableProperties) {
|
||||
target.saveableProperties = [];
|
||||
}
|
||||
target.saveableProperties.push(key);
|
||||
};
|
||||
}
|
||||
|
||||
export class smartDataDbDoc<T> {
|
||||
/**
|
||||
* the collection object an Doc belongs to
|
||||
*/
|
||||
collection: SmartdataCollection<T>;
|
||||
|
||||
/**
|
||||
* how the Doc in memory was created, may prove useful later.
|
||||
*/
|
||||
creationStatus: TDocCreation = 'new';
|
||||
|
||||
/**
|
||||
* an array of saveable properties of a doc
|
||||
*/
|
||||
saveableProperties: string[];
|
||||
|
||||
/**
|
||||
* name
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* primary id in the database
|
||||
*/
|
||||
dbDocUniqueId: string;
|
||||
|
||||
/**
|
||||
* class constructor
|
||||
*/
|
||||
constructor() {
|
||||
this.name = this.constructor['name'];
|
||||
this.collection = this.constructor['dbTable'];
|
||||
}
|
||||
|
||||
static async getInstances<T>(filterArg): Promise<T[]> {
|
||||
let self: any = this; // fool typesystem
|
||||
let referenceTable: SmartdataCollection<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<smartDataDbDoc<any>> = null) {
|
||||
if (!savedMapArg) {
|
||||
savedMapArg = new Objectmap<smartDataDbDoc<any>>();
|
||||
}
|
||||
savedMapArg.add(this);
|
||||
this.save();
|
||||
for (let propertyKey in this) {
|
||||
let property: any = this[propertyKey];
|
||||
if (property instanceof smartDataDbDoc && !savedMapArg.checkForObject(property)) {
|
||||
property.saveDeep(savedMapArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async createSavableObject() {
|
||||
let saveableObject: any = {}; // is not exposed to outside, so any is ok here
|
||||
for (let propertyNameString of this.saveableProperties) {
|
||||
saveableObject[propertyNameString] = this[propertyNameString];
|
||||
}
|
||||
return saveableObject;
|
||||
}
|
||||
}
|
113
ts/smartdata.classes.dbtable.ts
Normal file
113
ts/smartdata.classes.dbtable.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import * as plugins from './smartdata.plugins';
|
||||
import { SmartdataDb } from './smartdata.classes.db';
|
||||
import { smartDataDbDoc } from './smartdata.classes.dbdoc';
|
||||
|
||||
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: SmartdataDb) {
|
||||
return function(constructor) {
|
||||
constructor['mongoDbCollection'] = new SmartdataCollection(constructor, db);
|
||||
};
|
||||
}
|
||||
|
||||
export class SmartdataCollection<T> {
|
||||
/**
|
||||
* the collection that is used
|
||||
*/
|
||||
mongoDbCollection: plugins.mongodb.Collection;
|
||||
objectValidation: IDocValidationFunc<T> = null;
|
||||
collectionName: string;
|
||||
smartdataDb: SmartdataDb;
|
||||
|
||||
constructor(collectedClassArg: T & smartDataDbDoc<T>, smartDataDbArg: SmartdataDb) {
|
||||
// tell the collection where it belongs
|
||||
this.collectionName = collectedClassArg.name;
|
||||
this.smartdataDb = smartDataDbArg;
|
||||
|
||||
// tell the db class about it (important since Db uses different systems under the hood)
|
||||
this.smartdataDb.addTable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* makes sure a collection exists within MongoDb that maps to the SmartdataCollection
|
||||
*/
|
||||
async init() {
|
||||
if (!this.mongoDbCollection) {
|
||||
// connect this instance to a MongoDB collection
|
||||
const availableMongoDbCollections = await this.smartdataDb.mongoDb.collections();
|
||||
const wantedCollection = availableMongoDbCollections.find(collection => {
|
||||
return collection.collectionName === this.collectionName;
|
||||
});
|
||||
if (!wantedCollection) {
|
||||
await this.smartdataDb.mongoDb.createCollection(this.collectionName);
|
||||
}
|
||||
this.mongoDbCollection = await this.smartdataDb.mongoDb.collection(this.collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* create an object in the database
|
||||
*/
|
||||
async insert(dbDocArg: T & smartDataDbDoc<T>): Promise<any> {
|
||||
await this.init();
|
||||
await this.checkDoc(dbDocArg);
|
||||
const saveableObject = await dbDocArg.createSavableObject();
|
||||
const result = await this.mongoDbCollection.insertOne(saveableObject);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts object into the DbCollection
|
||||
*/
|
||||
async update(dbDocArg: T & smartDataDbDoc<T>): Promise<any> {
|
||||
await this.init();
|
||||
await this.checkDoc(dbDocArg);
|
||||
const saveableObject = await dbDocArg.createSavableObject();
|
||||
this.mongoDbCollection.updateOne(saveableObject.dbDocUniqueId, saveableObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks a Doc for constraints
|
||||
* if this.objectValidation is not set it passes.
|
||||
*/
|
||||
private checkDoc(docArg: T): Promise<void> {
|
||||
let done = plugins.smartq.defer<void>();
|
||||
let validationResult = true;
|
||||
if (this.objectValidation) {
|
||||
validationResult = this.objectValidation(docArg);
|
||||
}
|
||||
if (validationResult) {
|
||||
done.resolve();
|
||||
} else {
|
||||
done.reject('validation of object did not pass');
|
||||
}
|
||||
return done.promise;
|
||||
}
|
||||
}
|
3
ts/smartdata.mongohelpers.ts
Normal file
3
ts/smartdata.mongohelpers.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const addPassword = (mongoUrlArg: string, passwordArg: string): string => {
|
||||
return mongoUrlArg.replace('<PASSWORD>', passwordArg);
|
||||
};
|
@ -1,5 +1,8 @@
|
||||
import 'typings-global'
|
||||
export import assert = require('assert')
|
||||
export import beautylog = require('beautylog')
|
||||
export import mongodb = require('mongodb')
|
||||
export import q = require('q')
|
||||
import * as assert from 'assert';
|
||||
import * as smartlog from '@pushrocks/smartlog';
|
||||
import * as lodash from 'lodash';
|
||||
import * as mongodb from 'mongodb';
|
||||
import * as smartq from 'smartq';
|
||||
import * as smartstring from 'smartstring';
|
||||
|
||||
export { assert, smartlog, lodash, smartq, mongodb, smartstring };
|
||||
|
8
tsconfig.json
Normal file
8
tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"lib": [
|
||||
"es2015"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "tslint-config-standard"
|
||||
}
|
Reference in New Issue
Block a user