Compare commits

..

17 Commits

Author SHA1 Message Date
02af9f5c4b 3.1.28 2020-06-11 23:08:38 +00:00
17de480272 fix(core): update 2020-06-11 23:08:38 +00:00
776fd3ee4e 3.1.27 2020-06-11 23:05:46 +00:00
3272bb7235 fix(core): update 2020-06-11 23:05:45 +00:00
116dfbc3b0 update module structure 2020-06-11 23:05:32 +00:00
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
14 changed files with 4250 additions and 1363 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

@ -3,14 +3,14 @@ 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
- test - test
- release - release
- metadata - metadata
# ==================== # ====================
# security stage # security stage
@ -18,21 +18,24 @@ stages:
mirror: mirror:
stage: security stage: security
script: script:
- npmci git mirror - npmci git mirror
tags: tags:
- docker - lossless
- notpriv - docker
- 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:
- docker - lossless
- notpriv - docker
- notpriv
# ==================== # ====================
# test stage # test stage
@ -41,37 +44,40 @@ snyk:
testStable: testStable:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
- npmci node install stable - npmci node install stable
- npmci npm install - npmci npm install
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - lossless
- priv - docker
- priv
testBuild: 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:
- docker - lossless
- notpriv - docker
- 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:
- docker - lossless
- notpriv - docker
- notpriv
# ==================== # ====================
# metadata stage # metadata stage
@ -81,33 +87,35 @@ 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:
- docker - lossless
- priv - docker
- priv
trigger: trigger:
stage: metadata stage: metadata
script: script:
- npmci trigger - npmci trigger
only: only:
- tags - tags
tags: tags:
- docker - lossless
- notpriv - docker
- 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:
@ -115,5 +123,5 @@ pages:
artifacts: artifacts:
expire_in: 1 week expire_in: 1 week
paths: paths:
- public - public
allow_failure: true allow_failure: true

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"]
}
}
}
}
}
}
]
}

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",

