update module structure

This commit is contained in:
Philipp Kunz 2020-06-11 23:05:32 +00:00
parent 3f714b1a33
commit 116dfbc3b0
13 changed files with 3944 additions and 1386 deletions

4
.gitignore vendored
View File

@ -15,8 +15,6 @@ node_modules/
# builds # builds
dist/ dist/
dist_web/ dist_*/
dist_serve/
dist_ts_web/
# custom # custom

View File

@ -4,7 +4,7 @@ image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache: cache:
paths: paths:
- .npmci_cache/ - .npmci_cache/
key: "$CI_BUILD_STAGE" key: '$CI_BUILD_STAGE'
stages: stages:
- security - security
@ -20,17 +20,20 @@ mirror:
script: script:
- npmci git mirror - npmci git mirror
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
snyk: audit:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security stage: security
script: script:
- npmci npm prepare - npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts - npmci command npm install --ignore-scripts
- npmci command snyk test - npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
@ -47,6 +50,7 @@ testStable:
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- lossless
- docker - docker
- priv - priv
@ -54,22 +58,24 @@ testBuild:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
- npmci node install lts - npmci node install stable
- npmci npm install - npmci npm install
- npmci command npm run build - npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
release: release:
stage: release stage: release
script: script:
- npmci node install lts - npmci node install stable
- npmci npm publish - npmci npm publish
only: only:
- tags - tags
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
@ -81,9 +87,11 @@ codequality:
allow_failure: true allow_failure: true
script: script:
- npmci command npm install -g tslint typescript - npmci command npm install -g tslint typescript
- npmci npm prepare
- npmci npm install - npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts" - npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags: tags:
- lossless
- docker - docker
- priv - priv
@ -94,20 +102,20 @@ trigger:
only: only:
- tags - tags
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
pages: pages:
image: hosttoday/ht-docker-dbase:npmci
services:
- docker:stable-dind
stage: metadata stage: metadata
script: script:
- npmci node install lts
- npmci command npm install -g @gitzone/tsdoc - npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare - npmci npm prepare
- npmci npm install - npmci npm install
- npmci command tsdoc - npmci command tsdoc
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
only: only:

29
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,29 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "current file",
"type": "node",
"request": "launch",
"args": [
"${relativeFile}"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
}
]
}

26
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"schema": {
"type": "object",
"properties": {
"npmci": {
"type": "object",
"description": "settings for npmci"
},
"gitzone": {
"type": "object",
"description": "settings for gitzone",
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm"]
}
}
}
}
}
}
]
}

137
README.md
View File

