w-serv-orm 1.1.8 → 1.1.10

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/src/getProc.mjs CHANGED
@@ -1,189 +1,106 @@
1
- import get from 'lodash-es/get.js'
2
- import filter from 'lodash-es/filter.js'
3
- import isarr from 'wsemi/src/isarr.mjs'
4
- import isestr from 'wsemi/src/isestr.mjs'
5
- import iseobj from 'wsemi/src/iseobj.mjs'
6
- import haskey from 'wsemi/src/haskey.mjs'
7
- import pmSeries from 'wsemi/src/pmSeries.mjs'
8
- import isfun from 'wsemi/src/isfun.mjs'
9
- import isbol from 'wsemi/src/isbol.mjs'
10
-
11
-
12
- function addFun(fs, f, name, useGuard = false) {
13
- //由外部添加擴充函數至該實例之陣列
14
- //延後1ms生效係沿用既有之生效時序: 原為避開模組層陣列於循環引用時之「Cannot access before initialization」,
15
- //改為各實例狀態後該原因已不成立, 惟使用端之啟動流程可能依賴此時序, 故保留
16
-
17
- //check, 非函數於註冊時即拋錯; useGuard(check用)另推入恆reject之守門函數, 令拋錯被呼叫端攔下時該實例仍維持fail-closed
18
- //註冊時拋錯屬建構期錯誤故為Error; 守門函數於procOrm內reject, 與procOrm其餘拒絕一致為字串
19
- if (!isfun(f)) {
20
- let msg = `${name} needs a function, but got ${typeof f}`
21
- if (useGuard) {
22
- fs.push(() => {
23
- return Promise.reject(msg)
24
- })
25
- }
26
- throw new Error(msg)
27
- }
28
-
29
- setTimeout(() => {
30
- fs.push(f)
31
- }, 1)
32
-
33
- }
34
-
35
-
36
- async function procOrm(st, userId, woName, mode, input) {
37
- //封裝mapOrm, 添加檢查userId功能, st為該實例之狀態
38
-
39
- //check
40
- if (!isfun(st.mapOrm)) {
41
- return Promise.reject(`invalid mapOrm`)
42
- }
43
-
44
- //check
45
- if (st.useCheckUser && !isestr(userId)) {
46
- console.log('userId', userId)
47
- console.log('invalid userId')
48
- return Promise.reject(`invalid userId`)
49
- }
50
-
51
- //isAdmin
52
- let isAdmin = 'n'
53
-
54
- //useCheckUser
55
- if (st.useCheckUser) {
56
-
57
- //check
58
- if (!isfun(st.getUserById)) {
59
- return Promise.reject(`invalid getUserById`)
60
- }
61
-
62
- //oSelf
63
- let oSelf = await st.getUserById(userId)
64
-
65
- //check
66
- if (!oSelf) {
67
- console.log('userId', userId)
68
- console.log('can not find user')
69
- return Promise.reject(`can not find user`)
70
- }
71
-
72
- //isAdmin
73
- isAdmin = get(oSelf, 'isAdmin')
74
- if (isAdmin !== 'y' && isAdmin !== 'n') {
75
- isAdmin = 'n'
76
- }
77
-
78
- //isActive
79
- let isActive = get(oSelf, 'isActive')
80
- if (isActive !== 'y' && isActive !== 'n') {
81
- isActive = 'n'
82
- }
83
-
84
- //check
85
- if (isActive !== 'y') {
86
- console.log('userId', userId)
87
- console.log('oSelf', oSelf)
88
- console.log('user is inactive or invalid')
89
- return Promise.reject(`user is inactive or invalid`)
90
- }
91
-
92
- }
93
-
94
- //funChecks, 擴充檢查, 提供給各 mOrm[OOO].mjs 檢查
95
- await pmSeries(st.funChecks, (v) => {
96
- return v({ woName, userId, isAdmin, mode, input })
97
- })
98
-
99
- //funPreProcessing, 擴充前處理input, 提供給各 mOrm[OOO].mjs 前處理
100
- //逐一呼叫, 各前處理皆收新建之參數物件, input為前一個回傳之input; 回傳須為含input之物件, 否則reject, 避免input成為undefined而令select回全表
101
- //迭代前先取快照, 呼叫進行中註冊者不套用於本次呼叫
102
- for (let f of [...st.funPreProcessing]) {
103
- let paramsOut = await f({ woName, userId, isAdmin, mode, input })
104
- if (!iseobj(paramsOut) || paramsOut.input === undefined) {
105
- return Promise.reject(`invalid return of pre-processing, need an object with input`)
106
- }
107
- input = paramsOut.input
108
- }
109
-
110
- //output
111
- let output = await st.mapOrm(userId, woName, mode, input)
112
-
113
- //useExcludeWhenNotAdmin, 非管理者則要過濾掉已刪除之數據
114
- if (st.useExcludeWhenNotAdmin && isAdmin === 'n') {
115
- if (mode === 'select' && isarr(output)) { //有可能為錯誤物件
116
- output = filter(output, (v) => {
117
- if (haskey(v, 'isActive')) { //針對有isActive屬性
118
- return !(v.isActive === 'n') //過濾isActive='n'
119
- }
120
- return true
121
- })
122
- }
123
- }
124
-
125
- //funPostProcessing, 擴充後處理output, 提供給各 mOrm[OOO].mjs 後處理
126
- //逐一呼叫, 各後處理皆收新建之參數物件, output為前一個之回傳值, 回傳值成為新output; 迭代前先取快照
127
- for (let f of [...st.funPostProcessing]) {
128
- output = await f({ woName, userId, isAdmin, mode, input, output })
129
- }
130
-
131
- return output
132
- }
133
-
134
-
135
- function getProc(mapOrm, opt = {}) {
136
-
137
- //check
138
- if (!isfun(mapOrm)) {
139
- return Promise.reject(`invalid mapOrm`)
140
- }
141
-
142
- //useCheckUser
143
- let useCheckUser = get(opt, 'useCheckUser')
144
- if (!isbol(useCheckUser)) {
145
- useCheckUser = true
146
- }
147
-
148
- //getUserById, 不事先檢查, 因若useCheckUser=false可允許不給
149
- let getUserById = get(opt, 'getUserById')
150
-
151
- //useExcludeWhenNotAdmin
152
- let useExcludeWhenNotAdmin = get(opt, 'useExcludeWhenNotAdmin')
153
- if (!isbol(useExcludeWhenNotAdmin)) {
154
- useExcludeWhenNotAdmin = true
155
- }
156
-
157
- //st, 各實例之狀態, 每次呼叫各自建立, 令同一行程內之多個實例互不干擾
158
- let st = {
159
- funChecks: [],
160
- funPreProcessing: [],
161
- funPostProcessing: [],
162
- mapOrm,
163
- getUserById,
164
- useCheckUser,
165
- useExcludeWhenNotAdmin,
166
- }
167
-
168
- //回傳函數綁定st而不依賴this, 使用端可解構取用並當裸函數傳遞
169
- return {
170
- addFunCheck: (f) => {
171
- //由外部添加擴充檢查函數
172
- addFun(st.funChecks, f, 'addFunCheck', true)
173
- },
174
- addFunPreProcessing: (f) => {
175
- //由外部添加擴充前處理函數
176
- addFun(st.funPreProcessing, f, 'addFunPreProcessing')
177
- },
178
- addFunPostProcessing: (f) => {
179
- //由外部添加擴充後置處理函數
180
- addFun(st.funPostProcessing, f, 'addFunPostProcessing')
181
- },
182
- procOrm: async (userId, woName, mode, input) => {
183
- return procOrm(st, userId, woName, mode, input)
184
- },
185
- }
186
- }
187
-
188
-
189
- export default getProc
1
+ import iseobj from 'wsemi/src/iseobj.mjs'
2
+ import pmSeries from 'wsemi/src/pmSeries.mjs'
3
+ import isfun from 'wsemi/src/isfun.mjs'
4
+ import checkOptRemoved from './checkOptRemoved.mjs'
5
+
6
+
7
+ function addFun(fs, f, name, useGuard = false) {
8
+ //由外部添加擴充函數至該實例之陣列
9
+ //延後1ms生效係沿用既有之生效時序: 原為避開模組層陣列於循環引用時之「Cannot access before initialization」,
10
+ //改為各實例狀態後該原因已不成立, 惟使用端之啟動流程可能依賴此時序, 故保留
11
+
12
+ //check, 非函數於註冊時即拋錯; useGuard(check用)另推入恆reject之守門函數, 令拋錯被呼叫端攔下時該實例仍維持fail-closed
13
+ //註冊時拋錯屬建構期錯誤故為Error; 守門函數於procOrm內reject, 與procOrm其餘拒絕一致為字串
14
+ if (!isfun(f)) {
15
+ let msg = `${name} needs a function, but got ${typeof f}`
16
+ if (useGuard) {
17
+ fs.push(() => {
18
+ return Promise.reject(msg)
19
+ })
20
+ }
21
+ throw new Error(msg)
22
+ }
23
+
24
+ setTimeout(() => {
25
+ fs.push(f)
26
+ }, 1)
27
+
28
+ }
29
+
30
+
31
+ async function procOrm(st, userId, woName, mode, input) {
32
+ //封裝mapOrm, 依序執行擴充檢查、前處理、ORM操作與後處理, st為該實例之狀態
33
+ //不做授權: 不檢查使用者亦不依使用者過濾數據, userId只供寫入稽核欄位與交給擴充函數; 開放給前端時須由開放處負責授權
34
+ //st.mapOrm已於getProc建立st時驗證為函數, 且st不外露, 故此處不再檢查
35
+
36
+ //funChecks, 擴充檢查, 提供給各 mOrm[OOO].mjs 檢查
37
+ await pmSeries(st.funChecks, (v) => {
38
+ return v({ woName, userId, mode, input })
39
+ })
40
+
41
+ //funPreProcessing, 擴充前處理input, 提供給各 mOrm[OOO].mjs 前處理
42
+ //逐一呼叫, 各前處理皆收新建之參數物件, input為前一個回傳之input; 回傳須為含input之物件, 否則reject, 避免input成為undefined而令select回全表
43
+ //迭代前先取快照, 呼叫進行中註冊者不套用於本次呼叫
44
+ for (let f of [...st.funPreProcessing]) {
45
+ let paramsOut = await f({ woName, userId, mode, input })
46
+ if (!iseobj(paramsOut) || paramsOut.input === undefined) {
47
+ return Promise.reject(`invalid return of pre-processing, need an object with input`)
48
+ }
49
+ input = paramsOut.input
50
+ }
51
+
52
+ //output
53
+ let output = await st.mapOrm(userId, woName, mode, input)
54
+
55
+ //funPostProcessing, 擴充後處理output, 提供給各 mOrm[OOO].mjs 後處理
56
+ //逐一呼叫, 各後處理皆收新建之參數物件, output為前一個之回傳值, 回傳值成為新output; 迭代前先取快照
57
+ for (let f of [...st.funPostProcessing]) {
58
+ output = await f({ woName, userId, mode, input, output })
59
+ }
60
+
61
+ return output
62
+ }
63
+
64
+
65
+ function getProc(mapOrm, opt = {}) {
66
+ //mapOrm為getMapOrm之回傳函數, opt目前無設定鍵, 只檢查已移除之設定; 使用端有直接呼叫者(如測試以getMapOrm與getProc組出procOrm), 故檢查與WServOrm一致
67
+ //建構期之錯誤一律為Error, 與procOrm之字串reject區隔
68
+
69
+ //checkOptRemoved
70
+ checkOptRemoved(opt)
71
+
72
+ //check
73
+ if (!isfun(mapOrm)) {
74
+ throw new Error(`invalid mapOrm`)
75
+ }
76
+
77
+ //st, 各實例之狀態, 每次呼叫各自建立, 令同一行程內之多個實例互不干擾
78
+ let st = {
79
+ funChecks: [],
80
+ funPreProcessing: [],
81
+ funPostProcessing: [],
82
+ mapOrm,
83
+ }
84
+
85
+ //回傳函數綁定st而不依賴this, 使用端可解構取用並當裸函數傳遞
86
+ return {
87
+ addFunCheck: (f) => {
88
+ //由外部添加擴充檢查函數
89
+ addFun(st.funChecks, f, 'addFunCheck', true)
90
+ },
91
+ addFunPreProcessing: (f) => {
92
+ //由外部添加擴充前處理函數
93
+ addFun(st.funPreProcessing, f, 'addFunPreProcessing')
94
+ },
95
+ addFunPostProcessing: (f) => {
96
+ //由外部添加擴充後置處理函數
97
+ addFun(st.funPostProcessing, f, 'addFunPostProcessing')
98
+ },
99
+ procOrm: async (userId, woName, mode, input) => {
100
+ return procOrm(st, userId, woName, mode, input)
101
+ },
102
+ }
103
+ }
104
+
105
+
106
+ export default getProc
@@ -27,7 +27,7 @@ describe('procOrm接w-orm-lowdb', function() {
27
27
  before(function() {
28
28
  fs.rmSync(fd, { recursive: true, force: true })
29
29
  fs.mkdirSync(fd, { recursive: true })
30
- so = WServOrm(ds, WOrm, `${fd}/db.json`, 'worm', { useCheckUser: false, useExcludeWhenNotAdmin: false })
30
+ so = WServOrm(ds, WOrm, `${fd}/db.json`, 'worm')
31
31
  })
32
32
 
33
33
  after(async function() {