-
Notifications
You must be signed in to change notification settings - Fork 0
/
gubu-errmsg.ts
107 lines (82 loc) · 2.61 KB
/
gubu-errmsg.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/* Copyright (c) 2024 Richard Rodger and other contributors, MIT License */
import type { PatrunRouter } from 'patrun'
import { Patrun } from 'patrun'
type ErrPat = {
key: string // Key of failing value.
type: string // type of node
value: any // Failing value.
path: string // Key path to value.
why: string // Error code ("why").
check: string // Check function name.
[prop: `${string}_${string}`]: any // custom prop in format base_name
}
type ErrDef = {
text: string
}
type MsgMapVal = { [val: string]: MsgMap }
type MsgMap = { [prop: string]: MsgMapVal | ErrDef }
const ALLOWED_PROPS: any = {
key: 1,
type: 1,
value: 1,
path: 1,
why: 1,
check: 1,
}
function GubuErrMsg(msgmap: MsgMap) {
const self = {
_router: Patrun(),
find(pat: any): undefined | ErrDef {
let errdef = self._router.find(pat)
if (errdef) {
errdef = { ...errdef }
errdef.text.replace(/($[\w\d]+)/g, (match: string) => {
let out = pat[match]
return null == out ? match : out
})
}
errdef = errdef || pat
return errdef
},
print() {
return self._router.toString((errdef: any) => JSON.stringify(errdef, undefined, undefined))
}
}
_walkprop(msgmap, [], self._router)
function _walkprop(msgmap: MsgMap, path: string[][], router: PatrunRouter) {
const errdef = msgmap.$
if (errdef) {
if (null == errdef.text) {
throw new Error('GubuErrMsg: ' +
path.reduce((a, n) => (a.push(n[0] + ':' + n[1]), a), []).join(',') +
' - invalid error definition: property `text` is required.')
}
const pat = path.reduce((a: any, pv: string[]) => (a[pv[0]] = pv[1], a), {})
router.add(pat, errdef)
}
const props = Object.keys(msgmap).filter(k => '$' !== k)
for (let p of props) {
if (ALLOWED_PROPS[p] || p.match(/^[^_]+_[^_]+$/)) {
_walkval(msgmap[p] as MsgMapVal, path.concat([[p]]), router)
}
else {
throw new Error('GubuErrMsg: ' +
path.reduce((a, n) => (a.push(n[0] + ':' + n[1]), a), []).join(',') +
' - invalid property format: "' + p +
'" (must match <base>_<name>, or be one of: [' +
Object.keys(ALLOWED_PROPS).join(', ') + ']).')
}
}
}
function _walkval(msgmapval: MsgMapVal, path: string[][], router: PatrunRouter) {
const vals = Object.keys(msgmapval)
for (let v of vals) {
path[path.length - 1][1] = v
_walkprop(msgmapval[v], path, router)
}
}
return self
}
export {
GubuErrMsg
}