@jsonui/core 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +51 -0
- package/.prettierrc +6 -0
- package/LICENSE +21 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.module.mjs +2 -0
- package/dist/index.module.mjs.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/stock/Stock.d.ts +27 -0
- package/dist/stock/appRootFunctions.d.ts +7 -0
- package/dist/stock/functions.d.ts +7 -0
- package/dist/stock/validation.d.ts +7 -0
- package/dist/store/persistConfig.d.ts +8 -0
- package/dist/store/reducers.d.ts +4 -0
- package/dist/store/renderers/actions.d.ts +10 -0
- package/dist/store/renderers/reducer.d.ts +2 -0
- package/dist/store/renderers/selectors.d.ts +5 -0
- package/dist/store/root/actions.d.ts +10 -0
- package/dist/store/root/reducer.d.ts +4 -0
- package/dist/store/root/selectors.d.ts +11 -0
- package/dist/util/I18n.d.ts +27 -0
- package/dist/util/constants.d.ts +19 -0
- package/dist/util/contextHandler.d.ts +3 -0
- package/dist/util/jsonRefResolver.d.ts +2 -0
- package/dist/util/types.d.ts +27 -0
- package/dist/util/util.d.ts +22 -0
- package/dist/utils/I18n.d.ts +27 -0
- package/dist/utils/constants.d.ts +19 -0
- package/dist/utils/contextHandler.d.ts +4 -0
- package/dist/utils/jsonRefResolver.d.ts +2 -0
- package/dist/utils/types.d.ts +27 -0
- package/dist/utils/util.d.ts +22 -0
- package/dist/wrapper/wrapperUtil.d.ts +15 -0
- package/package.json +46 -0
- package/src/index.ts +30 -0
- package/src/stock/Stock.ts +75 -0
- package/src/stock/appRootFunctions.ts +15 -0
- package/src/stock/functions.ts +25 -0
- package/src/stock/validation.ts +30 -0
- package/src/store/persistConfig.ts +20 -0
- package/src/store/reducers.ts +6 -0
- package/src/store/root/actions.ts +12 -0
- package/src/store/root/reducer.ts +71 -0
- package/src/store/root/selectors.ts +61 -0
- package/src/typings/key-value-replace.d.ts +8 -0
- package/src/utils/I18n.ts +99 -0
- package/src/utils/constants.ts +21 -0
- package/src/utils/contextHandler.ts +5 -0
- package/src/utils/jsonRefResolver.ts +88 -0
- package/src/utils/types.ts +35 -0
- package/src/utils/util.ts +142 -0
- package/src/wrapper/wrapperUtil.tsx +139 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import jsonpointer from 'jsonpointer'
|
|
2
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
3
|
+
import drop from 'lodash/drop'
|
|
4
|
+
import findIndex from 'lodash/findIndex'
|
|
5
|
+
import pull from 'lodash/pull'
|
|
6
|
+
import compact from 'lodash/compact'
|
|
7
|
+
import findLastIndex from 'lodash/findLastIndex'
|
|
8
|
+
import unset from 'lodash/unset'
|
|
9
|
+
import * as c from './constants'
|
|
10
|
+
import { PropsType } from './types'
|
|
11
|
+
|
|
12
|
+
export const jsonPointerGet = (json: any, path?: string) => {
|
|
13
|
+
if (json === null || json === undefined || path === null || path === undefined || typeof path !== 'string') return null
|
|
14
|
+
if (path === c.SEPARATOR /* || path === '' same effect */) return json
|
|
15
|
+
try {
|
|
16
|
+
return jsonpointer.get(json, path.startsWith(c.SEPARATOR) ? path : `${c.SEPARATOR}${path}`)
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const jsonPointerSet = (json: any, path?: string, value?: any) => {
|
|
23
|
+
if (json === null || json === undefined || path === null || path === undefined || typeof path !== 'string') return
|
|
24
|
+
if (path === c.SEPARATOR || path === '') {
|
|
25
|
+
// eslint-disable-next-line no-param-reassign
|
|
26
|
+
json = value
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
jsonpointer.set(json, path.startsWith(c.SEPARATOR) ? path : `${c.SEPARATOR}${path}`, value)
|
|
31
|
+
// eslint-disable-next-line no-empty
|
|
32
|
+
} catch (e) {}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const getCleanedTopic = (text: string | any) => {
|
|
36
|
+
if (!text || typeof text !== 'string' || text.length === 0 || text.length > 1024) {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
return text.replace(/[^0-9a-zA-Z]/g, '-')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const pathArrayToPathString = (array: string[]) => array.map((i, index) => (Number.isInteger(i) ? `[${i}]` : `${index > 0 ? '.' : ''}${i}`)).join('')
|
|
43
|
+
|
|
44
|
+
export const pathArrayToJsonPointer = (array: string[]) => `/${array.join('/')}`
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Simple object check.
|
|
48
|
+
* @param item
|
|
49
|
+
* @returns {boolean}
|
|
50
|
+
*/
|
|
51
|
+
export function isObject(item: any) {
|
|
52
|
+
return item && typeof item === 'object' && !Array.isArray(item)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Deep merge two objects.
|
|
57
|
+
* @param target
|
|
58
|
+
* @param ...sources
|
|
59
|
+
*/
|
|
60
|
+
export function mergeDeep(target: any, ...sources: any): any {
|
|
61
|
+
if (!sources.length) return target
|
|
62
|
+
const source = sources.shift()
|
|
63
|
+
|
|
64
|
+
if (isObject(target) && isObject(source)) {
|
|
65
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
66
|
+
for (const key in source) {
|
|
67
|
+
if (isObject(source[key])) {
|
|
68
|
+
if (!target[key]) Object.assign(target, { [key]: {} })
|
|
69
|
+
mergeDeep(target[key], source[key])
|
|
70
|
+
} else {
|
|
71
|
+
Object.assign(target, { [key]: source[key] })
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return mergeDeep(target, ...sources)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const mergePath = (target: any, newState: any) => {
|
|
80
|
+
if (!newState || typeof newState !== 'object') return target
|
|
81
|
+
const newTarget = cloneDeep(target)
|
|
82
|
+
Object.entries(newState).forEach(([key, value]) => {
|
|
83
|
+
jsonpointer.set(newTarget, key, value)
|
|
84
|
+
})
|
|
85
|
+
return newTarget
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
89
|
+
export const changeRelativePath = (path: string) => {
|
|
90
|
+
let pathArray = path.split(c.SEPARATOR)
|
|
91
|
+
if (pathArray && pathArray.length > 1 && pathArray[pathArray.length - 1] === '') {
|
|
92
|
+
pathArray.pop()
|
|
93
|
+
}
|
|
94
|
+
const absolutepathIndex = findLastIndex(pathArray, (i) => i === '')
|
|
95
|
+
if (absolutepathIndex > 0) {
|
|
96
|
+
pathArray = drop(pathArray, absolutepathIndex)
|
|
97
|
+
}
|
|
98
|
+
pathArray = pull(pathArray, '.')
|
|
99
|
+
let count = 0
|
|
100
|
+
let relativepathIndex = -1
|
|
101
|
+
do {
|
|
102
|
+
count += 1
|
|
103
|
+
relativepathIndex = findIndex(pathArray, (i) => i === '..')
|
|
104
|
+
if (relativepathIndex !== -1) {
|
|
105
|
+
unset(pathArray, `[${relativepathIndex}]`)
|
|
106
|
+
unset(pathArray, `[${relativepathIndex - 1}]`)
|
|
107
|
+
pathArray = compact(pathArray)
|
|
108
|
+
}
|
|
109
|
+
} while (relativepathIndex !== -1 && count < 100)
|
|
110
|
+
return pathArray.join(c.SEPARATOR)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// changeRelativePath('111/22222/3333/./anything/../../start')
|
|
114
|
+
|
|
115
|
+
const genStyle = (props: PropsType) => {
|
|
116
|
+
const { parentComp } = props
|
|
117
|
+
const style = { display: 'flex', flexDirection: 'column', ...(props.style as any), ...(props[c.STYLE_WEB_NAME] as any) }
|
|
118
|
+
|
|
119
|
+
if (style && style.borderWidth && !style.borderStyle) {
|
|
120
|
+
style.borderStyle = 'solid'
|
|
121
|
+
}
|
|
122
|
+
if (style && style.flex) {
|
|
123
|
+
if (
|
|
124
|
+
parentComp &&
|
|
125
|
+
(parentComp as any).style &&
|
|
126
|
+
(parentComp as any).style.flex &&
|
|
127
|
+
(parentComp as any).style.flex < 1
|
|
128
|
+
// if smaller or larger, noesn't matter
|
|
129
|
+
) {
|
|
130
|
+
style.height = `100%`
|
|
131
|
+
style.width = `100%`
|
|
132
|
+
} else if (!style.height) {
|
|
133
|
+
style.height = `${style.flex * 100}%`
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return style
|
|
137
|
+
}
|
|
138
|
+
export const getStyleForWeb = (props: PropsType = {}, component: string) =>
|
|
139
|
+
component === 'View' ? genStyle(props) : { ...(props.style as any), ...(props[c.STYLE_WEB_NAME] as any) }
|
|
140
|
+
|
|
141
|
+
// TODO it have to be configurable
|
|
142
|
+
export const noChildren = (component: string) => ['Image'].includes(component)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import isEmpty from 'lodash/isEmpty'
|
|
3
|
+
import orderBy from 'lodash/orderBy'
|
|
4
|
+
import omit from 'lodash/omit'
|
|
5
|
+
import isNumber from 'lodash/isNumber'
|
|
6
|
+
import traverse from 'traverse'
|
|
7
|
+
import * as c from 'utils/constants'
|
|
8
|
+
import * as util from 'utils/util'
|
|
9
|
+
import Stock from 'stock/Stock'
|
|
10
|
+
import { PathModifiersType, PathModifierType, PathsType, PropsType, WrapperType } from '../utils/types'
|
|
11
|
+
|
|
12
|
+
export const actionBuilder = (props: PropsType, stock: InstanceType<typeof Stock>) => {
|
|
13
|
+
const paths: PathsType = []
|
|
14
|
+
// eslint-disable-next-line func-names
|
|
15
|
+
traverse(omit(props, ['parentComp'])).forEach(function (x) {
|
|
16
|
+
if (
|
|
17
|
+
!!x &&
|
|
18
|
+
!!x[c.ACTION_KEY] &&
|
|
19
|
+
// && !c.REDUX_FUNCTIONS.includes(x[c.ACTION_KEY])
|
|
20
|
+
!(this.path.length > 1 && this.path.includes(c.V_CHILDREN_NAME))
|
|
21
|
+
) {
|
|
22
|
+
paths.push({ path: this.path, level: this.level })
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
orderBy(paths, ['level'], ['desc']).forEach(async (i) => {
|
|
26
|
+
const { [c.ACTION_KEY]: functionName, ...functionParams } = traverse(props).get(i.path)
|
|
27
|
+
traverse(props).set(i.path, async (...callerArgs: any[]) => {
|
|
28
|
+
await stock.callFunction(functionName, functionParams, props, callerArgs)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const modifierBuilder = (props: PropsType, stock: InstanceType<typeof Stock>) => {
|
|
34
|
+
const paths: PathsType = []
|
|
35
|
+
// eslint-disable-next-line func-names
|
|
36
|
+
traverse(omit(props, ['parentComp'])).forEach(function (x) {
|
|
37
|
+
if (!!x && !!x[c.MODIFIER_KEY] && !c.REDUX_FUNCTIONS.includes(x[c.MODIFIER_KEY]) && !(this.path.length > 1 && this.path.includes(c.V_CHILDREN_NAME))) {
|
|
38
|
+
paths.push({ path: this.path, level: this.level })
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
orderBy(paths, ['level'], ['desc']).forEach(async (i) => {
|
|
42
|
+
const { [c.MODIFIER_KEY]: functionName, ...functionParams } = traverse(props).get(i.path)
|
|
43
|
+
traverse(props).set(i.path, stock.callFunction(functionName, functionParams, props))
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const pathModifierBuilder = (props: PropsType, pathModifier: PathModifiersType) => {
|
|
48
|
+
const currentPaths: PathModifiersType = { ...(props.currentPaths as PathModifiersType) }
|
|
49
|
+
let modified = false
|
|
50
|
+
if (pathModifier && !isEmpty(pathModifier)) {
|
|
51
|
+
Object.keys(pathModifier).forEach((key: string) => {
|
|
52
|
+
if (!!key && !!pathModifier[key] && pathModifier[key][c.PATHNAME] !== undefined && pathModifier[key][c.PATHNAME] !== null) {
|
|
53
|
+
const path = pathModifier[key][c.PATHNAME]
|
|
54
|
+
const parent = currentPaths[key]
|
|
55
|
+
modified = true
|
|
56
|
+
if (`${path}`.startsWith(c.SEPARATOR) || !(parent && parent[c.PATHNAME])) {
|
|
57
|
+
currentPaths[key] = { [c.PATHNAME]: path }
|
|
58
|
+
} else {
|
|
59
|
+
currentPaths[key] = { [c.PATHNAME]: util.changeRelativePath(`${parent[c.PATHNAME]}${c.SEPARATOR}${path}`) }
|
|
60
|
+
}
|
|
61
|
+
if (!!currentPaths[key] && !`${currentPaths[key][c.PATHNAME]}`.startsWith(c.SEPARATOR)) {
|
|
62
|
+
currentPaths[key][c.PATHNAME] = `${c.SEPARATOR}${currentPaths[key][c.PATHNAME]}`
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
return modified ? { currentPaths } : undefined
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const getWrapperProps = (props: PropsType, parentComp?: any) => {
|
|
71
|
+
const res: PropsType = {
|
|
72
|
+
...(c.SIMPLE_DATA_TYPES.includes(typeof props) ? {} : props),
|
|
73
|
+
parentComp,
|
|
74
|
+
[c.V_COMP_NAME]: c.SIMPLE_DATA_TYPES.includes(typeof props) || props === undefined || props === null ? '_PrimitiveProp' : props[c.V_COMP_NAME],
|
|
75
|
+
[c.V_CHILDREN_NAME]: c.SIMPLE_DATA_TYPES.includes(typeof props) || props === undefined || props === null ? props : props[c.V_CHILDREN_NAME],
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
78
|
+
for (const i in res) if (typeof res[i] === 'undefined') delete res[i]
|
|
79
|
+
return res
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const genChildenFromListItem = (props: PropsType) => {
|
|
83
|
+
let { page = 0, listLength = 0, itemPerPage = c.PAGINATION_ITEM_PER_PAGE } = props
|
|
84
|
+
const { listItem } = props
|
|
85
|
+
const pathModifiers: PathModifiersType = props[c.PATH_MODIFIERS_KEY] as PathModifiersType
|
|
86
|
+
const children: PropsType[] = []
|
|
87
|
+
if (isNumber(page) && isNumber(listLength) && isNumber(itemPerPage) && pathModifiers) {
|
|
88
|
+
page = page >= 0 ? page : 0
|
|
89
|
+
itemPerPage = itemPerPage >= 0 ? itemPerPage : 0
|
|
90
|
+
listLength = listLength >= 0 ? listLength : 0
|
|
91
|
+
const offset = page * itemPerPage <= listLength ? page * itemPerPage : 0
|
|
92
|
+
const itemkey: string = Object.keys(pathModifiers)[0]
|
|
93
|
+
const firstItem: PathModifierType = pathModifiers[itemkey]
|
|
94
|
+
// eslint-disable-next-line no-plusplus
|
|
95
|
+
for (let i = offset; i < listLength && i < offset + itemPerPage; i++) {
|
|
96
|
+
children.push({
|
|
97
|
+
...(listItem as PropsType),
|
|
98
|
+
[c.PATH_MODIFIERS_KEY]: {
|
|
99
|
+
...(pathModifiers as PathModifiersType),
|
|
100
|
+
[Object.keys(pathModifiers)[0]]: {
|
|
101
|
+
...(firstItem as PathModifierType),
|
|
102
|
+
path: i,
|
|
103
|
+
},
|
|
104
|
+
} as PathModifiersType,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return children
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const getRootWrapperProps = (props: PropsType, stock: InstanceType<typeof Stock>) => {
|
|
112
|
+
const newProps = {
|
|
113
|
+
...props,
|
|
114
|
+
// if the children generation move to wrapper, the redux genAllStateProps doesn't wortk properly. why?
|
|
115
|
+
}
|
|
116
|
+
modifierBuilder(newProps, stock)
|
|
117
|
+
actionBuilder(newProps, stock)
|
|
118
|
+
if (newProps.isList) {
|
|
119
|
+
newProps[c.V_CHILDREN_NAME] = genChildenFromListItem(newProps)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return newProps
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const getChildrensForRoot = (props: PropsType, children: any, Wrapper: WrapperType) => {
|
|
126
|
+
// eslint-disable-next-line no-nested-ternary
|
|
127
|
+
const parentComp = omit(props, [c.V_CHILDREN_NAME, 'parentComp'])
|
|
128
|
+
return !!props && Array.isArray(children) ? (
|
|
129
|
+
children.map((childrenItem, index) => {
|
|
130
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
131
|
+
return <Wrapper key={index} {...getWrapperProps(childrenItem, parentComp)} />
|
|
132
|
+
})
|
|
133
|
+
) : (
|
|
134
|
+
<Wrapper {...getWrapperProps(children, parentComp)} />
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const generateChildren = (props: PropsType, { Wrapper }: InstanceType<typeof Stock>) =>
|
|
139
|
+
props[c.V_COMP_NAME] !== '_PrimitiveProp' ? getChildrensForRoot(props, props[c.V_CHILDREN_NAME], Wrapper as WrapperType) : props[c.V_CHILDREN_NAME]
|