q-koa 13.8.23 → 13.8.25

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.
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, getUserByCtx, getConfig, lodash } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx, getUserByCtx, getConfig } = require('q-koa')
2
3
 
3
4
  exports.login = async (ctx) => {
4
5
  const { app, appName } = getAppByCtx(ctx)
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, getConfig, lodash, moment, getService } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx, getConfig, moment, getService } = require('q-koa')
2
3
  const util = require('util')
3
4
  const axios = require('axios')
4
5
  const qr = require('qr-image')
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, lodash } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx } = require('q-koa')
2
3
 
3
4
  exports.update = async (ctx) => {
4
5
  const { app } = getAppByCtx(ctx)
@@ -1,5 +1,5 @@
1
- const { getConfig } = require('q-koa')
2
1
  const lodash = require('lodash')
2
+ const { getConfig } = require('q-koa')
3
3
  const axios = require('axios')
4
4
 
5
5
  const is_dev = process.env.NODE_ENV !== 'production'
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, lodash } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx } = require('q-koa')
2
3
 
3
4
  const fs = require('fs')
4
5
  const path = require('path')
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
3
  const fsPromise = require('fs/promises')
4
- const { lodash } = require('q-koa')
4
+ const lodash = require('lodash')
5
5
  exports.loadModel = async ({ app, appName }) => {
6
6
  const data = await fsPromise.readdir(
7
7
  path.resolve(__dirname, `${process.cwd()}/app/${appName}/plugins`)
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, lodash } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx } = require('q-koa')
2
3
 
3
4
  exports.bulkUpdate = async (ctx) => {
4
5
  const { app, appName } = getAppByCtx(ctx)
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, getConfig, lodash, is_dev } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx, getConfig, is_dev } = require('q-koa')
2
3
 
3
4
  const fs = require('fs')
4
5
  const path = require('path')
@@ -1,4 +1,5 @@
1
- const { Sequelize, Random, lodash, moment } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { Sequelize, Random, moment } = require('q-koa')
2
3
 
