接口参数类型认证 source:接口文档数据 qs:请求的参数
8340
function CheckParams(data, query)
{
    for (let key in data) {
        let par = data[key];
        if(par.constructor!=Object)continue;//非
        let errkey = par.lbl?par.lbl:(par.rem?par.rem:key);//发生错误时的key的称呼方式
        if(par.constructor != Object){return `${errkey}接口文档定义错误。`}
        if (null==par.rem && null==par.lbl) {//这里则认为是两层及以上对象嵌套,递归
            if(par.need && null==query[key]){query[key]={};delete par.need;delete par.rem;delete par.lbl;}//如果需要的传外层的话,且为空时,默认给空对象
            let msg =CheckParams(data[key],query[key]);
            if(msg){return msg;}
        }else {
            //参数是否缺少
            if(!query){return 0;}
            let val = query[key];
            //检验必要的请求参数,非必要参数则不验证
            if (par.need&&null==val) {return`缺少${par.lbl?par.lbl:(par.rem?par.rem:key)}参数。`;}
            //若未传,且有默认值,则设置默认值,然后继续向下检验默认值
            if(null!=par.default&&null==val){query[key]=par.default;val = par.default;CTX.usedefault = true;}
            if(null!=par.def&&null==val){query[key]=par.def;val = par.def;CTX.usedefault = true;}
            if(null==val){continue;}//未传的非必须参数不需要校验
            //参数类型
            if(par.type) {
                let isObj=true;
                try{
                    switch(par.type.toLowerCase()){
                        case 'number':
                        case 'int':
                            if((par.type == 'number'||par.type =='int')&& parseInt(val)!=val)throw Error('类型错误');
                            query[key] = parseInt(val);
                            val = query[key];
                            break;
                        case 'float':
                            if(par.type == 'float' && parseFloat(val)!=val)throw Error('类型错误');
                            query[key] = parseFloat(val);
                            val = query[key];
                            break;
                        case 'string':if(val.constructor.name != 'String')throw Error('类型错误');break;
                        case 'boolean':
                            if(par.type == 'boolean'&&val.constructor!=Boolean&&(val.trim()!="false"&&val.trim()!="true"))throw Error('类型错误');
                            if(val.constructor!=Boolean)query[key]=(val.trim()==="false"?false:true);
                            val = query[key];
                            break;
                        case 'object':
                            if(val.constructor != Object){
                                try{
                                    val=JSON.parse(val);
                                }catch(err){isObj=false;}
                            }
                            if(!isObj)throw Error('类型错误');break;
                        case 'array':
                            if(val.constructor != Array){
                                try{
                                    val=JSON.parse(val);
                                }catch(err){isObj=false}
                            }
                            if(!isObj)throw Error('类型错误');break;
                        case 'array':if(val.constructor.name != 'Array')throw Error('类型错误');break;
                        case 'file':if(val.path && !isExist(val.path)) throw Error('类型错误');break;
                        case 'json':
                            try{
                                let t=JSON.parse(val);
                                query[key]=t;
                                val=t;
                            }catch(err){
                                throw Error('json格式错误');
                            }
                            break;
                        default :
                            if(val.constructor.name != 'String')throw Error('类型错误');
                    }
                }catch(err){return `${errkey}参数类型错误。`;}
            }
            let msg;
            //参数长度控制
            if(par.len){
                //接口文档在定义的时候定义为一个对象
                var ol = 0;
                let name = "长度";
                switch (par.type.toLowerCase()){
                    case 'array':
                        ol =  val.length;
                        name = "数组长度";
                        break;
                    case 'object'://数组或者对象
                        ol =  Object.keys(val).length;
                        name = "对象长度";
                        break;
                    case 'string':
                        ol = val.length;
                        name = "字符串长度";
                        break;
                    case 'file':
                        ol = val.size;//文件大小
                        name = "文件大小";
                        break;
                    default:
                        ol = val.length;
                        name = "字符串长度";
                        break;
                }
                if((msg=getRange(ol,par.len))){
                    return `${errkey}${name}${msg}${'file'==par.type?'字节':''}`;
                }
            }
            //范围控制
            if(par.range && (msg=getRange(val,par.range))){return `${errkey}${'string'==par.type?"字符内容":""}${msg}`;}
            //枚举型判断参数是否在设置范围内
            if (par.enum && par.enum.indexOf(val)<0) {return `${errkey}参数只能是${par.enum}。`;}
            //正则验证参数是否合法
            if(par.reg && !eval(par.reg).test((par.type == 'file' ? val.name:par.type=='json'?JSON.stringify(val):val))){return `${errkey}格式错误`;}
            // RES.usedefault = null;
        }
    }
    return 0;
}
145786
function getReqOptions(options) {
    var reqConf = options.reqConfig;
    var pp = _processPathsAndPackages(reqConf.paths, reqConf.packages, options);

    var options = {
        appDir: options.appDir,
        baseUrl: options.baseUrl,
        dir: options.dir,
        //    modules: _.map(options.entryPack, _entryToReqMod),
        modules: options.entryPack,
        paths: pp.paths,
        shim: reqConf.shim || {},
        packages: reqConf.packages || [],
        optimize: "none",
        onBuildRead: function (moduleName, path, contents) {
            if (moduleName.indexOf('require-conf') > -1) {
                // 将调试状态改成发布状态
                return contents.replace(/debug\s*\:\s*(true|false)/g, 'debug: false, optimized: true');
            }
            return contents;
        },
        preserveLicenseComments: false,
        removeCombined: options.removeCombined,
        fileExclusionRegExp: /^\./,
        writeBuildTxt: options.writeBuildTxt || false
    };

    return options;
}
395946
def parse(self, response):
        
        # 工作&输出路径
        self.template_dir = self.settings.get('TEMPLATE_DIR')
        shutil.rmtree(
            self.settings.get('BUILD_SOURCE_DIR'), ignore_errors=True)
        self.build_source_dir = utils.mkdirp(
            self.settings.get('BUILD_SOURCE_DIR'))

        # 获取Post模板对象
        template_post_path = os.path.join(self.template_dir, 'post.html')
        with open(template_post_path, 'r') as f:
            self.template_post = Template(f.read())

        self._logger.info('构建处理路径 => {0}'.format(self.build_source_dir))

        image_filter = self.options.get('image_filter', '')
        common_image_filter = self.options.get('common_image_filter', [])
        for sections in self.data.values():
            for p in sections:
                item = MoearPackageMobiItem()
                pmeta = p.get('meta', {})
                item['url'] = p.get('origin_url', '')
                item['title'] = p.get('title', '')
                item['cover_image'] = pmeta.get('moear.cover_image_slug')
                item['content'] = p.get('content', '')

                # 为图片持久化pipeline执行做数据准备
                item['image_urls'] = [item['cover_image']] \
                    if item['cover_image'] is not None else []
                item['image_urls'] += \
                    self._populated_image_urls_with_content(item['content'])
                self._logger.debug(
                    '待处理的图片url(过滤前): {}'.format(item['image_urls']))
                item['image_urls'], item['image_urls_removed'] = \
                    self.filter_images_urls(
                        item['image_urls'], image_filter, common_image_filter)
                self._logger.debug(
                    '待处理的图片url: {}'.format(item['image_urls']))

                yield item
