@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.
- package/dist/basic-errors.d.ts +1 -1
- package/dist/basic-errors.js +1 -0
- package/dist/deps/cache/index.d.ts +2 -2
- package/dist/deps/cache/index.js +1 -1
- package/dist/deps/defines.d.ts +0 -2
- package/dist/deps/defines.js +0 -2
- package/dist/deps/parallel/index.d.ts +1 -8
- package/dist/deps/parallel/index.js +7 -6
- package/dist/deps/rest/index.d.ts +2 -1
- package/dist/deps/rest/index.js +2 -3
- package/dist/deps/rest/utils.d.ts +0 -10
- package/dist/deps/rest/utils.js +55 -50
- package/dist/http/index.js +1 -1
- package/dist/http/router.js +0 -1
- package/dist/http/utils.js +17 -2
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/dist/deps/checker/index.d.ts +0 -15
- package/dist/deps/checker/index.js +0 -24
package/dist/basic-errors.d.ts
CHANGED
|
@@ -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>>;
|
package/dist/basic-errors.js
CHANGED
|
@@ -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?:
|
|
8
|
+
redis?: RedisOptions;
|
|
9
9
|
}
|
|
10
10
|
export interface DepsDef {
|
|
11
11
|
IORedis: typeof Redis;
|
package/dist/deps/cache/index.js
CHANGED
|
@@ -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;
|
package/dist/deps/defines.d.ts
CHANGED
|
@@ -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;
|
package/dist/deps/defines.js
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
67
|
+
await (0, async_1.eachLimit)([...doings], 10, async (key) => {
|
|
67
68
|
await redis.expire(key, maxExpireSeconds);
|
|
68
69
|
});
|
|
69
70
|
};
|
|
70
|
-
|
|
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
|
|
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 = ["
|
|
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:
|
|
46
|
+
export declare const Deps: never[];
|
package/dist/deps/rest/index.js
CHANGED
|
@@ -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 = [
|
|
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) => {
|
package/dist/deps/rest/utils.js
CHANGED
|
@@ -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
|
-
|
|
59
|
-
if (!
|
|
63
|
+
lodash_1.default.each(cols, (x) => {
|
|
64
|
+
if (!lodash_1.default.has(params, x))
|
|
60
65
|
return;
|
|
61
|
-
if (!
|
|
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 &&
|
|
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) &&
|
|
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 || !
|
|
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 =
|
|
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
|
|
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 (!
|
|
146
|
+
if (!lodash_1.default.isString(qstr))
|
|
142
147
|
return undefined;
|
|
143
|
-
const q = qstr.trim() ?
|
|
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 ?
|
|
151
|
+
const searchs = searchStr ? lodash_1.default.split(searchStr, ",") : null;
|
|
147
152
|
const ors = [];
|
|
148
153
|
if (!Model.searchCols)
|
|
149
154
|
return undefined;
|
|
150
|
-
|
|
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 && !
|
|
163
|
+
if (searchs && searchs.length && !lodash_1.default.includes(searchs, _col))
|
|
159
164
|
return;
|
|
160
|
-
ors.push(
|
|
161
|
-
const arr =
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (
|
|
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 =
|
|
241
|
-
const endDate =
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
343
|
+
lodash_1.default.each(["gt", "gte", "lt", "lte"], (x) => {
|
|
339
344
|
const c = `${name}_${x}`;
|
|
340
|
-
if (!
|
|
345
|
+
if (!lodash_1.default.isString(params[c]) && !lodash_1.default.isNumber(params[c]))
|
|
341
346
|
return;
|
|
342
|
-
value =
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
411
|
+
lodash_1.default.each(includes, (x) => {
|
|
407
412
|
const includeWhere = {};
|
|
408
|
-
const filterAttrs = x.model.filterAttrs ||
|
|
409
|
-
|
|
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 =
|
|
443
|
-
if (
|
|
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
|
}
|
package/dist/http/index.js
CHANGED
package/dist/http/router.js
CHANGED
|
@@ -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) => {
|
package/dist/http/utils.js
CHANGED
|
@@ -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
|
-
|
|
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, ...
|
|
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> =
|
|
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
|
|
23
|
-
[
|
|
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
|
|
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,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"];
|