w-web-api 1.0.28 → 1.0.30
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/README.md +23 -16
- package/dist/css/app.d38a4241.css +1 -0
- package/dist/index.tmp +3 -1
- package/dist/js/app-legacy.9b4e9f9b.js +2 -0
- package/dist/js/app-legacy.9b4e9f9b.js.map +1 -0
- package/dist/js/app.9b4e9f9b.js +2 -0
- package/dist/js/app.9b4e9f9b.js.map +1 -0
- package/dist/js/chunk-vendors-legacy.2a4fa50d.js +14 -0
- package/dist/js/chunk-vendors-legacy.2a4fa50d.js.map +1 -0
- package/dist/js/chunk-vendors.2a4fa50d.js +14 -0
- package/dist/js/chunk-vendors.2a4fa50d.js.map +1 -0
- package/dist/w-web-api.umd.js +2 -2
- package/dist/w-web-api.umd.js.map +1 -1
- package/docs/WWebApi.html +44 -4
- package/docs/WWebApi.mjs.html +195 -66
- package/docs/index.html +1 -1
- package/{g.mDb.mjs → g.backupDb.mjs} +1 -1
- package/{g.mInitialTestData.mjs → g.initialTestData.mjs} +1 -1
- package/package.json +5 -10
- package/public/index.html +8 -1
- package/server/WWebApi.mjs +194 -65
- package/server/provideApis.mjs +2 -2
- package/src/App.vue +17 -10
- package/src/components/LayoutContent.vue +15 -35
- package/src/main.js +0 -2
- package/src/store/mutations.mjs +6 -13
- package/srv.mjs +23 -12
- package/tableTags-web-api.json +1 -1
- package/vue.config.js +1 -1
- package/dist/css/app.8f83f1ad.css +0 -1
- package/dist/css/chunk-vendors.004a7134.css +0 -5
- package/dist/js/app-legacy.fe5cd851.js +0 -2
- package/dist/js/app-legacy.fe5cd851.js.map +0 -1
- package/dist/js/app.fe5cd851.js +0 -2
- package/dist/js/app.fe5cd851.js.map +0 -1
- package/dist/js/chunk-vendors-legacy.1bbf0550.js +0 -14
- package/dist/js/chunk-vendors-legacy.1bbf0550.js.map +0 -1
- package/dist/js/chunk-vendors.1bbf0550.js +0 -14
- package/dist/js/chunk-vendors.1bbf0550.js.map +0 -1
- package/src/plugins/mVuetify.mjs +0 -12
package/server/WWebApi.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs'
|
|
3
3
|
import get from 'lodash/get'
|
|
4
|
-
// import map from 'lodash/map'
|
|
5
4
|
import each from 'lodash/each'
|
|
6
5
|
import keys from 'lodash/keys'
|
|
7
|
-
// import cloneDeep from 'lodash/cloneDeep'
|
|
8
6
|
import j2o from 'wsemi/src/j2o.mjs'
|
|
9
7
|
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
10
8
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
9
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
11
10
|
import ispint from 'wsemi/src/ispint.mjs'
|
|
12
11
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
13
12
|
import ispm from 'wsemi/src/ispm.mjs'
|
|
@@ -19,6 +18,7 @@ import strdelright from 'wsemi/src/strdelright.mjs'
|
|
|
19
18
|
import pm2resolve from 'wsemi/src/pm2resolve.mjs'
|
|
20
19
|
import b642str from 'wsemi/src/b642str.mjs'
|
|
21
20
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
21
|
+
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
22
22
|
import replace from 'wsemi/src/replace.mjs'
|
|
23
23
|
import WServHapiServer from 'w-serv-hapi/src/WServHapiServer.mjs'
|
|
24
24
|
import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
@@ -26,7 +26,7 @@ import ds from '../src/schema/index.mjs'
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* API伺服器
|
|
30
30
|
*
|
|
31
31
|
* @class
|
|
32
32
|
* @param {Function} WOrm 輸入資料庫ORM函數
|
|
@@ -43,12 +43,12 @@ import ds from '../src/schema/index.mjs'
|
|
|
43
43
|
* @param {Object} [opt.webDescription={}] 輸入站台描述物件,至少包含語系eng與cht鍵的名稱,預設{}
|
|
44
44
|
* @param {String} [opt.webLogo=''] 輸入站台logo字串,採base64格式,預設''
|
|
45
45
|
* @param {String} [opt.subfolder=''] 輸入站台所在子目錄字串,提供站台位於內網採反向代理進行服務時,故需支援位於子目錄情形,預設''
|
|
46
|
+
* @param {String} [opt.urlRedirect=''] 輸入錯誤時自動轉址字串,提供站台例如無法登入或驗證失敗時須自動轉址,預設''
|
|
46
47
|
* @returns {Object} 回傳物件,其內server為hapi伺服器實體,wsrv為w-converhp的伺服器事件物件,wsds為w-serv-webdata的伺服器事件物件,可監聽error事件
|
|
47
48
|
* @example
|
|
48
|
-
*
|
|
49
49
|
* import WOrm from 'w-orm-mongodb/src/WOrmMongodb.mjs' //自行選擇引用ORM, 使用Mongodb測試
|
|
50
|
-
* import getSettings from './server/getSettings.mjs'
|
|
51
50
|
* import WWebApi from './server/WWebApi.mjs'
|
|
51
|
+
* import getSettings from './g.getSettings.mjs'
|
|
52
52
|
*
|
|
53
53
|
* //st
|
|
54
54
|
* let st = getSettings()
|
|
@@ -57,22 +57,55 @@ import ds from '../src/schema/index.mjs'
|
|
|
57
57
|
* let db = st.dbName
|
|
58
58
|
* let opt = {
|
|
59
59
|
*
|
|
60
|
-
* getUserById: null,
|
|
61
60
|
* bCheckUser: false,
|
|
61
|
+
* getUserById: null,
|
|
62
62
|
* bExcludeWhenNotAdmin: false,
|
|
63
63
|
*
|
|
64
64
|
* serverPort: 11005,
|
|
65
|
-
* subfolder: '', //
|
|
65
|
+
* subfolder: '', //mapi
|
|
66
66
|
*
|
|
67
67
|
* webName: {
|
|
68
68
|
* 'eng': 'API Service',
|
|
69
|
-
* 'cht': 'API管理系統'
|
|
69
|
+
* 'cht': 'API管理系統',
|
|
70
70
|
* },
|
|
71
|
+
* webDescription: {
|
|
72
|
+
* 'eng': 'A web service package as methods to send requests to and receive responses from an API.',
|
|
73
|
+
* 'cht': 'A web service package as methods to send requests to and receive responses from an API.',
|
|
74
|
+
* },
|
|
75
|
+
* webLogo: 'data:image/svg+xml;base64,...',
|
|
76
|
+
*
|
|
77
|
+
* }
|
|
71
78
|
*
|
|
79
|
+
* let getUserByToken = (token) => {
|
|
80
|
+
* // return {} //測試無法登入
|
|
81
|
+
* if (token === '{token-for-application}') { //提供外部應用系統作為存取使用者
|
|
82
|
+
* return {
|
|
83
|
+
* id: 'id-for-application',
|
|
84
|
+
* name: 'application',
|
|
85
|
+
* email: 'admin@example.com',
|
|
86
|
+
* isAdmin: 'y',
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* if (token === 'sys') { //開發階段w-ui-loginout自動給予browser使用者(且位於localhost)的token為sys
|
|
90
|
+
* return {
|
|
91
|
+
* id: 'id-for-admin',
|
|
92
|
+
* name: '測試者',
|
|
93
|
+
* email: 'admin@example.com',
|
|
94
|
+
* isAdmin: 'y',
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* console.log('invalid token', token)
|
|
98
|
+
* console.log('於生產環境時得加入SSO等驗證token機制')
|
|
99
|
+
* return {}
|
|
100
|
+
* }
|
|
101
|
+
*
|
|
102
|
+
* let verifyUser = (user) => {
|
|
103
|
+
* console.log('於生產環境時得加入驗證user機制')
|
|
104
|
+
* return user.isAdmin === 'y' //測試僅系統管理者使用
|
|
72
105
|
* }
|
|
73
106
|
*
|
|
74
107
|
* //WWebApi
|
|
75
|
-
* let instWWebApi = WWebApi(WOrm, url, db, opt)
|
|
108
|
+
* let instWWebApi = WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt)
|
|
76
109
|
*
|
|
77
110
|
* instWWebApi.on('error', (err) => {
|
|
78
111
|
* console.log(err)
|
|
@@ -162,6 +195,10 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
162
195
|
}
|
|
163
196
|
|
|
164
197
|
|
|
198
|
+
//urlRedirect
|
|
199
|
+
let urlRedirect = get(opt, 'urlRedirect', '')
|
|
200
|
+
|
|
201
|
+
|
|
165
202
|
//WServOrm
|
|
166
203
|
let optWServOrm = {
|
|
167
204
|
bCheckUser,
|
|
@@ -188,32 +225,39 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
188
225
|
}
|
|
189
226
|
|
|
190
227
|
|
|
191
|
-
//
|
|
192
|
-
let
|
|
228
|
+
//getTokenUserForSelf
|
|
229
|
+
let getTokenUserForSelf = async (token) => {
|
|
193
230
|
|
|
194
231
|
//getUserByToken
|
|
195
|
-
let
|
|
196
|
-
if (ispm(
|
|
197
|
-
|
|
232
|
+
let userSelf = getUserByToken(token)
|
|
233
|
+
if (ispm(userSelf)) {
|
|
234
|
+
userSelf = await userSelf
|
|
198
235
|
}
|
|
199
|
-
|
|
200
|
-
|
|
236
|
+
|
|
237
|
+
//check
|
|
238
|
+
if (!iseobj(userSelf)) {
|
|
239
|
+
console.log(`token`, token)
|
|
240
|
+
console.log(`can not find the user from token`)
|
|
241
|
+
return Promise.reject(`can not find the user from token`)
|
|
201
242
|
}
|
|
202
243
|
|
|
203
244
|
//verifyUser
|
|
204
|
-
let b = verifyUser(
|
|
245
|
+
let b = verifyUser(userSelf)
|
|
205
246
|
if (ispm(b)) {
|
|
206
247
|
b = await b
|
|
207
248
|
}
|
|
208
249
|
|
|
209
250
|
//check
|
|
210
251
|
if (!b) {
|
|
252
|
+
console.log('userSelf', userSelf)
|
|
253
|
+
console.log(`user does not have permission`)
|
|
211
254
|
return Promise.reject(`user does not have permission`)
|
|
212
255
|
}
|
|
213
256
|
|
|
214
|
-
return
|
|
257
|
+
return userSelf
|
|
215
258
|
}
|
|
216
259
|
|
|
260
|
+
|
|
217
261
|
//getAPIsList
|
|
218
262
|
let getAPIsList = async (query = {}) => {
|
|
219
263
|
let rs = await woItems.apis.select(query)
|
|
@@ -222,7 +266,9 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
222
266
|
|
|
223
267
|
|
|
224
268
|
//parsePayload
|
|
225
|
-
let parsePayload = (req) => {
|
|
269
|
+
let parsePayload = async (req) => {
|
|
270
|
+
|
|
271
|
+
//inp
|
|
226
272
|
let inp = get(req, 'payload')
|
|
227
273
|
|
|
228
274
|
//to obj
|
|
@@ -230,37 +276,60 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
230
276
|
inp = j2o(inp)
|
|
231
277
|
}
|
|
232
278
|
|
|
233
|
-
//
|
|
234
|
-
if (iseobj(inp)) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
//apis
|
|
240
|
-
each(apis, (api, kapi) => {
|
|
241
|
-
// console.log(kapi, api.name)
|
|
242
|
-
each(api, (v, k) => {
|
|
243
|
-
// console.log(k, v)
|
|
244
|
-
if (isestr(v)) {
|
|
245
|
-
if (strleft(v, 7) === 'base64:') {
|
|
246
|
-
// console.log(k, 'get base64')
|
|
247
|
-
v = strdelleft(v, 7)
|
|
248
|
-
v = b642str(v)
|
|
249
|
-
// console.log(v)
|
|
250
|
-
apis[kapi][k] = v
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
})
|
|
254
|
-
})
|
|
279
|
+
//check
|
|
280
|
+
if (!iseobj(inp)) {
|
|
281
|
+
console.log('inp', inp)
|
|
282
|
+
console.log(`invalid inp from req`)
|
|
283
|
+
return Promise.reject(`invalid inp from req`)
|
|
284
|
+
}
|
|
255
285
|
|
|
256
|
-
|
|
257
|
-
|
|
286
|
+
//group
|
|
287
|
+
let group = get(inp, 'group', '')
|
|
258
288
|
|
|
289
|
+
//check
|
|
290
|
+
if (!isestr(group)) {
|
|
291
|
+
console.log('inp', inp)
|
|
292
|
+
console.log('group', group)
|
|
293
|
+
console.log(`invalid group from inp`)
|
|
294
|
+
return Promise.reject(`invalid group from inp`)
|
|
259
295
|
}
|
|
260
|
-
|
|
261
|
-
|
|
296
|
+
|
|
297
|
+
//apis
|
|
298
|
+
let apis = get(inp, 'apis', [])
|
|
299
|
+
|
|
300
|
+
//check
|
|
301
|
+
if (!isearr(apis)) {
|
|
302
|
+
console.log('inp', inp)
|
|
303
|
+
console.log('apis', apis)
|
|
304
|
+
console.log(`invalid apis from inp`)
|
|
305
|
+
return Promise.reject(`invalid apis from inp`)
|
|
262
306
|
}
|
|
263
307
|
|
|
308
|
+
//偵測b64自動恢復
|
|
309
|
+
each(apis, (api, kapi) => {
|
|
310
|
+
// console.log(kapi, api.name)
|
|
311
|
+
each(api, (v, k) => {
|
|
312
|
+
// console.log(k, v)
|
|
313
|
+
if (isestr(v)) {
|
|
314
|
+
if (strleft(v, 7) === 'base64:') {
|
|
315
|
+
// console.log(k, 'get base64')
|
|
316
|
+
v = strdelleft(v, 7)
|
|
317
|
+
v = b642str(v)
|
|
318
|
+
// console.log(v)
|
|
319
|
+
apis[kapi][k] = v
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
})
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
//save group
|
|
326
|
+
each(apis, (api, kapi) => {
|
|
327
|
+
apis[kapi].group = group
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
//resave
|
|
331
|
+
inp = { group, apis }
|
|
332
|
+
|
|
264
333
|
return inp
|
|
265
334
|
}
|
|
266
335
|
|
|
@@ -280,19 +349,38 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
280
349
|
}
|
|
281
350
|
|
|
282
351
|
|
|
283
|
-
//
|
|
284
|
-
let
|
|
352
|
+
//syncAndReplaceApis
|
|
353
|
+
let syncAndReplaceApis = async (params) => {
|
|
285
354
|
|
|
286
|
-
//
|
|
287
|
-
let
|
|
355
|
+
//group
|
|
356
|
+
let group = get(params, 'group', '')
|
|
288
357
|
// console.log('group', group)
|
|
289
|
-
|
|
358
|
+
|
|
359
|
+
//check
|
|
360
|
+
if (!isestr(group)) {
|
|
361
|
+
console.log('params', params)
|
|
362
|
+
console.log('group', group)
|
|
363
|
+
console.log(`invalid group`)
|
|
364
|
+
return Promise.reject(`invalid group`)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
//apis
|
|
368
|
+
let apis = get(params, 'apis', [])
|
|
369
|
+
// console.log('apis', apis)
|
|
370
|
+
|
|
371
|
+
//check
|
|
372
|
+
if (!isearr(apis)) {
|
|
373
|
+
console.log('params', params)
|
|
374
|
+
console.log('apis', apis)
|
|
375
|
+
console.log(`invalid apis`)
|
|
376
|
+
return Promise.reject(`invalid apis`)
|
|
377
|
+
}
|
|
290
378
|
|
|
291
379
|
//delAll group
|
|
292
380
|
await woItems.apis.delAll({ group })
|
|
293
381
|
|
|
294
382
|
//insert
|
|
295
|
-
let r = await woItems.apis.insert(
|
|
383
|
+
let r = await woItems.apis.insert(apis)
|
|
296
384
|
|
|
297
385
|
return r
|
|
298
386
|
}
|
|
@@ -312,9 +400,18 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
312
400
|
let fnEntryOut = 'index.html'
|
|
313
401
|
try {
|
|
314
402
|
let fpEntryIn = path.resolve(pathStaticFiles, fnEntryIn)
|
|
403
|
+
if (!fsIsFile(fpEntryIn)) {
|
|
404
|
+
fpEntryIn = path.resolve(pathStaticFiles, fnEntryOut) //本機開發另使用html替代tmp
|
|
405
|
+
}
|
|
406
|
+
if (!fsIsFile(fpEntryIn)) {
|
|
407
|
+
console.log('fpEntryIn', fpEntryIn)
|
|
408
|
+
throw new Error(`invalid fpEntryIn`)
|
|
409
|
+
}
|
|
315
410
|
let fpEntryOut = path.resolve(pathStaticFiles, fnEntryOut)
|
|
316
411
|
let c = fs.readFileSync(fpEntryIn, 'utf8')
|
|
412
|
+
c = replace(c, '/mapi/', '{sfd}/') //方法同genEntry
|
|
317
413
|
c = replace(c, '{sfd}', subfolder)
|
|
414
|
+
c = replace(c, '{urlRedirect}', urlRedirect)
|
|
318
415
|
fs.writeFileSync(fpEntryOut, c, 'utf8')
|
|
319
416
|
}
|
|
320
417
|
catch (err) {
|
|
@@ -354,8 +451,16 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
354
451
|
//token
|
|
355
452
|
let token = get(req, 'query.token', '')
|
|
356
453
|
|
|
357
|
-
//
|
|
358
|
-
let user = await
|
|
454
|
+
//getTokenUserForSelf
|
|
455
|
+
let user = await getTokenUserForSelf(token)
|
|
456
|
+
|
|
457
|
+
//check
|
|
458
|
+
if (!iseobj(user)) {
|
|
459
|
+
console.log('token', token)
|
|
460
|
+
console.log('[API]getUserByToken/check user: invalid user')
|
|
461
|
+
console.log(`token does not have permission`)
|
|
462
|
+
return Promise.reject(`token does not have permission`)
|
|
463
|
+
}
|
|
359
464
|
|
|
360
465
|
return user
|
|
361
466
|
}
|
|
@@ -378,8 +483,16 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
378
483
|
//token
|
|
379
484
|
let token = get(req, 'query.token', '')
|
|
380
485
|
|
|
381
|
-
//
|
|
382
|
-
await
|
|
486
|
+
//getTokenUserForSelf
|
|
487
|
+
let user = await getTokenUserForSelf(token)
|
|
488
|
+
|
|
489
|
+
//check
|
|
490
|
+
if (!iseobj(user)) {
|
|
491
|
+
console.log('token', token)
|
|
492
|
+
console.log('[API]getAPIsList/check user: invalid user')
|
|
493
|
+
console.log(`token does not have permission`)
|
|
494
|
+
return Promise.reject(`token does not have permission`)
|
|
495
|
+
}
|
|
383
496
|
|
|
384
497
|
//getAPIsList
|
|
385
498
|
let r = await getAPIsList({ isActive: 'y' })
|
|
@@ -406,11 +519,19 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
406
519
|
//token
|
|
407
520
|
let token = get(req, 'query.token', '')
|
|
408
521
|
|
|
409
|
-
//
|
|
410
|
-
await
|
|
522
|
+
//getTokenUserForSelf
|
|
523
|
+
let user = await getTokenUserForSelf(token)
|
|
524
|
+
|
|
525
|
+
//check
|
|
526
|
+
if (!iseobj(user)) {
|
|
527
|
+
console.log('token', token)
|
|
528
|
+
console.log('[API]updateAPIs/check user: invalid user')
|
|
529
|
+
console.log(`token does not have permission`)
|
|
530
|
+
return Promise.reject(`token does not have permission`)
|
|
531
|
+
}
|
|
411
532
|
|
|
412
533
|
//parsePayload
|
|
413
|
-
let inp = parsePayload(req)
|
|
534
|
+
let inp = await parsePayload(req)
|
|
414
535
|
|
|
415
536
|
//updateAPIs
|
|
416
537
|
let r = await updateAPIs(inp)
|
|
@@ -427,9 +548,9 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
427
548
|
},
|
|
428
549
|
{
|
|
429
550
|
method: 'POST',
|
|
430
|
-
path: '/
|
|
551
|
+
path: '/syncAndReplaceApis',
|
|
431
552
|
handler: async function (req, res) {
|
|
432
|
-
// console.log('
|
|
553
|
+
// console.log('syncAndReplaceApis', req)
|
|
433
554
|
// console.log('payload', req.payload)
|
|
434
555
|
|
|
435
556
|
async function core() {
|
|
@@ -437,14 +558,22 @@ function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
|
437
558
|
//token
|
|
438
559
|
let token = get(req, 'query.token', '')
|
|
439
560
|
|
|
440
|
-
//
|
|
441
|
-
await
|
|
561
|
+
//getTokenUserForSelf
|
|
562
|
+
let user = await getTokenUserForSelf(token)
|
|
563
|
+
|
|
564
|
+
//check
|
|
565
|
+
if (!iseobj(user)) {
|
|
566
|
+
console.log('token', token)
|
|
567
|
+
console.log('[API]syncAndReplaceApis/check user: invalid user')
|
|
568
|
+
console.log(`token does not have permission`)
|
|
569
|
+
return Promise.reject(`token does not have permission`)
|
|
570
|
+
}
|
|
442
571
|
|
|
443
572
|
//parsePayload
|
|
444
|
-
let inp = parsePayload(req)
|
|
573
|
+
let inp = await parsePayload(req)
|
|
445
574
|
|
|
446
|
-
//
|
|
447
|
-
let r = await
|
|
575
|
+
//syncAndReplaceApis
|
|
576
|
+
let r = await syncAndReplaceApis(inp)
|
|
448
577
|
|
|
449
578
|
return r
|
|
450
579
|
}
|
package/server/provideApis.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import genPm from 'wsemi/src/genPm.mjs'
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
async function provideApis(url, group, apis) {
|
|
7
|
-
//url: 指API伺服器提供的接入網址, 例如 http://localhost:11005/
|
|
8
|
-
//group: 指API
|
|
7
|
+
//url: 指API伺服器提供的接入網址, 例如 http://localhost:11005/syncAndReplaceApis
|
|
8
|
+
//group: 指API所屬群組
|
|
9
9
|
|
|
10
10
|
//pm
|
|
11
11
|
let pm = genPm()
|
package/src/App.vue
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
<script>
|
|
17
17
|
import get from 'lodash/get'
|
|
18
18
|
import cloneDeep from 'lodash/cloneDeep'
|
|
19
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
20
|
+
import isDev from 'wsemi/src/isDev.mjs'
|
|
19
21
|
import wui from 'w-ui-loginout/src/WUiLoginout.mjs'
|
|
20
22
|
import Layout from './components/Layout.vue'
|
|
21
23
|
import LayoutState from './components/LayoutState.vue'
|
|
@@ -50,12 +52,25 @@ export default {
|
|
|
50
52
|
console.log('login error', cloneDeep(data))
|
|
51
53
|
vo.$ui.updateConnState(data.text)
|
|
52
54
|
vo.$ui.updateUserToken('')
|
|
53
|
-
|
|
55
|
+
let urlRedirect = get(window, '___pmwapi___.urlRedirect', '')
|
|
56
|
+
if (!isestr(urlRedirect)) {
|
|
57
|
+
console.log('urlRedirect', urlRedirect)
|
|
58
|
+
throw new Error(`invalid urlRedirect`)
|
|
59
|
+
}
|
|
60
|
+
if (isDev()) {
|
|
61
|
+
console.log('60s redirect to:', urlRedirect)
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
window.location.href = urlRedirect
|
|
64
|
+
}, 60 * 1000)
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
window.location.href = urlRedirect
|
|
68
|
+
}
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
//login
|
|
57
72
|
console.log('login...')
|
|
58
|
-
let ll = wui('
|
|
73
|
+
let ll = wui('wapi', {
|
|
59
74
|
timeWaitAnimation: 2000,
|
|
60
75
|
params: {},
|
|
61
76
|
})
|
|
@@ -110,14 +125,6 @@ button {
|
|
|
110
125
|
font-family: inherit;
|
|
111
126
|
}
|
|
112
127
|
|
|
113
|
-
.v-application, .v-application--wrap {
|
|
114
|
-
font-family: inherit;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.v-chip {
|
|
118
|
-
cursor: inherit;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
128
|
.fade-enter-active {
|
|
122
129
|
animation: go 1s;
|
|
123
130
|
}
|
|
@@ -8,21 +8,20 @@
|
|
|
8
8
|
|
|
9
9
|
<template v-if="syncState">
|
|
10
10
|
|
|
11
|
-
<!-- menu left, 使用opacity:0.999讓WDrawer使用浮動模式時不會遮蔽vuetify彈窗, 僅由Layout處設定即可, 其內dom皆受影響 -->
|
|
12
11
|
<WDrawer
|
|
13
|
-
:style="`height:${panelHeight}px; width:100
|
|
12
|
+
:style="`height:${panelHeight}px; width:100%;`"
|
|
14
13
|
v-model="drawer"
|
|
15
14
|
:drawerWidth.sync="drawerWidth"
|
|
16
15
|
:drawerWidthMin="drawerWidthMin"
|
|
17
16
|
:drawerWidthMax="drawerWidthMax"
|
|
18
17
|
:mode="'from-left'"
|
|
19
|
-
:afloat="drawerAfloat"
|
|
20
18
|
:dragDrawerWidth="true"
|
|
19
|
+
:autoSwitch="true"
|
|
20
|
+
:switchWidth="drawerWidth*2.3"
|
|
21
21
|
>
|
|
22
22
|
|
|
23
23
|
<template v-slot:drawer="props">
|
|
24
|
-
|
|
25
|
-
<div :style="`height:${props.height}px; background:${drawerAfloat?'#fff':'transparent'}; position:relative;`">
|
|
24
|
+
<div :style="`height:${props.height}px; background:#fff; position:relative;`">
|
|
26
25
|
|
|
27
26
|
<WTree
|
|
28
27
|
:style="`height:${props.height}px;`"
|
|
@@ -87,7 +86,6 @@
|
|
|
87
86
|
</div>
|
|
88
87
|
|
|
89
88
|
</div>
|
|
90
|
-
|
|
91
89
|
</template>
|
|
92
90
|
|
|
93
91
|
<template v-slot:content="props">
|
|
@@ -327,7 +325,10 @@
|
|
|
327
325
|
|
|
328
326
|
<div style="border:1px solid #ddd; background:#fff">
|
|
329
327
|
|
|
330
|
-
<div
|
|
328
|
+
<div
|
|
329
|
+
style="padding:10px 15px;"
|
|
330
|
+
v-if="optputMenuItemSelectId==='tree'"
|
|
331
|
+
>
|
|
331
332
|
<WJsonView
|
|
332
333
|
style="width:100%;"
|
|
333
334
|
:viewHeightMax="null"
|
|
@@ -335,8 +336,11 @@
|
|
|
335
336
|
></WJsonView>
|
|
336
337
|
</div>
|
|
337
338
|
|
|
338
|
-
<div
|
|
339
|
-
|
|
339
|
+
<div
|
|
340
|
+
style="padding:15px; color:#555; font-size:0.85rem;"
|
|
341
|
+
v-if="optputMenuItemSelectId==='raw'
|
|
342
|
+
">
|
|
343
|
+
<pre style="margin:0px; padding:0px;">{{getOutputJson(apiSelect)}}</pre>
|
|
340
344
|
</div>
|
|
341
345
|
|
|
342
346
|
</div>
|
|
@@ -430,11 +434,9 @@ export default {
|
|
|
430
434
|
return {
|
|
431
435
|
|
|
432
436
|
panelWidth: 0,
|
|
433
|
-
panelWidthTemp: 0,
|
|
434
437
|
panelHeight: 0,
|
|
435
438
|
|
|
436
439
|
drawer: true,
|
|
437
|
-
drawerAfloat: false,
|
|
438
440
|
drawerWidth: 320,
|
|
439
441
|
drawerWidthMin: 200,
|
|
440
442
|
drawerWidthMax: 700,
|
|
@@ -512,30 +514,6 @@ export default {
|
|
|
512
514
|
vo.panelHeight = msg.snew.clientHeight
|
|
513
515
|
// console.log('vo.panelHeight', vo.panelHeight)
|
|
514
516
|
|
|
515
|
-
//modeResize
|
|
516
|
-
let modeResize = '' //寬度可能相同故得有預設空字串的種類
|
|
517
|
-
if (vo.panelWidth > vo.panelWidthTemp) {
|
|
518
|
-
modeResize = 'toLarge'
|
|
519
|
-
}
|
|
520
|
-
else if (vo.panelWidth < vo.panelWidthTemp) {
|
|
521
|
-
modeResize = 'toSmall'
|
|
522
|
-
}
|
|
523
|
-
// console.log('modeResize', modeResize, vo.panelWidth, vo.panelWidthTemp)
|
|
524
|
-
|
|
525
|
-
//drawer
|
|
526
|
-
if (vo.drawer && modeResize === 'toSmall' && vo.panelWidth < 1.7 * vo.drawerWidthMax) { //已開啟抽屜且為變窄時才偵測
|
|
527
|
-
vo.drawer = false
|
|
528
|
-
}
|
|
529
|
-
else if (!vo.drawer && modeResize === 'toLarge' && vo.panelWidth >= 1.7 * vo.drawerWidthMax) { //已隱藏抽屜且為變寬時才偵測
|
|
530
|
-
vo.drawer = true
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
//drawerAfloat
|
|
534
|
-
vo.drawerAfloat = vo.panelWidth < 1.7 * vo.drawerWidthMax
|
|
535
|
-
|
|
536
|
-
//save
|
|
537
|
-
vo.panelWidthTemp = vo.panelWidth
|
|
538
|
-
|
|
539
517
|
},
|
|
540
518
|
|
|
541
519
|
genTree: function () {
|
|
@@ -574,6 +552,8 @@ export default {
|
|
|
574
552
|
let tree = convertToTree(tr, { bindRoot: '全部' })
|
|
575
553
|
// console.log('tree', cloneDeep(tree))
|
|
576
554
|
|
|
555
|
+
//filepathToTree
|
|
556
|
+
|
|
577
557
|
//apiSelect, 預先選定api項目, 非tree選單active物件, 因id由convertToTree轉換提供, 故不能直接算得active選單物件id
|
|
578
558
|
let apiSelect = get(apis, 0, null)
|
|
579
559
|
// console.log('apiSelect', cloneDeep(apiSelect))
|
package/src/main.js
CHANGED
|
@@ -11,7 +11,6 @@ import domResize from 'w-component-vue/src/js/domResize.mjs'
|
|
|
11
11
|
import domDragDrop from 'w-component-vue/src/js/domDragDrop.mjs'
|
|
12
12
|
import App from './App.vue'
|
|
13
13
|
import store from './store/index.mjs'
|
|
14
|
-
import mVuetify from './plugins/mVuetify.mjs'
|
|
15
14
|
import ui from './plugins/mUI.mjs'
|
|
16
15
|
import mDataSelectorSchema from './plugins/mDataSelectorSchema.mjs'
|
|
17
16
|
import mDataSupport from './plugins/mDataSupport.mjs'
|
|
@@ -96,7 +95,6 @@ WServHapiClient({
|
|
|
96
95
|
|
|
97
96
|
//new
|
|
98
97
|
new Vue({
|
|
99
|
-
vuetify: mVuetify,
|
|
100
98
|
store,
|
|
101
99
|
render: h => h(App)
|
|
102
100
|
}).$mount('#app')
|
package/src/store/mutations.mjs
CHANGED
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
import each from 'lodash/each'
|
|
2
2
|
import set from 'lodash/set'
|
|
3
|
-
import cloneDeep from 'lodash/cloneDeep'
|
|
4
3
|
import * as types from './types.mjs'
|
|
5
4
|
import ds from '../schema/index.mjs'
|
|
6
5
|
|
|
7
6
|
|
|
8
|
-
//userDef
|
|
9
|
-
let userDef = {
|
|
10
|
-
id: '', //id-for-admin
|
|
11
|
-
name: '', //測試者
|
|
12
|
-
email: '', //id-for-admin@gmail.com
|
|
13
|
-
// isVirtual: 'n',
|
|
14
|
-
isAdmin: 'n',
|
|
15
|
-
// isActive: 'n',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
7
|
//state, 全域狀態
|
|
19
8
|
let state = {
|
|
20
9
|
|
|
@@ -35,8 +24,12 @@ let state = {
|
|
|
35
24
|
menu: {}, //初始值需為物件, 否則LayoutContent會取menu.key出錯
|
|
36
25
|
|
|
37
26
|
userToken: '',
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
user: {
|
|
28
|
+
id: '', //id-for-admin
|
|
29
|
+
name: '', //測試者
|
|
30
|
+
email: '', //admin@example.com
|
|
31
|
+
isAdmin: 'n',
|
|
32
|
+
},
|
|
40
33
|
|
|
41
34
|
lang: 'cht',
|
|
42
35
|
keyLangs: {
|