@domain.js/main 0.2.3 → 0.3.0
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/cfg/index.js +2 -21
- package/dist/cli/index.js +20 -15
- package/dist/deps/redis/index.d.ts +3 -1
- package/dist/deps/redis/index.js +13 -1
- package/dist/http/defines.d.ts +8 -2
- package/dist/http/index.d.ts +4 -8
- package/dist/http/index.js +1 -2
- package/dist/http/router.d.ts +11 -2
- package/dist/http/router.js +7 -4
- package/dist/http/socket.js +11 -10
- package/package.json +1 -1
package/dist/cfg/index.js
CHANGED
|
@@ -1,31 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
4
|
};
|
|
24
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
6
|
exports.Main = void 0;
|
|
26
|
-
const _ = __importStar(require("lodash"));
|
|
27
7
|
const ajv_1 = __importDefault(require("ajv"));
|
|
28
8
|
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
9
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
29
10
|
function Main(object, schema) {
|
|
30
11
|
if (typeof schema !== "object")
|
|
31
12
|
throw Error("object type isnt an object");
|
|
@@ -33,7 +14,7 @@ function Main(object, schema) {
|
|
|
33
14
|
const ajv = new ajv_1.default({ allowUnionTypes: true, coerceTypes: true, useDefaults: true });
|
|
34
15
|
(0, ajv_formats_1.default)(ajv);
|
|
35
16
|
const validate = ajv.compile(schema);
|
|
36
|
-
const obj =
|
|
17
|
+
const obj = lodash_1.default.pick(object, [...FIELDS]);
|
|
37
18
|
if (!validate(obj)) {
|
|
38
19
|
console.log("Config object data validate failed", obj);
|
|
39
20
|
console.log(JSON.stringify(validate.errors, null, 2));
|
package/dist/cli/index.js
CHANGED
|
@@ -62,7 +62,7 @@ const makeDefineFile = async (modules, targetFile, isTS) => {
|
|
|
62
62
|
else {
|
|
63
63
|
content.push(`const ${variable} = require("./${name}")`);
|
|
64
64
|
}
|
|
65
|
-
_exports.push(`"${file2Module(name)}": ${variable},`);
|
|
65
|
+
_exports.push(`"${file2Module(name).replace(/[/]/, ".")}": ${variable},`);
|
|
66
66
|
}
|
|
67
67
|
// 处理导出
|
|
68
68
|
content.push("\n");
|
|
@@ -116,28 +116,33 @@ const loadDeps = async (rootDir, ext = "js") => {
|
|
|
116
116
|
const targetFile = path.resolve(rootDir, `./defines.${ext}`);
|
|
117
117
|
await makeDefineFile(modules.sort(), targetFile, isTS);
|
|
118
118
|
};
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
};
|
|
126
|
-
const loadServices = async (rootDir = process.cwd(), ext = "js") => {
|
|
119
|
+
/**
|
|
120
|
+
* 自动加载领域方法
|
|
121
|
+
* @param rootDir 项目根目录
|
|
122
|
+
* @param ext 文件后缀
|
|
123
|
+
*/
|
|
124
|
+
const loadDomain = async (rootDir = process.cwd(), ext = "js") => {
|
|
127
125
|
const isTS = ext === "ts";
|
|
128
126
|
const modules = [];
|
|
129
127
|
const dir = path.resolve(rootDir, "src/domain/services/");
|
|
130
|
-
for (const
|
|
128
|
+
for (const domain of fs.readdirSync(dir)) {
|
|
131
129
|
// 忽略隐藏目录, 忽略私有目录
|
|
132
|
-
if (
|
|
130
|
+
if (domain[0] === "." || domain[0] === "_")
|
|
133
131
|
continue;
|
|
134
|
-
const _dir = path.resolve(dir,
|
|
132
|
+
const _dir = path.resolve(dir, domain);
|
|
135
133
|
const stat = fs.statSync(_dir);
|
|
136
134
|
// 非目录忽略,模块必须是目录
|
|
137
135
|
if (!stat.isDirectory())
|
|
138
136
|
continue;
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
for (const name of fs.readdirSync(_dir)) {
|
|
138
|
+
// 忽略隐藏目录, 忽略私有目录
|
|
139
|
+
if (name[0] === "." || name[0] === "_")
|
|
140
|
+
continue;
|
|
141
|
+
const extname = path.extname(name);
|
|
142
|
+
if (extname.toLowerCase() !== `.${ext}`)
|
|
143
|
+
continue;
|
|
144
|
+
modules.push(path.join(dir, domain, path.basename(name, extname)));
|
|
145
|
+
}
|
|
141
146
|
}
|
|
142
147
|
// 按字典排序,后续有变动的时候不容易冲突
|
|
143
148
|
const targetFile = path.resolve(rootDir, `src/domain/services/defines.${ext}`);
|
|
@@ -185,7 +190,7 @@ const loadSchemas = async (rootDir = process.cwd(), ext = "js") => {
|
|
|
185
190
|
const targetFile = path.resolve(rootDir, `src/domain/services/schemas.${ext}`);
|
|
186
191
|
await makeDefineFile(modules.sort(), targetFile, isTS);
|
|
187
192
|
};
|
|
188
|
-
const actions = { loadDeps,
|
|
193
|
+
const actions = { loadDeps, loadSchemas, loadDomain };
|
|
189
194
|
const main = async (command) => {
|
|
190
195
|
const action = actions[command];
|
|
191
196
|
if (!action) {
|
|
@@ -12,6 +12,8 @@ interface Deps {
|
|
|
12
12
|
* @param cnf
|
|
13
13
|
* @returns An instance of ioredis
|
|
14
14
|
*/
|
|
15
|
-
export declare function Main(cnf: Cnf, deps: Deps): Redis.Redis
|
|
15
|
+
export declare function Main(cnf: Cnf, deps: Deps): Redis.Redis & {
|
|
16
|
+
update: (key: string, data: string) => Promise<void>;
|
|
17
|
+
};
|
|
16
18
|
export declare const Deps: string[];
|
|
17
19
|
export {};
|
package/dist/deps/redis/index.js
CHANGED
|
@@ -11,7 +11,19 @@ exports.Deps = exports.Main = void 0;
|
|
|
11
11
|
function Main(cnf, deps) {
|
|
12
12
|
const { redis } = cnf;
|
|
13
13
|
const { IORedis } = deps;
|
|
14
|
-
|
|
14
|
+
const rds = new IORedis(redis);
|
|
15
|
+
/**
|
|
16
|
+
* 在不改变原数据的有效性、过期时间的前提下更新数据
|
|
17
|
+
* @param key redis 存储的 key
|
|
18
|
+
* @param data redis 要更新的数据
|
|
19
|
+
*/
|
|
20
|
+
const update = async (key, data) => {
|
|
21
|
+
const ttl = await rds.ttl(key);
|
|
22
|
+
if (ttl < 1)
|
|
23
|
+
return;
|
|
24
|
+
await rds.setex(key, ttl, data);
|
|
25
|
+
};
|
|
26
|
+
return Object.assign(rds, { update });
|
|
15
27
|
}
|
|
16
28
|
exports.Main = Main;
|
|
17
29
|
exports.Deps = ["IORedis"];
|
package/dist/http/defines.d.ts
CHANGED
|
@@ -33,9 +33,15 @@ export interface HttpCodes {
|
|
|
33
33
|
[propName: string]: number;
|
|
34
34
|
}
|
|
35
35
|
export interface Domain {
|
|
36
|
-
[propName: string]:
|
|
36
|
+
[propName: string]: {
|
|
37
|
+
/** 领域方法第一个参数 schema 定义 */
|
|
38
|
+
profile: any;
|
|
39
|
+
/** 领域方法第二个参数 schema 定义 */
|
|
40
|
+
params: any;
|
|
41
|
+
/** 领域方法 */
|
|
42
|
+
method: (profile: any, params?: any) => any;
|
|
43
|
+
};
|
|
37
44
|
}
|
|
38
|
-
export declare type GetSchemaByPath = (methodPath: string) => [any, any];
|
|
39
45
|
export interface Err {
|
|
40
46
|
message: string;
|
|
41
47
|
code?: number | string;
|
package/dist/http/index.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import * as restify from "restify";
|
|
2
|
-
import { Cnf, Domain,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
routers: (r: ReturnType<typeof Router>) => void;
|
|
2
|
+
import { Cnf, Domain, HttpCodes, Profile } from "./defines";
|
|
3
|
+
export declare function Main(cnf: Cnf, deps: {
|
|
4
|
+
routers: (r: any) => void;
|
|
6
5
|
domain: Domain;
|
|
7
6
|
httpCodes: HttpCodes;
|
|
8
|
-
getSchemaByPath: GetSchemaByPath;
|
|
9
7
|
makeProfileHook?: (obj: Profile, req: restify.Request) => any;
|
|
10
|
-
}
|
|
11
|
-
export declare function Main(cnf: Cnf, deps: Deps): () => restify.Server;
|
|
12
|
-
export {};
|
|
8
|
+
}): () => restify.Server;
|
package/dist/http/index.js
CHANGED
|
@@ -27,7 +27,7 @@ const socket_1 = require("./socket");
|
|
|
27
27
|
const utils_1 = require("./utils");
|
|
28
28
|
function Main(cnf, deps) {
|
|
29
29
|
const utils = (0, utils_1.Utils)(cnf);
|
|
30
|
-
const { routers,
|
|
30
|
+
const { routers, domain, httpCodes, makeProfileHook } = deps;
|
|
31
31
|
const server = restify.createServer();
|
|
32
32
|
server.use(restify.plugins.queryParser());
|
|
33
33
|
server.use(restify.plugins.bodyParser({
|
|
@@ -39,7 +39,6 @@ function Main(cnf, deps) {
|
|
|
39
39
|
server,
|
|
40
40
|
httpCodes,
|
|
41
41
|
makeProfileHook,
|
|
42
|
-
getSchemaByPath,
|
|
43
42
|
domain,
|
|
44
43
|
apisRoute: cnf.apisRoute,
|
|
45
44
|
});
|
package/dist/http/router.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as restify from "restify";
|
|
2
|
-
import { Domain,
|
|
2
|
+
import { Domain, HttpCodes, Profile } from "./defines";
|
|
3
3
|
import { Utils } from "./utils";
|
|
4
4
|
interface Deps {
|
|
5
5
|
domain: Domain;
|
|
6
|
-
getSchemaByPath: GetSchemaByPath;
|
|
7
6
|
utils: ReturnType<typeof Utils>;
|
|
8
7
|
server: restify.Server;
|
|
9
8
|
httpCodes: HttpCodes;
|
|
@@ -25,4 +24,14 @@ export declare function Router(deps: Deps): {
|
|
|
25
24
|
model: (res: string, routePath?: string) => void;
|
|
26
25
|
resource: (res: string, routePath?: string) => void;
|
|
27
26
|
};
|
|
27
|
+
declare type TRouter = ReturnType<typeof Router>;
|
|
28
|
+
declare type normal = Parameters<TRouter["get"]>;
|
|
29
|
+
declare type ReplaceArrayItem<T extends any[], index extends number, R, S extends any[] = [], L extends number = S["length"]> = T extends [infer A, ...infer rest] ? L extends index ? [...S, R, ...rest] : ReplaceArrayItem<rest, index, R, [...S, A]> : never;
|
|
30
|
+
declare type Keys = "get" | "post" | "put" | "patch" | "del";
|
|
31
|
+
/**
|
|
32
|
+
* 利用领域方法路径类型集合,收窄 methodPath, 同时可以自动提示
|
|
33
|
+
*/
|
|
34
|
+
export declare type NarrowDomainPaths<Paths extends string> = Omit<TRouter, Keys> & {
|
|
35
|
+
[k in Keys]: (...args: ReplaceArrayItem<normal, 1, Paths>) => void;
|
|
36
|
+
};
|
|
28
37
|
export {};
|
package/dist/http/router.js
CHANGED
|
@@ -23,7 +23,7 @@ exports.Router = void 0;
|
|
|
23
23
|
const _ = __importStar(require("lodash"));
|
|
24
24
|
const errors = __importStar(require("restify-errors"));
|
|
25
25
|
function Router(deps) {
|
|
26
|
-
const { domain, apisRoute,
|
|
26
|
+
const { domain, apisRoute, utils, server, httpCodes = {}, makeProfileHook } = deps;
|
|
27
27
|
const { ucwords, makeParams, makeProfile, outputCSV } = utils;
|
|
28
28
|
// 改写 HttpErrorToJSON 处理 data
|
|
29
29
|
const HttpErrorToJSON = errors.HttpError.prototype.toJSON;
|
|
@@ -61,8 +61,9 @@ function Router(deps) {
|
|
|
61
61
|
const { path } = req.query;
|
|
62
62
|
try {
|
|
63
63
|
const { all } = req.query;
|
|
64
|
-
const
|
|
65
|
-
|
|
64
|
+
const profile = domain[path]["profile"];
|
|
65
|
+
const params = domain[path]["params"];
|
|
66
|
+
res.send(all === undefined ? params : [profile, params]);
|
|
66
67
|
}
|
|
67
68
|
catch (e) {
|
|
68
69
|
next(error2httpError(e));
|
|
@@ -79,7 +80,9 @@ function Router(deps) {
|
|
|
79
80
|
*/
|
|
80
81
|
apis.push(`[${verb.toUpperCase()}] ${route} Domain: ${methodPath}`);
|
|
81
82
|
apisHTML += `\n<li><a href="./${apisRoute}/_schema?path=${methodPath}">[${verb.toUpperCase()}] ${route} Domain: ${methodPath}</a></li>`;
|
|
82
|
-
|
|
83
|
+
if (!domain[methodPath])
|
|
84
|
+
throw Error(`Missing domain method: ${methodPath}`);
|
|
85
|
+
const { method } = domain[methodPath];
|
|
83
86
|
/** 如果都没有则抛出异常 */
|
|
84
87
|
if (!method || !_.isFunction(method)) {
|
|
85
88
|
throw Error(`Missing domain method: ${methodPath}`);
|
package/dist/http/socket.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.BridgeSocket = void 0;
|
|
7
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
8
4
|
const proxyIps = new Set(["127.0.0.1"]);
|
|
9
5
|
class MyError extends Error {
|
|
10
6
|
constructor(code, message, data) {
|
|
@@ -72,9 +68,9 @@ const makeProfile = (client, type = "user", auth, extra = {}) => {
|
|
|
72
68
|
return obj;
|
|
73
69
|
};
|
|
74
70
|
function BridgeSocket(io, domain) {
|
|
75
|
-
const subscribe =
|
|
76
|
-
const unsubscribe =
|
|
77
|
-
const entrance =
|
|
71
|
+
const { method: subscribe } = domain["message.subscribe"];
|
|
72
|
+
const { method: unsubscribe } = domain["message.unsubscribe"];
|
|
73
|
+
const { method: entrance } = domain["message.entrance"];
|
|
78
74
|
if (!subscribe)
|
|
79
75
|
throw Error("要启用 socket 服务,必须要要有 message.subscribe 方法,用来处理 socket 订阅");
|
|
80
76
|
if (!unsubscribe)
|
|
@@ -138,7 +134,7 @@ function BridgeSocket(io, domain) {
|
|
|
138
134
|
client.use(async ([name, params, responseId], next) => {
|
|
139
135
|
if (name === "init" || name === "entrance")
|
|
140
136
|
return next();
|
|
141
|
-
const method = domain[name];
|
|
137
|
+
const { method } = domain[name];
|
|
142
138
|
try {
|
|
143
139
|
if (!method)
|
|
144
140
|
throw new MyError("notFound", "不存在该领域方法");
|
|
@@ -165,13 +161,18 @@ function BridgeSocket(io, domain) {
|
|
|
165
161
|
return next();
|
|
166
162
|
});
|
|
167
163
|
// 掉线
|
|
168
|
-
client.on("disconnect", () => {
|
|
164
|
+
client.on("disconnect", async () => {
|
|
169
165
|
if (!client.profile)
|
|
170
166
|
return;
|
|
171
167
|
if (!client.inited)
|
|
172
168
|
return;
|
|
173
169
|
// 这里要取消对领域消息的监听
|
|
174
|
-
|
|
170
|
+
try {
|
|
171
|
+
return await unsubscribe(client.profile, client);
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
console.error(e);
|
|
175
|
+
}
|
|
175
176
|
});
|
|
176
177
|
});
|
|
177
178
|
}
|