Skip to content

Commit 4a669eb

Browse files
endinkendink
authored andcommitted
lint fix
1 parent 30b8a8b commit 4a669eb

File tree

11 files changed

+465
-99
lines changed

11 files changed

+465
-99
lines changed

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "infra-sdk-core",
3-
"version": "1.5.0",
3+
"version": "1.6.0",
44
"description": "A type script sdk for infra java spring server.",
55
"main": "lib/index.js",
66
"scripts": {
@@ -16,7 +16,7 @@
1616
"debug": "node --inspect-brk node_modules/.bin/jest --runInBand --no-cache --no-watchman",
1717
"debug-win": "node --inspect-brk ./node_modules/jest/bin/jest.js",
1818
"pretty": "prettier -c --write \"src/**\"",
19-
"gen":"webpack"
19+
"gen": "webpack"
2020
},
2121
"keywords": [
2222
"npm",
@@ -37,8 +37,9 @@
3737
},
3838
"homepage": "https://github.com/endink/infra-typescript-sdk",
3939
"dependencies": {
40-
"ali-oss": "^6.15.2",
41-
"umi-request": "^1.3.5"
40+
"ali-oss": "^6.16.0",
41+
"dayjs": "^1.10.7",
42+
"umi-request": "^1.4.0"
4243
},
4344
"devDependencies": {
4445
"@types/ali-oss": "^6.0.8",
@@ -54,7 +55,6 @@
5455
"html-webpack-plugin": "^5.3.1",
5556
"jest": "^26.6.3",
5657
"local-package-publisher": "^1.0.3",
57-
"moment": "^2.29.1",
5858
"pre-commit": "^1.2.2",
5959
"prettier": "^2.3.0",
6060
"source-map-loader": "^2.0.1",

src/minio/minio.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isNullOrEmptyString } from "../utils";
1+
import { isNullOrBlankString } from "../utils";
22
import { RequestResponse } from "umi-request";
33
import { AssumedCredentials, MinioConfig } from ".";
44
import { ExtendedRequestMethod, ExtendedRequestOptionsInit, initRequestNoneOAuth2 } from "../request";
@@ -94,7 +94,7 @@ export class MinioUtils {
9494

9595
public generateObjectUrl(key: string): string {
9696
const config = minioContext.config;
97-
if (config && !isNullOrEmptyString(config.publicBucket)) {
97+
if (config && !isNullOrBlankString(config.publicBucket)) {
9898
const file = key.startsWith("/") ? key.substr(1, key.length - 1) : key;
9999
if (config.port) {
100100
return `${config.schema}://${config.host}:${config.port}/${config.publicBucket}/${file}`;

src/oauth2/session.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { UserPrincipal, OAuth2AccessToken } from "./types";
22
import { OAuth2Session } from "../core";
3-
import { isNullOrEmptyString } from "../utils";
3+
import { isNullOrBlankString } from "../utils";
44

55
interface SaveObject {
66
token: OAuth2AccessToken;
@@ -82,11 +82,11 @@ function tokenToPrincipal(token: OAuth2AccessToken): UserPrincipal {
8282
},
8383

8484
get isAnonymous(): boolean {
85-
return isNullOrEmptyString(this.token?.user_id);
85+
return isNullOrBlankString(this.token?.user_id);
8686
},
8787

8888
hasRole(role: string): boolean {
89-
return isNullOrEmptyString(this.roles?.find((item) => item === role));
89+
return isNullOrBlankString(this.roles?.find((item) => item === role));
9090
},
9191

9292
hasAnyOfRoles(...roleNames: string[]): boolean {

src/request/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import {
77
RequestResponse
88
} from "umi-request";
99
import { RefreshTokenParam, OAuth2AccessToken, GrantTypes, LoginParam, CheckTokenResult } from "../oauth2";
10-
import { ErrorContext, CustomErrorHandler, RequestOptions } from "./types";
10+
import { ErrorContext, CustomErrorHandler, RequestOptions, RequestContext } from "./types";
1111
import { OAuth2Session, ApplicationError } from "../core";
1212
import { clientSession } from "../oauth2/session";
13-
import { notNullOrEmptyString } from "../utils";
13+
import { isNotNullOrBlankString } from "../utils";
1414

1515
const codeMessage = {
1616
200: "服务器成功返回请求的数据。",
@@ -33,7 +33,7 @@ const codeMessage = {
3333
function translateError(data: ApplicationError, response: Response, options: RequestOptions): ApplicationError {
3434
const { errorDescriber, httpCodeDescriber } = options;
3535
let msg: any;
36-
if (data !== undefined && notNullOrEmptyString(data.error)) {
36+
if (data !== undefined && isNotNullOrBlankString(data.error)) {
3737
const desc = errorDescriber ? errorDescriber[data.error!!] : data.error_description;
3838
msg = desc || `未处理错误: ${data.error}`;
3939
} else {
@@ -112,7 +112,7 @@ export type OAuth2RequestOptions = Omit<
112112
"data" | "method" | "headers" | "requestType" | "skipAuth"
113113
>;
114114

115-
const requestContext: Pick<RequestOptions, "accessTokenUrl" | "checkTokenUrl"> & { session?: OAuth2Session } = {
115+
const requestContext:RequestContext = {
116116
accessTokenUrl: "",
117117
checkTokenUrl: ""
118118
};
@@ -225,3 +225,5 @@ export function initRequest(options: RequestOptions, session?: OAuth2Session): E
225225

226226
return req;
227227
}
228+
229+

src/request/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ResponseError } from "umi-request";
2-
import { ToastAdapter } from "../core";
2+
import { OAuth2Session, ToastAdapter } from "../core";
33

44
export interface ErrorContext {
55
error: ResponseError;
@@ -22,3 +22,5 @@ export interface RequestOptions {
2222
errorHandlers?: CustomErrorHandler[];
2323
noneOAuth2?: boolean;
2424
}
25+
26+
export type RequestContext = Pick<RequestOptions, "accessTokenUrl" | "checkTokenUrl"> & { session?: OAuth2Session };

src/utils/array.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
2+
3+
export function maxValue<T>(data: T[], field: (item:T)=>number): number | undefined {
4+
if(data.length){
5+
let current = Number.MIN_VALUE;
6+
data.forEach(i=>{
7+
const filedValue = field(i);
8+
current = Math.max(filedValue, current);
9+
});
10+
return current;
11+
}
12+
return undefined;
13+
}
14+
15+
16+
17+
export function sum<T>(array: T[], getter: (item:T)=>number){
18+
let c = 0;
19+
for(const item of array){
20+
const v = getter(item);
21+
c += v;
22+
}
23+
return c;
24+
}
25+
26+
export function max<T>(array: T[], getter: (item:T)=>number): T | undefined{
27+
let item: T | undefined;
28+
if(array.length){
29+
let current = Number.MIN_VALUE;
30+
array.forEach(i=>{
31+
const filedValue = getter(i);
32+
if(filedValue > current){
33+
current = filedValue;
34+
item = i;
35+
}
36+
});
37+
return item;
38+
}
39+
return undefined;
40+
}
41+
42+
export function min<T>(array: T[], getter: (item:T)=>number): T | undefined{
43+
let item: T | undefined;
44+
if(array.length){
45+
let current = Number.MAX_VALUE;
46+
array.forEach(i=>{
47+
const filedValue = getter(i);
48+
if(filedValue < current){
49+
current = filedValue;
50+
item = i;
51+
}
52+
});
53+
return item;
54+
}
55+
return undefined;
56+
}
57+
58+
export interface GroupItem<T, TKey> {
59+
key: TKey,
60+
list: T[]
61+
}
62+
63+
export function groupBy<T, TKey extends string | number>(array: T[], getter:(item:T)=>TKey): GroupItem<T, TKey>[]{
64+
const group: GroupItem<T, TKey>[] = [];
65+
for(const item of array){
66+
const key = getter(item);
67+
if(key === undefined || key === null){
68+
throw new Error("group key can not be undefined or null");
69+
}
70+
const values = group.find(g=>g.key === key);
71+
if(values){
72+
values.list.push(item);
73+
}else{
74+
const newGroup: GroupItem<T, TKey> = { key, list:[] };
75+
newGroup.list.push(item);
76+
group.push(newGroup);
77+
}
78+
}
79+
return group;
80+
}
81+
82+
export function orderBy<T, TKey extends string | number>(array: T[], getter: (item:T)=>TKey): T[] {
83+
const rec = (arr: T[]) => {
84+
if(arr.length <= 1) {
85+
return arr;
86+
}
87+
const left: T[] = [];
88+
const right: T[] = [];
89+
const base = arr[0];
90+
// 因为基准线是arr[0],所以从下标是1也就是第二个开始
91+
for(let i = 1; i < arr.length; i += 1) {
92+
const ikey = getter(arr[i]);
93+
const baseKey = getter(base);
94+
95+
let r = 0;
96+
if(typeof ikey === "string"){
97+
r = ikey < (baseKey as string) ? -1 : 1
98+
}
99+
if(typeof ikey === "number"){
100+
r = ikey < (baseKey as number) ? -1 : 1
101+
}
102+
103+
if(r < 0) {
104+
left.push(arr[i])
105+
} else {
106+
right.push(arr[i])
107+
}
108+
}
109+
// 解构一下
110+
// 递归左边数组和右边数组
111+
// 左边加上右边加上基准才是完整数组哈
112+
return [...rec(left), base, ...rec(right)];
113+
}
114+
const res = rec(array);
115+
// 遍历res,赋值到this也就是当前数组本身
116+
res.forEach((item, key) => {
117+
array[key] = item;
118+
});
119+
120+
return array;
121+
}

src/utils/asynchronous.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
export function delay(ms: number): Promise<void> {
2+
return new Promise(resolve => {
3+
const timeout = setTimeout(() => {
4+
clearTimeout(timeout);
5+
resolve();
6+
}, ms)
7+
});
8+
}
9+
10+
async function retryCore<T=any>(
11+
action: ()=>T | Promise<T>,
12+
resolve: (value: T | PromiseLike<T>) => void,
13+
reject: (reason?: any) => void,
14+
retryIndex: number,
15+
retryCount: number,
16+
intervalMilss: number) {
17+
try{
18+
const v = await wrapPromise(()=>action());
19+
resolve(v);
20+
}catch(e){
21+
if((retryIndex + 1) < retryCount){
22+
await delay(intervalMilss);
23+
retryCore(action, resolve, reject, retryIndex + 1, retryCount, intervalMilss);
24+
}else{
25+
reject(e);
26+
}
27+
}
28+
}
29+
30+
export function retry<T=any>(action: ()=>T | Promise<T>, maxRetryCount: number, intervalMilss: number) : Promise<T> {
31+
return new Promise<T>((resolve, reject)=>{
32+
retryCore(action, resolve, reject, 0, maxRetryCount, intervalMilss);
33+
});
34+
}
35+
36+
export function isPromise(r: any) {
37+
return r && (r as Promise<any>).then !== undefined;
38+
}
39+
40+
export function wrapPromise<T = any>(action: () => T | Promise<T>): Promise<T> {
41+
let r: any;
42+
try {
43+
r = action();
44+
} catch (error) {
45+
return Promise.reject<T>(error);
46+
}
47+
if (isPromise(r)) {
48+
return r as Promise<T>;
49+
}
50+
return Promise.resolve<T>(r);
51+
}

src/utils/core.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import dayjs, { Dayjs } from "dayjs";
2+
3+
/* eslint no-useless-escape:0 import/prefer-default-export:0 */
4+
const regexUrl =
5+
/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
6+
const regexEmail =
7+
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
8+
const regexPositiveNumber = /^([0]*[1-9][0-9]*)(\.[0-9]*)?$/;
9+
const regexChineseMobileNumber =
10+
/^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\d{8}$/;
11+
12+
export const isUrl = (path: string): boolean => regexUrl.test(path);
13+
export const isEmail = (path: string): boolean => regexEmail.test(path);
14+
export const isPositiveNumber = (path: string): boolean => regexPositiveNumber.test(path);
15+
export const isChineseMobileNumber = (path: string): boolean => regexChineseMobileNumber.test(path);
16+
export function isPositiveInt(value?: string): boolean {
17+
return value !== undefined && /^\d+$/.test(value) && Number(value) > 0;
18+
}
19+
20+
export const rangeNumber = (from: number, to: number, step: number = 1) => [...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
21+
22+
export const isNullOrBlankString = (value?: any) =>
23+
typeof value !== "string" || value == null || value!!.trim().length === 0;
24+
25+
export const isNotNullOrBlankString = (value?: any) => !isNullOrBlankString(value);
26+
27+
export function generateUUID() {
28+
let d = new Date().getTime();
29+
const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
30+
const r = (d + Math.random() * 16) % 16 | 0;
31+
d = Math.floor(d / 16);
32+
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
33+
});
34+
return uuid;
35+
}
36+
37+
export function randomStr(len: number = 8) {
38+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
39+
const maxPos = chars.length
40+
let s = ""
41+
for (let i = 0; i < len; i++) {
42+
s += chars.charAt(Math.floor(Math.random() * maxPos))
43+
}
44+
return s
45+
}
46+
47+
48+
export type SessionCachedType<T> = {
49+
[P in keyof T]?: T[P];
50+
};
51+
52+
export class SessionCached<T> implements SessionCachedType<{ data: T; expired: number }> {
53+
constructor(public data: T, public expired: number) {}
54+
}
55+
56+
export async function getOrSetCached<T>(key: string, timeout: Dayjs, setter: () => Promise<T | undefined | null>) {
57+
const cached = sessionStorage.getItem(key);
58+
if (isNotNullOrBlankString(cached)) {
59+
let item: any;
60+
try {
61+
item = JSON.parse(cached as string) as SessionCached<T>;
62+
} catch (e) {
63+
console.warn(e);
64+
}
65+
if (item !== undefined && item.expired > dayjs()) {
66+
return item.data;
67+
} else {
68+
sessionStorage.removeItem(key);
69+
}
70+
}
71+
const data = await setter();
72+
if (data !== undefined && data !== null) {
73+
const cache = new SessionCached<T>(data, timeout.valueOf());
74+
sessionStorage.setItem(key, JSON.stringify(cache));
75+
}
76+
return data;
77+
}
78+
79+
export { regexUrl, regexEmail, regexPositiveNumber, regexChineseMobileNumber };
80+
81+

0 commit comments

Comments
 (0)