1
0
mirror of https://github.com/dzeiocom/libs.git synced 2025-04-22 10:52:11 +00:00

Added ObjectUtil

Signed-off-by: Florian Bouillon <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2020-09-11 10:43:07 +02:00
parent 6269f5c27e
commit 7e3fe2f7f1
12 changed files with 312 additions and 2 deletions

View File

@ -24,7 +24,7 @@ jobs:
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- run: yarn - run: yarn
- run: yarn workspaces run build - run: yarn workspaces run build
- run: yarn workspaces run test - run: yarn workspaces run test
# You may pin to the exact commit or the version. # You may pin to the exact commit or the version.
@ -32,4 +32,4 @@ jobs:
- uses: codecov/codecov-action@v1.0.13 - uses: codecov/codecov-action@v1.0.13
with: with:
# Comma-separated list of files to upload # 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

View File

@ -0,0 +1,10 @@
{
"presets": [
["@babel/preset-env", {
"targets": {
"node": "current"
}
}],
"@babel/preset-typescript"
]
}

2
packages/object-util/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/dist/
coverage

View File

@ -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

View File

@ -0,0 +1,92 @@
/// <reference types="jest" />
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)
})
})

View File

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

View File

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

View File

@ -0,0 +1,103 @@
export const objectMap = <T = any, J = any>(items: Record<string, T>, fn: (el: T, key: string) => J) => {
const list: Array<J> = []
objectLoop(items, (item, key) => {
list.push(fn(item, key))
})
return list
}
export const objectLoop = <T = any>(items: Record<string, T>, 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<T = any>(obj: Record<string, T>): Array<T> {
return Object.values(obj)
}
export function objectSize(obj: Record<string, any>) {
return Object.keys(obj).length
}
export function objectSort<T = Record<string, any>>(obj: Record<string, any>, 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<T = Record<string, any>>(obj: T): T {
const clone: T = {} as any
objectLoop(obj, (value, key) => {
if (typeof value === 'object' && value != null) {
clone[key as Extract<keyof T, string>] = cloneObject(value)
return
}
clone[key as Extract<keyof T, string>] = value
})
return clone
}
export function objectSet(obj: Record<string, any>, path: Array<string | number>, 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<string, any>, y: Record<string, any>): 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
}

View File

@ -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

View File

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist"
},
"files": [
"src/ObjectUtil.ts"
]
}

View File

@ -0,0 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"esModuleInterop": true
}
}

View File

@ -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/
}
]
}
}