@questwork/q-utilities 0.1.0 → 0.1.2
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/dist/index.min.cjs +1154 -0
- package/dist/index.min.js +1140 -0
- package/package.json +29 -13
- package/index.js +0 -3
- package/lib/authenticator/authenticator.js +0 -56
- package/lib/authenticator/clientApp.js +0 -46
- package/lib/authenticator/index.js +0 -5
- package/lib/convertString/convertString.js +0 -20
- package/lib/convertString/index.js +0 -1
- package/lib/cryptoHelper/cryptoHelper.js +0 -93
- package/lib/cryptoHelper/index.js +0 -5
- package/lib/getValidation/getValidation.js +0 -117
- package/lib/getValidation/index.js +0 -1
- package/lib/getValueByKeys/getValueByKeys.js +0 -20
- package/lib/getValueByKeys/index.js +0 -1
- package/lib/index.js +0 -14
- package/lib/jwtHelper/index.js +0 -5
- package/lib/jwtHelper/jwtHelper.js +0 -254
- package/lib/keyValueObject/index.js +0 -1
- package/lib/keyValueObject/keyValueObject.js +0 -163
|
@@ -0,0 +1,1154 @@
|
|
|
1
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
+
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
else if(typeof define === 'function' && define.amd)
|
|
5
|
+
define([], factory);
|
|
6
|
+
else {
|
|
7
|
+
var a = factory();
|
|
8
|
+
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
|
|
9
|
+
}
|
|
10
|
+
})(this, () => {
|
|
11
|
+
return /******/ (() => { // webpackBootstrap
|
|
12
|
+
/******/ "use strict";
|
|
13
|
+
/******/ // The require scope
|
|
14
|
+
/******/ var __webpack_require__ = {};
|
|
15
|
+
/******/
|
|
16
|
+
/************************************************************************/
|
|
17
|
+
/******/ /* webpack/runtime/define property getters */
|
|
18
|
+
/******/ (() => {
|
|
19
|
+
/******/ // define getter functions for harmony exports
|
|
20
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
|
21
|
+
/******/ for(var key in definition) {
|
|
22
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
23
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
24
|
+
/******/ }
|
|
25
|
+
/******/ }
|
|
26
|
+
/******/ };
|
|
27
|
+
/******/ })();
|
|
28
|
+
/******/
|
|
29
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
30
|
+
/******/ (() => {
|
|
31
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
32
|
+
/******/ })();
|
|
33
|
+
/******/
|
|
34
|
+
/******/ /* webpack/runtime/make namespace object */
|
|
35
|
+
/******/ (() => {
|
|
36
|
+
/******/ // define __esModule on exports
|
|
37
|
+
/******/ __webpack_require__.r = (exports) => {
|
|
38
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
39
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
40
|
+
/******/ }
|
|
41
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
42
|
+
/******/ };
|
|
43
|
+
/******/ })();
|
|
44
|
+
/******/
|
|
45
|
+
/************************************************************************/
|
|
46
|
+
var __webpack_exports__ = {};
|
|
47
|
+
// ESM COMPAT FLAG
|
|
48
|
+
__webpack_require__.r(__webpack_exports__);
|
|
49
|
+
|
|
50
|
+
// EXPORTS
|
|
51
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
52
|
+
ApiResponse: () => (/* reexport */ ApiResponse),
|
|
53
|
+
KeyValueObject: () => (/* reexport */ KeyValueObject),
|
|
54
|
+
Metadata: () => (/* reexport */ Metadata),
|
|
55
|
+
Repo: () => (/* reexport */ Repo),
|
|
56
|
+
Service: () => (/* reexport */ Service),
|
|
57
|
+
convertString: () => (/* reexport */ convertString),
|
|
58
|
+
formatDate: () => (/* reexport */ formatDate),
|
|
59
|
+
getValidation: () => (/* reexport */ getValidation),
|
|
60
|
+
getValueByKeys: () => (/* reexport */ getValueByKeys),
|
|
61
|
+
jwtHelper: () => (/* reexport */ jwtHelper),
|
|
62
|
+
makeApiResponse: () => (/* reexport */ makeApiResponse),
|
|
63
|
+
makeService: () => (/* reexport */ makeService),
|
|
64
|
+
padZeros: () => (/* reexport */ padZeros),
|
|
65
|
+
stringFormatter: () => (/* reexport */ stringFormatter)
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
;// ./lib/helpers/convertString/convertString.js
|
|
69
|
+
function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByKeys) {
|
|
70
|
+
if (!string || typeof getValueByKeys !== 'function') {
|
|
71
|
+
return ''
|
|
72
|
+
}
|
|
73
|
+
const reg = new RegExp(patternMatch, 'g')
|
|
74
|
+
return string.replace(reg, (match, key) => {
|
|
75
|
+
const result = getValueByKeys({ keys: key.split('.'), obj: value })
|
|
76
|
+
if (result === null || result === undefined) {
|
|
77
|
+
return ''
|
|
78
|
+
}
|
|
79
|
+
return typeof result === 'object' ? JSON.stringify(result) : result
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* harmony default export */ const convertString_convertString = ({
|
|
84
|
+
convertString
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
;// ./lib/helpers/convertString/index.js
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
;// ./lib/helpers/formatDate/formatDate.js
|
|
92
|
+
|
|
93
|
+
function formatDate(date, format) {
|
|
94
|
+
const _date = date && date instanceof Date ? date : new Date(date)
|
|
95
|
+
const dayMapChi = ['日','一','二','三','四','五','六']
|
|
96
|
+
const dayMapEng = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
|
|
97
|
+
const dayMapEngShort = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
|
|
98
|
+
const _format = format || 'YYYY/MM/DD hh:mm'
|
|
99
|
+
const e = _date.getDay()
|
|
100
|
+
const ee = dayMapEngShort[e]
|
|
101
|
+
const eee = dayMapChi[e]
|
|
102
|
+
const eeee = dayMapEng[e]
|
|
103
|
+
const y = _date.getFullYear()
|
|
104
|
+
const m = _date.getMonth() + 1
|
|
105
|
+
const d = _date.getDate()
|
|
106
|
+
const h = _date.getHours()
|
|
107
|
+
const mm = _date.getMinutes()
|
|
108
|
+
const s = _date.getSeconds()
|
|
109
|
+
|
|
110
|
+
return _format.replace('YYYY', y)
|
|
111
|
+
.replace('MM', padding(m))
|
|
112
|
+
.replace('MM', padding(m))
|
|
113
|
+
.replace('DD', padding(d))
|
|
114
|
+
.replace('hh', padding(h))
|
|
115
|
+
.replace('mm', padding(mm))
|
|
116
|
+
.replace('ss', padding(s))
|
|
117
|
+
.replace('M', m)
|
|
118
|
+
.replace('D', d)
|
|
119
|
+
.replace('h', h)
|
|
120
|
+
.replace('m', mm)
|
|
121
|
+
.replace('s', s)
|
|
122
|
+
.replace('EEEE', padding(eeee))
|
|
123
|
+
.replace('EEE', padding(eee))
|
|
124
|
+
.replace('EE', padding(ee))
|
|
125
|
+
.replace('E', padding(e))
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function padding(m) {
|
|
129
|
+
return m < 10 ? `0${m}` : m
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
/* harmony default export */ const formatDate_formatDate = ({
|
|
134
|
+
formatDate
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
;// ./lib/helpers/formatDate/index.js
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
;// ./lib/helpers/getValidation/getValidation.js
|
|
143
|
+
function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
144
|
+
if (!rule) {
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
147
|
+
if (typeof getDataByKey !== 'function' || typeof KeyValueObject !== 'function') {
|
|
148
|
+
return false
|
|
149
|
+
}
|
|
150
|
+
const { key = '', value, keyValuePath = '' } = rule
|
|
151
|
+
const [valueAttribute] = Object.keys(value)
|
|
152
|
+
|
|
153
|
+
if (!key) {
|
|
154
|
+
switch (valueAttribute) {
|
|
155
|
+
case '$and': {
|
|
156
|
+
return value['$and'].reduce((acc, item) => (acc && getValidation(item, data, getDataByKey, KeyValueObject)), true)
|
|
157
|
+
}
|
|
158
|
+
case '$or': {
|
|
159
|
+
return value['$or'].reduce((acc, item) => (acc || getValidation(item, data, getDataByKey, KeyValueObject)), false)
|
|
160
|
+
}
|
|
161
|
+
default:
|
|
162
|
+
return false
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let rowValue = getDataByKey(key, data)
|
|
167
|
+
|
|
168
|
+
// debugger
|
|
169
|
+
|
|
170
|
+
// if KeyValue object
|
|
171
|
+
if (keyValuePath) {
|
|
172
|
+
console.log('keyValuePath', keyValuePath)
|
|
173
|
+
const rowValueData = KeyValueObject.toObject(rowValue)
|
|
174
|
+
rowValue = getDataByKey(keyValuePath, rowValueData)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
switch (valueAttribute) {
|
|
178
|
+
case '$empty': {
|
|
179
|
+
const isEmpty = rowValue === null || rowValue === undefined
|
|
180
|
+
return isEmpty === value['$empty']
|
|
181
|
+
}
|
|
182
|
+
case '$eq': {
|
|
183
|
+
return rowValue === value['$eq']
|
|
184
|
+
}
|
|
185
|
+
case '$gt': {
|
|
186
|
+
return rowValue > value['$gt']
|
|
187
|
+
}
|
|
188
|
+
case '$gte': {
|
|
189
|
+
return rowValue >= value['$gte']
|
|
190
|
+
}
|
|
191
|
+
case '$lt': {
|
|
192
|
+
return rowValue < value['$lt']
|
|
193
|
+
}
|
|
194
|
+
case '$lte': {
|
|
195
|
+
return rowValue <= value['$lte']
|
|
196
|
+
}
|
|
197
|
+
case '$in': {
|
|
198
|
+
if (Array.isArray(rowValue)) {
|
|
199
|
+
return !!rowValue.find((e) => (value['$in'].includes(e)))
|
|
200
|
+
}
|
|
201
|
+
if (typeof rowValue !== 'object') {
|
|
202
|
+
return !!value['$in'].includes(rowValue)
|
|
203
|
+
}
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
case '$inValue': {
|
|
207
|
+
const result = getDataByKey(value['$inValue'], data)
|
|
208
|
+
const _value = Array.isArray(result) ? result : []
|
|
209
|
+
if (Array.isArray(rowValue)) {
|
|
210
|
+
return !!rowValue.find((e) => (_value.includes(e)))
|
|
211
|
+
}
|
|
212
|
+
if (typeof rowValue === 'string') {
|
|
213
|
+
return !!_value.includes(rowValue)
|
|
214
|
+
}
|
|
215
|
+
return false
|
|
216
|
+
}
|
|
217
|
+
case '$ne': {
|
|
218
|
+
return rowValue !== value['$ne']
|
|
219
|
+
}
|
|
220
|
+
case '$notIn': {
|
|
221
|
+
if (Array.isArray(rowValue)) {
|
|
222
|
+
return !rowValue.find((e) => (value['$notIn'].includes(e)))
|
|
223
|
+
}
|
|
224
|
+
if (typeof rowValue !== 'object') {
|
|
225
|
+
return !value['$notIn'].includes(rowValue)
|
|
226
|
+
}
|
|
227
|
+
return false
|
|
228
|
+
}
|
|
229
|
+
case '$notInValue': {
|
|
230
|
+
const result = getDataByKey(value['$notInValue'], data)
|
|
231
|
+
const _value = Array.isArray(result) ? result : []
|
|
232
|
+
if (Array.isArray(rowValue)) {
|
|
233
|
+
return !rowValue.find((e) => (_value.includes(e)))
|
|
234
|
+
}
|
|
235
|
+
if (typeof rowValue !== 'object') {
|
|
236
|
+
return !_value.includes(rowValue)
|
|
237
|
+
}
|
|
238
|
+
return false
|
|
239
|
+
}
|
|
240
|
+
case '$range': {
|
|
241
|
+
const [min, max] = value['$range']
|
|
242
|
+
if (typeof min === 'number' && typeof max === 'number' && rowValue >= min && rowValue <= max) {
|
|
243
|
+
return true
|
|
244
|
+
}
|
|
245
|
+
return false
|
|
246
|
+
}
|
|
247
|
+
default:
|
|
248
|
+
return false
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* harmony default export */ const getValidation_getValidation = ({
|
|
253
|
+
getValidation
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
;// ./lib/helpers/getValidation/index.js
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
;// ./lib/helpers/getValueByKeys/getValueByKeys.js
|
|
261
|
+
// keys can be array or string
|
|
262
|
+
function getValueByKeys(keys, data) {
|
|
263
|
+
let _keys = keys
|
|
264
|
+
let _data = data
|
|
265
|
+
if (!Array.isArray(keys)) {
|
|
266
|
+
const { keys: keyArr, obj } = keys
|
|
267
|
+
_keys = keyArr
|
|
268
|
+
_data = obj
|
|
269
|
+
}
|
|
270
|
+
if (_keys.length === 0) {
|
|
271
|
+
return _data
|
|
272
|
+
}
|
|
273
|
+
const firstKey = _keys.shift()
|
|
274
|
+
if (_data && Object.prototype.hasOwnProperty.call(_data, firstKey)) {
|
|
275
|
+
return getValueByKeys(_keys, _data[firstKey])
|
|
276
|
+
}
|
|
277
|
+
if (_data && firstKey) {
|
|
278
|
+
return _data[firstKey]
|
|
279
|
+
}
|
|
280
|
+
return _data
|
|
281
|
+
|
|
282
|
+
}
|
|
283
|
+
/* harmony default export */ const getValueByKeys_getValueByKeys = ({
|
|
284
|
+
getValueByKeys
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
;// ./lib/helpers/getValueByKeys/index.js
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
;// ./lib/helpers/jwtHelper/jwtHelper.js
|
|
293
|
+
// 'use strict'
|
|
294
|
+
|
|
295
|
+
/* eslint-disable new-cap */
|
|
296
|
+
/* eslint-disable camelcase */
|
|
297
|
+
/* eslint-disable no-mixed-operators */
|
|
298
|
+
/* eslint-disable no-useless-escape */
|
|
299
|
+
/* eslint-disable no-param-reassign */
|
|
300
|
+
|
|
301
|
+
/* eslint func-names: 0 */
|
|
302
|
+
|
|
303
|
+
// const Buffer = require('buffer/').Buffer
|
|
304
|
+
|
|
305
|
+
const EXPIRY = 3600 // in second
|
|
306
|
+
const ALGORITHM = 'HS256'
|
|
307
|
+
const SECRET = 'ab1234cd'
|
|
308
|
+
|
|
309
|
+
const _hasBuffer = typeof Buffer === 'function'
|
|
310
|
+
|
|
311
|
+
const jwtHelper = {
|
|
312
|
+
create(obj, { secret, algorithm, expiry } = {}) {
|
|
313
|
+
const sAlgorithm = algorithm || ALGORITHM
|
|
314
|
+
const sSecret = secret || SECRET
|
|
315
|
+
const exp = expiry || getTimeInSecond() + EXPIRY
|
|
316
|
+
const payload = {
|
|
317
|
+
...obj,
|
|
318
|
+
exp
|
|
319
|
+
}
|
|
320
|
+
return encode(payload, sSecret, sAlgorithm)
|
|
321
|
+
},
|
|
322
|
+
createByUser(loginAccount) {
|
|
323
|
+
const exp = getTimeInSecond() + EXPIRY
|
|
324
|
+
const payload = {
|
|
325
|
+
loginAccount,
|
|
326
|
+
exp
|
|
327
|
+
}
|
|
328
|
+
return this.encode(payload)
|
|
329
|
+
},
|
|
330
|
+
encode(payload, algorithm) {
|
|
331
|
+
return encode(payload, SECRET, algorithm)
|
|
332
|
+
},
|
|
333
|
+
decode(token, algorithm) {
|
|
334
|
+
const noVerify = !this.verify(token)
|
|
335
|
+
return decode(token, SECRET, noVerify, algorithm) // if noVerify = true, may skip verification
|
|
336
|
+
},
|
|
337
|
+
getPayload(token) {
|
|
338
|
+
const payload = getPayload(token)
|
|
339
|
+
return {
|
|
340
|
+
payload
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
getPayloadIdByKey(token, key) {
|
|
344
|
+
const payload = getPayload(token)
|
|
345
|
+
const id = payload[key] ? payload[key].id : null
|
|
346
|
+
return {
|
|
347
|
+
id,
|
|
348
|
+
jwtToken: token
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
resolve(token, secret, algorithm) {
|
|
352
|
+
const sSecret = secret || SECRET
|
|
353
|
+
return decode(token, sSecret, false, algorithm) // need verification
|
|
354
|
+
},
|
|
355
|
+
verify(token) {
|
|
356
|
+
const payload = getPayload(token)
|
|
357
|
+
const today = getTimeInSecond()
|
|
358
|
+
return (payload.exp && (today <= payload.exp)) || false
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Private functions
|
|
364
|
+
*/
|
|
365
|
+
|
|
366
|
+
const getPayload = (token) => decode(token, SECRET, true)
|
|
367
|
+
|
|
368
|
+
const getTimeInSecond = () => Math.floor(Date.now() / 1000)
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Private functions, based on jwt-simple 0.2.0
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
const { cryptoHelper } = require('../cryptoHelper')
|
|
375
|
+
|
|
376
|
+
const algorithmMap = {
|
|
377
|
+
HS256: 'sha256',
|
|
378
|
+
HS384: 'sha384',
|
|
379
|
+
HS512: 'sha512',
|
|
380
|
+
RS256: 'RSA-SHA256'
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const typeMap = {
|
|
384
|
+
HS256: 'hmac',
|
|
385
|
+
HS384: 'hmac',
|
|
386
|
+
HS512: 'hmac',
|
|
387
|
+
RS256: 'sign'
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Decode jwt
|
|
393
|
+
*
|
|
394
|
+
* @param {Object} token
|
|
395
|
+
* @param {String} key
|
|
396
|
+
* @param {Boolean} noVerify
|
|
397
|
+
* @param {String} algorithm
|
|
398
|
+
* @return {Object} payload
|
|
399
|
+
* @api public
|
|
400
|
+
*/
|
|
401
|
+
const decode = function jwt_decode(token, key, noVerify, algorithm) {
|
|
402
|
+
// check token
|
|
403
|
+
if (!token) {
|
|
404
|
+
throw new Error('No token supplied')
|
|
405
|
+
}
|
|
406
|
+
// check segments
|
|
407
|
+
const segments = token.split('.')
|
|
408
|
+
if (segments.length !== 3) {
|
|
409
|
+
throw new Error('Not enough or too many segments')
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// All segment should be base64
|
|
413
|
+
const headerSeg = segments[0]
|
|
414
|
+
const payloadSeg = segments[1]
|
|
415
|
+
const signatureSeg = segments[2]
|
|
416
|
+
|
|
417
|
+
// base64 decode and parse JSON
|
|
418
|
+
const header = JSON.parse(base64urlDecode(headerSeg))
|
|
419
|
+
|
|
420
|
+
const payload = JSON.parse(base64urlDecode(payloadSeg))
|
|
421
|
+
|
|
422
|
+
if (!noVerify) {
|
|
423
|
+
const signingMethod = algorithmMap[algorithm || header.alg]
|
|
424
|
+
const signingType = typeMap[algorithm || header.alg]
|
|
425
|
+
if (!signingMethod || !signingType) {
|
|
426
|
+
throw new Error('Algorithm not supported')
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// verify signature. `sign` will return base64 string.
|
|
430
|
+
const signingInput = [headerSeg, payloadSeg].join('.')
|
|
431
|
+
if (!verify(signingInput, key, signingMethod, signingType, signatureSeg)) {
|
|
432
|
+
throw new Error('Signature verification failed')
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return payload
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Encode jwt
|
|
442
|
+
*
|
|
443
|
+
* @param {Object} payload
|
|
444
|
+
* @param {String} key
|
|
445
|
+
* @param {String} algorithm
|
|
446
|
+
* @return {String} token
|
|
447
|
+
* @api public
|
|
448
|
+
*/
|
|
449
|
+
const encode = function jwt_encode(payload, key, algorithm) {
|
|
450
|
+
// Check key
|
|
451
|
+
if (!key) {
|
|
452
|
+
throw new Error('Require key')
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Check algorithm, default is HS256
|
|
456
|
+
if (!algorithm) {
|
|
457
|
+
algorithm = ALGORITHM
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const signingMethod = algorithmMap[algorithm]
|
|
461
|
+
const signingType = typeMap[algorithm]
|
|
462
|
+
if (!signingMethod || !signingType) {
|
|
463
|
+
throw new Error('Algorithm not supported')
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// header, typ is fixed value.
|
|
467
|
+
const header = { typ: 'JWT', alg: algorithm }
|
|
468
|
+
|
|
469
|
+
// create segments, all segments should be base64 string
|
|
470
|
+
const segments = []
|
|
471
|
+
segments.push(base64urlEncode(JSON.stringify(header)))
|
|
472
|
+
segments.push(base64urlEncode(JSON.stringify(payload)))
|
|
473
|
+
segments.push(sign(segments.join('.'), key, signingMethod, signingType))
|
|
474
|
+
|
|
475
|
+
return segments.join('.')
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* private util functions
|
|
481
|
+
*/
|
|
482
|
+
|
|
483
|
+
function verify(input, key, method, type, signature) {
|
|
484
|
+
if (type === 'hmac') {
|
|
485
|
+
return (signature === sign(input, key, method, type))
|
|
486
|
+
} else if (type === 'sign') {
|
|
487
|
+
try {
|
|
488
|
+
return cryptoHelper.createStringVerify({
|
|
489
|
+
algorithm: method,
|
|
490
|
+
data: input,
|
|
491
|
+
object: key,
|
|
492
|
+
signature: base64urlUnescape(signature),
|
|
493
|
+
signatureEncoding: 'base64'
|
|
494
|
+
})
|
|
495
|
+
} catch (error) {
|
|
496
|
+
throw new Error('createStringVerify failed')
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
throw new Error('Algorithm type not recognized')
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
function sign(input, key, method, type) {
|
|
503
|
+
let base64str
|
|
504
|
+
if (type === 'hmac') {
|
|
505
|
+
base64str = cryptoHelper.createStringHmac({
|
|
506
|
+
algorithm: method,
|
|
507
|
+
key,
|
|
508
|
+
data: input,
|
|
509
|
+
outputEncoding: 'base64'
|
|
510
|
+
})
|
|
511
|
+
} else if (type === 'sign') {
|
|
512
|
+
try {
|
|
513
|
+
base64str = cryptoHelper.createSignature({
|
|
514
|
+
algorithm: method,
|
|
515
|
+
data: input,
|
|
516
|
+
privateKey: key,
|
|
517
|
+
outputEncoding: 'base64'
|
|
518
|
+
})
|
|
519
|
+
} catch (error) {
|
|
520
|
+
throw new Error('createSignature failed')
|
|
521
|
+
}
|
|
522
|
+
} else {
|
|
523
|
+
throw new Error('Algorithm type not recognized')
|
|
524
|
+
}
|
|
525
|
+
return base64urlEscape(base64str)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function _decode(str) {
|
|
529
|
+
if (_hasBuffer) {
|
|
530
|
+
return Buffer.from(base64urlUnescape(str), 'base64').toString('utf8')
|
|
531
|
+
}
|
|
532
|
+
return atob(base64urlUnescape(str))
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function _encode(str) {
|
|
536
|
+
if (_hasBuffer) {
|
|
537
|
+
return base64urlEscape(Buffer.from(str, 'utf8').toString('base64'))
|
|
538
|
+
}
|
|
539
|
+
return base64urlEscape(btoa(str))
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
function base64urlDecode(str) {
|
|
543
|
+
// fixed bug if decode string is incorrect
|
|
544
|
+
// return (new Buffer.from(base64urlUnescape(str), 'base64')).toString() || '{}'
|
|
545
|
+
return _decode(str)
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function base64urlUnescape(str) {
|
|
549
|
+
str += new Array(5 - str.length % 4).join('=')
|
|
550
|
+
return str.replace(/\-/g, '+').replace(/_/g, '/')
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function base64urlEncode(str) {
|
|
554
|
+
// return base64urlEscape(new Buffer.from((str)).toString('base64'))
|
|
555
|
+
return _encode(str)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function base64urlEscape(str) {
|
|
559
|
+
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
;// ./lib/helpers/jwtHelper/index.js
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
;// ./lib/helpers/padZeros/padZeros.js
|
|
571
|
+
function padZeros(num, minLength = 6) {
|
|
572
|
+
num = num.toString()
|
|
573
|
+
if (num.length < minLength) {
|
|
574
|
+
return padZeros('0' + num, minLength)
|
|
575
|
+
}
|
|
576
|
+
return num
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
;// ./lib/helpers/padZeros/index.js
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
;// ./lib/helpers/stringFormatter/stringFormatter.js
|
|
587
|
+
function stringFormatter(str) {
|
|
588
|
+
return (str || '').toUpperCase().replace('-', '_').replace(' ', '_')
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
;// ./lib/helpers/stringFormatter/index.js
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
;// ./lib/helpers/index.js
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
;// ./lib/models/apiResponse/apiResponse.js
|
|
608
|
+
class ApiResponse {
|
|
609
|
+
constructor(options = {}) {
|
|
610
|
+
options = options || {}
|
|
611
|
+
this._data = options.data || options._data || []
|
|
612
|
+
this.err = options.err
|
|
613
|
+
this.isNew = options.isNew || false
|
|
614
|
+
this.message = options.message
|
|
615
|
+
this.total = options.total || 0
|
|
616
|
+
this._instanceBuilder = options._instanceBuilder
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
static init(options = {}) {
|
|
620
|
+
if (options instanceof this) {
|
|
621
|
+
return options
|
|
622
|
+
}
|
|
623
|
+
const instance = new this(options)
|
|
624
|
+
return instance
|
|
625
|
+
}
|
|
626
|
+
static get _classname() {
|
|
627
|
+
return 'ApiResponse'
|
|
628
|
+
}
|
|
629
|
+
static get _superclass() {
|
|
630
|
+
return 'ApiResponse'
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// getters
|
|
634
|
+
get data() {
|
|
635
|
+
if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
|
|
636
|
+
return this._data.map(this._instanceBuilder)
|
|
637
|
+
}
|
|
638
|
+
return this._data
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
;// ./lib/models/apiResponse/makeApiResponse.js
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
function makeApiResponse({ repo, result }) {
|
|
648
|
+
return ApiResponse.init({
|
|
649
|
+
...result,
|
|
650
|
+
_instanceBuilder: (i) => {
|
|
651
|
+
return repo.init(i)
|
|
652
|
+
}
|
|
653
|
+
})
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
;// ./lib/models/apiResponse/index.js
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
;// ./lib/models/keyValueObject/keyValueObject.js
|
|
665
|
+
class KeyValueObject {
|
|
666
|
+
constructor(options = {}) {
|
|
667
|
+
options = options || {}
|
|
668
|
+
this.key = options.key || null
|
|
669
|
+
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// Class methods
|
|
673
|
+
static init(options = {}) {
|
|
674
|
+
if (options instanceof this) {
|
|
675
|
+
return options
|
|
676
|
+
}
|
|
677
|
+
const instance = new this(options)
|
|
678
|
+
return instance.isValid ? instance : null
|
|
679
|
+
}
|
|
680
|
+
static initFromArray(arr = []) {
|
|
681
|
+
if (Array.isArray(arr)) {
|
|
682
|
+
return arr.map((a) => this.init(a))
|
|
683
|
+
}
|
|
684
|
+
return []
|
|
685
|
+
}
|
|
686
|
+
static initOnlyValidFromArray(arr = []) {
|
|
687
|
+
return this.initFromArray(arr).filter((i) => i)
|
|
688
|
+
}
|
|
689
|
+
static get _classname() {
|
|
690
|
+
return 'KeyValueObject'
|
|
691
|
+
}
|
|
692
|
+
static get _superclass() {
|
|
693
|
+
return 'KeyValueObject'
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
static addItem(arr, key, value) {
|
|
697
|
+
arr.push(
|
|
698
|
+
{ key, value }
|
|
699
|
+
)
|
|
700
|
+
}
|
|
701
|
+
static addRecord(arr = [], key, value) {
|
|
702
|
+
const self = this
|
|
703
|
+
if (!this.hasKeyValue(arr, key, value)) {
|
|
704
|
+
arr.push(self.init({ key, value }))
|
|
705
|
+
}
|
|
706
|
+
return arr
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
static appendRecord(arr = [], key, value) {
|
|
710
|
+
return arr.map((item) => {
|
|
711
|
+
if (item.key === key) {
|
|
712
|
+
item.value = [...item.value, ...value]
|
|
713
|
+
}
|
|
714
|
+
return item
|
|
715
|
+
})
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
static fromObject(options = {}) {
|
|
719
|
+
const self = this
|
|
720
|
+
return Object.keys(options).reduce((acc, key) => {
|
|
721
|
+
acc.push(self.init({ key, value: options[key] }))
|
|
722
|
+
return acc
|
|
723
|
+
}, [])
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
static removeByKey(arr, key) {
|
|
727
|
+
return arr.reduce((acc, item) => {
|
|
728
|
+
if (item.key !== key) {
|
|
729
|
+
acc.push(item)
|
|
730
|
+
}
|
|
731
|
+
return acc
|
|
732
|
+
}, [])
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
static foundByKey(arr = [], key) {
|
|
736
|
+
const found = arr.find((m) => {
|
|
737
|
+
return m.key === key
|
|
738
|
+
})
|
|
739
|
+
return found || null
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
static foundValueByKey(arr = [], key) {
|
|
743
|
+
const found = this.foundByKey(arr, key)
|
|
744
|
+
return found ? found.value : null
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
static getValueByKey(arr = [], key) {
|
|
748
|
+
const found = arr.find((i) => {
|
|
749
|
+
return i.key === key
|
|
750
|
+
})
|
|
751
|
+
if (found) {
|
|
752
|
+
return found.value
|
|
753
|
+
}
|
|
754
|
+
return null
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
static getValueByKeyFromArray(arr = [], key) {
|
|
758
|
+
if (arr.length === 0) {
|
|
759
|
+
return null
|
|
760
|
+
}
|
|
761
|
+
const firstArr = arr.shift()
|
|
762
|
+
const found = firstArr.find((i) => {
|
|
763
|
+
return i.key === key
|
|
764
|
+
})
|
|
765
|
+
if (found && found.value) {
|
|
766
|
+
return found.value
|
|
767
|
+
}
|
|
768
|
+
return this.getValueByKeyFromArray(arr, key)
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
static getValuesByKey(arr = [], key) {
|
|
772
|
+
return arr.reduce((acc, item) => {
|
|
773
|
+
if (item.key === key) {
|
|
774
|
+
acc.push(item.value)
|
|
775
|
+
}
|
|
776
|
+
return acc
|
|
777
|
+
}, [])
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
static hasKeyValue(arr = [], key, value) {
|
|
781
|
+
if (typeof value === 'undefined') {
|
|
782
|
+
return arr.filter((item) => item.key === key).length > 0
|
|
783
|
+
}
|
|
784
|
+
return arr.filter((item) => (item.key === key && item.value === value)).length > 0
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
static insertOrUpdateRecord(arr = [], key, value) {
|
|
788
|
+
const self = this
|
|
789
|
+
let copy = [...arr]
|
|
790
|
+
if (!self.hasKeyValue(arr, key)) {
|
|
791
|
+
copy.push(self.init({ key, value }))
|
|
792
|
+
} else {
|
|
793
|
+
copy = self.updateRecord(arr, key, value)
|
|
794
|
+
}
|
|
795
|
+
return copy
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
static keys(arr = []) {
|
|
799
|
+
if (Array.isArray(arr)) {
|
|
800
|
+
return arr.reduce((acc, item) => {
|
|
801
|
+
acc.push(item.key)
|
|
802
|
+
return acc
|
|
803
|
+
}, [])
|
|
804
|
+
}
|
|
805
|
+
return []
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
static merge(toArr, fromArr) {
|
|
809
|
+
(fromArr || []).map((from) => {
|
|
810
|
+
const found = toArr.find((to) => {
|
|
811
|
+
return to.key === from.key
|
|
812
|
+
})
|
|
813
|
+
if (found) {
|
|
814
|
+
found.value = (found.value || []).concat(from.value)
|
|
815
|
+
} else {
|
|
816
|
+
toArr.push(from)
|
|
817
|
+
}
|
|
818
|
+
})
|
|
819
|
+
return toArr
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
static toObject(arr = []) {
|
|
823
|
+
if (Array.isArray(arr)) {
|
|
824
|
+
return arr.reduce((acc, item) => {
|
|
825
|
+
acc[item.key] = item.value
|
|
826
|
+
return acc
|
|
827
|
+
}, {})
|
|
828
|
+
}
|
|
829
|
+
return {}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
static toString(arr = [], delimiter = '; ') {
|
|
833
|
+
if (Array.isArray(arr)) {
|
|
834
|
+
return arr.reduce((acc, item) => {
|
|
835
|
+
acc.push(`${item.key}: ${item.value}`)
|
|
836
|
+
return acc
|
|
837
|
+
}, []).join(delimiter)
|
|
838
|
+
}
|
|
839
|
+
return ''
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
static updateRecord(arr = [], key, value) {
|
|
843
|
+
return arr.map((item) => {
|
|
844
|
+
if (item.key === key) {
|
|
845
|
+
return {
|
|
846
|
+
...item,
|
|
847
|
+
value
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return item
|
|
851
|
+
})
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
static updateOrInsertRecord(arr = [], key, value) {
|
|
855
|
+
return this.insertOrUpdateRecord(arr, key, value)
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
static updateRecordsFromArray(arr = [], updateArr = []) {
|
|
859
|
+
if (Array.isArray(arr) && Array.isArray(updateArr)) {
|
|
860
|
+
const obj1 = this.toObject(arr)
|
|
861
|
+
const obj2 = this.toObject(updateArr)
|
|
862
|
+
return this.fromObject({
|
|
863
|
+
...obj1,
|
|
864
|
+
...obj2
|
|
865
|
+
})
|
|
866
|
+
}
|
|
867
|
+
return []
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
static values(arr = []) {
|
|
871
|
+
if (Array.isArray(arr)) {
|
|
872
|
+
return arr.reduce((acc, item) => {
|
|
873
|
+
acc.push(item.value)
|
|
874
|
+
return acc
|
|
875
|
+
}, [])
|
|
876
|
+
}
|
|
877
|
+
return []
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// getters
|
|
881
|
+
get isValid() {
|
|
882
|
+
return !!this.key
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
get toObject() {
|
|
886
|
+
const obj = {}
|
|
887
|
+
if (this.isValid) {
|
|
888
|
+
obj[this.key] = this.value
|
|
889
|
+
}
|
|
890
|
+
return obj
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
;// ./lib/models/keyValueObject/index.js
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
;// ./lib/models/metadata/metadata.js
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
class Metadata extends KeyValueObject {
|
|
906
|
+
static init(options = {}) {
|
|
907
|
+
if (options instanceof this) {
|
|
908
|
+
return options
|
|
909
|
+
}
|
|
910
|
+
const instance = new this({
|
|
911
|
+
...options,
|
|
912
|
+
key: stringFormatter(options.key),
|
|
913
|
+
})
|
|
914
|
+
return instance.isValid ? instance : null
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
static foundByKey(arr = [], key) {
|
|
918
|
+
const found = (arr || []).find((m) => {
|
|
919
|
+
return m.key === stringFormatter(key)
|
|
920
|
+
})
|
|
921
|
+
return found || null
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
static get _classname() {
|
|
925
|
+
return 'Metadata'
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
;// ./lib/models/metadata/index.js
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
;// ./lib/models/repo/repo.js
|
|
937
|
+
class Repo {
|
|
938
|
+
constructor(options) {
|
|
939
|
+
this.model = options.model
|
|
940
|
+
this.dbTransaction = options.dbTransaction
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
static get _classname() {
|
|
944
|
+
return 'Repo'
|
|
945
|
+
}
|
|
946
|
+
static get _superclass() {
|
|
947
|
+
return 'Repo'
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
init(options) {
|
|
951
|
+
throw new Error('subclass should implement .init(options)')
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
async deleteOne({ id }) {
|
|
955
|
+
try {
|
|
956
|
+
const result = await this.model.deleteOne({ _id: id })
|
|
957
|
+
return {
|
|
958
|
+
...result, // { message: 'ok', total }
|
|
959
|
+
isNew: false,
|
|
960
|
+
data: []
|
|
961
|
+
}
|
|
962
|
+
} catch (err) {
|
|
963
|
+
throw err
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
findAll({ query }) {
|
|
968
|
+
const options = {}
|
|
969
|
+
return new Promise((resolve, reject) => {
|
|
970
|
+
this.model.findAll(query, options, (err, data, total) => {
|
|
971
|
+
if (err) {
|
|
972
|
+
reject(err)
|
|
973
|
+
} else {
|
|
974
|
+
resolve({
|
|
975
|
+
isNew: false,
|
|
976
|
+
data,
|
|
977
|
+
total: total || data.length
|
|
978
|
+
})
|
|
979
|
+
}
|
|
980
|
+
})
|
|
981
|
+
})
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
findOne({ query }) {
|
|
985
|
+
const options = { session: this.dbTransaction }
|
|
986
|
+
return new Promise((resolve, reject) => {
|
|
987
|
+
this.model.findAll(query, options, (err, data) => {
|
|
988
|
+
if (err) {
|
|
989
|
+
reject(err)
|
|
990
|
+
} else if (data.length === 1) {
|
|
991
|
+
resolve({
|
|
992
|
+
isNew: false,
|
|
993
|
+
data,
|
|
994
|
+
total: 1
|
|
995
|
+
})
|
|
996
|
+
} else if (data.length === 0) {
|
|
997
|
+
reject(new Error('record not found'))
|
|
998
|
+
} else {
|
|
999
|
+
reject(new Error('more than one is found'))
|
|
1000
|
+
}
|
|
1001
|
+
})
|
|
1002
|
+
})
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
saveAll({ docs }) {
|
|
1006
|
+
const self = this
|
|
1007
|
+
let isNew
|
|
1008
|
+
return Promise.all(docs.map(async (doc) => {
|
|
1009
|
+
if (doc) {
|
|
1010
|
+
const result = await self.saveOne({ doc })
|
|
1011
|
+
isNew = result.isNew
|
|
1012
|
+
return result.data[0]
|
|
1013
|
+
}
|
|
1014
|
+
return null
|
|
1015
|
+
})).then((savedData) => {
|
|
1016
|
+
if (savedData.length !== 1) isNew = null
|
|
1017
|
+
return {
|
|
1018
|
+
data: savedData,
|
|
1019
|
+
isNew,
|
|
1020
|
+
total: savedData.length
|
|
1021
|
+
}
|
|
1022
|
+
})
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
saveOne({ doc }) {
|
|
1026
|
+
const options = { session: this.dbTransaction }
|
|
1027
|
+
return new Promise((resolve, reject) => {
|
|
1028
|
+
this.model.saveOne(doc, options, (err, result) => {
|
|
1029
|
+
if (err) {
|
|
1030
|
+
reject(err)
|
|
1031
|
+
} else {
|
|
1032
|
+
resolve(result)
|
|
1033
|
+
}
|
|
1034
|
+
})
|
|
1035
|
+
})
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
;// ./lib/models/repo/index.js
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
|
|
1046
|
+
;// ./lib/models/service/service.js
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
class Service {
|
|
1051
|
+
constructor({ repo }) {
|
|
1052
|
+
this.repo = repo
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
static get _classname() {
|
|
1056
|
+
return 'Service'
|
|
1057
|
+
}
|
|
1058
|
+
static get _superclass() {
|
|
1059
|
+
return 'Service'
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
deleteOne({ id }) {
|
|
1063
|
+
return this.repo.deleteOne({ id })
|
|
1064
|
+
.catch(() => {
|
|
1065
|
+
throw new Error(`Not found for query: ${id}`)
|
|
1066
|
+
})
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
async findAll({ query = {} } = {}) {
|
|
1070
|
+
const result = await this.repo.findAll({ query })
|
|
1071
|
+
return makeApiResponse({
|
|
1072
|
+
repo: this.repo,
|
|
1073
|
+
result
|
|
1074
|
+
})
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
async findOne({ query = {} } = {}) {
|
|
1078
|
+
const result = await this.repo.findOne({ query })
|
|
1079
|
+
return makeApiResponse({
|
|
1080
|
+
repo: this.repo,
|
|
1081
|
+
result
|
|
1082
|
+
})
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
init(options) {
|
|
1086
|
+
return this.repo.init(options)
|
|
1087
|
+
}
|
|
1088
|
+
initFromArray(arr = []) {
|
|
1089
|
+
return arr.map((i) => this.init(i))
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
async saveAll({ docs = [] } = {}) {
|
|
1093
|
+
const copies = docs.map((doc) => {
|
|
1094
|
+
return this.init(doc)
|
|
1095
|
+
})
|
|
1096
|
+
const result = await this.repo.saveAll({ docs: copies })
|
|
1097
|
+
return makeApiResponse({
|
|
1098
|
+
repo: this.repo,
|
|
1099
|
+
result
|
|
1100
|
+
})
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
async saveOne({ doc = {} } = {}) {
|
|
1104
|
+
const copy = this.init(doc)
|
|
1105
|
+
if (copy) {
|
|
1106
|
+
const result = await this.repo.saveOne({ doc: copy })
|
|
1107
|
+
return makeApiResponse({
|
|
1108
|
+
repo: this.repo,
|
|
1109
|
+
result
|
|
1110
|
+
})
|
|
1111
|
+
}
|
|
1112
|
+
return {
|
|
1113
|
+
isNew: null,
|
|
1114
|
+
data: [],
|
|
1115
|
+
err: new Error('doc is not a valid instance')
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
function makeService({ repo }) {
|
|
1121
|
+
if (repo === undefined) {
|
|
1122
|
+
throw new Error('repo is required.')
|
|
1123
|
+
}
|
|
1124
|
+
// if (!(repo instanceof Repo)) {
|
|
1125
|
+
// throw new Error('repo is not an instance of Repo.')
|
|
1126
|
+
// }
|
|
1127
|
+
return new Service({ repo })
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
;// ./lib/models/service/index.js
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
;// ./lib/models/index.js
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
;// ./lib/index.js
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
;// ./index.js
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
/******/ return __webpack_exports__;
|
|
1152
|
+
/******/ })()
|
|
1153
|
+
;
|
|
1154
|
+
});
|