@polyv/utils-ua-info 3.0.0

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.
@@ -0,0 +1,56 @@
1
+ import { OSInfo } from './os-info';
2
+ /**
3
+ * 品牌信息类。
4
+ */
5
+ export declare class BrandInfo {
6
+ /**
7
+ * 是否华为设备。
8
+ */
9
+ readonly isHuawei: boolean;
10
+ /**
11
+ * 是否小米设备。
12
+ */
13
+ readonly isMi: boolean;
14
+ /**
15
+ * 是否 Oppo 设备。
16
+ */
17
+ readonly isOppo: boolean;
18
+ /**
19
+ * 是否 Vivo 设备。
20
+ */
21
+ readonly isVivo: boolean;
22
+ /**
23
+ * 是否一加设备。
24
+ */
25
+ readonly isOnePlus: boolean;
26
+ /**
27
+ * 是否三星设备。
28
+ */
29
+ readonly isSamsung: boolean;
30
+ /**
31
+ * 是否苹果 iPod。
32
+ */
33
+ readonly isIPod: boolean;
34
+ /**
35
+ * 是否苹果 iPhone。
36
+ */
37
+ readonly isIPhone: boolean;
38
+ /**
39
+ * 是否苹果 iPad。
40
+ */
41
+ readonly isIPad: boolean;
42
+ /**
43
+ * 是否苹果 Mac 电脑。
44
+ */
45
+ readonly isMac: boolean;
46
+ /**
47
+ * 是否苹果设备。
48
+ */
49
+ readonly isApple: boolean;
50
+ /**
51
+ * 品牌信息类构造函数。
52
+ * @param ua User agent 字符串。
53
+ * @param os 操作系统信息。
54
+ */
55
+ constructor(ua: string, os: Readonly<OSInfo>);
56
+ }
@@ -0,0 +1,39 @@
1
+ import { Version } from './version';
2
+ /**
3
+ * 浏览器内核信息类。
4
+ */
5
+ export declare class BrowserInfo {
6
+ /**
7
+ * 是否 Chrome 内核。
8
+ */
9
+ readonly isChrome: boolean;
10
+ /**
11
+ * 是否 Safari 内核。
12
+ */
13
+ readonly isSafari: boolean;
14
+ /**
15
+ * 是否 Edge(EdgeHTML) 内核。
16
+ */
17
+ readonly isEdge: boolean;
18
+ /**
19
+ * 是否 IE 内核。
20
+ */
21
+ readonly isIE: boolean;
22
+ /**
23
+ * 是否 Firefox 内核。
24
+ */
25
+ readonly isFirefox: boolean;
26
+ /**
27
+ * 是否 Opera(Presto) 内核。
28
+ */
29
+ readonly isPrestoOpera: boolean;
30
+ /**
31
+ * 浏览器内核版本号。
32
+ */
33
+ readonly version: Readonly<Version>;
34
+ /**
35
+ * 浏览器内核信息类构造函数。
36
+ * @param ua User agent 字符串。
37
+ */
38
+ constructor(ua: string);
39
+ }
@@ -0,0 +1,91 @@
1
+ import { Version } from './version';
2
+ /**
3
+ * 客户端信息类。
4
+ */
5
+ export declare class ClientInfo {
6
+ /**
7
+ * 是否企业微信。
8
+ */
9
+ readonly isWxWork: boolean;
10
+ /**
11
+ * 是否微信。
12
+ */
13
+ readonly isWx: boolean;
14
+ /**
15
+ * 是否微信小程序 WebView。
16
+ */
17
+ readonly isWxMiniProgram: boolean;
18
+ /**
19
+ * 是否钉钉。
20
+ */
21
+ readonly isDing: boolean;
22
+ /**
23
+ * 是否 QQ。
24
+ */
25
+ readonly isQQ: boolean;
26
+ /**
27
+ * 是否微博。
28
+ */
29
+ readonly isWeibo: boolean;
30
+ /**
31
+ * 是否 Edge 浏览器.
32
+ */
33
+ readonly isEdge: boolean;
34
+ /**
35
+ * 是否 Opera 浏览器。
36
+ */
37
+ readonly isOpera: boolean;
38
+ /**
39
+ * 是否 QQ 浏览器。
40
+ */
41
+ readonly isQQBrowser: boolean;
42
+ /**
43
+ * 是否 UC 浏览器。
44
+ */
45
+ readonly isUCBrowser: boolean;
46
+ /**
47
+ * 是否夸克浏览器。
48
+ */
49
+ readonly isQuark: boolean;
50
+ /**
51
+ * 是否傲游浏览器。
52
+ */
53
+ readonly isMaxthon: boolean;
54
+ /**
55
+ * 是否世界之窗浏览器。
56
+ */
57
+ readonly isTheWorld: boolean;
58
+ /**
59
+ * 是否百度浏览器。
60
+ */
61
+ readonly isBaiduBrowser: boolean;
62
+ /**
63
+ * 是否百度 app。
64
+ */
65
+ readonly isBaiduApp: boolean;
66
+ /**
67
+ * 是否 Chrome 浏览器。
68
+ */
69
+ readonly isChrome: boolean;
70
+ /**
71
+ * 是否 Safari 浏览器。
72
+ */
73
+ readonly isSafari: boolean;
74
+ /**
75
+ * 是否 IE 浏览器。
76
+ */
77
+ readonly isIE: boolean;
78
+ /**
79
+ * 是否 Firefox 浏览器。
80
+ */
81
+ readonly isFirefox: boolean;
82
+ /**
83
+ * 客户端版本号。
84
+ */
85
+ readonly version: Readonly<Version>;
86
+ /**
87
+ * 客户端信息类构造函数。
88
+ * @param ua User agent 字符串。
89
+ */
90
+ constructor(ua: string);
91
+ }
package/index.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,t){e=e.toLowerCase();let n=/[/\s;_-]/,r=/[/\s;_-]/;return t.some(t=>{let i=e.indexOf(t.toLowerCase());if(i!==-1&&(n.test(e[i-1])||i===0)&&(r.test(e[i+t.length])||i+t.length>=e.length))return!0})}function t(e,t){return/;\s*([^;:)]*?)(?:;?\s+Build\/[^;)]+)?(?:;(?:\s*wv)?)?\)/.test(e)?t.test(RegExp.$1):!1}function n(n,r){let i;return r.some(r=>{let a=!1,o;return r.regExp?(a=r.regExp.test(n),a&&(o=RegExp.$1)):r.keywords?a=e(n,r.keywords):r.modelRegExp&&(a=t(n,r.modelRegExp)),a&&(i={name:r.name,version:o}),a}),i}var r=[{name:`windows`,regExp:/\bWindows\s?NT\s?(([\d.]+))\b/},{name:`ios`,regExp:/\bOS(?:\s([\d_.]+))?\slike\sMac\sOS\sX\b/},{name:`macos`,regExp:/\bMac\sOS\sX(?:\s([\d_.]+))?/},{name:`openharmony`,regExp:/\bOpenHarmony\s([\d.]+)\b/},{name:`android`,regExp:/\bAndroid;?(?:[-/\s]([\d.]+))?(?:\b|_)/},{name:`android`,regExp:/\bAdr\s([\d.]+)(?:\b|_)/}];function i(e,t){let n=/(\.0+)+$/,r=String(e).replace(n,``).split(`.`),i=String(t).replace(n,``).split(`.`),a=Math.min(r.length,i.length);for(let e=0;e<a;e++){let t=parseInt(r[e])-parseInt(i[e]);if(t)return t}return r.length-i.length}var a=class{constructor(e){this._ver=(e||``).replace(/_/g,`.`).replace(/\.+$/,``),Object.freeze(this)}_compare(e,t){if(!this._ver||!e)return!1;let n=Array.isArray(t)?t:[t],r=i(this._ver,e);return n.some(function(e){return r*e>0||r===0&&e===0})}gt(e){return this._compare(e,1)}gte(e){return this._compare(e,[1,0])}lt(e){return this._compare(e,-1)}lte(e){return this._compare(e,[-1,0])}eq(e){return this._compare(e,0)}toString(){return this._ver}},o={ios:`isIOS`,openharmony:`isOpenHarmony`,android:`isAndroid`,windows:`isWindows`,macos:`isMacOS`},s=class{constructor(e,t){this.isIOS=!1,this.isAndroid=!1,this.isHarmonyOS=!1,this.isOpenHarmony=!1,this.isWindows=!1,this.isMacOS=!1;let i=n(e,r);if(!i){this.version=new a(``);return}i.name===`macos`&&t?.maxTouchPoints&&(i.name=`ios`,i.version=``),this[o[i.name]]=!0,this.version=new a(i.version),this.isAndroid&&/\bHarmonyOS\b/.test(e)&&(this.isHarmonyOS=!0),Object.freeze(this)}},c=[{name:`ipad`,regExp:/iPad/},{name:`ipod`,regExp:/iPod/},{name:`iphone`,regExp:/iPhone/}],l=[{name:`huawei`,regExp:/\b(?:huawei|honor)/i},{name:`huawei`,keywords:[`ideahub`,`figi`]},{name:`vivo`,keywords:[`vivo`]},{name:`oppo`,keywords:[`oppo`]},{name:`mi`,keywords:[`redmi`,`hongmi`,`shark`,`Mi`,`MIX`,`POCO`,`POCOPHONE`]},{name:`mi`,regExp:/\bxiaomi/i},{name:`samsung`,keywords:[`samsung`,`galaxy`]},{name:`oneplus`,keywords:[`oneplus`,`one`]},{name:`huawei`,modelRegExp:/^Mate\s*\d{2}/i},{name:`huawei`,modelRegExp:/^Nova\s\d$/},{name:`huawei`,regExp:/\b(?:Hi)?MatePad/i},{name:`huawei`,regExp:/\b(?:Liantong|UNICOMVSENS)VP\d{3}\b/},{name:`huawei`,regExp:/\bCMDCSP\d{3}\b/},{name:`huawei`,regExp:/\bTDTECH/i},{name:`huawei`,modelRegExp:/^[A-Z]{3}\d?-W[0-5]9[A-Z]*$/},{name:`huawei`,modelRegExp:/^[A-Z][A-Za-z]{2,3}-(?:AN|BD|BX|AL|TL)\d{2}[A-Za-z]*$/},{name:`huawei`,modelRegExp:/^TYH\d+[A-Z]?$/},{name:`huawei`,modelRegExp:/^H60-L0[12]$/},{name:`mi`,modelRegExp:/^MI\s?(?:\d|CC|Note|MAX|PLAY|PAD)/i},{name:`mi`,modelRegExp:/^(?:AWM|SKR|SKW|DLT)-/},{name:`mi`,modelRegExp:/^XIG\d{2}$/},{name:`mi`,modelRegExp:/^M\d{4}[A-Z]\d{1,2}[A-Z]{1,3}$/},{name:`mi`,modelRegExp:/^2\d{3}[A-Z0-9]{6}$/},{name:`mi`,modelRegExp:/^2\d{5}[0-9A-Z]{2}[A-Z]$/},{name:`mi`,modelRegExp:/^2\d{6}[A-Z]$/},{name:`mi`,modelRegExp:/^2\d{7}[A-Z]{2,3}$/},{name:`samsung`,modelRegExp:/^S(?:M|[CGP]H)-[A-Za-z0-9]+$/},{name:`samsung`,modelRegExp:/^SCV3\d$/},{name:`samsung`,modelRegExp:/^SC-\d{2}[A-Z]$/},{name:`samsung`,modelRegExp:/^SH[WV]-/},{name:`samsung`,modelRegExp:/^GT[-_][A-Z][A-Z0-9]{3,}$/i},{name:`oppo`,modelRegExp:/^(?:CPH|OPD|iPA)\d{4}$/},{name:`oppo`,modelRegExp:/^OPG\d{2}$/},{name:`oppo`,modelRegExp:/^A[1-5]0[1-9]OP$/},{name:`oneplus`,modelRegExp:/^(?:KB|HD|IN|GM|NE|LE|MT)\d{4}$/},{name:`vivo`,modelRegExp:/^V[12]\d{3}[A-Z]{0,2}$/}],u={ipod:`isIPod`,iphone:`isIPhone`,ipad:`isIPad`,huawei:`isHuawei`,mi:`isMi`,oppo:`isOppo`,vivo:`isVivo`,oneplus:`isOnePlus`,samsung:`isSamsung`},d=class{constructor(e,t){this.isHuawei=!1,this.isMi=!1,this.isOppo=!1,this.isVivo=!1,this.isOnePlus=!1,this.isSamsung=!1,this.isIPod=!1,this.isIPhone=!1,this.isIPad=!1,this.isMac=!1,this.isApple=!1;let r;if(t.isIOS?(r=c,this.isApple=!0):t.isMacOS?(this.isMac=!0,this.isApple=!0):(t.isAndroid||t.isOpenHarmony)&&(r=l),r){let i=n(e,r);i?this[u[i.name]]=!0:t.isIOS&&(this.isIPad=!0)}Object.freeze(this)}},f=[{name:`edge`,regExp:/\bEdge\/([\d.]+)/},{name:`chrome`,regExp:/\b(?:Chrome|CrMo|CriOS)\/([\d.]+)/},{name:`safari`,regExp:/\b(?:Version\/([\d.]+).*\s?)?Safari\b/},{name:`ie`,regExp:/\bMSIE\s(\d+)/i},{name:`ie`,regExp:/\bTrident\/.*;\srv:(\d+)/},{name:`firefox`,regExp:/\bFirefox\/([\d.]+)/},{name:`opera-presto`,regExp:/\bOpera\/([\d.]+)/}],p={chrome:`isChrome`,safari:`isSafari`,edge:`isEdge`,ie:`isIE`,firefox:`isFirefox`,"opera-presto":`isPrestoOpera`},m=class{constructor(e){this.isChrome=!1,this.isSafari=!1,this.isEdge=!1,this.isIE=!1,this.isFirefox=!1,this.isPrestoOpera=!1;let t=n(e,f);t?(this[p[t.name]]=!0,this.version=new a(t.version)):this.version=new a(``),Object.freeze(this)}},h=[{name:`wxwork`,regExp:/\bwxwork\/([\d.]+)/},{name:`wx`,regExp:/\bMicroMessenger\/([\d.]+)/},{name:`ding`,regExp:/\bDingTalk\/([\d.]+)/},{name:`qq`,regExp:/\bQQ\/([\d.]+)/},{name:`qq`,regExp:/\bIPadQQ\b/},{name:`weibo`,regExp:/(?:\b|_)Weibo(?:\b|_)/i},{name:`edge`,regExp:/\bEdge?\/([\d.]+)/},{name:`opera-blink`,regExp:/\bOPR\/([\d.]+)/},{name:`qqbrowser`,regExp:/\bM?QQBrowser(?:\/([\d.]+))?/i},{name:`ucbrowser`,regExp:/\b(?:UCBrowser|UCWEB)(?:-CMCC)?\/?\s?([\d.]+)/},{name:`ucbrowser`,regExp:/\bUC\b/},{name:`quark`,regExp:/\bQuark\/([\d.]+)/},{name:`maxthon`,regExp:/\b(?:Maxthon|MxBrowser)(?:[/\s]([\d.]+))?/},{name:`theworld`,regExp:/\bTheWorld(?:\s([\d.]+))?/i},{name:`baidubrowser`,regExp:/\b(?:baidubrowser|bdbrowser_i18n|BIDUBrowser)(?:[/\s]([\d.]+))?/i},{name:`baidubrowser`,regExp:/\bbaidubrowserpad\b/},{name:`baiduapp`,regExp:/\bbaiduboxapp\b\/([\d.]+)?/i},{name:`baiduapp`,regExp:/\bbaiduboxpad\b/i}];h=h.concat(f);var g={wxwork:`isWxWork`,wx:`isWx`,ding:`isDing`,qq:`isQQ`,weibo:`isWeibo`,edge:`isEdge`,"opera-blink":`isOpera`,"opera-presto":`isOpera`,qqbrowser:`isQQBrowser`,ucbrowser:`isUCBrowser`,quark:`isQuark`,maxthon:`isMaxthon`,theworld:`isTheWorld`,baidubrowser:`isBaiduBrowser`,baiduapp:`isBaiduApp`,chrome:`isChrome`,safari:`isSafari`,ie:`isIE`,firefox:`isFirefox`},_=class{constructor(e){this.isWxWork=!1,this.isWx=!1,this.isWxMiniProgram=!1,this.isDing=!1,this.isQQ=!1,this.isWeibo=!1,this.isEdge=!1,this.isOpera=!1,this.isQQBrowser=!1,this.isUCBrowser=!1,this.isQuark=!1,this.isMaxthon=!1,this.isTheWorld=!1,this.isBaiduBrowser=!1,this.isBaiduApp=!1,this.isChrome=!1,this.isSafari=!1,this.isIE=!1,this.isFirefox=!1;let t=n(e,h);t?(this[g[t.name]]=!0,this.version=new a(t.version)):this.version=new a(``),this.isWxMiniProgram=(this.isWx||this.isWxWork)&&/\bMiniProgramEnv\b/.test(e),Object.freeze(this)}},v=class{constructor(e,t){if(this.os=Object.freeze(new s(e,t)),this.brand=Object.freeze(new d(e,this.os)),this.browser=Object.freeze(new m(e)),this.client=Object.freeze(new _(e)),this.isTabletLike=this.isTablet=this.brand.isIPad||/\bTablet\b/i.test(e)||this.os.isAndroid&&!/\bMobile\b/i.test(e),!this.isTabletLike&&(this.os.isAndroid||this.os.isOpenHarmony)&&t){let e=t.screenWidth??0,n=t.screenHeight??0,r=t.dpr??0;if(e>0&&n>0&&r>0){let t=Math.max(e,n),i=Math.min(e,n);this.isTabletLike=t/i<1.8&&i*r>=1200}}this.os.isIOS||this.os.isAndroid||this.isTablet?this.isPortable=!0:/\(X11[;)]/i.test(e)||this.os.isWindows||this.os.isMacOS?this.isPortable=!1:this.isPortable=/mobile|android/i.test(e),Object.freeze(this)}},y;function b(){return y||=Object.freeze(typeof window<`u`?new v(window.navigator.userAgent,{maxTouchPoints:window.navigator.maxTouchPoints,screenWidth:window.screen.width,screenHeight:window.screen.height,dpr:window.devicePixelRatio}):new v(``)),y}exports.BrandInfo=d,exports.BrowserInfo=m,exports.ClientInfo=_,exports.OSInfo=s,exports.UAInfo=v,exports.Version=a,exports.getCurrentUAInfo=b;
package/index.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { UAInfo } from './ua-info';
2
+ import { OSInfo } from './os-info';
3
+ import { BrandInfo } from './brand-info';
4
+ import { BrowserInfo } from './browser-info';
5
+ import { ClientInfo } from './client-info';
6
+ import { Version } from './version';
7
+ /**
8
+ * 获取当前运行环境的 user agent 信息实例。
9
+ * @returns 当前运行环境的 user agent 信息实例。
10
+ */
11
+ export declare function getCurrentUAInfo(): Readonly<UAInfo>;
12
+ export { UAInfo, OSInfo, BrandInfo, BrowserInfo, ClientInfo, Version };
13
+ export type { IFeatureInfo } from './types';
package/index.js ADDED
@@ -0,0 +1,458 @@
1
+ //#region src/internal/ua-detector.ts
2
+ function e(e, t) {
3
+ e = e.toLowerCase();
4
+ let n = /[/\s;_-]/, r = /[/\s;_-]/;
5
+ return t.some((t) => {
6
+ let i = e.indexOf(t.toLowerCase());
7
+ if (i !== -1 && (n.test(e[i - 1]) || i === 0) && (r.test(e[i + t.length]) || i + t.length >= e.length)) return !0;
8
+ });
9
+ }
10
+ function t(e, t) {
11
+ return /;\s*([^;:)]*?)(?:;?\s+Build\/[^;)]+)?(?:;(?:\s*wv)?)?\)/.test(e) ? t.test(RegExp.$1) : !1;
12
+ }
13
+ function n(n, r) {
14
+ let i;
15
+ return r.some((r) => {
16
+ let a = !1, o;
17
+ return r.regExp ? (a = r.regExp.test(n), a && (o = RegExp.$1)) : r.keywords ? a = e(n, r.keywords) : r.modelRegExp && (a = t(n, r.modelRegExp)), a && (i = {
18
+ name: r.name,
19
+ version: o
20
+ }), a;
21
+ }), i;
22
+ }
23
+ //#endregion
24
+ //#region src/internal/os-rules.ts
25
+ var r = [
26
+ {
27
+ name: "windows",
28
+ regExp: /\bWindows\s?NT\s?(([\d.]+))\b/
29
+ },
30
+ {
31
+ name: "ios",
32
+ regExp: /\bOS(?:\s([\d_.]+))?\slike\sMac\sOS\sX\b/
33
+ },
34
+ {
35
+ name: "macos",
36
+ regExp: /\bMac\sOS\sX(?:\s([\d_.]+))?/
37
+ },
38
+ {
39
+ name: "openharmony",
40
+ regExp: /\bOpenHarmony\s([\d.]+)\b/
41
+ },
42
+ {
43
+ name: "android",
44
+ regExp: /\bAndroid;?(?:[-/\s]([\d.]+))?(?:\b|_)/
45
+ },
46
+ {
47
+ name: "android",
48
+ regExp: /\bAdr\s([\d.]+)(?:\b|_)/
49
+ }
50
+ ];
51
+ //#endregion
52
+ //#region src/version.ts
53
+ function i(e, t) {
54
+ let n = /(\.0+)+$/, r = String(e).replace(n, "").split("."), i = String(t).replace(n, "").split("."), a = Math.min(r.length, i.length);
55
+ for (let e = 0; e < a; e++) {
56
+ let t = parseInt(r[e]) - parseInt(i[e]);
57
+ if (t) return t;
58
+ }
59
+ return r.length - i.length;
60
+ }
61
+ var a = class {
62
+ constructor(e) {
63
+ this._ver = (e || "").replace(/_/g, ".").replace(/\.+$/, ""), Object.freeze(this);
64
+ }
65
+ _compare(e, t) {
66
+ if (!this._ver || !e) return !1;
67
+ let n = Array.isArray(t) ? t : [t], r = i(this._ver, e);
68
+ return n.some(function(e) {
69
+ return r * e > 0 || r === 0 && e === 0;
70
+ });
71
+ }
72
+ gt(e) {
73
+ return this._compare(e, 1);
74
+ }
75
+ gte(e) {
76
+ return this._compare(e, [1, 0]);
77
+ }
78
+ lt(e) {
79
+ return this._compare(e, -1);
80
+ }
81
+ lte(e) {
82
+ return this._compare(e, [-1, 0]);
83
+ }
84
+ eq(e) {
85
+ return this._compare(e, 0);
86
+ }
87
+ toString() {
88
+ return this._ver;
89
+ }
90
+ }, o = {
91
+ ios: "isIOS",
92
+ openharmony: "isOpenHarmony",
93
+ android: "isAndroid",
94
+ windows: "isWindows",
95
+ macos: "isMacOS"
96
+ }, s = class {
97
+ constructor(e, t) {
98
+ this.isIOS = !1, this.isAndroid = !1, this.isHarmonyOS = !1, this.isOpenHarmony = !1, this.isWindows = !1, this.isMacOS = !1;
99
+ let i = n(e, r);
100
+ if (!i) {
101
+ this.version = new a("");
102
+ return;
103
+ }
104
+ i.name === "macos" && t?.maxTouchPoints && (i.name = "ios", i.version = ""), this[o[i.name]] = !0, this.version = new a(i.version), this.isAndroid && /\bHarmonyOS\b/.test(e) && (this.isHarmonyOS = !0), Object.freeze(this);
105
+ }
106
+ }, c = [
107
+ {
108
+ name: "ipad",
109
+ regExp: /iPad/
110
+ },
111
+ {
112
+ name: "ipod",
113
+ regExp: /iPod/
114
+ },
115
+ {
116
+ name: "iphone",
117
+ regExp: /iPhone/
118
+ }
119
+ ], l = [
120
+ {
121
+ name: "huawei",
122
+ regExp: /\b(?:huawei|honor)/i
123
+ },
124
+ {
125
+ name: "huawei",
126
+ keywords: ["ideahub", "figi"]
127
+ },
128
+ {
129
+ name: "vivo",
130
+ keywords: ["vivo"]
131
+ },
132
+ {
133
+ name: "oppo",
134
+ keywords: ["oppo"]
135
+ },
136
+ {
137
+ name: "mi",
138
+ keywords: [
139
+ "redmi",
140
+ "hongmi",
141
+ "shark",
142
+ "Mi",
143
+ "MIX",
144
+ "POCO",
145
+ "POCOPHONE"
146
+ ]
147
+ },
148
+ {
149
+ name: "mi",
150
+ regExp: /\bxiaomi/i
151
+ },
152
+ {
153
+ name: "samsung",
154
+ keywords: ["samsung", "galaxy"]
155
+ },
156
+ {
157
+ name: "oneplus",
158
+ keywords: ["oneplus", "one"]
159
+ },
160
+ {
161
+ name: "huawei",
162
+ modelRegExp: /^Mate\s*\d{2}/i
163
+ },
164
+ {
165
+ name: "huawei",
166
+ modelRegExp: /^Nova\s\d$/
167
+ },
168
+ {
169
+ name: "huawei",
170
+ regExp: /\b(?:Hi)?MatePad/i
171
+ },
172
+ {
173
+ name: "huawei",
174
+ regExp: /\b(?:Liantong|UNICOMVSENS)VP\d{3}\b/
175
+ },
176
+ {
177
+ name: "huawei",
178
+ regExp: /\bCMDCSP\d{3}\b/
179
+ },
180
+ {
181
+ name: "huawei",
182
+ regExp: /\bTDTECH/i
183
+ },
184
+ {
185
+ name: "huawei",
186
+ modelRegExp: /^[A-Z]{3}\d?-W[0-5]9[A-Z]*$/
187
+ },
188
+ {
189
+ name: "huawei",
190
+ modelRegExp: /^[A-Z][A-Za-z]{2,3}-(?:AN|BD|BX|AL|TL)\d{2}[A-Za-z]*$/
191
+ },
192
+ {
193
+ name: "huawei",
194
+ modelRegExp: /^TYH\d+[A-Z]?$/
195
+ },
196
+ {
197
+ name: "huawei",
198
+ modelRegExp: /^H60-L0[12]$/
199
+ },
200
+ {
201
+ name: "mi",
202
+ modelRegExp: /^MI\s?(?:\d|CC|Note|MAX|PLAY|PAD)/i
203
+ },
204
+ {
205
+ name: "mi",
206
+ modelRegExp: /^(?:AWM|SKR|SKW|DLT)-/
207
+ },
208
+ {
209
+ name: "mi",
210
+ modelRegExp: /^XIG\d{2}$/
211
+ },
212
+ {
213
+ name: "mi",
214
+ modelRegExp: /^M\d{4}[A-Z]\d{1,2}[A-Z]{1,3}$/
215
+ },
216
+ {
217
+ name: "mi",
218
+ modelRegExp: /^2\d{3}[A-Z0-9]{6}$/
219
+ },
220
+ {
221
+ name: "mi",
222
+ modelRegExp: /^2\d{5}[0-9A-Z]{2}[A-Z]$/
223
+ },
224
+ {
225
+ name: "mi",
226
+ modelRegExp: /^2\d{6}[A-Z]$/
227
+ },
228
+ {
229
+ name: "mi",
230
+ modelRegExp: /^2\d{7}[A-Z]{2,3}$/
231
+ },
232
+ {
233
+ name: "samsung",
234
+ modelRegExp: /^S(?:M|[CGP]H)-[A-Za-z0-9]+$/
235
+ },
236
+ {
237
+ name: "samsung",
238
+ modelRegExp: /^SCV3\d$/
239
+ },
240
+ {
241
+ name: "samsung",
242
+ modelRegExp: /^SC-\d{2}[A-Z]$/
243
+ },
244
+ {
245
+ name: "samsung",
246
+ modelRegExp: /^SH[WV]-/
247
+ },
248
+ {
249
+ name: "samsung",
250
+ modelRegExp: /^GT[-_][A-Z][A-Z0-9]{3,}$/i
251
+ },
252
+ {
253
+ name: "oppo",
254
+ modelRegExp: /^(?:CPH|OPD|iPA)\d{4}$/
255
+ },
256
+ {
257
+ name: "oppo",
258
+ modelRegExp: /^OPG\d{2}$/
259
+ },
260
+ {
261
+ name: "oppo",
262
+ modelRegExp: /^A[1-5]0[1-9]OP$/
263
+ },
264
+ {
265
+ name: "oneplus",
266
+ modelRegExp: /^(?:KB|HD|IN|GM|NE|LE|MT)\d{4}$/
267
+ },
268
+ {
269
+ name: "vivo",
270
+ modelRegExp: /^V[12]\d{3}[A-Z]{0,2}$/
271
+ }
272
+ ], u = {
273
+ ipod: "isIPod",
274
+ iphone: "isIPhone",
275
+ ipad: "isIPad",
276
+ huawei: "isHuawei",
277
+ mi: "isMi",
278
+ oppo: "isOppo",
279
+ vivo: "isVivo",
280
+ oneplus: "isOnePlus",
281
+ samsung: "isSamsung"
282
+ }, d = class {
283
+ constructor(e, t) {
284
+ this.isHuawei = !1, this.isMi = !1, this.isOppo = !1, this.isVivo = !1, this.isOnePlus = !1, this.isSamsung = !1, this.isIPod = !1, this.isIPhone = !1, this.isIPad = !1, this.isMac = !1, this.isApple = !1;
285
+ let r;
286
+ if (t.isIOS ? (r = c, this.isApple = !0) : t.isMacOS ? (this.isMac = !0, this.isApple = !0) : (t.isAndroid || t.isOpenHarmony) && (r = l), r) {
287
+ let i = n(e, r);
288
+ i ? this[u[i.name]] = !0 : t.isIOS && (this.isIPad = !0);
289
+ }
290
+ Object.freeze(this);
291
+ }
292
+ }, f = [
293
+ {
294
+ name: "edge",
295
+ regExp: /\bEdge\/([\d.]+)/
296
+ },
297
+ {
298
+ name: "chrome",
299
+ regExp: /\b(?:Chrome|CrMo|CriOS)\/([\d.]+)/
300
+ },
301
+ {
302
+ name: "safari",
303
+ regExp: /\b(?:Version\/([\d.]+).*\s?)?Safari\b/
304
+ },
305
+ {
306
+ name: "ie",
307
+ regExp: /\bMSIE\s(\d+)/i
308
+ },
309
+ {
310
+ name: "ie",
311
+ regExp: /\bTrident\/.*;\srv:(\d+)/
312
+ },
313
+ {
314
+ name: "firefox",
315
+ regExp: /\bFirefox\/([\d.]+)/
316
+ },
317
+ {
318
+ name: "opera-presto",
319
+ regExp: /\bOpera\/([\d.]+)/
320
+ }
321
+ ], p = {
322
+ chrome: "isChrome",
323
+ safari: "isSafari",
324
+ edge: "isEdge",
325
+ ie: "isIE",
326
+ firefox: "isFirefox",
327
+ "opera-presto": "isPrestoOpera"
328
+ }, m = class {
329
+ constructor(e) {
330
+ this.isChrome = !1, this.isSafari = !1, this.isEdge = !1, this.isIE = !1, this.isFirefox = !1, this.isPrestoOpera = !1;
331
+ let t = n(e, f);
332
+ t ? (this[p[t.name]] = !0, this.version = new a(t.version)) : this.version = new a(""), Object.freeze(this);
333
+ }
334
+ }, h = [
335
+ {
336
+ name: "wxwork",
337
+ regExp: /\bwxwork\/([\d.]+)/
338
+ },
339
+ {
340
+ name: "wx",
341
+ regExp: /\bMicroMessenger\/([\d.]+)/
342
+ },
343
+ {
344
+ name: "ding",
345
+ regExp: /\bDingTalk\/([\d.]+)/
346
+ },
347
+ {
348
+ name: "qq",
349
+ regExp: /\bQQ\/([\d.]+)/
350
+ },
351
+ {
352
+ name: "qq",
353
+ regExp: /\bIPadQQ\b/
354
+ },
355
+ {
356
+ name: "weibo",
357
+ regExp: /(?:\b|_)Weibo(?:\b|_)/i
358
+ },
359
+ {
360
+ name: "edge",
361
+ regExp: /\bEdge?\/([\d.]+)/
362
+ },
363
+ {
364
+ name: "opera-blink",
365
+ regExp: /\bOPR\/([\d.]+)/
366
+ },
367
+ {
368
+ name: "qqbrowser",
369
+ regExp: /\bM?QQBrowser(?:\/([\d.]+))?/i
370
+ },
371
+ {
372
+ name: "ucbrowser",
373
+ regExp: /\b(?:UCBrowser|UCWEB)(?:-CMCC)?\/?\s?([\d.]+)/
374
+ },
375
+ {
376
+ name: "ucbrowser",
377
+ regExp: /\bUC\b/
378
+ },
379
+ {
380
+ name: "quark",
381
+ regExp: /\bQuark\/([\d.]+)/
382
+ },
383
+ {
384
+ name: "maxthon",
385
+ regExp: /\b(?:Maxthon|MxBrowser)(?:[/\s]([\d.]+))?/
386
+ },
387
+ {
388
+ name: "theworld",
389
+ regExp: /\bTheWorld(?:\s([\d.]+))?/i
390
+ },
391
+ {
392
+ name: "baidubrowser",
393
+ regExp: /\b(?:baidubrowser|bdbrowser_i18n|BIDUBrowser)(?:[/\s]([\d.]+))?/i
394
+ },
395
+ {
396
+ name: "baidubrowser",
397
+ regExp: /\bbaidubrowserpad\b/
398
+ },
399
+ {
400
+ name: "baiduapp",
401
+ regExp: /\bbaiduboxapp\b\/([\d.]+)?/i
402
+ },
403
+ {
404
+ name: "baiduapp",
405
+ regExp: /\bbaiduboxpad\b/i
406
+ }
407
+ ];
408
+ h = h.concat(f);
409
+ //#endregion
410
+ //#region src/client-info.ts
411
+ var g = {
412
+ wxwork: "isWxWork",
413
+ wx: "isWx",
414
+ ding: "isDing",
415
+ qq: "isQQ",
416
+ weibo: "isWeibo",
417
+ edge: "isEdge",
418
+ "opera-blink": "isOpera",
419
+ "opera-presto": "isOpera",
420
+ qqbrowser: "isQQBrowser",
421
+ ucbrowser: "isUCBrowser",
422
+ quark: "isQuark",
423
+ maxthon: "isMaxthon",
424
+ theworld: "isTheWorld",
425
+ baidubrowser: "isBaiduBrowser",
426
+ baiduapp: "isBaiduApp",
427
+ chrome: "isChrome",
428
+ safari: "isSafari",
429
+ ie: "isIE",
430
+ firefox: "isFirefox"
431
+ }, _ = class {
432
+ constructor(e) {
433
+ this.isWxWork = !1, this.isWx = !1, this.isWxMiniProgram = !1, this.isDing = !1, this.isQQ = !1, this.isWeibo = !1, this.isEdge = !1, this.isOpera = !1, this.isQQBrowser = !1, this.isUCBrowser = !1, this.isQuark = !1, this.isMaxthon = !1, this.isTheWorld = !1, this.isBaiduBrowser = !1, this.isBaiduApp = !1, this.isChrome = !1, this.isSafari = !1, this.isIE = !1, this.isFirefox = !1;
434
+ let t = n(e, h);
435
+ t ? (this[g[t.name]] = !0, this.version = new a(t.version)) : this.version = new a(""), this.isWxMiniProgram = (this.isWx || this.isWxWork) && /\bMiniProgramEnv\b/.test(e), Object.freeze(this);
436
+ }
437
+ }, v = class {
438
+ constructor(e, t) {
439
+ if (this.os = Object.freeze(new s(e, t)), this.brand = Object.freeze(new d(e, this.os)), this.browser = Object.freeze(new m(e)), this.client = Object.freeze(new _(e)), this.isTabletLike = this.isTablet = this.brand.isIPad || /\bTablet\b/i.test(e) || this.os.isAndroid && !/\bMobile\b/i.test(e), !this.isTabletLike && (this.os.isAndroid || this.os.isOpenHarmony) && t) {
440
+ let e = t.screenWidth ?? 0, n = t.screenHeight ?? 0, r = t.dpr ?? 0;
441
+ if (e > 0 && n > 0 && r > 0) {
442
+ let t = Math.max(e, n), i = Math.min(e, n);
443
+ this.isTabletLike = t / i < 1.8 && i * r >= 1200;
444
+ }
445
+ }
446
+ this.os.isIOS || this.os.isAndroid || this.isTablet ? this.isPortable = !0 : /\(X11[;)]/i.test(e) || this.os.isWindows || this.os.isMacOS ? this.isPortable = !1 : this.isPortable = /mobile|android/i.test(e), Object.freeze(this);
447
+ }
448
+ }, y;
449
+ function b() {
450
+ return y ||= Object.freeze(typeof window < "u" ? new v(window.navigator.userAgent, {
451
+ maxTouchPoints: window.navigator.maxTouchPoints,
452
+ screenWidth: window.screen.width,
453
+ screenHeight: window.screen.height,
454
+ dpr: window.devicePixelRatio
455
+ }) : new v("")), y;
456
+ }
457
+ //#endregion
458
+ export { d as BrandInfo, m as BrowserInfo, _ as ClientInfo, s as OSInfo, v as UAInfo, a as Version, b as getCurrentUAInfo };
@@ -0,0 +1,9 @@
1
+ import { IRule } from './types';
2
+ /**
3
+ * 苹果设备匹配规则。
4
+ */
5
+ export declare const appleRules: IRule[];
6
+ /**
7
+ * 安卓设备匹配规则。
8
+ */
9
+ export declare const androidRules: IRule[];
@@ -0,0 +1,5 @@
1
+ import { IRule } from './types';
2
+ /**
3
+ * 浏览器内核匹配规则。
4
+ */
5
+ export declare const browserRules: IRule[];
@@ -0,0 +1,6 @@
1
+ import { IRule } from './types';
2
+ /**
3
+ * 客户端匹配规则。
4
+ */
5
+ declare let clientRules: IRule[];
6
+ export { clientRules };
@@ -0,0 +1,5 @@
1
+ import { IRule } from './types';
2
+ /**
3
+ * 操作系统匹配规则。
4
+ */
5
+ export declare const osRules: IRule[];
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 内部类型与接口。
3
+ * @packageDocumentation
4
+ * @internal
5
+ */
6
+ /**
7
+ * User-Agent 分析结果。
8
+ */
9
+ export interface IMatchResult {
10
+ /**
11
+ * 结果的名称。
12
+ */
13
+ name: string;
14
+ /**
15
+ * 结果的版本号。
16
+ */
17
+ version?: string;
18
+ }
19
+ /**
20
+ * 匹配规则。
21
+ */
22
+ export interface IRule {
23
+ /**
24
+ * 匹配结果名称。
25
+ */
26
+ name: string;
27
+ /**
28
+ * 正则表达式(优先级最高)。
29
+ */
30
+ regExp?: RegExp;
31
+ /**
32
+ * 关键词列表(优先级中)。
33
+ */
34
+ keywords?: string[];
35
+ /**
36
+ * 机型正则表达式(优先级低)。
37
+ */
38
+ modelRegExp?: RegExp;
39
+ }
@@ -0,0 +1,8 @@
1
+ import { IMatchResult, IRule } from './types';
2
+ /**
3
+ * 执行匹配。
4
+ * @param ua User agent 字符串。
5
+ * @param rules 匹配规则。
6
+ * @return 匹配结果。
7
+ */
8
+ export declare function execRules(ua: string, rules: IRule[]): IMatchResult | undefined;
package/os-info.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { Version } from './version';
2
+ import { IFeatureInfo } from './types';
3
+ /**
4
+ * 操作系统信息类。
5
+ */
6
+ export declare class OSInfo {
7
+ /**
8
+ * 是否苹果 iOS。
9
+ */
10
+ readonly isIOS: boolean;
11
+ /**
12
+ * 是否安卓。
13
+ */
14
+ readonly isAndroid: boolean;
15
+ /**
16
+ * 是否鸿蒙。
17
+ */
18
+ readonly isHarmonyOS: boolean;
19
+ /**
20
+ * 是否 OpenHarmony。
21
+ */
22
+ readonly isOpenHarmony: boolean;
23
+ /**
24
+ * 是否微软 Windows。
25
+ */
26
+ readonly isWindows: boolean;
27
+ /**
28
+ * 是否苹果 macOS 或 OSX。
29
+ */
30
+ readonly isMacOS: boolean;
31
+ /**
32
+ * 操作系统版本号。
33
+ */
34
+ readonly version: Readonly<Version>;
35
+ /**
36
+ * 操作系统信息类构造函数。
37
+ * @param ua User agent 字符串。
38
+ * @param featureInfo 设备特性信息。
39
+ */
40
+ constructor(ua: string, featureInfo?: Readonly<IFeatureInfo>);
41
+ }
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@polyv/utils-ua-info",
3
+ "version": "3.0.0",
4
+ "description": "User agent utilities for Polyv frontend development.",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "module": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "miniprogram": "./",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./index.d.ts",
13
+ "import": "./index.js",
14
+ "require": "./index.cjs"
15
+ }
16
+ },
17
+ "sideEffects": false
18
+ }
package/types.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * 外部可调用的类型与接口。
3
+ * @packageDocumentation
4
+ */
5
+ /**
6
+ * 设备特性信息。
7
+ */
8
+ export interface IFeatureInfo {
9
+ /**
10
+ * 触摸屏最大触点数,可传入 navigator.maxTouchPoints。
11
+ */
12
+ maxTouchPoints?: number | undefined;
13
+ /**
14
+ * 屏幕宽度,可传入 window.screen.width
15
+ */
16
+ screenWidth?: number;
17
+ /**
18
+ * 屏幕高度,可传入 window.screen.height
19
+ */
20
+ screenHeight?: number;
21
+ /**
22
+ * 物理像素与逻辑像素的比值,可传入 window.devicePixelRatio
23
+ */
24
+ dpr?: number;
25
+ }
package/ua-info.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { OSInfo } from './os-info';
2
+ import { BrandInfo } from './brand-info';
3
+ import { BrowserInfo } from './browser-info';
4
+ import { ClientInfo } from './client-info';
5
+ import { IFeatureInfo } from './types';
6
+ /**
7
+ * User agent 信息类。
8
+ */
9
+ export declare class UAInfo {
10
+ /**
11
+ * 操作系统信息。
12
+ */
13
+ readonly os: Readonly<OSInfo>;
14
+ /**
15
+ * 品牌信息。
16
+ */
17
+ readonly brand: Readonly<BrandInfo>;
18
+ /**
19
+ * 浏览器内核信息。
20
+ */
21
+ readonly browser: Readonly<BrowserInfo>;
22
+ /**
23
+ * 客户端信息。
24
+ */
25
+ readonly client: Readonly<ClientInfo>;
26
+ /**
27
+ * 是否便携设备。
28
+ */
29
+ readonly isPortable: boolean;
30
+ /**
31
+ * 是否平板设备。
32
+ */
33
+ readonly isTablet: boolean;
34
+ /**
35
+ * 是否为类平板设备。
36
+ */
37
+ readonly isTabletLike: boolean;
38
+ /**
39
+ * 设备信息类构造函数。
40
+ * @param ua User agent 字符串。
41
+ * @param featureInfo 设备特性信息。
42
+ */
43
+ constructor(ua: string, featureInfo?: Readonly<IFeatureInfo>);
44
+ }
package/version.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * 版本号信息。
3
+ * @packageDocumentation
4
+ */
5
+ /**
6
+ * 版本号对比。
7
+ * @param verA 待比较版本 A。
8
+ * @param verB 待比较版本 B。
9
+ * @return 大于 0 时,表示版本 A 大于版本 B;
10
+ * 小于 0 时,表示版本 B 大于版本 A;
11
+ * 等于 0 时,表示两个版本号一致。
12
+ */
13
+ export declare function compareVersions(verA: string, verB: string): number;
14
+ /**
15
+ * 版本号类。
16
+ */
17
+ export declare class Version {
18
+ /**
19
+ * 版本号字符串。
20
+ */
21
+ protected readonly _ver: string;
22
+ /**
23
+ * 版本号类构造函数
24
+ * @param ver 版本号字符串。
25
+ */
26
+ constructor(ver: string | undefined | null);
27
+ /**
28
+ * 当前版本号与指定版本号对比。
29
+ * @param cmpVer 指定版本号。
30
+ * @param suposed 预期结果。
31
+ * @returns 对比结果是否与预期结果一致。
32
+ */
33
+ protected _compare(cmpVer: string, suposed: number | number[]): boolean;
34
+ /**
35
+ * 判断当前版本号是否大于指定版本号。
36
+ * @param cmpVer 指定版本号。
37
+ * @returns 当前版本号是否大于指定版本号。
38
+ */
39
+ gt(cmpVer: string): boolean;
40
+ /**
41
+ * 判断当前版本号是否大于等于指定版本号。
42
+ * @param cmpVer 指定版本号。
43
+ * @returns 当前版本号是否大于等于指定版本号。
44
+ */
45
+ gte(cmpVer: string): boolean;
46
+ /**
47
+ * 判断当前版本号是否小于指定版本号。
48
+ * @param cmpVer 指定版本号。
49
+ * @returns 当前版本号是否小于指定版本号。
50
+ */
51
+ lt(cmpVer: string): boolean;
52
+ /**
53
+ * 判断当前版本号是否小于等于指定版本号。
54
+ * @param cmpVer 指定版本号。
55
+ * @returns 当前版本号是否小于等于指定版本号。
56
+ */
57
+ lte(cmpVer: string): boolean;
58
+ /**
59
+ * 判断当前版本号是否与指定版本号相等。
60
+ * @param cmpVer 指定版本号。
61
+ * @returns 当前版本号是否与指定版本号相等。
62
+ */
63
+ eq(cmpVer: string): boolean;
64
+ /**
65
+ * 返回版本的字符串表示。
66
+ * @returns 版本的字符串表示。
67
+ */
68
+ toString(): string;
69
+ }