@cloudbase/app 2.0.3-alpha.0 → 2.5.1-beta.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.
@@ -2,27 +2,25 @@ import {
2
2
  DATA_VERSION,
3
3
  getSdkVersion,
4
4
  getEndPoint,
5
- getBaseEndPoint
6
- } from '../constants/common';
5
+ getBaseEndPoint,
6
+ } from '../constants/common'
7
7
  import {
8
8
  IRequestOptions,
9
9
  SDKRequestInterface,
10
10
  ResponseObject,
11
11
  IUploadRequestOptions,
12
- IRequestConfig
13
- } from '@cloudbase/adapter-interface';
14
- import { utils, adapters, constants } from '@cloudbase/utilities';
15
- import { KV } from '@cloudbase/types';
16
- import { IGetAccessTokenResult, ICloudbaseRequestConfig, IAppendedRequestInfo, IRequestBeforeHook } from '@cloudbase/types/request';
17
- import { ICloudbaseCache } from '@cloudbase/types/cache';
18
- import { getLocalCache } from './cache';
19
- import { Platform } from './adapter';
20
- const { ERRORS } = constants;
21
- const { genSeqId, isFormData, formatUrl, createSign } = utils;
22
- const { RUNTIME } = adapters;
12
+ IRequestConfig,
13
+ } from '@cloudbase/adapter-interface'
14
+ import { utils, adapters, constants } from '@cloudbase/utilities'
15
+ import { KV } from '@cloudbase/types'
16
+ import { IGetAccessTokenResult, ICloudbaseRequestConfig, IAppendedRequestInfo, IRequestBeforeHook } from '@cloudbase/types/request'
17
+ import { ICloudbaseCache } from '@cloudbase/types/cache'
18
+ import { getLocalCache } from './cache'
19
+ import { Platform } from './adapter'
20
+ const { ERRORS } = constants
21
+ const { genSeqId, isFormData, formatUrl, createSign } = utils
22
+ const { RUNTIME } = adapters
23
23
 
24
- // import FingerprintJS from '@fingerprintjs/fingerprintjs'
25
- // const fpPromise = FingerprintJS.load()
26
24
 
27
25
  // 下面几种 action 不需要 access token
28
26
  const ACTIONS_WITHOUT_ACCESSTOKEN = [
@@ -36,50 +34,50 @@ const ACTIONS_WITHOUT_ACCESSTOKEN = [
36
34
  'auth.activateEndUserMail',
37
35
  'auth.sendPasswordResetEmail',
38
36
  'auth.resetPasswordWithToken',
39
- 'auth.isUsernameRegistered'
40
- ];
37
+ 'auth.isUsernameRegistered',
38
+ ]
41
39
 
42
40
  function bindHooks(instance: SDKRequestInterface, name: string, hooks: IRequestBeforeHook[]) {
43
- const originMethod = instance[name];
41
+ const originMethod = instance[name]
44
42
  instance[name] = function (options: IRequestOptions) {
45
- const data = {};
46
- const headers = {};
47
- hooks.forEach(hook => {
48
- const { data: appendedData, headers: appendedHeaders } = hook.call(instance, options);
49
- Object.assign(data, appendedData);
50
- Object.assign(headers, appendedHeaders);
51
- });
52
- const originData = options.data;
43
+ const data = {}
44
+ const headers = {}
45
+ hooks.forEach((hook) => {
46
+ const { data: appendedData, headers: appendedHeaders } = hook.call(instance, options)
47
+ Object.assign(data, appendedData)
48
+ Object.assign(headers, appendedHeaders)
49
+ })
50
+ const originData = options.data
53
51
  originData && (() => {
54
52
  if (isFormData(originData)) {
55
- for (const key in data) {
56
- (originData as FormData).append(key, data[key]);
57
- }
58
- return;
53
+ Object.keys(data).forEach((key) => {
54
+ (originData as FormData).append(key, data[key])
55
+ })
56
+ return
59
57
  }
60
58
  options.data = {
61
59
  ...originData,
62
- ...data
63
- };
64
- })();
60
+ ...data,
61
+ }
62
+ })()
65
63
  options.headers = {
66
64
  ...(options.headers || {}),
67
- ...headers
68
- };
69
- return (originMethod as Function).call(instance, options);
70
- };
65
+ ...headers,
66
+ }
67
+ return (originMethod as Function).call(instance, options)
68
+ }
71
69
  }
