├── .eslintrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── package.json
└── test
└── index.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "think"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | coverage.lcov
40 |
41 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | coverage/
3 | demo/
4 | test/
5 | src/
6 | ISSUE_TEMPLATE.md
7 | appveyor.yml
8 | README_zh-CN.md
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '6'
4 | sudo: false
5 | script:
6 | - "npm test"
7 | after_success:
8 | - 'npm install coveralls && ./node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls'
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 ThinkJS
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # think-helper
2 | [](https://travis-ci.org/thinkjs/think-helper)
3 | [](https://coveralls.io/github/thinkjs/think-helper)
4 | [](https://www.npmjs.com/package/think-helper)
5 |
6 | `think-helper` defines a set of helper functions for ThinkJS.
7 |
8 | ## Installation
9 |
10 | Using npm:
11 |
12 | ```sh
13 | npm install think-helper
14 | ```
15 |
16 | In Node.js:
17 |
18 | ```js
19 | import helper from 'think-helper';
20 |
21 | let md5 = helper.md5('');
22 |
23 | ```
24 |
25 | APIs:
26 |
27 | API | Param | Description
28 | ---|---|---
29 | `isInt` | | check integer
30 | `isIP` | | check IP
31 | `isIPv4` | | check IPv4
32 | `isIPv6` | | check IPv6
33 | `isMaster` | |cluster.isMaster
34 | `isArray` | `arg`{mix}
`return`{Boolean} | check if a variable is an Array
35 | `isBoolean` | `arg`{mix}
`return`{Boolean} | check if a variable is an Boolean
36 | `isNull` | `arg`{mix}
`return`{Boolean} | check if a variable is an null
37 | `isNullOrUndefined` | `arg`{mix}
`return`{Boolean} | check if a variable is null or undefined
38 | `isNumber` | `arg`{mix}
`return`{Boolean} | check if a variable is an Number
39 | `isString` | `arg`{mix}
`return`{Boolean} | check if a variable is an String
40 | `isSymbol` | `arg`{mix}
`return`{Boolean} | check if a variable is an Symbol
41 | `isUndefined` | `arg`{mix}
`return`{Boolean} | check if a variable is an undefined
42 | `isRegExp` | `arg`{mix}
`return`{Boolean} | check if a variable is an RegExp
43 | `isObject` | `arg`{mix}
`return`{Boolean} | check if a variable is an Object
44 | `isDate` | `arg`{mix}
`return`{Boolean} | check if a variable is an Date
45 | `isError` | `arg`{mix}
`return`{Boolean} | check if a variable is an Error
46 | `isFunction` | `arg`{mix}
`return`{Boolean} | check if a variable is an Function
47 | `isPrimitive` | `arg`{mix}
`return`{Boolean} | check if a variable is an Primitive
48 | `isBuffer` | `arg`{mix}
`return`{Boolean} | check if a variable is an Buffer
49 | `promisify` | `function`{function}
`receiver`{object}
`return` Promise | make callback function to promise
50 | `extend` | `target`{object\|array}
`args`{Object\|Array}
`return`{Object} | extend object
51 | `camelCase` | `str`{string}
`return`{String} | make indexAction to index_action
52 | `isNumberString` | `str`{string}
`return`{Boolean} | check object is number string
53 | `isTrueEmpty` | `obj`{mixed}
`return`{Boolean}| truely
54 | `isEmpty` | `obj`{object}
`return`{Boolean}| check object is mepty
55 | `defer` | `return` defer | get deferred object
56 | `md5` | `str`{string}
`return`{string} | get content md5
57 | `timeout` | `time`{Number}
`return` Promise | get timeout Promise
58 | `escapeHtml` | `str`{String}
`return` {string} | escape html
59 | `datetime` | `date`{Date\|String}
`format`{String}
`return`{String} | get datetime
60 | `uuid` | `version`{String} v1 or v4 | generate uuid
61 | `isExist` | `dir`{String} | check path is exist
62 | `isFile` | `filePath`{String} | check filepath is file
63 | `isDirectory` | `filePath`{String} | check path is directory
64 | `chmod` | `path`{String}
`mode`{String} | change path mode
65 | `mkdir` | `dir`{String}
`mode`{String} | make dir
66 | `getdirFiles` | `dir`{String}
`prefix`{String} | get files in path
67 | `rmdir` | `path`{String}
`reserve`{Boolean}
`return`{Promise} | remove dir async
68 | `parseAdapterConfig` | `config`{Object}
`extConfig`{Object\|String} | parse adapter config
69 | `ms` | `time`{String} | transform humanize time to ms
70 | `omit` | `obj`{obj}
`prop` {String|Array} | omit object props
71 |
72 |
73 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for think-helper in ThinkJs 3.x
2 | // Project: https://thinkjs.org/
3 | // Definitions by: SijieCai
4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5 |
6 |
7 |
8 | declare namespace ThinkHelper {
9 | interface Defer {
10 | promise: Promise,
11 | resolve: Function,
12 | reject: Function
13 | }
14 | export function camelCase(str: any): any;
15 |
16 |
17 | /**
18 | * change path mode
19 | *
20 | * @export
21 | * @param {string} p
22 | * @param {string} mode default is '0777'
23 | * @returns {*}
24 | */
25 | export function chmod(p: string, mode?: string): any;
26 |
27 | /**
28 | * get datetime
29 | *
30 | * @export
31 | * @param {*} date
32 | * @param {*} format default is 'YYYY-MM-DD HH:mm:ss'
33 | * @returns {*}
34 | */
35 | export function datetime(date?: Date | string | number, format?: string): string;
36 |
37 | /**
38 | * get deferred object
39 | *
40 | * @export
41 | * @returns {Defer}
42 | */
43 | export function defer(): Defer;
44 |
45 | /**
46 | * escape html
47 | *
48 | * @export
49 | * @param {string} str
50 | * @returns {string}
51 | */
52 | export function escapeHtml(str: string): string;
53 |
54 | export function extend(target: Object, ...args: Object[]): any;
55 |
56 |
57 | /**
58 | *
59 | * get files in path
60 | * @export
61 | * @param {string} dir
62 | * @param {string} prefix
63 | * @returns {string}
64 | */
65 | export function getdirFiles(dir: string, prefix?: string): Array;
66 |
67 | export function isArray(arg: any): boolean;
68 |
69 | export function isBoolean(arg: any): boolean;
70 |
71 | export function isBuffer(b: any): boolean;
72 |
73 | export function isDate(d: any): boolean;
74 |
75 | export function isDirectory(filePath: any): boolean;
76 |
77 | export function isEmpty(obj: any): boolean;
78 |
79 | export function isError(e: any): boolean;
80 |
81 | export function isExist(dir: any): boolean;
82 |
83 | export function isFile(filePath: any): boolean;
84 |
85 | export function isFunction(arg: any): boolean;
86 |
87 | export function isInt(value: string): boolean;
88 |
89 | export function isIP(value: string): boolean;
90 |
91 | export function isIPv4(value: string): boolean;
92 |
93 | export function isIPv6(value: string): boolean;
94 |
95 | export var isMaster: boolean;
96 |
97 | export function isNull(arg: any): boolean;
98 |
99 | export function isNullOrUndefined(arg: any): boolean;
100 |
101 | export function isNumber(arg: any): boolean;
102 |
103 | export function isNumberString(obj: any): boolean;
104 |
105 | export function isObject(obj: any): boolean;
106 |
107 | export function isPrimitive(arg: any): boolean;
108 |
109 | export function isRegExp(re: any): boolean;
110 |
111 | export function isString(arg: any): boolean;
112 |
113 | export function isSymbol(arg: any): boolean;
114 |
115 | export function isTrueEmpty(obj: any): boolean;
116 |
117 | export function isUndefined(arg: any): boolean;
118 |
119 | export function md5(str: string): string;
120 |
121 | /**
122 | *
123 | *
124 | * @export
125 | * @param {string} dir
126 | * @param {string} mode default to '0777'
127 | * @returns {*}
128 | */
129 | export function mkdir(dir: string, mode?: string): any;
130 |
131 | /**
132 | * transform humanize time to ms
133 | *
134 | * @export
135 | * @param {*} time
136 | * @returns {*}
137 | */
138 | export function ms(time: any): number;
139 |
140 |
141 | /**
142 | * omit some props in object
143 | *
144 | * @export
145 | * @param {Object} obj
146 | * @param {(string | Array)} props ',' seperate string or array of props
147 | * @returns {Object}
148 | */
149 | export function omit(obj: Object, props: string | Array): Object;
150 |
151 |
152 | export function parseAdapterConfig(config: Object, ...extConfig: Array): Object;
153 |
154 | /**
155 | * make callback function to promise
156 | *
157 | * @param {Function} fn []
158 | * @param {Object} receiver []
159 | * @return {Function} []
160 | */
161 | export function promisify(fn: Function, receiver: Object): Function;
162 | /**
163 | * remove dir aync
164 | * @param {String} p [path]
165 | * @param {Boolean} reserve []
166 | * @return {Promise} []
167 | */
168 | export function rmdir(p: String, reserve?: Boolean): Promise;
169 |
170 | /**
171 | * snakeCase string
172 | * @param {String} str []
173 | * @return {String} []
174 | */
175 | export function snakeCase(str: string): string;
176 |
177 | /**
178 | * get timeout Promise default 1000
179 | * @param {Number} time []
180 | * @return {Promise} []
181 | */
182 | export function timeout(time?: Number): Promise;
183 | /**
184 | * generate uuid
185 | * @param {String} version [uuid RFC version defautl to v4, or v1]
186 | * @return {String} []
187 | */
188 | export function uuid(version?: string): string;
189 |
190 | export interface Think {
191 |
192 | camelCase(str: any): any;
193 |
194 |
195 | /**
196 | * change path mode
197 | *
198 | * @export
199 | * @param {string} p
200 | * @param {string} mode default is '0777'
201 | * @returns {*}
202 | */
203 | chmod(p: string, mode?: string): any;
204 |
205 | /**
206 | * get datetime
207 | *
208 | * @export
209 | * @param {*} date
210 | * @param {*} format default is 'YYYY-MM-DD HH:mm:ss'
211 | * @returns {*}
212 | */
213 | datetime(date: any, format?: string): any;
214 |
215 | /**
216 | * get deferred object
217 | *
218 | * @export
219 | * @returns {Defer}
220 | */
221 | defer(): Defer;
222 |
223 | /**
224 | * escape html
225 | *
226 | * @export
227 | * @param {string} str
228 | * @returns {string}
229 | */
230 | escapeHtml(str: string): string;
231 |
232 | extend(target: Object, ...args: Object[]): any;
233 |
234 |
235 | /**
236 | *
237 | * get files in path
238 | * @export
239 | * @param {string} dir
240 | * @param {string} prefix
241 | * @returns {string}
242 | */
243 | getdirFiles(dir: string, prefix?: string): Array;
244 |
245 | isArray(arg: any): boolean;
246 |
247 | isBoolean(arg: any): boolean;
248 |
249 | isBuffer(b: any): boolean;
250 |
251 | isDate(d: any): boolean;
252 |
253 | isDirectory(filePath: any): boolean;
254 |
255 | isEmpty(obj: any): boolean;
256 |
257 | isError(e: any): boolean;
258 |
259 | isExist(dir: any): boolean;
260 |
261 | isFile(filePath: any): boolean;
262 |
263 | isFunction(arg: any): boolean;
264 |
265 | isIP(value: string): boolean;
266 |
267 | isIPv4(value: string): boolean;
268 |
269 | isIPv6(value: string): boolean;
270 |
271 | isMaster: boolean;
272 |
273 | isNull(arg: any): boolean;
274 |
275 | isNullOrUndefined(arg: any): boolean;
276 |
277 | isNumber(arg: any): boolean;
278 |
279 | isNumberString(obj: any): boolean;
280 |
281 | isObject(obj: any): boolean;
282 |
283 | isPrimitive(arg: any): boolean;
284 |
285 | isRegExp(re: any): boolean;
286 |
287 | isString(arg: any): boolean;
288 |
289 | isSymbol(arg: any): boolean;
290 |
291 | isTrueEmpty(obj: any): boolean;
292 |
293 | isUndefined(arg: any): boolean;
294 |
295 | md5(str: string): string;
296 |
297 | /**
298 | *
299 | *
300 | * @export
301 | * @param {string} dir
302 | * @param {string} mode default to '0777'
303 | * @returns {*}
304 | */
305 | mkdir(dir: string, mode?: string): any;
306 |
307 | /**
308 | * transform humanize time to ms
309 | *
310 | * @export
311 | * @param {*} time
312 | * @returns {*}
313 | */
314 | ms(time: any): number;
315 |
316 |
317 | /**
318 | * omit some props in object
319 | *
320 | * @export
321 | * @param {Object} obj
322 | * @param {(string | Array)} props ',' seperate string or array of props
323 | * @returns {Object}
324 | */
325 | omit(obj: Object, props: string | Array): Object;
326 |
327 |
328 | parseAdapterConfig(config: Object, ...extConfig: Array): Object;
329 |
330 | /**
331 | * make callback function to promise
332 | *
333 | * @param {Function} fn []
334 | * @param {Object} receiver []
335 | * @return {Function} []
336 | */
337 | promisify(fn: Function, receiver: Object): Function;
338 | /**
339 | * remove dir aync
340 | * @param {String} p [path]
341 | * @param {Boolean} reserve []
342 | * @return {Promise} []
343 | */
344 | rmdir(p: String, reserve?: Boolean): Promise;
345 |
346 | /**
347 | * snakeCase string
348 | * @param {String} str []
349 | * @return {String} []
350 | */
351 | snakeCase(str: string): string;
352 |
353 | /**
354 | * get timeout Promise default 1000
355 | * @param {Number} time []
356 | * @return {Promise} []
357 | */
358 | timeout(time?: Number): Promise;
359 | /**
360 | * generate uuid
361 | * @param {String} version [uuid RFC version defautl to v4, or v1]
362 | * @return {String} []
363 | */
364 | uuid(version?: string): string;
365 |
366 | }
367 | }
368 |
369 | export = ThinkHelper;
370 |
371 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const crypto = require('crypto');
4 | const net = require('net');
5 | const cluster = require('cluster');
6 | const uuid = require('uuid');
7 | const ms = require('ms');
8 | const {
9 | isArray,
10 | isBoolean,
11 | isNull,
12 | isNullOrUndefined,
13 | isNumber,
14 | isString,
15 | isSymbol,
16 | isUndefined,
17 | isRegExp,
18 | isObject,
19 | isDate,
20 | isError,
21 | isFunction,
22 | isPrimitive,
23 | isBuffer
24 | } = require('core-util-is');
25 |
26 | const fsRmdir = promisify(fs.rmdir, fs);
27 | const fsUnlink = promisify(fs.unlink, fs);
28 | const fsReaddir = promisify(fs.readdir, fs);
29 |
30 | const numberReg = /^((-?(\d+\.|\d+|\.\d)\d*(?:e[+-]?\d*(?:\d?\.?|\.?\d?)\d*)?)|(0[0-7]+)|(0x[0-9a-f]+))$/i;
31 | const toString = Object.prototype.toString;
32 |
33 | exports.isIP = net.isIP;
34 | exports.isIPv4 = net.isIPv4;
35 | exports.isIPv6 = net.isIPv6;
36 | exports.isMaster = cluster.isMaster;
37 |
38 | exports.isArray = isArray;
39 | exports.isBoolean = isBoolean;
40 | exports.isNull = isNull;
41 | exports.isNullOrUndefined = isNullOrUndefined;
42 | exports.isNumber = isNumber;
43 | exports.isString = isString;
44 | exports.isSymbol = isSymbol;
45 | exports.isUndefined = isUndefined;
46 | exports.isRegExp = isRegExp;
47 | exports.isObject = isObject;
48 | exports.isDate = isDate;
49 | exports.isError = isError;
50 | exports.isFunction = isFunction;
51 | exports.isPrimitive = isPrimitive;
52 | exports.isBuffer = isBuffer;
53 |
54 | /**
55 | * override isObject method in `core-util-is` module
56 | */
57 | exports.isObject = obj => {
58 | return toString.call(obj) === '[object Object]';
59 | };
60 |
61 | /**
62 | * check value is integer
63 | */
64 | function isInt(value) {
65 | if (isNaN(value) || exports.isString(value)) {
66 | return false;
67 | }
68 | var x = parseFloat(value);
69 | return (x | 0) === x;
70 | }
71 |
72 | exports.isInt = isInt;
73 |
74 | /**
75 | * make callback function to promise
76 | * @param {Function} fn []
77 | * @param {Object} receiver []
78 | * @return {Promise} []
79 | */
80 | function promisify(fn, receiver) {
81 | return (...args) => {
82 | return new Promise((resolve, reject) => {
83 | fn.apply(receiver, [...args, (err, res) => {
84 | return err ? reject(err) : resolve(res);
85 | }]);
86 | });
87 | };
88 | }
89 |
90 | exports.promisify = promisify;
91 |
92 | exports.extend = require('lodash.merge');
93 |
94 | /**
95 | * camelCase string
96 | * @param {String} str []
97 | * @return {String} []
98 | */
99 | function camelCase(str) {
100 | if (str.indexOf('_') > -1) {
101 | str = str.replace(/_(\w)/g, (a, b) => {
102 | return b.toUpperCase();
103 | });
104 | }
105 | return str;
106 | }
107 | exports.camelCase = camelCase;
108 |
109 | /**
110 | * snakeCase string
111 | * @param {String} str []
112 | * @return {String} []
113 | */
114 | function snakeCase(str) {
115 | return str.replace(/([^A-Z])([A-Z])/g, function($0, $1, $2) {
116 | return $1 + '_' + $2.toLowerCase();
117 | });
118 | };
119 | exports.snakeCase = snakeCase;
120 |
121 | /**
122 | * check object is number string
123 | * @param {Mixed} obj []
124 | * @return {Boolean} []
125 | */
126 | function isNumberString(obj) {
127 | if (!obj) return false;
128 | return numberReg.test(obj);
129 | }
130 | exports.isNumberString = isNumberString;
131 |
132 | /**
133 | * true empty
134 | * @param {Mixed} obj []
135 | * @return {Boolean} []
136 | */
137 | function isTrueEmpty(obj) {
138 | if (obj === undefined || obj === null || obj === '') return true;
139 | if (exports.isNumber(obj) && isNaN(obj)) return true;
140 | return false;
141 | }
142 | exports.isTrueEmpty = isTrueEmpty;
143 |
144 | /**
145 | * check object is mepty
146 | * @param {[Mixed]} obj []
147 | * @return {Boolean} []
148 | */
149 | function isEmpty(obj) {
150 | if (isTrueEmpty(obj)) return true;
151 | if (exports.isRegExp(obj)) {
152 | return false;
153 | } else if (exports.isDate(obj)) {
154 | return false;
155 | } else if (exports.isError(obj)) {
156 | return false;
157 | } else if (exports.isArray(obj)) {
158 | return obj.length === 0;
159 | } else if (exports.isString(obj)) {
160 | return obj.length === 0;
161 | } else if (exports.isNumber(obj)) {
162 | return obj === 0;
163 | } else if (exports.isBoolean(obj)) {
164 | return !obj;
165 | } else if (exports.isObject(obj)) {
166 | for (const key in obj) {
167 | return false && key; // only for eslint
168 | }
169 | return true;
170 | }
171 | return false;
172 | }
173 | exports.isEmpty = isEmpty;
174 |
175 | /**
176 | * get deferred object
177 | * @return {Object} []
178 | */
179 | function defer() {
180 | const deferred = {};
181 | deferred.promise = new Promise((resolve, reject) => {
182 | deferred.resolve = resolve;
183 | deferred.reject = reject;
184 | });
185 | return deferred;
186 | }
187 | exports.defer = defer;
188 |
189 | /**
190 | * get content md5
191 | * @param {String} str [content]
192 | * @return {String} [content md5]
193 | */
194 | function md5(str) {
195 | return crypto.createHash('md5').update(str + '', 'utf8').digest('hex');
196 | }
197 | exports.md5 = md5;
198 |
199 | /**
200 | * get timeout Promise
201 | * @param {Number} time []
202 | * @return {[type]} []
203 | */
204 | function timeout(time = 1000) {
205 | return new Promise((resolve) => {
206 | setTimeout(resolve, time);
207 | });
208 | }
209 | exports.timeout = timeout;
210 |
211 | /**
212 | * escape html
213 | */
214 | function escapeHtml(str) {
215 | return (str + '').replace(/[<>'"]/g, a => {
216 | switch (a) {
217 | case '<':
218 | return '<';
219 | case '>':
220 | return '>';
221 | case '"':
222 | return '"e;';
223 | case '\'':
224 | return ''';
225 | }
226 | });
227 | }
228 | exports.escapeHtml = escapeHtml;
229 |
230 | /**
231 | * get datetime
232 | * @param {Date} date []
233 | * @return {String} []
234 | */
235 | function datetime(date = new Date(), format) {
236 | if (date && isString(date)) {
237 | const dateString = date;
238 | date = new Date(Date.parse(date));
239 |
240 | if (isNaN(date.getTime()) && !format) {
241 | format = dateString;
242 | date = new Date();
243 | }
244 | }
245 | format = format || 'YYYY-MM-DD HH:mm:ss';
246 |
247 | const fn = d => {
248 | return ('0' + d).slice(-2);
249 | };
250 |
251 | const d = new Date(date);
252 | const formats = {
253 | YYYY: d.getFullYear(),
254 | MM: fn(d.getMonth() + 1),
255 | DD: fn(d.getDate()),
256 | HH: fn(d.getHours()),
257 | mm: fn(d.getMinutes()),
258 | ss: fn(d.getSeconds())
259 | };
260 |
261 | return format.replace(/([a-z])\1+/ig, a => {
262 | return formats[a] || a;
263 | });
264 | }
265 | exports.datetime = datetime;
266 |
267 | /**
268 | * generate uuid
269 | * @param {String} version [uuid RFC version]
270 | * @return {String} []
271 | */
272 | exports.uuid = function(version) {
273 | if (version === 'v1') return uuid.v1();
274 | return uuid.v4();
275 | };
276 |
277 | /**
278 | * parse adapter config
279 | */
280 | exports.parseAdapterConfig = (config = {}, ...extConfig) => {
281 | config = exports.extend({}, config);
282 | // {handle: ''}
283 | if (!config.type) config.type = '_';
284 | // {type: 'xxx', handle: ''}
285 | if (config.handle) {
286 | const type = config.type;
287 | delete config.type;
288 | config = { type, [type]: config };
289 | }
290 | extConfig = extConfig.map(item => {
291 | if (!item) return {};
292 | // only change type
293 | // 'xxx'
294 | if (exports.isString(item)) {
295 | item = { type: item };
296 | }
297 | // {handle: 'www'}
298 | // only add some configs
299 | if (!item.type) {
300 | item = { type: config.type, [config.type]: item };
301 | }
302 | // {type: 'xxx', handle: 'www'}
303 | if (item.handle) {
304 | const type = item.type;
305 | delete item.type;
306 | item = { type, [type]: item };
307 | }
308 | return item;
309 | });
310 | // merge config
311 | config = exports.extend({}, config, ...extConfig);
312 | const value = config[config.type] || {};
313 | // add type for return value
314 | value.type = config.type;
315 | return value;
316 | };
317 | /**
318 | * transform humanize time to ms
319 | */
320 | exports.ms = function(time) {
321 | if (typeof time === 'number') return time;
322 | const result = ms(time);
323 | if (result === undefined) {
324 | throw new Error(`think-ms('${time}') result is undefined`);
325 | }
326 | return result;
327 | };
328 |
329 | /**
330 | * omit some props in object
331 | */
332 | exports.omit = function(obj, props) {
333 | if (exports.isString(props)) {
334 | props = props.split(',');
335 | }
336 | const keys = Object.keys(obj);
337 | const result = {};
338 | keys.forEach(item => {
339 | if (props.indexOf(item) === -1) {
340 | result[item] = obj[item];
341 | }
342 | });
343 | return result;
344 | };
345 |
346 | /**
347 | * check path is exist
348 | */
349 | function isExist(dir) {
350 | dir = path.normalize(dir);
351 | try {
352 | fs.accessSync(dir, fs.R_OK);
353 | return true;
354 | } catch (e) {
355 | return false;
356 | }
357 | }
358 |
359 | exports.isExist = isExist;
360 |
361 | /**
362 | * check filepath is file
363 | */
364 | function isFile(filePath) {
365 | if (!isExist(filePath)) return false;
366 | try {
367 | const stat = fs.statSync(filePath);
368 | return stat.isFile();
369 | } catch (e) {
370 | return false;
371 | }
372 | }
373 | exports.isFile = isFile;
374 |
375 | /**
376 | * check path is directory
377 | */
378 | function isDirectory(filePath) {
379 | if (!isExist(filePath)) return false;
380 | try {
381 | const stat = fs.statSync(filePath);
382 | return stat.isDirectory();
383 | } catch (e) {
384 | return false;
385 | }
386 | }
387 | exports.isDirectory = isDirectory;
388 |
389 | /**
390 | * change path mode
391 | * @param {String} p [path]
392 | * @param {String} mode [path mode]
393 | * @return {Boolean} []
394 | */
395 | function chmod(p, mode) {
396 | try {
397 | fs.chmodSync(p, mode);
398 | return true;
399 | } catch (e) {
400 | return false;
401 | }
402 | }
403 | exports.chmod = chmod;
404 |
405 | /**
406 | * make dir
407 | */
408 | function mkdir(dir, mode) {
409 | if (isExist(dir)) {
410 | if (mode) return chmod(dir, mode);
411 | return true;
412 | }
413 | const pp = path.dirname(dir);
414 | if (isExist(pp)) {
415 | try {
416 | fs.mkdirSync(dir, mode);
417 | return true;
418 | } catch (e) {
419 | return false;
420 | }
421 | }
422 | if (mkdir(pp, mode)) return mkdir(dir, mode);
423 | return false;
424 | }
425 | exports.mkdir = mkdir;
426 |
427 | /**
428 | * get files in path
429 | * @param {} dir []
430 | * @param {} prefix []
431 | * @return {} []
432 | */
433 | function getdirFiles(dir, prefix = '') {
434 | dir = path.normalize(dir);
435 | if (!fs.existsSync(dir)) return [];
436 | const files = fs.readdirSync(dir);
437 | let result = [];
438 | files.forEach(item => {
439 | const currentDir = path.join(dir, item);
440 | const stat = fs.statSync(currentDir);
441 | if (stat.isFile()) {
442 | result.push(path.join(prefix, item));
443 | } else if (stat.isDirectory()) {
444 | const cFiles = getdirFiles(currentDir, path.join(prefix, item));
445 | result = result.concat(cFiles);
446 | }
447 | });
448 | return result;
449 | };
450 |
451 | exports.getdirFiles = getdirFiles;
452 |
453 | /**
454 | * remove dir aync
455 | * @param {String} p [path]
456 | * @param {Boolean} reserve []
457 | * @return {Promise} []
458 | */
459 | function rmdir(p, reserve) {
460 | if (!isDirectory(p)) return Promise.resolve();
461 | return fsReaddir(p).then(files => {
462 | const promises = files.map(item => {
463 | const filepath = path.join(p, item);
464 | if (isDirectory(filepath)) return rmdir(filepath, false);
465 | return fsUnlink(filepath);
466 | });
467 | return Promise.all(promises).then(() => {
468 | if (!reserve) return fsRmdir(p);
469 | });
470 | });
471 | }
472 | exports.rmdir = rmdir;
473 |
474 | exports.isBuffer = Buffer.isBuffer;
475 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "think-helper",
3 | "description": "Helper for ThinkJS",
4 | "version": "1.1.4",
5 | "author": {
6 | "name": "songguangyu",
7 | "email": "522963130@qq.com"
8 | },
9 | "scripts": {
10 | "test": "eslint index.js && nyc ava test/",
11 | "coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
12 | "lint": "eslint index.js",
13 | "lint-fix": "eslint --fix index.js"
14 | },
15 | "ava": {
16 | "require": [
17 | "babel-core/register"
18 | ]
19 | },
20 | "contributors": [
21 | {
22 | "name": "songguangyu",
23 | "email": "522963130@qq.com"
24 | }
25 | ],
26 | "main": "index.js",
27 | "types": "index.d.ts",
28 | "dependencies": {
29 | "core-util-is": "^1.0.2",
30 | "lodash.merge": "^4.6.2",
31 | "ms": "^1.0.0",
32 | "uuid": "^7.0.3"
33 | },
34 | "devDependencies": {
35 | "ava": "^0.18.0",
36 | "codecov": "^3.7.1",
37 | "coveralls": "^2.11.16",
38 | "eslint": "^4.2.0",
39 | "eslint-config-think": "^1.0.1",
40 | "nyc": "^7.1.0"
41 | },
42 | "keywords": [],
43 | "repository": {
44 | "type": "git",
45 | "url": "https://github.com/thinkjs/think-helper"
46 | },
47 | "engines": {
48 | "node": ">=6.0.0"
49 | },
50 | "readmeFilename": "README.md",
51 | "bugs": {
52 | "url": "https://github.com/thinkjs/think-helper/issues"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | import test from 'ava';
2 | import {
3 | isInt,
4 | isFunction,
5 | isExist,
6 | isFile,
7 | isDirectory,
8 | extend,
9 | promisify,
10 | defer,
11 | md5,
12 | mkdir,
13 | rmdir,
14 | chmod,
15 | uuid,
16 | datetime,
17 | escapeHtml,
18 | isEmpty,
19 | isNumberString,
20 | camelCase,
21 | getdirFiles,
22 | isTrueEmpty,
23 | isIP,
24 | timeout,
25 | parseAdapterConfig,
26 | ms,
27 | snakeCase,
28 | isBuffer,
29 | omit
30 | } from '../index.js';
31 | import fs from 'fs';
32 | import path from 'path';
33 |
34 | test('isInt', t => {
35 | t.is(isInt(42), true);
36 | });
37 |
38 | test('isInt1', t => {
39 | t.is(isInt('42'), false);
40 | });
41 |
42 | test('isInt2', t => {
43 | t.is(isInt(4e2), true);
44 | });
45 |
46 | test('isInt3', t => {
47 | t.is(isInt('4e2'), false);
48 | });
49 |
50 | test('isInt4', t => {
51 | t.is(isInt(' 1 '), false);
52 | });
53 |
54 | test('isInt5', t => {
55 | t.is(isInt(''), false);
56 | });
57 |
58 | test('isInt6', t => {
59 | t.is(isInt(' '), false);
60 | });
61 |
62 | test('isInt7', t => {
63 | t.is(isInt('1a'), false);
64 | });
65 |
66 | test('isInt8', t => {
67 | t.is(isInt('42e2a'), false);
68 | });
69 |
70 | test('isInt9', t => {
71 | t.is(isInt(null), false);
72 | });
73 |
74 | test('isInt10', t => {
75 | t.is(isInt(undefined), false);
76 | });
77 |
78 | test('isInt11', t => {
79 | t.is(isInt(NaN), false);
80 | });
81 |
82 | test('isInt12', t => {
83 | t.is(isInt(42.1), false);
84 | });
85 |
86 | test('isExist', t => {
87 | t.is(isExist('/www/fasdfasfasdfa'), false);
88 | });
89 |
90 | test('isExist 2', t => {
91 | t.is(isExist(__filename), true);
92 | });
93 |
94 | test('isExist 3', t => {
95 | t.is(isExist(__dirname), true);
96 | });
97 |
98 | test('isExist 4', t => {
99 | t.is(isExist('/root'), false);
100 | });
101 |
102 | test('isFile', t => {
103 | t.is(isFile('/root'), false);
104 | });
105 |
106 | test('isFile 2', t => {
107 | t.is(isFile(__filename), true);
108 | });
109 |
110 | test('isDirectory', t => {
111 | t.is(isDirectory(__filename), false);
112 | });
113 |
114 | test('isDirectory 2', t => {
115 | t.is(isDirectory(__dirname), true);
116 | });
117 |
118 | test('extend 1', t => {
119 | const data = extend({}, {name: 'test'});
120 | t.deepEqual(data, {name: 'test'});
121 | });
122 |
123 | test('extend 2', t => {
124 | const data = extend({
125 | name: 'xd'
126 | }, {name: ['1', '2']});
127 | t.deepEqual(data, {name: ['1', '2']});
128 | });
129 |
130 | test('extend 3', t => {
131 | const data = extend({
132 | name: 'xd'
133 | }, {name: {value: '1'}});
134 | t.deepEqual(data, {name: {value: '1'}});
135 | });
136 |
137 | test('extend 4', t => {
138 | const data = extend({
139 | name: ['1']
140 | }, {name: ['2']});
141 | t.deepEqual(data, {name: ['2']});
142 | });
143 |
144 | test('extend 5', t => {
145 | const data = extend({}, {name: 'welefen'}, {name: 'suredy'});
146 | t.deepEqual(data, {name: 'suredy'});
147 | });
148 |
149 | test('extend 6', t => {
150 | const data = extend({}, {name: 'welefen'}, {name2: 'suredy'});
151 | t.deepEqual(data, {name: 'welefen', name2: 'suredy'});
152 | });
153 |
154 | test('extend 7', t => {
155 | const data = extend(null, {name: 'welefen'}, {name2: 'suredy'});
156 | t.deepEqual(data, {name: 'welefen', name2: 'suredy'});
157 | });
158 |
159 | test('extend 8', t => {
160 | const data = extend({}, {name: [4, 5]});
161 | t.deepEqual(data, {name: [4, 5]});
162 | });
163 |
164 | test('extend 9', t => {
165 | const data = extend({}, '', {name: 'sgy'});
166 | t.deepEqual(data, {name: 'sgy'});
167 | });
168 |
169 | test('extend 10', t => {
170 | const data = extend({name: 'sgy'}, {name: 'sgy'});
171 | t.deepEqual(data, {name: 'sgy'});
172 | });
173 |
174 | // test('extend getter', t => {
175 | // let source = {
176 | // get a(){
177 | // return this.b();
178 | // },
179 | // b(){
180 | // return 1;
181 | // }
182 | // }
183 | // let data = extend({name:'sgy'}, source);
184 | // t.deepEqual(data.a, 1);
185 | // })
186 |
187 | // test('extend setter', t => {
188 | // let source = {
189 | // get a(){
190 | // return this.xxx;
191 | // },
192 | // set a(val){
193 | // this.xxx = val;
194 | // },
195 | // b(){
196 | // return 1;
197 | // }
198 | // }
199 | // let data = extend({name:'sgy'}, source);
200 | // data.a = 222;
201 | // t.deepEqual(data.a, 222);
202 | // t.deepEqual(data.xxx, 222)
203 | // })
204 |
205 | test('promisify', async(t) => {
206 | const fn = promisify(fs.readFile, fs);
207 | const data = await fn(__filename);
208 | t.is(data.length > 0, true);
209 | });
210 |
211 | test('promisify 2', async(t) => {
212 | const fn = promisify(fs.readFile, fs);
213 | const data = await fn(path.join(__filename, 'dddd')).catch(() => false);
214 | t.is(data, false);
215 | });
216 |
217 | test('defer', t => {
218 | const deferred = defer();
219 | t.is(isFunction(deferred.promise.then), true);
220 | });
221 |
222 | test('md5', t => {
223 | t.is(md5(''), 'd41d8cd98f00b204e9800998ecf8427e');
224 | });
225 |
226 | test('mkdir', t => {
227 | mkdir('welefen22');
228 | t.is(isDirectory('welefen22'), true);
229 | fs.rmdirSync('welefen22');
230 | });
231 |
232 | test('mkdir 2', t => {
233 | mkdir('welefen/suredy/www');
234 | t.is(isDirectory('welefen/suredy/www'), true);
235 | fs.rmdirSync('welefen/suredy/www');
236 | fs.rmdirSync('welefen/suredy');
237 | fs.rmdirSync('welefen');
238 | });
239 |
240 | test('mkdir 3', t => {
241 | mkdir('welefen44/suredy/www');
242 | mkdir('welefen44/suredy/www');
243 | t.is(isDirectory('welefen44/suredy/www'), true);
244 | fs.rmdirSync('welefen44/suredy/www');
245 | fs.rmdirSync('welefen44/suredy');
246 | fs.rmdirSync('welefen44');
247 | });
248 |
249 | test('mkdir 4', async(t) => {
250 | mkdir('songguangyu78');
251 | t.is(mkdir('songguangyu78/smart', '9527'), false);
252 | await rmdir('songguangyu78');
253 | });
254 |
255 | test('mkdir 5', async(t) => {
256 | t.is(mkdir('songguangyu79/smart', '9527'), false);
257 | await rmdir('songguangyu79');
258 | });
259 |
260 | test('rmdir', async(t) => {
261 | mkdir('songguangyu75');
262 | t.is(isDirectory('songguangyu75'), true);
263 | await rmdir('songguangyu75');
264 | t.is(isDirectory('songguangyu75'), false);
265 | });
266 |
267 | test('rmdir 1', async(t) => {
268 | mkdir('songguangyu76');
269 | fs.writeFileSync('songguangyu76/abc.js', '123');
270 | mkdir('songguangyu76/xiaoming');
271 | t.is(isDirectory('songguangyu76'), true);
272 | await rmdir('songguangyu76');
273 | t.is(isDirectory('songguangyu76'), false);
274 | });
275 |
276 | test('rmdir 2', async(t) => {
277 | mkdir('songguangyu77');
278 | fs.rmdirSync('songguangyu77');
279 | chmod('songguangyu77');
280 | await rmdir('songguangyu77');
281 | });
282 |
283 | test('uuid', t => {
284 | var uuid1 = uuid('v1');
285 | t.is(uuid1.length > 1, true);
286 | var uuid2 = uuid();
287 | t.is(uuid2.length > 1, true);
288 | });
289 |
290 | test('ms 1200', t => {
291 | var value = ms(1200);
292 | t.is(value, 1200);
293 | });
294 | test('ms 2 days', t => {
295 | var value = ms('2 days');
296 | t.is(value, 172800000);
297 | });
298 | test('ms 1d', t => {
299 | var value = ms('1d');
300 | t.is(value, 86400000);
301 | });
302 | test('ms 10h', t => {
303 | var value = ms('10h');
304 | t.is(value, 36000000);
305 | });
306 | test('ms 2.5 hrs', t => {
307 | var value = ms('2.5 hrs');
308 | t.is(value, 9000000);
309 | });
310 | test('ms 1y', t => {
311 | var value = ms('1y');
312 | t.is(value, 31557600000);
313 | });
314 | test('ms 1b', t => {
315 | try {
316 | const value = ms('1b');
317 | t.is(1, value);
318 | } catch (e) {
319 | t.is(e.toString(), "Error: think-ms('1b') result is undefined");
320 | }
321 | });
322 |
323 | test('datetime', t => {
324 | datetime();
325 | datetime('123');
326 | });
327 |
328 | test('datetime 1', t => {
329 | t.plan(4);
330 | const now = new Date();
331 | t.is(datetime('2017-12-12 10:00:00', 'YYYY-MM-DD'), '2017-12-12');
332 | t.is(datetime('', 'YYYY-MM-DD'), 'YYYY-aN-aN');
333 | t.is(
334 | datetime(new Date('2017/10/10'), 'YYYY-MM-DD HH:mm:ss'),
335 | '2017-10-10 00:00:00'
336 | );
337 | t.is(
338 | datetime('YYYY/MM/DD'),
339 | [
340 | now.getFullYear(),
341 | ('0' + (now.getMonth() + 1)).slice(-2),
342 | now.getDate()
343 | ].join('/')
344 | );
345 | });
346 |
347 | test('escapeHtml', t => {
348 | t.deepEqual(escapeHtml(''), '<div width='200'></div>');
349 | });
350 | test('escapeHtml 1', t => {
351 | t.deepEqual(escapeHtml(('')), '<div width="e;200"e;></div>');
352 | });
353 | test('isEmpty', t => {
354 | t.is(isEmpty({}), true);
355 | t.is(isEmpty(NaN), true);
356 | t.is(isEmpty(1), false);
357 | t.is(isEmpty('sgy'), false);
358 | t.is(isEmpty(false), true);
359 | t.is(isEmpty(null), true);
360 | t.is(isEmpty(undefined), true);
361 | t.is(isEmpty(''), true);
362 | t.is(isEmpty({'a': 1}), false);
363 | var date = new Date();
364 | t.is(isEmpty(date), false);
365 | var func = function() {};
366 | t.is(isEmpty(func), false);
367 | t.is(isEmpty([]), true);
368 | t.is(isEmpty(new Error('errror')), false);
369 | t.is(isEmpty(/test/), false);
370 | });
371 | test('isNumberString', t => {
372 | t.is(isNumberString(''), false);
373 | t.is(isNumberString('111d111'), false);
374 | t.is(isNumberString('111111'), true);
375 | t.is(isNumberString('.1'), true);
376 | t.is(isNumberString('.e1'), false);
377 | t.is(isNumberString('.1e1'), true);
378 | t.is(isNumberString('1.e1'), true);
379 | t.is(isNumberString('e1'), false);
380 | t.is(isNumberString('1e1'), true);
381 | t.is(isNumberString('1.1e1'), true);
382 | t.is(isNumberString('e1499451'), false);
383 | t.is(isNumberString('149e9451'), true);
384 | });
385 |
386 | test('camelCase', t => {
387 | t.deepEqual(camelCase('index_test'), 'indexTest');
388 | });
389 |
390 | test('getdirFiles', t => {
391 | mkdir('songguangyu79');
392 | mkdir('songguangyu79/songguangyu80');
393 | fs.writeFileSync('songguangyu79/abc.js', '123');
394 | fs.writeFileSync('songguangyu79/songguangyu80/abc.js', '123');
395 | getdirFiles('songguangyu79');
396 | getdirFiles('songguangyu80');
397 | rmdir('songguangyu79');
398 | });
399 |
400 | test('isTrueEmpty', t => {
401 | t.deepEqual(isTrueEmpty(null), true);
402 | });
403 |
404 | test('chmod', t => {
405 | mkdir('songguangyu81');
406 | chmod('songguangyu81', '0777');
407 | t.is(chmod('songguangyu82', '0777'), false);
408 | rmdir('songguangyu81');
409 | });
410 |
411 | test('isIP', t => {
412 | t.deepEqual(isIP('127.0.0.1') === 4, true);
413 | });
414 |
415 | test('timeout', t => {
416 | timeout(1000).then(() => {
417 | t.pass('success');
418 | });
419 | });
420 |
421 | test('snakeCase', t => {
422 | var value = snakeCase('wwwTest');
423 | t.deepEqual(value, 'www_test');
424 | });
425 |
426 | test('isBuffer', t => {
427 | var value = isBuffer('wwwTest');
428 | t.deepEqual(value, false);
429 | });
430 |
431 | test('isBuffer 2', t => {
432 | var value = isBuffer(Buffer.from('test'));
433 | t.deepEqual(value, true);
434 | });
435 |
436 | test('parseAdapterConfig', t => {
437 | const config = {
438 | type: 'nunjucks',
439 | common: {
440 | viewPath: 'thinkjs',
441 | extname: '.html',
442 | sep: '_' // seperator between controller and action
443 | },
444 | nunjucks: {
445 | handle: 'nunjucks'
446 | },
447 | ejs: {
448 | handle: 'ejs'
449 | }
450 | };
451 | const extConfig = 'ejs';
452 | const extConfig2 = {
453 | handle: 'ejs'
454 | };
455 | t.deepEqual(parseAdapterConfig(config).handle, 'nunjucks');
456 | t.deepEqual(parseAdapterConfig(config, extConfig).handle, 'ejs');
457 | t.deepEqual(parseAdapterConfig(config, extConfig2).handle, 'ejs');
458 | });
459 |
460 | test('parseAdapterConfig 2', t => {
461 | const config = {
462 | type: 'nunjucks',
463 | common: {
464 | viewPath: 'thinkjs',
465 | extname: '.html',
466 | sep: '_' // seperator between controller and action
467 | },
468 | nunjucks: {
469 | handle: 'nunjucks'
470 | },
471 | ejs: {
472 | handle: 'ejs'
473 | }
474 | };
475 | // const extConfig = 'ejs';
476 | const extConfig2 = {
477 | type: 'ejs',
478 | handle: 'ejs'
479 | };
480 | t.deepEqual(parseAdapterConfig(config, extConfig2).type, 'ejs');
481 | });
482 |
483 | test('parseAdapterConfig 3', t => {
484 | const config = {
485 | type: 'nunjucks',
486 | common: {
487 | viewPath: 'thinkjs',
488 | extname: '.html',
489 | sep: '_' // seperator between controller and action
490 | },
491 | nunjucks: {
492 | handle: 'nunjucks'
493 | },
494 | ejs: {
495 | handle: 'ejs'
496 | }
497 | };
498 | // const extConfig = 'ejs';
499 | const extConfig2 = {
500 | type: 'ejs',
501 | handle: 'ejs'
502 | };
503 | const value = parseAdapterConfig(config);
504 | t.deepEqual(parseAdapterConfig(value, extConfig2).type, 'ejs');
505 | });
506 |
507 | test('parseAdapterConfig 3', t => {
508 | const value = parseAdapterConfig({});
509 | t.deepEqual(parseAdapterConfig(value).type, '_');
510 | });
511 |
512 | test('parseAdapterConfig 4', t => {
513 | const value = parseAdapterConfig({handle: 'www', value: '222'});
514 | t.deepEqual(parseAdapterConfig(value).value, '222');
515 | });
516 |
517 | test('parseAdapterConfig 5', t => {
518 | const value = parseAdapterConfig({
519 | type: 'www',
520 | www: {
521 | handle: 'www', value: '222'
522 | },
523 | aaa: {
524 | value: 333
525 | }
526 | }, 'test', 'aaa');
527 | t.deepEqual(value.value, 333);
528 | });
529 |
530 | test('parseAdapterConfig 6', t => {
531 | const value = parseAdapterConfig({
532 | type: 'www',
533 | www: {
534 | handle: 'www', value: '222'
535 | },
536 | aaa: {
537 | value: 333
538 | }
539 | }, 'test', {timeout: 20});
540 | t.deepEqual(value.timeout, 20);
541 | });
542 |
543 | test('omit 1', t => {
544 | const value = omit({
545 | a: 1,
546 | b: 2
547 | }, 'test');
548 | t.deepEqual(value, {a: 1, b: 2});
549 | });
550 |
551 | test('omit 1', t => {
552 | const value = omit({
553 | a: 1,
554 | b: 2
555 | }, 'a');
556 | t.deepEqual(value, {b: 2});
557 | });
558 |
559 | test('omit 2', t => {
560 | const value = omit({
561 | a: 1,
562 | b: 2
563 | }, 'a,b');
564 | t.deepEqual(value, {});
565 | });
566 |
567 | test('omit 3', t => {
568 | const value = omit({
569 | a: 1,
570 | b: 2
571 | }, ['a', 'b']);
572 | t.deepEqual(value, {});
573 | });
574 |
--------------------------------------------------------------------------------