@domain.js/main 0.1.3 → 0.1.8
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/.husky/pre-commit +1 -1
- package/dist/cli/index.js +45 -70
- package/dist/cli/schema2ts.d.ts +1 -0
- package/dist/cli/schema2ts.js +37 -0
- package/dist/deps/cia/index.d.ts +2 -0
- package/dist/deps/cia/index.js +21 -1
- package/dist/deps/cron/index.js +1 -1
- package/dist/deps/defines.d.ts +2 -2
- package/dist/deps/defines.js +2 -2
- package/dist/deps/myCia/errors.d.ts +6 -0
- package/dist/deps/myCia/errors.js +36 -0
- package/dist/deps/myCia/index.d.ts +63 -0
- package/dist/deps/myCia/index.js +308 -0
- package/dist/deps/request/index.js +1 -1
- package/dist/deps/signer/index.d.ts +2 -2
- package/dist/deps/signer/index.js +1 -1
- package/dist/dm/index.d.ts +1 -1
- package/dist/http/defines.d.ts +0 -1
- package/dist/http/index.d.ts +0 -1
- package/dist/http/index.js +1 -2
- package/dist/http/router.d.ts +8 -4
- package/dist/http/router.js +2 -50
- package/dist/http/utils.d.ts +0 -1
- package/dist/http/utils.js +0 -35
- package/dist/index.d.ts +7 -7
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/index.js +1 -1
- package/package.json +5 -4
package/.husky/pre-commit
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -31,10 +31,11 @@ const codeStyleFormat = (targetFile) => new Promise((resolve, reject) => {
|
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
const makeDefineFile = async (modules, targetFile, isTS) => {
|
|
34
|
+
const dirname = path.dirname(targetFile);
|
|
34
35
|
const content = ["// domain-cli 自动生成"];
|
|
35
36
|
const _exports = [];
|
|
36
37
|
for (let i = 0; i < modules.length; i += 1) {
|
|
37
|
-
const name = modules[i];
|
|
38
|
+
const name = path.relative(dirname, modules[i]);
|
|
38
39
|
const variable = filePath2Var(name);
|
|
39
40
|
if (isTS) {
|
|
40
41
|
content.push(`import * as ${variable} from "./${name}"`);
|
|
@@ -76,10 +77,10 @@ const checkHookExport = (_dir) => {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
};
|
|
79
|
-
const loadDeps = async (rootDir
|
|
80
|
+
const loadDeps = async (rootDir, ext = "js") => {
|
|
80
81
|
const isTS = ext === "ts";
|
|
81
82
|
const modules = [];
|
|
82
|
-
const dir = path.resolve(rootDir, "
|
|
83
|
+
const dir = path.resolve(rootDir, "./");
|
|
83
84
|
for (const x of fs.readdirSync(dir)) {
|
|
84
85
|
// 忽略隐藏目录
|
|
85
86
|
if (x[0] === ".")
|
|
@@ -90,10 +91,10 @@ const loadDeps = async (rootDir = process.cwd(), ext = "js") => {
|
|
|
90
91
|
if (!stat.isDirectory())
|
|
91
92
|
continue;
|
|
92
93
|
checkHookExport(_dir);
|
|
93
|
-
modules.push(x);
|
|
94
|
+
modules.push(path.join(dir, x));
|
|
94
95
|
}
|
|
95
96
|
// 按字典排序,后续有变动的时候不容易冲突
|
|
96
|
-
const targetFile = path.resolve(rootDir,
|
|
97
|
+
const targetFile = path.resolve(rootDir, `./defines.${ext}`);
|
|
97
98
|
await makeDefineFile(modules.sort(), targetFile, isTS);
|
|
98
99
|
};
|
|
99
100
|
const checkService = (_dir) => {
|
|
@@ -106,7 +107,7 @@ const checkService = (_dir) => {
|
|
|
106
107
|
const loadServices = async (rootDir = process.cwd(), ext = "js") => {
|
|
107
108
|
const isTS = ext === "ts";
|
|
108
109
|
const modules = [];
|
|
109
|
-
const dir = path.resolve(rootDir, "src/services/");
|
|
110
|
+
const dir = path.resolve(rootDir, "src/domain/services/");
|
|
110
111
|
for (const x of fs.readdirSync(dir)) {
|
|
111
112
|
// 忽略隐藏目录, 忽略私有目录
|
|
112
113
|
if (x[0] === "." || x[0] === "_")
|
|
@@ -117,81 +118,55 @@ const loadServices = async (rootDir = process.cwd(), ext = "js") => {
|
|
|
117
118
|
if (!stat.isDirectory())
|
|
118
119
|
continue;
|
|
119
120
|
checkService(_dir);
|
|
120
|
-
modules.push(x);
|
|
121
|
+
modules.push(path.join(dir, x));
|
|
121
122
|
}
|
|
122
123
|
// 按字典排序,后续有变动的时候不容易冲突
|
|
123
|
-
const targetFile = path.resolve(rootDir, `src/services/defines.${ext}`);
|
|
124
|
+
const targetFile = path.resolve(rootDir, `src/domain/services/defines.${ext}`);
|
|
124
125
|
await makeDefineFile(modules.sort(), targetFile, isTS);
|
|
125
126
|
};
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
/**
|
|
128
|
+
* 尝试读取目录下的文件
|
|
129
|
+
* @param dir 目录路径
|
|
130
|
+
* @param list 读取到schema后压入改列表
|
|
131
|
+
*/
|
|
132
|
+
const tryReadSchemas = (dir, list, isTS = false) => {
|
|
133
|
+
if (!fs.existsSync(dir))
|
|
134
|
+
return;
|
|
135
|
+
const stat = fs.statSync(dir);
|
|
136
|
+
if (stat.isFile())
|
|
137
|
+
return;
|
|
129
138
|
for (const x of fs.readdirSync(dir)) {
|
|
130
|
-
|
|
131
|
-
if (x[0] === ".")
|
|
139
|
+
if (x.startsWith("."))
|
|
132
140
|
continue;
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
const { name, ext } = path.parse(x);
|
|
136
|
-
const relativeFilePath = `./${path.join(parent, name)}`;
|
|
137
|
-
const moduleName = file2Module(name);
|
|
138
|
-
// 如果是文件则记录
|
|
139
|
-
if (stat.isFile()) {
|
|
140
|
-
if (ext === ".ts") {
|
|
141
|
-
const JSFile = path.resolve(dir, `${name}.js`);
|
|
142
|
-
// 对应的js文件存在,则ts文件忽略
|
|
143
|
-
if (fs.existsSync(JSFile))
|
|
144
|
-
continue;
|
|
145
|
-
// 对应的js文件不存在,抛出异常提示用户要先编译
|
|
146
|
-
throw Error(`请先编译ts文件: ${file}`);
|
|
147
|
-
}
|
|
148
|
-
files.push(relativeFilePath);
|
|
149
|
-
paths[moduleName] = relativeFilePath;
|
|
141
|
+
const ext = path.extname(x);
|
|
142
|
+
if (isTS && ext !== ".ts")
|
|
150
143
|
continue;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
144
|
+
if (!isTS && ext !== ".js")
|
|
145
|
+
continue;
|
|
146
|
+
list.push(path.join(dir, path.basename(x, isTS ? ".ts" : ".js")));
|
|
155
147
|
}
|
|
156
|
-
return paths;
|
|
157
148
|
};
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
content.push(`const ${variable} = require("${_path}")`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
// 处理导出
|
|
179
|
-
content.push("\n");
|
|
180
|
-
let _exports = JSON.stringify(paths, null, 2);
|
|
181
|
-
for (let i = 0; i < files.length; i += 1) {
|
|
182
|
-
_exports = _exports.replace(`"${files[i]}"`, filePath2Var(files[i]));
|
|
183
|
-
}
|
|
184
|
-
if (isTS) {
|
|
185
|
-
content.push(`export = ${_exports}`);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
content.push(`module.exports = ${_exports}`);
|
|
149
|
+
const loadSchemas = async (rootDir = process.cwd(), ext = "js") => {
|
|
150
|
+
const isTS = ext === "ts";
|
|
151
|
+
const modules = [];
|
|
152
|
+
const dir = path.resolve(rootDir, "src/domain/services/");
|
|
153
|
+
for (const x of fs.readdirSync(dir)) {
|
|
154
|
+
// 忽略隐藏目录, 忽略私有目录
|
|
155
|
+
if (x[0] === "." || x[0] === "_")
|
|
156
|
+
continue;
|
|
157
|
+
const _dir = path.resolve(dir, x);
|
|
158
|
+
const stat = fs.statSync(_dir);
|
|
159
|
+
// 非目录忽略,模块必须是目录
|
|
160
|
+
if (!stat.isDirectory())
|
|
161
|
+
continue;
|
|
162
|
+
// 尝试读取子目录里的 schemas 目录
|
|
163
|
+
tryReadSchemas(path.join(_dir, "schemas"), modules, isTS);
|
|
189
164
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
165
|
+
// 按字典排序,后续有变动的时候不容易冲突
|
|
166
|
+
const targetFile = path.resolve(rootDir, `src/domain/services/schemas.${ext}`);
|
|
167
|
+
await makeDefineFile(modules.sort(), targetFile, isTS);
|
|
193
168
|
};
|
|
194
|
-
const actions = { loadDeps, loadServices,
|
|
169
|
+
const actions = { loadDeps, loadServices, loadSchemas };
|
|
195
170
|
const main = async (command) => {
|
|
196
171
|
const action = actions[command];
|
|
197
172
|
if (!action) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const json_schema_to_typescript_1 = require("json-schema-to-typescript");
|
|
6
|
+
const _require = require;
|
|
7
|
+
async function main(file, single = false, name = "Params") {
|
|
8
|
+
const stats = fs.statSync(file);
|
|
9
|
+
if (stats.isFile()) {
|
|
10
|
+
const arr = file.split(".");
|
|
11
|
+
if (arr.pop() !== "js")
|
|
12
|
+
return;
|
|
13
|
+
const obj = _require(file);
|
|
14
|
+
if (!single) {
|
|
15
|
+
if (!Array.isArray(obj))
|
|
16
|
+
return;
|
|
17
|
+
if (typeof obj[1] !== "object")
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const ts = await (0, json_schema_to_typescript_1.compile)(single ? obj : obj[1], name);
|
|
22
|
+
arr.push("d.ts");
|
|
23
|
+
fs.writeFileSync(arr.join("."), ts);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
console.error(file, e);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const files = fs.readdirSync(file);
|
|
31
|
+
for await (const x of files) {
|
|
32
|
+
if (x === "." || x === "..")
|
|
33
|
+
continue;
|
|
34
|
+
await main(path.resolve(file, x), single, name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
main(process.argv[2], process.argv[3] === "single", process.argv[4]);
|
package/dist/deps/cia/index.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export declare function Main(cnf: Cnf, deps: Deps): {
|
|
|
56
56
|
link: (name: string, type: string, waiter: Function) => void;
|
|
57
57
|
submit: (name: string, data: any, callback?: Function | undefined) => void;
|
|
58
58
|
setFn: (type: "error" | "timeout", fn: (...args: any[]) => any) => void;
|
|
59
|
+
domainPaths: Set<string>;
|
|
60
|
+
modelHooks: Set<string>;
|
|
59
61
|
};
|
|
60
62
|
export declare const Deps: string[];
|
|
61
63
|
export {};
|
package/dist/deps/cia/index.js
CHANGED
|
@@ -282,7 +282,27 @@ function Main(cnf, deps) {
|
|
|
282
282
|
const isExiting = () => Boolean(exiting);
|
|
283
283
|
// 进程是否已经退出
|
|
284
284
|
const isExited = () => Boolean(exited);
|
|
285
|
-
|
|
285
|
+
/**
|
|
286
|
+
* 领域方法注册到 cia 上的路径集合
|
|
287
|
+
*/
|
|
288
|
+
const domainPaths = new Set();
|
|
289
|
+
/**
|
|
290
|
+
* Model hook 注册到 cia 上的路径集合
|
|
291
|
+
*/
|
|
292
|
+
const modelHooks = new Set();
|
|
293
|
+
return {
|
|
294
|
+
isExiting,
|
|
295
|
+
isExited,
|
|
296
|
+
checkReady,
|
|
297
|
+
getStats,
|
|
298
|
+
getUnlinks,
|
|
299
|
+
regist,
|
|
300
|
+
link,
|
|
301
|
+
submit,
|
|
302
|
+
setFn,
|
|
303
|
+
domainPaths,
|
|
304
|
+
modelHooks,
|
|
305
|
+
};
|
|
286
306
|
}
|
|
287
307
|
exports.Main = Main;
|
|
288
308
|
exports.Deps = ["_", "async", "logger", "utils", "redis", "graceful", "uuid"];
|
package/dist/deps/cron/index.js
CHANGED
package/dist/deps/defines.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as aes from "./aes";
|
|
2
2
|
import * as cache from "./cache";
|
|
3
3
|
import * as checker from "./checker";
|
|
4
|
-
import * as cia from "./cia";
|
|
5
4
|
import * as counter from "./counter";
|
|
6
5
|
import * as cron from "./cron";
|
|
7
6
|
import * as graceful from "./graceful";
|
|
8
7
|
import * as hash from "./hash";
|
|
9
8
|
import * as logger from "./logger";
|
|
9
|
+
import * as myCia from "./myCia";
|
|
10
10
|
import * as parallel from "./parallel";
|
|
11
11
|
import * as redis from "./redis";
|
|
12
12
|
import * as request from "./request";
|
|
@@ -18,12 +18,12 @@ declare const _default: {
|
|
|
18
18
|
aes: typeof aes;
|
|
19
19
|
cache: typeof cache;
|
|
20
20
|
checker: typeof checker;
|
|
21
|
-
cia: typeof cia;
|
|
22
21
|
counter: typeof counter;
|
|
23
22
|
cron: typeof cron;
|
|
24
23
|
graceful: typeof graceful;
|
|
25
24
|
hash: typeof hash;
|
|
26
25
|
logger: typeof logger;
|
|
26
|
+
myCia: typeof myCia;
|
|
27
27
|
parallel: typeof parallel;
|
|
28
28
|
redis: typeof redis;
|
|
29
29
|
request: typeof request;
|
package/dist/deps/defines.js
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
const aes = require("./aes");
|
|
4
4
|
const cache = require("./cache");
|
|
5
5
|
const checker = require("./checker");
|
|
6
|
-
const cia = require("./cia");
|
|
7
6
|
const counter = require("./counter");
|
|
8
7
|
const cron = require("./cron");
|
|
9
8
|
const graceful = require("./graceful");
|
|
10
9
|
const hash = require("./hash");
|
|
11
10
|
const logger = require("./logger");
|
|
11
|
+
const myCia = require("./myCia");
|
|
12
12
|
const parallel = require("./parallel");
|
|
13
13
|
const redis = require("./redis");
|
|
14
14
|
const request = require("./request");
|
|
@@ -20,12 +20,12 @@ module.exports = {
|
|
|
20
20
|
aes,
|
|
21
21
|
cache,
|
|
22
22
|
checker,
|
|
23
|
-
cia,
|
|
24
23
|
counter,
|
|
25
24
|
cron,
|
|
26
25
|
graceful,
|
|
27
26
|
hash,
|
|
28
27
|
logger,
|
|
28
|
+
myCia,
|
|
29
29
|
parallel,
|
|
30
30
|
redis,
|
|
31
31
|
request,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const util = require("util");
|
|
4
|
+
exports.default = () => {
|
|
5
|
+
const defines = [
|
|
6
|
+
["duplicatRegistMessage", "The message has been registed: %s"],
|
|
7
|
+
["registWhenReadyAfter", "The message dont registed when mcenter be ready after: %s"],
|
|
8
|
+
[
|
|
9
|
+
"submitUnregistedMessage",
|
|
10
|
+
"The message has not been registed: %s, data: %o, when will submit",
|
|
11
|
+
],
|
|
12
|
+
["linkUnregistedMessage", "The message has not been registed: %s, when will link"],
|
|
13
|
+
[
|
|
14
|
+
"linkUnknowTypes",
|
|
15
|
+
"The message link type unknown, message name is: %s, type is: %s, when will link",
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
"linkDuplicateType",
|
|
19
|
+
"The message link type duplicate, message name is: %s, type is: %s, when will link",
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
"linkListernerMustBeFunctionType",
|
|
23
|
+
"The message link waiter must be a function, message name is: %s, type is: %s, when will link",
|
|
24
|
+
],
|
|
25
|
+
["setFnNotAllowed", "Set function but unknown type: %s"],
|
|
26
|
+
];
|
|
27
|
+
const fns = {};
|
|
28
|
+
for (const [code, message] of defines) {
|
|
29
|
+
fns[code] = (...args) => {
|
|
30
|
+
const error = Error(util.format(message, ...args));
|
|
31
|
+
error.code = code;
|
|
32
|
+
return error;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return fns;
|
|
36
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as _ from "lodash";
|
|
2
|
+
import * as async from "async";
|
|
3
|
+
import { v4 } from "uuid";
|
|
4
|
+
interface Cnf {
|
|
5
|
+
cia?: {
|
|
6
|
+
concurrency?: number;
|
|
7
|
+
storeKey?: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
interface Deps {
|
|
11
|
+
_: Pick<typeof _, "pick" | "map" | "isFunction">;
|
|
12
|
+
async: Pick<typeof async, "eachSeries" | "queue">;
|
|
13
|
+
uuid: {
|
|
14
|
+
v4: typeof v4;
|
|
15
|
+
};
|
|
16
|
+
logger: {
|
|
17
|
+
info: (...args: any[]) => void;
|
|
18
|
+
error: (...args: any[]) => void;
|
|
19
|
+
};
|
|
20
|
+
redis: {
|
|
21
|
+
hset: Function;
|
|
22
|
+
hdel: Function;
|
|
23
|
+
hgetall: Function;
|
|
24
|
+
};
|
|
25
|
+
graceful: {
|
|
26
|
+
exit: (fn: () => Promise<void>) => void;
|
|
27
|
+
};
|
|
28
|
+
U: {
|
|
29
|
+
tryCatchLog<Fn extends (...args: any[]) => any>(fn: Fn, errorFn: (...args: any[]) => any): Fn;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface Stats {
|
|
33
|
+
pendings: number;
|
|
34
|
+
doings: number;
|
|
35
|
+
errors: number;
|
|
36
|
+
dones: number;
|
|
37
|
+
}
|
|
38
|
+
declare type Type = {
|
|
39
|
+
type: string;
|
|
40
|
+
timeout?: number;
|
|
41
|
+
validator?: Function;
|
|
42
|
+
};
|
|
43
|
+
export declare function Main(cnf: Cnf, deps: Deps): {
|
|
44
|
+
isExiting: () => boolean;
|
|
45
|
+
isExited: () => boolean;
|
|
46
|
+
checkReady: () => boolean;
|
|
47
|
+
getStats: () => {
|
|
48
|
+
[name: string]: Stats & {
|
|
49
|
+
_types: ({
|
|
50
|
+
type: string;
|
|
51
|
+
} & Stats)[];
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
getUnlinks: () => string[];
|
|
55
|
+
regist: (name: string, validator: Function | undefined, types: Type[]) => number;
|
|
56
|
+
link: (name: string, type: string, waiter: Function) => void;
|
|
57
|
+
submit: (name: string, data: any, callback?: Function | undefined) => void;
|
|
58
|
+
setFn: (type: "error" | "timeout", fn: (...args: any[]) => any) => void;
|
|
59
|
+
domainPaths: Set<string>;
|
|
60
|
+
modelHooks: Set<string>;
|
|
61
|
+
};
|
|
62
|
+
export declare const Deps: string[];
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Deps = exports.Main = void 0;
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
function Main(cnf, deps) {
|
|
6
|
+
const { _, async, uuid: { v4: uuid }, logger, redis, graceful, U: { tryCatchLog }, } = deps;
|
|
7
|
+
const { cia } = cnf;
|
|
8
|
+
const concurrency = Math.max(1, ((cia && cia.concurrency) || 10) | 0);
|
|
9
|
+
const storeKey = (cia && cia.storeKey) || "cia-store";
|
|
10
|
+
const errors = (0, errors_1.default)();
|
|
11
|
+
let doingCount = 0; // 正在执行的消息数量
|
|
12
|
+
let exited = false; // 是否已经完成退出
|
|
13
|
+
let exiting = false; // 是否正在退出
|
|
14
|
+
let readyToExitFn; // 完成退出前准备后执行函数
|
|
15
|
+
let unlinkdCount = 0; // 未被订阅的数量, 基于 {name}::{type} 判断
|
|
16
|
+
let isReady = false; // 系统是否已准备妥当
|
|
17
|
+
const registeds = {};
|
|
18
|
+
// 默认通知函数
|
|
19
|
+
const fns = {
|
|
20
|
+
error: logger.error,
|
|
21
|
+
timeout: logger.info,
|
|
22
|
+
};
|
|
23
|
+
// 记录监听回调函数
|
|
24
|
+
// { [${name}::${type}]: { [type]: fn } }
|
|
25
|
+
const waiters = new Map();
|
|
26
|
+
// 更新等待数量
|
|
27
|
+
const updatePendings = (registed) => {
|
|
28
|
+
const { result = {}, types } = registed;
|
|
29
|
+
const withouts = new Set(Object.keys(result));
|
|
30
|
+
registed.pendings += 1;
|
|
31
|
+
types.forEach((x) => {
|
|
32
|
+
if (!withouts.has(x.type))
|
|
33
|
+
x.pendings += 1;
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
// 更新 doings 统计信息
|
|
37
|
+
const updateDoings = (item) => {
|
|
38
|
+
item.pendings -= 1;
|
|
39
|
+
item.doings += 1;
|
|
40
|
+
};
|
|
41
|
+
// 更新 errors 统计信息
|
|
42
|
+
const updateErrors = (item) => {
|
|
43
|
+
item.doings -= 1;
|
|
44
|
+
item.errors += 1;
|
|
45
|
+
};
|
|
46
|
+
// 更新 dones 统计信息
|
|
47
|
+
const updateDones = (item) => {
|
|
48
|
+
item.doings -= 1;
|
|
49
|
+
item.dones += 1;
|
|
50
|
+
};
|
|
51
|
+
// 消息分发函数,分发到对应的订阅函数上
|
|
52
|
+
const dispatch = async (item) => {
|
|
53
|
+
const { id, name, data, result = {}, callback } = item;
|
|
54
|
+
const registed = registeds[name];
|
|
55
|
+
const { types } = registed;
|
|
56
|
+
const withouts = new Set(Object.keys(result));
|
|
57
|
+
updateDoings(registed);
|
|
58
|
+
doingCount += 1;
|
|
59
|
+
let errorCount = 0;
|
|
60
|
+
await async.eachSeries(types, async (_type) => {
|
|
61
|
+
const { type, timeout, validator } = _type;
|
|
62
|
+
// 看看是否有设置要忽略掉某些订阅者
|
|
63
|
+
// 这个功能主要是留给应用无故中断后系统自动恢复的任务执行
|
|
64
|
+
if (withouts && withouts.has(type))
|
|
65
|
+
return;
|
|
66
|
+
if (exiting)
|
|
67
|
+
return;
|
|
68
|
+
const fn = waiters.get(`${name}::${type}`);
|
|
69
|
+
const startAt = Date.now();
|
|
70
|
+
let err = null;
|
|
71
|
+
let ret = null;
|
|
72
|
+
try {
|
|
73
|
+
updateDoings(_type);
|
|
74
|
+
ret = await fn(data);
|
|
75
|
+
if (validator)
|
|
76
|
+
validator(ret);
|
|
77
|
+
updateDones(_type);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
updateErrors(_type);
|
|
81
|
+
fns.error(e, id, name, type, data);
|
|
82
|
+
errorCount += 1;
|
|
83
|
+
err = e;
|
|
84
|
+
}
|
|
85
|
+
const consumedMS = Date.now() - startAt;
|
|
86
|
+
if (timeout && timeout < consumedMS)
|
|
87
|
+
fns.timeout(consumedMS, id, name, type);
|
|
88
|
+
result[type] = [err, ret, consumedMS];
|
|
89
|
+
// 记录执行结果
|
|
90
|
+
logger.info(`cia.dispatch\t${id}\t${type}`, result[type]);
|
|
91
|
+
});
|
|
92
|
+
doingCount -= 1;
|
|
93
|
+
if (errorCount) {
|
|
94
|
+
updateErrors(registed);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
updateDones(registed);
|
|
98
|
+
}
|
|
99
|
+
// submit 设置了callback 要记得执行回调函数
|
|
100
|
+
if (callback)
|
|
101
|
+
callback(result);
|
|
102
|
+
// 正在退出,且完成的不等于总共的,则需要储存, 以备下次启动后执行
|
|
103
|
+
if (exiting) {
|
|
104
|
+
if (Object.keys(result).length !== types.length) {
|
|
105
|
+
item.result = result;
|
|
106
|
+
// 存储以备下次启动恢复执行
|
|
107
|
+
await redis.hset(storeKey, item.id, JSON.stringify(item));
|
|
108
|
+
}
|
|
109
|
+
// 全部处理完毕后,执行退出
|
|
110
|
+
if (!doingCount) {
|
|
111
|
+
exited = true;
|
|
112
|
+
exiting = false;
|
|
113
|
+
readyToExitFn();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const statsFields = Object.freeze(["pendings", "doings", "dones", "errors"]);
|
|
118
|
+
// 获取统计信息
|
|
119
|
+
const getStats = () => {
|
|
120
|
+
const stats = {};
|
|
121
|
+
for (const name of Object.keys(registeds)) {
|
|
122
|
+
const { types } = registeds[name];
|
|
123
|
+
stats[name] = {
|
|
124
|
+
..._.pick(registeds[name], statsFields),
|
|
125
|
+
_types: types.map((x) => _.pick(x, "type", ...statsFields)),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return stats;
|
|
129
|
+
};
|
|
130
|
+
// 内部消息队列, 初始化后立即暂定,等待 regist, link 都准备好了在开始执行
|
|
131
|
+
// 这样就不会有未成功订阅函数执行遗漏的问题了
|
|
132
|
+
// 例如: A 函数要监听 1 好消息的 save 类型,结果在完成订阅前,已经有某个区域 submit 了 1 号事件
|
|
133
|
+
// 如果队列一开始不暂停就会出现A函数遗漏执行
|
|
134
|
+
const queue = async.queue(dispatch, concurrency);
|
|
135
|
+
queue.pause();
|
|
136
|
+
graceful.exit(async () => {
|
|
137
|
+
exiting = true;
|
|
138
|
+
await new Promise((resolve) => {
|
|
139
|
+
// 如果队列已经清空,且没有正在执行的消息,则直接退出
|
|
140
|
+
if (!queue.length() && !doingCount) {
|
|
141
|
+
exited = true;
|
|
142
|
+
exiting = false;
|
|
143
|
+
resolve();
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
readyToExitFn = resolve;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
// 恢复上次残留的消息订阅执行
|
|
151
|
+
const recover = async () => {
|
|
152
|
+
const items = await redis.hgetall(storeKey);
|
|
153
|
+
if (!items)
|
|
154
|
+
return;
|
|
155
|
+
for await (const id of Object.keys(items)) {
|
|
156
|
+
const item = items[id];
|
|
157
|
+
const ok = await redis.hdel(storeKey, id);
|
|
158
|
+
if (ok !== 1)
|
|
159
|
+
continue;
|
|
160
|
+
try {
|
|
161
|
+
const data = JSON.parse(item);
|
|
162
|
+
const { name } = data;
|
|
163
|
+
queue.push(data);
|
|
164
|
+
updatePendings(registeds[name]);
|
|
165
|
+
logger.info("cia-recover: %s", item);
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
logger.error(e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
// regist 消息注册,提前注册好需要submit和link的消息
|
|
173
|
+
// 这么做的目的是可以随时检测是否所有的消息都消费者,消费者类型是否正确
|
|
174
|
+
// 同时在submit的时候也可以检测发送的数据是否符合规定的格式
|
|
175
|
+
// name: String 消息名称
|
|
176
|
+
// validator?: Function 消息体数据格式验证函数
|
|
177
|
+
// types: [{
|
|
178
|
+
// type: 'updateUser', // 类型名称
|
|
179
|
+
// timeout?: 100, // 执行超时限定, 单位毫秒,可选 默认为 0, 不限制
|
|
180
|
+
// validator?: fn, // 返回值格式验证函数, 可选
|
|
181
|
+
// }]
|
|
182
|
+
const regist = (name, validator, types) => {
|
|
183
|
+
if (isReady)
|
|
184
|
+
throw errors.registWhenReadyAfter(name);
|
|
185
|
+
if (registeds[name])
|
|
186
|
+
throw errors.duplicatRegistMessage(name);
|
|
187
|
+
const typeNames = new Set(_.map(types, "type"));
|
|
188
|
+
types.forEach((x) => {
|
|
189
|
+
Object.assign(x, { pendings: 0, dones: 0, doings: 0, errors: 0 });
|
|
190
|
+
});
|
|
191
|
+
const item = {
|
|
192
|
+
validator,
|
|
193
|
+
types: types,
|
|
194
|
+
typeNames,
|
|
195
|
+
pendings: 0,
|
|
196
|
+
dones: 0,
|
|
197
|
+
doings: 0,
|
|
198
|
+
errors: 0,
|
|
199
|
+
};
|
|
200
|
+
unlinkdCount += typeNames.size;
|
|
201
|
+
registeds[name] = item;
|
|
202
|
+
return Object.keys(registeds).length;
|
|
203
|
+
};
|
|
204
|
+
// start 启动系统执行, 这之前一定要regist 和 link 都准备好
|
|
205
|
+
const start = async () => {
|
|
206
|
+
queue.resume();
|
|
207
|
+
await recover();
|
|
208
|
+
};
|
|
209
|
+
// check 消息注册、监听检测
|
|
210
|
+
// 检查是否存在注册了的消息,但没有人监听消费
|
|
211
|
+
const checkReady = () => {
|
|
212
|
+
if (unlinkdCount !== 0)
|
|
213
|
+
return false;
|
|
214
|
+
if (!isReady) {
|
|
215
|
+
isReady = true;
|
|
216
|
+
start();
|
|
217
|
+
}
|
|
218
|
+
return true;
|
|
219
|
+
};
|
|
220
|
+
// link 消息订阅
|
|
221
|
+
const link = (name, type, waiter) => {
|
|
222
|
+
if (!registeds[name])
|
|
223
|
+
throw errors.linkUnregistedMessage(name);
|
|
224
|
+
const { typeNames } = registeds[name];
|
|
225
|
+
if (!typeNames.has(type))
|
|
226
|
+
throw errors.linkUnknowTypes(name, type);
|
|
227
|
+
if (!_.isFunction(waiter))
|
|
228
|
+
throw errors.linkListernerMustBeFunctionType(name, type);
|
|
229
|
+
const key = `${name}::${type}`;
|
|
230
|
+
if (waiters.get(key))
|
|
231
|
+
throw errors.linkDuplicateType(name, type);
|
|
232
|
+
waiters.set(key, waiter);
|
|
233
|
+
unlinkdCount -= 1;
|
|
234
|
+
checkReady();
|
|
235
|
+
};
|
|
236
|
+
// submit 消息发布
|
|
237
|
+
// name string 消息名称
|
|
238
|
+
// data any 消息数据
|
|
239
|
+
// callback function 消息执行完毕回调
|
|
240
|
+
const submit = (name, data, callback) => {
|
|
241
|
+
if (!registeds[name]) {
|
|
242
|
+
// 这里记录error就可以了。throw没有意义,因为submit是异步的
|
|
243
|
+
// throw error并没有被捕获,还会导致调用方的后续代码不执行
|
|
244
|
+
logger.error(errors.submitUnregistedMessage(name, data));
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (callback && !_.isFunction(callback))
|
|
248
|
+
callback = undefined;
|
|
249
|
+
const { validator } = registeds[name];
|
|
250
|
+
if (validator)
|
|
251
|
+
validator(data);
|
|
252
|
+
const id = uuid();
|
|
253
|
+
queue.push({ id, name, data, callback });
|
|
254
|
+
updatePendings(registeds[name]);
|
|
255
|
+
logger.info(`cia.submit\t${id}`, { name, data });
|
|
256
|
+
};
|
|
257
|
+
// 设置通知函数,错误通知,超时通知
|
|
258
|
+
// 在消息分发执行的时候遇到错误会调用错误通知函数
|
|
259
|
+
// 在消息分发执行的时候遇到超时会调用超时通知函数
|
|
260
|
+
// type string 类型,error or timeout
|
|
261
|
+
// fn function 通知函数
|
|
262
|
+
const setFn = (type, fn) => {
|
|
263
|
+
if (!fns[type])
|
|
264
|
+
throw errors.setFnNotAllowed(type);
|
|
265
|
+
// 这里之所以会用 tryCatchLog 封装函数,是不想让这些函数的执行影响主流程
|
|
266
|
+
// 这些函数内部抛出的异常不会导致主流程执行中断
|
|
267
|
+
fns[type] = tryCatchLog(fn, logger.error);
|
|
268
|
+
};
|
|
269
|
+
// 获取未被连接的任务消息
|
|
270
|
+
const getUnlinks = () => {
|
|
271
|
+
const losts = [];
|
|
272
|
+
for (const name of Object.keys(registeds)) {
|
|
273
|
+
for (const { type } of registeds[name].types) {
|
|
274
|
+
const key = `${name}::${type}`;
|
|
275
|
+
if (!waiters.has(key))
|
|
276
|
+
losts.push(key);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return losts;
|
|
280
|
+
};
|
|
281
|
+
// 进程是否正在退出
|
|
282
|
+
const isExiting = () => Boolean(exiting);
|
|
283
|
+
// 进程是否已经退出
|
|
284
|
+
const isExited = () => Boolean(exited);
|
|
285
|
+
/**
|
|
286
|
+
* 领域方法注册到 cia 上的路径集合
|
|
287
|
+
*/
|
|
288
|
+
const domainPaths = new Set();
|
|
289
|
+
/**
|
|
290
|
+
* Model hook 注册到 cia 上的路径集合
|
|
291
|
+
*/
|
|
292
|
+
const modelHooks = new Set();
|
|
293
|
+
return {
|
|
294
|
+
isExiting,
|
|
295
|
+
isExited,
|
|
296
|
+
checkReady,
|
|
297
|
+
getStats,
|
|
298
|
+
getUnlinks,
|
|
299
|
+
regist,
|
|
300
|
+
link,
|
|
301
|
+
submit,
|
|
302
|
+
setFn,
|
|
303
|
+
domainPaths,
|
|
304
|
+
modelHooks,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
exports.Main = Main;
|
|
308
|
+
exports.Deps = ["_", "async", "logger", "utils", "redis", "graceful", "uuid"];
|
|
@@ -19,7 +19,7 @@ function Main(cnf, deps) {
|
|
|
19
19
|
const d = r.data;
|
|
20
20
|
if (typeof d === "string")
|
|
21
21
|
return [r.status, d];
|
|
22
|
-
return [d.code || r.status, d.message ||
|
|
22
|
+
return [d.code || r.status, d.message || JSON.stringify(d)];
|
|
23
23
|
})().join("\t");
|
|
24
24
|
if (!cnf.axios)
|
|
25
25
|
cnf.axios = {};
|
|
@@ -5,7 +5,7 @@ export interface Opt {
|
|
|
5
5
|
/** Key for signature calculation */
|
|
6
6
|
key: string;
|
|
7
7
|
/** Second timestamp */
|
|
8
|
-
timestamp: number;
|
|
8
|
+
timestamp: number | string;
|
|
9
9
|
/** Signature algorithm, fixed as hmacsha256 */
|
|
10
10
|
signMethod: "HmacSHA256";
|
|
11
11
|
/** Signature version, fixed as 1 */
|
|
@@ -37,7 +37,7 @@ export declare function Main(): {
|
|
|
37
37
|
readonly "x-auth-signature": string;
|
|
38
38
|
readonly "x-auth-key": string;
|
|
39
39
|
readonly "x-auth-method": string;
|
|
40
|
-
readonly "x-auth-timestamp":
|
|
40
|
+
readonly "x-auth-timestamp": string;
|
|
41
41
|
readonly "x-auth-sign-method": "HmacSHA256";
|
|
42
42
|
readonly "x-auth-sign-version": "1";
|
|
43
43
|
};
|
package/dist/dm/index.d.ts
CHANGED
package/dist/http/defines.d.ts
CHANGED
package/dist/http/index.d.ts
CHANGED
package/dist/http/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const router_1 = require("./router");
|
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
function Main(cnf, deps) {
|
|
8
8
|
const utils = (0, utils_1.Utils)(cnf);
|
|
9
|
-
const { routers, getSchemaByPath, domain, httpCodes,
|
|
9
|
+
const { routers, getSchemaByPath, domain, httpCodes, makeProfileHook } = deps;
|
|
10
10
|
const server = restify.createServer();
|
|
11
11
|
server.use(restify.plugins.queryParser());
|
|
12
12
|
server.use(restify.plugins.bodyParser({
|
|
@@ -21,7 +21,6 @@ function Main(cnf, deps) {
|
|
|
21
21
|
getSchemaByPath,
|
|
22
22
|
domain,
|
|
23
23
|
apisRoute: cnf.apisRoute,
|
|
24
|
-
swagger: [cnf.swaggerApiPath, swaggerDocJson],
|
|
25
24
|
});
|
|
26
25
|
routers(router);
|
|
27
26
|
// Http server start
|
package/dist/http/router.d.ts
CHANGED
|
@@ -11,11 +11,15 @@ interface Deps {
|
|
|
11
11
|
apisRoute?: string;
|
|
12
12
|
swagger?: [any, any];
|
|
13
13
|
}
|
|
14
|
+
/** 对 params 的处理函数 */
|
|
15
|
+
declare type Handler = (params: any) => void;
|
|
16
|
+
/** 对执行结构的处理 */
|
|
17
|
+
declare type ResHandler = (results: any, res: restify.Response) => void;
|
|
14
18
|
export declare function Router(deps: Deps): {
|
|
15
|
-
get: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?:
|
|
16
|
-
post: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?:
|
|
17
|
-
put: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?:
|
|
18
|
-
del: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?:
|
|
19
|
+
get: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?: Handler | undefined, resHandler?: ResHandler | undefined) => void;
|
|
20
|
+
post: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?: Handler | undefined, resHandler?: ResHandler | undefined) => void;
|
|
21
|
+
put: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?: Handler | undefined, resHandler?: ResHandler | undefined) => void;
|
|
22
|
+
del: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?: Handler | undefined, resHandler?: ResHandler | undefined) => void;
|
|
19
23
|
} & {
|
|
20
24
|
collection: (res: string, _routePath?: string | undefined, controller?: string | undefined) => void;
|
|
21
25
|
model: (res: string, routePath?: string) => void;
|
package/dist/http/router.js
CHANGED
|
@@ -3,10 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Router = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const errors = require("restify-errors");
|
|
6
|
-
const swaggerUi = require("swagger-ui-restify");
|
|
7
6
|
function Router(deps) {
|
|
8
|
-
const { domain, apisRoute, getSchemaByPath, utils, server, httpCodes = {}, makeProfileHook,
|
|
9
|
-
const { ucwords, makeParams, makeProfile, outputCSV
|
|
7
|
+
const { domain, apisRoute, getSchemaByPath, utils, server, httpCodes = {}, makeProfileHook, } = deps;
|
|
8
|
+
const { ucwords, makeParams, makeProfile, outputCSV } = utils;
|
|
10
9
|
// 改写 HttpErrorToJSON 处理 data
|
|
11
10
|
const HttpErrorToJSON = errors.HttpError.prototype.toJSON;
|
|
12
11
|
errors.HttpError.prototype.toJSON = function toJSON() {
|
|
@@ -24,21 +23,8 @@ function Router(deps) {
|
|
|
24
23
|
e.body.data = data;
|
|
25
24
|
return e;
|
|
26
25
|
};
|
|
27
|
-
const [apiSwagger, swaggerDocJson] = swagger;
|
|
28
26
|
const apis = [];
|
|
29
27
|
let apisHTML = "<h3>API 目录,点击可以查看参数格式定义</h3>";
|
|
30
|
-
let swaggerHtml = "";
|
|
31
|
-
if (apiSwagger) {
|
|
32
|
-
server.get(`/${apiSwagger}/*.*`, ...swaggerUi.serve);
|
|
33
|
-
server.get(`/${apiSwagger}`, (req, res) => {
|
|
34
|
-
res.writeHead(200, {
|
|
35
|
-
"Content-Length": Buffer.byteLength(swaggerHtml),
|
|
36
|
-
"Content-Type": "text/html",
|
|
37
|
-
});
|
|
38
|
-
res.write(swaggerHtml);
|
|
39
|
-
res.end();
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
28
|
/** 判断是否需要提供apis的查询接口 */
|
|
43
29
|
if (apisRoute) {
|
|
44
30
|
server.get(`/${apisRoute}`, (req, res, next) => {
|
|
@@ -66,39 +52,6 @@ function Router(deps) {
|
|
|
66
52
|
next();
|
|
67
53
|
});
|
|
68
54
|
}
|
|
69
|
-
const getAPISchemaDoc = (verb, route, methodPath) => {
|
|
70
|
-
if (!apiSwagger)
|
|
71
|
-
return;
|
|
72
|
-
let apiSchema = [];
|
|
73
|
-
let desc = "";
|
|
74
|
-
try {
|
|
75
|
-
apiSchema = getSchemaByPath(methodPath);
|
|
76
|
-
desc = apiSchema[1] ? apiSchema[1].description : "unknow";
|
|
77
|
-
apiSchema = jsonSchema2Swagger(apiSchema[1] ? apiSchema[1] : {}, verb, methodPath, swaggerDocJson);
|
|
78
|
-
}
|
|
79
|
-
catch (e) {
|
|
80
|
-
console.log(methodPath, "schema to swagger error.");
|
|
81
|
-
}
|
|
82
|
-
swaggerHtml = swaggerUi.generateHTML(swaggerDocJson, {
|
|
83
|
-
baseURL: `${swaggerDocJson.basePath}${apiSwagger}`,
|
|
84
|
-
explorer: true,
|
|
85
|
-
});
|
|
86
|
-
const apiTag = methodPath.split(".")[0];
|
|
87
|
-
swaggerDocJson.paths[route] = {
|
|
88
|
-
[verb]: {
|
|
89
|
-
"x-swagger-router-controller": methodPath,
|
|
90
|
-
operationId: methodPath,
|
|
91
|
-
tags: [apiTag],
|
|
92
|
-
externalDocs: {
|
|
93
|
-
description: "查看接口参数 json schema 定义",
|
|
94
|
-
url: `./${apisRoute}/_schema?path=${methodPath}`,
|
|
95
|
-
},
|
|
96
|
-
description: desc,
|
|
97
|
-
parameters: apiSchema || [],
|
|
98
|
-
responses: {},
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
55
|
function register(verb, route, methodPath, code = 200, isList = false, handler, resHandler) {
|
|
103
56
|
/**
|
|
104
57
|
* 暂存起来,提供给apis接口来用
|
|
@@ -111,7 +64,6 @@ function Router(deps) {
|
|
|
111
64
|
if (!method || !_.isFunction(method)) {
|
|
112
65
|
throw Error(`Missing domain method: ${methodPath}`);
|
|
113
66
|
}
|
|
114
|
-
getAPISchemaDoc(verb, route, methodPath);
|
|
115
67
|
server[verb](route, async (req, res, next) => {
|
|
116
68
|
const profile = makeProfile(req, methodPath, makeProfileHook);
|
|
117
69
|
const params = makeParams(req);
|
package/dist/http/utils.d.ts
CHANGED
package/dist/http/utils.js
CHANGED
|
@@ -144,41 +144,6 @@ function Utils(cnf) {
|
|
|
144
144
|
}
|
|
145
145
|
return true;
|
|
146
146
|
},
|
|
147
|
-
jsonSchema2Swagger(schema, verb, methodPath, swaggerDocJson) {
|
|
148
|
-
if (verb === "post" || verb === "put" || verb === "patch") {
|
|
149
|
-
swaggerDocJson.definitions[methodPath] = schema;
|
|
150
|
-
return [
|
|
151
|
-
{
|
|
152
|
-
name: "body",
|
|
153
|
-
in: "body",
|
|
154
|
-
require: true,
|
|
155
|
-
description: schema.description,
|
|
156
|
-
operationId: methodPath,
|
|
157
|
-
schema: {
|
|
158
|
-
$ref: `#/definitions/${methodPath}`,
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
];
|
|
162
|
-
}
|
|
163
|
-
const parameters = [];
|
|
164
|
-
if (!_.has(schema, "properties")) {
|
|
165
|
-
return parameters;
|
|
166
|
-
}
|
|
167
|
-
const requireds = schema.required ? schema.required : [];
|
|
168
|
-
for (const prop of Object.keys(schema.properties)) {
|
|
169
|
-
const val = schema.properties[prop];
|
|
170
|
-
const param = {
|
|
171
|
-
name: prop,
|
|
172
|
-
in: "query",
|
|
173
|
-
...val,
|
|
174
|
-
};
|
|
175
|
-
if (requireds.includes("prop")) {
|
|
176
|
-
param.required = true;
|
|
177
|
-
}
|
|
178
|
-
parameters.push(param);
|
|
179
|
-
}
|
|
180
|
-
return parameters;
|
|
181
|
-
},
|
|
182
147
|
};
|
|
183
148
|
return utils;
|
|
184
149
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,31 +19,31 @@ export declare function Main<T extends Readonly<Array<keyof TDeps>>>(features: T
|
|
|
19
19
|
aes: typeof import("./deps/aes");
|
|
20
20
|
cache: typeof import("./deps/cache");
|
|
21
21
|
checker: typeof import("./deps/checker");
|
|
22
|
-
cia: typeof import("./deps/cia");
|
|
23
22
|
counter: typeof import("./deps/counter");
|
|
24
23
|
cron: typeof import("./deps/cron");
|
|
25
24
|
graceful: typeof import("./deps/graceful");
|
|
26
25
|
hash: typeof import("./deps/hash");
|
|
27
26
|
logger: typeof import("./deps/logger");
|
|
27
|
+
myCia: typeof import("./deps/myCia");
|
|
28
28
|
parallel: typeof import("./deps/parallel");
|
|
29
|
-
redis: typeof import("./deps/redis");
|
|
29
|
+
redis: typeof import("./deps/redis");
|
|
30
30
|
request: typeof import("./deps/request");
|
|
31
31
|
rest: typeof import("./deps/rest");
|
|
32
32
|
schema: typeof import("./deps/schema");
|
|
33
33
|
sequelize: typeof import("./deps/sequelize");
|
|
34
34
|
signer: typeof import("./deps/signer");
|
|
35
|
-
}[Include<"schema", RemoveReadonlyArray<T>> | Include<"logger", RemoveReadonlyArray<T>> | Include<"aes", RemoveReadonlyArray<T>> | Include<"request", RemoveReadonlyArray<T>> | Include<"sequelize", RemoveReadonlyArray<T>> | Include<"cache", RemoveReadonlyArray<T>> | Include<"redis", RemoveReadonlyArray<T>> | Include<"
|
|
35
|
+
}[Include<"schema", RemoveReadonlyArray<T>> | Include<"logger", RemoveReadonlyArray<T>> | Include<"aes", RemoveReadonlyArray<T>> | Include<"request", RemoveReadonlyArray<T>> | Include<"sequelize", RemoveReadonlyArray<T>> | Include<"cache", RemoveReadonlyArray<T>> | Include<"redis", RemoveReadonlyArray<T>> | Include<"counter", RemoveReadonlyArray<T>> | Include<"cron", RemoveReadonlyArray<T>> | Include<"myCia", RemoveReadonlyArray<T>> | Include<"hash", RemoveReadonlyArray<T>> | Include<"rest", RemoveReadonlyArray<T>> | Include<"parallel", RemoveReadonlyArray<T>> | Include<"graceful", RemoveReadonlyArray<T>> | Include<"checker", RemoveReadonlyArray<T>> | Include<"signer", RemoveReadonlyArray<T>>]["Main"] extends (arg: infer R, ...args: any[]) => any ? R : {}>) => { [k in keyof Pick<{
|
|
36
36
|
aes: typeof import("./deps/aes");
|
|
37
37
|
cache: typeof import("./deps/cache");
|
|
38
38
|
checker: typeof import("./deps/checker");
|
|
39
|
-
cia: typeof import("./deps/cia");
|
|
40
39
|
counter: typeof import("./deps/counter");
|
|
41
40
|
cron: typeof import("./deps/cron");
|
|
42
41
|
graceful: typeof import("./deps/graceful");
|
|
43
42
|
hash: typeof import("./deps/hash");
|
|
44
43
|
logger: typeof import("./deps/logger");
|
|
44
|
+
myCia: typeof import("./deps/myCia");
|
|
45
45
|
parallel: typeof import("./deps/parallel");
|
|
46
|
-
redis: typeof import("./deps/redis");
|
|
46
|
+
redis: typeof import("./deps/redis");
|
|
47
47
|
request: typeof import("./deps/request");
|
|
48
48
|
rest: typeof import("./deps/rest");
|
|
49
49
|
schema: typeof import("./deps/schema");
|
|
@@ -53,14 +53,14 @@ export declare function Main<T extends Readonly<Array<keyof TDeps>>>(features: T
|
|
|
53
53
|
aes: typeof import("./deps/aes");
|
|
54
54
|
cache: typeof import("./deps/cache");
|
|
55
55
|
checker: typeof import("./deps/checker");
|
|
56
|
-
cia: typeof import("./deps/cia");
|
|
57
56
|
counter: typeof import("./deps/counter");
|
|
58
57
|
cron: typeof import("./deps/cron");
|
|
59
58
|
graceful: typeof import("./deps/graceful");
|
|
60
59
|
hash: typeof import("./deps/hash");
|
|
61
60
|
logger: typeof import("./deps/logger");
|
|
61
|
+
myCia: typeof import("./deps/myCia");
|
|
62
62
|
parallel: typeof import("./deps/parallel");
|
|
63
|
-
redis: typeof import("./deps/redis");
|
|
63
|
+
redis: typeof import("./deps/redis");
|
|
64
64
|
request: typeof import("./deps/request");
|
|
65
65
|
rest: typeof import("./deps/rest");
|
|
66
66
|
schema: typeof import("./deps/schema");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare type ReadonlyArray2union<T extends ReadonlyArray<any>> = T extends ReadonlyArray<infer A> ? A : never;
|
package/dist/utils/index.js
CHANGED
|
@@ -17,7 +17,7 @@ const md5 = (str) => {
|
|
|
17
17
|
return hash.update(str.toString()).digest().toString("hex");
|
|
18
18
|
};
|
|
19
19
|
exports.md5 = md5;
|
|
20
|
-
function randStr(len, type) {
|
|
20
|
+
function randStr(len, type = "normal") {
|
|
21
21
|
const dict = type === "strong" || type === "normal" ? RAND_STR_DICT[type] : type;
|
|
22
22
|
const { length } = dict;
|
|
23
23
|
/** 随机字符串的长度不能等于 0 或者负数 */
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domain.js/main",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "DDD framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"bin":
|
|
6
|
+
"bin": {
|
|
7
|
+
"domain-cli": "dist/cli/index.js"
|
|
8
|
+
},
|
|
7
9
|
"scripts": {
|
|
8
10
|
"build": "tsc",
|
|
9
11
|
"test": "export NODE_ENV=test && jest ./src --coverage",
|
|
@@ -72,8 +74,7 @@
|
|
|
72
74
|
"mysql2": "^2.3.3",
|
|
73
75
|
"restify": "^8.6.0",
|
|
74
76
|
"restify-errors": "^8.0.2",
|
|
75
|
-
"sequelize": "
|
|
76
|
-
"swagger-ui-restify": "^3.0.8",
|
|
77
|
+
"sequelize": "6.12.1",
|
|
77
78
|
"type-fest": "^2.8.0",
|
|
78
79
|
"uuid": "^8.3.2",
|
|
79
80
|
"xlsx": "^0.17.4"
|