@polyv/utils 1.5.1 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +33 -18
  2. package/dist/cjs/boolean.d.ts +45 -0
  3. package/dist/cjs/boolean.js +1 -0
  4. package/dist/cjs/countdown.d.ts +97 -0
  5. package/dist/cjs/countdown.js +1 -0
  6. package/dist/cjs/date.d.ts +44 -0
  7. package/dist/cjs/date.js +1 -0
  8. package/dist/cjs/json.d.ts +43 -0
  9. package/dist/cjs/json.js +1 -0
  10. package/dist/cjs/net.d.ts +32 -0
  11. package/dist/cjs/net.js +1 -0
  12. package/dist/cjs/string.d.ts +94 -0
  13. package/dist/cjs/string.js +1 -0
  14. package/dist/cjs/validate.d.ts +26 -0
  15. package/dist/cjs/validate.js +1 -0
  16. package/dist/es/boolean.d.ts +45 -0
  17. package/dist/es/boolean.js +1 -0
  18. package/dist/es/countdown.d.ts +97 -0
  19. package/dist/es/countdown.js +1 -0
  20. package/dist/es/date.d.ts +44 -0
  21. package/dist/es/date.js +1 -0
  22. package/dist/es/json.d.ts +43 -0
  23. package/dist/es/json.js +1 -0
  24. package/dist/es/net.d.ts +32 -0
  25. package/dist/es/net.js +1 -0
  26. package/dist/es/string.d.ts +94 -0
  27. package/dist/es/string.js +1 -0
  28. package/dist/es/validate.d.ts +26 -0
  29. package/dist/es/validate.js +1 -0
  30. package/package.json +31 -26
  31. package/dist/boolean.js +0 -1
  32. package/dist/browser.js +0 -1
  33. package/dist/cookie.js +0 -1
  34. package/dist/countdown.js +0 -1
  35. package/dist/date.js +0 -1
  36. package/dist/lang.js +0 -1
  37. package/dist/net.js +0 -1
  38. package/dist/polling.js +0 -1
  39. package/dist/querystring.js +0 -1
  40. package/dist/storage.js +0 -1
  41. package/dist/string.js +0 -1
  42. package/dist/validate.js +0 -1
  43. package/src/boolean.js +0 -67
  44. package/src/browser.js +0 -81
  45. package/src/cookie.js +0 -115
  46. package/src/countdown.js +0 -91
  47. package/src/date.js +0 -92
  48. package/src/internal/core.js +0 -59
  49. package/src/internal/timeunit.js +0 -63
  50. package/src/lang.js +0 -120
  51. package/src/net.js +0 -54
  52. package/src/polling.js +0 -142
  53. package/src/querystring.js +0 -121
  54. package/src/storage.js +0 -106
  55. package/src/string.js +0 -105
  56. package/src/validate.js +0 -42
