w-serv-orm 1.0.0

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.
Files changed (56) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.js +54 -0
  4. package/.jsdoc +25 -0
  5. package/LICENSE +21 -0
  6. package/README.md +74 -0
  7. package/SECURITY.md +5 -0
  8. package/babel.config.js +14 -0
  9. package/dist/w-serv-orm.umd.js +7 -0
  10. package/dist/w-serv-orm.umd.js.map +1 -0
  11. package/docs/WServOrm.html +582 -0
  12. package/docs/WServOrm.mjs.html +171 -0
  13. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  14. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  15. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  16. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  17. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  18. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  19. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  20. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  21. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  23. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  24. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  25. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  28. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  29. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  30. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  31. package/docs/index.html +81 -0
  32. package/docs/scripts/collapse.js +20 -0
  33. package/docs/scripts/linenumber.js +25 -0
  34. package/docs/scripts/nav.js +12 -0
  35. package/docs/scripts/polyfill.js +4 -0
  36. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  37. package/docs/scripts/prettify/lang-css.js +2 -0
  38. package/docs/scripts/prettify/prettify.js +28 -0
  39. package/docs/scripts/search.js +83 -0
  40. package/docs/styles/jsdoc.css +765 -0
  41. package/docs/styles/prettify.css +79 -0
  42. package/g.mOrm.mjs +54 -0
  43. package/package.json +37 -0
  44. package/schema/gi.mjs +8 -0
  45. package/schema/index.mjs +16 -0
  46. package/schema/tables/tests.mjs +78 -0
  47. package/src/WServOrm.mjs +102 -0
  48. package/src/getDbBackupAndRecover.mjs +90 -0
  49. package/src/getMapOrm.mjs +298 -0
  50. package/src/getProc.mjs +176 -0
  51. package/src/getWoItems.mjs +69 -0
  52. package/test/all.test.mjs +10 -0
  53. package/toolg/addVersion.mjs +4 -0
  54. package/toolg/cleanFolder.mjs +4 -0
  55. package/toolg/gDistRollup.mjs +21 -0
  56. package/toolg/modifyReadme.mjs +4 -0
