16 Commits

Author SHA1 Message Date
5ed1446ced 1.0.12 2023-07-12 19:59:28 +02:00
17be38125f fix(core): update 2023-07-12 19:59:28 +02:00
9e343aab84 1.0.11 2023-07-12 19:40:42 +02:00
a58c2881b9 fix(core): update 2023-07-12 19:40:41 +02:00
61fcd5b992 switch to new org scheme 2023-07-11 01:18:39 +02:00
4fe5198816 switch to new org scheme 2023-07-10 10:17:03 +02:00
a0dc540a7c 1.0.10 2022-03-08 01:49:39 +01:00
b4f780216f fix(core): update 2022-03-08 01:49:38 +01:00
1ae72169b2 1.0.9 2022-03-08 01:42:40 +01:00
e240c71c83 fix(core): update 2022-03-08 01:42:39 +01:00
e382922398 1.0.8 2022-03-07 15:28:32 +01:00
0f2003d0bc fix(core): update 2022-03-07 15:28:32 +01:00
2c1440082e 1.0.7 2022-03-06 11:09:54 +01:00
a7c12795fb fix(core): update 2022-03-06 11:09:53 +01:00
1ccc67215c 1.0.6 2021-03-22 02:33:23 +00:00
6c9b19cb9f fix(core): update 2021-03-22 02:33:23 +00:00
24 changed files with 5347 additions and 11812 deletions

View File

@@ -0,0 +1,66 @@
name: Default (not tags)
on:
push:
tags-ignore:
- '**'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
- name: Run npm prepare
run: npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build

View File

@@ -0,0 +1,124 @@
name: Default (tags)
on:
push:
tags:
- '*'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build
release:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Release
run: |
npmci node install stable
npmci npm publish
metadata:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Code quality
run: |
npmci command npm install -g typescript
npmci npm install
- name: Trigger
run: npmci trigger
- name: Build docs and upload artifacts
run: |
npmci node install stable
npmci npm install
pnpm install -g @gitzone/tsdoc
npmci command tsdoc
continue-on-error: true

View File

@@ -19,23 +19,35 @@ mirror:
stage: security stage: security
script: script:
- npmci git mirror - npmci git mirror
only:
- tags
tags: tags:
- lossless - lossless
- docker - docker
- notpriv - notpriv
audit: auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --production --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=prod --production
tags:
- docker
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci 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 --ignore-scripts - npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org - npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high - npmci command npm audit --audit-level=high --only=dev
tags: tags:
- lossless
- docker - docker
- notpriv allow_failure: true
# ==================== # ====================
# test stage # test stage
@@ -50,9 +62,7 @@ testStable:
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- lossless
- docker - docker
- priv
testBuild: testBuild:
stage: test stage: test
@@ -63,9 +73,7 @@ testBuild:
- 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
release: release:
stage: release stage: release
@@ -85,6 +93,8 @@ release:
codequality: codequality:
stage: metadata stage: metadata
allow_failure: true allow_failure: true
only:
- tags
script: script:
- npmci command npm install -g tslint typescript - npmci command npm install -g tslint typescript
- npmci npm prepare - npmci npm prepare

24
.vscode/launch.json vendored
View File

@@ -2,28 +2,10 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "current file", "command": "npm test",
"type": "node", "name": "Run npm test",
"request": "launch", "request": "launch",
"args": [ "type": "node-terminal"
"${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"
} }
] ]
} }

View File

@@ -15,7 +15,7 @@
"properties": { "properties": {
"projectType": { "projectType": {
"type": "string", "type": "string",
"enum": ["website", "element", "service", "npm"] "enum": ["website", "element", "service", "npm", "wcc"]
} }
} }
} }

View File

@@ -3,10 +3,10 @@
"projectType": "npm", "projectType": "npm",
"module": { "module": {
"githost": "gitlab.com", "githost": "gitlab.com",
"gitscope": "pushrocks", "gitscope": "push.rocks",
"gitrepo": "smartobject", "gitrepo": "smartobject",
"shortDescription": "work with objects", "description": "work with objects",
"npmPackagename": "@pushrocks/smartobject", "npmPackagename": "@push.rocks/smartobject",
"license": "MIT", "license": "MIT",
"projectDomain": "push.rocks" "projectDomain": "push.rocks"
} }