72
70
  function beforeEach(): IAppendedRequestInfo {
73
- const seqId = genSeqId();
71
+ const seqId = genSeqId()
74
72
  return {
75
73
  data: {
76
- seqId
74
+ seqId,
77
75
  },
78
76
  headers: {
79
77
  'X-SDK-Version': `@cloudbase/js-sdk/${getSdkVersion()}`,
80
- 'x-seqid': seqId
81
- }
82
- };
78
+ 'x-seqid': seqId,
79
+ },
80
+ }
83
81
  }
84
82
  export interface ICloudbaseRequest {
85
83
  post: (options: IRequestOptions) => Promise<ResponseObject>;
@@ -93,45 +91,42 @@ export interface ICloudbaseRequest {
93
91
  * @class CloudbaseRequest
94
92
  */
95
93
  export class CloudbaseRequest implements ICloudbaseRequest {
96
- config: ICloudbaseRequestConfig;
97
- _shouldRefreshAccessTokenHook: Function
98
- _refreshAccessTokenPromise: Promise<IGetAccessTokenResult> | null
99
- _reqClass: SDKRequestInterface;
94
+ config: ICloudbaseRequestConfig
95
+ private reqClass: SDKRequestInterface
100
96
  // 请求失败是否抛出Error
101
- private _throwWhenRequestFail = false;
97
+ private throwWhenRequestFail = false
102
98
  // 持久化本地存储
103
- private _localCache: ICloudbaseCache;
99
+ private localCache: ICloudbaseCache
104
100
  /**
105
101
  * 初始化
106
102
  * @param config
107
103
  */
108
104
  constructor(config: ICloudbaseRequestConfig & { throw?: boolean }) {
109
-
110
- this.config = config;
111
- // eslint-disable-next-line
112
- this._reqClass = new Platform.adapter.reqClass(<IRequestConfig>{
105
+ this.config = config
106
+ const reqConfig: IRequestConfig = {
113
107
  timeout: this.config.timeout,
114
108
  timeoutMsg: `[@cloudbase/js-sdk] 请求在${this.config.timeout / 1000}s内未完成,已中断`,
115
- restrictedMethods: ['post', 'put']
116
- });
117
- this._throwWhenRequestFail = config.throw || false;
118
- this._localCache = getLocalCache(this.config.env);
119
- bindHooks(this._reqClass, 'post', [beforeEach]);
120
- bindHooks(this._reqClass, 'upload', [beforeEach]);
121
- bindHooks(this._reqClass, 'download', [beforeEach]);
109
+ restrictedMethods: ['post', 'put'],
110
+ }
111
+ this.reqClass = new Platform.adapter.reqClass(reqConfig)
112
+ this.throwWhenRequestFail = config.throw || false
113
+ this.localCache = getLocalCache(this.config.env)
114
+ bindHooks(this.reqClass, 'post', [beforeEach])
115
+ bindHooks(this.reqClass, 'upload', [beforeEach])
116
+ bindHooks(this.reqClass, 'download', [beforeEach])
122
117
  }
123
118
 
124
119
  public async post(options: IRequestOptions): Promise<ResponseObject> {
125
- const res = await this._reqClass.post(options);
126
- return res;
120
+ const res = await this.reqClass.post(options)
121
+ return res
127
122
  }
128
123
  public async upload(options: IUploadRequestOptions): Promise<ResponseObject> {
129
- const res = await this._reqClass.upload(options);
130
- return res;
124
+ const res = await this.reqClass.upload(options)
125
+ return res
131
126
  }
132
127
  public async download(options: IRequestOptions): Promise<ResponseObject> {
133
- const res = await this._reqClass.download(options);
134
- return res;
128
+ const res = await this.reqClass.download(options)
129
+ return res
135
130
  }
136
131
 
137
132
  public getBaseEndPoint() {
@@ -140,153 +135,151 @@ export class CloudbaseRequest implements ICloudbaseRequest {
140
135
 
141
136
  public async getOauthAccessTokenV2(oauthClient: any): Promise<IGetAccessTokenResult> {
142
137
  const validAccessToken = await oauthClient.getAccessToken()
143
- const credentials = await oauthClient._getCredentials()
138
+ const credentials = await oauthClient.getCredentials()
144
139
  return {
145
140
  accessToken: validAccessToken,
146
- accessTokenExpire: new Date(credentials.expires_at).getTime()
141
+ accessTokenExpire: new Date(credentials.expires_at).getTime(),
147
142
  }
148
143
  }
149
144
 
150
145
 
151
146
  /* eslint-disable complexity */
152
147
  public async request(action: string, params: KV<any>, options?: KV<any>): Promise<ResponseObject> {
153
- const tcbTraceKey = `x-tcb-trace_${this.config.env}`;
154
- let contentType = 'application/x-www-form-urlencoded';
155
- // const webDeviceId = await getTcbFingerprintId();
148
+ const tcbTraceKey = `x-tcb-trace_${this.config.env}`
149
+ let contentType = 'application/x-www-form-urlencoded'
156
150
  const tmpObj: KV<any> = {
157
151
  action,
158
- // webDeviceId,
159
152
  dataVersion: DATA_VERSION,
160
153
  env: this.config.env,
161
- ...params
162
- };
154
+ ...params,
155
+ }
163
156
 
164
157
  if (ACTIONS_WITHOUT_ACCESSTOKEN.indexOf(action) === -1) {
165
158
  const app = this.config._fromApp
166
159
 
167
160
  if (!app.oauthInstance) {
168
- throw new Error(`you can't request without auth`)
161
+ throw new Error('you can\'t request without auth')
169
162
  }
170
163
 
171
- const oauthInstance = app.oauthInstance
164
+ const { oauthInstance } = app
172
165
  const oauthClient = oauthInstance.oauth2client
173
166
  tmpObj.access_token = (await this.getOauthAccessTokenV2(oauthClient)).accessToken
174
167
  }
175
168
 
176
169
  // 拼body和content-type
177
- let payload;
170
+ let payload
178
171
  if (action === 'storage.uploadFile') {
179
- payload = new FormData();
180
- for (let key in payload) {
181
- if (payload.hasOwnProperty(key) && payload[key] !== undefined) {
182
- payload.append(key, tmpObj[key]);
172
+ payload = new FormData()
173
+ Object.keys(payload).forEach((key) => {
174
+ if (Object.prototype.hasOwnProperty.call(payload, key) && payload[key] !== undefined) {
175
+ payload.append(key, tmpObj[key])
183
176
  }
184
- }
185
- contentType = 'multipart/form-data';
177
+ })
178
+ contentType = 'multipart/form-data'
186
179
  } else {
187
- contentType = 'application/json;charset=UTF-8';
188
- payload = {};
189
- for (let key in tmpObj) {
180
+ contentType = 'application/json;charset=UTF-8'
181
+ payload = {}
182
+ Object.keys(tmpObj).forEach((key) => {
190
183
  if (tmpObj[key] !== undefined) {
191
- payload[key] = tmpObj[key];
184
+ payload[key] = tmpObj[key]
192
185
  }
193
- }
186
+ })
194
187
  }
195
- let opts: any = {
188
+ const opts: any = {
196
189
  headers: {
197
- 'content-type': contentType
198
- }
199
- };
200
- if (options?.['onUploadProgress']) {
201
- opts.onUploadProgress = options['onUploadProgress'];
190
+ 'content-type': contentType,
191
+ },
192
+ }
193
+ if (options?.onUploadProgress) {
194
+ opts.onUploadProgress = options.onUploadProgress
202
195
  }
203
196
 
204
197
  if (this.config.region) {
205
- opts.headers['X-TCB-Region'] = this.config.region;
198
+ opts.headers['X-TCB-Region'] = this.config.region
206
199
  }
207
200
 
208
- const traceHeader = this._localCache.getStore(tcbTraceKey);
201
+ const traceHeader = this.localCache.getStore(tcbTraceKey)
209
202
  if (traceHeader) {
210
- opts.headers['X-TCB-Trace'] = traceHeader;
203
+ opts.headers['X-TCB-Trace'] = traceHeader
211
204
  }
212
205
  // 非web平台使用凭证检验有效性
213
206
  if (Platform.runtime !== RUNTIME.WEB) {
214
- const { appSign, appSecret } = this.config;
215
- const timestamp = Date.now();
216
- const { appAccessKey, appAccessKeyId } = appSecret;
207
+ const { appSign, appSecret } = this.config
208
+ const timestamp = Date.now()
209
+ const { appAccessKey, appAccessKeyId } = appSecret
217
210
  const sign = createSign({
218
211
  data: {}, // 校验签名流程实际未用到,可设空
219
212
  timestamp,
220
213
  appAccessKeyId,
221
- appSign
222
- }, appAccessKey);
214
+ appSign,
215
+ }, appAccessKey)
223
216
 
224
- opts.headers['X-TCB-App-Source'] = `timestamp=${timestamp};appAccessKeyId=${appAccessKeyId};appSign=${appSign};sign=${sign}`;
217
+ opts.headers['X-TCB-App-Source'] = `timestamp=${timestamp};appAccessKeyId=${appAccessKeyId};appSign=${appSign};sign=${sign}`
225
218
  }
226
219
 
227
220
  // 发出请求
228
221
  // 新的 url 需要携带 env 参数进行 CORS 校验
229
222
  // 请求链接支持添加动态 query 参数,方便用户调试定位请求
230
- const { parse, inQuery, search } = params;
223
+ const { parse, inQuery, search } = params
231
224
  let formatQuery: Record<string, any> = {
232
- env: this.config.env
233
- };
225
+ env: this.config.env,
226
+ }
234
227
  // 尝试解析响应数据为 JSON
235
- parse && (formatQuery.parse = true);
228
+ parse && (formatQuery.parse = true)
236
229
  inQuery && (formatQuery = {
237
230
  ...inQuery,
238
- ...formatQuery
239
- });
240
- const { BASE_URL, PROTOCOL } = getEndPoint();
231
+ ...formatQuery,
232
+ })
233
+ const { BASE_URL, PROTOCOL } = getEndPoint()
241
234
  // 生成请求 url
242
- let newUrl = formatUrl(PROTOCOL, BASE_URL, formatQuery);
235
+ let newUrl = formatUrl(PROTOCOL, BASE_URL, formatQuery)
243
236
 
244
237
  if (search) {
245
- newUrl += search;
238
+ newUrl += search
246
239
  }
247
240
 
248
241
  const res: ResponseObject = await this.post({
249
242
  url: newUrl,
250
243
  data: payload,
251
- ...opts
252
- });
244
+ ...opts,
245
+ })
253
246
 
