@tomo-inc/wallet-utils 0.0.2
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.
- package/CHANGELOG.md +3 -0
- package/README.md +14 -0
- package/package.json +30 -0
- package/project.json +59 -0
- package/src/broswer.ts +38 -0
- package/src/cache.ts +120 -0
- package/src/email.ts +26 -0
- package/src/global-config.ts +79 -0
- package/src/index.ts +34 -0
- package/src/password.ts +6 -0
- package/src/string.ts +88 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +15 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tomo-inc/wallet-utils",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"author": "tomo.inc",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"private": false,
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"uuid": "13.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^20.0.0",
|
|
23
|
+
"tsup": "^8.0.0",
|
|
24
|
+
"typescript": "^5.0.0",
|
|
25
|
+
"vitest": "^3.2.4"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/project.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wallet-utils",
|
|
3
|
+
"sourceRoot": "packages/wallet-utils/src",
|
|
4
|
+
"projectType": "library",
|
|
5
|
+
"targets": {
|
|
6
|
+
"build": {
|
|
7
|
+
"executor": "nx:run-commands",
|
|
8
|
+
"outputs": ["{projectRoot}/dist"],
|
|
9
|
+
"options": {
|
|
10
|
+
"command": "tsup src/index.ts --format esm,cjs --dts --treeshake",
|
|
11
|
+
"cwd": "packages/wallet-utils"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dev": {
|
|
15
|
+
"executor": "nx:run-commands",
|
|
16
|
+
"options": {
|
|
17
|
+
"command": "tsup src/index.ts --format esm,cjs --watch --dts",
|
|
18
|
+
"cwd": "packages/wallet-utils"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"lint": {
|
|
22
|
+
"executor": "nx:run-commands",
|
|
23
|
+
"options": {
|
|
24
|
+
"command": "eslint src/**/*.ts",
|
|
25
|
+
"cwd": "packages/wallet-utils"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"lint:fix": {
|
|
29
|
+
"executor": "nx:run-commands",
|
|
30
|
+
"options": {
|
|
31
|
+
"command": "eslint src/**/*.ts --fix",
|
|
32
|
+
"cwd": "packages/wallet-utils"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"format": {
|
|
36
|
+
"executor": "nx:run-commands",
|
|
37
|
+
"options": {
|
|
38
|
+
"command": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
39
|
+
"cwd": "packages/wallet-utils"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"test": {
|
|
43
|
+
"executor": "nx:run-commands",
|
|
44
|
+
"outputs": ["{projectRoot}/coverage"],
|
|
45
|
+
"options": {
|
|
46
|
+
"command": "vitest run",
|
|
47
|
+
"cwd": "packages/wallet-utils"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"test:watch": {
|
|
51
|
+
"executor": "nx:run-commands",
|
|
52
|
+
"options": {
|
|
53
|
+
"command": "vitest",
|
|
54
|
+
"cwd": "packages/wallet-utils"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"tags": ["npm:public", "scope:wallet-utils", "type:library"]
|
|
59
|
+
}
|
package/src/broswer.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const getBrowserName = (): string => {
|
|
2
|
+
if (typeof window === "undefined") {
|
|
3
|
+
return "";
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const userAgent = window.navigator.userAgent;
|
|
7
|
+
|
|
8
|
+
// Safari (must be checked before Chrome as Chrome also includes Safari in userAgent)
|
|
9
|
+
if (userAgent.includes("Safari/") && !userAgent.includes("Chrome/")) {
|
|
10
|
+
return "Safari";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (userAgent.includes("Edg/")) {
|
|
14
|
+
return "Edge";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (userAgent.includes("Firefox/")) {
|
|
18
|
+
return "Firefox";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Chrome (check after other Chromium-based browsers)
|
|
22
|
+
if (userAgent.includes("Chrome/")) {
|
|
23
|
+
return "Chrome";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const brave = (window.navigator as any)?.brave;
|
|
27
|
+
if (brave?.isBrave?.()) {
|
|
28
|
+
return "Brave";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Opera
|
|
32
|
+
if (userAgent.includes("Opera/") || userAgent.includes("OPR/")) {
|
|
33
|
+
return "Opera";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Default fallback
|
|
37
|
+
return "";
|
|
38
|
+
};
|
package/src/cache.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/*
|
|
2
|
+
1: JSON.stringfy --> set --> get --> JSON.parse
|
|
3
|
+
2: data format well return as set`s
|
|
4
|
+
3: undefined in array will be null after stringfy+parse
|
|
5
|
+
4: NS --> namespace
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
//key += account id
|
|
9
|
+
let keyNS = "tomo-";
|
|
10
|
+
|
|
11
|
+
function get(key: string) {
|
|
12
|
+
/*
|
|
13
|
+
legal data: "" [] {} null flase true
|
|
14
|
+
|
|
15
|
+
illegal: undefined
|
|
16
|
+
1: key not set
|
|
17
|
+
2: key is cleared
|
|
18
|
+
3: key removed
|
|
19
|
+
4: wrong data format
|
|
20
|
+
*/
|
|
21
|
+
// Check if we're in a browser environment
|
|
22
|
+
if (typeof window === "undefined") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const tempKey = keyNS + key;
|
|
27
|
+
if (!isKeyExist(tempKey)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
// maybe keyNS could avoid conflict
|
|
31
|
+
let val: { data: any; type: string } | null = null;
|
|
32
|
+
try {
|
|
33
|
+
const data: any = window.localStorage.getItem(tempKey) || window.sessionStorage.getItem(tempKey);
|
|
34
|
+
val = JSON.parse(data);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.error(err);
|
|
37
|
+
}
|
|
38
|
+
// val format check
|
|
39
|
+
if (
|
|
40
|
+
val !== null &&
|
|
41
|
+
Object.prototype.hasOwnProperty.call(val, "type") &&
|
|
42
|
+
Object.prototype.hasOwnProperty.call(val, "data")
|
|
43
|
+
) {
|
|
44
|
+
return val["data"];
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
// isPersistent
|
|
49
|
+
function set(key: string, val: any, isTemp: boolean) {
|
|
50
|
+
// Check if we're in a browser environment
|
|
51
|
+
if (typeof window === "undefined") {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let store;
|
|
56
|
+
if (isTemp) {
|
|
57
|
+
store = window.sessionStorage;
|
|
58
|
+
} else {
|
|
59
|
+
store = window.localStorage;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const data = JSON.stringify({
|
|
63
|
+
data: val,
|
|
64
|
+
time: new Date().getTime(), //for manage by time limit
|
|
65
|
+
type: typeof val,
|
|
66
|
+
});
|
|
67
|
+
try {
|
|
68
|
+
store.setItem(keyNS + key, data);
|
|
69
|
+
return true;
|
|
70
|
+
} catch (err: any) {
|
|
71
|
+
if (err?.name?.toUpperCase().indexOf("QUOTA") >= 0) {
|
|
72
|
+
window.localStorage.clear();
|
|
73
|
+
store.setItem(keyNS + key, data);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function remove(key: string) {
|
|
80
|
+
// Check if we're in a browser environment
|
|
81
|
+
if (typeof window === "undefined") {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const tempKey = keyNS + key;
|
|
86
|
+
window.localStorage.removeItem(tempKey);
|
|
87
|
+
window.sessionStorage.removeItem(tempKey);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function clear() {
|
|
91
|
+
// Check if we're in a browser environment
|
|
92
|
+
if (typeof window === "undefined") {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
window?.localStorage?.clear();
|
|
97
|
+
window?.sessionStorage?.clear();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function isKeyExist(key: string) {
|
|
101
|
+
// Check if we're in a browser environment
|
|
102
|
+
if (typeof window === "undefined") {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// do not depend on value cause of "",0
|
|
107
|
+
return (
|
|
108
|
+
Object.prototype.hasOwnProperty.call(window.localStorage, key) ||
|
|
109
|
+
Object.prototype.hasOwnProperty.call(window.sessionStorage, key)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function setKeyNS(NS: string) {
|
|
114
|
+
const isString = typeof NS === "string";
|
|
115
|
+
if (isString && NS !== "") {
|
|
116
|
+
keyNS = NS;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export { clear, get, remove, set, setKeyNS };
|
package/src/email.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const maskEmail = (email: string) => {
|
|
2
|
+
if (!email) {
|
|
3
|
+
return;
|
|
4
|
+
}
|
|
5
|
+
const parts = email.split("@");
|
|
6
|
+
|
|
7
|
+
if (parts.length === 2) {
|
|
8
|
+
let username = parts[0];
|
|
9
|
+
const domain = parts[1];
|
|
10
|
+
|
|
11
|
+
if (username.length >= 4) {
|
|
12
|
+
username = username.slice(0, -3) + "***";
|
|
13
|
+
} else {
|
|
14
|
+
username = username + "*".repeat(4 - username.length);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const maskedEmail = `${username}@${domain}`;
|
|
18
|
+
return maskedEmail;
|
|
19
|
+
} else {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const isEmail = (email: string) => {
|
|
25
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
26
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export enum ChainTypes {
|
|
2
|
+
BTC = "btc",
|
|
3
|
+
DOGE = "doge",
|
|
4
|
+
EVM = "evm",
|
|
5
|
+
SOL = "sol",
|
|
6
|
+
SUI = "sui",
|
|
7
|
+
TON = "ton",
|
|
8
|
+
TRON = "tron",
|
|
9
|
+
COSMOS = "cosmos",
|
|
10
|
+
APTOS = "aptos",
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ChainTypeConfig {
|
|
14
|
+
chainId?: string;
|
|
15
|
+
chainIndex?: number;
|
|
16
|
+
support: boolean;
|
|
17
|
+
gasFee: number;
|
|
18
|
+
dust: number;
|
|
19
|
+
reserve?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const SupportedChainTypes: Record<ChainTypes, ChainTypeConfig> = {
|
|
23
|
+
[ChainTypes.DOGE]: {
|
|
24
|
+
chainId: "3",
|
|
25
|
+
chainIndex: 300,
|
|
26
|
+
support: true,
|
|
27
|
+
gasFee: 0.5,
|
|
28
|
+
dust: 0.0001,
|
|
29
|
+
},
|
|
30
|
+
[ChainTypes.EVM]: {
|
|
31
|
+
chainId: "1",
|
|
32
|
+
chainIndex: 100,
|
|
33
|
+
support: true,
|
|
34
|
+
gasFee: 0.00001,
|
|
35
|
+
dust: 0,
|
|
36
|
+
},
|
|
37
|
+
[ChainTypes.SOL]: {
|
|
38
|
+
chainId: "501",
|
|
39
|
+
chainIndex: 50100,
|
|
40
|
+
support: true,
|
|
41
|
+
gasFee: 0.0001,
|
|
42
|
+
dust: 0,
|
|
43
|
+
reserve: 0.0009, // Available balance = Total balance - Reserve balance (for rent exemption)
|
|
44
|
+
},
|
|
45
|
+
[ChainTypes.TRON]: {
|
|
46
|
+
chainId: "19484",
|
|
47
|
+
chainIndex: 1948400,
|
|
48
|
+
support: true,
|
|
49
|
+
gasFee: 0.5,
|
|
50
|
+
dust: 0,
|
|
51
|
+
},
|
|
52
|
+
[ChainTypes.BTC]: {
|
|
53
|
+
chainId: "0", //livenet
|
|
54
|
+
chainIndex: 0,
|
|
55
|
+
support: false,
|
|
56
|
+
gasFee: 0.00001,
|
|
57
|
+
dust: 0.0001,
|
|
58
|
+
},
|
|
59
|
+
[ChainTypes.SUI]: {
|
|
60
|
+
support: false,
|
|
61
|
+
gasFee: 0,
|
|
62
|
+
dust: 0,
|
|
63
|
+
},
|
|
64
|
+
[ChainTypes.TON]: {
|
|
65
|
+
support: false,
|
|
66
|
+
gasFee: 0,
|
|
67
|
+
dust: 0,
|
|
68
|
+
},
|
|
69
|
+
[ChainTypes.COSMOS]: {
|
|
70
|
+
support: false,
|
|
71
|
+
gasFee: 0,
|
|
72
|
+
dust: 0,
|
|
73
|
+
},
|
|
74
|
+
[ChainTypes.APTOS]: {
|
|
75
|
+
support: false,
|
|
76
|
+
gasFee: 0,
|
|
77
|
+
dust: 0,
|
|
78
|
+
},
|
|
79
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as cache from "./cache";
|
|
2
|
+
export { cache };
|
|
3
|
+
|
|
4
|
+
export * from "./broswer";
|
|
5
|
+
export * from "./email";
|
|
6
|
+
export * from "./global-config";
|
|
7
|
+
export * from "./password";
|
|
8
|
+
export * from "./string";
|
|
9
|
+
|
|
10
|
+
export type TomoStage = "prod" | "pre" | "dev";
|
|
11
|
+
export type CubeStage = "gamma" | "prod";
|
|
12
|
+
export const CubeStages = {
|
|
13
|
+
prod: "prod",
|
|
14
|
+
pre: "prod",
|
|
15
|
+
dev: "gamma",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const CubeOrgIds = {
|
|
19
|
+
prod: "Org#49944bce-9daf-423f-a982-269f6d0d301b",
|
|
20
|
+
pre: "Org#71c13f6d-b992-4660-874d-2ae0fadc789f",
|
|
21
|
+
dev: "Org#3d07a75a-1188-4bd0-acfa-671a198b83eb",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const RelayOrigins = {
|
|
25
|
+
prod: "https://social-relay.tomo.inc",
|
|
26
|
+
pre: "https://social-relay.tomo.inc",
|
|
27
|
+
dev: "https://social-relay-dev.tomo.inc",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const TomoApiDomains = {
|
|
31
|
+
prod: "https://wallet-pro.tomo.inc",
|
|
32
|
+
pre: "https://wallet-pre-wlfi.tomo.inc",
|
|
33
|
+
dev: "https://wallet-test.tomo.inc",
|
|
34
|
+
};
|
package/src/password.ts
ADDED
package/src/string.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export function stripHexPrefix(str: string) {
|
|
2
|
+
if (typeof str !== "string") {
|
|
3
|
+
return str;
|
|
4
|
+
}
|
|
5
|
+
return str.startsWith("0x") ? str.slice(2) : str;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function compareString(a: string, b: string) {
|
|
9
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function subs(temp: string, data: any, regexp?: RegExp) {
|
|
13
|
+
if (!(Object.prototype.toString.call(data) === "[object Array]")) data = [data];
|
|
14
|
+
const ret = [];
|
|
15
|
+
for (let i = 0, j = data.length; i < j; i++) {
|
|
16
|
+
ret.push(replaceAction(data[i]));
|
|
17
|
+
}
|
|
18
|
+
return ret.join("");
|
|
19
|
+
function replaceAction(object: any) {
|
|
20
|
+
return temp.replace(regexp || /\\?\{([^}]+)\}/g, function (match, name) {
|
|
21
|
+
if (match.charAt(0) == "\\") return match.slice(1);
|
|
22
|
+
return object[name] != undefined ? object[name] : "";
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getExplorerUrl(chainIndex: number, data: { txId: string }) {
|
|
28
|
+
const linkTpls = {
|
|
29
|
+
"0": "",
|
|
30
|
+
"100": "https://etherscan.io/tx/{txId}",
|
|
31
|
+
"300": "https://dogechain.info/tx/{txId}",
|
|
32
|
+
"400": "",
|
|
33
|
+
"1000": "https://optimistic.etherscan.io/tx/{txId}",
|
|
34
|
+
"5600": "https://bscscan.com/tx/{txId}",
|
|
35
|
+
"12600": "https://explorer.movementnetwork.xyz/txn/{txId}?network=mainnet",
|
|
36
|
+
"13700": "https://polygonscan.com/tx/{txId}",
|
|
37
|
+
"20400": "https://opbnb.bscscan.com/tx/{txId}",
|
|
38
|
+
"22300": "https://explorer.bsquared.network/tx/{txId}",
|
|
39
|
+
"22700": "https://promscan.io/tx/{txId}",
|
|
40
|
+
"32400": "https://mainnet.era.zksync.io/tx/{txId}",
|
|
41
|
+
"48000": "https://worldchain-mainnet.explorer.alchemy.com/tx/{txId}",
|
|
42
|
+
"50100": "https://solscan.io/tx/{txId}",
|
|
43
|
+
"78400": "",
|
|
44
|
+
"110000": "",
|
|
45
|
+
"132900": "https://seitrace.com/tx/{txId}",
|
|
46
|
+
"151400": "https://mainnet.storyscan.xyz/tx/{txId}",
|
|
47
|
+
"162500": "https://explorer.gravity.xyz/tx/{txId}",
|
|
48
|
+
"264900": "https://mainnet-explorer.ailayer.xyz/tx/{txId}",
|
|
49
|
+
"420000": "https://scan.merlinchain.io/tx/{txId}",
|
|
50
|
+
"554500": "https://scan.duckchain.io/tx/{txId}",
|
|
51
|
+
"833300": "https://mainnet-rpc.b3.fun/http/tx/{txId}",
|
|
52
|
+
"845300": "https://base.blockscout.com/tx/{txId}",
|
|
53
|
+
"1948400": "https://tronscan.org/#/transaction/{txId}",
|
|
54
|
+
"4216100": "https://arbiscan.io/tx/{txId}",
|
|
55
|
+
"4311400": "https://snowtrace.io/tx/{txId}",
|
|
56
|
+
"4776300": "https://neotube.io/transaction/{txId}",
|
|
57
|
+
"5914400": "https://lineascan.build/tx/{txId}",
|
|
58
|
+
"6080800": "https://rpc.gobob.xyz/tx/{txId}",
|
|
59
|
+
"8009400": "https://berascan.com/tx/{txId}",
|
|
60
|
+
"8145700": "https://blastscan.io/tx/{txId}",
|
|
61
|
+
"20090100": "https://rpc.bitlayer.org/tx/{txId}",
|
|
62
|
+
"53435200": "https://scrollscan.com/tx/{txId}",
|
|
63
|
+
"221122420": "https://blockscout.devnet.doge.xyz/tx/{txId}",
|
|
64
|
+
"2100000000": "https://maizenet-explorer.usecorn.com/tx/{txId}",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const key = chainIndex.toString() as keyof typeof linkTpls;
|
|
68
|
+
const linkTpl: string = linkTpls[key] || "";
|
|
69
|
+
if (linkTpl === "") {
|
|
70
|
+
throw new Error(`chainIndex ${chainIndex} tpl not found`);
|
|
71
|
+
}
|
|
72
|
+
return subs(linkTpl, data);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function calcCtrLength(str: string) {
|
|
76
|
+
let length = 0;
|
|
77
|
+
str = str.trim();
|
|
78
|
+
for (let i = 0; i < str.length; i++) {
|
|
79
|
+
const code = str.charCodeAt(i);
|
|
80
|
+
//chianese character: \u4e00-\u9fa5
|
|
81
|
+
if (code >= 0x4e00 && code <= 0x9fa5) {
|
|
82
|
+
length += 2;
|
|
83
|
+
} else {
|
|
84
|
+
length += 1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { len: length, originLen: str.length };
|
|
88
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2020", "DOM"],
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"baseUrl": "./src"
|
|
13
|
+
},
|
|
14
|
+
"include": ["src"]
|
|
15
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ["src/index.ts"],
|
|
5
|
+
format: ["esm", "cjs"],
|
|
6
|
+
dts: true,
|
|
7
|
+
treeshake: true,
|
|
8
|
+
clean: true,
|
|
9
|
+
platform: "browser",
|
|
10
|
+
outExtension({ format }) {
|
|
11
|
+
return {
|
|
12
|
+
js: format === "esm" ? ".js" : ".cjs",
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
});
|