@ -1,137 +0,0 @@
# @pushrocks/smartdata
do more with data
## 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/@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
Use TypeScript for best in class instellisense.
smartdata is an ODM that adheres to TypeScript practices and uses classes to organize data.
It uses RethinkDB as persistent storage.
## Intention
There are many ODMs out there, however when we searched for an ODM that uses TypeScript,
acts smart while still embracing the NoSQL idea we didn't find a matching solution.
This is why we started smartdata.
How RethinkDB's terms map to the ones of smartdata:
| MongoDb term | smartdata class |
| ------------ | ----------------------------- |
| Database | smartdata.SmartdataDb |
| Collection | smartdata.SmartdataCollection |
| Document | smartdata.SmartadataDoc |
### class Db
represents a Database. Naturally it has .connect() etc. methods on it.
```typescript
import * as smartdata from 'smartdata';
const smartdataDb = new smartdata.SmartdataDb({
mongoDbUrl: '//someurl',
mongoDbName: 'myDatabase',
mongoDbPass: 'mypassword'
});
smartdataDb.connect();
```
### class DbCollection
represents a collection of objects.
A collection is defined by the object class (that is extending smartdata.dbdoc) it respresents
So to get to get access to a specific collection you document
```typescript
// continues from the block before...
@smartdata.Collection(smartdataDb)
class MyObject extends smartdata.DbDoc<MyObject> {
// read the next block about DbDoc
@smartdata.svDb()
property1: string; // @smartdata.svDb() marks the property for db save
property2: number; // this one is not marked, so it won't be save upon calling this.save()
constructor() {
super(); // the super call is important ;) But you probably know that.
}
}
// start to instantiate instances of classes from scratch or database
const 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.
### CRUD operations
smartdata supports full CRUD operations
**Store** or **Update** instances of classes to MongoDB:
DbDoc extends your class with the following methods:
- 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 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.
## 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. You don't need to install any additional types for smartdata.
For further information read the linked docs at the top of this readme.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

View File

@ -10,6 +10,7 @@
"npmRegistryUrl": "registry.npmjs.org" "npmRegistryUrl": "registry.npmjs.org"
}, },
"gitzone": { "gitzone": {
"projectType": "npm",
"module": { "module": {
"githost": "gitlab.com", "githost": "gitlab.com",
"gitscope": "pushrocks", "gitscope": "pushrocks",

5065
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,8 @@
"version": "3.1.26", "version": "3.1.26",
"private": false, "private": false,
"description": "do more with data", "description": "do more with data",
"main": "dist/index.js", "main": "dist_ts/index.js",
"typings": "dist/index.d.ts", "typings": "dist_ts/index.d.ts",
"scripts": { "scripts": {
"test": "(tstest test/)", "test": "(tstest test/)",
"testLocal": "(npmdocker)", "testLocal": "(npmdocker)",
@ -21,36 +21,37 @@
}, },
"homepage": "https://gitlab.com/pushrocks/smartdata#README", "homepage": "https://gitlab.com/pushrocks/smartdata#README",
"dependencies": { "dependencies": {
"@pushrocks/lik": "^3.0.19", "@pushrocks/lik": "^4.0.13",
"@pushrocks/smartlog": "^2.0.21", "@pushrocks/smartlog": "^2.0.35",
"@pushrocks/smartpromise": "^3.0.6", "@pushrocks/smartpromise": "^3.0.6",
"@pushrocks/smartstring": "^3.0.18", "@pushrocks/smartstring": "^3.0.18",
"@pushrocks/smartunique": "^3.0.1", "@pushrocks/smartunique": "^3.0.3",
"@types/lodash": "^4.14.149", "@types/lodash": "^4.14.155",
"@types/mongodb": "^3.3.16", "@types/mongodb": "^3.5.20",
"lodash": "^4.17.15", "lodash": "^4.17.15",
"mongodb": "^3.5.3", "mongodb": "^3.5.8",
"runtime-type-checks": "0.0.4" "runtime-type-checks": "0.0.4"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.17", "@gitzone/tsbuild": "^2.1.24",
"@gitzone/tstest": "^1.0.28", "@gitzone/tstest": "^1.0.33",
"@pushrocks/qenv": "^4.0.6", "@pushrocks/qenv": "^4.0.10",
"@pushrocks/tapbundle": "^3.2.0", "@pushrocks/tapbundle": "^3.2.1",
"@types/mongodb-memory-server": "^2.3.0", "@types/mongodb-memory-server": "^2.3.0",
"@types/node": "^13.7.2", "@types/node": "^14.0.13",
"@types/shortid": "0.0.29", "@types/shortid": "0.0.29",
"mongodb-memory-server": "^6.2.4", "mongodb-memory-server": "^6.6.1",
"tslint": "^6.0.0", "tslint": "^6.1.2",
"tslint-config-prettier": "^1.18.0" "tslint-config-prettier": "^1.18.0"
}, },
"files": [ "files": [
"ts/*", "ts/**/*",
"ts_web/*", "ts_web/**/*",
"dist/*", "dist/**/*",
"dist_web/*", "dist_*/**/*",
"dist_ts_web/*", "dist_ts/**/*",
"assets/*", "dist_ts_web/**/*",
"assets/**/*",
"cli.js", "cli.js",
"npmextra.json", "npmextra.json",
"readme.md" "readme.md"

View File

@ -101,8 +101,6 @@ tap.test('should be able to delete an instance of car', async () => {
expect(myCar2.color).to.equal('red'); expect(myCar2.color).to.equal('red');
}); });
// tslint:disable-next-line: max-classes-per-file // tslint:disable-next-line: max-classes-per-file
@smartdata.Collection(() => { @smartdata.Collection(() => {
return testDb; return testDb;
@ -132,10 +130,8 @@ tap.test('should store a new Truck', async () => {
await myTruck.save(); await myTruck.save();
const myTruck2 = await Truck.getInstance<Truck>({ color: 'blue' }); const myTruck2 = await Truck.getInstance<Truck>({ color: 'blue' });
console.log(myTruck2); console.log(myTruck2);
}); });
// ======================================= // =======================================
// close the database connection // close the database connection
// ======================================= // =======================================

View File

@ -1,9 +1,10 @@
import * as plugins from './smartdata.plugins'; import * as plugins from './smartdata.plugins';
import { Objectmap } from '@pushrocks/lik'; import { ObjectMap } from '@pushrocks/lik';
import { SmartdataCollection } from './smartdata.classes.collection'; import { SmartdataCollection } from './smartdata.classes.collection';
import * as mongoHelpers from './smartdata.mongohelpers'; import * as mongoHelpers from './smartdata.mongohelpers';
import { logger } from './smartdata.logging';
/** /**
* interface - indicates the connection status of the db * interface - indicates the connection status of the db
@ -32,7 +33,7 @@ export class SmartdataDb {
mongoDbClient: plugins.mongodb.MongoClient; mongoDbClient: plugins.mongodb.MongoClient;
mongoDb: plugins.mongodb.Db; mongoDb: plugins.mongodb.Db;
status: TConnectionStatus; status: TConnectionStatus;
smartdataCollectionMap = new Objectmap<SmartdataCollection<any>>(); smartdataCollectionMap = new ObjectMap<SmartdataCollection<any>>();
constructor(smartdataOptions: ISmartdataOptions) { constructor(smartdataOptions: ISmartdataOptions) {
this.smartdataOptions = smartdataOptions; this.smartdataOptions = smartdataOptions;
@ -68,10 +69,7 @@ export class SmartdataDb {
public async close(): Promise<any> { public async close(): Promise<any> {
await this.mongoDbClient.close(); await this.mongoDbClient.close();
this.status = 'disconnected'; this.status = 'disconnected';
plugins.smartlog.defaultLogger.log( logger.log('info', `disconnected from database ${this.smartdataOptions.mongoDbName}`);
'info',
`disconnected from database ${this.smartdataOptions.mongoDbName}`
);
} }
// handle table to class distribution // handle table to class distribution

View File

@ -1,6 +1,6 @@
import * as plugins from './smartdata.plugins'; import * as plugins from './smartdata.plugins';
import { Objectmap } from '@pushrocks/lik'; import { ObjectMap } from '@pushrocks/lik';
import { SmartdataDb } from './smartdata.classes.db'; import { SmartdataDb } from './smartdata.classes.db';
import { SmartdataCollection } from './smartdata.classes.collection'; import { SmartdataCollection } from './smartdata.classes.collection';
@ -150,9 +150,9 @@ export class SmartDataDbDoc<T, TImplements> {
* also store any referenced objects to DB * also store any referenced objects to DB
* better for data consistency * better for data consistency
*/ */
public saveDeep(savedMapArg: Objectmap<SmartDataDbDoc<any, any>> = null) { public saveDeep(savedMapArg: ObjectMap<SmartDataDbDoc<any, any>> = null) {
if (!savedMapArg) { if (!savedMapArg) {
savedMapArg = new Objectmap<SmartDataDbDoc<any, any>>(); savedMapArg = new ObjectMap<SmartDataDbDoc<any, any>>();
} }
savedMapArg.add(this); savedMapArg.add(this);
this.save(); this.save();

3
ts/smartdata.logging.ts Normal file
View File

@ -0,0 +1,3 @@
import * as plugins from './smartdata.plugins';
export const logger = new plugins.smartlog.ConsoleLog();

View File

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