@api-client/core 0.3.6 → 0.3.9
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/build/browser.d.ts +5 -1
- package/build/browser.js +7 -0
- package/build/browser.js.map +1 -1
- package/build/index.d.ts +6 -2
- package/build/index.js +7 -0
- package/build/index.js.map +1 -1
- package/build/src/lib/calculators/DataCalculator.d.ts +27 -0
- package/build/src/lib/calculators/DataCalculator.js +88 -0
- package/build/src/lib/calculators/DataCalculator.js.map +1 -0
- package/build/src/lib/parsers/UrlEncoder.d.ts +51 -0
- package/build/src/lib/parsers/UrlEncoder.js +74 -0
- package/build/src/lib/parsers/UrlEncoder.js.map +1 -0
- package/build/src/lib/parsers/UrlParser.d.ts +104 -0
- package/build/src/lib/parsers/UrlParser.js +189 -0
- package/build/src/lib/parsers/UrlParser.js.map +1 -0
- package/build/src/lib/parsers/UrlValueParser.d.ts +92 -0
- package/build/src/lib/parsers/UrlValueParser.js +172 -0
- package/build/src/lib/parsers/UrlValueParser.js.map +1 -0
- package/build/src/models/User.d.ts +25 -9
- package/build/src/runtime/store/StoreSdk.d.ts +12 -0
- package/build/src/runtime/store/StoreSdk.js +57 -0
- package/build/src/runtime/store/StoreSdk.js.map +1 -1
- package/build/src/testing/TestCliHelper.d.ts +7 -1
- package/build/src/testing/TestCliHelper.js +10 -1
- package/build/src/testing/TestCliHelper.js.map +1 -1
- package/package.json +2 -2
- package/src/lib/calculators/DataCalculator.ts +91 -0
- package/src/lib/parsers/UrlEncoder.ts +74 -0
- package/src/lib/parsers/UrlParser.ts +201 -0
- package/src/lib/parsers/UrlValueParser.ts +211 -0
- package/src/models/User.ts +26 -9
- package/src/runtime/store/StoreSdk.ts +57 -0
- package/src/testing/TestCliHelper.ts +12 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
export interface IUrlValueParserOptions {
|
|
2
|
+
/**
|
|
3
|
+
* A query string delimiter to use when processing query parameters.
|
|
4
|
+
*/
|
|
5
|
+
queryDelimiter?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface DataValues {
|
|
9
|
+
/**
|
|
10
|
+
* A protocol value in format `protocol` + ':'
|
|
11
|
+
*/
|
|
12
|
+
protocol?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The authority part of the URL value
|
|
15
|
+
*/
|
|
16
|
+
host?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Path part of the URL.
|
|
19
|
+
*/
|
|
20
|
+
path?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Anchor part of the URL.
|
|
23
|
+
*/
|
|
24
|
+
anchor?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Search part of the URL.
|
|
27
|
+
*/
|
|
28
|
+
search?: string;
|
|
29
|
+
opts?: IUrlValueParserOptions | undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Implements logic for parsing URL string.
|
|
34
|
+
*/
|
|
35
|
+
export class UrlValueParser {
|
|
36
|
+
protected __data: DataValues;
|
|
37
|
+
|
|
38
|
+
constructor(opts?: IUrlValueParserOptions) {
|
|
39
|
+
this.__data = {};
|
|
40
|
+
this.opts = opts;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @returns Class options.
|
|
45
|
+
*/
|
|
46
|
+
get opts(): IUrlValueParserOptions {
|
|
47
|
+
return this.__data.opts || {
|
|
48
|
+
queryDelimiter: '&',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Sets parser options.
|
|
54
|
+
* Unknown options are ignored.
|
|
55
|
+
*/
|
|
56
|
+
set opts(opts: IUrlValueParserOptions | undefined) {
|
|
57
|
+
const options = (opts || {}) as IUrlValueParserOptions;
|
|
58
|
+
this.__data.opts = {
|
|
59
|
+
queryDelimiter: options.queryDelimiter || '&'
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Returns protocol value in format `protocol` + ':'
|
|
65
|
+
*
|
|
66
|
+
* @param value URL to parse.
|
|
67
|
+
* @return Value of the protocol or undefined if value not set
|
|
68
|
+
*/
|
|
69
|
+
protected _parseProtocol(value: string): string | undefined {
|
|
70
|
+
if (!value) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
const delimiterIndex = value.indexOf('://');
|
|
74
|
+
if (delimiterIndex !== -1) {
|
|
75
|
+
return value.substring(0, delimiterIndex + 1);
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets a host value from the url.
|
|
82
|
+
* It reads the whole authority value of given `value`. It doesn't parses it
|
|
83
|
+
* to host, port and
|
|
84
|
+
* credentials parts. For URL panel it's enough.
|
|
85
|
+
*
|
|
86
|
+
* @param value The URL to parse
|
|
87
|
+
* @return Value of the host or undefined.
|
|
88
|
+
*/
|
|
89
|
+
protected _parseHost(value: string): string | undefined {
|
|
90
|
+
if (!value) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
let result = value;
|
|
94
|
+
const delimiterIndex = result.indexOf('://');
|
|
95
|
+
if (delimiterIndex !== -1) {
|
|
96
|
+
result = result.substring(delimiterIndex + 3);
|
|
97
|
+
}
|
|
98
|
+
if (!result) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
// We don't need specifics here (username, password, port)
|
|
102
|
+
const host = result.split('/')[0];
|
|
103
|
+
return host;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Parses the path part of the URL.
|
|
108
|
+
*
|
|
109
|
+
* @param value URL value
|
|
110
|
+
* @returns Path part of the URL
|
|
111
|
+
*/
|
|
112
|
+
protected _parsePath(value: string): string | undefined {
|
|
113
|
+
if (!value) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
let result = value;
|
|
117
|
+
const isBasePath = result[0] === '/';
|
|
118
|
+
if (!isBasePath) {
|
|
119
|
+
const index = result.indexOf('://');
|
|
120
|
+
if (index !== -1) {
|
|
121
|
+
result = result.substring(index + 3);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
let index = result.indexOf('?');
|
|
125
|
+
if (index !== -1) {
|
|
126
|
+
result = result.substring(0, index);
|
|
127
|
+
}
|
|
128
|
+
index = result.indexOf('#');
|
|
129
|
+
if (index !== -1) {
|
|
130
|
+
result = result.substring(0, index);
|
|
131
|
+
}
|
|
132
|
+
const lastIsSlash = result[result.length - 1] === '/';
|
|
133
|
+
const parts = result.split('/').filter((part) => !!part);
|
|
134
|
+
if (!isBasePath) {
|
|
135
|
+
parts.shift();
|
|
136
|
+
}
|
|
137
|
+
let path = `/${ parts.join('/')}`;
|
|
138
|
+
if (lastIsSlash && parts.length > 1) {
|
|
139
|
+
path += '/';
|
|
140
|
+
}
|
|
141
|
+
return path;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Returns query parameters string (without the '?' sign) as a whole.
|
|
146
|
+
*
|
|
147
|
+
* @param value The URL to parse
|
|
148
|
+
* @returns Value of the search string or undefined.
|
|
149
|
+
*/
|
|
150
|
+
protected _parseSearch(value: string): string | undefined {
|
|
151
|
+
if (!value) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
let index = value.indexOf('?');
|
|
155
|
+
if (index === -1) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
const result = value.substring(index + 1);
|
|
159
|
+
index = result.indexOf('#');
|
|
160
|
+
if (index === -1) {
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
return result.substring(0, index);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Reads a value of the anchor (or hash) parameter without the `#` sign.
|
|
168
|
+
*
|
|
169
|
+
* @param value The URL to parse
|
|
170
|
+
* @returns Value of the anchor (hash) or undefined.
|
|
171
|
+
*/
|
|
172
|
+
protected _parseAnchor(value: string): string | undefined {
|
|
173
|
+
if (!value) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const index = value.indexOf('#');
|
|
177
|
+
if (index === -1) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
return value.substring(index + 1);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Returns an array of items where each item is an array where first
|
|
185
|
+
* item is param name and second is it's value. Both always strings.
|
|
186
|
+
*
|
|
187
|
+
* @param search Parsed search parameter
|
|
188
|
+
* @returns Always returns an array.
|
|
189
|
+
*/
|
|
190
|
+
protected _parseSearchParams(search?: string): string[][] {
|
|
191
|
+
const result: string[][] = [];
|
|
192
|
+
if (!search) {
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
const parts = search.split(this.opts.queryDelimiter as string);
|
|
196
|
+
parts.forEach((item) => {
|
|
197
|
+
const _part = ['', ''];
|
|
198
|
+
const _params = item.split('=');
|
|
199
|
+
let _name = _params.shift();
|
|
200
|
+
if (!_name && _name !== '') {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
_name = _name.trim();
|
|
204
|
+
const _value = _params.join('=').trim();
|
|
205
|
+
_part[0] = _name;
|
|
206
|
+
_part[1] = _value;
|
|
207
|
+
result.push(_part);
|
|
208
|
+
});
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
}
|
package/src/models/User.ts
CHANGED
|
@@ -64,15 +64,7 @@ export interface IUserPicture {
|
|
|
64
64
|
|
|
65
65
|
export const Kind = 'ARC#User';
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
* Represents a user in the system.
|
|
69
|
-
* This can be embedded in various situations like project's revision history,
|
|
70
|
-
* ACL, Authorization, etc.
|
|
71
|
-
*
|
|
72
|
-
* Note, the store implementation may have additional fields that support external
|
|
73
|
-
* identity providers. However, this is not exposed to the user through the API.
|
|
74
|
-
*/
|
|
75
|
-
export interface IUser {
|
|
67
|
+
interface BaseUser {
|
|
76
68
|
/**
|
|
77
69
|
* Data store key of the user.
|
|
78
70
|
*/
|
|
@@ -103,6 +95,21 @@ export interface IUser {
|
|
|
103
95
|
provider?: unknown;
|
|
104
96
|
}
|
|
105
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Represents a user in the system.
|
|
100
|
+
* This can be embedded in various situations like project's revision history,
|
|
101
|
+
* ACL, Authorization, etc.
|
|
102
|
+
*
|
|
103
|
+
* Note, the store implementation may have additional fields that support external
|
|
104
|
+
* identity providers. However, this is not exposed to the user through the API.
|
|
105
|
+
*/
|
|
106
|
+
export interface IUser extends BaseUser {
|
|
107
|
+
/**
|
|
108
|
+
* Optional metadata related to the auth provider.
|
|
109
|
+
*/
|
|
110
|
+
provider?: unknown;
|
|
111
|
+
}
|
|
112
|
+
|
|
106
113
|
/**
|
|
107
114
|
* This object may be created for each user in the system.
|
|
108
115
|
* It describes to which spaces user has access to.
|
|
@@ -118,3 +125,13 @@ export interface IUserSpaces {
|
|
|
118
125
|
*/
|
|
119
126
|
user: string;
|
|
120
127
|
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* An abstract user object that contains access information to a space.
|
|
131
|
+
*/
|
|
132
|
+
export interface ISpaceUser extends BaseUser {
|
|
133
|
+
/**
|
|
134
|
+
* The level that the user has access to.
|
|
135
|
+
*/
|
|
136
|
+
level: AccessControlLevel;
|
|
137
|
+
}
|
|
@@ -474,6 +474,36 @@ class SpacesSdk extends SdkBase {
|
|
|
474
474
|
throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Lists uses having access to the user space.
|
|
480
|
+
*
|
|
481
|
+
* @param key The user space key
|
|
482
|
+
*/
|
|
483
|
+
async listUsers(key: string): Promise<IListResponse> {
|
|
484
|
+
const { token } = this.sdk;
|
|
485
|
+
const url = this.sdk.getUrl(`/spaces/${key}/users`);
|
|
486
|
+
const result = await this.sdk.http.get(url.toString(), { token });
|
|
487
|
+
this.inspectCommonStatusCodes(result.status);
|
|
488
|
+
const E_PREFIX = 'Unable to list users in the space. ';
|
|
489
|
+
if (result.status !== 200) {
|
|
490
|
+
this.logInvalidResponse(result);
|
|
491
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
|
|
492
|
+
}
|
|
493
|
+
if (!result.body) {
|
|
494
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
|
|
495
|
+
}
|
|
496
|
+
let data: IListResponse;
|
|
497
|
+
try {
|
|
498
|
+
data = JSON.parse(result.body);
|
|
499
|
+
} catch (e) {
|
|
500
|
+
throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
|
|
501
|
+
}
|
|
502
|
+
if (!Array.isArray(data.data)) {
|
|
503
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_UNKNOWN}.`);
|
|
504
|
+
}
|
|
505
|
+
return data;
|
|
506
|
+
}
|
|
477
507
|
}
|
|
478
508
|
|
|
479
509
|
class HttpClient extends SdkBase {
|
|
@@ -835,4 +865,31 @@ class UsersSdk extends SdkBase {
|
|
|
835
865
|
}
|
|
836
866
|
return data;
|
|
837
867
|
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Reads a user information from the store.
|
|
871
|
+
* @param key The user key.
|
|
872
|
+
* @returns The user object
|
|
873
|
+
*/
|
|
874
|
+
async read(key: string): Promise<IUser> {
|
|
875
|
+
const { token } = this.sdk;
|
|
876
|
+
const url = this.sdk.getUrl(`/users/${key}`);
|
|
877
|
+
const result = await this.sdk.http.get(url.toString(), { token });
|
|
878
|
+
this.inspectCommonStatusCodes(result.status);
|
|
879
|
+
const E_PREFIX = 'Unable to read the user info. ';
|
|
880
|
+
if (result.status !== 200) {
|
|
881
|
+
this.logInvalidResponse(result);
|
|
882
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_STATUS}${result.status}`);
|
|
883
|
+
}
|
|
884
|
+
if (!result.body) {
|
|
885
|
+
throw new Error(`${E_PREFIX}${E_RESPONSE_NO_VALUE}`);
|
|
886
|
+
}
|
|
887
|
+
let data: IUser;
|
|
888
|
+
try {
|
|
889
|
+
data = JSON.parse(result.body);
|
|
890
|
+
} catch (e) {
|
|
891
|
+
throw new Error(`${E_PREFIX}${E_INVALID_JSON}.`);
|
|
892
|
+
}
|
|
893
|
+
return data;
|
|
894
|
+
}
|
|
838
895
|
}
|
|
@@ -4,6 +4,12 @@ export interface ITestRunCommandOptions {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export class TestCliHelper {
|
|
7
|
+
/**
|
|
8
|
+
* The globally set test timeout.
|
|
9
|
+
* @default 2000 The mocha default test timeout.
|
|
10
|
+
*/
|
|
11
|
+
static testTimeout = 2000;
|
|
12
|
+
|
|
7
13
|
static cleanTerminalOutput(s: string): string {
|
|
8
14
|
let result = s.trim();
|
|
9
15
|
result = result.replace(/[^\x20-\x7E\n]/gm, '');
|
|
@@ -37,9 +43,10 @@ export class TestCliHelper {
|
|
|
37
43
|
* ```
|
|
38
44
|
*
|
|
39
45
|
* @param fn The function to execute.
|
|
46
|
+
* @param timeout The test timeout. After this time the output is reset.
|
|
40
47
|
* @returns The terminal output.
|
|
41
48
|
*/
|
|
42
|
-
static async grabOutput(fn: () => Promise<void
|
|
49
|
+
static async grabOutput(fn: () => Promise<void>, timeout=TestCliHelper.testTimeout): Promise<string> {
|
|
43
50
|
const messages: string[] = [];
|
|
44
51
|
function noop(): void {
|
|
45
52
|
//
|
|
@@ -64,11 +71,15 @@ export class TestCliHelper {
|
|
|
64
71
|
process.stderr.write = messageHandler;
|
|
65
72
|
console.clear = noop;
|
|
66
73
|
|
|
74
|
+
const handle = setTimeout(() => stop(), timeout);
|
|
75
|
+
|
|
67
76
|
try {
|
|
68
77
|
await fn();
|
|
69
78
|
stop();
|
|
79
|
+
clearTimeout(handle);
|
|
70
80
|
} catch (e) {
|
|
71
81
|
stop();
|
|
82
|
+
clearTimeout(handle);
|
|
72
83
|
throw e;
|
|
73
84
|
}
|
|
74
85
|
return messages.join('');
|