diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index f1c3b88..c0f2010 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -24,7 +24,7 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- - run: yarn
+ - run: yarn
- run: yarn workspaces run build
- run: yarn workspaces run test
# You may pin to the exact commit or the version.
@@ -32,4 +32,4 @@ jobs:
- uses: codecov/codecov-action@v1.0.13
with:
# Comma-separated list of files to upload
- files: ./packages/url-manager/coverage/coverage-final.json # optional
+ files: ./packages/url-manager/coverage/coverage-final.json,./packages/object-util/coverage/coverage-final.json # optional
diff --git a/packages/object-util/.babelrc b/packages/object-util/.babelrc
new file mode 100644
index 0000000..c4bf74f
--- /dev/null
+++ b/packages/object-util/.babelrc
@@ -0,0 +1,10 @@
+{
+ "presets": [
+ ["@babel/preset-env", {
+ "targets": {
+ "node": "current"
+ }
+ }],
+ "@babel/preset-typescript"
+ ]
+}
diff --git a/packages/object-util/.gitignore b/packages/object-util/.gitignore
new file mode 100644
index 0000000..782d4a6
--- /dev/null
+++ b/packages/object-util/.gitignore
@@ -0,0 +1,2 @@
+/dist/
+coverage
diff --git a/packages/object-util/.npmignore b/packages/object-util/.npmignore
new file mode 100644
index 0000000..b873d06
--- /dev/null
+++ b/packages/object-util/.npmignore
@@ -0,0 +1,13 @@
+node_modules
+src
+test
+.babelrc
+.eslintrc.js
+.gitignore
+.npmignore
+tsconfig.*
+webpack.config.js
+yarn-error.log
+coverage
+__tests__
+jest.config.js
diff --git a/packages/object-util/__tests__/index.test.ts b/packages/object-util/__tests__/index.test.ts
new file mode 100644
index 0000000..ee8ccdf
--- /dev/null
+++ b/packages/object-util/__tests__/index.test.ts
@@ -0,0 +1,92 @@
+///
+
+import { objectSize, objectToArray, objectMap, objectSort, cloneObject, objectEqual } from '../src/ObjectUtil'
+
+
+describe('Basic tests', () => {
+ it('shoud return length of the object', () => {
+ const obj = {
+ index0: true,
+ index1: false,
+ index2: false,
+ index3: false,
+ index4: false,
+ index5: false,
+ index6: false,
+ index7: false,
+ index8: false,
+ index9: false,
+ index10: false
+ }
+ expect(objectSize(obj)).toBe(11)
+ })
+
+ it('should convert the object to an array', () => {
+ const obj = {
+ pouet: 'first',
+ toto: 'second'
+ }
+ expect(objectToArray(obj)).toEqual(['first', 'second'])
+ })
+
+ it('should run through the object', () => {
+ const obj = {
+ pouet: 'first',
+ toto: 'second'
+ }
+ expect(objectMap(obj, (value, index) => {
+ return [index, value]
+ })).toEqual([['pouet', 'first'],['toto','second']])
+ })
+
+ it('should sort the object', () => {
+ const obj = {
+ b: 'first',
+ a: 'second'
+ }
+ expect(objectSort(obj)).toEqual({
+ a: 'second',
+ b: 'first'
+ })
+ })
+
+ it('should clone the object', () => {
+ const obj = {
+ pouet: 'first',
+ toto: 'second'
+ }
+ const clone = cloneObject(obj)
+ expect(clone).toEqual(obj)
+ clone.pouet = 'third'
+ expect(clone).not.toEqual(obj)
+ })
+
+ it('should deeply clone the object', () => {
+ const obj = {
+ pouet: {is: 'first'},
+ toto: 'second'
+ }
+ const clone = cloneObject(obj)
+ expect(clone).toEqual(obj)
+ clone.toto = 'third'
+ expect(clone).not.toEqual(obj)
+ })
+});
+
+describe('Object Equal Test', () => {
+ it('should be equal', () => {
+ expect(objectEqual({pouet: true}, {pouet: true})).toBe(true)
+ })
+ it('should not be equal', () => {
+ expect(objectEqual({pouet: true}, {pouet: false})).toBe(false)
+ })
+ it('should be deeply equal', () => {
+ expect(objectEqual({pouet: {is: true}}, {pouet: {is: true}})).toBe(true)
+ })
+ it('should not be deeply equal', () => {
+ expect(objectEqual({pouet: {is: true}}, {pouet: {is: false}})).toBe(false)
+ })
+ it('should not be differently equal', () => {
+ expect(objectEqual({pouet: true}, {})).toBe(false)
+ })
+})
diff --git a/packages/object-util/jest.config.js b/packages/object-util/jest.config.js
new file mode 100644
index 0000000..3c46609
--- /dev/null
+++ b/packages/object-util/jest.config.js
@@ -0,0 +1,18 @@
+module.exports = {
+ globals: {
+ 'ts-jest': {
+ tsConfig: 'tsconfig.test.json'
+ },
+ "transform": {
+ ".(ts|tsx)": " ../../node_modules/ts-jest/preprocessor.js"
+ },
+ "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
+ "testResultsProcessor": "../../node_modules/ts-jest/coverageprocessor.js",
+ "collectCoverageFrom": ["src/URLManager.ts"],
+ "moduleFileExtensions": [
+ "ts",
+ "tsx",
+ "js"
+ ],
+ },
+}
diff --git a/packages/object-util/package.json b/packages/object-util/package.json
new file mode 100644
index 0000000..a6febbe
--- /dev/null
+++ b/packages/object-util/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "@dzeio/object-util",
+ "version": "0.0.1",
+ "description": "some Function to make work on objects easier",
+ "repository": "https://github.com/dzeiocom/libs.git",
+ "author": "Aviortheking",
+ "license": "MIT",
+ "main": "./dist/URLManager.js",
+ "browser": "./dist/browser.js",
+ "types": "./dist/URLManager.d.ts",
+ "devDependencies": {
+ "@babel/core": "^7.11.4",
+ "@babel/preset-env": "^7.11.0",
+ "@babel/preset-typescript": "^7.10.4",
+ "@types/chai": "^4.2.12",
+ "@types/jest": "^26.0.10",
+ "babel-loader": "^8.1.0",
+ "codecov": "^3.7.2",
+ "jest": "^26.4.2",
+ "ts-loader": "^8.0.3",
+ "ts-node": "^9.0.0",
+ "typescript": "^4.0.2",
+ "webpack": "^4.44.1",
+ "webpack-cli": "^3.3.12"
+ },
+ "scripts": {
+ "prepublishOnly": "yarn build",
+ "build": "webpack --mode=\"production\" && tsc",
+ "test": "jest --coverage"
+ }
+}
diff --git a/packages/object-util/src/ObjectUtil.ts b/packages/object-util/src/ObjectUtil.ts
new file mode 100644
index 0000000..d4f496d
--- /dev/null
+++ b/packages/object-util/src/ObjectUtil.ts
@@ -0,0 +1,103 @@
+export const objectMap = (items: Record, fn: (el: T, key: string) => J) => {
+ const list: Array = []
+ objectLoop(items, (item, key) => {
+ list.push(fn(item, key))
+ })
+ return list
+}
+
+export const objectLoop = (items: Record, fn: (el: T, key: string) => void | boolean) => {
+ let res: void | boolean
+ for (const key in items) {
+ if (!Object.prototype.hasOwnProperty.call(items, key)) {
+ continue
+ }
+ res = fn(items[key], key)
+ if (typeof res === 'boolean' && !res) {
+ return res
+ }
+ }
+ return res
+}
+
+export function objectToArray(obj: Record): Array {
+ return Object.values(obj)
+}
+
+export function objectSize(obj: Record) {
+ return Object.keys(obj).length
+}
+
+export function objectSort>(obj: Record, fn?: (a: string, b: string) => number): T {
+ const ordered: any = {};
+ for (const key of Object.keys(obj).sort(fn)) {
+ ordered[key] = obj[key]
+ }
+ return ordered
+}
+
+export function cloneObject>(obj: T): T {
+ const clone: T = {} as any
+ objectLoop(obj, (value, key) => {
+ if (typeof value === 'object' && value != null) {
+ clone[key as Extract] = cloneObject(value)
+ return
+ }
+ clone[key as Extract] = value
+ })
+ return clone
+}
+
+export function objectSet(obj: Record, path: Array, value: any) {
+ let pointer = obj
+ for (let index = 0; index < path.length; index++) {
+ const key = path[index]
+ if ((!Object.prototype.hasOwnProperty.call(pointer, key)) && (index+1) < path.length) {
+ const key1 = path[index + 1]
+ if (typeof key1 === 'number') {
+ pointer[key] = []
+ } else {
+ pointer[key] = {}
+ }
+ }
+
+ // if last index
+ if ((index+1) === path.length) {
+ pointer[key] = value
+ if (value === undefined) {
+ delete pointer[key]
+ }
+ break
+ }
+ // move pointer to new key
+ pointer = pointer[key]
+ }
+}
+
+export function objectEqual(x: Record, y: Record): boolean {
+ const res = objectLoop(x, (item, key) => {
+ if (!(key in y)) {
+ return false
+ }
+ const item2 = y[key]
+ if (typeof item === 'object' && typeof item2 === 'object') {
+ return objectEqual(item, item2)
+ }
+ return item === item2
+ })
+ if (typeof res !== 'boolean') {
+ return true
+ }
+ return res
+}
+
+export default {
+ objectMap,
+ objectLoop,
+ objectToArray,
+ objectSize,
+ objectSort,
+ cloneObject,
+ objectSet,
+ objectEqual
+}
diff --git a/packages/object-util/src/index.ts b/packages/object-util/src/index.ts
new file mode 100644
index 0000000..90342c7
--- /dev/null
+++ b/packages/object-util/src/index.ts
@@ -0,0 +1,9 @@
+import ObjectUtil from './ObjectUtil'
+
+ObjectUtil.objectLoop(ObjectUtil, (fn, key) => {
+ // @ts-expect-error
+ window[key as any] = fn
+})
+
+// @ts-expect-error
+window.ObjectUtil = ObjectUtil
diff --git a/packages/object-util/tsconfig.json b/packages/object-util/tsconfig.json
new file mode 100644
index 0000000..7bc1d43
--- /dev/null
+++ b/packages/object-util/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "dist"
+ },
+ "files": [
+ "src/ObjectUtil.ts"
+ ]
+}
diff --git a/packages/object-util/tsconfig.test.json b/packages/object-util/tsconfig.test.json
new file mode 100644
index 0000000..67ae45c
--- /dev/null
+++ b/packages/object-util/tsconfig.test.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "esModuleInterop": true
+ }
+}
diff --git a/packages/object-util/webpack.config.js b/packages/object-util/webpack.config.js
new file mode 100644
index 0000000..6273b45
--- /dev/null
+++ b/packages/object-util/webpack.config.js
@@ -0,0 +1,17 @@
+module.exports = {
+ entry: './src/index',
+ output: {
+ path: __dirname,
+ filename: './dist/browser.js',
+ },
+ resolve: {
+ extensions: ['.js', '.ts'],
+ },
+ module: {
+ rules: [
+ {
+ test: /\.ts$/, use: ['babel-loader', 'ts-loader'], exclude: /node_modules/
+ }
+ ]
+ }
+}