cherry-rest
Advanced tools
Sorry, the diff of this file is too big to display
| global.fetch = require('node-fetch') | ||
| import Cherry,{module as CherryModule,config as CherryConfig} from '../dist/index.js' | ||
| //http://ip.taobao.com/service/getIpInfo.php?ip=114.114.114.114 | ||
| jest.setTimeout(1200000); | ||
| CherryConfig({ | ||
| credentials:'include' | ||
| },{ | ||
| baseUrl:'http://ip.taobao.com', | ||
| formatter:function(res){ | ||
| return res.json() | ||
| } | ||
| }) | ||
| CherryModule('ip|service',{ | ||
| formatter:[function(data){ | ||
| return data.data; | ||
| }], | ||
| filters:[{ | ||
| name:'over', | ||
| options:['city_id|id'] | ||
| }] | ||
| }); | ||
| it('async & filters test', () => { | ||
| expect.assertions(1); | ||
| return Cherry.ip.query({path:'getIpInfo.php',query:{ip:'114.114.114.114'}}).then(data => { | ||
| expect(JSON.stringify(data)).toEqual(JSON.stringify({"id":"320100"})) | ||
| }); | ||
| }); |
+3
-2
| { | ||
| "name": "cherry-rest", | ||
| "repository":"https://github.com/daoxiaozhang/cherry-rest.git", | ||
| "version": "0.0.2", | ||
| "version": "0.0.3", | ||
| "description": "", | ||
@@ -11,3 +11,4 @@ "keywords":"rest,cherry,cherry rest", | ||
| "pack": "webpack", | ||
| "test": "jest" | ||
| "test": "jest", | ||
| "async": "jest ./test/async.test.js" | ||
| }, | ||
@@ -14,0 +15,0 @@ "jest": { |
+37
-1
@@ -10,3 +10,4 @@ | ||
| - 可以给模块单独设置baseUrl | ||
| - 支持response transform配置、支持单个module formatter | ||
| - 支持response formatter配置、支持单个module formatter | ||
| - 内置默认filter,当前只有一个over,重载response data filed | ||
@@ -59,1 +60,36 @@ | ||
| ``` | ||
| Demo | ||
| ```js | ||
| import Cherry,{module as CherryModule,config as CherryConfig} from '../dist/index.js' | ||
| //http://ip.taobao.com/service/getIpInfo.php?ip=114.114.114.114 | ||
| jest.setTimeout(1200000); | ||
| CherryConfig({ | ||
| credentials:'include' | ||
| },{ | ||
| baseUrl:'http://ip.taobao.com', | ||
| formatter:function(res){ | ||
| return res.json() | ||
| } | ||
| }) | ||
| CherryModule('ip|service',{ | ||
| formatter:[function(data){ | ||
| return data.data; | ||
| }], | ||
| filters:[{ | ||
| name:'over', | ||
| options:['city_id|id'] | ||
| }] | ||
| }); | ||
| it('async & filters test', () => { | ||
| expect.assertions(1); | ||
| return Cherry.ip.query({path:'getIpInfo.php',query:{ip:'114.114.114.114'}}).then(data => { | ||
| expect(JSON.stringify(data)).toEqual(JSON.stringify({"id":"320100"})) | ||
| }); | ||
| }); | ||
| ``` | ||
+132
-27
@@ -0,1 +1,8 @@ | ||
| /** | ||
| * CherryRest | ||
| * 一个优雅的Rest接口访问器 | ||
| * @version 0.0.1 | ||
| * @author daoxiaozhang | ||
| */ | ||
| import "@babel/polyfill"; | ||
@@ -5,8 +12,14 @@ | ||
| const UNDEFINED_PATTERN = /^undefined | undefined$|^[^(]* undefined /i; | ||
| //rest对象 | ||
| let Cherry = {}; | ||
| //fetch基础配置 | ||
| let fetchOption = {}; | ||
| //全局配置 | ||
| let commonOption={ | ||
| noFetch:false, | ||
| baseUrl:'/', | ||
| //数据加载、默认使用fetch | ||
| loader:function(options) { | ||
@@ -16,2 +29,3 @@ let { url, ...rest } = Object.assign({}, fetchOption, options); | ||
| }, | ||
| //全局response数据转换器 | ||
| formatter:function(response){ | ||
@@ -21,26 +35,71 @@ return response | ||
| } | ||
| //rest对象 | ||
| let Cherry = {}; | ||
| /** | ||
| * 默认模块配置 | ||
| * @type {Object} | ||
| */ | ||
| let defaultModuleOptions={ | ||
| formatter:[], | ||
| baseUrl:undefined | ||
| } | ||
| //优雅的取值 | ||
| export function need(props, callback, defaultValue) { | ||
| try { | ||
| return callback(props); | ||
| } catch (error) { | ||
| if (error instanceof TypeError) { | ||
| if (NULL_PATTERN.test(error)) { | ||
| return defaultValue || null; | ||
| } else if (UNDEFINED_PATTERN.test(error)) { | ||
| return defaultValue || undefined; | ||
| } | ||
| function toBe(data,type){ | ||
| return Object.prototype.toString.call(data) === '[object '+type+']' | ||
| } | ||
| const filterOptions={ | ||
| over:function(source,opts=[]){ | ||
| let result={}; | ||
| let type=Object.prototype.toString.call(source); | ||
| let format=function(data){ | ||
| let _temp={}; | ||
| opts.map(item=>{ | ||
| let [key,alias]=item.split('|'); | ||
| let _key=alias||key; | ||
| _temp[_key]=data[key]; | ||
| }) | ||
| return _temp; | ||
| } | ||
| throw error; | ||
| if( type=== '[object Object]'){ | ||
| result=format(source); | ||
| }else if( type=== '[object Array]'){ | ||
| result=source.map(data=>{ | ||
| return format(data); | ||
| }) | ||
| } | ||
| return result; | ||
| } | ||
| } | ||
| //将path、qeuery参数转成url | ||
| function format({ | ||
| path = [], | ||
| query = {} | ||
| }) { | ||
| function log(){ | ||
| console.log(arguments) | ||
| } | ||
| /** | ||
| * debounce创建方法 | ||
| * @param {Function} fun 需要执行的function | ||
| * @param {Long} delay 延迟时间,单位:毫秒 | ||
| * @return {Function} | ||
| */ | ||
| function debounceCreator(fun, delay) { | ||
| return function(args) { | ||
| //获取函数的作用域和变量 | ||
| let that = this | ||
| let _args = args | ||
| //每次事件被触发,都会清除当前的timeer,然后重写设置超时调用 | ||
| clearTimeout(fun.id) | ||
| fun.id = setTimeout(function() { | ||
| fun.call(that, _args) | ||
| }, delay) | ||
| } | ||
| } | ||
| /** | ||
| * 根据参数、格式化为URL字符串 | ||
| * @param {Array} [path=[]] url path 默认类型为数组、可以是字符串、以逗号分割 | ||
| * @param {Object} [query={} }] url query参数 | ||
| * @return {String} url | ||
| */ | ||
| function format({ path = [], query = {} }) { | ||
| let url = ''; | ||
@@ -67,4 +126,7 @@ let params = []; | ||
| /** | ||
| * 模块 Class | ||
| */ | ||
| class Module { | ||
| constructor(props, options) { | ||
@@ -77,4 +139,7 @@ this.$name = props.name; | ||
| } else { | ||
| this.$options = Object.assign({}, options, props.options); | ||
| this.$options = Object.assign({}, defaultModuleOptions, props.options); | ||
| } | ||
| if(this.$options.debounce){ | ||
| this.$debouncer=debounceCreator(commonOption.loader,this.$options.debounce) | ||
| } | ||
| } | ||
@@ -106,9 +171,19 @@ getUrl(fetchParams){ | ||
| }else{ | ||
| return commonOption.loader(fetchOption) | ||
| .then(res=>{ | ||
| let formatter=this.$options.formatter||commonOption.formatter; | ||
| return formatter(res); | ||
| }); | ||
| let _prms=this.$debouncer?his.$debouncer(fetchOption):commonOption.loader(fetchOption); | ||
| console.log(fetchOption) | ||
| return _prms.then(commonOption.formatter).then(res=>{ | ||
| let formatterArrays=this.$options.formatter; | ||
| let filters=this.$options.filters; | ||
| let result=res; | ||
| formatterArrays.map(formatter=>{ | ||
| result=formatter(result); | ||
| }) | ||
| if(toBe(filters,'Array')){ | ||
| filters.map(filter=>{ | ||
| result=filterOptions[filter.name](result,filter.options) | ||
| }) | ||
| } | ||
| return result; | ||
| }); | ||
| } | ||
| } | ||
@@ -134,2 +209,8 @@ create(fetchParams) { | ||
| /** | ||
| * 通过字符串的形式实例化module对象 | ||
| * @param {[type]} name 字符串配置形式 | ||
| * @param {[type]} options 模块的配置 | ||
| * @return {[type]} [description] | ||
| */ | ||
| function createModuleByString(name, options) { | ||
@@ -169,2 +250,25 @@ let moduleNames = name.split(','); | ||
| /** | ||
| * 一个优雅的取值形式 | ||
| * @param {Object} props 需要取值的数据源 | ||
| * @param {Function} callback | ||
| * @param {Object} defaultValue 当取值异常、或者值为false时返回的默认值 | ||
| * @return {Object} 返回值 | ||
| */ | ||
| export function need(props, callback, defaultValue) { | ||
| try { | ||
| return callback(props); | ||
| } catch (error) { | ||
| if (error instanceof TypeError) { | ||
| if (NULL_PATTERN.test(error)) { | ||
| return defaultValue || null; | ||
| } else if (UNDEFINED_PATTERN.test(error)) { | ||
| return defaultValue || undefined; | ||
| } | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
| export function config(fetch,common) { | ||
@@ -181,2 +285,3 @@ fetchOption = fetch; | ||
| } | ||
| export default Cherry; |
@@ -9,2 +9,6 @@ global.fetch = require('jest-fetch-mock') | ||
| CherryModule('goods',{ | ||
| debounce:1000 | ||
| }); | ||
| CherryModule('module2|home,moudle3|user'); | ||
@@ -11,0 +15,0 @@ CherryModule([{ |
@@ -29,2 +29,3 @@ const path = require('path'); | ||
| }, | ||
| devtool:'source-map', | ||
| plugins: [ | ||
@@ -31,0 +32,0 @@ new CleanWebpackPlugin(['dist', |
Sorry, the diff of this file is too big to display
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
749501
68.56%12
20%8745
138.54%94
62.07%2
-96.61%14
-95.1%