@domain.js/main 0.2.5 → 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/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
- const checkService = (_dir) => {
120
- const TSFile = path.resolve(_dir, "index.ts");
121
- const JSFile = path.resolve(_dir, "index.js");
122
- if (!fs.existsSync(TSFile) && !fs.existsSync(JSFile)) {
123
- throw Error("目录下缺少index.ts 或 index.js 文件");
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 x of fs.readdirSync(dir)) {
128
+ for (const domain of fs.readdirSync(dir)) {
131
129
  // 忽略隐藏目录, 忽略私有目录
132
- if (x[0] === "." || x[0] === "_")
130
+ if (domain[0] === "." || domain[0] === "_")
133
131
  continue;
134
- const _dir = path.resolve(dir, x);
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
- checkService(_dir);
140
- modules.push(path.join(dir, x));
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, loadServices, loadSchemas };
193
+ const actions = { loadDeps, loadSchemas, loadDomain };
189
194
  const main = async (command) => {
190
195
  const action = actions[command];
191
196
  if (!action) {
@@ -33,9 +33,15 @@ export interface HttpCodes {
33
33
  [propName: string]: number;
34
34
  }
35
35
  export interface Domain {
36
- [propName: string]: (profile: Profile, params: any) => any | Domain;
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;
@@ -1,12 +1,8 @@
1
1
  import * as restify from "restify";
2
- import { Cnf, Domain, GetSchemaByPath, HttpCodes, Profile } from "./defines";
3
- import { Router } from "./router";
4
- interface Deps {
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;
@@ -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, getSchemaByPath, domain, httpCodes, makeProfileHook } = deps;
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
  });
@@ -1,9 +1,8 @@
1
1
  import * as restify from "restify";
2
- import { Domain, GetSchemaByPath, HttpCodes, Profile } from "./defines";
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 {};
@@ -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, getSchemaByPath, utils, server, httpCodes = {}, makeProfileHook, } = deps;
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 schema = getSchemaByPath(path);
65
- res.send(all === undefined ? schema[1] : schema);
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
- const method = _.get(domain, methodPath);
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}`);
@@ -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 = lodash_1.default.get(domain, "message.subscribe");
76
- const unsubscribe = lodash_1.default.get(domain, "message.unsubscribe");
77
- const entrance = lodash_1.default.get(domain, "message.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", "不存在该领域方法");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@domain.js/main",
3
- "version": "0.2.5",
3
+ "version": "0.3.0",
4
4
  "description": "DDD framework",
5
5
  "main": "dist/index.js",
6
6
  "bin": {