package/src/cookie.js DELETED
@@ -1,115 +0,0 @@
1
- /**
2
- * 本模块提供 cookie 读写方法。
3
- * @module cookie
4
- */
5
-
6
- import { isDate } from './internal/core';
7
- import { addToDate } from './internal/timeunit';
8
-
9
- /**
10
- * 写入 cookie。
11
- * @author luoliquan
12
- * @param {string} key cookie 键。
13
- * @param {string} value cookie 值。
14
- * @param {Object} [options] 参数。
15
- * @param {string} [options.domain] 所在域。
16
- * @param {string} [options.path] 所在路径。
17
- * @param {(Date|number|string)} [options.expires] 过期时间。
18
- * 为日期类型时表示绝对时间;
19
- * 为数字(单位毫秒)时表示相对时间(当前时间+相对值);
20
- * 为字符串时表示相对时间(当前时间+相对值),支持格式包括(%表示数字):
21
- * %secs,
22
- * %mins,
23
- * %hours,
24
- * %days,
25
- * %months,
26
- * %years。
27
- * @param {boolean} [options.secure] 是否只在 https 连接中有效。
28
- * @param {string} [options.sameSite] 访问限制:Lax、Strict 或 None。
29
- * @example
30
- * cookie.set('a', '1')
31
- * cookie.set('b', '2', {
32
- * expires: '6months', // 180 天
33
- * domain: '.polyv.net',
34
- * path: '/'
35
- * });
36
- */
37
- export function set(key, value, options) {
38
- options = options || {};
39
-
40
- let content = encodeURIComponent(key) + '=' + encodeURIComponent(value);
41
- if (options.expires != null) {
42
- content += '; expires=' + (
43
- isDate(options.expires) ?
44
- options.expires :
45
- addToDate(new Date(), options.expires)
46
- ).toUTCString();
47
- }
48
- if (options.path) { content += '; path=' + options.path; }
49
- if (options.domain) { content += '; domain=' + options.domain; }
50
- if (options.secure === true) { content += '; secure'; }
51
- if (options.sameSite) {
52
- const sameSite = String(options.sameSite).toLowerCase();
53
- if (['lax', 'strict', 'none'].indexOf(sameSite) !== -1) {
54
- content += '; samesite=' + sameSite;
55
- }
56
- }
57
-
58
- document.cookie = content;
59
- }
60
-
61
- /**
62
- * 读取 cookie。
63
- * @author luoliquan
64
- * @param {string} name cookie 名。
65
- * @return {string} cookie 值。
66
- * @example
67
- * cookie.get('a');
68
- */
69
- export function get(key) {
70
- key = '; ' + encodeURIComponent(key) + '=';
71
- const cookie = '; ' + document.cookie;
72
-
73
- let beginPos = cookie.indexOf(key);
74
- if (beginPos === -1) { return null; }
75
- beginPos += key.length;
76
-
77
- let endPos = cookie.indexOf(';', beginPos);
78
- if (endPos === -1) { endPos = cookie.length; }
79
-
80
- return decodeURIComponent(cookie.substring(beginPos, endPos));
81
- }
82
-
83
- // iOS 9 下设置过期不会马上生效,先设为空
84
- const shouldSetEmptyBeforeRemove = (function() {
85
- // 兼容 Node 端(主要针对同构应用)引入
86
- if (typeof document === 'undefined') { return false; }
87
-
88
- const TEST_KEY = '__jraiser__test__cookie__';
89
- document.cookie = TEST_KEY + '=1';
90
- document.cookie = TEST_KEY + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
91
- return !!get(TEST_KEY);
92
- })();
93
-
94
- /**
95
- * 移除 cookie。
96
- * @author luoliquan
97
- * @param {string} name cookie 名。
98
- * @param {Object} [options] 参数。
99
- * @param {string} [options.domain] 所在域。
100
- * @param {string} [options.path] 所在路径。
101
- * @example
102
- * remove('a');
103
- * remove('b' {
104
- * domain: '.polyv.net',
105
- * path: '/abc'
106
- * })
107
- */
108
- export function remove(name, options) {
109
- if (shouldSetEmptyBeforeRemove) { set(name, '', options); }
110
-
111
- options = options || {};
112
- // 让其过期即为删除
113
- options.expires = new Date(0);
114
- set(name, '', options);
115
- }
package/src/countdown.js DELETED
@@ -1,91 +0,0 @@
1
- /**
2
- * 本模块提供倒数功能。
3
- * @module countdown
4
- */
5
-
6
- const computes = [
7
- { divisor: 24 * 60 * 60 * 1000, unit: 'days' },
8
- { divisor: 60 * 60 * 1000, unit: 'hours' },
9
- { divisor: 60 * 1000, unit: 'minutes' },
10
- { divisor: 1000, unit: 'seconds' }
11
- ];
12
-
13
- /**
14
- * 倒计时回调函数。
15
- * @callback countdownCallback
16
- * @memberof module:countdown.Countdown
17
- * @param {Object} rest 剩余的时间。
18
- * @param {number} rest.days 剩余天数。
19
- * @param {number} rest.hours 剩余小时数。
20
- * @param {number} rest.minutes 剩余分钟数。
21
- * @param {number} rest.seconds 剩余秒数。
22
- * @param {boolean} rest.totalMsecs 剩余的总毫秒数。
23
- */
24
- /**
25
- * 倒计时类。
26
- * @memberof module:countdown
27
- * @class
28
- * @name Countdown
29
- * @author luoliquan
30
- * @param {number} secs 总秒数。
31
- * @param {countdownCallback} [cb] 回调函数。
32
- * @example
33
- * const countdown = new Countdown(60, (rest) => {
34
- * console.dir(rest);
35
- * });
36
- * countdown.start();
37
- */
38
- export default class Countdown {
39
- constructor(secs, cb) {
40
- secs = parseInt(secs);
41
- if (isNaN(secs)) { throw new Error('Total seconds must be a number'); }
42
- this._secs = secs * 1000; // 倒计时毫秒数
43
- this._cb = typeof cb === 'function' ? cb : function() {}; // 倒计时回调函数
44
- }
45
-
46
- _exec() {
47
- if (!this._startTime) { return; }
48
-
49
- let value = Math.max(0, this._secs - (Date.now() - this._startTime));
50
- if (value > 0 && !this._stopped) {
51
- setTimeout(() => { this._exec(); }, 1000);
52
- }
53
-
54
- if (value >= 0) {
55
- const rest = {
56
- totalMsecs: value
57
- };
58
- computes.forEach((item, i) => {
59
- rest[item.unit] = value / item.divisor;
60
- if (i === computes.length - 1) {
61
- rest[item.unit] = Math.round(rest[item.unit]);
62
- } else {
63
- rest[item.unit] = Math.floor(rest[item.unit]);
64
- value = value % item.divisor;
65
- }
66
- });
67
- this._cb(rest);
68
- }
69
- }
70
-
71
- /**
72
- * 开始倒计时。
73
- * @method
74
- * @memberof module:countdown.Countdown.prototype
75
- */
76
- start() {
77
- if (this.secs <= 0) { return; }
78
- this._startTime = Date.now();
79
- this._exec();
80
- }
81
-
82
- /**
83
- * 停止倒计时。
84
- * @method
85
- * @memberof module:countdown.Countdown.prototype
86
- */
87
- stop() {
88
- if (this._timerId) { clearTimeout(this._timerId); }
89
- this._stopped = true;
90
- }
91
- }
package/src/date.js DELETED
@@ -1,92 +0,0 @@
1
- /**
2
- * 本模块提供日期处理相关方法。
3
- * @module date
4
- */
5
-
6
- import { extend } from './lang';
7
-
8
- // 保证日期相关函数的操作对象为日期类型
9
- export function ensureDate(date) {
10
- if (typeof date !== 'object') { date = new Date(date); }
11
- return date;
12
- }
13
-
14
- /**
15
- * 格式化日期。
16
- * @author luoliquan
17
- * @param {(Date|number)} date 日期对象或时间戳(毫秒)。
18
- * @param {string} formation 格式。
19
- * @return {string} 格式化结果。
20
- * @example
21
- * formatDate(new Date(2018, 9, 8, 8, 50, 56), 'YYYY-MM-DD hh:mm:ss'); // '2018-10-08 08:50:56'
22
- */
23
- export function formatDate(date, formation) {
24
- date = ensureDate(date);
25
-
26
- const values = {
27
- Y: date.getFullYear(),
28
- M: date.getMonth() + 1,
29
- D: date.getDate(),
30
- h: date.getHours(),
31
- m: date.getMinutes(),
32
- s: date.getSeconds()
33
- };
34
-
35
- return formation.replace(/([YMDhms])\1*/g, (match) => {
36
- let result = values[match[0]];
37
- if (match.length > 1 && result.toString().length !== match.length) {
38
- result = ((new Array(match.length)).join('0') + result).slice(-match.length);
39
- }
40
- return result;
41
- });
42
- }
43
-
44
- /**
45
- * 把秒数格式化成「时:分:秒」格式。
46
- * @author luoliquan
47
- * @param {number} secs 秒数。
48
- * @param {Object} [options] 格式化配置。
49
- * @param {number} [options.segments=2] 段数,2 或者 3。
50
- * 为 2 时,如果小时为 0,则格式化样式为「分:秒」。
51
- * @param {number} [options.digits=2] 每一段数字的最小位数,不足位数时补 0。
52
- * @return {string} 格式化结果。
53
- * @example
54
- * formatSeconds(3682); // '01:01:22'
55
- * formatSeconds(82); // '01:22'
56
- * formatSeconds(82, { segments: 3 }); // '00:01:22'
57
- * formatSeconds(3682, { digits: 1 }); // '1:1:22'
58
- */
59
- export function formatSeconds(secs, options) {
60
- secs = Number(secs);
61
- if (isNaN(secs) || secs < 0) {
62
- throw new Error('"secs" must be a positive integer');
63
- }
64
-
65
- // 参数合法性校验
66
- options = extend({}, options);
67
- options.segments = parseInt(options.segments);
68
- // 位数最小为 1
69
- options.digits = Math.max(1, parseInt(options.digits) || 2);
70
- // 段数只能为 2 或者 3
71
- if ([2, 3].indexOf(options.segments) === -1) {
72
- options.segments = 2;
73
- }
74
-
75
- // 需要补多少个 0
76
- const zeros = (new Array(options.digits + 1).join('0'));
77
-
78
- const result = [
79
- 60 * 60,
80
- 60,
81
- 1
82
- ].map((num) => {
83
- const subResult = Math.floor(secs / num);
84
- const len = subResult.toString().length;
85
- secs = secs % num;
86
- return (zeros + subResult).slice(-Math.max(len, options.digits));
87
- });
88
-
89
- if (options.segments < 3 && !Number(result[0])) { result.shift(); }
90
-
91
- return result.join(':');
92
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * @module internal-core
3
- * @ignore
4
- */
5
-
6
- // ESLint 不推荐直接使用 obj.hasOwnProperty
7
- const hasOwnProperty = Object.prototype.hasOwnProperty;
8
- /**
9
- * 检查指定对象是否具有某个 own property。
10
- * @function
11
- * @name hasOwnProp
12
- * @author luoliquan
13
- * @param {Any} obj 指定对象。
14
- * @param {string} prop 属性名。
15
- * @return {boolean} 指定对象是否具有某个 own property。
16
- */
17
- export function hasOwnProp(obj, prop) {
18
- return hasOwnProperty.call(obj, prop);
19
- }
20
-
21
- // 单个源扩展
22
- export function extendSingle(target, src) {
23
- if (src != null) {
24
- let key, value;
25
- for (key in src) {
26
- value = src[key];
27
- if (key === '__proto__' || target === value) { continue; }
28
- if (hasOwnProp(src, key)) { target[key] = value; }
29
- }
30
- }
31
- }
32
-
33
-
34
- const toString = Object.prototype.toString;
35
-
36
- // 是否 Object 类型
37
- export function isObject(value) {
38
- return toString.call(value) === '[object Object]';
39
- }
40
-
41
- // 是否 Date 类型
42
- export function isDate(value) {
43
- return toString.call(value) === '[object Date]';
44
- }
45
-
46
-
47
- /**
48
- * 全局对象,浏览器环境下为 window,Node 环境下为 global。
49
- * @type {Object}
50
- */
51
- let theGlobal;
52
- if (typeof window !== 'undefined') {
53
- theGlobal = window;
54
- } else if (typeof global !== 'undefined') {
55
- theGlobal = global;
56
- } else {
57
- theGlobal = null;
58
- }
59
- export { theGlobal };
@@ -1,63 +0,0 @@
1
- /**
2
- * @module
3
- * @ignore
4
- */
5
-
6
- import { hasOwnProp } from './core';
7
-
8
- // 时间单位
9
- const timeUnits = {
10
- SEC: 1000,
11
- MIN: 60 * 1000,
12
- HOUR: 60 * 60 * 1000,
13
- DAY: 24 * 60 * 60 * 1000,
14
- MONTH: 30 * 24 * 60 * 60 * 1000,
15
- YEAR: 365 * 24 * 60 * 60 * 1000
16
- };
17
-
18
- /**
19
- * 把带单位的时间跨度转换为毫秒表示。
20
- * @author luoliquan
21
- * @param {(number|string)} timespan 时间跨度。为数字时表示毫秒,为字符串时支持以下格式(%表示数字):
22
- * %secs;
23
- * %mins;
24
- * %hours;
25
- * %days;
26
- * %months;
27
- * %years。
28
- * @return {number} 时间跨度的毫秒表示。
29
- */
30
- export function parse(timespan) {
31
- // str为数字,直接返回
32
- if (typeof timespan === 'number') { return timespan; }
33
- if (!isNaN(timespan)) { return Number(timespan); }
34
-
35
- const num = parseFloat(timespan);
36
- if (isNaN(num)) {
37
- throw new Error('Invalid timespan string');
38
- }
39
-
40
- const unit = timespan.split(num)[1]
41
- .trim()
42
- .toUpperCase()
43
- .replace(/S$/, ''); // 移除复数时的s
44
-
45
- if (hasOwnProp(timeUnits, unit)) {
46
- return num * timeUnits[unit];
47
- } else {
48
- throw new Error('Invalid time unit "' + unit + '"');
49
- }
50
- }
51
-
52
- /**
53
- * 以指定日期对象的毫秒表示加上指定时间跨度的毫秒表示,生成新的日期对象。
54
- * @author luoliquan
55
- * @param {(Date|number)} date 指定日期对象或日期的毫秒表示。
56
- * @param {(number|string)} timespan 时间跨度,为数字时表示毫秒,为字符串时支持的格式同 parse。
57
- * @return {Date} 表示相加结果的日期对象。
58
- */
59
- export function addToDate(date, timespan) {
60
- return new Date(
61
- (typeof date === 'number' ? date : date.getTime()) + parse(timespan)
62
- );
63
- }
package/src/lang.js DELETED
@@ -1,120 +0,0 @@
1
- /**
2
- * 本模块提供基础方法。
3
- * @module lang
4
- */
5
-
6
- import { extendSingle, hasOwnProp, isObject } from './internal/core';
7
-
8
- /**
9
- * 检查指定对象是否具有某个 own property(ESLint 不推荐直接使用 obj.hasOwnProperty)。
10
- * @author luoliquan
11
- * @name hasOwnProp
12
- * @function
13
- * @static
14
- * @param {Any} obj 指定对象。
15
- * @param {string} prop 属性名。
16
- * @return {boolean} 指定对象是否具有某个 own property。
17
- */
18
- export { hasOwnProp };
19
-
20
- /**
21
- * 检查指定对象是否为类数组结构。
22
- * @author luoliquan
23
- * @param {Any} obj 指定对象。
24
- * @return {boolean} 检查指定对象是否为类数组结构。
25
- * @example
26
- * isArrayLike([]); // true
27
- * isArrayLike(document.getElementsByTagName('body')); // true
28
- * isArrayLike({}); // false
29
- */
30
- export function isArrayLike(obj) {
31
- return obj != null &&
32
- typeof obj !== 'function' &&
33
- typeof obj.length === 'number' &&
34
- obj.length >= 0 &&
35
- obj.length % 1 === 0; // 不是小数
36
- }
37
-
38
- /**
39
- * 检查指定值是否为空数据。以下情况会判断为空数据:
40
- * null 或者 undefined;
41
- * 数组结构,但长度为 0;
42
- * 空字符串或仅包含空白字符的字符串;
43
- * 没有 own property 的纯对象。
44
- * @author luoliquan
45
- * @param {Any} value 指定值。
46
- * @return {boolean} 指定值是否为空数据。
47
- * @example
48
- * isEmptyData(null); // true
49
- * isEmptyData([]); // true
50
- * isEmptyData(''); // true
51
- * isEmptyData({}); // true
52
- * isEmptyData({ a: 1 }); // false
53
- * isEmptyData([1]); // false
54
- */
55
- export function isEmptyData(value) {
56
- if (value == null) { return true; }
57
- if (typeof value === 'string') {
58
- return value.trim() === '';
59
- } else if (Array.isArray(value)) {
60
- return !value.length;
61
- } else if (isObject(value)) {
62
- for (const key in value) {
63
- if (hasOwnProp(value, key)) { return false; }
64
- }
65
- return true;
66
- }
67
- return false;
68
- }
69
-
70
- /**
71
- * 把源对象的属性(own property)扩展到目标对象(同 Object.assign)。
72
- * @author luoliquan
73
- * @param {Any} target 目标对象。
74
- * @param {...Any} [source] 源对象。若有同名属性,则后者覆盖前者。
75
- * @return {Any} 目标对象。
76
- */
77
- export function extend(target) {
78
- if (target == null) {
79
- throw new Error('The target argument cannot be null or undefined');
80
- }
81
-
82
- const len = arguments.length;
83
- let i = 0;
84
- while (++i < len) {
85
- extendSingle(target, arguments[i]);
86
- }
87
- return target;
88
- }
89
-
90
- /**
91
- * 深度克隆指定对象(仅限 JSON 支持的数据类型)。
92
- * @author liumin
93
- * @param {Any} obj 指定对象。
94
- * @return {Any} 克隆结果。
95
- * @example
96
- * cloneJSON({ a: 1, b: 2 }); // { a: 1, b: 2 }
97
- */
98
- export function cloneJSON(obj) {
99
- if (obj == null) { return obj; }
100
- return JSON.parse(JSON.stringify(obj));
101
- }
102
-
103
- /**
104
- * 尝试把指定字符串解析为 JSON 对象。
105
- * @author luoliquan
106
- * @param {string} str 指定字符串。
107
- * @return {Any} 解析结果,解析失败时返回 undefined。
108
- * @example
109
- * tryParseJSON('ss&&**'); // undefined
110
- * tryParseJSON('{"a": 1}'); // { a: 1 }
111
- */
112
- export function tryParseJSON(str) {
113
- let result;
114
- try {
115
- result = JSON.parse(str);
116
- } catch (e) {
117
-
118
- }
119
- return result;
120
- }
package/src/net.js DELETED
@@ -1,54 +0,0 @@
1
- /**
2
- * 本模块提供网络协议相关方法。
3
- * @module net
4
- */
5
-
6
- // 匹配协议
7
- const reProtocol = /^(?:([a-z]+):)?\/{2,3}/i;
8
-
9
- /**
10
- * 检查目标字符串是否以特定 URL 协议开头。
11
- * @author luoliquan
12
- * @param {string} str 目标字符串。
13
- * @param {Array} [protocols] 特定协议(不含冒号和斜杠),不指定时表示允许任何协议。
14
- * @return {boolean} 目标字符串是否以特定 URL 协议开头。
15
- * @example
16
- * startsWithProtocol('//abc.com'); // true
17
- * startsWithProtocol('https://abc.com'); // true
18
- * startsWithProtocol('file:///Users/'); // true
19
- * startsWithProtocol('abc.com'); // false
20
- * startsWithProtocol('http://abc.com', ['http', 'https']); // true
21
- * startsWithProtocol('ftp://abc.com', ['http', 'https']); // false
22
- */
23
- export function startsWithProtocol(str, protocols) {
24
- const result = reProtocol.test(str);
25
- if (result && protocols) {
26
- const protocol = (RegExp.$1 || '').toLowerCase();
27
- for (let i = protocols.length - 1; i >= 0; i--) {
28
- if (protocol === protocols[i].toLowerCase()) {
29
- return true;
30
- }
31
- }
32
- return false;
33
- }
34
- return result;
35
- }
36
-
37
- /**
38
- * 替换目标字符串中的 URL 协议。如果字符串中不包含协议,则加上协议。
39
- * @author luoliquan
40
- * @param {string} url 目标字符串。
41
- * @param {string} protocol 协议。
42
- * @return {string} 替换结果。
43
- * @example
44
- * changeProtocol('abc.com', 'https'); // 'https://abc.com'
45
- * changeProtocol('http://abc.com', 'https'); // 'https://abc.com'
46
- */
47
- export function changeProtocol(url, protocol) {
48
- if (!reProtocol.test(protocol)) {
49
- protocol += '://';
50
- }
51
- return startsWithProtocol(url) ?
52
- url.replace(reProtocol, protocol) :
53
- protocol + url;
54
- }