@domain.js/main 1.0.0-alpha.2 → 1.0.0-alpha.4

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 +1 @@
1
- export declare const errors: Readonly<Record<"notFound" | "notAllowed" | "noAuth", import("./Errors").ErrorFn>>;
1
+ export declare const errors: Readonly<Record<"notFound" | "notAllowed" | "noAuth" | "resourceDuplicateAdd", import("./Errors").ErrorFn>>;
@@ -6,5 +6,6 @@ const defines = [
6
6
  ["notFound", "Resource not found"],
7
7
  ["notAllowed", "No access"],
8
8
  ["noAuth", "Not authentication"],
9
+ ["resourceDuplicateAdd", "Resource duplicate add"],
9
10
  ];
10
11
  exports.errors = Object.freeze((0, Errors_1.Errors)(defines));
@@ -1,11 +1,11 @@
1
- import { Redis } from "ioredis";
1
+ import { Redis, RedisOptions } from "ioredis";
2
2
  import { LRUCache } from "lru-cache";
3
3
  export interface CnfDef {
4
4
  cache: {
5
5
  isMulti?: boolean;
6
6
  delSignalChannel?: string;
7
7
  } & LRUCache.Options<{}, {}, unknown>;
8
- redis?: any;
8
+ redis?: RedisOptions;
9
9
  }