622315
private function createSearchData()
    {
        $search_data = [];
        $files = $this->files;
        // 单页文件不解析
        foreach ($files as $key => $file) {
            if (in_array($file['page_uuid'], $this->single_pages)) {
                unset($files[$key]);
                continue;
            }
            $full_content = $this->fileSys->getContent($file['file_path'])['content'];
            // $desc_content = mb_substr($full_content, 0, 1000, 'utf-8');
            // $file['description'] = $this->markd2html->makeHtml( $desc_content );
            $search_data[] = [
                'title' => $file['title'],
                'href' => $file['href'],
                'date' => $file['date'],
                'tags' => implode(',', $file['tags']),
                'type' => implode(',', $file['type']),
                // 'desc' => $file['description'],
            ];
        }
        $file_path = $this->public_dir . DIRECTORY_SEPARATOR . 'articles/data.json';
        $html = json_encode($search_data, JSON_UNESCAPED_UNICODE);
        $this->fileSys->create($file_path, $html);
    }
837107
function getCurrentPath(){

  try{

    // FF, Chrome, Modern browsers
    // use their API to get the path of current script

    // a.b();
    // console.log('wpStage1');

    return document.currentScript.src;

    if(DOC.currentScript){ // FF 4+
      return DOC.currentScript.src;
    }

  }catch(e){

    // document.currentScript doesn't supports

    // console.log('wpStage2');

    // Method 1
    // https://github.com/mozilla/pdf.js/blob/e081a708c36cb2aacff7889048863723fcf23671/src/shared/compatibility.js#L97
    // IE, Chrome < 29

    let scripts = document.getElementsByTagName('script');
    return scripts[scripts.length - 1].src;

/*
    // Method 2
    // parse the error stack trace maually
    // https://github.com/workhorsy/uncompress.js/blob/master/js/uncompress.js#L25

    let stack = e.stack;
    let line = null;

    // Chrome and IE
    if (stack.indexOf('@') !== -1) {
      line = stack.split('@')[1].split('\n')[0];
    // Firefox
    } else {
      line = stack.split('(')[1].split(')')[0];
    }
    line = line.substring(0, line.lastIndexOf('/')) + '/';
    return line;
*/
/*
    // Method 3
    // https://www.cnblogs.com/rubylouvre/archive/2013/01/23/2872618.html

    let stack = e.stack;
    if(!stack && window.opera){
      // Opera 9没有e.stack,但有e.Backtrace,但不能直接取得,需要对e对象转字符串进行抽取
      stack = (String(e).match(/of linked script \S+/g) || []).join(' ');
    }
    if(stack){
      // e.stack最后一行在所有支持的浏览器大致如下:
      // chrome23:
      // @ http://113.93.50.63/data.js:4:1
      // firefox17:
      // @http://113.93.50.63/query.js:4
      // opera12:
      // @http://113.93.50.63/data.js:4
      // IE10:
      // @ Global code (http://113.93.50.63/data.js:4:1)
      stack = stack.split(/[@ ]/g).pop(); // 取得最后一行,最后一个空格或@之后的部分
      stack = stack[0] == '(' ? stack.slice(1,-1) : stack;
      return stack.replace(/(:\d+)?:\d+$/i, ''); // 去掉行号与或许存在的出错字符起始位置
    }
    let nodes = head.getElementsByTagName('script'); // 只在head标签中寻找
    for(var i = 0, node; node = nodes[i++];){
      if(node.readyState === 'interactive'){
        return node.className = node.src;
      }
    }
*/
  }

}
1293941
function getPath(tpl, config) {
    const defaultExt = config.extension;
    const tplAbsPath = path.resolve(config.root, tpl);

    if (TPL_MATCH[tplAbsPath]) return TPL_MATCH[tplAbsPath];

    const tplExt = path.extname(tpl);

    // 如果有后缀名，且等于默认后缀名，则直接返回
    if (tplExt && tplExt === `.${defaultExt}`) {
      return TPL_MATCH[tplAbsPath] = tplAbsPath;
    }

    try {
      let stats = fs.statSync(tplAbsPath);
      // 如果当前是一个文件目录，则返回： 文件目录 + index.html
      if (stats.isDirectory()) {
        return TPL_MATCH[tplAbsPath] = path.resolve(tplAbsPath, `index.${defaultExt}`)
      }

      // 否则是一个文件路径，直接返回 tplAbsPath
      return TPL_MATCH[tplAbsPath] = tplAbsPath

    } catch (err) {
      // 进入报错，则说明文件找不到，直接返回自动添加文件名的情况
      return TPL_MATCH[tplAbsPath] = `${tplAbsPath}.${defaultExt}`
    }

  }