254
247
  // 保存 trace header
255
- const resTraceHeader = res.header && res.header['x-tcb-trace'];
248
+ const resTraceHeader = res.header?.['x-tcb-trace']
256
249
  if (resTraceHeader) {
257
- this._localCache.setStore(tcbTraceKey, resTraceHeader);
250
+ this.localCache.setStore(tcbTraceKey, resTraceHeader)
258
251
  }
259
252
 
260
253
  if ((Number(res.status) !== 200 && Number(res.statusCode) !== 200) || !res.data) {
261
- throw new Error('network request error');
254
+ throw new Error('network request error')
262
255
  }
263
256
 
264
- return res;
257
+ return res
265
258
  }
266
259
 
267
260
  public async send(action: string, data: KV<any> = {}): Promise<any> {
268
- let response = await this.request(action, data, { onUploadProgress: data.onUploadProgress });
261
+ const response = await this.request(action, data, { onUploadProgress: data.onUploadProgress })
269
262
 
270
- if (response.data.code && this._throwWhenRequestFail) {
263
+ if (response.data.code && this.throwWhenRequestFail) {
271
264
  throw new Error(JSON.stringify({
272
265
  code: ERRORS.OPERATION_FAIL,
273
- msg: `[${response.data.code}] ${response.data.message}`
274
- }));
266
+ msg: `[${response.data.code}] ${response.data.message}`,
267
+ }))
275
268
  }
