@steedos/client 2.2.50-beta.7 → 2.2.51-beta.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@steedos/client",
4
- "version": "2.2.50-beta.7",
4
+ "version": "2.2.51-beta.2",
5
5
  "description": "client lib for steedos",
6
6
  "main": "lib/index.js",
7
7
  "scripts": {
@@ -19,8 +19,8 @@
19
19
  },
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@steedos/filters": "2.2.50-beta.7",
22
+ "@steedos/filters": "2.2.51-beta.2",
23
23
  "node-fetch": "^2.6.1"
24
24
  },
25
- "gitHead": "60824bd4d74665ac98fb269bd9279c2dea0d9620"
25
+ "gitHead": "c324c40fa8facd3bf73a51e8c417293a9349f9fb"
26
26
  }
package/src/client4.ts DELETED
@@ -1,557 +0,0 @@
1
- // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2
- // See LICENSE.txt for license information.
3
-
4
- import fetch from './fetch_etag';
5
- import {cleanUrlForLogging} from './utils/sentry';
6
- import { Options, ClientResponse } from './types/client4';
7
- import {buildQueryString} from './utils/helpers';
8
- import { UserProfile } from './types/users';
9
- import { ServerError } from './types/errors';
10
- import { Space } from './types/spaces';
11
- import SObject from './sobject';
12
- import Graphql from './graphql';
13
-
14
- const HEADER_AUTH = 'Authorization';
15
- const HEADER_BEARER = 'Bearer';
16
- const HEADER_REQUESTED_WITH = 'X-Requested-With';
17
- const HEADER_USER_AGENT = 'User-Agent';
18
- const HEADER_X_CLUSTER_ID = 'X-Cluster-Id';
19
- const HEADER_X_CSRF_TOKEN = 'X-CSRF-Token';
20
- export const HEADER_X_VERSION_ID = 'X-Version-Id';
21
- const PER_PAGE_DEFAULT = 60;
22
- const LOGS_PER_PAGE_DEFAULT = 10000;
23
- export const DEFAULT_LIMIT_BEFORE = 30;
24
- export const DEFAULT_LIMIT_AFTER = 30;
25
-
26
- const DEFAULT_LOGIN_EXPIRATION_DAYS = 90;
27
- const LOGIN_UNEXPIRING_TOKEN_DAYS = 365 * 100;
28
-
29
- export default class SteedosClient {
30
- LOGIN_TOKEN_KEY = "Meteor.loginToken";
31
- LOGIN_TOKEN_EXPIRES_KEY = "Meteor.loginTokenExpires";
32
- USER_ID_KEY = "Meteor.userId";
33
- logToConsole = false;
34
- _lastLoginTokenWhenPolled= null;
35
- loginExpirationInDays = null;
36
- serverVersion = '';
37
- clusterId = '';
38
- token = '';
39
- spaceId = '';
40
- authToken = '';
41
- csrf = '';
42
- url = (process.env.NODE_ENV == 'development' && process.env.REACT_APP_API_URL)? process.env.REACT_APP_API_URL as string : '';
43
- urlVersion = '';
44
- userAgent: string|null = null;
45
- enableLogging = false;
46
- defaultHeaders: {[x: string]: string} = {
47
- 'Content-Type': 'application/json'
48
- };
49
- userId = '';
50
- diagnosticId = '';
51
- includeCookies = true;
52
- isRudderKeySet = false;
53
- translations = {
54
- connectionError: 'There appears to be a problem with your internet connection.',
55
- unknownError: 'We received an unexpected status code from the server.',
56
- };
57
- userRoles?: string;
58
-
59
- sobjects = {};
60
- graphql = new Graphql(this);
61
-
62
- getUrl() {
63
- if(!this.url){
64
- var href = new URL(window.location.href);
65
- var foo = href.pathname.split('/accounts');
66
- var ROOT_URL_PATH_PREFIX = '';
67
- if(foo.length > 1){
68
- ROOT_URL_PATH_PREFIX = foo[0];
69
- }
70
- return ROOT_URL_PATH_PREFIX;
71
- }
72
- return this.url;
73
- }
74
-
75
- getAbsoluteUrl(baseUrl: string) {
76
- if (typeof baseUrl !== 'string' || !baseUrl.startsWith('/')) {
77
- return baseUrl;
78
- }
79
- return this.getUrl() + baseUrl;
80
- }
81
-
82
- setUrl(url: string) {
83
- this.url = url;
84
- }
85
-
86
- setUserAgent(userAgent: string) {
87
- this.userAgent = userAgent;
88
- }
89
-
90
- getToken() {
91
- return this.token;
92
- }
93
-
94
- setToken(token: string) {
95
- this.token = token;
96
- this.authToken = this.getSpaceId() + ',' + token;
97
- }
98
-
99
- getSpaceId(){
100
- return this.spaceId;
101
- }
102
-
103
- setSpaceId(spaceId){
104
- this.spaceId = spaceId;
105
- this.authToken = spaceId + ',' + this.getToken();
106
- }
107
-
108
- getAuthToken(){
109
- // return this.getSpaceId() + ',' + this.getToken();
110
- return this.authToken;
111
- }
112
-
113
- setCSRF(csrfToken: string) {
114
- this.csrf = csrfToken;
115
- }
116
-
117
- setAcceptLanguage(locale: string) {
118
- this.defaultHeaders['Accept-Language'] = locale;
119
- }
120
-
121
- setEnableLogging(enable: boolean) {
122
- this.enableLogging = enable;
123
- }
124
-
125
- setIncludeCookies(include: boolean) {
126
- this.includeCookies = include;
127
- }
128
-
129
- setUserId(userId: string) {
130
- this.userId = userId;
131
- }
132
-
133
- setUserRoles(roles: string) {
134
- this.userRoles = roles;
135
- }
136
-
137
- setDiagnosticId(diagnosticId: string) {
138
- this.diagnosticId = diagnosticId;
139
- }
140
-
141
- enableRudderEvents() {
142
- this.isRudderKeySet = true;
143
- }
144
-
145
- getServerVersion() {
146
- return this.serverVersion;
147
- }
148
-
149
- getUrlVersion() {
150
- return this.urlVersion;
151
- }
152
-
153
- getBaseRoute() {
154
- return `${this.getUrl()}${this.urlVersion}`;
155
- }
156
-
157
- getAccountsRoute() {
158
- return `${this.getBaseRoute()}/accounts`;
159
- }
160
-
161
- getCSRFFromCookie() {
162
- if (typeof document !== 'undefined' && typeof document.cookie !== 'undefined') {
163
- const cookies = document.cookie.split(';');
164
- for (let i = 0; i < cookies.length; i++) {
165
- const cookie = cookies[i].trim();
166
- if (cookie.startsWith('MMCSRF=')) {
167
- return cookie.replace('MMCSRF=', '');
168
- }
169
- }
170
- }
171
- return '';
172
- }
173
-
174
- getOptions(options: Options) {
175
- const newOptions: Options = {...options};
176
-
177
- const headers: {[x: string]: string} = {
178
- [HEADER_REQUESTED_WITH]: 'XMLHttpRequest',
179
- ...this.defaultHeaders,
180
- };
181
-
182
- if (this.authToken) {
183
- headers[HEADER_AUTH] = `${HEADER_BEARER} ${this.authToken}`;
184
- }
185
-
186
- const csrfToken = this.csrf || this.getCSRFFromCookie();
187
- if (options.method && options.method.toLowerCase() !== 'get' && csrfToken) {
188
- headers[HEADER_X_CSRF_TOKEN] = csrfToken;
189
- }
190
-
191
- if (this.includeCookies) {
192
- newOptions.credentials = 'include';
193
- }
194
-
195
- if (this.userAgent) {
196
- headers[HEADER_USER_AGENT] = this.userAgent;
197
- }
198
-
199
- if (newOptions.headers) {
200
- Object.assign(headers, newOptions.headers);
201
- }
202
-
203
- return {
204
- ...newOptions,
205
- headers,
206
- };
207
- }
208
-
209
- getTranslations = (url: string) => {
210
- return this.doFetch<Record<string, string>>(
211
- url,
212
- {method: 'get'},
213
- );
214
- }
215
-
216
-
217
- logClientError = (message: string, level = 'ERROR') => {
218
- // const url = `${this.getBaseRoute()}/logs`;
219
-
220
- // if (!this.enableLogging) {
221
- // throw new ClientError(this.getUrl(), {
222
- // message: 'Logging disabled.',
223
- // url,
224
- // });
225
- // }
226
-
227
- // return this.doFetch<{
228
- // message: string;
229
- // }>(
230
- // url,
231
- // {method: 'post', body: JSON.stringify({message, level})},
232
- // );
233
- };
234
-
235
- login = (user: string | object, password: string, token = '', deviceId = '') => {
236
- this.trackEvent('api', 'api_users_login');
237
-
238
- const body: any = {
239
- device_id: deviceId,
240
- user,
241
- password,
242
- token,
243
- locale: "zh-cn"
244
- };
245
-
246
- return this.doFetch<UserProfile>(
247
- `${this.getAccountsRoute()}/password/login`,
248
- {method: 'POST', body: JSON.stringify(body)},
249
- );
250
-
251
- };
252
-
253
-
254
- createUser = (user: UserProfile, token: string, inviteId: string, redirect: string) => {
255
- this.trackEvent('api', 'api_users_createUser');
256
-
257
- const queryParams: any = {};
258
-
259
- if (token) {
260
- queryParams.t = token;
261
- }
262
-
263
- if (inviteId) {
264
- queryParams.iid = inviteId;
265
- }
266
-
267
- if (redirect) {
268
- queryParams.r = redirect;
269
- }
270
-
271
- const auth:any = this.doFetch<UserProfile>(
272
- `${this.getAccountsRoute()}/password/register${buildQueryString(queryParams)}`,
273
- {method: 'POST', body: JSON.stringify(user)},
274
- );
275
-
276
- return auth
277
- };
278
-
279
- createSpace = (name: string) => {
280
- this.trackEvent('api', 'api_users_createTenant');
281
-
282
- const queryParams: any = {};
283
-
284
- const auth:any = this.doFetch<UserProfile>(
285
- `${this.getBaseRoute()}/api/v4/spaces/register/tenant${buildQueryString(queryParams)}`,
286
- {method: 'POST', body: JSON.stringify({name: name})},
287
- );
288
-
289
- return auth
290
- };
291
-
292
- sendVerificationToken = (user: string) => {
293
- this.trackEvent('api', 'api_users_verify');
294
-
295
- const body: any = {
296
- user: user,
297
- };
298
-
299
- return this.doFetch<UserProfile>(
300
- `${this.getAccountsRoute()}/password/sendVerificationCode`,
301
- {method: 'POST', body: JSON.stringify(body)},
302
- );
303
- };
304
-
305
- getSettings = () => {
306
- return this.doFetch<UserProfile>(
307
- `${this.getAccountsRoute()}/settings`,
308
- {method: 'get'},
309
- );
310
- };
311
-
312
- getMe = () => {
313
- return this.doFetch<UserProfile>(
314
- `${this.getAccountsRoute()}/user`,
315
- {method: 'get'},
316
- );
317
- };
318
-
319
- getMySpaces = () => {
320
- return this.doFetch<Space[]>(
321
- `${this.getAccountsRoute()}/user/spaces`,
322
- {method: 'get'},
323
- );
324
- };
325
-
326
- logout = async () => {
327
- this.trackEvent('api', 'api_users_logout');
328
-
329
- const {response} = await this.doFetchWithResponse(
330
- `${this.getAccountsRoute()}/logout`,
331
- {method: 'post'},
332
- );
333
-
334
- if (response.ok) {
335
- this.token = '';
336
- }
337
-
338
- this.serverVersion = '';
339
-
340
- return response;
341
- };
342
-
343
- // Client Helpers
344
-
345
- doFetch = async <T>(url: string, options: Options): Promise<T> => {
346
- const {data} = await this.doFetchWithResponse<T>(url, options);
347
-
348
- return data;
349
- };
350
-
351
- doFetchWithResponse = async <T>(url: string, options: Options): Promise<ClientResponse<T>> => {
352
- const response = await fetch(url, this.getOptions(options));
353
- const headers = parseAndMergeNestedHeaders(response.headers);
354
-
355
- let data;
356
- try {
357
- data = await response.json();
358
- } catch (err) {
359
- throw new ClientError(this.getUrl(), {
360
- message: 'Received invalid response from the server.',
361
- intl: {
362
- id: 'mobile.request.invalid_response',
363
- defaultMessage: 'Received invalid response from the server.',
364
- },
365
- url,
366
- });
367
- }
368
-
369
- if (headers.has(HEADER_X_VERSION_ID) && !headers.get('Cache-Control')) {
370
- const serverVersion = headers.get(HEADER_X_VERSION_ID);
371
- if (serverVersion && this.serverVersion !== serverVersion) {
372
- this.serverVersion = serverVersion as string;
373
- }
374
- }
375
-
376
- if (headers.has(HEADER_X_CLUSTER_ID)) {
377
- const clusterId = headers.get(HEADER_X_CLUSTER_ID);
378
- if (clusterId && this.clusterId !== clusterId) {
379
- this.clusterId = clusterId as string;
380
- }
381
- }
382
-
383
- if (response.ok) {
384
- return {
385
- response,
386
- headers: headers as Map<string, string>,
387
- data,
388
- };
389
- }
390
-
391
-
392
- const error = data && data.error ? data.error : data
393
- const msg = error.message || '';
394
-
395
- if (this.logToConsole) {
396
- console.error(msg); // eslint-disable-line no-console
397
- }
398
-
399
- throw new ClientError(this.getUrl(), {
400
- message: msg,
401
- server_error_id: data.id,
402
- status_code: error.code,
403
- url,
404
- });
405
- };
406
-
407
- trackEvent(category: string, event: string, props?: any) {
408
- if (!this.isRudderKeySet) {
409
- return;
410
- }
411
-
412
- const properties = Object.assign({
413
- category,
414
- type: event,
415
- // user_actual_role: this.userRoles && isSystemAdmin(this.userRoles) ? 'system_admin, system_user' : 'system_user',
416
- user_actual_id: this.userId,
417
- }, props);
418
- const options = {
419
- context: {
420
- ip: '0.0.0.0',
421
- },
422
- page: {
423
- path: '',
424
- referrer: '',
425
- search: '',
426
- title: '',
427
- url: '',
428
- },
429
- anonymousId: '00000000000000000000000000',
430
- };
431
-
432
- // rudderAnalytics.track('event', properties, options);
433
- }
434
-
435
- changePassword = (oldPassword: string, newPassword: string)=>{
436
- return this.doFetch<UserProfile>(
437
- `${this.getAccountsRoute()}/password/changePassword`,
438
- {method: 'POST', body: JSON.stringify({
439
- oldPassword: oldPassword,
440
- newPassword: newPassword,
441
- })},
442
- );
443
- }
444
-
445
- verifyEmail = (email: string, code: string)=>{
446
- return this.doFetch<UserProfile>(
447
- `${this.getAccountsRoute()}/password/verify/email`,
448
- {method: 'POST', body: JSON.stringify({
449
- email: email,
450
- code: code,
451
- })},
452
- );
453
- }
454
-
455
- verifyMobile = (mobile: string, code: string)=>{
456
- return this.doFetch<UserProfile>(
457
- `${this.getAccountsRoute()}/password/verify/mobile`,
458
- {method: 'POST', body: JSON.stringify({
459
- mobile: mobile,
460
- code: code,
461
- })},
462
- );
463
- }
464
-
465
- sobject = function(objectName) {
466
- this.sobjects = this.sobjects || {};
467
- var sobject = this.sobjects[objectName] = this.sobjects[objectName] || new SObject(this, objectName);
468
- return sobject;
469
- };
470
-
471
- // graphql = function(){
472
- // if(!this._graphql){
473
- // this._graphql = new Graphql(this);
474
- // }
475
- // return this._graphql;
476
- // }
477
-
478
- // _initLocalStorage(ROOT_URL_PATH_PREFIX){
479
- // if (ROOT_URL_PATH_PREFIX) {
480
- // let namespace = `:${ROOT_URL_PATH_PREFIX}`;
481
- // this.LOGIN_TOKEN_KEY += namespace;
482
- // this.LOGIN_TOKEN_EXPIRES_KEY += namespace;
483
- // this.USER_ID_KEY += namespace;
484
- // }
485
- // }
486
-
487
- // _getTokenLifetimeMs() {
488
- // const loginExpirationInDays = (this.loginExpirationInDays === null) ? LOGIN_UNEXPIRING_TOKEN_DAYS : this.loginExpirationInDays;
489
- // return (loginExpirationInDays || DEFAULT_LOGIN_EXPIRATION_DAYS) * 24 * 60 * 60 * 1000;
490
- // }
491
-
492
- // _tokenExpiration(when) {
493
- // return new Date((new Date(when)).getTime() + this._getTokenLifetimeMs());
494
- // }
495
-
496
- // _storeLoginToken(userId, token, tokenExpires) {
497
- // localStorage.setItem(this.USER_ID_KEY, userId);
498
- // localStorage.setItem(this.LOGIN_TOKEN_KEY, token);
499
- // if (! tokenExpires)
500
- // tokenExpires = this._tokenExpiration(new Date());
501
- // localStorage.setItem(this.LOGIN_TOKEN_EXPIRES_KEY, tokenExpires);
502
-
503
- // this._lastLoginTokenWhenPolled = token;
504
- // };
505
-
506
- // _unstoreLoginToken() {
507
- // localStorage.removeItem(this.USER_ID_KEY);
508
- // localStorage.removeItem(this.LOGIN_TOKEN_KEY);
509
- // localStorage.removeItem(this.LOGIN_TOKEN_EXPIRES_KEY);
510
-
511
- // this._lastLoginTokenWhenPolled = null;
512
- // };
513
- }
514
-
515
- function parseAndMergeNestedHeaders(originalHeaders: any) {
516
- const headers = new Map();
517
- let nestedHeaders = new Map();
518
- originalHeaders.forEach((val: string, key: string) => {
519
- const capitalizedKey = key.replace(/\b[a-z]/g, (l) => l.toUpperCase());
520
- let realVal = val;
521
- if (val && val.match(/\n\S+:\s\S+/)) {
522
- const nestedHeaderStrings = val.split('\n');
523
- realVal = nestedHeaderStrings.shift() as string;
524
- const moreNestedHeaders = new Map(
525
- nestedHeaderStrings.map((h: any) => h.split(/:\s/)),
526
- );
527
- nestedHeaders = new Map([...nestedHeaders, ...moreNestedHeaders]);
528
- }
529
- headers.set(capitalizedKey, realVal);
530
- });
531
- return new Map([...headers, ...nestedHeaders]);
532
- }
533
-
534
- export class ClientError extends Error implements ServerError {
535
- url?: string;
536
- intl?: {
537
- id: string;
538
- defaultMessage: string;
539
- values?: any;
540
- };
541
- server_error_id?: string;
542
- status_code?: number;
543
-
544
- constructor(baseUrl: string, data: ServerError) {
545
- super(data.message + ': ' + cleanUrlForLogging(baseUrl, data.url || ''));
546
-
547
- this.message = data.message;
548
- this.url = data.url;
549
- this.intl = data.intl;
550
- this.server_error_id = data.server_error_id;
551
- this.status_code = data.status_code;
552
-
553
- // Ensure message is treated as a property of this class when object spreading. Without this,
554
- // copying the object by using `{...error}` would not include the message.
555
- Object.defineProperty(this, 'message', {enumerable: true});
556
- }
557
- }
package/src/fetch_etag.ts DELETED
@@ -1,36 +0,0 @@
1
- const fetch = require('node-fetch');
2
- const data = {};
3
- const etags = {};
4
-
5
- export default (url:any = null, options:any = {headers: {}}) => {
6
- url = url || options.url; // eslint-disable-line no-param-reassign
7
-
8
- if (options.method === 'GET' || !options.method) {
9
- const etag = etags[url];
10
- const cachedResponse = data[`${url}${etag}`]; // ensure etag is for url
11
- if (etag) {
12
- options.headers['If-None-Match'] = etag;
13
- }
14
-
15
- return fetch(url, options).
16
- then((response) => {
17
- if (response.status === 304) {
18
- return cachedResponse.clone();
19
- }
20
-
21
- if (response.status === 200) {
22
- const responseEtag = response.headers.get('Etag');
23
-
24
- if (responseEtag) {
25
- data[`${url}${responseEtag}`] = response.clone();
26
- etags[url] = responseEtag;
27
- }
28
- }
29
-
30
- return response;
31
- });
32
- }
33
-
34
- // all other requests go straight to fetch
35
- return Reflect.apply(fetch, undefined, [url, options]); //eslint-disable-line no-undefined
36
- };
package/src/graphql.ts DELETED
@@ -1,56 +0,0 @@
1
- const _ = require('underscore');
2
- export default class Graphql {
3
- client: any;
4
- constructor(client){
5
- this.client = client;
6
- }
7
-
8
- async query(query: string){
9
- let url = this.client.getBaseRoute() + "/graphql";
10
- let body = {
11
- query: query
12
- };
13
- return await this.client.doFetch(url, {method: 'POST', body: JSON.stringify(body)});
14
- }
15
-
16
- async insert(objectName: string, data){
17
- let url = this.client.getBaseRoute() + "/graphql";
18
- let _data = data;
19
- if(!_.isString(_data)){
20
- _data = JSON.stringify(data)
21
- }
22
- let body = {
23
- query: `mutation {
24
- ${objectName}__insert(data:${_data})
25
- }`
26
- };
27
- console.log('insert body', body);
28
- return await this.client.doFetch(url, {method: 'POST', body: JSON.stringify(body)});
29
- }
30
-
31
- async update(objectName: string, _id: string, data){
32
- let url = this.client.getBaseRoute() + "/graphql";
33
- let _data = data;
34
- if(!_.isString(_data)){
35
- _data = JSON.stringify(data)
36
- }
37
- let body = {
38
- query: `mutation {
39
- ${objectName}__update(_id:"${_id}", data:${_data})
40
- }`
41
- };
42
- return await this.client.doFetch(url, {method: 'POST', body: JSON.stringify(body)});
43
- }
44
-
45
- async delete(objectName: string, _id: string){
46
- let url = this.client.getBaseRoute() + "/graphql";
47
- let body = {
48
- query: `mutation {
49
- ${objectName}__delete(_id:"${_id}")
50
- }`
51
- };
52
- return await this.client.doFetch(url, {method: 'POST', body: JSON.stringify(body)});
53
- }
54
-
55
-
56
- }
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
-
2
- import SteedosClient, {DEFAULT_LIMIT_AFTER, DEFAULT_LIMIT_BEFORE, HEADER_X_VERSION_ID} from './client4';
3
-
4
- export {
5
- SteedosClient, DEFAULT_LIMIT_AFTER, DEFAULT_LIMIT_BEFORE, HEADER_X_VERSION_ID,
6
- }
package/src/sobject.ts DELETED
@@ -1,125 +0,0 @@
1
- import { formatFiltersToODataQuery } from '@steedos/filters';
2
- import { buildQueryString } from './utils/helpers';
3
- import { Filters, Fields, Options, Record } from './types/sobject';
4
-
5
- const _ = require('underscore');
6
-
7
- export default class SObject {
8
- client: any;
9
- objectName: string;
10
- constructor(client, objectName){
11
- this.client = client;
12
- this.objectName = objectName;
13
- }
14
-
15
- private getFilter(filters: Filters){
16
- if(_.isArray(filters)){
17
- return formatFiltersToODataQuery(filters)
18
- }
19
- return filters;
20
- }
21
-
22
- private getSelect(fields){
23
- if(_.isArray(fields)){
24
- return fields.toString()
25
- }
26
- return fields;
27
- }
28
-
29
- private getQueryParams(filters: Filters, fields: Fields, options: Options){
30
- let params = Object.assign({}, options);
31
- const $filter = this.getFilter(filters);
32
- if($filter){
33
- params.$filter = $filter
34
- }
35
- const $select = this.getSelect(fields);
36
- if($select){
37
- params.$select = $select
38
- }
39
- return params;
40
- }
41
-
42
- /**
43
- * Find and fetch records which matches given conditions
44
- *
45
- * @param {String|Array} [filters] - filtering records
46
- * @param {String|Array} [fields] - Fields to fetch.
47
- * @param {Object} [options] - Query options.
48
- * @param {Number} [options.$top] - Maximum number of records the query will return.
49
- * @param {Number} [options.$skip] - Synonym of options.offset.
50
- * @param {String} [options.$orderby] - sorting.
51
- * @param {boolean} [options.$count] - count.
52
- * @returns {Promise<Array<Record>>}
53
- */
54
- async find(filters: Filters, fields: Fields, options: Options){
55
- let params = this.getQueryParams(filters, fields, options);
56
- let url = this.client.getBaseRoute() + "/api/v4/".concat(this.objectName) + buildQueryString(params);
57
- let result = await this.client.doFetch(url, {method: 'get'});
58
- return result.value
59
- }
60
-
61
- /**
62
- * TODO 根据条件查询数据,返回1条($top = 1)。
63
- * @param filters
64
- * @param fields
65
- * @param options
66
- * @returns {Promise<Record>}
67
- */
68
- async findOne(filters: Filters, fields: Fields, options: Options){
69
-
70
- }
71
-
72
- /**
73
- * TODO 根据id查询数据。
74
- * @param id
75
- * @param fields
76
- */
77
- async record(id: string, fields: Fields){
78
-
79
- }
80
-
81
- /**
82
- * TODO 根据ids查询数据。
83
- * @param ids
84
- * @param fields
85
- */
86
- async retrieve(ids: Array<string>, fields: Fields){
87
-
88
- }
89
-
90
- /**
91
- * TODO 写入数据,并返回新记录
92
- * @param doc
93
- */
94
- async insert(doc: Record){
95
-
96
- }
97
-
98
- /**
99
- * TODO 根据id,修改记录,并返回新记录
100
- * @param id
101
- * @param doc
102
- */
103
- async update(id: string, doc: Record){
104
-
105
- }
106
-
107
- /**
108
- * TODO 根据id, 删除记录
109
- * @param id
110
- */
111
- async delete(id: string){
112
-
113
- }
114
-
115
- /**
116
- * TODO 返回满足条件的记录数
117
- * @param filters
118
- */
119
- async count(filters: Filters){
120
-
121
- }
122
-
123
- // 预留
124
- // recent(){}
125
- }
@@ -1,38 +0,0 @@
1
- // I assume these are the loglevels
2
- export type logLevel = 'ERROR' | 'WARNING' | 'INFO';
3
-
4
- export type ClientResponse<T> = {
5
- response: Response;
6
- headers: Map<string, string>;
7
- data: T;
8
- };
9
-
10
- type ErrorOffline = {
11
- message: string;
12
- url: string;
13
- };
14
- type ErrorInvalidResponse = {
15
- intl: {
16
- id: string;
17
- defaultMessage: string;
18
- };
19
- };
20
- export type ErrorApi = {
21
- message: string;
22
- server_error_id: string;
23
- status_code: number;
24
- url: string;
25
- };
26
- export type Client4Error = ErrorOffline | ErrorInvalidResponse | ErrorApi;
27
-
28
- export type Options = {
29
- headers?: { [x: string]: string };
30
- method?: string;
31
- url?: string;
32
- credentials?: 'omit' | 'same-origin' | 'include';
33
- body?: any;
34
- };
35
-
36
- export type StatusOK = {
37
- status: 'OK';
38
- };
@@ -1,12 +0,0 @@
1
- export type ServerError = {
2
- server_error_id?: string;
3
- stack?: string;
4
- intl?: {
5
- id: string;
6
- defaultMessage: string;
7
- values?: any;
8
- };
9
- message: string;
10
- status_code?: number;
11
- url?: string;
12
- };
package/src/types/json.ts DELETED
@@ -1,25 +0,0 @@
1
- declare type Optional<T> = T | undefined;
2
-
3
- export interface Dictionary<T = unknown> {
4
- [key: string]: Optional<T>;
5
- }
6
-
7
- export declare type JsonPrimitive = null | boolean | number | string;
8
- /**
9
- * Any valid JSON collection value.
10
- */
11
- export declare type JsonCollection = JsonMap | JsonArray;
12
- /**
13
- * Any valid JSON value.
14
- */
15
- export declare type AnyJson = JsonPrimitive | JsonCollection;
16
- /**
17
- * Any JSON-compatible object.
18
- */
19
- export interface JsonMap extends Dictionary<AnyJson> {
20
- }
21
- /**
22
- * Any JSON-compatible array.
23
- */
24
- export interface JsonArray extends Array<AnyJson> {
25
- }
@@ -1,17 +0,0 @@
1
- import { JsonMap } from './json';
2
-
3
- export type Filters = string | Array<any>
4
-
5
- export type Fields = string | Array<string>
6
-
7
- export type Options = {
8
- $top?: Number,
9
- $skip?: Number,
10
- $orderby?: Number,
11
- $count?: boolean,
12
- $filter?: Filters,
13
- $select?: Fields
14
- }
15
-
16
- export type Record = JsonMap
17
-
@@ -1,19 +0,0 @@
1
- import {$ID, IDMappedObjects, RelationOneToMany, RelationOneToOne, Dictionary} from './utilities';
2
-
3
- export type Space = {
4
- _id: string;
5
- name: string;
6
- };
7
-
8
- export type SpaceUser = {
9
- _id: string
10
- space: string;
11
- user: string;
12
- };
13
-
14
- export type SpacesState = {
15
- currentSpaceId: string;
16
- spaces: IDMappedObjects<Space>;
17
- mySpaces: IDMappedObjects<Space>;
18
- mySpacesCount: number
19
- };
@@ -1,20 +0,0 @@
1
- import {$ID, IDMappedObjects, RelationOneToMany, RelationOneToOne, Dictionary} from './utilities';
2
-
3
- export type UserProfile = {
4
- _id: string;
5
- create_at: number;
6
- update_at: number;
7
- delete_at: number;
8
- username: string;
9
- password: string;
10
- email: string;
11
- email_verified: boolean;
12
- name: string;
13
- failed_attempts: number;
14
- locale: string;
15
- };
16
-
17
- export type UsersState = {
18
- currentUserId: string;
19
- users: IDMappedObjects<UserProfile>;
20
- };
@@ -1,28 +0,0 @@
1
- export type $ID<E extends {_id: string}> = E['_id'];
2
- export type $UserID<E extends {user_id: string}> = E['user_id'];
3
- export type $Name<E extends {name: string}> = E['name'];
4
- export type $Username<E extends {username: string}> = E['username'];
5
- export type $Email<E extends {email: string}> = E['email'];
6
- export type RelationOneToOne<E extends {_id: string}, T> = {
7
- [x in $ID<E>]: T;
8
- };
9
- export type RelationOneToMany<E1 extends {_id: string}, E2 extends {_id: string}> = {
10
- [x in $ID<E1>]: Array<$ID<E2>>;
11
- };
12
- export type IDMappedObjects<E extends {_id: string}> = RelationOneToOne<E, E>;
13
- export type UserIDMappedObjects<E extends {user_id: string}> = {
14
- [x in $UserID<E>]: E;
15
- };
16
- export type NameMappedObjects<E extends {name: string}> = {
17
- [x in $Name<E>]: E;
18
- };
19
- export type UsernameMappedObjects<E extends {username: string}> = {
20
- [x in $Username<E>]: E;
21
- };
22
- export type EmailMappedObjects<E extends {email: string}> = {
23
- [x in $Email<E>]: E;
24
- };
25
-
26
- export type Dictionary<T> = {
27
- [key: string]: T;
28
- };
@@ -1,20 +0,0 @@
1
- import {Dictionary} from '../types/utilities';
2
-
3
- export function buildQueryString(parameters: Dictionary<any>): string {
4
- const keys = Object.keys(parameters);
5
- if (keys.length === 0) {
6
- return '';
7
- }
8
-
9
- let query = '?';
10
- for (let i = 0; i < keys.length; i++) {
11
- const key = keys[i];
12
- query += key + '=' + encodeURIComponent(parameters[key]);
13
-
14
- if (i < keys.length - 1) {
15
- query += '&';
16
- }
17
- }
18
-
19
- return query;
20
- }
@@ -1,53 +0,0 @@
1
- // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2
- // See LICENSE.txt for license information.
3
- // @flow
4
-
5
- // Given a URL from an API request, return a URL that has any parts removed that are either sensitive or that would
6
- // prevent properly grouping the messages in Sentry.
7
- export function cleanUrlForLogging(baseUrl, apiUrl) {
8
- let url = apiUrl;
9
-
10
- // Trim the host name
11
- url = url.substring(baseUrl.length);
12
-
13
- // Filter the query string
14
- const index = url.indexOf('?');
15
- if (index !== -1) {
16
- url = url.substring(0, index);
17
- }
18
-
19
- // A non-exhaustive whitelist to exclude parts of the URL that are unimportant (eg IDs) or may be sentsitive
20
- // (eg email addresses). We prefer filtering out fields that aren't recognized because there should generally
21
- // be enough left over for debugging.
22
- //
23
- // Note that new API routes don't need to be added here since this shouldn't be happening for newly added routes.
24
- const whitelist = [
25
- 'api', 'v4', 'users', 'teams', 'scheme', 'name', 'members', 'channels', 'posts', 'reactions', 'commands',
26
- 'files', 'preferences', 'hooks', 'incoming', 'outgoing', 'oauth', 'apps', 'emoji', 'brand', 'image',
27
- 'data_retention', 'jobs', 'plugins', 'roles', 'system', 'timezones', 'schemes', 'redirect_location', 'patch',
28
- 'mfa', 'password', 'reset', 'send', 'active', 'verify', 'terms_of_service', 'login', 'logout', 'ids',
29
- 'usernames', 'me', 'username', 'email', 'default', 'sessions', 'revoke', 'all', 'audits', 'device', 'status',
30
- 'search', 'switch', 'authorized', 'authorize', 'deauthorize', 'tokens', 'disable', 'enable', 'exists', 'unread',
31
- 'invite', 'batch', 'stats', 'import', 'schemeRoles', 'direct', 'group', 'convert', 'view', 'search_autocomplete',
32
- 'thread', 'info', 'flagged', 'pinned', 'pin', 'unpin', 'opengraph', 'actions', 'thumbnail', 'preview', 'link',
33
- 'delete', 'logs', 'ping', 'config', 'client', 'license', 'websocket', 'webrtc', 'token', 'regen_token',
34
- 'autocomplete', 'execute', 'regen_secret', 'policy', 'type', 'cancel', 'reload', 'environment', 's3_test', 'file',
35
- 'caches', 'invalidate', 'database', 'recycle', 'compliance', 'reports', 'cluster', 'ldap', 'test', 'sync', 'saml',
36
- 'certificate', 'public', 'private', 'idp', 'elasticsearch', 'purge_indexes', 'analytics', 'old', 'webapp', 'fake',
37
- ];
38
-
39
- url = url.split('/').map((part) => {
40
- if (part !== '' && whitelist.indexOf(part) === -1) {
41
- return '<filtered>';
42
- }
43
-
44
- return part;
45
- }).join('/');
46
-
47
- if (index !== -1) {
48
- // Add this on afterwards since it wouldn't pass the whitelist
49
- url += '?<filtered>';
50
- }
51
-
52
- return url;
53
- }
package/test/init.js DELETED
@@ -1,8 +0,0 @@
1
- /*
2
- * Copyright (c) 2018, salesforce.com, inc.
3
- * All rights reserved.
4
- * SPDX-License-Identifier: BSD-3-Clause
5
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
- */
7
- const path = require('path');
8
- process.env.TS_NODE_PROJECT = path.resolve('test/tsconfig.json');
package/test/mocha.opts DELETED
@@ -1,6 +0,0 @@
1
- --require test/init.js
2
- --require ts-node/register
3
- --watch-extensions ts
4
- --recursive
5
- --reporter spec
6
- --timeout 5000
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "../../../node_modules/@salesforce/dev-config/tsconfig",
3
- "include": ["unit/**/*.ts", "../node_modules/@types/**/*.d.ts"],
4
- "compilerOptions": {
5
- "noEmit": true,
6
- "strict": false,
7
- "noUnusedLocals": false,
8
- "emitDecoratorMetadata": true,
9
- "experimentalDecorators": true,
10
- "lib": [
11
- "dom",
12
- "dom.iterable",
13
- "esnext"
14
- ],
15
- }
16
- }
package/test/tslint.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "../tslint.json",
3
- "rules": {
4
- "no-unused-expression": false
5
- }
6
- }
@@ -1,41 +0,0 @@
1
- import { SteedosClient } from '../../src';
2
- import { expect } from 'chai';
3
-
4
- const client = new SteedosClient();
5
- //设置服务地址
6
- client.setUrl('http://127.0.0.1:8088');
7
-
8
- client.logToConsole = true;
9
-
10
- before(async function () {
11
- let userProfile: any = await client.login('username', 'password');
12
- //设置认证信息
13
- client.setToken(userProfile.token);
14
- //设置所属工作区
15
- client.setSpaceId("w3TT34PfeFjsoqsdx");
16
- });
17
-
18
- const testId = '_graphqlTestRecordId';
19
-
20
- describe('Test Graphql: ', () => {
21
- it('query', async () => {
22
- const results: any = await client.graphql.query(`
23
- {
24
- pages:community_page{
25
- _id,
26
- name,
27
- path,
28
- title,
29
- schema
30
- }
31
- }
32
- `)
33
- console.log('results', results);
34
- expect(results.data.pages.length).to.gt(0);
35
- });
36
- it('insert', async () => {
37
- const results: any = await client.graphql.insert('community_page', {name: '_graphqlTestRecordId'})
38
- console.log('results', results);
39
- expect(results.data.pages.length).to.gt(0);
40
- });
41
- });
@@ -1,25 +0,0 @@
1
- import { SteedosClient } from '../../src';
2
- import { expect } from 'chai';
3
-
4
- const client = new SteedosClient();
5
- //设置服务地址
6
- client.setUrl('http://192.168.3.2:5000/test');
7
-
8
- before(async function () {
9
- let userProfile: any = await client.login('chenzhipei@hotoa.com', '1');
10
- //设置认证信息
11
- client.setToken(userProfile.token);
12
- //设置所属工作区
13
- client.setSpaceId("jYgTB7xC3ScqmXYdW");
14
- });
15
-
16
- describe('Test SObject: ', () => {
17
- it('find', async () => {
18
- const results: Array<any> = await client.sobject('accounts').find(['name', '=', 'test1'], ['name'], {$top: 2, $count: true})
19
- expect(results.length).to.gt(0);
20
- });
21
- it('findOne', async () => {
22
- //TODO
23
- expect('TODO').to.equal('TODO');
24
- });
25
- });
package/tsconfig.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "sourceMap": true,
4
- "module": "CommonJS",
5
- "target": "es5",
6
- "outDir": "./lib",
7
- "lib": [
8
- "dom",
9
- "dom.iterable",
10
- "esnext"
11
- ],
12
- "jsx": "react",
13
- "rootDir": "src",
14
- "moduleResolution": "node",
15
- "noImplicitReturns": true,
16
- "noImplicitThis": false,
17
- "noImplicitAny": false,
18
- "strictNullChecks": true,
19
- "skipLibCheck": true,
20
- "esModuleInterop": true,
21
- "noEmit": false,
22
- //"declaration": true,
23
- "allowJs": true,
24
- "isolatedModules": false,
25
- "allowSyntheticDefaultImports": true,
26
- "strict": true,
27
- "forceConsistentCasingInFileNames": true,
28
- "downlevelIteration": true,
29
- "resolveJsonModule": true
30
- },
31
- "include": [
32
- "src",
33
- ],
34
- }