@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,75 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { JsonUIFunctions, JsonUIFunctionType } from './appRootFunctions'
|
|
3
|
+
|
|
4
|
+
interface JsonUIComponentsType {
|
|
5
|
+
[key: string]: React.ReactNode
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface NewStockType {
|
|
9
|
+
components: JsonUIComponentsType
|
|
10
|
+
functions: JsonUIFunctions
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type InitType = (prop: NewStockType) => void
|
|
14
|
+
type RegisterFunctionType = (key: string, value: JsonUIFunctionType) => void
|
|
15
|
+
type RegisterComponentType = (key: string, value: React.ReactNode) => void
|
|
16
|
+
type CallFunctionType = (name: string, attr?: any, props?: any, callerArgs?: any) => void
|
|
17
|
+
type GetComponentType = (componentName: string) => React.ReactNode
|
|
18
|
+
|
|
19
|
+
export default class Stock {
|
|
20
|
+
stock: NewStockType
|
|
21
|
+
|
|
22
|
+
Wrapper: React.ReactNode
|
|
23
|
+
|
|
24
|
+
reduxStore: any
|
|
25
|
+
|
|
26
|
+
validations: any
|
|
27
|
+
|
|
28
|
+
constructor(newStock: NewStockType, Wrapper: React.ReactNode, reduxStore: any) {
|
|
29
|
+
this.stock = {
|
|
30
|
+
components: {} as JsonUIComponentsType,
|
|
31
|
+
functions: {} as JsonUIFunctions,
|
|
32
|
+
}
|
|
33
|
+
this.Wrapper = Wrapper
|
|
34
|
+
this.validations = []
|
|
35
|
+
this.reduxStore = reduxStore
|
|
36
|
+
this.init(newStock)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
init: InitType = ({ components, functions }) => {
|
|
40
|
+
this.stock.components = {
|
|
41
|
+
...this.stock.components,
|
|
42
|
+
...components,
|
|
43
|
+
}
|
|
44
|
+
this.stock.functions = {
|
|
45
|
+
...this.stock.functions,
|
|
46
|
+
...functions,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
registerComponent: RegisterComponentType = (key, value) => {
|
|
51
|
+
if (!!key && typeof key === 'string' && key.length > 0 && !(key in this.stock.components)) {
|
|
52
|
+
this.stock.components[key] = value
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
registerFunction: RegisterFunctionType = (key, value) => {
|
|
57
|
+
if (!!key && typeof key === 'string' && key.length > 0 && !(key in this.stock.functions)) {
|
|
58
|
+
this.stock.functions[key] = value
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
callFunction: CallFunctionType = (name, attr, props, callerArgs) => {
|
|
63
|
+
if (!!attr && !!name && name in this.stock.functions) {
|
|
64
|
+
const result = this.stock.functions[name](attr, props, callerArgs, this)
|
|
65
|
+
return result
|
|
66
|
+
}
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
getComponent: GetComponentType = (componentName) =>
|
|
71
|
+
!!componentName && componentName in this.stock.components
|
|
72
|
+
? this.stock.components[componentName]
|
|
73
|
+
: // eslint-disable-next-line no-underscore-dangle
|
|
74
|
+
this.stock.components._Undefined
|
|
75
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { purge } from '../store/root/actions'
|
|
2
|
+
|
|
3
|
+
export type JsonUIFunctionType = (attr: any, props: any, callerArgs: any, stock: any) => Promise<void> | void | any
|
|
4
|
+
|
|
5
|
+
export interface JsonUIFunctions {
|
|
6
|
+
[key: string]: JsonUIFunctionType
|
|
7
|
+
}
|
|
8
|
+
export const deletePersistDataStore: JsonUIFunctionType = async (attr, props, callerArgs, stock) => {
|
|
9
|
+
stock.reduxStore.dispatch(purge(null))
|
|
10
|
+
await stock.callFunction('reloadApp', {})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const appRootFunctions: JsonUIFunctions = { deletePersistDataStore }
|
|
14
|
+
|
|
15
|
+
export default appRootFunctions
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getStateValue as getStateValueSelector } from '../store/root/selectors'
|
|
2
|
+
import { set as setAction } from '../store/root/actions'
|
|
3
|
+
import { JsonUIFunctionType } from './appRootFunctions'
|
|
4
|
+
import { PathModifiersType } from '../utils/types'
|
|
5
|
+
|
|
6
|
+
const getStateValue: JsonUIFunctionType = (attr, { currentPaths } = {}, callerArgs, stock) => {
|
|
7
|
+
const { store, path } = attr
|
|
8
|
+
const state = stock.reduxStore.getState()
|
|
9
|
+
return getStateValueSelector(state, { store, path }, currentPaths as PathModifiersType)
|
|
10
|
+
}
|
|
11
|
+
const get: JsonUIFunctionType = (attr, { currentPaths } = {}, callerArgs, stock) => {
|
|
12
|
+
const { store, path } = attr
|
|
13
|
+
const state = stock.reduxStore.getState()
|
|
14
|
+
return getStateValueSelector(state, { store, path }, currentPaths as PathModifiersType)
|
|
15
|
+
}
|
|
16
|
+
const set: JsonUIFunctionType = (attr, props, callerArgs, stock) => {
|
|
17
|
+
stock.reduxStore.dispatch(
|
|
18
|
+
setAction({ ...attr, value: attr && attr.value !== undefined ? attr.value : callerArgs[0], currentPaths: props.currentPaths, stock })
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
export default {
|
|
22
|
+
getStateValue,
|
|
23
|
+
get,
|
|
24
|
+
set,
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Ajv, { ErrorObject, JSONSchemaType } from 'ajv'
|
|
2
|
+
import jsonpointer from 'jsonpointer'
|
|
3
|
+
import * as c from '../utils/constants'
|
|
4
|
+
|
|
5
|
+
const pathConverter = (path: string) => path.replace(/\./g, c.SEPARATOR)
|
|
6
|
+
|
|
7
|
+
export const errorConverter = (errors: ErrorObject<string, Record<string, any>, unknown>[] | null | undefined) => {
|
|
8
|
+
const res = {}
|
|
9
|
+
if (errors) {
|
|
10
|
+
errors.forEach((i) => {
|
|
11
|
+
if (i.keyword === 'required') {
|
|
12
|
+
jsonpointer.set(res, `${pathConverter(`${i.instancePath}.${i.params.missingProperty}`)}/-`, i.message)
|
|
13
|
+
} else {
|
|
14
|
+
jsonpointer.set(res, `${pathConverter(i.instancePath)}/-`, i.message)
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
return res
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const validateJSON = (schema: any, store: string, data: any) => {
|
|
22
|
+
const ajv = new Ajv({ allErrors: true })
|
|
23
|
+
const validate = ajv.compile(schema as JSONSchemaType<any>)
|
|
24
|
+
const valid = validate(data)
|
|
25
|
+
return {
|
|
26
|
+
store: `${store}${c.STORE_ERROR_POSTFIX}`,
|
|
27
|
+
valid,
|
|
28
|
+
value: valid ? null : errorConverter(validate.errors),
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createTransform } from 'redux-persist'
|
|
2
|
+
import pick from 'lodash/pick'
|
|
3
|
+
import * as c from '../utils/constants'
|
|
4
|
+
|
|
5
|
+
const SetTransform = createTransform(
|
|
6
|
+
(inboundState, key) => {
|
|
7
|
+
if (key !== 'root') return inboundState
|
|
8
|
+
return pick(inboundState, c.PERSIST_STORAGE_NAMES)
|
|
9
|
+
},
|
|
10
|
+
(outboundState, key) => {
|
|
11
|
+
if (key !== 'root') return outboundState
|
|
12
|
+
return pick(outboundState, c.PERSIST_STORAGE_NAMES)
|
|
13
|
+
}
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
key: 'main',
|
|
18
|
+
whitelist: ['root'],
|
|
19
|
+
transforms: [SetTransform],
|
|
20
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import produce from 'immer'
|
|
2
|
+
import { AnyAction } from 'redux'
|
|
3
|
+
import { ValidationType } from '../../utils/types'
|
|
4
|
+
import * as c from '../../utils/constants'
|
|
5
|
+
import * as util from '../../utils/util'
|
|
6
|
+
import { validateJSON } from '../../stock/validation'
|
|
7
|
+
import { DATA_UPDATE, PURGE } from './actions'
|
|
8
|
+
import Stock from '../../stock/Stock'
|
|
9
|
+
|
|
10
|
+
export type RootStateType = any
|
|
11
|
+
|
|
12
|
+
const initialState: RootStateType = {
|
|
13
|
+
data: {},
|
|
14
|
+
}
|
|
15
|
+
const validateNewState = (stock: InstanceType<typeof Stock>, newState: RootStateType, actionStore: string, actionPath: string) => {
|
|
16
|
+
if (stock?.validations) {
|
|
17
|
+
stock.validations.forEach((validateItem: ValidationType) => {
|
|
18
|
+
if (validateItem.store === actionStore && `${actionPath}`.startsWith(validateItem.path)) {
|
|
19
|
+
if (validateItem.schema) {
|
|
20
|
+
const stateToBeValidated = util.jsonPointerGet(newState, `${c.SEPARATOR}${actionStore}${validateItem.path}`)
|
|
21
|
+
const errors = validateJSON(validateItem.schema, actionStore, stateToBeValidated)
|
|
22
|
+
// console.log('matched validator', `${c.SEPARATOR}${errors.store}${validateItem.path}`, errors)
|
|
23
|
+
util.jsonPointerSet(newState, `${c.SEPARATOR}${errors.store}${validateItem.path}`, errors.value)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const reducer = (state = initialState, action: AnyAction) => {
|
|
30
|
+
switch (action.type) {
|
|
31
|
+
case DATA_UPDATE: {
|
|
32
|
+
const { store, path, value, jsonataDef, currentPaths, stock } = action.payload
|
|
33
|
+
if (store && path) {
|
|
34
|
+
const storekey = `${store}`
|
|
35
|
+
const convertedPath =
|
|
36
|
+
currentPaths && currentPaths[storekey] && currentPaths[storekey].path
|
|
37
|
+
? util.changeRelativePath(`${currentPaths[storekey].path}${c.SEPARATOR}${path}`)
|
|
38
|
+
: util.changeRelativePath(path)
|
|
39
|
+
const absolutePathWithStoreKey = `${c.SEPARATOR}${storekey}${convertedPath}`
|
|
40
|
+
const newState = produce(state, (draft: RootStateType) => {
|
|
41
|
+
if (jsonataDef) {
|
|
42
|
+
try {
|
|
43
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
44
|
+
const jsonata = require('jsonata')
|
|
45
|
+
const expression = jsonata(jsonataDef)
|
|
46
|
+
const newValue = expression.evaluate(value)
|
|
47
|
+
util.jsonPointerSet(draft, absolutePathWithStoreKey, newValue)
|
|
48
|
+
} catch (error) {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.error('jsonata error', error, jsonataDef)
|
|
51
|
+
util.jsonPointerSet(draft, absolutePathWithStoreKey, value)
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
util.jsonPointerSet(draft, absolutePathWithStoreKey, value)
|
|
55
|
+
}
|
|
56
|
+
// if validatior has match, need to validate it synchronously
|
|
57
|
+
validateNewState(stock, draft, store, convertedPath)
|
|
58
|
+
})
|
|
59
|
+
return newState
|
|
60
|
+
}
|
|
61
|
+
return state
|
|
62
|
+
}
|
|
63
|
+
case PURGE: {
|
|
64
|
+
return initialState
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
return state
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default reducer
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import traverse from 'traverse'
|
|
2
|
+
import omit from 'lodash/omit'
|
|
3
|
+
import orderBy from 'lodash/orderBy'
|
|
4
|
+
import * as c from '../../utils/constants'
|
|
5
|
+
import * as util from '../../utils/util'
|
|
6
|
+
import { PathModifiersType, PathType, PropsType } from '../../utils/types'
|
|
7
|
+
import { RootStateType } from './reducer'
|
|
8
|
+
|
|
9
|
+
export const getState = (state: any): RootStateType => state.root
|
|
10
|
+
|
|
11
|
+
export const getValue = (state: any, store: string, path: string) => util.jsonPointerGet(state[store], path)
|
|
12
|
+
|
|
13
|
+
export interface ReduxPathType {
|
|
14
|
+
store: string
|
|
15
|
+
path: string
|
|
16
|
+
isError?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const getStateValue = (globalState: any, { store, path, isError = false }: ReduxPathType, currentPaths: PathModifiersType) => {
|
|
20
|
+
const state = getState(globalState)
|
|
21
|
+
|
|
22
|
+
if (store && path) {
|
|
23
|
+
const convertedPath =
|
|
24
|
+
currentPaths && currentPaths[store] && currentPaths[store].path ? util.changeRelativePath(`${currentPaths[store].path}${c.SEPARATOR}${path}`) : path
|
|
25
|
+
|
|
26
|
+
return getValue(state, `${store}${isError ? c.STORE_ERROR_POSTFIX : ''}`, convertedPath)
|
|
27
|
+
}
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const genAllStateProps = (globalState: any, props: PropsType) => {
|
|
32
|
+
const { currentPaths } = props
|
|
33
|
+
const result: PropsType = {}
|
|
34
|
+
const paths: PathType[] = []
|
|
35
|
+
// eslint-disable-next-line func-names
|
|
36
|
+
traverse(omit(props, ['parentComp'])).forEach(function (x) {
|
|
37
|
+
if (!!x && !!x[c.MODIFIER_KEY] && x[c.MODIFIER_KEY] === 'get' && !(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
|
+
if (functionName === 'get' && functionParams.store && functionParams.path) {
|
|
44
|
+
let value = getStateValue(globalState, functionParams, currentPaths as PathModifiersType)
|
|
45
|
+
if (functionParams.jsonataDef) {
|
|
46
|
+
try {
|
|
47
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
48
|
+
const jsonata = require('jsonata')
|
|
49
|
+
const expression = jsonata(functionParams.jsonataDef)
|
|
50
|
+
value = expression.evaluate(value)
|
|
51
|
+
} catch (error) {
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.error('jsonata error', error, functionParams.jsonataDef)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// traverse(result).set(i.path, value)
|
|
57
|
+
result[util.pathArrayToJsonPointer(i.path)] = value
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
return result
|
|
61
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface KeyValues {
|
|
2
|
+
[key: string]: string | number | null | undefined | boolean
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
declare module 'key-value-replace' {
|
|
6
|
+
function functionProps(str: string, obj: KeyValues, delimiter?: [prefix?: string, postfix?: string]): string
|
|
7
|
+
export default functionProps
|
|
8
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import Ajv from 'ajv'
|
|
2
|
+
import keyValueReplace from 'key-value-replace'
|
|
3
|
+
|
|
4
|
+
interface I18nResources {
|
|
5
|
+
[key: string]: {
|
|
6
|
+
translation: {
|
|
7
|
+
[key: string]: string
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface I18nProps {
|
|
13
|
+
language?: string
|
|
14
|
+
resources?: I18nResources
|
|
15
|
+
keyPrefix?: string
|
|
16
|
+
keyPostfix?: string
|
|
17
|
+
nonExistsHandler?: (key: string) => void
|
|
18
|
+
}
|
|
19
|
+
const I18nSchema = {
|
|
20
|
+
$id: 'http://example.com/schemas/schema.json',
|
|
21
|
+
type: 'object',
|
|
22
|
+
additionalProperties: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
translation: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
additionalProperties: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
},
|
|
30
|
+
propertyNames: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
},
|
|
33
|
+
minProperties: 1,
|
|
34
|
+
},
|
|
35
|
+
additionalProperties: false,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
propertyNames: {
|
|
39
|
+
pattern: '^[A-Za-z0-9_-]*$',
|
|
40
|
+
type: 'string',
|
|
41
|
+
},
|
|
42
|
+
minProperties: 1,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default class I18n {
|
|
46
|
+
language: string
|
|
47
|
+
|
|
48
|
+
languages: string[]
|
|
49
|
+
|
|
50
|
+
resources?: I18nResources
|
|
51
|
+
|
|
52
|
+
keyPrefix?: string
|
|
53
|
+
|
|
54
|
+
keyPostfix?: string
|
|
55
|
+
|
|
56
|
+
nonExistsHandler?: (key: string) => void
|
|
57
|
+
|
|
58
|
+
availableLanguageKey?: string
|
|
59
|
+
|
|
60
|
+
// eslint-disable-next-line consistent-this
|
|
61
|
+
constructor({ language = 'en', resources, nonExistsHandler, keyPrefix = '{{', keyPostfix = '}}' }: I18nProps) {
|
|
62
|
+
this.language = language
|
|
63
|
+
this.nonExistsHandler = nonExistsHandler
|
|
64
|
+
this.keyPrefix = keyPrefix
|
|
65
|
+
this.keyPostfix = keyPostfix
|
|
66
|
+
|
|
67
|
+
const ajv = new Ajv()
|
|
68
|
+
const validate = ajv.compile(I18nSchema)
|
|
69
|
+
const isValid = validate(resources)
|
|
70
|
+
if (isValid) {
|
|
71
|
+
this.resources = resources
|
|
72
|
+
}
|
|
73
|
+
this.languages = Object.keys(resources as any)
|
|
74
|
+
if (this.languages && this.languages.includes(this.language)) {
|
|
75
|
+
this.availableLanguageKey = this.language
|
|
76
|
+
} else if (this.languages && this.languages.includes(this.getLocales())) {
|
|
77
|
+
this.availableLanguageKey = this.getLocales()
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getLocales = () => (this.language.includes('-') ? this.language.split('-') : this.language.split('_') || [])[0]
|
|
82
|
+
|
|
83
|
+
t = (key: string, options?: any, language?: string | null) => {
|
|
84
|
+
if (!this.resources || (!this.resources && !this.language && !language) || !this.resources[`${this.availableLanguageKey || language}`]) {
|
|
85
|
+
return key
|
|
86
|
+
}
|
|
87
|
+
const value = this.resources[`${this.availableLanguageKey || language}`].translation[key]
|
|
88
|
+
if (!value) {
|
|
89
|
+
if (this.nonExistsHandler && typeof this.nonExistsHandler === 'function') {
|
|
90
|
+
this.nonExistsHandler(key)
|
|
91
|
+
}
|
|
92
|
+
return key
|
|
93
|
+
}
|
|
94
|
+
if (options) {
|
|
95
|
+
return keyValueReplace(value, options, [this.keyPrefix, this.keyPostfix])
|
|
96
|
+
}
|
|
97
|
+
return value
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const SEPARATOR = '/'
|
|
2
|
+
export const STORE_ERROR_POSTFIX = '.error'
|
|
3
|
+
|
|
4
|
+
export const PATH_MODIFIERS_KEY = '$pathModifiers'
|
|
5
|
+
export const MODIFIER_KEY = '$modifier'
|
|
6
|
+
export const ACTION_KEY = '$action'
|
|
7
|
+
export const PERSIST_STORAGE_KEY = '$persistStores'
|
|
8
|
+
export const PERSIST_STORAGE_NAMES = ['data']
|
|
9
|
+
export const REF_ASSETS = '$assetsRef'
|
|
10
|
+
export const REF_LOCALES = '$locales'
|
|
11
|
+
export const REF_VALIDATES = '$validations'
|
|
12
|
+
export const STYLE_WEB_NAME = 'styleWeb'
|
|
13
|
+
export const STYLE_RN_NAME = 'styleRN'
|
|
14
|
+
export const REDUX_FUNCTIONS = ['set', 'get']
|
|
15
|
+
|
|
16
|
+
export const PATHNAME = 'path'
|
|
17
|
+
export const SIMPLE_DATA_TYPES = ['string', 'number', 'boolean', 'null']
|
|
18
|
+
export const V_CHILDREN_NAME = '$children'
|
|
19
|
+
export const V_COMP_NAME = '$comp'
|
|
20
|
+
export const ITEM_OF_ARRAY = 'item'
|
|
21
|
+
export const PAGINATION_ITEM_PER_PAGE = 1
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import traverse from 'traverse'
|
|
2
|
+
import uniq from 'lodash/uniq'
|
|
3
|
+
import compact from 'lodash/compact'
|
|
4
|
+
import unset from 'lodash/unset'
|
|
5
|
+
import findIndex from 'lodash/findIndex'
|
|
6
|
+
import pull from 'lodash/pull'
|
|
7
|
+
import defaultsDeep from 'lodash/defaultsDeep'
|
|
8
|
+
import * as c from './constants'
|
|
9
|
+
|
|
10
|
+
export const collectJsonKeys = (refConst: string, json: any) => {
|
|
11
|
+
const refs: any[] = []
|
|
12
|
+
// eslint-disable-next-line func-names
|
|
13
|
+
traverse(json).forEach(function (x) {
|
|
14
|
+
if (x && x[refConst] && !!this && !this.circular) {
|
|
15
|
+
refs.push(x[refConst])
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
const res = {}
|
|
19
|
+
uniq(compact(refs)).forEach((i) => defaultsDeep(res, i))
|
|
20
|
+
return res
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const isFullPath = (path?: string) => {
|
|
24
|
+
if (!!path && typeof path === 'string') {
|
|
25
|
+
const regex = /^[A-Za-z]*:\/\//
|
|
26
|
+
return regex.test(path)
|
|
27
|
+
}
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const isRelativePath = (path?: string) => !!path && typeof path === 'string' && !isFullPath(path) && !path.startsWith(c.SEPARATOR) // if not full and not start with /
|
|
32
|
+
|
|
33
|
+
const isRootPath = (path?: string) => !!path && typeof path === 'string' && !isFullPath(path) && path.startsWith(c.SEPARATOR) // if not full and start with /
|
|
34
|
+
|
|
35
|
+
const changeRelativePath = (path: string) => {
|
|
36
|
+
let pathArray = path.split(c.SEPARATOR)
|
|
37
|
+
pathArray = pull(pathArray, '.') // remove all ./
|
|
38
|
+
let count = 0
|
|
39
|
+
let relativepathIndex = -1
|
|
40
|
+
do {
|
|
41
|
+
count += 1
|
|
42
|
+
relativepathIndex = findIndex(pathArray, (i) => i === '..')
|
|
43
|
+
if (relativepathIndex !== -1) {
|
|
44
|
+
unset(pathArray, `[${relativepathIndex}]`)
|
|
45
|
+
unset(pathArray, `[${relativepathIndex - 1}]`)
|
|
46
|
+
pathArray = compact(pathArray)
|
|
47
|
+
}
|
|
48
|
+
} while (relativepathIndex !== -1 && count < 100)
|
|
49
|
+
return pathArray.join(c.SEPARATOR)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// TODO: just workaround, not works with http://localhost for example
|
|
53
|
+
const getRoot = (url3?: string) => {
|
|
54
|
+
if (!!url3 && typeof url3 === 'string') {
|
|
55
|
+
const regex = /^([A-Za-z]*:\/\/[^/]*)(\/|)/
|
|
56
|
+
const found = url3.match(regex)
|
|
57
|
+
if (found) {
|
|
58
|
+
return `${found[1]}/`
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// console.error('test',isFullPath('asdasd://'))
|
|
65
|
+
export const getRefs = (refConst: string, json: any, projectPath = '') => {
|
|
66
|
+
const refs: any[] = []
|
|
67
|
+
// eslint-disable-next-line func-names
|
|
68
|
+
traverse(json).forEach(function (x) {
|
|
69
|
+
if (x && x[refConst] && !!this && !this.circular) {
|
|
70
|
+
const ref = x[refConst]
|
|
71
|
+
let absolutePath
|
|
72
|
+
// TODO: If the projectPath is absolute, will be wrong
|
|
73
|
+
if (isRootPath(ref)) {
|
|
74
|
+
const root = getRoot(projectPath)
|
|
75
|
+
absolutePath = changeRelativePath(`${root}${ref}`)
|
|
76
|
+
} else if (isRelativePath(ref)) {
|
|
77
|
+
absolutePath = changeRelativePath(`${projectPath}${ref}`)
|
|
78
|
+
} else {
|
|
79
|
+
absolutePath = ref
|
|
80
|
+
}
|
|
81
|
+
// eslint-disable-next-line no-param-reassign
|
|
82
|
+
x[refConst] = absolutePath
|
|
83
|
+
refs.push(absolutePath)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
// console.warn(refs);
|
|
87
|
+
return uniq(compact(refs))
|
|
88
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import * as c from 'utils/constants'
|
|
3
|
+
|
|
4
|
+
export type UIDefinition = any
|
|
5
|
+
export type Path = string
|
|
6
|
+
export type ArraysType = any[]
|
|
7
|
+
export type WrapperType = React.ElementType
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line no-use-before-define
|
|
10
|
+
export type PropValue = PropsType | ArraysType | string | null | boolean | number | undefined | PathModifiersType
|
|
11
|
+
|
|
12
|
+
export interface PathModifierType {
|
|
13
|
+
path: string
|
|
14
|
+
}
|
|
15
|
+
export interface PathModifiersType {
|
|
16
|
+
[key: string]: PathModifierType
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PropsType {
|
|
20
|
+
[key: string]: PropValue
|
|
21
|
+
[c.PATH_MODIFIERS_KEY]?: PathModifiersType
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PathType {
|
|
25
|
+
path: string[]
|
|
26
|
+
level: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type PathsType = PathType[]
|
|
30
|
+
|
|
31
|
+
export interface ValidationType {
|
|
32
|
+
store: string
|
|
33
|
+
path: string
|
|
34
|
+
schema: any
|
|
35
|
+
}
|