@midwayjs/mock 3.9.0 → 3.10.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.
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="bluebird" />
3
2
  import type { Channel, Options } from 'amqplib';
4
3
  declare class ChannelManager {
5
4
  private connection;
@@ -11,7 +10,7 @@ declare class ChannelManager {
11
10
  createChannel(queueName: any): Promise<Channel>;
12
11
  sendToQueue(queueName: string, content: Buffer, options?: Options.Publish): boolean;
13
12
  sendToExchange(exchange: string, routingKey: string, content: Buffer, options?: Options.Publish): boolean;
14
- assertExchange(exchange: string, type: 'direct' | 'topic' | 'headers' | 'fanout' | 'match' | string, options?: Options.AssertExchange): import("bluebird")<import("amqplib").Replies.AssertExchange>;
13
+ assertExchange(exchange: string, type: 'direct' | 'topic' | 'headers' | 'fanout' | 'match' | string, options?: Options.AssertExchange): Promise<import("amqplib").Replies.AssertExchange>;
15
14
  close(): Promise<void>;
16
15
  }
17
16
  export declare function createRabbitMQProducer(options: {
package/dist/creator.js CHANGED
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBootstrap = exports.createLightApp = exports.createFunctionApp = exports.close = exports.createApp = exports.create = void 0;
4
4
  const core_1 = require("@midwayjs/core");
5
5
  const path_1 = require("path");
6
- const fs_extra_1 = require("fs-extra");
7
6
  const logger_1 = require("@midwayjs/logger");
8
7
  const utils_1 = require("./utils");
9
8
  const util_1 = require("util");
@@ -24,95 +23,121 @@ function formatPath(baseDir, p) {
24
23
  async function create(appDir = process.cwd(), options, customFramework) {
25
24
  debug(`[mock]: Create app, appDir="${appDir}"`);
26
25
  process.env.MIDWAY_TS_MODE = 'true';
27
- if (appDir) {
28
- // 处理测试的 fixtures
29
- if (!(0, path_1.isAbsolute)(appDir)) {
30
- appDir = (0, path_1.join)(process.cwd(), 'test', 'fixtures', appDir);
26
+ try {
27
+ if (appDir) {
28
+ // 处理测试的 fixtures
29
+ if (!(0, path_1.isAbsolute)(appDir)) {
30
+ appDir = (0, path_1.join)(process.cwd(), 'test', 'fixtures', appDir);
31
+ }
32
+ if (!(0, fs_1.existsSync)(appDir)) {
33
+ throw new core_1.MidwayCommonError(`Path "${appDir}" not exists, please check it.`);
34
+ }
35
+ }
36
+ (0, logger_1.clearAllLoggers)();
37
+ options = options || {};
38
+ if (options.baseDir) {
39
+ (0, core_1.safeRequire)((0, path_1.join)(`${options.baseDir}`, 'interface'));
31
40
  }
32
- if (!(0, fs_1.existsSync)(appDir)) {
33
- throw new core_1.MidwayCommonError(`Path "${appDir}" not exists, please check it.`);
41
+ else if (appDir) {
42
+ options.baseDir = `${appDir}/src`;
43
+ (0, core_1.safeRequire)((0, path_1.join)(`${options.baseDir}`, 'interface'));
34
44
  }
35
- }
36
- (0, logger_1.clearAllLoggers)();
37
- options = options || {};
38
- if (options.baseDir) {
39
- (0, core_1.safeRequire)((0, path_1.join)(`${options.baseDir}`, 'interface'));
40
- }
41
- else if (appDir) {
42
- options.baseDir = `${appDir}/src`;
43
- (0, core_1.safeRequire)((0, path_1.join)(`${options.baseDir}`, 'interface'));
44
- }
45
- if (options.entryFile) {
46
- // start from entry file, like bootstrap.js
47
- options.entryFile = formatPath(appDir, options.entryFile);
48
- global['MIDWAY_BOOTSTRAP_APP_READY'] = false;
49
- // set app in @midwayjs/bootstrap
50
- require(options.entryFile);
51
- await new Promise((resolve, reject) => {
52
- const timeoutHandler = setTimeout(() => {
53
- clearInterval(internalHandler);
54
- reject(new Error('[midway]: bootstrap timeout'));
55
- }, options.bootstrapTimeout || 30 * 1000);
56
- const internalHandler = setInterval(() => {
57
- if (global['MIDWAY_BOOTSTRAP_APP_READY'] === true) {
45
+ if (options.entryFile) {
46
+ // start from entry file, like bootstrap.js
47
+ options.entryFile = formatPath(appDir, options.entryFile);
48
+ global['MIDWAY_BOOTSTRAP_APP_READY'] = false;
49
+ // set app in @midwayjs/bootstrap
50
+ require(options.entryFile);
51
+ await new Promise((resolve, reject) => {
52
+ const timeoutHandler = setTimeout(() => {
58
53
  clearInterval(internalHandler);
59
- clearTimeout(timeoutHandler);
60
- resolve();
54
+ reject(new Error('[midway]: bootstrap timeout'));
55
+ }, options.bootstrapTimeout || 30 * 1000);
56
+ const internalHandler = setInterval(() => {
57
+ if (global['MIDWAY_BOOTSTRAP_APP_READY'] === true) {
58
+ clearInterval(internalHandler);
59
+ clearTimeout(timeoutHandler);
60
+ resolve();
61
+ }
62
+ else {
63
+ debug('[mock]: bootstrap not ready and wait next check');
64
+ }
65
+ }, 200);
66
+ });
67
+ return;
68
+ }
69
+ if (!options.imports && customFramework) {
70
+ options.imports = (0, utils_1.transformFrameworkToConfiguration)(customFramework);
71
+ }
72
+ if (customFramework === null || customFramework === void 0 ? void 0 : customFramework['Configuration']) {
73
+ options.imports = customFramework;
74
+ customFramework = customFramework['Framework'];
75
+ }
76
+ if (options.ssl) {
77
+ const sslConfig = {
78
+ koa: {
79
+ key: (0, path_1.join)(__dirname, '../ssl/ssl.key'),
80
+ cert: (0, path_1.join)(__dirname, '../ssl/ssl.pem'),
81
+ },
82
+ egg: {
83
+ key: (0, path_1.join)(__dirname, '../ssl/ssl.key'),
84
+ cert: (0, path_1.join)(__dirname, '../ssl/ssl.pem'),
85
+ },
86
+ express: {
87
+ key: (0, path_1.join)(__dirname, '../ssl/ssl.key'),
88
+ cert: (0, path_1.join)(__dirname, '../ssl/ssl.pem'),
89
+ },
90
+ };
91
+ options.globalConfig = (0, utils_1.mergeGlobalConfig)(options.globalConfig, sslConfig);
92
+ }
93
+ const container = new core_1.MidwayContainer();
94
+ const bindModuleMap = new WeakMap();
95
+ // 这里设置是因为在 midway 单测中会不断的复用装饰器元信息,又不能清理缓存,所以在这里做一些过滤
96
+ container.onBeforeBind(target => {
97
+ bindModuleMap.set(target, true);
98
+ });
99
+ const originMethod = container.listModule;
100
+ container.listModule = key => {
101
+ const modules = originMethod.call(container, key);
102
+ if (key === core_1.CONFIGURATION_KEY) {
103
+ return modules;
104
+ }
105
+ return modules.filter((module) => {
106
+ var _a;
107
+ if (bindModuleMap.has(module)) {
108
+ return true;
61
109
  }
62
110
  else {
63
- debug('[mock]: bootstrap not ready and wait next check');
111
+ debug('[mock] Filter "%o" module without binding when list module %s.', (_a = module.name) !== null && _a !== void 0 ? _a : module, key);
112
+ return false;
64
113
  }
65
- }, 200);
114
+ });
115
+ };
116
+ options.applicationContext = container;
117
+ await (0, core_1.initializeGlobalApplicationContext)({
118
+ ...options,
119
+ appDir,
120
+ asyncContextManager: (0, async_hooks_context_manager_1.createContextManager)(),
121
+ imports: []
122
+ .concat(options.imports)
123
+ .concat(options.baseDir
124
+ ? (0, core_1.safeRequire)((0, path_1.join)(options.baseDir, 'configuration'))
125
+ : []),
66
126
  });
67
- return;
68
- }
69
- if (!options.imports && customFramework) {
70
- options.imports = (0, utils_1.transformFrameworkToConfiguration)(customFramework);
71
- }
72
- if (customFramework === null || customFramework === void 0 ? void 0 : customFramework['Configuration']) {
73
- options.imports = customFramework;
74
- customFramework = customFramework['Framework'];
75
- }
76
- const container = new core_1.MidwayContainer();
77
- const bindModuleMap = new WeakMap();
78
- // 这里设置是因为在 midway 单测中会不断的复用装饰器元信息,又不能清理缓存,所以在这里做一些过滤
79
- container.onBeforeBind(target => {
80
- bindModuleMap.set(target, true);
81
- });
82
- const originMethod = container.listModule;
83
- container.listModule = key => {
84
- const modules = originMethod.call(container, key);
85
- if (key === core_1.CONFIGURATION_KEY) {
86
- return modules;
127
+ if (customFramework) {
128
+ return container.getAsync(customFramework);
129
+ }
130
+ else {
131
+ const frameworkService = await container.getAsync(core_1.MidwayFrameworkService);
132
+ return frameworkService.getMainFramework();
87
133
  }
88
- return modules.filter((module) => {
89
- var _a;
90
- if (bindModuleMap.has(module)) {
91
- return true;
92
- }
93
- else {
94
- debug('[mock] Filter "%o" module without binding when list module %s.', (_a = module.name) !== null && _a !== void 0 ? _a : module, key);
95
- return false;
96
- }
97
- });
98
- };
99
- options.applicationContext = container;
100
- await (0, core_1.initializeGlobalApplicationContext)({
101
- ...options,
102
- appDir,
103
- asyncContextManager: (0, async_hooks_context_manager_1.createContextManager)(),
104
- imports: []
105
- .concat(options.imports)
106
- .concat(options.baseDir
107
- ? (0, core_1.safeRequire)((0, path_1.join)(options.baseDir, 'configuration'))
108
- : []),
109
- });
110
- if (customFramework) {
111
- return container.getAsync(customFramework);
112
134
  }
113
- else {
114
- const frameworkService = await container.getAsync(core_1.MidwayFrameworkService);
115
- return frameworkService.getMainFramework();
135
+ catch (err) {
136
+ // catch for jest beforeAll can't throw error
137
+ if (process.env.JEST_WORKER_ID) {
138
+ console.error(err);
139
+ }
140
+ throw err;
116
141
  }
117
142
  }
118
143
  exports.create = create;
@@ -130,11 +155,11 @@ async function close(app, options) {
130
155
  if ((0, utils_1.isTestEnvironment)()) {
131
156
  // clean first
132
157
  if (options.cleanLogsDir && !(0, utils_1.isWin32)()) {
133
- await (0, fs_extra_1.remove)((0, path_1.join)(app.getAppDir(), 'logs'));
158
+ await (0, utils_1.removeFile)((0, path_1.join)(app.getAppDir(), 'logs'));
134
159
  }
135
160
  if (core_1.MidwayFrameworkType.WEB === app.getFrameworkType()) {
136
161
  if (options.cleanTempDir && !(0, utils_1.isWin32)()) {
137
- await (0, fs_extra_1.remove)((0, path_1.join)(app.getAppDir(), 'run'));
162
+ await (0, utils_1.removeFile)((0, path_1.join)(app.getAppDir(), 'run'));
138
163
  }
139
164
  }
140
165
  if (options.sleep > 0) {
@@ -170,12 +195,14 @@ async function createFunctionApp(baseDir = process.cwd(), options = {}, customFr
170
195
  options.appDir = baseDir;
171
196
  debug(`[mock]: Create app, appDir="${options.appDir}"`);
172
197
  process.env.MIDWAY_TS_MODE = 'true';
173
- // 处理测试的 fixtures
174
- if (!(0, path_1.isAbsolute)(options.appDir)) {
175
- options.appDir = (0, path_1.join)(process.cwd(), 'test', 'fixtures', options.appDir);
176
- }
177
- if (!(0, fs_1.existsSync)(options.appDir)) {
178
- throw new core_1.MidwayCommonError(`Path "${options.appDir}" not exists, please check it.`);
198
+ if (options.appDir) {
199
+ // 处理测试的 fixtures
200
+ if (!(0, path_1.isAbsolute)(options.appDir)) {
201
+ options.appDir = (0, path_1.join)(process.cwd(), 'test', 'fixtures', options.appDir);
202
+ }
203
+ if (!(0, fs_1.existsSync)(options.appDir)) {
204
+ throw new core_1.MidwayCommonError(`Path "${options.appDir}" not exists, please check it.`);
205
+ }
179
206
  }
180
207
  (0, logger_1.clearAllLoggers)();
181
208
  options = options || {};
@@ -197,38 +224,81 @@ async function createFunctionApp(baseDir = process.cwd(), options = {}, customFr
197
224
  const app = appManager.getApplication(core_1.MidwayFrameworkType.FAAS);
198
225
  const faasConfig = (_b = configService.getConfiguration('faas')) !== null && _b !== void 0 ? _b : {};
199
226
  const customPort = (_d = (_c = process.env.MIDWAY_HTTP_PORT) !== null && _c !== void 0 ? _c : faasConfig['port']) !== null && _d !== void 0 ? _d : options['port'];
200
- app.callback2 = () => {
201
- // mock a real http server response for local dev
202
- return async (req, res) => {
203
- const url = new URL(req.url, `http://${req.headers.host}`);
204
- req.query = Object.fromEntries(url.searchParams);
205
- req.path = url.pathname;
206
- // 如果需要解析body并且body是个stream,函数网关不会接受比 10m 更大的文件了
207
- if (['post', 'put', 'delete'].indexOf(req.method.toLowerCase()) !== -1 &&
208
- !req.body &&
209
- typeof req.on === 'function') {
210
- req.body = await getRawBody(req, {
211
- limit: '10mb',
227
+ if (options.starter.callback2) {
228
+ app.callback2 = options.starter.callback2;
229
+ }
230
+ else {
231
+ app.callback2 = () => {
232
+ // mock a real http server response for local dev
233
+ return async (req, res) => {
234
+ const url = new URL(req.url, `http://${req.headers.host}`);
235
+ req.query = Object.fromEntries(url.searchParams);
236
+ req.path = url.pathname;
237
+ // 如果需要解析body并且body是个stream,函数网关不会接受比 10m 更大的文件了
238
+ if (['post', 'put', 'delete'].indexOf(req.method.toLowerCase()) !==
239
+ -1 &&
240
+ !req.body &&
241
+ typeof req.on === 'function') {
242
+ req.body = await getRawBody(req, {
243
+ limit: '10mb',
244
+ });
245
+ }
246
+ req.getOriginEvent = () => {
247
+ var _a;
248
+ return ((_a = options.starter) === null || _a === void 0 ? void 0 : _a.createDefaultMockHttpEvent()) || {};
249
+ };
250
+ req.getOriginContext = () => {
251
+ var _a;
252
+ return ((_a = options.starter) === null || _a === void 0 ? void 0 : _a.createDefaultMockContext()) || {};
253
+ };
254
+ const ctx = await framework.wrapHttpRequest(req);
255
+ // create event and invoke
256
+ const result = await framework.invokeTriggerFunction(ctx, url.pathname, {
257
+ isHttpFunction: true,
212
258
  });
213
- }
214
- const ctx = await framework.wrapHttpRequest(req);
215
- // create event and invoke
216
- const result = await framework.invokeTriggerFunction(ctx, url.pathname, {
217
- isHttpFunction: true,
218
- });
219
- const { statusCode, headers, body } = result;
220
- if (res.headersSent) {
221
- return;
222
- }
223
- for (const key in headers) {
224
- res.setHeader(key, headers[key]);
225
- }
226
- if (res.statusCode !== statusCode) {
227
- res.statusCode = statusCode;
228
- }
229
- // http trigger only support `Buffer` or a `string` or a `stream.Readable`
230
- res.end(body);
259
+ const { statusCode, headers, body } = result;
260
+ if (res.headersSent) {
261
+ return;
262
+ }
263
+ for (const key in headers) {
264
+ res.setHeader(key, headers[key]);
265
+ }
266
+ if (res.statusCode !== statusCode) {
267
+ res.statusCode = statusCode;
268
+ }
269
+ // http trigger only support `Buffer` or a `string` or a `stream.Readable`
270
+ res.end(body);
271
+ };
231
272
  };
273
+ }
274
+ app.getServerlessInstance = async (serviceClass, customContext = {}) => {
275
+ const instance = new Proxy({}, {
276
+ get: (target, prop) => {
277
+ let funcInfo;
278
+ if (typeof serviceClass === 'string') {
279
+ funcInfo = framework['funMappingStore'].get(`${serviceClass}.${prop}`);
280
+ }
281
+ else {
282
+ funcInfo = Array.from(framework['funMappingStore'].values()).find((item) => {
283
+ return (item.id === (0, core_1.getProviderUUId)(serviceClass) &&
284
+ item.method === prop);
285
+ });
286
+ }
287
+ if (funcInfo) {
288
+ return async (...args) => {
289
+ var _a, _b, _c, _d, _e;
290
+ const context = app.createAnonymousContext({
291
+ originContext: (_b = customContext !== null && customContext !== void 0 ? customContext : (_a = options.starter) === null || _a === void 0 ? void 0 : _a.createDefaultMockContext()) !== null && _b !== void 0 ? _b : {},
292
+ originEvent: (_e = (_c = args[0]) !== null && _c !== void 0 ? _c : (_d = options.starter) === null || _d === void 0 ? void 0 : _d.createDefaultMockEvent()) !== null && _e !== void 0 ? _e : {},
293
+ });
294
+ return framework.invokeTriggerFunction(context, funcInfo.funcHandlerName, {
295
+ isHttpFunction: false,
296
+ });
297
+ };
298
+ }
299
+ },
300
+ });
301
+ return instance;
232
302
  };
233
303
  if (customPort) {
234
304
  await new Promise(resolve => {
@@ -2,8 +2,9 @@ import { IMidwayBootstrapOptions } from '@midwayjs/core';
2
2
  export interface MockAppConfigurationOptions extends IMidwayBootstrapOptions {
3
3
  cleanLogsDir?: boolean;
4
4
  cleanTempDir?: boolean;
5
+ ssl?: boolean;
5
6
  }
6
- export declare type ComponentModule = {
7
+ export type ComponentModule = {
7
8
  Configuration: new () => any;
8
9
  };
9
10
  //# sourceMappingURL=interface.d.ts.map
package/dist/utils.d.ts CHANGED
@@ -11,4 +11,6 @@ export declare function transformFrameworkToConfiguration<T extends IMidwayFrame
11
11
  [key: string]: any;
12
12
  Configuration: any;
13
13
  };
14
+ export declare function removeFile(file: string): Promise<void>;
15
+ export declare function mergeGlobalConfig(globalConfig: any, newConfigObject: Record<string, any>): any;
14
16
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -6,10 +6,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.transformFrameworkToConfiguration = exports.findFirstExistModule = exports.isWin32 = exports.isTestEnvironment = void 0;
9
+ exports.mergeGlobalConfig = exports.removeFile = exports.transformFrameworkToConfiguration = exports.findFirstExistModule = exports.isWin32 = exports.isTestEnvironment = void 0;
10
10
  const core_1 = require("@midwayjs/core");
11
11
  const os = require("os");
12
12
  const assert = require("assert");
13
+ const promises_1 = require("fs/promises");
13
14
  function isTestEnvironment() {
14
15
  const testEnv = ['test', 'unittest'];
15
16
  return (testEnv.includes(process.env.MIDWAY_SERVER_ENV) ||
@@ -70,4 +71,38 @@ function transformFrameworkToConfiguration(Framework) {
70
71
  };
71
72
  }
72
73
  exports.transformFrameworkToConfiguration = transformFrameworkToConfiguration;
74
+ async function removeFile(file) {
75
+ try {
76
+ await (0, promises_1.access)(file, promises_1.constants.W_OK);
77
+ await (0, promises_1.unlink)(file);
78
+ }
79
+ catch (_a) {
80
+ // ignore
81
+ }
82
+ }
83
+ exports.removeFile = removeFile;
84
+ function mergeGlobalConfig(globalConfig, newConfigObject) {
85
+ if (globalConfig) {
86
+ if (Array.isArray(globalConfig)) {
87
+ globalConfig.push({
88
+ default: {
89
+ ...newConfigObject,
90
+ },
91
+ });
92
+ }
93
+ else {
94
+ globalConfig = {
95
+ ...newConfigObject,
96
+ ...globalConfig,
97
+ };
98
+ }
99
+ }
100
+ else {
101
+ globalConfig = {
102
+ ...newConfigObject,
103
+ };
104
+ }
105
+ return globalConfig;
106
+ }
107
+ exports.mergeGlobalConfig = mergeGlobalConfig;
73
108
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midwayjs/mock",
3
- "version": "3.9.0",
3
+ "version": "3.10.0",
4
4
  "description": "create your test app from midway framework",
5
5
  "main": "dist/index",
6
6
  "typings": "dist/index.d.ts",
@@ -27,28 +27,27 @@
27
27
  },
28
28
  "license": "MIT",
29
29
  "devDependencies": {
30
- "@midwayjs/core": "^3.9.0",
30
+ "@midwayjs/core": "^3.10.0",
31
31
  "@midwayjs/logger": "^2.15.0",
32
- "@types/amqplib": "0.8.2",
32
+ "@types/amqplib": "0.10.1",
33
33
  "amqplib": "0.10.3",
34
34
  "kafkajs": "2.2.3",
35
- "socket.io": "4.5.3",
36
- "socket.io-client": "4.5.3",
37
- "ws": "8.10.0"
35
+ "socket.io": "4.5.4",
36
+ "socket.io-client": "4.5.4",
37
+ "ws": "8.12.0"
38
38
  },
39
39
  "dependencies": {
40
- "@midwayjs/async-hooks-context-manager": "^3.9.0",
40
+ "@midwayjs/async-hooks-context-manager": "^3.10.0",
41
41
  "@types/superagent": "4.1.14",
42
42
  "@types/supertest": "2.0.12",
43
- "fs-extra": "10.0.1",
44
43
  "js-yaml": "4.1.0",
45
44
  "raw-body": "2.5.1",
46
- "supertest": "6.3.0"
45
+ "supertest": "6.3.3"
47
46
  },
48
47
  "author": "Harry Chen <czy88840616@gmail.com>",
49
48
  "repository": {
50
49
  "type": "git",
51
50
  "url": "https://github.com/midwayjs/midway.git"
52
51
  },
53
- "gitHead": "5f6603d2c9606fc6fc7ece71f956e89e394efeee"
52
+ "gitHead": "33d28f1a020963404488e866432916fd15c0952c"
54
53
  }