689669
private Object[] paramTypesToObj(Class<?>[] paramTypes) throws Exception{
		if(ArrayUtil.isEmpty(paramTypes)){
			return new Object[]{};
		}
		
		//由于需要复杂的类型判断，因此无参方式的Action方法性能更好
		Object[] params = new Object[paramTypes.length];
		Class<?> paramType;
		Param paramAnnotation;
		String paramName;
		for(int i = 0; i < paramTypes.length; i++){
			paramType = paramTypes[i];
			paramAnnotation = paramType.getAnnotation(Param.class);
			if(null != paramAnnotation){
				//Annotation 参数注入
				paramName = paramAnnotation.value();
				if(StrUtil.isNotBlank(paramName)){
					if(CharSequence.class.isAssignableFrom(paramType)){
						//字符串
						params[i] = Request.getParam(paramName);
					}else if(Number.class.isAssignableFrom(paramType)){
						//数字
						params[i] = Request.getNumberParam(paramName, null);
					}else if(UploadFile.class.isAssignableFrom(paramType)){
						//上传文件
						params[i] = Request.getFileParam(paramName);
					}else if(Date.class.isAssignableFrom(paramType)){
						//日期
						params[i] = Request.getDateParam(paramName, null);
					}
				}
			}else{
				//类型注入
				if(Dict.class.isAssignableFrom(paramType)){
					//Dict对象参数
					params[i] = Request.fill((Dict)paramType.newInstance());
				}else if(ServletRequest.class.isAssignableFrom(paramType)){
					//ServletRequest
					params[i] = Request.getServletRequest();
				}else if(MultipartFormData.class.isAssignableFrom(paramType)){
					//MultipartFormData
					params[i] = Request.getMultipart();
				}else if(JSON.class.isAssignableFrom(paramType)){
					//JSON
					params[i] = Request.getJSONBody();
				}else if(ServletResponse.class.isAssignableFrom(paramType)){
					//ServletResponse
					params[i] = Response.getServletResponse();
				}else if(OutputStream.class.isAssignableFrom(paramType)){
					//OutputStream
					params[i] = Response.getOutputStream();
				}else if(Writer.class.isAssignableFrom(paramType)){
					//Writer
					params[i] = Response.getWriter();
				}else if(BeanUtil.isBean(paramType)){
					//JavaBean对象参数
					params[i] = Request.getBean(paramType);
				}
			}
		}
		return params;
	}
153755
function tryNoExtLookUp(info, file, opts) {
  // 支持没有指定后缀的 require 查找。
  return findResource(info.rest, file ? file.dirname : fis.project.getProjectPath(), opts.extList);
}
1096358
function inlineFileRegHandle(regFiles, buildInfo, options, reqModuleJS, file) {        
        var content = '';
        if(regFiles && regFiles.length) {
            var destMP = {'.js':options.jsDestPath,'.css':options.cssDestPath};
            for(var j=0;j<regFiles.length;j++) {
                var jp = regFiles[j].trim().replace(/(^['"]*)|(['"]*$)/g, '');               
                if(!jp) continue;
                //去除?之后面路径
                if(jp.indexOf('?') > -1) jp = jp.substr(0, jp.indexOf('?'));

                if(jp[0] == '/') {
                    //相对于当前根路径
                    var filepath = path.join(options.destPath, jp);
                }
                //相对于js构建目标目录
                else if(jp[0] != '.') { 
                    var ext = path.extname(jp).toLowerCase();
                    var dest = destMP[ext] || options.destPath;
                    var filepath = path.join(dest, jp);
                    
                    //如果不存在，则相对于当前html发布路径
                    if(!fs.existsSync(filepath)) {                        
                        filepath = path.join(options.dest, jp); 
                    }//如果不存在，则相对于当前根发布路径
                    if(!fs.existsSync(filepath) && options.destPath) {                        
                        filepath = path.join(options.destPath, jp); 
                    }                              
                    //如果文件还是不存在，则相对于项目发布路径
                    if(!fs.existsSync(filepath)) {
                        console.log(filepath + ' not exists, check dest path!');
                        //相对于当前html文件                  
                        filepath = path.join(path.dirname(file.path), jp); 
                    }
                }
                else {
                    //相对于当前html路径
                    var filepath = path.join(options.dest, jp);
                }
                //读取内联的文件内容
                content += readInlineContent(filepath, buildInfo, reqModuleJS, options) + '\n';
            }
        }
        return content;
    }
1139536
function ( err ) {
    // 报错文件名
    var fileName = err.fileName;
    // 报错类型
    var name = err.name;
    // 报错信息
    var message = err.message;
    // 出错代码位置
    var loc = err.loc;

    var logInfo = '报错文件：' + fileName + '报错类型：' + name + '出错代码位置：' + loc.line + ',' + loc.column;

    util.log( logInfo );

    this.end();
}
17649
function build(previousFileSizes) {
    let packText = userDevConfig ? '启动测试环境打包编译...' : '启动生产环境打包压缩...';
    let startTime = Date.now();
    let timer;
    let logProgress = function(stop) {
        var text = packText + '已耗时：' + ((Date.now() - startTime) / 1000).toFixed(3) + 's';

        if (stop) {
            clearTimeout(timer);
            spinner.succeed(chalk.green(text));
        } else {
            spinner.text = chalk.cyan(text);

            timer = setTimeout(logProgress, 100);
        }
    };

    clearConsole();
    logProgress();

    let compiler = webpack(config);

    return new Promise((resolve, reject) => {
        compiler.run((err, stats) => {
            let messages;

            logProgress(true); // 停止
            console.log();

            if (err) {
                if (!err.message) {
                    return reject(err);
                }

                messages = formatWebpackMessages({
                    errors: [err.message],
                    warnings: []
                });
            } else {
                messages = formatWebpackMessages(stats.toJson({ all: false, warnings: true, errors: true }));
            }

            if (messages.errors.length) {
                if (messages.errors.length > 1) {
                    messages.errors.length = 1;
                }

                return reject(new Error(messages.errors.join('\n\n')));
            }

            const resolveArgs = {
                stats,
                previousFileSizes,
                warnings: messages.warnings
            };

            return resolve(resolveArgs);
        });
    });
}
1074728
function () {
        var fileList = [];
        /*获取原文件列表*/
        Object.keys(src).forEach(function(key){
            fileList.push(src[key]);
        });
        return fileList;
    }
1143487
function replaceCSSUrl(content, options, buildInfo, filepath) {
        var reg = /url\s*\(\s*['"]?([^\)]+?)['"]?\s*\)/ig;
        return content.replace(reg, function (s, p, i) {
            //对base64的图片直接返回，无需处理
            if (p.indexOf('data:image') > -1) return s;
            var tmp = p;
            //去除?之后面路径
            if(p.indexOf('?') > -1) tmp = p.substr(0, p.indexOf('?'));

            var fpath = path.normalize(path.join(options.dest, tmp));
            var spath = path.join(options.base, tmp);
            var info = buildInfo[fpath] || buildInfo[spath];   
            //相对于根发布路径
            if(!info && options.destPath) info = buildInfo[path.join(options.destPath, tmp)];

            //如果上面的都不可以，则有可能是相对路径，
            if(!info && filepath) {
                fpath = path.normalize(path.join(path.dirname(filepath), tmp));
                info = buildInfo[fpath];
            }
                
            //如果有md5则，合到路径中
            if(info && info.path) {
                tmp = path.dirname(tmp) + '/' + path.basename(info.path);
                //如果后续还有?部门，也截取到tmp中
                if(p.indexOf('?') > -1) {
                    tmp += p.substr(p.indexOf('?'));
                }
            }

            //如果有md5码，且路径中需要替换md5,则替换。
            if(info && info.md5 && tmp.indexOf(info.md5) === -1) {
                if(tmp.indexOf('{md5}') > -1) {
                    tmp = tmp.replace('{md5}', info.md5);
                }
                else {
                    //默认把md5加到url后面
                    if(tmp.indexOf('?') > -1) {
                        tmp += '&' + info.md5;
                    }
                    else {
                        tmp += '?' + info.md5;
                    }
                }
            }
            

            //替换映射部分
            tmp = replaceUrlMap(tmp, options.urlMaps);    
            s = s.replace(p, tmp);

            //gutil.log(gutil.colors.blue('css url:'), gutil.colors.green(s));
            return s;
        });
    }
942303
function () {

        var htmlFile = this.htmlFile;
        var htmlParser = this.htmlParser;
        var options = this.options;
        var resources = [];

        // 获取外链样式资源
        var cssFiles =  htmlParser.getCssFiles();

        // 获取 style 标签内容资源
        var cssContents =  htmlParser.getCssContents();


        cssFiles.forEach(function (cssFile, index) {

            if (!cssFile) {
                return;
            }

            var line = index + 1;
            var from = 'link:nth-of-type(' + line + ')';

            resources.push(
                new Resource(
                    cssFile,
                    null,
                    utils.options(options, {
                        cache: true,
                        from: from
                    })
                )
            );

        });


        cssContents.forEach(function (content, index) {

            if (!content) {
                return;
            }

            var line = index + 1;
            var from = 'style:nth-of-type(' + line + ')';
            var cssFile = htmlFile + '#' + from;
            resources.push(
                new Resource(
                    cssFile,
                    content,
                    utils.options(options, {
                        cache: false,
                        from: from
                    })
                )
            );
        });



        return Promise.all(resources.map(function (resource) {
            return new CssParser(resource);
        }))

        // 对二维数组扁平化处理
        .then(utils.reduce);
    }
1213488
def hot_questions(self):
        
        from .question import Question
        hot_questions_url = Topic_Hot_Questions_Url.format(self.id)
        params = {'start': 0, '_xsrf': self.xsrf}
        res = self._session.get(hot_questions_url)
        soup = BeautifulSoup(res.content)
        while True:
            questions_duplicate = soup.find_all('a', class_='question_link')
            # 如果话题下无问题，则直接返回
            if len(questions_duplicate) == 0:
                return
                # 去除重复的问题
            questions = list(set(questions_duplicate))
            questions.sort(key=self._get_score, reverse=True)
            last_score = soup.find_all(
                'div', class_='feed-item')[-1]['data-score']
            for q in questions:
                question_url = Zhihu_URL + q['href']
                question_title = q.text.strip()
                question = Question(question_url, question_title,
                                    session=self._session)
                yield question
            params['offset'] = last_score
            res = self._session.post(hot_questions_url, data=params)
            gotten_feed_num = res.json()['msg'][0]
            # 如果得到问题数量为0则返回
            if gotten_feed_num == 0:
                return
            soup = BeautifulSoup(res.json()['msg'][1])
252026
function(url, params, onsuccess, onfail) {
    // url中包含 get 参数和 params 合并
    if (_typeof(params) == 'object') params = _params_2_url(params);
    else params = '';

    if (params) url = url + '?' + params;
    return request('GET', url, '', onsuccess, onfail);
  }
951460
def _get(self, q, params=''):
        ''''''
        if (q[-1] == '/'): q = q[:-1]
        headers = {'Content-Type': 'application/json'}
        r = requests.get('{url}{q}?api_key={key}{params}'.format(url=self.url, q=q, key=self.api_key, params=params),
                        headers=headers)
        ret = DotDict(r.json())
        if (not r.ok or ('error' in ret and ret.error == True)):
            raise Exception(r.url, r.reason, r.status_code, r.json())
        return DotDict(r.json())