@domain.js/main 0.2.0 → 0.2.3
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/http/defines.d.ts +8 -13
- package/dist/http/router.d.ts +1 -1
- package/dist/http/router.js +2 -2
- package/dist/http/socket.d.ts +14 -2
- package/dist/http/socket.js +64 -20
- package/dist/http/utils.js +4 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +6 -6
- package/dist/utils/index.d.ts +22 -1
- package/dist/utils/index.js +57 -4
- package/package.json +1 -1
package/dist/http/defines.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Opt as Sign } from "../deps/signer";
|
|
1
2
|
export interface Cnf {
|
|
2
3
|
proxyIps?: string;
|
|
3
4
|
port?: number;
|
|
@@ -7,15 +8,6 @@ export interface Cnf {
|
|
|
7
8
|
socket?: boolean;
|
|
8
9
|
[propName: string]: any;
|
|
9
10
|
}
|
|
10
|
-
interface Sign {
|
|
11
|
-
signature: string;
|
|
12
|
-
uri: string;
|
|
13
|
-
key: string;
|
|
14
|
-
timestamp: number;
|
|
15
|
-
signMethod: string;
|
|
16
|
-
signVersion: string;
|
|
17
|
-
method: string;
|
|
18
|
-
}
|
|
19
11
|
export interface Profile {
|
|
20
12
|
clientIp: string;
|
|
21
13
|
remoteIp: string;
|
|
@@ -23,15 +15,19 @@ export interface Profile {
|
|
|
23
15
|
userAgent: string;
|
|
24
16
|
startedAt: Date;
|
|
25
17
|
requestId: string;
|
|
18
|
+
/** 用户类型,例如 user, worker */
|
|
19
|
+
type: string;
|
|
26
20
|
/** 自由挂载信息的节点 */
|
|
27
21
|
extra: Record<string, any>;
|
|
28
22
|
revision?: string;
|
|
29
23
|
uuid?: string;
|
|
30
24
|
token?: string;
|
|
31
|
-
sign?: Sign
|
|
25
|
+
sign?: Sign & {
|
|
26
|
+
signature: string;
|
|
27
|
+
};
|
|
32
28
|
isSocket?: boolean;
|
|
33
|
-
/** socket
|
|
34
|
-
|
|
29
|
+
/** socket 的时候加入的房间 */
|
|
30
|
+
roomId?: string;
|
|
35
31
|
}
|
|
36
32
|
export interface HttpCodes {
|
|
37
33
|
[propName: string]: number;
|
|
@@ -45,4 +41,3 @@ export interface Err {
|
|
|
45
41
|
code?: number | string;
|
|
46
42
|
data?: any;
|
|
47
43
|
}
|
|
48
|
-
export {};
|
package/dist/http/router.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ interface Deps {
|
|
|
14
14
|
/** 对 params 的处理函数 */
|
|
15
15
|
declare type Handler = (params: any) => void;
|
|
16
16
|
/** 对执行结构的处理 */
|
|
17
|
-
declare type ResHandler = (results: any, res: restify.Response) => void;
|
|
17
|
+
declare type ResHandler = (results: any, res: restify.Response, params?: any) => void;
|
|
18
18
|
export declare function Router(deps: Deps): {
|
|
19
19
|
get: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?: Handler | undefined, resHandler?: ResHandler | undefined) => void;
|
|
20
20
|
post: (routePath: string, ctlAct: string, code?: number, isList?: boolean, handler?: Handler | undefined, resHandler?: ResHandler | undefined) => void;
|
package/dist/http/router.js
CHANGED
|
@@ -74,7 +74,7 @@ function Router(deps) {
|
|
|
74
74
|
// eslint-disable-next-line max-params
|
|
75
75
|
function register(verb, route, methodPath, code = 200, isList = false, handler, resHandler) {
|
|
76
76
|
/**
|
|
77
|
-
* 暂存起来,提供给apis
|
|
77
|
+
* 暂存起来,提供给apis接口来
|
|
78
78
|
* apis接口用来返回当前 services 提供的可用的 api
|
|
79
79
|
*/
|
|
80
80
|
apis.push(`[${verb.toUpperCase()}] ${route} Domain: ${methodPath}`);
|
|
@@ -97,7 +97,7 @@ function Router(deps) {
|
|
|
97
97
|
if (results === null || results === undefined)
|
|
98
98
|
results = "Ok";
|
|
99
99
|
if (resHandler) {
|
|
100
|
-
resHandler(results, res);
|
|
100
|
+
resHandler(results, res, params);
|
|
101
101
|
}
|
|
102
102
|
else if (isList) {
|
|
103
103
|
const { _ignoreTotal, _format } = params;
|
package/dist/http/socket.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
import { Server } from "socket.io";
|
|
2
|
-
import {
|
|
1
|
+
import { Server, Socket } from "socket.io";
|
|
2
|
+
import { DefaultEventsMap } from "socket.io/dist/typed-events";
|
|
3
|
+
import { Opt as Sign } from "../deps/signer";
|
|
4
|
+
import { Domain, Profile } from "./defines";
|
|
5
|
+
declare type Signature = Sign & {
|
|
6
|
+
signature: string;
|
|
7
|
+
};
|
|
8
|
+
export declare type Client = Socket<DefaultEventsMap, DefaultEventsMap, DefaultEventsMap, any> & {
|
|
9
|
+
profile?: ReturnType<typeof makeProfile>;
|
|
10
|
+
inited?: boolean;
|
|
11
|
+
roomId?: string;
|
|
12
|
+
};
|
|
13
|
+
declare const makeProfile: (client: Client, type: string | undefined, auth: string | Signature, extra?: Profile["extra"]) => Profile;
|
|
3
14
|
export declare function BridgeSocket(io: Server, domain: Domain): void;
|
|
15
|
+
export {};
|
package/dist/http/socket.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.BridgeSocket = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
4
8
|
const proxyIps = new Set(["127.0.0.1"]);
|
|
5
9
|
class MyError extends Error {
|
|
6
10
|
constructor(code, message, data) {
|
|
@@ -37,9 +41,8 @@ const utils = {
|
|
|
37
41
|
return realIp.split(",")[0];
|
|
38
42
|
},
|
|
39
43
|
};
|
|
40
|
-
const makeProfile = (client,
|
|
44
|
+
const makeProfile = (client, type = "user", auth, extra = {}) => {
|
|
41
45
|
const obj = {
|
|
42
|
-
token,
|
|
43
46
|
clientIp: utils.clientIp(client),
|
|
44
47
|
remoteIp: utils.remoteIp(client),
|
|
45
48
|
realIp: utils.realIp(client),
|
|
@@ -47,43 +50,84 @@ const makeProfile = (client, token, params, extra) => {
|
|
|
47
50
|
startedAt: new Date(),
|
|
48
51
|
userAgent: client.handshake.headers["user-agent"] || "Not captured",
|
|
49
52
|
requestId: client.id,
|
|
50
|
-
|
|
51
|
-
revision: params.revision,
|
|
52
|
-
/** 用户uuid 可以长期跨app */
|
|
53
|
-
uuid: params.uuid,
|
|
54
|
-
/** 额外信息,自由扩展 */
|
|
53
|
+
type,
|
|
55
54
|
extra,
|
|
56
55
|
};
|
|
56
|
+
if (extra) {
|
|
57
|
+
/** 客户端发布号 */
|
|
58
|
+
if (extra.revision)
|
|
59
|
+
obj.revision = extra.revision;
|
|
60
|
+
/** 用户uuid 可以长期跨app */
|
|
61
|
+
if (extra.uuid)
|
|
62
|
+
obj.uuid = extra.uuid;
|
|
63
|
+
}
|
|
64
|
+
if (typeof auth === "string") {
|
|
65
|
+
obj.token = auth;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
obj.sign = auth;
|
|
69
|
+
obj.sign.uri = "/socket.io";
|
|
70
|
+
obj.sign.method = "socket.init";
|
|
71
|
+
}
|
|
57
72
|
return obj;
|
|
58
73
|
};
|
|
59
74
|
function BridgeSocket(io, domain) {
|
|
60
|
-
const subscribe = domain
|
|
61
|
-
const unsubscribe = 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");
|
|
62
78
|
if (!subscribe)
|
|
63
79
|
throw Error("要启用 socket 服务,必须要要有 message.subscribe 方法,用来处理 socket 订阅");
|
|
64
80
|
if (!unsubscribe)
|
|
65
81
|
throw Error("要启用 socket 服务,必须要要有 message.unsubscribe 方法,用来处理 socket 退订");
|
|
82
|
+
if (!entrance)
|
|
83
|
+
throw Error("要启用 socket 服务,必须要要有 message.entrance 方法,用来处理 加入某个房间");
|
|
66
84
|
io.on("connection", (client) => {
|
|
85
|
+
// 定义toJSON 避免 schema 验证报错
|
|
86
|
+
Object.assign(client, {
|
|
87
|
+
toJSON() {
|
|
88
|
+
return {};
|
|
89
|
+
},
|
|
90
|
+
});
|
|
67
91
|
console.log("[%s] connection: client.id: %s", new Date(), client.id);
|
|
68
|
-
client.on("init", async (
|
|
92
|
+
client.on("init", async (type, auth, extra = {}) => {
|
|
69
93
|
console.log("[%s] socket.init: client.id: %s", new Date(), client.id);
|
|
70
|
-
if (!
|
|
71
|
-
client.emit("initError", "
|
|
94
|
+
if (!auth) {
|
|
95
|
+
client.emit("initError", "auth info lost");
|
|
72
96
|
return;
|
|
73
97
|
}
|
|
74
98
|
try {
|
|
75
|
-
Object.assign(client, { profile: makeProfile(client,
|
|
99
|
+
Object.assign(client, { profile: makeProfile(client, type, auth, extra) });
|
|
76
100
|
if (!client.profile)
|
|
77
101
|
throw new MyError("noAuth", "请先登录");
|
|
78
|
-
const session = await domain["auth.session"](client.profile, {});
|
|
79
102
|
// 创建消息监听函数
|
|
80
|
-
if (!client.
|
|
81
|
-
client.
|
|
103
|
+
if (!client.inited)
|
|
104
|
+
client.inited = true;
|
|
82
105
|
// 向领域注册改用户的监听函数
|
|
83
|
-
|
|
106
|
+
const session = await subscribe(client.profile, client);
|
|
84
107
|
client.emit("inited", session);
|
|
85
108
|
}
|
|
86
109
|
catch (e) {
|
|
110
|
+
client.inited = false;
|
|
111
|
+
if (e instanceof MyError) {
|
|
112
|
+
client.emit("internalError", e.message, e.code || "unknown");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
console.error(e);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
client.on("entrance", async (roomId) => {
|
|
119
|
+
try {
|
|
120
|
+
if (!client.profile || !client.inited)
|
|
121
|
+
return;
|
|
122
|
+
const res = await entrance({ roomId, ...client.profile }, client);
|
|
123
|
+
client.profile.roomId = roomId;
|
|
124
|
+
client.roomId = roomId;
|
|
125
|
+
client.emit("entranced", res);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
client.roomId = undefined;
|
|
129
|
+
if (client.profile)
|
|
130
|
+
client.profile.roomId = undefined;
|
|
87
131
|
if (e instanceof MyError) {
|
|
88
132
|
client.emit("internalError", e.message, e.code || "unknown");
|
|
89
133
|
return;
|
|
@@ -92,7 +136,7 @@ function BridgeSocket(io, domain) {
|
|
|
92
136
|
}
|
|
93
137
|
});
|
|
94
138
|
client.use(async ([name, params, responseId], next) => {
|
|
95
|
-
if (name === "init")
|
|
139
|
+
if (name === "init" || name === "entrance")
|
|
96
140
|
return next();
|
|
97
141
|
const method = domain[name];
|
|
98
142
|
try {
|
|
@@ -124,10 +168,10 @@ function BridgeSocket(io, domain) {
|
|
|
124
168
|
client.on("disconnect", () => {
|
|
125
169
|
if (!client.profile)
|
|
126
170
|
return;
|
|
127
|
-
if (!client.
|
|
171
|
+
if (!client.inited)
|
|
128
172
|
return;
|
|
129
173
|
// 这里要取消对领域消息的监听
|
|
130
|
-
unsubscribe(client.profile, client
|
|
174
|
+
unsubscribe(client.profile, client);
|
|
131
175
|
});
|
|
132
176
|
});
|
|
133
177
|
}
|
package/dist/http/utils.js
CHANGED
|
@@ -71,8 +71,12 @@ function Utils(cnf) {
|
|
|
71
71
|
userAgent: req.userAgent(),
|
|
72
72
|
startedAt: new Date(),
|
|
73
73
|
requestId: req.id(),
|
|
74
|
+
type: "user",
|
|
74
75
|
extra: {},
|
|
75
76
|
};
|
|
77
|
+
if (req.headers["x-auth-user-type"]) {
|
|
78
|
+
obj.type = req.headers["x-auth-user-type"].toString();
|
|
79
|
+
}
|
|
76
80
|
const token = req.headers["x-auth-token"] || req.query.access_token || req.query.accessToken;
|
|
77
81
|
// token 和签名认证只能二选一
|
|
78
82
|
if (token) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Defaults } from "./defaults";
|
|
2
2
|
import Deps = require("./deps/defines");
|
|
3
|
-
export { Main as
|
|
4
|
-
export { Errors } from "./Errors";
|
|
3
|
+
export { Main as Cfg } from "./cfg";
|
|
5
4
|
export * as DM from "./dm";
|
|
5
|
+
export { Errors } from "./Errors";
|
|
6
|
+
export { Main as Http } from "./http";
|
|
6
7
|
export * as utils from "./utils";
|
|
7
|
-
export { Main as Cfg } from "./cfg";
|
|
8
8
|
export declare const basicErrors: Readonly<Record<"notFound" | "notAllowed" | "noAuth", import("./Errors").ErrorFn>>;
|
|
9
9
|
declare type TDeps = typeof Deps;
|
|
10
10
|
declare type Merge<T> = {
|
package/dist/index.js
CHANGED
|
@@ -19,18 +19,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.Main = exports.basicErrors = exports.
|
|
22
|
+
exports.Main = exports.basicErrors = exports.utils = exports.Http = exports.Errors = exports.DM = exports.Cfg = void 0;
|
|
23
23
|
const defaults_1 = require("./defaults");
|
|
24
24
|
const DM = __importStar(require("./dm"));
|
|
25
25
|
const Deps = require("./deps/defines");
|
|
26
|
-
var
|
|
27
|
-
Object.defineProperty(exports, "
|
|
26
|
+
var cfg_1 = require("./cfg");
|
|
27
|
+
Object.defineProperty(exports, "Cfg", { enumerable: true, get: function () { return cfg_1.Main; } });
|
|
28
|
+
exports.DM = __importStar(require("./dm"));
|
|
28
29
|
var Errors_1 = require("./Errors");
|
|
29
30
|
Object.defineProperty(exports, "Errors", { enumerable: true, get: function () { return Errors_1.Errors; } });
|
|
30
|
-
|
|
31
|
+
var http_1 = require("./http");
|
|
32
|
+
Object.defineProperty(exports, "Http", { enumerable: true, get: function () { return http_1.Main; } });
|
|
31
33
|
exports.utils = __importStar(require("./utils"));
|
|
32
|
-
var cfg_1 = require("./cfg");
|
|
33
|
-
Object.defineProperty(exports, "Cfg", { enumerable: true, get: function () { return cfg_1.Main; } });
|
|
34
34
|
exports.basicErrors = defaults_1.defaults.errors;
|
|
35
35
|
function Main(features) {
|
|
36
36
|
const { _ } = defaults_1.defaults;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare const md5: (str: {
|
|
|
12
12
|
* @param type "strong" or "normal" or other string that custom character range string
|
|
13
13
|
*/
|
|
14
14
|
export declare function randStr(len: number, type: "strong"): string;
|
|
15
|
-
export declare function randStr(len: number, type
|
|
15
|
+
export declare function randStr(len: number, type?: "normal"): string;
|
|
16
16
|
export declare function randStr(len: number, type: string): string;
|
|
17
17
|
/**
|
|
18
18
|
* Replace line breaks and tabs in the string with ordinary spaces
|
|
@@ -75,4 +75,25 @@ declare type Params = {
|
|
|
75
75
|
* @returns Modified address
|
|
76
76
|
*/
|
|
77
77
|
export declare const modifiyURL: (address: string, adds?: Params | undefined, removes?: string[] | undefined) => string;
|
|
78
|
+
/**
|
|
79
|
+
* 等待,知道 test 返回 true
|
|
80
|
+
* @param test 检测函数
|
|
81
|
+
* @param intervalMS 间隔多久判断一次, 单位毫秒 默认 100
|
|
82
|
+
*/
|
|
83
|
+
export declare const waitFor: (test: () => boolean, intervalMS?: number) => Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* 读取录下的所有文件,之后返回数组
|
|
86
|
+
* params
|
|
87
|
+
* dir 要加载的目录
|
|
88
|
+
* exts 要加载的模块文件后缀,多个可以是数组, 默认为 coffee
|
|
89
|
+
* excludes 要排除的文件, 默认排除 index
|
|
90
|
+
*/
|
|
91
|
+
/**
|
|
92
|
+
* 读取录下的所有文件,之后返回数组
|
|
93
|
+
* @param dir 要读取的目录
|
|
94
|
+
* @param exts 要读取的文件后缀,不包含 (.) 点,例如 jpg 而非 .jpg
|
|
95
|
+
* @param excludes 要排除的文件列表
|
|
96
|
+
* @param files 读取到的文件路径存放地址
|
|
97
|
+
*/
|
|
98
|
+
export declare const deepReaddir: (dir: string, exts: Set<string>, excludes?: Set<string>, files?: string[]) => string[];
|
|
78
99
|
export {};
|
package/dist/utils/index.js
CHANGED
|
@@ -18,9 +18,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
21
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.modifiyURL = exports.inExpired = exports.tryCatchLog = exports.deepFreeze = exports.sleep = exports.lcfirst = exports.ucfirst = exports.nt2space = exports.randStr = exports.md5 = void 0;
|
|
25
|
+
exports.deepReaddir = exports.waitFor = exports.modifiyURL = exports.inExpired = exports.tryCatchLog = exports.deepFreeze = exports.sleep = exports.lcfirst = exports.ucfirst = exports.nt2space = exports.randStr = exports.md5 = void 0;
|
|
26
|
+
const async_1 = __importDefault(require("async"));
|
|
23
27
|
const crypto = __importStar(require("crypto"));
|
|
28
|
+
const fs_1 = __importDefault(require("fs"));
|
|
29
|
+
const path_1 = __importDefault(require("path"));
|
|
24
30
|
/** 随机字符串字典 */
|
|
25
31
|
const RAND_STR_DICT = {
|
|
26
32
|
normal: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
|
|
@@ -40,9 +46,8 @@ function randStr(len, type = "normal") {
|
|
|
40
46
|
const dict = type === "strong" || type === "normal" ? RAND_STR_DICT[type] : type;
|
|
41
47
|
const { length } = dict;
|
|
42
48
|
/** 随机字符串的长度不能等于 0 或者负数 */
|
|
43
|
-
len
|
|
44
|
-
|
|
45
|
-
return Array(len)
|
|
49
|
+
const _len = Math.max(3, len | 0);
|
|
50
|
+
return Array(_len)
|
|
46
51
|
.fill("")
|
|
47
52
|
.map(() => dict[Math.floor(Math.random() * length)])
|
|
48
53
|
.join("");
|
|
@@ -147,3 +152,51 @@ const modifiyURL = (address, adds, removes) => {
|
|
|
147
152
|
return obj.toString();
|
|
148
153
|
};
|
|
149
154
|
exports.modifiyURL = modifiyURL;
|
|
155
|
+
/**
|
|
156
|
+
* 等待,知道 test 返回 true
|
|
157
|
+
* @param test 检测函数
|
|
158
|
+
* @param intervalMS 间隔多久判断一次, 单位毫秒 默认 100
|
|
159
|
+
*/
|
|
160
|
+
const waitFor = async (test, intervalMS = 100) => {
|
|
161
|
+
await async_1.default.doUntil(async () => {
|
|
162
|
+
await (0, exports.sleep)(intervalMS);
|
|
163
|
+
}, async () => test());
|
|
164
|
+
};
|
|
165
|
+
exports.waitFor = waitFor;
|
|
166
|
+
/**
|
|
167
|
+
* 读取录下的所有文件,之后返回数组
|
|
168
|
+
* params
|
|
169
|
+
* dir 要加载的目录
|
|
170
|
+
* exts 要加载的模块文件后缀,多个可以是数组, 默认为 coffee
|
|
171
|
+
* excludes 要排除的文件, 默认排除 index
|
|
172
|
+
*/
|
|
173
|
+
/**
|
|
174
|
+
* 读取录下的所有文件,之后返回数组
|
|
175
|
+
* @param dir 要读取的目录
|
|
176
|
+
* @param exts 要读取的文件后缀,不包含 (.) 点,例如 jpg 而非 .jpg
|
|
177
|
+
* @param excludes 要排除的文件列表
|
|
178
|
+
* @param files 读取到的文件路径存放地址
|
|
179
|
+
*/
|
|
180
|
+
const deepReaddir = (dir, exts, excludes = new Set(), files = []) => {
|
|
181
|
+
for (const x of fs_1.default.readdirSync(dir)) {
|
|
182
|
+
const file = path_1.default.resolve(dir, x);
|
|
183
|
+
const stat = fs_1.default.lstatSync(file);
|
|
184
|
+
if (stat.isFile()) {
|
|
185
|
+
// 忽略隐藏文件
|
|
186
|
+
if (x[0] === ".")
|
|
187
|
+
continue;
|
|
188
|
+
const arr = x.split(".");
|
|
189
|
+
const ext = arr.pop();
|
|
190
|
+
const name = arr.join(".");
|
|
191
|
+
// 如果是不希望的后缀或者排除的名称,则直接忽略/跳过
|
|
192
|
+
if ((ext && !exts.has(ext)) || excludes.has(name))
|
|
193
|
+
continue;
|
|
194
|
+
files.push(file);
|
|
195
|
+
}
|
|
196
|
+
else if (stat.isDirectory()) {
|
|
197
|
+
(0, exports.deepReaddir)(file, exts, excludes, files);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return files;
|
|
201
|
+
};
|
|
202
|
+
exports.deepReaddir = deepReaddir;
|