@cloudbase/oauth 0.0.3-alpha.0 → 1.0.0-alpha.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.
- package/.eslintrc +1 -1
- package/CHANGELOG.md +30 -0
- package/Dockerfile +15 -0
- package/README.md +165 -3
- package/_exmaple/assets/scripts/function/function.ts +99 -0
- package/_exmaple/assets/scripts/index.ts +101 -0
- package/_exmaple/assets/scripts/request.ts +11 -0
- package/_exmaple/index.html +15 -0
- package/_exmaple/package.json +33 -0
- package/_exmaple/tsconfig.json +71 -0
- package/_exmaple/typings.d.ts +0 -0
- package/_exmaple/webpack.config.js +42 -0
- package/dist/auth/apis.d.ts +15 -4
- package/dist/auth/apis.js +138 -41
- package/dist/auth/consts.d.ts +26 -2
- package/dist/auth/consts.js +28 -3
- package/dist/auth/models.d.ts +210 -1
- package/dist/auth/models.js +1 -1
- package/dist/captcha/captcha.js +2 -2
- package/dist/index.d.ts +7 -0
- package/dist/index.js +33 -8
- package/dist/oauth2client/interface.d.ts +6 -3
- package/dist/oauth2client/interface.js +1 -1
- package/dist/oauth2client/oauth2client.d.ts +7 -1
- package/dist/oauth2client/oauth2client.js +40 -7
- package/package.json +28 -28
- package/publish.sh +2 -0
- package/src/auth/apis.ts +554 -441
- package/src/auth/consts.ts +27 -1
- package/src/auth/models.ts +258 -1
- package/src/captcha/captcha.ts +181 -181
- package/src/index.ts +29 -4
- package/src/oauth2client/interface.ts +18 -5
- package/src/oauth2client/oauth2client.ts +505 -450
- package/wiki/README.md +75 -0
package/src/captcha/captcha.ts
CHANGED
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
import {SimpleStorage, RequestFunction} from '../oauth2client/interface';
|
|
2
|
-
import {AuthClientRequestOptions} from "../oauth2client/models";
|
|
3
|
-
import {defaultStorage} from "../oauth2client/oauth2client";
|
|
1
|
+
import { SimpleStorage, RequestFunction } from '../oauth2client/interface';
|
|
2
|
+
import { AuthClientRequestOptions } from "../oauth2client/models";
|
|
3
|
+
import { defaultStorage } from "../oauth2client/oauth2client";
|
|
4
4
|
|
|
5
5
|
export interface CaptchaOptions {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
clientId: string
|
|
7
|
+
request: RequestFunction;
|
|
8
|
+
storage: SimpleStorage;
|
|
9
|
+
// 打开网页并通过URL回调获取 CaptchaToken,针对不通的平台,该函数可以自定义实现, 默认集成浏览器端认证
|
|
10
|
+
openURIWithCallback?: OpenURIWithCallbackFuction;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
type OpenURIWithCallbackFuction = (url: string) => Promise<CaptchaToken>;
|
|
14
14
|
|
|
15
15
|
export interface CaptchaToken {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
captcha_token: string
|
|
17
|
+
expires_in: number
|
|
18
|
+
expires_at?: Date | null;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export interface CaptchaRequestOptions extends AuthClientRequestOptions {
|
|
22
|
-
|
|
22
|
+
withCaptcha?: boolean;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export interface GetCaptchaResponse {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
captcha_token?: string
|
|
27
|
+
expires_in?: number
|
|
28
|
+
url?: string
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const GET_CAPTCHA_URL = '/auth/v1/captcha/init'
|
|
32
32
|
|
|
33
33
|
export class Captcha {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
private _config: CaptchaOptions;
|
|
35
|
+
private _tokenSectionName: string;
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
if (!opts.storage) {
|
|
46
|
-
opts.storage = defaultStorage
|
|
47
|
-
}
|
|
48
|
-
this._config = opts
|
|
49
|
-
this._tokenSectionName = 'captcha_' + opts.clientId
|
|
37
|
+
/**
|
|
38
|
+
* constructor
|
|
39
|
+
* @param {CaptchaOptions} opts
|
|
40
|
+
*/
|
|
41
|
+
constructor(opts: CaptchaOptions) {
|
|
42
|
+
if (!opts.openURIWithCallback) {
|
|
43
|
+
opts.openURIWithCallback = this._getDefaultOpenURIWithCallback()
|
|
50
44
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* request http like simple fetch api, exp:request('/v1/user/me', {withCredentials:true})
|
|
54
|
-
* @param {string} url
|
|
55
|
-
* @param {AuthClientRequestOptions} options
|
|
56
|
-
*/
|
|
57
|
-
public async request<T>(
|
|
58
|
-
url: string,
|
|
59
|
-
options?: CaptchaRequestOptions,
|
|
60
|
-
): Promise<T> {
|
|
61
|
-
if (!options) {
|
|
62
|
-
options = {};
|
|
63
|
-
}
|
|
64
|
-
if (!options.method) {
|
|
65
|
-
options.method = 'GET'
|
|
66
|
-
}
|
|
67
|
-
const state = options.method + ":" + url
|
|
68
|
-
let reqURL = url;
|
|
69
|
-
if (options.withCaptcha) {
|
|
70
|
-
reqURL = await this._appendCaptchaTokenToURL(url, state, false);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
return this._config.request<T>(reqURL, options)
|
|
74
|
-
} catch (err) {
|
|
75
|
-
if (err.error === 'captcha_required' || err.error === 'captcha_invalid') {
|
|
76
|
-
url = await this._appendCaptchaTokenToURL(url, state, err.error === 'captcha_invalid')
|
|
77
|
-
return this._config.request<T>(url, options)
|
|
78
|
-
} else {
|
|
79
|
-
return Promise.reject(err)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
45
|
+
if (!opts.storage) {
|
|
46
|
+
opts.storage = defaultStorage
|
|
82
47
|
}
|
|
48
|
+
this._config = opts
|
|
49
|
+
this._tokenSectionName = 'captcha_' + opts.clientId
|
|
50
|
+
}
|
|
83
51
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
52
|
+
/**
|
|
53
|
+
* request http like simple fetch api, exp:request('/v1/user/me', {withCredentials:true})
|
|
54
|
+
* @param {string} url
|
|
55
|
+
* @param {AuthClientRequestOptions} options
|
|
56
|
+
*/
|
|
57
|
+
public async request<T>(
|
|
58
|
+
url: string,
|
|
59
|
+
options?: CaptchaRequestOptions,
|
|
60
|
+
): Promise<T> {
|
|
61
|
+
if (!options) {
|
|
62
|
+
options = {};
|
|
63
|
+
}
|
|
64
|
+
if (!options.method) {
|
|
65
|
+
options.method = 'GET'
|
|
66
|
+
}
|
|
67
|
+
const state = options.method + ":" + url
|
|
68
|
+
let reqURL = url;
|
|
69
|
+
if (options.withCaptcha) {
|
|
70
|
+
reqURL = await this._appendCaptchaTokenToURL(url, state, false);
|
|
96
71
|
}
|
|
72
|
+
try {
|
|
73
|
+
return this._config.request<T>(reqURL, options)
|
|
74
|
+
} catch (err) {
|
|
75
|
+
if (err.error === 'captcha_required' || err.error === 'captcha_invalid') {
|
|
76
|
+
url = await this._appendCaptchaTokenToURL(url, state, err.error === 'captcha_invalid')
|
|
77
|
+
return this._config.request<T>(url, options)
|
|
78
|
+
} else {
|
|
79
|
+
return Promise.reject(err)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
97
83
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
private async _defaultOpenURIWithCallback(url: string): Promise<CaptchaToken> {
|
|
102
|
-
const target = document.getElementById('captcha_panel_wrap'),
|
|
103
|
-
iframe = document.createElement('iframe')
|
|
104
|
-
target.innerHTML = '';
|
|
105
|
-
iframe.setAttribute('src', url)
|
|
106
|
-
iframe.setAttribute('id', 'review-panel-iframe')
|
|
107
|
-
iframe.style.cssText = 'min-width:355px;display:block;height:355px;margin:0 auto;background-color: rgb(255, 255, 255);border: none;';
|
|
108
|
-
target.appendChild(iframe);
|
|
109
|
-
target.style.display = 'block';
|
|
110
|
-
return new Promise<CaptchaToken>((resolve, reject) => {
|
|
111
|
-
iframe.onload = function () {
|
|
112
|
-
try {
|
|
113
|
-
var windowLocation = window.location;
|
|
114
|
-
var iframeLocation = iframe.contentWindow.location;
|
|
115
|
-
if (
|
|
116
|
-
iframeLocation.host +
|
|
117
|
-
iframeLocation.pathname ===
|
|
118
|
-
windowLocation.host +
|
|
119
|
-
windowLocation.pathname
|
|
120
|
-
) {
|
|
121
|
-
target.style.display = 'none';
|
|
122
|
-
const iframeUrlParams = new URLSearchParams(iframeLocation.search);
|
|
123
|
-
const captchToken = iframeUrlParams.get('captcha_token');
|
|
124
|
-
if (captchToken) {
|
|
125
|
-
return resolve({
|
|
126
|
-
captcha_token: captchToken,
|
|
127
|
-
expires_in: Number(iframeUrlParams.get('expires_in'))
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
return reject({
|
|
131
|
-
error: iframeUrlParams.get('error'),
|
|
132
|
-
error_description: iframeUrlParams.get('error_description')
|
|
133
|
-
})
|
|
134
|
-
} else {
|
|
135
|
-
target.style.display = 'block';
|
|
136
|
-
}
|
|
137
|
-
} catch (error) {
|
|
138
|
-
target.style.display = 'block';
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
})
|
|
84
|
+
private _getDefaultOpenURIWithCallback(): OpenURIWithCallbackFuction {
|
|
85
|
+
if (window.location.search.indexOf('__captcha') > 0) {
|
|
86
|
+
document.body.style.display = 'none';
|
|
142
87
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const captchaToken = await this._findCaptchaToken()
|
|
150
|
-
if (captchaToken) {
|
|
151
|
-
return captchaToken
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
const redirectURL = window.location.origin + window.location.pathname + "?__captcha=on"
|
|
155
|
-
const captchaTokenResp = await this._config.request<GetCaptchaResponse>(GET_CAPTCHA_URL, {
|
|
156
|
-
method: 'POST',
|
|
157
|
-
body: {
|
|
158
|
-
client_id: this._config.clientId,
|
|
159
|
-
redirect_uri: redirectURL,
|
|
160
|
-
state: state
|
|
161
|
-
},
|
|
162
|
-
withCredentials: false,
|
|
163
|
-
})
|
|
164
|
-
if (captchaTokenResp.captcha_token) {
|
|
165
|
-
const captchaToken = {
|
|
166
|
-
captcha_token: captchaTokenResp.captcha_token,
|
|
167
|
-
expires_in: captchaTokenResp.expires_in,
|
|
168
|
-
}
|
|
169
|
-
this._saveCaptchaToken(captchaToken)
|
|
170
|
-
return captchaTokenResp.captcha_token
|
|
171
|
-
}
|
|
172
|
-
const captchaToken = await this._config.openURIWithCallback(captchaTokenResp.url)
|
|
173
|
-
this._saveCaptchaToken(captchaToken)
|
|
174
|
-
return captchaToken.captcha_token
|
|
88
|
+
if (document.getElementById('captcha_panel_wrap') === null) {
|
|
89
|
+
var elementDiv = document.createElement('div');
|
|
90
|
+
elementDiv.style.cssText =
|
|
91
|
+
'background-color: rgba(0, 0, 0, 0.7);position: fixed;left: 0px;right: 0px;top: 0px;bottom: 0px;padding: 9vw 0 0 0;display: none;z-index:100;';
|
|
92
|
+
elementDiv.setAttribute('id', 'captcha_panel_wrap');
|
|
93
|
+
document.body.appendChild(elementDiv);
|
|
175
94
|
}
|
|
95
|
+
return this._defaultOpenURIWithCallback
|
|
96
|
+
}
|
|
176
97
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
98
|
+
/**
|
|
99
|
+
* 默认通过浏览器打开网页并获取回调
|
|
100
|
+
*/
|
|
101
|
+
private async _defaultOpenURIWithCallback(url: string): Promise<CaptchaToken> {
|
|
102
|
+
const target = document.getElementById('captcha_panel_wrap'),
|
|
103
|
+
iframe = document.createElement('iframe')
|
|
104
|
+
target.innerHTML = '';
|
|
105
|
+
iframe.setAttribute('src', url)
|
|
106
|
+
iframe.setAttribute('id', 'review-panel-iframe')
|
|
107
|
+
iframe.style.cssText = 'min-width:355px;display:block;height:355px;margin:0 auto;background-color: rgb(255, 255, 255);border: none;';
|
|
108
|
+
target.appendChild(iframe);
|
|
109
|
+
target.style.display = 'block';
|
|
110
|
+
return new Promise<CaptchaToken>((resolve, reject) => {
|
|
111
|
+
iframe.onload = function () {
|
|
112
|
+
try {
|
|
113
|
+
var windowLocation = window.location;
|
|
114
|
+
var iframeLocation = iframe.contentWindow.location;
|
|
115
|
+
if (
|
|
116
|
+
iframeLocation.host +
|
|
117
|
+
iframeLocation.pathname ===
|
|
118
|
+
windowLocation.host +
|
|
119
|
+
windowLocation.pathname
|
|
120
|
+
) {
|
|
121
|
+
target.style.display = 'none';
|
|
122
|
+
const iframeUrlParams = new URLSearchParams(iframeLocation.search);
|
|
123
|
+
const captchToken = iframeUrlParams.get('captcha_token');
|
|
124
|
+
if (captchToken) {
|
|
125
|
+
return resolve({
|
|
126
|
+
captcha_token: captchToken,
|
|
127
|
+
expires_in: Number(iframeUrlParams.get('expires_in'))
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
return reject({
|
|
131
|
+
error: iframeUrlParams.get('error'),
|
|
132
|
+
error_description: iframeUrlParams.get('error_description')
|
|
133
|
+
})
|
|
134
|
+
} else {
|
|
135
|
+
target.style.display = 'block';
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
target.style.display = 'block';
|
|
183
139
|
}
|
|
184
|
-
|
|
140
|
+
};
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* _getCaptchaToken 获取captchaToken
|
|
145
|
+
*/
|
|
146
|
+
private async _getCaptchaToken(forceNewToken: boolean, state: string): Promise<string> {
|
|
147
|
+
if (!forceNewToken) {
|
|
148
|
+
// 如果本地存在,则直接返回
|
|
149
|
+
const captchaToken = await this._findCaptchaToken()
|
|
150
|
+
if (captchaToken) {
|
|
151
|
+
return captchaToken
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const redirectURL = window.location.origin + window.location.pathname + "?__captcha=on"
|
|
155
|
+
const captchaTokenResp = await this._config.request<GetCaptchaResponse>(GET_CAPTCHA_URL, {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
body: {
|
|
158
|
+
client_id: this._config.clientId,
|
|
159
|
+
redirect_uri: redirectURL,
|
|
160
|
+
state: state
|
|
161
|
+
},
|
|
162
|
+
withCredentials: false,
|
|
163
|
+
})
|
|
164
|
+
if (captchaTokenResp.captcha_token) {
|
|
165
|
+
const captchaToken = {
|
|
166
|
+
captcha_token: captchaTokenResp.captcha_token,
|
|
167
|
+
expires_in: captchaTokenResp.expires_in,
|
|
168
|
+
}
|
|
169
|
+
this._saveCaptchaToken(captchaToken)
|
|
170
|
+
return captchaTokenResp.captcha_token
|
|
185
171
|
}
|
|
172
|
+
const captchaToken = await this._config.openURIWithCallback(captchaTokenResp.url)
|
|
173
|
+
this._saveCaptchaToken(captchaToken)
|
|
174
|
+
return captchaToken.captcha_token
|
|
175
|
+
}
|
|
186
176
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
177
|
+
private async _appendCaptchaTokenToURL(url: string, state: string, forceNewToken: boolean): Promise<string> {
|
|
178
|
+
const captchaToken = await this._getCaptchaToken(forceNewToken, state);
|
|
179
|
+
if (url.indexOf("?") > 0) {
|
|
180
|
+
url += "&captcha_token=" + captchaToken
|
|
181
|
+
} else {
|
|
182
|
+
url += "?captcha_token=" + captchaToken
|
|
193
183
|
}
|
|
184
|
+
return url
|
|
185
|
+
}
|
|
194
186
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
187
|
+
private async _saveCaptchaToken(token: CaptchaToken) {
|
|
188
|
+
token.expires_at = new Date(
|
|
189
|
+
Date.now() + (token.expires_in - 10) * 1000,
|
|
190
|
+
);
|
|
191
|
+
const tokenStr: string = JSON.stringify(token);
|
|
192
|
+
await this._config.storage.setItem(this._tokenSectionName, tokenStr);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private async _findCaptchaToken(): Promise<string> {
|
|
196
|
+
const tokenStr: string = await this._config.storage.getItem(
|
|
197
|
+
this._tokenSectionName,
|
|
198
|
+
);
|
|
199
|
+
if (tokenStr !== undefined && tokenStr !== null) {
|
|
200
|
+
try {
|
|
201
|
+
const captchaToken = JSON.parse(tokenStr);
|
|
202
|
+
if (captchaToken?.expires_at) {
|
|
203
|
+
captchaToken.expires_at = new Date(captchaToken.expires_at);
|
|
204
|
+
}
|
|
205
|
+
const isExpired = captchaToken.expires_at < new Date();
|
|
206
|
+
if (isExpired) {
|
|
207
|
+
return null
|
|
214
208
|
}
|
|
209
|
+
return captchaToken.captcha_token
|
|
210
|
+
} catch (error) {
|
|
211
|
+
await this._config.storage.removeItem(this._tokenSectionName);
|
|
215
212
|
return null
|
|
213
|
+
}
|
|
216
214
|
}
|
|
215
|
+
return null
|
|
216
|
+
}
|
|
217
217
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export {Syntax, ErrorType} from './oauth2client/consts';
|
|
1
|
+
export { Syntax, ErrorType } from './oauth2client/consts';
|
|
2
|
+
|
|
3
|
+
import { OAuth2Client } from './oauth2client/oauth2client'
|
|
2
4
|
|
|
3
5
|
export {
|
|
4
6
|
defaultStorage,
|
|
@@ -9,8 +11,9 @@ export {
|
|
|
9
11
|
OAuth2Client,
|
|
10
12
|
} from './oauth2client/oauth2client';
|
|
11
13
|
|
|
12
|
-
export {AuthClient, SimpleStorage} from './oauth2client/interface';
|
|
14
|
+
export { AuthClient, SimpleStorage } from './oauth2client/interface';
|
|
13
15
|
|
|
16
|
+
// import { Credentials } from './oauth2client/models'
|
|
14
17
|
export {
|
|
15
18
|
Credentials,
|
|
16
19
|
ResponseError,
|
|
@@ -18,7 +21,29 @@ export {
|
|
|
18
21
|
AuthClientRequestOptions,
|
|
19
22
|
} from './oauth2client/models';
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
import { AuthOptions, Auth } from './auth/apis'
|
|
25
|
+
|
|
26
|
+
export { AuthOptions, Auth } from './auth/apis';
|
|
22
27
|
|
|
23
28
|
import * as authModels from './auth/models';
|
|
24
|
-
export {authModels};
|
|
29
|
+
export { authModels };
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
export class CloudbaseOAuth {
|
|
33
|
+
public oauth2client: OAuth2Client
|
|
34
|
+
public authApi: Auth
|
|
35
|
+
|
|
36
|
+
constructor(authOptions: AuthOptions) {
|
|
37
|
+
const { apiOrigin, clientId } = authOptions
|
|
38
|
+
this.oauth2client = new OAuth2Client({
|
|
39
|
+
apiOrigin,
|
|
40
|
+
clientId
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
this.authApi = new Auth({
|
|
44
|
+
credentialsClient: this.oauth2client,
|
|
45
|
+
...authOptions
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Credentials, AuthClientRequestOptions} from './models';
|
|
1
|
+
import { Credentials, AuthClientRequestOptions } from './models';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* the interface for the Oauth2Client
|
|
@@ -25,20 +25,33 @@ export abstract class AuthClient {
|
|
|
25
25
|
abstract getAccessToken(): Promise<string>;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export type RequestFunction = <T>(url: string,options?: AuthClientRequestOptions) => Promise<T>;
|
|
28
|
+
export type RequestFunction = <T>(url: string, options?: AuthClientRequestOptions) => Promise<T>;
|
|
29
29
|
|
|
30
30
|
/** An interface of the Simple Web Storage API */
|
|
31
31
|
export interface SimpleStorage {
|
|
32
32
|
/**
|
|
33
33
|
* value = storage[key]
|
|
34
34
|
*/
|
|
35
|
-
getItem(key: string)
|
|
35
|
+
getItem: (key: string) => Promise<string | null>;
|
|
36
36
|
/**
|
|
37
37
|
* delete storage[key]
|
|
38
38
|
*/
|
|
39
|
-
removeItem(key: string)
|
|
39
|
+
removeItem: (key: string) => Promise<void>;
|
|
40
40
|
/**
|
|
41
41
|
* storage[key] = value
|
|
42
42
|
*/
|
|
43
|
-
setItem(key: string, value: string)
|
|
43
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* value = storage[key]
|
|
47
|
+
*/
|
|
48
|
+
getItemSync: (key: string) => string | null;
|
|
49
|
+
/**
|
|
50
|
+
* delete storage[key]
|
|
51
|
+
*/
|
|
52
|
+
removeItemSync: (key: string) => void;
|
|
53
|
+
/**
|
|
54
|
+
* storage[key] = value
|
|
55
|
+
*/
|
|
56
|
+
setItemSync: (key: string, value: string) => void;
|
|
44
57
|
}
|