5308
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
{ {
"name": "@pushrocks/smartdata", "name": "@pushrocks/smartdata",
"version": "3.1.20", "version": "3.1.28",
"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)",
"build": "(tsbuild)" "build": "(tsbuild --web)"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -21,36 +21,37 @@
}, },
"homepage": "https://gitlab.com/pushrocks/smartdata#README", "homepage": "https://gitlab.com/pushrocks/smartdata#README",
"dependencies": { "dependencies": {
"@pushrocks/lik": "^3.0.11", "@pushrocks/lik": "^4.0.13",
"@pushrocks/smartlog": "^2.0.19", "@pushrocks/smartlog": "^2.0.35",
"@pushrocks/smartpromise": "^3.0.2", "@pushrocks/smartpromise": "^3.0.6",
"@pushrocks/smartstring": "^3.0.10", "@pushrocks/smartstring": "^3.0.18",
"@pushrocks/smartunique": "^3.0.1", "@pushrocks/smartunique": "^3.0.3",
"@types/lodash": "^4.14.138", "@types/lodash": "^4.14.155",
"@types/mongodb": "^3.3.1", "@types/mongodb": "^3.5.20",
"lodash": "^4.17.15", "lodash": "^4.17.15",
"mongodb": "^3.3.2", "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.24", "@gitzone/tstest": "^1.0.33",
"@pushrocks/qenv": "^4.0.4", "@pushrocks/qenv": "^4.0.10",
"@pushrocks/tapbundle": "^3.0.13", "@pushrocks/tapbundle": "^3.2.1",
"@types/mongodb-memory-server": "^1.8.0", "@types/mongodb-memory-server": "^2.3.0",
"@types/node": "^12.7.3", "@types/node": "^14.0.13",
"@types/shortid": "0.0.29", "@types/shortid": "0.0.29",
"mongodb-memory-server": "^5.2.0", "mongodb-memory-server": "^6.6.1",
"tslint": "^5.19.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

@ -29,14 +29,6 @@ tap.test('should create a testinstance as database', async () => {
testDb = new smartdata.SmartdataDb(smartdataOptions); testDb = new smartdata.SmartdataDb(smartdataOptions);
}); });
tap.skip.test('should create a smartdb', async () => {
testDb = new smartdata.SmartdataDb({
mongoDbName: testQenv.getEnvVarOnDemand('MONGO_DBNAME'),
mongoDbUrl: testQenv.getEnvVarOnDemand('MONGO_URL'),
mongoDbPass: testQenv.getEnvVarOnDemand('MONGO_PASS')
});
});
tap.test('should establish a connection to the rethink Db cluster', async () => { tap.test('should establish a connection to the rethink Db cluster', async () => {
await testDb.init(); await testDb.init();
}); });
@ -52,7 +44,7 @@ tap.test('should establish a connection to the rethink Db cluster', async () =>
@smartdata.Collection(() => { @smartdata.Collection(() => {
return testDb; return testDb;
}) })
class Car extends smartdata.SmartDataDbDoc<Car> { class Car extends smartdata.SmartDataDbDoc<Car, Car> {
@smartdata.unI() @smartdata.unI()
public index: string = smartunique.shortId(); public index: string = smartunique.shortId();
@ -109,6 +101,37 @@ 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
@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 // close the database connection
// ======================================= // =======================================

View File

@ -42,7 +42,7 @@ export class SmartdataCollection<T> {
public smartdataDb: SmartdataDb; public smartdataDb: SmartdataDb;
public uniqueIndexes: string[] = []; public uniqueIndexes: string[] = [];
constructor(collectedClassArg: T & SmartDataDbDoc<T>, smartDataDbArg: SmartdataDb) { constructor(collectedClassArg: T & SmartDataDbDoc<T, unknown>, smartDataDbArg: SmartdataDb) {
// tell the collection where it belongs // tell the collection where it belongs
this.collectionName = collectedClassArg.name; this.collectionName = collectedClassArg.name;
this.smartdataDb = smartDataDbArg; this.smartdataDb = smartDataDbArg;
@ -103,7 +103,7 @@ export class SmartdataCollection<T> {
/** /**
* create an object in the database * create an object in the database
*/ */
public async insert(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> { public async insert(dbDocArg: T & SmartDataDbDoc<T, unknown>): Promise<any> {
await this.init(); await this.init();
await this.checkDoc(dbDocArg); await this.checkDoc(dbDocArg);
this.markUniqueIndexes(dbDocArg.uniqueIndexes); this.markUniqueIndexes(dbDocArg.uniqueIndexes);
@ -115,13 +115,11 @@ export class SmartdataCollection<T> {
/** /**
* inserts object into the DbCollection * inserts object into the DbCollection
*/ */
public async update(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> { public async update(dbDocArg: T & SmartDataDbDoc<T, unknown>): Promise<any> {
await this.init(); await this.init();
await this.checkDoc(dbDocArg); await this.checkDoc(dbDocArg);
const identifiableObject = await dbDocArg.createIdentifiableObject(); const identifiableObject = await dbDocArg.createIdentifiableObject();
const saveableObject = await dbDocArg.createSavableObject(); const saveableObject = await dbDocArg.createSavableObject();
console.log(identifiableObject);
console.log(saveableObject);
const updateableObject: any = {}; const updateableObject: any = {};
for (const key of Object.keys(saveableObject)) { for (const key of Object.keys(saveableObject)) {
if (identifiableObject[key]) { if (identifiableObject[key]) {
@ -129,7 +127,6 @@ export class SmartdataCollection<T> {
} }
updateableObject[key] = saveableObject[key]; updateableObject[key] = saveableObject[key];
} }
console.log(updateableObject);
this.mongoDbCollection.updateOne( this.mongoDbCollection.updateOne(
identifiableObject, identifiableObject,
{ $set: updateableObject }, { $set: updateableObject },
@ -137,11 +134,13 @@ export class SmartdataCollection<T> {
); );
} }
public async delete(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> { public async delete(dbDocArg: T & SmartDataDbDoc<T, unknown>): Promise<any> {
await this.init(); await this.init();
await this.checkDoc(dbDocArg); await this.checkDoc(dbDocArg);
const identifiableObject = await dbDocArg.createIdentifiableObject(); const identifiableObject = await dbDocArg.createIdentifiableObject();
this.mongoDbCollection.deleteOne(identifiableObject); await this.mongoDbCollection.deleteOne(identifiableObject, {
w: 1
});
} }
/** /**

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;
@ -54,7 +55,8 @@ export class SmartdataDb {
} }
console.log(`connection Url: ${finalConnectionUrl}`); console.log(`connection Url: ${finalConnectionUrl}`);
this.mongoDbClient = await plugins.mongodb.MongoClient.connect(finalConnectionUrl, { this.mongoDbClient = await plugins.mongodb.MongoClient.connect(finalConnectionUrl, {
useNewUrlParser: true useNewUrlParser: true,
useUnifiedTopology: true
}); });
this.mongoDb = this.mongoDbClient.db(this.smartdataOptions.mongoDbName); this.mongoDb = this.mongoDbClient.db(this.smartdataOptions.mongoDbName);
this.status = 'connected'; this.status = 'connected';
@ -67,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';
@ -11,7 +11,7 @@ export type TDocCreation = 'db' | 'new' | 'mixed';
* saveable - saveable decorator to be used on class properties * saveable - saveable decorator to be used on class properties
*/ */
export function svDb() { export function svDb() {
return (target: SmartDataDbDoc<any>, key: string) => { return (target: SmartDataDbDoc<unknown, unknown>, key: string) => {
console.log(`called svDb() on ${key}`); console.log(`called svDb() on ${key}`);
if (!target.saveableProperties) { if (!target.saveableProperties) {
target.saveableProperties = []; target.saveableProperties = [];
@ -24,7 +24,7 @@ export function svDb() {
* unique index - decorator to mark a unique index * unique index - decorator to mark a unique index
*/ */
export function unI() { export function unI() {
return (target: SmartDataDbDoc<any>, key: string) => { return (target: SmartDataDbDoc<unknown, unknown>, key: string) => {
console.log('called unI'); console.log('called unI');
// mark the index as unique // mark the index as unique
@ -41,7 +41,7 @@ export function unI() {
}; };
} }
export class SmartDataDbDoc<T> { export class SmartDataDbDoc<T, TImplements> {
/** /**
* the collection object an Doc belongs to * the collection object an Doc belongs to
*/ */
@ -103,17 +103,15 @@ export class SmartDataDbDoc<T> {
for (const item of foundDocs) { for (const item of foundDocs) {
const newInstance = new this(); const newInstance = new this();
newInstance.creationStatus = 'db'; newInstance.creationStatus = 'db';
for (const key in item) { for (const key of Object.keys(item)) {
if (key !== 'id') { newInstance[key] = item[key];
newInstance[key] = item[key];
}
} }
returnArray.push(newInstance); returnArray.push(newInstance);
} }
return returnArray; return returnArray;
} }
static async getInstance<T>(filterArg): Promise<T> { public static async getInstance<T>(filterArg): Promise<T> {
const result = await this.getInstances<T>(filterArg); const result = await this.getInstances<T>(filterArg);
if (result && result.length > 0) { if (result && result.length > 0) {
return result[0]; return result[0];
@ -152,9 +150,9 @@ export class SmartDataDbDoc<T> {
* 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>> = null) { public saveDeep(savedMapArg: ObjectMap<SmartDataDbDoc<any, any>> = null) {
if (!savedMapArg) { if (!savedMapArg) {
savedMapArg = new Objectmap<SmartDataDbDoc<any>>(); savedMapArg = new ObjectMap<SmartDataDbDoc<any, any>>();
} }
savedMapArg.add(this); savedMapArg.add(this);
this.save(); this.save();
@ -169,12 +167,12 @@ export class SmartDataDbDoc<T> {
/** /**
* creates a saveable object so the instance can be persisted as json in the database * creates a saveable object so the instance can be persisted as json in the database
*/ */
public async createSavableObject() { public async createSavableObject(): Promise<TImplements> {
const saveableObject: any = {}; // is not exposed to outside, so any is ok here const saveableObject: unknown = {}; // is not exposed to outside, so any is ok here
for (const propertyNameString of this.saveableProperties) { for (const propertyNameString of this.saveableProperties) {
saveableObject[propertyNameString] = this[propertyNameString]; saveableObject[propertyNameString] = this[propertyNameString];
} }
return saveableObject; return saveableObject as TImplements;
} }
/** /**

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);
}; };