276
269
 
277
- return response.data;
270
+ return response.data
278
271
  }
279
272
  }
280
273
 
281
- const requestMap: KV<CloudbaseRequest> = {};
274
+ const requestMap: KV<CloudbaseRequest> = {}
282
275
 
283
276
  export function initRequest(config: ICloudbaseRequestConfig) {
284
277
  requestMap[config.env] = new CloudbaseRequest({
285
278
  ...config,
286
- throw: true
287
- });
279
+ throw: true,
280
+ })
288
281
  }
289
282
 
290
283
  export function getRequestByEnvId(env: string): CloudbaseRequest {
291
- return requestMap[env];
292
- }
284
+ return requestMap[env]
285
+ }
package/.eslintrc DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "extends": [
3
- "eslint-config-alloy/typescript"
4
- ],
5
- "rules": {
6
- "indent": [
7
- "error",
8
- 2,
9
- {
10
- "SwitchCase": 1,
11
- "flatTernaryExpressions": true
12
- }
13
- ],
14
- "guard-for-in": 0,
15
- "no-param-reassign": 0,
16
- "no-undefined": 0,
17
- "@typescript-eslint/explicit-member-accessibility": 0,
18
- "@typescript-eslint/consistent-type-assertions": 0,
19
- "@typescript-eslint/no-loss-of-precision": 0,
20
- "@typescript-eslint/no-duplicate-imports": 0
21
- },
22
- "parserOptions": {
23
- "ecmaVersion": 6,
24
- "sourceType": "module",
25
- "ecmaFeatures": {
26
- "modules": true
27
- }
28
- }
29
- }