3
4
  exports.name = {
4
5
  type: Sequelize.STRING(),
@@ -3,7 +3,8 @@ const path = require('path')
3
3
  const fsPromise = require('fs/promises')
4
4
  const { VM } = require('vm2')
5
5
  const axios = require('axios')
6
- const { lodash, getAppByCtx, getConfig, Sequelize, moment } = require('q-koa')
6
+ const lodash = require('lodash')
7
+ const { getAppByCtx, getConfig, Sequelize, moment } = require('q-koa')
7
8
  const { LRUCache } = require('lru-cache')
8
9
  const cache = new LRUCache({
9
10
  max: 10,
@@ -1,4 +1,5 @@
1
- const { getConfig, lodash, Sequelize } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getConfig, Sequelize } = require('q-koa')
2
3
  const { formatLiteralObj, filterFunction } = require('../../utils')
3
4
  const formatPostFunction = (str) => `eval(${str})`
4
5
  const nodeVm = require('vm')
@@ -1,4 +1,5 @@
1
- const { getAppByCtx, getConfig, getService, lodash } = require('q-koa')
1
+ const lodash = require('lodash')
2
+ const { getAppByCtx, getConfig, getService } = require('q-koa')
2
3
 
3
4
  const util = require('util')
4
5
  const axios = require('axios')
@@ -1,6 +1,7 @@
1
1
  const md5 = require('js-md5')
2
- const { getAppByCtx, getConfig, lodash, moment } = require('q-koa')
3
- const { getAppConfig } = require('../../utils')
2
+ const lodash = require('lodash')
3
+ const { getAppByCtx, getConfig, moment } = require('q-koa')
4
+ const { getCachedLoginData } = require('../../utils')
4
5
 
5
6
  exports.login = async (ctx) => {
6
7
  const { app, appName } = getAppByCtx(ctx)
@@ -155,31 +156,19 @@ exports.login = async (ctx) => {
155
156
  ].filter((item) => item.model)
156
157
  : []
157
158
  if (app.appConfig.loginData) {
158
- const application = await getAppConfig({ app, config })
159
-
160
- const loginData = lodash.mergeWith(
161
- lodash.cloneDeep(app.appConfig.loginData),
162
- lodash.get(application, 'loginData', {}),
163
- (objValue, srcValue) => {
164
- if (lodash.isArray(objValue)) {
165
- return objValue.concat(srcValue)
166
- }
167
- }
168
- )
159
+ const { loginData, excludeList } = await getCachedLoginData({
160
+ app,
161
+ config,
162
+ })
169
163
  const include = includeDefault.filter((i) => {
170
164
  return loginData.excludeInclude.every((m) => {
171
165
  return app.model[m] !== i.model
172
166
  })
173
167
  })
174
168
 
175
- const exclude_list = lodash.get(application, 'exclude_list', [])
176
-
177
169
  const attributes = {
178
170
  exclude: Array.from(
179
- new Set([
180
- ...loginData.attributes.exclude,
181
- ...(Array.isArray(exclude_list) ? exclude_list : []),
182
- ])
171
+ new Set([...loginData.attributes.exclude, ...excludeList])
183
172
  ),
184
173
  }
185
174
  result = await app.model.user.findOne({
@@ -367,17 +356,11 @@ exports.checkLogin = async (ctx) => {
367
356
  ].filter((item) => item.model)
368
357
 
369
358
  if (app.appConfig.loginData) {
370
- const application = await getAppConfig({ app, config })
371
-
372
- const loginData = lodash.mergeWith(
373
- lodash.cloneDeep(app.appConfig.loginData),
374
- lodash.get(application, 'loginData', {}),
375
- (objValue, srcValue) => {
376
- if (lodash.isArray(objValue)) {
377
- return objValue.concat(srcValue)
378
- }
379
- }
380
- )
359
+ const { loginData, excludeList } = await getCachedLoginData({
360
+ app,
361
+ config,
362
+ lodash,
363
+ })
381
364
 
382
365
  const include = includeDefault.filter((i) => {
383
366
  return loginData.excludeInclude.every((m) => {
@@ -385,14 +368,9 @@ exports.checkLogin = async (ctx) => {
385
368
  })
386
369
  })
387
370
 
388
- const exclude_list = lodash.get(application, 'exclude_list', [])
389
-
390
371
  const attributes = {
391
372
  exclude: Array.from(
392
- new Set([
393
- ...loginData.attributes.exclude,
394
- ...(Array.isArray(exclude_list) ? exclude_list : []),
395
- ])
373
+ new Set([...loginData.attributes.exclude, ...excludeList])
396
374
  ),
397
375
  }
398
376
 
@@ -20,7 +20,7 @@ const fxp = require('fast-xml-parser')
20
20
  const crypto = require('crypto')
21
21
  const path = require('path')
22
22
  const fsPromise = require('fs/promises')
23
- const { getAppConfig } = require('../../utils')
23
+ const { getCachedLoginData } = require('../../utils')
24
24
 
25
25
  const AllinPay = require('../../services/allinpay')
26
26
 
@@ -471,30 +471,19 @@ exports.mp_login = async (ctx) => {
471
471
  ].filter((item) => item.model)
472
472
 
473
473
  if (app.appConfig.loginData) {
474
- const application = await getAppConfig({ app, config })
475
- const loginData = lodash.mergeWith(
476
- lodash.cloneDeep(app.appConfig.loginData),
477
- lodash.get(application, 'loginData', {}),
478
- (objValue, srcValue) => {
479
- if (lodash.isArray(objValue)) {
480
- return objValue.concat(srcValue)
481
- }
482
- }
483
- )
474
+ const { loginData, excludeList } = await getCachedLoginData({
475
+ app,
476
+ config,
477
+ })
484
478
  const include = includeDefault.filter((i) => {
485
479
  return loginData.excludeInclude.every((m) => {
486
480
  return app.model[m] !== i.model
487
481
  })
488
482
  })
489
483
 
490
- const exclude_list = lodash.get(application, 'exclude_list', [])
491
-
492
484
  const attributes = {
493
485
  exclude: Array.from(
494
- new Set([
495
- ...app.appConfig.loginData.attributes.exclude,
496
- ...(Array.isArray(exclude_list) ? exclude_list : []),
497
- ])
486
+ new Set([...loginData.attributes.exclude, ...excludeList])
498
487
  ),
499
488
  }
500
489
  result = await app.model.user.findOne({
@@ -11,7 +11,8 @@
11
11
  const util = require('util')
12
12
  const axios = require('axios')
13
13
  const crypto = require('crypto')
14
- const { lodash, ServiceError } = require('q-koa')
14
+ const lodash = require('lodash')
15
+ const { ServiceError } = require('q-koa')
15
16
  const getAccessTokenUrl = 'https://api.weixin.qq.com/cgi-bin/stable_token'
16
17
  const getPhoneNumberUrl =
17
18
  'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s'
@@ -15,7 +15,7 @@ const wxHttpsAgent = new https.Agent({
15
15
  const wxAxios = axios.create({
16
16
  httpsAgent: wxHttpsAgent,
17
17
  })
18
- const { lodash } = require('q-koa')
18
+ const lodash = require('lodash')
19
19
  const getAccessTokenUrl =
20
20
  'https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s'
21
21
 
@@ -1,8 +1,7 @@
1
- const { lodash } = require('q-koa')
1
+ const lodash = require('lodash')
2
2
  const Sequelize = require('sequelize')
3
3
  const md5 = require('md5')
4
4
  const moment = require('moment')
5
- const _ = require('lodash')
6
5
 
7
6
  const findConfig = (type) => (item) =>
8
7
  item.key === type ||
@@ -196,6 +195,66 @@ exports.getAppConfig = async ({ app, config, key, app_id, id }) => {
196
195
  return target || null
197
196
  }
198
197
 
198
+ const LOGIN_DATA_CACHE_PREFIX = 'login_data:'
199
+
200
+ /**
201
+ * 获取并缓存 loginData 分支里稳定的"应用配置合并结果"。
202
+ * 缓存 key:`login_data:<config>`,挂在现有 app.cache(LRUCache)上,
203
+ * 复用其全局 TTL(默认 1 天,第一个用户后不会更改 → 长期命中)。
204
+ *
205
+ * 返回:{ loginData, excludeList }
206
+ * - loginData:structuredClone(base) 与 application.loginData 按数组 concat
207
+ * 语义合并后的对象,缓存命中时直接是结构化结果,跳过 structuredClone+mergeWith
208
+ * - excludeList:已做 Array.isArray 校验、用于 attributes.exclude 追加的数组,
209
+ * 消费点只需 [...loginData.attributes.exclude, ...excludeList]
210
+ */
211
+ exports.getCachedLoginData = async ({ app, config }) => {
212
+ const cacheKey = LOGIN_DATA_CACHE_PREFIX + String(config || '')
213
+ const cached = app.cache.get(cacheKey)
214
+ if (cached) return cached
215
+
216
+ const base = app.appConfig.loginData
217
+ const application = await exports.getAppConfig({ app, config })
218
+ const overLoginData = lodash.get(application, 'loginData', {})
219
+
220
+ const loginData = lodash.mergeWith(
221
+ structuredClone(base),
222
+ overLoginData,
223
+ (objValue, srcValue) => {
224
+ if (lodash.isArray(objValue)) {
225
+ return objValue.concat(lodash.isArray(srcValue) ? srcValue : [])
226
+ }
227
+ }
228
+ )
229
+
230
+ const rawExclude = lodash.get(application, 'exclude_list', [])
231
+ const excludeList = Array.isArray(rawExclude) ? rawExclude : []
232
+
233
+ const payload = { loginData, excludeList }
234
+ app.cache.set(cacheKey, payload)
235
+ return payload
236
+ }
237
+
238
+ /**
239
+ * 清除 getCachedLoginData 的缓存(应用配置变更后手动失效时调用)。
240
+ * 不传 config 则清空所有 login_data:* 键。
241
+ */
242
+ exports.clearCachedLoginData = ({ app, config }) => {
243
+ if (!app || !app.cache) return
244
+ if (config) {
245
+ app.cache.delete(LOGIN_DATA_CACHE_PREFIX + String(config))
246
+ return
247
+ }
248
+ // 兜底:LRU v11 提供 keys() 迭代器
249
+ if (typeof app.cache.keys === 'function') {
250
+ for (const k of app.cache.keys()) {
251
+ if (typeof k === 'string' && k.startsWith(LOGIN_DATA_CACHE_PREFIX)) {
252
+ app.cache.delete(k)
253
+ }
254
+ }
255
+ }
256
+ }
257
+
199
258
  exports.signResult = (params, salt) => {
200
259
  var skip_arr = ['thirdparty_id', 'app_id', 'sign']
201
260
  var paramArray = new Array()
@@ -333,7 +392,7 @@ const filterFunction = (target, data) => {
333
392
  }
334
393
  return Object.keys(target).every((key) => {
335
394
  if (key.includes('.')) {
336
- return _.get(data, key) === target[key]
395
+ return lodash.get(data, key) === target[key]
337
396
  }
338
397
  if (typeof target[key] === 'boolean') {
339
398
  return Boolean(data[key]) === target[key]
@@ -351,7 +410,7 @@ const filterFunction = (target, data) => {
351
410
  if (Array.isArray(target[key])) {
352
411
  return target[key].includes(data[key])
353
412
  }
354
- if (_.isObject(target[key])) {
413
+ if (lodash.isObject(target[key])) {
355
414
  if ('$gt' in target[key]) {
356
415
  if (key.endsWith('time') || key.endsWith('_at')) {
357
416
  return moment(data[key]).diff(moment(target[key].$gt), 'seconds') > 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "13.8.23",
3
+ "version": "13.8.25",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {