{"id":15560930,"url":"https://github.com/brainpoint/febs","last_synced_at":"2025-06-23T11:35:07.481Z","repository":{"id":51344410,"uuid":"62530974","full_name":"brainpoint/febs","owner":"brainpoint","description":"a useful utilities set for web","archived":false,"fork":false,"pushed_at":"2021-07-15T13:01:28.000Z","size":10959,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-01T04:23:05.138Z","etag":null,"topics":["ajax","animation-frame","base64","crc32","crypt","css","dom","febs","jquery","js","md5","nodejs","string","uploader","zepto"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brainpoint.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-04T04:16:42.000Z","updated_at":"2021-07-15T13:01:31.000Z","dependencies_parsed_at":"2022-09-26T21:40:45.052Z","dependency_job_id":null,"html_url":"https://github.com/brainpoint/febs","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/brainpoint/febs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brainpoint","download_url":"https://codeload.github.com/brainpoint/febs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brainpoint%2Ffebs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261469494,"owners_count":23163108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ajax","animation-frame","base64","crc32","crypt","css","dom","febs","jquery","js","md5","nodejs","string","uploader","zepto"],"created_at":"2024-10-02T16:04:07.190Z","updated_at":"2025-06-23T11:35:02.453Z","avatar_url":"https://github.com/brainpoint.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"febs 库是一些常用的工具的合集;\n\n支持browser端与node server端;\n\n\u003e browser支持 IE9及以上浏览器.\n\n\u003e browser支持常用的jquery操作, 可以在大多数场景下替代jquery.\n\nbrowser详见 [reamde](./browser/README.md)\n\nfebs 包含browser端与server端代码.\n独立的 browser端代码在 [febs-browser](https://www.npmjs.com/package/febs-browser) 库中\n\n\n# Install\n\nUse npm to install:\n\n```js\nnpm install febs --save\n```\n\n# nodejs\n\n以下列方式使用\n\n```js\nvar febs = require('febs');\n\n//\nfebs.string.replace();\n```\n\n# browser\n\n以下列方式使用\n\n\u003e copy directory `node_modules/febs/browser/dist/febs` to client\n\n```html\n\u003cmeta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" /\u003e  \u003c!-- 如ie9等早期浏览器提示使用最新渲染器 --\u003e\n\u003clink rel=\"stylesheet\" type=\"text/css\" href=\"path/febs/febs.css\" /\u003e\n\u003cscript charset='UTF-8' type=\"text/javascript\" src=\"path/febs/febs.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\nfebs.string.replace();\n\u003c/script\u003e\n```\n\n# babel\n\n```js\nimport * as febs from 'febs';\n\n//\nfebs.string.replace();\n```\n\n# framework\n\n![](doc/framework.png)\n\nfebs web库分为客户端与服务器端;\n\n\n- 通用于客户端与服务端的库如下\n  - [date](#date)\n  - [utils](#utils)\n  - [string](#string)\n  - [crypt](#crypt)\n  - [net](#net)\n  - [dom](./browser/README.md#dom)\n\n- 客户端独有库\n  - [animationFrame](#animationFrame)\n  - [jquery模拟](./browser/README.md)\n\n- 服务端独有库\n  - [exception](#exception)\n  - [file](#file)\n  - [upload](#upload)\n\n# 说明\n\n客户端中已将旧版本中的jquery依赖的相关内容抽出到 [febs-ui](https://www.npmjs.com/package/febs-ui) 库中, `febs`将不再依赖 `jquery`. (ie9以下浏览器需要jquery/zepto).\n\n\n* 定义了如下一些全局变量\n\n| name           | description |\n|----------------|-------------|\n| __line  | 当前所在行, 可以配合 __filename 定位错误日志   |\n| __column | 当前所在列, 可以配合 __filename 定位错误日志   |\n| __debug  |  判断当前的环境process.env.NODE_ENV是否为development, 如对此值设置后, 使用设置后的值.  |\n| console.debug  | development 环境下输出日志  |\n\n\u003e 其他\n* 函数调用使用 `类名.xxx` 的方式调用, 例如: `febs.utils.browserIsMobile()` \n* 对早期的浏览器定义了`window.requestAnimationFrame`和`window.cancelAnimationFrame`方法,可进行动画帧操作.\n* 对早期的浏览器添加了`Promise`支持.\n\n# date\n\ndate库包含了一些常用的时间操作库, 如验证时间对象是否有效等.\n\n```js\n\n  /**\n  * @desc: 判断是否是有效时间.\n  */\n  febs.date.isValidate(date: Date): boolean;\n\n  /**\n   * @desc: 获取时间的string.\n   * @param localtime: ms.\n   * @param fmt: 格式化, 默认为 'HH:mm:ss'\n   *             年(y)、月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)\n   *              'yyyy-MM-dd hh:mm:ss.S' ==\u003e 2006-07-02 08:09:04.423\n   *              'yyyy-MM-dd E HH:mm:ss' ==\u003e 2009-03-10 星期二 20:09:04\n   *              'yyyy-M-d h:m:s.S'      ==\u003e 2006-7-2 8:9:4.18\n   * @param weekFmt: 星期的文字格式, 默认为 {'0':'星期天', '1': '星期一', ..., '6':'星期六'}\n   * @return: string.\n   */\n  febs.date.getTimeString(localtime: number, fmt: string, weekFmt: WeekFmt): string;\n\n  /**\n   * @desc: 获取时间的协调世界时间 string.\n   * @param localtime: ms. (本地时间)\n   * @param fmt: 格式化, 默认为 'HH:mm:ss'\n   *             年(y)、月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)\n   *              'yyyy-MM-dd hh:mm:ss.S' ==\u003e 2006-07-02 08:09:04.423\n   *              'yyyy-MM-dd E HH:mm:ss' ==\u003e 2009-03-10 星期二 20:09:04\n   *              'yyyy-M-d h:m:s.S'      ==\u003e 2006-7-2 8:9:4.18\n   * @param weekFmt: 星期的文字格式, 默认为 {'0':'星期天', '1': '星期一', ..., '6':'星期六'}\n   * @return: string.\n   */\n   febs.date.getUTCTimeString(localtime: number, fmt: string, weekFmt: WeekFmt): string;\n\n  /**\n   * @desc: 获取指定时间距离现在的时间描述.\n   *        例如, 昨天, 1小时前等.\n   * @param localtime: ms. 小于当前时间, 大于当前时间将显示为 '刚刚';\n   * @param strFmt: 需要显示的文字. \n   *                默认为 {\n   *                        now:    '刚刚',           // 3秒钟以内将显示此信息.\n   *                        second: '秒前',\n   *                        minute: '分钟前',\n   *                        hour:   '小时前',\n   *                        day_yesterday: '昨天',\n   *                        day:    '天前',\n   *                        month:  '个月前',          // 6个月内将显示此信息.\n   *                        time:   'yyyy-M-d h:m:s'  // 超过6个月将使用此格式格式化时间\n   *                       }\n   * @return: string.\n   */\n  febs.date.getTimeStringFromNow(localtime: number, strFmt: string): string;\n\n  /**\n   * @desc: getDate('2012-05-09')\n   * @return: Date.\n   */\n  febs.date.getDate(strDate: string): Date\n\n  /**\n   * @desc: 通过世界时间获取date. getDateFromUTC('2012-05-09')\n   * @param strDateUTC: 世界日期字符串. '2012-05-09' \n   * @return: Date.\n   */\n  febs.date.getDateFromUTC(strDateUTC: string): Date;\n\n  /**\n   * @desc: getDate2('20120509')\n   * @return: Date.\n   */\n  febs.date.getDate2(strDate: string): Date;\n\n\n  /**\n   * @desc: 通过世界时间获取date. getDate2FromUTC('20120509')\n   * @param strDateUTC: 世界日期字符串. '20120509' \n   * @return: Date.\n   */\n  febs.date.getDate2FromUTC(strDateUTC: string): Date;\n\n\n  /**\n   * @desc: 通过字符串获取date. getTime('2012-05-09 11:10:12')\n   * @param strTime: 时间字符串. '2012-05-09 11:10:12' \n   * @return: Date.\n   */\n  febs.date.getTime(strTime:string): Date;\n\n  /**\n   * @desc: 通过时间获取date. getTime2('20120509111012')\n   * @param strTime: 时间字符串. '20120509111012' \n   * @return: Date.\n   */\n  febs.date.getTime2(strTime:string): Date;\n\n  /**\n   * @desc: 通过世界时间获取date. getTimeFromUTC('2012-05-09 11:10:12')\n   * @param strTimeUTC: 世界时间字符串. '2012-05-09 11:10:12' \n   * @return: Date.\n   */\n  febs.date.getTimeFromUTC(strTimeUTC: string): Date;\n\n  /**\n   * @desc: 通过世界时间获取date. getTime2FromUTC('20120509111012')\n   * @param strTimeUTC: 世界日期字符串. '20120509111012' \n   * @return: Date.\n   */\n  febs.date.getTime2FromUTC(strTimeUTC: string): Date;\n```\n\n\n# utils\n\nutils库包含了一些常用的函数, 如判断浏览器是否是手机/时间字符串格式化等.\n```js\n/**\n * @desc: 模拟sleep.\n * @return: Promise.\n *     在ms时间后执行.\n * @e.g.\n *     febs.utils.sleep(1000).then(()=\u003e{\n          //1000ms之后resolve.\n       });\n */\nfebs.utils.sleep(ms)\n```\n\n```js\n/**\n * @desc: the browser is mobile.\n * @param userAgent: 在服务器调用时需传入客户端的userAgent\n */\nfebs.utils.browserIsMobile(userAgent?:string)\n/**\n * @desc: the browser is ios.\n * @param userAgent: 在服务器调用时需传入客户端的userAgent\n */\nfebs.utils.browserIsIOS(userAgent?:string)\n/**\n * @desc: the browser is phone.\n * @param userAgent: 在服务器调用时需传入客户端的userAgent\n */\nfebs.utils.browserIsPhone(userAgent?:string)\n/**\n * @desc: the browser is weixin.\n * @param userAgent: 在服务器调用时需传入客户端的userAgent\n */\nfebs.utils.browserIsWeixin(userAgent?:string)\n/**\n* @desc: [only in browser] 判断是否是ie.\n*/\nfebs.utils.browserIsIE()\n/**\n* @desc: [only in browser] 判断ie版本号.\n* @return number. 非ie返回Number.MAX_SAFE_INTEGER.\n*/\nfebs.utils.browserIEVer()\n/**\n * @desc: [only in browser] the browser is support html5.\n */\nfebs.utils.browserIsSupportHtml5()\n/**\n* @desc: 判断是否是safari.\n*/\nfebs.utils.browserIsSafari(userAgent?:string)\n/**\n* @desc: 判断是否是opera.\n*/\nfebs.utils.browserIsOpera(userAgent?:string)\n/**\n* @desc: 判断是否是firefox.\n*/\nfebs.utils.browserIsFirefox(userAgent?:string)\n/**\n* @desc: 判断是否是chrome.\n*/\nfebs.utils.browserIsChrome(userAgent?:string)\n/**\n* @desc: 判断是否是edge.\n*/\nfebs.utils.browserIsEdge(userAgent?:string)\n```\n```js\n/**\n * @desc: 合并多个map.\n * @return: {}\n */\nfebs.utils.mergeMap(...)\n```\n```js\n/**\n* @desc: 判断参数是否是null,undefined,NaN\n* @return: boolean\n*/\nfebs.utils.isNull(e)\n/**\n* @desc: 将异步回调方式的方法转换成promise, 函数中的this可以为指定值.\n*         例如: yield denodeify(fs.exists)(path);\n* @param self: 指定的调用对象\n* @return: promise.\n*/\nfebs.utils.denodeify(fn, self, argumentCount)\n/**\n* @desc: 执行cmd (仅server端可用).\n* @param cmd: 指令.\n* @param params: 输入参数数组.\n* @param cbFinish: 完成的回调.\n*/\nfebs.utils.execCommand(cmd:string, params:string[], cbFinish:(err:any)=\u003evoid);\n```\n\n```js\n// 大数运算.\n\n大数类型: febs.BigNumber\n\n/**\n * @desc: 进行bigint类型转换. 如果数值超过15位,等同于 new BigNumber(v)\n */\nfebs.utils.bigint(v: any): number|BigNumber;\n\n/**\n * @desc: 判断是否是bigint.\n */\nfebs.utils.bigint_check(v)\n\n/**\n* @desc: calc bigint\n* @return: bignumber.\n*/\nfebs.utils.bigint_add(a, b)\nfebs.utils.bigint_minus(a, b)\nfebs.utils.bigint_dividedBy(a, b)\nfebs.utils.bigint_mul(a, b)\n/**\n* @desc: compare with bigint.\n* @return: boolean.\n*/\nfebs.utils.bigint_equal(a, b)\nfebs.utils.bigint_more_than(a, b)\nfebs.utils.bigint_more_than_e(a, b)   // more than or equal.\nfebs.utils.bigint_less_than(a, b)\nfebs.utils.bigint_less_than_e(a, b)   // less than or equal.\n/**\n* @desc: 转换bigint-\u003estring.\n* @param fixed: 小数位个数, 默认为0.\n* @return: string.\n*/\nfebs.utils.bigint_toFixed(a, fixed)\n```\n\n# string\nstring 提供了一些js string对象缺少且较常使用的函数.\n```js\n/**\n* @desc: 判断是否是手机号码.\n* @return: boolean.\n*/\nfebs.string.isPhoneMobile(str)\n/**\n * @desc: 是否为空串.\n * @return: boolean.\n */\nfebs.string.isEmpty(s)\n/**\n * @desc: 获得字符串utf8编码后的字节长度.\n * @return: u32.\n */\nfebs.string.getByteSize(s)\n/**\n * @desc: 替换字符串中所有的strSrc-\u003estrDest.\n * @return: string.\n */\nfebs.string.replace(str, strSrc, strDest)\n/**\n * @desc: 将utf8字符串转为字节数组.\n * @return: [].\n */\nfebs.string.utf8ToBytes(str)\n/**\n* @desc: 将utf8字节数组转为字符串.\n*/\nfebs.string.bytesToUtf8(utfBytes:number[]):string;\n/**\n * @desc 去除两端空格.\n */\nfebs.string.trim(str: string) : string;\n\n/**\n* @desc: 对字符串中的 \u003c\u003e空格\"\u0026 标签进行转义为 \u0026 lt;, \u0026 gt;\n* @return: string.\n*/\nfebs.string.escapeHtml(str); \n```\n\n# crypt\n目前提供了uuid,crc32,base64.\n\n服务端独有.\n```js\n/**\n * @desc: 直接对文件进行计算.\n * @param filename: 文件路径\n * @return: string\n */\nfebs.crypt.md5_file(filename)\n/**\n * @desc: 直接对文件进行计算.\n * @param filename: 文件路径\n * @return: string\n */\nfebs.crypt.sha1_file(filename)\n/**\n* @return 生成一个uuid字符串. (uuid v1)\n*/\nfebs.crypt.uuid()\n/**\n * @desc: 直接对文件进行计算.\n * @param filename: 文件路径\n * @return: number\n */\nfebs.crypt.crc32_file(filename):number\n/**\n * @desc: [only in server] 直接对文件进行计算.\n * @param filename: 文件路径\n * @param length: 如果\u003c0, 将会计算到文件的末尾.\n * @return: number\n */\nfebs.crypt.crc32_fileSegment(filename: string, offset:number, length:number): number;\n/**\n * @desc: 分段计算方式.\n *  var hash = md5_begin();\n *  md5_update(hash, 'xxx');\n *  var hex = md5_finish(hash);\n */\nfebs.crypt.md5_begin():any;\nfebs.crypt.md5_update(hash:any, str: string|Buffer):void;\nfebs.crypt.md5_finish(hash:any):string;\n\n/**\n * @desc: 分段计算方式.\n *  var hash = sha1_begin();\n *  sha1_update(hash, 'xxx');\n *  var hex = sha1_finish(hash);\n */\nfebs.crypt.sha1_begin():any;\nfebs.crypt.sha1_update(hash:any, str: string|Buffer):void;\nfebs.crypt.sha1_finish(hash:any):string;\n\n\n/**\n* @desc: 使用上次的解码的数据继续进行base64解码.\n* @return: \n        {\n            c1,\n            c2,\n            c3,\n            c4,\n            data, // 字节数组\n        }.\n*/\nfebs.crypt.base64_decode(strBase64, c2 = 0, c3 = 0, c4 = 0)\n```\n\n客户端独有.\n```js\n/**\n * @desc: 通过文件表单控件进行文件的crc32计算.\n * @param fileObj: 表单文件对象, 例如表单为:\n *                  \u003cform enctype=\"multipart/form-data\"\u003e\n *                    \u003cinput id=\"file\" type=\"file\" name=\"file\" multiple\u003e\n *                  \u003c/form\u003e\n *             $('#file')[0].files[0] 即为第一个文件对象.\n * @param cb: function(crc32) {}; 计算出来的crc32通过回调函数返回\n */\nfebs.crypt.crc32_file(fileObj, cb)\n/**\n * @desc: [客户端调用] 通过文件表单控件进行文件的crc32计算.\n * @param fileObj: 表单文件对象, 例如表单为:\n *                  \u003cform enctype=\"multipart/form-data\"\u003e\n *                    \u003cinput id=\"file\" type=\"file\" name=\"file\" multiple\u003e\n *                  \u003c/form\u003e\n *             dom('#file')[0].files[0] 即为第一个文件对象.\n * @param length: 如果\u003c0, 将会计算到文件的末尾.\n * @param cb: function(crc32) {}; 计算出来的crc32通过回调函数返回\n */\nfebs.crypt.crc32_fileSegment(fileObj: any, offset:number, length:number, cb: (crc32: number) =\u003e void): void;\n/**\n* @desc: base64解码.\n* @return: 字节数组.\n*/\nfebs.crypt.base64_decode(strBase64)\n```\n\n通用.\n```js\n/**\n * @desc: 计算字符串的crc32值\n * @param crc 可以在这个值得基础上继续计算\n * @return: number.\n */\nfebs.crypt.crc32( str, crc )\n/**\n * @desc: 计算md5.\n * @return: string\n */\nfebs.crypt.md5( strOrBuffer )\n/**\n * @desc: 计算sh1.\n * @return: string\n */\nfebs.crypt.sha1( strOrBuffer )\n\n/**\n* @desc: base64编码.\n* @param arrByte: 字节数组. 或字符串.\n* @return: string.\n*/\nfebs.crypt.base64_encode(arrByte)\n```\n\n# animationFrame\n\n各浏览器兼容的 `requestAnimationFrame`, `cancelAnimationFrame` 动画方法.\n\n```js\n\nvar total = 0;\nvar timer;\nvar now = Date.now();\n\nfunction foo(tm) {\n  var now2 = Date.now();\n  total += now2-now;\n  now = now2;\n  if (total \u003e 10000) {\n    cancelAnimationFrame(timer);\n  } else {\n    timer = requestAnimationFrame(foo);\n  }\n}\n\ntimer = requestAnimationFrame(foo);\n\n```\n\n# net\nnet封装了浏览器通信方法: fetch, jsonp\n```js\n/**\n * @desc: 使用fetch方式进行数据请求.\n *        如果超時, 可以catch到 'timeout'\n * @param option: 请求选项.\n *          {\n              method, // 请求方法 get, post, delete 等.\n              mode,   // 'no-cors', 'same-origin'等; (可忽略)\n              headers, // 请求header, 例如:\n                            {\n                              \"Content-Type\": \"application/json\",\n                              \"Accept\": 'application/json',\n                            }\n              body,    // 请求内容.\n              timeout, // 超时 (ms), 默认为5000,\n              credentials,  // 携带了credentials='include'则服务器需设置Access-Control-Allow-Credentials\n            }\n * @return: 返回 Promise;\n * @e.g.\n      febs.net.fetch(url, {})\n      .then(response=\u003eresponse.json())\n      .then(data=\u003e{})\n      .catch(err=\u003e{\n        if (err === 'timeout)  // 超时.\n      });\n */\nfebs.net.fetch(url, option)\n/**\n * @desc: [only in browser] jsonp方式获取数据.\n *        如果超時, 可以catch到 'timeout'\n * @param option: 请求选项同fetch. 可以附带如下的更多属性. jsonp只能使用`get`方式.\n *          {\n              jsonpCallback, // jsonp请求时附带到地址中的callback参数, 默认为 'callback';\n                             // 服务端需将查询字符串中的此参数作为返回数据中 `callback`([data])的 callback值\n            }\n * @return: 返回 Promise;\n * @e.g.\n      febs.net.jsonp(url, {})\n      .then(response=\u003eresponse.json())\n      .then(data=\u003e{})\n      .catch(err=\u003e{\n        if (err === 'timeout)  // 超时.\n      });\n */\nfebs.net.jsonp(url, option)\n```\n\n\n# exception\n定义了服务端常用的错误类型.\n\n    febs.code = code;\n    febs.msg = msg;\n    febs.filename = filename;\n    febs.line = line;\n```js\n// @desc: 一般错误.\nfebs.exception.ERROR\n// @desc: 参数错误.\nfebs.exception.PARAM\n// @desc: 越界\nfebs.exception.OUT_OF_RANGE\n```\n异常类如下\n```js\n/**\n* @desc: 构造异常对象.\n* @param msg: 异常消息\n* @param code: 异常代码\n* @param filename: 异常文件名\n* @param line: 异常文件所在行\n* @return: \n*/\nfebs.exception(msg, code, filename, line)\n```\n\n# file\n```js\n/**\n * @desc: 判断文件夹是否存在.\n * @return: boolean.\n */\nfebs.file.dirIsExist(dir)\n/**\n * @desc: 保证文件夹存在.\n * @return: bool. 若不存在新建; 文件夹存在返回true.\n */\nfebs.file.dirAssure(dir)\n/**\n * @desc: 复制文件夹.\n * @param callback: (err) =\u003e {}, 执行此函数时表示复制完成.\n * @return: bool.\n */\nfebs.file.dirCopy(src, dest, callback)\n/**\n * @desc: [only in server]  复制文件夹 返回promise.\n * @return: Promise(()=\u003e{}).\n */\nfebs.file.dirCopyAsync(src: string, dest: string): Promise\u003c()=\u003e{}\u003e;\n/**\n* @desc: copy dir exclude specify path.\n* @param excludePath: regex.\n* @return: Promise(()=\u003e{})\n*/\nfebs.file.dirCopyExcludeAsync(src: string, dest: string, excludePath:RegExp = null): Promise\u003c()=\u003e{}\u003e;\n/**\n * @desc: 删除文件夹.\n * @return:bool.指明是否删除.\n */\nfebs.file.dirRemoveRecursive(dir)\n/**\n* @desc: 获取当前目录下的子文件与子目录.\n* @param dir: 要搜索的目录路径.\n* @param pattern: 子文件或子目录名称,匹配的正则表达式\n*                 仅从名称的第一个字符开始匹配, 例如: / a.* /, 匹配 a开头的文件名.\n* @return: {files:[], dirs:[]}; 发生错误返回null.\n*/\nfebs.file.dirExplorer(dir)\n/**\n* @desc: 递归获取当前目录下的所有子文件.\n* @param dir: 要搜索的目录路径.\n* @param pattern: 子文件或子目录名称,匹配的正则表达式\n*                 仅从名称的第一个字符开始匹配, 例如: / a.* /, 匹配 a开头的文件名.\n* @return: Array; 发生错误返回null.\n*/\nfebs.file.dirExplorerFilesRecursive(dir, pattern)\n/**\n* @desc: 递归获取当前目录下的所有子目录.\n* @param dir: 要搜索的目录路径.\n* @param pattern: 子文件或子目录名称,匹配的正则表达式\n*                 仅从名称的第一个字符开始匹配, 例如: / a.* /, 匹配 a开头的文件名.\n* @return: Array; 发生错误返回null.\n*/\nfebs.file.dirExplorerDirsRecursive(dir, pattern)\n/**\n * @desc: 获得文件的字节大小.\n * @return: number.-1表示错误.\n */\nfebs.file.fileSize(file)\n/**\n * @desc: 判断文件是否存在.\n * @return: boolean.\n */\nfebs.file.fileIsExist(file)\n/**\n * @desc: 复制文件.\n * @param callback: (err) =\u003e {}, 执行此函数时表示复制完成.\n * @return: bool.\n */\nfebs.file.fileCopy(src, dest, callback)\n/**\n * @desc: [only in server]  复制文件 返回promise.\n * @return: Promise(()=\u003e{}).\n */\nfebs.file.fileCopyAsync(src: string, dest: string): Promise\u003c()=\u003e{}\u003e;\n/**\n * @desc: 移除文件.\n * @return: bool.指明是否删除.\n */\nfebs.file.fileRemove(file)\n/**\n * @desc: [only in server]  移除文件 返回promise.\n * @return: Promise(()=\u003e{}).\n */\nfebs.file.fileRemoveAsync(file: string): Promise\u003c()=\u003e{}\u003e;\n```\n\n\n# upload\n\n## multipart/form-data方式上传.\n\n```js\n/**\n * 接收上传文件内容. 接收客户端  multipart/form-data方式上传的数据.\n * @param conditionCB: async function(data, filesize, filename, filemimeType):string.\n *                      - data: 用户上传的数据.\n *                      - filesize: 将要存储的文件大小.\n *                      - filename: 上传的文件名.\n *                      - filemimeType: 文件类型, 例如: 'image/jpeg'.\n *                      - return: 存储的文件路径, 返回null表示不存储.\n * @param checkCrc32: 是否检测crc32值, 如果为true则, 请求时需附带crc32参数.\n * @param append: 是否追加存储.\n * @return Promise.\n * @resolve\n *     - bool. 指明是否存储成功.\n */\nfebs.upload.accept(ctx, conditionCB, checkCrc32=true, append=false)\n```\n\n## base64数据流分段方式上传.\n\n```js\n/**\n * 准备接收上传文件.\n * @param conditionCB: async function(data, filesize):string.\n *                      - filesize: 将要存储的文件大小(base64大小)\n *                      - data: 用户上传的数据.\n *                      - return: 本地存储的文件路径, 返回null表示不存储. 存储的文件必须不存在.\n * @param sessionSet:  function(data){} 用于设置存储在session中的临时文件信息;\n * @return Promise.\n * @resolve\n *     - bool. 指明是否开始接收文件流.\n */\nfebs.upload.base64_acceptHeader(ctx, conditionCB, sessionSet)\n```\n```js\n/**\n * 上传文件内容.\n *  发生错误会自动调用 cleanup\n * @param finishCB: async function(filename):object.\n *                      - filename: 本地存储的文件名.\n *                      - return: 返回给客户端的数据. 不能包含err数据.\n *\n * @param sessionGet:  function() {} 用于获取存储在session中的临时文件信息;\n * @param sessionSet:  function(data){} 用于设置存储在session中的临时文件信息;\n * @param sessionClear: function() {} 用于清除存储在session中的临时信息\n * @return Promise\n * @resolve\n */\nfebs.upload.base64_accept(ctx, finishCB, sessionGet, sessionSet, sessionClear)\n```\n```js\n/**\n* @desc: 在用户登出或其他中断传输中清除上传的数据.\n* @param sessionGet:  function() {} 用于获取存储在session中的临时文件信息;\n* @param sessionClear: function() {} 用于清除存储在session中的临时信息\n* @return: \n*/\nfebs.upload.base64_cleanup(sessionGet, sessionClear, cleanFile = true)\n```\n\n\n## multipart/form-data方式实例\n\n```js\n/**\n * Desc:\n *      upload控件使用一个接口来上传文件, 使用multpart/form-data方式传输:\n *          1. uploadUrl: 上传文件.\n * Example:\n *      前台引入:\n *          1. 在需要upload的页面上引入 control_upload.hbs页面; 或者使用如下语句:\n *                \u003cform method=\"post\" role=\"form\" enctype=\"multipart/form-data\" id=\"fileForm\"\u003e\n *                  \u003cinput type=\"file\" class=\"form-control\" name=\"file\" onchange=\"febs.controls.upload(cfg)\" multiple\u003e\n *                \u003c/form\u003e\n *      后台:\n *          1. 在uploadUrl中调用  await require('febs').upload.accept(ctx, conditionCB); 当满足条件时将存储, 并返回true表示成功.\n */\n```\n\n 客户端使用multipart/form-data方式上传文件时, 需使用url参数上传如下参数:\n\n| name           | description |\n|----------------|-------------|\n| crc32  | 文件内容的crc32计算值   |\n| size  |  文件字节大小  |\n| data  | (可选) 自定义数据; 自定义数据会在字节流上传完成后, 通过回调传递.  |\n\n\u003e 例如: 上传url为 `/upload?crc32=2134141\u0026size=11231`\n\n也可以在浏览器端直接使用 `febs-ui` 中的上传方法.\n\n服务端调用如下接口接收文件.\n\n```js\nexports.upload = async function(ctx, next)\n{\n  var r = await require('febs').upload.accept(ctx, async function(data, filesize, filename, filemimeType){\n    console.log(filesize);\n    console.log(filename);\n    console.log(filemimeType);\n\n    return 'tempPath/temp.filename';  // 返回空, 则表明不存在文件.\n  });\n};\n```\n\n前台:\n```js\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/jquery/jquery.min.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/jquery/jquery.form.min.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/febs/febs.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript type=\"text/javascript\"\u003e\nfunction upload() {\n  febs.ui.upload({  // 引入febs-ui库.\n    formObj:  $('#fileForm'),\n    fileObj:  $(\"#filec\"),\n    uploadUrl:  '/uploadFile',\n    finishCB: function(err, fileObj, serverData){\n      console.log(serverData);\n    },\n    progressCB: function(fileObj, percent){\n      console.log(percent);\n    })\n  });\n\n}\n\u003c/script\u003e\n\n\u003cform method=\"post\" role=\"form\" enctype=\"multipart/form-data\" id=\"fileForm\"\u003e\n  \u003cinput id=\"filec\" type=\"file\" name=\"file\" onchange=\"javascript:upload()\" multiple\u003e\n\u003c/form\u003e\n```\n\n## base64方式上传.\n\nbase64方式上传, 浏览器端将数据编码为base64后, 分段上传给服务端; 服务端对数据进行分段解码后存储至文件中.\n\n\n服务端调用如下接口接收文件.\n\n```js\n// 处理上传请求.\nexports.uploadByBase64Header = async function (ctx) {\n    await febs.upload.base64_acceptHeader(ctx, \n      async function(data, filesize){\n          return \"/tmp/filename.jpg\";\n      }, function(data){ // set upload sessoin info.\n          ctx.session.uploadSegInfo = data;\n      });\n}\n\n// 处理上传片段.\nexports.uploadByBase64 = async function (ctx) {\n    await febs.upload.base64_accept(ctx, \n      async function(filename){\n          let img = sharp(filename);\n          let info = await img.metadata();\n          return febs.utils.mergeMap(errCode.OK, { width: info.width, height: info.height });\n      }, function(){  // get upload session info.\n          return ctx.session.uploadSegInfo;\n      }, function(data){ // set upload sessoin info.\n          ctx.session.uploadSegInfo = data;\n      }, function() {  // clear upload session info.\n          ctx.session.uploadSegInfo = undefined;\n      });\n}\n```\n\n前台:\n```js\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/jquery/jquery.min.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" charset=\"utf-8\" src=\"/febs/febs.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript type=\"text/javascript\"\u003e\n  febs.ui.uploadBase64({    // 引入febs-ui库.\n      data: {msg :'这是一个用户数据'},\n      fileBase64Str: base64Imagestr,\n      headerUrl: '/api/mgr/uploadimgByBase64Header',\n      uploadUrl: '/api/mgr/uploadimgByBase64',\n      finishCB: function(err, serverData) {\n        if (err) {\n          console.log('err: ');\n          console.log(err);\n          console.log(serverData);\n        }\n        else {\n          console.log('finish: ');\n          console.log(serverData);\n        }\n      },\n      progressCB: function(percent) {\n        console.log(Math.ceil(percent*100)+'%');\n      }\n    });\n\u003c/script\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrainpoint%2Ffebs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrainpoint%2Ffebs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrainpoint%2Ffebs/lists"}