10
10
  export interface DepsDef {
11
11
  IORedis: typeof Redis;
@@ -40,7 +40,7 @@ function Main(cnf, deps) {
40
40
  const needToBroad = Boolean(cnf.cache.isMulti);
41
41
  // 如果不是多节点分部署部署,则不需要处理
42
42
  // 开启多节点分布式部署后,要通过redis广播cache的del事件,依次来保持cache的有效性
43
- if (needToBroad) {
43
+ if (needToBroad && cnf.redis) {
44
44
  const pub = new IORedis(cnf.redis);
45
45
  const sub = new IORedis(cnf.redis);
46
46
  const { delSignalChannel = "LRU_DEL_SIGNAL_CHANNEL" } = cnf.cache;
@@ -1,6 +1,5 @@
1
1
  import * as aes from "./aes";
2
2
  import * as cache from "./cache";
3
- import * as checker from "./checker";
4
3
  import * as counter from "./counter";
5
4
  import * as cron from "./cron";
6
5
  import * as frequency from "./frequency";
@@ -17,7 +16,6 @@ import * as signer from "./signer";
17
16
  declare const _default: {
18
17
  aes: typeof aes;
19
18
  cache: typeof cache;
20
- checker: typeof checker;
21
19
  counter: typeof counter;
22
20
  cron: typeof cron;
23
21
  frequency: typeof frequency;
@@ -35,7 +35,6 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  // domain-cli 自动生成
36
36
  const aes = __importStar(require("./aes"));
37
37
  const cache = __importStar(require("./cache"));
38
- const checker = __importStar(require("./checker"));
39
38
  const counter = __importStar(require("./counter"));
40
39
  const cron = __importStar(require("./cron"));
41
40
  const frequency = __importStar(require("./frequency"));
@@ -52,7 +51,6 @@ const signer = __importStar(require("./signer"));
52
51
  module.exports = {
53
52
  aes: aes,
54
53
  cache: cache,
55
- checker: checker,
56
54
  counter: counter,
57
55
  cron: cron,
58
56
  frequency: frequency,
@@ -1,7 +1,6 @@
1
- import { eachLimit, forever, whilst } from "async";
2
1
  import { Redis } from "ioredis";
3
- import { Main as Logger } from "../logger";
4
2
  import { Main as Graceful } from "../graceful";
3
+ import { Main as Logger } from "../logger";
5
4
  interface Cnf {
6
5
  parallel: {
7
6
  /** Record the redis key prefix of the concurrency control lock */
@@ -26,12 +25,6 @@ interface Deps {
26
25
  };
27
26
  /** redis instance */
28
27
  redis: Pick<Redis, "get" | "set" | "del" | "expire" | "exists">;
29
- /** async package */
30
- async: {
31
- eachLimit: typeof eachLimit;
32
- whilst: typeof whilst;
33
- forever: typeof forever;
34
- };
35
28
  }
36
29
  export interface Option {
37
30
  path: string;
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Deps = void 0;
37
37
  exports.Main = Main;
38
+ const async_1 = require("async");
38
39
  const utils = __importStar(require("../../utils"));
39
40
  /**
40
41
  * Parallel control module
@@ -44,7 +45,7 @@ const utils = __importStar(require("../../utils"));
44
45
  */
45
46
  function Main(cnf, deps) {
46
47
  const { parallel: { key: KEY, defaultErrorFn, maxExpireSeconds = 300, resetExpireIntervalMS = 100 * 1000, }, } = cnf;
47
- const { async, logger, graceful, redis } = deps;
48
+ const { logger, graceful, redis } = deps;
48
49
  const { sleep } = utils;
49
50
  // 存放当前处于执行中的 key
50
51
  const doings = new Set();
@@ -53,7 +54,7 @@ function Main(cnf, deps) {
53
54
  const onExit = async () => {
54
55
  exiting = true;
55
56
  logger.info("graceful.onExit parallel start", [...doings]);
56
- await async.eachLimit([...doings], 10, async (key) => {
57
+ await (0, async_1.eachLimit)([...doings], 10, async (key) => {
57
58
  doings.delete(key);
58
59
  await redis.del(key);
59
60
  logger.info(`graceful.onExit parallel del: ${key}`);
@@ -63,11 +64,11 @@ function Main(cnf, deps) {
63
64
  const delay = async () => {
64
65
  if (!doings.size)
65
66
  return;
66
- await async.eachLimit([...doings], 10, async (key) => {
67
+ await (0, async_1.eachLimit)([...doings], 10, async (key) => {
67
68
  await redis.expire(key, maxExpireSeconds);
68
69
  });
69
70
  };
70
- async.forever(async () => {
71
+ (0, async_1.forever)(async () => {
71
72
  try {
72
73
  await sleep(resetExpireIntervalMS);
73
74
  await delay();
@@ -110,7 +111,7 @@ function Main(cnf, deps) {
110
111
  if (!needWaitMS)
111
112
  throw error;
112
113
  // 需要等待
113
- await async.whilst(async () => Boolean(await redis.exists(key)), async () => sleep(needWaitMS));
114
+ await (0, async_1.whilst)(async () => Boolean(await redis.exists(key)), async () => sleep(needWaitMS));
114
115
  return paralleled(...args);
115
116
  }
116
117
  const startAt = Date.now(); // 执行开始毫秒数
@@ -132,4 +133,4 @@ function Main(cnf, deps) {
132
133
  graceful.exit(onExit);
133
134
  return control;
134
135
  }
135
- exports.Deps = ["async", "logger", "graceful", "redis"];
136
+ exports.Deps = ["logger", "graceful", "redis"];
@@ -8,6 +8,7 @@ type Cnf = Parameters<typeof Utils>[0] & Parameters<typeof Stats>[0];
8
8
  type Deps = Parameters<typeof Utils>[1] & Parameters<typeof Stats>[1] & {
9
9
  _: typeof _;
10
10
  Sequelize: Pick<typeof Sequelize, "literal" | "and" | "fn" | "Op">;
11
+ errors: any;
11
12
  };
12
13
  type UserId = string | number;
13
14
  export interface CreatorAndClientIp {
@@ -42,4 +43,4 @@ export declare function Main(cnf: Cnf, deps: Deps, utils: ReturnType<typeof Util
42
43
  rows: Record<string, string | number>[];
43
44
  }>;
44
45
  };
45
- export declare const Deps: string[];
46
+ export declare const Deps: never[];
@@ -17,7 +17,6 @@ Object.defineProperty(exports, "Before", { enumerable: true, get: function () {
17
17
  * @returns modify, add, remove, list, stats five methods
18
18
  */
19
19
  function Main(cnf, deps, utils) {
20
- const { errors } = deps;
21
20
  const { findAllOpts, pickParams } = utils;
22
21
  /**
23
22
  * Restful modify(U of CRUD) for update a resource
@@ -75,7 +74,7 @@ function Main(cnf, deps, utils) {
75
74
  return Model.create(attr);
76
75
  // 资源存在但是并非已删除的,抛出资源重复添加的error
77
76
  if (model.isDeleted === "no")
78
- throw errors.resourceDuplicateAdd(where);
77
+ throw deps.errors.resourceDuplicateAdd(where);
79
78
  // 资源存在,恢复
80
79
  model.isDeleted = "no";
81
80
  Object.assign(model, attr);
@@ -117,4 +116,4 @@ function Main(cnf, deps, utils) {
117
116
  }
118
117
  return { modify, add, remove, list, stats: (0, stats_1.Stats)(cnf, deps, utils) };
119
118
  }
120
- exports.Deps = ["errors", "_", "dayjs", "mysql", "Sequelize"];
119
+ exports.Deps = [];
@@ -1,6 +1,3 @@
1
- import dayjs from "dayjs";
2
- import type { LoDashStatic } from "lodash";
3
- import * as mysql from "mysql2";
4
1
  import { ModelBase, ModelStatic } from "../sequelize";
5
2
  interface Cnf {
6
3
  rest: {
@@ -8,13 +5,6 @@ interface Cnf {
8
5
  };
9
6
  }
10
7
  interface Deps {
11
- _: LoDashStatic;
12
- mysql: Pick<typeof mysql, "escape">;
13
- dayjs: typeof dayjs extends (...args: infer A) => infer B ? (...args: A) => B : never;
14
- errors: {
15
- notAllowed: (...args: any[]) => Error;
16
- resourceDuplicateAdd: (...args: any[]) => Error;
17
- };
18
8
  }
19
9
  export declare function Utils(cnf: Cnf, deps: Deps): Readonly<{
20
10
  pickParams: <T extends ModelBase>(params: any, cols: string[], Model: ModelStatic<T>, isAdmin: boolean) => {
@@ -32,13 +32,18 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  exports.Utils = Utils;
40
+ const dayjs_1 = __importDefault(require("dayjs"));
41
+ const lodash_1 = __importDefault(require("lodash"));
37
42
  const mysql = __importStar(require("mysql2"));
38
43
  const sequelize_1 = require("sequelize");
44
+ const basic_errors_1 = require("../../basic-errors");
39
45
  function Utils(cnf, deps) {
40
46
  const { rest: { relativeMaxRangeDays: RELATIVE_MAX_RANGE = 100 }, } = cnf;
41
- const { _, errors, dayjs } = deps;
42
47
  /**
43
48
  * 相对多少天的时间
44
49
  * @param Number days 相对多少天
@@ -55,19 +60,19 @@ function Utils(cnf, deps) {
55
60
  const pickParams = (params, cols, Model, isAdmin) => {
56
61
  const attr = {};
57
62
  const { rawAttributes, onlyAdminCols = [] } = Model;
58
- _.each(cols, (x) => {
59
- if (!_.has(params, x))
63
+ lodash_1.default.each(cols, (x) => {
64
+ if (!lodash_1.default.has(params, x))
60
65
  return;
61
- if (!_.has(rawAttributes, x))
66
+ if (!lodash_1.default.has(rawAttributes, x))
62
67
  return;
63
68
  const C = rawAttributes[x];
64
69
  // 当设置了只有管理员才可以修改的字段,并且当前用户不是管理员
65
70
  // 则去掉那些只有管理员才能修改的字段
66
- if (onlyAdminCols && !isAdmin && _.includes(onlyAdminCols, x))
71
+ if (onlyAdminCols && !isAdmin && lodash_1.default.includes(onlyAdminCols, x))
67
72
  return;
68
73
  let value = params[x];
69
74
  // 如果字段允许为空,且默认值为 null 则在等于空字符串的时候赋值为 null
70
- if ((value === "" || value === null || value === undefined) && _.has(C, "defaultValue")) {
75
+ if ((value === "" || value === null || value === undefined) && lodash_1.default.has(C, "defaultValue")) {
71
76
  value = C.allowNull === true ? null : C.defaultValue;
72
77
  }
73
78
  attr[x] = value;
@@ -90,12 +95,12 @@ function Utils(cnf, deps) {
90
95
  const order = isDesc ? x.slice(1) : x;
91
96
  const theOrder = order.split(".");
92
97
  // 如果请求的排序方式不允许,则返回null
93
- if (theOrder.length !== 2 && (!conf.allow || !_.includes(conf.allow, order)))
98
+ if (theOrder.length !== 2 && (!conf.allow || !lodash_1.default.includes(conf.allow, order)))
94
99
  return undefined;
95
100
  // 处理使用模型名称作为关联名称按关联模型的 字段 排序
96
101
  if (theOrder.length === 2) {
97
102
  if (includes && Array.isArray(params._includes)) {
98
- const ret = _.filter(params._includes, (val) => includes[val]);
103
+ const ret = lodash_1.default.filter(params._includes, (val) => includes[val]);
99
104
  if (!ret.includes(theOrder[0]) ||
100
105
  !((_a = includes[theOrder[0]].model.sort) === null || _a === void 0 ? void 0 : _a.allow.includes(theOrder[1]))) {
101
106
  return undefined;
@@ -108,7 +113,7 @@ function Utils(cnf, deps) {
108
113
  theOrder.push(direction);
109
114
  return theOrder;
110
115
  });
111
- return _.compact(orders);
116
+ return lodash_1.default.compact(orders);
112
117
  };
113
118
  // searchOpt 的处理,处理参数参数里的q, 实现简易搜索功能
114
119
  /**
@@ -138,16 +143,16 @@ function Utils(cnf, deps) {
138
143
  const searchOpt = (Model, searchStr, qstr, as) => {
139
144
  if (!qstr)
140
145
  return undefined;
141
- if (!_.isString(qstr))
146
+ if (!lodash_1.default.isString(qstr))
142
147
  return undefined;
143
- const q = qstr.trim() ? _.split(qstr.trim(), " ", 5) : null;
148
+ const q = qstr.trim() ? lodash_1.default.split(qstr.trim(), " ", 5) : null;
144
149
  if (!q)
145
150
  return undefined;
146
- const searchs = searchStr ? _.split(searchStr, ",") : null;
151
+ const searchs = searchStr ? lodash_1.default.split(searchStr, ",") : null;
147
152
  const ors = [];
148
153
  if (!Model.searchCols)
149
154
  return undefined;
150
- _.each(Model.searchCols, (conf, col) => {
155
+ lodash_1.default.each(Model.searchCols, (conf, col) => {
151
156
  // 如果设置了搜索的字段,并且当前字读不在设置的搜索字段内,则直接返回
152
157
  // 相当于跳过这个设置
153
158
  const _col = as ? `${as}.${col}` : col;
@@ -155,10 +160,10 @@ function Utils(cnf, deps) {
155
160
  // 这么做是为了避免用户不知情的一些筛选过滤
156
161
  if (!searchs && as)
157
162
  return;
158
- if (searchs && searchs.length && !_.includes(searchs, _col))
163
+ if (searchs && searchs.length && !lodash_1.default.includes(searchs, _col))
159
164
  return;
160
- ors.push(_.map(q, (x) => {
161
- const arr = _.map(conf.match, (match) => {
165
+ ors.push(lodash_1.default.map(q, (x) => {
166
+ const arr = lodash_1.default.map(conf.match, (match) => {
162
167
  const v = match.replace("{1}", x);
163
168
  return [`(\`${as || Model.name}\`.\`${col}\``, conf.op, `${mysql.escape(v)})`].join(" ");
164
169
  });
@@ -173,16 +178,16 @@ function Utils(cnf, deps) {
173
178
  // 单个关键词在不同的搜索字段之间是 OR 的关系
174
179
  const mergeSearchOrs = (orss) => {
175
180
  const ands = [];
176
- _.each(orss, (_orss) => {
177
- _.each(_orss, (ors) => {
178
- _.each(ors, (_or, index) => {
181
+ lodash_1.default.each(orss, (_orss) => {
182
+ lodash_1.default.each(_orss, (ors) => {
183
+ lodash_1.default.each(ors, (_or, index) => {
179
184
  if (!ands[index])
180
185
  ands[index] = [];
181
186
  ands[index].push(_or);
182
187
  });
183
188
  });
184
189
  });
185
- const andsStr = _.map(ands, (x) => `(${x.join(" OR ")})`);
190
+ const andsStr = lodash_1.default.map(ands, (x) => `(${x.join(" OR ")})`);
186
191
  return `(${andsStr.join(" AND ")})`;
187
192
  };
188
193
  // 处理关联包含
@@ -194,11 +199,11 @@ function Utils(cnf, deps) {
194
199
  return undefined;
195
200
  if (!Array.isArray(params._includes))
196
201
  return undefined;
197
- const ret = _.filter(params._includes, (x) => includes[x]);
202
+ const ret = lodash_1.default.filter(params._includes, (x) => includes[x]);
198
203
  if (ret.length === 0)
199
204
  return undefined;
200
205
  // 这里之所以要用 _.clone 是为了防止修改了原始了配置信息,从而导致不同请求之间的干扰
201
- return _.map(ret, (x) => _.clone(includes[x]));
206
+ return lodash_1.default.map(ret, (x) => lodash_1.default.clone(includes[x]));
202
207
  };
203
208
  const DEFAULT_PAGE_PARAMS = Object.freeze({
204
209
  maxResults: 10,
@@ -214,7 +219,7 @@ function Utils(cnf, deps) {
214
219
  limit: Math.min(maxResults, _pagination.maxResultsLimit),
215
220
  };
216
221
  };
217
- const RELATIVE_RANGE_ERROR = errors.notAllowed(`相对时间跨度最多 ${RELATIVE_MAX_RANGE} 天`);
222
+ const RELATIVE_RANGE_ERROR = basic_errors_1.errors.notAllowed(`相对时间跨度最多 ${RELATIVE_MAX_RANGE} 天`);
218
223
  // findOptFilter 的处理
219
224
  // eslint-disable-next-line complexity
220
225
  const findOptFilter = (params, name, where, modelAlias4Ins, col = name) => {
@@ -224,7 +229,7 @@ function Utils(cnf, deps) {
224
229
  if (typeof params !== "object")
225
230
  return;
226
231
  // 处理相对时间过滤
227
- if (_.isString(params[`${name}_relative`])) {
232
+ if (lodash_1.default.isString(params[`${name}_relative`])) {
228
233
  let [start, end, ignoreYear] = params[`${name}_relative`].split(",");
229
234
  start |= 0;
230
235
  end |= 0;
@@ -237,8 +242,8 @@ function Utils(cnf, deps) {
237
242
  where[col][sequelize_1.Op.and] = [];
238
243
  if (ignoreYear) {
239
244
  // 忽略年,这里要处理跨年的问题
240
- const startDate = dayjs(Date.now() + start * 86400000).format("MM-DD");
241
- const endDate = dayjs(Date.now() + end * 86400000).format("MM-DD");
245
+ const startDate = (0, dayjs_1.default)(Date.now() + start * 86400000).format("MM-DD");
246
+ const endDate = (0, dayjs_1.default)(Date.now() + end * 86400000).format("MM-DD");
242
247
  if (endDate < startDate) {
243
248
  where[col][sequelize_1.Op.and].push({
244
249
  [sequelize_1.Op.or]: [
@@ -258,7 +263,7 @@ function Utils(cnf, deps) {
258
263
  }
259
264
  }
260
265
  // 处理 where 的等于
261
- if (_.isString(params[name])) {
266
+ if (lodash_1.default.isString(params[name])) {
262
267
  value = params[name].trim();
263
268
  // 特殊处理null值
264
269
  if (value === ".null.")
@@ -267,37 +272,37 @@ function Utils(cnf, deps) {
267
272
  where[col] = {};
268
273
  where[col][sequelize_1.Op.eq] = value;
269
274
  }
270
- if (_.isNumber(params[name])) {
275
+ if (lodash_1.default.isNumber(params[name])) {
271
276
  if (!where[col])
272
277
  where[col] = {};
273
278
  where[col][sequelize_1.Op.eq] = params[name];
274
279
  }
275
280
  // 处理where in
276
- if (_.isString(params[`${name}s`])) {
281
+ if (lodash_1.default.isString(params[`${name}s`])) {
277
282
  if (!where[col])
278
283
  where[col] = {};
279
284
  where[col][sequelize_1.Op.in] = params[`${name}s`].trim().split(",");
280
285
  }
281
286
  // in 直接是数组的格式
282
- if (_.isArray(params[`${name}s`])) {
287
+ if (lodash_1.default.isArray(params[`${name}s`])) {
283
288
  if (!where[col])
284
289
  where[col] = {};
285
290
  where[col][sequelize_1.Op.in] = params[`${name}s`];
286
291
  }
287
292
  // 处理where not in
288
- if (_.isString(params[`${name}s!`])) {
293
+ if (lodash_1.default.isString(params[`${name}s!`])) {
289
294
  if (!where[col])
290
295
  where[col] = {};
291
296
  where[col][sequelize_1.Op.notIn] = params[`${name}s!`].trim().split(",");
292
297
  }
293
298
  // not in 直接是数组的格式
294
- if (_.isArray(params[`${name}s!`])) {
299
+ if (lodash_1.default.isArray(params[`${name}s!`])) {
295
300
  if (!where[col])
296
301
  where[col] = {};
297
302
  where[col][sequelize_1.Op.notIn] = params[`${name}s!`];
298
303
  }
299
304
  // 处理不等于的判断
300
- if (_.isString(params[`${name}!`])) {
305
+ if (lodash_1.default.isString(params[`${name}!`])) {
301
306
  value = params[`${name}!`].trim();
302
307
  if (!where[col])
303
308
  where[col] = {};
@@ -311,14 +316,14 @@ function Utils(cnf, deps) {
311
316
  }
312
317
  }
313
318
  // 处理like
314
- if (_.isString(params[`${name}_like`])) {
319
+ if (lodash_1.default.isString(params[`${name}_like`])) {
315
320
  value = params[`${name}_like`].trim().replace(/\*/g, "%").replace(/_/g, "\\_");
316
321
  if (!where[col])
317
322
  where[col] = {};
318
323
  where[col][sequelize_1.Op.like] = value;
319
324
  }
320
325
  // 处理likes [like or]
321
- if (_.isString(params[`${name}_likes`])) {
326
+ if (lodash_1.default.isString(params[`${name}_likes`])) {
322
327
  const likes = params[`${name}_likes`].trim().split(",");
323
328
  if (!where[col])
324
329
  where[col] = {};
@@ -328,36 +333,36 @@ function Utils(cnf, deps) {
328
333
  });
329
334
  }
330
335
  // 处理notLike
331
- if (_.isString(params[`${name}_notLike`])) {
336
+ if (lodash_1.default.isString(params[`${name}_notLike`])) {
332
337
  value = params[`${name}_notLike`].trim().replace(/\*/g, "%").replace(/_/g, "\\_");
333
338
  if (!where[col])
334
339
  where[col] = {};
335
340
  where[col][sequelize_1.Op.notLike] = value;
336
341
  }
337
342
  // 处理大于,小于, 大于等于,小于等于的判断
338
- _.each(["gt", "gte", "lt", "lte"], (x) => {
343
+ lodash_1.default.each(["gt", "gte", "lt", "lte"], (x) => {
339
344
  const c = `${name}_${x}`;
340
- if (!_.isString(params[c]) && !_.isNumber(params[c]))
345
+ if (!lodash_1.default.isString(params[c]) && !lodash_1.default.isNumber(params[c]))
341
346
  return;
342
- value = _.isString(params[c]) ? params[c].trim() : params[c];
347
+ value = lodash_1.default.isString(params[c]) ? params[c].trim() : params[c];
343
348
  if (!where[col])
344
349
  where[col] = {};
345
350
  where[col][sequelize_1.Op[x]] = value;
346
351
  });
347
352
  // 处理 find_in_set 方式的过滤
348
- if (_.isString(params[`${name}_ins`]) || _.isNumber(params[`${name}_ins`])) {
353
+ if (lodash_1.default.isString(params[`${name}_ins`]) || lodash_1.default.isNumber(params[`${name}_ins`])) {
349
354
  if (!where[sequelize_1.Op.and])
350
355
  where[sequelize_1.Op.and] = [];
351
356
  where[sequelize_1.Op.and].push(sequelize_1.Sequelize.where(sequelize_1.Sequelize.fn("FIND_IN_SET", params[`${name}_ins`], sequelize_1.Sequelize.col(`${modelAlias4Ins}.${col}`)), sequelize_1.Op.gte, 1));
352
357
  }
353
358
  // 处理 json_contains 方式的过滤
354
- if (_.isString(params[`${name}_contains`]) || _.isNumber(params[`${name}_contains`])) {
359
+ if (lodash_1.default.isString(params[`${name}_contains`]) || lodash_1.default.isNumber(params[`${name}_contains`])) {
355
360
  if (!where[sequelize_1.Op.and])
356
361
  where[sequelize_1.Op.and] = [];
357
362
  where[sequelize_1.Op.and].push(sequelize_1.Sequelize.where(sequelize_1.Sequelize.fn("JSON_CONTAINS", sequelize_1.Sequelize.col(`${modelAlias4Ins}.${col}`), params[`${name}_contains`]), true));
358
363
  }
359
364
  // 处理 find_in_set 方式的过滤 _ins_and
360
- if (_.isString(params[`${name}_ins_and`])) {
365
+ if (lodash_1.default.isString(params[`${name}_ins_and`])) {
361
366
  if (!where[sequelize_1.Op.and])
362
367
  where[sequelize_1.Op.and] = [];
363
368
  for (const v of params[`${name}_ins_and`].split(",")) {
@@ -365,7 +370,7 @@ function Utils(cnf, deps) {
365
370
  }
366
371
  }
367
372
  // 处理 find_in_set 方式的过滤 _ins_or
368
- if (_.isString(params[`${name}_ins_or`])) {
373
+ if (lodash_1.default.isString(params[`${name}_ins_or`])) {
369
374
  if (!where[sequelize_1.Op.and])
370
375
  where[sequelize_1.Op.and] = [];
371
376
  where[sequelize_1.Op.and].push({
@@ -373,7 +378,7 @@ function Utils(cnf, deps) {
373
378
  });
374
379
  }
375
380
  // 处理 find_in_set 方式的过滤 _ins_not
376
- if (_.isString(params[`${name}_ins_not`])) {
381
+ if (lodash_1.default.isString(params[`${name}_ins_not`])) {
377
382
  if (!where[sequelize_1.Op.and])
378
383
  where[sequelize_1.Op.and] = [];
379
384
  for (const v of params[`${name}_ins_not`].split(",")) {
@@ -386,7 +391,7 @@ function Utils(cnf, deps) {
386
391
  const where = {};
387
392
  const searchOrs = [];
388
393
  const includes = modelInclude(params, Model.includes);
389
- _.each(Model.filterAttrs || _.keys(Model.rawAttributes), (name) => {
394
+ lodash_1.default.each(Model.filterAttrs || lodash_1.default.keys(Model.rawAttributes), (name) => {
390
395
  findOptFilter(params, name, where, Model.name);
391
396
  });
392
397
  if (!params._showDeleted) {
@@ -403,10 +408,10 @@ function Utils(cnf, deps) {
403
408
  // 处理关联资源的过滤条件
404
409
  // 以及关联资源允许返回的字段
405
410
  if (includes) {
406
- _.each(includes, (x) => {
411
+ lodash_1.default.each(includes, (x) => {
407
412
  const includeWhere = {};
408
- const filterAttrs = x.model.filterAttrs || _.keys(x.model.rawAttributes);
409
- _.each(filterAttrs, (name) => {
413
+ const filterAttrs = x.model.filterAttrs || lodash_1.default.keys(x.model.rawAttributes);
414
+ lodash_1.default.each(filterAttrs, (name) => {
410
415
  findOptFilter(params, `${x.as}.${name}`, includeWhere, x.as, name);
411
416
  });
412
417
  const rawAttributes = x.model.getAttributes();
@@ -439,8 +444,8 @@ function Utils(cnf, deps) {
439
444
  order: sort(params, Model.sort, Model.includes),
440
445
  };
441
446
  // 将 searchOrs 赋到 where 上
442
- const _searchOrs = _.filter(_.compact(searchOrs), (x) => x.length);
443
- if (_.size(where) || where[sequelize_1.Op.and] || where[sequelize_1.Op.or] || where[sequelize_1.Op.not]) {
447
+ const _searchOrs = lodash_1.default.filter(lodash_1.default.compact(searchOrs), (x) => x.length);
448
+ if (lodash_1.default.size(where) || where[sequelize_1.Op.and] || where[sequelize_1.Op.or] || where[sequelize_1.Op.not]) {
444
449
  if (_searchOrs.length) {
445
450
  ret.where = sequelize_1.Sequelize.and(where, (0, sequelize_1.literal)(mergeSearchOrs(_searchOrs)));
446
451
  }
@@ -74,7 +74,7 @@ function Main(cnf, deps) {
74
74
  console.error(err);
75
75
  process.exit(1);
76
76
  }
77
- console.log("%s listening at %s", host, address);
77
+ console.log("[%s] listening at %s", new Date().toISOString(), address);
78
78
  });
79
79
  return server;
80
80
  };
@@ -11,7 +11,6 @@ function Router(deps) {
11
11
  const { ucwords, makeParams, makeProfile, outputCSV } = utils;
12
12
  const apis = [];
13
13
  let apisHTML = "<h3>API 目录,点击可以查看参数格式定义</h3>";
14
- console.error("server", server, "server");
15
14
  /** 判断是否需要提供apis的查询接口 */
16
15
  if (apisRoute) {
17
16
  server.get(`/${apisRoute}`, (req, res) => {
@@ -142,6 +142,7 @@ function Utils(cnf) {
142
142
  * 构造领域方法所需的 params 参数
143
143
  */
144
144
  async makeParams(req) {
145
+ var _a;
145
146
  let params = { ...(req.query || {}), ...(req.params || {}) };
146
147
  if (lodash_1.default.isObject(req.body) && !Array.isArray(req.body)) {
147
148
  params = { ...(req.body || {}), ...params };
@@ -154,9 +155,23 @@ function Utils(cnf) {
154
155
  if (params[k] && lodash_1.default.isString(params[k]))
155
156
  params[k] = params[k].split(",");
156
157
  }
157
- const files = await RestifyFileConvertUploadFiles(await req.file());
158
+ // 检查请求是否包含文件上传
159
+ let files = {};
160
+ try {
161
+ // 只有在 multipart 请求时才处理文件
162
+ if ((_a = req.headers["content-type"]) === null || _a === void 0 ? void 0 : _a.includes("multipart/form-data")) {
163
+ const uploadedFile = await req.file();
164
+ if (uploadedFile) {
165
+ files = await RestifyFileConvertUploadFiles(uploadedFile);
166
+ }
167
+ }
168
+ }
169
+ catch (error) {
170
+ // 如果文件处理出错,记录错误但不中断请求处理
171
+ console.warn("File upload processing error:", error);
172
+ }
158
173
  // 将上传文件附加到 params 中
159
- return { ...params, ...req.files };
174
+ return { ...params, ...files };
160
175
  },
161
176
  /**
162
177
  *
package/dist/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import { Defaults } from "./defaults";
2
2
  import Deps = require("./deps/defines");
3
- import type { CnfDef as CacheCnfDef } from "./deps/cache";
4
3
  export { Main as Cfg } from "./cfg";
5
4
  export * as DM from "./dm";
6
5
  export { Errors } from "./Errors";
7
6
  export { Main as Http } from "./http";
8
7
  export * as utils from "./utils";
9
- export declare const basicErrors: Readonly<Record<"notFound" | "notAllowed" | "noAuth", import("./Errors").ErrorFn>>;
8
+ export declare const basicErrors: Readonly<Record<"notFound" | "notAllowed" | "noAuth" | "resourceDuplicateAdd", import("./Errors").ErrorFn>>;
10
9
  type TDeps = typeof Deps;
10
+ export type Feature = keyof typeof Deps;
11
11
  /**
12
12
  * 获取模块配置类型
13
13
  */
14
- type ModuleConfig<T extends keyof TDeps> = T extends "cache" ? CacheCnfDef : TDeps[T]["Main"] extends (arg: infer R, ...args: any[]) => any ? R : {};
14
+ type ModuleConfig<T extends keyof TDeps> = Parameters<TDeps[T]["Main"]>[0];
15
15
  /**
16
16
  * 获取模块返回类型
17
17
  */
@@ -19,8 +19,8 @@ type ModuleReturn<T extends keyof TDeps> = ReturnType<TDeps[T]["Main"]>;
19
19
  /**
20
20
  * 合并多个模块的配置类型(可选)
21
21
  */
22
- type MergeConfigs<T extends readonly (keyof TDeps)[]> = {
23
- [K in T[number]]?: ModuleConfig<K>;
22
+ type Merge<T> = {
23
+ [k in keyof T]: T[k];
24
24
  };
25
25
  /**
26
26
  * 合并多个模块的返回类型
@@ -28,4 +28,4 @@ type MergeConfigs<T extends readonly (keyof TDeps)[]> = {
28
28
  type MergeReturns<T extends readonly (keyof TDeps)[]> = {
29
29
  [K in T[number]]: ModuleReturn<K>;
30
30
  };
31
- export declare function Main<T extends readonly (keyof TDeps)[]>(features: T): (cnf?: MergeConfigs<T>) => MergeReturns<T> & Defaults;
31
+ export declare function Main<T extends Feature[] | Readonly<Feature[]> | ReadonlyArray<Feature>>(features: T): (cnf?: Merge<ModuleConfig<T[number]>>) => MergeReturns<T> & Defaults;
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ const lodash_1 = __importDefault(require("lodash"));
42
42
  const defaults_1 = require("./defaults");
43
43
  const DM = __importStar(require("./dm"));
44
44
  const Deps = require("./deps/defines");
45
+ // 显式导入 cache 模块的类型定义
45
46
  var cfg_1 = require("./cfg");
46
47
  Object.defineProperty(exports, "Cfg", { enumerable: true, get: function () { return cfg_1.Main; } });
47
48
  exports.DM = __importStar(require("./dm"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@domain.js/main",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.4",
4
4
  "description": "DDD framework",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -1,15 +0,0 @@
1
- import { someSeries } from "async";
2
- interface Deps {
3
- async: {
4
- someSeries: typeof someSeries;
5
- };
6
- errors: {
7
- notAllowed(...args: any[]): Error;
8
- };
9
- }
10
- export declare function Main(cnf: {}, deps: Deps): {
11
- equal: (v1: any, v2: any) => boolean;
12
- privacy: (fns: [Function, ...any[]][], error?: Error) => Promise<void>;
13
- };
14
- export declare const Deps: string[];
15
- export {};
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Deps = void 0;
4
- exports.Main = Main;
5
- function Main(cnf, deps) {
6
- const { async, errors } = deps;
7
- /** 检测两个值是否相等 */
8
- const equal = (v1, v2) => v1 === v2;
9
- /** 判断判断,一次执行数组里的函数 遇到成功的立刻停止,否则抛出信息 */
10
- const PRIVACY_DEFAULT_ERROR = errors.notAllowed("权限不足");
11
- const privacy = async (fns, error = PRIVACY_DEFAULT_ERROR) => {
12
- const passed = (await async.someSeries(fns, async ([fn, ...args]) => {
13
- const ret = await fn(...args);
14
- return ret;
15
- }));
16
- if (!passed)
17
- throw error;
18
- };
19
- return {
20
- equal,
21
- privacy,
22
- };
23
- }
24
- exports.Deps = ["errors", "async"];