UNPKG

@lxlib/mock

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.1.

627 lines (617 loc) 18.2 kB
import { Injectable, Injector, NgModule } from '@angular/core'; import { HttpErrorResponse, HttpResponseBase, HttpResponse, HTTP_INTERCEPTORS } from '@angular/common/http'; import { throwError, of } from 'rxjs'; import { delay } from 'rxjs/operators'; /** * @fileoverview added by tsickle * Generated from: src/interface.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @record */ function MockCachedRule() { } if (false) { /** @type {?} */ MockCachedRule.prototype.method; /** @type {?} */ MockCachedRule.prototype.url; /** @type {?} */ MockCachedRule.prototype.martcher; /** @type {?} */ MockCachedRule.prototype.segments; /* Skipping unhandled member: [key: string]: any;*/ /** * @param {?} req * @return {?} */ MockCachedRule.prototype.callback = function (req) { }; } /** * @record */ function MockRule() { } if (false) { /** @type {?} */ MockRule.prototype.method; /** @type {?} */ MockRule.prototype.url; /** * 路由参数 * @type {?|undefined} */ MockRule.prototype.params; /* Skipping unhandled member: [key: string]: any;*/ /** * @param {?} req * @return {?} */ MockRule.prototype.callback = function (req) { }; } /** * @record */ function MockRequest() { } if (false) { /** * 路由参数 * @type {?|undefined} */ MockRequest.prototype.params; /** * URL参数 * @type {?|undefined} */ MockRequest.prototype.queryString; /** @type {?|undefined} */ MockRequest.prototype.headers; /** @type {?|undefined} */ MockRequest.prototype.body; /** * 原始 `HttpRequest` * @type {?} */ MockRequest.prototype.original; } /** * @fileoverview added by tsickle * Generated from: src/status.error.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MockStatusError { /** * @param {?} status * @param {?=} error */ constructor(status, error) { this.status = status; this.error = error; } } if (false) { /** @type {?} */ MockStatusError.prototype.statusText; /** @type {?} */ MockStatusError.prototype.status; /** @type {?} */ MockStatusError.prototype.error; } /** * @fileoverview added by tsickle * Generated from: src/mock.config.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class LxlibMockConfig { constructor() { /** * 请求延迟,单位:毫秒,默认:`300` */ this.delay = 300; /** * 是否强制所有请求都Mock,`true` 表示当请求的URL不存在时直接返回 404 错误,`false` 表示未命中时发送真实HTTP请求 */ this.force = false; /** * 是否打印 Mock 请求信息,弥补浏览器无Network信息 */ this.log = true; /** * 是否拦截命中后继续调用后续拦截器的 `intercept` 方法,默认:`true` */ this.executeOtherInterceptors = true; } } if (false) { /** * 规则定义数据 * @type {?} */ LxlibMockConfig.prototype.data; /** * 请求延迟,单位:毫秒,默认:`300` * @type {?} */ LxlibMockConfig.prototype.delay; /** * 是否强制所有请求都Mock,`true` 表示当请求的URL不存在时直接返回 404 错误,`false` 表示未命中时发送真实HTTP请求 * @type {?} */ LxlibMockConfig.prototype.force; /** * 是否打印 Mock 请求信息,弥补浏览器无Network信息 * @type {?} */ LxlibMockConfig.prototype.log; /** * 是否拦截命中后继续调用后续拦截器的 `intercept` 方法,默认:`true` * @type {?} */ LxlibMockConfig.prototype.executeOtherInterceptors; } /** * @fileoverview added by tsickle * Generated from: src/mock.service.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MockService { /** * @param {?} config */ constructor(config) { this.config = config; this.cached = []; this.applyMock(); delete this.config.data; } // #region parse rule /** * @private * @return {?} */ applyMock() { this.cached = []; try { this.realApplyMock(); } catch (e) { this.outputError(e); } } /** * @private * @return {?} */ realApplyMock() { /** @type {?} */ const data = this.config.data; if (!data) return; Object.keys(data).forEach((/** * @param {?} key * @return {?} */ (key) => { /** @type {?} */ const rules = data[key]; if (!rules) return; Object.keys(rules).forEach((/** * @param {?} ruleKey * @return {?} */ (ruleKey) => { /** @type {?} */ const value = rules[ruleKey]; if (!(typeof value === 'function' || typeof value === 'object' || typeof value === 'string')) { throw Error(`mock value of [${key}-${ruleKey}] should be function or object or string, but got ${typeof value}`); } /** @type {?} */ const rule = this.genRule(ruleKey, value); if (['GET', 'POST', 'PUT', 'HEAD', 'DELETE', 'PATCH', 'OPTIONS'].indexOf(rule.method) === -1) { throw Error(`method of ${key}-${ruleKey} is not valid`); } /** @type {?} */ const item = this.cached.find((/** * @param {?} w * @return {?} */ w => w.url === rule.url && w.method === rule.method)); if (item) { item.callback = rule.callback; } else { this.cached.push(rule); } })); })); // regular ordering this.cached.sort((/** * @param {?} a * @param {?} b * @return {?} */ (a, b) => (b.martcher || '').toString().length - (a.martcher || '').toString().length)); } /** * @private * @param {?} key * @param {?} callback * @return {?} */ genRule(key, callback) { /** @type {?} */ let method = 'GET'; /** @type {?} */ let url = key; if (key.indexOf(' ') > -1) { /** @type {?} */ const splited = key.split(' '); method = splited[0].toLowerCase(); url = splited[1]; } /** @type {?} */ let martcher = null; /** @type {?} */ let segments = []; if (~url.indexOf(':')) { segments = (/** @type {?} */ (url)).split('/') .filter((/** * @param {?} segment * @return {?} */ segment => segment.startsWith(':'))) .map((/** * @param {?} v * @return {?} */ v => v.substring(1))); /** @type {?} */ const reStr = (/** @type {?} */ (url)).split('/') .map((/** * @param {?} segment * @return {?} */ segment => (segment.startsWith(':') ? `([^/]+)` : segment))) .join('/'); martcher = new RegExp(`^${reStr}`, 'i'); } else if (/(\([^)]+\))/i.test(url)) { martcher = new RegExp(url, 'i'); } return { url, martcher, segments, callback, method: method.toUpperCase(), }; } /** * @private * @param {?} error * @return {?} */ outputError(error) { /** @type {?} */ const filePath = error.message.split(': ')[0]; /** @type {?} */ const errors = ((/** @type {?} */ (error.stack))) .split('\n') .filter((/** * @param {?} line * @return {?} */ line => line.trim().indexOf('at ') !== 0)) .map((/** * @param {?} line * @return {?} */ line => line.replace(`${filePath}: `, ''))); errors.splice(1, 0, ''); console.group(); console.warn(`==========Failed to parse mock config.==========`); console.log(errors.join('\n')); console.groupEnd(); throw error; } // #endregion /** * @param {?} method * @param {?} url * @return {?} */ getRule(method, url) { method = (method || 'GET').toUpperCase(); /** @type {?} */ const params = {}; /** @type {?} */ const list = this.cached.filter((/** * @param {?} w * @return {?} */ w => w.method === method && (w.martcher ? w.martcher.test(url) : w.url === url))); if (list.length === 0) return null; /** @type {?} */ const ret = list.find((/** * @param {?} w * @return {?} */ w => w.url === url)) || list[0]; if (ret.martcher) { /** @type {?} */ const execArr = ret.martcher.exec(url); (/** @type {?} */ (execArr)).slice(1).map((/** * @param {?} value * @param {?} index * @return {?} */ (value, index) => { params[ret.segments[index]] = value; })); } return { url, method: ret.method, params, callback: ret.callback, }; } /** * @return {?} */ clearCache() { this.cached = []; } /** * @return {?} */ get rules() { return this.cached; } /** * @return {?} */ ngOnDestroy() { this.clearCache(); } } MockService.decorators = [ { type: Injectable } ]; /** @nocollapse */ MockService.ctorParameters = () => [ { type: LxlibMockConfig } ]; if (false) { /** * @type {?} * @private */ MockService.prototype.cached; /** * @type {?} * @private */ MockService.prototype.config; } /** * @fileoverview added by tsickle * Generated from: src/mock.interceptor.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class HttpMockInterceptorHandler { /** * @param {?} next * @param {?} interceptor */ constructor(next, interceptor) { this.next = next; this.interceptor = interceptor; } /** * @param {?} req * @return {?} */ handle(req) { return this.interceptor.intercept(req, this.next); } } if (false) { /** * @type {?} * @private */ HttpMockInterceptorHandler.prototype.next; /** * @type {?} * @private */ HttpMockInterceptorHandler.prototype.interceptor; } class MockInterceptor { /** * @param {?} injector */ constructor(injector) { this.injector = injector; } /** * @param {?} req * @param {?} next * @return {?} */ intercept(req, next) { /** @type {?} */ const src = this.injector.get(MockService); /** @type {?} */ const config = Object.assign({ delay: 300, force: false, log: true, executeOtherInterceptors: true }, this.injector.get(LxlibMockConfig)); /** @type {?} */ const rule = src.getRule(req.method, req.url.split('?')[0]); if (!rule && !config.force) { return next.handle(req); } /** @type {?} */ let res; switch (typeof (/** @type {?} */ (rule)).callback) { case 'function': /** @type {?} */ const mockRequest = { original: req, body: req.body, queryString: {}, headers: {}, params: (/** @type {?} */ (rule)).params, }; /** @type {?} */ const urlParams = req.url.split('?'); if (urlParams.length > 1) { urlParams[1].split('&').forEach((/** * @param {?} item * @return {?} */ item => { /** @type {?} */ const itemArr = item.split('='); /** @type {?} */ const key = itemArr[0]; /** @type {?} */ const value = itemArr[1]; // is array if (Object.keys(mockRequest.queryString).includes(key)) { if (!Array.isArray(mockRequest.queryString[key])) { mockRequest.queryString[key] = [mockRequest.queryString[key]]; } mockRequest.queryString[key].push(value); } else { mockRequest.queryString[key] = value; } })); } req.params.keys().forEach((/** * @param {?} key * @return {?} */ key => (mockRequest.queryString[key] = req.params.get(key)))); req.headers.keys().forEach((/** * @param {?} key * @return {?} */ key => (mockRequest.headers[key] = req.headers.get(key)))); try { res = (/** @type {?} */ (rule)).callback.call(this, mockRequest); } catch (e) { res = new HttpErrorResponse({ url: req.url, headers: req.headers, status: 400, statusText: e.statusText || 'Unknown Error', error: e.error, }); if (e instanceof MockStatusError) { res.status = e.status; } } break; default: res = (/** @type {?} */ (rule)).callback; break; } if (!(res instanceof HttpResponseBase)) { res = new HttpResponse({ status: 200, url: req.url, body: res, }); } if (config.log) { console.log(`%c👽${req.method}->${req.url}->request`, 'background:#000;color:#bada55', req); console.log(`%c👽${req.method}->${req.url}->response`, 'background:#000;color:#bada55', res); } /** @type {?} */ const res$ = res instanceof HttpErrorResponse ? throwError(res) : of(res); if (config.executeOtherInterceptors) { /** @type {?} */ const interceptors = this.injector.get(HTTP_INTERCEPTORS, []); /** @type {?} */ const lastInterceptors = interceptors.slice(interceptors.indexOf(this) + 1); if (lastInterceptors.length > 0) { /** @type {?} */ const chain = lastInterceptors.reduceRight((/** * @param {?} _next * @param {?} _interceptor * @return {?} */ (_next, _interceptor) => new HttpMockInterceptorHandler(_next, _interceptor)), (/** @type {?} */ ({ handle: (/** * @return {?} */ () => res$), }))); return chain.handle(req).pipe(delay(config.delay)); } } return res$.pipe(delay(config.delay)); } } MockInterceptor.decorators = [ { type: Injectable } ]; /** @nocollapse */ MockInterceptor.ctorParameters = () => [ { type: Injector } ]; if (false) { /** * @type {?} * @private */ MockInterceptor.prototype.injector; } /** * @fileoverview added by tsickle * Generated from: src/mock.module.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class LxlibMockModule { /** * @param {?} config * @return {?} */ static forRoot(config) { return { ngModule: LxlibMockModule, providers: [ MockService, { provide: LxlibMockConfig, useValue: config }, { provide: HTTP_INTERCEPTORS, useClass: MockInterceptor, multi: true }, ], }; } /** * @return {?} */ static forChild() { return { ngModule: LxlibMockModule, providers: [{ provide: HTTP_INTERCEPTORS, useClass: MockInterceptor, multi: true }], }; } } LxlibMockModule.decorators = [ { type: NgModule, args: [{},] } ]; /** * @fileoverview added by tsickle * Generated from: public_api.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * Generated from: mock.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { LxlibMockConfig, LxlibMockModule, MockInterceptor, MockService, MockStatusError }; //# sourceMappingURL=mock.js.map