11652
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartobject", "name": "@push.rocks/smartobject",
"version": "1.0.5", "version": "1.0.12",
"private": false, "private": false,
"description": "work with objects", "description": "work with objects",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@@ -10,18 +10,19 @@
"scripts": { "scripts": {
"test": "(tstest test/)", "test": "(tstest test/)",
"build": "(tsbuild --web)", "build": "(tsbuild --web)",
"format": "(gitzone format)" "format": "(gitzone format)",
"buildDocs": "tsdoc"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.25", "@gitzone/tsbuild": "^2.1.66",
"@gitzone/tstest": "^1.0.52", "@gitzone/tsrun": "^1.2.42",
"@pushrocks/tapbundle": "^3.2.14", "@gitzone/tstest": "^1.0.74",
"@types/node": "^14.14.35", "@push.rocks/tapbundle": "^5.0.8",
"tslint": "^6.1.3", "@types/node": "^20.4.1"
"tslint-config-prettier": "^1.15.0"
}, },
"dependencies": { "dependencies": {
"fast-deep-equal": "^3.1.3" "fast-deep-equal": "^3.1.3",
"minimatch": "^9.0.3"
}, },
"browserslist": [ "browserslist": [
"last 1 chrome versions" "last 1 chrome versions"
@@ -37,5 +38,6 @@
"cli.js", "cli.js",
"npmextra.json", "npmextra.json",
"readme.md" "readme.md"
] ],
"type": "module"
} }

4727
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +1,26 @@
# @pushrocks/smartobject # @push.rocks/smartobject
work with objects work with objects
## Availabililty and Links ## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartobject) * [npmjs.org (npm package)](https://www.npmjs.com/package/@push.rocks/smartobject)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartobject) * [gitlab.com (source)](https://gitlab.com/push.rocks/smartobject)
* [github.com (source mirror)](https://github.com/pushrocks/smartobject) * [github.com (source mirror)](https://github.com/push.rocks/smartobject)
* [docs (typedoc)](https://pushrocks.gitlab.io/smartobject/) * [docs (typedoc)](https://push.rocks.gitlab.io/smartobject/)
## Status for master ## Status for master
Status Category | Status Badge Status Category | Status Badge
-- | -- -- | --
GitLab Pipelines | [![pipeline status](https://gitlab.com/pushrocks/smartobject/badges/master/pipeline.svg)](https://lossless.cloud) GitLab Pipelines | [![pipeline status](https://gitlab.com/push.rocks/smartobject/badges/master/pipeline.svg)](https://lossless.cloud)
GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/pushrocks/smartobject/badges/master/coverage.svg)](https://lossless.cloud) GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/push.rocks/smartobject/badges/master/coverage.svg)](https://lossless.cloud)
npm | [![npm downloads per month](https://badgen.net/npm/dy/@pushrocks/smartobject)](https://lossless.cloud) npm | [![npm downloads per month](https://badgen.net/npm/dy/@push.rocks/smartobject)](https://lossless.cloud)
Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/pushrocks/smartobject)](https://lossless.cloud) Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/push.rocks/smartobject)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud) TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/) node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud) Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@pushrocks/smartobject)](https://lossless.cloud) PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@push.rocks/smartobject)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@pushrocks/smartobject)](https://lossless.cloud) PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@push.rocks/smartobject)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@pushrocks/smartobject)](https://lossless.cloud) BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@push.rocks/smartobject)](https://lossless.cloud)
Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20Windows%2010/yes/green?icon=windows)](https://lossless.cloud) [![Supports Mac OS X](https://badgen.net/badge/supports%20Mac%20OS%20X/yes/green?icon=apple)](https://lossless.cloud)
## Usage ## Usage
@@ -33,7 +32,6 @@ We are always happy for code contributions. If you are not the code contributing
For further information read the linked docs at the top of this readme. For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) ## Legal
> MIT licensed | **©** [Task Venture Capital GmbH](https://task.vc)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy) | 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

@@ -1,5 +1,5 @@
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@push.rocks/tapbundle';
import * as smartobject from '../ts/index'; import * as smartobject from '../ts/index.js';
tap.test('first test', async () => { tap.test('first test', async () => {
const result = smartobject.compareObjects( const result = smartobject.compareObjects(
@@ -10,8 +10,60 @@ tap.test('first test', async () => {
}); });
tap.test('should fast deep equal objects', async () => { tap.test('should fast deep equal objects', async () => {
expect(smartobject.fastDeepEqual({hello: 'yes'}, {hello: 'yes'})).to.be.true; expect(smartobject.fastDeepEqual({ hello: 'yes' }, { hello: 'yes' })).toBeTrue();
expect(smartobject.fastDeepEqual({hello: 'yes'}, {hello: 3})).to.be.false; expect(smartobject.fastDeepEqual({ hello: 'yes' }, { hello: 3 })).toBeFalse();
});
let parentObject: any = {};
let childObject: any = {};
tap.test('childObject should not yet be in parentObject', async () => {
expect(smartobject.exists(parentObject, 'childObject')).toBeFalse();
parentObject.childObject = childObject;
});
tap.test('childObject should now be in parentObject', async () => {
expect(smartobject.exists(parentObject, 'childObject')).toBeTrue();
});
tap.test('should be able to deepAdd an childParam', async () => {
const parentObject = {
hello: 'there',
};
const parentObject2 = smartobject.smartAdd(parentObject, 'wow.za', 'yes');
console.log(parentObject2);
expect(smartobject.exists(parentObject2.wow, 'za')).toBeTrue();
});
tap.test('should be able to deep get an item', async () => {
const testObject = {
hey: {
there: {
so: 'cool',
},
},
};
const item = smartobject.smartGet(testObject, 'hey.there.so');
expect(item).toEqual('cool');
});
tap.test('should call properties for minimatched properties', async () => {
let testObject = {
matchedOne: 'Hey!',
matchedTwo: 'this works!',
notmatched: 'NOT!',
};
const matchedStrings: string[] = [];
await smartobject.forEachMinimatch(testObject, 'matched*', (matchedProperty) => {
matchedStrings.push(matchedProperty);
console.log(matchedProperty);
});
expect(matchedStrings).toContain('Hey!');
expect(matchedStrings).toContain('this works!');
expect(matchedStrings).not.toContain('NOT!');
}); });
tap.start(); tap.start();

24
test/test.smartobject.ts Normal file
View File

@@ -0,0 +1,24 @@
import { expect, expectAsync, tap } from '@push.rocks/tapbundle';
import * as smartobject from '../ts/index.js';
let testSmartobject: smartobject.SmartObject;
tap.test('should create a smartobject', async () => {
const originalObject = {
test: 'hey',
deep: {
yeah: 'so deep',
evendeeper: {
sodeep: 2,
deepArray: ['one array', 'two array'],
},
},
};
testSmartobject = new smartobject.SmartObject(originalObject);
testSmartobject.addValueAtFlatPathString('deep.nice', 'yeah that has been added');
console.log(testSmartobject.originalObject);
console.log(testSmartobject.toFlatObject());
expect(testSmartobject.getValueAtFlatPathString('deep.yeah')).toEqual('so deep');
});
tap.start();

8
ts/00_commitinfo_data.ts Normal file
View File

@@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartobject',
version: '1.0.12',
description: 'work with objects'
}

View File

@@ -1,76 +1,6 @@
import * as plugins from './smartobject.plugins'; import * as plugins from './smartobject.plugins.js';
const fastDeepEqual = plugins.fastDeepEqual; const fastDeepEqual = plugins.fastDeepEqual;
export { export { fastDeepEqual };
fastDeepEqual
};
export interface IObjectCompareResult { export * from './smartobject.classes.smartobject.js';
presentInBothProperties: string[]; export * from './tools/index.js';
missingProperties: string[];
additionalProperties: string[];
nulledProperties: string[];
undefinedProperties: string[];
divergingProperties: string[];
equalProperties: string[];
}
export const compareObjects = (referenceObjectArg: any, comparisonObjectArg: any): IObjectCompareResult => {
const returnComparisonObject = {
missingProperties: [],
additionalProperties: [],
presentInBothProperties: [],
nulledProperties: [],
undefinedProperties: [],
divergingProperties: [],
equalProperties: [],
};
const allProperties = Object.keys(referenceObjectArg).concat(Object.keys(comparisonObjectArg));
for (const currentProperty of allProperties) {
// lets find presentInBothProperties
if (referenceObjectArg[currentProperty] && comparisonObjectArg[currentProperty]) {
returnComparisonObject.presentInBothProperties.push(currentProperty);
}
// lets find missingProperties
if (referenceObjectArg[currentProperty] && !comparisonObjectArg[currentProperty]) {
returnComparisonObject.missingProperties.push(currentProperty);
}
// lets find additionalProperties
if (!referenceObjectArg[currentProperty] && comparisonObjectArg[currentProperty]) {
returnComparisonObject.additionalProperties.push(currentProperty);
}
// lets find nulledProperties
if (comparisonObjectArg[currentProperty] === null) {
returnComparisonObject.nulledProperties.push(currentProperty);
}
// lets find undefinedProperties
if (comparisonObjectArg[currentProperty] === undefined) {
returnComparisonObject.undefinedProperties.push(currentProperty);
}
// lets find divergingProperties
if (JSON.stringify(referenceObjectArg[currentProperty]) !== JSON.stringify(comparisonObjectArg[currentProperty])) {
returnComparisonObject.divergingProperties.push(currentProperty);
}
// lets find equalProperties
if (JSON.stringify(referenceObjectArg[currentProperty]) === JSON.stringify(comparisonObjectArg[currentProperty])) {
returnComparisonObject.equalProperties.push(currentProperty);
}
}
for (const currentProperty of Object.keys(returnComparisonObject)) {
const onlyUnique = (value, index, self) => {
return self.indexOf(value) === index;
};
const uniqueArray = returnComparisonObject[currentProperty].filter(onlyUnique);
returnComparisonObject[currentProperty] = uniqueArray;
}
return returnComparisonObject;
};

View File

@@ -0,0 +1,24 @@
import * as tools from './tools/index.js';
/**
* a smartobject that simplifies accessing objects
*/
export class SmartObject {
// instance
public originalObject: object;
constructor(originalObjectArg: object) {
this.originalObject = originalObjectArg;
}
public getValueAtFlatPathString(pathArg: string) {
return tools.smartGet(this.originalObject, pathArg);
}
public addValueAtFlatPathString(pathArg: string, valueArg: any) {
return tools.smartAdd(this.originalObject, pathArg, valueArg);
}
public toFlatObject() {
return tools.toFlatObject(this.originalObject);
}
}

View File

@@ -1,6 +1,6 @@
// thirdparty scope
// tslint:disable-next-line: no-submodule-imports // tslint:disable-next-line: no-submodule-imports
import fastDeepEqual from 'fast-deep-equal/es6'; import fastDeepEqual from 'fast-deep-equal/es6/index.js';
import * as minimatch from 'minimatch';
export { export { fastDeepEqual, minimatch };
fastDeepEqual
};

View File

@@ -0,0 +1,85 @@
import * as plugins from '../smartobject.plugins.js';
export interface IObjectCompareResult {
presentInBothProperties: string[];
missingProperties: string[];
additionalProperties: string[];
nulledProperties: string[];
undefinedProperties: string[];
divergingProperties: string[];
equalProperties: string[];
}
export const compareObjects = (
referenceObjectArg: any,
comparisonObjectArg: any
): IObjectCompareResult => {
const returnComparisonObject = {
missingProperties: [] as string[],
additionalProperties: [] as string[],
presentInBothProperties: [] as string[],
nulledProperties: [] as string[],
undefinedProperties: [] as string[],
divergingProperties: [] as string[],
equalProperties: [] as string[],
};
const allProperties = Object.keys(referenceObjectArg).concat(Object.keys(comparisonObjectArg));
for (const currentProperty of allProperties) {
// lets find presentInBothProperties
if (referenceObjectArg[currentProperty] && comparisonObjectArg[currentProperty]) {
returnComparisonObject.presentInBothProperties.push(currentProperty);
}
// lets find missingProperties
if (referenceObjectArg[currentProperty] && !comparisonObjectArg[currentProperty]) {
returnComparisonObject.missingProperties.push(currentProperty);
}
// lets find additionalProperties
if (!referenceObjectArg[currentProperty] && comparisonObjectArg[currentProperty]) {
returnComparisonObject.additionalProperties.push(currentProperty);
}
// lets find nulledProperties
if (comparisonObjectArg[currentProperty] === null) {
returnComparisonObject.nulledProperties.push(currentProperty);
}
// lets find undefinedProperties
if (comparisonObjectArg[currentProperty] === undefined) {
returnComparisonObject.undefinedProperties.push(currentProperty);
}
// lets find divergingProperties
if (
JSON.stringify(referenceObjectArg[currentProperty]) !==
JSON.stringify(comparisonObjectArg[currentProperty])
) {
returnComparisonObject.divergingProperties.push(currentProperty);
}
// lets find equalProperties
if (
plugins.fastDeepEqual(
referenceObjectArg[currentProperty],
comparisonObjectArg[currentProperty]
)
) {
returnComparisonObject.equalProperties.push(currentProperty);
}
}
for (const currentProperty of Object.keys(returnComparisonObject)) {
const onlyUnique = (value: any, index: number, self: Array<any>) => {
return self.indexOf(value) === index;
};
const uniqueArray =
returnComparisonObject[currentProperty as keyof typeof returnComparisonObject].filter(
onlyUnique
);
returnComparisonObject[currentProperty as keyof typeof returnComparisonObject] = uniqueArray;
}
return returnComparisonObject;
};

14
ts/tools/exists.ts Normal file
View File

@@ -0,0 +1,14 @@
import * as plugins from '../smartobject.plugins.js';
/**
* checks if an object has a parameter with a given key name, returns true if yes.
* @param parentObject
* @param childParam
* @returns {boolean}
*/
export let exists = (parentObject: object, childParam: string): boolean => {
if (parentObject.hasOwnProperty(childParam)) {
return true;
}
return false;
};

View File

@@ -0,0 +1,21 @@
import * as plugins from '../smartobject.plugins.js';
/**
* runs a function for all properties of an object whose key matches a regex expression
* @param parentObjectArg the parent object
* @param wildcardArg the rege expression to match the property keys against
* @param callbackArg the function to run with those properties
*/
export let forEachMinimatch = async (
parentObjectArg: any,
wildcardArg: string,
callbackArg: (matchedArg: string) => void
) => {
let propertyNames = Object.getOwnPropertyNames(parentObjectArg);
let propertyNamesMatched = propertyNames.filter((propertyNameArg) => {
return plugins.minimatch.minimatch(propertyNameArg, wildcardArg);
});
for (let propertyNameArg of propertyNamesMatched) {
await callbackArg(parentObjectArg[propertyNameArg]);
}
};

5
ts/tools/index.ts Normal file
View File

@@ -0,0 +1,5 @@
export * from './compareobjects.js';
export * from './exists.js';
export * from './foreachminimatch.js';
export * from './smart_add_get.js';
export * from './toFlatObject.js';

92
ts/tools/smart_add_get.ts Normal file
View File

@@ -0,0 +1,92 @@
import * as plugins from '../smartobject.plugins.js';
/**
* adds an object to the parent object if it doesn't exists
* @param parentObject
* @param childParam
* @param logBool
* @returns {boolean}
*/
export const smartAdd = (
parentObject: object,
childParam: string,
valueArg: any = {},
optionsArg?: {
interpretDotsAsLevel: boolean;
}
): typeof parentObject & any => {
optionsArg = {
interpretDotsAsLevel: true,
...optionsArg,
};
let paramLevels: string[];
let referencePointer: any = parentObject;
if (optionsArg.interpretDotsAsLevel) {
paramLevels = childParam.split('.');
} else {
paramLevels = [childParam];
}
for (let i = 0; i !== paramLevels.length; i++) {
const varName: string = paramLevels[i];
// is there a next variable ?
const varNameNext: string = (() => {
if (paramLevels[i + 1]) {
return paramLevels[i + 1];
}
return null;
})();
// build the tree in parentObject
if (!referencePointer[varName] && !varNameNext) {
referencePointer[varName] = valueArg;
referencePointer = null;
} else if (!referencePointer[varName] && varNameNext) {
referencePointer[varName] = {};
referencePointer = referencePointer[varName];
} else if (referencePointer[varName] && varNameNext) {
referencePointer = referencePointer[varName];
} else {
throw new Error('Something is strange!');
}
}
return parentObject;
};
/**
* gets an object from the parent object using dots as levels by default
* @param parentObject
* @param childParam
* @param optionsArg
*/
export const smartGet = <T>(
parentObject: object,
childParam: string,
optionsArg?: {
interpretDotsAsLevel: boolean;
}
): T => {
optionsArg = {
interpretDotsAsLevel: true,
...optionsArg,
};
let paramLevels: string[];
if (optionsArg.interpretDotsAsLevel) {
paramLevels = childParam.split('.');
} else {
paramLevels = [childParam];
}
let referencePointer: any = parentObject;
for (const level of paramLevels) {
if (referencePointer[level as any]) {
referencePointer = referencePointer[level as any];
} else {
return null;
}
}
return referencePointer as T;
};

29
ts/tools/toFlatObject.ts Normal file
View File

@@ -0,0 +1,29 @@
export const toFlatObject = (objectArg: object) => {
const returnObject: { [key: string]: any } = {};
const extractLayer = (
subObject: { [key: string]: any },
pathArg: string,
loopProtection: object[]
) => {
if (loopProtection.indexOf(subObject) > -1) {
return;
}
if (subObject)
for (const key of Object.keys(subObject)) {
let localPathArg = pathArg;
if (typeof subObject[key] === 'object' && !(subObject[key] instanceof Array)) {
const newLoopbackArray = loopProtection.slice();
newLoopbackArray.push(subObject);
extractLayer(
subObject[key],
localPathArg ? (localPathArg += `.${key}`) : key,
newLoopbackArray
);
} else {
returnObject[localPathArg ? (localPathArg += `.${key}`) : key] = subObject[key];
}
}
};
extractLayer(objectArg, '', []);
return returnObject;
};

11
tsconfig.json Normal file
View File

@@ -0,0 +1,11 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"verbatimModuleSyntax": true,
}
}

View File

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