@@ -0,0 +1,298 @@
1
+ import get from 'lodash/get'
2
+ import each from 'lodash/each'
3
+ import map from 'lodash/map'
4
+ import size from 'lodash/size'
5
+ import nowms2str from 'wsemi/src/nowms2str.mjs'
6
+ import isarr from 'wsemi/src/isarr.mjs'
7
+ import iseobj from 'wsemi/src/iseobj.mjs'
8
+ import isestr from 'wsemi/src/isestr'
9
+
10
+
11
+ let _ds = null
12
+ let _woItems = null
13
+
14
+
15
+ function adjustData(woName, userId, data, mode = 'save') { //mode: 'insert', 'save', 'insert+save'
16
+
17
+ //check
18
+ if (!iseobj(_ds)) {
19
+ throw new Error('invalid ds')
20
+ }
21
+
22
+ //keys
23
+ let keys = _ds[woName].keys
24
+
25
+ //one
26
+ let one = false
27
+ if (!isarr(data)) {
28
+ one = true
29
+ data = [data]
30
+ }
31
+
32
+ //t
33
+ let t = nowms2str()
34
+
35
+ //userId, timeCreate
36
+ if (mode.indexOf('insert') >= 0) {
37
+
38
+ //userId
39
+ if (keys.indexOf('userId') >= 0) {
40
+ each(data, (v, k) => {
41
+ data[k].userId = userId
42
+ })
43
+ }
44
+
45
+ //timeCreate
46
+ if (keys.indexOf('timeCreate') >= 0) {
47
+
48
+ each(data, (v, k) => {
49
+ data[k].timeCreate = t
50
+ })
51
+ }
52
+
53
+ }
54
+
55
+ //userIdUpdate, timeUpdate, 不能用else否則無法同時處理
56
+ if (mode.indexOf('insert') >= 0 || mode.indexOf('save') >= 0) {
57
+
58
+ //userIdUpdate
59
+ if (keys.indexOf('userIdUpdate') >= 0) {
60
+ each(data, (v, k) => {
61
+ data[k].userIdUpdate = userId
62
+ })
63
+ }
64
+
65
+ //timeUpdate
66
+ if (keys.indexOf('timeUpdate') >= 0) {
67
+ each(data, (v, k) => {
68
+ data[k].timeUpdate = t
69
+ })
70
+ }
71
+
72
+ }
73
+
74
+ //復原data型態, 若原本data為物件則取第0個回傳
75
+ data = one ? data[0] : data
76
+
77
+ return data
78
+ }
79
+
80
+
81
+ async function mapOrm(userId, woName, mode, input) {
82
+ //由woName自動綁定至woItems內的ORM物件
83
+ let err = null
84
+ let r
85
+
86
+ //check
87
+ if (!iseobj(_woItems)) {
88
+ return Promise.reject(`無有效woItems`)
89
+ }
90
+
91
+ //wo
92
+ let wo = get(_woItems, woName, null)
93
+
94
+ //check
95
+ if (wo === null) {
96
+ return Promise.reject(`ORM找不到表名稱: ${woName}`)
97
+ }
98
+
99
+ if (mode === 'select') {
100
+
101
+ //select
102
+ r = await wo.select(input)
103
+ .catch((msg) => {
104
+ console.log(`${woName}.select catch`, msg)
105
+ err = '取得資料失敗'
106
+ })
107
+
108
+ //check
109
+ if (isestr(err)) {
110
+ return Promise.reject(err)
111
+ }
112
+
113
+ }
114
+ else if (mode === 'insert' || mode === 'save') {
115
+
116
+ //adjustData
117
+ try {
118
+ input = adjustData(woName, userId, input, mode)
119
+ }
120
+ catch (e) {
121
+ console.log(`adjustData catch`, e.toString())
122
+ err = '調整資料失敗'
123
+ return Promise.reject(err)
124
+ }
125
+
126
+ //save
127
+ if (mode === 'insert') {
128
+ r = await wo.insert(input)
129
+ .catch((msg) => {
130
+ console.log(`${woName}.save catch`, msg)
131
+ err = '新增資料失敗'
132
+ })
133
+ }
134
+ else if (mode === 'save') {
135
+ r = await wo.save(input, { atomic: true })
136
+ .catch((msg) => {
137
+ console.log(`${woName}.save catch`, msg)
138
+ err = '儲存資料失敗'
139
+ })
140
+ }
141
+
142
+ //check
143
+ if (isestr(err)) {
144
+ return Promise.reject(err)
145
+ }
146
+
147
+ //僅回傳id避免大量數據時造成負擔
148
+ if (isarr(input)) {
149
+ r = map(input, (v) => {
150
+ return { id: v.id }
151
+ })
152
+ }
153
+ else {
154
+ r = { id: input.id }
155
+ }
156
+ //console.log(mode, ' r', r)
157
+
158
+ }
159
+ else if (mode === 'del') {
160
+
161
+ //del
162
+ r = await wo.del(input)
163
+ .catch((msg) => {
164
+ console.log(`${woName}.del catch`, msg)
165
+ err = '刪除資料失敗'
166
+ })
167
+
168
+ }
169
+ else if (mode === 'delAll') {
170
+
171
+ //delAll
172
+ r = await wo.delAll(input)
173
+ .catch((msg) => {
174
+ console.log(`${woName}.delAll catch`, msg)
175
+ err = '刪除資料失敗'
176
+ })
177
+
178
+ }
179
+ else if (mode === 'mix') {
180
+
181
+ //check
182
+ if (!iseobj(input)) {
183
+ return Promise.reject('mix僅支援輸入ltdtdiff結果物件')
184
+ }
185
+
186
+ //rt,r
187
+ let rt
188
+ r = [] //default to array
189
+
190
+ let add = get(input, 'add', [])
191
+ if (size(add) > 0) {
192
+
193
+ //adjustData
194
+ try {
195
+ add = adjustData(woName, userId, add, 'insert+save')
196
+ }
197
+ catch (e) {
198
+ console.log(`adjustData catch`, e.toString())
199
+ err = '調整資料失敗'
200
+ return Promise.reject(err)
201
+ }
202
+
203
+ //insert
204
+ await wo.insert(add)
205
+ .catch((msg) => {
206
+ console.log(`${woName}.save catch`, msg)
207
+ err = '新增資料失敗'
208
+ })
209
+
210
+ //check
211
+ if (isestr(err)) {
212
+ return Promise.reject(err)
213
+ }
214
+
215
+ //r
216
+ rt = map(add, (v) => {
217
+ return { id: v.id } //僅回傳id避免大量數據時造成負擔
218
+ })
219
+ r = [...r, ...rt]
220
+ }
221
+
222
+ let del = get(input, 'del', [])
223
+ if (size(del) > 0) {
224
+
225
+ //del
226
+ await wo.del(del)
227
+ .catch((msg) => {
228
+ console.log(`${woName}.save catch`, msg)
229
+ err = '刪除資料失敗'
230
+ })
231
+
232
+ //check
233
+ if (isestr(err)) {
234
+ return Promise.reject(err)
235
+ }
236
+
237
+ //r
238
+ rt = map(del, (v) => {
239
+ return { id: v.id } //僅回傳id避免大量數據時造成負擔
240
+ })
241
+ r = [...r, ...rt]
242
+ }
243
+
244
+ let diff = get(input, 'diff', [])
245
+ if (size(diff) > 0) {
246
+
247
+ //adjustData
248
+ try {
249
+ diff = adjustData(woName, userId, diff)
250
+ }
251
+ catch (e) {
252
+ console.log(`adjustData catch`, e.toString())
253
+ err = '調整資料失敗'
254
+ return Promise.reject(err)
255
+ }
256
+
257
+ //save
258
+ await wo.save(diff)
259
+ .catch((msg) => {
260
+ console.log(`${woName}.save catch`, msg)
261
+ err = '變更資料失敗'
262
+ })
263
+
264
+ //check
265
+ if (isestr(err)) {
266
+ return Promise.reject(err)
267
+ }
268
+
269
+ //r
270
+ rt = map(diff, (v) => {
271
+ return { id: v.id } //僅回傳id避免大量數據時造成負擔
272
+ })
273
+ r = [...r, ...rt]
274
+ }
275
+
276
+ //console.log('mix r', r)
277
+ }
278
+ else {
279
+ err = `invalid mode: ${mode}`
280
+ }
281
+
282
+ //check
283
+ if (isestr(err)) {
284
+ return Promise.reject(err)
285
+ }
286
+
287
+ return r
288
+ }
289
+
290
+
291
+ function getMapOrm(ds, woItems) {
292
+ _ds = ds
293
+ _woItems = woItems
294
+ return mapOrm
295
+ }
296
+
297
+
298
+ export default getMapOrm
@@ -0,0 +1,176 @@
1
+ import get from 'lodash/get'
2
+ import size from 'lodash/size'
3
+ import filter from 'lodash/filter'
4
+ import isarr from 'wsemi/src/isarr.mjs'
5
+ import isestr from 'wsemi/src/isestr'
6
+ import haskey from 'wsemi/src/haskey'
7
+ import pmSeries from 'wsemi/src/pmSeries'
8
+ import pmChain from 'wsemi/src/pmChain'
9
+ import isfun from 'wsemi/src/isfun'
10
+ import isbol from 'wsemi/src/isbol'
11
+
12
+
13
+ let _funChecks = []
14
+ let _funPreProcessing = []
15
+ let _funPostProcessing = []
16
+ let _mapOrm = null
17
+ let _getUserById = null
18
+ let bCheckUser = true
19
+ let bExcludeWhenNotAdmin = true
20
+
21
+
22
+ function addFunCheck(f) {
23
+ //由外部添加擴充檢查函數
24
+
25
+ setTimeout(() => { //因互相引用的關係會出現「Cannot access '_funChecks' before initialization」, 故通過timer脫勾成為動態引用, 避開執行mInitialTestData時會先編譯與偵測問題
26
+ _funChecks.push(f)
27
+ }, 1)
28
+
29
+ }
30
+
31
+
32
+ function addFunPreProcessing(f) {
33
+ //由外部添加擴充前處理函數
34
+
35
+ setTimeout(() => { //因互相引用的關係會出現「Cannot access '_funChecks' before initialization」, 故通過timer脫勾成為動態引用, 避開執行mInitialTestData時會先編譯與偵測問題
36
+ _funPreProcessing.push(f)
37
+ }, 1)
38
+
39
+ }
40
+
41
+
42
+ function addFunPostProcessing(f) {
43
+ //由外部添加擴充後置處理函數
44
+
45
+ setTimeout(() => { //因互相引用的關係會出現「Cannot access '_funChecks' before initialization」, 故通過timer脫勾成為動態引用, 避開執行mInitialTestData時會先編譯與偵測問題
46
+ _funPostProcessing.push(f)
47
+ }, 1)
48
+
49
+ }
50
+
51
+
52
+ async function procOrm(userId, woName, mode, input) {
53
+ //封裝mapOrm, 添加檢查userId功能
54
+
55
+ //check
56
+ if (!isfun(_mapOrm)) {
57
+ return Promise.reject(`invalid mapOrm`)
58
+ }
59
+
60
+ //check
61
+ if (!isestr(userId)) {
62
+ console.log(`找不到使用者主鍵: (${userId})`)
63
+ return Promise.reject(`找不到使用者主鍵`)
64
+ }
65
+
66
+ //isAdmin
67
+ let isAdmin = 'n'
68
+
69
+ //bCheckUser
70
+ if (bCheckUser) {
71
+
72
+ //check
73
+ if (!isfun(_getUserById)) {
74
+ return Promise.reject(`invalid getUserById`)
75
+ }
76
+
77
+ //oSelf
78
+ let oSelf = await _getUserById(userId)
79
+
80
+ //check
81
+ if (!oSelf) {
82
+ console.log(`找不到使用者資訊: (${userId})`)
83
+ return Promise.reject(`找不到使用者資訊`)
84
+ }
85
+
86
+ //isAdmin
87
+ isAdmin = get(oSelf, 'isAdmin')
88
+ if (isAdmin !== 'y' && isAdmin !== 'n') {
89
+ isAdmin = 'n'
90
+ }
91
+
92
+ //isActive
93
+ let isActive = get(oSelf, 'isActive')
94
+ if (isActive !== 'y' && isActive !== 'n') {
95
+ isActive = 'n'
96
+ }
97
+
98
+ //check
99
+ if (isActive !== 'y') {
100
+ console.log(`使用者被停權或無有效使用者資訊: (${userId})`)
101
+ return Promise.reject(`使用者被停權或無有效使用者資訊`)
102
+ }
103
+
104
+ }
105
+
106
+ //_funChecks, 擴充檢查, 提供給各 mOrm[OOO].mjs 檢查
107
+ await pmSeries(_funChecks, (v) => {
108
+ return v({ woName, userId, isAdmin, mode, input })
109
+ })
110
+
111
+ //_funPreProcessing, 擴充前處理input, 提供給各 mOrm[OOO].mjs 前處理
112
+ if (size(_funPreProcessing) > 0) {
113
+ let paramsIn = { woName, userId, isAdmin, mode, input } //將input與其他資訊一起封裝成params
114
+ let paramsOut = await pmChain(_funPreProcessing, paramsIn) //各非同步函數拿到輸入處理完皆輸出一樣結構數據params, 使各非同步函數都可拿到非input的重要資訊
115
+ input = paramsOut.input //由params提取input出來
116
+ }
117
+
118
+ //output
119
+ let output = await _mapOrm(userId, woName, mode, input)
120
+
121
+ //bExcludeWhenNotAdmin, 非管理者則要過濾掉已刪除之數據
122
+ if (bExcludeWhenNotAdmin && isAdmin === 'n') {
123
+ if (mode === 'select' && isarr(output)) { //有可能為錯誤物件
124
+ output = filter(output, (v) => {
125
+ if (haskey(v, 'isActive')) { //針對有isActive屬性
126
+ return !(v.isActive === 'n') //過濾isActive='n'
127
+ }
128
+ return true
129
+ })
130
+ }
131
+ }
132
+
133
+ //_funPostProcessing, 擴充後處理output, 提供給各 mOrm[OOO].mjs 後處理
134
+ if (size(_funPostProcessing) > 0) {
135
+ output = await pmChain(_funPostProcessing, { woName, userId, isAdmin, mode, input, output })
136
+ }
137
+
138
+ return output
139
+ }
140
+
141
+
142
+ function getProc(mapOrm, opt = {}) {
143
+
144
+ //check
145
+ if (!isfun(mapOrm)) {
146
+ return Promise.reject(`invalid mapOrm`)
147
+ }
148
+
149
+ //save _mapOrm
150
+ _mapOrm = mapOrm
151
+
152
+ //save _getUserById, 不事先檢查, 因若bCheckUser=false可允許不給
153
+ _getUserById = get(opt, 'getUserById')
154
+
155
+ //bCheckUser
156
+ bCheckUser = get(opt, 'bCheckUser')
157
+ if (!isbol(bCheckUser)) {
158
+ bCheckUser = true
159
+ }
160
+
161
+ //bExcludeWhenNotAdmin
162
+ bExcludeWhenNotAdmin = get(opt, 'bExcludeWhenNotAdmin')
163
+ if (!isbol(bExcludeWhenNotAdmin)) {
164
+ bExcludeWhenNotAdmin = true
165
+ }
166
+
167
+ return {
168
+ addFunCheck,
169
+ addFunPreProcessing,
170
+ addFunPostProcessing,
171
+ procOrm,
172
+ }
173
+ }
174
+
175
+
176
+ export default getProc
@@ -0,0 +1,69 @@
1
+ import get from 'lodash/get'
2
+ import each from 'lodash/each'
3
+ import keys from 'lodash/keys'
4
+ import size from 'lodash/size'
5
+ import isfun from 'wsemi/src/isfun'
6
+ import iseobj from 'wsemi/src/iseobj'
7
+ import isestr from 'wsemi/src/isestr'
8
+
9
+
10
+ function getWoItems(ds, WOrm, opt = {}) {
11
+
12
+ //check ds
13
+ if (size(ds) === 0) {
14
+ console.log('ds', ds)
15
+ throw new Error('invalid ds')
16
+ }
17
+
18
+ //check WOrm
19
+ if (!isfun(WOrm)) {
20
+ console.log('WOrm', WOrm)
21
+ throw new Error('invalid WOrm')
22
+ }
23
+
24
+ //check opt
25
+ if (!iseobj(opt)) {
26
+ console.log('opt', opt)
27
+ throw new Error('invalid opt')
28
+ }
29
+
30
+ //url
31
+ let url = get(opt, 'url')
32
+ if (!isestr(url)) {
33
+ console.log('url', url)
34
+ throw new Error('invalid url')
35
+ }
36
+
37
+ //db
38
+ let db = get(opt, 'db')
39
+ if (!isestr(db)) {
40
+ console.log('db', db)
41
+ throw new Error('invalid db')
42
+ }
43
+
44
+ //woItems
45
+ let woItems = {}
46
+ each(keys(ds), (v) => {
47
+
48
+ //useOpt
49
+ let useOpt = { url, db, cl: v }
50
+
51
+ //wo
52
+ let wo = new WOrm(useOpt)
53
+
54
+ //save
55
+ woItems[v] = wo
56
+
57
+ // //change, 當數據有改變時清除快取
58
+ // wo.on('change', (mode) => {
59
+ // //console.log(`${v} change`, mode)
60
+ // cache.clear(`${v}.select`) //變更後會馬上重撈資料, 故需直接清除快取
61
+ // })
62
+
63
+ })
64
+
65
+ return woItems
66
+ }
67
+
68
+
69
+ export default getWoItems
@@ -0,0 +1,10 @@
1
+ import assert from 'assert'
2
+
3
+
4
+ describe('all', function() {
5
+
6
+ it('test in localhost', function() {
7
+ assert.strict.deepEqual(1, 1)
8
+ })
9
+
10
+ })
@@ -0,0 +1,4 @@
1
+ import addVersion from 'w-package-tools/src/addVersion.mjs'
2
+
3
+
4
+ addVersion()
@@ -0,0 +1,4 @@
1
+ import cleanFolder from 'w-package-tools/src/cleanFolder.mjs'
2
+
3
+
4
+ cleanFolder('docs')
@@ -0,0 +1,21 @@
1
+ import rollupFiles from 'w-package-tools/src/rollupFiles.mjs'
2
+
3
+
4
+ let fdSrc = './src'
5
+ let fdTar = './dist'
6
+
7
+ rollupFiles({
8
+ fns: ['WServOrm.mjs'],
9
+ fdSrc,
10
+ fdTar,
11
+ nameDistType: 'kebabCase',
12
+ globals: {
13
+ 'path': 'path',
14
+ 'fs': 'fs',
15
+ },
16
+ external: [
17
+ 'path',
18
+ 'fs',
19
+ ],
20
+ })
21
+
@@ -0,0 +1,4 @@
1
+ import modifyReadme from 'w-package-tools/src/modifyReadme.mjs'
2
+
3
+
4
+ modifyReadme()